Code::Blocks Forums

Developer forums (C::B DEVELOPMENT STRICTLY!) => Development => Topic started by: thomas on December 22, 2005, 08:44:03 pm

Title: wxJoy
Post by: thomas on December 22, 2005, 08:44:03 pm
Does anyone know a method to construct a dialog with a wxGrid control which is not pure madness?

I have tried creating an XRC file with a wxGrid element, this throws an exception "no handler for control of type wxGrid".
I have tried putting a wxPanel into the XRC file instead, and adding the wxGrid to the panel. This does not resize the control properly.
I have tried calling GetParent() on the wxPanel, removing the panel and adding the wxGrid instead. This crashes with a null pointer exception in parent->Remove(), whether you use the version working on indices or on pointers.

The only thing I have not tried is hardcoding the whole dialog... there must be a reasonable solution to add one single control to a dialog that is loaded from XRC?

Title: Re: wxJoy
Post by: rickg22 on December 23, 2005, 12:25:37 am
I think you need to use subclassing here... XRC allows for subclasses for certain kind of objects, but I'm not acquainted with it.
Title: Re: wxJoy
Post by: Game_Ender on December 23, 2005, 12:54:44 am
If you give me about 18 hours I can upload a working xrc based dialog (.h, .cpp, and .xrc files) with a wxGrid sizer generated from Dialog Blocks.  Dialog Blocks is a very awesome program and definitely work the price for all the development speed up it provides.  I hope wxSmith will reach its level, because have a RAD integrated with the IDE would be even better.

EDIT: Anything specific you want it to be able to do?
Title: Re: wxJoy
Post by: thomas on December 23, 2005, 01:18:47 pm
This is so typically wxWidgets. I am spending the second day now on one freaking dialog. If you want anything more complicated than a button and a static text, you're totally lost...

Rick: This subclassing stuff is no alternative. I looked into that too, and it is an evil hack, even for wxWidgets. There is no documentation for this either, except an article written by three people who have tampered with it some day and somehow got it to run for themselves.

Game_Ender: Just a wxGrid with two columns is needed, no fancy stuff, just two columns and a couple of rows where the user can enter data. My problem is not writing the XRC, though. That's easy.

The problem is that wxWidgets 2.6.2 has no XRC handler for wxGrid:

D:\wxWidgets-2.6.2\src\xrc>grep IsOfClass *.cpp
xh_bmp.cpp:    return IsOfClass(node, wxT("wxBitmap"));
xh_bmp.cpp:    return IsOfClass(node, wxT("wxIcon"));
xh_bmpbt.cpp:    return IsOfClass(node, wxT("wxBitmapButton"));
xh_bttn.cpp:    return IsOfClass(node, wxT("wxButton"));
xh_cald.cpp:    return IsOfClass(node, wxT("wxCalendarCtrl"));
xh_chckb.cpp:    return IsOfClass(node, wxT("wxCheckBox"));
xh_chckl.cpp:    return (IsOfClass(node, wxT("wxCheckListBox")) ||
xh_chckl.cpp:            IsOfClass(node, wxT("wxCheckList")) ||
xh_choic.cpp:    return (IsOfClass(node, wxT("wxChoice")) ||
xh_choicbk.cpp:    return ((!m_isInside && IsOfClass(node, wxT("wxChoicebook"))) ||
xh_choicbk.cpp:            (m_isInside && IsOfClass(node, wxT("choicebookpage"))));
xh_combo.cpp:    return (IsOfClass(node, wxT("wxComboBox")) ||
xh_datectrl.cpp:    return IsOfClass(node, wxT("wxDatePickerCtrl"));
xh_dlg.cpp:    return IsOfClass(node, wxT("wxDialog"));
xh_frame.cpp:    return IsOfClass(node, wxT("wxFrame"));
xh_gauge.cpp:    return IsOfClass(node, wxT("wxGauge"));
xh_gdctl.cpp:    return IsOfClass(node, wxT("wxGenericDirCtrl"));
xh_html.cpp:    return IsOfClass(node, wxT("wxHtmlWindow"));
xh_listb.cpp:    return (IsOfClass(node, wxT("wxListBox")) ||
xh_listbk.cpp:    return ((!m_isInside && IsOfClass(node, wxT("wxListbook"))) ||
xh_listbk.cpp:            (m_isInside && IsOfClass(node, wxT("listbookpage"))));
xh_listc.cpp:    return IsOfClass(node, wxT("wxListCtrl"));
xh_mdi.cpp:    return (IsOfClass(node, wxT("wxMDIParentFrame")) ||
xh_mdi.cpp:            IsOfClass(node, wxT("wxMDIChildFrame")));
xh_menu.cpp:    return IsOfClass(node, wxT("wxMenu")) ||
xh_menu.cpp:               (IsOfClass(node, wxT("wxMenuItem")) ||
xh_menu.cpp:                IsOfClass(node, wxT("break")) ||
xh_menu.cpp:                IsOfClass(node, wxT("separator")))
xh_menu.cpp:    return IsOfClass(node, wxT("wxMenuBar"));
xh_notbk.cpp:    return ((!m_isInside && IsOfClass(node, wxT("wxNotebook"))) ||
xh_notbk.cpp:            (m_isInside && IsOfClass(node, wxT("notebookpage"))));
xh_panel.cpp:    return IsOfClass(node, wxT("wxPanel"));
xh_radbt.cpp:    return IsOfClass(node, wxT("wxRadioButton"));
xh_radbx.cpp:    return (IsOfClass(node, wxT("wxRadioBox")) ||
xh_scrol.cpp:    return IsOfClass(node, wxT("wxScrollBar"));
xh_scwin.cpp:    return IsOfClass(node, wxT("wxScrolledWindow"));
xh_sizer.cpp:             (m_isInside && IsOfClass(node, wxT("sizeritem"))) ||
xh_sizer.cpp:             (m_isInside && IsOfClass(node, wxT("spacer")))
xh_sizer.cpp:    return (IsOfClass(node, wxT("wxBoxSizer"))) ||
xh_sizer.cpp:           (IsOfClass(node, wxT("wxStaticBoxSizer"))) ||
xh_sizer.cpp:           (IsOfClass(node, wxT("wxGridSizer"))) ||
xh_sizer.cpp:           (IsOfClass(node, wxT("wxFlexGridSizer"))) ||
xh_sizer.cpp:           (IsOfClass(node, wxT("wxGridBagSizer")));
xh_sizer.cpp:    return (!m_isInside && IsOfClass(node, wxT("wxStdDialogButtonSizer"))) ||
xh_sizer.cpp:           (m_isInside && IsOfClass(node, wxT("button")));
xh_slidr.cpp:    return IsOfClass(node, wxT("wxSlider"));
xh_spin.cpp:    return IsOfClass(node, wxT("wxSpinButton"));
xh_spin.cpp:    return IsOfClass(node, wxT("wxSpinCtrl"));
xh_split.cpp:     return IsOfClass(node, wxT("wxSplitterWindow"));
xh_statbar.cpp:    return IsOfClass(node, wxT("wxStatusBar"));
xh_stbmp.cpp:    return IsOfClass(node, wxT("wxStaticBitmap"));
xh_stbox.cpp:    return IsOfClass(node, wxT("wxStaticBox"));
xh_stlin.cpp:    return IsOfClass(node, wxT("wxStaticLine"));
xh_sttxt.cpp:    return IsOfClass(node, wxT("wxStaticText"));
xh_text.cpp:    return IsOfClass(node, wxT("wxTextCtrl"));
xh_tglbtn.cpp:    return IsOfClass(node, wxT("wxToggleButton"));
xh_toolb.cpp:                if (!IsOfClass(n, wxT("tool")) &&
xh_toolb.cpp:                    !IsOfClass(n, wxT("separator")) &&
xh_toolb.cpp:    return ((!m_isInside && IsOfClass(node, wxT("wxToolBar"))) ||
xh_toolb.cpp:            (m_isInside && IsOfClass(node, wxT("tool"))) ||
xh_toolb.cpp:            (m_isInside && IsOfClass(node, wxT("separator"))));
xh_tree.cpp:    return IsOfClass(node, wxT("wxTreeCtrl"));
xh_unkwn.cpp:    return IsOfClass(node, wxT("unknown"));
xh_wizrd.cpp:    return IsOfClass(node, wxT("wxWizard")) ||
xh_wizrd.cpp:                (IsOfClass(node, wxT("wxWizardPage")) ||
xh_wizrd.cpp:                 IsOfClass(node, wxT("wxWizardPageSimple")))


I created a wxGrid manually and added it to a sizer, and assigned that sizer to the parent panel. Creating dialogs programmatically is the kind of stuff which I try to avoid, but there seems no other way.
However, unless you explicitely give the wxGrid an absolute size, it renders in a size of about 60x20, no matter what kind of sizer you provide or whether you call FitInside() or SetSizeHints(). And when given the size of its parent, then it is of course bigger than the parent and adds a horizontal scroll bar. Stupid me, of course "same size" means "make it bigger", I should have known...

    wxPanel *panel = XRCCTRL(*this, "panel", wxPanel);

//    wxGrid *grid = new wxGrid(panel, -1, wxDefaultPosition, wxDefaultSize);    // see left side of image
    wxGrid *grid = new wxGrid(panel, -1, wxDefaultPosition, panel->GetSize());  // ow man...
    grid->CreateGrid(25,2);

    //grid->AutoSizeColumns(true); // sizes according to the *contents*, not do the bounding box
    grid->SetColSize(0, panel->GetSize().x / 2);  // duh...
    grid->SetColSize(1, panel->GetSize().x / 2);
    grid->SetRowLabelSize(0);


    wxGridSizer *s = new wxGridSizer(1,1);
    //wxFlexGridSizer *s = new wxFlexGridSizer( 1, 1, 0, 0);  // flex grid does not work any better
    //s->AddGrowableCol(0);    s->AddGrowableRow(0);

    s->Add(grid, 0, wxEXPAND);

    //s->FitInside(panel); // does nothing
    panel->SetSizer(s);
    //s->FitInside(panel); // does nothing

    panel->SetBackgroundColour(*wxRED); // let's see the panel's full size...


(http://img477.imageshack.us/img477/532/size0lk.png)

I am seriously thinking about simply adding a dozen rows of textedit controls by hand - this is probably easier.
Title: Re: wxJoy
Post by: takeshimiya on December 23, 2005, 07:55:56 pm
I am seriously thinking about simply adding a dozen rows of textedit controls by hand - this is probably easier.

I will do that, because entering text in wxGrid by default sucks, you have to do a double-click to let it enter text.
Title: Re: wxJoy
Post by: zmodem on March 08, 2006, 06:00:17 am
Didn't realize this thread was a bit old when I started typing this out.  Heh, oh well, hopefully someone has figured this out before now...
******

Yes, you're right, XRC does not at all support adding grids.  Definately a major shortcoming of XRC.  Hopefully it will be fixed soon. 

Until then, use a foreign window

Code
int ID_GRID = wxNewId();

wxXmlResource::Get()->LoadFrame(this, parent, "ID_MAIN_FRAME");
wxGrid mygrid = new wxGrid(....);
wxXmlResource::Get()->AttachUnknownControl( "ID_GRID", mygrid );

Then, in the XRC file, enter this where you want the grid...

Code
<object class="unknown" name="ID_GRID">
    <size> .... </size>
</object>

HTH

--cheers