def create_item(self, component, coords=(), item=None, canvas=None, silently=False, **kwargs): canvas = canvas or self.canvas if item is None: opts = dict(**component.defaults) opts.update(kwargs) item = component(canvas, *coords, **opts) # generate a unique id item.name = self.generator.generate(component, self._ids) canvas._cv_items.append(item) item._prev_index = canvas._cv_items.index(item) node = canvas._cv_tree.add_as_node(item=item) item.bind("<ButtonRelease-1>", lambda e: self._handle_select(item, e), True) item.bind("<ButtonRelease-1>", lambda e: self._handle_end(item, e), True) item.bind("<Motion>", lambda e: self._handle_move(item, e), True) MenuUtils.bind_context(item, self._show_item_menu(item)) MenuUtils.bind_all_context(node, self._show_item_menu(item)) if not silently: self.studio.new_action( Action(lambda _: self.remove_items([item], silently=True), lambda _: self.restore_items([item]))) return item
def setup_widget(self): self.level = 0 self.layout = None self.recent_layout_info = None self._properties = get_properties(self) self.set_name(self.id) self.node = None self.__on_context = None self.last_menu_position = (0, 0) MenuUtils.bind_context(self, self.__handle_context_menu, add='+')
def on_widget_add(self, widget: PseudoWidget, parent=None): if parent is None: node = self._tree.add_as_node(widget=widget) else: parent = parent.node node = parent.add_as_node(widget=widget) # let the designer render the menu for us MenuUtils.bind_all_context( node, lambda e: self.studio.designer.show_menu(e, widget) if self.studio.designer else None)
def __init__(self, canvas, tool, item=None, **kw): super(LinearController, self).__init__(canvas, tool, item, **kw) if item: self.highlight(item) self._link_context = MenuUtils.make_dynamic( (("command", "add point", icon( "add", 14, 14), self._add_point, {}), ), tool.studio, tool.studio.style) self._coord_context = MenuUtils.make_dynamic( (("command", "remove", icon( "close", 14, 14), self._remove_point, {}), ), tool.studio, tool.studio.style) self._active_link = None self._active_coord = None self._active_point = None
def __init__(self, canvas, controller, coord1, coord2): self.canvas = canvas self.controller = controller self._id = canvas.create_line( coord1.x, coord1.y, coord2.x, coord2.y, fill=self.controller.tool.studio.style.colors["accent"], tag=("link", "controller"), dash=(5, 4), width=2) self.link_coord(coord1, coord2) canvas.tag_bind(self._id, "<ButtonRelease-1>", self._end_drag) MenuUtils.bind_canvas_context(self.canvas, self._id, self._context_menu) canvas.tag_bind(self._id, "<Motion>", self._drag) self.active.add(self) self._coord_latch = None
def __init__(self, canvas, controller, x, y): self.radius = self.min_radius self.canvas = canvas self.controller = controller self.x = x self.y = y self._id = canvas.create_oval( x - self.radius, y - self.radius, x + self.radius, y + self.radius, fill=self.controller.tool.studio.style.colors["accent"], tags=("coordinate", "controller")) canvas.tag_bind(self._id, "<ButtonRelease-1>", self._end_drag) canvas.tag_bind(self._id, "<Motion>", self._drag) canvas.tag_bind(self._id, "<Enter>", lambda _: self.grow_effect()) canvas.tag_bind(self._id, "<Leave>", lambda _: self.grow_effect(True)) MenuUtils.bind_canvas_context(self.canvas, self._id, self._context_menu) self.active.add(self) self._listeners = []
def _attach(self, obj): # bind events for context menu and object selection # all widget additions call this method so clear empty message self._show_empty(False) MenuUtils.bind_all_context(obj, lambda e: self.show_menu(e, obj), add='+') obj.bind_all( '<Shift-ButtonPress-1>', lambda e: self.highlight.set_function(self.highlight.move, e), add='+') obj.bind_all('<Motion>', self.on_motion, '+') obj.bind_all('<ButtonRelease>', self.highlight.clear_resize, '+') if "text" in obj.keys(): obj.bind_all("<Double-Button-1>", lambda _: self._show_text_editor(obj)) self.objects.append(obj) if self.root_obj is None: self.root_obj = obj obj.bind_all("<Button-1>", lambda e: self._handle_select(obj, e), add='+') # bind shortcuts self._shortcut_mgr.bind_widget(obj)
def __init__(self, master, studio): super().__init__(master) self.id = None self.setup_widget() self.parent = self self.studio = studio self.config(**self.style.bright, takefocus=True) self.objects = [] self.root_obj = None self.layout_strategy = DesignLayoutStrategy(self) self.highlight = HighLight(self) self.highlight.on_resize(self._on_size_changed) self.highlight.on_move(self._on_move) self.highlight.on_release(self._on_release) self._update_throttling() self.studio.pref.add_listener( "designer::frame_skip", self._update_throttling ) self.current_obj = None self.current_container = None self.current_action = None self._frame.bind("<Button-1>", lambda *_: self.focus_set()) self._frame.bind('<Motion>', self.on_motion, '+') self._padding = 30 self.design_path = None self.xml = XMLForm(self) self._load_progress = None self._shortcut_mgr = KeyMap(self._frame) self._set_shortcuts() self._last_click_pos = None # create the dynamic menu self._context_menu = MenuUtils.make_dynamic( self.studio.menu_template + ToolManager.get_tool_menu(self.studio) + (LoadLater(lambda: self.current_obj.create_menu() if self.current_obj else ()),), self.studio, self.style ) self._coord_indicator = self.studio.install_status_widget(CoordinateIndicator) self._empty = Label( self, image=get_tk_image("paint", 30, 30), compound="top", text="Drag a container here to start", **self.style.dark_text_passive, ) self._empty.config(**self.style.bright) self._show_empty(True)
def show_menu(self, event, obj=None): # select object generating the context menu event first if obj is not None: self.select(obj) MenuUtils.popup(event, self._context_menu)
def __init__(self, master, studio): super().__init__(master) self.id = None self.context = master self.studio = studio self.name_generator = NameGenerator(self.studio.pref) self.setup_widget() self.parent = self self.config(**self.style.bright, takefocus=True) self.objects = [] self.root_obj = None self.layout_strategy = DesignLayoutStrategy(self) self.highlight = HighLight(self) self.highlight.on_resize(self._on_size_changed) self.highlight.on_move(self._on_move) self.highlight.on_release(self._on_release) self.highlight.on_start(self._on_start) self._update_throttling() self.studio.pref.add_listener("designer::frame_skip", self._update_throttling) self.current_obj = None self.current_container = None self.current_action = None self._displace_active = False self._last_displace = time.time() self._frame.bind("<Button-1>", lambda _: self.focus_set(), '+') self._frame.bind("<Button-1>", self.set_pos, '+') self._frame.bind('<Motion>', self.on_motion, '+') self._frame.bind('<KeyRelease>', self._stop_displace, '+') self._padding = 30 self.design_path = None self.builder = DesignBuilder(self) self._shortcut_mgr = KeyMap(self._frame) self._set_shortcuts() self._last_click_pos = None self._empty = Label( self, image=get_tk_image("paint", 30, 30), compound="top", text=" ", **self.style.text_passive, ) self._empty.config(**self.style.bright) self._show_empty(True) # create the dynamic menu self._context_menu = MenuUtils.make_dynamic( self.studio.menu_template + (LoadLater(self.studio.tool_manager.get_tool_menu), ) + (LoadLater(lambda: self.current_obj.create_menu() if self.current_obj else ()), ), self.studio, self.style) design_menu = (EnableIf( lambda: self.studio._clipboard is not None, ("command", "paste", icon("clipboard", 14, 14), lambda: self.paste(self.studio._clipboard, paste_to=self), {})), ) self.set_up_context(design_menu) self._empty.set_up_context(design_menu) if Designer._coord_indicator is None: Designer._coord_indicator = self.studio.install_status_widget( CoordinateIndicator) self._text_editor = Text(self, wrap='none') self._text_editor.on_change(self._text_change) self._text_editor.bind("<FocusOut>", self._text_hide) self._base_font = FontStyle()
def show(event): if item in self.selected_items: MenuUtils.popup(event, self._item_context_menu)
def __init__(self, studio, manager): super(CanvasTool, self).__init__(studio, manager) self._component_pane: ComponentPane = self.studio.get_feature( ComponentPane) self.item_select = self._component_pane.register_group( "Canvas", CANVAS_ITEMS, SelectToDrawGroup, self._evaluator) self.style_group = studio.style_pane.add_group(CanvasStyleGroup, tool=self) CanvasStudioAdapter._tool = self # connect the canvas adapter to load canvas objects to the studio DesignBuilder.add_adapter(CanvasStudioAdapter, Canvas) self.generator = NameGenerator(self.studio.pref) self.items = [] self.item_select.on_select(self.set_draw) self.canvas = None self._cursor = "arrow" self.current_draw = None self.selected_items = [] self._clipboard = None self._latch_pos = 0, 0 self._image_placeholder = icon("image_dark", 60, 60) self.square_draw = SquareDraw(self) self.line_draw = LinearDraw(self) self.text_draw = TextDraw(self) self.bitmap_draw = PointDraw(self, bitmap="gray25") self.image_draw = PointDraw(self, image=self._image_placeholder) self.draw_map = { Oval: self.square_draw, Rectangle: self.square_draw, Arc: self.square_draw, Line: self.line_draw, Polygon: self.line_draw, Text: self.text_draw, Bitmap: self.bitmap_draw, Image: self.image_draw, } self.controller_map = { Oval: SquareController, Rectangle: SquareController, Arc: SquareController, Line: LinearController, Polygon: ClosedLinearController, Text: PointController, Bitmap: PointController, Image: PointController, } self.keymap = KeyMap(None) CTRL = KeyMap.CTRL self.routines = ( Routine(self.cut_items, 'CV_CUT', 'Cut selected items', 'canvas', CTRL + CharKey('x')), Routine(self.copy_items, 'CV_COPY', 'Copy selected items', 'canvas', CTRL + CharKey('c')), Routine(self.paste_items, 'CV_PASTE', 'Paste selected items', 'canvas', CTRL + CharKey('v')), Routine(self.delete_items, 'CV_DELETE', 'Delete selected items', 'canvas', KeyMap.DELETE), Routine(self.duplicate_items, 'CV_DUPLICATE', 'Duplicate selected items', 'canvas', CTRL + CharKey('d')), Routine(self._send_back, 'CV_BACK', 'Send item to back', 'canvas', CharKey(']')), Routine(self._bring_front, 'CV_FRONT', 'Bring item to front', 'canvas', CharKey('[')), Routine(lambda: self._send_back(1), 'CV_BACK_1', 'send item back one step', 'canvas', CTRL + CharKey(']')), Routine(lambda: self._bring_front(1), 'CV_FRONT_1', 'bring item forward one step', 'canvas', CTRL + CharKey('[')), ) self.keymap.add_routines(*self.routines) self._item_context_menu = MenuUtils.make_dynamic((EnableIf( lambda: self.selected_items, ("separator", ), ("command", "copy", icon("copy", 14, 14), self._get_routine('CV_COPY'), {}), ("command", "duplicate", icon( "copy", 14, 14), self._get_routine('CV_DUPLICATE'), {}), EnableIf(lambda: self._clipboard is not None, ("command", "paste", icon("clipboard", 14, 14), self._get_routine('CV_PASTE'), {})), ("command", "cut", icon("cut", 14, 14), self._get_routine('CV_CUT'), {}), ("separator", ), ("command", "delete", icon( "delete", 14, 14), self._get_routine('CV_DELETE'), {}), ("separator", ), ("command", "send to back", icon( "send_to_back", 14, 14), self._get_routine('CV_BACK'), {}), ("command", "bring to front", icon( "bring_to_front", 14, 14), self._get_routine('CV_FRONT'), {}), ("command", "back one step", icon( "send_to_back", 14, 14), self._get_routine('CV_BACK_1'), {}), ("command", "forward one step", icon("bring_to_front", 14, 14), self._get_routine('CV_FRONT_1'), {}), ), ), self.studio, self.studio.style) self._canvas_menu = MenuUtils.make_dynamic( (EnableIf(lambda: self._clipboard is not None, ("command", "paste", icon("clipboard", 14, 14), self._get_routine('CV_PASTE'), {})), ), self.studio, self.studio.style)
def on_coord_context(self, coord, event): MenuUtils.popup(event, self._coord_context) self._active_coord = coord self._active_point = self.canvas.canvasx(event.x), self.canvas.canvasy( event.y)
def on_link_context(self, link, event): MenuUtils.popup(event, self._link_context) self._active_link = link self._active_point = self.canvas.canvasx(event.x), self.canvas.canvasy( event.y)
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()
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
def show(event): x, y = canvas.canvasx(event.x), canvas.canvasy(event.y) self._latch_pos = x, y if not canvas.find_overlapping(x, y, x, y): MenuUtils.popup(event, self._canvas_menu) return 'break'