mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-06 20:10:08 +01:00
Merge branch 'tianzhuqiao-agw_aui_4.0.x' into wxPy-4.0.x
(cherry picked from commit dcf0b99068)
This commit is contained in:
@@ -53,7 +53,10 @@ Changes in this release include the following:
|
||||
on Python3
|
||||
|
||||
* Added a dependency on the Pillow package since it's used in some wx.lib.agw
|
||||
modules. (#908)
|
||||
modules. (PR #908)
|
||||
|
||||
* Add flag to hide page in wx.lib.agw.aui.notebook. (#895)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -90,6 +93,7 @@ Changes in this release include the following:
|
||||
|
||||
|
||||
|
||||
|
||||
4.0.2 "Cute as a June bug!"
|
||||
---------------------------
|
||||
* 16-June-2018
|
||||
|
||||
@@ -340,6 +340,7 @@ class AuiNotebookPage(object):
|
||||
self.rect = wx.Rect() # tab's hit rectangle
|
||||
self.active = False # True if the page is currently active
|
||||
self.enabled = True # True if the page is currently enabled
|
||||
self.hidden = False # true if the page is currently hidden
|
||||
self.hasCloseButton = True # True if the page has a close button using the style
|
||||
# AUI_NB_CLOSE_ON_ALL_TABS
|
||||
self.control = None # A control can now be inside a tab
|
||||
@@ -1129,9 +1130,12 @@ class AuiTabContainer(object):
|
||||
if page.window == wnd:
|
||||
page.active = True
|
||||
found = True
|
||||
page.hidden = False
|
||||
else:
|
||||
page.active = False
|
||||
|
||||
self.DoShowHide()
|
||||
|
||||
return found
|
||||
|
||||
|
||||
@@ -1203,6 +1207,41 @@ class AuiTabContainer(object):
|
||||
|
||||
return len(self._pages)
|
||||
|
||||
def GetShownPageCount(self):
|
||||
""" Returns the number of pages shown in the :class:`AuiTabContainer`. """
|
||||
cnt = 0
|
||||
for page in self._pages:
|
||||
if not page.hidden:
|
||||
cnt += 1
|
||||
return cnt
|
||||
|
||||
def GetHidden(self, idx):
|
||||
"""
|
||||
Returns whether a tab is hidden or not.
|
||||
|
||||
:param integer `idx`: the tab index.
|
||||
"""
|
||||
|
||||
if idx < 0 or idx >= len(self._pages):
|
||||
return False
|
||||
|
||||
return self._pages[idx].hidden
|
||||
|
||||
def HideTab(self, idx, hidden=True):
|
||||
"""
|
||||
hides/shows a tab in the :class:`AuiTabContainer`.
|
||||
|
||||
:param integer `idx`: the tab index;
|
||||
:param bool `hidden`: ``True`` to hide a tab, ``False`` to show it.
|
||||
"""
|
||||
|
||||
if idx < 0 or idx >= len(self._pages):
|
||||
raise Exception("Invalid Page index")
|
||||
|
||||
self._pages[idx].hidden = hidden
|
||||
if hidden:
|
||||
wnd = self.GetWindowFromIdx(idx)
|
||||
wnd.Show(False)
|
||||
|
||||
def GetEnabled(self, idx):
|
||||
"""
|
||||
@@ -1232,6 +1271,25 @@ class AuiTabContainer(object):
|
||||
wnd = self.GetWindowFromIdx(idx)
|
||||
wnd.Enable(enable)
|
||||
|
||||
def FindNextActiveTab(self, idx):
|
||||
"""
|
||||
Finds the next active tab in the :class:`AuiTabContainer`.
|
||||
|
||||
:param integer `idx`: the index of the first (most obvious) tab to check for active status;
|
||||
"""
|
||||
|
||||
if self.GetEnabled(idx) and not self.GetHidden(idx):
|
||||
return idx
|
||||
|
||||
for indx in range(idx+1, self.GetPageCount()):
|
||||
if self.GetEnabled(indx) and not self.GetHidden(indx):
|
||||
return indx
|
||||
|
||||
for indx in range(idx-1, -1, -1):
|
||||
if self.GetEnabled(indx) and not self.GetHidden(indx):
|
||||
return indx
|
||||
|
||||
return 0
|
||||
|
||||
def AddButton(self, id, location, normal_bitmap=wx.NullBitmap, disabled_bitmap=wx.NullBitmap, name=""):
|
||||
"""
|
||||
@@ -1371,6 +1429,9 @@ class AuiTabContainer(object):
|
||||
for i in range(page_count):
|
||||
page = self._pages[i]
|
||||
|
||||
if page.hidden:
|
||||
continue
|
||||
|
||||
# determine if a close button is on this tab
|
||||
close_button = False
|
||||
if (self._agwFlags & AUI_NB_CLOSE_ON_ALL_TABS and page.hasCloseButton) or \
|
||||
@@ -1537,6 +1598,10 @@ class AuiTabContainer(object):
|
||||
for i in range(self._tab_offset, page_count):
|
||||
|
||||
page = self._pages[i]
|
||||
|
||||
if page.hidden:
|
||||
continue
|
||||
|
||||
tab_button = self._tab_close_buttons[i]
|
||||
|
||||
# determine if a close button is on this tab
|
||||
@@ -1676,6 +1741,10 @@ class AuiTabContainer(object):
|
||||
for i in range(tabOffset, page_count):
|
||||
|
||||
page = self._pages[i]
|
||||
|
||||
if page.hidden:
|
||||
continue
|
||||
|
||||
tab_button = self._tab_close_buttons[i]
|
||||
|
||||
rect.x = offset
|
||||
@@ -1738,6 +1807,10 @@ class AuiTabContainer(object):
|
||||
|
||||
for i in range(self._tab_offset, len(self._pages)):
|
||||
page = self._pages[i]
|
||||
|
||||
if page.hidden:
|
||||
continue
|
||||
|
||||
if page.rect.Contains((x,y)):
|
||||
return page.window
|
||||
|
||||
@@ -2420,15 +2493,21 @@ class AuiTabCtrl(wx.Control, AuiTabContainer):
|
||||
|
||||
if button == AUI_BUTTON_LEFT or button == AUI_BUTTON_RIGHT:
|
||||
if button == AUI_BUTTON_LEFT:
|
||||
if self.GetTabOffset() > 0:
|
||||
|
||||
self.SetTabOffset(self.GetTabOffset()-1)
|
||||
self.Refresh()
|
||||
self.Update()
|
||||
for i in range(self.GetTabOffset()-1, -1, -1):
|
||||
page = self._pages[i]
|
||||
if not page.hidden:
|
||||
self.SetTabOffset(i)
|
||||
self.Refresh()
|
||||
self.Update()
|
||||
break
|
||||
else:
|
||||
self.SetTabOffset(self.GetTabOffset()+1)
|
||||
self.Refresh()
|
||||
self.Update()
|
||||
for i in range(self.GetTabOffset()+1, self.GetPageCount()):
|
||||
page = self._pages[i]
|
||||
if not page.hidden:
|
||||
self.SetTabOffset(i)
|
||||
self.Refresh()
|
||||
self.Update()
|
||||
break
|
||||
|
||||
elif button == AUI_BUTTON_WINDOWLIST:
|
||||
idx = self.GetArtProvider().ShowDropDown(self, self._pages, self.GetActivePage())
|
||||
@@ -3561,13 +3640,50 @@ class AuiNotebook(wx.Panel):
|
||||
:see: :meth:`DeletePage`
|
||||
"""
|
||||
|
||||
# save active window pointer
|
||||
if not self.HidePage(page_idx):
|
||||
return False
|
||||
|
||||
active_wnd = None
|
||||
if self._curpage >= 0:
|
||||
active_wnd = self._tabs.GetWindowFromIdx(self._curpage)
|
||||
|
||||
# save pointer of window being deleted
|
||||
wnd = self._tabs.GetWindowFromIdx(page_idx)
|
||||
|
||||
# make sure we found the page
|
||||
if not wnd:
|
||||
return False
|
||||
|
||||
# find out which onscreen tab ctrl owns this tab
|
||||
ctrl, ctrl_idx = self.FindTab(wnd)
|
||||
if not ctrl:
|
||||
return False
|
||||
|
||||
# remove the tab from main catalog
|
||||
if not self._tabs.RemovePage(wnd):
|
||||
return False
|
||||
|
||||
# remove the tab from the onscreen tab ctrl
|
||||
ctrl.RemovePage(wnd)
|
||||
|
||||
self.RemoveEmptyTabFrames()
|
||||
|
||||
# set the active window since its index may be changed
|
||||
if active_wnd and not self.IsBeingDeleted():
|
||||
self.SetSelectionToWindow(active_wnd)
|
||||
|
||||
return True
|
||||
|
||||
def HidePage(self, page_idx, hidden=True):
|
||||
"""
|
||||
Sets whether a page is hidden.
|
||||
|
||||
:param integer `page_idx`: the page index;
|
||||
:param bool `hidden`: ``True`` to hide the page, ``False`` to show it.
|
||||
"""
|
||||
|
||||
# save pointer of window being hidden
|
||||
wnd = self._tabs.GetWindowFromIdx(page_idx)
|
||||
new_active = None
|
||||
|
||||
# make sure we found the page
|
||||
@@ -3583,84 +3699,72 @@ class AuiNotebook(wx.Panel):
|
||||
is_curpage = (self._curpage == page_idx)
|
||||
is_active_in_split = currentPage.active
|
||||
|
||||
# remove the tab from main catalog
|
||||
if not self._tabs.RemovePage(wnd):
|
||||
return False
|
||||
# hide the tab from main catalog
|
||||
self._tabs.HideTab(page_idx, hidden)
|
||||
|
||||
# remove the tab from the onscreen tab ctrl
|
||||
ctrl.RemovePage(wnd)
|
||||
|
||||
if is_active_in_split:
|
||||
|
||||
ctrl_new_page_count = ctrl.GetPageCount()
|
||||
|
||||
if ctrl_idx >= ctrl_new_page_count:
|
||||
ctrl_idx = ctrl_new_page_count - 1
|
||||
|
||||
if ctrl_idx >= 0 and ctrl_idx < ctrl.GetPageCount():
|
||||
|
||||
ctrl_idx = self.FindNextActiveTab(ctrl_idx, ctrl)
|
||||
|
||||
# set new page as active in the tab split
|
||||
ctrl.SetActivePage(ctrl_idx)
|
||||
|
||||
# if the page deleted was the current page for the
|
||||
# entire tab control, then record the window
|
||||
# pointer of the new active page for activation
|
||||
if is_curpage:
|
||||
new_active = ctrl.GetWindowFromIdx(ctrl_idx)
|
||||
# hide the tab from the onscreen tab ctrl
|
||||
ctrl.HideTab(ctrl_idx, hidden)
|
||||
|
||||
# hide the tab ctrl if there is no shown tab.
|
||||
if ctrl.GetShownPageCount() == 0:
|
||||
self._mgr.ShowPane(self.GetTabFrameFromTabCtrl(ctrl), False)
|
||||
ctrl.Show(False)
|
||||
else:
|
||||
self._mgr.ShowPane(self.GetTabFrameFromTabCtrl(ctrl), True)
|
||||
ctrl.Show(True)
|
||||
|
||||
# we are not deleting the active page, so keep it the same
|
||||
new_active = active_wnd
|
||||
if hidden:
|
||||
|
||||
if not new_active:
|
||||
if is_active_in_split:
|
||||
if ctrl.GetShownPageCount() > 0:
|
||||
|
||||
# we haven't yet found a new page to active,
|
||||
# so select the next page from the main tab
|
||||
# catalogue
|
||||
ctrl_idx = ctrl.FindNextActiveTab(ctrl_idx)
|
||||
|
||||
if 0 <= page_idx < self._tabs.GetPageCount():
|
||||
new_active = self._tabs.GetPage(page_idx).window
|
||||
if not new_active and self._tabs.GetPageCount() > 0:
|
||||
new_active = self._tabs.GetPage(0).window
|
||||
# set new page as active in the tab split
|
||||
ctrl.SetActivePage(ctrl_idx)
|
||||
|
||||
self.RemoveEmptyTabFrames()
|
||||
# if the page hidden was the current page for the
|
||||
# entire tab control, then record the window
|
||||
# pointer of the new active page for activation
|
||||
if is_curpage:
|
||||
new_active = ctrl.GetWindowFromIdx(ctrl_idx)
|
||||
else:
|
||||
ctrl.SetNoneActive()
|
||||
|
||||
# set new active pane
|
||||
if new_active:
|
||||
if not self.IsBeingDeleted():
|
||||
self._curpage = -1
|
||||
self.SetSelectionToWindow(new_active)
|
||||
if is_curpage:
|
||||
if not new_active and self.GetShownPageCount() > 0:
|
||||
idx = self.FindNextActiveTab(page_idx)
|
||||
new_active = self.GetPage(idx)
|
||||
|
||||
# set new active pane
|
||||
if new_active:
|
||||
self.SetSelectionToWindow(new_active)
|
||||
else:
|
||||
# no shown page
|
||||
self._curpage = -1
|
||||
self._tabs.SetNoneActive()
|
||||
else:
|
||||
self._curpage = -1
|
||||
self._tabs.SetNoneActive()
|
||||
if ctrl.GetActivePage() < 0:
|
||||
# no active page on tab ctrl, set it to wnd
|
||||
ctrl.SetActivePage(wnd)
|
||||
|
||||
if self._curpage < 0:
|
||||
# no current page, set it to wnd
|
||||
self.SetSelectionToWindow(wnd)
|
||||
|
||||
self.Refresh()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def FindNextActiveTab(self, ctrl_idx, ctrl):
|
||||
def FindNextActiveTab(self, idx):
|
||||
"""
|
||||
Finds the next active tab (used mainly when :class:`AuiNotebook` has inactive/disabled
|
||||
tabs in it).
|
||||
|
||||
:param integer `ctrl_idx`: the index of the first (most obvious) tab to check for active status;
|
||||
:param `ctrl`: an instance of :class:`AuiTabCtrl`.
|
||||
:param integer `idx`: the index of the first (most obvious) tab to check for active status;
|
||||
"""
|
||||
|
||||
if self.GetEnabled(ctrl_idx):
|
||||
return ctrl_idx
|
||||
|
||||
for indx in range(ctrl_idx, ctrl.GetPageCount()):
|
||||
if self.GetEnabled(indx):
|
||||
return indx
|
||||
|
||||
for indx in range(ctrl_idx, -1, -1):
|
||||
if self.GetEnabled(indx):
|
||||
return indx
|
||||
|
||||
return 0
|
||||
return self._tabs.FindNextActiveTab(idx)
|
||||
|
||||
|
||||
def HideAllTabs(self, hidden=True):
|
||||
@@ -4187,7 +4291,6 @@ class AuiNotebook(wx.Panel):
|
||||
ctrl, ctrl_idx = self.FindTab(wnd)
|
||||
|
||||
if ctrl:
|
||||
self._tabs.SetActivePage(wnd)
|
||||
ctrl.SetActivePage(ctrl_idx)
|
||||
self.DoSizing()
|
||||
ctrl.DoShowHide()
|
||||
@@ -4262,6 +4365,9 @@ class AuiNotebook(wx.Panel):
|
||||
|
||||
return self._tabs.GetPageCount()
|
||||
|
||||
def GetShownPageCount(self):
|
||||
""" Returns the number of pages shown in the notebook. """
|
||||
return self._tabs.GetShownPageCount()
|
||||
|
||||
def GetPage(self, page_idx):
|
||||
"""
|
||||
@@ -4310,6 +4416,14 @@ class AuiNotebook(wx.Panel):
|
||||
self._tabs.EnableTab(page_idx, enable)
|
||||
self.Refresh()
|
||||
|
||||
def GetHidden(self, page_idx):
|
||||
"""
|
||||
Returns whether the page specified by the index `page_idx` is hidden.
|
||||
|
||||
:param integer `page_idx`: the page index.
|
||||
"""
|
||||
|
||||
return self._tabs.GetHidden(page_idx)
|
||||
|
||||
def DoSizing(self):
|
||||
""" Performs all sizing operations in each tab control. """
|
||||
|
||||
@@ -4334,13 +4334,16 @@ class AuiManager(wx.EvtHandler):
|
||||
|
||||
if p.IsOk():
|
||||
if p.IsNotebookPage():
|
||||
if show:
|
||||
|
||||
notebook = self._notebooks[p.notebook_id]
|
||||
id = notebook.GetPageIndex(p.window)
|
||||
if id >= 0:
|
||||
notebook.SetSelection(id)
|
||||
notebook = self._notebooks[p.notebook_id]
|
||||
page_idx = notebook.GetPageIndex(p.window)
|
||||
if page_idx >= 0:
|
||||
notebook.HidePage(page_idx, not show)
|
||||
if show:
|
||||
notebook.SetSelection(page_idx)
|
||||
if notebook.GetShownPageCount() > 0:
|
||||
self.ShowPane(notebook, True)
|
||||
else:
|
||||
self.ShowPane(notebook, False)
|
||||
|
||||
else:
|
||||
p.Show(show)
|
||||
@@ -5031,14 +5034,14 @@ class AuiManager(wx.EvtHandler):
|
||||
if pane_info.window and pane_info.window.IsShown():
|
||||
pane_info.window.Show(False)
|
||||
|
||||
# make sure that we are the parent of this window
|
||||
if pane_info.window and pane_info.window.GetParent() != self._frame:
|
||||
pane_info.window.Reparent(self._frame)
|
||||
|
||||
# if we have a frame, destroy it
|
||||
if pane_info.frame:
|
||||
# make sure that we are the parent of this window
|
||||
if pane_info.window and pane_info.window.GetParent() != self._frame:
|
||||
pane_info.window.Reparent(self._frame)
|
||||
pane_info.frame.Destroy()
|
||||
pane_info.frame = None
|
||||
pane_info.Hide()
|
||||
|
||||
elif pane_info.IsNotebookPage():
|
||||
# if we are a notebook page, remove ourselves...
|
||||
@@ -5053,7 +5056,14 @@ class AuiManager(wx.EvtHandler):
|
||||
notebook = self._notebooks[nid]
|
||||
page_idx = notebook.GetPageIndex(pane_info.window)
|
||||
if page_idx >= 0:
|
||||
notebook.RemovePage(page_idx)
|
||||
if not pane_info.IsDestroyOnClose():
|
||||
self.ShowPane(pane_info.window, False)
|
||||
|
||||
else:
|
||||
if pane_info.window and pane_info.window.GetParent() != self._frame:
|
||||
pane_info.window.Reparent(self._frame)
|
||||
pane_info.Dock().Hide()
|
||||
|
||||
|
||||
# now we need to either destroy or hide the pane
|
||||
to_destroy = 0
|
||||
@@ -5066,20 +5076,17 @@ class AuiManager(wx.EvtHandler):
|
||||
if pane_info.dock_direction in [AUI_DOCK_LEFT, AUI_DOCK_RIGHT]:
|
||||
tb.SetAGWWindowStyleFlag(tb.GetAGWWindowStyleFlag() | AUI_TB_VERTICAL)
|
||||
|
||||
pane_info.Dock().Hide()
|
||||
|
||||
if pane_info.IsNotebookControl():
|
||||
|
||||
notebook = self._notebooks[pane_info.notebook_id]
|
||||
while notebook.GetPageCount():
|
||||
window = notebook.GetPage(0)
|
||||
notebook.RemovePage(0)
|
||||
for idx in range(notebook.GetPageCount()-1, -1, -1):
|
||||
window = notebook.GetPage(idx)
|
||||
info = self.GetPane(window)
|
||||
if info.IsOk():
|
||||
info.notebook_id = -1
|
||||
info.dock_direction = AUI_DOCK_NONE
|
||||
# Note: this could change our paneInfo reference ...
|
||||
self.ClosePane(info)
|
||||
# close page if its IsDestroyOnClose flag is set
|
||||
if info.IsDestroyOnClose():
|
||||
if info.IsOk():
|
||||
# Note: this could change our paneInfo reference ...
|
||||
self.ClosePane(info)
|
||||
|
||||
if to_destroy:
|
||||
to_destroy.Destroy()
|
||||
@@ -6617,6 +6624,7 @@ class AuiManager(wx.EvtHandler):
|
||||
window.Reparent(self._frame)
|
||||
pageCounter -= 1
|
||||
allPages -= 1
|
||||
paneInfo.Direction(self.GetPane(notebook).dock_direction)
|
||||
|
||||
pageCounter += 1
|
||||
|
||||
@@ -6675,6 +6683,7 @@ class AuiManager(wx.EvtHandler):
|
||||
if child_pane.IsOk() and notebook_pane.IsOk():
|
||||
|
||||
child_pane.SetDockPos(notebook_pane)
|
||||
child_pane.Show(notebook_pane.IsShown())
|
||||
child_pane.window.Hide()
|
||||
child_pane.window.Reparent(self._frame)
|
||||
child_pane.frame = None
|
||||
|
||||
Reference in New Issue
Block a user