def on_drop_widget(self, event, reset=None): """replaces self with a widget in self.sizer. This method is called to add every non-toplevel widget or sizer, and in turn calls the appropriate builder function (found in the ``common.widgets'' dict)""" if not common.adding_widget: # widget focused/selecte misc.set_focused_widget(self) if self.widget: self.widget.Refresh() self.widget.SetFocus() return if common.adding_sizer and self.parent.CHILDREN is not 1 and not self.IS_SLOT: return if self.widget: self.widget.SetCursor(wx.NullCursor) common.adding_window = event and event.GetEventObject( ).GetTopLevelParent() or None # call the appropriate builder new_widget = common.widgets[common.widget_to_add](self.parent, self.pos) if new_widget is None: return misc.rebuild_tree(new_widget) if reset is False: return if event is None or not misc.event_modifier_copy(event): common.adding_widget = common.adding_sizer = False common.widget_to_add = None
def undo(self): path = self.slot_path or self.path.rsplit("/", 1)[0] # slot or parent widget = common.root.find_widget_from_path(path) if widget.IS_ROOT: # or widget.IS_CONTAINER: widget.clipboard_paste(self.xml_data, self.index) elif self.IS_SLOT: widget.insert_item(None, self.index) # placeholder if self.slot_tab is not None: tabs_p = widget.properties["tabs"] tabs_p.value.insert(self.index, [self.slot_tab]) tabs_p.reset() if widget.IS_SIZER: from edit_sizers import SizerSlot as Slot else: from edit_base import Slot slot = Slot(widget, index=self.index) if widget.widget: slot.create_widget() widget.child_widget_created(slot, 0) # update structure misc.rebuild_tree(widget, focus=False) # update following slots for c in widget.children[self.index + 1:]: if c.IS_SLOT: common.app_tree.refresh(c) misc.set_focused_widget(slot) else: widget.clipboard_paste(self.xml_data)
def on_drop_widget(self, event, reset=None): """replaces self with a widget. This method is called to add every non-toplevel widget or sizer, and in turn calls the appropriate builder function (found in the 'common.widgets' dict).""" if not common.adding_widget: # widget focused/selected misc.set_focused_widget(self) if self.widget: self.widget.Refresh() self.widget.SetFocus() return if not self.check_drop_compatibility()[0]: return if self.widget: self.widget.SetCursor(wx.NullCursor) common.adding_window = event and event.GetEventObject( ).GetTopLevelParent() or None # call the appropriate builder new_widget = common.widgets[common.widget_to_add](self.parent, self.index) if new_widget is None: return misc.rebuild_tree(new_widget) if reset is False: return if event is None or not misc.event_modifier_copy(event): common.adding_widget = common.adding_sizer = False common.widget_to_add = None if event is not None and new_widget.widget: # set focus; required mainly on macOS to receive keys widget = None if new_widget.IS_WINDOW: widget = new_widget.widget elif new_widget.IS_SIZER: widget = new_widget.toplevel_parent_window.widget if hasattr(widget, "SetFocus"): widget.SetFocus() common.history.widget_added(new_widget)
def undo(self): # identical to HistoryAddedItem.redo, except for the slot_tab part path = self.slot_path or self.path.rsplit("/", 1)[0] # slot or parent widget = common.root.find_widget_from_path(path) if widget is None: # something was pasted/added to e.g. a panel which had a slot as child parent_path, leaf = path.rsplit("/", 1) assert leaf.startswith('SLOT ') widget = common.root.find_widget_from_path(parent_path) if widget.IS_ROOT: # or widget.IS_CONTAINER: widget.clipboard_paste(self.xml_data, self.index) elif self.IS_SLOT: widget.insert_item(None, self.index) # placeholder if self.slot_tab is not None: tabs_p = widget.properties["tabs"] tabs_p.value.insert(self.index, [self.slot_tab]) tabs_p.reset() if widget.IS_SIZER: from edit_sizers import SizerSlot as Slot else: from edit_base import Slot slot = Slot(widget, index=self.index) if widget.widget: slot.create_widget() widget.child_widget_created(slot, 0) # update structure misc.rebuild_tree(widget, focus=False) # update following slots for c in widget.children[self.index + 1:]: if c.IS_SLOT: common.app_tree.refresh(c) misc.set_focused_widget(slot) else: widget.clipboard_paste(self.xml_data)
def remove(self, *args): # entry point from GUI common.root.saved = False # update the status of the app # remove is called from the context menus; for other uses, delete is applicable self._dont_destroy = False # always destroy when explicitly asked self.recursive_remove() misc.rebuild_tree(self.parent, recursive=False, focus=True)
def insert_tab(self, index, label, add_panel=True, add_sizer=False): # add tab/page; called from GUI self.properties["tabs"].insert(index, [ label, ]) # create panel and node, add to tree self.insert_item(None, index) # placeholder if add_panel: if not isinstance(add_panel, compat.unicode): add_panel = self.next_pane_name() editor = panel.EditPanel(add_panel, self, index) if add_sizer: sizer = edit_sizers._builder(editor, 0) else: # just add a slot editor = edit_base.Slot(self, index) if self.widget: # add to widget editor.create() compat.SetToolTip(editor.widget, _("Notebook page pane:\nAdd a sizer here")) self.vs_insert_tab(index) try: wx.CallAfter(editor.sel_marker.update) except AttributeError: #self._logger.exception(_('Internal Error')) if config.debugging: raise self.widget.SetSelection(index) self.properties["tabs"].update_display() misc.rebuild_tree(self)
def remove(self, focus=True, user=True): # entry point from GUI or script if user: common.history.widget_removing(self) common.root.saved = False # update the status of the app self.recursive_remove(level=0) misc.rebuild_tree(self.parent, recursive=False, focus=focus) if user: common.history.widget_removed(None)
def add_toplevel_object(event): "Adds a toplevel widget (Frame or Dialog) to the current app" palette.reset_togglebuttons() editor = widgets[refs[event.GetId()]](root, 0) if editor is None: return history.widget_adding(root) history.widget_added(editor) misc.rebuild_tree(widget=editor, recursive=editor.children, focus=True)
def redo(self): sizer = common.root.find_widget_from_path(self.path) with sizer.window.frozen(): for n in range(self.count): if self.index == -1: sizer._add_slot() else: sizer._insert_slot(self.index + n) if sizer.widget: sizer.layout() misc.rebuild_tree(sizer, recursive=False, focus=False)
def drop_sizer(self, event=None, reset=None): if self.children or not common.adding_sizer: self.on_set_focus(event) # default behaviour: call show_properties return if self.widget: self.widget.SetCursor(wx.NullCursor) new_widget = common.widgets[common.widget_to_add](self, None) if new_widget is None: return misc.rebuild_tree(new_widget) if reset is False: return if event is None or not misc.event_modifier_copy(event): common.adding_widget = common.adding_sizer = False common.widget_to_add = None
def on_value_edited(self, new_value, active=None): # user has clicked the checkbox # the main modification to np.Property.on_value_edited is that it does not store the modification in the history if active is not None: self.deactivated = not active # create or remove the bar: if new_value: bar = common.widgets["Edit"+self.widget_name](self.owner, self.widget_index, True) else: bar = getattr(self.owner, self.widget_index).remove() setattr(self.owner, self.widget_index, bar) misc.rebuild_tree(widget=self.owner, recursive=False, focus=True) self.set(new_value) self._notify()
def remove(self): # entry point from GUI common.root.saved = False # update the status of the app if self.parent.WX_CLASS in ("wxNotebook", ): self.parent.remove_tab(self.pos) return # set focused widget i = self.pos self._remove() if i >= len(self.parent.children): i = len(self.parent.children) - 1 misc.rebuild_tree(self.parent, recursive=False, focus=False) if i >= 0: misc.set_focused_widget(self.parent.children[i]) else: misc.set_focused_widget(self.parent)
def properties_changed(self, modified): if not modified or "icon" in modified and self.widget: self._set_widget_icon() if not modified or "menubar" in modified: self._set_menu_bar() if not modified or "statusbar" in modified: self._set_status_bar() if not modified or "toolbar" in modified: self._set_tool_bar() if modified: intersection = {"menubar", "statusbar", "toolbar"}.intersection(modified) if intersection and self.properties[ intersection.pop()].previous_value is not None: # previous value is not None -> triggered by user misc.rebuild_tree(widget=self, recursive=False, focus=False) TopLevelBase.properties_changed(self, modified) EditStylesMixin.properties_changed(self, modified)
def _paste(parent, pos, clipboard_data): "parse XML and insert widget" option, span, flag, border, xml_unicode = clipboard2widget( clipboard_data ) if not xml_unicode: return False import xml_parse try: wx.BeginBusyCursor() # widget representation is still unicode, but parser need UTF8 xml_utf8 = xml_unicode.encode('utf8') parser = xml_parse.ClipboardXmlWidgetBuilder(parent, pos, option, span, flag, border) with parent and parent.frozen() or misc.dummy_contextmanager(): parser.parse_string(xml_utf8) if parent and hasattr(parent, "on_child_pasted"): parent.on_child_pasted() # trigger e.g. re-sizing of the children misc.rebuild_tree( parser.top_obj ) return True # Widget hierarchy pasted. except xml_parse.XmlParsingError: if config.debugging: raise return False finally: wx.EndBusyCursor()
def _paste(parent, index, clipboard_data, rebuild_tree=True): "parse XML and insert widget" option, span, flag, border, xml_unicode = clipboard2widget( clipboard_data ) if not xml_unicode: return None import xml_parse try: wx.BeginBusyCursor() # widget representation is still unicode, but parser need UTF8 xml_utf8 = xml_unicode.encode('utf8') parser = xml_parse.ClipboardXmlWidgetBuilder(parent, index, option, span, flag, border) with parent and parent.frozen() or misc.dummy_contextmanager(): parser.parse_string(xml_utf8) if parent and hasattr(parent, "on_child_pasted"): parent.on_child_pasted() # trigger e.g. re-sizing of the children freeze = parser._object_counter>80 # for more objects, we freeze the Tree during re-build if rebuild_tree: misc.rebuild_tree( parser.top_obj, freeze=freeze ) return parser.top_obj # Widget hierarchy pasted. except xml_parse.XmlParsingError: if config.debugging: raise return None finally: wx.EndBusyCursor()
def OnData(self, x,y,default): compatible, message = self._check_compatibility(x,y) if not compatible: return wx.DragCancel # workaround for wxPython 4.1 if default == wx.DragNone and hasattr(self, "_last_on_drag_over"): default = self._last_on_drag_over copy = (default==wx.DragCopy) src_widget = None dst_widget = self.window.find_editor_by_pos(x,y) if _current_drag_source: src_widget = _current_drag_source # was set in begin_drag if not copy and _current_drag_source is misc.focused_widget: if hasattr(_current_drag_source, "parent"): misc.set_focused_widget(_current_drag_source.parent) elif hasattr(_current_drag_source, "window"): # a sizer misc.set_focused_widget(_current_drag_source.window) if compatible=="AddSlot": # dropped on a sizer -> add slot dst_widget._add_slot() dst_widget.layout() dst_widget = dst_widget.children[-1] # the slot elif compatible=="Slot": # insert a slot or fill empty slot index = dst_widget.index dst_widget.sizer._insert_slot(index) dst_widget = dst_widget.sizer.children[index] # the slot elif compatible=="Reorder": # a toplevel dragged onto another toplevel # internal drag: just re-order; external drag: paste before src_index = common.root.children.index(src_widget) dst_index = common.root.children.index(dst_widget) common.root.children.insert(dst_index, src_widget) if src_index>dst_index: del common.root.children[src_index+1] else: del common.root.children[src_index] common.app_tree.SortChildren(common.root.item) # this does sort one level only return default fmt = self._get_received_format() self.fmt = None # non-wxglade file dropped ##################################################################################### if fmt=="file.bitmap": bitmap = self.file_data_object.GetFilenames()[0] if not os.path.isfile(bitmap): return wx.DragCancel if dst_widget.IS_SLOT: # fill slot with a StaticBitmap import widgets.static_bitmap.static_bitmap new_widget = widgets.static_bitmap.static_bitmap.builder(dst_widget.parent, dst_widget.index, bitmap) misc.rebuild_tree(new_widget) return default # set attribute value dst_widget.set_attribute(fmt, bitmap) return default # use cut and paste functionality from clipboard to do the actual work ######################################### if not hasattr(dst_widget, "clipboard_paste"): return wx.DragCancel data = self.data_objects[fmt].GetData() # the data as string self.fmt = None if wx.Platform=="__WXMAC__": # delay action, as otherwise there will be a segmentation fault; 50ms were too short sometimes wx.CallLater(100, self._OnData, _current_drag_source, src_widget, dst_widget, data, copy) else: wx.CallAfter(self._OnData, _current_drag_source, src_widget, dst_widget, data, copy) return default
def free_slot(self, pos, force_layout=True): "Replaces the element at pos with an empty slot" # called from ManagedBase context menu when removing an item slot = self._free_slot(pos, force_layout) misc.rebuild_tree(slot)
def remove(self, focus=True): # entry point from GUI or script common.root.saved = False # update the status of the app self.recursive_remove(level=0) misc.rebuild_tree(self.parent, recursive=False, focus=focus)
def insert_tab(self, index, label): # add tab/page; called from GUI tab = self._insert_tab(index, label) misc.rebuild_tree(self)