wxStatusBar click event

160 views
Skip to first unread message

QuentinC

unread,
Jun 24, 2021, 5:21:29 PM6/24/21
to wx-u...@googlegroups.com
Hello,

I have a small question about status bar.
I want to react to mouse clicks inside the status bar. How can I know
inside the event listener which field has been clicked ?
I don't find anything simple in the documentation for wxStatusBar. Did I
miss something obvious ?


const int sizes[] = { -1, -1, -1, 50, 50 };
wxStatusBar* status = mainFrame->CreateStatusBar(5);
status->SetFieldCount(5, sizes);
status->SetStatusText("First", 0);
status->SetStatusText("Second", 1);
status->SetStatusText("Third", 2);
status->SetStatusText("Fourth", 3);
status->SetStatusText("Fifth", 4);
status->Bind(wxEVT_LEFT_UP, [&](auto& e){
// The event is correctly received, but
// How can I know which field has been clicked ?
// i.e. "First", "Second", "Third", "Fourth" or "Fifth" ?
wxMessageBox("You have clicked on ??????", "Status bar test", wxOK);
});


Thank you for your answers.
Have a good night or nice day.


Vadim Zeitlin

unread,
Jun 24, 2021, 5:31:06 PM6/24/21
to wx-u...@googlegroups.com
On Thu, 24 Jun 2021 23:21:17 +0200 QuentinC wrote:

Q> I want to react to mouse clicks inside the status bar. How can I know
Q> inside the event listener which field has been clicked ?
Q> I don't find anything simple in the documentation for wxStatusBar. Did I
Q> miss something obvious ?

You can use GetFieldRect() for this, but it would be better to avoid
handling clicks on the status bar itself, as this is not guaranteed to work
if a native control is used (although it does work in practice right now),
and instead embed a custom control in the status bar and handle clicks in
it instead. The statbar sample shows how to do this.

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

David Connet

unread,
Jun 24, 2021, 5:40:54 PM6/24/21
to wx-u...@googlegroups.com
Rather than binding to the up event, you might want to bind to the click
event. For instance, I support context menus and double click on my
status bar via:
        statusbar->Bind(wxEVT_CONTEXT_MENU,
&CMainFrame::OnStatusBarContextMenu, this);
        statusbar->Bind(wxEVT_LEFT_DCLICK,
&CMainFrame::OnStatusBarDblClick, this);

I then walk down all the fields and check which rect it's in. (Note, the
GetPosition() for context menus and mouseevents is different - the first
is in screen coords, the 2nd in client)

Basically:
    for (int id = 1; id < static_cast<int>(m_Widths.size()); ++id) // I
track the sizes, so the array size is how many fields there are
    {
        if (statusbar->GetFieldRect(id, rect) && rect.Contains(point))
            return id; // The function this is in is: int
CStatusBarHelper::GetDoubleClickFieldId(wxMouseEvent const& evt) const
    }

I start at 1 because I don't care about position 0 - that's the flex
area for help messages

If you want to see the actual code, look at:
https://github.com/dconnet/AgilityBook/blob/master/src/Win/MainFrm.cpp
https://github.com/dconnet/AgilityBook/blob/master/src/Libraries/LibARBWin/StatusBarHelper.cpp

Dave

David Connet

unread,
Jun 24, 2021, 5:42:35 PM6/24/21
to wx-u...@googlegroups.com
On 6/24/2021 2:31 PM, Vadim Zeitlin wrote:
> but it would be better to avoid
> handling clicks on the status bar itself, as this is not guaranteed to work
> if a native control is used (although it does work in practice right now),

Oh. That's good to know... Something to add to my TODO list...

Dave

QuentinC

unread,
Jun 25, 2021, 2:28:31 PM6/25/21
to wx-u...@googlegroups.com
Hello,

VZ> You can use GetFieldRect() for this, but it would be better to
avoid handling clicks on the status bar itself, as this is not
guaranteed to work if a native control is used (although it does work in
practice right now), and instead embed a custom control in the status
bar and handle clicks in it instead. The statbar sample shows how to do
this.

I have tried GetFieldRect, and it's enough for now, thank you. It works
well.

I have had a look at the statbar sample, but I don't well understand how
the custom controls are added to the status bar.
Is it enough for a control to have the status bar as a parent to be part
of it ? There's nothing else to do ?
Is creating a subclass of wxStatusBar mandatory ?
I have the impression that I have missed something important.

DC> Rather than binding to the up event, you might want to bind to the
click event. For instance, I support context menus and double click on
my status bar
...
I then walk down all the fields and check which rect it's in. (Note, the
GetPosition() for context menus and mouseevents is different - the first
is in screen coords, the 2nd in client)

Well done, I have been caught by the trap !
is there a reason why the coordinates of a context menu event are in
screen and not client coordinates ?

Thank you for your help.
And good evening / night.

Vadim Zeitlin

unread,
Jun 25, 2021, 6:08:56 PM6/25/21
to wx-u...@googlegroups.com
On Fri, 25 Jun 2021 20:28:21 +0200 QuentinC wrote:

Q> is there a reason why the coordinates of a context menu event are in
Q> screen and not client coordinates ?

It's a command event, so it bubbles up the window chain and it's more
convenient to use screen coordinates when you are not handling the event in
the same window which generated it.
Reply all
Reply to author
Forward
0 new messages