Page 1 of 1

StatusBar field width problem (Linux and OS-X)

Posted: Thu Sep 14, 2017 8:11 pm
by xaviou
Hi.

I have a status bar with 2 fields (created from the constructor of a wxFrame with "CreateStatusBar(2)".

The second field is for displaying a simple text that never changes.
I am trying to set the width of this field to the minimal needed for the text I wand to show.

Here is an example of what I have in the code :

Code: Select all

// Status bar (2 fields)
wxStatusBar* stb=CreateStatusBar(2);
// String to display in the second field
wxString sTxt=_T("Hello, World!");
// Needed width for this text
int widths[2];
wxClientDC dc(stb);
dc.GetTextExtent(sTxt, &widths[1], &widths[0]);
widths[0]=-1; // Make first field extensible
stb->SetStatusWidths(2, widths);
SetStatusText(sTxt, 1);
It works fine under Windows, but the text is truncated under Linux and OS-X.
I have tested with both wx-3.0.3 and wx-3.1.1.
I've also tested this code with the minimal sample (juste replace the code between the "#if wxUSE_STATUSBAR" and "#endif" lines 175 to 179 of the "minimal.cpp" file) and get the same result.

Does someone know a best way to achieve this ?

Regards
Xav'

Re: StatusBar field width problem (Linux and OS-X)

Posted: Fri Sep 15, 2017 12:53 pm
by eranon
Hi Xaviou,

Also got this type of issue ! In a first place I thought it came from the fact Mac is able to return fraction of points, but I tried in the past going through wxGraphicsContext::GetTextExtent (returning doubles), but it didn't change the result... So, and since I had no time to spend on a status-bar, I stated (depending on the concerned app and its requirements) to get ride of this kind of detail using one of these two "workarounds":

- Adding a margin to the result of GetTexExtent on Mac (#ifdef __WXOSX__)
- Or removing any notion of fields (I simply add separators to mimic fields -- see attachments below)

Windows:
snap_0004950.png
snap_0004950.png (3.89 KiB) Viewed 2225 times
Mac:
snap_0004951.png
snap_0004951.png (20 KiB) Viewed 2225 times
But, of course, it's not a solution, it's a workaround :mrgreen:

Re: StatusBar field width problem (Linux and OS-X)

Posted: Fri Sep 15, 2017 3:09 pm
by xaviou
Hi.
eranon wrote:So, and since I had no time to spend on a status-bar, I stated (depending on the concerned app and its requirements) to get ride of this kind of detail using one of these two "workarounds":

- Adding a margin to the result of GetTexExtent on Mac (#ifdef __WXOSX__)
- Or removing any notion of fields (I simply add separators to mimic fields -- see attachments below)
Others solutions can also be :
- Getting the needed sizes on each system with a test app, and hard setting the width using #ifdef statements
- Creating a wxStaticText as child of the statusbar, and manage its position in the "OnSize" event

I've tested the second solution, and it works, but if the width of the frame isn't big to include the text of the first field, overlapping gives a bad result:
Image

But testing this gave me the final solution : creating a temporary wxStaticText with the needed text, getting its width and immediately deleting it.

I'll have to test this again under Linux, and see...
Here is the final code :

Code: Select all

// Status bar (2 fields)
wxStatusBar* stb=CreateStatusBar(2);
// String to display in the second field
wxString sTxt=_T("Hello, World!");
// Needed width for this text
int widths[2];
#ifndef __WXMSW__
	wxStaticText *tmpLabel=new wxStaticText(this, wxID_STATIC, sTxt);
	tmpLabel->GetSize(&widths[1], &widths[0]);
	delete tmpLabel;
#else
	wxClientDC dc(stb);
	dc.GetTextExtent(sTxt, &widths[1], &widths[0]);
#endif
widths[0]=-1; // Make first field extensible
stb->SetStatusWidths(2, widths);
SetStatusText(sTxt, 1);
Image
eranon wrote:But, of course, it's not a solution, it's a workaround :mrgreen:
My solution is also a workaround, but I think I'll do with it.

Thank you for your response.

Regards
Xav'

Re: StatusBar field width problem (Linux and OS-X)

Posted: Fri Sep 15, 2017 3:14 pm
by doublemax
But testing this gave me the final solution : creating a temporary wxStaticText with the needed text, getting its width and immediately deleting it.
If this works, the it could be that the wxClientDC in your original code does not use the proper font for the size calculation.

I would try to set the font to wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ) before getting the text size.

Re: StatusBar field width problem (Linux and OS-X)

Posted: Fri Sep 15, 2017 4:37 pm
by xaviou
Hi doublemax.
doublemax wrote:I would try to set the font to wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ) before getting the text size.
I've just tested, but it doesn't work :
Image

I'll try to make other tests if I find the time to.

Thanks.

Xav'

Re: StatusBar field width problem (Linux and OS-X)

Posted: Fri Sep 15, 2017 7:20 pm
by eranon
Yep, a lot of possible workarounds ;)

Here is a light one (tested successfully under OS X 10.9) I would maybe retain for Mac in my own code if a day I go back to text fields in status-bar:

Code: Select all

wxStatusBar* stb=CreateStatusBar(2);
wxString sTxt=_T("Hello, World!");
int widths[2];
wxClientDC dc(stb);

#ifdef __WXOSX__ 
wxFont font(wxSystemSettings::GetFont(wxSYS_SYSTEM_FONT));
font.Scale(1.05); // we increase by 5% for computation only
dc.SetFont(font);
#endif

dc.GetTextExtent(sTxt, &widths[1], &widths[0]);
widths[0]=-1; // Make first field extensible
stb->SetStatusWidths(2, widths);
SetStatusText(sTxt, 1);
Also, I read somewhere in the wxTrac that Windows added margin(s) natively. So, maybe wxWidgets compensates in some ways internally and this would become a problem in OS X where no margin is added... Pure hypothesis (certified not verified)!