def __init__(self, controller): View.__init__(self, controller) # Lade Hilfe zu Befehlen # TODO aus Datei laden self.max_taktrate = 5 self.schriftart = "helvetica" self.schriftgröße = 10 #self.befehle = {"LDAD": ("n", "Lädt n in Akkumulator")} self.befehle = eval(open("befehle.txt").read(-1), {"__builtins__": None}) # Hauptfenster self.haupt = tk.Tk() self.dateiname = None self.setze_titel() self.haupt.protocol("WM_DELETE_WINDOW", self.beende) self.haupt.resizable(True, True) try: self.haupt.iconbitmap(default = "gui.ico") except TclError: pass self.haupt.rowconfigure(1, weight = 1) self.haupt.columnconfigure(0, weight = 1) menü = tk.Menu(self.haupt) menü_datei = tk.Menu(menü) menü_datei.add_command(label = "Neu", command = self.menü_datei_neu) menü_datei.add_command(label = "Öffnen", command = self.menü_datei_öffnen) menü_datei.add_command(label = "Speichern", command = self.menü_datei_speichern) menü_datei.add_command(label = "Speichern unter", command = self.menü_datei_speichern_unter) menü_datei.add_command(label = "Beenden", command = self.beende) menü.add_cascade(label = "Datei", menu = menü_datei) menü_bearbeiten = tk.Menu(menü) menü_bearbeiten.add_command(label = "Rückgängig", command = self.menü_bearbeiten_rückgängig) menü_bearbeiten.add_command(label = "Wiederherstellen", command = self.menü_bearbeiten_wiederherstellen) menü_bearbeiten.add_command(label = "Ausschneiden", command = self.menü_bearbeiten_ausschneiden) menü_bearbeiten.add_command(label = "Kopieren", command = self.menü_bearbeiten_kopieren) menü_bearbeiten.add_command(label = "Einfügen", command = self.menü_bearbeiten_einfügen) menü.add_cascade(label = "Bearbeiten", menu = menü_bearbeiten) menü_rechner = tk.Menu(menü) menü_rechner.add_command(label = "Starten", command = self.menü_rechner_starten) menü.add_cascade(label = "Rechner", menu = menü_rechner) menü_hilfe = tk.Menu(menü) menü_hilfe.add_command(label = "Über", command = self.menü_hilfe_über) menü.add_cascade(label = "Hilfe", menu = menü_hilfe) self.haupt.config(menu = menü) self.lbl_programm_code = tk.Label(self.haupt, text = "Programm-Code") self.lbl_programm_code.grid(row = 0, column = 0, sticky = "W") self.txt_code = SyntaxText(self.haupt, wrap = "none", bg = "#FFFFFF", schriftgröße = self.schriftgröße, schriftart = self.schriftart, befehle = list(self.befehle)) self.scy_code = tk.Scrollbar(self.haupt, command = self.txt_code.yview) self.scx_code = tk.Scrollbar(self.haupt, command = self.txt_code.xview, orient = "horizontal") self.txt_code.config(yscrollcommand = self.scy_code.set, xscrollcommand = self.scx_code.set) self.scx_code.grid(row = 6, column = 0, sticky = "EW") self.scy_code.grid(row = 1, column = 1, rowspan = 5, sticky = "NS") self.txt_code.grid(row = 1, column = 0, rowspan = 5, sticky = "NSEW") self.lst_befehle = tk.Listbox(self.haupt, activestyle = "dotbox", exportselection = 0, bg = "#FFFFFF") self.scy_befehle = tk.Scrollbar(command = self.lst_befehle.yview) self.lst_befehle.config(yscrollcommand = self.scy_befehle.set) self.lst_befehle.insert("end", *list(sorted(self.befehle))) self.scy_befehle.grid(row = 1, column = 3, rowspan = 5, sticky = "NS") self.lst_befehle.grid(row = 1, column = 2, rowspan = 5, sticky = "NSEW") self.lst_befehle.bind('<ButtonRelease-1>', self.befehl_anzeigen) self.lst_befehle.bind('<Return>', self.befehl_einfügen) self.lbl_befehl = tk.Label(self.haupt, text = "", width = 30, justify = "left") self.lbl_befehl.grid(row = 1, column = 4, sticky = "NW") self.lbl_befehl_erklärung = tk.Label(self.haupt, text = "n: Natürliche Zahl\na: Adresse\nU: unmittelbar\nD: direkt\nI: indirekt", justify = "left") self.lbl_befehl_erklärung.grid(row = 2, column = 4, sticky = "NW") # Rechner-Fenster self.rechner = tk.Toplevel(self.haupt) self.rechner.withdraw() self.rechner.title("Simulation - Von-Neumann-Rechner") self.rechner.protocol("WM_DELETE_WINDOW", self.rechner_beenden) self.rechner.rowconfigure(1, weight = 1) self.rechner.columnconfigure(4, weight = 1) self.rechner.resizable(False, False) self.img_schritt = tk.PhotoImage(file = "buttons/schritt.gif") self.btn_schritt = tk.Button(self.rechner, command = self.rechner_schritt, text = "Schritt", image = self.img_schritt) self.btn_schritt.grid(row = 0, column = 0, sticky = "NSW") self.img_start = tk.PhotoImage(file = "buttons/start.gif") self.btn_start = tk.Button(self.rechner, command = self.rechner_start, image = self.img_start) self.btn_start.grid(row = 0, column = 1, sticky = "NSW") self.img_pause = tk.PhotoImage(file = "buttons/pause.gif") self.btn_pause = tk.Button(self.rechner, command = self.rechner_pause, image = self.img_pause) self.btn_pause.grid(row = 0, column = 2, sticky = "NSW") self.img_stop = tk.PhotoImage(file = "buttons/stop.gif") self.btn_stop = tk.Button(self.rechner, command = self.rechner_beenden, image = self.img_stop) self.btn_stop.grid(row = 0, column = 3, sticky = "NSW") self.diagramm = RechnerDiagramm(self.rechner) self.diagramm.grid(row = 1, column = 0, columnspan = 5, sticky = "NSWE")
class ViewGUI(View): filetypes = [("Assembler-Code", "*.asm"), ("Text-Datei", "*.txt")] def __init__(self, controller): View.__init__(self, controller) # Lade Hilfe zu Befehlen # TODO aus Datei laden self.max_taktrate = 5 self.schriftart = "helvetica" self.schriftgröße = 10 #self.befehle = {"LDAD": ("n", "Lädt n in Akkumulator")} self.befehle = eval(open("befehle.txt").read(-1), {"__builtins__": None}) # Hauptfenster self.haupt = tk.Tk() self.dateiname = None self.setze_titel() self.haupt.protocol("WM_DELETE_WINDOW", self.beende) self.haupt.resizable(True, True) try: self.haupt.iconbitmap(default = "gui.ico") except TclError: pass self.haupt.rowconfigure(1, weight = 1) self.haupt.columnconfigure(0, weight = 1) menü = tk.Menu(self.haupt) menü_datei = tk.Menu(menü) menü_datei.add_command(label = "Neu", command = self.menü_datei_neu) menü_datei.add_command(label = "Öffnen", command = self.menü_datei_öffnen) menü_datei.add_command(label = "Speichern", command = self.menü_datei_speichern) menü_datei.add_command(label = "Speichern unter", command = self.menü_datei_speichern_unter) menü_datei.add_command(label = "Beenden", command = self.beende) menü.add_cascade(label = "Datei", menu = menü_datei) menü_bearbeiten = tk.Menu(menü) menü_bearbeiten.add_command(label = "Rückgängig", command = self.menü_bearbeiten_rückgängig) menü_bearbeiten.add_command(label = "Wiederherstellen", command = self.menü_bearbeiten_wiederherstellen) menü_bearbeiten.add_command(label = "Ausschneiden", command = self.menü_bearbeiten_ausschneiden) menü_bearbeiten.add_command(label = "Kopieren", command = self.menü_bearbeiten_kopieren) menü_bearbeiten.add_command(label = "Einfügen", command = self.menü_bearbeiten_einfügen) menü.add_cascade(label = "Bearbeiten", menu = menü_bearbeiten) menü_rechner = tk.Menu(menü) menü_rechner.add_command(label = "Starten", command = self.menü_rechner_starten) menü.add_cascade(label = "Rechner", menu = menü_rechner) menü_hilfe = tk.Menu(menü) menü_hilfe.add_command(label = "Über", command = self.menü_hilfe_über) menü.add_cascade(label = "Hilfe", menu = menü_hilfe) self.haupt.config(menu = menü) self.lbl_programm_code = tk.Label(self.haupt, text = "Programm-Code") self.lbl_programm_code.grid(row = 0, column = 0, sticky = "W") self.txt_code = SyntaxText(self.haupt, wrap = "none", bg = "#FFFFFF", schriftgröße = self.schriftgröße, schriftart = self.schriftart, befehle = list(self.befehle)) self.scy_code = tk.Scrollbar(self.haupt, command = self.txt_code.yview) self.scx_code = tk.Scrollbar(self.haupt, command = self.txt_code.xview, orient = "horizontal") self.txt_code.config(yscrollcommand = self.scy_code.set, xscrollcommand = self.scx_code.set) self.scx_code.grid(row = 6, column = 0, sticky = "EW") self.scy_code.grid(row = 1, column = 1, rowspan = 5, sticky = "NS") self.txt_code.grid(row = 1, column = 0, rowspan = 5, sticky = "NSEW") self.lst_befehle = tk.Listbox(self.haupt, activestyle = "dotbox", exportselection = 0, bg = "#FFFFFF") self.scy_befehle = tk.Scrollbar(command = self.lst_befehle.yview) self.lst_befehle.config(yscrollcommand = self.scy_befehle.set) self.lst_befehle.insert("end", *list(sorted(self.befehle))) self.scy_befehle.grid(row = 1, column = 3, rowspan = 5, sticky = "NS") self.lst_befehle.grid(row = 1, column = 2, rowspan = 5, sticky = "NSEW") self.lst_befehle.bind('<ButtonRelease-1>', self.befehl_anzeigen) self.lst_befehle.bind('<Return>', self.befehl_einfügen) self.lbl_befehl = tk.Label(self.haupt, text = "", width = 30, justify = "left") self.lbl_befehl.grid(row = 1, column = 4, sticky = "NW") self.lbl_befehl_erklärung = tk.Label(self.haupt, text = "n: Natürliche Zahl\na: Adresse\nU: unmittelbar\nD: direkt\nI: indirekt", justify = "left") self.lbl_befehl_erklärung.grid(row = 2, column = 4, sticky = "NW") # Rechner-Fenster self.rechner = tk.Toplevel(self.haupt) self.rechner.withdraw() self.rechner.title("Simulation - Von-Neumann-Rechner") self.rechner.protocol("WM_DELETE_WINDOW", self.rechner_beenden) self.rechner.rowconfigure(1, weight = 1) self.rechner.columnconfigure(4, weight = 1) self.rechner.resizable(False, False) self.img_schritt = tk.PhotoImage(file = "buttons/schritt.gif") self.btn_schritt = tk.Button(self.rechner, command = self.rechner_schritt, text = "Schritt", image = self.img_schritt) self.btn_schritt.grid(row = 0, column = 0, sticky = "NSW") self.img_start = tk.PhotoImage(file = "buttons/start.gif") self.btn_start = tk.Button(self.rechner, command = self.rechner_start, image = self.img_start) self.btn_start.grid(row = 0, column = 1, sticky = "NSW") self.img_pause = tk.PhotoImage(file = "buttons/pause.gif") self.btn_pause = tk.Button(self.rechner, command = self.rechner_pause, image = self.img_pause) self.btn_pause.grid(row = 0, column = 2, sticky = "NSW") self.img_stop = tk.PhotoImage(file = "buttons/stop.gif") self.btn_stop = tk.Button(self.rechner, command = self.rechner_beenden, image = self.img_stop) self.btn_stop.grid(row = 0, column = 3, sticky = "NSW") self.diagramm = RechnerDiagramm(self.rechner) self.diagramm.grid(row = 1, column = 0, columnspan = 5, sticky = "NSWE") def setze_schriftart(self, art, größe): self.txt_code.setze_schriftart(art, größe) def befehl_anzeigen(self, event): b = self.lst_befehle.get(self.lst_befehle.curselection()[0]) befehl = self.befehle[b] self.lbl_befehl.config(text = b+" "+befehl[0]+"\n"+befehl[1]) def befehl_einfügen(self, event): b = self.lst_befehle.get(self.lst_befehle.curselection()[0]) self.txt_code.insert("insert", b+" ") self.txt_code.changed() def setze_titel(self): if (self.dateiname==None): self.haupt.title("Von-Neumann-Rechner") else: self.haupt.title(basename(self.dateiname)+" - Von-Neumann-Rechner") def beende(self): self.haupt.destroy() self.controller.beende() def schritt(self): self.haupt.update() def menü_datei_neu(self): self.dateiname = None self.txt_code.delete(1.0, "end") self.txt_code.changed() self.setze_titel() def menü_datei_öffnen(self): dateiname = tk.filedialog.askopenfilename(parent = self.haupt, title = "Datei öffnen", defaultextension = ".asm", filetypes = self.filetypes, initialdir = "programme/") if (dateiname!=""): try: f = open(dateiname) code = f.read(-1) f.close() self.dateiname = dateiname self.setze_titel() self.txt_code.delete("1.0", "end") self.txt_code.insert("1.0", code) self.txt_code.changed() except IOError: tk.messagebox.showerror("Fehler", "Konnte Datei '"+dateiname+"' nicht öffnen.") def datei_speichern(self, datei): print("Datei speichern: "+str(datei)) if (type(datei)==str): dateiname = datei try: f = open(dateiname, "w") except: tk.messagebox.showerror("Fehler", "Konnte Datei '"+dateiname+"' nicht öffnen.") return False else: dateiname = datei.name f = datei f.write(self.txt_code.get(1.0, "end")) f.close() self.dateiname = dateiname self.setze_titel() return True def menü_datei_speichern(self): # TODO bei jedem Speichern Unter wird am Ende eine neue Zeile hinzugefügt. Warum? if (self.dateiname==None): self.menü_datei_speichern_unter() else: self.datei_speichern(self.dateiname) def menü_datei_speichern_unter(self): datei = tk.filedialog.asksaveasfile(parent = self.haupt, title = "Datei speichern", defaultextension = ".asm", filetypes = self.filetypes, initialdir = "programme/") self.datei_speichern(datei) def menü_bearbeiten_rückgängig(self): self.txt_code.edit_undo() def menü_bearbeiten_wiederherstellen(self): self.txt_code.edit_redo() def menü_bearbeiten_ausschneiden(self): self.txt_code.event_generate("<<Cut>>") def menü_bearbeiten_kopieren(self): self.txt_code.event_generate("<<Copy>>") def menü_bearbeiten_einfügen(self): self.txt_code.event_generate("<<Paste>>") def menü_rechner_starten(self): self.controller.erzeuge_rechner() try: self.asmhints = self.controller.lade_programm(self.txt_code.get(1.0, "end")) self.rechner_zeige_status() self.rechner.deiconify() self.rechner.lift(self.haupt) except (SyntaxError, RuntimeError) as e: self.programm_fehler(e) def menü_hilfe_über(self): über = "Von-Neumann-Rechner "+self.controller.version+"\n"+\ "von Janosch Gräf <*****@*****.**>\n\n"+\ "Dieses Programm simuliert einen einfachen Computer nach der von-Neumann-Architektur" tk.messagebox.showinfo("Über Von-Neumann-Rechner", über, parent = self.haupt) def programm_fehler(self, e): if (type(e)==SyntaxError): tk.messagebox.showerror("Syntax-Fehler", str(e), parent = self.haupt) else: tk.messagebox.showerror("Fehler", str(e), parent = self.haupt) def rechner_eingabe(self, p): wert = PIOEingabeDialog(self.rechner, p).warte() self.diagramm.set_eingabe(p, wert) return wert def rechner_ausgabe(self, p, wert): self.diagramm.set_ausgabe(p, wert) tk.messagebox.showinfo("PIO-Ausgabe", "Port "+str(p)+":\n"+str(wert), parent = self.rechner) def rechner_beenden(self): self.rechner.withdraw() self.controller.zerstöre_rechner() def rechner_schritt(self): self.controller.rechner.schritt() self.rechner_zeige_status() def rechner_start(self): pass def rechner_pause(self): pass def rechner_zeige_status(self): r = self.controller.rechner d = self.diagramm for reg in d.register: if (reg=="BR" and r.register[reg] in r.befehle): d.set_register(reg, r.befehle[r.register[reg]][0]) else: d.set_register(reg, str(r.register[reg])) d.set_speicher(r, self.asmhints)