Ejemplo n.º 1
0
class EdaPlacer(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master, relief=tk.SUNKEN, bd=2)
        self.create_menubar()
        self.master.config(menu=self.menubar)
        #self.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.canvas = XCanvas(self.master,
                              bg="white",
                              width=900,
                              height=540,
                              scalewidget=False,
                              bd=0,
                              highlightthickness=0)
        self.tkcon = TkConsole(self.master,
                               height=12,
                               width=90,
                               background='ivory')
        self.status = StatusBar(self.master)
        self.canvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.tkcon.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.status.pack(side=tk.BOTTOM, fill=tk.X, expand=True)

        self.tkcon.focus_set()

        self.lastdir = os.environ['HOMEPATH']
        self.units = []
        self.title()
        self.status.set("Level Placer Status")
        #self.update()

    def create_menubar(self):
        self.menubar = tk.Menu(self)

        # File menu
        menu = tk.Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="File", menu=menu)
        menu.add_command(label="New", command=self.new)
        menu.add_command(label="Open", command=self.open)
        menu.add_command(label="Exit", command=self.exit)

        # Edit menu
        menu = tk.Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="Edit", menu=menu)
        menu.add_command(label="Run Placer", command=self.place)
        menu.add_command(label="Collapse", command=self.collapse)
        menu.add_command(label="Clear ALL", command=self.clear)
        menu.add_separator()
        self.showNets = tk.IntVar(master=self.menubar, value=True)
        menu.add_checkbutton(label="Show nets",
                             variable=self.showNets,
                             command=self.draw_nets)

        # Help menu
        menu = tk.Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="Help", menu=menu)
        menu.add_command(label="About", command=self.about)
        menu.add_command(label="Help", command=self.help)

    def new(self):
        easygui.msgbox("The 'new' method is not implemented yet",
                       "Not implemented")

    def open(self, locfile=None):
        if locfile is None:
            filetypes = [['.loc', 'LOCATION files']]
            #lastdir = self.lastdir + '/*.loc'
            lastdir = self.lastdir
            locfile = easygui.fileopenbox('Dialog',
                                          'Select Location File',
                                          default=lastdir,
                                          filetypes=filetypes)
        if locfile is None:
            return
        design_dir, locfile = os.path.split(locfile)
        design_name = os.path.splitext(locfile)[0]
        self.design = Design(design_dir, design_name)
        self.title(self.design.name)
        self.clear()
        #self.canvas.fit()
        self.draw_units()
        self.draw_nets(True)
        self.status.set("units=%s  nets=%s  Total Area = %s  Total Length = %s" % \
                (len(self.design.units), len(self.design.nets), self.design.total_area(), self.design.total_length()))

    def draw_units(self):
        width = self.design.tech['design_width']
        height = self.design.tech['design_height']
        self.canvas.config(scrollregion=(-50, -50, width + 50, height + 50))
        self.canvas.draw_axis(10, 10)
        self.design.chip.draw(self.canvas,
                              outline='maroon',
                              width=3,
                              fill=None,
                              stipple=None,
                              tags=['root', 'chip'])
        for u in self.design.units:
            u.draw(self.canvas, fill='red', stipple='gray12')

    def draw_nets(self, show=None):
        if show is None:
            show = self.showNets.get()

        if show:
            for net in self.design.nets:
                net.draw(self.canvas)
        else:
            self.canvas.delete('net')

    def place(self, netlist=None):
        self.clear('eda&&net')
        if self.units is None:
            print("You must open a loc file first!")
            return
        self.placer = LevelPlacer(self.design.chip, self.design.units)
        self.placer.run()
        self.unplaced_units = self.placer.list_unplaced_units()
        print("Unplaced units:", self.unplaced_units)

        for u in self.placer.list_placed_units():
            #print(u)
            self.canvas.delete(u.name)
            u.draw(self.canvas, fill='green', stipple='gray12')
            #self.update()
            #time.sleep(0.05)
        for u in self.unplaced_units:
            self.canvas.tag_raise(u.name)

        if netlist is not None:
            nets = read_nets(netlist, udict)
            for n in nets:
                n.draw(self.canvas)
                #self.update()
                #time.sleep(1)
                self.canvas.delete(n.name)

        self.unplaced()

    def unplaced(self):
        "Put the unplaced units in a special container called unchip"
        x1 = self.design.chip.x1
        y1 = self.design.chip.y1 + self.design.chip.height() + 40
        x2 = self.design.chip.x2
        y2 = self.design.chip.y2 + self.design.chip.height() + 40
        self.unchip = Unit("unchip", x1, y1, x2, y2)
        self.unchip.draw(self.canvas,
                         outline='blue',
                         width=3,
                         tags=['unchip', 'unplaced'])
        self.canvas.config(scrollregion=(-50, -50, x2 + 50, y2 + 50))

        placer = LevelPlacer(self.unchip, list(self.unplaced_units), False)
        placer.run()
        for u in placer.list_placed_units():
            #print(u)
            self.canvas.delete(u.name)
            u.draw(self.canvas,
                   fill='red',
                   stipple='gray12',
                   tags=['unplaced'])
            #self.update()
            #time.sleep(0.05)

    def collapse(self):
        self.clear()
        for u in self.units:
            u.place(0, 0)
        self.draw_units()

    def exit(self):
        answer = easygui.ynbox("Exit?", "Are you sure you want to exit?")
        if answer:
            sys.exit(0)

    def clear(self, tag='eda'):
        self.canvas.delete(tag)

    def help(self):
        try:
            self.help_top.destroy()
        except:
            pass
        self.help_top = tk.Tk()
        self.help_top.wm_title('HELP WINDOW')
        t = tk.Text(self.help_top,
                    font=('Consolas', 10, 'bold'),
                    width=80,
                    height=24,
                    background='cornsilk',
                    foreground='blue')
        t.insert(
            END,
            "Edit the help method:\nRead some help file and insert it here")
        t.pack(fill=BOTH, expand=True)

    def title(self, postfix=None):
        ttl = "Simple Shelf Placer"
        if not postfix is None:
            ttl += ":" + " " + postfix
        self.master.wm_title(ttl)

    def about(self):
        easygui.msgbox(
            "Engineering Design Project\nEEE Depatment\nSimpleton College",
            "About EDA Application")

    def debug(self, event):
        #print(event.keysym)
        #print(self.panwin.cget('sashwidth'))
        #self.panwin.config(sashwidth=6)
        #print(self.winfo_geometry())
        #self.panwin.paneconfigure(self.tkcon, minsize=100)
        pass
Ejemplo n.º 2
0
class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title('THEE')
        self.minsize(550, 40)  # (width, height)
        self.winfo_screenwidth = self.winfo_screenwidth()
        self.winfo_screenheight = self.winfo_screenheight()
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)
        self.width = int(self.winfo_screenwidth / 3)
        self.height = int(self.winfo_screenheight / 3)
        self.geometry(f'{self.width}x{self.height}')

        self.thee_mode = 0  # 0: welcome, 1: editor, 2: terminal, 3: help
        self.count_text_changed = 0
        self.editor_mode_buffer = ""
        self.terminal_mode_buffer = ""
        self.key_buffer = []

        self.file_name = "untitled"
        self.status = "unsaved"
        self.spaces = 4
        self.line = 1
        self.column = 1

        self.foreground = config.color['foreground']
        self.background = config.color['background']
        self.text_foreground = config.color['text_foreground']
        self.text_background = config.color['text_background']
        self.insertbackground = config.color['insertbackground']
        self.statusbar_background = config.color['statusbarbg']

        self.frame1 = tk.Frame(self,
                               bg=self.background,
                               width=self.width,
                               height=self.height - 15)
        self.frame2 = tk.Frame(self,
                               bg=self.statusbar_background,
                               width=self.width,
                               height=10)

        self.frame1.grid(row=0, column=0, sticky='wens')
        self.frame2.grid(row=1, column=0, sticky='wens')

        self.frame1.grid_columnconfigure(1, weight=1)
        self.frame1.grid_rowconfigure(0, weight=1)

        self.config_dir = os.path.join(str(Path.home()), '.thee')

        self.text_font_size = config.font['text']['size']
        self.text_font_family = config.font['text']['family']

        self.statusbar_font_size = config.font['statusbar']['size']
        self.statusbar_font_family = config.font['statusbar']['family']

        self.create_widget()  # Entry point ==========#
        self.terminal = Terminal(self, self.text_area)  # run terminal

        self.bind_events()

        self.open_file = ''

        self.protocol("WM_DELETE_WINDOW", self.close_window)

    def create_widget(self):
        self.text_area = TextArea(self.frame1,
                                  bg=self.text_background,
                                  fg=self.text_foreground,
                                  undo=True,
                                  relief=tk.FLAT,
                                  font=(self.text_font_family,
                                        self.text_font_size),
                                  insertbackground=self.insertbackground)
        self.text_area.config(highlightthickness=0)
        self.text_area.grid(row=0, column=1, sticky='wens')
        self.text_area.focus_set()
        self.welcome(event=None)

        self.status_bar1 = StatusBar(self.frame2,
                                     bg="pink",
                                     width=30,
                                     height=10)
        self.status_bar2 = StatusBar(self.frame2,
                                     bg="orange",
                                     width=30,
                                     height=10)
        self.status_bar3 = StatusBar(self.frame2,
                                     bg="blue",
                                     width=30,
                                     height=10)
        self.status_bar4 = StatusBar(self.frame2,
                                     bg="green",
                                     width=30,
                                     height=10)
        self.status_bar5 = StatusBar(self.frame2,
                                     bg="purple",
                                     width=30,
                                     height=10)

        self.status_bar1.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        self.status_bar2.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        self.status_bar3.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        self.status_bar4.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        self.status_bar5.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

    def editor_mode(self, event=None):
        self.text_area.config(state=tk.NORMAL, tabs=4)
        self.text_area.delete('1.0', tk.END)
        self.text_area.insert(tk.END, self.editor_mode_buffer)
        self.highlighter = Highlighter(self.text_area)
        self.thee_mode = 1

        self.line_numbers = LineNumbers(self.frame1, self.text_area)
        self.line_numbers.config(bg=self.text_background,
                                 width=len(self.line_numbers.line_number) * 10,
                                 highlightthickness=0)
        self.line_numbers.grid(row=0, column=0, sticky='ns')

        self.status_bar1.set("Line %d, Column %d" % (self.line, self.column))
        self.status_bar3.set("%s" % self.file_name)
        self.status_bar4.set("Spaces: %d" % self.spaces)
        self.status_bar5.set("%s" % self.status)

    def terminal_mode(self, event=None):
        if self.thee_mode == 1:
            self.line_numbers.destroy()
        self.text_area.config(state=tk.NORMAL, tabs=4)
        self.text_area.delete('1.0', tk.END)
        self.text_area.insert(tk.END, self.terminal_mode_buffer)
        self.terminal.writeLoop()
        self.highlighter = Highlighter(self.text_area)
        self.thee_mode = 2

    def text_been_modified(self, event=None):
        flag = self.text_area.edit_modified()
        if flag:  # prevent from getting called twice
            if self.thee_mode == 1 and self.count_text_changed > 1:  # editor mode
                self.editor_mode_buffer = self.text_area.get(
                    1.0, tk.END + "-1c")
                self.status = "unsaved"
                self.status_bar5.set("%s" % self.status)
                self.update_line_column()
                self.line_numbers.config(
                    width=len(self.line_numbers.line_number) * 10)
            elif self.thee_mode == 2 and self.count_text_changed > 1:  # terminal mode
                self.terminal_mode_buffer = self.text_area.get(
                    1.0, tk.END + "-1c")
            self.count_text_changed += 1
        #reset so this will be called on the next change
        self.text_area.edit_modified(False)

    def retrieve_selected_line(self, event=None):
        if self.thee_mode == 1:
            self.current_line = self.text_area.get("1.0", 'end').rstrip()
            if event.keysym.isnumeric():
                self.key_buffer.append(event.keysym)
                # check buffer after 500ms (0.5s)
                self.after(500, self.selected_line_action)

    def selected_line_action(self):
        if self.key_buffer:
            index = int(''.join(self.key_buffer)) - 1
            self.key_buffer.clear()
            self.selected_line = self.current_line.split('\n')[index]
            selected_str = self.selected_line + "\n"
            # write selected code line(s) to the console in order to it running
            self.terminal.proc.stdin.write(selected_str.encode())
            self.terminal.proc.stdin.flush()
            self.terminal_mode()

    def update_line_column(self, event=None):
        if self.thee_mode == 1:
            line, column = self.text_area.index(tk.INSERT).split('.')
            self.line = int(line)
            self.column = int(column) + 1
            self.status_bar1.set("Line %d, Column %d" %
                                 (self.line, self.column))

    def close_window(self):
        if self.editor_mode_buffer and self.status == "unsaved":  #and self.status.get() == "unsaved": #SATUSBAR
            if msg.askokcancel("Quit", "Would you like to save the data?"):
                self.file_save()
                self.terminal.alive = False
                self.terminal.destroy()
            else:
                self.terminal.alive = False
                self.terminal.destroy()
        else:
            self.terminal.alive = False
            self.terminal.destroy()

    def bind_events(self):
        self.focus_set()
        self.text_area.bind_all('<<Modified>>', self.text_been_modified)
        self.text_area.bind('<Return>', self.enter)
        self.bind_all('<Button-1>', self.update_line_column)

        self.bind_all('<Control-e>', self.editor_mode)
        self.bind_all('<Control-t>', self.terminal_mode)
        self.bind_all('<Control-Key>', self.retrieve_selected_line)
        self.bind('<Control-f>', self.show_find_window)

        self.bind('<Control-n>', self.file_new)
        self.bind('<Control-o>', self.file_open)
        self.bind('<Control-s>', self.file_save)
        self.bind('<Control-S>', self.file_save_as)

        self.bind('<Control-w>', self.welcome)
        self.bind('<Control-h>', self.help_about)

    def enter(self, event=None):
        if self.thee_mode == 2:
            self.terminal.enter()

    def show_find_window(self, event=None):
        FindWindow(self.frame1, self.text_area)

    def show_welcome_page(self):
        if self.thee_mode == 1:
            self.line_numbers.destroy()
        self.text_area.config(state=tk.NORMAL)
        self.text_area.delete('1.0', tk.END)
        message = '''
   		\n\n
   		            THEE

   		         version 1.0

   	   THE simple python key bindings  Editor

   	     type   Ctrl-h 	for help information

   	by Fidel R. Monteiro <*****@*****.**>
   		\n

   	    The Pynosso Project | Sat, Jun 26 2020 
   		'''
        self.text_area.insert(tk.END, message)
        self.text_area.config(state=tk.DISABLED)
        self.thee_mode = 0

    def show_about_page(self):
        if self.thee_mode == 1:
            self.line_numbers.destroy()
        self.text_area.config(state=tk.NORMAL)
        self.text_area.delete('1.0', tk.END)
        message = '''
                        HELP

        Mode Commands
            Ctrl+e : Text mode
            Ctrl+t : Terminal mode
            Ctrl+<number> : Run selected line in python console

        Editing Commands
            Ctrl+a : Select all text
            Ctrl+x : Cut selected text
            Ctrl+c : Copy selected text
            Ctrl+v : Paste cut/copied text
            Ctrl+z : Undo
            Ctrl+y : Redo

        File Commands
            Ctrl+o : Open file
            Ctrl+s : Save current content
            Ctrl+S : Save current content as <filename>
            Ctrl+p : Print current content
            Ctrl+n : Open new file

        General
            Ctrl+m : Change syntax highlighting
            Ctrl+g : Change colour scheme
            Ctrl+l : Change font
            Ctrl+h : Display this help window

        AUTHOR
                Written by Fidel R. Monteiro (fm65)
                Sat, Jun 26 2020

        thee version 1.0

        "simple is better than complex"
        '''
        self.text_area.insert(tk.END, message)
        self.text_area.config(state=tk.DISABLED)
        self.thee_mode = 3

    def apply_colour_scheme(self, foreground, background, text_foreground,
                            text_background):
        self.text_area.configure(fg=text_foreground, bg=text_background)
        self.background = background
        self.foreground = foreground
        for menu in self.all_menus:
            menu.configure(bg=self.background, fg=self.foreground)

    def update_font(self):
        #self.load_font_file(self.font_scheme_path)
        self.text_area.configure(font=(self.text_font_family,
                                       self.text_font_size))

    def create_config_directory_if_needed(self):
        if not os.path.exists(self.config_dir):
            os.mkdir(self.config_dir)

    # =========== Menu Functions ==============

    def file_new(self, event=None):
        """
        Ctrl+N
        """
        self.text_area.delete(1.0, tk.END)
        self.open_file = None
        self.editor_mode()
        self.line_numbers.force_update()

    def file_open(self, event=None):
        """
        Ctrl+O
        """
        self.editor_mode()
        file_to_open = filedialog.askopenfilename(filetypes=[('Python files',
                                                              '*.py')],
                                                  defaultextension='.py')
        if file_to_open:
            self.open_file = file_to_open
            self.file_name = self.open_file.split('/')[-1]
            self.status_bar3.set("%s" % self.file_name)

            self.text_area.display_file_contents(file_to_open)
            self.highlighter.force_highlight()
            self.line_numbers.force_update()

    def file_save(self, event=None):
        """
        Ctrl+s
        """
        current_file = self.open_file if self.open_file else None
        if not current_file:
            current_file = filedialog.asksaveasfilename(filetypes=[
                ('Python files', '*.py')
            ],
                                                        defaultextension='.py')
            self.open_file = current_file
            self.file_name = current_file.split('/')[-1]
            self.status_bar3.set("%s" % self.file_name)

        if current_file:
            contents = self.text_area.get(1.0, tk.END)
            with open(current_file, 'w') as file:
                file.write(contents)
                self.status = "saved"
                self.status_bar5.set("%s" % self.status)

    def file_save_as(self, event=None):
        """
        Ctrl+S
        """
        new_file_name = filedialog.asksaveasfilename(filetypes=[
            ('Python files', '*.py')
        ],
                                                     defaultextension='.py',
                                                     confirmoverwrite=False)
        f = open(self.new_file_name, 'w')
        f.write(self.get('1.0', 'end'))
        f.close()
        self.status = "saved"
        self.status_bar5.set("%s" % self.status)

    def edit_cut(self, event=None):
        """
        Ctrl+X
        """
        self.text_area.event_generate("<Control-x>")
        self.line_numbers.force_update()

    def edit_paste(self, event=None):
        """
        Ctrl+V
        """
        self.text_area.event_generate("<Control-v>")
        self.line_numbers.force_update()
        self.highlighter.force_highlight()

    def edit_copy(self, event=None):
        """
        Ctrl+C
        """
        self.text_area.event_generate("<Control-c>")

    def edit_select_all(self, event=None):
        """
        Ctrl+A
        """
        self.text_area.event_generate("<Control-a>")

    def edit_find_and_replace(self, event=None):
        """
        Ctrl+F
        """
        self.show_find_window()

    def welcome(self, event=None):
        """
        Ctrl+W
        """
        self.show_welcome_page()

    def help_about(self, event=None):
        """
        Ctrl+H
        """
        self.show_about_page()
Ejemplo n.º 3
0
class EdaApp(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master, relief=SUNKEN, bd=2)

        self.create_menubar()
        self.master.config(menu=self.menubar)
        self.pack(side=TOP, fill=BOTH, expand=True)

        panwin = PanedWindow(self,
                             orient=VERTICAL,
                             sashwidth=5,
                             bd=0,
                             bg='gray80',
                             opaqueresize=0)
        self.canvas = XCanvas(self.master,
                              bg="white",
                              width=1200,
                              height=640,
                              x_axis=11,
                              scalewidget=False,
                              bd=0,
                              highlightthickness=0)
        self.tkcon = TkConsole(self.master,
                               height=12,
                               width=90,
                               background='ivory')
        self.status = StatusBar(self.master)
        self.canvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.tkcon.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.status.pack(side=BOTTOM, fill=X, expand=False)

        self.tkcon.focus_set()

        # Put here all initializations you want to have in console
        # However it's better to use an initialization file for tkcon (look at tkcon.py)
        self.tkcon.eval('import os')
        self.tkcon.eval('import sys')
        self.tkcon.eval('from basics import *')
        self.status.set("%-60s %-16s %-16s",
                        "Status line for this eda app (60 chars)",
                        "Part2 (16c)", "Part3 (16c)")

    def create_menubar(self):
        self.menubar = tk.Menu(self)

        # File menu
        menu = tk.Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="File", menu=menu)
        menu.add_command(label="New", command=self.new)
        menu.add_command(label="Open", command=self.open)
        menu.add_command(label="Exit", command=self.exit)

        # Edit menu
        menu = tk.Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="Edit", menu=menu)
        menu.add_command(label="Cut", command=self.cut)
        menu.add_command(label="Copy", command=self.copy)
        menu.add_command(label="Paste", command=self.paste)
        menu.add_command(label="Clear ALL", command=self.clear)

        # Help menu
        menu = tk.Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="Help", menu=menu)
        menu.add_command(label="About", command=self.about)
        menu.add_command(label="Help", command=self.help)

    def debug(self, event):
        #print(event.keysym)
        #print(self.panwin.cget('sashwidth'))
        #self.panwin.config(sashwidth=6)
        #print(self.winfo_geometry())
        #self.panwin.paneconfigure(self.tkcon, minsize=100)
        pass

    def new(self):
        messagebox.showwarning("Not implemented",
                               "The 'new' method is not implemented yet")

    def open(self):
        messagebox.showwarning("Not implemented",
                               "The 'open' method is not implemented yet")

    def exit(self):
        answer = messagebox.askyesno("Exit?", "Are you sure you want to exit?")
        if answer:
            sys.exit(0)

    def clear(self):
        self.tkcon.clear()

    def cut(self):
        messagebox.showwarning("Not implemented",
                               "The 'cut' method is not implemented yet")

    def copy(self):
        messagebox.showwarning("Not implemented",
                               "The 'copy' method is not implemented yet")

    def paste(self):
        messagebox.showwarning("Not implemented",
                               "The 'paste' method is not implemented yet")

    def help(self):
        try:
            self.help_top.destroy()
        except:
            pass
        self.help_top = tk.Tk()
        self.help_top.wm_title('HELP WINDOW')
        t = tk.Text(self.help_top,
                    font=('Consolas', 10, 'bold'),
                    width=80,
                    height=24,
                    background='cornsilk',
                    foreground='blue')
        t.insert(
            END,
            "Edit the help method:\nRead some help file and insert it here")
        t.pack(fill=BOTH, expand=True)

    def about(self):
        messagebox.showinfo(
            "About EDA Application",
            "Engineering Design Project\nEEE Depatment\nPublic Education College"
        )