first program

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
Dark_Phoenix
Knows some wx things
Knows some wx things
Posts: 48
Joined: Sat Jul 04, 2009 2:27 pm
Location: Houston, TX

first program

Post by Dark_Phoenix » Wed Jul 22, 2009 12:36 pm

I am working on a simple app that has 3 wxTextCtrl's that allows the user to enter an RBG value and display the color. I want to be able to tab between the controls but I have not been able to find any information on this. Can anyone point me in the right direction?

I will post the code I have so if anyone wants to take a look and see if there is anything that I could do different / better please feel free.

Code: Select all

#include <wx/wx.h>

class ColorsApp : public wxApp
{
    public:
        virtual bool OnInit();
};

class ColorsFrame: public wxFrame
{
    public:
        ColorsFrame(const wxString& title);
        ~ColorsFrame() { }

    private:
        void OnClose(wxCloseEvent& event)   { Destroy(); }
        void OnQuit(wxCommandEvent& event)  { Destroy(); }
        void OnOK(wxCommandEvent& event);
        wxTextCtrl *m_pRedTxtCtrl;
        wxTextCtrl *m_pGreenTxtCtrl;
        wxTextCtrl *m_pBlueTxtCtrl;
        wxPanel    *m_pColorPanel;
        long m_rColor;
        long m_gColor;
        long m_bColor;
        DECLARE_EVENT_TABLE()
};

enum
{
    idMenuQuit  = 1000,
    idRED,
    idGREEN,
    idBLUE
};

BEGIN_EVENT_TABLE(ColorsFrame, wxFrame)
    EVT_CLOSE(ColorsFrame::OnClose)
    EVT_MENU(idMenuQuit, ColorsFrame::OnQuit)
    EVT_BUTTON(wxID_OK, ColorsFrame::OnOK)
END_EVENT_TABLE()

IMPLEMENT_APP(ColorsApp);

bool ColorsApp::OnInit()
{
    ColorsFrame* Frame = new ColorsFrame("Color Selector");
    Frame->Centre();
    Frame->Show();

    return true;
}

ColorsFrame::ColorsFrame(const wxString& title)
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition), m_rColor(0), m_gColor(0), m_bColor(0)
{
    wxMenuBar* mbar = new wxMenuBar();
    wxMenu* fileMenu = new wxMenu("");
    fileMenu->Append(idMenuQuit, "&Quit", "Quit the application");
    mbar->Append(fileMenu, "&File");
    SetMenuBar(mbar);

    CreateStatusBar(1);
    SetStatusText("Enter RGB values to see the color", 0);

    m_pColorPanel = new wxPanel(this, -1);
    wxBoxSizer *hBox = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer *vBox1 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer *vBox2 = new wxBoxSizer(wxVERTICAL);

    wxStaticText *rText = new wxStaticText(this,
                                           -1,
                                           "RED",
                                           wxPoint(5, 5),
                                           wxSize(35, 20) );
    wxStaticText *gText = new wxStaticText(this,
                                           -1,
                                           "GREEN",
                                           wxPoint(5, 5),
                                           wxSize(35, 20) );
    wxStaticText *bText = new wxStaticText(this,
                                           -1,
                                           "BLUE",
                                           wxPoint(5, 5),
                                           wxSize(35, 20) );
    m_pRedTxtCtrl = new wxTextCtrl(this,
                                   idRED,
                                   "0",
                                   wxPoint(5, 5),
                                   wxSize(30, 20),
                                   0,
                                   wxTextValidator(wxFILTER_NUMERIC) );
    m_pGreenTxtCtrl = new wxTextCtrl(this,
                                     idGREEN,
                                     "0",
                                     wxPoint(5, 5),
                                     wxSize(30, 20),
                                     0,
                                     wxTextValidator(wxFILTER_NUMERIC) );
    m_pBlueTxtCtrl = new wxTextCtrl(this,
                                    idBLUE,
                                    "0",
                                    wxPoint(5, 5),
                                    wxSize(30, 20),
                                    0,
                                    wxTextValidator(wxFILTER_NUMERIC) );
    wxButton *okButton = new wxButton(this,
                                      wxID_OK,
                                      "OK",
                                      wxDefaultPosition,
                                      wxSize(30, 30) );

    vBox1->Add(rText, 0, wxTOP | wxBOTTOM | wxLEFT | wxRIGHT, 5);
    vBox1->Add(gText, 0, wxTOP | wxBOTTOM | wxLEFT | wxRIGHT, 5);
    vBox1->Add(bText, 0, wxTOP | wxBOTTOM | wxLEFT | wxRIGHT, 5);

    vBox2->Add(m_pRedTxtCtrl, 0, wxTOP | wxBOTTOM | wxLEFT | wxRIGHT, 5);
    vBox2->Add(m_pGreenTxtCtrl, 0, wxTOP | wxBOTTOM | wxLEFT | wxRIGHT, 5);
    vBox2->Add(m_pBlueTxtCtrl, 0, wxTOP | wxBOTTOM | wxLEFT | wxRIGHT, 5);
    vBox2->Add(okButton, 0, wxTOP | wxBOTTOM | wxLEFT | wxRIGHT, 5);

    hBox->Add(vBox1);
    hBox->Add(vBox2);
    hBox->Add(m_pColorPanel, 1, wxEXPAND, 0);

    SetSizer(hBox);

    m_pColorPanel->SetBackgroundColour(wxColor(0, 0, 0) );
    m_pRedTxtCtrl->SetFocus();
}

void ColorsFrame::OnOK(wxCommandEvent& event)
{
    wxString str;

    str = m_pRedTxtCtrl->GetValue();
    str.ToLong(&m_rColor);

    str = m_pGreenTxtCtrl->GetValue();
    str.ToLong(&m_gColor);

    str = m_pBlueTxtCtrl->GetValue();
    str.ToLong(&m_bColor);

    if (m_rColor < 0 || m_rColor > 255 || m_gColor < 0 || m_gColor > 255 || m_bColor < 0 || m_bColor > 255)
    {
        wxMessageBox("An Incorrect value has been entered\nValue range is 0 - 255");
    }
    else
    {
        m_pColorPanel->SetBackgroundColour(wxColour(m_rColor, m_gColor, m_bColor) );
        Refresh();
    }
}

spectrum
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 207
Joined: Sat Jul 21, 2007 12:17 pm

Post by spectrum » Wed Jul 22, 2009 12:53 pm

hello,

i would try to create the controls adding wxTAB_TRAVERSAL style.

regards
spectrum

Dark_Phoenix
Knows some wx things
Knows some wx things
Posts: 48
Joined: Sat Jul 04, 2009 2:27 pm
Location: Houston, TX

Post by Dark_Phoenix » Wed Jul 22, 2009 1:14 pm

spectrum wrote:i would try to create the controls adding wxTAB_TRAVERSAL style.
regards
I did try that and it did not work... in fact, after I added that style (I added it to all 3 text controls and the button) I could no longer enter values into the text boxes and clicking the button would not do anything?!?

DavidHart
Site Admin
Site Admin
Posts: 4008
Joined: Thu Jan 12, 2006 6:23 pm
Location: IoW, UK

Post by DavidHart » Wed Jul 22, 2009 2:19 pm

Hi,

I suggest you put a wxPanel in your frame as its only child control. Then give the panel a sizer, and do everything else inside this, with controls parented by the panel.

Doing so cures various obscure bugs, including troubles with tab traversal.

Regards,

David

Dark_Phoenix
Knows some wx things
Knows some wx things
Posts: 48
Joined: Sat Jul 04, 2009 2:27 pm
Location: Houston, TX

Post by Dark_Phoenix » Wed Jul 22, 2009 6:37 pm

OK, Makes sense now.... On a related note, I am doing something different with it now. Instead of typing in an RGB value and displaying the color, I am using a wxColourPickerCtrl to let the user select a color and then display the value as well as change the background color of a panel to reflect that color. Everything works fine except the EVT_COLOURPICKER_CHANGED event does not seem to be processing, as the wxMessageBox inside the handler never comes up. Any ideas?

Code: Select all

#include <wx/wx.h>
#include <wx/clrpicker.h>

class ColorsApp : public wxApp
{
    public:
        virtual bool OnInit();
};

class ColorsFrame: public wxFrame
{
    public:
        ColorsFrame(const wxString& title);
        ~ColorsFrame() { }

    private:
        void OnChangeColour(wxColourPickerEvent &event);
        wxPanel *m_pPanel;
        DECLARE_EVENT_TABLE()
};

const int idChangeColour = 1000;

BEGIN_EVENT_TABLE(ColorsFrame, wxFrame)
    EVT_COLOURPICKER_CHANGED(idChangeColour, OnChangeColour)
END_EVENT_TABLE()

IMPLEMENT_APP(ColorsApp);

bool ColorsApp::OnInit()
{
    ColorsFrame* Frame = new ColorsFrame("Color Selector");
    Frame->Centre();
    Frame->Show();

    return true;
}

ColorsFrame::ColorsFrame(const wxString& title)
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(1000, 600), wxDEFAULT_FRAME_STYLE)
{
    CreateStatusBar(5);
    SetStatusText("Select a color to see its RGB value", 0);
    SetStatusText("RED =", 2);
    SetStatusText("GREEN =", 3);
    SetStatusText("BLUE =", 4);

    wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL);

    wxColourPickerCtrl *ColourPicker = new wxColourPickerCtrl(this,
                                                              wxID_ANY,
                                                              *wxBLACK,
                                                              wxDefaultPosition,
                                                              wxDefaultSize,
                                                              wxCLRP_USE_TEXTCTRL);
    m_pPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(900, 400) );

    vSizer->Add(ColourPicker,0, wxTOP | wxBOTTOM | wxCENTER, 10);
    vSizer->Add(m_pPanel, 0, wxTOP | wxBOTTOM | wxCENTER, 10);
    SetSizer(vSizer);

    m_pPanel->SetBackgroundColour(ColourPicker->GetColour() );
}

void ColorsFrame::OnChangeColour(wxColourPickerEvent &event)
{
    wxColour Colour = event.GetColour();
    m_pPanel->SetBackgroundColour(Colour);
    Refresh();
    wxMessageBox(Colour.GetAsString(wxC2S_CSS_SYNTAX) );
}

DavidHart
Site Admin
Site Admin
Posts: 4008
Joined: Thu Jan 12, 2006 6:23 pm
Location: IoW, UK

Post by DavidHart » Wed Jul 22, 2009 6:47 pm

That should be:
EVT_COLOURPICKER_CHANGED(idChangeColour, ColorsFrame::OnChangeColour)

Dark_Phoenix
Knows some wx things
Knows some wx things
Posts: 48
Joined: Sat Jul 04, 2009 2:27 pm
Location: Houston, TX

Post by Dark_Phoenix » Wed Jul 22, 2009 6:53 pm

DavidHart wrote:That should be:
EVT_COLOURPICKER_CHANGED(idChangeColour, ColorsFrame::OnChangeColour)
Argh! Darn newbie mistakes!

Still, that did not have any effect at all on the problem.... Still doing the same thing.

Dark_Phoenix
Knows some wx things
Knows some wx things
Posts: 48
Joined: Sat Jul 04, 2009 2:27 pm
Location: Houston, TX

Post by Dark_Phoenix » Wed Jul 22, 2009 7:40 pm

OK, Figured it out. I had an ID mismatch...

Code: Select all

const int idChangeColour = 1000;

Code: Select all

    wxColourPickerCtrl *ColourPicker = new wxColourPickerCtrl(this,
                                                              wxID_ANY, <----!!
                                                              *wxBLACK,

Dark_Phoenix
Knows some wx things
Knows some wx things
Posts: 48
Joined: Sat Jul 04, 2009 2:27 pm
Location: Houston, TX

Post by Dark_Phoenix » Wed Jul 22, 2009 8:47 pm

so here is my (first) finished app. Code is attached. If anyone cares to review of critic it, see if there are any errors I missed or perhaps a better / more efficient way of doing something, I would appreciate it. Thanks for the help!

Code: Select all

#include <wx/wx.h>
#include <wx/clrpicker.h>

class CApp : public wxApp
{
    public:
        virtual bool OnInit();
};

class CFrame: public wxFrame
{
    public:
        CFrame(const wxString& title);
        ~CFrame() { }

    private:
        void OnChangeColour(wxColourPickerEvent &event);
        void OnOK(wxCommandEvent& event);
        wxPanel            *m_pPanel;
        wxStatusBar        *m_pStatusBar;
        wxColourPickerCtrl *m_pColourPicker;
        wxTextCtrl         *m_pRedTextCtrl;
        wxTextCtrl         *m_pGreenTextCtrl;
        wxTextCtrl         *m_pBlueTextCtrl;
        DECLARE_EVENT_TABLE()
};

enum
{
    idColourPicker = 1000,
    idRedCtrl,
    idGreenCtrl,
    idBlueCtrl
};

BEGIN_EVENT_TABLE(CFrame, wxFrame)
    EVT_COLOURPICKER_CHANGED(idColourPicker, CFrame::OnChangeColour)
    EVT_BUTTON(wxID_OK, CFrame::OnOK)
END_EVENT_TABLE()

IMPLEMENT_APP(CApp);

bool CApp::OnInit()
{
    CFrame* Frame = new CFrame("Color Selector");
    Frame->Centre();
    Frame->Show();

    return true;
}

CFrame::CFrame(const wxString& title)
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(1000, 600) )
{
    int widths[5] = { 350, -1, -1, -1, 350 };
    m_pStatusBar = new wxStatusBar(this);
    m_pStatusBar->SetFieldsCount(5, widths);
    m_pStatusBar->SetStatusText("", 0);
    m_pStatusBar->SetStatusText("RED = 0", 1);
    m_pStatusBar->SetStatusText("GREEN = 0", 2);
    m_pStatusBar->SetStatusText("BLUE = 0", 3);

    wxPanel *ParentPanel = new wxPanel(this,
                                       wxID_ANY,
                                       wxDefaultPosition,
                                       wxSize(1000, 550) );
    wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer *hSizer = new wxBoxSizer(wxHORIZONTAL);

    m_pColourPicker = new wxColourPickerCtrl(ParentPanel,
                                            idColourPicker,
                                            *wxBLACK,
                                            wxDefaultPosition,
                                            wxDefaultSize,
                                            wxCLRP_USE_TEXTCTRL);
    m_pPanel = new wxPanel(ParentPanel,
                           wxID_ANY,
                           wxDefaultPosition,
                           wxSize(900, 400) );
    m_pRedTextCtrl = new wxTextCtrl(ParentPanel,
                                    idRedCtrl,
                                    "0",
                                    wxPoint(5, 5),
                                    wxSize(30, 20),
                                    0,
                                    wxTextValidator(wxFILTER_NUMERIC) );
    m_pGreenTextCtrl = new wxTextCtrl(ParentPanel,
                                      idGreenCtrl,
                                      "0",
                                      wxPoint(5, 5),
                                      wxSize(30, 20),
                                      0,
                                      wxTextValidator(wxFILTER_NUMERIC) );
    m_pBlueTextCtrl = new wxTextCtrl(ParentPanel,
                                     idBlueCtrl,
                                     "0",
                                     wxPoint(5, 5),
                                     wxSize(30, 20),
                                     0,
                                     wxTextValidator(wxFILTER_NUMERIC) );
    wxButton *okButton = new wxButton(ParentPanel,
                                      wxID_OK,
                                      "OK",
                                      wxDefaultPosition,
                                      wxSize(30, 30) );

    hSizer->Add(m_pRedTextCtrl, 0, wxALL, 10);
    hSizer->Add(m_pGreenTextCtrl, 0, wxALL, 10);
    hSizer->Add(m_pBlueTextCtrl, 0, wxALL, 10);
    hSizer->Add(okButton, 0, wxALL, 10);
    vSizer->Add(m_pColourPicker, 0, wxTOP | wxBOTTOM | wxALIGN_CENTER, 10);
    vSizer->Add(m_pPanel, 0, wxTOP | wxBOTTOM | wxALIGN_CENTER, 10);
    vSizer->Add(hSizer, 0, wxALIGN_CENTER_HORIZONTAL , 0);
    SetSizer(vSizer);

    m_pPanel->SetBackgroundColour(m_pColourPicker->GetColour() );
}

void CFrame::OnChangeColour(wxColourPickerEvent &event)
{
    wxColour Colour = event.GetColour();
    m_pPanel->SetBackgroundColour(Colour);
    Refresh();
    m_pStatusBar->SetStatusText(wxString::Format("RED = %d", Colour.Red() ), 1);
    m_pStatusBar->SetStatusText(wxString::Format("GREEN = %d", Colour.Green() ), 2);
    m_pStatusBar->SetStatusText(wxString::Format("BLUE = %d", Colour.Blue() ), 3);
}

void CFrame::OnOK(wxCommandEvent& event)
{
    wxString str;
    long rColour = 0, gColour = 0, bColour = 0;
    m_pRedTextCtrl->GetValue().ToLong(&rColour);
    m_pGreenTextCtrl->GetValue().ToLong(&gColour);
    m_pBlueTextCtrl->GetValue().ToLong(&bColour);

    if (rColour < 0 || rColour > 255 || gColour < 0 || gColour > 255 || bColour < 0 || bColour > 255)
    {
        wxMessageBox("An Incorrect value has been entered\nValue range is 0 - 255");
    }
    else
    {
        m_pPanel->SetBackgroundColour(wxColour(rColour, gColour, bColour) );
        m_pColourPicker->SetColour(wxColour(rColour, gColour, bColour) );
        Refresh();
        m_pStatusBar->SetStatusText(wxString::Format("RED = %d", rColour), 1);
        m_pStatusBar->SetStatusText(wxString::Format("GREEN = %d", gColour), 2);
        m_pStatusBar->SetStatusText(wxString::Format("BLUE = %d", bColour), 3);
    }
}

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria » Thu Jul 23, 2009 1:29 am

After a quick look it look good, only noticed this :

Code: Select all


void CFrame::OnOK(wxCommandEvent& event)
{
    wxString str; // <---- this variable is never used
    long rColour = 0, gColour = 0, bColour = 0;
    m_pRedTextCtrl->GetValue().ToLong(&rColour);
    m_pGreenTextCtrl->GetValue().ToLong(&gColour);
    m_pBlueTextCtrl->GetValue().ToLong(&bColour);
Also, in all code conventions I used, constants (like IDs) where written in ALL_CAPS (though that's not an error if you do it otherwise, just a matter of code conventions)

I also noticed you implicitely passed srings literals to wxStrings :

Code: Select all

CFrame* Frame = new CFrame("Color Selector");
This is OK in wxWidgets 2.8 ANSI builds, and wxWidgets 2.9/3.0 (upcoming), but will fail on wxWidgets 2.8 Unicode - so if you expect to need Unicode support before wxWidgets 3.0 (or 2.9 if you're willing to use unstable versions), surround you literals with wxT()

apart from that, good job :)
"Keyboard not detected. Press F1 to continue"
-- Windows

Dark_Phoenix
Knows some wx things
Knows some wx things
Posts: 48
Joined: Sat Jul 04, 2009 2:27 pm
Location: Houston, TX

Post by Dark_Phoenix » Thu Jul 23, 2009 12:13 pm

Auria wrote: wxString str; // <---- this variable is never used
Wow, never noticed that!
I also noticed you implicitely passed srings literals to wxStrings
so if you expect to need Unicode support before wxWidgets 3.0 (or 2.9 if you're willing to use unstable versions), surround you literals with wxT()
Never really messed with unicode before, but probably not a bad practice to get into
apart from that, good job :)
Thanks!

Post Reply