blob: 138af3a3abbeae3df98c58182caeafb401147dc0 [file] [log] [blame]
Philipp Lee93a2c42022-04-26 22:11:14 +02001# SPDX-License-Identifier: MPL-2.0
2# Copyright (c) 2022 Philipp Le <philipp@philipple.de>.
3# This Source Code Form is subject to the terms of the Mozilla Public
4# License, v. 2.0. If a copy of the MPL was not distributed with this
5# file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
7
8from typing import Type
9from tkinter import ttk, StringVar
10from pydantic import BaseModel
11from enum import Enum
12
13from .base import make_config_widget_base
14
15
16class EnumDropdownWidget(make_config_widget_base(ttk.OptionMenu)):
17 MODEL_TYPE = Enum
18 FLAVOUR = 'dropdown'
19
20 def __init__(self, model: BaseModel, model_key: str, tp: Type, parent, *args, **kwargs):
21 self._var = StringVar(parent)
22 super().__init__(model, model_key, tp, parent, self._var, *args, **kwargs)
23
24 def _get_choices(self):
25 return [val for val in self.type_.__members__.values()]
26
27 def _get_choices_str(self):
28 return [str(val.value) for val in self._get_choices()]
29
30 def sync_out(self) -> None:
31 try:
32 index = self._get_choices_str().index(self._var.get())
33 val = self._get_choices()[index]
34 setattr(self.model, self.model_key, val)
35 self.notify_change()
36 except ValueError:
37 # Tolerate temporarily invalid values
38 raise
39 pass
40
41 def sync_in(self) -> None:
42 val = getattr(self.model, self.model_key)
43 index = self._get_choices().index(val)
44 choices = self._get_choices_str()
45 self.set_menu(choices[index], *choices)
46
47 def _config_widget(self):
48 self._var.trace('w', lambda x, y, z: self.sync_out())
49 self.sync_in()