Legacy Maemo 5 Documentation/Graphical UI Tutorial/Navigation

(Pannable area example)
(wikify slightly)
 
(5 intermediate revisions not shown)
Line 1: Line 1:
-
=Navigation =
+
{{Legacy documentation}}
-
In previous examples only one widget was added to a window so we could simply use a <code>gtk_container_add()</code> to "pack" it into the window. To pack more than one widget into a window, use container widgets.
+
-
To develop Hildon user interfaces, you can use any container widget provided by GTK+. For more information, see the GTK+ 2.0 Tutorial.
+
In previous examples only one widget was added to a window so we can simply use a <code>gtk_container_add()</code> to "pack" it into the window. To pack more than one widget into a window, use container widgets.
-
Apart from supporting those containers, the Hildon framework also provides a new container widget called HildonPannableArea, a scrolling widget designed for touch screens.
+
To develop Hildon user interfaces, use any container widget provided by GTK+. For more information, see the GTK+ 2.0 Tutorial.
 +
Apart from supporting those containers, the Hildon framework also provides a new container widget called <code>HildonPannableArea</code>, a scrolling widget designed for touch screens.
== Pannable area ==
== Pannable area ==
-
HildonPannableArea is used to create an area with another widget inside which is accessible regardless of the size using the touchscreen to scroll it. You may insert any type of widget into a pannable area and it is always accessible by using the fingers to pan, or scroll, in the area.
+
 
 +
<code>HildonPannableArea</code> is used to create an area with another widget inside which is accessible regardless of the size using the touchscreen to scroll it. You can insert any type of widget into a pannable area; it is always accessible by using the fingers to pan, or scroll, in the area.
This widget can be "panned" (scrolled) in any direction using the touchscreen with the fingers. One remarkable characteristic is that the scrolling is "kinetic", meaning that the motion continues from the initial motion by gradually slowing down to stop.
This widget can be "panned" (scrolled) in any direction using the touchscreen with the fingers. One remarkable characteristic is that the scrolling is "kinetic", meaning that the motion continues from the initial motion by gradually slowing down to stop.
-
The use of this widget is very similar to GTK+ scrolled windows. In fact, both widgets implement a similar concept and its APIs are very similar.
+
Using this widget is very similar to GTK+ scrolled windows. In fact, both widgets implement a similar concept and its APIs are very similar.
To create a new pannable area, choose one of the following functions:
To create a new pannable area, choose one of the following functions:
-
<tt>GtkWidget<span><font color="#990000"><nowiki>*</nowiki></font></span> <span>'''<span><font color="#000000">hildon_pannable_area_new</font></span>'''</span>       <span><font color="#990000">(</font></span><span><font color="#009900">void</font></span><span><font color="#990000">);</font></span>
+
<source lang="c">
-
GtkWidget<span><font color="#990000"><nowiki>*</nowiki></font></span> <span>'''<span><font color="#000000">hildon_pannable_area_new_full</font></span>'''</span>   <span><font color="#990000">(</font></span>gint mode<span><font color="#990000">,</font></span>
+
GtkWidget*  hildon_pannable_area_new        (void);
-
                                              gboolean enabled<span><font color="#990000">,</font></span>
+
GtkWidget*  hildon_pannable_area_new_full  (gint mode,
-
                                              gdouble vel_min<span><font color="#990000">,</font></span>
+
                                            gboolean enabled,
-
                                              gdouble vel_max<span><font color="#990000">,</font></span>
+
                                            gdouble vel_min,
-
                                              gdouble decel<span><font color="#990000">,</font></span>
+
                                            gdouble vel_max,
-
                                              guint sps<span><font color="#990000">);</font></span>
+
                                            gdouble decel,
-
</tt>
+
                                            guint sps);
 +
</source>
The first one creates a new pannable area with the properties set to the default values. The second one allows you to set the value of the most important properties of this widget:
The first one creates a new pannable area with the properties set to the default values. The second one allows you to set the value of the most important properties of this widget:
-
* mode: Used to change the behaviour of the pannable area allowing to choose whether to use the "kinetic" effect described above.
+
* <code>mode</code>: Used to change the behaviour of the pannable area allowing to choose whether to use the "kinetic" effect described above.
-
* enabled: Enable or disable finger-scroll.
+
* <code>enabled</code>: Enable or disable finger-scroll.
-
* vel_min, vel_max: Allows developers to adjust how many pixels the child widget moves per "frame".
+
* <code>vel_min</code>, <code>vel_max</code>: Allows developers to adjust how many pixels the child widget moves per "frame".
-
* decel: Value for the deceleration property.
+
* <code>decel</code>: Value for the deceleration property.
-
* sps: Amount of scroll events to generate per second.
+
* <code>sps</code>: Amount of scroll events to generate per second.
The default values of these properties are right for most applications and so the simpler constructor is sufficient. For more information on the properties of the pannable area, see the Hildon reference manual.
The default values of these properties are right for most applications and so the simpler constructor is sufficient. For more information on the properties of the pannable area, see the Hildon reference manual.
-
Once the area is created, you can place your object into the pannable window using the following function.
+
When the area is created, place your object into the pannable window using the following function.
-
<tt><span><font color="#009900">void</font></span>       <span>'''<span><font color="#000000">hildon_pannable_area_add_with_viewport</font></span>'''</span> <span><font color="#990000">(</font></span>HildonPannableArea <span><font color="#990000"><nowiki>*</nowiki></font></span>area<span><font color="#990000">,</font></span>
+
<source lang="c">
-
                                                    GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>child<span><font color="#990000">);</font></span>
+
void        hildon_pannable_area_add_with_viewport (HildonPannableArea *area,
-
</tt>
+
                                                    GtkWidget *child);
 +
</source>
-
That is a convenience function used to add a child to a GtkViewport, and add the viewport to the pannable area.
+
That is a convenience function used to add a child to a <code>GtkViewport</code>, and add the viewport to the pannable area.
'''Warning'''
'''Warning'''
-
Widgets with native scrolling should be added directly inside a pannable area. Widgets such as, for example, GtkTextView, GtkTreeView, GtkIconView and GtkLayout should be added by calling <code>gtk_container_add()</code>. Otherwise, panning could not work properly.
+
Add widgets with native scrolling directly inside a pannable area. Add widgets such as <code>GtkTextView</code>, <code>GtkTreeView</code>, <code>GtkIconView</code> and <code>GtkLayout</code> by calling <code>gtk_container_add()</code>. Otherwise, panning may not work properly.
 +
== Pannable area example ==
-
==Pannable area example ==
 
Functions explained above are enough for a simple example. The following example packs a table with 100 toggle buttons into a pannable area.
Functions explained above are enough for a simple example. The following example packs a table with 100 toggle buttons into a pannable area.
-
[[Image:example-pannable-area.png|400px]]
+
[[Image:example-pannable-area.png|frame|center|alt=Screenshot of pannable area with buttons|Pannable area]]
'''Example 5.1. Example of a pannable area'''
'''Example 5.1. Example of a pannable area'''
-
<tt><span>'''<span><font color="#000080"><nowiki>#include</nowiki></font></span>'''</span> <span><font color="#FF0000">&lt;stdio.h&gt;</font></span>
+
<source lang="c">
-
<span>'''<span><font color="#000080"><nowiki>#include</nowiki></font></span>'''</span> <span><font color="#FF0000">&lt;hildon/hildon.h&gt;</font></span>
+
#include <stdio.h>
-
+
#include <hildon/hildon.h>
-
<span>'''<span><font color="#0000FF">static</font></span>'''</span> GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span><span>'''<span><font color="#000000">create_table</font></span>'''</span> <span><font color="#990000">()</font></span>
+
-
<span><font color="#FF0000">{</font></span>
+
-
+
-
  GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>hbox<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
  GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>table<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
  GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>button<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
  <span><font color="#009900">char</font></span> buffer<span><font color="#990000">[</font></span><span><font color="#993399">32</font></span><span><font color="#990000">];</font></span>
+
-
  <span><font color="#009900">int</font></span> i<span><font color="#990000">,</font></span> j<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
+
-
  <span>''<span><font color="#9A1900">/* create a table of 10 by 10 squares. */</font></span>''</span>
+
-
  table <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_table_new</font></span>'''</span> <span><font color="#990000">(</font></span><span><font color="#993399">10</font></span><span><font color="#990000">,</font></span> <span><font color="#993399">10</font></span><span><font color="#990000">,</font></span> FALSE<span><font color="#990000">);</font></span>
+
-
+
-
  <span>''<span><font color="#9A1900">/* set the spacing to 10 on x and 10 on y */</font></span>''</span>
+
-
  <span>'''<span><font color="#000000">gtk_table_set_row_spacings</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_TABLE</font></span>'''</span> <span><font color="#990000">(</font></span>table<span><font color="#990000">),</font></span> <span><font color="#993399">10</font></span><span><font color="#990000">);</font></span>
+
-
  <span>'''<span><font color="#000000">gtk_table_set_col_spacings</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_TABLE</font></span>'''</span> <span><font color="#990000">(</font></span>table<span><font color="#990000">),</font></span> <span><font color="#993399">10</font></span><span><font color="#990000">);</font></span>
+
-
+
-
  <span>'''<span><font color="#000000">gtk_widget_show</font></span>'''</span> <span><font color="#990000">(</font></span>table<span><font color="#990000">);</font></span>
+
-
+
-
  <span>''<span><font color="#9A1900">/* this simply creates a grid of toggle buttons on the table</font></span>''</span>
+
-
<span>''<span><font color="#9A1900">  * to demonstrate the scrolled window. */</font></span>''</span>
+
-
  <span>'''<span><font color="#0000FF">for</font></span>'''</span> <span><font color="#990000">(</font></span>i <span><font color="#990000"><nowiki>=</nowiki></font></span> <span><font color="#993399">1</font></span><span><font color="#990000"><nowiki>;</nowiki></font></span> i <span><font color="#990000">&lt;</font></span> <span><font color="#993399">10</font></span><span><font color="#990000"><nowiki>;</nowiki></font></span> i<span><font color="#990000">++)</font></span>
+
-
    <span>'''<span><font color="#0000FF">for</font></span>'''</span> <span><font color="#990000">(</font></span>j <span><font color="#990000"><nowiki>=</nowiki></font></span> <span><font color="#993399">1</font></span><span><font color="#990000"><nowiki>;</nowiki></font></span> j <span><font color="#990000">&lt;</font></span> <span><font color="#993399">10</font></span><span><font color="#990000"><nowiki>;</nowiki></font></span> j<span><font color="#990000">++)</font></span> <span><font color="#FF0000">{</font></span>
+
-
      <span>'''<span><font color="#000000">sprintf</font></span>'''</span> <span><font color="#990000">(</font></span>buffer<span><font color="#990000">,</font></span> <span><font color="#FF0000">"button (%d,%d)</font></span><span><font color="#CC33CC">\n</font></span><span><font color="#FF0000">"</font></span><span><font color="#990000">,</font></span> i<span><font color="#990000">,</font></span> j<span><font color="#990000">);</font></span>
+
-
      button <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_toggle_button_new_with_label</font></span>'''</span> <span><font color="#990000">(</font></span>buffer<span><font color="#990000">);</font></span>
+
-
+
-
      <span>'''<span><font color="#000000">gtk_table_attach_defaults</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_TABLE</font></span>'''</span> <span><font color="#990000">(</font></span>table<span><font color="#990000">),</font></span> button<span><font color="#990000">,</font></span>
+
-
                                  i<span><font color="#990000">,</font></span> i<span><font color="#990000">+</font></span><span><font color="#993399">1</font></span><span><font color="#990000">,</font></span> j<span><font color="#990000">,</font></span> j<span><font color="#990000">+</font></span><span><font color="#993399">1</font></span><span><font color="#990000">);</font></span>
+
-
    <span><font color="#FF0000">}</font></span>
+
-
+
-
  <span>'''<span><font color="#0000FF">return</font></span>'''</span> table<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
<span><font color="#FF0000">}</font></span>
+
-
+
-
<span><font color="#009900">int</font></span> <span>'''<span><font color="#000000">main</font></span>'''</span><span><font color="#990000">(</font></span> <span><font color="#009900">int</font></span>  argc<span><font color="#990000">,</font></span>
+
-
          <span><font color="#009900">char</font></span> <span><font color="#990000"><nowiki>*</nowiki></font></span>argv<span><font color="#990000">[]</font></span> <span><font color="#990000">)</font></span>
+
-
<span><font color="#FF0000">{</font></span>
+
-
  <span>'''<span><font color="#0000FF">static</font></span>'''</span> GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>window<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
  GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>button<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
  GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>pannable_area<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
  GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>table<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
+
-
  <span>'''<span><font color="#000000">hildon_gtk_init</font></span>'''</span> <span><font color="#990000">(&amp;</font></span>argc<span><font color="#990000">,</font></span> <span><font color="#990000">&amp;</font></span>argv<span><font color="#990000">);</font></span>
+
-
+
-
  window <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">hildon_stackable_window_new</font></span>'''</span> <span><font color="#990000">();</font></span>
+
-
  <span>'''<span><font color="#000000">g_signal_connect</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">G_OBJECT</font></span>'''</span> <span><font color="#990000">(</font></span>window<span><font color="#990000">),</font></span> <span><font color="#FF0000">"destroy"</font></span><span><font color="#990000">,</font></span>
+
-
                    <span>'''<span><font color="#000000">G_CALLBACK</font></span>'''</span> <span><font color="#990000">(</font></span>gtk_widget_destroy<span><font color="#990000">),</font></span> NULL<span><font color="#990000">);</font></span>
+
-
+
-
  pannable_area <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">hildon_pannable_area_new</font></span>'''</span> <span><font color="#990000">();</font></span>
+
-
+
-
  table <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">create_table</font></span>'''</span> <span><font color="#990000">();</font></span>
+
-
+
-
  <span>''<span><font color="#9A1900">/* pack the table into the scrolled window */</font></span>''</span>
+
-
  <span>'''<span><font color="#000000">hildon_pannable_area_add_with_viewport</font></span>'''</span> <span><font color="#990000">(</font></span>
+
-
    <span>'''<span><font color="#000000">HILDON_PANNABLE_AREA</font></span>'''</span> <span><font color="#990000">(</font></span>pannable_area<span><font color="#990000">),</font></span> table<span><font color="#990000">);</font></span>
+
-
+
-
  <span>''<span><font color="#9A1900">/* Add the box into the window*/</font></span>''</span>
+
-
  <span>'''<span><font color="#000000">gtk_container_add</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_CONTAINER</font></span>'''</span> <span><font color="#990000">(</font></span>window<span><font color="#990000">),</font></span> pannable_area<span><font color="#990000">);</font></span>
+
-
+
-
  <span>'''<span><font color="#000000">gtk_widget_show_all</font></span>'''</span> <span><font color="#990000">(</font></span>window<span><font color="#990000">);</font></span>
+
-
+
-
  <span>'''<span><font color="#000000">gtk_main</font></span>'''</span> <span><font color="#990000">();</font></span>
+
-
+
-
  <span>'''<span><font color="#0000FF">return</font></span>'''</span> <span><font color="#993399">0</font></span><span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
<span><font color="#FF0000">}</font></span>
+
-
</tt>
+
-
In the example above, two calls are enough to use a pannable area. The rest of the code in the example is no different from that used in a GTK+ application.
+
static GtkWidget *create_table ()
 +
{
-
<tt>  <span>''<span><font color="#9A1900">/* Create a new pannable area. */</font></span>''</span>
+
  GtkWidget *hbox;
-
  pannable_area <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">hildon_pannable_area_new</font></span>'''</span> <span><font color="#990000">();</font></span>
+
  GtkWidget *table;
-
  <span>''<span><font color="#9A1900">/* Pack the table into the pannable area */</font></span>''</span>
+
  GtkWidget *button;
-
  <span>'''<span><font color="#000000">hildon_pannable_area_add_with_viewport</font></span>'''</span> <span><font color="#990000">(</font></span> <span>'''<span><font color="#000000">HILDON_PANNABLE_AREA</font></span>'''</span> <span><font color="#990000">(</font></span>pannable_area<span><font color="#990000">),</font></span> table<span><font color="#990000">);</font></span>
+
  char buffer[32];
-
</tt>
+
  int i, j;
-
To see all the buttons, users can scroll with the fingers. In this example, horizontal and vertical panning are activated as that is needed to allow users to be able to interact both all the widgets. The property "mov-mode" controls if the area can scroll horizontally, vertically (default value) or both, using HILDON_MOVEMENT_MODE_HORIZ, HILDON_MOVEMENT_MODE_VERT or HILDON_MOVEMENT_MODE_BOTH, respectively.
+
  /* create a table of 10 by 10 squares. */
 +
  table = gtk_table_new (10, 10, FALSE);
 +
 
 +
  /* set the spacing to 10 on x and 10 on y */
 +
  gtk_table_set_row_spacings (GTK_TABLE (table), 10);
 +
  gtk_table_set_col_spacings (GTK_TABLE (table), 10);
 +
 
 +
  gtk_widget_show (table);
 +
 
 +
  /* this simply creates a grid of toggle buttons on the table
 +
  * to demonstrate the scrolled window. */
 +
  for (i = 1; i < 10; i++)
 +
    for (j = 1; j < 10; j++) {
 +
      sprintf (buffer, "button (%d,%d)\n", i, j);
 +
      button = gtk_toggle_button_new_with_label (buffer);
 +
 
 +
      gtk_table_attach_defaults (GTK_TABLE (table), button,
 +
                                i, i+1, j, j+1);
 +
    }
 +
 
 +
  return table;
 +
}
 +
 
 +
int main( int  argc,
 +
          char *argv[] )
 +
{
 +
  static GtkWidget *window;
 +
  GtkWidget *button;
 +
  GtkWidget *pannable_area;
 +
  GtkWidget *table;
 +
 
 +
  hildon_gtk_init (&argc, &argv);
 +
 
 +
  window = hildon_stackable_window_new ();
 +
  g_signal_connect (G_OBJECT (window), "destroy",
 +
                    G_CALLBACK (gtk_widget_destroy), NULL);
 +
 
 +
  pannable_area = hildon_pannable_area_new ();
 +
 
 +
  table = create_table ();
 +
 
 +
  /* pack the table into the scrolled window */
 +
  hildon_pannable_area_add_with_viewport (
 +
    HILDON_PANNABLE_AREA (pannable_area), table);
 +
 
 +
  /* Add the box into the window*/
 +
  gtk_container_add (GTK_CONTAINER (window), pannable_area);
 +
 
 +
  gtk_widget_show_all (window);
 +
 
 +
  gtk_main ();
 +
 
 +
  return 0;
 +
}
 +
</source>
 +
 
 +
In the example above, two calls are enough to use a pannable area. The rest of the code in the example is no different from the one used in a GTK+ application.
 +
 
 +
<source lang="c">
 +
/* Create a new pannable area. */
 +
pannable_area = hildon_pannable_area_new ();
 +
/* Pack the table into the pannable area */
 +
hildon_pannable_area_add_with_viewport ( HILDON_PANNABLE_AREA (pannable_area), table);
 +
</source>
 +
 
 +
To see all the buttons, users can scroll with the fingers. In this example, horizontal and vertical panning are activated because that is needed to allow users to be able to interact both all the widgets. The property "<code>mov-mode</code>" controls if the area can scroll horizontally, vertically (default value) or both, using <code>HILDON_MOVEMENT_MODE_HORIZ</code>, <code>HILDON_MOVEMENT_MODE_VERT</code> or <code>HILDON_MOVEMENT_MODE_BOTH</code>, respectively.
 +
 
 +
== Additional features ==
-
==Additional features ==
 
Pannable areas provide a set of convenience functions that make it easier to move to a certain element inside the area without users interaction.
Pannable areas provide a set of convenience functions that make it easier to move to a certain element inside the area without users interaction.
Line 140: Line 146:
For example, the first of the functions changes the current position on the pannable area to ensure position (x,y) is visible. The movement is a quick jump. The second function performs a smoothly scroll towards the selected position.
For example, the first of the functions changes the current position on the pannable area to ensure position (x,y) is visible. The movement is a quick jump. The second function performs a smoothly scroll towards the selected position.
-
<tt><span><font color="#009900">void</font></span>       <span>'''<span><font color="#000000">hildon_pannable_area_jump_to</font></span>'''</span>   <span><font color="#990000">(</font></span>HildonPannableArea <span><font color="#990000"><nowiki>*</nowiki></font></span>area<span><font color="#990000">,</font></span>
+
<source lang="c">
-
                                              <span>'''<span><font color="#0000FF">const</font></span>'''</span> gint x<span><font color="#990000">,</font></span>
+
void        hildon_pannable_area_jump_to    (HildonPannableArea *area,
-
                                              <span>'''<span><font color="#0000FF">const</font></span>'''</span> gint y<span><font color="#990000">);</font></span>
+
                                            const gint x,
-
<span><font color="#009900">void</font></span>       <span>'''<span><font color="#000000">hildon_pannable_area_scroll_to</font></span>'''</span> <span><font color="#990000">(</font></span>HildonPannableArea <span><font color="#990000"><nowiki>*</nowiki></font></span>area<span><font color="#990000">,</font></span>
+
                                            const gint y);
-
                                              <span>'''<span><font color="#0000FF">const</font></span>'''</span> gint x<span><font color="#990000">,</font></span>
+
void        hildon_pannable_area_scroll_to  (HildonPannableArea *area,
-
                                              <span>'''<span><font color="#0000FF">const</font></span>'''</span> gint y<span><font color="#990000">);</font></span>
+
                                            const gint x,
-
</tt>
+
                                            const gint y);
 +
</source>
The following functions make it possible to jump or scroll to a certain descendent of the area. The argument should be a reference to a descendent widget.
The following functions make it possible to jump or scroll to a certain descendent of the area. The argument should be a reference to a descendent widget.
-
<tt><span><font color="#009900">void</font></span>       <span>'''<span><font color="#000000">hildon_pannable_area_jump_to_child</font></span>'''</span> <span><font color="#990000">(</font></span>HildonPannableArea <span><font color="#990000"><nowiki>*</nowiki></font></span>area<span><font color="#990000">,</font></span>
+
<source lang="c">
-
                                                GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>child<span><font color="#990000">);</font></span>
+
void        hildon_pannable_area_jump_to_child (HildonPannableArea *area,
-
<span><font color="#009900">void</font></span>       hildon_pannable_area_scroll_to_child
+
                                                GtkWidget *child);
-
                                            <span><font color="#990000">(</font></span>HildonPannableArea <span><font color="#990000"><nowiki>*</nowiki></font></span>area<span><font color="#990000">,</font></span>
+
void        hildon_pannable_area_scroll_to_child
-
                                              GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>child<span><font color="#990000">);</font></span>
+
                                            (HildonPannableArea *area,
-
</tt>
+
                                            GtkWidget *child);
 +
</source>
-
Here is a modified version of the previous example. The pannable area is packed into an GtkVBox and a new button is also added to navigate to the last clicked button.
+
Here is a modified version of the previous example. The pannable area is packed into an <code>GtkVBox</code> and a new button is also added to navigate to the last clicked button.
'''Example 5.2. Example of a pannable area and a "jump-to" button'''
'''Example 5.2. Example of a pannable area and a "jump-to" button'''
-
<tt><span>'''<span><font color="#000080"><nowiki>#include</nowiki></font></span>'''</span> <span><font color="#FF0000">&lt;stdio.h&gt;</font></span>
+
<source lang="c">
-
<span>'''<span><font color="#000080"><nowiki>#include</nowiki></font></span>'''</span> <span><font color="#FF0000">&lt;hildon/hildon.h&gt;</font></span>
+
#include <stdio.h>
-
+
#include <hildon/hildon.h>
-
GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span> last_clicked_button<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
 
-
GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span> pannable_area<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
GtkWidget * last_clicked_button;
-
+
GtkWidget * pannable_area;
-
<span>'''<span><font color="#0000FF">static</font></span>'''</span> <span><font color="#009900">void</font></span> <span>'''<span><font color="#000000">destroy</font></span>'''</span><span><font color="#990000">(</font></span> GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>widget<span><font color="#990000">,</font></span>
+
 
-
                      gpointer  data <span><font color="#990000">)</font></span>
+
 
-
<span><font color="#FF0000">{</font></span>
+
static void destroy( GtkWidget *widget,
-
    <span>'''<span><font color="#000000">gtk_main_quit</font></span>'''</span> <span><font color="#990000">();</font></span>
+
                    gpointer  data )
-
<span><font color="#FF0000">}</font></span>
+
{
-
+
    gtk_main_quit ();
-
<span>'''<span><font color="#0000FF">static</font></span>'''</span> <span><font color="#009900">void</font></span> <span>'''<span><font color="#000000">clicked</font></span>'''</span> <span><font color="#990000">(</font></span>GtkButton <span><font color="#990000"><nowiki>*</nowiki></font></span>button<span><font color="#990000">,</font></span>
+
}
-
                      gpointer  user_data<span><font color="#990000">)</font></span>
+
 
-
<span><font color="#FF0000">{</font></span>
+
static void clicked (GtkButton *button,
-
      last_clicked_button <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">GTK_WIDGET</font></span>'''</span> <span><font color="#990000">(</font></span>button<span><font color="#990000">);</font></span>
+
                    gpointer  user_data)
-
<span><font color="#FF0000">}</font></span>
+
{
-
+
    last_clicked_button = GTK_WIDGET (button);
-
<span>'''<span><font color="#0000FF">static</font></span>'''</span> <span><font color="#009900">void</font></span> <span>'''<span><font color="#000000">go_to_last_clicked</font></span>'''</span> <span><font color="#990000">(</font></span>GtkButton <span><font color="#990000"><nowiki>*</nowiki></font></span>button<span><font color="#990000">,</font></span>
+
}
-
                                gpointer  user_data<span><font color="#990000">)</font></span>
+
 
-
<span><font color="#FF0000">{</font></span>
+
static void go_to_last_clicked (GtkButton *button,
-
<span>''<span><font color="#9A1900">/*      hildon_pannable_area_jump_to_child (HILDON_PANNABLE_AREA (pannable_area), */</font></span>''</span>
+
                                gpointer  user_data)
-
<span>''<span><font color="#9A1900">/*                                         last_clicked_button); */</font></span>''</span>
+
{
-
  <span>'''<span><font color="#000000">hildon_pannable_area_jump_to_child</font></span>'''</span>    <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">HILDON_PANNABLE_AREA</font></span>'''</span> <span><font color="#990000">(</font></span>pannable_area<span><font color="#990000">),</font></span>
+
  hildon_pannable_area_jump_to_child   (HILDON_PANNABLE_AREA (pannable_area),
-
                                          last_clicked_button<span><font color="#990000">);</font></span>
+
                                         last_clicked_button);
-
+
}
-
<span><font color="#FF0000">}</font></span>
+
 
-
+
static GtkWidget *create_table ()
-
<span>'''<span><font color="#0000FF">static</font></span>'''</span> GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span><span>'''<span><font color="#000000">create_table</font></span>'''</span> <span><font color="#990000">()</font></span>
+
{
-
<span><font color="#FF0000">{</font></span>
+
    GtkWidget *table;
-
+
    GtkWidget *button;
-
    GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>hbox<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
    char buffer[32];
-
    GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>table<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
    int i, j;
-
    GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>button<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
 
-
    <span><font color="#009900">char</font></span> buffer<span><font color="#990000">[</font></span><span><font color="#993399">32</font></span><span><font color="#990000">];</font></span>
+
    /* create a table of 10 by 10 squares. */
-
    <span><font color="#009900">int</font></span> i<span><font color="#990000">,</font></span> j<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
    table = gtk_table_new (10, 10, FALSE);
-
+
 
-
    <span>''<span><font color="#9A1900">/* create a table of 10 by 10 squares. */</font></span>''</span>
+
    /* set the spacing to 10 on x and 10 on y */
-
    table <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_table_new</font></span>'''</span> <span><font color="#990000">(</font></span><span><font color="#993399">10</font></span><span><font color="#990000">,</font></span> <span><font color="#993399">10</font></span><span><font color="#990000">,</font></span> FALSE<span><font color="#990000">);</font></span>
+
    gtk_table_set_row_spacings (GTK_TABLE (table), 10);
-
+
    gtk_table_set_col_spacings (GTK_TABLE (table), 10);
-
    <span>''<span><font color="#9A1900">/* set the spacing to 10 on x and 10 on y */</font></span>''</span>
+
 
-
    <span>'''<span><font color="#000000">gtk_table_set_row_spacings</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_TABLE</font></span>'''</span> <span><font color="#990000">(</font></span>table<span><font color="#990000">),</font></span> <span><font color="#993399">10</font></span><span><font color="#990000">);</font></span>
+
    gtk_widget_show (table);
-
    <span>'''<span><font color="#000000">gtk_table_set_col_spacings</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_TABLE</font></span>'''</span> <span><font color="#990000">(</font></span>table<span><font color="#990000">),</font></span> <span><font color="#993399">10</font></span><span><font color="#990000">);</font></span>
+
 
-
+
    /* this simply creates a grid of toggle buttons on the table
-
    <span>'''<span><font color="#000000">gtk_widget_show</font></span>'''</span> <span><font color="#990000">(</font></span>table<span><font color="#990000">);</font></span>
+
    * to demonstrate the scrolled window. */
-
+
    for (i = 1; i < 10; i++)
-
    <span>''<span><font color="#9A1900">/* this simply creates a grid of toggle buttons on the table</font></span>''</span>
+
      for (j = 1; j < 10; j++) {
-
<span>''<span><font color="#9A1900">    * to demonstrate the scrolled window. */</font></span>''</span>
+
          sprintf (buffer, "button (%d,%d)\n", i, j);
-
    <span>'''<span><font color="#0000FF">for</font></span>'''</span> <span><font color="#990000">(</font></span>i <span><font color="#990000"><nowiki>=</nowiki></font></span> <span><font color="#993399">1</font></span><span><font color="#990000"><nowiki>;</nowiki></font></span> i <span><font color="#990000">&lt;</font></span> <span><font color="#993399">10</font></span><span><font color="#990000"><nowiki>;</nowiki></font></span> i<span><font color="#990000">++)</font></span>
+
  button = gtk_toggle_button_new_with_label (buffer);
-
        <span>'''<span><font color="#0000FF">for</font></span>'''</span> <span><font color="#990000">(</font></span>j <span><font color="#990000"><nowiki>=</nowiki></font></span> <span><font color="#993399">1</font></span><span><font color="#990000"><nowiki>;</nowiki></font></span> j <span><font color="#990000">&lt;</font></span> <span><font color="#993399">10</font></span><span><font color="#990000"><nowiki>;</nowiki></font></span> j<span><font color="#990000">++)</font></span> <span><font color="#FF0000">{</font></span>
+
 
-
          <span>'''<span><font color="#000000">sprintf</font></span>'''</span> <span><font color="#990000">(</font></span>buffer<span><font color="#990000">,</font></span> <span><font color="#FF0000">"button (%d,%d)</font></span><span><font color="#CC33CC">\n</font></span><span><font color="#FF0000">"</font></span><span><font color="#990000">,</font></span> i<span><font color="#990000">,</font></span> j<span><font color="#990000">);</font></span>
+
          g_signal_connect (G_OBJECT (button),
-
  button <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_toggle_button_new_with_label</font></span>'''</span> <span><font color="#990000">(</font></span>buffer<span><font color="#990000">);</font></span>
+
                            "clicked",
-
+
                            G_CALLBACK (clicked),
-
          <span>'''<span><font color="#000000">g_signal_connect</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">G_OBJECT</font></span>'''</span> <span><font color="#990000">(</font></span>button<span><font color="#990000">),</font></span>
+
                            NULL);
-
                            <span><font color="#FF0000">"clicked"</font></span><span><font color="#990000">,</font></span>
+
 
-
                            <span>'''<span><font color="#000000">G_CALLBACK</font></span>'''</span> <span><font color="#990000">(</font></span>clicked<span><font color="#990000">),</font></span>
+
  gtk_table_attach_defaults (GTK_TABLE (table), button,
-
                            NULL<span><font color="#990000">);</font></span>
+
                            i, i+1, j, j+1);
-
+
 
-
  <span>'''<span><font color="#000000">gtk_table_attach_defaults</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_TABLE</font></span>'''</span> <span><font color="#990000">(</font></span>table<span><font color="#990000">),</font></span> button<span><font color="#990000">,</font></span>
+
          gtk_widget_show (button);
-
                            i<span><font color="#990000">,</font></span> i<span><font color="#990000">+</font></span><span><font color="#993399">1</font></span><span><font color="#990000">,</font></span> j<span><font color="#990000">,</font></span> j<span><font color="#990000">+</font></span><span><font color="#993399">1</font></span><span><font color="#990000">);</font></span>
+
      }
-
+
 
-
          <span>'''<span><font color="#000000">gtk_widget_show</font></span>'''</span> <span><font color="#990000">(</font></span>button<span><font color="#990000">);</font></span>
+
    return table;
-
        <span><font color="#FF0000">}</font></span>
+
}
-
+
 
-
    <span>'''<span><font color="#0000FF">return</font></span>'''</span> table<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
int main( int  argc,
-
<span><font color="#FF0000">}</font></span>
+
          char *argv[] )
-
+
{
-
<span><font color="#009900">int</font></span> <span>'''<span><font color="#000000">main</font></span>'''</span><span><font color="#990000">(</font></span> <span><font color="#009900">int</font></span>   argc<span><font color="#990000">,</font></span>
+
    static GtkWidget *window;
-
          <span><font color="#009900">char</font></span> <span><font color="#990000"><nowiki>*</nowiki></font></span>argv<span><font color="#990000">[]</font></span> <span><font color="#990000">)</font></span>
+
    GtkWidget *button;
-
<span><font color="#FF0000">{</font></span>
+
    GtkWidget *table;
-
    <span>'''<span><font color="#0000FF">static</font></span>'''</span> GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>window<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
    GtkWidget *hbox;
-
<span>''<span><font color="#9A1900">//    GtkWidget *pannable_area;</font></span>''</span>
+
 
-
    GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>button<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
    hildon_gtk_init (&argc, &argv);
-
    GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>table<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
 
-
    GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>hbox<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
    /* Create a new hildon window for the pannable area to be
-
+
    * packed into.  */
-
    <span>'''<span><font color="#000000">gtk_init</font></span>'''</span> <span><font color="#990000">(&amp;</font></span>argc<span><font color="#990000">,</font></span> <span><font color="#990000">&amp;</font></span>argv<span><font color="#990000">);</font></span>
+
    window = hildon_stackable_window_new ();
-
+
    g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);
-
    <span>''<span><font color="#9A1900">/* Create a new hildon window for the pannable area to be</font></span>''</span>
+
    gtk_window_set_title (GTK_WINDOW (window), "HildonPannableArea example");
-
<span>''<span><font color="#9A1900">    * packed into.  */</font></span>''</span>
+
 
-
    window <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">hildon_stackable_window_new</font></span>'''</span> <span><font color="#990000">();</font></span>
+
    /* Create a table which will be inside the pannable area */
-
    <span>'''<span><font color="#000000">g_signal_connect</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">G_OBJECT</font></span>'''</span> <span><font color="#990000">(</font></span>window<span><font color="#990000">),</font></span> <span><font color="#FF0000">"destroy"</font></span><span><font color="#990000">,</font></span>
+
    table = create_table ();
-
      <span>'''<span><font color="#000000">G_CALLBACK</font></span>'''</span> <span><font color="#990000">(</font></span>destroy<span><font color="#990000">),</font></span> NULL<span><font color="#990000">);</font></span>
+
 
-
    <span>'''<span><font color="#000000">gtk_window_set_title</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_WINDOW</font></span>'''</span> <span><font color="#990000">(</font></span>window<span><font color="#990000">),</font></span> <span><font color="#FF0000">"HildonPannableArea example"</font></span><span><font color="#990000">);</font></span>
+
    /* Create a box and pack the widgets into it */
-
+
    hbox = gtk_hbox_new (FALSE, 0);
-
    <span>''<span><font color="#9A1900">/* Create a table which will be inside the pannable area */</font></span>''</span>
+
 
-
    table <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">create_table</font></span>'''</span> <span><font color="#990000">();</font></span>
+
    /* Add a button to jump */
-
+
    /* Button to go to last clicked */
-
    hbox <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_hbox_new</font></span>'''</span> <span><font color="#990000">(</font></span>FALSE<span><font color="#990000">,</font></span> <span><font color="#993399">0</font></span><span><font color="#990000">);</font></span>
+
    button = gtk_button_new_with_label ("Go to last clicked");
-
    <span>''<span><font color="#9A1900">/* Add a button to jump */</font></span>''</span>
+
 
-
    <span>''<span><font color="#9A1900">/* Button to go to last clicked */</font></span>''</span>
+
    g_signal_connect (G_OBJECT (button),
-
+
                      "clicked",
-
    button <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_button_new_with_label</font></span>'''</span> <span><font color="#990000">(</font></span><span><font color="#FF0000">"Go to last clicked"</font></span><span><font color="#990000">);</font></span>
+
                      G_CALLBACK (go_to_last_clicked),
-
    <span>'''<span><font color="#000000">gtk_widget_show</font></span>'''</span> <span><font color="#990000">(</font></span>button<span><font color="#990000">);</font></span>
+
                      NULL);
-
+
 
-
    <span>'''<span><font color="#000000">g_signal_connect</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">G_OBJECT</font></span>'''</span> <span><font color="#990000">(</font></span>button<span><font color="#990000">),</font></span>
+
    gtk_box_pack_start (GTK_BOX (hbox),
-
                      <span><font color="#FF0000">"clicked"</font></span><span><font color="#990000">,</font></span>
+
                        button,
-
                      <span>'''<span><font color="#000000">G_CALLBACK</font></span>'''</span> <span><font color="#990000">(</font></span>go_to_last_clicked<span><font color="#990000">),</font></span>
+
                        FALSE,
-
                      NULL<span><font color="#990000">);</font></span>
+
                        FALSE,
-
+
                        0);
-
    <span>'''<span><font color="#000000">gtk_box_pack_start</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_BOX</font></span>'''</span> <span><font color="#990000">(</font></span>hbox<span><font color="#990000">),</font></span>
+
 
-
                        button<span><font color="#990000">,</font></span>
+
    /* create a new pannable area. */
-
                        TRUE<span><font color="#990000">,</font></span>
+
    pannable_area = hildon_pannable_area_new ();
-
                        TRUE<span><font color="#990000">,</font></span>
+
    g_object_set (G_OBJECT (pannable_area),
-
                        <span><font color="#993399">0</font></span><span><font color="#990000">);</font></span>
+
                  "mov-mode", HILDON_MOVEMENT_MODE_BOTH, NULL);
-
+
 
-
    <span>''<span><font color="#9A1900">/* create a new pannable area. */</font></span>''</span>
+
    /* pack the table into the scrolled window */
-
    pannable_area <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">hildon_pannable_area_new</font></span>'''</span> <span><font color="#990000">();</font></span>
+
    hildon_pannable_area_add_with_viewport (
-
+
                  HILDON_PANNABLE_AREA (pannable_area), table);
-
    <span>''<span><font color="#9A1900">/* pack the table into the scrolled window */</font></span>''</span>
+
 
-
    <span>'''<span><font color="#000000">hildon_pannable_area_add_with_viewport</font></span>'''</span> <span><font color="#990000">(</font></span>
+
    gtk_box_pack_start (GTK_BOX (hbox),
-
                    <span>'''<span><font color="#000000">HILDON_PANNABLE_AREA</font></span>'''</span> <span><font color="#990000">(</font></span>pannable_area<span><font color="#990000">),</font></span> table<span><font color="#990000">);</font></span>
+
                        pannable_area,
-
+
                        TRUE,
-
    <span>'''<span><font color="#000000">gtk_box_pack_start</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_BOX</font></span>'''</span> <span><font color="#990000">(</font></span>hbox<span><font color="#990000">),</font></span>
+
                        TRUE,
-
                        pannable_area<span><font color="#990000">,</font></span>
+
                        0);
-
                        TRUE<span><font color="#990000">,</font></span>
+
 
-
                        TRUE<span><font color="#990000">,</font></span>
+
    /* Add the box into the window*/
-
                        <span><font color="#993399">0</font></span><span><font color="#990000">);</font></span>
+
    gtk_container_add (GTK_CONTAINER (window), hbox);
-
+
 
-
<span>''<span><font color="#9A1900">//    gtk_container_add (GTK_CONTAINER (hbox), pannable_area);</font></span>''</span>
+
    gtk_widget_show_all (window);
-
+
    gtk_main();
-
    <span>''<span><font color="#9A1900">//HACK THAT SHOULD DETROYED</font></span>''</span>
+
 
-
    <span>'''<span><font color="#000000">g_object_set</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">G_OBJECT</font></span>'''</span> <span><font color="#990000">(</font></span>pannable_area<span><font color="#990000">),</font></span>
+
    return 0;
-
                  <span><font color="#FF0000">"mov-mode"</font></span><span><font color="#990000">,</font></span> HILDON_MOVEMENT_MODE_BOTH <span><font color="#990000">);</font></span>
+
}
-
+
</source>
-
<span>''<span><font color="#9A1900">//    gtk_container_set_border_width (GTK_CONTAINER (pannable_area), 10);</font></span>''</span>
+
-
+
-
    <span>''<span><font color="#9A1900">/* Adding pannable area into window*/</font></span>''</span>
+
-
    <span>'''<span><font color="#000000">gtk_container_add</font></span>'''</span> <span><font color="#990000">(</font></span> <span>'''<span><font color="#000000">GTK_CONTAINER</font></span>'''</span> <span><font color="#990000">(</font></span>window<span><font color="#990000">),</font></span> pannable_area<span><font color="#990000">);</font></span>
+
-
    <span>'''<span><font color="#000000">gtk_widget_show</font></span>'''</span> <span><font color="#990000">(</font></span>hbox<span><font color="#990000">);</font></span>
+
-
+
-
    <span>'''<span><font color="#000000">gtk_widget_show_all</font></span>'''</span> <span><font color="#990000">(</font></span>window<span><font color="#990000">);</font></span>
+
-
+
-
    <span>'''<span><font color="#000000">gtk_widget_show</font></span>'''</span> <span><font color="#990000">(</font></span>pannable_area<span><font color="#990000">);</font></span>
+
-
+
-
    <span>'''<span><font color="#000000">gtk_main</font></span>'''</span><span><font color="#990000">();</font></span>
+
-
+
-
    <span>'''<span><font color="#0000FF">return</font></span>'''</span> <span><font color="#993399">0</font></span><span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
<span><font color="#FF0000">}</font></span>
+
-
</tt>
+
-
The example used a global variable to store a reference to the last clicked button. This reference is used by the callback go_to_last_clicked to jump to it by calling one of the navigation functions. This function is used as a handler for the signal "clicked" of the button outside the pannable area.
+
The example used a global variable to store a reference to the last clicked button. This reference is used by the callback <code>go_to_last_clicked</code> to jump to it by calling one of the navigation functions. This function is used as a handler for the signal "<code>clicked</code>" of the button outside the pannable area.
To test the different navigation functions, just change the call in the callback.
To test the different navigation functions, just change the call in the callback.
-
When you use the navigation functions that allow to navigate to a certain child, the widget must be already realized. Use the GTK_WIDGET_REALIZED macro to check it. If you want to call it during the initialization process, use the navigation function inside a callback to the "realized" signal, connecting it with <code>g_signal_connect_after()</code>.
+
When you use the navigation functions that allow to navigate to a certain child, the widget must already be realized. Use the <code>GTK_WIDGET_REALIZED</code> macro to check it. If you want to call it during the initialization process, use the navigation function inside a callback to the "<code>realized</code>" signal, connecting it with <code>g_signal_connect_after()</code>.

Latest revision as of 13:51, 15 October 2010

Image:Ambox_content.png
This article is legacy documentation, and is superseded by Forum Nokia documentation.
The Forum Nokia documentation is available as the Hildon 2.2 UI style guide, Fremantle master layout guide and the Hildon 2.2 widget UI specification

In previous examples only one widget was added to a window so we can simply use a gtk_container_add() to "pack" it into the window. To pack more than one widget into a window, use container widgets.

To develop Hildon user interfaces, use any container widget provided by GTK+. For more information, see the GTK+ 2.0 Tutorial.

Apart from supporting those containers, the Hildon framework also provides a new container widget called HildonPannableArea, a scrolling widget designed for touch screens.

[edit] Pannable area

HildonPannableArea is used to create an area with another widget inside which is accessible regardless of the size using the touchscreen to scroll it. You can insert any type of widget into a pannable area; it is always accessible by using the fingers to pan, or scroll, in the area.

This widget can be "panned" (scrolled) in any direction using the touchscreen with the fingers. One remarkable characteristic is that the scrolling is "kinetic", meaning that the motion continues from the initial motion by gradually slowing down to stop.

Using this widget is very similar to GTK+ scrolled windows. In fact, both widgets implement a similar concept and its APIs are very similar.

To create a new pannable area, choose one of the following functions:

GtkWidget*  hildon_pannable_area_new        (void);
GtkWidget*  hildon_pannable_area_new_full   (gint mode,
                                             gboolean enabled,
                                             gdouble vel_min,
                                             gdouble vel_max,
                                             gdouble decel,
                                             guint sps);

The first one creates a new pannable area with the properties set to the default values. The second one allows you to set the value of the most important properties of this widget:

  • mode: Used to change the behaviour of the pannable area allowing to choose whether to use the "kinetic" effect described above.
  • enabled: Enable or disable finger-scroll.
  • vel_min, vel_max: Allows developers to adjust how many pixels the child widget moves per "frame".
  • decel: Value for the deceleration property.
  • sps: Amount of scroll events to generate per second.

The default values of these properties are right for most applications and so the simpler constructor is sufficient. For more information on the properties of the pannable area, see the Hildon reference manual.

When the area is created, place your object into the pannable window using the following function.

void        hildon_pannable_area_add_with_viewport (HildonPannableArea *area,
                                                    GtkWidget *child);

That is a convenience function used to add a child to a GtkViewport, and add the viewport to the pannable area.

Warning

Add widgets with native scrolling directly inside a pannable area. Add widgets such as GtkTextView, GtkTreeView, GtkIconView and GtkLayout by calling gtk_container_add(). Otherwise, panning may not work properly.

[edit] Pannable area example

Functions explained above are enough for a simple example. The following example packs a table with 100 toggle buttons into a pannable area.

Screenshot of pannable area with buttons
Pannable area

Example 5.1. Example of a pannable area

#include <stdio.h>
#include <hildon/hildon.h>
 
static GtkWidget *create_table ()
{
 
  GtkWidget *hbox;
  GtkWidget *table;
  GtkWidget *button;
  char buffer[32];
  int i, j;
 
  /* create a table of 10 by 10 squares. */
  table = gtk_table_new (10, 10, FALSE);
 
  /* set the spacing to 10 on x and 10 on y */
  gtk_table_set_row_spacings (GTK_TABLE (table), 10);
  gtk_table_set_col_spacings (GTK_TABLE (table), 10);
 
  gtk_widget_show (table);
 
  /* this simply creates a grid of toggle buttons on the table
   * to demonstrate the scrolled window. */
  for (i = 1; i < 10; i++)
    for (j = 1; j < 10; j++) {
      sprintf (buffer, "button (%d,%d)\n", i, j);
      button = gtk_toggle_button_new_with_label (buffer);
 
      gtk_table_attach_defaults (GTK_TABLE (table), button,
                                 i, i+1, j, j+1);
    }
 
  return table;
}
 
int main( int   argc,
          char *argv[] )
{
  static GtkWidget *window;
  GtkWidget *button;
  GtkWidget *pannable_area;
  GtkWidget *table;
 
  hildon_gtk_init (&argc, &argv);
 
  window = hildon_stackable_window_new ();
  g_signal_connect (G_OBJECT (window), "destroy",
                    G_CALLBACK (gtk_widget_destroy), NULL);
 
  pannable_area = hildon_pannable_area_new ();
 
  table = create_table ();
 
  /* pack the table into the scrolled window */
  hildon_pannable_area_add_with_viewport (
    HILDON_PANNABLE_AREA (pannable_area), table);
 
  /* Add the box into the window*/
  gtk_container_add (GTK_CONTAINER (window), pannable_area);
 
  gtk_widget_show_all (window);
 
  gtk_main ();
 
  return 0;
}

In the example above, two calls are enough to use a pannable area. The rest of the code in the example is no different from the one used in a GTK+ application.

/* Create a new pannable area. */
pannable_area = hildon_pannable_area_new ();
/* Pack the table into the pannable area */
hildon_pannable_area_add_with_viewport ( HILDON_PANNABLE_AREA (pannable_area), table);

To see all the buttons, users can scroll with the fingers. In this example, horizontal and vertical panning are activated because that is needed to allow users to be able to interact both all the widgets. The property "mov-mode" controls if the area can scroll horizontally, vertically (default value) or both, using HILDON_MOVEMENT_MODE_HORIZ, HILDON_MOVEMENT_MODE_VERT or HILDON_MOVEMENT_MODE_BOTH, respectively.

[edit] Additional features

Pannable areas provide a set of convenience functions that make it easier to move to a certain element inside the area without users interaction.

These functions allow to scroll or jump to a position which ensures that a certain point or a certain child widget is visible for the user.

For example, the first of the functions changes the current position on the pannable area to ensure position (x,y) is visible. The movement is a quick jump. The second function performs a smoothly scroll towards the selected position.

void        hildon_pannable_area_jump_to    (HildonPannableArea *area,
                                             const gint x,
                                             const gint y);
void        hildon_pannable_area_scroll_to  (HildonPannableArea *area,
                                             const gint x,
                                             const gint y);

The following functions make it possible to jump or scroll to a certain descendent of the area. The argument should be a reference to a descendent widget.

void        hildon_pannable_area_jump_to_child (HildonPannableArea *area,
                                                GtkWidget *child);
void        hildon_pannable_area_scroll_to_child
                                            (HildonPannableArea *area,
                                             GtkWidget *child);

Here is a modified version of the previous example. The pannable area is packed into an GtkVBox and a new button is also added to navigate to the last clicked button.

Example 5.2. Example of a pannable area and a "jump-to" button

#include <stdio.h>
#include <hildon/hildon.h>
 
GtkWidget * last_clicked_button;
GtkWidget * pannable_area;
 
 
static void destroy( GtkWidget *widget,
                     gpointer   data )
{
    gtk_main_quit ();
}
 
static void clicked (GtkButton *button,
                     gpointer   user_data)
{
     last_clicked_button = GTK_WIDGET (button);
}
 
static void go_to_last_clicked (GtkButton *button,
                                gpointer   user_data)
{
  hildon_pannable_area_jump_to_child    (HILDON_PANNABLE_AREA (pannable_area),
                                         last_clicked_button);
}
 
static GtkWidget *create_table ()
{
    GtkWidget *table;
    GtkWidget *button;
    char buffer[32];
    int i, j;
 
    /* create a table of 10 by 10 squares. */
    table = gtk_table_new (10, 10, FALSE);
 
    /* set the spacing to 10 on x and 10 on y */
    gtk_table_set_row_spacings (GTK_TABLE (table), 10);
    gtk_table_set_col_spacings (GTK_TABLE (table), 10);
 
    gtk_widget_show (table);
 
    /* this simply creates a grid of toggle buttons on the table
     * to demonstrate the scrolled window. */
    for (i = 1; i < 10; i++)
       for (j = 1; j < 10; j++) {
          sprintf (buffer, "button (%d,%d)\n", i, j);
	  button = gtk_toggle_button_new_with_label (buffer);
 
          g_signal_connect (G_OBJECT (button),
                            "clicked",
                            G_CALLBACK (clicked),
                            NULL);
 
	  gtk_table_attach_defaults (GTK_TABLE (table), button,
	                             i, i+1, j, j+1);
 
          gtk_widget_show (button);
       }
 
    return table;
}
 
int main( int   argc,
          char *argv[] )
{
    static GtkWidget *window;
    GtkWidget *button;
    GtkWidget *table;
    GtkWidget *hbox;
 
    hildon_gtk_init (&argc, &argv);
 
    /* Create a new hildon window for the pannable area to be
     * packed into.  */
    window = hildon_stackable_window_new ();
    g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);
    gtk_window_set_title (GTK_WINDOW (window), "HildonPannableArea example");
 
    /* Create a table which will be inside the pannable area */
    table = create_table ();
 
    /* Create a box and pack the widgets into it */
    hbox = gtk_hbox_new (FALSE, 0);
 
    /* Add a button to jump */
    /* Button to go to last clicked */
    button = gtk_button_new_with_label ("Go to last clicked");
 
    g_signal_connect (G_OBJECT (button),
                      "clicked",
                      G_CALLBACK (go_to_last_clicked),
                      NULL);
 
    gtk_box_pack_start (GTK_BOX (hbox),
                        button,
                        FALSE,
                        FALSE,
                        0);
 
    /* create a new pannable area. */
    pannable_area = hildon_pannable_area_new ();
    g_object_set (G_OBJECT (pannable_area),
                  "mov-mode", HILDON_MOVEMENT_MODE_BOTH, NULL);
 
    /* pack the table into the scrolled window */
    hildon_pannable_area_add_with_viewport (
                   HILDON_PANNABLE_AREA (pannable_area), table);
 
    gtk_box_pack_start (GTK_BOX (hbox),
                        pannable_area,
                        TRUE,
                        TRUE,
                        0);
 
    /* Add the box into the window*/
    gtk_container_add (GTK_CONTAINER (window), hbox);
 
    gtk_widget_show_all (window);
    gtk_main();
 
    return 0;
}

The example used a global variable to store a reference to the last clicked button. This reference is used by the callback go_to_last_clicked to jump to it by calling one of the navigation functions. This function is used as a handler for the signal "clicked" of the button outside the pannable area.

To test the different navigation functions, just change the call in the callback.

When you use the navigation functions that allow to navigate to a certain child, the widget must already be realized. Use the GTK_WIDGET_REALIZED macro to check it. If you want to call it during the initialization process, use the navigation function inside a callback to the "realized" signal, connecting it with g_signal_connect_after().