Source code for Toggle

"""Widget to select among alternative options using a list of buttons displayed horizontally or vertically."""
# Author(s): Davide.De-Marchi@ec.europa.eu
# Copyright © European Union 2022-2023
# 
# Licensed under the EUPL, Version 1.2 or as soon they will be approved by 
# the European Commission subsequent versions of the EUPL (the "Licence");
# 
# You may not use this work except in compliance with the Licence.
# 
# You may obtain a copy of the Licence at:
# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12

# Unless required by applicable law or agreed to in writing, software
# distributed under the Licence is distributed on an "AS IS"
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied.
# 
# See the Licence for the specific language governing permissions and
# limitations under the Licence.
import ipyvuetify as v
from vois.vuetify import Button
from vois.vuetify.utils.util import *
from typing import Callable, Optional


#####################################################################################################################################################
# Toggle buttons control
#####################################################################################################################################################
[docs] class Toggle(v.Row): """ Widget to select among alternative options using a list of buttons displayed horizontally or vertically. Parameters ---------- index : int Index of the selected option at start (from 0 to len(labels)-1) labels : list of strings Strings to be displayed as text of the options tooltips : list of strings, optional Tooltip text for the options (default is the empty list) icons : list of strings, optional Icons for the options (default is the empty list) on_change : function, optional Python function to call when the user clicks on one of the buttons. The function will receive a parameter of type int containing the index of the clicked button, from 0 to len(labels)-1 row : bool, optional Flag to display the buttons horizontally or vertically (default is True) width : int, optional Width in pixels of the buttons (default is 150) height : int, optional Height in pixels of the buttons (default is 36) justify : str, optional In case of horizontal placement, applies the justify-content css property. Available options are: start, center, end, space-between and space-around. rounded : bool, optional Flag to display the buttons with a rounded shape (default is the button_rounded flag defined in the settings.py module) outlined : bool, optional Flag to display the buttons as outlined (default is False) color_selected : str, optional Color used for the buttons when they are selected (default is settings.color_first) color_unselected : str, optional Color used for the buttons when they are not selected (default is settings.color_second) dark : bool, optional Flag that controls the color of the text and icons in foreground (if True, the text and icons will be displayed in white, otherwise in black) padding_row : int, optional Horizontal padding among toggle buttons (1 unit means 4 pixels). Default is 1 padding_col : int, optional Vertical padding among toggle buttons (1 unit means 4 pixels). Default is 2 tile : bool, optional Flag to remove the buttons small border (default is False) large : bool, optional Flag that sets the large version of the button (default is False) x_large : bool, optional Flag that sets the xlarge version of the button (default is False) small : bool, optional Flag that sets the small version of the button (default is False) x_small : bool, optional Flag that sets the xsmall version of the button (default is False) Example ------- Creation and display of a widget for the selection among 3 options:: from vois.vuetify import Toggle from ipywidgets import widgets from IPython.display import display output = widgets.Output() def onchange(index): with output: print(index) t = Toggle(0, ['Option 1', 'Option 2', 'Option 3'], tooltips=['Tooltip for option 1'], on_change=onchange, row=False, width=150, rounded=False) display(t) display(output) .. figure:: figures/toggle.png :scale: 100 % :alt: toggle widget Toogle widget for selecting alternative options using buttons. """ deprecation_alias = dict(onchange='on_change', colorselected='color_selected', colorunselected='color_unselected', paddingrow='padding_row', paddingcol='padding_col', xsmall='x_small', xlarge='x_large') # Initialization @deprecated_init_alias(**deprecation_alias) def __init__(self, index: int, labels: list[str], tooltips: list[str] = [], icons: list[str] = [], on_change: Optional[Callable[[int], None]] = None, row: bool = True, width: int = 150, height: int = 36, justify: str = 'space-between', rounded: Optional[bool] = None, outlined: bool = False, color_selected: Optional[str] = None, color_unselected: Optional[str] = None, dark: Optional[bool] = None, padding_row: int = 1, padding_col: int = 2, tile: bool = False, small: bool = False, x_small: bool = False, large: bool = False, x_large: bool = False, **kwargs): super().__init__(class_="pa-0 ma-0", justify=self.justify, style_="overflow: hidden;", **kwargs) from vois.vuetify import settings self.index = index # Index of the selected button self.labels = labels self.tooltips = tooltips self.icons = icons self.on_change = on_change self.row = row self.width = width self.height = height self.justify = justify self.rounded = rounded if rounded is not None else settings.button_rounded self.outlined = outlined self._color_selected = color_selected if color_selected is not None else settings.color_first self._color_unselected = color_unselected if color_unselected is not None else settings.color_second self._dark = dark if dark is not None else settings.dark_mode self.padding_row = padding_row self.padding_col = padding_col self.tile = tile self.small = small self.x_small = x_small self.large = large self.x_large = x_large self.__createButtons() for alias, new in self.deprecation_alias.items(): create_deprecated_alias(self, alias, new) # Create the toggle buttons def __createButtons(self): icon_color = 'black' if self._dark: icon_color = 'white' self.buttons = [] i = 0 for label in self.labels: tooltip = '' if i < len(self.tooltips): tooltip = self.tooltips[i] icon = None if i < len(self.icons): icon = self.icons[i] if self.row: c = "pa-0 ma-0 mr-%d" % self.padding_row else: c = "pa-0 ma-0 mb-%d" % self.padding_col b = Button(label, dark=self._dark, class_=c, small=self.small, xsmall=self.x_small, large=self.large, xlarge=self.x_large, icon=icon, icon_color=icon_color, on_click=self.__internal_onchange, argument=i, width=self.width, height=self.height, tooltip=tooltip, selected=(i == self.index), rounded=self.rounded, tile=self.tile, outlined=self.outlined, color_selected=self._color_selected, color_unselected=self._color_unselected) self.buttons.append(b) i += 1 if self.row: self.children = self.buttons else: self.col = v.Col(cols=12, class_="pa-0 ma-0", children=[x for x in self.buttons], style_="overflow: hidden;") self.children = [self.col] # Get the active button @property def value(self): """ Get/Set the active option index. Returns -------- index : int Index of the selected option (from 0 to len(labels)-1) Example ------- Programmatically select one of the options and print the index of the selected option:: t.value = 2 print(t.value) """ return self.index # Set the active button @value.setter def value(self, index): if index >= 0 and index < len(self.buttons): self.buttons[self.index].selected = False self.index = index self.buttons[self.index].selected = True if self.on_change: self.on_change(self.index) # Get/Set the color of the selected button @property def color_selected(self): """ Get/Set the color of the selected button. Returns -------- color : str Color of the selected button Example ------- Programmatically change the color of the selected button:: t.colorselected = '#ff0000' print(t.colorselected) """ return self._color_selected @color_selected.setter def color_selected(self, color): for b in self.buttons: b.color_selected = color if b._selected: b.b.color = color # Get/Set the color of the unselected button @property def color_unselected(self): """ Get/Set the color of the unselected buttons. Returns -------- color : str Color of the unselected buttons Example ------- Programmatically change the color of the unselected buttons:: t.colorunselected = '#ff0000' print(t.colorunselected) """ return self._color_unselected @color_unselected.setter def color_unselected(self, color): for b in self.buttons: b.color_unselected = color if not b._selected: b.b.color = color # Get/Set the dark mode @property def dark(self): """ Get/Set the dark mode of the buttons. Returns -------- flag : bool If True the text and the icons are displayed in white color, otherwise in black color Example ------- Programmatically change the dark mode:: t.dark = Fals print(t.dark) """ return self._dark @dark.setter def dark(self, flag): self._dark = flag for b in self.buttons: b.dark = self._dark # Manage onchange event def __internal_onchange(self, index): self.buttons[self.index].selected = False self.index = index self.buttons[self.index].selected = True if self.on_change: self.on_change(self.index) # Returns the vuetify object to display
[docs] def draw(self): """Returns the ipyvuetify object to display (the internal v.Row or v.Col widget)""" warnings.warn('The "draw" method is deprecated, please just use the object widget itself.', category=DeprecationWarning, stacklevel=2) return self