mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-09-26 09:56:32 +08:00
Merge branch 'aui-button-event'
Restore generation of wxEVT_AUINOTEBOOK_BUTTON events. See #26978.
This commit is contained in:
@@ -149,6 +149,11 @@ Changes in behaviour not resulting in compilation errors
|
||||
values was previously silently allowed but couldn't work correctly, so now
|
||||
attempting to do it will assert. Don't set these values for the central pane.
|
||||
|
||||
- Handling wxEVT_AUINOTEBOOK_BUTTON events without calling event.Skip() now
|
||||
consistently prevents the default handling from taking place, for whichever
|
||||
button that was pressed. Check the button ID and call Skip() if you want the
|
||||
the default handling to take place.
|
||||
|
||||
|
||||
Changes in behaviour which may result in build errors
|
||||
-----------------------------------------------------
|
||||
|
||||
@@ -666,6 +666,10 @@ protected:
|
||||
// control: notice that this is _not_ the same as the index of the page, in
|
||||
// general, m_tabs.GetIdxFromWindow(wxAuiTabCtrl::GetWindowFromIdx()) must
|
||||
// be used to get it.
|
||||
//
|
||||
// They all return void, except OnTabButton() which returns true if the
|
||||
// application had handled the event generated by it without skipping it,
|
||||
// in which case the button must not be handled by wxAuiTabCtrl neither.
|
||||
friend class wxAuiTabEventSource;
|
||||
|
||||
void OnTabClicked(wxAuiTabCtrl* ctrl, int tabIdx);
|
||||
@@ -673,7 +677,7 @@ protected:
|
||||
void OnTabDragMotion(wxAuiTabCtrl* ctrl, int tabIdx);
|
||||
void OnTabEndDrag(wxAuiTabCtrl* ctrl, int tabIdx);
|
||||
void OnTabCancelDrag(wxAuiTabCtrl* ctrl, int tabIdx);
|
||||
void OnTabButton(wxAuiTabCtrl* ctrl, int tabIdx, int button_id);
|
||||
bool OnTabButton(wxAuiTabCtrl* ctrl, int tabIdx, int button_id);
|
||||
void OnTabMiddleDown(wxAuiTabCtrl* ctrl, int tabIdx);
|
||||
void OnTabMiddleUp(wxAuiTabCtrl* ctrl, int tabIdx);
|
||||
void OnTabRightDown(wxAuiTabCtrl* ctrl, int tabIdx);
|
||||
|
||||
@@ -232,7 +232,14 @@ struct wxAuiNotebookPosition
|
||||
@event{EVT_AUINOTEBOOK_PAGE_CHANGING(id, func)}
|
||||
The page selection is about to be changed. Processes a @c wxEVT_AUINOTEBOOK_PAGE_CHANGING event. This event can be vetoed.
|
||||
@event{EVT_AUINOTEBOOK_BUTTON(id, func)}
|
||||
The window list button has been pressed. Processes a @c wxEVT_AUINOTEBOOK_BUTTON event.
|
||||
A button in the tab control, e.g. the close or the window list button,
|
||||
has been pressed. Processes a @c wxEVT_AUINOTEBOOK_BUTTON event. Use
|
||||
wxCommandEvent::GetInt() to retrieve the id of the button, which is one
|
||||
of @c wxAUI_BUTTON_XXX constants. Handling this event without skipping
|
||||
it prevents the default action associated with the button, e.g. closing
|
||||
the page for @c wxAUI_BUTTON_CLOSE or showing the list of the pages for
|
||||
@c wxAUI_BUTTON_WINDOWLIST, from taking place, so the handler must call
|
||||
wxEvent::Skip() if this is not desired.
|
||||
@event{EVT_AUINOTEBOOK_BEGIN_DRAG(id, func)}
|
||||
Dragging is about to begin. Processes a @c wxEVT_AUINOTEBOOK_BEGIN_DRAG event.
|
||||
@event{EVT_AUINOTEBOOK_END_DRAG(id, func)}
|
||||
@@ -1323,7 +1330,14 @@ using wxAuiDefaultTabArt = wxAuiFlatTabArt;
|
||||
@event{EVT_AUINOTEBOOK_PAGE_CHANGING(id, func)}
|
||||
The page selection is about to be changed. Processes a @c wxEVT_AUINOTEBOOK_PAGE_CHANGING event. This event can be vetoed.
|
||||
@event{EVT_AUINOTEBOOK_BUTTON(id, func)}
|
||||
The window list button has been pressed. Processes a @c wxEVT_AUINOTEBOOK_BUTTON event.
|
||||
A button in the tab control, e.g. the close or the window list button,
|
||||
has been pressed. Processes a @c wxEVT_AUINOTEBOOK_BUTTON event. Use
|
||||
wxCommandEvent::GetInt() to retrieve the id of the button, which is one
|
||||
of @c wxAUI_BUTTON_XXX constants. Handling this event without skipping
|
||||
it prevents the default action associated with the button, e.g. closing
|
||||
the page for @c wxAUI_BUTTON_CLOSE or showing the list of the pages for
|
||||
@c wxAUI_BUTTON_WINDOWLIST, from taking place, so the handler must call
|
||||
wxEvent::Skip() if this is not desired.
|
||||
@event{EVT_AUINOTEBOOK_BEGIN_DRAG(id, func)}
|
||||
Dragging is about to begin. Processes a @c wxEVT_AUINOTEBOOK_BEGIN_DRAG event.
|
||||
@event{EVT_AUINOTEBOOK_END_DRAG(id, func)}
|
||||
|
||||
+50
-21
@@ -120,9 +120,9 @@ private:
|
||||
ctrl->GetBook()->OnTabCancelDrag(ctrl, tabIdx);
|
||||
}
|
||||
|
||||
static void TabButton(wxAuiTabCtrl* ctrl, int tabIdx, int button_id)
|
||||
static bool TabButton(wxAuiTabCtrl* ctrl, int tabIdx, int button_id)
|
||||
{
|
||||
ctrl->GetBook()->OnTabButton(ctrl, tabIdx, button_id);
|
||||
return ctrl->GetBook()->OnTabButton(ctrl, tabIdx, button_id);
|
||||
}
|
||||
|
||||
static void TabMiddleDown(wxAuiTabCtrl* ctrl, int tabIdx)
|
||||
@@ -1704,6 +1704,17 @@ wxAuiTabCtrl::UpdateButtonStateAndRefresh(wxAuiTabContainerButton& button,
|
||||
|
||||
void wxAuiTabCtrl::OnButton(int tabIdx, int button)
|
||||
{
|
||||
// Let wxAuiNotebook generate the event for this button click and perform
|
||||
// the default action for the buttons handled at its level, such as closing
|
||||
// or pinning the tab.
|
||||
//
|
||||
// It only returns true the application handled the event without skipping
|
||||
// it, which means that it handled the button completely on its own.
|
||||
if (wxAuiTabEventSource::TabButton(this, tabIdx, button))
|
||||
return;
|
||||
|
||||
// For mostly historical (but also convenience) reasons, some buttons are
|
||||
// handled here instead of in wxAuiNotebook.
|
||||
if (button == wxAUI_BUTTON_LEFT || button == wxAUI_BUTTON_RIGHT)
|
||||
{
|
||||
if (button == wxAUI_BUTTON_LEFT)
|
||||
@@ -1731,10 +1742,6 @@ void wxAuiTabCtrl::OnButton(int tabIdx, int button)
|
||||
wxAuiTabEventSource::TabClicked(this, idx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxAuiTabEventSource::TabButton(this, tabIdx, button);
|
||||
}
|
||||
}
|
||||
|
||||
void wxAuiTabCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event))
|
||||
@@ -3685,32 +3692,50 @@ void wxAuiNotebook::OnNavigationKeyNotebook(wxNavigationKeyEvent& event)
|
||||
}
|
||||
}
|
||||
|
||||
void wxAuiNotebook::OnTabButton(wxAuiTabCtrl* tabs, int tabIdx, int button_id)
|
||||
bool wxAuiNotebook::OnTabButton(wxAuiTabCtrl* tabs, int tabIdx, int button_id)
|
||||
{
|
||||
int selection = tabIdx;
|
||||
if (selection == -1 && button_id == wxAUI_BUTTON_CLOSE)
|
||||
{
|
||||
// if the close button is to the right, use the active
|
||||
// page selection to determine which page to close
|
||||
selection = tabs->GetActivePage();
|
||||
}
|
||||
|
||||
// Notify the application about the button click.
|
||||
{
|
||||
wxAuiNotebookEvent e(wxEVT_AUINOTEBOOK_BUTTON, m_windowId);
|
||||
e.SetSelection(selection != -1
|
||||
? m_tabs.GetIdxFromWindow(tabs->GetWindowFromIdx(selection))
|
||||
: wxNOT_FOUND
|
||||
);
|
||||
e.SetInt(button_id);
|
||||
e.SetEventObject(this);
|
||||
|
||||
// Note that if the application handles this event without skipping
|
||||
// it, we don't do anything else, neither here nor in wxAuiTabCtrl:
|
||||
// this is compatible with the previous versions, in which handling
|
||||
// this event prevented our own handler, executed after the application
|
||||
// one, from running at all.
|
||||
if (ProcessWindowEvent(e))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (button_id == wxAUI_BUTTON_CLOSE)
|
||||
{
|
||||
int selection = tabIdx;
|
||||
if (selection == -1)
|
||||
{
|
||||
// if the close button is to the right, use the active
|
||||
// page selection to determine which page to close
|
||||
selection = tabs->GetActivePage();
|
||||
}
|
||||
|
||||
if (selection != -1)
|
||||
{
|
||||
wxWindow* close_wnd = tabs->GetWindowFromIdx(selection);
|
||||
|
||||
// ask owner if it's ok to close the tab
|
||||
wxAuiNotebookEvent e(wxEVT_AUINOTEBOOK_PAGE_CLOSE, m_windowId);
|
||||
e.SetSelection(m_tabs.GetIdxFromWindow(close_wnd));
|
||||
const int idx = m_tabs.GetIdxFromWindow(close_wnd);
|
||||
e.SetSelection(idx);
|
||||
e.SetOldSelection(selection);
|
||||
e.SetEventObject(this);
|
||||
ProcessWindowEvent(e);
|
||||
if (!e.IsAllowed())
|
||||
return;
|
||||
return false;
|
||||
|
||||
|
||||
#if wxUSE_MDI
|
||||
@@ -3722,7 +3747,8 @@ void wxAuiNotebook::OnTabButton(wxAuiTabCtrl* tabs, int tabIdx, int button_id)
|
||||
#endif
|
||||
{
|
||||
int main_idx = m_tabs.GetIdxFromWindow(close_wnd);
|
||||
wxCHECK_RET( main_idx != wxNOT_FOUND, wxT("no page to delete?") );
|
||||
wxCHECK_MSG( main_idx != wxNOT_FOUND, false,
|
||||
wxT("no page to delete?") );
|
||||
|
||||
DeletePage(main_idx);
|
||||
}
|
||||
@@ -3736,8 +3762,9 @@ void wxAuiNotebook::OnTabButton(wxAuiTabCtrl* tabs, int tabIdx, int button_id)
|
||||
}
|
||||
else if (button_id == wxAUI_BUTTON_PIN)
|
||||
{
|
||||
// For now we don't send any event, this can be always added later if
|
||||
// necessary.
|
||||
// Note that we don't send any event specific to pinning the tab, the
|
||||
// generic button event above is the only notification for it, but such
|
||||
// event could be always added later if necessary.
|
||||
wxWindow* const wnd = tabs->GetWindowFromIdx(tabIdx);
|
||||
|
||||
const auto idx = m_tabs.GetIdxFromWindow(wnd);
|
||||
@@ -3758,11 +3785,13 @@ void wxAuiNotebook::OnTabButton(wxAuiTabCtrl* tabs, int tabIdx, int button_id)
|
||||
break;
|
||||
}
|
||||
|
||||
wxCHECK_RET(newKind != wxAuiTabKind::Locked,
|
||||
wxCHECK_MSG(newKind != wxAuiTabKind::Locked, false,
|
||||
"locked pages shouldn't have pin button");
|
||||
|
||||
SetPageKind(idx, newKind);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
using wxAuiNotebook::OnTabButton;
|
||||
using wxAuiNotebook::OnTabMiddleDown;
|
||||
using wxAuiNotebook::OnTabMiddleUp;
|
||||
using wxAuiNotebook::OnTabRightDown;
|
||||
@@ -415,6 +416,76 @@ TEST_CASE("wxAuiNotebook::SplitTabEventSelections", "[aui]")
|
||||
CHECK( selections[0] == 1 );
|
||||
}
|
||||
|
||||
// This tests for the problem of https://github.com/wxWidgets/wxWidgets/issues/26801
|
||||
TEST_CASE("wxAuiNotebook::ButtonEvent", "[aui]")
|
||||
{
|
||||
TestAuiNotebook nb;
|
||||
wxPanel *p1 = new wxPanel(&nb);
|
||||
wxPanel *p2 = new wxPanel(&nb);
|
||||
REQUIRE( nb.AddPage(p1, "Page 1") );
|
||||
REQUIRE( nb.AddPage(p2, "Page 2") );
|
||||
|
||||
// Split the notebook to check that the event uses the index of the page in
|
||||
// the notebook and not its position in its own tab control.
|
||||
nb.Split(1, wxRIGHT);
|
||||
|
||||
wxAuiTabCtrl *tabCtrl = nullptr;
|
||||
int tabIdx = wxNOT_FOUND;
|
||||
REQUIRE( nb.FindTab(p2, &tabCtrl, &tabIdx) );
|
||||
REQUIRE( tabCtrl );
|
||||
REQUIRE( tabIdx == 0 );
|
||||
|
||||
int numEvents = 0;
|
||||
int selection = wxNOT_FOUND;
|
||||
int button = wxID_NONE;
|
||||
bool skip = true;
|
||||
|
||||
nb.Bind(wxEVT_AUINOTEBOOK_BUTTON,
|
||||
[&](wxAuiNotebookEvent& event)
|
||||
{
|
||||
numEvents++;
|
||||
selection = event.GetSelection();
|
||||
button = event.GetInt();
|
||||
event.Skip(skip);
|
||||
});
|
||||
|
||||
// Note that this event must be skipped by the handler if the default
|
||||
// action, e.g. closing the page, is still to be performed.
|
||||
|
||||
SECTION( "Custom button" )
|
||||
{
|
||||
nb.OnTabButton(tabCtrl, tabIdx, wxAUI_BUTTON_CUSTOM1);
|
||||
|
||||
CHECK( numEvents == 1 );
|
||||
CHECK( selection == 1 );
|
||||
CHECK( button == wxAUI_BUTTON_CUSTOM1 );
|
||||
}
|
||||
|
||||
SECTION( "Close button" )
|
||||
{
|
||||
nb.OnTabButton(tabCtrl, tabIdx, wxAUI_BUTTON_CLOSE);
|
||||
|
||||
CHECK( numEvents == 1 );
|
||||
CHECK( selection == 1 );
|
||||
CHECK( button == wxAUI_BUTTON_CLOSE );
|
||||
|
||||
CHECK( nb.GetPageCount() == 1 );
|
||||
}
|
||||
|
||||
SECTION( "Close button not skipped" )
|
||||
{
|
||||
skip = false;
|
||||
|
||||
nb.OnTabButton(tabCtrl, tabIdx, wxAUI_BUTTON_CLOSE);
|
||||
|
||||
CHECK( numEvents == 1 );
|
||||
|
||||
// Handling the event without skipping it prevents the page from being
|
||||
// closed, as this was the case in the previous versions too.
|
||||
CHECK( nb.GetPageCount() == 2 );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(AuiNotebookTestCase, "wxAuiNotebook::Layout", "[aui]")
|
||||
{
|
||||
const auto addPage = [this](int n)
|
||||
|
||||
Reference in New Issue
Block a user