Source code for interface.execute

"""
Frontend Systems Execute Page File for AGE-ABM Visual Interface
@Author Meghan Ireland
@Co-Authors Max Hall and Matthew Fleischman

@Reference thepythoncode.com. (n.d.). Code for How to Make a Python Code Editor using Tkinter in Python - Python Code. [online] 
Available at: https://thepythoncode.com/code/python-code-editor-using-tkinter-python [Accessed 14 Sep. 2023].
| Used as a basis for the designed code editor used as opposed library options

"""

import tkinter as tk
import re
import customtkinter


[docs] class Execute: """This class defines how the execute page looks and works. """ def __init__(self, ec_app_ui): """Defines all the variables and widgets for the execute page. """ self.ec_app_ui = ec_app_ui ### Comboboxes ### self.combobox_execute_systems = customtkinter.CTkOptionMenu(self.ec_app_ui.page_frame , values = [], fg_color = self.ec_app_ui.dropdown_menu_color , button_hover_color= self.ec_app_ui.highlight_colour , button_color=self.ec_app_ui.comp_btn_colour , height=self.ec_app_ui.entry_height, command=self.btn_execute_code , width=self.ec_app_ui.entry_height*6 , font = self.ec_app_ui.font2) self.combobox_execute_systems.set("Select System") ### Buttons ### self.button_execute_code = customtkinter.CTkButton(self.ec_app_ui.page_frame , hover_color=self.ec_app_ui.highlight_colour, text="💻 Code" , fg_color=self.ec_app_ui.comp_btn_colour , font = self.ec_app_ui.font2, height=self.ec_app_ui.entry_height , width=self.ec_app_ui.entry_height*4 - self.ec_app_ui.space_btw_btns) self.button_execute_save = customtkinter.CTkButton(self.ec_app_ui.page_frame , hover_color=self.ec_app_ui.highlight_colour, text="✔️ Save Execute" , command=self.btn_execute_save, fg_color=self.ec_app_ui.comp_btn_colour , font = self.ec_app_ui.font2, width = self.ec_app_ui.entry_height*9) ### Labels ### self.label_execute_choose_system = tk.Label(self.ec_app_ui.page_frame , text="System's Execute to code:", font=self.ec_app_ui.font2 , bg=self.ec_app_ui.frame_colour, fg=self.ec_app_ui.label_text_colour) ### Titles ### self.label_execute_title = tk.Label(self.ec_app_ui.title_frame, text="Execute Function" , font=self.ec_app_ui.font1, bg=self.ec_app_ui.title_colour , fg=self.ec_app_ui.label_text_colour) self.previous_text = '' # Define colors for the variouse types of tokens self.normal = "white" self.keywords = "#C766FE" self.comments = "#5b8746" self.string = "#bf6839" self.function = "#63b5e3" self.brackets = "#f3bb11" self.background = "#2A2A2A" self.square = "#bf68d1" self.font = 'Consolas 11' self.repl = [['(^| )(False|None|True|and|as|assert|async|await|break|class|continue|del|elif|else|except|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|raise|return|try|while|with|yield)($| )', self.keywords], ['(^|\t)(False|None|True|and|as|assert|async|await|break|class|continue|del|elif|else|except|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|raise|return|try|while|with|yield)($| )', self.keywords], ['".*?"', self.string], ['\'.*?\'', self.string], ['#.*?$', self.comments], ['def', self.function], ['self', self.function], ['\(', self.brackets], ['\)', self.brackets], ['\[',self.square], ['\]',self.square]] # Make the Text Widget self.horizontal_scroll=tk.Scrollbar(self.ec_app_ui.root, orient='horizontal') self.edit_area = tk.Text( self.ec_app_ui.page_frame, background=self.background, foreground=self.normal, insertbackground=self.normal, relief="flat", borderwidth=0, font=self.font, wrap='none', xscrollcommand=self.horizontal_scroll.set ) self.edit_area.configure(wrap=None) self.edit_area.bind('<KeyRelease>', self.changes)
[docs] def clear_execute(self): """This method clears the execute page. """ self.label_execute_title.grid_forget() self.label_execute_choose_system.grid_forget() self.edit_area.grid_forget() self.combobox_execute_systems.grid_forget() self.button_execute_code.grid_forget() self.button_execute_save.grid_forget()
[docs] def execute_tab_btn(self): """This method creats the execute page. """ if not self.ec_app_ui.collapsed: self.ec_app_ui.collapsed = False self.ec_app_ui.collapse_tab_btn() self.ec_app_ui.clear_all() self.label_execute_title.grid(row = 0, column = 0) self.label_execute_choose_system.grid(row = 0, column = 0,padx = 150,pady = 5,sticky="W") self.combobox_execute_systems.configure(self , values=self.ec_app_ui.new_model.get_list_systems()) self.combobox_execute_systems.grid(row = 0, column = 2,pady = 5)
[docs] def btn_execute_save(self): """This saves the execute function for the selected system. """ system_selected = self.combobox_execute_systems.get() self.combobox_execute_systems.set("Select System") function = self.edit_area.get('1.0','end') self.ec_app_ui.new_model.add_execute(system_selected, function) self.edit_area.delete('1.0','end') self.edit_area.grid_forget() self.button_execute_save.grid_forget() self.combobox_execute_systems.grid(row = 0, column = 2,pady = 5)
[docs] def btn_execute_code(self, *args): """This method allows the user to edit the execute function for the selected system """ system_selected = self.combobox_execute_systems.get() if not system_selected == "": self.edit_area.insert('1.0',self.ec_app_ui.new_model.get_execute(system_selected)) self.edit_area.configure(width = 2*self.ec_app_ui.window_width//18, height = 27) self.edit_area.grid(row = 1, column = 0,pady = 5,columnspan = 5, padx=20) self.button_execute_save.grid(row = 2, column = 2,pady = 5) self.combobox_execute_systems.grid_forget() self.button_execute_code.grid_forget()
[docs] def selected_system(self,*args): """This method is required by a combobox """ if self.combobox_execute_systems.get() != "Select System": self.button_execute_code.grid(row = 0, column = 3,pady = 5,padx=5)
[docs] def changes(self, *args): """Adds the edits """ # If actually no changes have been made stop / return the function if self.edit_area.get('1.0', 'end') == self.previous_text: return # Remove all tags so they can be redrawn for tag in self.edit_area.tag_names(): self.edit_area.tag_remove(tag, "1.0", "end") # Add tags where the search_re function found the pattern i = 0 for pattern, color in self.repl: for start, end in self.search_re(pattern, self.edit_area.get('1.0', 'end')): self.edit_area.tag_add(f'{i}', start, end) self.edit_area.tag_config(f'{i}', foreground=color) i+=1 self.previous_text = self.edit_area.get('1.0', 'end')
[docs] def search_re(self, pattern, text): """Searches for patterns """ matches = [] text = text.splitlines() for i, line in enumerate(text): for match in re.finditer(pattern, line): matches.append( (f"{i + 1}.{match.start()}", f"{i + 1}.{match.end()}") ) return matches
[docs] def rgb(self, rgb): """RGB value """ return "#%02x%02x%02x" % rgb
[docs] def opened_from_systems(self, system): """If user opened tab from the systems page """ if not system == "": self.ec_app_ui.clear_all() self.label_execute_title.grid(row = 0, column = 0) self.label_execute_choose_system.grid(row = 0, column = 0,padx = 150,pady = 5,sticky="W") self.edit_area.insert('1.0',self.ec_app_ui.new_model.get_execute(system)) self.edit_area.configure(width = 2*self.ec_app_ui.window_width//18, height = 27) self.edit_area.grid(row = 1, column = 0,pady = 5,columnspan = 5, padx=20) self.button_execute_save.grid(row = 2, column = 2,pady = 5) self.combobox_execute_systems.grid_forget() self.button_execute_code.grid_forget() self.combobox_execute_systems.configure(self , values=self.ec_app_ui.new_model.get_list_systems()) if not self.ec_app_ui.collapsed: self.ec_app_ui.collapsed = False self.ec_app_ui.collapse_tab_btn()