My previous post covered my last week of development and my feeling of the SoC program. Now, I think it would be a good idea to write a summary. The objective of my project was to implement the ribbon paradigm for Gtk# using managed code only. Since this is a GU library, a tiny sample application had to be created to show the implemented features.
During the SoC program, I have implemented the following classes:
- Ribbon: This is the main ribbon, which displays tabs and pages. This is similar to a notebook, but more using the Ribbon way of doing (drawing) things. Each page has a label widget placed in the corresponding tab, and a widget displayed as the page.
- RibbonGroup: This is more like a decoration. It draws a frame around its child, and a label. It may also display a special button, next to the label, to ‘expand’ the group. Expanding a group means displaying a window with more options.
- Gallery: This is used to display a table of tiles. The user has the ability to select a tile. The developer may draw whatever he want in the tile.
- GalleryPopupWindow: This is a popup window which is really convenient to display more tiles than it would be possible using the Gallery. This popup is opened by clicking on a particular button of the Gallery. The developer does not need to care about this popup.
- Button: I required a button that could work in three mode: click only, drop down menu only, or click and separate drop down menu. In addition I had to be able to easily change its design (ask it not to draw its background when the mouse is not over).
- ToggleButton: Its visual appearance is similar to the button described above, except that it is a toggle button.
- BaseButton: Since Button and ToggleButton share a lot of common behavior, a class had to be created to contain that behavior.
- ToolPack: This is used to pack several Button’s or ToggleButton’s together in a single (visual) block. It is only used to visual purposes.
- FlowLayoutContainer: This container layouts its children using a flow layout. It has not be throughly tested, and the code should be optimized to handle cases where the heigh is fixed better.
- ToolBox: This is similar to FlowLayoutContainer, except that all rows have the same height, and children are scaled to fit the height of the row.
- Theme: It is used to draw the appearance of all widgets above. The objective is to be able to change the theme used by a widget to customize the appearance of the application.
- ColorScheme: It is supposed to represents some variants (dark, bright, etc) of a color (bluish, gray, black theme).
The documentation of the classes is included in the classes themselves using the XML syntax because
- It is more convenient for me since I can update the documentation whenever I change the API.
- There is less files, and consequently, the structures of folders is simpler.
- Many developers are used to it since it is the standard way of documenting code.
- Newcomer can read the code, and the corresponding documentation in a single window, instead of switching between multiple windows.
In addition, I had to imagine a special mechanism to work with windowless widgets easily. Indeed, next-gen widgets needs to be transparent because they have all kind of shapes, shadows, etc. Gtk windowed widgets can only enable this if the desktop supports compositing. Some may suggests using compositing where available, and using opaque widgets else. However, this is not an option because I would have to design two themes. Consequently, the resulting applications would not have the same style depending on the computer it runs on. It would look rather awkward to the end-user I think. Therefore, I have used windowless widgets. The disadvantages of such widgets is that the only event that is propagated is expose. That event is used to tell the widget to render its content. Thus, I have built a special window which propagates other events to windowless widgets. This mechanism is implemented in the SyntheticWindow class.
In addition to the transparency problem with Gtk, I have also experienced troubles because Gtk does not seem to support size negotiations between a container in its children.
I think that I have implemented most features required to use a ribbon, and using the Gtk phylosophy. On the other side, I would have liked to provide a more complete sample. Nevertheless, it presents almost all features of my library. It is now up to you to build a usefull application using it.
Remember that the code can be obtained at http://mono-soc-2007.googlecode.com/svn/trunk/laurent/src/.