Esempio n. 1
0
    def selection_set(self, node):
        """Node names on the breakpoint tree are the filename.

        On Windows, this requires escaping, because backslashes
        in filenames cause problems with Tk.
        """
        Treeview.selection_set(self, self._nodify(node))
class Multicolumn_Listbox(object):
    _style_index = 0

    class List_Of_Rows(object):
        def __init__(self, multicolumn_listbox):
            self._multicolumn_listbox = multicolumn_listbox

        def data(self, index):
            return self._multicolumn_listbox.row_data(index)

        def get(self, index):
            return Row(self._multicolumn_listbox, index)

        def insert(self, data, index=None):
            self._multicolumn_listbox.insert_row(data, index)

        def delete(self, index):
            self._multicolumn_listbox.delete_row(index)

        def update(self, index, data):
            self._multicolumn_listbox.update_row(index, data)

        def select(self, index):
            self._multicolumn_listbox.select_row(index)

        def deselect(self, index):
            self._multicolumn_listbox.deselect_row(index)

        def set_selection(self, indices):
            self._multicolumn_listbox.set_selection(indices)

        def __getitem__(self, index):
            return self.get(index)

        def __setitem__(self, index, value):
            return self._multicolumn_listbox.update_row(index, value)

        def __delitem__(self, index):
            self._multicolumn_listbox.delete_row(index)

        def __len__(self):
            return self._multicolumn_listbox.number_of_rows

    class List_Of_Columns(object):
        def __init__(self, multicolumn_listbox):
            self._multicolumn_listbox = multicolumn_listbox

        def data(self, index):
            return self._multicolumn_listbox.get_column(index)

        def get(self, index):
            return Column(self._multicolumn_listbox, index)

        def delete(self, index):
            self._multicolumn_listbox.delete_column(index)

        def update(self, index, data):
            self._multicolumn_listbox.update_column(index, data)

        def __getitem__(self, index):
            return self.get(index)

        def __setitem__(self, index, value):
            return self._multicolumn_listbox.update_column(index, value)

        def __delitem__(self, index):
            self._multicolumn_listbox.delete_column(index)

        def __len__(self):
            return self._multicolumn_listbox.number_of_columns

    def __init__(self,
                 master,
                 columns,
                 data=None,
                 command=None,
                 sort=True,
                 select_mode=None,
                 heading_anchor=CENTER,
                 cell_anchor=W,
                 style=None,
                 height=None,
                 padding=None,
                 adjust_heading_to_content=False,
                 stripped_rows=None,
                 selection_background=None,
                 selection_foreground=None,
                 field_background=None,
                 heading_font=None,
                 heading_background=None,
                 heading_foreground=None,
                 cell_pady=2,
                 cell_background=None,
                 cell_foreground=None,
                 cell_font=None,
                 headers=True):

        self._stripped_rows = stripped_rows

        self._columns = columns

        self._number_of_rows = 0
        self._number_of_columns = len(columns)

        self.row = self.List_Of_Rows(self)
        self.column = self.List_Of_Columns(self)

        s = Style()

        if style is None:
            style_name = "Multicolumn_Listbox%s.Treeview" % self._style_index
            self._style_index += 1
        else:
            style_name = style

        style_map = {}
        if selection_background is not None:
            style_map["background"] = [('selected', selection_background)]

        if selection_foreground is not None:
            style_map["foeground"] = [('selected', selection_foreground)]

        if style_map:
            s.map(style_name, **style_map)

        style_config = {}
        if cell_background is not None:
            style_config["background"] = cell_background

        if cell_foreground is not None:
            style_config["foreground"] = cell_foreground

        if cell_font is None:
            font_name = s.lookup(style_name, "font")
            cell_font = nametofont(font_name)
        else:
            if not isinstance(cell_font, Font):
                if isinstance(cell_font, basestring):
                    cell_font = nametofont(cell_font)
                else:
                    if len(font) == 1:
                        cell_font = Font(family=cell_font[0])
                    elif len(font) == 2:
                        cell_font = Font(family=cell_font[0],
                                         size=cell_font[1])

                    elif len(font) == 3:
                        cell_font = Font(family=cell_font[0],
                                         size=cell_font[1],
                                         weight=cell_font[2])
                    else:
                        raise ValueError(
                            "Not possible more than 3 values for font")

            style_config["font"] = cell_font

        self._cell_font = cell_font

        self._rowheight = cell_font.metrics("linespace") + cell_pady
        style_config["rowheight"] = self._rowheight

        if field_background is not None:
            style_config["fieldbackground"] = field_background

        s.configure(style_name, **style_config)

        heading_style_config = {}
        if heading_font is not None:
            heading_style_config["font"] = heading_font
        if heading_background is not None:
            heading_style_config["background"] = heading_background
        if heading_foreground is not None:
            heading_style_config["foreground"] = heading_foreground

        heading_style_name = style_name + ".Heading"
        s.configure(heading_style_name, **heading_style_config)

        treeview_kwargs = {"style": style_name}

        if height is not None:
            treeview_kwargs["height"] = height

        if padding is not None:
            treeview_kwargs["padding"] = padding

        if headers:
            treeview_kwargs["show"] = "headings"
        else:
            treeview_kwargs["show"] = ""

        if select_mode is not None:
            treeview_kwargs["selectmode"] = select_mode

        self.interior = Treeview(master, columns=columns, **treeview_kwargs)

        if command is not None:
            self._command = command
            self.interior.bind("<<TreeviewSelect>>", self._on_select)

        for i in range(0, self._number_of_columns):

            if sort:
                self.interior.heading(
                    i,
                    text=columns[i],
                    anchor=heading_anchor,
                    command=lambda col=i: self.sort_by(col, descending=False))
            else:
                self.interior.heading(i,
                                      text=columns[i],
                                      anchor=heading_anchor)

            if adjust_heading_to_content:
                self.interior.column(i, width=Font().measure(columns[i]))

            self.interior.column(i, anchor=cell_anchor)

        if data is not None:
            for row in data:
                self.insert_row(row)

    @property
    def row_height(self):
        return self._rowheight

    @property
    def font(self):
        return self._cell_font

    def configure_column(self,
                         index,
                         width=None,
                         minwidth=None,
                         anchor=None,
                         stretch=None):
        kwargs = {}
        for config_name in ("width", "anchor", "stretch", "minwidth"):
            config_value = locals()[config_name]
            if config_value is not None:
                kwargs[config_name] = config_value

        self.interior.column('#%s' % (index + 1), **kwargs)

    def row_data(self, index):
        try:
            item_ID = self.interior.get_children()[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        return self.item_ID_to_row_data(item_ID)

    def update_row(self, index, data):
        try:
            item_ID = self.interior.get_children()[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        if len(data) == len(self._columns):
            self.interior.item(item_ID, values=data)
        else:
            raise ValueError("The multicolumn listbox has only %d columns" %
                             self._number_of_columns)

    def delete_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.delete(item_ID)
        self._number_of_rows -= 1

        if self._stripped_rows:
            for i in range(index, self._number_of_rows):
                self.interior.tag_configure(list_of_items[i + 1],
                                            background=self._stripped_rows[i %
                                                                           2])

    def insert_row(self, data, index=None):
        if len(data) != self._number_of_columns:
            raise ValueError("The multicolumn listbox has only %d columns" %
                             self._number_of_columns)

        if index is None:
            index = self._number_of_rows - 1

        item_ID = self.interior.insert('', index, values=data)
        self.interior.item(item_ID, tags=item_ID)

        self._number_of_rows += 1

        if self._stripped_rows:
            list_of_items = self.interior.get_children()

            self.interior.tag_configure(item_ID,
                                        background=self._stripped_rows[index %
                                                                       2])

            for i in range(index + 1, self._number_of_rows):
                self.interior.tag_configure(list_of_items[i],
                                            background=self._stripped_rows[i %
                                                                           2])

    def column_data(self, index):
        return [
            self.interior.set(child_ID, index)
            for child_ID in self.interior.get_children('')
        ]

    def update_column(self, index, data):
        for i, item_ID in enumerate(self.interior.get_children()):
            data_row = self.item_ID_to_row_data(item_ID)
            data_row[index] = data[i]

            self.interior.item(item_ID, values=data_row)

        return data

    def clear(self):
        # Another possibility:
        #  self.interior.delete(*self.interior.get_children())

        for row in self.interior.get_children():
            self.interior.delete(row)

        self._number_of_rows = 0

    def update(self, data):
        self.clear()

        for row in data:
            self.insert_row(row)

    def focus(self, index=None):
        if index is None:
            return self.interior.item(self.interior.focus())
        else:
            item = self.interior.get_children()[index]
            self.interior.focus(item)

    def state(self, state=None):
        if stateSpec is None:
            return self.interior.state()
        else:
            self.interior.state(state)

    @property
    def number_of_rows(self):
        return self._number_of_rows

    @property
    def number_of_columns(self):
        return self._number_of_columns

    def toogle_selection(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.selection_toggle(item_ID)

    def select_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.selection_add(item_ID)

    def deselect_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.selection_remove(item_ID)

    def deselect_all(self):
        self.interior.selection_remove(self.interior.selection())

    def set_selection(self, indices):
        list_of_items = self.interior.get_children()

        self.interior.selection_set(" ".join(list_of_items[row_index]
                                             for row_index in indices))

    @property
    def selected_rows(self):
        data = []
        for item_ID in self.interior.selection():
            data_row = self.item_ID_to_row_data(item_ID)
            data.append(data_row)

        return data

    @property
    def indices_of_selected_rows(self):
        list_of_indices = []
        for index, item_ID in enumerate(self.interior.get_children()):
            if item_ID in self.interior.selection():
                list_of_indices.append(index)

        return list_of_indices

    def delete_all_selected_rows(self):
        selected_items = self.interior.selection()
        for item_ID in selected_items:
            self.interior.delete(item_ID)

        number_of_deleted_rows = len(selected_items)
        self._number_of_rows -= number_of_deleted_rows

        return number_of_deleted_rows

    def _on_select(self, event):
        for item_ID in event.widget.selection():
            data_row = self.item_ID_to_row_data(item_ID)
            self._command(data_row)

    def item_ID_to_row_data(self, item_ID):
        item = self.interior.item(item_ID)
        return item["values"]

    @property
    def table_data(self):
        data = []

        for item_ID in self.interior.get_children():
            data_row = self.item_ID_to_row_data(item_ID)
            data.append(data_row)

        return data

    @table_data.setter
    def table_data(self, data):
        self.update(data)

    def cell_data(self, row, column):
        """Get the value of a table cell"""
        try:
            item = self.interior.get_children()[row]
        except IndexError:
            raise ValueError("Row index out of range: %d" % row)

        return self.interior.set(item, column)

    def update_cell(self, row, column, value):
        """Set the value of a table cell"""

        item_ID = self.interior.get_children()[row]

        data = self.item_ID_to_row_data(item_ID)

        data[column] = value
        self.interior.item(item_ID, values=data)

    def __getitem__(self, index):
        if isinstance(index, tuple):
            row, column = index
            return self.cell_data(row, column)
        else:
            raise Exception("Row and column indices are required")

    def __setitem__(self, index, value):
        if isinstance(index, tuple):
            row, column = index
            self.update_cell(row, column, value)
        else:
            raise Exception("Row and column indices are required")

    def bind(self, event, handler):
        self.interior.bind(event, handler)

    def sort_by(self, col, descending):
        """
        sort tree contents when a column header is clicked
        """
        # grab values to sort
        data = [(self.interior.set(child_ID, col), child_ID)
                for child_ID in self.interior.get_children('')]

        # if the Demo_programs to be sorted is numeric change to float
        try:
            data = [(float(number), child_ID) for number, child_ID in data]
        except ValueError:
            pass

        # now sort the Demo_programs in place
        data.sort(reverse=descending)
        for idx, item in enumerate(data):
            self.interior.move(item[1], '', idx)

        # switch the heading so that it will sort in the opposite direction
        self.interior.heading(
            col, command=lambda col=col: self.sort_by(col, not descending))

        if self._stripped_rows:
            list_of_items = self.interior.get_children('')
            for i in range(len(list_of_items)):
                self.interior.tag_configure(list_of_items[i],
                                            background=self._stripped_rows[i %
                                                                           2])

    def destroy(self):
        self.interior.destroy()

    def item_ID(self, index):
        return self.interior.get_children()[index]
Esempio n. 3
0
class App:
    def __init__(self, window):
        self.window = window
        self.mainDaemonAlive = False
        self.reportServerAlive = False
        self.reportServerBut = None
        self.progressbarRunning = False
        self.modelTree = None
        self.nsListStr = StringVar(self.window)
        self.filterStatusStr = StringVar(self.window)
        self.reportClientStatusStr = StringVar(self.window)
        self.playModeStr = StringVar(self.window, PLAY_MODES[0])
        self.pktCopyMaxSize = StringVar(self.window, "60")
        self.netInterfaceStr = StringVar(self.window, NET_INTERFACES[0])
        self.servicePortsStr = StringVar(self.window, "DNS")
        self.debugLevelStr = StringVar(self.window, DEBUG_LEVELS[0])
        self.filterControlButStr = StringVar(self.window, "START")
        self.reportClientControlButStr = StringVar(self.window, "START")
        self.progressFrame = Frame(self.window, width=700, height=20)
        self.progressFrame.pack(side=TOP)
        Frame(self.window, width=700, height=10).pack(side=TOP)
        self.parseNS("/etc/resolv.conf")
        self.getDaemonStatus()
        self.home()
        Frame(self.window, width=700, height=10).pack(side=TOP)
        self.window.resizable(width=False, height=False)
        Style().configure("TButton",
                          padding=6,
                          relief="raised",
                          background="#999")

    def home(self):
        """
    Initialize main window.
    """
        #Configured NS info frame
        nsFrame = Frame(self.window, relief="groove", borderwidth=1)
        Label(nsFrame, text="Configured nameservers:", height=2,
              anchor='w').grid(row=0, sticky="nsew")
        Label(nsFrame, textvariable=self.nsListStr,
              relief="sunken").grid(row=1, sticky="nsew")
        nsFrame.pack(side=TOP, fill=X, padx=20, pady=10, ipadx=20, ipady=5)
        Separator(self.window, orient="horizontal").pack(side=TOP,
                                                         padx=20,
                                                         fill=X)
        #Runtime params frame
        nsFrame = Frame(self.window, relief="groove", borderwidth=1)
        Label(nsFrame, text="Runtime configurations:", height=2,
              anchor='w').grid(row=0, sticky="nsew")
        Label(nsFrame, text="Play mode:").grid(row=1, column=0)
        OptionMenu(nsFrame, self.playModeStr, *PLAY_MODES).grid(row=1,
                                                                column=1)
        Separator(nsFrame, orient="vertical").grid(row=1,
                                                   column=2,
                                                   sticky="ns",
                                                   padx=20)
        Label(nsFrame, text="Interface:").grid(row=1, column=3)
        OptionMenu(nsFrame, self.netInterfaceStr,
                   *NET_INTERFACES).grid(row=1, column=4)
        Separator(nsFrame, orient="vertical").grid(row=1,
                                                   column=5,
                                                   sticky="ns",
                                                   padx=20)
        Label(nsFrame, text="Service:").grid(row=1, column=6)
        OptionMenu(nsFrame, self.servicePortsStr,
                   *NET_PORTS.keys()).grid(row=1, column=7)
        Separator(nsFrame, orient="vertical").grid(row=1,
                                                   column=8,
                                                   sticky="ns",
                                                   padx=20)
        Label(nsFrame, text="Debug level:").grid(row=1, column=9)
        OptionMenu(nsFrame, self.debugLevelStr, *DEBUG_LEVELS).grid(row=1,
                                                                    column=10)
        nsFrame.pack(side=TOP, fill=X, padx=20, pady=10, ipadx=20, ipady=5)
        Separator(nsFrame, orient="vertical").grid(row=2,
                                                   column=2,
                                                   sticky="ns",
                                                   padx=20)
        Label(nsFrame, text="Max datagram bytes to copy:").grid(row=2,
                                                                column=3)
        Entry(nsFrame,
              width=5,
              text=self.pktCopyMaxSize.get(),
              textvariable=self.pktCopyMaxSize).grid(row=2, column=4)
        Separator(nsFrame, orient="vertical").grid(row=2,
                                                   column=5,
                                                   sticky="ns",
                                                   padx=20)
        nsFrame.pack(side=TOP, fill=X, padx=20, pady=10, ipadx=20, ipady=5)
        Separator(self.window, orient="horizontal").pack(side=TOP,
                                                         padx=20,
                                                         fill=X)
        #filter daemon status frame
        statusFrame = Frame(self.window)
        Label(statusFrame, text="DNS filter status:", height=2,
              anchor='w').grid(row=0, column=0)
        Label(statusFrame, textvariable=self.filterStatusStr).grid(row=0,
                                                                   column=1)
        Button(statusFrame,
               textvariable=self.filterControlButStr,
               command=self.changeFilterStatus).grid(row=1, column=0, sticky=W)
        statusFrame.pack(side=TOP, fill=X, padx=20, pady=10, ipadx=20, ipady=5)
        Separator(self.window, orient="horizontal").pack(side=TOP,
                                                         padx=20,
                                                         fill=X)
        #model files frame
        modelFrame = Frame(self.window)
        Label(modelFrame,
              text="Model tags: [{}]".format(configs["model_tags"]),
              height=2,
              anchor='w').grid(row=0, sticky="nsew")
        Label(modelFrame, text="Model configuration", height=2).grid(row=1,
                                                                     sticky=W)
        self.modelConfigFrame(modelFrame).grid(row=2, columnspan=2, sticky=W)
        modelFrame.pack(side=TOP, fill=X, padx=20, pady=10, ipadx=20, ipady=5)
        Separator(self.window, orient="horizontal").pack(side=TOP,
                                                         padx=20,
                                                         fill=X)
        #web report client frame
        reportClientFrame = Frame(self.window)
        Label(reportClientFrame,
              text="Realtime report client status:",
              height=2,
              anchor='w').grid(row=0, column=0)
        Label(reportClientFrame,
              textvariable=self.reportClientStatusStr).grid(row=0, column=1)
        self.reportServerBut = Button(
            reportClientFrame,
            textvariable=self.reportClientControlButStr,
            command=self.changeReportClientStatus,
            state=self.getButtonStateForBool(self.mainDaemonAlive))
        self.reportServerBut.grid(row=1, column=0, sticky=W)
        reportClientFrame.pack(side=TOP,
                               fill=X,
                               padx=20,
                               pady=10,
                               ipadx=20,
                               ipady=5)
        Separator(self.window, orient="horizontal").pack(side=TOP,
                                                         padx=20,
                                                         fill=X)
        #Refresh status frame
        reloadFrame = Frame(self.window)
        Button(reloadFrame, text="Reload",
               command=self.getDaemonStatus).grid(row=0, column=1, sticky=E)
        reloadFrame.pack(side=TOP, fill=X, padx=20, pady=10, ipadx=20, ipady=5)
        Separator(self.window, orient="horizontal").pack(side=TOP,
                                                         padx=20,
                                                         fill=X)
        return

    def modelConfigFrame(self, parent):
        """
    Create and place next under parent a frame containing the current model configuration.
    """
        #Create container
        frame = Frame(parent)
        #Create treeView for model configuration
        self.modelTree = Treeview(parent, columns=('size', 'modified'))
        self.populateModelTree()
        self.modelTree.grid(row=1)

        #Bind right-click (<Button-3>) on tree items for contextual menus
        def treeContextualMenu(event):
            itemId = self.modelTree.identify_row(event.y)
            if itemId:
                self.modelTree.selection_set(itemId)
                item = self.modelTree.selection()
                ctxMenu = Menu(self.window, tearoff=0)
                ctxMenu.add_separator()
                if item[0][:4] == "tag:":
                    tag = item[0][4:]
                    ctxMenu.add_command(
                        label="Add samples (from a csv file)",
                        command=lambda: self.addSampleFileToModelDir(tag))
                    ctxMenu.add_separator()
                    ctxMenu.add_command(
                        label="Visualize feature map w.r.t loaded model",
                        command=lambda: self.testOnLoadedModel(
                            join(configs["model_data_dir"], tag), True))
                elif item[0][:5] == "file:":
                    filename = item[0][5:]
                    ctxMenu.add_command(
                        label="Test on loaded model",
                        command=lambda: self.testOnLoadedModel(
                            join(configs["model_data_dir"], filename), False))
                    ctxMenu.add_separator()
                    ctxMenu.add_command(
                        label="Delete",
                        command=lambda: self.deleteModelFile(filename))
                ctxMenu.add_separator()
                ctxMenu.tk_popup(event.x_root, event.y_root)

        self.modelTree.bind("<Button-3>", treeContextualMenu)
        return frame

    def testOnLoadedModel(self, sampleFile, isDir):
        try:
            modelviz.model_viz(sampleFile, isDir)
        except Exception as exc:
            tkMessageBox.showinfo("Sorry!", exc)
        return

    def populateModelTree(self):
        if self.modelTree is None: return
        #Extract model tags
        tags = [s.strip() for s in configs["model_tags"].split(",")]
        self.modelTree.column('size', width=200, anchor='center')
        self.modelTree.column('modified', width=200, anchor='center')
        self.modelTree.heading('size', text='Length')
        self.modelTree.heading('modified', text='Modified')
        treeHeight = 0
        #Populate treeView with current configuration
        self.modelTree.delete(*self.modelTree.get_children())
        for i in range(len(tags)):
            treeHeight += 1
            dirName = join(configs["model_data_dir"], tags[i])
            children = self.getDirContentDescr(dirName)
            rowId = self.modelTree.insert('',
                                          i,
                                          "tag:{}".format(tags[i]),
                                          text=tags[i])
            for child in children:
                treeHeight += 1
                self.modelTree.insert(
                    rowId,
                    "end",
                    "file:{}/{}".format(tags[i], child['name']),
                    text=child['name'],
                    values=(child['size'], child['modified']))
        self.modelTree['height'] = treeHeight + 1
        return

    def addSampleFileToModelDir(self, tag):
        modelDir = join(configs["model_data_dir"], tag)
        file_opts = {
            'defaultextension': '.csv',
            'filetypes': [('CSV files', '.csv'), ('all files', '.*')],
            'initialdir': expanduser("~"),
            'title': 'Select data file'
        }
        filename = tkFileDialog.askopenfilename(**file_opts)
        try:
            modelLoader.add_file_to_model_dir(filename, modelDir)
        except Exception as exc:
            tkMessageBox.showerror("Error copying files", exc)
            return
        self.populateModelTree()
        tkMessageBox.showinfo(
            "Success", "Successfully copied data file {} to {}.".format(
                filename, modelDir))
        return

    def deleteModelFile(self, filename):
        if tkMessageBox.askyesno("Confirm deleting {}".format(filename),
                                 "Are you sure about deleting this file?"):
            try:
                remove(join(configs["model_data_dir"], filename))
                self.populateModelTree()
            except Exception, exc:
                tkMessageBox.showerror("Error deleting {}".format(filename),
                                       exc)
        return
Esempio n. 4
0
class App:
    def __init__(self,master):
        self.master = master
        self.master.resizable(0,0)
        self.master.update_idletasks()
        self.master.overrideredirect(1)
        self.master.attributes("-topmost",True)
        self.master.title("New Graph")
        self.master.lift()
        self.menubar = Menu(self.master)
        self.master.config(menu=self.menubar)
        self.default_color = self.master.cget("bg")
        self.active_edit_flag = 0
        self.modify_flag = 0
        self.graph_types = ['Default','Maelstrom','Rankine Half-Body','Rankine Oval', 'Cylinder','Stagnation & Vortex']
       #-----------------------------------------------------------------------
        self.file_menu = Menu(self.menubar)
        
        self.Fig = matplotlib.figure.Figure(figsize=(2.148,1.777),dpi=100,tight_layout=True)
        self.FigSubPlot = self.Fig.add_subplot(111)     
        frame = Frame(master,bg='#%02x%02x%02x' % (231, 231, 231))
        frame.pack(fill=BOTH, expand=1)
        frame2 = Frame(frame,bg='#%02x%02x%02x' % (221, 221, 221))
        frame2.pack(fill=BOTH, expand=1,padx=20,pady=23)
        self.frame3 = Frame(frame2, bg='#%02x%02x%02x' % (221, 221, 221))
        self.frame3.pack(fill=BOTH, padx=17,pady=17,expand=1)
        self.radio_frame = Frame(self.frame3,bg='#%02x%02x%02x' % (221, 221, 221))
      
        #self.listbox = Listbox(self.frame3)
        self.radio_var = StringVar()
        self.radio_var.set('Default')
        for key in self.graph_types:
            b = Radiobutton(self.radio_frame,text=key,variable=self.radio_var,value = key,bg='#%02x%02x%02x' % (221, 221, 221),indicatoron=1)
            b.pack(anchor=W)
#        for key_num in range(0,len(self.graph_types)):
#            self.listbox.insert(END,self.graph_types[key_num])
#        self.listbox.select_set(0)
#        self.listbox.bind('<<ListboxSelect>>',self.changegraph)
        self.radio_var.trace('w',self.changegraph)
#        self.old = self.listbox.get(self.listbox.curselection())
        self.blankc = Canvas(self.frame3,width=225,height=188)
        self.canvas = FigureCanvasTkAgg(self.Fig, master=self.frame3)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side=RIGHT,padx=0,pady=5)
        self.radio_frame.pack(side=LEFT,anchor=W,padx=8,pady=5,fill=BOTH,expand=1) 
        #self.listbox.pack(side=LEFT,anchor=W,padx=8,pady=5,fill=BOTH,expand=1)   
        self.button_frame = Frame(frame,bg='#%02x%02x%02x' % (231, 231, 231))
        self.button_frame.pack(side=RIGHT)
        self.buffer_frame = Frame(self.button_frame,bg='#%02x%02x%02x' % (231, 231, 231))
        self.buffer_frame.pack(side=BOTTOM,pady=8)
        self.buffer_frame2 = Frame(self.button_frame,bg='#%02x%02x%02x' % (231, 231, 231))
        self.buffer_frame2.pack(side=RIGHT,padx=11)
        self.button_c = Button(self.button_frame,width=9, text='Choose',bg='#%02x%02x%02x' % (231, 231, 231),command=self.Continue)
        self.button_x = Button(self.button_frame,text='Cancel',bg='#%02x%02x%02x' % (231, 231, 231),width=9,command=self.quit)
        self.button_c.focus()
        self.button_c.pack(side=RIGHT)
        self.button_x.pack(side=RIGHT,padx=14)
        self.line_color = StringVar()
        self.line_color.set('#000000')
        self.wt_var = StringVar()
        self.wt_var.set('- WT:')
        self.wt_var.trace('w',self.wt_update)
        self.linet_var = StringVar()
        self.linet_var.set('-')
        self.linet_var.trace('w',self.line_style_update)
        self.line_var = IntVar()
        self.line_var.set(25)
        self.line_val = 25
        self.div_check_var = IntVar()
        self.div_check_var.set(50)
        self.div_val = 50
        self.density_var = IntVar()
        self.density_var.set(35)
        self.density_val = 35
        self.arrow_var = IntVar()
        self.arrow_var.set(25) 
        self.arrow_val = 25
        self.div_var = IntVar()
        self.div_var.set(0)
        self.mark_var = IntVar()
        self.mark_var.set(0)
        self.lock_var = IntVar()
        self.lock_var.set(1)
        self.active_numbers = {'s':0,'v':0,'u':0,'d':0,'n':0}
        self.sel_point = None
        self.selected = None
    def changegraph(self,*args):
        self.xlim = [-5.0,5.0]
        self.ylim = [-5.0,5.0]
        Y, X = mgrid[-5:5:100j, -5:5:100j]
        self.X,self.Y = X,Y
        self.FigSubPlot.clear()
        #if self.listbox.get(self.listbox.curselection()) == 'Default':
        if self.radio_var.get() == 'Default':
            self.U = 0*X
            self.V = 0*X
            self.FigSubPlot.streamplot(X,Y,self.U,self.V)
        #elif self.listbox.get(self.listbox.curselection()) == 'Maelstrom':
        elif self.radio_var.get() == 'Maelstrom':    
            self.U = self.source(X,Y,1)[0]+self.vortex(X,Y,1)[0]
            self.V = self.source(X,Y,1)[1]+self.vortex(X,Y,1)[1]
            self.FigSubPlot.streamplot(X,Y,self.U,self.V, color='k', linewidth=(2.0/71.0)*self.line_var.get()+(13.0/71.0),density=(2.0/71.0)*self.density_var.get()+(13.0/71.0),arrowstyle='-')
        #elif self.listbox.get(self.listbox.curselection()) == 'Rankine Half-Body':
        elif self.radio_var.get() == 'Rankine Half-Body':
            self.U = self.source(X,Y,10)[0]+self.uniform(X,Y,1,1,0)[0]
            self.V = self.source(X,Y,10)[1]+self.uniform(X,Y,1,1,0)[1]
            self.FigSubPlot.streamplot(X, Y,self.U,self.V, color='k', linewidth=(2.0/71.0)*self.line_var.get()+(13.0/71.0),density=(2.0/71.0)*self.density_var.get()+(13.0/71.0),arrowstyle='-')
        #elif self.listbox.get(self.listbox.curselection()) == 'Rankine Oval':
        elif self.radio_var.get() == 'Rankine Oval':
            self.U = self.source(X+2,Y,10)[0]+self.source(X-2,Y,-10)[0]+self.uniform(X,Y,1,1,0)[0]
            self.V = self.source(X+2,Y,10)[1]+self.source(X-2,Y,-10)[1]+self.uniform(X,Y,1,1,0)[1]
            self.FigSubPlot.streamplot(X, Y,self.U,self.V, color='k', linewidth=(2.0/71.0)*self.line_var.get()+(13.0/71.0),density=(2.0/71.0)*self.density_var.get()+(13.0/71.0),arrowstyle='-')
        #elif self.listbox.get(self.listbox.curselection()) == 'Cylinder':
        elif self.radio_var.get() == 'Cylinder':
            self.U = self.doublet(X,Y,25)[0]+self.uniform(X,Y,1,1,0)[0]
            self.V = self.doublet(X,Y,25)[1]+self.uniform(X,Y,1,1,0)[1]
            self.FigSubPlot.streamplot(X, Y,self.U,self.V, color='k', linewidth=(2.0/71.0)*self.line_var.get()+(13.0/71.0),density=(2.0/71.0)*self.density_var.get()+(13.0/71.0),arrowstyle='-')
        #elif self.listbox.get(self.listbox.curselection()) == 'Stagnation & Vortex':
        elif self.radio_var.get() == 'Stagnation & Vortex':
            self.U = self.vortex(X,Y,25)[0]+self.corner(X,Y,'2,1')[0]
            self.V = self.vortex(X,Y,25)[1]+self.corner(X,Y,'2,1')[1]
            self.FigSubPlot.streamplot(X, Y,self.U,self.V, color='k', linewidth=(2.0/71.0)*self.line_var.get()+(13.0/71.0),density=(2.0/71.0)*self.density_var.get()+(13.0/71.0),arrowstyle='-')
        self.FigSubPlot.set_xlim(self.xlim)
        self.FigSubPlot.set_ylim(self.ylim)
        self.canvas.draw()
#        self.old = self.listbox.get(self.listbox.curselection())
    def source(self,X,Y,l):
        l = float(l)
        U = (l/(2*pi))*X/(X*X + Y*Y)
        V = (l/(2*pi))*Y/(X*X + Y*Y)
        return (U,V)
    def vortex(self,X,Y,g):
        g = float(g)
        U = (g/(2*pi))*Y/(X*X + Y*Y)
        V = (g/(2*pi))*-X/(X*X + Y*Y)
        return (U,V)
    def uniform(self,X,Y,v_0,x_0,y_0):
        v_0 = float(v_0)
        x_0 = float(x_0)
        y_0 = float(y_0)
        U = v_0*x_0/(x_0*x_0+y_0*y_0)**0.5
        V = v_0*y_0/(x_0*x_0+y_0*y_0)**0.5
        return (U,V)
    def doublet(self,X,Y,k):
        k = float(k)
        U = (k/(2*pi))*((2*Y*Y/((X*X+Y*Y)*(X*X+Y*Y)))-(1/(X*X+Y*Y)))
        V = -(k/(2*pi))*(2*X*Y/((X*X+Y*Y)*(X*X+Y*Y)))
        return (U,V)
    def corner(self,X,Y,tup):
        comma_flag = 0
        A = ''
        n = ''
        for char in tup:
            if char == ',':
                comma_flag = 1
            elif comma_flag == 0:
                n += char
            elif comma_flag == 1:
                A += char
        A = float(A)
        n = float(n)
        R = (X*X+Y*Y)**0.5
        t = arctan2(-Y,-X)
        U = -A*n*R**(n-1)*(cos(n*t)*cos(t)+sin(n*t)*sin(t))
        V = -A*n*R**(n-1)*(cos(n*t)*sin(t)-sin(n*t)*cos(t))
        return (U,V)
    def stream_source(self,X,Y,l):
        l = float(l)
        stream = (l/(2*pi))*arctan2(-Y,-X)
        return stream
    def stream_vortex(self,X,Y,g):
        g = float(g)
        stream = (g/(2*pi))*log((X*X + Y*Y)**0.5)
        return stream
    def stream_uniform(self,X,Y,v_0,x_0,y_0):
        v_0 = float(v_0)
        x_0 = float(x_0)
        y_0 = float(y_0)
        stream = (v_0*Y*x_0/(x_0*x_0+y_0*y_0)**0.5)-(v_0*X*y_0/(x_0*x_0+y_0*y_0)**0.5)
        return stream
    def stream_doublet(self,X,Y,k):
        k = float(k)
        stream = -(k/(2*pi))*Y/(X*X+Y*Y)
        return stream
    def stream_corner(self,X,Y,tup):
        comma_flag = 0
        A = ''
        n = ''
        for char in tup:
            if char == ',':
                comma_flag = 1
            elif comma_flag == 0:
                n += char
            elif comma_flag == 1:
                A += char
        A = float(A)
        n = float(n)
        stream = A*(X*X+Y*Y)**(n*0.5)*sin(n*arctan2(-Y,-X))
        return stream
    def quit(self):
        self.master.destroy()    
    def Continue(self):
        self.master.withdraw()
        self.main = Toplevel(self.master)
        self.main.geometry("%dx%d+%d+%d" % (1038-206, 
                               694,
                               int((500.0/2560.0)*screen_resolution[0]), 
                               int((60.0/1440.0)*screen_resolution[1])))
        self.main.minsize(376,227)                      
        self.interior = PanedWindow(self.main,sashwidth=5)
        self.interior.pack(fill=BOTH, expand=1)

        self.elements_frame = Frame(self.interior, height=1038, width=212,relief=RIDGE,borderwidth=0)
        self.interior.add(self.elements_frame) 
        self.interior.paneconfig(self.elements_frame,minsize=130)
        self.graph_frame = Frame(self.interior)
        self.interior.add(self.graph_frame)
        self.interior.paneconfig(self.graph_frame,minsize=130)

        self.main.bind("<ButtonRelease-1>",self.pan_update)
        self.main.bind("<ButtonRelease-3>",self.pan_update)
        self.main.bind("<Button-3>",self.right_menu)
        
        self.edit_frame = Frame(self.graph_frame)
        self.edit_frame.pack(side=TOP,fill=X,padx=10)
        self.canvas = FigureCanvasTkAgg(self.Fig, master=self.graph_frame)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(fill=BOTH,expand=1)
        self.nav_frame = Frame(self.edit_frame)
        self.nav_frame.pack(side=LEFT,anchor=W)
        self.toolbar = NavigationToolbar(self.canvas, self.nav_frame)
        
        self.main.protocol('WM_DELETE_WINDOW',self.master.destroy) 
        self.elements = Treeview(self.elements_frame,columns=("values","xlocations","ylocations"),selectmode=BROWSE)
        self.elements.heading("#0",text="Components")
        self.elements.heading("values",text="Str")
        self.elements.heading("xlocations",text="X")
        self.elements.heading("ylocations",text="Y")
        self.elements.column("#0",width=90,anchor=CENTER)
        self.elements.column("values",width=45,anchor=CENTER)
        self.elements.column("xlocations",width=26,anchor=CENTER)
        self.elements.column("ylocations",width=26,anchor=CENTER)
        self.elements.pack(fill=BOTH,expand=1)
        
        self.as_button_frame = Frame(self.elements_frame)
        self.add_button = Button(self.as_button_frame,text = '+',width=2,command=self.add)       
        self.sub_button = Button(self.as_button_frame,text = '-',width=2,command=self.subtract) 
        self.options_button = Button(self.as_button_frame,text='Options',command=self.options)
        self.as_button_frame.pack(side=BOTTOM,anchor=W)
        self.options_button.pack(side=RIGHT)
        self.sub_button.pack(side=RIGHT,anchor=W)
        self.add_button.pack(side=LEFT,anchor=W)
        self.addsub_menu = Menu(self.as_button_frame,tearoff=0)
        self.addsub_menu.add_command(command=self.add_source,label='Source')
        self.addsub_menu.add_command(command=self.add_vortex,label='Vortex')
        self.addsub_menu.add_command(command=self.add_uniform,label='Uniform')
        self.addsub_menu.add_command(command=self.add_doublet,label='Doublet')
        self.addsub_menu.add_command(command=self.add_corner,label='Corner')
        

        #if self.listbox.get(self.listbox.curselection()) == 'Default':
        if self.radio_var.get() == 'Default':
            self.active_components = []
            self.active_calls = {} 
            pass
        #elif self.listbox.get(self.listbox.curselection()) == 'Maelstrom':
        elif self.radio_var.get() == 'Maelstrom':
            self.elements.insert("",0,"M",text="Maelstrom",open=TRUE)
            self.active_components = ['M']
            self.elements.insert("M",0,iid='s%s'%self.active_numbers['s'],text="Source",values=("%s"%1,0,0))
            self.elements.insert("M",0,iid='v%s'%self.active_numbers['v'],text="Vortex",values=("%s"%1,0,0))
            self.active_calls = {'s%s'%self.active_numbers['s']:("s",self.elements.item('s%s'%self.active_numbers['s'],"values")),
                                 'v%s'%self.active_numbers['v']:("v",self.elements.item('v%s'%self.active_numbers['v'],"values"))}
            self.active_numbers['s'] += 1
            self.active_numbers['v'] += 1
        elif self.radio_var.get() == 'Rankine Half-Body':
            self.elements.insert("",0,"RHF",text="Rankine Half-Body",open=TRUE)
            self.active_components = ['RHF']
            self.elements.insert("RHF",0,iid='s%s'%self.active_numbers['s'],text="Source",values=("%s"%10,0,0))
            self.elements.insert("RHF",0,iid='u%s'%self.active_numbers['u'],text="Uniform",values=("%s"%1,1,0))
            self.active_calls = {'s%s'%self.active_numbers['s']:("s",self.elements.item('s%s'%self.active_numbers['s'],"values")),
                                 'u%s'%self.active_numbers['u']:("u",self.elements.item('u%s'%self.active_numbers['u'],"values"))}
            self.active_numbers['s'] += 1
            self.active_numbers['u'] += 1
        elif self.radio_var.get() == 'Rankine Oval':
            self.elements.insert("",0,"RO",text="Rankine Oval",open=TRUE)
            self.active_components = ['RO']
            self.elements.insert("RO",0,iid='s%s'%self.active_numbers['s'],text="Source",values=("%s"%10,-2,0))
            self.elements.insert("RO",0,iid='s%s'%(self.active_numbers['s']+1),text="Source",values=("%s"%-10,2,0))
            self.elements.insert("RO",0,iid='u%s'%self.active_numbers['u'],text="Uniform",values=("%s"%1,1,0))
            self.active_calls = {'s%s'%self.active_numbers['s']:("s",self.elements.item('s%s'%self.active_numbers['s'],"values")),
                                 's%s'%(self.active_numbers['s']+1):("s",self.elements.item('s%s'%(self.active_numbers['s']+1),"values")),
                                 'u%s'%self.active_numbers['u']:("u",self.elements.item('u%s'%self.active_numbers['u'],"values"))}
            self.active_numbers['s'] += 2
            self.active_numbers['u'] += 1       
        elif self.radio_var.get() == 'Cylinder':
            self.elements.insert("",0,'D+U',text="Cylinder",open=TRUE)
            self.active_components = ['D+U']
            self.elements.insert('D+U',0,iid='d%s'%self.active_numbers['d'],text="Doublet",values=("%s"%25,0,0))
            self.elements.insert('D+U',0,iid='u%s'%self.active_numbers['u'],text="Uniform",values=("%s"%1,1,0))
            self.active_calls = {'d%s'%self.active_numbers['d']:("d",self.elements.item('d%s'%self.active_numbers['d'],"values")),
                                 'u%s'%self.active_numbers['u']:("u",self.elements.item('u%s'%self.active_numbers['u'],"values"))}
            self.active_numbers['d'] += 1
            self.active_numbers['u'] += 1
        elif self.radio_var.get() == 'Stagnation & Vortex':
            self.elements.insert("",0,'S+V',text="Stag+Vort",open=TRUE)
            self.active_components = ['S+V']
            self.elements.insert('S+V',0,iid='n%s'%self.active_numbers['n'],text="C (n,A)",values=("%s,%s"%(2,1),0,0))
            self.elements.insert('S+V',0,iid='v%s'%self.active_numbers['v'],text="Vortex",values=("%s"%25,0,0))
            self.active_calls = {'n%s'%self.active_numbers['n']:("n",self.elements.item('n%s'%self.active_numbers['n'],"values")),
                                 'v%s'%self.active_numbers['v']:("v",self.elements.item('v%s'%self.active_numbers['v'],"values"))}
            self.active_numbers['n'] += 1
            self.active_numbers['v'] += 1
        self.elements.bind("<Double-Button-1>",self.edit)
        self.elements.bind('<<TreeviewSelect>>',self.treeview_select)
        self.main.bind("<Return>",self.edit_return)
        self.main.bind("<Escape>",self.edit_return)

        
        self.rightc_menu = Menu(self.graph_frame,tearoff=0)
        self.add_menu = Menu(self.rightc_menu,tearoff=0)
        self.rightc_menu.add_cascade(label="Add",menu=self.add_menu)
        self.add_menu.add_command(command=self.addm_source,label='Source')
        self.add_menu.add_command(command=self.addm_vortex,label='Vortex')
        self.add_menu.add_command(command=self.addm_uniform,label='Uniform')
        self.add_menu.add_command(command=self.addm_doublet,label='Doublet')
        self.add_menu.add_command(command=self.addm_corner,label='Corner')
    def right_menu(self,event):
        print "event", event.x,event.y
        #print "graph", self.main.winfo_x()+self.interior.winfo_x()+self.graph_frame.winfo_x(), self.main.winfo_y()+self.interior.winfo_y()+self.graph_frame.winfo_y()
        self.plot_x,self.plot_y = self.FigSubPlot.transData.inverted().transform((event.x,event.y+20))
        self.plot_y = -self.plot_y
        self.rightc_menu.post(self.main.winfo_x()+self.interior.winfo_x()+self.graph_frame.winfo_x()+event.x+9,self.main.winfo_y()+self.graph_frame.winfo_y()+event.y+66)
        
    def treeview_select(self,event):
        if self.elements.get_children(self.elements.selection()[0]) == ():
            if self.mark_var.get() == 0 or self.selected == self.elements.selection():
                pass
            elif self.mark_var.get() == 1:
                
                #add red markers here
                
                if self.elements.selection() != '':
                    child = self.elements.selection()[0]
                    if child != '':
                        self.sel_point = (self.elements.item(child,"values")[1],self.elements.item(child,"values")[2])
                        self.graph_update()
                        self.selected = self.elements.selection()
                else:
                    pass
        else:
            if self.mark_var.get() == 0 or self.selected == self.elements.selection():
                pass
            elif self.mark_var.get() == 1:
                if self.elements.selection() != '':
                    child = self.elements.selection()[0]
                    if child != '':
                        self.sel_point = None
                        self.graph_update()
                        self.selected = self.elements.selection()
    def mark_check_fun(self):
        if self.mark_var.get() == 0:
            self.sel_point = None
            self.graph_update()
        elif self.elements.selection() != '':
            child = self.elements.selection()[0]
            self.sel_point = [self.elements.item(child,"values")[1],self.elements.item(child,"values")[2]]
            self.graph_update()
            
    def add(self):
        self.addsub_menu.post(self.main.winfo_x()+self.as_button_frame.winfo_x()+self.add_button.winfo_x(),self.main.winfo_y()+self.as_button_frame.winfo_y()+self.add_button.winfo_y()-len(self.active_numbers.keys())*14)
    def subtract(self):
        if self.active_edit_flag == 1:
            self.del_edit(self)
        child = self.elements.selection()[0]
        if child == '':
            return
        if self.elements.parent(child) == '':
            ID = child
            self.active_components.remove(child)
            self.elements.delete(child)
        else:
            ID = self.elements.parent(child)
            self.active_components.remove(ID)
            for comp in self.elements.get_children(ID):
                if comp != child:
                    self.active_components.append(comp)
                    self.elements.move(comp,"",0)
            self.elements.delete(ID)
        self.sel_point = None
        self.graph_update()
    def options(self):
        self.options_window = Toplevel(self.main)
        self.options_window.geometry("%dx%d+%d+%d" % (280, 
                                                      200+20,
                                                      self.main.winfo_x()+self.as_button_frame.winfo_x()+self.options_button.winfo_x()-272+26+72+86,
                                                      self.main.winfo_y()+self.as_button_frame.winfo_y()+self.options_button.winfo_y()-196-20))
        self.main.bind('<FocusIn>',self.close_options)
        self.options_window.title("Options")
        self.options_window.update_idletasks()
        self.options_window.bind("<ButtonRelease-1>",self.pan_update)
        self.options_frame = Frame(self.options_window)
        self.options_frame.pack(fill=BOTH,expand=1)
        self.options_window.attributes("-topmost",True)

        self.line_frame = Frame(self.options_frame,bd=2,relief=RIDGE)
        self.line_frame.grid(row=0,column=1,sticky=N+S+E+W,ipady=7)
        self.color_frame = Frame(self.options_frame,bd=2,relief=RIDGE,padx=2)
        self.color_frame.grid(row=0,column=0,sticky=N+S+E+W)
        
        self.color_button = Label(self.color_frame,bg=self.line_color.get(),text = '     ')
        self.color_button.pack(side=RIGHT)
        Label(self.color_frame,text='C:').pack(side=RIGHT)
        self.color_button.bind('<Button-1>',self.getColor)
        
        self.wt_slider = Scale(self.line_frame,from_=1,to=100,orient=HORIZONTAL,variable=self.line_var)
        if self.wt_var.get() == '-> WT:':
            self.wt_slider.config(variable=self.arrow_var)
        elif self.wt_var.get() == '- WT:':
            self.wt_slider.config(variable=self.line_var)
        elif self.wt_var.get() == 'div WT:':
            self.wt_slider.config(variable=self.div_check_var)
        self.wt_slider.pack(side=RIGHT)
        
        self.wt_menu = OptionMenu(self.line_frame,self.wt_var,'- WT:','-> WT:','div WT:')
        self.wt_menu.pack(side=RIGHT,anchor='center',fill=X,expand=1)
        self.wt_menu.config(width=8)
        self.density_frame = Frame(self.options_frame,bd=2,relief=RIDGE)
        self.density_frame.grid(row=1,column=1,sticky=N+S+E+W)
        self.density_slider = Scale(self.density_frame,from_=1,to=100,orient=HORIZONTAL,variable=self.density_var)
        self.density_slider.pack(side=RIGHT)
        Label(self.density_frame,text='Density').pack(side=LEFT,anchor=CENTER,fill=X,expand=1)
        
        self.linet_frame = Frame(self.options_frame,bd=2,relief=RIDGE)
        self.linet_frame.grid(row=1,column=0,sticky=N+S+E+W)
        Label(self.linet_frame,text='Style').pack(anchor='n')
        self.linet_menu = OptionMenu(self.linet_frame,self.linet_var,'-','->','-|>')
        self.linet_menu.pack(anchor='s',side=BOTTOM)
        self.linet_menu.config(width=5)
        
        self.div_check = Checkbutton(self.options_frame,text = 'Dividing Streamline',variable=self.div_var,onvalue=1,offvalue=0,command = self.graph_update)
        self.div_check.grid(row=2,column=1,sticky=W)
        self.mark_check = Checkbutton(self.options_frame,text = 'Selection Marker',variable=self.mark_var,onvalue=1,offvalue=0,command = self.mark_check_fun)
        self.mark_check.grid(row=3,column=1,sticky=W)
        
        self.limit_frame = Frame(self.options_frame)
        self.limit_frame.grid(row=4,column=1,sticky=W)
        #self.aspect_lock = Checkbutton(self.limit_frame,text='LK',variable = self.lock_var)
        #self.aspect_lock.grid(row=0,column=4,rowspan=2,sticky=E)
        
        Label(self.limit_frame,text='x').grid(row=0,column=0)
        self.xlimlow_var = DoubleVar()
        self.xlimlow_var.set(self.FigSubPlot.get_xlim()[0])
        self.xlimlow_entry = Entry(self.limit_frame,textvariable=self.xlimlow_var,width=5)
        self.xlimlow_entry.grid(row=0,column=1)
        Label(self.limit_frame,text='...').grid(row=0,column=2)
        self.xlimhigh_var = DoubleVar()
        self.xlimhigh_var.set(self.FigSubPlot.get_xlim()[1])
        self.xlimhigh_entry = Entry(self.limit_frame,textvariable=self.xlimhigh_var,width=5)
        self.xlimhigh_entry.grid(row=0,column=3)
        Label(self.limit_frame,text='y').grid(row=1,column=0)
        self.ylimlow_var = DoubleVar()
        self.ylimlow_var.set(self.FigSubPlot.get_ylim()[0])
        self.ylimlow_entry = Entry(self.limit_frame,textvariable=self.ylimlow_var,width=5)
        self.ylimlow_entry.grid(row=1,column=1)
        Label(self.limit_frame,text='...').grid(row=1,column=2)
        self.ylimhigh_var = DoubleVar()
        self.ylimhigh_var.set(self.FigSubPlot.get_ylim()[1])
        self.ylimhigh_entry = Entry(self.limit_frame,textvariable=self.ylimhigh_var,width=5)
        self.ylimhigh_entry.grid(row=1,column=3)
        
        
        #self.limit_frame.bind('<FocusOut>',self.limits_update)
        self.xlimhigh_var.trace('w',self.limits_update)
        self.ylimhigh_var.trace('w',self.limits_update)
        self.xlimlow_var.trace('w',self.limits_update)
        self.ylimlow_var.trace('w',self.limits_update)
        
    def limits_update(self,*args):

        if self.xlimlow_entry.get() == '' or self.ylimlow_entry.get() == '' or self.xlimhigh_entry.get() == '' or self.ylimhigh_entry.get() == '':
            pass
        elif self.xlimlow_entry.get() == '-' or self.ylimlow_entry.get() == '-' or self.xlimhigh_entry.get() == '-' or self.ylimhigh_entry.get() == '-':
            pass
        elif self.xlimlow_entry.get() == '.' or self.ylimlow_entry.get() == '.' or self.xlimhigh_entry.get() == '.' or self.ylimhigh_entry.get() == '.':
            pass
        else:
            self.xlim = [float(self.xlimlow_var.get()),float(self.xlimhigh_var.get())]
            self.ylim = [float(self.ylimlow_var.get()),float(self.ylimhigh_var.get())]

            self.FigSubPlot.set_xlim(self.xlim)
            self.FigSubPlot.set_ylim(self.ylim)
            self.graph_update()
    def getColor(self,event):
        color=askcolor(self.line_color.get())
        if color != "None":
            self.line_color.set(color[1])
            self.graph_update()
    def wt_update(self,*args):
        if self.wt_var.get() == '-> WT:':
            self.wt_slider.config(variable=self.arrow_var)
        elif self.wt_var.get() == '- WT:':
            self.wt_slider.config(variable=self.line_var)
        elif self.wt_var.get() == 'div WT:':
            self.wt_slider.config(variable=self.div_check_var)
    def line_style_update(self,*args):
        self.graph_update()
    def close_options(self,event):
        self.options_window.destroy()
    def add_source(self):
        if self.modify_flag == 0:
            self.plot_x,self.plot_y = 0,0
        self.elements.insert("",0,iid='s%s'%self.active_numbers['s'],text="Source",values=("%s"%1,self.plot_x,self.plot_y))
        self.active_calls['s%s'%self.active_numbers['s']] = ("s",self.elements.item('s%s'%self.active_numbers['s'],"values"))
        self.active_components.append('s%s'%self.active_numbers['s'])
        if self.modify_flag == 1:
            self.elements.selection_set('s%s'%self.active_numbers['s'])
            self.modify_flag = 0
        self.graph_update()
        self.active_numbers['s'] += 1
        
    def add_vortex(self):
        if self.modify_flag == 0:
            self.plot_x,self.plot_y = 0,0
        self.elements.insert("",0,iid='v%s'%self.active_numbers['v'],text="Vortex",values=("%s"%1,self.plot_x,self.plot_y))
        self.active_calls['v%s'%self.active_numbers['v']] = ("v",self.elements.item('v%s'%self.active_numbers['v'],"values"))
        self.active_components.append('v%s'%self.active_numbers['v'])

        if self.modify_flag == 1:
            self.elements.selection_set('v%s'%self.active_numbers['v'])
            self.modify_flag = 0
        self.graph_update()
        self.active_numbers['v'] += 1
    def add_uniform(self):
        if self.modify_flag == 0:
            self.plot_x,self.plot_y = 1,0
        self.elements.insert("",0,iid='u%s'%self.active_numbers['u'],text="Uniform",values=("%s"%1,self.plot_x,self.plot_y))
        self.active_calls['u%s'%self.active_numbers['u']] = ("u",self.elements.item('u%s'%self.active_numbers['u'],"values"))
        self.active_components.append('u%s'%self.active_numbers['u'])
        if self.modify_flag == 1:
            self.elements.selection_set('u%s'%self.active_numbers['u'])
            self.modify_flag = 0
        self.graph_update()
        self.active_numbers['u'] += 1
    def add_doublet(self):
        if self.modify_flag == 0:
            self.plot_x,self.plot_y = 0,0
        self.elements.insert("",0,iid='d%s'%self.active_numbers['d'],text="Doublet",values=("%s"%1,self.plot_x,self.plot_y))
        self.active_calls['d%s'%self.active_numbers['d']] = ("d",self.elements.item('d%s'%self.active_numbers['d'],"values"))
        self.active_components.append('d%s'%self.active_numbers['d'])
        if self.modify_flag == 1:
            self.elements.selection_set('d%s'%self.active_numbers['d'])
            self.modify_flag = 0
        self.graph_update()
        self.active_numbers['d'] += 1
    def add_corner(self):
        if self.modify_flag == 0:
            self.plot_x,self.plot_y = 0,0
        self.elements.insert("",0,iid='n%s'%self.active_numbers['n'],text="Corner (n,A)",values=("%s,%s"%(2,1),self.plot_x,self.plot_y))
        self.active_calls['n%s'%self.active_numbers['n']] = ("n",self.elements.item('n%s'%self.active_numbers['n'],"values"))
        self.active_components.append('n%s'%self.active_numbers['n'])
        if self.modify_flag == 1:
            self.elements.selection_set('n%s'%self.active_numbers['n'])
            self.modify_flag = 0
        self.graph_update()
        self.active_numbers['n'] += 1
    def addm_source(self):
        self.modify_flag = 1 
        self.add_source()
    def addm_vortex(self):
        self.modify_flag = 1
        self.add_vortex()
    def addm_uniform(self):
        self.modify_flag = 1
        self.add_uniform()
    def addm_doublet(self):
        self.modify_flag = 1
        self.add_doublet()
    def addm_corner(self):
        self.modify_flag = 1
        self.add_corner()
    def pan_update(self,event):
        if [self.FigSubPlot.get_xlim()[0],self.FigSubPlot.get_xlim()[1]] != self.xlim or [self.FigSubPlot.get_ylim()[0],self.FigSubPlot.get_ylim()[1]] != self.ylim or self.density_var.get() != self.density_val or self.line_var.get() != self.line_val or self.arrow_var.get() != self.arrow_val or self.arrow_var.get() != self.arrow_val or self.div_check_var.get() != self.div_val:
            self.graph_update()
            self.density_val = self.density_var.get()
            self.line_val = self.line_var.get()
            self.arrow_val = self.arrow_var.get()
            self.div_val = self.div_check_var.get()
        else:
            return
    def graph_update(self):
        self.FigSubPlot.clear()
        Y, X = mgrid[self.FigSubPlot.get_ylim()[0]:self.FigSubPlot.get_ylim()[1]:100j, self.FigSubPlot.get_xlim()[0]:self.FigSubPlot.get_xlim()[1]:100j]     
        self.xlim = [self.FigSubPlot.get_xlim()[0],self.FigSubPlot.get_xlim()[1]]
        self.ylim = [self.FigSubPlot.get_ylim()[0],self.FigSubPlot.get_ylim()[1]]
        self.U = 0*X
        self.V = 0*X      
        self.stream = 0*X
        for ID in self.active_components:
            if self.elements.get_children(ID) == ():
                child = ID
                self.active_calls[child] = (child[0],self.elements.item(child,"values"))
                if self.active_calls[child][0] == "s":
                    self.U += self.source(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                    self.V += self.source(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                    self.stream += self.stream_source(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
                elif self.active_calls[child][0] == 'v':
                    self.U += self.vortex(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                    self.V += self.vortex(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                    self.stream += self.stream_vortex(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
                elif self.active_calls[child][0] == 'u':
                    if self.active_calls[child][1][1] == '0' and self.active_calls[child][1][2] == '0':
                        pass
                    else:
                        self.U += self.uniform(X,Y,self.active_calls[child][1][0],self.active_calls[child][1][1],self.active_calls[child][1][2])[0]
                        self.V += self.uniform(X,Y,self.active_calls[child][1][0],self.active_calls[child][1][1],self.active_calls[child][1][2])[1]
                        self.stream += self.stream_uniform(X,Y,self.active_calls[child][1][0],self.active_calls[child][1][1],self.active_calls[child][1][2])
                elif self.active_calls[child][0] == 'd':
                    self.U += self.doublet(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                    self.V += self.doublet(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                    self.stream += self.stream_doublet(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
                elif self.active_calls[child][0] == 'n':
                    self.U += self.corner(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                    self.V += self.corner(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                    self.stream += self.stream_corner(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
            else:
                for child in self.elements.get_children(ID):
                    self.active_calls[child] = (child[0],self.elements.item(child,"values"))
                    if self.active_calls[child][0] == "s":
                        self.U += self.source(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                        self.V += self.source(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                        self.stream += self.stream_source(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
                    elif self.active_calls[child][0] == 'v':
                        self.U += self.vortex(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                        self.V += self.vortex(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                        self.stream += self.stream_vortex(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
                    elif self.active_calls[child][0] == 'u':
                        if self.active_calls[child][1][1] == '0' and self.active_calls[child][1][2] == '0':
                            pass
                        else:
                            self.U += self.uniform(X,Y,self.active_calls[child][1][0],self.active_calls[child][1][1],self.active_calls[child][1][2])[0]
                            self.V += self.uniform(X,Y,self.active_calls[child][1][0],self.active_calls[child][1][1],self.active_calls[child][1][2])[1]
                            self.stream += self.stream_uniform(X,Y,self.active_calls[child][1][0],self.active_calls[child][1][1],self.active_calls[child][1][2])
                    elif self.active_calls[child][0] == 'd':
                        self.U += self.doublet(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                        self.V += self.doublet(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                        self.stream += self.stream_doublet(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
                    elif self.active_calls[child][0] == 'n':
                        self.U += self.corner(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                        self.V += self.corner(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                        self.stream += self.stream_corner(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])

        self.FigSubPlot.streamplot(X,Y,self.U,self.V,color=self.line_color.get(), linewidth=(2.0/71.0)*self.line_var.get()+(13.0/71.0),density=(2.0/71.0)*self.density_var.get()+(13.0/71.0),arrowstyle=self.linet_var.get(),arrowsize=(4.0/71.0)*self.arrow_var.get()+(13.0/71.0))
        if self.div_var.get() == 1:
            #self.FigSubPlot.contour(X,Y,self.stream,[-0.01,0.01],linewidths=[(4.0/71.0)*self.div_check_var.get()+(13.0/71.0),(4.0/71.0)*self.div_check_var.get()+(13.0/71.0)])
            
            self.FigSubPlot.contour(X,Y,self.stream,[0],linewidths=[(4.0/71.0)*self.div_check_var.get()+(13.0/71.0)])
        if self.mark_var.get() == 1:
            if self.sel_point != None:
                self.plot_point()
        self.FigSubPlot.set_xlim(self.xlim)
        self.FigSubPlot.set_ylim(self.ylim)
        self.canvas.draw()
    def plot_point(self):
        if self.elements.selection()[0][0] == 'u':
            norm = float(float(self.sel_point[0])*float(self.sel_point[0])+float(self.sel_point[1])*float(self.sel_point[1]))**0.5
            if norm == 0:
                norm = 1
            X,Y,U,V = 0,0, float(self.sel_point[0])/norm,float(self.sel_point[1])/norm
            self.FigSubPlot.quiver(X,Y,U,V,angles='xy',scale_units='xy',scale=1,color='g')
        else:
            self.FigSubPlot.plot([self.sel_point[0]],[self.sel_point[1]],'r^',ms=10)
    def edit(self,event):
        if self.active_edit_flag == 1 or self.elements.identify_row(event.y) == '':
            pass
        else:
            self.rowid = self.elements.identify_row(event.y)
            self.column = self.elements.identify_column(event.x)
            self.edit_var = StringVar()
            if int(self.column[-1]) == 0:
                self.edit_var.set('%s'%self.elements.item("%s"%self.elements.identify("item",event.x, event.y))['text'])

            else:
                self.edit_var.set('%s'%self.elements.item("%s"%self.elements.identify("item",event.x, event.y))['values'][int(self.column[-1])-1])

            x,y,width,height = self.elements.bbox(self.rowid, self.column)
            self.edit_entry = Entry(self.elements_frame,textvariable=self.edit_var)
            self.edit_entry.place(x=x,y=y,width=width)
            self.edit_entry.focus_force()
            self.edit_entry.bind("<FocusOut>", self.del_edit)
            self.active_edit_flag = 1
    def edit_return(self,event):
        self.main.focus()
    def del_edit(self,event):
        if self.column[-1] == '0':
            self.elements.item(self.rowid,text='%s'%self.edit_var.get())
        elif self.rowid[0] == 'n' and self.column[-1] == '1' and ',' not in self.edit_var.get():
            pass
        else:
            value = ''
            initial_value = str(self.elements.item(self.rowid)['values'][int(self.column[-1])-1])
            comma_flag = 0
            div_flag = 0
            for index in range(0,len(self.edit_var.get())):
                char = self.edit_var.get()[index]
                if char in '-0123456789.':
                    value += char
                elif self.rowid[0] == 'n' and char == ',':
                    if comma_flag == 1:
                        self.edit_entry.destroy()
                        self.active_edit_flag = 0
                        return
                    value += char
                    comma_flag = 1
                    comma_index = index
                if char == '/':
                    if div_flag == 0:
                        div_flag = 1
                        div_index = index
                    elif div_flag == 1 and comma_flag == 1:
                        div_flag = 2
                        div_index2 = index
                    elif div_flag == 1 and comma_flag == 0 or div_flag == 2:
                        self.edit_entry.destroy()
                        self.active_edit_flag = 0
                        return
                   
            if div_flag == 1:
                if comma_flag == 1:
                    if div_index < comma_index:
                        arg = int(float(value[:div_index])*100/float(value[div_index:comma_index-1]))/100.0
                        value = str(arg)+value[comma_index-1:]
                    elif div_index > comma_index:
                        arg = int(float(value[comma_index+1:div_index])*100/float(value[div_index:]))/100.0
                        value = value[:comma_index+1]+str(arg)
                else:
                    arg = int(float(value[:div_index])*100/float(value[div_index:]))/100.0
                    value = str(arg)
            elif div_flag == 2: 
                arg1 = int(float(value[:div_index])*100/float(value[div_index:comma_index-1]))/100.0
                arg2 = int(float(value[comma_index:div_index2-1])*100/float(value[div_index2-1:]))/100.0
                value = str(arg1)+','+str(arg2)
            if value == '' or value == initial_value:
                self.edit_entry.destroy()
                self.active_edit_flag = 0
                return
            
            self.elements.set(self.rowid,column=(int(self.column[-1])-1),value=value)
            if self.mark_var.get() == 1:
                self.sel_point = [self.elements.item(self.rowid,"values")[1],self.elements.item(self.rowid,"values")[2]]
            self.graph_update()
        self.edit_entry.destroy()
        self.active_edit_flag = 0
Esempio n. 5
0
class Multicolumn_Listbox(object):
    _style_index = 0

    class List_Of_Rows(object):
        def __init__(self, multicolumn_listbox):
            self._multicolumn_listbox = multicolumn_listbox

        def data(self, index):
            return self._multicolumn_listbox.row_data(index)
            
        def get(self, index):
            return Row(self._multicolumn_listbox, index)

        def insert(self, data, index=None):
            self._multicolumn_listbox.insert_row(data, index)

        def delete(self, index):
            self._multicolumn_listbox.delete_row(index)

        def update(self, index, data):
            self._multicolumn_listbox.update_row(index, data)

        def select(self, index):
            self._multicolumn_listbox.select_row(index)

        def deselect(self, index):
            self._multicolumn_listbox.deselect_row(index)

        def set_selection(self, indices):
            self._multicolumn_listbox.set_selection(indices)

        def __getitem__(self, index): 
            return self.get(index)

        def __setitem__(self, index, value): 
            return self._multicolumn_listbox.update_row(index, value)

        def __delitem__(self, index): 
            self._multicolumn_listbox.delete_row(index)

        def __len__(self): 
            return self._multicolumn_listbox.number_of_rows

    class List_Of_Columns(object):
        def __init__(self, multicolumn_listbox):
            self._multicolumn_listbox = multicolumn_listbox
        
        def data(self, index):
            return self._multicolumn_listbox.get_column(index)

        def get(self, index):
            return Column(self._multicolumn_listbox, index)

        def delete(self, index):
            self._multicolumn_listbox.delete_column(index)

        def update(self, index, data):
            self._multicolumn_listbox.update_column(index, data)

        def __getitem__(self, index): 
            return self.get(index)

        def __setitem__(self, index, value): 
            return self._multicolumn_listbox.update_column(index, value)

        def __delitem__(self, index): 
            self._multicolumn_listbox.delete_column(index)

        def __len__(self): 
            return self._multicolumn_listbox.number_of_columns

    def __init__(self, master, columns, data=None, command=None, sort=True, select_mode=None, heading_anchor = CENTER, cell_anchor=W, style=None, height=None, padding=None, adjust_heading_to_content=False, stripped_rows=None, selection_background=None, selection_foreground=None, field_background=None, heading_font= None, heading_background=None, heading_foreground=None, cell_pady=2, cell_background=None, cell_foreground=None, cell_font=None, headers=True):

        self._stripped_rows = stripped_rows

        self._columns = columns
        
        self._number_of_rows = 0
        self._number_of_columns = len(columns)
        
        self.row = self.List_Of_Rows(self)
        self.column = self.List_Of_Columns(self)
        
        s = Style()

        if style is None:
            style_name = "Multicolumn_Listbox%s.Treeview"%self._style_index
            self._style_index += 1
        else:
            style_name = style
        
        style_map = {}
        if selection_background is not None:
            style_map["background"] = [('selected', selection_background)]
            
        if selection_foreground is not None:
            style_map["foeground"] = [('selected', selection_foreground)]

        if style_map:
            s.map(style_name, **style_map)

        style_config = {}
        if cell_background is not None:
            style_config["background"] = cell_background

        if cell_foreground is not None:
            style_config["foreground"] = cell_foreground

        if cell_font is None:
            font_name = s.lookup(style_name, "font")
            cell_font = nametofont(font_name)
        else:
            if not isinstance(cell_font, Font):
                if isinstance(cell_font, basestring):
                    cell_font = nametofont(cell_font)
                else:
                    if len(font) == 1:
                        cell_font = Font(family=cell_font[0])
                    elif len(font) == 2:
                        cell_font = Font(family=cell_font[0], size=cell_font[1])
                        
                    elif len(font) == 3:
                        cell_font = Font(family=cell_font[0], size=cell_font[1], weight=cell_font[2])
                    else:
                        raise ValueError("Not possible more than 3 values for font")
        
            style_config["font"] = cell_font
        
        self._cell_font = cell_font

        self._rowheight = cell_font.metrics("linespace")+cell_pady
        style_config["rowheight"]=self._rowheight

        if field_background is not None:
            style_config["fieldbackground"] = field_background

        s.configure(style_name, **style_config)

        heading_style_config = {}
        if heading_font is not None:
            heading_style_config["font"] = heading_font
        if heading_background is not None:
            heading_style_config["background"] = heading_background
        if heading_foreground is not None:
            heading_style_config["foreground"] = heading_foreground

        heading_style_name = style_name + ".Heading"
        s.configure(heading_style_name, **heading_style_config)

        treeview_kwargs = {"style": style_name}

        if height is not None:
            treeview_kwargs["height"] = height
            
        if padding is not None:
            treeview_kwargs["padding"] = padding
            
        if headers:
            treeview_kwargs["show"] = "headings"
        else:
            treeview_kwargs["show"] = ""
        
        if select_mode is not None:
            treeview_kwargs["selectmode"] = select_mode

        self.interior = Treeview(master, columns=columns, **treeview_kwargs)
        
        if command is not None:
            self._command = command
            self.interior.bind("<<TreeviewSelect>>", self._on_select)

        for i in range(0, self._number_of_columns):

            if sort:
                self.interior.heading(i, text=columns[i], anchor=heading_anchor, command=lambda col=i: self.sort_by(col, descending=False))
            else:
                self.interior.heading(i, text=columns[i], anchor=heading_anchor)
                
            if adjust_heading_to_content:
                self.interior.column(i, width=Font().measure(columns[i]))

            self.interior.column(i, anchor=cell_anchor)
            
        if data is not None:
            for row in data:
                self.insert_row(row)

    @property
    def row_height(self):
        return self._rowheight
        
    @property
    def font(self):
        return self._cell_font

    def configure_column(self, index, width=None, minwidth=None, anchor=None, stretch=None):
        kwargs = {}
        for config_name in ("width", "anchor", "stretch", "minwidth"):
            config_value = locals()[config_name]
            if config_value is not None:
                kwargs[config_name] = config_value
            
        self.interior.column('#%s'%(index+1), **kwargs)

    def row_data(self, index):
        try:
            item_ID = self.interior.get_children()[index]
        except IndexError:
            raise ValueError("Row index out of range: %d"%index)        

        return self.item_ID_to_row_data(item_ID)

    def update_row(self, index, data):
        try:
            item_ID = self.interior.get_children()[index]
        except IndexError:
            raise ValueError("Row index out of range: %d"%index)
            
        if len(data) == len(self._columns):
            self.interior.item(item_ID, values=data)
        else:
            raise ValueError("The multicolumn listbox has only %d columns"%self._number_of_columns)

    def delete_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d"%index)

        self.interior.delete(item_ID)
        self._number_of_rows -= 1
        
        if self._stripped_rows:
            for i in range(index, self._number_of_rows):
                self.interior.tag_configure(list_of_items[i+1], background=self._stripped_rows[i%2])
            
    def insert_row(self, data, index=None):
        if len(data) != self._number_of_columns:
            raise ValueError("The multicolumn listbox has only %d columns"%self._number_of_columns)
        
        if index is None:
            index = self._number_of_rows-1

        item_ID = self.interior.insert('', index, values=data)        
        self.interior.item(item_ID, tags=item_ID)

        self._number_of_rows += 1        

        if self._stripped_rows:            
            list_of_items = self.interior.get_children()

            self.interior.tag_configure(item_ID, background=self._stripped_rows[index%2])

            for i in range(index+1, self._number_of_rows):
                self.interior.tag_configure(list_of_items[i], background=self._stripped_rows[i%2])

    def column_data(self, index):
        return [self.interior.set(child_ID, index) for child_ID in self.interior.get_children('')]

    def update_column(self, index, data):
        for i, item_ID in enumerate(self.interior.get_children()): 
            data_row = self.item_ID_to_row_data(item_ID)
            data_row[index] = data[i]

            self.interior.item(item_ID, values=data_row)

        return data

    def clear(self):
        # Another possibility:
        #  self.interior.delete(*self.interior.get_children())

        for row in self.interior.get_children():
            self.interior.delete(row)
            
        self._number_of_rows = 0
            
    def update(self, data):
        self.clear()

        for row in data:
            self.insert_row(row)
            
    def focus(self, index=None):
        if index is None:
            return self.interior.item(self.interior.focus())
        else:
            item = self.interior.get_children()[index]
            self.interior.focus(item)

    def state(self, state=None):
        if stateSpec is None:
            return self.interior.state()
        else:
            self.interior.state(state)

    @property
    def number_of_rows(self):
        return self._number_of_rows
        
    @property
    def number_of_columns(self):
        return self._number_of_columns
        
    def toogle_selection(self, index):
        list_of_items = self.interior.get_children()
        
        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d"%index)

        self.interior.selection_toggle(item_ID)     

    def select_row(self, index):
        list_of_items = self.interior.get_children()
        
        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d"%index)

        self.interior.selection_add(item_ID)

    def deselect_row(self, index):
        list_of_items = self.interior.get_children()
        
        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d"%index)

        self.interior.selection_remove(item_ID)
        
    def deselect_all(self):
        self.interior.selection_remove(self.interior.selection())

    def set_selection(self, indices):
        list_of_items = self.interior.get_children()

        self.interior.selection_set(" ".join(list_of_items[row_index] for row_index in indices))

    @property
    def selected_rows(self):
        data = []
        for item_ID in self.interior.selection():
            data_row = self.item_ID_to_row_data(item_ID)
            data.append(data_row)
        
        return data

    @property
    def indices_of_selected_rows(self):
        list_of_indices = []
        for index, item_ID in enumerate(self.interior.get_children()):
            if item_ID in self.interior.selection():
                list_of_indices.append(index)

        return list_of_indices
        
    def delete_all_selected_rows(self):
        selected_items = self.interior.selection()
        for item_ID in selected_items:
            self.interior.delete(item_ID)
        
        number_of_deleted_rows = len(selected_items)
        self._number_of_rows -= number_of_deleted_rows

        return number_of_deleted_rows

    def _on_select(self, event):
        for item_ID in event.widget.selection():
            data_row = self.item_ID_to_row_data(item_ID)
            self._command(data_row)

    def item_ID_to_row_data(self, item_ID):
        item = self.interior.item(item_ID)
        return item["values"]
    
    @property
    def table_data(self):
        data = []

        for item_ID in self.interior.get_children():
            data_row = self.item_ID_to_row_data(item_ID)
            data.append(data_row)

        return data
    
    @table_data.setter
    def table_data(self, data):
        self.update(data)
    
    def cell_data(self, row, column):
        """Get the value of a table cell"""
        try:
            item = self.interior.get_children()[row]
        except IndexError:
            raise ValueError("Row index out of range: %d"%row)
            
        return self.interior.set(item, column)
            
    def update_cell(self, row, column, value):
        """Set the value of a table cell"""

        item_ID = self.interior.get_children()[row]
        
        data = self.item_ID_to_row_data(item_ID)
        
        data[column] = value
        self.interior.item(item_ID, values=data)
    
    def __getitem__(self, index):
        if isinstance(index, tuple):
            row, column = index
            return self.cell_data(row, column)
        else:
            raise Exception("Row and column indices are required")
        
    def __setitem__(self, index, value):
        if isinstance(index, tuple):
            row, column = index
            self.update_cell(row, column, value)
        else:
            raise Exception("Row and column indices are required")

    def bind(self, event, handler):
        self.interior.bind(event, handler)

    def sort_by(self, col, descending):
        """
        sort tree contents when a column header is clicked
        """
        # grab values to sort
        data = [(self.interior.set(child_ID, col), child_ID) for child_ID in self.interior.get_children('')]
        
        # if the data to be sorted is numeric change to float
        try:
            data = [(float(number), child_ID) for number, child_ID in data]
        except ValueError:
            pass

        # now sort the data in place
        data.sort(reverse=descending)
        for idx, item in enumerate(data):
            self.interior.move(item[1], '', idx)

        # switch the heading so that it will sort in the opposite direction
        self.interior.heading(col, command=lambda col=col: self.sort_by(col, not descending))
        
        if self._stripped_rows:
            list_of_items = self.interior.get_children('')
            for i in range(len(list_of_items)):
                self.interior.tag_configure(list_of_items[i], background=self._stripped_rows[i%2])

    def destroy(self):
        self.interior.destroy()
        
    def item_ID(self, index):
        return self.interior.get_children()[index]
class LobbyUI(Frame):
    """
    Sudoku multiplayer lobby UI class.
    In case of incorrect inputs error messages are shown.
    """
    action = None

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.row, self.col = -1, -1
        self.__initUI()

    def __initUI(self):
        """
        Initialize UI with a list and required entry fields and submit buttons."""

        self.parent.title('Multiplayer Game')
        self.pack(fill=BOTH, expand=1)

        self.lobby_list = Treeview(self, columns=('room', 'players'))
        self.lobby_list['show'] = 'headings'
        self.lobby_list.heading('room', text='Room ID')
        self.lobby_list.column('room', width=250, anchor=CENTER)
        self.lobby_list.heading('players', text='Players')
        self.lobby_list.column('players', width=100, anchor=CENTER)
        self.lobby_list.grid(row=1,
                             column=0,
                             columnspan=2,
                             rowspan=2,
                             padx=20,
                             pady=(10, 0))

        self.connect_lobby = Button(self,
                                    text='Joining Sudoku\n Solving Session',
                                    command=self.__connect_lobby)
        self.connect_lobby.grid(row=3, column=1, pady=(0, 10))

        Label(self,
              text='Creating new Sudoku\n solving session:').grid(row=4,
                                                                  column=0)

        self.max_players = Entry(self)
        self.max_players.grid(row=4, column=1)

        self.create_game = Button(self,
                                  text='Join new game',
                                  command=self.__create_game)
        self.create_game.grid(row=5, column=1)

    def __connect_lobby(self):
        """
        Handle lobby connection button."""
        LOG.debug('Lobby connect button has been pressed.')
        current_item = self.lobby_list.focus()
        selected_id = None

        if current_item is not None and current_item.strip() != '':
            # Select game column value from item values dictionary.
            selected_id = self.lobby_list.item(current_item)['values'][0]
            LOG.debug('Player wishes to join game ' + str(selected_id))

            if selected_id is not None:
                self.action = ('select', selected_id)
        else:
            tkMessageBox.showwarning(
                "Connection error",
                "Please select a game from the lobby to join.")

    def __create_game(self):
        """
        Create game with some number of max players."""
        max_ok = False

        try:
            max_count = int(self.max_players.get())
        except (ValueError, TypeError):
            max_count = -1
            tkMessageBox.showwarning("Input error",
                                     "Max player count has to be an integer.")

        if isinstance(max_count, int):
            if max_count >= 2:
                max_ok = True
                LOG.debug('Ok max player count.')
            else:
                tkMessageBox.showwarning(
                    "Input error", "Max player count has to be larger than 2.")
                LOG.error('Bad max count.')

        if max_ok:
            self.action = ('create', max_count)

    def populate_list(self, games):
        """
        Method to re-populate the lobby list every poll.
        Additionally retains the focused line during polling.
        :param games:
        """
        previous_selection = self.lobby_list.selection()
        prev_item = None
        if len(previous_selection) > 0:
            prev_item = self.lobby_list.item(previous_selection[0])

        self.lobby_list.delete(*self.lobby_list.get_children())
        for game in games:
            self.lobby_list.insert('',
                                   'end',
                                   values=(str(game[0]),
                                           str(game[1]) + '/' + str(game[2])))

        if prev_item is not None:
            for item in self.lobby_list.get_children():
                if self.lobby_list.item(item) == prev_item:
                    self.lobby_list.selection_set(item)
                    self.lobby_list.focus(item)
Esempio n. 7
0
class SDCard: 
	def __init__(self, root, prtr, settings, log):
		self.app = root
		self.printer = prtr
		self.settings = settings
		self.log = log
		self.top = None

	def isActive(self):
		return self.top != None

	def start(self):
		self.app.sdchecking = True
		self.printer.send_now("M21")
		
	def sdCheckComplete(self, ready):
		if not ready:
			self.log.logMsg("Error initializing SD card")
		else:
			self.app.sdlisting = True
			self.printer.send_now("M20")
			
	def refresh(self):
		self.top.destroy()
		self.app.sdlisting = True
		self.printer.send_now("M20")
			
	def sdListComplete(self, sdlist):
		top = self.top = Toplevel(self.app) 
		top.title("SD Card Control")
		top.protocol('WM_DELETE_WINDOW', self.delTop)
		f = Frame(top, height=150, width=150)
		f.grid(row=1, column=1);
		self.tree = Treeview(f, height=12, selectmode='browse') 
		self.tree.column("#0", minwidth=100)
		self.tree.bind("<<TreeviewSelect>>", self.treeSelect)
		self.sb = Scrollbar(f)
		self.sb.config(command=self.tree.yview)
		self.tree.config(yscrollcommand=self.sb.set)
			
		self.sb.pack(side=RIGHT, fill=Y)
		self.tree.pack(side=LEFT, fill=BOTH, expand=1)

		SDroot = SDDir('')
		for item in sdlist:
			if item.startswith('/'):
				cd = SDroot
				l = item[1:].split('/')
				for d in l[:-1]:
					ncd = cd.getDir(d)
					if ncd == None:
						ncd = cd.addDir(d)
			
					cd = ncd
				cd.addFile(l[-1], fqn=item)
					
			else:
				SDroot.addFile(item)
				
		SDroot.sortAll()
		
		self.fileMap = {}
		self.startFile = None
		self.loadDir(SDroot, '')
		bf = Frame(top, width=50)
		bf.grid(column=3, row=1)
		
		blf = LabelFrame(bf, text="Print from SD Card", width=48, height=40)
		
		self.bPrint = Button(blf, text='Print', command=self.doPrint, width = 6) 
		self.bPrint.pack()
		blf.pack(fill='x')
		
		blf = LabelFrame(bf, text="Delete from SD Card", width=48, height=40)
		
		self.bDelete = Button(blf, text="Delete", command=self.doDelete, width=6)
		self.bDelete.pack()
		blf.pack(fill='x')
		
		blf = LabelFrame(bf, text="Upload to SD Card", width=48, height=180)

		self.upDir = Label(blf, text="Dir:", justify=LEFT)
		self.upDir.pack()

		ef = Frame(blf)

		l = Label(ef, text="File:", justify=LEFT)
		l.pack(side=LEFT)

		self.entry = Entry(ef, width=12)
		self.entry.pack(side=LEFT)
		fn = 'untitled.g'
		if self.app.GCodeFile:
			fn = os.path.basename(self.app.GCodeFile)
			if len(fn) > 8:
				fn = fn[0:8]
			fn += ".g"
		self.entry.delete(0, END)
		self.entry.insert(0, fn)
		ef.pack()
		
		self.bUpload = Button(blf, text="Upload", command=self.doUpload, width=6)
		self.bUpload.pack()

		blf.pack(fill='x')
		
		if self.app.printing or self.app.sdprinting:
			self.bPrint.config(state=DISABLED)
			self.bUpload.config(state=DISABLED)
			
		if not self.app.GCodeFile:
			self.bUpload.config(state=DISABLED)
			
		blf = Frame(bf)
		self.bExit = Button(blf, text='Exit', command=self.doExit, width=6) 
		self.bExit.pack()
		blf.pack()

		if self.startFile:
			self.tree.selection_set(self.startFile)
			
		self.top.geometry("360x300+100+100")

	def delTop(self):
		self.top.destroy()
		self.top = None
	
	def treeSelect(self, *arg):
		s = self.tree.selection()[0]
		
		try:
			d = s.split(':')[0]
		except:
			d = ""
			
		if len(d) == 0:
			d = '(root)'
			
		self.upDir.config(text="Dir: " + d)
		
		if self.app.printing or self.app.sdprinting or not self.app.GCodeFile:
			self.bUpload.config(state=DISABLED)
		else:
			self.bUpload.config(state=NORMAL)
			
		if ':' in s: # a file is chosen
			if self.app.printing or self.app.sdprinting:
				self.bPrint.config(state=DISABLED)
			else:
				self.bPrint.config(state=NORMAL)
			self.bDelete.config(state=NORMAL)
			
		else: # a directory is chosen
			self.bPrint.config(state=DISABLED)
			self.bDelete.config(state=DISABLED)


	def loadDir(self, d, did):
		d.resetDir()
		nd = d.nextDir()
		while (nd):
			myid = did + '/' + nd.dirName()
			self.tree.insert(did, 'end', myid, text=nd.dirName())
			self.loadDir(nd, myid)
			nd = d.nextDir()
			
		d.resetFile()
		f = d.nextFile()
		while (f):
			myid = did + ':' + f[0]
			self.fileMap[myid] = f[1]
			self.tree.insert(did, 'end', myid, text=f[0])
			if self.startFile == None:
				self.startFile = myid
			f = d.nextFile()		
		
	def doExit(self): 
		self.top.destroy()
		self.top = None

	def doPrint(self): 
		s = self.tree.selection()[0]
		if s in self.fileMap:
			fn = self.fileMap[s].lower()
			self.log.logMsg("Starting print of SD file %s" % fn)
			self.printer.send_now("M23 %s" % fn)  # select the file
			self.printer.send_now("M24") # start the print
			self.app.sdprinting = True
			self.app.setToolbarSDPrint()
			self.top.destroy()
			self.top = None
		
	def doDelete(self):
		s = self.tree.selection()[0]
		if s in self.fileMap:
			fn = self.fileMap[s].lower()
			self.log.logMsg("Deleting file %s" % fn)
			self.printer.send_now("M30 %s" % fn)
			self.refresh()
		
	def doUpload(self):
		bn = self.entry.get()

		try:		
			d = self.tree.selection()[0].split(':')[0]
		except:
			d = ""
			
		if len(d) != 0:
			d += '/'
		
		fn = (d + bn).lower()
		self.log.logMsg("Starting upload to SD file %s" % fn)
		self.printer.send_now("M28 %s" % fn)  # select the file
		self.app.startUpload()
		self.top.destroy()
		self.top = None