Re: GTK+ canvas?



Qui, 2006-08-31 �20:22 +0200, Soeren Sandmann escreveu:
> Someone posted a link to the minutes of the gtk+ meeting at GUADEC
> which reminded me that I promised to write up some of the ideas I had
> for a canvas-type widget.
> 
> The reason model/view is a useful model is that it allows applications
> to keep a data structure (the model) containing all the business logic
> (what the application *does*) in one place and then have separate
> modules displaying views of this data structure. Whenever something
> changes about the model the view is signalled to change itself as
> appropriate. 

  That theory breaks when you need to access the view in order to layout
the items in the model.  For instance (real life example!) suppose you
want to draw a rectangle around a unconstrained text item.  Obviously
the size and position of the rectangle are properties of the rectangle
item model.  Also obviously, you don't know beforehand how much size a
pango layout will take without access to the text item view, since the
text item model only contains a text string and pango font description;
from this information to the actual size on screen is a long long way.

> Applications keep a datastructure containing the application
> model. Whenever something changes in this datastructure the
> corresponding area is invalidated. The scroll area will then emit an
> expose signal and the application will repaint the invalid area. Ie
> basically like the gtk+ drawing model.

  Basically, the gtk+ drawing model sucks for drawing large and complex
content.  Programmers avoid this problem by using lots of small widgets
instead of a single large and complex widget.  The biggest pain when
using GtkDrawinArea, for instance, is handling of expose events.  You
know you want to draw a set of objects in the drawing area; now, for
each expose event, which objects are affected by the exposed region, so
that I draw only them?  Of course no programmer ever worries about this
detail, and everyone ends up just blindly  drawing everything, which is
much slower.  This is one of the key areas where a canvas should help.
And for a canvas to be able to help, it needs to be retained mode, i.e.
keep state of objects to be drawn.

> 
> The difference is in how input is handled. During the expose handling,
> the application is not only drawing stuff, it is also setting input
> regions. These input regions are remembered by the canvas, but *get
> invalidated along with the pixels*. Ie., you are required to "repaint"
> all the input regions on every expose. If you paint two input regions
> on top of each other, the top one will get the event first (and can
> optionally pass it along to lower layers).
> 
> This way, all information about stacking and overlapping input regions
> is *implicit* in the application model rather than explicit in the
> canvas hierarchy. So even input handling is immediate mode rather than
> retained mode.

  Yeah, right, goocanvas already does this too.

> 
> Example of why this is useful:
> 
> Suppose you are writing an illustration program like Inkscape. Your
> data model might be a tree of groups containing shapes and curves. One
> of these shapes might be selected which means it has little handles
> you can use to change the shape.
> 
> In the FooScrollArea model all you need to write is expose code for
> the shape:
> 
> expose_shape (Shape *shape, ScrollArea *area, Region *region)

                  ^^^ 
  Is this supposed to be immediate mode?  This is retained mode IMHO;
the canvas is keeping state about shapes here...

> {
>         draw_shape (area);
> 
>         draw_input_region (area, shape);
> 
>         if (shape->selected)
>         {
>                 for (points in shape)
>                 {
>                         draw_drag_handle();
>         
>                         set_drag_handle_input (handle_shape_input);
>                 }
>         }
> }
> 
> When a shape is clicked, the old selected shape gets its "selected"
> bit cleared and the new one gets it set in the application model. Then
> both areas are invalidad. When a drag handle is dragged, the
> corresponding point needs to be moved and the item invalidated. So
> there is only one copy of the state pertaining to the shape.
> 
> 
> In the retained model, this will need to happen:
> 
> When a shape is clicked, the old selected shape needs to be unslected,
> which means deleting a canvas item for each point on the shape. Then
> new canvas items must be created for each of the handle points in the
> new shape. When a drag handle is clicked, three different objects must
> be updated: the application model object, the canvas item for the
> shape, and the drag handle for the clicked point.
> 
> And this is just for editing a simple shape.
> 
> I believe this 'immediate' mode canvas is a simpler and more efficient
> model than retained mode canvases, at least for most non-trivial
> applications.

  Immediate mode is more memory efficient, but less CPU efficient.  I
guess this is a tradeoff; which to pick depends largely on the
application domain.

  Regards.

-- 
Gustavo J. A. M. Carneiro
<gjc inescporto pt> <gustavo users sourceforge net>
The universe is always one step beyond logic




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]