2022-02-15 20:03:45 +01:00
|
|
|
import tkinter as tk
|
|
|
|
import util
|
|
|
|
|
|
|
|
# easy way to get data out of window events
|
|
|
|
class Window_Interaction_Handler:
|
|
|
|
# constructor
|
|
|
|
def __init__(self):
|
|
|
|
self.__window_interactions = {}
|
|
|
|
|
|
|
|
# add a result for an interaction event, saves results in reverse order by default, can optionally call another function
|
|
|
|
def interact(self, name, result, reverse_order=True, additional_action=None, additional_action_parameters=()):
|
|
|
|
if name in self.__window_interactions:
|
|
|
|
if reverse_order:
|
|
|
|
self.__window_interactions[name] = [result] + self.__window_interactions[name]
|
|
|
|
else:
|
|
|
|
self.__window_interactions[name] = self.__window_interactions[name] + [result]
|
|
|
|
else:
|
|
|
|
self.__window_interactions[name] = [result]
|
|
|
|
|
|
|
|
if not additional_action==None:
|
|
|
|
additional_action(*additional_action_parameters)
|
|
|
|
|
|
|
|
# get first result for a given event from the list of results (newest (default) or oldest), removes the returned result from the list by default
|
|
|
|
def get_result(self, name, remove=True):
|
|
|
|
if name in self.__window_interactions and len(self.__window_interactions[name])>0:
|
|
|
|
if remove:
|
|
|
|
result = self.__window_interactions[name].pop(0)
|
|
|
|
if len(self.__window_interactions[name])==0:
|
|
|
|
del self.__window_interactions[name]
|
|
|
|
return result
|
|
|
|
else:
|
|
|
|
return self.__window_interactions[name][0]
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
|
|
|
# get all results for a given event
|
|
|
|
def get_results(self, name, clear=False):
|
|
|
|
if name in self.__window_interactions and len(self.__window_interactions[name])>0:
|
|
|
|
results = self.__window_interactions[name]
|
|
|
|
if clear:
|
|
|
|
del self.__window_interactions[name]
|
|
|
|
return results
|
|
|
|
|
|
|
|
# clear results for a given event
|
|
|
|
def clear(self, name):
|
|
|
|
if name in self.__window_interactions:
|
|
|
|
del self.__window_interactions[name]
|
|
|
|
|
|
|
|
# destructor
|
|
|
|
def __del__(self):
|
|
|
|
if len(self.__window_interactions)>0:
|
|
|
|
util.warn("__window_interactions not empty upon destruction of Window_Interaction_Handler:\n"+str(self.__window_interactions))
|
|
|
|
|
|
|
|
|
|
|
|
def not_implemented():
|
|
|
|
util.warn("Not implemented!")
|
|
|
|
|
|
|
|
# format:
|
|
|
|
# "":{} -> menu or submenu
|
|
|
|
# "":function -> menu entry
|
|
|
|
# "":None -> disabled menu entry
|
|
|
|
# None:None -> separator
|
|
|
|
#
|
|
|
|
# Entries with ... at the end are supposed to open dialogs whereas entries without dots are supposed to take effect immediately
|
|
|
|
menu_structure = {
|
|
|
|
"IDE": {
|
|
|
|
"Preferences...": not_implemented,
|
|
|
|
None: None,
|
|
|
|
"Quit": not_implemented
|
|
|
|
},
|
|
|
|
"Project": {
|
|
|
|
"New": {
|
|
|
|
"No known project types": None
|
|
|
|
},
|
|
|
|
"Open...": not_implemented,
|
|
|
|
"Close": {
|
|
|
|
"No open projects": None
|
|
|
|
},
|
|
|
|
None: None,
|
|
|
|
"Preferences...": not_implemented,
|
|
|
|
"Search...": not_implemented,
|
|
|
|
"Build": not_implemented
|
|
|
|
},
|
|
|
|
"File": {
|
|
|
|
"New...": not_implemented,
|
|
|
|
"Open...": not_implemented,
|
|
|
|
"Save": not_implemented,
|
|
|
|
"Close": not_implemented,
|
|
|
|
None: None,
|
|
|
|
"Rename...": not_implemented,
|
|
|
|
"Move...": not_implemented,
|
|
|
|
"View in File Explorer...": not_implemented
|
|
|
|
},
|
|
|
|
"Edit": {
|
|
|
|
"Cut": not_implemented,
|
|
|
|
"Copy": not_implemented,
|
|
|
|
"Paste": not_implemented,
|
|
|
|
"Move code...": not_implemented,
|
|
|
|
None: None,
|
|
|
|
"Search and Replace...": not_implemented,
|
|
|
|
None: None,
|
|
|
|
"Format": not_implemented,
|
|
|
|
"Indent": not_implemented,
|
|
|
|
"Unindent": not_implemented,
|
|
|
|
"Toggle Comment": not_implemented
|
|
|
|
},
|
|
|
|
"View": {
|
|
|
|
"Zoom in": not_implemented,
|
|
|
|
"Zoom out": not_implemented,
|
|
|
|
"Normal Size": not_implemented
|
|
|
|
},
|
|
|
|
"Help": {
|
|
|
|
"Manual...": not_implemented,
|
|
|
|
"About IDE...": not_implemented,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-19 04:46:36 +01:00
|
|
|
#FIXME: come up with a way to uniquely declare separators so they don't become the same element of a dict
|
|
|
|
|
2022-02-15 20:03:45 +01:00
|
|
|
def build_menu(structure_dict, menu):
|
|
|
|
for entry in structure_dict:
|
|
|
|
if structure_dict[entry]==None:
|
|
|
|
if entry==None:
|
|
|
|
menu.add_separator()
|
|
|
|
else:
|
|
|
|
menu.add_command(label=entry)
|
|
|
|
menu.entryconfig(entry, state="disabled")
|
|
|
|
if isinstance(structure_dict[entry], dict):
|
|
|
|
submenu = tk.Menu(menu, tearoff=False)
|
|
|
|
build_menu(structure_dict[entry], submenu)
|
|
|
|
menu.add_cascade(label=entry, menu=submenu)
|
|
|
|
if callable(structure_dict[entry]):
|
|
|
|
menu.add_command(label=entry, command=structure_dict[entry])
|
|
|
|
|