Re: GTK+ canvas?
- From: Havoc Pennington <hp redhat com>
- To: "W. Borgert" <debacle debian org>
- Cc: gtk-devel-list gnome org
- Subject: Re: GTK+ canvas?
- Date: Wed, 30 Aug 2006 16:17:37 -0400
I posted some sort of blue-sky canvas ideas a year ago:
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:
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:
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
- it's width-for-height so text items work right
- you can set padding on all 4 sides separately (and in the base
- 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
Anyway hth, sorry it isn't more organized, I don't have time to be very
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.
] [Thread Prev