Legacy Maemo 5 Documentation/Graphical UI Tutorial/Windows and dialogs

(Windows and dialogs)
m (another <code>)
 
(13 intermediate revisions not shown)
Line 1: Line 1:
-
= Windows and dialogs =
+
{{Legacy documentation}}
 +
 
When creating applications for hand-held devices, you should take into account several issues about usability and device limitations. Screen size is a particularly large restriction; a simple interface is essential.
When creating applications for hand-held devices, you should take into account several issues about usability and device limitations. Screen size is a particularly large restriction; a simple interface is essential.
In contrast with GTK+ applications, Hildon applications display only one window at a time. A typical Hildon application uses several windows representing different views in a tree-like hierarchy.
In contrast with GTK+ applications, Hildon applications display only one window at a time. A typical Hildon application uses several windows representing different views in a tree-like hierarchy.
-
[[Documentation/Maemo 5 Developer Guide/Application Development/Getting started#Hello World in Hildon | Example 1.2]], has already shown how to use a simple HildonWindow can be used and how it resembles the use of a classical GTK+ window. The tree-like views represent a new concept introduced by Hildon.
+
[[Documentation/Maemo 5 Developer Guide/Application Development/Getting started#Hello World in Hildon | Example 1.2]] has already shown how to use a simple <code>HildonWindow</code> can be used and how it resembles the use of a classical GTK+ window. The tree-like views represent a new concept introduced by Hildon.
To properly understand what views are, think of an application as a program that allows the user to perform one or more tasks. Each task can be broken down into several main activities.
To properly understand what views are, think of an application as a program that allows the user to perform one or more tasks. Each task can be broken down into several main activities.
-
Main activities in tasks should be done and presented in separate application views or windows, while assistance activities and steps to fulfill those tasks should be done in dialogs and menus on top of the currently displayed view.
+
Main activities in tasks must be done and presented in separate application views or windows, while assistance activities and steps to fulfill those tasks must be done in dialogs and menus on top of the currently displayed view.
Views work in a tree-like hierarchy. Root View acts as the "root" for the tree, and the subsequent Sub Views branch down the hierarchy.
Views work in a tree-like hierarchy. Root View acts as the "root" for the tree, and the subsequent Sub Views branch down the hierarchy.
-
[[Image:Rootview.png|400px]] [[Image:Subview.png|400px]]
+
[[Image:Rootview.png|thumb|center|400px|alt=Screenshot of root view|Root view]] [[Image:Subview.png|thumb|center|400px|alt=Screenshot of sub view|Sub view]]
-
 
+
-
The view concept is implemented by the widget HildonStackableWindow. This widget allows building a navigable hierarchy of windows with less code.
+
 +
The view concept is implemented by the widget <code>HildonStackableWindow</code>. This widget allows building a navigable hierarchy of windows with less code.
==Stackable windows ==
==Stackable windows ==
-
The HildonStackableWindow is a GTK+ widget which represents a top-level window in the Hildon framework. Stackable windows can be organized in a hierarchical way.
 
-
A stack sets the hierarchical relationships between windows. A child window is on top of its parent window. That allows navigate to previous window by removing the topmost window.
+
The <code>HildonStackableWindow</code> is a GTK+ widget which represents a top-level window in the Hildon framework. Stackable windows can be organized in a hierarchical way.
-
Users can only see and interact with the window on the top of stack. All other windows are mapped and visible but they are obscured by the topmost one. And they can go back to a root view from a subview by clicking in the navigation button in the top right corner of the window.
+
A stack sets the hierarchical relationships between windows. A child window is on top of its parent window. That allows navigation to previous window by removing the topmost window.
 +
 
 +
Users can only see and interact with the window on the top of stack. All other windows are mapped and visible but they are obscured by the topmost one. And the users can go back to a root view from a subview by clicking in the navigation button in the top right corner of the window.
Each application has a default stack, and windows are automatically added to it when they are shown using <code>gtk_widget_show()</code>. Most applications do not need to create extra stacks. Create more than one stack could make your UI too complex, so think twice before doing it.
Each application has a default stack, and windows are automatically added to it when they are shown using <code>gtk_widget_show()</code>. Most applications do not need to create extra stacks. Create more than one stack could make your UI too complex, so think twice before doing it.
Line 30: Line 31:
'''Example 2.1. Example of stackable windows'''
'''Example 2.1. Example of stackable windows'''
-
<tt><span>'''<span><font color="#000080"><nowiki>#include</nowiki></font></span>'''</span>                                       <span><font color="#FF0000">&lt;hildon/hildon.h&gt;</font></span>
+
<source lang="c">
-
<span>'''<span><font color="#0000FF">static</font></span>'''</span> <span><font color="#009900">void</font></span>
+
#include                                        <hildon/hildon.h>
-
<span>'''<span><font color="#000000">show_new_window</font></span>'''</span> <span><font color="#990000">(</font></span><span><font color="#009900">void</font></span><span><font color="#990000">)</font></span>
+
 
-
<span><font color="#FF0000">{</font></span>
+
static void
-
    GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>win<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
show_new_window (void)
-
    GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>vbox<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
{
-
    GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>label<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
    GtkWidget *win;
-
    <span>''<span><font color="#9A1900">/* Create the main window */</font></span>''</span>
+
    GtkWidget *vbox;
-
    win <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>
+
    GtkWidget *label;
-
    <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>win<span><font color="#990000">),</font></span> <span><font color="#FF0000">"Subview"</font></span><span><font color="#990000">);</font></span>
+
 
-
    <span>''<span><font color="#9A1900">/* Setting a label in the new window */</font></span>''</span>
+
    /* Create the main window */
-
    label <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_label_new</font></span>'''</span> <span><font color="#990000">(</font></span><span><font color="#FF0000">"This is a subview"</font></span><span><font color="#990000">);</font></span>
+
    win = hildon_stackable_window_new();
-
    vbox <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_vbox_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>
+
    gtk_window_set_title ( GTK_WINDOW (win), "Subview");
-
    <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>vbox<span><font color="#990000">),</font></span>
+
 
-
                        label<span><font color="#990000">,</font></span>
+
    /* Setting a label in the new window */
-
                        TRUE<span><font color="#990000">,</font></span>
+
    label =  gtk_label_new ("This is a subview");
-
                        TRUE<span><font color="#990000">,</font></span>
+
 
-
                        <span><font color="#993399">0</font></span><span><font color="#990000">);</font></span>
+
    vbox = gtk_vbox_new (FALSE, 0);
-
    <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>win<span><font color="#990000">),</font></span>
+
    gtk_box_pack_start (GTK_BOX (vbox),
-
                        vbox<span><font color="#990000">);</font></span>
+
                        label,
-
    <span>'''<span><font color="#000000">g_signal_connect</font></span>'''</span> <span><font color="#990000">(</font></span>win<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>test<span><font color="#990000">),</font></span> NULL<span><font color="#990000">);</font></span>
+
                        TRUE,
-
    <span>''<span><font color="#9A1900">/* This call show the window and also add the window to the stack */</font></span>''</span>
+
                        TRUE,
-
    <span>'''<span><font color="#000000">gtk_widget_show_all</font></span>'''</span> <span><font color="#990000">(</font></span>win<span><font color="#990000">);</font></span>
+
                        0);
-
<span><font color="#FF0000">}</font></span>
+
 
-
<span><font color="#009900">int</font></span>
+
    gtk_container_add (GTK_CONTAINER (win),
-
<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>
+
                      vbox);
-
      <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="#FF0000">{</font></span>
+
    /* This call show the window and also add the window to the stack */
-
    HildonProgram <span><font color="#990000"><nowiki>*</nowiki></font></span>program<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
    gtk_widget_show_all (win);
-
    GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>win<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>'''<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>
+
 
-
    program <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">hildon_program_get_instance</font></span>'''</span> <span><font color="#990000">();</font></span>
+
int
-
    <span>''<span><font color="#9A1900">/* Create the main window */</font></span>''</span>
+
main (int argc,
-
    win <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>
+
      char **argv)
-
    <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>win<span><font color="#990000">),</font></span> <span><font color="#FF0000">"Main window"</font></span><span><font color="#990000">);</font></span>
+
{
-
    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 subview"</font></span><span><font color="#990000">);</font></span>
+
    HildonProgram *program;
-
    <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>win<span><font color="#990000">),</font></span>
+
 
-
                        button<span><font color="#990000">);</font></span>
+
    GtkWidget *win;
-
    <span>'''<span><font color="#000000">g_signal_connect</font></span>'''</span> <span><font color="#990000">(</font></span>button<span><font color="#990000">,</font></span> <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>show_new_window<span><font color="#990000">),</font></span> NULL<span><font color="#990000">);</font></span>
+
    GtkWidget *button;
-
    <span>'''<span><font color="#000000">g_signal_connect</font></span>'''</span> <span><font color="#990000">(</font></span>win<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>test<span><font color="#990000">),</font></span> NULL<span><font color="#990000">);</font></span>
+
 
-
    <span>'''<span><font color="#000000">g_signal_connect</font></span>'''</span> <span><font color="#990000">(</font></span>win<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_main_quit<span><font color="#990000">),</font></span> NULL<span><font color="#990000">);</font></span>
+
    hildon_gtk_init (&argc, &argv);
-
    <span>''<span><font color="#9A1900">/* This call show the window and also add the window to the stack */</font></span>''</span>
+
 
-
    <span>'''<span><font color="#000000">gtk_widget_show_all</font></span>'''</span> <span><font color="#990000">(</font></span>win<span><font color="#990000">);</font></span>
+
    program = hildon_program_get_instance ();
-
    <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>
+
    /* Create the main window */
-
<span><font color="#FF0000">}</font></span>
+
    win = hildon_stackable_window_new ();
-
</tt>
+
    gtk_window_set_title ( GTK_WINDOW (win), "Main window");
 +
 
 +
    button =  gtk_button_new_with_label ("Go to subview");
 +
    gtk_container_add ( GTK_CONTAINER (win),
 +
                        button);
 +
 
 +
    g_signal_connect (button, "clicked", G_CALLBACK (show_new_window), NULL);
 +
 
 +
    g_signal_connect (win, "destroy", G_CALLBACK (gtk_main_quit), NULL);
 +
 
 +
    /* This call show the window and also add the window to the stack */
 +
    gtk_widget_show_all (win);
 +
    gtk_main();
 +
 
 +
    return 0;
 +
}
 +
</source>
The function <code>show_new_window()</code> is set up as a handler for when the signal "clicked" is emitted. This function creates a new stackable window which is added on top of the stack by calling <code>gtk_widget_show()</code>.
The function <code>show_new_window()</code> is set up as a handler for when the signal "clicked" is emitted. This function creates a new stackable window which is added on top of the stack by calling <code>gtk_widget_show()</code>.
Line 86: Line 103:
In some applications it could be necessary to push and/or pop windows on the stack without destroying them, or even to build and handle extra windows' stacks. Next section explains how to do that.
In some applications it could be necessary to push and/or pop windows on the stack without destroying them, or even to build and handle extra windows' stacks. Next section explains how to do that.
-
 
==Advanced stack handling ==
==Advanced stack handling ==
-
The object which represents a stack of windows in the Hildon framework is the HildonWindowStack. This object provides functions to push and/or pop windows on the stack, functions to access the topmost window or retrieve the current size of the stack are provided as well. Usual operations
+
 
 +
The object which represents a stack of windows in the Hildon framework is the <code>HildonWindowStack</code>. This object provides functions to push and/or pop windows on the stack, functions to access the topmost window or retrieve the current size of the stack are provided as well. Usual operations
To access the default stack, use the function <code>hildon_window_stack_get_default()</code>. To access the stack that contains a particular window, use <code>hildon_stackable_window_get_stack()</code>.
To access the default stack, use the function <code>hildon_window_stack_get_default()</code>. To access the stack that contains a particular window, use <code>hildon_stackable_window_get_stack()</code>.
-
<tt>HildonWindowStack<span><font color="#990000"><nowiki>*</nowiki></font></span> <span>'''<span><font color="#000000">hildon_window_stack_get_default</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">
-
</tt>
+
HildonWindowStack* hildon_window_stack_get_default          (void);
 +
</source>
The following functions are available to push and/or pop windows on a stack:
The following functions are available to push and/or pop windows on a stack:
-
<tt>        <span><font color="#009900">void</font></span>       <span>'''<span><font color="#000000">hildon_window_stack_push</font></span>'''</span>             <span><font color="#990000">(</font></span>HildonWindowStack <span><font color="#990000"><nowiki>*</nowiki></font></span>stack<span><font color="#990000">,</font></span>
+
<source lang="c">
-
                                                  HildonStackableWindow <span><font color="#990000"><nowiki>*</nowiki></font></span>win1<span><font color="#990000">,</font></span>
+
void        hildon_window_stack_push              (HildonWindowStack *stack,
-
                                                  <span><font color="#990000">...);</font></span>
+
                                                  HildonStackableWindow *win1,
-
<span><font color="#009900">void</font></span>       <span>'''<span><font color="#000000">hildon_window_stack_push_list</font></span>'''</span>         <span><font color="#990000">(</font></span>HildonWindowStack <span><font color="#990000"><nowiki>*</nowiki></font></span>stack<span><font color="#990000">,</font></span>
+
                                          ...);
-
                                                  GList <span><font color="#990000"><nowiki>*</nowiki></font></span>list<span><font color="#990000">);</font></span>
+
void        hildon_window_stack_push_list        (HildonWindowStack *stack,
-
<span><font color="#009900">void</font></span>       <span>'''<span><font color="#000000">hildon_window_stack_push_1</font></span>'''</span>           <span><font color="#990000">(</font></span>HildonWindowStack <span><font color="#990000"><nowiki>*</nowiki></font></span>stack<span><font color="#990000">,</font></span>
+
                                          GList *list);
-
                                                  HildonStackableWindow <span><font color="#990000"><nowiki>*</nowiki></font></span>win<span><font color="#990000">);</font></span>
+
void        hildon_window_stack_push_1            (HildonWindowStack *stack,
-
<span><font color="#009900">void</font></span>       <span>'''<span><font color="#000000">hildon_window_stack_pop</font></span>'''</span>               <span><font color="#990000">(</font></span>HildonWindowStack <span><font color="#990000"><nowiki>*</nowiki></font></span>stack<span><font color="#990000">,</font></span>
+
                                          HildonStackableWindow *win);
-
                                                  gint nwindows<span><font color="#990000">,</font></span>
+
void        hildon_window_stack_pop              (HildonWindowStack *stack,
-
                                                  GList <span><font color="#990000"><nowiki>**</nowiki></font></span>popped_windows<span><font color="#990000">);</font></span>
+
                                          gint nwindows,
-
GtkWidget<span><font color="#990000"><nowiki>*</nowiki></font></span> <span>'''<span><font color="#000000">hildon_window_stack_pop_1</font></span>'''</span>             <span><font color="#990000">(</font></span>HildonWindowStack <span><font color="#990000"><nowiki>*</nowiki></font></span>stack<span><font color="#990000">);</font></span>
+
                                          GList **popped_windows);
-
<span><font color="#009900">void</font></span>       <span>'''<span><font color="#000000">hildon_window_stack_pop_and_push</font></span>'''</span>     <span><font color="#990000">(</font></span>HildonWindowStack <span><font color="#990000"><nowiki>*</nowiki></font></span>stack<span><font color="#990000">,</font></span>
+
GtkWidget*  hildon_window_stack_pop_1            (HildonWindowStack *stack);
-
                                                  gint nwindows<span><font color="#990000">,</font></span>
+
void        hildon_window_stack_pop_and_push      (HildonWindowStack *stack,
-
                                                  GList <span><font color="#990000"><nowiki>**</nowiki></font></span>popped_windows<span><font color="#990000">,</font></span>
+
                                          gint nwindows,
-
                                                  HildonStackableWindow <span><font color="#990000"><nowiki>*</nowiki></font></span>win1<span><font color="#990000">,</font></span>
+
                                          GList **popped_windows,
-
                                                  <span><font color="#990000">...);</font></span>
+
                                          HildonStackableWindow *win1,
-
<span><font color="#009900">void</font></span>       <span>'''<span><font color="#000000">hildon_window_stack_pop_and_push_list</font></span>'''</span> <span><font color="#990000">(</font></span>HildonWindowStack <span><font color="#990000"><nowiki>*</nowiki></font></span>stack<span><font color="#990000">,</font></span>
+
                                          ...);
-
                                                  gint nwindows<span><font color="#990000">,</font></span>
+
void        hildon_window_stack_pop_and_push_list (HildonWindowStack *stack,
-
                                                  GList <span><font color="#990000"><nowiki>**</nowiki></font></span>popped_windows<span><font color="#990000">,</font></span>
+
                                          gint nwindows,
-
                                                  GList <span><font color="#990000"><nowiki>*</nowiki></font></span>list<span><font color="#990000">);</font></span>
+
                                          GList **popped_windows,
-
</tt>
+
                                          GList *list);
 +
</source>
The example shows how to get the default stack and push a newly created window on the stack. (Note that you also can do the same in a single stack by calling <code>gtk_widget_show()</code>).
The example shows how to get the default stack and push a newly created window on the stack. (Note that you also can do the same in a single stack by calling <code>gtk_widget_show()</code>).
Line 124: Line 143:
'''Example 2.2. Pushing a new window into a stack'''
'''Example 2.2. Pushing a new window into a stack'''
-
<tt>    HildonWindowStack <span><font color="#990000"><nowiki>*</nowiki></font></span>stack <span><font color="#990000"><nowiki>=</nowiki></font></span> NULL<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
<source lang="c">
-
    GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>window<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
HildonWindowStack *stack = NULL;
-
    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>
+
GtkWidget *window;
-
    stack <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">hildon_window_stack_get_default</font></span>'''</span> <span><font color="#990000">();</font></span>
+
window = hildon_stackable_window_new ();
-
    <span>'''<span><font color="#000000">hildon_window_stack_push_1</font></span>'''</span> <span><font color="#990000">(</font></span>stack<span><font color="#990000">,</font></span> <span>'''<span><font color="#000000">HILDON_STACKABLE_WINDOW</font></span>'''</span> <span><font color="#990000">(</font></span>window<span><font color="#990000">));</font></span>
+
stack = hildon_window_stack_get_default ();
-
</tt>
+
hildon_window_stack_push_1 (stack, HILDON_STACKABLE_WINDOW (window));
 +
</source>
-
The push functions also displays the window. <code>gtk_window_show()</code> is not needed after a push operation.
+
The push functions also displays the window. <code>gdk_window_show()</code> is not needed after a push operation.
A function also exists to push a list of windows in a single step. Windows are stacked in the listed order and users only see the window that was last pushed.
A function also exists to push a list of windows in a single step. Windows are stacked in the listed order and users only see the window that was last pushed.
Line 137: Line 157:
'''Example 2.3. Pushing a list of windows into a stack'''
'''Example 2.3. Pushing a list of windows into a stack'''
-
<tt> <span>'''<span><font color="#0000FF">static</font></span>'''</span> GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>
+
<source lang="c">
-
<span>'''<span><font color="#000000">create_customized_selector</font></span>'''</span><span><font color="#990000">()</font></span>
+
GList *list = NULL;
-
<span><font color="#FF0000">{</font></span>
+
HildonWindowStack *stack = NULL;
-
  GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>selector<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
HildonStackableWindow *window;
-
  GSList <span><font color="#990000"><nowiki>*</nowiki></font></span>icon_list <span><font color="#990000"><nowiki>=</nowiki></font></span> NULL<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
gint nwindows = 10;
-
  GtkListStore <span><font color="#990000"><nowiki>*</nowiki></font></span>store_icons <span><font color="#990000"><nowiki>=</nowiki></font></span> NULL<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
 
-
  GSList <span><font color="#990000"><nowiki>*</nowiki></font></span>item <span><font color="#990000"><nowiki>=</nowiki></font></span> NULL<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
stack = hildon_stackable_window_get_stack (window);
-
  GtkCellRenderer <span><font color="#990000"><nowiki>*</nowiki></font></span>renderer <span><font color="#990000"><nowiki>=</nowiki></font></span> NULL<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
 
-
  HildonTouchSelectorColumn <span><font color="#990000"><nowiki>*</nowiki></font></span>column <span><font color="#990000"><nowiki>=</nowiki></font></span> NULL<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
while (nwindows > 0) {
-
  <span>''<span><font color="#9A1900">/* Create a touch selector */</font></span>''</span>
+
    parent = hildon_stackable_window_new ();
-
  selector <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">hildon_touch_selector_new</font></span>'''</span><span><font color="#990000">();</font></span>
+
    list = g_list_append (list, window);
-
  <span>''<span><font color="#9A1900">/* Stock icons will be used for the example */</font></span>''</span>
+
    nwindows--;
-
  icon_list <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_stock_list_ids</font></span>'''</span><span><font color="#990000">();</font></span>
+
}
-
  <span>''<span><font color="#9A1900">/* Create model to store selector's items */</font></span>''</span>
+
hildon_window_stack_push_list (stack, list);
-
  store_icons <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_list_store_new</font></span>'''</span> <span><font color="#990000">(</font></span><span><font color="#993399">1</font></span><span><font color="#990000">,</font></span> G_TYPE_STRING<span><font color="#990000">);</font></span>
+
g_list_free (list);
-
  <span>''<span><font color="#9A1900">/* Populate model */</font></span>''</span>
+
</source>
-
  <span>'''<span><font color="#0000FF">for</font></span>'''</span> <span><font color="#990000">(</font></span>item <span><font color="#990000"><nowiki>=</nowiki></font></span> icon_list<span><font color="#990000"><nowiki>;</nowiki></font></span> item<span><font color="#990000"><nowiki>;</nowiki></font></span> item <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">g_slist_next</font></span>'''</span> <span><font color="#990000">(</font></span>item<span><font color="#990000">))</font></span> <span><font color="#FF0000">{</font></span>
+
-
    GtkTreeIter iter<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
    gchar <span><font color="#990000"><nowiki>*</nowiki></font></span>label <span><font color="#990000"><nowiki>=</nowiki></font></span> item<span><font color="#990000">-&gt;</font></span>data<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
    <span>'''<span><font color="#000000">gtk_list_store_append</font></span>'''</span> <span><font color="#990000">(</font></span>store_icons<span><font color="#990000">,</font></span> <span><font color="#990000">&amp;</font></span>iter<span><font color="#990000">);</font></span>
+
-
    <span>'''<span><font color="#000000">gtk_list_store_set</font></span>'''</span> <span><font color="#990000">(</font></span>store_icons<span><font color="#990000">,</font></span> <span><font color="#990000">&amp;</font></span>iter<span><font color="#990000">,</font></span> <span><font color="#993399">0</font></span><span><font color="#990000">,</font></span> label<span><font color="#990000">,</font></span> <span><font color="#990000">-</font></span><span><font color="#993399">1</font></span><span><font color="#990000">);</font></span>
+
-
    <span>'''<span><font color="#000000">g_free</font></span>'''</span> <span><font color="#990000">(</font></span>label<span><font color="#990000">);</font></span>
+
-
  <span><font color="#FF0000">}</font></span>
+
-
  <span>'''<span><font color="#000000">g_slist_free</font></span>'''</span> <span><font color="#990000">(</font></span>icon_list<span><font color="#990000">);</font></span>
+
-
  <span>''<span><font color="#9A1900">/* Create and set up a pixbuf renderer to use in the selector */</font></span>''</span>
+
-
  renderer <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_cell_renderer_pixbuf_new</font></span>'''</span><span><font color="#990000">();</font></span>
+
-
  <span>'''<span><font color="#000000">gtk_cell_renderer_set_fixed_size</font></span>'''</span> <span><font color="#990000">(</font></span>renderer<span><font color="#990000">,</font></span> <span><font color="#990000">-</font></span><span><font color="#993399">1</font></span><span><font color="#990000">,</font></span> <span><font color="#993399">100</font></span><span><font color="#990000">);</font></span>
+
-
  <span>''<span><font color="#9A1900">/* Add the column to the selector */</font></span>''</span>
+
-
  column <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">hildon_touch_selector_append_column</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">HILDON_TOUCH_SELECTOR</font></span>'''</span> <span><font color="#990000">(</font></span>selector<span><font color="#990000">),</font></span>
+
-
                                                <span>'''<span><font color="#000000">GTK_TREE_MODEL</font></span>'''</span> <span><font color="#990000">(</font></span>store_icons<span><font color="#990000">),</font></span>
+
-
                                                renderer<span><font color="#990000">,</font></span>
+
-
                                                <span><font color="#FF0000">"stock-id"</font></span><span><font color="#990000">,</font></span> <span><font color="#993399">0</font></span><span><font color="#990000">,</font></span>
+
-
                                                NULL<span><font color="#990000">);</font></span>
+
-
  <span>''<span><font color="#9A1900">/* Set the selection mode */</font></span>''</span>
+
-
  <span>'''<span><font color="#000000">hildon_touch_selector_set_column_selection_mode</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">HILDON_TOUCH_SELECTOR</font></span>'''</span> <span><font color="#990000">(</font></span>selector<span><font color="#990000">),</font></span>
+
-
                                    HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE<span><font color="#990000">);</font></span>
+
-
  <span>''<span><font color="#9A1900">/* Set the property "text-column" that indicates the column</font></span>''</span>
+
-
<span>''<span><font color="#9A1900">  * of the model to get the string from */</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>column<span><font color="#990000">),</font></span> <span><font color="#FF0000">"text-column"</font></span><span><font color="#990000">,</font></span> <span><font color="#993399">0</font></span><span><font color="#990000">,</font></span> NULL<span><font color="#990000">);</font></span>
+
-
  <span>'''<span><font color="#0000FF">return</font></span>'''</span> selector<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
-
<span><font color="#FF0000">}</font></span>
+
-
</tt>
+
Similar functions exist for the pop operation. The example uses <code>hildon_window_stack_pop_list()</code> to pop N windows from the default stack and stores them in the list of arguments. Notice that <code>hildon_stackable_window_size()</code> is used to check the size of the stack.
Similar functions exist for the pop operation. The example uses <code>hildon_window_stack_pop_list()</code> to pop N windows from the default stack and stores them in the list of arguments. Notice that <code>hildon_stackable_window_size()</code> is used to check the size of the stack.
Line 184: Line 178:
'''Example 2.4. Popping a number of windows from a stack into a list'''
'''Example 2.4. Popping a number of windows from a stack into a list'''
-
<tt>GList <span><font color="#990000"><nowiki>*</nowiki></font></span>list <span><font color="#990000"><nowiki>=</nowiki></font></span> NULL<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
<source lang="c">
-
    HildonWindowStack <span><font color="#990000"><nowiki>*</nowiki></font></span>stack<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
GList *list = NULL;
-
    HildonStackableWindow <span><font color="#990000"><nowiki>*</nowiki></font></span>window<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
HildonWindowStack *stack;
-
    gint nwindows <span><font color="#990000"><nowiki>=</nowiki></font></span> <span><font color="#993399">10</font></span><span><font color="#990000"><nowiki>;</nowiki></font></span>
+
HildonStackableWindow *window;
-
    stack <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">hildon_stackable_window_get_default</font></span>'''</span> <span><font color="#990000">();</font></span>
+
gint nwindows = 10;
-
    <span>'''<span><font color="#0000FF">if</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">hildon_stackable_window_size</font></span>'''</span> <span><font color="#990000">(</font></span>stack<span><font color="#990000">)</font></span> <span><font color="#990000">&gt;</font></span> nwindows<span><font color="#990000">)</font></span><span><font color="#FF0000">{</font></span>
+
stack = hildon_stackable_window_get_default ();
-
        <span>'''<span><font color="#000000">hildon_window_stack_pop</font></span>'''</span> <span><font color="#990000">(</font></span>stack<span><font color="#990000">,</font></span> nwindows<span><font color="#990000">,</font></span> list<span><font color="#990000">);</font></span>
+
if (hildon_stackable_window_size (stack) > nwindows){
-
    <span><font color="#FF0000">}</font></span>
+
    hildon_window_stack_pop (stack, nwindows, list);
-
</tt>
+
}
 +
</source>
HildonWindowStack object also provides more advanced functions to perform both pop and push operations at once such as, for example, <code>hildon_window_stack_pop_and_push()</code> or <code>hildon_window_stack_pop_and_push_list()</code>. These functions do everything in a single transition, so the user only sees the last pushed window.
HildonWindowStack object also provides more advanced functions to perform both pop and push operations at once such as, for example, <code>hildon_window_stack_pop_and_push()</code> or <code>hildon_window_stack_pop_and_push_list()</code>. These functions do everything in a single transition, so the user only sees the last pushed window.
-
When you perform push/pop operations you should take into account two things:
+
When you perform push/pop operations, consider two things:
* All stacked windows are visible and all visible windows are stacked.
* All stacked windows are visible and all visible windows are stacked.
* Each window can only be in one stack at a time.
* Each window can only be in one stack at a time.
-
Due to the first one, a push operation always shows the window and a pop operation always hides the window. Functions <code>gtk_widget_show()</code> and <code>gtk_window_hide()</code> always push and remove the window from its current stack, respectively.
+
Due to the first one, a push operation always shows the window and a pop operation always hides the window. Functions <code>gtk_widget_show()</code> and <code>gdk_window_hide()</code> always push and remove the window from its current stack, respectively.
Regarding the second one, operation push has no effect on windows which are already on a stack.
Regarding the second one, operation push has no effect on windows which are already on a stack.
Line 212: Line 207:
Once a new stack is created, use the functions explained in the previous section to pop and/or push windows on the stack.
Once a new stack is created, use the functions explained in the previous section to pop and/or push windows on the stack.
-
 
==Dialogs ==
==Dialogs ==
-
Dialog boxes are a convenient way to prompt the user for a small amount of input, e.g. to display a message, ask a question, or anything else that does not require extensive effort on the user's part.
 
-
Hildon provides specialized widgets to cover the most common dialog's use cases: HildonNote and HildonBanner.
+
Dialog boxes are a convenient way to prompt the user for a small amount of input, for example to display a message, ask a question, or anything else that does not require extensive effort on the user's part.
 +
 
 +
Hildon provides specialized widgets to cover the most common dialog's use cases: <code>HildonNote</code> and <code>HildonBanner</code>.
-
HildonNote is useful to ask users a question and HildonBanner is used to show textual information which automatically disappear after a certain period of time without user interaction. For more information on these widgets, see [[Documentation/Maemo_5_Developer_Guide/Application_Development/Controls#Notification_widgets |Notification widgets]] .
+
<code>HildonNote</code> is useful to ask users a question and <code>HildonBanner</code> is used to show textual information which automatically disappear after a certain period of time without user interaction. For more information on these widgets, see [[Documentation/Maemo_5_Developer_Guide/Application_Development/Controls#Notification_widgets|Notification widgets]] .
-
Besides those widgets, Hildon provides also specialized GtkDialogs designed to cover different use cases: HildonPickerDialog and HildonWizardDialog.
+
Besides those widgets, Hildon provides also specialized GtkDialogs designed to cover different use cases: <code>HildonPickerDialog</code> and <code>HildonWizardDialog</code>.
-
The widget HildonPickerDialog is used along with HildonPickerButton and HildonTouchSelector to give a way to make data selections. [[Documentation/Maemo_5_Developer_Guide/Application_Development/Data_selection|Data Selection]] explains the use of such widgets.
+
The widget <code>HildonPickerDialog</code> is used along with <code>HildonPickerButton</code> and <code>HildonTouchSelector</code> to give a way to make data selections. [[Documentation/Maemo 5 Developer Guide/Application Development/Data selection|Data Selection]] explains the use of such widgets.
-
To create a guided process which helps users accomplish complex tasks step by step, Hildon provides the HildonWizardDialog widget.
+
To create a guided process which helps users accomplish complex tasks step by step, Hildon provides the <code>HildonWizardDialog</code> widget.
===HildonWizardDialog===
===HildonWizardDialog===
-
HildonWizardDialog is a widget that allows one to create a guided process. The dialog has three standard buttons, previous, next and finish, and contains several pages. Users can close the dialog by tapping the dimmed area outside the dialog's window.
 
-
A good example of a guided process which could be implemented with this widget is the setup of a new e-mail account in an e-mail client. Users would have to fill several entries through several steps to accomplish the setup of the new account. The process of installing an application is another example of the uses of this widget.
+
<code>HildonWizardDialog</code> is a widget that allows one to create a guided process. The dialog has three standard buttons, previous, next and finish, and contains several pages. Users can close the dialog by tapping the dimmed area outside the dialog's window.
-
This widget uses a GtkNotebook that contains the actual wizard pages. The notebook widget is pointed by the property "wizard-notebook" of the wizard. You need to create the notebook as well as the pages that are displayed. For more information on GtkNotebook, see the GTK+ Reference Manual.
+
A good example of a guided process which can be implemented with this widget is the setup of a new e-mail account in an e-mail client. Users have to fill several entries through several steps to accomplish the setup of the new account. The process of installing an application is another example of the uses of this widget.
-
To create a new wizard dialog you should call:
+
This widget uses a <code>GtkNotebook</code> that contains the actual wizard pages. The notebook widget is pointed by the property "<code>wizard-notebook</code>" of the wizard. You need to create the notebook as well as the pages that are displayed. For more information on <code>GtkNotebook</code>, see the GTK+ Reference Manual.
-
<tt>GtkWidget<span><font color="#990000"><nowiki>*</nowiki></font></span> <span>'''<span><font color="#000000">hildon_wizard_dialog_new</font></span>'''</span>       <span><font color="#990000">(</font></span>GtkWindow <span><font color="#990000"><nowiki>*</nowiki></font></span>parent<span><font color="#990000">,</font></span>
+
To create a new wizard dialog, call:
-
                                              <span>'''<span><font color="#0000FF">const</font></span>'''</span> <span><font color="#009900">char</font></span> <span><font color="#990000"><nowiki>*</nowiki></font></span>wizard_name<span><font color="#990000">,</font></span>
+
 
-
                                              GtkNotebook <span><font color="#990000"><nowiki>*</nowiki></font></span>notebook<span><font color="#990000">);</font></span>
+
<source lang="c">
-
</tt>
+
GtkWidget*  hildon_wizard_dialog_new        (GtkWindow *parent,
 +
                                            const char *wizard_name,
 +
                                            GtkNotebook *notebook);
 +
</source>
The parent window is usually the current visible view. The wizard name is displayed as title in the wizard dialog.
The parent window is usually the current visible view. The wizard name is displayed as title in the wizard dialog.
Line 245: Line 242:
Usually, you want to validate user input to decide whether it should move to the next step or not. To do that, set a user function by using:
Usually, you want to validate user input to decide whether it should move to the next step or not. To do that, set a user function by using:
-
<tt><span>'''<span><font color="#000000">gboolean</font></span>'''</span>   <span><font color="#990000">(*</font></span>HildonWizardDialogPageFunc<span><font color="#990000">)</font></span>   <span><font color="#990000">(</font></span>GtkNotebook <span><font color="#990000"><nowiki>*</nowiki></font></span>notebook<span><font color="#990000">,</font></span>
+
<source lang="c">
-
                                              gint current_page<span><font color="#990000">,</font></span>
+
gboolean    (*HildonWizardDialogPageFunc)  (GtkNotebook *notebook,
-
                                              gpointer data<span><font color="#990000">);</font></span>
+
                                            gint current_page,
-
</tt>
+
                                            gpointer data);
 +
</source>
-
The function above sets the function "page_func" to be used to decide whether the user can go to the next page when pressing the forward button. The function should have the following signature:
+
The function above sets the function "<code>page_func</code>" to be used to decide whether the user can go to the next page when pressing the forward button. The function must have the following signature:
-
<tt><span>'''<span><font color="#000000">gboolean</font></span>'''</span>   <span><font color="#990000">(*</font></span>HildonWizardDialogPageFunc<span><font color="#990000">)</font></span>   <span><font color="#990000">(</font></span>GtkNotebook <span><font color="#990000"><nowiki>*</nowiki></font></span>notebook<span><font color="#990000">,</font></span>
+
<source lang="c">
-
                                              gint current_page<span><font color="#990000">,</font></span>
+
gboolean    (*HildonWizardDialogPageFunc)  (GtkNotebook *notebook,
-
                                              gpointer data<span><font color="#990000">);</font></span>
+
                                            gint current_page,
-
</tt>
+
                                            gpointer data);
 +
</source>
-
Here, an example of using a HildonWizardDialog
+
Here, an example of using a <code>HildonWizardDialog</code>
-
@@IMAGE@@: EXAMPLE BELOW
+
[[Image:example_wizard_dialog.png‎|frame|center|alt=Screeshot of wizard dialog|Wizard dialog]]
'''Example 2.5. Example of a Hildon wizard dialog'''
'''Example 2.5. Example of a Hildon wizard dialog'''
-
<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;stdlib.h&gt;</font></span>
+
#include <stdio.h>
-
<span>'''<span><font color="#000080"><nowiki>#include</nowiki></font></span>'''</span>                                        <span><font color="#FF0000">&lt;string.h&gt;</font></span>
+
#include <stdlib.h>
-
<span>'''<span><font color="#000080"><nowiki>#include</nowiki></font></span>'''</span>                                        <span><font color="#FF0000">&lt;hildon/hildon.h&gt;</font></span>
+
#include <string.h>
-
gboolean
+
#include <hildon/hildon.h>
-
<span>'''<span><font color="#000000">on_page_switch</font></span>'''</span> <span><font color="#990000">(</font></span>GtkNotebook <span><font color="#990000"><nowiki>*</nowiki></font></span>notebook<span><font color="#990000">,</font></span>
+
                                                                                                                        gboolean
-
                GtkNotebookPage <span><font color="#990000"><nowiki>*</nowiki></font></span>page<span><font color="#990000">,</font></span>
+
on_page_switch (GtkNotebook *notebook,
-
                guint num<span><font color="#990000">,</font></span>
+
                GtkNotebookPage *page,
-
                HildonWizardDialog <span><font color="#990000"><nowiki>*</nowiki></font></span>dialog<span><font color="#990000">)</font></span>
+
                guint num,
-
<span><font color="#FF0000">{</font></span>
+
                HildonWizardDialog *dialog)
-
    <span>'''<span><font color="#000000">g_debug</font></span>'''</span> <span><font color="#990000">(</font></span><span><font color="#FF0000">"Page %d"</font></span><span><font color="#990000">,</font></span> num<span><font color="#990000">);</font></span>
+
{
-
    <span>'''<span><font color="#0000FF">return</font></span>'''</span> TRUE<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
    g_debug ("Page %d", num);
-
<span><font color="#FF0000">}</font></span>
+
    return TRUE;
-
<span>'''<span><font color="#0000FF">static</font></span>'''</span> gboolean
+
}
-
<span>'''<span><font color="#000000">some_page_func</font></span>'''</span> <span><font color="#990000">(</font></span>GtkNotebook <span><font color="#990000"><nowiki>*</nowiki></font></span>nb<span><font color="#990000">,</font></span>
+
                                                                                                                          static gboolean
-
                gint current<span><font color="#990000">,</font></span>
+
some_page_func (GtkNotebook *nb,
-
                gpointer userdata<span><font color="#990000">)</font></span>
+
                gint current,
-
<span><font color="#FF0000">{</font></span>
+
                gpointer userdata)
-
  HildonEntry <span><font color="#990000"><nowiki>*</nowiki></font></span>entry<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
{
-
  <span>''<span><font color="#9A1900">/* Validate data only for the third page. */</font></span>''</span>
+
  HildonEntry *entry;
-
  <span>'''<span><font color="#0000FF">switch</font></span>'''</span> <span><font color="#990000">(</font></span>current<span><font color="#990000">)</font></span> <span><font color="#FF0000">{</font></span>
+
  /* Validate data only for the third page. */
-
  <span>'''<span><font color="#0000FF">case</font></span>'''</span> <span><font color="#993399">2</font></span><span><font color="#990000"><nowiki>:</nowiki></font></span>
+
  switch (current) {
-
    entry <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">HILDON_ENTRY</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">gtk_notebook_get_nth_page</font></span>'''</span> <span><font color="#990000">(</font></span>nb<span><font color="#990000">,</font></span> current<span><font color="#990000">));</font></span>
+
  case 2:
-
    <span>'''<span><font color="#0000FF">return</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">strlen</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">hildon_entry_get_text</font></span>'''</span> <span><font color="#990000">(</font></span>entry<span><font color="#990000">))</font></span> <span><font color="#990000"><nowiki>!=</nowiki></font></span> <span><font color="#993399">0</font></span><span><font color="#990000">);</font></span>
+
    entry = HILDON_ENTRY (gtk_notebook_get_nth_page (nb, current));
-
  <span>'''<span><font color="#0000FF">default</font></span>'''</span><span><font color="#990000"><nowiki>:</nowiki></font></span>
+
    return (strlen (hildon_entry_get_text (entry)) != 0);
-
    <span>'''<span><font color="#0000FF">return</font></span>'''</span> TRUE<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
  default:
-
  <span><font color="#FF0000">}</font></span>
+
    return TRUE;
-
<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>
+
                                                                                                                            int
-
<span><font color="#FF0000">{</font></span>
+
main (int argc, char **argv)
-
    <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>
+
{
-
    GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>dialog<span><font color="#990000">,*</font></span>notebook<span><font color="#990000">,</font></span> <span><font color="#990000"><nowiki>*</nowiki></font></span>label_1<span><font color="#990000">,</font></span> <span><font color="#990000"><nowiki>*</nowiki></font></span>label_2<span><font color="#990000">,</font></span> <span><font color="#990000"><nowiki>*</nowiki></font></span>entry_3<span><font color="#990000">,</font></span> <span><font color="#990000"><nowiki>*</nowiki></font></span>label_4<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
    hildon_gtk_init (&argc, &argv);
-
    <span>''<span><font color="#9A1900">/* Create a notebook */</font></span>''</span>
+
    GtkWidget *dialog,*notebook, *label_1, *label_2, *entry_3, *label_4;
-
    notebook <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_notebook_new</font></span>'''</span> <span><font color="#990000">();</font></span>
+
    /* Create a notebook */
-
    <span>''<span><font color="#9A1900">/* Create widgets to palce into the notebook's pages */</font></span>''</span>
+
    notebook = gtk_notebook_new ();
-
    label_1 <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_label_new</font></span>'''</span> <span><font color="#990000">(</font></span><span><font color="#FF0000">"Page 1"</font></span><span><font color="#990000">);</font></span>
+
    /* Create widgets to palce into the notebook's pages */
-
    label_2 <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_label_new</font></span>'''</span> <span><font color="#990000">(</font></span><span><font color="#FF0000">"Page 2"</font></span><span><font color="#990000">);</font></span>
+
    label_1 = gtk_label_new ("Page 1");
-
    entry_3 <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">hildon_entry_new</font></span>'''</span> <span><font color="#990000">(</font></span>HILDON_SIZE_AUTO<span><font color="#990000">);</font></span>
+
    label_2 = gtk_label_new ("Page 2");
-
    <span>'''<span><font color="#000000">hildon_entry_set_placeholder</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">HILDON_ENTRY</font></span>'''</span> <span><font color="#990000">(</font></span>entry_3<span><font color="#990000">),</font></span>
+
    entry_3 = hildon_entry_new (HILDON_SIZE_AUTO);
-
                                  <span><font color="#FF0000">" Write something to continue"</font></span><span><font color="#990000">);</font></span>
+
    hildon_entry_set_placeholder (HILDON_ENTRY (entry_3),
-
    label_4 <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_label_new</font></span>'''</span> <span><font color="#990000">(</font></span><span><font color="#FF0000">"Page 4"</font></span><span><font color="#990000">);</font></span>
+
                                  " Write something to continue");
-
    <span>''<span><font color="#9A1900">/* Append pages */</font></span>''</span>
+
    label_4 = gtk_label_new ("Page 4");
-
    <span>'''<span><font color="#000000">gtk_notebook_append_page</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_NOTEBOOK</font></span>'''</span> <span><font color="#990000">(</font></span>notebook<span><font color="#990000">),</font></span> label_1<span><font color="#990000">,</font></span> NULL<span><font color="#990000">);</font></span>
+
    /* Append pages */
-
    <span>'''<span><font color="#000000">gtk_notebook_append_page</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_NOTEBOOK</font></span>'''</span> <span><font color="#990000">(</font></span>notebook<span><font color="#990000">),</font></span> label_2<span><font color="#990000">,</font></span> NULL<span><font color="#990000">);</font></span>
+
    gtk_notebook_append_page (GTK_NOTEBOOK (notebook), label_1, NULL);
-
    <span>'''<span><font color="#000000">gtk_notebook_append_page</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_NOTEBOOK</font></span>'''</span> <span><font color="#990000">(</font></span>notebook<span><font color="#990000">),</font></span> entry_3<span><font color="#990000">,</font></span> NULL<span><font color="#990000">);</font></span>
+
    gtk_notebook_append_page (GTK_NOTEBOOK (notebook), label_2, NULL);
-
    <span>'''<span><font color="#000000">gtk_notebook_append_page</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_NOTEBOOK</font></span>'''</span> <span><font color="#990000">(</font></span>notebook<span><font color="#990000">),</font></span> label_4<span><font color="#990000">,</font></span> NULL<span><font color="#990000">);</font></span>
+
    gtk_notebook_append_page (GTK_NOTEBOOK (notebook), entry_3, NULL);
-
    <span>''<span><font color="#9A1900">/* Create wizard dialog */</font></span>''</span>
+
    gtk_notebook_append_page (GTK_NOTEBOOK (notebook), label_4, NULL);
-
    dialog <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">hildon_wizard_dialog_new</font></span>'''</span> <span><font color="#990000">(</font></span>NULL<span><font color="#990000">,</font></span> <span><font color="#FF0000">"Wizard"</font></span><span><font color="#990000">,</font></span>
+
    /* Create wizard dialog */
-
                                        <span>'''<span><font color="#000000">GTK_NOTEBOOK</font></span>'''</span> <span><font color="#990000">(</font></span>notebook<span><font color="#990000">));</font></span>
+
    dialog = hildon_wizard_dialog_new (NULL, "Wizard",
-
    <span>''<span><font color="#9A1900">/* Set a handler for "switch-page" signal */</font></span>''</span>
+
                                      GTK_NOTEBOOK (notebook));
-
    <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>notebook<span><font color="#990000">),</font></span>
+
    /* Set a handler for "switch-page" signal */
-
                      <span><font color="#FF0000">"switch-page"</font></span><span><font color="#990000">,</font></span>
+
    g_signal_connect (G_OBJECT (notebook),
-
                      <span>'''<span><font color="#000000">G_CALLBACK</font></span>'''</span> <span><font color="#990000">(</font></span>on_page_switch<span><font color="#990000">),</font></span>
+
                      "switch-page",
-
                      dialog<span><font color="#990000">);</font></span>
+
                      G_CALLBACK (on_page_switch),
-
    <span>''<span><font color="#9A1900">/* Set a function to decide if user can go to next page */</font></span>''</span>
+
                      dialog);
-
    <span>'''<span><font color="#000000">hildon_wizard_dialog_set_forward_page_func</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">HILDON_WIZARD_DIALOG</font></span>'''</span> <span><font color="#990000">(</font></span>dialog<span><font color="#990000">),</font></span>
+
    /* Set a function to decide if user can go to next page */
-
                                                some_page_func<span><font color="#990000">,</font></span> NULL<span><font color="#990000">,</font></span> NULL<span><font color="#990000">);</font></span>
+
    hildon_wizard_dialog_set_forward_page_func (HILDON_WIZARD_DIALOG (dialog),
-
    <span>'''<span><font color="#000000">gtk_widget_show_all</font></span>'''</span> <span><font color="#990000">(</font></span>dialog<span><font color="#990000">);</font></span>
+
                                                some_page_func, NULL, NULL);
-
    <span>'''<span><font color="#000000">gtk_dialog_run</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_DIALOG</font></span>'''</span> <span><font color="#990000">(</font></span>dialog<span><font color="#990000">));</font></span>
+
    gtk_widget_show_all (dialog);
-
    <span>'''<span><font color="#0000FF">return</font></span>'''</span> <span><font color="#993399">0</font></span><span><font color="#990000"><nowiki>;</nowiki></font></span>
+
    gtk_dialog_run (GTK_DIALOG (dialog));
-
<span><font color="#FF0000">}</font></span>
+
    return 0;
-
</tt>
+
}
 +
</source>
-
Apart from how to create and use a wizard dialog, this example also sets up a handler to catch the signal "switch-page" from the notepad. This signal is emitted by the widget GtkNotebook when the user or a function changes the current page.
+
Apart from how to create and use a wizard dialog, this example also sets up a handler to catch the signal "<code>switch-page</code>" from the notepad. This signal is emitted by the widget <code>GtkNotebook</code> when the user or a function changes the current page.
===Using GtkDialogs in Hildon applications===
===Using GtkDialogs in Hildon applications===
-
In general, you can use GtkDialog much like you would use it in a GTK+ application, but you have to take into account the following:
 
-
* In Hildon applications, buttons "cancel", "reject" and "close" are allowed. However, buttons which emit the signal "response" with GTK_RESPONSE_CANCEL, GTK_RESPONSE_REJECT or GTK_RESPONSE_CLOSE as the response's identifier are not displayed. Therefore, if you need to deal with the action of closing a GtkDialog in a Hildon application, you need to be aware of this detail and to handle the GTK_RESPONSE_DELETE_EVENT response identifier properly.
+
In general, you can use <code>GtkDialog</code> much like you use it in a GTK+ application, but consider the following:
-
* Another detail to take care of is that GtkDialogs can work in two modalities in a Hildon application: task-model or system-model. A dialog is task-modal if it is transient for the main window. That is the case when the function <code>gtk_window_set_transient_for()</code> is used or the dialog was created by calling gtk_dialog_new_with_buttons() specifying a parent window. Otherwise, the dialog is system-modal.
+
 
 +
* In Hildon applications, buttons "cancel", "reject" and "close" are allowed. However, buttons which emit the signal "<code>response</code>" with <code>GTK_RESPONSE_CANCEL</code>, <code>GTK_RESPONSE_REJECT</code> or <code>GTK_RESPONSE_CLOSE</code> as the response's identifier are not displayed. Therefore, if you need to deal with the action of closing a GtkDialog in a Hildon application, be aware of this detail and handle the <code>GTK_RESPONSE_DELETE_EVENT</code> response identifier properly.
 +
* Another detail to take care of is that <code>GtkDialog</code>s can work in two modalities in a Hildon application: task-model or system-model. A dialog is task-modal if it is transient for the main window. That is the case when the function <code>gtk_window_set_transient_for()</code> is used or the dialog was created by calling <code>gtk_dialog_new_with_buttons()</code> specifying a parent window. Otherwise, the dialog is system-modal.
If the dialog is task-modal, the Platform UI (Task button and Status area) are visible on top and can be used normally to switch between tasks.
If the dialog is task-modal, the Platform UI (Task button and Status area) are visible on top and can be used normally to switch between tasks.
Line 343: Line 344:
'''Example 2.6. Application modal dialog example'''
'''Example 2.6. Application modal dialog example'''
-
<tt><span>'''<span><font color="#000080"><nowiki>#include</nowiki></font></span>'''</span> <span><font color="#FF0000">&lt;hildon/hildon.h&gt;</font></span>
+
<source lang="c">
-
<span><font color="#009900">int</font></span>
+
#include <hildon/hildon.h>
-
<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>
+
int
-
                                                  <span><font color="#009900">char</font></span> <span><font color="#990000"><nowiki>**</nowiki></font></span>argv<span><font color="#990000">)</font></span>
+
main                                            (int argc,
-
<span><font color="#FF0000">{</font></span>
+
                                                char **argv)
-
  GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>dialog<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
{
-
  GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>win<span><font color="#990000"><nowiki>;</nowiki></font></span>
+
  GtkWidget *dialog;
-
  <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>
+
  GtkWidget *win;
-
  win <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><font color="#990000"><nowiki>;</nowiki></font></span>
+
  hildon_gtk_init (&argc, &argv);
-
  <span>'''<span><font color="#000000">gtk_widget_show</font></span>'''</span> <span><font color="#990000">(</font></span>win<span><font color="#990000">);</font></span>
+
  win = hildon_stackable_window_new () ;
-
  dialog <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">gtk_dialog_new</font></span>'''</span> <span><font color="#990000">();</font></span>
+
  gtk_widget_show (win);
-
  <span>'''<span><font color="#000000">gtk_window_set_transient_for</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>dialog<span><font color="#990000">),</font></span>
+
  dialog = gtk_dialog_new ();
-
                                  <span>'''<span><font color="#000000">GTK_WINDOW</font></span>'''</span> <span><font color="#990000">(</font></span>win<span><font color="#990000">));</font></span>
+
  gtk_window_set_transient_for  (GTK_WINDOW (dialog),
-
  <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>dialog<span><font color="#990000">),</font></span> <span><font color="#FF0000">"Hello!"</font></span><span><font color="#990000">);</font></span>
+
                                GTK_WINDOW (win));
-
  <span>'''<span><font color="#000000">gtk_widget_show_all</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_WIDGET</font></span>'''</span> <span><font color="#990000">(</font></span>dialog<span><font color="#990000">));</font></span>
+
  gtk_window_set_title (GTK_WINDOW (dialog), "Hello!");
-
  <span>'''<span><font color="#000000">gtk_dialog_run</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">GTK_DIALOG</font></span>'''</span> <span><font color="#990000">(</font></span>dialog<span><font color="#990000">));</font></span>
+
  gtk_widget_show_all (GTK_WIDGET (dialog));
-
  <span>'''<span><font color="#0000FF">return</font></span>'''</span> <span><font color="#993399">0</font></span><span><font color="#990000"><nowiki>;</nowiki></font></span>
+
  gtk_dialog_run (GTK_DIALOG (dialog));
-
<span><font color="#FF0000">}</font></span>
+
  return 0;
-
</tt>
+
}
 +
</source>
 +
 
 +
<hr/>
 +
<table width=100%>
 +
<tr><td width=30% align=left>
 +
Prev: [[{{BASEPAGENAME}}/Getting_started|Getting Started]]</td>
 +
<td align=center>Up: [[{{BASEPAGENAME}}|Table of Contents]]</td>
 +
<td width=30% align=right>
 +
Next: [[{{BASEPAGENAME}}/Menus|Menus]]</td>
 +
</tr></table>

Latest revision as of 10:43, 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

When creating applications for hand-held devices, you should take into account several issues about usability and device limitations. Screen size is a particularly large restriction; a simple interface is essential.

In contrast with GTK+ applications, Hildon applications display only one window at a time. A typical Hildon application uses several windows representing different views in a tree-like hierarchy.

Example 1.2 has already shown how to use a simple HildonWindow can be used and how it resembles the use of a classical GTK+ window. The tree-like views represent a new concept introduced by Hildon.

To properly understand what views are, think of an application as a program that allows the user to perform one or more tasks. Each task can be broken down into several main activities.

Main activities in tasks must be done and presented in separate application views or windows, while assistance activities and steps to fulfill those tasks must be done in dialogs and menus on top of the currently displayed view.

Views work in a tree-like hierarchy. Root View acts as the "root" for the tree, and the subsequent Sub Views branch down the hierarchy.

Screenshot of root view
Root view
Screenshot of sub view
Sub view

The view concept is implemented by the widget HildonStackableWindow. This widget allows building a navigable hierarchy of windows with less code.

Contents

[edit] Stackable windows

The HildonStackableWindow is a GTK+ widget which represents a top-level window in the Hildon framework. Stackable windows can be organized in a hierarchical way.

A stack sets the hierarchical relationships between windows. A child window is on top of its parent window. That allows navigation to previous window by removing the topmost window.

Users can only see and interact with the window on the top of stack. All other windows are mapped and visible but they are obscured by the topmost one. And the users can go back to a root view from a subview by clicking in the navigation button in the top right corner of the window.

Each application has a default stack, and windows are automatically added to it when they are shown using gtk_widget_show(). Most applications do not need to create extra stacks. Create more than one stack could make your UI too complex, so think twice before doing it.

Let's see a simple example to show the use of this widget. This simple program creates a stackable window with a button to navigate towards a subview, a new window on top of the stack.

Example 2.1. Example of stackable windows

#include                                        <hildon/hildon.h>
 
static void
show_new_window (void)
{
    GtkWidget *win;
    GtkWidget *vbox;
    GtkWidget *label;
 
    /* Create the main window */
    win = hildon_stackable_window_new();
    gtk_window_set_title ( GTK_WINDOW (win), "Subview");
 
    /* Setting a label in the new window */
    label =  gtk_label_new ("This is a subview");
 
    vbox = gtk_vbox_new (FALSE, 0);
    gtk_box_pack_start (GTK_BOX (vbox),
                        label,
                        TRUE,
                        TRUE,
                        0);
 
    gtk_container_add (GTK_CONTAINER (win),
                       vbox);
 
    /* This call show the window and also add the window to the stack */
    gtk_widget_show_all (win);
}
 
 
int
main (int argc,
      char **argv)
{
    HildonProgram *program;
 
    GtkWidget *win;
    GtkWidget *button;
 
    hildon_gtk_init (&argc, &argv);
 
    program = hildon_program_get_instance ();
 
    /* Create the main window */
    win = hildon_stackable_window_new ();
    gtk_window_set_title ( GTK_WINDOW (win), "Main window");
 
    button =  gtk_button_new_with_label ("Go to subview");
    gtk_container_add ( GTK_CONTAINER (win),
                        button);
 
    g_signal_connect (button, "clicked", G_CALLBACK (show_new_window), NULL);
 
    g_signal_connect (win, "destroy", G_CALLBACK (gtk_main_quit), NULL);
 
    /* This call show the window and also add the window to the stack */
    gtk_widget_show_all (win);
    gtk_main();
 
    return 0;
}

The function show_new_window() is set up as a handler for when the signal "clicked" is emitted. This function creates a new stackable window which is added on top of the stack by calling gtk_widget_show().

Displaying a stackable window by calling gtk_widget_show() or gtk_widget_show_all() automatically adds it on top of the default stack.

Note that no extra code exists for navigation between views because the navigation button in the top-right corner of the window allows users to return from subviews. When the user presses the navigation button, the topmost window is destroyed and the previous window becomes the topmost one.

In some applications it could be necessary to push and/or pop windows on the stack without destroying them, or even to build and handle extra windows' stacks. Next section explains how to do that.

[edit] Advanced stack handling

The object which represents a stack of windows in the Hildon framework is the HildonWindowStack. This object provides functions to push and/or pop windows on the stack, functions to access the topmost window or retrieve the current size of the stack are provided as well. Usual operations

To access the default stack, use the function hildon_window_stack_get_default(). To access the stack that contains a particular window, use hildon_stackable_window_get_stack().

HildonWindowStack* hildon_window_stack_get_default          (void);

The following functions are available to push and/or pop windows on a stack:

void        hildon_window_stack_push              (HildonWindowStack *stack,
                                                  HildonStackableWindow *win1,
        	                                   ...);
void        hildon_window_stack_push_list         (HildonWindowStack *stack,
        	                                   GList *list);
void        hildon_window_stack_push_1            (HildonWindowStack *stack,
        	                                   HildonStackableWindow *win);
void        hildon_window_stack_pop               (HildonWindowStack *stack,
        	                                   gint nwindows,
                	                           GList **popped_windows);
GtkWidget*  hildon_window_stack_pop_1             (HildonWindowStack *stack);
void        hildon_window_stack_pop_and_push      (HildonWindowStack *stack,
        	                                   gint nwindows,
                	                           GList **popped_windows,
                        	                   HildonStackableWindow *win1,
                                	           ...);
void        hildon_window_stack_pop_and_push_list (HildonWindowStack *stack,
        	                                   gint nwindows,
                	                           GList **popped_windows,
                        	                   GList *list);

The example shows how to get the default stack and push a newly created window on the stack. (Note that you also can do the same in a single stack by calling gtk_widget_show()).

Example 2.2. Pushing a new window into a stack

HildonWindowStack *stack = NULL;
GtkWidget *window;
window = hildon_stackable_window_new ();
stack = hildon_window_stack_get_default ();
hildon_window_stack_push_1 (stack, HILDON_STACKABLE_WINDOW (window));

The push functions also displays the window. gdk_window_show() is not needed after a push operation.

A function also exists to push a list of windows in a single step. Windows are stacked in the listed order and users only see the window that was last pushed.

Example 2.3. Pushing a list of windows into a stack

GList *list = NULL;
HildonWindowStack *stack = NULL;
HildonStackableWindow *window;
gint nwindows = 10;
 
stack = hildon_stackable_window_get_stack (window);
 
while (nwindows > 0) {
    parent = hildon_stackable_window_new ();
    list = g_list_append (list, window);
    nwindows--;
}
hildon_window_stack_push_list (stack, list);
g_list_free (list);

Similar functions exist for the pop operation. The example uses hildon_window_stack_pop_list() to pop N windows from the default stack and stores them in the list of arguments. Notice that hildon_stackable_window_size() is used to check the size of the stack.

Example 2.4. Popping a number of windows from a stack into a list

GList *list = NULL;
HildonWindowStack *stack;
HildonStackableWindow *window;
gint nwindows = 10;
stack = hildon_stackable_window_get_default ();
if (hildon_stackable_window_size (stack) > nwindows){
    hildon_window_stack_pop (stack, nwindows, list);
}

HildonWindowStack object also provides more advanced functions to perform both pop and push operations at once such as, for example, hildon_window_stack_pop_and_push() or hildon_window_stack_pop_and_push_list(). These functions do everything in a single transition, so the user only sees the last pushed window.

When you perform push/pop operations, consider two things:

  • All stacked windows are visible and all visible windows are stacked.
  • Each window can only be in one stack at a time.

Due to the first one, a push operation always shows the window and a pop operation always hides the window. Functions gtk_widget_show() and gdk_window_hide() always push and remove the window from its current stack, respectively.

Regarding the second one, operation push has no effect on windows which are already on a stack.

Multiple Stacks

Most applications do not need more than the default stack. Although you can use multiple stacks in one application, note that this increases the complexity of the UI, which is not desirable.

To create a new stack just use hildon_window_stack_new(). A new stacks behaves like a new application or task. Newly created stacks are displayed on top of the current stack. Users need to use the task selector to change between stacks when they change tasks (applications).

Once a new stack is created, use the functions explained in the previous section to pop and/or push windows on the stack.

[edit] Dialogs

Dialog boxes are a convenient way to prompt the user for a small amount of input, for example to display a message, ask a question, or anything else that does not require extensive effort on the user's part.

Hildon provides specialized widgets to cover the most common dialog's use cases: HildonNote and HildonBanner.

HildonNote is useful to ask users a question and HildonBanner is used to show textual information which automatically disappear after a certain period of time without user interaction. For more information on these widgets, see Notification widgets .

Besides those widgets, Hildon provides also specialized GtkDialogs designed to cover different use cases: HildonPickerDialog and HildonWizardDialog.

The widget HildonPickerDialog is used along with HildonPickerButton and HildonTouchSelector to give a way to make data selections. Data Selection explains the use of such widgets.

To create a guided process which helps users accomplish complex tasks step by step, Hildon provides the HildonWizardDialog widget.

[edit] HildonWizardDialog

HildonWizardDialog is a widget that allows one to create a guided process. The dialog has three standard buttons, previous, next and finish, and contains several pages. Users can close the dialog by tapping the dimmed area outside the dialog's window.

A good example of a guided process which can be implemented with this widget is the setup of a new e-mail account in an e-mail client. Users have to fill several entries through several steps to accomplish the setup of the new account. The process of installing an application is another example of the uses of this widget.

This widget uses a GtkNotebook that contains the actual wizard pages. The notebook widget is pointed by the property "wizard-notebook" of the wizard. You need to create the notebook as well as the pages that are displayed. For more information on GtkNotebook, see the GTK+ Reference Manual.

To create a new wizard dialog, call:

GtkWidget*  hildon_wizard_dialog_new        (GtkWindow *parent,
                                             const char *wizard_name,
                                             GtkNotebook *notebook);

The parent window is usually the current visible view. The wizard name is displayed as title in the wizard dialog.

Usually, you want to validate user input to decide whether it should move to the next step or not. To do that, set a user function by using:

gboolean    (*HildonWizardDialogPageFunc)   (GtkNotebook *notebook,
                                             gint current_page,
                                             gpointer data);

The function above sets the function "page_func" to be used to decide whether the user can go to the next page when pressing the forward button. The function must have the following signature:

gboolean    (*HildonWizardDialogPageFunc)   (GtkNotebook *notebook,
                                             gint current_page,
                                             gpointer data);

Here, an example of using a HildonWizardDialog

Screeshot of wizard dialog
Wizard dialog

Example 2.5. Example of a Hildon wizard dialog

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hildon/hildon.h>
                                                                                                                         gboolean
on_page_switch (GtkNotebook *notebook,
                GtkNotebookPage *page,
                guint num,
                HildonWizardDialog *dialog)
{
    g_debug ("Page %d", num);
    return TRUE;
}
                                                                                                                           static gboolean
some_page_func (GtkNotebook *nb,
                gint current,
                gpointer userdata)
{
  HildonEntry *entry;
  /* Validate data only for the third page. */
  switch (current) {
  case 2:
    entry = HILDON_ENTRY (gtk_notebook_get_nth_page (nb, current));
    return (strlen (hildon_entry_get_text (entry)) != 0);
  default:
    return TRUE;
  }
}
                                                                                                                            int
main (int argc, char **argv)
{
    hildon_gtk_init (&argc, &argv);
    GtkWidget *dialog,*notebook, *label_1, *label_2, *entry_3, *label_4;
    /* Create a notebook */
    notebook = gtk_notebook_new ();
    /* Create widgets to palce into the notebook's pages */
    label_1 = gtk_label_new ("Page 1");
    label_2 = gtk_label_new ("Page 2");
    entry_3 = hildon_entry_new (HILDON_SIZE_AUTO);
    hildon_entry_set_placeholder (HILDON_ENTRY (entry_3),
                                  " Write something to continue");
    label_4 = gtk_label_new ("Page 4");
    /* Append pages */
    gtk_notebook_append_page (GTK_NOTEBOOK (notebook), label_1, NULL);
    gtk_notebook_append_page (GTK_NOTEBOOK (notebook), label_2, NULL);
    gtk_notebook_append_page (GTK_NOTEBOOK (notebook), entry_3, NULL);
    gtk_notebook_append_page (GTK_NOTEBOOK (notebook), label_4, NULL);
    /* Create wizard dialog */
    dialog = hildon_wizard_dialog_new (NULL, "Wizard",
                                       GTK_NOTEBOOK (notebook));
    /* Set a handler for "switch-page" signal */
    g_signal_connect (G_OBJECT (notebook),
                      "switch-page",
                      G_CALLBACK (on_page_switch),
                      dialog);
    /* Set a function to decide if user can go to next page */
    hildon_wizard_dialog_set_forward_page_func (HILDON_WIZARD_DIALOG (dialog),
                                                some_page_func, NULL, NULL);
    gtk_widget_show_all (dialog);
    gtk_dialog_run (GTK_DIALOG (dialog));
    return 0;
}

Apart from how to create and use a wizard dialog, this example also sets up a handler to catch the signal "switch-page" from the notepad. This signal is emitted by the widget GtkNotebook when the user or a function changes the current page.

[edit] Using GtkDialogs in Hildon applications

In general, you can use GtkDialog much like you use it in a GTK+ application, but consider the following:

  • In Hildon applications, buttons "cancel", "reject" and "close" are allowed. However, buttons which emit the signal "response" with GTK_RESPONSE_CANCEL, GTK_RESPONSE_REJECT or GTK_RESPONSE_CLOSE as the response's identifier are not displayed. Therefore, if you need to deal with the action of closing a GtkDialog in a Hildon application, be aware of this detail and handle the GTK_RESPONSE_DELETE_EVENT response identifier properly.
  • Another detail to take care of is that GtkDialogs can work in two modalities in a Hildon application: task-model or system-model. A dialog is task-modal if it is transient for the main window. That is the case when the function gtk_window_set_transient_for() is used or the dialog was created by calling gtk_dialog_new_with_buttons() specifying a parent window. Otherwise, the dialog is system-modal.

If the dialog is task-modal, the Platform UI (Task button and Status area) are visible on top and can be used normally to switch between tasks.

If the dialog is system-modal, both the task button and status area are blurred and dimmed. They are not active while the dialog is open and task switching is not possible until it closes.

The following is an example for creating a task-modal dialog.

Example 2.6. Application modal dialog example

#include <hildon/hildon.h>
int
main                                            (int argc,
                                                 char **argv)
{
  GtkWidget *dialog;
  GtkWidget *win;
  hildon_gtk_init (&argc, &argv);
  win = hildon_stackable_window_new () ;
  gtk_widget_show (win);
  dialog = gtk_dialog_new ();
  gtk_window_set_transient_for  (GTK_WINDOW (dialog),
                                 GTK_WINDOW (win));
  gtk_window_set_title (GTK_WINDOW (dialog), "Hello!");
  gtk_widget_show_all (GTK_WIDGET (dialog));
  gtk_dialog_run (GTK_DIALOG (dialog));
  return 0;
}

Prev: Getting Started Up: Table of Contents Next: Menus