diff --git a/program/MainWindow.cs b/program/MainWindow.cs new file mode 100644 index 0000000..e4f74dd --- /dev/null +++ b/program/MainWindow.cs @@ -0,0 +1,192 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Gtk; +using UI = Gtk.Builder.ObjectAttribute; + +public class MainWindow : Window +{ + [UI] private Button Option1Button = null; + [UI] private Button Option2Button = null; + [UI] private Button Option3Button = null; + [UI] private Switch LanguageSwitch = null; + [UI] private Label LanguageLabel = null; + [UI] private Button CloseButton = null; + + private CssProvider _scaleCssProvider; + private CssProvider _languageCssProvider; + private int _lastAppliedWidth = -1; + + private const int BaseWidth = 1920; + private const int BaseHeight = 1080; + + private const string EngCssPath = "lang_eng.css"; + private const string JpnCssPath = "lang_jpn.css"; + + private Dictionary _engText; + private Dictionary _jpnText; + private Dictionary _buttonsById; + + public MainWindow() : this(CreateBuilder()) { } + + private static Builder CreateBuilder() + { + var builder = new Builder(); + builder.AddFromFile("homepage.glade"); + return builder; + } + + private MainWindow(Builder builder) : base(builder.GetObject("SplashWindow").Handle) + { + builder.Autoconnect(this); + + _scaleCssProvider = new CssProvider(); + _languageCssProvider = new CssProvider(); + + StyleContext.AddProviderForScreen(Gdk.Screen.Default, _scaleCssProvider, 600); + StyleContext.AddProviderForScreen(Gdk.Screen.Default, _languageCssProvider, 600); + + this.Fullscreen(); + + Option1Button.Clicked += OnNormalSessionClicked; + Option2Button.Clicked += OnPositionRecordingClicked; + Option3Button.Clicked += OnExamModeClicked; + CloseButton.Clicked += OnCloseClicked; + LanguageSwitch.AddNotification("active", OnLanguageSwitchNotify); + + DeleteEvent += OnDeleteEvent; + SizeAllocated += OnWindowSizeAllocated; + + _buttonsById = new Dictionary + { + { "Option1Button", Option1Button }, + { "Option2Button", Option2Button }, + { "Option3Button", Option3Button }, + { "CloseButton", CloseButton }, + }; + + // CSS ID selectors (#Option1Button etc.) need the widget Name set explicitly + foreach (var kvp in _buttonsById) + kvp.Value.Name = kvp.Key; + + _engText = LoadButtonText("info_eng.csv"); + _jpnText = LoadButtonText("info_jpn.csv"); + + ApplyLanguage(LanguageSwitch.Active); + } + + private Dictionary LoadButtonText(string path) + { + var result = new Dictionary(); + + if (!File.Exists(path)) + { + Console.WriteLine($"Warning: text file not found: {path}"); + return result; + } + + var lines = File.ReadAllLines(path); + for (int i = 1; i < lines.Length; i++) // skip header row + { + var line = lines[i].Trim(); + if (string.IsNullOrEmpty(line)) continue; + + var parts = line.Split(new[] { ',' }, 2); // split into max 2 pieces, in case text has commas + if (parts.Length < 2) continue; + + result[parts[0]] = parts[1]; + } + + return result; + } + + private void ApplyLanguage(bool isEnglish) + { + var text = isEnglish ? _engText : _jpnText; + string cssPath = isEnglish ? EngCssPath : JpnCssPath; + + foreach (var kvp in _buttonsById) + { + if (text.TryGetValue(kvp.Key, out var buttonText)) + kvp.Value.Label = buttonText; + } + + if (File.Exists(cssPath)) + { + _languageCssProvider.LoadFromPath(cssPath); + } + else + { + Console.WriteLine($"Warning: CSS file not found: {cssPath}"); + } + + LanguageLabel.Text = isEnglish ? "あ" : "A"; + } + private void OnWindowSizeAllocated(object o, SizeAllocatedArgs args) + { + int width = args.Allocation.Width; + int height = args.Allocation.Height; + + if (width == _lastAppliedWidth) return; + _lastAppliedWidth = width; + + double scaleX = (double)width / BaseWidth; + double scaleY = (double)height / BaseHeight; + double scale = Math.Min(scaleX, scaleY); + + ApplyScale(scale); + } + + private void ApplyScale(double scale) + { + int fontSize = Math.Max(10, (int)(20 * scale)); + int buttonPadV = Math.Max(4, (int)(12 * scale)); + int buttonPadH = Math.Max(8, (int)(24 * scale)); + + string css = $@" + grid, label, button, switch {{ + font-size: {fontSize}px; + }} + button {{ + padding: {buttonPadV}px {buttonPadH}px; + }} + switch {{ + min-width: {40 * scale}px; + min-height: {24 * scale}px; + }} + "; + + _scaleCssProvider.LoadFromData(css); + } + + private void OnDeleteEvent(object sender, DeleteEventArgs a) + { + Application.Quit(); + a.RetVal = true; + } + + private void OnNormalSessionClicked(object sender, EventArgs e) + { + Console.WriteLine("Normal Session selected"); + } + + private void OnPositionRecordingClicked(object sender, EventArgs e) + { + Console.WriteLine("Position Recording Mode selected"); + } + + private void OnExamModeClicked(object sender, EventArgs e) + { + Console.WriteLine("Exam Mode selected"); + } + + private void OnCloseClicked(object sender, EventArgs e) + { + Application.Quit(); + } + + private void OnLanguageSwitchNotify(object o, GLib.NotifyArgs args) + { + ApplyLanguage(LanguageSwitch.Active); + } +} \ No newline at end of file diff --git a/program/homepage.glade b/program/homepage.glade new file mode 100644 index 0000000..dca2529 --- /dev/null +++ b/program/homepage.glade @@ -0,0 +1,175 @@ + + + + + + False + EARS + + + + True + False + 3 + 5 + + + Normal Session + True + True + True + 50 + 50 + True + True + + + 1 + 1 + + + + + Position Recording Mode + True + True + True + 50 + 50 + True + True + + + 1 + 2 + + + + + Exam Mode + True + True + True + 50 + 50 + True + True + + + 1 + 3 + + + + + True + True + True + + + 3 + 0 + + + + + True + False + Language + + + 2 + 0 + + + + + Close + True + True + True + True + + + 4 + 4 + + + + + Settings + True + True + True + + + 4 + 3 + + + + + True + True + 6 + + + 4 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/program/homepage.glade~ b/program/homepage.glade~ new file mode 100644 index 0000000..dca2529 --- /dev/null +++ b/program/homepage.glade~ @@ -0,0 +1,175 @@ + + + + + + False + EARS + + + + True + False + 3 + 5 + + + Normal Session + True + True + True + 50 + 50 + True + True + + + 1 + 1 + + + + + Position Recording Mode + True + True + True + 50 + 50 + True + True + + + 1 + 2 + + + + + Exam Mode + True + True + True + 50 + 50 + True + True + + + 1 + 3 + + + + + True + True + True + + + 3 + 0 + + + + + True + False + Language + + + 2 + 0 + + + + + Close + True + True + True + True + + + 4 + 4 + + + + + Settings + True + True + True + + + 4 + 3 + + + + + True + True + 6 + + + 4 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/program/info_eng.csv b/program/info_eng.csv new file mode 100644 index 0000000..a9c11e2 --- /dev/null +++ b/program/info_eng.csv @@ -0,0 +1,5 @@ +ButtonId,Text +Option1Button,Normal Session +Option2Button,Position Recording Mode +Option3Button,Exam Mode +CloseButton,Close \ No newline at end of file diff --git a/program/info_jpn.csv b/program/info_jpn.csv new file mode 100644 index 0000000..9273e75 --- /dev/null +++ b/program/info_jpn.csv @@ -0,0 +1,5 @@ +ButtonId,Text +Option1Button,通常セッション +Option2Button,位置記録モード +Option3Button,試験モード +CloseButton,閉じる \ No newline at end of file diff --git a/program/lang_eng.css b/program/lang_eng.css new file mode 100644 index 0000000..89a9bc2 --- /dev/null +++ b/program/lang_eng.css @@ -0,0 +1,27 @@ +#Option1Button { + font-family: 'Sans'; + font-size: 20px; + font-weight: normal; + font-style: normal; +} + +#Option2Button { + font-family: 'Sans'; + font-size: 20px; + font-weight: normal; + font-style: normal; +} + +#Option3Button { + font-family: 'Sans'; + font-size: 20px; + font-weight: normal; + font-style: normal; +} + +#CloseButton { + font-family: 'Sans'; + font-size: 18px; + font-weight: bold; + font-style: normal; +} \ No newline at end of file diff --git a/program/lang_jpn.css b/program/lang_jpn.css new file mode 100644 index 0000000..6916073 --- /dev/null +++ b/program/lang_jpn.css @@ -0,0 +1,27 @@ +#Option1Button { + font-family: 'Noto Sans JP'; + font-size: 20px; + font-weight: normal; + font-style: normal; +} + +#Option2Button { + font-family: 'Noto Sans JP'; + font-size: 20px; + font-weight: normal; + font-style: normal; +} + +#Option3Button { + font-family: 'Noto Sans JP'; + font-size: 20px; + font-weight: normal; + font-style: normal; +} + +#CloseButton { + font-family: 'Noto Sans JP'; + font-size: 18px; + font-weight: bold; + font-style: normal; +} \ No newline at end of file diff --git a/program/program.cs b/program/program.cs new file mode 100644 index 0000000..f9db539 --- /dev/null +++ b/program/program.cs @@ -0,0 +1,16 @@ +using System; +using Gtk; + +class Program +{ + [STAThread] + static void Main(string[] args) + { + Application.Init(); + + var app = new MainWindow(); + app.ShowAll(); + + Application.Run(); + } +} \ No newline at end of file diff --git a/program/style.css b/program/style.css new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/program/style.css