marcp
marcp

Reputation: 1227

Is this possible with wxWidgets?

I have been learning wxWidgets for the last week, both by using IDEs and writing C++ code. I'm starting to despair at ever getting something that looks nice, as the ability to position items seems very limited.

I'm porting a large-ish project from C++Builder to VStudio, for cost reasons. I've got quite a few dialogs to recreate. They generally contain varying combinations of a 'blocks' of input - for lack of a better word. I chose wxWidgets for my GUI because I thought I could build up the dialogs in code from functions that produce a row of the form. For example in the dialog shown below I might have functions CreateLabelEdit, CreateLabelCombo, CreateBoldLabel, etc. I'm actually having some success at that part but failing miserably in styling the dialog.

enter image description here

Here are some of the design criteria from this particular form:

  1. All of the inputs are left aligned and different widths appropriate to their contents.

  2. The input labels are all right aligned.

  3. The alignment point (ie. the width of the column containing the input labels is the same across all dialogs, and the widths of the various inputs is as well. Of course there are exceptions!

  4. Other types of labels are aligned at a different spot. BoldLabels in this case.

Basically I want to control the size, location and alignment of my objects. Is this a case of having the wrong mindset for the tool I have chosen? Or can these types of things be accomplished with this tool?


PARTIAL SOLUTION I've tried using absolute positions mixed with sizers and that doesn't work at all.

Then I tried using a flexgrid sizer to do a part of the example, If I can make one of the blocks then I can stitch together multiple blocks. It's all good except when I set the width of the first column using SetItemMinSize, as @VZ suggested, that item loses it's sizerflag settings:

form4::form4() :wxDialog(nullptr, wxID_ANY, "title")
{
    wxSizerFlags flagT1(1);
    flagT1.Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT).Border(wxTOP | wxLEFT, 10);
    wxSizerFlags flagT2(1);
    flagT2.Align(wxALIGN_CENTER_VERTICAL ).Border(wxTOP | wxLEFT, 10);
    wxSizerFlags flagT3(1);
    flagT3.Align(wxALIGN_CENTER_VERTICAL).Border(wxTOP | wxLEFT| wxRIGHT, 10);

    wxBoxSizer* bSize = new wxBoxSizer(wxVERTICAL);
    wxStaticText* _Text = new wxStaticText(this, wxID_ANY, "this should be bold");
    wxFont _Font = _Text->GetFont();
    _Font.MakeBold();
    _Font.SetPixelSize(_Font.GetPixelSize()*1.1);
    _Text->SetFont(_Font);
    bSize->Add(_Text, wxSizerFlags().Border(wxTOP, 10).Center());
    bSize->Add(new wxStaticText(this, wxID_ANY, "this should be bold"), 

    wxSizerFlags().Border(wxTOP, 10).Center());
    wxFlexGridSizer* bSizer = new wxFlexGridSizer(3,0,0);
    _Text = new wxStaticText(this, wxID_ANY, "bob");
    // bSizer->SetItemMinSize(_Text, wxSize(150, -1)); //this has no effect here
    bSizer->Add(_Text, flagT1);
    bSizer->SetItemMinSize(_Text, wxSize(150, -1));// loses styling of flagT1
    bSizer->Add(new wxTextCtrl(this, wxID_ANY, "default_value", wxDefaultPosition, wxSize(150, -1)), flagT2);
    bSizer->Add(new wxStaticText(this, wxID_ANY, "cm", wxPoint(200, 20)), flagT3);

    bSizer->Add(new wxStaticText(this, wxID_ANY, " longer"), flagT1);
    bSizer->Add(new wxTextCtrl(this, wxID_ANY, "default_value2", wxPoint(-1, -1), wxSize(150, -1)), flagT2);
    bSizer->Add(new wxStaticText(this, wxID_ANY, "cm", wxPoint(200, 20)), flagT3);

    bSizer->Add(new wxStaticText(this, wxID_ANY, "bob"), flagT1);
    bSizer->Add(new wxTextCtrl(this, wxID_ANY, "default_value3", wxPoint(-1, -1), wxSize(150, -1)), flagT2);
    bSizer->Add(new wxStaticText(this, wxID_ANY, "cm", wxPoint(200, 20)), flagT3);

    bSize->Add(bSizer);

    bSize->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), wxSizerFlags(0).Border(wxALL, 10));
    this->SetSizerAndFit(bSize);
    //  this->Layout();
    this->Centre(wxBOTH);
}

produces this:

enter image description here

Upvotes: 1

Views: 694

Answers (1)

VZ.
VZ.

Reputation: 22678

This particular dialog is not especially simply to create in wxWidgets because it can't be done with a simple wxFlexGridSizer. You have several choices:

  1. If you're willing to compromise slightly, move the bold labels entirely into the left column. Then it becomes a simple two column wxFlexGridSizer and creating it should be very easy in either the code or a dialog editor.
  2. If you want to keep precisely this layout but still would like to use wxFlexGridSizer, you need to have several of them and manually align their first columns. The way to do is to find the width of the longest label (use GetTextExtent()) and set the minimal item size (SetItemMinSize()) to it for all sizers.
  3. If you don't want to bother with width computation but still want to have this exact layout, you can also use wxGridBagSizer. Personally, I don't recommend using it because it's messier (you have to manually track columns/rows), but it does allow to do exactly what you want.

Upvotes: 2

Related Questions