Most efficient way to update drawing on sibling panels Topic is solved

Are you writing your own components and need help with how to set them up or have questions about the components you are deriving from ? Ask them here.
Post Reply
empaticus
In need of some credit
In need of some credit
Posts: 3
Joined: Sun Oct 12, 2008 6:00 pm

Most efficient way to update drawing on sibling panels

Post by empaticus »

I am trying to write a wxWidgets-based application for labeling regions on images.
- Load an image
- Select a region/regions on the image using mouse
- Label the selected region, extract low-level features, etc.

In this application, wxWidgets is resposible for a user-friendly region selection interface. Attached is a scrrenshot from the dialog to be used for region selection. I use a wxImagePanel class derived from wxPanel to display and draw on images. On the attached image, top left will show the original image, bottom left will be used to draw on the image, top right image will display the foreground image pixels corresponding to selected region as the user draws on the bottom left image (by painting). For instance, (looking at the example screeshot attached), the user will select the region corresponding to the walking man by painting on it with mouse on the bottom left image (wxImagePanel object), and as the user paints on the lower right image (s)he would like to see the selected region on the top right as the mouse moves (realtime or near realtime).

I create a wxDialog containing 3 instances of wxImagePanel to represent the 3 images on the selection dialog window (pls the see attached image).

Code: Select all

///*** Incomplete ***
class RegionSelection: public wxDialog
{
    public:
        RegionSelection( wxWindow* parent, wxImage* src, IplImage* mask, int rid, bool* valid );
        void construct( int w, int h );
        wxPanel* makeControlPanel( int w, int h );


    /// === DATA ==========================

    /// input image
    wxImage* image;

    /// output mask, indicating the selected region
    IplImage* mask;

    /// region ID, foreground pixel values in output mask image, background: 0
    int rid;

    /// is the selection OK, or should it be discarded?
    bool* valid;

    /// === GUI related ===

    /// panel for original image drawing
    WxImagePanel* panelSrc;
    /// selection will be done on this panel
    WxImagePanel* panelSelect;
    /// output mask is shown on this panel
    WxImagePanel* panelMask;

    /// control panel containing buttons, etc.
    wxPanel* controlPanel;

};

Code: Select all

///*** Incomplete ***
class WxImagePanel: public wxPanel
{
    public:
        WxImagePanel( wxWindow* parent, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize );
        ~WxImagePanel();

        void setBitmapImage( wxImage* src );

    private:
        void paintEvent( wxPaintEvent& evt );
        /// process mouse events to draw on the image
        void mouseEvent( wxMouseEvent& evt );

        void paintNow();
        void render(wxDC& dc);

        //wxPoint  pos;
        wxBitmap* bmp;

        // bool

        // to keep the previous point clicked by mouse
        int x1;
        int y1;

        DECLARE_EVENT_TABLE()    
};
Here comes the question:
I keep 3 instances of wxImagePanel object within the dialog. How to tell the top right wxImagePanel to redraw itself (and show the foreground pıxels selected until now) as the user selects a region on the bottom left wxImagePanel. I need a general and efficient solution, hence the wxImagePanel class can be a general-purpose on-image drawing class.

Should I create a custom event and send it, or should I set a timer to refresh the image panel at regular intervals, or what else?

Thanks a lot in advance.
Attachments
Region selection on an image. Each image is represented by a wxImagePanel, on which we can draw with a mouse. Top left: original image, bottom left: image to draw on, top right: image to shot the selected foreground pixels.
Region selection on an image. Each image is represented by a wxImagePanel, on which we can draw with a mouse. Top left: original image, bottom left: image to draw on, top right: image to shot the selected foreground pixels.
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

usually, calling Update() followed by Refresh() causes a redraw (a paint event is fired). Otherwise you could draw directly using a wxClientDC
empaticus
In need of some credit
In need of some credit
Posts: 3
Joined: Sun Oct 12, 2008 6:00 pm

Post by empaticus »

Yes, but the panel on the top right should know about the events processed by the bottom left panel,
and should have access to which part of the image is painted so that it can update itself accordingly.

The question is how to make the two sibling panels communicate efficiently.
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

empaticus wrote:Yes, but the panel on the top right should know about the events processed by the bottom left panel,
and should have access to which part of the image is painted so that it can update itself accordingly.

The question is how to make the two sibling panels communicate efficiently.
You could simply pass pointers around, so they can call methods. Or you could share the base image in a common place that all panels can access. There's a few possible architectures there, depending on your needs. I personnaly tend to like the approach with data separate from the GUI in a central/common object, but there's other ways for different needs.
Post Reply