Hi,

I posted some sort of blue-sky canvas ideas a year ago:
http://mail.gnome.org/archives/gtk-devel-list/2005-August/msg00067.html


Since then I've learned HTML/CSS much more thoroughly and also used 
Flash a bit. And in the last week needed to write a canvas in 2-3 days 
to use for Mugshot. Which is maybe interesting as a case study - "if you 
had to strongly prioritize features since you only have 2-3 days, what 
would be really important for a real-world application"

The code is here:
http://svn.mugshot.org/dumbhippo/trunk/client/linux/src/hippo-canvas-item.c
http://svn.mugshot.org/dumbhippo/trunk/client/linux/src/hippo-canvas.c
http://svn.mugshot.org/dumbhippo/trunk/client/linux/src/hippo-canvas-box.c
http://svn.mugshot.org/dumbhippo/trunk/client/linux/src/hippo-canvas-text.c

Remember, written in a few days for a single app; not intended to become 
a maintained library API. The HippoCanvasBox is the base class for all 
the items, i.e. all items are containers.

Thoughts since last "canvas notes"
===

- I think an important thing to keep in mind is that a canvas is just an 
alternate widget system. You can think of it as a GUI toolkit with 
different tradeoffs from GtkWidget, or a GUI toolkit with some of the 
misfeatures/limitations of GtkWidget corrected. But in any case it is 
basically defining the same thing as gtkwidget.c, gtkcontainer.c and 
other core GTK classes.

- Along the same lines you can also think of a canvas as an alternative 
to Flash or HTML/CSS, two systems many programmers will be familiar with.

- This poses a huge question for a canvas in GTK, namely, how much does 
it overlap widgets; if I'm writing an app, when do I use the canvas vs. 
widgets; exactly what is the scope of a canvas project; etc.

- My opinion is that the canvas should "replace" the GTK core in a way, 
i.e. GtkWidget becomes a specialized thing you can embed in a canvas.
This obviously makes the canvas into a pretty big project.

- In fact a useful bit of discipline might be that gtkwidget.h does not 
get #include'd by the canvas item implementations. (except the canvas 
item that embeds a widget)

Notes on how the Mugshot canvas worked out so far
===

- note that we're using it cross-platform but not using gtk 
cross-platform, so the canvas widget uses gtk, but none of the items do; 
the items don't have a concept of being on a canvas or even in a tree of 
items, they are all just standalone objects that can be sized and 
painted. Cairo and Pango are used cross-platform though.

- canvas items always see only their own coordinates (what gnomecanvas 
called "item coordinates"), this removes a _lot_ of confusion that 
GnomeCanvas had - unlike GtkAllocation, this means the canvas item only 
needs to store its allocated size, not its allocated origin. Cairo makes 
this possible since drawing doesn't require converting to drawable 
coords (the cairo_t can have its translation matrix already set up)

- we had previously coded the Mugshot custom display separately for 
Linux and Windows. On Linux, we used an atrocious custom widget from hell:
http://svn.mugshot.org/dumbhippo/trunk/client/linux/src/hippo-bubble.c
and on Windows we used an embedded IE control, i.e. HTML/CSS.

- GnomeCanvas wouldn't have helped much if at all with cleaning up 
hippo-bubble.c, because the disaster is all the custom layout code. So, 
the canvas should support layout.

- in the canvas layout code, we fixed several suboptimal aspects of 
GtkWidget:
   - it's width-for-height so text items work right
   - you can set padding on all 4 sides separately (and in the base
     class)
   - GtkMisc functionality is built in to all the items (but changed
     to enum FILL,START,CENTER,END instead of xscale/yscale/xfill/yfill)

- I think making CanvasItem an interface worked very well, I haven't 
looked at GooCanvas but I see its website says it does the same.

- the image item is able to tile, which is a common way to draw e.g. the 
edge of a box in html

- the text item has a nice "size-mode" setting for whether you want it 
to be its natural full width, wrapped, or ellipsized which are the three 
cases I consider common

- a link item, or somehow adding link support to Pango markup, is very 
useful; many custom displays are made to look html-like or web-page-like

- I wanted a "canvas shape" item but Cairo supports no good way to store 
a shape, so instead we made the "paint" method a signal so you can hook 
in and draw something custom. But this is painful, as you also have to 
override hit detection and size request/allocation.

- a deficiency vs. HTML is the lack of cascading or class-based styles.
So e.g. if you set the font size for a box, it should become the default 
font size for all items that are children of the box, similar to how 
nested GtkTextTag get their attributes composited. Alternatively or in 
addition, it might be interesting to be able to define named styles that 
are then applied to multiple items, as in CSS classes.
Lack of these two leads to notably more typing than HTML in some cases.

- typing in C is definitely worse than HTML, so having a markup language 
as an integral part of a canvas design is of interest.

- a general theme I think is to pack a lot more than gtkwidget does into 
the base class - so 4 sided padding, GtkMisc equivalent, ability to act 
as container, maybe style properties such as bg/fg color and fonts that 
get inherited by children. this isn't just a short-term hack, I also 
think it's right.

Stuff that isn't resolved yet:

- we need to be able to do animations, which may involve adding some 
kind of absolute positioning and/or other stuff; don't really know yet. 
But I think it is a big open question.

- haven't dealt with the equivalent of gtk_widget_show/hide or CSS
visibility. but it might be useful to support visibility=hidden (reserve 
space for the item but don't draw it) in addition to just show/hide

- haven't really dealt with events beyond "button press" - though people 
do a lot in HTML, and it doesn't support much beyond button press 
either. But events are where you really start copying huge chunks of GTK 
and the duplication between the canvas toolkit and GtkWidget become 
evident. e.g. dealing with focus and mouse grabs.

I might be tempted to go extremist and not even use GdkEvent, on the 
grounds that GdkWindow should not be special or known about by canvas 
items, but that could be overboard. (It's somewhat clean and arguably 
correct in fact that the canvas sits alongside GDK rather than depending 
on gdk/gtk)


Anyway hth, sorry it isn't more organized, I don't have time to be very 
thorough.

I think the biggest question about a canvas in gtk in my mind really is 
this thing about "how far to go" - how do you define the thing, both in 
absolute terms, and relative to the core gtkwidget/gtkcontainer stuff.

Havoc

_______________________________________________
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list

Reply via email to