Hittest in wxAuiNotebook not working Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
walderich
Earned a small fee
Earned a small fee
Posts: 24
Joined: Sat Sep 17, 2011 6:09 pm

Hittest in wxAuiNotebook not working

Post by walderich »

I am trying to implement an automatic tab-switch when the user drags something over the tabs of a wxAuiNotebook. Therefore I am using "Hittest". Unfortunately the method always returns a wxNOT_FOUND as result. When I exchange the wxAuiNotebook with a wxNotebook object, the Hittest method returns the expected result. How is it possible to get the page under the cursor for a wxAuiNotebook?
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7479
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Hittest in wxAuiNotebook not working

Post by ONEEYEMAN »

Hi,
What wx version?
What platform/toolkit?
Can you reproduce it in a auidemo sample?

Thank you.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Hittest in wxAuiNotebook not working

Post by doublemax »

Code: Select all

int wxAuiNotebook::HitTest (const wxPoint& WXUNUSED(pt), long* WXUNUSED(flags)) const
{
    wxFAIL_MSG("Not implemented for wxAuiNotebook");
    return wxNOT_FOUND;
}
This method could use GetActiveTabCtrl()->TabHitTest(...), but unfortunately it doesn't. And GetActiveTabCtrl() is protected, so you can only access it by subclassing wxAuiNotebook.
Use the source, Luke!
walderich
Earned a small fee
Earned a small fee
Posts: 24
Joined: Sat Sep 17, 2011 6:09 pm

Re: Hittest in wxAuiNotebook not working

Post by walderich »

@ONEEYEMAN: I am working on WIndows 7 64-bit, using wxWidgets 3.1.

@doublemax:
Thanks for the deeper look into it. That explains why it doesn't work. I tried to implement your suggestion:

Code: Select all

class DT: public wxDropTarget {
public:
  DT(wxBookCtrlBase *nb): tgt(nb) { SetDataObject(new wxTextDataObject); }
  wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult defResult) { return wxDragNone; }
  wxDragResult OnDragOver(wxCoord x, wxCoord y, wxDragResult defResult) {
    tgt->HitTest(wxPoint(x, y));
    return wxDragNone;
  }
private:
  wxBookCtrlBase *tgt;
};

class NB: public wxAuiNotebook {
public:
  NB(wxWindow *parent): wxAuiNotebook(parent) {
    SetDropTarget(new DT(this));
  };
  int HitTest(const wxPoint &pt, long *flags = NULL) const {
    wxWindow *w = NULL;
    m_tabs.TabHitTest(pt.x, pt.y, &w);
    wxLogInfo("HitTest: %dx%d: %p", pt.x, pt.y, w);
    return wxNOT_FOUND;
  }
}
Although "GetActiveTabCtrl()" is declated protected, I couldn't use it, as the compiler complains: "cannot convert 'this' pointer from 'const NB' to 'wxAuiNotebook &'".

But using "TabHitTest()" always returns "false" and the wxWindow pointer is not assigned. I also tried to convert the wxPoint via "ClientToScreen" but without success. I have no idea what the issue is here. The output from "wxLogInfo" seems to be correct, though.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Hittest in wxAuiNotebook not working

Post by doublemax »

I also tried to convert the wxPoint via "ClientToScreen" but without success.
The coordinates should be client coordinates relative to the wxTabCtrl. I don't have time to test this myself at the moment, but try researching in that direction. E..g try passing fixed coordinates of (10,8) and check if it finds something. If yes, you're on the right track.
Use the source, Luke!
walderich
Earned a small fee
Earned a small fee
Posts: 24
Joined: Sat Sep 17, 2011 6:09 pm

Re: Hittest in wxAuiNotebook not working

Post by walderich »

Oh dear, now I finally got it. I used the "m_tabs" member. But this isn't the currently active tab but the tab container (as the AUI can have multiple tabs). But trying to read the active tab within "HitTest" is not possible, as it is declared "const", but "GetActiveTabCtrl" isn't, as it may create a new tab control if none is active ... Phew! That was harder than I thought. Maybe I should have read your answer more precisely @doublemax :-) Thanks a lot!
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7479
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Hittest in wxAuiNotebook not working

Post by ONEEYEMAN »

If that works as it should - consider donating this code to the library either thru the GitHub PR or trac.wxwidgets.org.

Thank you.
walderich
Earned a small fee
Earned a small fee
Posts: 24
Joined: Sat Sep 17, 2011 6:09 pm

Re: Hittest in wxAuiNotebook not working

Post by walderich »

Yes, I got it to work now. The problem is, that I couldn't add the code inside the HitTest() function, as it conflicts with the called function GetTabCtrlFromPoint():

Code: Select all

int wxAuiNotebook::HitTest (const wxPoint&, long*) const;
wxAuiTabCtrl* wxAuiNotebook::GetTabCtrlFromPoint(const wxPoint&); // Can't be called in HitTest as not defined as "const"
wxAuiPaneInfoArray& wxAuiManager::GetAllPanes(); // GetTabCtrlFromPoint() needs those
The only way I could add it directly to HitTest(), would be to make the internal GetTabCtrlFromPoint() "const", which in turn needs to change GetAllPanes() to "const". But GetAllPanes() is called 14 times in "auibook.cpp" (and only there). I tried to manually change all calls of GetAllPanes() to "const" which actually works. But I guess it's not how it is intended, as the panes' contents are indeed changed, e.g. in DoModifySelection():

Code: Select all

wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes(); // Ok to make all_panes "const", as not directly changed
for (i = 0; i < all_panes.GetCount(); ++i) {
    wxAuiPaneInfo& pane = all_panes.Item(i);
    wxAuiTabCtrl* tabctrl = ((wxTabFrame*)pane.window)->m_tabs;
    tabctrl->SetSelectedFont(m_selectedFont);        // Contents are changed
    tabctrl->Refresh();
I have no idea how to resolve this. Adding another method like GetConstPanes() just for my HitTest() doesn't seem to be appropriate. Maybe if I change all other methods to "const" which only are not because of this call? Or do you have another suggestion?
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7479
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Hittest in wxAuiNotebook not working

Post by ONEEYEMAN »

Hi,
For questions like this you need to contact wx core developers at wx-dev mailing list.
But my guess is that if you create such an override const function and submit the PR on github, you will get a reply much sooner.

Thank you.
walderich
Earned a small fee
Earned a small fee
Posts: 24
Joined: Sat Sep 17, 2011 6:09 pm

Re: Hittest in wxAuiNotebook not working

Post by walderich »

Made my first GitHub contribution and created a PR.
Post Reply