blob: ec6ba239cbdef5665783daff119c7a0fa16cbfb7 [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, List, Dict, Optional
10from pydantic import BaseModel
11
12from .base import ConfigWidget
Philipp Lecefab922022-04-26 22:06:33 +020013from .num_widget import NumWidget
Philipp Lecfb6d2a2022-04-26 22:08:48 +020014from .str_widget import StrWidget
Philipp Lee93a2c42022-04-26 22:11:14 +020015from .enum_widget import EnumDropdownWidget
Philipp Le6206b9c2022-04-26 22:14:03 +020016from .list_widget import ListBoxWidget
Philipp Le4071d912022-04-26 22:02:43 +020017
18
19_CLASS_REGISTRY: List[Type[ConfigWidget]] = [
Philipp Lecefab922022-04-26 22:06:33 +020020 NumWidget,
Philipp Lecfb6d2a2022-04-26 22:08:48 +020021 StrWidget,
Philipp Lee93a2c42022-04-26 22:11:14 +020022 EnumDropdownWidget,
Philipp Le4071d912022-04-26 22:02:43 +020023]
24
25
26def _find_widget_classes(tp: Type, is_list: bool = False) -> Dict[Optional[str], Type[ConfigWidget]]:
27 widget_classes: Dict[Optional[str], Type[ConfigWidget]] = {}
28 if is_list:
Philipp Le6206b9c2022-04-26 22:14:03 +020029 widget_classes[ListBoxWidget.FLAVOUR] = ListBoxWidget
Philipp Le4071d912022-04-26 22:02:43 +020030 else:
31 for cls in _CLASS_REGISTRY:
32 if issubclass(tp, cls.MODEL_TYPE):
33 widget_classes[cls.FLAVOUR] = cls
34 if len(widget_classes) == 0:
35 raise TypeError(f'No widget class for {repr(tp)} found.')
36 return widget_classes
37
38
39def _add_ui_create(model_cls: BaseModel, tp: Type[int], name: str, widget_type: Type[ConfigWidget],
40 flavour: Optional[str]):
41 suffix = f'_{flavour}' if flavour is not None else ''
42 setattr(model_cls, f'ui_create_{name}{suffix}', widget_type.make_ui_create_method(tp, name))
43
44
45def ui_create(cls: BaseModel):
46 for field in cls.__fields__.values():
47 name = field.name
48 tp = field.type_
49 is_list = isinstance(field.default, list)
50 try:
51 widget_classes = _find_widget_classes(tp, is_list)
52 for flavour, wgd_cls in widget_classes.items():
53 _add_ui_create(cls, tp, name, wgd_cls, flavour)
54 except TypeError as e:
55 print(e)
56 return cls