Author Topic: wxJoy  (Read 6060 times)

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
wxJoy
« 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?

"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline rickg22

  • Lives here!
  • ****
  • Posts: 2283
Re: wxJoy
« Reply #1 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.

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: wxJoy
« Reply #2 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?

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: wxJoy
« Reply #3 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...




I am seriously thinking about simply adding a dozen rows of textedit controls by hand - this is probably easier.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

takeshimiya

  • Guest
Re: wxJoy
« Reply #4 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.

zmodem

  • Guest
Re: wxJoy
« Reply #5 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