widgets: init choice_toggle widget

parent 0cb2d2c1
......@@ -144,7 +144,7 @@ class BaseSetting:
)
def _needs_range_map(self):
return self.type in ("choice", "choice_entry", "choice_radio", "list_dual", "number")
return self.type in ("choice", "choice_entry", "choice_radio", "choice_toggle", "list_dual", "number")
def _build_map_from_range(self, range_value):
if range_value is None:
......
from gi.repository import Gtk, Gdk, Adw, GObject
from .BaseWidget import BaseWidget
_css_provider = None
def _ensure_css():
global _css_provider
if _css_provider is not None:
return
_css_provider = Gtk.CssProvider()
_css_provider.load_from_string(
".toggle-choice { min-height: 0; min-width: 0; padding: 5px 12px; }"
)
Gtk.StyleContext.add_provider_for_display(
Gdk.Display.get_default(),
_css_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
)
class _BalancedFlowBox(Gtk.FlowBox):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._balanced_max = 0
def do_size_allocate(self, width, height, baseline):
first = self.get_first_child()
if first:
_, nat = first.get_preferred_size()
n = 0
child = first
while child:
n += 1
child = child.get_next_sibling()
if n > 1 and nat.width > 0:
spacing = self.get_column_spacing()
m = max(1, (width + spacing) // (nat.width + spacing))
target = n if m >= n else -(-n // -(-n // m))
if target != self._balanced_max:
self._balanced_max = target
self.set_max_children_per_line(target)
Gtk.FlowBox.do_size_allocate(self, width, height, baseline)
class ToggleChoiceWidget(BaseWidget):
def create_row(self):
_ensure_css()
self.row = Adw.PreferencesRow(
activatable=False,
focusable=False
)
content_box = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL,
spacing=6,
margin_top=8,
margin_bottom=8,
margin_start=12,
margin_end=12
)
self.row.set_child(content_box)
title_horizontal_box = Gtk.Box(
orientation=Gtk.Orientation.HORIZONTAL,
hexpand=True,
)
content_box.append(title_horizontal_box)
title_box = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL,
hexpand=True,
spacing=1,
)
title_horizontal_box.append(title_box)
title_label = Gtk.Label(
label=self.setting.name,
halign=Gtk.Align.START,
)
title_box.append(title_label)
if self.setting.help:
subtitle_label = Gtk.Label(
label=self.setting.help,
halign=Gtk.Align.START,
wrap=True,
margin_bottom=4
)
subtitle_label.add_css_class("caption")
subtitle_label.add_css_class("dim-label")
title_box.append(subtitle_label)
self.reset_prefix.set_halign(Gtk.Align.END)
title_horizontal_box.append(self.reset_prefix)
self.flow_box = _BalancedFlowBox(
homogeneous=True,
selection_mode=Gtk.SelectionMode.NONE,
column_spacing=6,
row_spacing=6,
)
content_box.append(self.flow_box)
self.toggle_buttons = {}
self._build_toggles()
self._update_reset_visibility()
return self.row
def on_map_updated(self):
self.toggle_buttons = {}
while child := self.flow_box.get_first_child():
self.flow_box.remove(child)
self._build_toggles()
self._update_reset_visibility()
def _build_toggles(self):
if not self.setting.map:
return
current_value = self.setting._get_backend_value()
group = None
for label, value in self.setting.map.items():
btn = Gtk.ToggleButton(label=str(label), active=(value == current_value))
btn.add_css_class("toggle-choice")
btn.set_hexpand(True)
if group:
btn.set_group(group)
else:
group = btn
handler_id = btn.connect("toggled", self._on_toggled, value)
self.toggle_buttons[value] = (btn, handler_id)
self.flow_box.append(btn)
def update_display(self):
if not self.setting.map:
return
current_value = self.setting._get_backend_value()
for value, (btn, handler_id) in self.toggle_buttons.items():
with GObject.signal_handler_block(btn, handler_id):
btn.set_active(value == current_value)
self._update_reset_visibility()
def _on_toggled(self, button, value):
if button.get_active():
self.setting._set_backend_value(value)
def _on_reset_clicked(self, button):
if self.setting.default is not None:
self.setting._set_backend_value(self.setting.default)
def _update_reset_visibility(self):
if not self.setting.map:
self.reset_button.set_sensitive(False)
return
current_value = self.setting._get_backend_value()
default_value = self.setting.default
self.reset_button.set_sensitive(
current_value != default_value if default_value is not None else False
)
......@@ -18,6 +18,7 @@ from .DualListWidget import DualListWidget
from .ImageChooserWidget import ImageChooserWidget
from .DualImageChooserWidget import DualImageChooserWidget
from .FontWidget import FontWidget
from .ToggleChoiceWidget import ToggleChoiceWidget
import logging
logger = logging.getLogger(f"{__name__}")
......@@ -31,6 +32,7 @@ class WidgetFactory:
'choice': ChoiceWidget,
'choice_entry': ChoiceEntryWidget,
'choice_radio': RadioChoiceWidget,
'choice_toggle': ToggleChoiceWidget,
'theme_chooser': ThemeChooserWidget,
'accent_color': AccentColorWidget,
'boolean': BooleanWidget,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment