GtkTransform - a data transform interface for GTK+



This is an idea that was bounced around the office today. We don't have
patches, but it doesn't seem like it would be too hard to implement. I
just thought I'd get people's thoughts first.


GtkTransform - a data transform interface for GTK+
==================================================

Davyd Madeley and Matt Johnston - Fugro Seismic Imaging P/L

Rationale
---------

Often, in GTK+ applications, the data being stored by a widget or a model is
not the same as the data you wish to display to the user. For example, a
model might be storing floating point file sizes (e.g. 1069547.52), which you
wish to report to the user as human readable file sizes (e.g. 1.02 MB). As
it stands today, the only solution to this problem is to have two sets of
data: the raw data and the data you wish to display to the user. A problem
then arises with keeping this data in sync (N.B. with models, this can be
solved by implementing your own proxy model that has a number of read-only
columns).

Our idea is to offer a generic method for handling forwards and backwards
transforms of data between the internal data storage of a widget or model
and the view.

Implementation
--------------

Transforms would be handled by a GtkTransform class:

    class GtkTransform inherits from GInitiallyUnowned

    Properties:
        "transform-forwards" (* GtkForwardTransform)
	"transform-backwards" (* GtkBackwardTransform)

    Constructor:
    	new (* GtkForwardTransform, * GtkBackwardTransform)

    Methods:
        void set_forward_transform (* GtkForwardTransform)
	void set_backward_transform (* GtkBackwardTransform)
        GtkForwardTransform *get_forward_transform (void)
	GtkBackwardTransform *get_backward_transform (void)

	char *transform_forwards (const GValue *value)
	void transform_backwards (const char *string, GValue *value)

The subroutines GtkForwardTransform and GtkBackwardTransform have the
prototypes:
    
    char *(* GtkForwardTransform) (GtkTransform *transform,
                                    const GValue *value);
    void (* GtkBackwardTransform) (GtkTransform *transform,
                                    const char *string,
				    GValue *value);

There would also be several canned transforms that inherited from
GtkTransform, e.g. GtkIntTransform, GtkFloatTransform, GtkStringTransform.

Widgets would then implement the GtkTransformable interface:

    interface GtkTransformable

    Properties:
        "transform" GtkTransform

    Methods:
        void set_transform (GtkTransform)
	GtkTransform *get_transform (void)

When a widget that implements GtkTransformable wants to render data to the
screen it feeds the internal data through the function
gtk_transform_transform_forwards(). Widgets that can receive user input will
pass that input through gtk_transform_transform_backwards() before storing
it.

Widgets that might implement GtkTransformable include: GtkEntry,
GtkCellRendererText, GtkSpinButton, GtkLabel. These widgets would provide
default transforms that cause them to have the same behavior they have
today.

Comments
--------

Currently all of this can be achieved using a mixture of subclassing, hooks
and signals throughout each of the widgets. The problem is that there is no
consistent method for solving the problem among all of the widgets.

For the case of TreeView/CellRenderer, the forward direction can be handled
by gtk_tree_view_column_set_cell_data_func(), which is actually offers more
flexibility for controlling renderer properties and also allows for the
floating point->human readable case. It does not however allow for the
reverse transform case.

-- 
Davyd Madeley        Software Engineer
Fugro Seismic Imaging, Perth Australia



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