Exemplo n.º 1
0
 def __init__(self, master, style_def):
     super().__init__(master, style_def)
     self.set_def(style_def)
     self.config(width=150, height=110)
     self.n = ToggleButton(self, text="N", width=20, height=20)
     self.n.grid(row=0, column=0, columnspan=3, sticky='ns')
     self.w = ToggleButton(self, text='W', width=20, height=20)
     self.w.grid(row=1, column=0, sticky='ew')
     self.pad = Frame(self,
                      width=60,
                      height=60,
                      **self.style.dark,
                      **self.style.dark_highlight_active)
     self.pad.grid(row=1, column=1, padx=1, pady=1)
     self.pad.grid_propagate(0)
     self.pad.grid_columnconfigure(0, minsize=60)
     self.pad.grid_rowconfigure(0, minsize=60)
     self.floating = Frame(self.pad,
                           **self.style.dark_on_hover,
                           width=20,
                           height=20)
     self.floating.grid(row=0, column=0, pady=1, padx=1)
     self.e = ToggleButton(self, text="E", width=20, height=20)
     self.e.grid(row=1, column=2, sticky='ew')
     self.s = ToggleButton(self, text='S', width=20, height=20)
     self.s.grid(row=2, column=0, columnspan=3, sticky='ns')
     self.anchors = {"n": self.n, "w": self.w, "e": self.e, "s": self.s}
     self._order = ("n", "s", "e", "w")
     self._selected = []
     self._exclusive_pairs = ({"n", "s"}, {"e", "w"})
     self._is_multiple = re.compile(r'(.*[ns].*[ns])|(.*[ew].*[ew])')
     for anchor in self.anchors:
         self.anchors[anchor].on_change(self._change, anchor)
Exemplo n.º 2
0
        def render(self):
            self.config(height=40)
            seq_frame = Frame(self, **self.style.highlight)
            seq_frame.grid(row=0, column=0, sticky="nsew")
            seq_frame.pack_propagate(False)
            self.sequence = Entry(seq_frame, **self.style.input)
            self.sequence.place(x=0, y=0, relwidth=1, relheight=1, width=-40)
            self.sequence.set(self.value.sequence)
            self.sequence.configure(**self.style.no_highlight)
            self.sequence.focus_set()
            self.handler = Entry(self, **self.style.input)
            self.handler.grid(row=0, column=1, sticky="ew")
            self.handler.set(self.value.handler)
            self.handler.config(**self.style.highlight)
            self.add_arg = Checkbutton(self, **self.style.checkbutton)
            self.add_arg.grid(row=0, column=2, sticky="ew")
            self.add_arg.set(self.value.add)
            del_btn = Label(self,
                            **self.style.button,
                            image=get_icon_image("delete", 14, 14))
            del_btn.grid(row=0, column=3, sticky='nswe')
            del_btn.bind("<Button-1>", self._delete_entry)
            # set the first two columns to expand evenly
            for column in range(2):
                self.grid_columnconfigure(column, weight=1, uniform=1)

            for widget in (self.sequence, self.handler):
                widget.on_change(self._on_value_change)

            self.add_arg._var.trace("w", lambda *_: self._on_value_change())
Exemplo n.º 3
0
    def __init__(self, master, studio, **cnf):
        super().__init__(master, studio, **cnf)
        self.body = ScrolledFrame(self, **self.style.dark)
        self.body.pack(side="top", fill="both", expand=True)

        self._toggle_btn = Button(self._header,
                                  image=get_icon_image("chevron_down", 15, 15),
                                  **self.style.dark_button,
                                  width=25,
                                  height=25)
        self._toggle_btn.pack(side="right")
        self._toggle_btn.on_click(self._toggle)

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

        self.groups = []

        self._identity_group = self.add_group(IdentityGroup)
        self._layout_group = self.add_group(LayoutGroup)
        self._attribute_group = self.add_group(AttributeGroup)

        self._empty_frame = Frame(self.body)
        self.show_empty()
        self._current = None
        self._expanded = False
Exemplo n.º 4
0
 def render(self, _):
     self.detail = Label(self, **self.style.text, text=self.message)
     self.detail.pack(fill="x")
     warn_frame = Frame(self, **self.style.surface)
     self._warning = Label(
         warn_frame,
         **self.style.text_passive,
         padx=5,
         anchor='w',
         compound="left",
         image=get_tk_image("dialog_warning", 15, 15),
     )
     self.event_pad = Label(
         self, **self.style.text_accent)
     self._add_button(text="Cancel", value=None)
     self._add_button(text="Okay", command=self.exit_with_key, focus=True)
     warn_frame.pack(side="bottom", fill="x")
     self.event_pad.config(
         **self.style.bright, takefocus=True,
         text="Tap here to begin capturing shortcuts."
     )
     self.event_pad.bind("<Any-KeyPress>", self.on_key_change)
     # for some reason alt needs to be bound separately
     self.event_pad.bind("<Alt-KeyPress>", self.on_key_change)
     self.event_pad.bind("<Button-1>", lambda e: self.event_pad.focus_set())
     self.event_pad.pack(fill="both", expand=True)
Exemplo n.º 5
0
    def setup_style_pane(self):
        self.body = ScrolledFrame(self, **self.style.surface)
        self.body.pack(side="top", fill="both", expand=True)

        self._toggle_btn = Button(self.get_header(),
                                  image=get_icon_image("chevron_down", 15, 15),
                                  **self.style.button,
                                  width=25,
                                  height=25)
        self._toggle_btn.pack(side="right")
        self._toggle_btn.on_click(self._toggle)

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

        self.groups = []

        self._empty_frame = Frame(self.body)
        self.show_empty()
        self._current = None
        self._expanded = False
        self._is_loading = False
        self._search_query = None
Exemplo n.º 6
0
    def __init__(self, master, studio=None, **cnf):
        super().__init__(master, studio, **cnf)
        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")
        self._toggle_btn.on_click(self._toggle)

        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.body = Frame(self, **self.style.surface)
        self.body.pack(side="top", fill="both", expand=True)
        self._empty_label = Label(self.body, **self.style.text_passive)

        self._selected = None
        self._expanded = False
        self._tree = None
Exemplo n.º 7
0
 def __init__(self, master, studio=None, **cnf):
     super().__init__(master, **cnf)
     self.update_defaults()
     self.__class__._instance = self
     if not self.__class__._view_mode:
         self.__class__._view_mode = StringVar(None, self.get_pref('mode'))
         self.__class__._transparency_flag = t = BooleanVar(None, self.get_pref('inactive_transparency'))
         self.__class__._side = side = StringVar(None, self.get_pref('side'))
         t.trace_add("write", lambda *_: self.set_pref('inactive_transparency', t.get()))
     self.studio = studio
     self._header = Frame(self, **self.style.dark, **self.style.dark_highlight_dim, height=30)
     self._header.pack(side="top", fill="x")
     self._header.pack_propagate(0)
     self._header.allow_drag = True
     Label(self._header, **self.style.dark_text_passive, text=self.name).pack(side="left")
     self._min = Button(self._header, image=get_icon_image("close", 15, 15), **self.style.dark_button, width=25,
                        height=25)
     self._min.pack(side="right")
     self._min.on_click(self.minimize)
     self._pref = MenuButton(self._header, **self.style.dark_button)
     self._pref.configure(image=get_icon_image("settings", 15, 15))
     self._pref.pack(side="right")
     self._pref.tooltip("Options")
     self._search_bar = SearchBar(self._header, height=20)
     self._search_bar.on_query_clear(self.on_search_clear)
     self._search_bar.on_query_change(self.on_search_query)
     menu = self.make_menu((
         ("cascade", "View Mode", None, None, {"menu": (
             ("radiobutton", "Docked", None, self.open_as_docked, {"variable": self._view_mode, "value": "docked"}),
             ("radiobutton", "Window", None, self.open_as_window, {"variable": self._view_mode, "value": "window"}),
         )}),
         ("cascade", "Position", None, None, {"menu": (
             ("radiobutton", "Left", None, lambda: self.reposition("left"),
              {"variable": self._side, "value": "left"}),
             ("radiobutton", "Right", None, lambda: self.reposition("right"),
              {"variable": self._side, "value": "right"}),
         )}),
         EnableIf(lambda: self._view_mode.get() == 'window',
                  ("cascade", "Window options", None, None, {"menu": (
                      (
                          "checkbutton", "Transparent when inactive", None, None,
                          {"variable": self._transparency_flag}),
                  )})),
         ("command", "Close", get_icon_image("close", 14, 14), self.minimize, {}),
         ("separator",),
         *self.create_menu()
     ), self._pref)
     self._pref.config(menu=menu)
     # self._pref.on_click(self.minimize)
     self.config(**self.style.dark)
     self.indicator = None
     self.window_handle = None
     self.on_focus(self._on_focus_get)
     self.on_focus_lost(self._on_focus_release)
     self.on_close(self.close_window)
     self._mode_map = {
         'window': self.open_as_window,
         'docked': self.open_as_docked
     }
Exemplo n.º 8
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])
Exemplo n.º 9
0
 def __init__(self, master, **cnf):
     super().__init__(master, **cnf)
     self.config(**self.style.dark)
     self._label_frame = Frame(self, **self.style.bright, height=20)
     self._label_frame.pack(side="top", fill="x", padx=2)
     self._label_frame.pack_propagate(0)
     self._label = Label(self._label_frame, **self.style.bright,
                         **self.style.text_bright)
     self._label.pack(side="left")
     self._collapse_btn = Button(self._label_frame,
                                 width=20,
                                 **self.style.bright,
                                 **self.style.text_bright)
     self._collapse_btn.config(text=get_icon("triangle_up"))
     self._collapse_btn.pack(side="right", fill="y")
     self._collapse_btn.on_click(self.toggle)
     self.body = Frame(self, **self.style.dark)
     self.body.pack(side="top", fill="both", pady=2)
     self.__ref = Frame(self.body, height=0, width=0, **self.style.dark)
     self.__ref.pack(side="top")
     self._collapsed = False
Exemplo n.º 10
0
 def __init__(self, master, **cnf):
     super(Pane, self).__init__(master, **cnf)
     self.config(**self.style.surface)
     self._header = Frame(self,
                          **self.style.surface,
                          **self.style.highlight_dim,
                          height=30)
     self._header.pack(side="top", fill="x")
     self._header.pack_propagate(0)
     self._search_bar = SearchBar(self._header, height=20)
     self._search_bar.on_query_clear(self.on_search_clear)
     self._search_bar.on_query_change(self.on_search_query)
Exemplo n.º 11
0
 def __init__(self, master, pane, **cnf):
     super().__init__(master)
     self.style_pane = pane
     self.configure(**{**self.style.surface, **cnf})
     self._empty_message = "Select an item to see styles"
     self._empty = Frame(self.body, **self.style.surface)
     self._empty_label = Label(
         self._empty,
         **self.style.text_passive,
     )
     self._empty_label.pack(fill="both", expand=True, pady=15)
     self._widget = None
     self._prev_widget = None
     self._has_initialized = False  # Flag to mark whether Style Items have been created
     self.items = {}
Exemplo n.º 12
0
    def __init__(self, master, studio=None, **cnf):
        super().__init__(master, studio, **cnf)
        f = Frame(self, **self.style.dark)
        f.pack(side="top", fill="both", expand=True, pady=4)
        f.pack_propagate(0)

        self._variable_pane = ScrolledFrame(f, width=150)
        self._variable_pane.place(x=0, y=0, relwidth=0.4, relheight=1)

        self._detail_pane = ScrolledFrame(f, width=150)
        self._detail_pane.place(relx=0.4,
                                y=0,
                                relwidth=0.6,
                                relheight=1,
                                x=15,
                                width=-20)

        self._search_btn = Button(self._header,
                                  image=get_icon_image("search", 15, 15),
                                  width=25,
                                  height=25,
                                  **self.style.dark_button)
        self._search_btn.pack(side="right")
        self._search_btn.on_click(self.start_search)
        self._add = MenuButton(self._header, **self.style.dark_button)
        self._add.configure(image=get_icon_image("add", 15, 15))
        self._add.pack(side="right")
        self._delete_btn = Button(self._header,
                                  image=get_icon_image("delete", 15, 15),
                                  width=25,
                                  height=25,
                                  **self.style.dark_button)
        self._delete_btn.pack(side="right")
        self._delete_btn.on_click(self._delete)
        self._var_types_menu = self.make_menu(self._get_add_menu(), self._add)
        self._add.config(menu=self._var_types_menu)
        self._selected = None
        self._links = {}
        self._overlay = Label(f,
                              **self.style.dark_text_passive,
                              text="Add variables",
                              compound="top")
        self._overlay.configure(image=get_icon_image("add", 25, 25))
        self._show_overlay(True)
        self._editors = []
Exemplo n.º 13
0
    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)
Exemplo n.º 14
0
    def __init__(self, master, studio=None, **cnf):
        if not self._var_init:
            self._init_var(studio)
        super().__init__(master, studio, **cnf)

        f = Frame(self, **self.style.surface)
        f.pack(side="top", fill="both", expand=True, pady=4)
        f.pack_propagate(0)

        self._widget_set = Spinner(self._header, width=150)
        self._widget_set.config(**self.style.no_highlight)
        self._widget_set.set_values(list(self.CLASSES.keys()))
        self._widget_set.pack(side="left")
        self._widget_set.on_change(self.collect_groups)
        self._select_pane = ScrolledFrame(f, width=150)
        self._select_pane.place(x=0, y=0, relwidth=0.4, relheight=1)

        self._search_btn = Button(self._header, image=get_icon_image("search", 15, 15), width=25, height=25,
                                  **self.style.button)
        self._search_btn.pack(side="right")
        self._search_btn.on_click(self.start_search)
        self._search_selector = Label(self._select_pane.body, **self.style.text, text="search", anchor="w")
        self._search_selector.configure(**self.style.hover)

        self._widget_pane = ScrolledFrame(f, width=150)
        self._select_pane.body.config(**self.style.surface)
        self._widget_pane.place(relx=0.4, y=0, relwidth=0.6, relheight=1)

        self._pool = {}
        self._selectors = []
        self._selected = None
        self._component_cache = None
        self._extern_groups = []
        self._widget = None
        self.collect_groups(self.get_pref("widget_set"))
        # add custom widgets config to settings
        templates.update(_widget_pref_template)
        self._custom_group = None
        self._custom_widgets = []
        Preferences.acquire().add_listener(self._custom_pref_path, self._init_custom)
        self._reload_custom()
Exemplo n.º 15
0
    def __init__(self, master, studio=None, **cnf):
        if not self._var_init:
            self._init_var(studio)
        super().__init__(master, studio, **cnf)

        f = Frame(self, **self.style.dark)
        f.pack(side="top", fill="both", expand=True, pady=4)
        f.pack_propagate(0)

        self._widget_set = Spinner(self._header, width=150)
        self._widget_set.config(**self.style.no_highlight)
        self._widget_set.set_values(list(self.CLASSES.keys()))
        self._widget_set.pack(side="left")
        self._widget_set.on_change(self.collect_groups)
        self._select_pane = ScrolledFrame(f, width=150)
        self._select_pane.place(x=0, y=0, relwidth=0.4, relheight=1)

        self._search_btn = Button(self._header,
                                  image=get_icon_image("search", 15, 15),
                                  width=25,
                                  height=25,
                                  **self.style.dark_button)
        self._search_btn.pack(side="right")
        self._search_btn.on_click(self.start_search)
        self._search_selector = Label(self._select_pane.body,
                                      **self.style.dark_text,
                                      text="search",
                                      anchor="w")
        self._search_selector.configure(**self.style.dark_on_hover)

        self._widget_pane = ScrolledFrame(f, width=150, bg="orange")
        self._select_pane.body.config(**self.style.dark)
        self._widget_pane.place(relx=0.4, y=0, relwidth=0.6, relheight=1)

        self._pool = {}
        self._selectors = []
        self._selected = None
        self._component_cache = None
        self.collect_groups(self.get_pref("widget_set"))
Exemplo n.º 16
0
    def __init__(self, master, studio=None, **cnf):
        super().__init__(master, studio, **cnf)
        f = Frame(self, **self.style.surface)
        f.pack(side="top", fill="both", expand=True, pady=4)
        f.pack_propagate(0)

        self._variable_pane = ScrolledFrame(f, width=150)
        self._variable_pane.place(x=0, y=0, relwidth=0.4, relheight=1)

        self._detail_pane = ScrolledFrame(f, width=150)
        self._detail_pane.place(relx=0.4,
                                y=0,
                                relwidth=0.6,
                                relheight=1,
                                x=15,
                                width=-20)

        Label(self._detail_pane.body,
              **self.style.text_passive,
              text="Type",
              anchor="w").pack(side="top", fill="x")
        self.var_type_lbl = Label(self._detail_pane.body,
                                  **self.style.text,
                                  anchor="w")
        self.var_type_lbl.pack(side="top", fill="x")
        Label(self._detail_pane.body,
              **self.style.text_passive,
              text="Name",
              anchor="w").pack(side="top", fill="x")
        self.var_name = editors.get_editor(self._detail_pane.body,
                                           self._definitions["name"])
        self.var_name.pack(side="top", fill="x")
        Label(self._detail_pane.body,
              **self.style.text_passive,
              text="Value",
              anchor="w").pack(fill="x", side="top")
        self._editors = {}
        self._editor = None

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

        self._add = MenuButton(self._header, **self.style.button)
        self._add.configure(image=get_icon_image("add", 15, 15))
        self._add.pack(side="right")
        self._delete_btn = Button(self._header,
                                  image=get_icon_image("delete", 15, 15),
                                  width=25,
                                  height=25,
                                  **self.style.button)
        self._delete_btn.pack(side="right")
        self._delete_btn.on_click(self._delete)
        self._var_types_menu = self.make_menu(self._get_add_menu(),
                                              self._add,
                                              title="Add variable")
        self._var_types_menu.configure(tearoff=True)
        self._add.config(menu=self._var_types_menu)
        self._selected = None
        self._links = {}
        self._overlay = Label(f,
                              **self.style.text_passive,
                              text=self._empty_message,
                              compound="top")
        self._overlay.configure(image=get_icon_image("add", 25, 25))
        self._show_overlay(True)
Exemplo n.º 17
0
 def _make_button_bar(self):
     self.bar = Frame(self, **self.style.dark,
                      **self.style.dark_highlight_dim)
     self.bar.pack(side="bottom", fill="x")
Exemplo n.º 18
0
    def __init__(self, master=None, **cnf):
        super().__init__(master, **cnf)
        # Load icon asynchronously to prevent issues which have been known to occur when loading it synchronously
        icon_image = load_tk_image(self.ICON_PATH)
        self.iconphoto(True, icon_image)
        self.pref = pref
        self._restore_position()
        self.title('Formation Studio')
        self.protocol('WM_DELETE_WINDOW', self._on_close)
        self.shortcuts = ShortcutManager(self, pref)
        self.shortcuts.bind_all()
        self._register_actions()
        self._toolbar = Frame(self, **self.style.dark, height=30)
        self._toolbar.pack(side="top", fill="x")
        self._toolbar.pack_propagate(0)
        self._statusbar = Frame(self, **self.style.dark, height=20)
        self._statusbar.pack(side="bottom", fill="x")
        self._statusbar.pack_propagate(0)
        body = Frame(self, **self.style.dark)
        body.pack(fill="both", expand=True, side="top")
        self._right_bar = SideBar(body)
        self._right_bar.pack(side="right", fill="y")
        self._left_bar = SideBar(body)
        self._left_bar.pack(side="left", fill="y")
        self._pane = PanedWindow(body, **self.style.dark_pane_horizontal)
        self._pane.pack(side="left", fill="both", expand=True)
        self._left = PanedWindow(self._pane, **self.style.dark_pane_vertical)
        self._center = PanedWindow(self._pane, **self.style.dark_pane_vertical)
        self._right = PanedWindow(self._pane, **self.style.dark_pane_vertical)

        self._bin = []
        self._clipboard = None
        self._undo_stack = []
        self._redo_stack = []
        self.current_preview = None

        self._pane.add(self._left, minsize=320, sticky='nswe', width=320)
        self._pane.add(self._center, minsize=400, width=16000, sticky='nswe')
        self._pane.add(self._right, minsize=320, sticky='nswe', width=320)

        self._panes = {
            "left": (self._left, self._left_bar),
            "right": (self._right, self._right_bar),
            "center": (self._center, None)
        }

        icon = get_icon_image

        self.actions = (
            ("Delete", icon("delete", 20, 20), lambda e: self.delete(),
             "Delete selected widget"),
            ("Undo", icon("undo", 20,
                          20), lambda e: self.undo(), "Undo action"),
            ("Redo", icon("redo", 20,
                          20), lambda e: self.redo(), "Redo action"),
            ("Cut", icon("cut", 20,
                         20), lambda e: self.cut(), "Cut selected widget"),
            ("separator", ),
            ("Fullscreen", icon("image_editor", 20, 20),
             lambda e: self.close_all(), "Design mode"),
            ("Separate", icon("separate", 20,
                              20), lambda e: self.features_as_windows(),
             "Open features in window mode"),
            ("Dock", icon("flip_horizontal", 15, 15),
             lambda e: self.features_as_docked(), "Dock all features"),
            ("separator", ),
            ("New", icon("add", 20,
                         20), lambda e: self.open_new(), "New design"),
            ("Save", icon("save", 20,
                          20), lambda e: self.save(), "Save design"),
            ("Preview", icon("play", 20,
                             20), lambda e: self.preview(), "Preview design"),
        )

        self.init_toolbar()
        self.selected = None
        # set the image option to blank if there is no image for the menu option
        self.blank_img = blank_img = icon("blank", 14, 14)

        # -------------------------------------------- menu definition ------------------------------------------------
        self.menu_template = (EnableIf(
            lambda: self.selected,
            ("separator", ),
            ("command", "copy", icon("copy", 14,
                                     14), actions.get('STUDIO_COPY'), {}),
            ("command", "paste", icon("clipboard", 14,
                                      14), actions.get('STUDIO_PASTE'), {}),
            ("command", "cut", icon("cut", 14,
                                    14), actions.get('STUDIO_CUT'), {}),
            ("separator", ),
            ("command", "delete", icon("delete", 14,
                                       14), actions.get('STUDIO_DELETE'), {}),
        ), )

        self.menu_bar = MenuUtils.make_dynamic(
            (("cascade", "File", None, None, {
                "menu": (
                    ("command", "New", icon(
                        "add", 14, 14), actions.get('STUDIO_NEW'), {}),
                    ("command", "Open", icon(
                        "folder", 14, 14), actions.get('STUDIO_OPEN'), {}),
                    ("cascade", "Recent", icon("clock", 14, 14), None, {
                        "menu": self._create_recent_menu()
                    }),
                    ("separator", ),
                    ("command", "Save", icon(
                        "save", 14, 14), actions.get('STUDIO_SAVE'), {}),
                    ("command", "Save As", icon(
                        "save", 14, 14), actions.get('STUDIO_SAVE_AS'), {}),
                    ("separator", ),
                    ("command", "Settings", icon("settings", 14, 14),
                     actions.get('STUDIO_SETTINGS'), {}),
                    ("command", "Exit", icon(
                        "exit", 14, 14), actions.get('STUDIO_EXIT'), {}),
                )
            }), ("cascade", "Edit", None, None, {
                "menu": (
                    EnableIf(lambda: len(self._undo_stack),
                             ("command", "undo", icon("undo", 14, 14),
                              actions.get('STUDIO_UNDO'), {})),
                    EnableIf(lambda: len(self._redo_stack),
                             ("command", "redo", icon("redo", 14, 14),
                              actions.get('STUDIO_REDO'), {})),
                    *self.menu_template,
                )
            }), ("cascade", "Code", None, None, {
                "menu":
                (EnableIf(lambda: self.designer and self.designer.root_obj,
                          ("command", "Preview design", icon("play", 14, 14),
                           actions.get('STUDIO_PREVIEW'), {}),
                          ("command", "close preview", icon("close", 14, 14),
                           actions.get('STUDIO_PREVIEW_CLOSE'), {})))
            }), ("cascade", "Window", None, None, {
                "menu":
                (("command", "show all", blank_img,
                  actions.get('FEATURE_SHOW_ALL'), {}),
                 ("command", "close all", icon(
                     "close", 14, 14), actions.get('FEATURE_CLOSE_ALL'), {}),
                 ("command", "close all on the right", blank_img,
                  actions.get('FEATURE_CLOSE_RIGHT'), {}),
                 ("command", "close all on the left", blank_img,
                  actions.get('FEATURE_CLOSE_LEFT'), {}), ("separator", ),
                 ("command", "Undock all windows", blank_img,
                  actions.get('FEATURE_UNDOCK_ALL'), {}),
                 ("command", "Dock all windows", blank_img,
                  actions.get('FEATURE_DOCK_ALL'), {}), ("separator", ),
                 LoadLater(self.get_features_as_menu), ("separator", ),
                 ("command", "Save window positions", blank_img,
                  actions.get('FEATURE_SAVE_POS'), {}))
            }), ("cascade", "Tools", None, None, {
                "menu": ToolManager.get_tools_as_menu(self)
            }), ("cascade", "Help", None, None, {
                "menu": (
                    ("command", "Help", icon('dialog_info', 14, 14),
                     actions.get('STUDIO_HELP'), {}),
                    ("command", "Check for updates", icon("cloud", 14,
                                                          14), None, {}),
                    ("separator", ),
                    ("command", "About Studio", blank_img,
                     lambda: about_window(self), {}),
                )
            })), self, self.style, False)
        self.config(menu=self.menu_bar)

        self.features = []

        self.designer = Designer(self._center, self)
        self._center.add(self.designer, sticky='nswe')
        self.install(ComponentPane)
        self.install(ComponentTree)
        self.install(StylePane)
        self.install(VariablePane)
        self._startup()
        self._restore_position()
Exemplo n.º 19
0
    def __init__(self, master, widget, menu=None):
        super().__init__(master, widget)
        self.title(f'Edit menu for {widget.id}')
        if not isinstance(menu, tk.Menu):
            menu = tk.Menu(widget, tearoff=False)
            widget.configure(menu=menu)
        self._base_menu = menu
        self._tool_bar = Frame(self, **self.style.dark, **self.style.dark_highlight_dim, height=30)
        self._tool_bar.pack(side="top", fill="x")
        self._tool_bar.pack_propagate(False)
        self._pane = PanedWindow(self, **self.style.dark_pane_horizontal)
        self._tree = MenuTree(self._pane, widget, menu)
        self._tree.allow_multi_select(True)
        self._tree.on_select(self._refresh_styles)
        self._tree.on_structure_change(self._refresh_styles)

        self._editor_pane = ScrolledFrame(self._pane)
        self._editor_pane_cover = Label(self._editor_pane, **self.style.dark_text_passive)
        self._editor_pane.pack(side="top", fill="both", expand=True)
        self._menu_item_styles = CollapseFrame(self._editor_pane.body)
        self._menu_item_styles.pack(side="top", fill="x", pady=4)
        self._menu_item_styles.label = "Menu Item attributes"
        self._menu_styles = CollapseFrame(self._editor_pane.body)
        self._menu_styles.pack(side="top", fill="x", pady=4)
        self._menu_styles.label = "Menu attributes"
        self._style_item_ref = {}
        self._menu_style_ref = {}
        self._prev_selection = None

        self._add = MenuButton(self._tool_bar, **self.style.dark_button)
        self._add.pack(side="left")
        self._add.configure(image=get_icon_image("add", 15, 15))
        _types = MenuTree.Node._type_def
        menu_types = self._tool_bar.make_menu(
            [(
                tk.COMMAND,
                i.title(),
                get_icon_image(_types[i][0], 14, 14),
                functools.partial(self.add_item, i), {}
            ) for i in _types],
            self._add)
        menu_types.configure(tearoff=True)
        self._add.config(menu=menu_types)
        self._delete_btn = Button(self._tool_bar, image=get_icon_image("delete", 15, 15), **self.style.dark_button,
                                  width=25,
                                  height=25)
        self._delete_btn.pack(side="left")
        self._delete_btn.on_click(self._delete)

        self._preview_btn = Button(self._tool_bar, image=get_icon_image("play", 15, 15), **self.style.dark_button,
                                   width=25, height=25)
        self._preview_btn.pack(side="left")
        self._preview_btn.on_click(self._preview)

        self._pane.pack(side="top", fill="both", expand=True)
        self._pane.add(self._tree, minsize=350, sticky='nswe', width=350, height=500)
        self._pane.add(self._editor_pane, minsize=320, sticky='nswe', width=320, height=500)
        self.load_menu(menu, self._tree)
        self._show_editor_message(self._MESSAGE_EDITOR_EMPTY)
        self.enable_centering()
        self.focus_set()
        self._load_all_properties()
Exemplo n.º 20
0
    def __init__(self, master=None, **cnf):
        super().__init__(master, **cnf)
        # Load icon asynchronously to prevent issues which have been known to occur when loading it synchronously
        icon_image = load_tk_image(self.ICON_PATH)
        self.load_styles(self.THEME_PATH)
        self.iconphoto(True, icon_image)
        self.pref = pref
        self._restore_position()
        self.title('Formation Studio')
        self.protocol('WM_DELETE_WINDOW', self._on_close)
        self.shortcuts = ShortcutManager(self, pref)
        self.shortcuts.bind_all()
        self._register_actions()
        self._toolbar = Frame(self, **self.style.surface, height=30)
        self._toolbar.pack(side="top", fill="x")
        self._toolbar.pack_propagate(0)
        self._statusbar = Frame(self, **self.style.surface, height=20)
        self._statusbar.pack(side="bottom", fill="x")
        self._statusbar.pack_propagate(0)
        body = Frame(self, **self.style.surface)
        body.pack(fill="both", expand=True, side="top")
        self._right_bar = SideBar(body)
        self._right_bar.pack(side="right", fill="y")
        self._left_bar = SideBar(body)
        self._left_bar.pack(side="left", fill="y")
        self._pane = PanedWindow(body, **self.style.pane_horizontal)
        self._pane.pack(side="left", fill="both", expand=True)
        self._left = FeaturePane(self._pane, **self.style.pane_vertical)
        self._center = PanedWindow(self._pane, **self.style.pane_vertical)
        self._right = FeaturePane(self._pane, **self.style.pane_vertical)

        self._bin = []
        self._clipboard = None
        self.current_preview = None

        self._pane.add(self._left, minsize=320, sticky='nswe', width=320)
        self._pane.add(self._center, minsize=400, width=16000, sticky='nswe')
        self._pane.add(self._right, minsize=320, sticky='nswe', width=320)

        self._panes = {
            "left": (self._left, self._left_bar),
            "right": (self._right, self._right_bar),
            "center": (self._center, None)
        }

        icon = get_icon_image

        self.actions = (
            ("Delete", icon("delete", 20, 20), lambda e: self.delete(), "Delete selected widget"),
            ("Undo", icon("undo", 20, 20), lambda e: self.undo(), "Undo action"),
            ("Redo", icon("redo", 20, 20), lambda e: self.redo(), "Redo action"),
            ("Cut", icon("cut", 20, 20), lambda e: self.cut(), "Cut selected widget"),
            ("separator",),
            ("Fullscreen", icon("image_editor", 20, 20), lambda e: self.close_all(), "Design mode"),
            ("Separate", icon("separate", 20, 20), lambda e: self.features_as_windows(),
             "Open features in window mode"),
            ("Dock", icon("flip_horizontal", 15, 15), lambda e: self.features_as_docked(),
             "Dock all features"),
            ("separator",),
            ("New", icon("add", 20, 20), lambda e: self.open_new(), "New design"),
            ("Save", icon("save", 20, 20), lambda e: self.save(), "Save design"),
            ("Preview", icon("play", 20, 20), lambda e: self.preview(), "Preview design"),
        )

        self.init_toolbar()
        self.selected = None
        # set the image option to blank if there is no image for the menu option
        self.blank_img = blank_img = icon("blank", 14, 14)

        self.tool_manager = ToolManager(self)

        # -------------------------------------------- menu definition ------------------------------------------------
        self.menu_template = (EnableIf(
            lambda: self.selected,
            ("separator",),
            ("command", "copy", icon("copy", 14, 14), actions.get('STUDIO_COPY'), {}),
            ("command", "duplicate", icon("copy", 14, 14), actions.get('STUDIO_DUPLICATE'), {}),
            EnableIf(
                lambda: self._clipboard is not None,
                ("command", "paste", icon("clipboard", 14, 14), actions.get('STUDIO_PASTE'), {})
            ),
            ("command", "cut", icon("cut", 14, 14), actions.get('STUDIO_CUT'), {}),
            ("separator",),
            ("command", "delete", icon("delete", 14, 14), actions.get('STUDIO_DELETE'), {}),
        ),)

        self.menu_bar = MenuUtils.make_dynamic(
            ((
                 ("cascade", "formation", None, None, {"menu": (
                     ("command", "Restart", None, actions.get('STUDIO_RESTART'), {}),
                     ("separator", ),
                     ("command", "About Formation", icon("formation", 14, 14), lambda: about_window(self), {}),
                 ), "name": "apple"}),
             ) if platform_is(MAC) else ()) +
            (
                ("cascade", "File", None, None, {"menu": (
                    ("command", "New", icon("add", 14, 14), actions.get('STUDIO_NEW'), {}),
                    ("command", "Open", icon("folder", 14, 14), actions.get('STUDIO_OPEN'), {}),
                    ("cascade", "Recent", icon("clock", 14, 14), None, {"menu": self._create_recent_menu()}),
                    ("separator",),
                    EnableIf(
                        lambda: self.designer,
                        ("command", "Save", icon("save", 14, 14), actions.get('STUDIO_SAVE'), {}),
                        ("command", "Save As", icon("blank", 14, 14), actions.get('STUDIO_SAVE_AS'), {})
                    ),
                    EnableIf(
                        # more than one design contexts open
                        lambda: len([i for i in self.contexts if isinstance(i, DesignContext)]) > 1,
                        ("command", "Save All", icon("blank", 14, 14), actions.get('STUDIO_SAVE_ALL'), {})
                    ),
                    ("separator",),
                    ("command", "Settings", icon("settings", 14, 14), actions.get('STUDIO_SETTINGS'), {}),
                    ("command", "Restart", icon("blank", 14, 14), actions.get('STUDIO_RESTART'), {}),
                    ("command", "Exit", icon("close", 14, 14), actions.get('STUDIO_EXIT'), {}),
                )}),
                ("cascade", "Edit", None, None, {"menu": (
                    EnableIf(lambda: self.context and self.context.has_undo(),
                             ("command", "undo", icon("undo", 14, 14), actions.get('STUDIO_UNDO'), {})),
                    EnableIf(lambda: self.context and self.context.has_redo(),
                             ("command", "redo", icon("redo", 14, 14), actions.get('STUDIO_REDO'), {})),
                    *self.menu_template,
                )}),
                ("cascade", "Code", None, None, {"menu": (
                    EnableIf(
                        lambda: self.designer and self.designer.root_obj,
                        ("command", "Preview design", icon("play", 14, 14), actions.get('STUDIO_PREVIEW'), {}),
                        ("command", "close preview", icon("close", 14, 14), actions.get('STUDIO_PREVIEW_CLOSE'), {}),
                        ("separator", ),
                        EnableIf(
                            lambda: self.designer and self.designer.design_path,
                            ("command", "Reload design file", icon("rotate_clockwise", 14, 14),
                             actions.get('STUDIO_RELOAD'), {}),
                        ),
                    )
                )}),
                ("cascade", "View", None, None, {"menu": (
                    ("command", "show all panes", blank_img, actions.get('FEATURE_SHOW_ALL'), {}),
                    ("command", "close all panes", icon("close", 14, 14), actions.get('FEATURE_CLOSE_ALL'), {}),
                    ("command", "close all panes on the right", blank_img, actions.get('FEATURE_CLOSE_RIGHT'), {}),
                    ("command", "close all panes on the left", blank_img, actions.get('FEATURE_CLOSE_LEFT'), {}),
                    ("separator",),
                    ("command", "Undock all windows", blank_img, actions.get('FEATURE_UNDOCK_ALL'), {}),
                    ("command", "Dock all windows", blank_img, actions.get('FEATURE_DOCK_ALL'), {}),
                    ("separator",),
                    LoadLater(self.get_features_as_menu),
                    ("separator",),
                    EnableIf(
                        lambda: self.context,
                        ("command", "close tab", icon("close", 14, 14), actions.get('CONTEXT_CLOSE'), {}),
                        ("command", "close all tabs", blank_img, actions.get('CONTEXT_CLOSE_ALL'), {}),
                        EnableIf(
                            lambda: self.context and len(self.tab_view.tabs()) > 1,
                            ("command", "close other tabs", blank_img, actions.get('CONTEXT_CLOSE_OTHER'), {})
                        ),
                        EnableIf(
                            lambda: self.context and self.context._contexts_right(),
                            ("command", "close all tabs on the right", blank_img,
                             actions.get('CONTEXT_CLOSE_OTHER_RIGHT'), {})
                        )
                    ),
                    ("separator",),
                    ("command", "Save window positions", blank_img, actions.get('FEATURE_SAVE_POS'), {})
                )}),
                ("cascade", "Tools", None, None, {"menu": (LoadLater(self.tool_manager.get_tools_as_menu), )}),
                ("cascade", "Help", None, None, {"menu": (
                    ("command", "Help", icon('dialog_info', 14, 14), actions.get('STUDIO_HELP'), {}),
                    ("command", "Check for updates", icon("cloud", 14, 14), self._check_updates, {}),
                    ("separator",),
                    ("command", "About Formation", icon("formation", 14, 14), lambda: about_window(self), {}),
                )})
            ), self, self.style, False)

        self.config(menu=self.menu_bar)

        if platform_is(MAC):
            self.createcommand("tk::mac::ShowPreferences", lambda: actions.get('STUDIO_SETTINGS').invoke())
            self.createcommand("tk::mac::ShowHelp", lambda: actions.get('STUDIO_HELP').invoke())
            self.createcommand("tk::mac::Quit", lambda: actions.get('STUDIO_EXIT').invoke())

        self.features = []
        self.context = None
        self.contexts = []
        self.tab_view = TabView(self._center)
        self.tab_view.malleable(True)
        self.tab_view.bind("<<TabSelectionChanged>>", self.on_context_switch)
        self.tab_view.bind("<<TabClosed>>", self.on_context_close)
        self.tab_view.bind("<<TabAdded>>", self.on_context_add)
        self.tab_view.bind("<<TabOrderChanged>>", lambda _: self.save_tab_status())
        self._center.add(self.tab_view, sticky='nswe')
        self._tab_view_empty = Label(
            self.tab_view, **self.style.text_passive, compound='top',
            image=get_icon_image("paint", 60, 60)
        )
        self._tab_view_empty.config(**self.style.bright)

        # install features
        for feature in FEATURES:
            self.install(feature)

        # common feature references
        self.style_pane = self.get_feature(StylePane)

        # initialize tools with everything ready
        self.tool_manager.initialize()

        self._ignore_tab_status = False
        self._startup()
        self._exit_failures = 0
        self._is_shutting_down = False
Exemplo n.º 21
0
 def initialize_tree(self):
     super(ComponentTreeView, self).initialize_tree()
     self._empty = Frame(self, **self.style.surface)
     self._empty_text = Label(self._empty, **self.style.text_passive)
     self._empty_text.pack(fill="both", expand=True, pady=30)
     self._show_empty("No items created yet")