Page 1 of 1

Display text on wxGauge

Posted: Thu Aug 01, 2019 2:37 am
by fishnet37222
I'm creating an app that displays a wxGauge control on the status bar as a progress bar. In Windows Forms and WPF it's trivial to display text on the progress bar control. What would be the best way to do that in wxWidgets? I was considering subclassing the existing wxGauge, but decided against it when reading in the documentation for the paint event that the drawing of the standard controls shouldn't be messed with: https://docs.wxwidgets.org/trunk/classw ... event.html

I did try adding both the wxGauge and a wxStaticText to the status bar and sizing them both to fit in the first pane, but the wxGauge always draws on top of the wxStaticText even though the wxGauge was added first.

Edit: I'm looking for something like in the screenshot below.
Untitled.png
Untitled.png (1.75 KiB) Viewed 93 times

Re: Display text on wxGauge

Posted: Thu Aug 01, 2019 6:50 am
by doublemax
I don't think there is an easy way to do this. You could create the wxStaticText as child of the wxGauge to make it appear on top of it, but it would have an opaque background and look ugly.

The only solution i can think of is to create a custom wxGauge from scratch. Which is not particularly difficult, but still a lot of stuff to type.

Re: Display text on wxGauge

Posted: Thu Aug 01, 2019 10:22 pm
by New Pagodi
This should be a class that looks like what you want. It hasn't been thoroughly tested though

Code: Select all

#include <wx/dcbuffer.h>
#include <wx/renderer.h>

class GaugeWithText:public wxWindow
{
public:
    GaugeWithText(){}
 	GaugeWithText(wxWindow *parent, wxWindowID id, int range,
                 const wxPoint &pos=wxDefaultPosition,
                 const wxSize &size=wxDefaultSize, long style=0,
                 const wxValidator &validator=wxDefaultValidator,
                 const wxString &name="GaugeWithText");
    virtual ~GaugeWithText(){}
    bool Create(wxWindow *parent, wxWindowID id, int range,
                const wxPoint &pos=wxDefaultPosition,
                const wxSize &size=wxDefaultSize, long style=0,
                const wxValidator &validator=wxDefaultValidator,
                const wxString &name="GaugeWithText");
    int GetRange () const{return m_range;}
    int GetValue () const{return m_value;}
    wxString GetText() const{return m_text;}
    void SetRange (int range){m_range=range;Refresh();}
    void SetValue (int pos){m_value=pos;Refresh();}
    void SetText(const wxString& s){m_text=s;Refresh();}
private:
    void OnPaint(wxPaintEvent&);
    int m_value;
    int m_range;
    wxString m_text;
};

GaugeWithText::GaugeWithText(wxWindow *parent, wxWindowID id, int range,
                             const wxPoint &pos, const wxSize &size, long style,
                             const wxValidator &validator, const wxString &name)
{
    Create(parent,id,range,pos,size,style,validator,name);
}

bool GaugeWithText::Create(wxWindow *parent, wxWindowID id, int range,
                           const wxPoint &pos, const wxSize &size, long style,
                           const wxValidator &validator, const wxString &name)
{
    style|=wxFULL_REPAINT_ON_RESIZE;
    wxSize size2 = size;
    if ( size == wxDefaultSize )
    {
        wxSize sz = GetTextExtent("M");
        size2.SetHeight(sz.GetHeight()+FromDIP(4));
    }

    if ( !wxWindow::Create(parent,id,pos,size2,style) )
    {
        return false;
    }

    m_value=0;
    m_range = range;
    SetBackgroundStyle(wxBG_STYLE_PAINT);
    Bind(wxEVT_PAINT,&GaugeWithText::OnPaint,this);
    return true;
}

void GaugeWithText::OnPaint(wxPaintEvent&)
{
    wxAutoBufferedPaintDC dc(this);
    wxRendererNative& renderer = wxRendererNative::GetDefault();
    renderer.DrawGauge(this, dc, GetClientRect(), m_value, m_range, 0);
    renderer.DrawItemText(this,dc,m_text,GetClientRect(),wxALIGN_CENTER|wxALIGN_CENTRE_VERTICAL);
}