Aug 2003, Frank de Lange <frank@unternet.org>
Last update: Aug 2003

===========
GtkFrameset
===========

GtkFrameset is a GTK container widget which implements the XHTML
FRAMESET tag as defined in the XHTML DTD xhtml-dtd-frameset from 20020801.
It is also compatible with the HTML 4 definition of FRAMESET as described in
the HTML 4.01 Specification from 19991224. As a GTK container widget,
it can be used to contain (and constrain) other widgets. In use,
GtkFrameset is similar to GtkTable, but there are some notable
differences.

Why not use Dw? DwTable?
========================

The problem of frameset rendering is more suited to GTK's approach to
widget display than Dw's. A frameset is by definition limited in size
and does not scroll. Dw widgets are presented in a viewport, which
does not limit their size. This is unnecessary for the display of a
frameset. A frameset widget should control the dimensions of its
children, not the other way around. DwTable sizes cells based on
textual content.

Another reason for choosing GTK over Dw is that GTK is less of a
moving target than Dw.

Usage hints
===========

GtkFrameset is quite easy to use in most cases. The
gtk_container_add() has been overloaded to provide somewhat
intelligent child placement, in that it fills frames sequentially
(left-to-right, top-to-bottom). Use gtk_container_add_with_args() to
set the frame attributes (currently marginwidth, marginheight, border,
noresize).

See the header file (gtkframeset.h) for the widget-specific
commands. All commands which take gchar *rows/gchar* columns as
arguments expect Length or MultiLengths. 

So, to create a frameset with two same-sized columns, use:

 (GtkFrameset *) frameset = gtk_frameset_new("*", "*,*");

This can also be done like this:

 (GtkFrameset *) frameset = gtk_frameset_new(NULL, "*,*");

as GtkFrameset interprets NULL as "*" (one row or column spanning the
whole frameset).

Any valid Length/MultiLength can be passed as argument. Bare numbers
are interpreted as pixel values, numbers followed by '%' are
percentages, number followed by '*' are relative sizes. A bare '*' is
identical to '1*'.


Some notes on child dimensioning
================================

Starting point is the frameset width and height. First come frames
with absolute dimensions. No frame can be bigger than the frameset, so
checks are performed to make sure that absolute frame dimensions do
not exceed frameset dimensions. When the total of all frames with
absolute dimensions exceeds the frameset dimensions, the available
space is divided by ratio to those frames. If there are only
absolute dimensioned frames the dimensions are changed into percentual
dimensions by ratio.

Next come frames with percentual dimensions. They get to divide the
remaining space after all absolute dimensions have been allocated. If
the total of all percentual dimensions adds up to more than 100, the
calculation is normalised to 100%.

Last come frames with relative dimensions. They get to divide the
remaining space after all absolute and percentual dimensions have been
allocated. All available space is divided by ratio to relative weights
and allocated to frames. Internally, relative dimensions are
translated into percentual dimensions.

The calculations are performed in two stages. In the first stage, the
total weight of absolute, percentual and relative dimensions is
calculated. All dimensions are translated into either absolute or
percentual dimensions. The results of these calculations are used in
the size_allocate callback to calculate the actual widget
dimensions. When frames are resized, the dimensions are recalculated.


Can this be optimised? Sure, but... later...

Source files
============

Source for GtkFrameset is contained in gtkframeset.[ch]


Limitations
===========

 - The scrolling attribute is not supported yet, as I have not found
   an easy way to disable scrolling for the docwin.
 - The frameborder="0" attribute does not completely remove the frame
   border, as the docwin insists on drawing a shadow border around
   itself even when its border is set to 0.

TODO
====

 - implement the scrolling attribute in some way
 - find a way to stop the docwin from drawing a border around itself
   when its border attribute is set to 0.
 
