Difference between revisions of "WxSmith Tutorial & Pointers"

From Code::Blocks
m (Request deletion)
 
(41 intermediate revisions by 6 users not shown)
Line 1: Line 1:
= "Hello world" Tutorial =
+
[[Category:Deletion Requests]]
 
+
This page is outdated, more recent tutorials can be found on [[WxSmith tutorials]]
Since wxSmith is able to do something already it's high time to write some tutorial on how to use it.
 
At the very beginning I must point - to use wxSmith You MUST have wxWidgets compiled (version 2.6 or more), build instructions can be found [[Compiling wxWidgets 2.6.1 to develop Code::Blocks (MSW)|here]]
 
 
 
WARNING: wxSmith is still unstable so use it at Your own risk. And there's no undo yet. I warned You ;)
 
 
 
Ok, let's start :)
 
 
 
 
 
 
 
== wxWidgets starts to breathe ==
 
 
 
 
 
 
 
wxSmith can be used inside any wxWidgets project. Currently we have only one option to easily create wxWidgets app.
 
Simply select '''File -> New Project -> wxWidgets Application''' from menu.
 
If You have compiled wxWidgets using wiki tutorial, select '''Using wxWidgets DLL''' in '''Project Options'''. Hit Create and save project.
 
If You're running on Windows, You will probably have to change WX_DIR Custom variable. It should point to root wxWidgets directory and it can be changed in '''Project -> Build Options''' menu on '''Custom variables''' tab.
 
 
 
After this step You should be able to produce app like this:
 
 
 
[[Image:WXSMITH1.JPG]]
 
 
 
 
 
 
 
=== Let's add some fireworks ===
 
 
 
 
 
 
 
Now it's time to fill empty frame with our "Hello World" message. We will do this by placing panel over frame.
 
Select '''wxSmith -> Add Panel''' from menu. If You do this for the first time in project, it should display this message box:
 
 
 
[[Image:WXSMITH2.JPG]]
 
 
 
Just click Yes, it will bring up some configuration dialog. You can set-up following options here:
 
* Class Name - name of class which will contain out panel
 
* Header File / Source File - files which will contain panel's class
 
* Xrc File - selecting this option allow to use xrc file containing panel's data
 
 
 
In our tutorial we will use class named HelloWorldPnl (notice that usually when typing class name, header and source file names are generated automatically). Config dialog should look like this:
 
 
 
[[Image:WXSMITH3.JPG]]
 
 
 
Click Create and we have our panel right in editor
 
 
 
== Building window ==
 
 
 
 
 
wxWidgets comes with something called ''Sizers''. But what is this for?
 
If You have been working with java you should remember something called Layout managers. Implementation in wxwidgets differs a little bit but it does almost the same.
 
Ok, but let's put some explanation here:
 
Usually when adding items into windowses You must specify item's position and size. wxWidgets tries to automate this proces and it uses sizers for that. They are automatically positioning and sizing window items. It has one big adventage. When You write cross-platform application, You can not assume that fonts, buttons and many other things are the same. It can even happen on same platform. When You use sizers, You don't have to worry about that. All is done automatically. And one more thing - sizers can even position and size window items when window change size.
 
So, let's add some sizers here, or one more thing before...
 
 
 
 
 
=== How can I add something ? ===
 
 
 
 
 
In newly opened editor You can see 8 black boxes around something which looks like button without label
 
 
 
[[Image:WXSMITH4.JPG]]
 
 
 
These black boxes are surrounding currently selected item and in our case it's whole panel.
 
Adding new item is simply done by clicking on one of buttons in palette at the bottom of C::B window.
 
 
 
[[Image:WXSMITH5.JPG]]
 
 
 
These buttons should have small pictures saying what they will add. If You're not sure, hold mouse over picture and after few seconds You should see name of wxWidgets class - that's our item.
 
 
 
New items are added relatively to current selection. You can add new item in one of three ways:
 
* Before currently selected widget
 
* After currently selected widget
 
* Into currently selected widget
 
You can change insert method inside Palette (it should be easy to find ;)).
 
Note that not allways all three settings will be accessible. For example You can not add anything into button. There are also some special situations when You can not add new item:
 
* When item has sizer inside, it can not contain anything else. Items can be added into this sizer only
 
* When item has anything but sizer inside, You can not add sizer into it.
 
* Spacer (empty field added into sizer instead of real item) can be added into sizers only
 
 
 
Always make sure that valid item is selected and valid insertion method is choosen.
 
 
 
 
 
=== Adding items ===
 
 
 
 
 
There are 5 types of sizers in wxWidgets, 4 are currently supported inside wxSmith (wxGridBagSizer is not supported yet). If You wish to learn about sizers i propose [http://www.wxwidgets.org/manuals/2.6.1/wx_sizeroverview.html#sizeroverview wxWidgets doccumentation]
 
In our sample we will add wxFlexGridSizer. To do this follow me:
 
 
 
* Select panel by clicking on it
 
* Click on wxFlexGridSizer button (third in Layout row)
 
 
 
You proably noticed that our panel decreased it's sizer. This is made because sizer tries to automatically adjust minimal size of it's parent. And there's additional red border - it shows where sizer is located.
 
 
 
Because this is "Hello World" application, we need this text here. We will put it into created sizer. To do this:
 
 
 
* Select sizer (click somewhere insided red border)
 
* Make sure that Insetion Type is ''Into''
 
* Click on wxStaticText button
 
* Click on newly created text item (should be "Label") and go to properties (It's inside Resources tab at the left of C::B)
 
* Change Label property to "Hello World !!"
 
 
 
And because this text looks so lonely, we will add button here:
 
 
 
* Select Newly created text
 
* Chose "After" Insertion type
 
* Click on Button's icon
 
 
 
Ok, now we have this:
 
 
 
[[Image:WXSMITH6.JPG]]
 
 
 
But I would preffer to put this button down. How to do this ?
 
As I mentioned before, sizers are automatically positioning items and in our case, sizer decided to put widgets in horizontal row, one next to another. If we want them to be in vertical row, we need to change some properties for sizer:
 
* Select wxFlexGridSizer in tree representing structure of our window (over properties)
 
* Expand Cols x Rows property and change X value to 1
 
What have we done ?
 
We said that this sizer should create only one column of widgets. We could also set number of rows (Y) to 2, effect would be same. Setting value to 0 means that sizer has to find this value automatically. Ok, let's see what have we done.
 
 
 
 
 
=== Using created panel ===
 
 
 
 
 
In this tutorial we will put out panel over main frame. To do this, just follow me:
 
* Open main.cpp file
 
* Add '''#include "helloworldpnl.h"''' at the begginning of file
 
* At the end of '''MyFrame::MyFrame''' add '''new HelloWorldPnl(this);'''
 
* Compile and Run
 
 
 
You should see something like this:
 
 
 
[[Image:WXSMITH7.JPG]]
 
 
 
 
 
=== But I want it to look better ===
 
 
 
 
 
Let's see. I would like my panel to be more interesting, I want it to change when we resize our window. And I want bigger font, and let's say, blue font colour. First can be done using previously created wxFlexGridSizer, need just few modifications:
 
 
 
* Select wxFlexGridSizer from resource browser
 
* Change growable cols property to 0 (zero)
 
* Change growable rows property to 0 (zero)
 
Changed properties keep information about columns and rows which should expand when window changes size. Values are integers (zero-based indexes) divided by coma.
 
 
 
Second is also easy:
 
* Select wxStaticText from resource browser (or click on it in editor)
 
* Find font property and expand it
 
* Change Use Font to True
 
* Click on font property below - button with "..." will appear, click on it
 
* Select new font, I used "Times New Roman", Bold, size: 20
 
* Find foreground property and expand it
 
* Change Use Colour to true
 
* In Colour below select Custom, colour dialog will appear
 
* Select colour You like :)
 
 
 
Ok, let's compile & run.
 
Now when we resize window, our panel changes dynamically, font is bigger and colour has changed :)
 
 
 
[[Image:WXSMITH8.JPG]]
 
 
 
 
 
=== How to make button respond ===
 
 
 
 
 
Now we'll add action to our button, let's say it will close program. First thing is to change button label to "Close". This should be pretty easy and I hope You won't have any problems with it.
 
Ok, now let's add some action.
 
 
 
wxWidgets works as many other gui systems - through events. Event is a small peace of informathion saying that something has happened - for example user clicked on button. But we waht to do something when such event happens. To connect event with action we have to create event handler and wxSmith can do it automatically:
 
 
 
* Select button
 
* Switch to Events tab (if You see properties, it's right there)
 
* In the line named EVT_BUTTON choose "-- Add new handler --"
 
* Change event handler name to something You want (I will leave it as it is ;)) and click OK
 
 
 
As You can see, new empty function has been created
 
 
 
  void HelloWorldPnl::OnButton1Click(wxCommandEvent& event)
 
  {
 
  }
 
 
 
Here we can write some code and it will be executed when You press button.
 
So, let's add Close() command
 
 
 
  void HelloWorldPnl::OnButton1Click(wxCommandEvent& event)
 
  {
 
    Close();
 
  }
 
 
 
and see what happens. I click on Close button and... nothing happens. Why ?
 
Because we want to close panel, not whole window. How I know that ?
 
Our event handler is member of HelloWorldPnl class and everything inside event handler will be relative to it and when we call Close() we call this function in wxPanel class.
 
But how to call it inside main frame ? Change the code to
 
 
 
  void HelloWorldPnl::OnButton1Click(wxCommandEvent& event)
 
  {
 
    GetParent()->Close();
 
  }
 
 
 
GetParent() function will return pointer to parent window - frame. Now it's easy to call Close inside it. But be careful. Our example was easy and we can assume that main frame will be panel's parent. Usually we can not be sure.
 
 
 
Our Hello World application is ready to go :) I hope It wasn't boring. Not bored ? Read next chapter ;)
 
 
 
= Pointers =
 
 
 
== Some technical info ==
 
 
 
 
 
 
 
Ok, I'll try to explain how wxSmith affects our code and how to work with it and not to be worry about loosing Your code
 
 
 
 
 
=== Where wxSmith generates its code ? ===
 
 
 
 
 
wxSmith is not not as intelligent as it looks like ;) When we say it generates code, it simply replaces whole code pieces without wondering if code is placed in the right position.
 
But the code works. How is it done ?!
 
 
 
When You look into files generated inside wxSmith, you may find some special comments like :
 
 
 
  //(*Headers(HelloWorldPnl)
 
  //*)
 
 
 
These comments are used by wxSmith to find the place where new code should be applied.
 
Each ''//(*'' comment starts automatically generated block of code and ''//*)'' closes it. Everything between these comments is regenerated, even if you add something there. The only exception is a block started with the ''//(*Handlers'' comment. wxSmith can only add to this block of code and if you want to write your event handler manually, you can put its declaration here.
 
 
 
Code outside the ''//(*'' - ''//*)'' comments won't be touched.
 
 
 
== Loading XRC resources ==
 
 
 
 
 
 
 
When using an XRC file, do not forget to initialize the wxXMLResouce Handlers & XRC File.  For example in your App::OnInit:
 
 
 
    // Loading XRC resource file (not in a zip file).
 
    wxXmlResource::Get()->InitAllHandlers();
 
    wxXmlResource::Get()->Load("<your XRC File name>.xrc");
 

Latest revision as of 22:03, 9 September 2011

This page is outdated, more recent tutorials can be found on WxSmith tutorials