Published on 25th of October 2017
Image and Scroller Widgets

In this lesson, we are going to show you how to create your second demo application. First of all, you will have to add the image, and then place it in the container with the scrollable area (Scroller). In the next lesson, after adding some logic, your application will turn into a mini game.

Image Creation

In the Tizen native application development, Image widget is usually used to display the image on the screen. This widget allows to display an image, as well as to display and to play animated .gif images.

This widget allows you to use an image file or directly the memory area where the image is stored. The last option is convenient when you download an image from the Internet, and you have no need to save it.

The basic project that you will need in this lesson is available here.

This is a normal UI application for a wearable device in which a window and a conformant supposed to be created. At first, create Image and make it the content of the conformant container as shown in the diagram below.

nw_018_01_en

Take the following image and load it into the application.

nw_018_02_en

It is advised to place graphics, audio and other resources in the res/ directory of your project. Only your application has access to this folder. During the application building, all the contents of this folder get into the .tpk package. Create the images/ directory inside the res/ directory and put the image there.

Extend your widgets structure with a pointer to the new widget, which will be created further. Just like all other widgets in the EFL, the pointer to the image will has Evas_Object type.

Evas_Object *image;

You should get the following contents of your widgets structure:

typedef struct _UIData {
   Evas_Object *win;
   Evas_Object *conform;
   Evas_Object *image;
} UIData;

Create a function to implement work with the image widget:

static void
_image_create(UIData *ui)
{
}

To create a new image widget, use the following function:

ui->image = elm_image_add(ui->conform);

Pass a pointer to the widget that will be parent for the image to the function for image creation. As a result, the method returns a pointer to the newly created image.

Specifying a Path to an Image Resource

Now we need to specify the path to the image that we will display in the widget. For this, use the function:

Eina_Bool elm_image_file_set(Evas_Object *obj, const char *file, const char *group);

This function takes the full path to the image file on the device as the second parameter; this path can be obtained at the run time. During the compilation, you know only the path to the image relative to the root of the project, or to the subdirectory res/. For example, in this case, you know that your image has the following path: images/image.jpg inside the res/ directory of your project. But at runtime you need to get the absolute path. For this tizen have functions for getting the full path to some directories of your application at runtime. Hence you can get the path to the directory and link it with the path to the file from the directory. The following function allows you to get the absolute path to the res/ directory of your application at runtime.

char *app_get_resource_path();

Let's implement a function that will generate full path from the relative:

static void
_file_abs_resource_path_get(char *res_file_path, char *abs_path, int buf_size)
{
   char *res_dir_path = app_get_resource_path();

   if (res_dir_path)
     {
        snprintf(abs_path, buf_size, "%s%s", res_dir_path, res_file_path);
        free(res_dir_path);
     }
}

The following function takes the relative path to the image as the first parameter, and a pointer to the buffer where to put the absolute path as the second parameter, and the buffer size as the third one.

Now this function can be used. Add the following code after creating the widget object:

char abs_path_to_image[PATH_MAX] = {0,};
_file_abs_resource_path_get("images/image.jpg", abs_path_to_image, PATH_MAX);

You can use this function, always when there will be a need to get the full path to any resource of your application.

Now you can upload the image to the widget:

elm_image_file_set(ui->image, abs_path_to_image, NULL);

Display the widget:

evas_object_show(ui->image);

Call the function to create an image widget and place it in a conformant:

static void
_conformant_create(UIData *ui)
{
   ...

   _image_create(ui);
   elm_object_content_set(ui->conform, ui->image);

   ...
}

Now you can launch the application and see the result.

nw_018_03_en
Using .gif Animation in Image Widget

As it was mentioned before, Image widget supports .gif animation. But by default, if you specify the path to such animation, the widget displays the file as a static image. You need to call several additional functions to launch the animation.

Let's try to use the following animation as a resource.

nw_018_04_en

Place it, using following path: res/images/animation.gif.

Now show the way to this animation for your widget.

Replace "images/image.jpg" with "images animation.gif"

_file_abs_resource_path_get("images/animation.gif",
                            abs_path_to_image,
                            PATH_MAX);

For the image widget, there is a function that checks whether the specified resource supports animation; it needs to be called after you have installed the image into the widget.

if (is_animated)
   {
      elm_image_animated_set(ui->image, EINA_TRUE);
      elm_image_animated_play_set(ui->image, EINA_TRUE);
   }

So, now if the specified image supports animation, then its playback will start automatically.

Let's see what the application will show.

Creating and Using the Scroller

In case you have a large amount of content to be placed on the screen, you can use a scroller that has a scroll area.

Next, extend the demo application with a scroller, adding it as a layer between the conformant and the image, so if the size of the original image is larger than the display size, you can scroll the image in areas that is not included to the display borders. The scroller will be placed in a conformant, and the image will be placed in the scroller as it shown in the diagram below.

nw_018_06_en

Extend your structure with widgets for a new container, which will be created later. As well as all widgets in the EFL, the pointer to the scroller will has Evas_Object type.

Evas_Object *scroller;

The structure with widgets supposed to looks like this:

typedef struct _UIData {
   Evas_Object *win;
   Evas_Object *conform;
   Evas_Object *scroller;
   Evas_Object *image;
} UIData;

Add a function in which implement work with the scroller:

static void
_scroller_create(UIData *ui)
{
}

To create a new scroller, use the following function:

ui->scroller = elm_scroller_add(ui->conform);

In the function for scroller creation, pass a pointer to the conformant that will be the parent for it. As a result, the method returns a pointer to the newly created scroller.

Instead of the image that we have previously directly inserted into the conformant, place scroller there.

static void
_conformant_create(UIData *ui)
{
   ...

   _scroller_create(ui);
   elm_object_content_set(ui->conform, ui->scroller);

   ...
}

Now it is necessary to change parent for the widget of the images to save the widgets hierarchy. In case of removing the scroller this image will not appear somewhere, but it will be correctly deleted together with the scroller.

ui->image = elm_image_add(ui->scroller);

By default, the Image widget displays an image that is scaled to the size of the widget, so if you use an image with a size 720x360 in a widget with 360x360 dimensions, then the image will be scaled to the size 360x180 and centered, as shown in the diagram below.

nw_018_07_en

We need to make the image widget size the same as the size of the original image.

First, take the lower-level image object that is at the level of the Evas module. From it you may get the size of the resource. Do not confuse the image (elm_image) from the Elementary module with the Evas (evas_object_image) image. The last one stores more detailed object information. Moreover, the first one is a smart object that has additional functions, for example for animation, or for receiving a signal for click event, made on the widget.

Evas_Object *evas_image = elm_image_object_get(ui->image);

Get the image size:

int w = 0;
int h = 0;
evas_object_image_size_get(evas_image, &w, &h);

The last step is to specify to the image widget the received size as the minimum and maximum size, so when you load images, the widget will assume exactly the same size as the file.

evas_object_size_hint_min_set(ui->image, w, h);
evas_object_size_hint_max_set(ui->image, w, h);

Now add the following image, which will be bigger than the screen of the watch (in this case the screen is 360x360).

nw_018_08_en

Place it in res/images/image_big.png.

Now show the way to this image for the widget.

Replace “images/animation.gif” on “images/image_big.png” :

file_abs_resource_path_get("images/image_big.png", abs_path_to_image, PATH_MAX);

Call the function to display the scroller:

evas_object_show(ui->scroller);

Place the image widget in the scroller using the function:

elm_object_content_set(ui->scroller, ui->image);

Below you may see the result.

The full source code of this tutorial is available here WearLesson018

Leave a Reply

Your email address will not be published. Required fields are marked *