World Clock Widget / src /

view.c

/*
 * Copyright (c) 2015 Samsung Electronics Co., Ltd
 *
 * Licensed under the Flora License, Version 1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://floralicense.org/license/
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ 

#include <tizen.h>
#include <widget_app.h>
#include <widget_app_efl.h>
#include <dlog.h>
#include "log.h"
#include "view.h"

#define FILE_CONTENT "edje/content.edj"
#define GROUP_NAME "content"

static Evas_Object *_create_win(widget_context_h context, int w, int h);
static Evas_Object *_create_content(Evas_Object *win);
static void _get_resource(const char *file_in, char *path_out, int path_max);
static void _widget_pressed_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);
static void _widget_released_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);

/*
 * @brief: Set image to given part
 * @param[user_data]: data needed in this function (widget_instance_data)
 * @param[part]: part name to which you want to set this image
 * @param[file_name]: name of image file
 */
void view_set_image(void *user_data, const char *part, const char *file_name)
{
	widget_instance_data_s *wid = NULL;
	Evas_Object *img = NULL;

	wid = user_data;
	if (wid == NULL) {
		dlog_print(DLOG_ERROR, LOG_TAG, "failed to widget data.");
		return;
	}

	char full_path[PATH_MAX] = {0, };

	img = elm_image_add(wid->win);
	if (img == NULL) {
		dlog_print(DLOG_ERROR, LOG_TAG, "failed to add a image.");
		return;
	}

	_get_resource(file_name, full_path, sizeof(full_path));
	elm_image_file_set(img, full_path, NULL);
	evas_object_size_hint_weight_set(img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
	elm_win_resize_object_add(wid->win, img);
	evas_object_show(img);

	elm_object_part_content_set(wid->content, part, img);
}

/*
 * @brief: Set text to the part
 * @param[user_data]: data needed in this function (widget_instance_data)
 * @param[part]: Part name to which you want to set text
 * @param[text]: text you want to set to the part
 */
void view_set_text(void *user_data, const char *part, const char *text)
{
	widget_instance_data_s *wid = NULL;

	wid = user_data;
	if (wid == NULL) {
		dlog_print(DLOG_ERROR, LOG_TAG, "failed to get widget data.");
		return;
	}

	elm_object_part_text_set(wid->content, part, text);
}

/*
 * @brief: Create essential object window, content and so on
 * @param[context]: context for widget instance
 * @param[w]: basic size of width for widget
 * @param[h]: basic size of height for widget
 */
widget_instance_data_s *view_create(widget_context_h context, int w, int h)
{

	widget_instance_data_s *wid = malloc(sizeof(widget_instance_data_s));

	wid->win = _create_win(context, w, h);
	if (wid->win == NULL) {
		dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a window.");
		free(wid);
		return NULL;
	}

	wid->content = _create_content(wid->win);
	if (wid->content == NULL) {
		dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a content.");
		evas_object_del(wid->win);
		free(wid);
		return NULL;
	}

	wid->root_width = w;
	wid->root_height = h;

	return wid;
}

/*
 * @brief: Destroy window and free important data to finish this application
 * @param[user_data]: data needed in this function (widget_instance_data)
 */
void view_destroy(void *user_data)
{
	widget_instance_data_s *wid = NULL;

	wid = user_data;
	if (wid == NULL) {
		dlog_print(DLOG_ERROR, LOG_TAG, "failed to destroy data.");
		return;
	}

	evas_object_del(wid->win);

	free(wid);
}

/*
 * @brief: Changes the size of the given Evas object
 * @param[user_data]: data needed in this function (widget_instance_data)
 * @param[w]: width to change size of widget
 * @param[h]: height to change size of widget
 */
void view_resize(void *user_data, int w, int h)
{
	widget_instance_data_s *wid = NULL;

	wid = user_data;
	if (wid == NULL) {
		dlog_print(DLOG_ERROR, LOG_TAG, "failed to widget data.");
		return;
	}

	evas_object_resize(wid->win, w, h);
}

/*
 * @brief: Set event callback to Evas Object that is a part of a given container widget
 * @param[user_data]: data needed in this function (widget_instance_data)
 * @param[part_name]: container's part name to get
 * @param[type]: widget event type
 * @param[func]: callback function
 */
void view_set_event_callback(void *user_data, const char *part_name, widget_event_type type, void *func)
{
	widget_instance_data_s *wid = NULL;
	Evas_Object *obj = NULL;

	wid = user_data;
	if (wid == NULL) {
		dlog_print(DLOG_ERROR, LOG_TAG, "failed to widget data.");
		return;
	}

	obj = elm_object_part_content_get(wid->content, part_name);

	if (!obj) {
		obj = (Evas_Object*) edje_object_part_object_get(elm_layout_edje_get(wid->content), part_name);
	}

	evas_object_data_set(obj, "callback_func_addr", (void*) func);
	evas_object_data_set(obj, "widget_event_type", (void*) type);

	if (type == WIDGET_EVENT_PRESSED) {
		evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN, _widget_pressed_cb, wid);
	} else if ((type == WIDGET_EVENT_RELEASED) || (type == WIDGET_EVENT_CLICKED)) {
		evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP, _widget_released_cb, wid);
	}
}


/*
 * @note
 * Below functions are static functions.
 */

/*
 * @brief: Get path of resource.
 * @param[file_in]: file name
 * @param[path_out]: the point to which save full path of the resource
 * @param[path_max]: size of file name include path
 */
static void _get_resource(const char *file_in, char *path_out, int path_max)
{
	char *res_path = app_get_resource_path();
	if (res_path) {
		snprintf(path_out, path_max, "%s/%s", res_path, file_in);
		free(res_path);
	}
}

/*
 * @brief: Create window for widget
 * @param[context]: context for widget instance
 * @param[w]: basic size of width for widget
 * @param[h]: basic size of height for widget
 */
static Evas_Object *_create_win(widget_context_h context, int w, int h)
{
	Evas_Object *win = NULL;
	int ret;

	if (context == NULL) {
		dlog_print(DLOG_ERROR, LOG_TAG, "failed to get context.");
		return NULL;
	}

	ret = widget_app_get_elm_win(context, &win);
	if (ret != WIDGET_ERROR_NONE) {
		dlog_print(DLOG_ERROR, LOG_TAG, "failed to get window. err = %d", ret);
		return NULL;
	}
	evas_object_resize(win, w, h);
	evas_object_show(win);

	return win;
}

/*
 * @brief: Make a content(layout) with edje file
 * @param[win]: The object to which you want to add this layout
 */
static Evas_Object *_create_content(Evas_Object *win)
{
	Evas_Object *content = NULL;
	char full_path[PATH_MAX] = { 0, };

	content = elm_layout_add(win);
	if (content == NULL) {
		dlog_print(DLOG_ERROR, LOG_TAG, "failed to add a content.");
		return NULL;
	}

	_get_resource(FILE_CONTENT, full_path, sizeof(full_path));
	elm_layout_file_set(content, full_path, GROUP_NAME);
	evas_object_size_hint_weight_set(content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
	elm_win_resize_object_add(win, content);
	evas_object_show(content);

	return content;
}

/*
 * @brief: This function will be operated when the widget is pressed
 * @param[data]: data will be the same value passed to evas_object_event_callback_add() as the data parameter
 * @param[evas]: e lets the user know what evas canvas the event occurred on
 * @param[obj]: object handles on which the event occurred
 * @param[event_info]: event_info is a pointer to a data structure about event
 */
static void _widget_pressed_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)
{
	widget_instance_data_s *wid = data;
	if (!wid) {
		return;
	}

	widget_event_cb func = evas_object_data_get(obj, "callback_func_addr");

	func(wid);
}

/*
 * @brief: This function will be operated when the widget is released
 * @param[data]: data will be the same value passed to evas_object_event_callback_add() as the data parameter
 * @param[evas]: e lets the user know what evas canvas the event occurred on
 * @param[obj]: object handles on which the event occurred
 * @param[event_info]: event_info is a pointer to a data structure about event
 */
static void _widget_released_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)
{
	widget_instance_data_s *wid = data;
	Evas_Event_Mouse_Up *ev = event_info;
	Evas_Coord x, y, w, h;

	if (!wid) {
		return;
	}

	widget_event_cb func = (widget_event_cb) evas_object_data_get(obj, "callback_func_addr");
	widget_event_type type = (widget_event_type) evas_object_data_get(obj, "widget_event_type");

	if (type == WIDGET_EVENT_RELEASED) {
		if (func) {
			func(wid);
		}
	} else if (type == WIDGET_EVENT_CLICKED) {
		evas_object_geometry_get(obj, &x, &y, &w, &h);

		if (!ELM_RECTS_POINT_OUT(x, y, w, h, ev->canvas.x, ev->canvas.y)) {
			if (func) {
				func(wid);
			}
		}
	}
}

/* End of file */