Scrollable Widgets (Re: [gtk-list] GtkText & scrollbars)



On 12 Oct 1998, Owen Taylor wrote:

> 
> "Damon Chaplin" <DAChaplin@email.msn.com> writes:

> > It would also help GUI builders, since connecting the scrollbars to the
> > text widget is pretty awkward. (But using a CList is simple.)
> 
> What really should be done (TM) - is that scrollbars should be _removed_ 
> from all widgets that have them currently. And then there should
> be a generic interface added so that you could drop a
> Viewport, a Text widget, a CList, a CTree, a GtkLayout, a
> GnomeCanvas... etc. inside a GtkScrolledWindow and
> it would work.
> 
> (Currently, a GtkScrolledWindow can only contain a GtkViewport)
> 
> Probably the way this would work is that any widget that
> wanted to be scrollable in this way would create a signal
> 
>  "set_adjustments" (GtkAdjustment *hadj, GtkAdjustment *vadj);
> 
> and the ScrolledWindow would check for the existance of such
> a signal when a child was added to it.

hm, what does "should" actually mean in the above sentence (i.e. do
you really want to enforce this idea at some point)?

what's actually problematic?

several widgets implment unneccessary complexity in order to get
scrolling facilities. the complexity actually consists of the widget
being a composite widget so it can handle scrollbars and thus occasionally
widgets need to implement container behaviour where it is not really required.
as a side effect these widgets usually can't be properly default constructed,
because the scrollbar adjustments are a somewhat mandatory part of the widget
implementation itself and thus have to be provided at construction time, we
gain a lot of unneccessary construction problems with that for language bindings
and gui builders.
also the code duplication for scrollbar handling is a waste of effort and prune
to bug duplication (e.g. getting the GTK_POLICY_ALWAYS and GTK_POLICY_AUTOMATIC
handling right).
the widgets in question are GtkText, GtkCList, GtkLayout and eventually some
other third party widgets that i'm not currently aware off (GnomeCanvas inherits
from GtkLayout and GtkTree doesn't implement scrolling facilities itself).

further, a GtkViewport implements a scrollable area and is not of actuall use
seperatedly from a GtkScrolledWindow, it's code should better be moved
into the gtkscrolledwindow.c. since a scrolled window automatically always
includes a GtkViewport, but tries to hide that from API, it does some nasty
hacks widget tree wise, like forwarding the GtkContainer::add and
GtkContainer::remove signals to the viewport. this occasionally leads to
problems, e.g. one would expect that the following code portion would work:

GtkWidget *sc;
GtkWidget *label;
sc = gtk_scrolled_window_new (NULL, NULL);
label = gtk_label_new ("i'm a child");
gtk_container_add (GTK_CONTAINER (sc), label);
gtk_container_remove (GTK_CONTAINER (sc), label);

but it doesn't, since gtk_container_remove() will abort because
label->parent != sc.
instead one needs to
gtk_container_remove (GTK_CONTAINER (GTK_SCROLLED_WINDOW (sc)->viewport),
                      label);


what's involved to solve these problems?

as owen said, scrollable widgets would implement an extra signal, which is not
mandatory for all widgets, similar to the "activate" signal implementation of
widgets, which always has the same semantics if implemented, but can be named
differently, depending on the implementation inheritance branch (e.g. a
GtkButton implements this signal as "clicked").
also, the scrollbar specific code of these scrollable widgets would get removed
from the actuall implementation, and they need to be put into a scrolled window
if one would want them to be scrollable.
this alltogether would impose some source incompatibilities, which is virtually
the only thing that could prevent us from actually cleaning up the scrolling
mess. i'll try to assemble these incompatibilities:

functions that would become deprecated:
---------------------------------------
(but could be compatibility-maintained to some extend (i.e. set/get of
adjustments will only work if the widget already got added to a parent)

void       gtk_text_set_adjustments (GtkText       *text,
                                     GtkAdjustment *hadj,
                                     GtkAdjustment *vadj);
void gtk_clist_set_policy (GtkCList      *clist,
                           GtkPolicyType  vscrollbar_policy,
                           GtkPolicyType  hscrollbar_policy);
GtkAdjustment* gtk_layout_get_hadjustment (GtkLayout     *layout);
GtkAdjustment* gtk_layout_get_vadjustment (GtkLayout     *layout);
void           gtk_layout_set_hadjustment (GtkLayout     *layout,
                                           GtkAdjustment *adjustment);
void           gtk_layout_set_vadjustment (GtkLayout     *layout,
                                           GtkAdjustment *adjustment);

functions that would be modified:
---------------------------------

GtkWidget* gtk_text_new             (GtkAdjustment *hadj,
                                     GtkAdjustment *vadj);
GtkWidget* gtk_layout_new           (GtkAdjustment *hadjustment,
                                     GtkAdjustment *vadjustment);
they would become:
GtkWidget* gtk_text_new             (void);
GtkWidget* gtk_layout_new           (void);

new API functions:
------------------

void gtk_widget_set_scroll_adjustments (GtkWidget     *widget,
                                        GtkAdjustment *hadj,
                                        GtkAdjustment *vadj);
[the implementation would be similar to the existing gtk_widget_activate]

GtkViewport would more or less vanish from the widget tree (we could
further maintain its code, but there wouldn't be much point in it, and it
doesn't seem to be used outside of gtkscrolledwindow.c, simply because it's
not of actuall use outside of it).
also, code that currently uses GtkLayout, GtkCList, GtkText or thereof derived
widgets would need to put them inside an extra scrolled window (if the
programmer intends these widgets to be scrollable at least).

all in all, these changes are not as bad as it may seem, use of the set/get
adjustment functions is actually extremely rare, they are mostly used within
code of derived widgets, also the gtk_text_new(void) and gtk_layout_new(void)
changes are extremely easy ones. what remains is the extra addition of these
widgets into a scrolled window, something that shouldn't be too hard to achive
actually ;).

i personally feel like we should go for something like the above, especially
since the situation will become more and more worse, as people continue to
write additional third party widgets (the GtkViewport and GtkScrolledWindow
changes actually need to be done regardless of what we do to the clist, layout
and text widgets).

> 
> Regards,
>                                         Owen
> 

---
ciaoTJ



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