Editing Documentation/Maemo 5 Developer Guide/Porting Software/Migration
Warning: You are not logged in.
Your IP address will be recorded in this page's edit history.
The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 1: | Line 1: | ||
+ | =Migration = | ||
Because Hildon 2.2 is a big step up from previous versions, many approaches in the development of your program's graphical user interface may need to be migrated to this new interface type. | Because Hildon 2.2 is a big step up from previous versions, many approaches in the development of your program's graphical user interface may need to be migrated to this new interface type. | ||
- | |||
== Menus == | == Menus == | ||
- | + | Hildon app menu represents a big difference from the normal menus. If your application is to be finger-friendly, a view specific menu, instead of application menu, is mandatory. | |
- | + | ||
The Maemo 4 application menu typically contains most or the full set of functionality of the application, organized in hierarchical menus. | The Maemo 4 application menu typically contains most or the full set of functionality of the application, organized in hierarchical menus. | ||
- | In Maemo 5, there is a strict | + | In Maemo 5, there is a strict limit of maximum 10 items in a view menu, and there is no menu hierarchy. |
The Maemo 5 View menus are not application menus, in the sense that a view menu only contains commands relevant to that particular view. The only exception to this is the Root view menu, which additionally contains menu item(s) for application settings. | The Maemo 5 View menus are not application menus, in the sense that a view menu only contains commands relevant to that particular view. The only exception to this is the Root view menu, which additionally contains menu item(s) for application settings. | ||
- | Because the view menu | + | Because also the view menu uses buttons, you can easily add them with the callback functions that the original menu items had. |
- | For example, consider an advanced text | + | For example, consider an advanced text edition program. The original menu bar had the following menus: |
'''Example 10.1. Menu example''' | '''Example 10.1. Menu example''' | ||
- | < | + | <div class="graybox"> |
- | File | + | |
- | + | File | |
- | + | \ New | |
- | + | \ Open | |
- | + | \ Save | |
- | + | \ Save As | |
- | Edit | + | \ Quit |
- | + | Edit | |
- | + | \ Copy | |
- | + | \ Paste | |
- | + | \ Cut | |
- | + | \ Indent Type | |
- | + | \ Tabs | |
- | + | \ Spaces | |
- | View | + | \ Preferences |
- | + | View | |
- | + | \ Zoom In | |
- | + | \ Zoom Out | |
- | + | \ Normal Size | |
- | + | \ Highlight | |
- | + | \ C | |
- | + | \ Python | |
- | Help | + | \ JAVA |
- | + | Help | |
- | + | \ Contents | |
- | </ | + | \ About |
+ | |||
+ | </div> | ||
Guidelines: | Guidelines: | ||
Line 52: | Line 53: | ||
* Additional menu commands can be made accessible via dialogs opened from the view menu, if those commands cannot be presented directly in the UI or simply removed. | * Additional menu commands can be made accessible via dialogs opened from the view menu, if those commands cannot be presented directly in the UI or simply removed. | ||
- | A text editor does not need subviews, so more or less all commands need to fit in a single view. See [[Documentation/ | + | A text editor does not need subviews, so more or less all commands need to fit in a single view. See [[Documentation/Maemo_5_Developer_Guide/Human_Interface_Guidelines/Redesigning_From_Maemo_4_to_Maemo_5 | Redesigning From Maemo 4 to Maemo 5]] for details about sub view redesign. |
Changes: | Changes: | ||
Line 63: | Line 64: | ||
The following example shows the implementation of the menu following the above decisions. The first figure below shows the final result of the app menu. The other showd the dialog activated by the menu command "Settings". | The following example shows the implementation of the menu following the above decisions. The first figure below shows the final result of the app menu. The other showd the dialog activated by the menu command "Settings". | ||
- | [[Image:example-migrating-menu1.png| | + | [[Image:example-migrating-menu1.png|400px]] |
- | [[Image:example-migrating-menu-view.png| | + | [[Image:example-migrating-menu-view.png|400px]] |
'''Example 10.2. Migrating a menu''' | '''Example 10.2. Migrating a menu''' | ||
- | + | #include <hildon/hildon.h> | |
- | #include <hildon/hildon.h> | + | #include <libintl.h> |
- | #include <libintl.h> | + | |
- | + | static void | |
- | static void | + | menu_settings_cb (GtkButton *widget, gpointer data) |
- | menu_settings_cb (GtkButton *widget, gpointer data) | + | { |
- | { | + | /* Code to set show settings dialog... */ |
- | + | g_assert(data); | |
- | + | GtkDialog *dialog = GTK_DIALOG( | |
- | + | gtk_dialog_new_with_buttons("Settings", | |
- | + | GTK_WINDOW(data), | |
- | + | GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, | |
- | + | dgettext("hildon-libs", "wdgt_bd_save"), | |
- | + | GTK_RESPONSE_OK, | |
- | + | NULL)); | |
- | + | gint response = 0; | |
- | + | GtkSizeGroup *titlegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); | |
- | + | GtkSizeGroup *valuegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); | |
- | + | ||
- | + | /* Syntax highlight */ | |
- | + | GtkWidget *syntax_selector = hildon_touch_selector_new_text (); | |
- | + | hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (syntax_selector), "C"); | |
- | + | hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (syntax_selector), "JAVA"); | |
- | + | hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (syntax_selector), "Python"); | |
- | + | GtkWidget *syntax_picker = hildon_picker_button_new (HILDON_SIZE_THUMB_HEIGHT | HILDON_SIZE_AUTO_WIDTH, | |
- | + | HILDON_BUTTON_ARRANGEMENT_HORIZONTAL); | |
- | + | hildon_button_set_title (HILDON_BUTTON (syntax_picker), "Syntax highlight"); | |
- | + | hildon_picker_button_set_selector (HILDON_PICKER_BUTTON(syntax_picker), | |
- | + | HILDON_TOUCH_SELECTOR(syntax_selector)); | |
- | + | hildon_picker_button_set_active (HILDON_PICKER_BUTTON(syntax_picker), 0); | |
- | + | ||
- | + | gtk_button_set_alignment (GTK_BUTTON (syntax_picker), 0.0, 0.5); | |
- | + | hildon_button_add_size_groups (HILDON_BUTTON (syntax_picker), titlegroup, valuegroup, NULL); | |
- | + | gtk_container_add (GTK_CONTAINER (dialog->vbox), syntax_picker); | |
- | + | ||
- | + | /* Indent type */ | |
- | + | GtkWidget *indent_selector = hildon_touch_selector_new_text (); | |
- | + | hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (indent_selector), "Tabs"); | |
- | + | hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (indent_selector), "Spaces"); | |
- | + | GtkWidget *indent_picker = hildon_picker_button_new (HILDON_SIZE_THUMB_HEIGHT | HILDON_SIZE_AUTO_WIDTH, | |
- | + | HILDON_BUTTON_ARRANGEMENT_HORIZONTAL); | |
- | + | hildon_button_set_title (HILDON_BUTTON (indent_picker), "Indent type"); | |
- | + | hildon_picker_button_set_selector (HILDON_PICKER_BUTTON(indent_picker), | |
- | + | HILDON_TOUCH_SELECTOR(indent_selector)); | |
- | + | hildon_picker_button_set_active (HILDON_PICKER_BUTTON(indent_picker), 0); | |
- | + | ||
- | + | gtk_button_set_alignment (GTK_BUTTON (indent_picker), 0.0, 0.5); | |
- | + | hildon_button_add_size_groups (HILDON_BUTTON (indent_picker), titlegroup, valuegroup, NULL); | |
- | + | gtk_container_add (GTK_CONTAINER (dialog->vbox), indent_picker); | |
- | + | ||
- | + | gtk_widget_show_all (GTK_WIDGET (dialog)); | |
- | + | ||
- | + | response = gtk_dialog_run(dialog); | |
- | + | if (response == GTK_RESPONSE_OK) { | |
- | + | /* "Save" button has been pressed, save/update the settings here */ | |
- | + | ||
- | + | /* ... */ | |
- | + | } | |
- | + | ||
- | + | /* close the dialog */ | |
- | + | gtk_widget_destroy(GTK_WIDGET(dialog)); | |
- | + | } | |
- | } | + | |
- | + | ||
- | static HildonAppMenu * | + | |
- | build_menu (GtkWidget *window) | + | static HildonAppMenu * |
- | { | + | build_menu (GtkWidget *window) |
- | + | { | |
- | + | HildonSizeType button_size = HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH; | |
- | + | HildonAppMenu *menu = HILDON_APP_MENU (hildon_app_menu_new ()); | |
- | + | GtkButton *button; | |
- | + | ||
- | + | /* Menus like New, Open, etc that would open new dialogs (no submenus) | |
- | + | * are not assigned any action in this example | |
- | + | */ | |
- | + | ||
- | + | button = GTK_BUTTON (hildon_gtk_button_new (button_size)); | |
- | + | gtk_button_set_label (button, "New"); | |
- | + | hildon_app_menu_append (menu, GTK_BUTTON (button)); | |
- | + | ||
- | + | button = GTK_BUTTON (hildon_gtk_button_new (button_size)); | |
- | + | gtk_button_set_label (button, "Open"); | |
- | + | hildon_app_menu_append (menu, GTK_BUTTON (button)); | |
- | + | ||
- | + | button = GTK_BUTTON (hildon_gtk_button_new (button_size)); | |
- | + | gtk_button_set_label (button, "Save"); | |
- | + | hildon_app_menu_append (menu, GTK_BUTTON (button)); | |
- | + | ||
- | + | button = GTK_BUTTON (hildon_gtk_button_new (button_size)); | |
- | + | gtk_button_set_label (button, "Settings"); | |
- | + | g_signal_connect (G_OBJECT (button), "clicked", | |
- | + | G_CALLBACK (menu_settings_cb), window); | |
- | + | hildon_app_menu_append (menu, GTK_BUTTON (button)); | |
- | + | ||
- | + | gtk_widget_show_all (GTK_WIDGET (menu)); | |
- | + | ||
- | } | + | return menu; |
- | + | } | |
- | int | + | |
- | main (int argc, char **argv) | + | int |
- | { | + | main (int argc, char **argv) |
- | + | { | |
- | + | hildon_gtk_init (&argc, &argv); | |
- | + | ||
- | + | GtkWidget *window; | |
- | + | window = hildon_stackable_window_new (); | |
- | + | gtk_window_set_title (GTK_WINDOW (window), "Editor"); | |
- | + | ||
- | + | HildonAppMenu *menu = build_menu (window); | |
- | + | hildon_stackable_window_set_main_menu (HILDON_STACKABLE_WINDOW (window), menu); | |
- | + | ||
- | + | GtkWidget *contents = gtk_label_new ("This example shows how an app menu could be " | |
- | + | "migrated.\nMenu item callbacks " | |
- | + | "are not fully implemented."); | |
- | + | gtk_container_add (GTK_CONTAINER (window), contents); | |
- | + | ||
- | + | /* ... other widgets in the application */ | |
- | + | ||
- | + | g_signal_connect (G_OBJECT (window), "destroy", | |
- | + | G_CALLBACK (gtk_main_quit), NULL); | |
- | + | ||
- | + | gtk_widget_show_all (window); | |
- | + | ||
- | + | gtk_main (); | |
- | } | + | return 0; |
- | + | } | |
==Choices == | ==Choices == | ||
- | |||
Some widgets for choosing options also need to be adapted to the new Hildon way of designing interfaces. If you have several radio buttons to express a choice, replacing them with a picker button is a good idea. | Some widgets for choosing options also need to be adapted to the new Hildon way of designing interfaces. If you have several radio buttons to express a choice, replacing them with a picker button is a good idea. | ||
Consider a dialog that includes, among other widgets, a frame labeled "Proxy Preferences" and three radio buttons: "None", "Auto" and "Manual", displayed vertically like Figure 10.1 "Three radio buttons" shows. The following example shows how such task could be accomplished using a picker button. The frame label becomes the picker button's title and the three radio buttons' labels become the choices in the picker's touch selector. The screenshot below shows the resulting graphical user interface. | Consider a dialog that includes, among other widgets, a frame labeled "Proxy Preferences" and three radio buttons: "None", "Auto" and "Manual", displayed vertically like Figure 10.1 "Three radio buttons" shows. The following example shows how such task could be accomplished using a picker button. The frame label becomes the picker button's title and the three radio buttons' labels become the choices in the picker's touch selector. The screenshot below shows the resulting graphical user interface. | ||
- | [[Image:choices.png| | + | [[Image:choices.png|Image choices|400px]] |
'''Example 10.3. Migrating choice widgets''' | '''Example 10.3. Migrating choice widgets''' | ||
- | < | + | <tt><span>'''<span><font color="#000080"><nowiki>#include</nowiki></font></span>'''</span> <span><font color="#FF0000"><hildon/hildon.h></font></span> |
- | #include <hildon/hildon.h> | + | <span><font color="#009900">int</font></span> |
- | int | + | <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> |
- | main (int argc, char **argv) | + | <span><font color="#FF0000">{</font></span> |
- | { | + | <span>'''<span><font color="#000000">hildon_gtk_init</font></span>'''</span> <span><font color="#990000">(&</font></span>argc<span><font color="#990000">,</font></span> <span><font color="#990000">&</font></span>argv<span><font color="#990000">);</font></span> |
- | + | GtkWidget <span><font color="#990000"><nowiki>*</nowiki></font></span>window<span><font color="#990000"><nowiki>;</nowiki></font></span> | |
- | + | window <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">hildon_window_new</font></span>'''</span> <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">"Preferences"</font></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_main_quit<span><font color="#990000">),</font></span> NULL<span><font color="#990000">);</font></span> | |
- | + | HildonPickerButton <span><font color="#990000"><nowiki>*</nowiki></font></span>picker <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">HILDON_PICKER_BUTTON</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">hildon_picker_button_new</font></span>'''</span> <span><font color="#990000">(</font></span> | |
- | + | HILDON_SIZE_THUMB_HEIGHT <span><font color="#990000"><nowiki>|</nowiki></font></span> HILDON_SIZE_HALFSCREEN_WIDTH<span><font color="#990000">,</font></span> | |
- | + | HILDON_BUTTON_ARRANGEMENT_VERTICAL<span><font color="#990000">));</font></span> | |
- | + | <span>'''<span><font color="#000000">hildon_button_set_title</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">HILDON_BUTTON</font></span>'''</span> <span><font color="#990000">(</font></span>picker<span><font color="#990000">),</font></span> <span><font color="#FF0000">"Proxy preferences:"</font></span><span><font color="#990000">);</font></span> | |
- | + | HildonTouchSelector <span><font color="#990000"><nowiki>*</nowiki></font></span>selector <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">HILDON_TOUCH_SELECTOR</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">hildon_touch_selector_new_text</font></span>'''</span> <span><font color="#990000">());</font></span> | |
- | + | <span>'''<span><font color="#000000">hildon_picker_button_set_selector</font></span>'''</span> <span><font color="#990000">(</font></span>picker<span><font color="#990000">,</font></span> selector<span><font color="#990000">);</font></span> | |
- | + | <span>'''<span><font color="#000000">hildon_touch_selector_append_text</font></span>'''</span> <span><font color="#990000">(</font></span>selector<span><font color="#990000">,</font></span> <span><font color="#FF0000">"None"</font></span><span><font color="#990000">);</font></span> | |
- | + | <span>'''<span><font color="#000000">hildon_touch_selector_append_text</font></span>'''</span> <span><font color="#990000">(</font></span>selector<span><font color="#990000">,</font></span> <span><font color="#FF0000">"Auto"</font></span><span><font color="#990000">);</font></span> | |
- | + | <span>'''<span><font color="#000000">hildon_touch_selector_append_text</font></span>'''</span> <span><font color="#990000">(</font></span>selector<span><font color="#990000">,</font></span> <span><font color="#FF0000">"Manual"</font></span><span><font color="#990000">);</font></span> | |
- | + | <span>'''<span><font color="#000000">hildon_picker_button_set_active</font></span>'''</span> <span><font color="#990000">(</font></span>picker<span><font color="#990000">,</font></span> <span><font color="#993399">0</font></span><span><font color="#990000">);</font></span> | |
- | + | GtkVBox <span><font color="#990000"><nowiki>*</nowiki></font></span>contents <span><font color="#990000"><nowiki>=</nowiki></font></span> <span>'''<span><font color="#000000">GTK_VBOX</font></span>'''</span> <span><font color="#990000">(</font></span><span>'''<span><font color="#000000">gtk_vbox_new</font></span>'''</span> <span><font color="#990000">(</font></span><span><font color="#993399">12</font></span><span><font color="#990000">,</font></span> FALSE<span><font color="#990000">));</font></span> | |
- | + | <span>''<span><font color="#9A1900">/* ... other widgets placed here */</font></span>''</span> | |
- | + | <span>'''<span><font color="#000000">gtk_box_pack_end</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>contents<span><font color="#990000">),</font></span> <span>'''<span><font color="#000000">GTK_WIDGET</font></span>'''</span> <span><font color="#990000">(</font></span>picker<span><font color="#990000">),</font></span> FALSE<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> | |
- | + | <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> <span>'''<span><font color="#000000">GTK_WIDGET</font></span>'''</span> <span><font color="#990000">(</font></span>contents<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> |
- | </ | + | |
==Notebooks == | ==Notebooks == | ||
- | + | Because the use of notebooks is not advised in Hildon, the way to migrate a Maemo 4 dialog with notebook to Maemo 5, is to simply put all the items inside a single pannable dialog. | |
- | Because the use of notebooks is not advised in Hildon, the way to migrate a Maemo 4 dialog with | + | |
- | + | ||
- | + | ||
- | + | ||
- | + |
Learn more about Contributing to the wiki.