Skip to content

Commit 3deb564

Browse files
committed
Polish compact utility pane
1 parent 310c98f commit 3deb564

10 files changed

Lines changed: 124 additions & 74 deletions

src/mini_eq/assets/icons/hicolor/scalable/apps/io.github.bhack.mini-eq.svg

Lines changed: 15 additions & 15 deletions
Loading

src/mini_eq/style.css

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ overlay-split-view.mini-eq-workspace > widget.sidebar-pane {
152152
border-radius: 10px;
153153
}
154154

155+
.utility-pane-tight .utility-section {
156+
padding: 4px 8px;
157+
}
158+
155159
.utility-row {
156160
padding: 4px 0;
157161
border-radius: 0;
@@ -163,6 +167,11 @@ overlay-split-view.mini-eq-workspace > widget.sidebar-pane {
163167
padding: 2px 0;
164168
}
165169

170+
.utility-pane-tight .utility-row,
171+
.utility-pane-tight .compare-row {
172+
padding: 1px 0;
173+
}
174+
166175
.output-scope-state-label {
167176
color: alpha(var(--window-fg-color), 0.86);
168177
}
@@ -178,31 +187,6 @@ overlay-split-view.mini-eq-workspace > widget.sidebar-pane {
178187
background-color: transparent;
179188
}
180189

181-
.compare-state-chip {
182-
min-width: 74px;
183-
padding: 3px 9px;
184-
border-radius: 999px;
185-
background-color: rgba(127, 145, 165, 0.10);
186-
color: alpha(var(--window-fg-color), 0.88);
187-
font-size: 9pt;
188-
font-weight: 800;
189-
}
190-
191-
.compare-state-equalized {
192-
background-color: rgba(78, 184, 109, 0.14);
193-
color: var(--mini-success-color);
194-
}
195-
196-
.compare-state-original {
197-
background-color: rgba(127, 145, 165, 0.12);
198-
color: alpha(var(--window-fg-color), 0.88);
199-
}
200-
201-
.compare-state-ready {
202-
background-color: alpha(var(--window-fg-color), 0.09);
203-
color: alpha(var(--window-fg-color), 0.82);
204-
}
205-
206190
.preset-row {
207191
margin-top: 2px;
208192
}
@@ -230,6 +214,13 @@ overlay-split-view.mini-eq-workspace > widget.sidebar-pane {
230214
background-color: var(--mini-border-soft);
231215
}
232216

217+
.popover-section-heading {
218+
padding: 2px 10px 1px;
219+
color: alpha(var(--window-fg-color), 0.58);
220+
font-size: 9pt;
221+
font-weight: 700;
222+
}
223+
233224
button.popover-action {
234225
min-width: 178px;
235226
min-height: 34px;
@@ -272,7 +263,6 @@ button.popover-action.destructive-action:not(:disabled) {
272263

273264
.utility-pane-dense .preset-state-chip,
274265
.utility-pane-dense .system-state-chip,
275-
.utility-pane-dense .compare-state-chip,
276266
.utility-pane-dense .headroom-peak-chip {
277267
padding: 2px 8px;
278268
}
@@ -348,6 +338,10 @@ button.popover-action.destructive-action:not(:disabled) {
348338
font-size: 12pt;
349339
}
350340

341+
.utility-pane-tight .headroom-state {
342+
font-size: 11pt;
343+
}
344+
351345
.headroom-peak-chip {
352346
padding: 3px 9px;
353347
border-radius: 999px;
@@ -400,6 +394,10 @@ button.popover-action.destructive-action:not(:disabled) {
400394
padding-top: 3px;
401395
}
402396

397+
.utility-pane-tight .monitor-strip {
398+
padding-top: 2px;
399+
}
400+
403401
.monitor-detail-row {
404402
min-height: 24px;
405403
}

src/mini_eq/window.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ def __init__(
207207
self.analyzer_last_frame_time = time.monotonic()
208208
self.utility_pane_button: Gtk.ToggleButton | None = None
209209
self.utility_pane_binding: GObject.Binding | None = None
210+
self.fallback_preset_row_visible = False
211+
self.default_preset_row: Gtk.Box | None = None
212+
self.preset_default_heading: Gtk.Label | None = None
210213
self.headroom_panel: Gtk.Box | None = None
211214
self.headroom_fix_button: Gtk.Button | None = None
212215
self.close_finish_source_id = 0
@@ -225,7 +228,6 @@ def __init__(
225228
self.mode_combo.set_sensitive(False)
226229
self.route_switch = Gtk.Switch()
227230
self.bypass_switch = Gtk.Switch()
228-
self.bypass_state_label = Gtk.Label(xalign=1.0)
229231
self.selected_band_gain_spin = Gtk.SpinButton.new_with_range(EQ_GAIN_MIN_DB, EQ_GAIN_MAX_DB, 0.1)
230232
self.analyzer_switch = Gtk.Switch()
231233
self.analyzer_freeze_switch = Gtk.Switch()

src/mini_eq/window_graph.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -275,27 +275,17 @@ def update_selected_band_editor(self) -> None:
275275
self.selected_band_solo_button.set_active(selected.solo)
276276

277277
def update_eq_power_indicator(self) -> None:
278-
self.bypass_state_label.remove_css_class("compare-state-equalized")
279-
self.bypass_state_label.remove_css_class("compare-state-original")
280-
self.bypass_state_label.remove_css_class("compare-state-ready")
281-
282278
route_enabled = self.is_system_routed()
283279
self.bypass_switch.set_sensitive(route_enabled)
284280

285281
if not route_enabled:
286-
self.bypass_state_label.add_css_class("compare-state-ready")
287-
self.bypass_state_label.set_tooltip_text("Turn on System-wide EQ to compare")
288-
self.bypass_state_label.set_text("Not Applied")
282+
self.bypass_switch.set_tooltip_text("Turn on System-wide EQ to compare")
289283
return
290284

291285
if self.controller.eq_enabled:
292-
self.bypass_state_label.add_css_class("compare-state-equalized")
293-
self.bypass_state_label.set_tooltip_text("EQ curve is applied")
294-
self.bypass_state_label.set_text("Equalized")
286+
self.bypass_switch.set_tooltip_text("A/B Compare: equalized audio is playing")
295287
else:
296-
self.bypass_state_label.add_css_class("compare-state-original")
297-
self.bypass_state_label.set_tooltip_text("Original audio is playing")
298-
self.bypass_state_label.set_text("Original")
288+
self.bypass_switch.set_tooltip_text("A/B Compare: original audio is playing")
299289

300290
def sync_ui_from_state(self) -> None:
301291
self.updating_ui = True

src/mini_eq/window_layout.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
COMPACT_FADER_SCROLLER_MIN_HEIGHT = 150
5959
ROOMY_FADER_SCROLLER_MIN_HEIGHT = 290
6060
UTILITY_DENSE_HEIGHT = 660
61+
UTILITY_TIGHT_HEIGHT = 620
6162

6263

6364
class MiniEqWindowLayoutMixin:
@@ -625,10 +626,21 @@ def sync_visual_layout(height: int | None = None) -> None:
625626
ROOMY_FADER_SCROLLER_MIN_HEIGHT,
626627
layout_height,
627628
)
628-
if layout_height <= UTILITY_DENSE_HEIGHT:
629+
dense_utility = layout_height <= UTILITY_DENSE_HEIGHT
630+
tight_utility = layout_height <= UTILITY_TIGHT_HEIGHT
631+
if dense_utility:
629632
right_column.add_css_class("utility-pane-dense")
630633
else:
631634
right_column.remove_css_class("utility-pane-dense")
635+
if tight_utility:
636+
right_column.add_css_class("utility-pane-tight")
637+
else:
638+
right_column.remove_css_class("utility-pane-tight")
639+
640+
fallback_row = getattr(self, "default_preset_row", None)
641+
if fallback_row is not None:
642+
fallback_row.set_visible(getattr(self, "fallback_preset_row_visible", False))
643+
632644
right_column.set_spacing(responsive_value(6, 12, layout_height))
633645
right_column.set_margin_top(responsive_value(2, 4, layout_height))
634646
right_column.set_margin_bottom(responsive_value(0, 2, layout_height))

src/mini_eq/window_presets.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,8 +612,12 @@ def refresh_preset_actions(self, state: PresetPanelUiState | None = None) -> Non
612612

613613
self.set_preset_widget_visible("default_preset_set_button", state.default_set_visible)
614614
self.set_preset_widget_visible("default_preset_clear_button", state.default_clear_visible)
615+
self.set_preset_widget_visible(
616+
"preset_default_heading",
617+
state.default_set_visible or state.default_clear_visible,
618+
)
615619
self.default_preset_set_button.set_sensitive(state.default_set_visible)
616-
self.default_preset_set_button.set_tooltip_text("Use this preset when no auto preset matches")
620+
self.default_preset_set_button.set_tooltip_text("Use the current preset when no auto preset matches")
617621
self.default_preset_clear_button.set_sensitive(state.default_clear_visible)
618622
self.default_preset_clear_button.set_tooltip_text(
619623
"Bypass unmatched outputs instead of loading a fallback preset"
@@ -708,10 +712,14 @@ def update_fallback_preset_state(self) -> None:
708712
label = getattr(self, "default_preset_state_label", None)
709713
set_button = getattr(self, "default_preset_set_button", None)
710714
clear_button = getattr(self, "default_preset_clear_button", None)
715+
row = getattr(self, "default_preset_row", None)
711716

712717
try:
713718
default_preset = get_output_preset_fallback_name()
714719
except Exception as exc:
720+
self.fallback_preset_row_visible = True
721+
if row is not None:
722+
row.set_visible(True)
715723
if label is not None:
716724
label.set_text("Unavailable")
717725
label.set_tooltip_text(str(exc))
@@ -721,6 +729,10 @@ def update_fallback_preset_state(self) -> None:
721729
clear_button.set_sensitive(False)
722730
return
723731

732+
self.fallback_preset_row_visible = default_preset is not None
733+
if row is not None:
734+
row.set_visible(self.fallback_preset_row_visible)
735+
724736
has_named_preset = self.current_preset_name is not None
725737
if set_button is not None:
726738
set_button.set_sensitive(has_named_preset)

src/mini_eq/window_utility.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ def make_preset_section(self) -> Gtk.Box:
111111

112112
default_preset_row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
113113
default_preset_row.add_css_class("utility-row")
114+
default_preset_row.set_visible(False)
115+
self.default_preset_row = default_preset_row
114116
default_preset_label = Gtk.Label(label="Fallback", xalign=0.0)
115117
default_preset_row.append(default_preset_label)
116118
default_preset_row.append(self.default_preset_state_label)
@@ -177,8 +179,12 @@ def make_preset_action(label: str, callback, *, destructive: bool = False) -> tu
177179

178180
self.preset_default_separator = append_preset_separator()
179181

182+
self.preset_default_heading = Gtk.Label(label="Unmatched Outputs", xalign=0.0)
183+
self.preset_default_heading.add_css_class("popover-section-heading")
184+
preset_more_box.append(self.preset_default_heading)
185+
180186
self.default_preset_set_button, self.default_preset_set_button_label = make_preset_action(
181-
"Use as Fallback",
187+
"Use Current as Fallback",
182188
self.on_use_preset_as_fallback_clicked,
183189
)
184190

@@ -243,23 +249,16 @@ def make_system_section(self) -> tuple[Gtk.Box, Gtk.Box]:
243249

244250
compare_panel = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)
245251
compare_panel.add_css_class("compare-row")
246-
compare_title = Gtk.Label(label="Compare", xalign=0.0)
252+
compare_title = Gtk.Label(label="A/B", xalign=0.0)
247253
compare_title.add_css_class("metric-title")
248254
bind_label_to_control(compare_title, self.bypass_switch)
249255
compare_panel.append(compare_title)
250256
compare_spacer = Gtk.Box()
251257
compare_spacer.set_hexpand(True)
252258
compare_panel.append(compare_spacer)
253-
self.bypass_state_label.add_css_class("compare-state-chip")
254-
self.bypass_state_label.set_accessible_role(Gtk.AccessibleRole.STATUS)
255-
set_accessible_label(self.bypass_state_label, "Compare State")
256-
self.bypass_state_label.set_width_chars(9)
257-
self.bypass_state_label.set_size_request(92, -1)
258-
self.bypass_state_label.set_xalign(0.5)
259-
compare_panel.append(self.bypass_state_label)
260-
self.bypass_switch.set_tooltip_text("Compare Audio")
259+
self.bypass_switch.set_tooltip_text("A/B Compare")
261260
self.bypass_switch.set_valign(Gtk.Align.CENTER)
262-
set_accessible_label(self.bypass_switch, "Equalized Audio")
261+
set_accessible_label(self.bypass_switch, "A/B Compare")
263262
compare_panel.append(self.bypass_switch)
264263
system_section.append(compare_panel)
265264

tests/test_mini_eq_atspi_widgets.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,8 @@ def verify_dropdown_exposes_options(frame, *, combo_name, required_options):
415415
lambda: find_accessible(frame, name="System-wide EQ", role="switch", showing=True),
416416
)
417417
compare_switch = wait_for(
418-
"Compare switch",
419-
lambda: find_accessible(frame, name="Compare", role="switch", showing=True),
418+
"A/B compare switch",
419+
lambda: find_accessible(frame, name="A/B", role="switch", showing=True),
420420
)
421421
monitor_switch = wait_for(
422422
"Monitor switch",

0 commit comments

Comments
 (0)