diff --git a/tugui/plot_settings.py b/tugui/plot_settings.py index f49e245..54e93db 100644 --- a/tugui/plot_settings.py +++ b/tugui/plot_settings.py @@ -1,7 +1,7 @@ from enum import Enum import tkinter as tk from tkinter import ttk -from typing import Callable, List, Union +from typing import Callable, List, Tuple, Union class FieldType(Enum): @@ -163,6 +163,9 @@ class PlotSettingsListBox(): alternative values. This widget also presents a vertical scrollbar to help the inspection of the available values. """ + # Maximum number of items that can be selected in the list box + MAX_SELECTABLE_ITEMS: int = 10 + def __init__(self, container: ttk.Frame, label_text: str, choices: Union[List[str], None], row_index: int) -> None: """ @@ -199,6 +202,11 @@ def __init__(self, container: ttk.Frame, label_text: str, # Bind the selection of the listbox items event to a function call that stores the list of items self.choice_lb.bind("<>", self.store_selected) + # Initialize the tuple storing the currently selected indices + self.stored_indxs: Tuple[int] = () + # Declare a list holding the values to store, based on the selection + self.lb_selected_values: List[str] = [] + # Add an X-Y padding to all the widgets herein defined self.label.grid_configure(padx=5, pady=2) self.choice_lb.grid_configure(padx=5, pady=2) @@ -220,10 +228,38 @@ def store_selected(self, event: tk.Event = None) -> None: """ # Get the indices of the currently selected items indexes = self.choice_lb.curselection() - # Declare a list holding the values to store, based on the selection - self.lb_selected_values = list() + # Deselect the items if more than the maximum allowed items have been + # selected + if len(indexes) > self.MAX_SELECTABLE_ITEMS: + print("WARNING: only 10 items can be selected at once.") + # Get the indices of the items to be deselected + indxs = list(set(indexes) - set(self.stored_indxs)) + # Handle the case where the elements of the previous selection were + # lesser than the maximum allowable number + if len(self.stored_indxs) < self.MAX_SELECTABLE_ITEMS: + # Get the indexes to include depending on whether the first element + # in the next selection is before or after the last one of the + # previous selection + if indxs[0] > self.stored_indxs[-1]: + indxs_to_add = indxs[ + 0:self.MAX_SELECTABLE_ITEMS-len(self.stored_indxs)] + else: + indxs_to_add = indxs[ + len(self.stored_indxs)-self.MAX_SELECTABLE_ITEMS:] + # Update the stored indexes + self.stored_indxs = set(self.stored_indxs) | set(indxs_to_add) + # Get the indexes of the elements to deselect + indxs = set(indexes) - set(self.stored_indxs) + # Deselect each item one by one + for i in indxs: + self.choice_lb.selection_clear(i, i) + else: + self.stored_indxs = indexes + + # Clear the list of selected values + self.lb_selected_values.clear() # Loop over all the indexes - for i in indexes: + for i in self.stored_indxs: # Fill the list of selected values of the listbox self.lb_selected_values.append(self.choice_lb.get(i))