Re: GTK+ canvas?



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




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