Source code for interface.edit_attributes

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

"""

import tkinter as tk
from tkinter import ttk
import customtkinter

[docs] class EditAttributes: """The class which is responsible for the look and workings of the edit_attributes page. """ def __init__(self, ec_app_ui): """Creates all variables and widgets for the edit_attributes page. """ self.ec_app_ui = ec_app_ui self.current_component = "" self.user_value_edit_attribute = tk.BooleanVar() self.primitive_types = ["int", "float", "bool"] self.selected_primitive_ea = tk.StringVar() self.selected_primitive_ea.set(self.primitive_types[0]) self.selected_level = tk.StringVar() self.selected_attribute = None ### Frames ### self.frame_small = tk.Frame(master = self.ec_app_ui.page_frame, bg=self.ec_app_ui.frame_colour , height = self.ec_app_ui.button_height , width = 3*self.ec_app_ui.button_width//2) ### Labels ### self.label_edit_attributes_name = tk.Label(self.ec_app_ui.page_frame,text="Attribute Name:" , font=self.ec_app_ui.font2, justify="left", bg=self.ec_app_ui.frame_colour , fg=self.ec_app_ui.label_text_colour) self.label_edit_attributes_type = tk.Label(self.ec_app_ui.page_frame,text="Attribute Type:" , font=self.ec_app_ui.font2, justify="left",bg=self.ec_app_ui.frame_colour , fg=self.ec_app_ui.label_text_colour) self.label_edit_attributes_default = tk.Label(self.ec_app_ui.page_frame , text="Attribute Default Value:", font=self.ec_app_ui.font2 , justify="left",bg=self.ec_app_ui.frame_colour,fg=self.ec_app_ui.label_text_colour) self.label_edit_attributes_component_name = tk.Label(self.ec_app_ui.page_frame , text="Select Component:",font=self.ec_app_ui.font2, justify="left" , bg=self.ec_app_ui.frame_colour,fg=self.ec_app_ui.label_text_colour) self.label_edit_attributes_layer = tk.Label(self.ec_app_ui.page_frame, text="At which layer:",font=self.ec_app_ui.font2, justify="left" , bg=self.ec_app_ui.frame_colour,fg=self.ec_app_ui.label_text_colour) ### Entry ### self.entry_edit_attributes_default = customtkinter.CTkTextbox(self.ec_app_ui.page_frame , font = self.ec_app_ui.font2, height=4*self.ec_app_ui.entry_height , fg_color = self.ec_app_ui.entry_colour,width = self.ec_app_ui.entry_width , text_color = self.ec_app_ui.entry_text_colour) self.entry_edit_attribute_name = customtkinter.CTkEntry(self.ec_app_ui.page_frame , font = self.ec_app_ui.font2, height = self.ec_app_ui.entry_height , width = self.ec_app_ui.entry_width, fg_color = self.ec_app_ui.entry_colour , text_color = self.ec_app_ui.entry_text_colour) ### Combobox ### self.dropdown_edit_attributes_components = customtkinter.CTkOptionMenu(self.ec_app_ui.page_frame , values = [], fg_color = self.ec_app_ui.dropdown_menu_color , button_color=self.ec_app_ui.comp_btn_colour, height=self.ec_app_ui.entry_height , button_hover_color= self.ec_app_ui.highlight_colour, width=self.ec_app_ui.entry_width , font = self.ec_app_ui.font2, command = self.selected_comp_attr) self.dropdown_edit_attributes_components.set("Select Component") self.dropdown_edit_attributes_attribute_type = customtkinter.CTkOptionMenu(self.ec_app_ui.page_frame , button_hover_color= self.ec_app_ui.highlight_colour , variable = self.selected_primitive_ea, values=self.primitive_types , fg_color = self.ec_app_ui.dropdown_menu_color , button_color=self.ec_app_ui.comp_btn_colour , height = self.ec_app_ui.entry_height, width=self.ec_app_ui.entry_width, font = self.ec_app_ui.font2) self.dropdown_edit_attributes_layer = customtkinter.CTkOptionMenu(self.ec_app_ui.page_frame , variable = self.selected_level , values = ["Component Layer", "Agent Layer", "Model Layer"] , fg_color = self.ec_app_ui.dropdown_menu_color , button_color=self.ec_app_ui.comp_btn_colour , button_hover_color= self.ec_app_ui.highlight_colour , height = self.ec_app_ui.entry_height, width=self.ec_app_ui.entry_width , font = self.ec_app_ui.font2, command = self.on_user_click) ### Buttons ### self.button_edit_attributes_edit = customtkinter.CTkButton(self.frame_small , hover_color=self.ec_app_ui.highlight_colour, text="Edit" , command=self.btn_edit_attributes_edit, fg_color=self.ec_app_ui.comp_btn_colour , font = self.ec_app_ui.font2, height=self.ec_app_ui.button_height , width=self.ec_app_ui.btn_comp_width) self.button_edit_attributes_remove = customtkinter.CTkButton(self.frame_small , hover_color=self.ec_app_ui.highlight_colour, text="Remove" , command=self.btn_edit_attributes_remove, fg_color=self.ec_app_ui.comp_btn_colour , font = self.ec_app_ui.font2, height=self.ec_app_ui.button_height , width=self.ec_app_ui.btn_comp_width) self.button_edit_attributes_save = customtkinter.CTkButton(self.ec_app_ui.page_frame , hover_color=self.ec_app_ui.highlight_colour, text="Save Attribute" , command=self.btn_edit_attributes_save, 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_width) ### Titles ### self.label_edit_attributes_title = tk.Label(self.ec_app_ui.title_frame ,text="Edit Attributes", font=self.ec_app_ui.font1, justify="left" ,bg=self.ec_app_ui.title_colour, fg=self.ec_app_ui.label_text_colour) ### Table for Attributes ### ttk.Style().configure("Treeview", background=self.ec_app_ui.tbl_colour , foreground=self.ec_app_ui.tbl_font_colour) self.attr_frame = customtkinter.CTkFrame(self.ec_app_ui.page_frame , fg_color=self.ec_app_ui.tbl_colour , height = 80 , width = self.ec_app_ui.window_width/4) self.attr_frame.grid_propagate(0) self.vertical_scroll = tk.Scrollbar(self.attr_frame) self.attr_tbl = ttk.Treeview(self.attr_frame,padding = 5,height = 5 , yscrollcommand=self.vertical_scroll.set) # The code below sets up the table for attributes self.attr_tbl['columns'] = 'Name' self.attr_tbl.column("#0", width=0, stretch='NO') self.attr_tbl.column("Name",anchor='center', width=self.ec_app_ui.btn_comp_width*3+5) self.attr_tbl.heading("#0",text="",anchor='center') self.attr_tbl.heading("Name",text="Attributes",anchor='center') self.attr_tbl.bind("<<TreeviewSelect>>", self.display_selected_attribute)
[docs] def clear_individual_attribute(self): """Clears the editing of attribute widgets """ self.dropdown_edit_attributes_attribute_type.grid_forget() self.label_edit_attributes_name.grid_forget() self.entry_edit_attribute_name.grid_forget() self.label_edit_attributes_type.grid_forget() self.label_edit_attributes_default.grid_forget() self.entry_edit_attributes_default.grid_forget() self.button_edit_attributes_save.grid_forget() self.label_edit_attributes_layer.grid_forget() self.dropdown_edit_attributes_layer.grid_forget()
[docs] def clear_edit_attributes(self): """Clears the tab as a whole """ self.attr_frame.grid_forget() self.attr_tbl.pack_forget() self.label_edit_attributes_component_name.grid_forget() self.dropdown_edit_attributes_components.grid_forget() self.button_edit_attributes_edit.grid_forget() self.button_edit_attributes_remove.grid_forget() self.label_edit_attributes_title.grid_forget() self.clear_individual_attribute() self.frame_small.grid_forget()
[docs] def on_user_click(self, *args): """When user selects the combo box """ att_vals = self.ec_app_ui.new_model.get_attribute(str(self.current_component) , str(self.selected_attribute)) level = att_vals.get_define_level() if self.dropdown_edit_attributes_layer.get() == "Component Layer" and level == "comp_lvl": self.entry_edit_attributes_default.delete("1.0", 'end-1c') default = self.ec_app_ui.new_model.get_attribute(self.current_component , self.selected_attribute).get_default_value() if default == {}: default = "" self.entry_edit_attributes_default.insert("1.0", default) self.label_edit_attributes_default.grid(row = 3, column = 0, padx = 150, pady = 5 , sticky="W") self.entry_edit_attributes_default.grid(row = 3, column = 1, pady = 5) elif self.dropdown_edit_attributes_layer.get() == "Component Layer" and level != "comp_lvl": self.entry_edit_attributes_default.delete("1.0", 'end-1c') default = "" self.entry_edit_attributes_default.insert("1.0", default) self.label_edit_attributes_default.grid(row = 3, column = 0, padx = 150, pady = 5 , sticky="W") self.entry_edit_attributes_default.grid(row = 3, column = 1, pady = 5) else: self.label_edit_attributes_default.grid_forget() self.entry_edit_attributes_default.grid_forget()
[docs] def edit_attribute_tab_btn(self): """Places all wigets on the page """ self.ec_app_ui.clear_all() self.button_edit_attributes_edit.grid_forget() self.button_edit_attributes_remove.grid_forget() self.label_edit_attributes_title.grid(row = 0, column = 0) self.dropdown_edit_attributes_components.configure(self ,values = self.ec_app_ui.new_model.get_list_components()) self.label_edit_attributes_component_name.grid(row = 0, column = 0, padx = (100,0) , pady = 5) self.dropdown_edit_attributes_components.grid(row = 0, column = 2, pady = 5, sticky = "W") self.dropdown_edit_attributes_components.set("Select Component")
[docs] def btn_edit_attributes_edit(self): """Fills in known information about the attribute. """ if self.selected_attribute != "": self.ec_app_ui.clear_all() self.label_edit_attributes_title.grid(row = 0, column = 0) self.button_edit_attributes_edit.grid_forget() self.button_edit_attributes_remove.grid_forget() att_vals = self.ec_app_ui.new_model.get_attribute(str(self.current_component) , str(self.selected_attribute)) ### Attribute name ### self.label_edit_attributes_name.grid(row = 0, column = 0,padx = 150,pady = 5,sticky="W") self.entry_edit_attribute_name.grid(row = 0, column = 1,pady = 5) self.entry_edit_attribute_name.insert(0, self.selected_attribute) self.entry_edit_attribute_name.configure(state= "disabled") ### Set Attribute Type ### self.selected_primitive_ea.set(att_vals.get_type_attr()) ### Set the level as what it was defined as ### level = att_vals.get_define_level() if level == "comp_lvl": level = "Component Layer" self.entry_edit_attributes_default.delete("1.0", 'end-1c') default = self.ec_app_ui.new_model.get_attribute(self.current_component , self.selected_attribute).get_default_value() if default == {}: default = "" self.entry_edit_attributes_default.insert("1.0", default) self.label_edit_attributes_default.grid(row = 3, column = 0, padx = 150, pady = 5 , sticky="W") self.entry_edit_attributes_default.grid(row = 3, column = 1, pady = 5) elif level == "model_lvl": level = "Model Layer" elif level == "agent_lvl": level = "Agent Layer" self.selected_level.set(level) ### Attribute type ### self.label_edit_attributes_type.grid(row = 1, column = 0,padx = 150, pady = 5, sticky="W") self.dropdown_edit_attributes_attribute_type.grid(row = 1, column = 1, pady = 5) if not self.ec_app_ui.new_model.get_component(self.current_component).get_is_class_component(): ### Attribute layer ### self.label_edit_attributes_layer.grid(row = 2, column = 0, padx = 150, pady = 5 , sticky="W") self.dropdown_edit_attributes_layer.grid(row = 2, column = 1, pady = 5) self.button_edit_attributes_save.grid(row = 4, column = 1, pady = 5)
[docs] def btn_edit_attributes_remove(self): """Phase 2 """ self.ec_app_ui.new_model.remove_attribute(self.current_component, self.selected_attribute) self.btn_edit_attributes_add()
[docs] def btn_edit_attributes_save(self): """Allows users to save the edited attribute to the backend. """ attribute = self.entry_edit_attribute_name.get() primitive = self.selected_primitive_ea.get() layer = self.dropdown_edit_attributes_layer.get() default = None if not self.ec_app_ui.new_model.get_component(self.current_component).get_is_class_component(): if layer == "Component Layer": default = self.entry_edit_attributes_default.get("1.0", 'end-1c') else: default = None layer = None if self.dropdown_edit_attributes_layer.get() == "Component Layer": layer = "comp_lvl" elif self.dropdown_edit_attributes_layer.get() == "Agent Layer": layer = "agent_lvl" default = None elif self.dropdown_edit_attributes_layer.get() == "Model Layer": layer = "model_lvl" default = None self.ec_app_ui.new_model.edit_attribute(self.current_component, attribute, primitive , layer, default) else: self.ec_app_ui.new_model.edit_attribute(self.current_component,attribute, primitive , "model_lvl", default) self.entry_edit_attribute_name.configure(state= "normal") self.entry_edit_attribute_name.delete(0,'end') self.clear_individual_attribute() self.edit_attribute_tab_btn()
[docs] def on_user_click_edit_attribute(self): """Checks whether the checkbox is clicked. """ if self.user_value_edit_attribute.get(): self.label_edit_attributes_default.grid_forget() self.entry_edit_attributes_default.grid_forget() else: self.entry_edit_attributes_default.delete("1.0", 'end-1c') self.label_edit_attributes_default.grid(row = 2, column = 0, padx = 150,pady = 5 , sticky="W") self.entry_edit_attributes_default.grid(row = 2, column = 1,pady = 5)
[docs] def on_selected_primitive(self, *args): """Required for dropdown box """
[docs] def selected_comp_attr(self, *args): """Checks which component the user has selected """ id4 = 0 self.selected_attribute = "" selected = self.dropdown_edit_attributes_components.get() self.current_component = selected self.attr_tbl.delete(*self.attr_tbl.get_children()) if not selected == "Select Component": arrt = self.ec_app_ui.new_model.get_list_attributes(selected) for i in (arrt): self.attr_tbl.insert(parent='',index="end",iid=id4,text='',values=(i,)) id4+=1 self.attr_frame.grid(row = 2,column = 1, pady = 20) self.vertical_scroll.pack(side="right", fill="y", padx=(0,5), pady=5) self.attr_tbl.pack(fill = "x", padx = (5,0), pady = 5) self.button_edit_attributes_edit.grid_forget() self.button_edit_attributes_remove.grid_forget()
[docs] def display_selected_attribute(self, *args): """Saves the attribute the user clicked on. """ selected_items = self.attr_tbl.selection() if selected_items: selected_item = self.attr_tbl.selection()[0] self.selected_attribute = self.attr_tbl.item(selected_item)['values'][0] self.frame_small.grid(row=3, column = 1) self.button_edit_attributes_edit.grid(row = 0,column = 0, padx = (0,15)) self.button_edit_attributes_remove.grid(row = 0,column = 1)