def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)

        self.title_bar = TitleBar(self, 'Dissector Builder Area')
        self.frame_canvas = tk.Frame(self, bg='white')
        self.frame_palette = SubAreaPalette(self)
        self.hbar = tk.Scrollbar(self, orient=tk.HORIZONTAL)
        self.vbar = tk.Scrollbar(self, orient=tk.VERTICAL)

        canvas = CanvasDnd(self.frame_canvas,
                           bg='white',
                           width=800,
                           height=500,
                           scrollregion=(0, 0, 5000, 5000))
        canvas.config(xscrollcommand=self.hbar.set,
                      yscrollcommand=self.vbar.set)
        self.hbar.config(command=canvas.xview)
        self.vbar.config(command=canvas.yview)
        canvas.hbar = self.hbar
        canvas.vbar = self.vbar

        # lbl_canvas = tk.Label(self.frame_canvas, text='Canvas')

        # Parent set-up
        self.title_bar.pack(fill=tk.X, expand=True, side=tk.TOP)
        self.frame_palette.pack(fill=tk.BOTH, expand=True, side=tk.RIGHT)
        self.vbar.pack(fill=tk.Y, expand=False, side=tk.RIGHT)
        self.frame_canvas.pack(fill=tk.BOTH, expand=False)
        self.hbar.pack(fill=tk.X, expand=True)

        # Frame Canvas set-up
        canvas.pack(fill=tk.BOTH, expand=True)
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.title_bar = TitleBar(self, 'Project Navigator')

        self.title_bar.bind()
        self.title_bar.pack(padx=2)

        self.label = tk.Label(self, text=Workspace.current.name)
        self.label.bind()
        self.label.pack()

        self.im_close = tk.PhotoImage(file="Closef.gif").subsample(5, 5)
        self.im_open = tk.PhotoImage(file="Openf.gif").subsample(5, 5)
        self.vars = []
        self.lbls = []

        for p in Workspace.current.projects:
            var_name = tk.StringVar(self, p.name)
            lbl = tk.Label(self,
                           textvariable=var_name,
                           compound='left',
                           pady=10,
                           padx=10,
                           image=self.im_close)
            lbl.bind("<Button-1>", lambda event: self.on_click(var_name, lbl))
            lbl.pack()

            self.vars.append(var_name)
            self.lbls.append(lbl)

        self.lbls[Workspace.current.selected_project]['image'] = self.im_open
예제 #3
0
    def __init__(self, title, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.title_bar = TitleBar(self, title)
        self.title_bar.set_max(lambda: self.text.grid())
        self.title_bar.set_min(lambda: self.text.grid_remove())
        self.text = tk.Text(self, width=35, height=20)

        self.title_bar.grid(column=0, row=0)
        self.text.grid(column=0, row=1)
예제 #4
0
 def __init__(self, parent=None):
     super().__init__(parent)
     self.monitor_info = None
     self.titleBar = TitleBar(self)
     self.windowEffect = WindowEffect()
     # 取消边框
     self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowSystemMenuHint
                         | Qt.WindowMinimizeButtonHint
                         | Qt.WindowMaximizeButtonHint)
     # 添加阴影和窗口动画
     self.windowEffect.addShadowEffect(self.winId())
     self.windowEffect.addWindowAnimation(self.winId())
     self.resize(500, 500)
     self.titleBar.raise_()
    def __init__(self, master, INFO_ID):
        View.__init__(self, master, INFO_ID)

        self['bg'] = 'red'
        self['height'] = 100
        self['width'] = 300

        from titlebar import TitleBar
        self.titlebar = TitleBar(self, 'Connector')

        # StringVars
        self.var_src = tk.StringVar(self, 'None')
        self.var_dst = tk.StringVar(self, 'None')
        self.src_idx = -1
        self.dst_idx = -1

        # Components
        self.arrow = tk.Label()

        self.src = tk.OptionMenu(self, self.var_src, None)
        self.src.bind('<Button-1>', self.on_menu_open)

        self.dst = tk.OptionMenu(self, self.var_dst, None)
        self.dst.bind('<Button-1>', self.on_menu_open)

        # Layout
        self.create_window((101, 10), width=400, window=self.titlebar)
        self.create_window((65, 40), window=self.src)
        self.create_window((65, 80), window=self.dst)
    def __init__(self, master, INFO_ID):
        View.__init__(self, master, INFO_ID)
        self['height']=30
        self['width']=150
        self.title_bar = TitleBar(self, 'End Field')

        self.create_window((75,12),width=150,window=self.title_bar)
    def __init__(self, master, INFO_ID):
        View.__init__(self, master, INFO_ID)
        self['height'] = 150

        self.titlebar = TitleBar(self, 'Start Field []')

        self.protocol_name_label = tk.Label(text='Protocol Name')
        self.var_proto_name = tk.StringVar()
        self.entry_proto_name = tk.Entry(self, textvariable=self.var_proto_name, width=40)

        self.create_window((47,50),window=self.protocol_name_label)
        self.create_window((190, 10), width=380, window=self.titlebar)
        self.create_window((250, 50), window=self.entry_proto_name)

        self.protocol_desc_label = tk.Label(text='Protocol Description')
        self.var_proto_desc = tk.StringVar()
        self.entry_proto_desc = tk.Entry(self, textvariable=self.var_proto_desc, width=40)

        self.create_window((60,70), window=self.protocol_desc_label)
        self.create_window((250,70), window= self.entry_proto_desc)
################
        self.protocol_dpn_label = tk.Label(text='Dependent Protocol Name')
        self.var_dep_proto_name = tk.StringVar()
        self.entry_dep_proto_name = tk.Entry(self, textvariable=self.var_dep_proto_name, width=35)

        self.create_window((76, 90), window=self.protocol_dpn_label)
        self.create_window((265, 90), window=self.entry_dep_proto_name)
#################
        self.dp_label = tk.Label(text='Dependency Pattern')
        self.var_dep_pattern = tk.StringVar()
        self.entry_dp = tk.Entry(self, textvariable=self.var_dep_pattern, width=40)

        self.create_window((60, 110), window=self.dp_label)
        self.create_window((250, 117), window=self.entry_dp)
        self['height']=150
    def __init__(self, master, INFO_ID):
        View.__init__(self, master, INFO_ID)
        self['height'] = 210

        self.titlebar = TitleBar(self, 'Field []')

        self.var_name = tk.StringVar()
        self.var_abbreviation = tk.StringVar()
        self.var_description = tk.StringVar()
        self.var_datatype = tk.StringVar()
        self.var_base = tk.StringVar()
        self.var_vc = tk.StringVar()
        self.var_required = tk.StringVar()

        self.proto_name_label = tk.Label(text="Name")
        self.entry_name = tk.Entry(self, textvariable=self.var_name, width=40)
        self.abbr_label = tk.Label(text="Abbreviation")
        self.abbr_entry = tk.Entry(self, textvariable=self.var_abbreviation, width=40)
        self.desc_label = tk.Label(text="Description")
        self.desc_entry = tk.Entry(self, textvariable=self.var_description, width=40)
        self.datatype_list = (
        'types.NONE', 'ftypes.PROTOCOL', 'ftypes.BOOLEAN', 'ftypes.UINT8', 'ftypes.UINT16', 'ftypes.UINT24',
        'ftypes.UINT32', 'ftypes.UINT64', 'ftypes.INT8', 'ftypes.INT16', 'ftypes.INT24', 'ftypes.INT32', 'ftypes.INT64',
        'ftypes.FLOAT', 'ftypes.DOUBLE', 'ftypes.ABSOLUTE_TIME', 'ftypes.RELATIVE_TIME', 'ftypes.STRING',
        'ftypes.STRINGZ', 'ftypes.UINT_STRING', 'ftypes.ETHER', 'ftypes.BYTES', 'ftypes.UINT_BYTES', 'ftypes.IPv4',
        'ftypes.IPv6', 'ftypes.IPXNET', 'ftypes.FRAMENUM', 'ftypes.PCRE', 'ftypes.GUID', 'ftypes.OID', 'ftypes.EUI6')
        self.var_datatype.set(self.datatype_list[0])
        self.entry_datatype = tk.OptionMenu(self, self.var_datatype, *self.datatype_list)
        self.datatype_label = tk.Label(text="Datatype")
        self.base_label = tk.Label(text="Base")
        self.base_list = ('base.NONE', 'base.DEC', 'base.HEX', 'base.OCT', 'base.DEC_HEX', 'base.HEX_DEC')
        self.var_base.set(self.base_list[0])
        self.entry_base = tk.OptionMenu(self, self.var_base, *self.base_list)
        self.vc_label = tk.Label(text="Value Constraint")
        self.vc_entry = tk.Entry(self, textvariable=self.var_vc, width=40)
        self.required_label = tk.Label(text="Required")
        self.required_list = ('Yes', 'No')
        self.var_required.set(self.required_list[0])
        self.required_entry = tk.OptionMenu(self, self.var_required, *self.required_list)

        self.create_window((47, 50), window=self.proto_name_label)
        self.create_window((190, 12), width=380, window=self.titlebar)
        self.create_window((250, 50), window=self.entry_name)
        self.create_window((38, 70), window=self.abbr_label)
        self.create_window((250, 70), window=self.abbr_entry)
        self.create_window((35, 90), window=self.desc_label)
        self.create_window((250, 90), window=self.desc_entry)
        self.create_window((250, 118), window=self.entry_datatype)
        self.create_window((28, 118), window=self.datatype_label)
        self.create_window((17, 140), window=self.base_label)
        self.create_window((250, 145), window=self.entry_base)
        self.create_window((45, 170), window=self.vc_label)
        self.create_window((250, 170), window=self.vc_entry)
        self.create_window((28, 196), window=self.required_label)
        self.create_window((250, 196), window=self.required_entry)
class AreaProjectNavigation(tk.Frame):
    def on_click(self, var_name, lbl):
        # Close the previous project
        prev_lbl = self.lbls[Workspace.current.selected_project]
        prev_lbl['image'] = self.im_close

        # Open the new project
        lbl['image'] = self.im_open
        # idx = next((i for i in range(len(Workspace.current.projects)) if Workspace.current.projects[i] == var_name.get()), 0)
        # Workspace.current.selected_project = idx

    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.title_bar = TitleBar(self, 'Project Navigator')

        self.title_bar.bind()
        self.title_bar.pack(padx=2)

        self.label = tk.Label(self, text=Workspace.current.name)
        self.label.bind()
        self.label.pack()

        self.im_close = tk.PhotoImage(file="Closef.gif").subsample(5, 5)
        self.im_open = tk.PhotoImage(file="Openf.gif").subsample(5, 5)
        self.vars = []
        self.lbls = []

        for p in Workspace.current.projects:
            var_name = tk.StringVar(self, p.name)
            lbl = tk.Label(self,
                           textvariable=var_name,
                           compound='left',
                           pady=10,
                           padx=10,
                           image=self.im_close)
            lbl.bind("<Button-1>", lambda event: self.on_click(var_name, lbl))
            lbl.pack()

            self.vars.append(var_name)
            self.lbls.append(lbl)

        self.lbls[Workspace.current.selected_project]['image'] = self.im_open
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.title_bar = TitleBar(self, "Packet Stream Area")
        self.table = tk.Frame(self)

        number = tk.Button(self.table, text="No.")
        time = tk.Button(self.table, text="Time")
        source = tk.Button(self.table, text="Source")
        destination = tk.Button(self.table, text="Destination")
        protocol = tk.Button(self.table, text="Protocol")
        info = tk.Button(self.table, text="Info")

        number.grid(row=0, column=0, sticky="E W")
        time.grid(row=0, column=1, sticky="E W")
        source.grid(row=0, column=2, sticky="E W")
        destination.grid(row=0, column=3, sticky="E W")
        protocol.grid(row=0, column=4, sticky="E W")
        info.grid(row=0, column=5, sticky="E W")

        self.table.grid(row=1, column=0)

        # self.grid(column=0, row=1)
        self.title_bar.set_max(lambda: self.table.grid())
        self.title_bar.set_min(lambda: self.table.grid_forget())

        self.title_bar.grid(column=0, row=0, sticky="E W")

        ##########################################################

        pcap_path = "C:\\Users\\xeroj\Desktop\\Local_Programming\\Python-Software-GUI\\example\\icmp.pcap"
        lua_path = "C:\\Users\\xeroj\Desktop\\Local_Programming\\Python-Software-GUI\\example\\icmp.lua"
        # self.fill_table(text)

        pdmltext = sp.check_output("tshark -r " + pcap_path +
                                   " -T pdml -X lua_script:" + lua_path)
        packets_info = self.get_packet_info("text.pdml", pdmltext)

        self.fill_table(packets_info)
예제 #11
0
    def init_frames(self):
        self.title_bar = TitleBar(self, 'Palette')
        self.title_bar.grid(column=0, row=0, columnspan=10, sticky='NWWE')

        self.frame_fields = tk.Frame(self, bg='white')
        self.frame_constructs = tk.Frame(self, bg='white')
        self.frame_decision = tk.Frame(self.frame_constructs)
        self.frame_connector = tk.Frame(self.frame_constructs)
        self.frame_expression = tk.Frame(self.frame_constructs)

        # Field Icon
        self.icon_field = tk.Label(self, text='', image=self.im_folder_open)
        self.lbl_field = tk.Label(self, text='Field', font=('', '12'))
        self.lbl_field.bind('<Button-1>', self.on_btn_click_field)
        self.icon_field.bind('<Button-1>', self.on_btn_click_field)

        # Construct Icon
        self.icon_construct = tk.Label(self, text='', image=self.im_folder_open)
        self.lbl_construct = tk.Label(self, text='Construct', font=('', '12'))
        self.lbl_construct.bind('<Button-1>', self.on_btn_click_construct)
        self.icon_construct.bind('<Button-1>', self.on_btn_click_construct)

        # Field Icon -> Field Frame -> Construct Icon -> Construct Frame
        self.icon_field.grid(row=1, column=0, sticky='WE')
        self.lbl_field.grid(row=1, column=1, columnspan=5, sticky='WE')

        self.frame_fields.grid(row=2, column=1, sticky='WE')

        self.icon_construct.grid(row=3, column=0, sticky='WE')
        self.lbl_construct.grid(row=3, column=1, columnspan=5, sticky='WE')

        self.frame_constructs.grid(row=4, column=1, columnspan=10, sticky='WE')

        # Decision Frame -> Connector Frame -> Expression Frame
        self.frame_decision.grid(column=0, row=1, columnspan=4, sticky='E')
        self.frame_connector.grid(column=0, row=2, columnspan=2, sticky='E')
        self.frame_expression.grid(column=0, row=3, columnspan=2, sticky='E')
예제 #12
0
class FramelessWindow(QWidget):

    BORDER_WIDTH = 5

    def __init__(self, parent=None):
        super().__init__(parent)
        self.monitor_info = None
        self.titleBar = TitleBar(self)
        self.windowEffect = WindowEffect()
        # 取消边框
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowSystemMenuHint
                            | Qt.WindowMinimizeButtonHint
                            | Qt.WindowMaximizeButtonHint)
        # 添加阴影和窗口动画
        self.windowEffect.addShadowEffect(self.winId())
        self.windowEffect.addWindowAnimation(self.winId())
        self.resize(500, 500)
        self.titleBar.raise_()

    def isWindowMaximized(self, hWnd) -> bool:
        """ 判断窗口是否最大化 """
        # 返回指定窗口的显示状态以及被恢复的、最大化的和最小化的窗口位置,返回值为元组
        windowPlacement = win32gui.GetWindowPlacement(hWnd)
        if not windowPlacement:
            return False
        return windowPlacement[1] == win32con.SW_MAXIMIZE

    def nativeEvent(self, eventType, message):
        """ 处理windows消息 """
        msg = MSG.from_address(message.__int__())
        if msg.message == win32con.WM_NCHITTEST:
            # 解决多屏下会出现鼠标一直为拖动状态的问题
            xPos = (win32api.LOWORD(msg.lParam) -
                    self.frameGeometry().x()) % 65536
            yPos = win32api.HIWORD(msg.lParam) - self.frameGeometry().y()
            w, h = self.width(), self.height()
            lx = xPos < self.BORDER_WIDTH
            rx = xPos + 9 > w - self.BORDER_WIDTH
            ty = yPos < self.BORDER_WIDTH
            by = yPos > h - self.BORDER_WIDTH
            if lx and ty:
                return True, win32con.HTTOPLEFT
            elif rx and by:
                return True, win32con.HTBOTTOMRIGHT
            elif rx and ty:
                return True, win32con.HTTOPRIGHT
            elif lx and by:
                return True, win32con.HTBOTTOMLEFT
            elif ty:
                return True, win32con.HTTOP
            elif by:
                return True, win32con.HTBOTTOM
            elif lx:
                return True, win32con.HTLEFT
            elif rx:
                return True, win32con.HTRIGHT
        elif msg.message == win32con.WM_NCCALCSIZE:
            if self.isWindowMaximized(msg.hWnd):
                self.monitorNCCALCSIZE(msg)
            return True, 0
        elif msg.message == win32con.WM_GETMINMAXINFO:
            if self.isWindowMaximized(msg.hWnd):
                window_rect = win32gui.GetWindowRect(msg.hWnd)
                if not window_rect:
                    return False, 0
                # 获取显示器句柄
                monitor = win32api.MonitorFromRect(window_rect)
                if not monitor:
                    return False, 0
                # 获取显示器信息
                monitor_info = win32api.GetMonitorInfo(monitor)
                monitor_rect = monitor_info['Monitor']
                work_area = monitor_info['Work']
                # 将lParam转换为MINMAXINFO指针
                info = cast(msg.lParam, POINTER(MINMAXINFO)).contents
                # 调整窗口大小
                info.ptMaxSize.x = work_area[2] - work_area[0]
                info.ptMaxSize.y = work_area[3] - work_area[1]
                info.ptMaxTrackSize.x = info.ptMaxSize.x
                info.ptMaxTrackSize.y = info.ptMaxSize.y
                # 修改左上角坐标
                info.ptMaxPosition.x = abs(window_rect[0] - monitor_rect[0])
                info.ptMaxPosition.y = abs(window_rect[1] - monitor_rect[1])
                return True, 1
        return QWidget.nativeEvent(self, eventType, message)

    def resizeEvent(self, e):
        """ 改变标题栏大小 """
        super().resizeEvent(e)
        self.titleBar.resize(self.width(), 40)
        # 更新最大化按钮图标
        self.titleBar.maxBt.setMaxState(
            self.isWindowMaximized(int(self.winId())))

    def monitorNCCALCSIZE(self, msg: MSG):
        """ 调整窗口大小 """
        monitor = win32api.MonitorFromWindow(msg.hWnd)
        # 如果没有保存显示器信息就直接返回,否则接着调整窗口大小
        if monitor is None and not self.monitor_info:
            return
        elif monitor is not None:
            self.monitor_info = win32api.GetMonitorInfo(monitor)
        # 调整窗口大小
        params = cast(msg.lParam, POINTER(NCCALCSIZE_PARAMS)).contents
        params.rgrc[0].left = self.monitor_info['Work'][0]
        params.rgrc[0].top = self.monitor_info['Work'][1]
        params.rgrc[0].right = self.monitor_info['Work'][2]
        params.rgrc[0].bottom = self.monitor_info['Work'][3]
class AreaPacketStream(Area):
    def __init__(self, *args, **kwargs):
        Area.__init__(self, "Packet Stream Area", *args, **kwargs)

    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.title_bar = TitleBar(self, "Packet Stream Area")
        self.table = tk.Frame(self)

        number = tk.Button(self.table, text="No.")
        time = tk.Button(self.table, text="Time")
        source = tk.Button(self.table, text="Source")
        destination = tk.Button(self.table, text="Destination")
        protocol = tk.Button(self.table, text="Protocol")
        info = tk.Button(self.table, text="Info")

        number.grid(row=0, column=0, sticky="E W")
        time.grid(row=0, column=1, sticky="E W")
        source.grid(row=0, column=2, sticky="E W")
        destination.grid(row=0, column=3, sticky="E W")
        protocol.grid(row=0, column=4, sticky="E W")
        info.grid(row=0, column=5, sticky="E W")

        self.table.grid(row=1, column=0)

        # self.grid(column=0, row=1)
        self.title_bar.set_max(lambda: self.table.grid())
        self.title_bar.set_min(lambda: self.table.grid_forget())

        self.title_bar.grid(column=0, row=0, sticky="E W")

        ##########################################################

        pcap_path = "C:\\Users\\xeroj\Desktop\\Local_Programming\\Python-Software-GUI\\example\\icmp.pcap"
        lua_path = "C:\\Users\\xeroj\Desktop\\Local_Programming\\Python-Software-GUI\\example\\icmp.lua"
        # self.fill_table(text)

        pdmltext = sp.check_output("tshark -r " + pcap_path +
                                   " -T pdml -X lua_script:" + lua_path)
        packets_info = self.get_packet_info("text.pdml", pdmltext)

        self.fill_table(packets_info)

    def get_packet_info(self, name, pdmltext):

        file = open(name, 'w')
        file.write(pdmltext)
        file.close()

        tree = ET.parse(name)
        root = tree.getroot()
        number = 0

        packets = []

        for packet in root:
            packet_info = PacketStreamItem()
            for proto in packet:
                if proto.attrib['name'] == 'ip':
                    for field in proto:
                        if field.attrib['name'] == 'ip.proto':
                            packet_info.protocol = field.attrib[
                                'showname'].split(' ')[1]

                if proto.attrib['name'] == 'frame':
                    for field in proto:
                        if field.attrib['name'] == 'frame.time_delta':
                            packet_info.time = field.attrib['show']

                if proto.attrib['name'] == 'ip':
                    attr = proto.attrib["showname"].split(',')
                    packet_info.source = attr[1].split(' ')[2]
                    packet_info.destination = attr[2].split(' ')[2]

            packet_info.number = number
            number += 1
            packets.append(packet_info)

        return packets

    def fill_table(self, packets_info):

        count = 1

        for info in packets_info:
            number_label = tk.Label(self.table, text=info.number)
            time_label = tk.Label(self.table, text=info.time)
            source_label = tk.Label(self.table, text=info.source)
            dest_label = tk.Label(self.table, text=info.destination)
            protocol_label = tk.Label(self.table, text=info.protocol)

            number_label.grid(row=count, column=0)
            time_label.grid(row=count, column=1)
            source_label.grid(row=count, column=2)
            dest_label.grid(row=count, column=3)
            protocol_label.grid(row=count, column=4)

            count += 1
예제 #14
0
class SubAreaPalette(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.is_field_open = True
        self.is_construct_open = True

        self.init_images()
        self.init_frames()
        self.init_fields()
        self.init_constructs()

    def init_images(self):
        self.im_folder_closed = ImageTk.PhotoImage(
            Image.open('folder_closed.png').resize((16, 16), Image.ANTIALIAS))
        self.im_folder_open = ImageTk.PhotoImage(Image.open('folder_opened.png').resize((16, 16), Image.ANTIALIAS))
        self.im_circle = ImageTk.PhotoImage(
            Image.open('circular-shape-silhouette.png').resize((40, 40), Image.ANTIALIAS))
        self.im_arrow = ImageTk.PhotoImage(Image.open('arrow-pointing-to-right.png'))
        self.im_diamond = ImageTk.PhotoImage(Image.open('rhombus.png').resize((40, 40), Image.ANTIALIAS))

    def init_frames(self):
        self.title_bar = TitleBar(self, 'Palette')
        self.title_bar.grid(column=0, row=0, columnspan=10, sticky='NWWE')

        self.frame_fields = tk.Frame(self, bg='white')
        self.frame_constructs = tk.Frame(self, bg='white')
        self.frame_decision = tk.Frame(self.frame_constructs)
        self.frame_connector = tk.Frame(self.frame_constructs)
        self.frame_expression = tk.Frame(self.frame_constructs)

        # Field Icon
        self.icon_field = tk.Label(self, text='', image=self.im_folder_open)
        self.lbl_field = tk.Label(self, text='Field', font=('', '12'))
        self.lbl_field.bind('<Button-1>', self.on_btn_click_field)
        self.icon_field.bind('<Button-1>', self.on_btn_click_field)

        # Construct Icon
        self.icon_construct = tk.Label(self, text='', image=self.im_folder_open)
        self.lbl_construct = tk.Label(self, text='Construct', font=('', '12'))
        self.lbl_construct.bind('<Button-1>', self.on_btn_click_construct)
        self.icon_construct.bind('<Button-1>', self.on_btn_click_construct)

        # Field Icon -> Field Frame -> Construct Icon -> Construct Frame
        self.icon_field.grid(row=1, column=0, sticky='WE')
        self.lbl_field.grid(row=1, column=1, columnspan=5, sticky='WE')

        self.frame_fields.grid(row=2, column=1, sticky='WE')

        self.icon_construct.grid(row=3, column=0, sticky='WE')
        self.lbl_construct.grid(row=3, column=1, columnspan=5, sticky='WE')

        self.frame_constructs.grid(row=4, column=1, columnspan=10, sticky='WE')

        # Decision Frame -> Connector Frame -> Expression Frame
        self.frame_decision.grid(column=0, row=1, columnspan=4, sticky='E')
        self.frame_connector.grid(column=0, row=2, columnspan=2, sticky='E')
        self.frame_expression.grid(column=0, row=3, columnspan=2, sticky='E')

    def init_fields(self):
        self.circlepic = tk.PhotoImage(file="circle.gif")
        self.sized_circle = self.circlepic.subsample(10, 10)
        self.circlebpic = tk.PhotoImage(file="circleb.gif")
        self.sized_circleb = self.circlebpic.subsample(10, 10)

        self.start_field = tk.Button(self.frame_fields,text='Start Field',image=self.sized_circle, compound='center')
        self.start_field.bind('<ButtonPress>',lambda event: self.on_dnd_start(event, PaletteType.START_FIELD))
        self.start_field.grid(column=0,row=1)

        self.field_1 = tk.Button(self.frame_fields, text='Field (1 byte)')
        self.field_1.bind('<ButtonPress>', lambda event: self.on_dnd_start(event, PaletteType.FIELD))
        self.field_1.grid(column=1, row=1)

        self.field_2 = tk.Button(self.frame_fields, text='Field (2 byte')
        self.field_2.bind('<ButtonPress>', lambda event: self.on_dnd_start(event, PaletteType.FIELD))
        self.field_2.grid(column=0, row=2)

        self.field_4 = tk.Button(self.frame_fields, text='Field (4 byte')
        self.field_4.bind('<ButtonPress>', lambda event: self.on_dnd_start(event, PaletteType.FIELD))
        self.field_4.grid(column=1, row=2)

        self.field_8 = tk.Button(self.frame_fields, text='Field (8 byte')
        self.field_8.bind('<ButtonPress>', lambda event: self.on_dnd_start(event, PaletteType.FIELD))
        self.field_8.grid(column=0, row=3)

        self.field_16 = tk.Button(self.frame_fields, text='Field (16 byte')
        self.field_16.bind('<ButtonPress>', lambda event: self.on_dnd_start(event, PaletteType.FIELD))
        self.field_16.grid(column=0, row=3)

        self.end_field = tk.Button(self.frame_fields, text='End Field', image=self.sized_circleb, compound='center', fg='red')
        self.end_field.bind('<ButtonPress>', lambda event: self.on_dnd_start(event, PaletteType.END_FIELD))
        self.end_field.grid(column=1, row=3)

    def init_constructs(self):
        self.init_decision_constructs()
        self.init_connector_constructs()
        self.init_expression_constructs()

    def init_decision_constructs(self):
        lbl_decision = tk.Label(self.frame_decision, text='Decision')
        lbl_decision.grid(column=0, row=0, sticky='W')

        btn_expression = tk.Button(self.frame_decision, text='Expression', image=self.im_diamond,
                                    compound=tk.CENTER)
        btn_expression.grid(column=0, row=1)

    def init_connector_constructs(self):
        lbl = tk.Label(self.frame_connector, text='Connector')
        lbl.grid(column=0, row=0, sticky='WE')

        connector = tk.Button(self.frame_connector, text='', image=self.im_arrow, compound=tk.CENTER, bg='white')
        connector.bind("<Button-1>", lambda event: self.on_dnd_start(event, PaletteType.CONNECTOR))
        connector.grid(column=0, row=1, sticky='WE')

    def init_expression_constructs(self):
        lbl = tk.Label(self.frame_expression, text='Expression')

        lbl2 = tk.Label(self.frame_expression, text='Relational Operator', bg='gray')
        op_frame1 = tk.Frame(self.frame_expression)
        op_less_than = tk.Button(op_frame1, text='<')
        op_less_than_equal = tk.Button(op_frame1, text='<=')
        op_greater_than = tk.Button(op_frame1, text='>')
        op_greater_than = tk.Button(op_frame1, text='>=')
        op_equal = tk.Button(op_frame1, text='==')
        op_not_equal = tk.Button(op_frame1, text='~=')

        lbl3 = tk.Label(self.frame_expression, text='Logical Operator')
        op_frame2 = tk.Frame(self.frame_expression)
        op_and = tk.Button(op_frame2, text='And')
        op_or = tk.Button(op_frame2, text='Or')
        op_not = tk.Button(op_frame2, text='Not')

        operand = tk.Button(self.frame_expression, text='Operand')

        lbl.grid(column=0, row=0, sticky='WE')
        lbl2.grid(column=0, row=1, sticky='WE')
        op_frame1.grid(column=0, row=2, sticky='WE')
        lbl3.grid(column=0, row=3, sticky='WE')
        op_frame2.grid(column=0, row=4)

        op_less_than.grid(column=1, row=0, sticky='WE')
        op_less_than_equal.grid(column=2, row=0, sticky='WE')
        op_greater_than.grid(column=3, row=0, sticky='WE')
        op_greater_than.grid(column=4, row=0, sticky='WE')
        op_equal.grid(column=5, row=0, sticky='WE')
        op_not_equal.grid(column=6, row=0, sticky='WE')

        op_and.grid(column=1, row=0, sticky='WE')
        op_or.grid(column=2, row=0, sticky='WE')
        op_not.grid(column=3, row=0, sticky='WE')

        operand.grid(column=0, row=7, sticky='WE')

    def on_btn_click_construct(self, event):
        if self.is_construct_open:
            self.icon_construct.configure(image=self.im_folder_closed)
            self.frame_constructs.grid_remove()
        else:
            self.icon_construct.configure(image=self.im_folder_open)
            self.frame_constructs.grid()

        self.is_construct_open = not self.is_construct_open

    def on_btn_click_field(self, event):
        if self.is_field_open:
            self.icon_field.configure(image=self.im_folder_closed)
            self.frame_fields.grid_remove()
        else:
            self.icon_field.configure(image=self.im_folder_open)
            self.frame_fields.grid()

        self.is_field_open = not self.is_field_open

    def on_dnd_start(self, event, type):
        # Create placeholder info and add it to tree
        print("dnd entered")
        ID = len(Workspace.current.get_tree().fields)
        info = self.info_from_type(ID, type)

        Workspace.current.get_tree().fields.insert(ID, info)

        ThingToDrag = Draggable(self, ID)
        Tkdnd.dnd_start(ThingToDrag, event)

    def info_from_type(self, ID, type):
        if type == PaletteType.START_FIELD:
            return StartFieldInfo()
        elif type == PaletteType.FIELD:
            return FieldInfo()
        elif type == PaletteType.END_FIELD:
            return EndFieldInfo()
        elif type == PaletteType.CONNECTOR:
            return ConnectorInfo()

        return StartFieldInfo()