SoC :: Ribbons :: Weekly Report #2

10 06 2007


Now that the drawing of the ribbon and ribbongroups is completed, I have been focusing on user interactions. To do this, I need mouse gesture events. However, this is not as simple as it seems. Indeed, for now I only use no-window widgets. This decision was made because I must have transparent widgets. For example, the ribbongroups must have its body transparent, to see the underlying ribbon. In order to have a transparent widgets, I see three ways:

  1. Using the RGBA color space in a widget with its own window, and painting the background with a transparent color. I’m not an expert in X.or, but AFAIK it requires some ‘advanced’ compositing features that are still rare. For example, only one of my three Linux installations supports it. Therefore it is not an option.
  2. Use the the ShapeCombineMask method with a widget that has its own window. But this only make it possible to have transparent widgets, not translucent ones. However it could be an option, but I would have to both draw the actual widget, and draw the mask…
  3. Use no-window widgets as I currently does. However some websites tell that this option has three side-effects:
    1. There is a risk that a child could draw out of its allocated space. This is not an issue, just clip the region in cairo.
    2. It is not possible to draw a background. Well, I have never understood this one since I just have to call paint in cairo.
    3. The only event that is received in such a widget is Expose. Well this one is a killer.

So, that’s what I have been studying this week, the synthetic propagation of some events to no-window widgets. The propagation of cursor motion and clicks has been trivial. On the other hand, the propagation of mouse leave/enter events is another story. First, Gtk# does not seem to provide a way to create such an event. You must be provided with an IntPtr from somewhere. As a consequence I have create my own managed struct that mimics the native GdkCrossingEvent. My struct is designed to be marshaled, and compatible with both 32 and 64-bits systems. But this as a consequence, my library is now “unsafe” because I must get the address of the struct and create an IntPtr from it. In order to use this new mechanism, the developer has to inherit from SyntheticWindow instead of Gtk.Window. I think that Gtk# should offer a way to create our own events, because a C programmer could. But since it is not possible now, I have to implement this littly hack.

The synthetic propagation is not complete yet, but almost. I have not been ably to do more, because I have had 3 exams during the week.




One response

10 06 2007
jonathan pobst

You may want to take a look at ToolStrip in Managed.Windows.Forms, as I think it does what you are trying to do. The ToolStrip itself is a Control (has an actual Window handle) and every button, label, etc. (ToolStripItems) derive from Component, which does not have an actual Window handle.

Whenever the ToolStrip receives a Paint command, it looks for ToolStripItems in the clip region and sends them a paint command. Every time the ToolStrip receives a MouseMove event, it calculates which ToolStripItems need a MouseEnter, MouseMove, and MouseLeave event. It also forwards MouseDown, MouseUp, and Click as needed.

I think this approach was chosen for ToolStrip as it is much more light weight than registering hundreds of new Windows with the window manager.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: