kvex.widgets.buttonbar
Home of XButtonBar
.
1"""Home of `XButtonBar`.""" 2 3from typing import Optional, Callable 4from functools import partial 5from .layouts import XFrame, XBox 6from .dropdown import XDropDown 7from .spinner import XSpinner, XSpinnerOption 8from ..colors import THEME_NAMES 9 10 11class XButtonBar(XFrame): 12 """A bar of buttons nested in two layers.""" 13 14 def __init__( 15 self, 16 *, 17 category_subtheme: Optional[str] = None, 18 dropdown_subtheme: Optional[str] = None, 19 nested_subtheme: Optional[str] = None, 20 **kwargs, 21 ): 22 """Initialize the class. 23 24 Args: 25 category_subtheme: Subtheme of category buttons. 26 dropdown_subtheme: Subtheme of dropdown. 27 nested_subtheme: Subtheme of nested buttons. 28 """ 29 super().__init__(**kwargs) 30 self._category_subtheme = category_subtheme 31 self._dropdown_subtheme = dropdown_subtheme 32 self._nested_subtheme = nested_subtheme 33 self._names: dict[list[str]] = dict() 34 self._spinners: dict[XSpinner] = dict() 35 self._callbacks: dict[str, Callable] = dict() 36 self._box = XBox() 37 self.add_widget(self._box) 38 self.register_event_type("on_select") 39 40 def _dropdown_factory(self, *args, **kwargs): 41 return XDropDown(*args, subtheme_name=self._dropdown_subtheme, **kwargs) 42 43 def add_category(self, category: str, /, *, display_as: Optional[str] = None): 44 """Add a category for buttons. 45 46 Args: 47 category: Category name, used for callbacks. 48 display_as: Button text, defaults to the capitalized category name. 49 """ 50 if category in self._names: 51 raise ValueError(f"Category {category!r} already in use.") 52 if display_as is None: 53 display_as = category.capitalize() 54 spinner = XSpinner( 55 text=display_as, 56 dropdown_cls=self._dropdown_factory, 57 option_cls=XButtonBarSpinnerOption, 58 subtheme_name=self._category_subtheme, 59 ) 60 self._spinners[category] = spinner 61 self._box.add_widget(spinner) 62 self._names[category] = [] 63 spinner.bind(on_select=partial(self._on_spinner_select, category)) 64 65 def add_button( 66 self, 67 category: str, 68 name: str, 69 /, 70 callback: Optional[Callable] = None, 71 *, 72 display_as: Optional[str] = None, 73 ): 74 """Add a button in a category. 75 76 Args: 77 category: Category name, used for callbacks. 78 name: Button name, used for callbacks. 79 callback: Callback when button is pressed. 80 display_as: Button text, defaults to a the button name formatted. 81 """ 82 if category not in self._names: 83 self.add_category(category) 84 if display_as is None: 85 display_as = name.replace("_", " ").capitalize() 86 spinner = self._spinners[category] 87 with self.app.subtheme_context(self._nested_subtheme): 88 spinner.values.append(display_as) 89 self._names[category].append(name) 90 self._callbacks[f"{category}.{name}"] = callback 91 92 def get_button( 93 self, 94 category: str, 95 button: Optional[str] = None, 96 ) -> XDropDown | XSpinnerOption: 97 """Get the XSpinnerOption button or XDropDown if no button specified.""" 98 spinner = self._spinners[category] 99 if not button: 100 return spinner 101 idx = self._names[category].index(button) 102 return spinner._dropdown.container.children[-idx - 1] 103 104 def set_callback(self, category: str, button: str, callback: Callable, /): 105 """Change a callback.""" 106 self._callbacks[f"{category}.{button}"] = callback 107 108 def on_select(self, category: str, button: str): 109 """Called when a button is pressed.""" 110 pass 111 112 def _on_spinner_select(self, category, w, index, text): 113 button = self._names[category][index] 114 callback = self._callbacks.get(f"{category}.{button}") 115 if callback: 116 callback() 117 self.dispatch("on_select", category, button) 118 119 def add_theme_selectors( 120 self, 121 *, 122 category: str = "Themes", 123 prefix: str = "Change to: ", 124 suffix: str = "", 125 ): 126 """Add theme selection buttons.""" 127 for tname in THEME_NAMES: 128 self.add_button( 129 "theme", 130 tname, 131 display_as=f"{prefix}{tname.capitalize()}{suffix}", 132 callback=lambda *a, t=tname: self.app.set_theme(t), 133 ) 134 135 136class XButtonBarSpinnerOption(XSpinnerOption): 137 """SpinnerOption.""" 138 139 def __init__(self, *args, **kwargs): 140 """Initialize the class.""" 141 kwargs |= dict( 142 halign="left", 143 valign="middle", 144 padding=(10, 0), 145 height="32dp", 146 ) 147 super().__init__(*args, **kwargs) 148 self.bind(size=self.on_size) 149 150 def on_size(self, w, size): 151 """Fix text size to widget size for alignment.""" 152 self.text_size = size 153 154 155__all__ = ( 156 "XButtonBar", 157 "XButtonBarSpinnerOption", 158)
12class XButtonBar(XFrame): 13 """A bar of buttons nested in two layers.""" 14 15 def __init__( 16 self, 17 *, 18 category_subtheme: Optional[str] = None, 19 dropdown_subtheme: Optional[str] = None, 20 nested_subtheme: Optional[str] = None, 21 **kwargs, 22 ): 23 """Initialize the class. 24 25 Args: 26 category_subtheme: Subtheme of category buttons. 27 dropdown_subtheme: Subtheme of dropdown. 28 nested_subtheme: Subtheme of nested buttons. 29 """ 30 super().__init__(**kwargs) 31 self._category_subtheme = category_subtheme 32 self._dropdown_subtheme = dropdown_subtheme 33 self._nested_subtheme = nested_subtheme 34 self._names: dict[list[str]] = dict() 35 self._spinners: dict[XSpinner] = dict() 36 self._callbacks: dict[str, Callable] = dict() 37 self._box = XBox() 38 self.add_widget(self._box) 39 self.register_event_type("on_select") 40 41 def _dropdown_factory(self, *args, **kwargs): 42 return XDropDown(*args, subtheme_name=self._dropdown_subtheme, **kwargs) 43 44 def add_category(self, category: str, /, *, display_as: Optional[str] = None): 45 """Add a category for buttons. 46 47 Args: 48 category: Category name, used for callbacks. 49 display_as: Button text, defaults to the capitalized category name. 50 """ 51 if category in self._names: 52 raise ValueError(f"Category {category!r} already in use.") 53 if display_as is None: 54 display_as = category.capitalize() 55 spinner = XSpinner( 56 text=display_as, 57 dropdown_cls=self._dropdown_factory, 58 option_cls=XButtonBarSpinnerOption, 59 subtheme_name=self._category_subtheme, 60 ) 61 self._spinners[category] = spinner 62 self._box.add_widget(spinner) 63 self._names[category] = [] 64 spinner.bind(on_select=partial(self._on_spinner_select, category)) 65 66 def add_button( 67 self, 68 category: str, 69 name: str, 70 /, 71 callback: Optional[Callable] = None, 72 *, 73 display_as: Optional[str] = None, 74 ): 75 """Add a button in a category. 76 77 Args: 78 category: Category name, used for callbacks. 79 name: Button name, used for callbacks. 80 callback: Callback when button is pressed. 81 display_as: Button text, defaults to a the button name formatted. 82 """ 83 if category not in self._names: 84 self.add_category(category) 85 if display_as is None: 86 display_as = name.replace("_", " ").capitalize() 87 spinner = self._spinners[category] 88 with self.app.subtheme_context(self._nested_subtheme): 89 spinner.values.append(display_as) 90 self._names[category].append(name) 91 self._callbacks[f"{category}.{name}"] = callback 92 93 def get_button( 94 self, 95 category: str, 96 button: Optional[str] = None, 97 ) -> XDropDown | XSpinnerOption: 98 """Get the XSpinnerOption button or XDropDown if no button specified.""" 99 spinner = self._spinners[category] 100 if not button: 101 return spinner 102 idx = self._names[category].index(button) 103 return spinner._dropdown.container.children[-idx - 1] 104 105 def set_callback(self, category: str, button: str, callback: Callable, /): 106 """Change a callback.""" 107 self._callbacks[f"{category}.{button}"] = callback 108 109 def on_select(self, category: str, button: str): 110 """Called when a button is pressed.""" 111 pass 112 113 def _on_spinner_select(self, category, w, index, text): 114 button = self._names[category][index] 115 callback = self._callbacks.get(f"{category}.{button}") 116 if callback: 117 callback() 118 self.dispatch("on_select", category, button) 119 120 def add_theme_selectors( 121 self, 122 *, 123 category: str = "Themes", 124 prefix: str = "Change to: ", 125 suffix: str = "", 126 ): 127 """Add theme selection buttons.""" 128 for tname in THEME_NAMES: 129 self.add_button( 130 "theme", 131 tname, 132 display_as=f"{prefix}{tname.capitalize()}{suffix}", 133 callback=lambda *a, t=tname: self.app.set_theme(t), 134 )
A bar of buttons nested in two layers.
XButtonBar( *, category_subtheme: Optional[str] = None, dropdown_subtheme: Optional[str] = None, nested_subtheme: Optional[str] = None, **kwargs)
15 def __init__( 16 self, 17 *, 18 category_subtheme: Optional[str] = None, 19 dropdown_subtheme: Optional[str] = None, 20 nested_subtheme: Optional[str] = None, 21 **kwargs, 22 ): 23 """Initialize the class. 24 25 Args: 26 category_subtheme: Subtheme of category buttons. 27 dropdown_subtheme: Subtheme of dropdown. 28 nested_subtheme: Subtheme of nested buttons. 29 """ 30 super().__init__(**kwargs) 31 self._category_subtheme = category_subtheme 32 self._dropdown_subtheme = dropdown_subtheme 33 self._nested_subtheme = nested_subtheme 34 self._names: dict[list[str]] = dict() 35 self._spinners: dict[XSpinner] = dict() 36 self._callbacks: dict[str, Callable] = dict() 37 self._box = XBox() 38 self.add_widget(self._box) 39 self.register_event_type("on_select")
Initialize the class.
Arguments:
- category_subtheme: Subtheme of category buttons.
- dropdown_subtheme: Subtheme of dropdown.
- nested_subtheme: Subtheme of nested buttons.
def
add_category(self, category: str, /, *, display_as: Optional[str] = None):
44 def add_category(self, category: str, /, *, display_as: Optional[str] = None): 45 """Add a category for buttons. 46 47 Args: 48 category: Category name, used for callbacks. 49 display_as: Button text, defaults to the capitalized category name. 50 """ 51 if category in self._names: 52 raise ValueError(f"Category {category!r} already in use.") 53 if display_as is None: 54 display_as = category.capitalize() 55 spinner = XSpinner( 56 text=display_as, 57 dropdown_cls=self._dropdown_factory, 58 option_cls=XButtonBarSpinnerOption, 59 subtheme_name=self._category_subtheme, 60 ) 61 self._spinners[category] = spinner 62 self._box.add_widget(spinner) 63 self._names[category] = [] 64 spinner.bind(on_select=partial(self._on_spinner_select, category))
Add a category for buttons.
Arguments:
- category: Category name, used for callbacks.
- display_as: Button text, defaults to the capitalized category name.
def
set_callback(self, category: str, button: str, callback: Callable, /):
105 def set_callback(self, category: str, button: str, callback: Callable, /): 106 """Change a callback.""" 107 self._callbacks[f"{category}.{button}"] = callback
Change a callback.
def
on_select(self, category: str, button: str):
109 def on_select(self, category: str, button: str): 110 """Called when a button is pressed.""" 111 pass
Called when a button is pressed.
def
add_theme_selectors( self, *, category: str = 'Themes', prefix: str = 'Change to: ', suffix: str = ''):
120 def add_theme_selectors( 121 self, 122 *, 123 category: str = "Themes", 124 prefix: str = "Change to: ", 125 suffix: str = "", 126 ): 127 """Add theme selection buttons.""" 128 for tname in THEME_NAMES: 129 self.add_button( 130 "theme", 131 tname, 132 display_as=f"{prefix}{tname.capitalize()}{suffix}", 133 callback=lambda *a, t=tname: self.app.set_theme(t), 134 )
Add theme selection buttons.
Inherited Members
- kivy.uix.anchorlayout.AnchorLayout
- padding
- anchor_x
- anchor_y
- do_layout
- kivy.uix.layout.Layout
- add_widget
- remove_widget
- layout_hint_with_bounds
- kivy.uix.widget.Widget
- proxy_ref
- apply_class_lang_rules
- collide_point
- collide_widget
- on_motion
- on_touch_down
- on_touch_move
- on_touch_up
- on_kv_post
- clear_widgets
- register_for_motion_event
- unregister_for_motion_event
- export_to_png
- export_as_image
- get_root_window
- get_parent_window
- walk
- walk_reverse
- to_widget
- to_window
- to_parent
- to_local
- get_window_matrix
- x
- y
- width
- height
- pos
- size
- get_right
- set_right
- right
- get_top
- set_top
- top
- get_center_x
- set_center_x
- center_x
- get_center_y
- set_center_y
- center_y
- center
- cls
- children
- parent
- size_hint_x
- size_hint_y
- size_hint
- pos_hint
- size_hint_min_x
- size_hint_min_y
- size_hint_min
- size_hint_max_x
- size_hint_max_y
- size_hint_max
- ids
- opacity
- on_opacity
- canvas
- get_disabled
- set_disabled
- inc_disabled
- dec_disabled
- disabled
- motion_filter
- kivy._event.EventDispatcher
- register_event_type
- unregister_event_types
- unregister_event_type
- is_event_type
- bind
- unbind
- fbind
- funbind
- unbind_uid
- get_property_observers
- events
- dispatch
- dispatch_generic
- dispatch_children
- setter
- getter
- property
- properties
- create_property
- apply_property
137class XButtonBarSpinnerOption(XSpinnerOption): 138 """SpinnerOption.""" 139 140 def __init__(self, *args, **kwargs): 141 """Initialize the class.""" 142 kwargs |= dict( 143 halign="left", 144 valign="middle", 145 padding=(10, 0), 146 height="32dp", 147 ) 148 super().__init__(*args, **kwargs) 149 self.bind(size=self.on_size) 150 151 def on_size(self, w, size): 152 """Fix text size to widget size for alignment.""" 153 self.text_size = size
SpinnerOption.
XButtonBarSpinnerOption(*args, **kwargs)
140 def __init__(self, *args, **kwargs): 141 """Initialize the class.""" 142 kwargs |= dict( 143 halign="left", 144 valign="middle", 145 padding=(10, 0), 146 height="32dp", 147 ) 148 super().__init__(*args, **kwargs) 149 self.bind(size=self.on_size)
Initialize the class.
def
on_size(self, w, size):
151 def on_size(self, w, size): 152 """Fix text size to widget size for alignment.""" 153 self.text_size = size
Fix text size to widget size for alignment.
Inherited Members
- kivy.uix.button.Button
- background_color
- background_normal
- background_down
- background_disabled_normal
- background_disabled_down
- border
- kivy.uix.behaviors.button.ButtonBehavior
- state
- last_touch
- min_state_time
- always_release
- cancel_event
- on_touch_down
- on_touch_move
- on_touch_up
- on_press
- on_release
- trigger_action
- kivy.uix.label.Label
- texture_update
- on_ref_press
- disabled_color
- text
- text_size
- base_direction
- text_language
- font_context
- font_family
- font_name
- font_size
- font_features
- line_height
- bold
- italic
- underline
- strikethrough
- padding_x
- padding_y
- padding
- halign
- valign
- color
- outline_width
- outline_color
- disabled_outline_color
- texture
- texture_size
- mipmap
- shorten
- shorten_from
- is_shortened
- split_str
- ellipsis_options
- unicode_errors
- markup
- refs
- anchors
- max_lines
- strip
- font_hinting
- font_kerning
- font_blended
- kivy.uix.widget.Widget
- proxy_ref
- apply_class_lang_rules
- collide_point
- collide_widget
- on_motion
- on_kv_post
- add_widget
- remove_widget
- clear_widgets
- register_for_motion_event
- unregister_for_motion_event
- export_to_png
- export_as_image
- get_root_window
- get_parent_window
- walk
- walk_reverse
- to_widget
- to_window
- to_parent
- to_local
- get_window_matrix
- x
- y
- width
- height
- pos
- size
- get_right
- set_right
- right
- get_top
- set_top
- top
- get_center_x
- set_center_x
- center_x
- get_center_y
- set_center_y
- center_y
- center
- cls
- children
- parent
- size_hint_x
- size_hint_y
- size_hint
- pos_hint
- size_hint_min_x
- size_hint_min_y
- size_hint_min
- size_hint_max_x
- size_hint_max_y
- size_hint_max
- ids
- opacity
- on_opacity
- canvas
- get_disabled
- set_disabled
- inc_disabled
- dec_disabled
- disabled
- motion_filter
- kivy._event.EventDispatcher
- register_event_type
- unregister_event_types
- unregister_event_type
- is_event_type
- bind
- unbind
- fbind
- funbind
- unbind_uid
- get_property_observers
- events
- dispatch
- dispatch_generic
- dispatch_children
- setter
- getter
- property
- properties
- create_property
- apply_property