On Tue, 18 Apr 2000, James Henstridge wrote:
> > Again, we see some conflicts because of termonilogy.
> > 
> > In Dia, the grapples/handles uses to resize a widget are call
> > connection points.
> 
> What I think Alex is getting at is that these sort of things would be
> better left for the application to handle.
Exactly.
 
> In the case of dia's connection point/handle idea, the GtkObject signal
> system makes this particularly easy to handle.  The derived canvas item
> has a move_cp signal or something.  When a handle is connected to the
> CP, the object with the handle connects to the move_cp signal.  When the
> object with the CP moves, it emits the move_cp signal, which the allows
> the connected objects to move themselves as well.
Yup.
 
> With such a canvas, all dia objects would probably be subclassed from some
> special dia canvas item type, rather than the base canvas item.
Yup.
 
> I have put a small diagram of how some of the classes for a new canvas
> might be arranged at:
>   http://www.daa.com.au/~james/images/new-canvas.png

Looks pretty good. 
 
> I have gotten rid of the idea of layers, as they are really just groups
> that are children of the root canvas item (I am not saying that dia should
> get rid of its layers concept -- just that they don't need to be in the
> base canvas implementation).
  
Good idea.

As I said, I've been doing some thinking about this some time ago (but
then I got distracted hacking gradients into libart...). I have some ideas
and stuff scribbled on a piece of paper here. I thought i might type it in
to generate some ideas.

Stuff to think about when (re)designing the Dia canvas.

* Model/View separation. The gnome-canvas does this in a totaly different
way, there each Gnome-canvas widget is a view of an app-internal
model. I'd like both the model and view to be supported by the Canvas
widget.

* It should be much closer to Gtk+ than the Dia canvas is, meaning all
Canvas items are derived from GtkObject, using signals instead of
function-pointers etc. The idea here is to create GtkCanvas,
GtkCanvasItem, GtkRenderer etc that can go into Gtk+ in 1.4 or later.

* Hierarchial grouping of objects must be a core feature.

* Direct support for undo/redo shouldn't be in the canvas, but it *must*
be possible to add support for state change saving or suchlike so that
undo can be implemented by the application. Basically, we must
think about it in the design.

* GnomeCanvas supports a general affine transformation of all objects,
should we have this? It can be very useful, but it also makes many
item-implementations very difficult, and might not be used by very many
applications.

* The libart micro-tile array structure might be a good way to handle
handling of partial repaints. That code can be taken from libart if we
don't want the libart dependency. It might be nice when intergrating
with bonobo and GnomeCanvas which use this.

* Should we allow CanvasItems to be GtkWidgets? This would mean
subclassing from GtkLayout with all its hocus-pocus mapping and unmapping
for scrolling. It means that some stuff will be hard to implement too,
like affine transformations (or just scaling, see below) of generic
widgets, or rendering to non-gdk renderers. Another problematic thing here
is that GtkWidgets generally cannot be displayed at the same time in
different views.

* The Canvas must handle the pixel to world coordinate mapping. This means
that each view can have different zoom levels etc. This obviously trips up
embedded GtkWidgets...

* The renderer. Ahh, this is cool stuff. This is actually the best part of
Dia in my opinion. It can be better though. First of all it should be a
GtkObject, with ref-counting and all, in the name of Gtk-ization. If this
is done well it could be used by other parts of Gtk too, as an abstract
printer interface etc.

It should support:
 Color specification
 Line attributes (dash, caps, joins)
 Fill styles
 Lines, polylines, polygons, rectangles
 Ellipses and arcs (axis-aligned, if you need general, use beziers)
 Bezier curves, (lines and filled)
 Image rendering (based on GdkPixbuf)
 Rotated text rendering, (pixmap rotation hack or whatever in Gdk)
 Text extents measuring
 All strings in UTF-8, font selection using Pango (A must for i18n)

The current libart renderer in Dia is horribly ineffective. This is due to
the current renderer interface. For each primitive rendering operation the
renderer must calculate a lot of data, which it then throws away, beacause
there is no way to store it for the next time. This would be solved by
using an API which lets you create "shapes" that can then be drawn by the
renderer. (Interested parties can glance some at the Java 2D spec for
inspiration.) Basically this means that you do something like:

 shape = renderer->create_bezier(renderer, ...);
 renderer->draw_shape(renderer, shape);

The shape object here is specific to the renderer it was created in, and
internally it contains shape-data and pointers to rendering-functions that
draw_shape calls. Using this the libart renderer can cache SVP:s, leading
to much better performance in the aa renderer.

There are of course helper-functions for drawing stuff once, but they
should not be used in time-critical code which can cache the shapes
between repaints.

Ugh, enough of my ravings. What do you think?

/ Alex












Reply via email to