diff --git a/program/MainWindow.cs b/program/MainWindow.cs index 28cdc98..e1f6e50 100644 --- a/program/MainWindow.cs +++ b/program/MainWindow.cs @@ -68,7 +68,7 @@ private static Builder CreateBuilder() { var builder = new Builder(); - builder.AddFromFile("homepageallv7.glade"); + builder.AddFromFile("homepageallv8.glade"); return builder; } diff --git a/program/MapWindow.cs b/program/MapWindow.cs index f1ef284..cd4b508 100644 --- a/program/MapWindow.cs +++ b/program/MapWindow.cs @@ -107,6 +107,14 @@ [UI] private Button SoundTestButton = null; [UI] private CheckButton BlackAudioCheck = null; [UI] private Label JacketSizeLabel = null; + // For new UI + [UI] private DrawingArea HeartWaveArea = null; + [UI] private DrawingArea BreathWaveArea = null; + [UI] private Label MapContactLabel = null; + [UI] private Label MapPointHeader = null; + [UI] private Label HeartWaveHeader = null; + [UI] private Label BreathWaveHeader = null; + [UI] private Button MapExplainButton = null; private readonly Language _lang; // private readonly SoundLooper _sound = new SoundLooper(); @@ -195,6 +203,14 @@ foreach (var w in mapWidgets) if (w != null) w.StyleContext.AddClass("mappage"); + AddClass(MapTitleLabel, "map-title"); + AddClass(MapContactLabel, "contact-chip"); + AddClass(MapPointHeader, "panel-header"); + AddClass(HeartWaveHeader, "panel-header"); + AddClass(BreathWaveHeader, "panel-header"); + AddClass(MapExplainButton, "nav-button"); + AddClass(MapBackButton, "nav-button"); + SetName(MapArea, "MapArea"); SetName(MapTitleLabel, "MapTitleLabel"); SetName(MapCaseLabel, "MapCaseLabel"); @@ -215,12 +231,16 @@ // ── signals ─────────────────────────────────────────────────── MapArea.Drawn += OnMapDrawn; + HeartWaveArea.Drawn += (o, a) => DrawWave(a, HeartWaveArea, 0.86, 0.22, 0.20); + BreathWaveArea.Drawn += (o, a) => DrawWave(a, BreathWaveArea, 0.21, 0.57, 0.78); MapBackButton.Clicked += OnBackClicked; BodySkeletonRadio.Toggled += (s, e) => { if (BodySkeletonRadio.Active) ReloadBody(); }; BodyJacketRadio.Toggled += (s, e) => { if (BodyJacketRadio.Active) ReloadBody(); }; JacketSizeCombo.Changed += (s, e) => { ReloadBody(); SyncSpins(); MapArea.QueueDraw(); }; + MapExplainButton.Clicked += (s, e) => { /* open 解説 */ }; + HookView(ViewFrontRadio, "front"); HookView(ViewBackRadio, "back"); HookView(ViewRightRadio, "right"); @@ -252,6 +272,11 @@ if (w != null) w.Name = name; } + private static void AddClass(Widget w, string cls) + { + if (w != null) w.StyleContext.AddClass(cls); + } + private void HookKeys() { if (_keysHooked) return; @@ -1381,4 +1406,21 @@ _debugSweepId = 0; Logger.Write("sound", "debug volume sweep stopped"); } + private void DrawWave(DrawnArgs args, DrawingArea area, double r, double g, double b) + { + var cr = args.Cr; + int w = area.AllocatedWidth, h = area.AllocatedHeight; + + cr.SetSourceRGB(0.85, 0.85, 0.85); + cr.Rectangle(0, 0, w, h); + cr.Fill(); + + cr.SetSourceRGB(r, g, b); + cr.LineWidth = 1.5; + cr.MoveTo(0, h / 2.0); + cr.LineTo(w, h / 2.0); + cr.Stroke(); + + args.RetVal = true; + } } \ No newline at end of file diff --git a/program/homepageallv8.glade b/program/homepageallv8.glade new file mode 100644 index 0000000..6cde001 --- /dev/null +++ b/program/homepageallv8.glade @@ -0,0 +1,1080 @@ + + + + + + False + False + + + True + True + False + False + + + + True + False + 20 + 5 + 20 + + + True + False + horizontal + 12 + end + center + True + False + 40 + 8 + + + True + False + center + Language + + + False + False + 0 + + + + + A / あ + True + True + True + False + center + + + False + False + 1 + + + + + True + False + network-offline + 6 + center + + + False + False + 2 + + + + + True + False + horizontal + 4 + center + + + True + False + center + 12 + 70 + 34 + True + + + False + False + 3 + + + + + False + False + 3 + + + + + 0 + 0 + 2 + + + + + Normal Session + True + True + True + 50 + 20 + True + True + + + 0 + 1 + + + + + Position Recording Mode + True + True + True + 50 + 20 + True + True + + + 0 + 2 + + + + + Exam Mode + True + True + True + 50 + 20 + True + True + + + 0 + 3 + + + + + Settings + True + True + True + center + center + True + True + 20 + 40 + + + 1 + 2 + + + + + Close + True + True + True + center + center + True + True + 20 + 40 + + + 1 + 3 + + + + + True + False + center + center + True + Problem connecting with device + + + 0 + 4 + 2 + + + + + + + + True + False + 3 + 3 + True + + + True + False + center + True + True + COM Port + + + 0 + 0 + + + + + True + False + center + True + True + + + 1 + 0 + + + + + Connect + True + True + True + start + center + True + True + + + 2 + 0 + + + + + Auto Connect + True + True + True + center + start + True + True + + + 1 + 1 + + + + + 戻る + True + True + True + end + end + True + True + + + 2 + 2 + + + + + True + False + Log + + + 0 + 2 + + + + + True + True + True + True + in + + + True + True + False + True + + + + + 1 + 2 + + + + + True + False + vertical + + + Refresh Ports + True + True + True + center + start + + + False + True + 0 + + + + + True + False + Disconnected + + + False + True + 1 + + + + + 2 + 1 + + + + + + + + 1 + + + + + True + False + vertical + + + True + False + label + + + False + True + 0 + + + + + True + True + False + False + never + in + + + True + False + + + + True + False + 6 + 6 + True + + + + + + + + + + + + + + + + + + + + + + + + + True + True + 1 + + + + + 戻る + True + True + True + end + True + right + + + False + True + 4 + + + + + 2 + + + + + True + False + 12 + + + 340 + True + True + never + + + True + False + + + True + False + 12 + 12 + 78 + 12 + vertical + 10 + + + False + True + False + 0 + in + + + True + False + 8 + 8 + 6 + 6 + - + True + 0 + + + + + True + False + 選択中の症例 + + + + + False + True + 0 + + + + + True + False + 0 + in + + + True + False + 8 + 8 + 6 + 6 + vertical + + + スケルトン + True + True + False + True + True + + + False + True + 0 + + + + + ジャケット + True + True + False + True + BodySkeletonRadio + + + False + True + 1 + + + + + + + True + False + 体の画像選択 + + + + + False + True + 1 + + + + + True + False + 8 + + + True + False + サイズ: + + + False + True + 0 + + + + + True + False + 0 + + L + XL + + + + False + True + 1 + + + + + False + True + 2 + + + + + True + False + 0 + in + + + True + False + 8 + 8 + 6 + 6 + True + + + 前 + True + True + False + True + False + + + True + True + 0 + + + + + 後 + True + True + False + False + ViewFrontRadio + + + True + True + 1 + + + + + 右 + True + True + False + False + ViewFrontRadio + + + True + True + 2 + + + + + 左 + True + True + False + False + ViewFrontRadio + + + True + True + 3 + + + + + + + True + False + 視点 + + + + + False + True + 3 + + + + + 番号を隠す + True + True + False + True + True + + + False + True + 4 + + + + + 黒画素でも再生 + True + True + False + True + + + False + True + 5 + + + + + 再生テスト + True + True + True + + + False + True + 6 + + + + + True + False + True + vertical + 8 + + + True + True + 7 + + + + + + + + + + False + True + 0 + + + + + True + False + 12 + 8 + 12 + True + vertical + 8 + + + True + False + horizontal + 12 + + + True + False + True + + + True + False + True + center + end + label + + + True + False + 0 + + + + + True + True + 0 + + + + + 380 + True + False + False + + + True + False + True + center + center + チェストピース未接触 + + + True + False + 0 + + + + + False + True + 1 + + + + + False + True + 0 + + + + + True + False + horizontal + 12 + True + True + + + True + False + vertical + True + True + + + True + False + 聴診点 + + + False + True + 0 + + + + + True + False + True + True + + + True + True + 1 + + + + + True + True + 0 + + + + + 380 + True + False + False + vertical + 12 + True + + + True + False + vertical + True + + + True + False + 心音波形 + + + False + True + 0 + + + + + 150 + True + False + False + True + + + True + True + 1 + + + + + True + True + 0 + + + + + True + False + vertical + True + + + True + False + 呼吸音波形 + + + False + True + 0 + + + + + 150 + True + False + False + True + + + True + True + 1 + + + + + True + True + 1 + + + + + True + False + vertical + 10 + 30 + 30 + 6 + + + 解説 + True + True + True + + + False + True + 0 + + + + + 戻る + True + True + True + + + False + True + 1 + + + + + False + False + 2 + + + + + False + True + 1 + + + + + True + True + 1 + + + + + True + True + 1 + + + + + 3 + + + + + + + + + \ No newline at end of file diff --git a/program/touch_friendly.css b/program/touch_friendly.css index 3a5b7e6..e0ca2a0 100644 --- a/program/touch_friendly.css +++ b/program/touch_friendly.css @@ -75,17 +75,19 @@ #LanguageToggle:checked label { color: #ffffff; } /* ---------- back buttons ---------- */ -#SoundBackButton, #MapBackButton, #SettingBackButton { +/* MapBackButton is deliberately NOT here — the map page pairs it with + MapExplainButton via .nav-button so both render at the same size. */ +#SoundBackButton, #SettingBackButton { min-width: 100px; min-height: 58px; background-color: #F0F0F0; border: 2px solid #B5B5B5; } -#SoundBackButton label, #MapBackButton label, #SettingBackButton label { +#SoundBackButton label, #SettingBackButton label { font-size: 20px; color: #111111; } -#SoundBackButton:hover, #MapBackButton:hover, #SettingBackButton:hover { +#SoundBackButton:hover, #SettingBackButton:hover { background-color: #E2E2E2; } @@ -111,16 +113,23 @@ #StatusLabel.status-off { color: #c62828; font-weight: bold; font-size: 17px; } /* ══════════════════════════════════════════════════════════════════ - MAP PAGE ONLY — scoped under #MapBox, so nothing here can leak to - the splash, sound or settings pages. Sizes target the `label` node - directly because _scaleCssProvider emits a plain `label {}` rule - that beats any inherited value. + MAP PAGE + Two selector styles are in play here, and the difference matters: + + #Id — works only for widgets MapWindow passes to SetName() in + its constructor. GTK3's Builder does not copy a glade id + into the CSS name, so an id alone matches nothing. + .class — applied via AddClass() in the same constructor. Used for + the header/title/button widgets because this build's + Builder rejects in the glade. + + Sizes target the `label` node directly because _scaleCssProvider + emits a plain `label {}` rule that beats any inherited value. ══════════════════════════════════════════════════════════════════ */ -/* ── map page: composite widgets whose inner button node has no class ── */ - -/* GtkRadioButton with draw-indicator=False renders as a button node that - is a CHILD of the widget carrying .mappage, so button.mappage misses it. */ +/* ── 視点 radios ── + GtkRadioButton with draw-indicator=False renders as a button node that + is a CHILD of the widget carrying the id, so `#Id button` is needed. */ #ViewFrontRadio, #ViewBackRadio, #ViewRightRadio, #ViewLeftRadio, #ViewFrontRadio button, #ViewBackRadio button, #ViewRightRadio button, #ViewLeftRadio button { @@ -134,7 +143,7 @@ #ViewFrontRadio label, #ViewBackRadio label, #ViewRightRadio label, #ViewLeftRadio label { color: #111111; - font-size: 18px; + font-size: 22px; font-weight: 700; } #ViewFrontRadio:checked, #ViewBackRadio:checked, @@ -149,15 +158,28 @@ color: #ffffff; } +/* ── left control column ── */ +#BodySkeletonRadio label, #BodyJacketRadio label, +#HideCircleCheck label, #BlackAudioCheck label, +#JacketSizeLabel { + font-size: 19px; + color: #1e1e1e; +} +#BodyFrame > label, #ViewFrame > label { + font-size: 19px; + font-weight: 700; + color: #1e1e1e; +} + /* 再生テスト — accent fill, white text is correct here */ #SoundTestButton { background-color: #0B3B6B; background-image: none; border: 2px solid #072a4d; border-radius: 0; - min-height: 46px; + min-height: 58px; } -#SoundTestButton label { color: #ffffff; font-size: 18px; font-weight: 700; } +#SoundTestButton label { color: #ffffff; font-size: 24px; font-weight: 700; } #SoundTestButton:hover { background-color: #14538F; } /* サイズ combo — the visible box is a button node inside the combobox */ @@ -175,7 +197,7 @@ #JacketSizeCombo button label, #JacketSizeCombo cellview { color: #111111; - font-size: 16px; + font-size: 19px; font-weight: 400; } #JacketSizeCombo arrow { color: #111111; min-width: 16px; min-height: 16px; } @@ -186,11 +208,48 @@ #JacketSizeCombo window.popup row label { color: #111111; background-color: #ffffff; - font-size: 16px; + font-size: 19px; } window.popup list row label { color: #111111; } -/* inactive buttons */ +/* ── map page: class-based widgets (see header note) ── */ +label.map-title { + font-family: 'Noto Sans JP', 'IPAPGothic', sans-serif; + font-size: 40px; + font-weight: 700; + color: #1e1e1e; + background-color: rgba(255,255,255,0.55); + padding: 6px 40px; +} +label.panel-header { + font-family: 'Noto Sans JP', 'IPAPGothic', sans-serif; + font-size: 28px; + font-weight: 700; + color: #111111; + background-color: #F0F0F0; + padding: 6px 0; +} +label.contact-chip { + font-size: 20px; + font-weight: 700; + color: #ffffff; + background-color: #C62828; + padding: 6px 18px; +} +label.contact-chip.contact-ok { background-color: #2e7d32; } + +button.nav-button { + min-height: 62px; + background-color: #F0F0F0; + border: 2px solid #B5B5B5; +} +button.nav-button label { + font-size: 24px; + color: #111111; +} +button.nav-button:hover { background-color: #E2E2E2; } + +/* ---------- disabled states ---------- */ /* splash: modes unavailable until the device connects */ #Option1Button:disabled, #Option2Button:disabled, #Option3Button:disabled { background-color: #A8AFA0;