feat: Main window and sub-window registration
Change-Id: I1cdb905ba06139f8b6f63b7411c7c0c3f8f821fa
diff --git a/dcs/__main__.py b/dcs/__main__.py
new file mode 100644
index 0000000..194ffbd
--- /dev/null
+++ b/dcs/__main__.py
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: MPL-2.0
+# Copyright (c) 2022 Philipp Le <philipp@philipple.de>.
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+from .main import main
+
+
+if __name__ == '__main__':
+ main()
diff --git a/dcs/frames/__init__.py b/dcs/frames/__init__.py
new file mode 100644
index 0000000..4e5dd51
--- /dev/null
+++ b/dcs/frames/__init__.py
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: MPL-2.0
+# Copyright (c) 2022 Philipp Le <philipp@philipple.de>.
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+from typing import List, Type
+from . import base
+
+
+def get_windows() -> List[Type[base.Window]]:
+ return [
+ ]
+
+
+def get_groups() -> List[Type[base.Group]]:
+ return base.get_groups(get_windows())
+
+
+def get_win_of_group(grp: Type[base.Group]) -> List[Type[base.Window]]:
+ return base.get_win_of_group(get_windows(), grp)
diff --git a/dcs/frames/base.py b/dcs/frames/base.py
new file mode 100644
index 0000000..bc939d8
--- /dev/null
+++ b/dcs/frames/base.py
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: MPL-2.0
+# Copyright (c) 2022 Philipp Le <philipp@philipple.de>.
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+import logging
+from tkinter import ttk, Tk, Toplevel, BOTH
+from typing import Type, List
+
+
+class Group:
+ NAME: str
+
+
+class BaseFrame(ttk.Frame):
+ pass
+
+
+class Window:
+ GROUP: Type[Group]
+ TITLE: str
+ FRAME: Type[BaseFrame]
+
+ @classmethod
+ def make_title(cls) -> str:
+ return f'{cls.GROUP.NAME} - {cls.TITLE}'
+
+ @classmethod
+ def make_frame(cls, root) -> ttk.Frame:
+ frm = cls.FRAME(root)
+ frm.pack(expand=True, fill=BOTH)
+ return frm
+
+ @classmethod
+ def make_window(cls, root) -> Toplevel:
+ win = Toplevel(root)
+ win.title(cls.make_title())
+ cls.make_frame(win)
+ return win
+
+ @classmethod
+ def main(cls):
+ logging.basicConfig(level=logging.INFO)
+
+ root = Tk()
+ root.title(cls.make_title())
+ cls.make_frame(root)
+ root.mainloop()
+
+
+def get_groups(win_cls: List[Type[Window]]) -> List[Type[Group]]:
+ grp_cls: List[Type[Group]] = []
+ for win in win_cls:
+ if win.GROUP not in grp_cls:
+ grp_cls.append(win.GROUP)
+ return list(sorted(grp_cls, key=lambda grp: grp.NAME))
+
+
+def get_win_of_group(win_cls: List[Type[Window]], grp: Type[Group]) -> List[Type[Window]]:
+ return list(filter(lambda win: win.GROUP == grp, win_cls))
diff --git a/dcs/frames/groups.py b/dcs/frames/groups.py
new file mode 100644
index 0000000..4ad16f4
--- /dev/null
+++ b/dcs/frames/groups.py
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: MPL-2.0
+# Copyright (c) 2022 Philipp Le <philipp@philipple.de>.
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+from .base import Group
+
+
+class Ch02Group(Group):
+ NAME = 'Chapter 02'
diff --git a/dcs/main.py b/dcs/main.py
new file mode 100644
index 0000000..a955249
--- /dev/null
+++ b/dcs/main.py
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: MPL-2.0
+# Copyright (c) 2022 Philipp Le <philipp@philipple.de>.
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+from dcs.frames import get_groups, get_win_of_group
+from dcs.frames.base import Group, Window
+import logging
+from tkinter import ttk, Tk, BOTTOM, BOTH
+from typing import Type, Dict, Any
+import webbrowser
+
+
+class MainWindow(ttk.Frame):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ self.wdg_treeview = ttk.Treeview(self)
+ self.wdg_treeview.pack(expand=True, fill=BOTH)
+ self.wdg_treeview.bind('<Double-Button-1>', self._on_double_click)
+
+ self.group_ids: Dict[Type[Group], Any] = {}
+ self.win_ids: Dict[Type[Window], Any] = {}
+ for grp in get_groups():
+ self.group_ids[grp] = self.wdg_treeview.insert('', 'end', None, text=grp.NAME)
+ for win in get_win_of_group(grp):
+ self.win_ids[win] = self.wdg_treeview.insert(self.group_ids[grp], 'end', None, text=win.TITLE)
+
+ self.frm_copyright = ttk.Frame(self, height=35)
+ self.frm_copyright.pack(side=BOTTOM, expand=False)
+ ttk.Label(self.frm_copyright, text='Copyright (c) 2022 Philipp Le').pack()
+ self.wdg_license = ttk.Button(self.frm_copyright, text='Mozilla Public License v2.0',
+ command=self._view_license)
+ self.wdg_license.pack()
+
+ def find_win(self, iid) -> Type[Window]:
+ for win, win_iid in self.win_ids.items():
+ if win_iid == iid:
+ return win
+ raise KeyError
+
+ def _on_double_click(self, event):
+ item_id = event.widget.focus()
+ try:
+ win = self.find_win(item_id)
+ win.make_window(self)
+ except KeyError:
+ pass
+
+ def _view_license(self):
+ webbrowser.open('https://mozilla.org/MPL/2.0/', new=1)
+
+
+def main():
+ logging.basicConfig(level=logging.INFO)
+
+ root = Tk()
+ root.title('Digital Communication Systemes - Interactive')
+ root.geometry('800x600')
+ win = MainWindow(root)
+ win.pack(expand=True, fill=BOTH)
+ root.mainloop()
+
+
+if __name__ == '__main__':
+ main()