Skip to content

Commit

Permalink
Improve support when specifying a pre-existing toolbar as the target …
Browse files Browse the repository at this point in the history
…for the restore icon when minimizing a pane in agw.aui
  • Loading branch information
jmoraleda committed Dec 8, 2023
1 parent 87674de commit dcf76cb
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 25 deletions.
40 changes: 27 additions & 13 deletions wx/lib/agw/aui/auibar.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,9 @@ class AuiToolBarItem(object):
"""
AuiToolBarItem is a toolbar element.
It has a unique id (except for the separators which always have id = -1), the
style (telling whether it is a normal button, separator or a control), the
It has a unique id (except for the separators which always have id = -1 and the
automatically added restore-from-minimize which always have id = ID_RESTORE_FRAME),
the style (telling whether it is a normal button, separator or a control), the
state (toggled or not, enabled or not) and short and long help strings. The
default implementations use the short help string for the tooltip text which
is popped up when the mouse pointer enters the tool and the long help string
Expand Down Expand Up @@ -2035,26 +2036,26 @@ def ClearTools(self):
self.Clear()


def DeleteTool(self, tool_id):
def DeleteTool(self, tool):
"""
Removes the specified tool from the toolbar and deletes it.
:param integer `tool_id`: the :class:`AuiToolBarItem` identifier.
:param `tool`: the :class:`AuiToolBarItem` or its integer identifier.
:returns: ``True`` if the tool was deleted, ``False`` otherwise.
:note: Note that it is unnecessary to call :meth:`Realize` for the change to
take place, it will happen immediately.
"""

idx = self.GetToolIndex(tool_id)

if idx >= 0 and idx < len(self._items):
self._items.pop(idx)
self.Realize()
return True

return False
if isinstance(tool, AuiToolBarItem):
try:
self._items.remove(tool)
self.Realize()
return True
except ValueError:
return False
# Assume tool is the id of the tool to be removed
return self.DeleteToolByPos(self.GetToolIndex(tool))


def DeleteToolByPos(self, pos):
Expand Down Expand Up @@ -2114,6 +2115,19 @@ def FindToolByLabel(self, label):
return None


def FindToolByUserData(self, userData):
"""
Finds a tool for the given client id.
:param PyObject `userData`: the user data object.
"""

for item in self._items:
if item.user_data == userData:
return item

return None

def FindToolForPosition(self, x, y):
"""
Finds a tool for the given mouse position.
Expand Down
76 changes: 64 additions & 12 deletions wx/lib/agw/aui/framemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -4779,6 +4779,11 @@ def DetachPane(self, window):
id = notebook.GetPageIndex(p.window)
notebook.RemovePage(id)
p.window.Reparent(self._frame)

elif p.IsMinimized():
# if we were minimized, restore so any restore icons in toolbars are removed
self.RestoreMinimizedPane(p)


# make sure there are no references to this pane in our uiparts,
# just in case the caller doesn't call Update() immediately after
Expand Down Expand Up @@ -4808,6 +4813,11 @@ def ClosePane(self, pane_info):
# if we were maximized, restore
if pane_info.IsMaximized():
self.RestorePane(pane_info)

# if we were minimized, restore so any restore icons in toolbars are removed
if pane_info.IsMinimized():
self.RestoreMinimizedPane(pane_info)


if pane_info.frame:
if self._agwFlags & AUI_MGR_ANIMATE_FRAMES:
Expand Down Expand Up @@ -5073,6 +5083,9 @@ def SavePaneInfo(self, pane):

result = "name=" + EscapeDelimiters(pane.name) + ";"
result += "caption=" + EscapeDelimiters(pane.caption) + ";"
if pane.minimize_target:
result += "minitarget=" + EscapeDelimiters(pane.minimize_target) + ";"
result += "minimode=%u;" % pane.minimize_mode

result += "state=%u;" % pane.state
result += "dir=%d;" % pane.dock_direction
Expand Down Expand Up @@ -5120,6 +5133,10 @@ def LoadPaneInfo(self, pane_part, pane):
pane.name = value
elif val_name == "caption":
pane.caption = value
elif val_name == "minitarget":
pane.minimize_target = value
elif val_name == "minimode":
pane.minimize_mode = int(value)
elif val_name == "state":
pane.state = int(value)
elif val_name == "dir":
Expand Down Expand Up @@ -5196,7 +5213,8 @@ def SavePerspective(self):
dock.size)
return result

def LoadPerspective(self, layout, update=True, restorecaption=False):
def LoadPerspective(self, layout, update=True, restorecaption=False,
restoreminimize=False):
"""
Loads a layout which was saved with :meth:`SavePerspective`.
Expand All @@ -5207,6 +5225,8 @@ def LoadPerspective(self, layout, update=True, restorecaption=False):
:param bool `update`: whether to update immediately the window or not;
:param bool `restorecaption`: ``False``, restore from persist storage,
otherwise use the caption defined in code.
:param bool `restoreminimize`: ``False``, restore from persist storage,
otherwise use the minimize_toolbar and minimize_mode defined in code.
"""

input = layout
Expand All @@ -5224,6 +5244,7 @@ def LoadPerspective(self, layout, update=True, restorecaption=False):
# mark all panes currently managed as docked and hidden
saveCapt = {} # see restorecaption param
saveIcon = {} # icons are not preserved by perspectives, so preserve them
saveMinimize = {} # see restoreminimize param
for pane in self._panes:

# dock the notebook pages
Expand All @@ -5239,6 +5260,7 @@ def LoadPerspective(self, layout, update=True, restorecaption=False):
pane.Dock().Hide()
saveCapt[pane.name] = pane.caption
saveIcon[pane.name] = pane.icon
saveMinimize[pane.name] = pane.minimize_target, pane.minimize_mode

# clear out the dock array; this will be reconstructed
self._docks = []
Expand Down Expand Up @@ -5299,6 +5321,10 @@ def LoadPerspective(self, layout, update=True, restorecaption=False):
# restore icons from code. This is always done. Since icons are not saved in perspectives
if pane.name in saveIcon:
pane.icon = saveIcon[pane.name]
# restore minimize parameters from code
if restoreminimize:
if pane.name in saveMinimize:
pane.minimize_target, pane.minimize_mode = saveMinimize[pane.name]

if not p.IsOk():
if pane.IsNotebookControl():
Expand All @@ -5320,10 +5346,29 @@ def LoadPerspective(self, layout, update=True, restorecaption=False):
if isinstance(pane.window, auibar.AuiToolBar) and (pane.IsFloatable() or pane.IsDockable()):
pane.window.SetGripperVisible(True)

for p in self._panes:
if p.IsMinimized():
self.MinimizePane(p, False)

inexistentPaneIndexes = []
for paneIndex, p in enumerate(self._panes):
if p.window:
if p.IsMinimized():
self.MinimizePane(p, False)
elif p.minimize_mode & AUI_MINIMIZE_POS_MASK == AUI_MINIMIZE_POS_TOOLBAR:
# If the pane specifies a minimize toolbar, which would be preserved by the loading
# operation rather than using an automatic toolbar which would not be preserved) then
# if pane was minimized before we loaded perspective but the new perspective unminimized
# it then its minimize-from-restore icon is still in the toolbar and must be removed
minimizeToolbar = self.GetPane(p.minimize_target).window
item = minimizeToolbar.FindToolByUserData((ID_RESTORE_FRAME, p.window))
if item: # Delete the icon if it was there
minimizeToolbar.DeleteTool(item)
else:
# The perspective is referencing a non-existing pane that was added nonetheless. This will
# happen with a notebook that ends up containing no pages
inexistentPaneIndexes.append(paneIndex)

for paneIndex in reversed(inexistentPaneIndexes): # reverse is required when deleting elements by index
del self._panes[index]


if update:
self.Update()

Expand Down Expand Up @@ -9863,13 +9908,20 @@ def MinimizePane(self, paneInfo, mgrUpdate=True):
restore_bitmap = img.ConvertToBitmap()

target = None
restoreToolAlreadyInToolbar = False
if posMask == AUI_MINIMIZE_POS_TOOLBAR:
target = paneInfo.name

minimize_toolbar.AddSimpleTool(ID_RESTORE_FRAME, paneInfo.caption, restore_bitmap,
_(six.u("Restore %s")) % paneInfo.caption, target=target)
minimize_toolbar.SetAuiManager(self)
minimize_toolbar.Realize()
if paneInfo.IsMinimized() and minimize_toolbar.FindToolByUserData((ID_RESTORE_FRAME, paneInfo.window)):
# We are loading a perspective. If the perspective contains the minimize_toolbar,
# then the restore tool for this pane is already in it and we should not add it again
restoreToolAlreadyInToolbar = True

if not restoreToolAlreadyInToolbar:
tool = minimize_toolbar.AddSimpleTool(ID_RESTORE_FRAME, paneInfo.caption, restore_bitmap,
_(six.u("Restore %s")) % paneInfo.caption, target=target)
tool.SetUserData((ID_RESTORE_FRAME, paneInfo.window))
minimize_toolbar.SetAuiManager(self)
minimize_toolbar.Realize()
toolpanelname = paneInfo.name + "_min"

if paneInfo.IsMaximized():
Expand Down Expand Up @@ -10031,8 +10083,8 @@ def RestoreMinimizedPane(self, paneInfo):
targetName = pane.minimize_target
toolbarPane = self.GetPane(targetName)
toolbar = toolbarPane.window
item = toolbar.FindToolByLabel(pane.caption)
toolbar.DeleteTool(item.id)
item = toolbar.FindToolByUserData((ID_RESTORE_FRAME, pane.window))
toolbar.DeleteTool(item)
else:
paneInfo.window.Show(False)
self.DetachPane(paneInfo.window)
Expand Down

0 comments on commit dcf76cb

Please sign in to comment.