blob: d61ba04c8e5d5ae4eedd729dcdf3072a3e4e030e [file] [log] [blame]
Philipp Le4071d912022-04-26 22:02:43 +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
7from __future__ import annotations
8
9from typing import Type, Callable, List, Optional
10from tkinter import ttk
11from pydantic import BaseModel
12
13
14class ConfigWidget:
15 MODEL_TYPE: Type
16 FLAVOUR: Optional[str] = None
17
18 def listen_change(self, cb: Callable[[BaseModel, str, ConfigWidget], None]) -> None:
19 raise NotImplementedError
20
21 def notify_change(self) -> None:
22 raise NotImplementedError
23
24 def sync_out(self) -> None:
25 raise NotImplementedError
26
27 def sync_in(self) -> None:
28 raise NotImplementedError
29
30 def set_value(self, val) -> None:
31 raise NotImplementedError
32
33 @classmethod
34 def make_ui_create_method(cls, tp: Type, name: str):
35 raise NotImplementedError
36
37 def get_widget(self) -> ttk.Widget:
38 raise NotImplementedError
39
40
41def make_config_widget_base(base: Type[ttk.Widget]) -> Type[ttk.Widget, ConfigWidget]:
42 # The Pythonic way for generics
43
44 class ConfigWidgetBase(base, ConfigWidget):
45 def __init__(self, model: BaseModel, model_key: str, tp: Type, parent, *args, **kwargs):
46 super().__init__(parent, *args, **kwargs)
47 self.parent = parent
48 self._listeners: List[Callable[[BaseModel, str, ConfigWidget], None]] = []
49 self.model = model
50 self.model_key = model_key
51 self.type_ = tp
52
53 def listen_change(self, cb: Callable[[BaseModel, str, ConfigWidget], None]) -> None:
54 self._listeners.append(cb)
55
56 def notify_change(self) -> None:
57 for cb in self._listeners:
58 cb(self.model, self.model_key, self)
59
60 def sync_out(self) -> None:
61 raise NotImplementedError
62
63 def sync_in(self) -> None:
64 raise NotImplementedError
65
66 @classmethod
67 def make_ui_create_method(cls, tp: Type, name: str):
68 def create(self: BaseModel, parent, *args, **kwargs):
69 widget = cls(self, name, tp, parent, *args, **kwargs)
70 widget._config_widget()
71 return widget
72 return create
73
74 def _config_widget(self) -> None:
75 pass
76
77 def get_widget(self) -> ttk.Widget:
78 return self
79
80 return ConfigWidgetBase