Author Topic: wxSmith extending widgets  (Read 9383 times)

Offline frithjofh

  • Regular
  • ***
  • Posts: 376
wxSmith extending widgets
« on: December 30, 2007, 07:08:52 pm »
hi everybody,

not sure if this is a good idea, but i wanted to suggest this:

a way that i can add a widget to a layout through wxsmith when the widget is not a pure panel for eexample but a new class derived from wxpanel but only extended by members and methods which do not interfer with the actual look of the widget, so it could be represented through the normal way of representing a wxpanel.

the idea behind it was, that i have a notebook with several pages. every page contains a closed set of information. only 90% of the information of this set is actualy presented to the user through widgets on the page but the remaining 10% are not visible data. i would do this creating a new class inheriting all of wxpanel, put the widgets in it and add the non-visible stuff, but then i cant use wxsmith, cant i ? if i code it somewhere else, i split into two what really should be in one place, the 90% in the panel and managed by wxsmith and the 10% in some file or even in the same file, but just somewhere else...

well, i'm definitly no very advanced or even good programmer, just learning around  :) if the idea is crapp, well, then its crapp ...

also missing badly a feature to do all those pages of my notebook in different files and still have them and the overall layout managed by wxsmith. like beeing able to design some panel and then insert this panel in another layout like it was just a stanadrd widget (through a listfield in the editor or so ... ) when i'm working on the containing layout the inserted sublayout is only a greyed-out static image, when i double-click the sublayout, the editor changes to grey out the containing layout and loads the sublayout ready to work with it... )

well, soon here is the day of "reyes" , the day of kings, the three biblical kings of bethlehem. they are the guys who bring the gifts here, not santa, so maybe i´m still on shedule with my wishes  :D

regards and greetings from asturias

nause
architect with some spare time  -  c::b compiled from last svn  -   openSuSE leap x86_64  -  AMD FX-4100

Offline byo

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 836
Re: wxSmith extending widgets
« Reply #1 on: December 30, 2007, 11:55:42 pm »
Hi.

ACtually there's a way to use some class instead of wxPanel and wxSmith will still see this widget as standard wxPanel item.
If you select panel and look into set of properties you will find one called "Class name". This property may be used to inform wxSmith that it should create class of different name instead of standard wxPanel. The only requirement is that such class would have to provide exactly the same constructor as original class (wxSmith will use same argument list as it would in case of wxPanel).

Here's an example of such item:

Code
class SomeClass: public wxPanel
{
    public:
        SomeClass(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name):
            wxPanel(parent,id,pos,size,style,name)
        {
            // Some extra initialization here
        }

        // Some extra stuff here
};

After you enter "SomeClass" in "Class name" property, wxSmith will create SomeClass instead of wxPanel.

If you don't use XRC files, the only extra requirement here is that you will have to add #include "SomeClass.h" manually into .h file of the resource (missing include will come out when you try to compile so it's easy to find).

When using XRC files, wxSmith will use something called subclassing (it's built into XRC loading system and allows to use one class instead of another) but it would require much more work.


Other solution is that you create separate wxPanel resource and insert this one into wxNotebook instead of wxPanel class. By using such solution you will have the main resource with wxNotebook in one editor and the content of each notebook's page in separate resources/editors (usually should be one resource per one page but that's not a rule). This can be done in few ways, I'll describe the easiest one:

  • For each notebook's page which should be in separate resource, you have to create new wxPanel resource.
    In "New wxPanel resource" dialog, expand advanced options, in "Constructor arguments" select all checkbockses in first column and unselect all in the second one, next copy this: "long style,const wxString& name" into "Custom arguments" - after that new resource will have same list of arguments as wxPanel class, other options may be as you wish.
  • When panel is ready, open resouce with wxNotebook
  • Now we have to add panels from other resources into the notebook, we will do this simillarily to the solution used before:
    add normal wxPanel pages and then change the "Class name" property to name of resource with required page
    finally add missing #include entries

Now you have one window divided into few resources.

Of course that's not as easy as "integrated" version, but hopefully this will be implemented one day :) I rather won't be able to implement it before the day of Reyes (hmm, I don't know yet when I'll start implementing this). But it definitely shouldn't wait forever.

Regards
   BYO

Offline frithjofh

  • Regular
  • ***
  • Posts: 376
Re: wxSmith extending widgets
« Reply #2 on: December 31, 2007, 01:09:42 am »
hi,

what a fine answer. allready put myself to work to try it out, and it works so far very fine. till now i only used the "other" solution, the "first" solution will have to wait. sadly code::blocks crashed after compiling and running the code for the first time, i just had the chance to get a glance at the newly insertred page, it seemed fine with a few sizer issues i had'nt the time to even see clearly. the really lacking thing was the notebook wxs file in the editor which showed only a empty wxpanel (as it seems, because shortly after changing to the file c::b crashed ). i atached the rpt file. how nice would it be to just see a static image of the page and not just the empty placeholder... :D

the ugly thing is, after the crash everything still works fine, the programm compiles, i had to add the new .cpp and .h of the notebook page manually though, they had just disapeared from the projects tab ... but i could add them and all is working. but the new .wxs file ( it was still on disk aperently) i could add manually to the project tab, but it also vanished from resource tab, and i dont know who i can make it reappear other than digging into the projects .cbp file and adding it there. i did that some time ago in another project and it is not very pleasant, especially because i was not sure to break anything. but still: it's just one line ...  :?

for today it's allready too late for me to go on, can't think strait anymore, tomorrow more...

thanks for the quick help

regards

nausea

ps: could'nt resist: i made the changes to paliate the crash and all fine, but the inserted page does not adapt size... it just stays the same size allthough it is an exact copy of a page that does resize correctly... ???

[attachment deleted by admin]
« Last Edit: December 31, 2007, 01:33:29 am by nausea »
architect with some spare time  -  c::b compiled from last svn  -   openSuSE leap x86_64  -  AMD FX-4100

Offline byo

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 836
Re: wxSmith extending widgets
« Reply #3 on: January 01, 2008, 10:05:14 pm »
Thanks for the crash report, looks like some ugly bug hard to find :(. I've added berlios report so I won't forget about it.

The image of page instead of empty panel may be a problem for now - but it will work like a charm as soon as adding one resource into another is implemented (I don't plan any other solution now since it would be quite hard to code).

And I also had some problems with size of page. I don't know if its same as in your case but I haven't had any other problem so far. While I was doing some tests it looked like inserted page don't use the size set in parent resource - the most probable reason is that the sizer-layout system does not always allow to resize items. Also note that wxWidgets tends to automatically change sizes in some situations (like when there's only one child item). But it may also be bug in wxSmith.

Regards
  BYO

Offline frithjofh

  • Regular
  • ***
  • Posts: 376
Re: wxSmith extending widgets
« Reply #4 on: March 23, 2008, 08:48:25 pm »
hi, byo,

a long time ago (before code::blocks 8.02 that is :D ) we had this post and it really served my needs very well ... very much satisfied ...

but: (allways there is this terrible "but") one day it ocurred to me that it would be nice to pass an object as an additional argument to a wxPanel created as in above thread. the reasons were, that i liked this object to initialise a const reference member of the panel and i wanted to initialise it in the initialisation-list of it's constructor ( well, i could just put a pointer in the panel and initalise it via a puplic method called from the outside, but i liked better the way of the ref ).

well when creating a wxPanel resource via the wxSmith menue and "Add wxPanel" in the uppopping dialog there is this option of putting additional arguments. i put "long style,const wxString& name" in there ( without the "" ) and additonally my new argument (commaseparated). now: in the newly generated files this argument shows up allright, put i does not show up in the base file where i insert this wxPanel. there only appears a call to the constructor with the arguments of a wxPanel, nothing more. why then can i give these extra arguments at all ... ?

really the only functionality now seems to be having the mere graphical representation of these added custom-tailored elements in the wxSmith editor, but nothing more ...

is it posible to make this additional arguments really show up in the code?

best wishes and greetings from asturias

nausea
« Last Edit: March 23, 2008, 08:50:02 pm by nausea »
architect with some spare time  -  c::b compiled from last svn  -   openSuSE leap x86_64  -  AMD FX-4100

Offline byo

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 836
Re: wxSmith extending widgets
« Reply #5 on: March 26, 2008, 12:04:27 am »
Hi again :) Nice to hear that my solution worked well before :).

For your current problem there's also a solution. Instead of adding wxPanel item inside the "parent" resource you will have to put something called "Custom". It's a little bit harder to work on but it's nothing more that just few minutes of initial set-up and you're ready to work :).

Here's the guide:
  • Create child wxPanel resource as before, you may customize constructor arguments, don't have to manually add extra includes
  • In the parent resource add "Custom" item - it's the last one on the Standard palette
  • Go to properties of this Custom item
  • Change "Class Name" property to name of the wxPanel resource
  • Enter name of panel's header file in the "Include file" property
  • Check the "Use "" for includes ..." so it will point to local file name
  • Open the "Creating code" property in editor (using ... button) - here you have some skeleton of how to create the child item. Here's some detailed description on how to use this property:

This property shows how wxSmith should build source code which will generate this custom item. It may contain any valid c++ code. Some things can be written using macro-like form like $(ID). Those macros are replaced with proper equivalents for this item:
  • $(THIS) - it's replaced with variable name of this custom item
  • $(CLASS) - it's replaced with name of item's class
  • $(PARENT) - replaced with pointer to parent item
  • $(ID) - replaced with item's id
  • $(POS) - replaced with item's position
  • $(SIZE) - replaced with item's size
  • $(STYLE) - replaced with items' style
  • $(NAME) - replaced with item's name (item's id represented as wxString)

In this code you can put other values passed to item's constructor, like:
Code
$(THIS) = new $(CLASS)($(PARENT),$(ID),$(POS),$(SIZE),elements);

This code will require the item to have constructor simillar to this one:
Code
SomeItem::SomeItem(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, SomeArray& elems)

So you can pass any value into item's constructor. The only requirement is that this value (int the example above it's elements variable) must be known in scope of creating code - so it may be member variable of parent resource class, some variable passed into parent resource constructor etc. It can also be some local variable declared in constructor but it will have to be declared (and probably initialized) before the //(*Initialize(...)  ... //*) code section.

Hope this description will be enough :) In case of any questions just write here :)

Regards
   BYO