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<string, string> _engText;
private Dictionary<string, string> _jpnText;
private Dictionary<string, Button> _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<string, Button>
{
{ "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<string, string> LoadButtonText(string path)
{
var result = new Dictionary<string, string>();
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);
}
}