Mobile native

[UI Sample] ThemeExtension Sample Overview

The [UI Sample] ThemeExtension sample application demonstrates how to customize the look and feel of your application with custom styles that are not provided by default. You can use custom styles to change the default appearance of UI components. You need to provide all extra elements, such as image files, in separate Edje files.

This sample uses UI components, such as elm_layout for view management and elm_button for the content of the view.

The following figure illustrates the main view of the [UI Sample] ThemeExtension sample application, its wireframe structure, and the UI component tree.

Figure: [UI Sample] ThemeExtension screen

[UI Sample] ThemeExtension screen

[UI Sample] ThemeExtension screen

Use the following methods to customize the UI component theme in the application:

elm_theme_extension_add(NULL, "/usr/apps/org.tizen.app/data/app_theme.edj");
elm_object_style_set(button, "new_style");

Figure: Customized style

Customized style

Application Layout

The create_base_gui() function is responsible for creating the application layout:

static void
create_base_gui(appdata_s *ad)
{
   char edj_path[PATH_MAX] = {0, };

   // Window
   ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
   elm_win_conformant_set(ad->win, EINA_TRUE);
   elm_win_autodel_set(ad->win, EINA_TRUE);

   if (elm_win_wm_rotation_supported_get(ad->win))
   {
      int rots[4] = { 0, 90, 180, 270 };
      elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
   }

   evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);
   eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad);

   // Base layout
   app_get_resource(EDJ_FILE, edj_path, (int)PATH_MAX);
   // Appends a theme extension to the list of extensions
   elm_theme_extension_add(NULL, edj_path);

   create_content(ad);

   // Show the window after the base GUI is set up
   evas_object_show(ad->win);
}

The function starts by creating a window and then adds elm_layout to create the main view.

The application uses an Edje file that contains custom themes. To apply a custom theme, the app_get_resource() function is called to retrieve the Edje file, and then the elm_theme_extension_add() function is called to append a theme from the file to the application UI.

The elm_theme_extension_add() function adds the Edje file to the theme search path, which is used to search for themes beyond the default theme. The function takes the following parameters:

  • NULL: Theme to add (NULL means that the default theme is added)
  • edj_path: Path of the Edje file containing the theme to add

Default and Customized Buttons

The following code adds 2 buttons to the layout:

static void
create_content(appdata_s *ad)
{
   Evas_Object *grid, *btn_origin, *btn_customized;

   grid = elm_grid_add(ad->win);
   elm_win_resize_object_add(ad->win, grid);
   evas_object_show(grid);

   btn_origin = elm_button_add(grid);
   elm_object_text_set(btn_origin, "Default style");
   elm_grid_pack(grid, btn_origin, 25, 30, 50, 10);
   evas_object_show(btn_origin);

   btn_customized = elm_button_add(ad->win);
   // Sets the style to be used by a button
   elm_object_style_set(btn_customized, "customized");
   elm_object_text_set(btn_customized, "Customized style");
   elm_grid_pack(grid, btn_customized, 25, 60, 50, 20);
   evas_object_show(btn_customized);
}

The first is a default button and the second a customized button. Use the elm_object_style_set() function to apply a custom style to the button. The style defines the button appearance.

Styles vary from UI component to UI component and can also be defined by other themes by means of extensions and overlays.

The elm_object_style_set() function takes the following parameters:

  • btn_customized: UI component that the style is applied to
  • customized: Name of the style to apply to the UI component

The following table shows a code comparison for a default button and customized button. The default code comes from the efl-theme-tizen/2.3-mobile/widget/button.edc file, and the customized code comes from the efl-theme-tizen/2.3-mobile/WVGA-inc.edc file.

Table: Default and customized button
Default code Customized code


   group
   {
      name: "elm/button/base/default";
      script
      {
         public mouse_down = 0;
         public multi_down = 0;
      }
      images
      {
         image: "core_list_button_bg.#.png" COMP;
         image: "core_list_button_effect_normal.#.png" COMP;
         image: "core_list_button_effect_pressed.#.png" COMP;
      }
      parts
      {
         part
         {
            name: "base";
            scale: 1;
            description
            {
               state: "default" 0.0;
               min: BUTTON_MIN_WIDTH BUTTON_MIN_HEIGHT;
               image.normal: "core_list_button_bg.#.png";
               color_class: "W012E1";
            }
            description
            {
               state: "pressed" 0.0;
               inherit: "default" 0.0;
               visible: 0;
            }
         }
         part
         {
            name: "bg";
            scale: 1;
            description
            {
               state: "default" 0.0;
               rel1.to: "base";
               rel2.to: "base";
               image.normal: "core_list_button_bg.#.png";
               color_class: "W012";
            }
            description
            {
               state: "pressed" 0.0;
               inherit: "default" 0.0;
               color_class: "W012P";
            }
            description
            {
               state: "disabled" 0.0;
               inherit: "default" 0.0;
               color_class: "W012D";
            }
         }
         part
         {
            name: "bg_effect";
            scale: 1;
            description
            {
               state: "default" 0.0;
               rel1.to: "bg";
               rel2.to: "bg";
               image.normal: "core_list_button_effect_normal.#.png";
            }
            description
            {
               state: "pressed" 0.0;
               inherit: "default" 0.0;
               image.normal: "core_list_button_effect_pressed.#.png";
            }
            description
            {
               state: "disabled" 0.0;
               inherit: "default" 0.0;
               visible:0;
            }
         }
         part
         {
            name: "padding_left_top";
...
...
...
      programs
      {
         program
         {
            name: "pressed";
            signal: "mouse,down,1*";
            source: "event";
            script
            {
               if ((get_int(multi_down) == 0) && (get_int(mouse_down) == 0))
               {
                  set_int(mouse_down, 1);
                  run_program(PROGRAM:"button_press1");
               }
            }
         }
         program
         {
            name: "button_press1";
            script
            {
               new st[31];
               new Float:vl;
               get_state(PART:"bg", st, 30, vl);
               if (strcmp(st, "disabled"))
               {
                  set_state(PART:"base", "pressed", 0.0);
                  set_state(PART:"bg", "pressed", 0.0);
                  set_state(PART:"bg_effect", "pressed", 0.0);
                  set_state(PART:"elm.text", "pressed", 0.0);
                  emit("elm,action,press", "");
               }
            }
         }
         program
         {
            name: "unpressed";
            signal: "mouse,up,1";
            source: "event";
            script
            {
               if (get_int(mouse_down) == 1)
               {
                  set_int(mouse_down, 0);
                  run_program(PROGRAM:"button_unpress1");
               }
            }
         }
         program
         {
            name: "button_unpress1";
            script
            {
               new st[31];
               new Float:vl;
               get_state(PART:"bg", st, 30, vl);
               if (strcmp(st, "disabled"))
               {
                  set_state(PART:"base", "default", 0.0);
                  set_state(PART:"bg", "default", 0.0);
                  set_state(PART:"bg_effect", "default", 0.0);
                  set_state(PART:"elm.text", "default", 0.0);
                  emit("elm,action,unpress", "");
               }
            }
         }
         program
         {
            name: "touch_snd";
            signal: "mouse,clicked,1";
            source: "event";
            script
            {
               new st[31];
               new Float:vl;
               if (get_int(multi_down) == 0)
               {
                  get_state(PART:"bg", st, 30, vl);
                  if (strcmp(st, "disabled"))
                  {
                     run_program(PROGRAM:"touch_sound");
                     emit("elm,action,click", "");
                  }
               }
            }
         }
         program
         {
            name: "touch_sound";
            action: RUN_PLUGIN "touch_sound";
         }
...
...
...
         program
         {
            name: "disable";
            signal: "elm,state,disabled";
            source: "elm";
            action: STATE_SET "disabled" 0.0;
            target: "bg";
            target: "bg_effect";
            target: "elm.text";
         }
         program
         {
            name: "enable";
            signal: "elm,state,enabled";
            source: "elm";
            action: STATE_SET "default" 0.0;
            target: "bg";
            target: "bg_effect";
            target: "elm.text";
         }
// Define value, button styles come from efl-theme-tizen/2.3-mobile/WVGA-inc.edc
#define BUTTON_MIN_WIDTH 142
#define BUTTON_MIN_HEIGHT 56
#define BUTTON_PADDING_LEFT_RIGHT 8
#define BUTTON_ICON_HEIGHT 46
#define BUTTON_ICON_WIDTH 46
#define BUTTON_TEXT_SIZE 30

#define STYLE_TAGS \
   tag:  "br" "\n";\
   tag:  "ps" "ps";\
   tag:  "tab" "\t";\
   tag:  "b" "+ font_weight=Bold";

styles
{
   style
   {
      name: "button_main";
      base: "font=Tizen:style=Regular font_size="BUTTON_TEXT_SIZE" color=#ffffff ellipsis=1.0";
      STYLE_TAGS
   }
   style
   {
      name: "button_main_dim";
      base: "font=Tizen:style=Regular font_size="BUTTON_TEXT_SIZE" color=#ffffff ellipsis=1.0";
      STYLE_TAGS
   }
   style
   {
      name: "button_main_press";
      base: "font=Tizen:style=Regular font_size="BUTTON_TEXT_SIZE" color=#ffffff ellipsis=1.0";
      STYLE_TAGS
   }
}

collections
{
   group
   {
      name: "elm/button/base/customized";
      script
      {
         public mouse_down = 0;
         public multi_down = 0;
      }
      images
      {
         image: "green.png" COMP;
         image: "red.png" COMP;
      }
      parts
      {
         part
         {
            name: "base";
            scale: 1;
            description
            {
               state: "default" 0.0;
               min: BUTTON_MIN_WIDTH BUTTON_MIN_HEIGHT;
               image.normal: "green.png";
            }
            description
            {
               state: "pressed" 0.0;
               inherit: "default" 0.0;
               visible: 0;
            }
         }
         part
         {
            name: "bg";
            scale: 1;
            description
            {
               state: "default" 0.0;
               rel1.to: "base";
               rel2.to: "base";
               image.normal: "green.png";
            }
            description
            {
               state: "pressed" 0.0;
               inherit: "default" 0.0;
               image.normal: "red.png";
            }
            description
            {
               state: "disabled" 0.0;
               inherit: "default" 0.0;
               visible:0;
            }
         }



























         part
         {
            name: "padding_left_top";
...
...
...
      programs
      {
         program
         {
            name: "pressed";
            signal: "mouse,down,1*";
            source: "event";
            script
            {
               if ((get_int(multi_down) == 0) && (get_int(mouse_down) == 0))
               {
                  set_int(mouse_down, 1);
                  run_program(PROGRAM:"button_press1");
               }
            }
         }
         program
         {
            name: "button_press1";
            script
            {
               new st[31];
               new Float:vl;
               get_state(PART:"bg", st, 30, vl);
               if (strcmp(st, "disabled"))
               {
                  set_state(PART:"base", "pressed", 0.0);
                  set_state(PART:"bg", "pressed", 0.0);
                  set_state(PART:"elm.text", "pressed", 0.0);
                  emit("elm,action,press", "");
               }
            }
         }
         program
         {
            name: "unpressed";
            signal: "mouse,up,1";
            source: "event";
            script
            {
               if (get_int(mouse_down) == 1)
               {
                  set_int(mouse_down, 0);
                  run_program(PROGRAM:"button_unpress1");
               }
            }
         }
         program
         {
            name: "button_unpress1";
            script
            {
               new st[31];
               new Float:vl;
               get_state(PART:"bg", st, 30, vl);
               if (strcmp(st, "disabled"))
               {
                  set_state(PART:"base", "default", 0.0);
                  set_state(PART:"bg", "default", 0.0);
                  set_state(PART:"elm.text", "default", 0.0);
                  emit("elm,action,unpress", "");
               }
            }
         }



























...
...
...
         program
         {
            name: "disable";
            signal: "elm,state,disabled";
            source: "elm";
            action: STATE_SET "disabled" 0.0;
            target: "bg";
            target: "elm.text";
         }
         program
         {
            name: "enable";
            signal: "elm,state,enabled";
            source: "elm";
            action: STATE_SET "default" 0.0;
            target: "bg";
            target: "elm.text";
         }



Go to top