Ejemplo n.º 1
0
 def init_toolbar(self):
     for action in self.actions:
         if len(action) == 1:
             Frame(self._toolbar, width=1, bg=self.style.colors.get("primarydarkaccent")).pack(
                 side='left', fill='y', pady=3, padx=5)
             continue
         btn = Button(self._toolbar, image=action[1], **self.style.button, width=25, height=25)
         btn.pack(side="left", padx=3)
         btn.tooltip(action[3])
         ActionNotifier.bind_event("<Button-1>", btn, action[2], text=action[3])
Ejemplo n.º 2
0
class ElementPane(Pane):
    name = "Widget tree"
    MAX_STARTING_DEPTH = 4

    def __init__(self, master, debugger):
        super(ElementPane, self).__init__(master)
        Label(self._header, **self.style.text_accent,
              text=self.name).pack(side="left")

        ElementTreeView.Node.debugger = debugger
        self._tree = ElementTreeView(self)
        self._tree.pack(side="top", fill="both", expand=True, pady=4)
        self._tree.allow_multi_select(True)
        self._tree.on_select(self.on_select)

        self._search_btn = Button(
            self._header,
            **self.style.button,
            image=get_icon_image("search", 15, 15),
            width=25,
            height=25,
        )
        self._search_btn.pack(side="right", padx=2)
        self._search_btn.on_click(self.start_search)

        self._reload_btn = Button(
            self._header,
            **self.style.button,
            image=get_icon_image("rotate_clockwise", 15, 15),
            width=25,
            height=25,
        )
        self._reload_btn.pack(side="right", padx=2)
        self._reload_btn.tooltip("reload tree")

        self._toggle_btn = Button(self._header,
                                  image=get_icon_image("chevron_down", 15, 15),
                                  **self.style.button,
                                  width=25,
                                  height=25)
        self._toggle_btn.pack(side="right", padx=2)

        self._select_btn = ToggleButton(
            self._header,
            **self.style.button,
            image=get_icon_image("cursor", 15, 15),
            width=25,
            height=25,
        )
        self._select_btn.pack(side="right", padx=2)
        self._select_btn.tooltip("select element to inspect")

        self.debugger = debugger
        self._tree.add_as_node(
            widget=debugger.root).update_preload_status(False)

        self.debugger.bind("<<WidgetCreated>>", self.on_widget_created)
        self.debugger.bind("<<WidgetDeleted>>", self.on_widget_deleted)
        self.debugger.bind("<<WidgetModified>>", self.on_widget_modified)

        tkinter.Misc.bind_all(self.debugger.root, "<Motion>", self.on_motion)
        tkinter.Misc.bind_all(self.debugger.root, "<Button-1>",
                              self.on_widget_tap)
        tkinter.Misc.bind_all(self.debugger.root, "<Button-3>",
                              self.on_widget_tap)
        tkinter.Misc.bind_all(self.debugger.root, "<Map>", self.on_widget_map)
        tkinter.Misc.bind_all(self.debugger.root, "<Unmap>",
                              self.on_widget_unmap)
        self.highlighted = None

    @property
    def selected(self):
        return self._tree.get()

    def on_select(self):
        self.debugger.update_selection(self._tree.get())

    def on_widget_tap(self, event):
        if self._select_btn.get():
            try:
                # widget = self.debugger.root.winfo_containing(event.x_root, event.y_root)
                widget = event.widget
                # print(widget)
                if widget.winfo_toplevel() == self.debugger or getattr(
                        widget, "_dbg_ignore", False):
                    widget = None
            except (KeyError, AttributeError):
                widget = None

            if widget:
                node = self._tree.expand_to(widget)
                if node:
                    node.select(event)

    def on_motion(self, event):
        if self._select_btn.get():
            try:
                # widget = self.debugger.root.winfo_containing(event.x_root, event.y_root)
                widget = event.widget
                if widget.winfo_toplevel() == self.debugger or getattr(
                        widget, "_dbg_ignore", False):
                    widget = None
                # print(f"motion : {widget} <> {event.widget}")
            except (KeyError, AttributeError):
                widget = None
            self.debugger.highlight_widget(widget)
            self.highlighted = widget

    def on_widget_created(self, _):
        widget = self.debugger.active_widget
        parent_node = getattr(widget.master, "_dbg_node", None)
        if parent_node:
            if parent_node.loaded:
                parent_node.add_as_node(widget=widget)
                self.debugger.hook_widget(widget)
            else:
                parent_node.update_preload_status(True)

    def on_widget_deleted(self, _):
        widget = self.debugger.active_widget
        parent_node = getattr(widget.master, "_dbg_node", None)
        if parent_node:
            if parent_node.loaded:
                node = widget._dbg_node
                if node in self.selected:
                    self._tree.toggle_from_selection(node)
                parent_node.remove(widget._dbg_node)
            else:
                parent_node.update_preload_status(False)

    def on_widget_modified(self, _):
        if self.debugger.active_widget not in self.selected:
            return

    def on_widget_map(self, _):
        pass

    def on_widget_unmap(self, _):
        pass
Ejemplo n.º 3
0
class EventPane(BaseFeature):
    name = "Event pane"
    icon = "blank"
    _defaults = {
        **BaseFeature._defaults,
        "side": "right",
    }
    NO_SELECTION_MSG = "You have not selected any widget selected"
    NO_EVENT_MSG = "You have not added any bindings"
    NO_MATCH_MSG = "No items match your search"

    def __init__(self, master, studio, **cnf):
        super().__init__(master, studio, **cnf)
        self.header = Frame(self, **self.style.surface)
        self.header.pack(side="top", fill="x")
        for i, title in enumerate(("Sequence", "Handler", "Add", " " * 3)):
            Label(
                self.header,
                **self.style.text_passive,
                text=title,
                anchor="w",
            ).grid(row=0, column=i, sticky='ew')

        # set the first two columns to expand evenly
        for column in range(2):
            self.header.grid_columnconfigure(column, weight=1, uniform=1)

        self.bindings = BindingsTable(self)
        self.bindings.on_value_change(self.modify_item)
        self.bindings.on_item_delete(self.delete_item)
        self.bindings.pack(fill="both", expand=True)

        self._add = Button(self._header,
                           **self.style.button,
                           width=25,
                           height=25,
                           image=get_icon_image("add", 15, 15))
        self._add.pack(side="right")
        self._add.tooltip("Add event binding")
        self._add.on_click(self.add_new)

        self._search_btn = Button(
            self._header,
            **self.style.button,
            image=get_icon_image("search", 15, 15),
            width=25,
            height=25,
        )
        self._search_btn.pack(side="right")
        self._search_btn.on_click(self.start_search)

        self._empty_frame = Label(self.bindings, **self.style.text_passive)
        self._show_empty(self.NO_SELECTION_MSG)

    def _show_empty(self, message):
        self._empty_frame.place(x=0, y=0, relwidth=1, relheight=1)
        self._empty_frame["text"] = message

    def _remove_empty(self):
        self._empty_frame.place_forget()

    def add_new(self, *_):
        if self.studio.selected is None:
            return
        self._remove_empty()
        new_binding = make_event("<>", "", False)
        widget = self.studio.selected
        if not hasattr(widget, "_event_map_"):
            setattr(widget, "_event_map_", {})
        widget._event_map_[new_binding.id] = new_binding
        self.bindings.add(new_binding)

    def delete_item(self, item):
        widget = self.studio.selected
        if widget is None:
            return
        widget._event_map_.pop(item.id)
        self.bindings.remove(item.id)

    def modify_item(self, value: EventBinding):
        widget = self.studio.selected
        widget._event_map_[value.id] = value

    def on_select(self, widget):
        if widget is None:
            self._show_empty(self.NO_SELECTION_MSG)
            return
        self._remove_empty()
        bindings = getattr(widget, "_event_map_", {})
        values = bindings.values()
        self.bindings.clear()
        self.bindings.add(*values)
        if not values:
            self._show_empty(self.NO_EVENT_MSG)

    def start_search(self, *_):
        if self.studio.selected:
            super().start_search()

    def on_search_query(self, query: str):
        showing = 0
        self._remove_empty()
        self.bindings.hide_all()
        for item in self.bindings.items:
            if query in item.value.sequence or query in item.value.handler:
                item.show()
                showing += 1
        if not showing:
            self._show_empty(self.NO_MATCH_MSG)

    def on_search_clear(self):
        self._remove_empty()
        self.bindings.hide_all()
        for item in self.bindings.items:
            item.show()
        super().on_search_clear()