@c -----------------------------------------------------------------------------
@c File     : gtk-adjustments.texi
@c License  : GNU General Public License (GPL)
@c Language : English
@c Author   : Dieter Kaiser
@c Date     : 09.03.2012
@c Revision : 01.08.2013
@c 
@c Copyright (C) 2012, 2013 by Dieter Kaiser
@c -----------------------------------------------------------------------------

@menu
* Introduction to Adjustments::
* Creating an Adjustment::
* Using Adjustments the Easy Way::
* Adjustment Internals::
@end menu

@c -----------------------------------------------------------------------------
@node Introduction to Adjustments, Creating an Adjustment, Top, Top
@section Introduction

@findex GtkAdjustment
@findex gtk-adjustment
@findex adjustment, gtk-adjustment

GTK+ has various widgets that can be visually adjusted by the user using the
mouse or the keyboard, such as the range widgets, described in
@ref{Range Widgets}.  There are also a few widgets that display some adjustable
portion of a larger area of data, such as the viewport widget
@xurl{gtk-viewport}.

Obviously, an application needs to be able to react to changes the user makes in
range widgets.  One way to do this would be to have each widget emit its own
type of signal when its adjustment changes, and either pass the new value to the
signal handler, or require it to look inside the data structure of the widget in
order to ascertain the value.  But you may also want to connect the adjustments
of several widgets together, so that adjusting one adjusts the others.  The most
obvious example of this is connecting a scrollbar to a panning viewport or a
scrolling text area.  If each widget has its own way of setting or getting the
adjustment value, then the programmer may have to write their own signal
handlers to translate between the "output" of one widget's signal and the
"input" of another's adjustment setting function.

GTK+ solves this problem using the object @xurl{gtk-adjustment}, which is not a
widget but a way for widgets to store and pass adjustment information in an
abstract and flexible form.  The most obvious use of @xurl{gtk-adjustment} is to
store the configuration parameters and values of range widgets, such as
scrollbars and scale controls.  However, since @xurl{gtk-adjustment} is derived
from @xurl{g-object}, adjustments have some special powers beyond those of normal
data structures.  Most importantly, they can emit signals, just like widgets,
and these signals can be used not only to allow a program to react to user input
on adjustable widgets, but also to propagate adjustment values transparently
between adjustable widgets.

You will see how adjustments fit in when you see the other widgets that
incorporate them: Progress Bars, Viewports, Scrolled Windows, and others.

@c -----------------------------------------------------------------------------
@node Creating an Adjustment, Using Adjustments the Easy Way, Introduction to Adjustments, Top
@section Creating an Adjustment

@findex gtk-adjustment-new
@findex adjustment-new, gtk-adjustment-new

Many of the widgets which use adjustment objects do so automatically, but some
cases will be shown in later examples where you may need to create an adjustment
yourself.  An adjustment can be created with the function
@xurl{gtk-adjustment-new} which has the arguments @code{value}, @code{lower},
@code{upper}, @code{step-increment}, @code{page-increment}, and
@code{page-size}.

The argument @code{value} is the initial value you want to give to the
adjustment, usually corresponding to the topmost or leftmost position of an
adjustable widget.  The argument @code{lower} specifies the lowest value which
the adjustment can hold.  The argument @code{step-increment} specifies the
"smaller" of the two increments by which the user can change the value, while
@code{page-increment} is the "larger" one.  The argument @code{page-size}
usually corresponds somehow to the visible area of a panning widget.  The
argument @code{upper} is used to represent the bottom most or right most
coordinate in a panning widget's child.  Therefore it is not always
the largest number that @code{value} can take, since @code{page-size} of such
widgets is usually non-zero.

@c -----------------------------------------------------------------------------
@node Using Adjustments the Easy Way, Adjustment Internals, Creating an Adjustment, Top
@section Using Adjustments the Easy Way

The adjustable widgets can be roughly divided into those which use and require
specific units for these values and those which treat them as arbitrary numbers.
The group which treats the values as arbitrary numbers includes the range
widgets (scrollbars and scales, the progress bar widget, and the spin button
widget).  These widgets are all the widgets which are typically "adjusted"
directly by the user with the mouse or keyboard.  They will treat the lower and
upper values of an adjustment as a range within which the user can manipulate
the value of the adjustment.  By default, they will only modify the value of an
adjustment.

The other group includes the text widget, the viewport widget, the compound list
widget, and the scrolled window widget.  All of these widgets use pixel values
for their adjustments.  These are also all widgets which are typically
"adjusted" indirectly using scrollbars.  While all widgets which use adjustments
can either create their own adjustments or use ones you supply, you will
generally want to let this particular category of widgets create its own
adjustments.  Usually, they will eventually override all the values except the
value itself in whatever adjustments you give them, but the results are, in
general, undefined (meaning, you'll have to read the source code to find out,
and it may be different from widget to widget).

Now, you are probably thinking, since text widgets and viewports insist on
setting everything except the value of their adjustments, while scrollbars will
only touch the value of the adjustment, if you share an adjustment object
between a scrollbar and a text widget, manipulating the scrollbar will
automagically adjust the viewport widget? Of course it will! Just like this:

@findex gtk-viewport-new
@findex viewport-new, gtk-viewport-new

@findex gtk-scrollable-get-vadjustment
@findex scrollable-get-vadjustment, gtk-scrollable-get-vadjustment

@verbatim
(let (;; A viewport creates its own adjustments
      (viewport (gtk-viewport-new))
      ;; use the adjustment from the viewport for the scrollbar
      (vscrollbar (make-instance 'gtk-scrollbar
                                 :orientation :vertical
                                 :vadjustment
                                 (gtk-scrollable-get-vadjustment viewport))))
  [...] )
@end verbatim

@c -----------------------------------------------------------------------------
@node Adjustment Internals, , Using Adjustments the Easy Way, Top
@section Adjustment Internals

Ok, you say, that's nice, but what if I want to create my own handlers to
respond when the user adjusts a range widget or a spin button, and how do I get
at the value of the adjustment in these handlers? To answer these questions and
more, let's start by taking a look at the Lisp class representing
@xurl{gtk-adjustment} itself:

@verbatim
(define-g-object-class "GtkAdjustment" gtk-adjustment
  (:superclass gtk-object
   :export t
   :interfaces nil
   :type-initializer "gtk_adjustment_get_type")
  ((lower
    gtk-adjustment-lower
    "lower" "gdouble" t t)
   (page-increment
    gtk-adjustment-page-increment
    "page-increment" "gdouble" t t)
   (page-size
    gtk-adjustment-page-size
    "page-size" "gdouble" t t)
   (step-increment
    gtk-adjustment-step-increment
    "step-increment" "gdouble" t t)
   (upper
    gtk-adjustment-upper
    "upper" "gdouble" t t)
   (value
    gtk-adjustment-value
    "value" "gdouble" t t)))
@end verbatim

@findex gtk-adjustment-get-value
@findex gtk-adjustment-set-value

@findex adjustment-get-value, gtk-adjustment-get-value
@findex adjustment-set-value, gtk-adjustment-set-value

The slots of the class are @code{lower}, @code{page-increment},
@code{page-size}, @code{step-increment}, @code{upper}, and @code{value}.  The
slots represent the properties of the C class @xurl{gtk-adjustment}.  The slots
can be accessed with the corresponding Lisp accessor functions.  Alternativly,
the C accessor functions like @code{gtk_adjustment_get_value()} and
@code{gtk_adjustment_set_value()} are availabe in the Lisp binding through e. g.
@xurl{gtk-adjustment-get-value} and @xurl{gtk-adjustment-set-value} for the
property @code{value}.

As mentioned earlier, an adjustment object is a subclass of @xurl{g-object} just
like all the various widgets, and thus it is able to emit signals.  This is, of
course, why updates happen automagically when you share an adjustment object
between a scrollbar and another adjustable widget; all adjustable widgets
connect signal handlers to their adjustment's "value-changed" signal, as can
your program.

The various widgets that use the adjustment object will emit the signal
"value-changed" on an adjustment whenever they change its value.  This happens
both when user input causes the slider to move on a range widget, as well as
when the program explicitly changes the value with
@xurl{gtk-adjustment-set-value}.  So, for example, if you have a scale widget,
and you want to change the rotation of a picture whenever its value changes, you
would create a callback like this:

@verbatim
(defun cb-rotate-picture (adj picture)
  (set-picture-rotation picture (gtk-adjustment-get-value adj))
  ... )
@end verbatim

and connect it to the scale widget's adjustment like this:

@verbatim
(g-signal-connect adj "value-changed"
                  (lambda (widget)
                    (cb-rotate-picture widget picture)))
@end verbatim

What about when a widget reconfigures the upper or lower fields of its
adjustment, such as when a user adds more text to a text widget? In this case,
it emits the signal "changed".  Range widgets typically connect a handler to
this signal, which changes their appearance to reflect the change - for example,
the size of the slider in a scrollbar will grow or shrink in inverse proportion
to the difference between the lower and upper values of its adjustment.

You probably won't ever need to attach a handler to the signal "changed", unless
you are writing a new type of range widget.  However, if you change any of the
values in an adjustment directly, you should emit this signal on it to
reconfigure whatever widgets are using it, like this
@code{(g-signal-emit-by-name adj "changed")}.

