Skip to content

Commit 881840c

Browse files
committed
Added Ttk catalog plugin (enabled by flag)
1 parent 7c4ea70 commit 881840c

File tree

4 files changed

+334
-2
lines changed

4 files changed

+334
-2
lines changed

EDMarketConnector.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,12 @@
184184
'--killswitches-file',
185185
help='Specify a custom killswitches file',
186186
)
187+
188+
parser.add_argument(
189+
'--ttk-catalog',
190+
help='Replace plugins with a catalog of Ttk widgets',
191+
action='store_true',
192+
)
187193
###########################################################################
188194

189195
args: argparse.Namespace = parser.parse_args()
@@ -220,6 +226,9 @@
220226
if args.eddn_tracking_ui:
221227
config.set_eddn_tracking_ui()
222228

229+
if args.ttk_catalog:
230+
config.set_ttk_catalog()
231+
223232
if args.force_edmc_protocol:
224233
if sys.platform == 'win32':
225234
config.set_auth_force_edmc_protocol()

config/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ class AbstractConfig(abc.ABC):
202202
__auth_force_edmc_protocol = False # Should we force edmc:// protocol ?
203203
__eddn_url = None # Non-default EDDN URL
204204
__eddn_tracking_ui = False # Show EDDN tracking UI ?
205+
__ttk_catalog = False # Load Ttk catalog plugin ?
205206

206207
def __init__(self) -> None:
207208
self.home_path = pathlib.Path.home()
@@ -245,6 +246,19 @@ def auth_force_edmc_protocol(self) -> bool:
245246
"""
246247
return self.__auth_force_edmc_protocol
247248

249+
def set_ttk_catalog(self):
250+
"""Set flag to load the Ttk widget catalog plugin."""
251+
self.__ttk_catalog = True
252+
253+
@property
254+
def ttk_catalog(self) -> bool:
255+
"""
256+
Determine if the Ttk widget catalog plugin is loaded.
257+
258+
:return: bool - Should the Ttk catalog plugin be loaded?
259+
"""
260+
return self.__ttk_catalog
261+
248262
def set_eddn_url(self, eddn_url: str):
249263
"""Set the specified eddn URL."""
250264
self.__eddn_url = eddn_url

plug.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,11 @@ def load_plugins(master: tk.Tk) -> None:
162162
# Add plugin folder to load path so packages can be loaded from plugin folder
163163
sys.path.append(config.plugin_dir)
164164

165-
found = _load_found_plugins()
166-
PLUGINS.extend(sorted(found, key=lambda p: operator.attrgetter('name')(p).lower()))
165+
if config.ttk_catalog:
166+
PLUGINS.append(_load_ttk_catalog_plugin())
167+
else:
168+
found = _load_found_plugins()
169+
PLUGINS.extend(sorted(found, key=lambda p: operator.attrgetter('name')(p).lower()))
167170

168171

169172
def _load_internal_plugins():
@@ -179,6 +182,15 @@ def _load_internal_plugins():
179182
return internal
180183

181184

185+
def _load_ttk_catalog_plugin():
186+
try:
187+
plugin = Plugin('ttk_catalog', os.path.join(config.internal_plugin_dir_path, '_ttk_catalog.py'), logger)
188+
plugin.folder = None
189+
return plugin
190+
except Exception:
191+
logger.exception(f'Failure loading internal Plugin "ttk_catalog"')
192+
193+
182194
def _load_found_plugins():
183195
found = []
184196
# Load any plugins that are also packages first, but note it's *still*

plugins/_ttk_catalog.py

Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
"""
2+
_ttk_catalog.py - Catalog of ttk widgets.
3+
4+
Copyright (c) EDCD, All Rights Reserved
5+
Licensed under the GNU General Public License.
6+
See LICENSE file.
7+
8+
Based on https://github.com/rdbende/Azure-ttk-theme/blob/main/example.py
9+
"""
10+
import tkinter as tk
11+
from tkinter import ttk
12+
13+
from EDMCLogging import get_main_logger
14+
15+
logger = get_main_logger()
16+
17+
18+
class Catalog(ttk.Frame):
19+
def __init__(self, parent):
20+
super().__init__()
21+
22+
# Make the app responsive
23+
for index in [0, 1, 2]:
24+
self.columnconfigure(index=index, weight=1)
25+
self.rowconfigure(index=index, weight=1)
26+
27+
# Create value lists
28+
self.option_menu_list = ["", "OptionMenu", "Option 1", "Option 2"]
29+
self.combo_list = ["Combobox", "Editable item 1", "Editable item 2"]
30+
self.readonly_combo_list = ["Readonly combobox", "Item 1", "Item 2"]
31+
32+
# Create control variables
33+
self.var_0 = tk.BooleanVar()
34+
self.var_1 = tk.BooleanVar(value=True)
35+
self.var_2 = tk.BooleanVar()
36+
self.var_3 = tk.IntVar(value=2)
37+
self.var_4 = tk.StringVar(value=self.option_menu_list[1])
38+
self.var_5 = tk.DoubleVar(value=75.0)
39+
40+
# Create widgets :)
41+
self.setup_widgets()
42+
43+
def setup_widgets(self):
44+
# Create a Frame for the Checkbuttons
45+
check_frame = ttk.LabelFrame(self, text="Checkbuttons", padding=(20, 10))
46+
check_frame.grid(
47+
row=0, column=0, padx=(20, 10), pady=(20, 10), sticky="nsew"
48+
)
49+
50+
# Checkbuttons
51+
check_1 = ttk.Checkbutton(
52+
check_frame, text="Unchecked", variable=self.var_0
53+
)
54+
check_1.grid(row=0, column=0, padx=5, pady=10, sticky="nsew")
55+
56+
check_2 = ttk.Checkbutton(
57+
check_frame, text="Checked", variable=self.var_1
58+
)
59+
check_2.grid(row=1, column=0, padx=5, pady=10, sticky="nsew")
60+
61+
check_3 = ttk.Checkbutton(
62+
check_frame, text="Third state", variable=self.var_2
63+
)
64+
check_3.state(["alternate"])
65+
check_3.grid(row=2, column=0, padx=5, pady=10, sticky="nsew")
66+
67+
check_4 = ttk.Checkbutton(
68+
check_frame, text="Disabled", state="disabled"
69+
)
70+
check_4.state(["disabled !alternate"])
71+
check_4.grid(row=3, column=0, padx=5, pady=10, sticky="nsew")
72+
73+
# Separator
74+
separator = ttk.Separator(self)
75+
separator.grid(row=1, column=0, padx=(20, 10), pady=10, sticky="ew")
76+
77+
# Create a Frame for the Radiobuttons
78+
radio_frame = ttk.LabelFrame(self, text="Radiobuttons", padding=(20, 10))
79+
radio_frame.grid(row=2, column=0, padx=(20, 10), pady=10, sticky="nsew")
80+
81+
# Radiobuttons
82+
radio_1 = ttk.Radiobutton(
83+
radio_frame, text="Unselected", variable=self.var_3, value=1
84+
)
85+
radio_1.grid(row=0, column=0, padx=5, pady=10, sticky="nsew")
86+
radio_2 = ttk.Radiobutton(
87+
radio_frame, text="Selected", variable=self.var_3, value=2
88+
)
89+
radio_2.grid(row=1, column=0, padx=5, pady=10, sticky="nsew")
90+
radio_4 = ttk.Radiobutton(
91+
radio_frame, text="Disabled", state="disabled"
92+
)
93+
radio_4.grid(row=3, column=0, padx=5, pady=10, sticky="nsew")
94+
95+
# Create a Frame for input widgets
96+
widgets_frame = ttk.Frame(self, padding=(0, 0, 0, 10))
97+
widgets_frame.grid(
98+
row=0, column=1, padx=10, pady=(30, 10), sticky="nsew", rowspan=3
99+
)
100+
widgets_frame.columnconfigure(index=0, weight=1)
101+
102+
# Entry
103+
entry = ttk.Entry(widgets_frame)
104+
entry.insert(0, "Entry")
105+
entry.grid(row=0, column=0, padx=5, pady=(0, 10), sticky="ew")
106+
107+
# Spinbox
108+
spinbox = ttk.Spinbox(widgets_frame, from_=0, to=100, increment=0.1)
109+
spinbox.insert(0, "Spinbox")
110+
spinbox.grid(row=1, column=0, padx=5, pady=10, sticky="ew")
111+
112+
# Combobox
113+
combobox = ttk.Combobox(widgets_frame, values=self.combo_list)
114+
combobox.current(0)
115+
combobox.grid(row=2, column=0, padx=5, pady=10, sticky="ew")
116+
117+
# Read-only combobox
118+
readonly_combo = ttk.Combobox(
119+
widgets_frame, state="readonly", values=self.readonly_combo_list
120+
)
121+
readonly_combo.current(0)
122+
readonly_combo.grid(row=3, column=0, padx=5, pady=10, sticky="ew")
123+
124+
# Menu for the Menubutton
125+
menu = tk.Menu(self)
126+
menu.add_command(label="Menu item 1")
127+
menu.add_command(label="Menu item 2")
128+
menu.add_separator()
129+
menu.add_command(label="Menu item 3")
130+
menu.add_command(label="Menu item 4")
131+
132+
# Menubutton
133+
menubutton = ttk.Menubutton(
134+
widgets_frame, text="Menubutton", menu=menu, direction="below"
135+
)
136+
menubutton.grid(row=4, column=0, padx=5, pady=10, sticky="nsew")
137+
138+
# OptionMenu
139+
optionmenu = ttk.OptionMenu(
140+
widgets_frame, self.var_4, *self.option_menu_list
141+
)
142+
optionmenu.grid(row=5, column=0, padx=5, pady=10, sticky="nsew")
143+
144+
# Button
145+
button = ttk.Button(widgets_frame, text="Button")
146+
button.grid(row=6, column=0, padx=5, pady=10, sticky="nsew")
147+
148+
# Accentbutton
149+
accentbutton = ttk.Button(
150+
widgets_frame, text="Accent button", style="Accent.TButton"
151+
)
152+
accentbutton.grid(row=7, column=0, padx=5, pady=10, sticky="nsew")
153+
154+
# Togglebutton
155+
togglebutton = ttk.Checkbutton(
156+
widgets_frame, text="Toggle button", style="Toggle.TButton"
157+
)
158+
togglebutton.grid(row=8, column=0, padx=5, pady=10, sticky="nsew")
159+
160+
# Switch
161+
switch = ttk.Checkbutton(
162+
widgets_frame, text="Switch", style="Switch.TCheckbutton"
163+
)
164+
switch.grid(row=9, column=0, padx=5, pady=10, sticky="nsew")
165+
166+
# Panedwindow
167+
paned = ttk.PanedWindow(self)
168+
paned.grid(row=0, column=2, pady=(25, 5), sticky="nsew", rowspan=3)
169+
170+
# Pane #1
171+
pane_1 = ttk.Frame(paned, padding=5)
172+
paned.add(pane_1, weight=1)
173+
174+
# Scrollbar
175+
scrollbar = ttk.Scrollbar(pane_1)
176+
scrollbar.pack(side="right", fill="y")
177+
178+
# Treeview
179+
treeview = ttk.Treeview(
180+
pane_1,
181+
selectmode="browse",
182+
yscrollcommand=scrollbar.set,
183+
columns=(1, 2),
184+
height=10,
185+
)
186+
treeview.pack(expand=True, fill="both")
187+
scrollbar.config(command=treeview.yview)
188+
189+
# Treeview columns
190+
treeview.column("#0", anchor="w", width=120)
191+
treeview.column(1, anchor="w", width=120)
192+
treeview.column(2, anchor="w", width=120)
193+
194+
# Treeview headings
195+
treeview.heading("#0", text="Column 1", anchor="center")
196+
treeview.heading(1, text="Column 2", anchor="center")
197+
treeview.heading(2, text="Column 3", anchor="center")
198+
199+
# Define treeview data
200+
treeview_data = [
201+
("", 1, "Parent", ("Item 1", "Value 1")),
202+
(1, 2, "Child", ("Subitem 1.1", "Value 1.1")),
203+
(1, 3, "Child", ("Subitem 1.2", "Value 1.2")),
204+
(1, 4, "Child", ("Subitem 1.3", "Value 1.3")),
205+
(1, 5, "Child", ("Subitem 1.4", "Value 1.4")),
206+
("", 6, "Parent", ("Item 2", "Value 2")),
207+
(6, 7, "Child", ("Subitem 2.1", "Value 2.1")),
208+
(6, 8, "Sub-parent", ("Subitem 2.2", "Value 2.2")),
209+
(8, 9, "Child", ("Subitem 2.2.1", "Value 2.2.1")),
210+
(8, 10, "Child", ("Subitem 2.2.2", "Value 2.2.2")),
211+
(8, 11, "Child", ("Subitem 2.2.3", "Value 2.2.3")),
212+
(6, 12, "Child", ("Subitem 2.3", "Value 2.3")),
213+
(6, 13, "Child", ("Subitem 2.4", "Value 2.4")),
214+
("", 14, "Parent", ("Item 3", "Value 3")),
215+
(14, 15, "Child", ("Subitem 3.1", "Value 3.1")),
216+
(14, 16, "Child", ("Subitem 3.2", "Value 3.2")),
217+
(14, 17, "Child", ("Subitem 3.3", "Value 3.3")),
218+
(14, 18, "Child", ("Subitem 3.4", "Value 3.4")),
219+
("", 19, "Parent", ("Item 4", "Value 4")),
220+
(19, 20, "Child", ("Subitem 4.1", "Value 4.1")),
221+
(19, 21, "Sub-parent", ("Subitem 4.2", "Value 4.2")),
222+
(21, 22, "Child", ("Subitem 4.2.1", "Value 4.2.1")),
223+
(21, 23, "Child", ("Subitem 4.2.2", "Value 4.2.2")),
224+
(21, 24, "Child", ("Subitem 4.2.3", "Value 4.2.3")),
225+
(19, 25, "Child", ("Subitem 4.3", "Value 4.3")),
226+
]
227+
228+
# Insert treeview data
229+
for item in treeview_data:
230+
treeview.insert(
231+
parent=item[0], index="end", iid=item[1], text=item[2], values=item[3]
232+
)
233+
if item[0] == "" or item[1] in {8, 21}:
234+
treeview.item(item[1], open=True) # Open parents
235+
236+
# Select and scroll
237+
treeview.selection_set(10)
238+
treeview.see(7)
239+
240+
# Notebook, pane #2
241+
pane_2 = ttk.Frame(paned, padding=5)
242+
paned.add(pane_2, weight=3)
243+
244+
# Notebook, pane #2
245+
notebook = ttk.Notebook(pane_2)
246+
notebook.pack(fill="both", expand=True)
247+
248+
# Tab #1
249+
tab_1 = ttk.Frame(notebook)
250+
for index in [0, 1]:
251+
tab_1.columnconfigure(index=index, weight=1)
252+
tab_1.rowconfigure(index=index, weight=1)
253+
notebook.add(tab_1, text="Tab 1")
254+
255+
# Scale
256+
scale = ttk.Scale(
257+
tab_1,
258+
from_=100,
259+
to=0,
260+
variable=self.var_5,
261+
command=lambda event: self.var_5.set(scale.get()),
262+
)
263+
scale.grid(row=0, column=0, padx=(20, 10), pady=(20, 0), sticky="ew")
264+
265+
# Progressbar
266+
progress = ttk.Progressbar(
267+
tab_1, value=0, variable=self.var_5, mode="determinate"
268+
)
269+
progress.grid(row=0, column=1, padx=(10, 20), pady=(20, 0), sticky="ew")
270+
271+
# Label
272+
label = ttk.Label(
273+
tab_1,
274+
text="ttk widgets for EDMC",
275+
justify="center",
276+
font=("-size", 15, "-weight", "bold"),
277+
)
278+
label.grid(row=1, column=0, pady=10, columnspan=2)
279+
280+
# Tab #2
281+
tab_2 = ttk.Frame(notebook)
282+
notebook.add(tab_2, text="Tab 2")
283+
284+
# Tab #3
285+
tab_3 = ttk.Frame(notebook)
286+
notebook.add(tab_3, text="Tab 3")
287+
288+
# Sizegrip
289+
sizegrip = ttk.Sizegrip(self)
290+
sizegrip.grid(row=100, column=100, padx=(0, 5), pady=(0, 5))
291+
292+
293+
def plugin_start3(path: str) -> str:
294+
return 'TtkCatalog'
295+
296+
297+
plugin_app = Catalog

0 commit comments

Comments
 (0)