Difference between revisions of "WxSmith tutorial: Creating items with custom paint and mouse handling"

From Code::Blocks
m (Minor edits for clarity)
m (Minor edits for clarity)
Line 3: Line 3:
 
Welcome back :) We've already learned nice techniques of working with wxSmith in previous tutorials and now it's time for something even better. Usually when writing some more advanced application, it turns out that none of the items provided by wxWidgets fits our purposes, especially when we need to present some data in graphical form. Hopefully as with almost all GUI toolkits, wxWidgets is also prepared for this and gives us the possibility to create an item with custom drawing and mouse handling - this allows us to create any item we like.
 
Welcome back :) We've already learned nice techniques of working with wxSmith in previous tutorials and now it's time for something even better. Usually when writing some more advanced application, it turns out that none of the items provided by wxWidgets fits our purposes, especially when we need to present some data in graphical form. Hopefully as with almost all GUI toolkits, wxWidgets is also prepared for this and gives us the possibility to create an item with custom drawing and mouse handling - this allows us to create any item we like.
  
= Creating item with custom paint procedure =
+
= Creating an item with the custom paint procedure =
  
 
Before we start creating our customized item, some background knowledge is needed.
 
Before we start creating our customized item, some background knowledge is needed.
First thing you should know is how wxWidgets draws items.
+
The first thing you should know is how wxWidgets draws items.
  
Most of items have custom paint procedures provided by operating system or some other toolkit available in system (like gtk+). In case of such items, when OS posts request to repaint item, either such message is forwarded by wxWidgets back into system or even the whole procedure is done without any wxWidgets' intervention. Unfortunately this means that we can not replace paint procedure in case of all items and even if it would work on some platforms, it won't on others. From items available in wxSmith, only wxPanel is guaranteed to work with custom paint procedure.
+
Most items have custom paint procedures provided by the operating system or some other toolkit available in the system (like gtk+). In the case of such items, when the OS posts a request to repaint the item, either this message is forwarded by wxWidgets back into the system or even the whole procedure is done without any wxWidgets' intervention. Unfortunately this means that we cannot replace the paint procedure for most items and even if it would work on some platforms, it won't on others. From the items available in wxSmith, only wxPanel is guaranteed to work with the custom paint procedure.
  
 
Now if we overwrite painting on wxPanel, wxWidgets will post two events on each paint request:
 
Now if we overwrite painting on wxPanel, wxWidgets will post two events on each paint request:
Line 14: Line 14:
 
  * paint event (EVT_PAINT)
 
  * paint event (EVT_PAINT)
  
First one is used to prepare area occupied by our item before adding content and the second one is used to do actual drawing. We don't have to override both events so we can only draw custom background or custom content leaving background as default one.
+
The first one is used to prepare the area occupied by our item before adding content and the second one is used to do the actual drawing. We don't have to override both events so we can draw just a custom background or just custom content, leaving the background as the default one.
  
  
Second thing you should know before writing custom paint method is that wxWidgets uses wxDC objects to draw. In case of erase background event, this object is provided within event, in case of paint event, we must create such object manually. To get more informations about wxDC and drawing functions, take look at [http://docs.wxwidgets.org/stable/wx_wxdc.html#wxdc this page in wxWidgets documentation].
+
The second thing you should know before writing a custom paint method is that wxWidgets uses wxDC objects to draw. In the case of the erase background event, this object is provided within the event; in the case of the paint event, we must create this object manually. To get more information about wxDC and drawing functions, take a look at [http://docs.wxwidgets.org/stable/wx_wxdc.html#wxdc this page in the wxWidgets documentation].
  
 
= Creating simple resource and overriding paint method =
 
= Creating simple resource and overriding paint method =

Revision as of 15:31, 6 December 2010

Warning: unfinished

Welcome back :) We've already learned nice techniques of working with wxSmith in previous tutorials and now it's time for something even better. Usually when writing some more advanced application, it turns out that none of the items provided by wxWidgets fits our purposes, especially when we need to present some data in graphical form. Hopefully as with almost all GUI toolkits, wxWidgets is also prepared for this and gives us the possibility to create an item with custom drawing and mouse handling - this allows us to create any item we like.

Creating an item with the custom paint procedure

Before we start creating our customized item, some background knowledge is needed. The first thing you should know is how wxWidgets draws items.

Most items have custom paint procedures provided by the operating system or some other toolkit available in the system (like gtk+). In the case of such items, when the OS posts a request to repaint the item, either this message is forwarded by wxWidgets back into the system or even the whole procedure is done without any wxWidgets' intervention. Unfortunately this means that we cannot replace the paint procedure for most items and even if it would work on some platforms, it won't on others. From the items available in wxSmith, only wxPanel is guaranteed to work with the custom paint procedure.

Now if we overwrite painting on wxPanel, wxWidgets will post two events on each paint request:

* erase background event (EVT_ERASE_BACKGROUND)
* paint event (EVT_PAINT)

The first one is used to prepare the area occupied by our item before adding content and the second one is used to do the actual drawing. We don't have to override both events so we can draw just a custom background or just custom content, leaving the background as the default one.


The second thing you should know before writing a custom paint method is that wxWidgets uses wxDC objects to draw. In the case of the erase background event, this object is provided within the event; in the case of the paint event, we must create this object manually. To get more information about wxDC and drawing functions, take a look at this page in the wxWidgets documentation.

Creating simple resource and overriding paint method

Now let's create some simple window. For our purposes we need some wxPanel inside the window which we will work on:

Wxs tut07 001.png

Now let's go to event's tab in properties browser. You may see that wxPanel can process much more events than other items. That's because it can be use as base for custom items which may have custom handler for any standard event. Ok, let's find EVT_PAINT method (sohuld be at the top) and add new empty event.

The first thing we should do inside the handler is to create wxDC object we will use. If you look at wxWidgets documentation you may read that not doing so causes wxWidgets to go into infinite loop because paint method will be recalled over and over again.

There are few types of wxDC objects we could use here. The most commonly used is wxPaintDC:

void Tutorial7Dialog::OnPanel1Paint(wxPaintEvent& event)
{
    wxPaintDC dc( Panel1 );
}

You can see that we passed panel's pointer as argument - wxPaintDC require pointer to item we will draw on on it's constructor. Remember not to use this opinter.

Now let's add some drawing code - just some diagonal line to test whether drawing does work:

void Tutorial7Dialog::OnPanel1Paint(wxPaintEvent& event)
{
    wxPaintDC dc( Panel1 );
    dc.DrawLine( 0, 0, 100, 100 );
}

Now if we run our aplication, the window will look like this:

Wxs tut07 002.png