Merge branch 'master' into svn_merge
[framework/uifw/elementary.git] / src / lib / elm_bg.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 typedef struct _Widget_Data Widget_Data;
5
6 struct _Widget_Data
7 {
8    Evas_Object *base, *rect, *img, *overlay;
9    const char  *file, *group;
10    Elm_Bg_Option option;
11    struct {
12       Evas_Coord w, h;
13    } load_opts;
14 };
15
16 static const char *widtype = NULL;
17
18 static void _del_hook(Evas_Object *obj);
19 static void _theme_hook(Evas_Object *obj);
20 static void _custom_resize(void *data, Evas *a, Evas_Object *obj, void *event_info);
21
22 static void
23 _del_hook(Evas_Object *obj)
24 {
25    Widget_Data *wd = elm_widget_data_get(obj);
26    free(wd);
27 }
28
29 static void
30 _theme_hook(Evas_Object *obj)
31 {
32    Widget_Data *wd = elm_widget_data_get(obj);
33    Evas_Coord w, h;
34
35    _elm_theme_object_set(obj, wd->base, "bg", "base",
36                          elm_widget_style_get(obj));
37
38    if (wd->rect)
39      edje_object_part_swallow(wd->base, "elm.swallow.rectangle", wd->rect);
40    if (wd->img)
41      edje_object_part_swallow(wd->base, "elm.swallow.background", wd->img);
42    if (wd->overlay)
43      edje_object_part_swallow(wd->base, "elm.swallow.content", wd->overlay);
44
45    // FIXME: if i don't do this, bg doesnt calc correctly. why?
46    evas_object_geometry_get(wd->base, NULL, NULL, &w, &h);
47    evas_object_resize(wd->base, w, h);
48 }
49
50 static void
51 _custom_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
52 {
53    Widget_Data *wd = data;
54    Evas_Coord bx = 0, by = 0, bw = 0, bh = 0;
55    Evas_Coord iw = 0, ih = 0, mw = -1, mh = -1;
56    Evas_Coord fx = 0, fy = 0, fw = 0, fh = 0;
57    Evas_Coord nx = 0, ny = 0, nw = 0, nh = 0;
58    const char *p;
59
60    if ((!wd->img) || (!wd->file)) return;
61    if (((p = strrchr(wd->file, '.'))) && (!strcasecmp(p, ".edj"))) return;
62
63    /* grab image size */
64    evas_object_image_size_get(wd->img, &iw, &ih);
65    if ((iw < 1) || (ih < 1)) return;
66
67    /* grab base object dimensions */
68    evas_object_geometry_get(wd->base, &bx, &by, &bw, &bh);
69
70    /* set some defaults */
71    nx = bx;
72    ny = by;
73    nw = bw;
74    nh = bh;
75
76    switch (wd->option)
77      {
78       case ELM_BG_OPTION_CENTER:
79          fw = nw = iw;
80          fh = nh = ih;
81          nx = ((bw - fw) / 2);
82          ny = ((bh - fh) / 2);
83          mw = iw;
84          mh = ih;
85          break;
86       case ELM_BG_OPTION_SCALE:
87          fw = bw;
88          fh = ((ih * fw) / iw);
89          if (fh < bh)
90            {
91               fh = bh;
92               fw = ((iw * fh) / ih);
93            }
94          fx = ((bw - fw) / 2);
95          fy = ((bh - fh) / 2);
96          break;
97       case ELM_BG_OPTION_TILE:
98          fw = iw;
99          fh = ih;
100          break;
101       case ELM_BG_OPTION_STRETCH:
102       default:
103          fw = bw;
104          fh = bh;
105          break;
106      }
107
108    evas_object_move(wd->img, nx, ny);
109    evas_object_resize(wd->img, nw, nh);
110    evas_object_image_fill_set(wd->img, fx, fy, fw, fh);
111
112    evas_object_size_hint_min_set(wd->img, mw, mh);
113    evas_object_size_hint_max_set(wd->img, mw, mh);
114 }
115
116 EAPI Evas_Object *
117 elm_bg_add(Evas_Object *parent)
118 {
119    Evas_Object *obj;
120    Evas *e;
121    Widget_Data *wd;
122
123    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
124
125    ELM_SET_WIDTYPE(widtype, "bg");
126    elm_widget_type_set(obj, "bg");
127    elm_widget_sub_object_add(parent, obj);
128    elm_widget_data_set(obj, wd);
129    elm_widget_del_hook_set(obj, _del_hook);
130    elm_widget_theme_hook_set(obj, _theme_hook);
131    elm_widget_can_focus_set(obj, EINA_FALSE);
132
133    wd->base = edje_object_add(e);
134    _elm_theme_object_set(obj, wd->base, "bg", "base", "default");
135    elm_widget_resize_object_set(obj, wd->base);
136
137    evas_object_event_callback_add(wd->base, EVAS_CALLBACK_RESIZE,
138                                   _custom_resize, wd);
139
140    wd->option = ELM_BG_OPTION_SCALE;
141    return obj;
142 }
143
144 EAPI void
145 elm_bg_file_set(Evas_Object *obj, const char *file, const char *group)
146 {
147    ELM_CHECK_WIDTYPE(obj, widtype);
148    Widget_Data *wd = elm_widget_data_get(obj);
149    const char *p;
150
151    if (wd->img)
152      {
153         evas_object_del(wd->img);
154         wd->img = NULL;
155      }
156    if (!file)
157      {
158         eina_stringshare_del(wd->file);
159         wd->file = NULL;
160         eina_stringshare_del(wd->group);
161         wd->group = NULL;
162         return;
163      }
164    eina_stringshare_replace(&wd->file, file);
165    eina_stringshare_replace(&wd->group, group);
166    if (((p = strrchr(file, '.'))) && (!strcasecmp(p, ".edj")))
167      {
168         wd->img = edje_object_add(evas_object_evas_get(wd->base));
169         edje_object_file_set(wd->img, file, group);
170      }
171    else
172      {
173         wd->img = evas_object_image_add(evas_object_evas_get(wd->base));
174         if ((wd->load_opts.w > 0) && (wd->load_opts.h > 0))
175           evas_object_image_load_size_set(wd->img, wd->load_opts.w, wd->load_opts.h);
176         evas_object_image_file_set(wd->img, file, group);
177      }
178    evas_object_repeat_events_set(wd->img, EINA_TRUE);
179    edje_object_part_swallow(wd->base, "elm.swallow.background", wd->img);
180    elm_widget_sub_object_add(obj, wd->img);
181    _custom_resize(wd, NULL, NULL, NULL);
182 }
183
184 EAPI void
185 elm_bg_file_get(const Evas_Object *obj, const char **file, const char **group)
186 {
187    ELM_CHECK_WIDTYPE(obj, widtype);
188    Widget_Data *wd = elm_widget_data_get(obj);
189    if (file) *file = wd->file;
190    if (group) *group = wd->group;
191 }
192
193 EAPI void
194 elm_bg_option_set(Evas_Object *obj, Elm_Bg_Option option)
195 {
196    ELM_CHECK_WIDTYPE(obj, widtype);
197    Widget_Data *wd;
198
199    wd = elm_widget_data_get(obj);
200    wd->option = option;
201    _custom_resize(wd, NULL, NULL, NULL);
202 }
203
204 EAPI Elm_Bg_Option
205 elm_bg_option_get(const Evas_Object *obj)
206 {
207    ELM_CHECK_WIDTYPE(obj, widtype) 0;
208    Widget_Data *wd;
209
210    wd = elm_widget_data_get(obj);
211    return wd->option;
212 }
213
214 EAPI void
215 elm_bg_color_set(Evas_Object *obj, int r, int g, int b)
216 {
217    ELM_CHECK_WIDTYPE(obj, widtype);
218    Widget_Data *wd;
219
220    wd = elm_widget_data_get(obj);
221    if (!wd->rect)
222      {
223         wd->rect = evas_object_rectangle_add(evas_object_evas_get(wd->base));
224         edje_object_part_swallow(wd->base, "elm.swallow.rectangle", wd->rect);
225         elm_widget_sub_object_add(obj, wd->rect);
226         _custom_resize(wd, NULL, NULL, NULL);
227      }
228    evas_object_color_set(wd->rect, r, g, b, 255);
229 }
230
231 EAPI void
232 elm_bg_color_get(const Evas_Object *obj, int *r, int *g, int *b)
233 {
234    ELM_CHECK_WIDTYPE(obj, widtype);
235    Widget_Data *wd;
236
237    wd = elm_widget_data_get(obj);
238    evas_object_color_get(wd->rect, r, g, b, NULL);
239 }
240
241 EAPI void
242 elm_bg_overlay_set(Evas_Object *obj, Evas_Object *overlay)
243 {
244    ELM_CHECK_WIDTYPE(obj, widtype);
245    Widget_Data *wd = elm_widget_data_get(obj);
246    if (!wd) return;
247    if (wd->overlay)
248      {
249         evas_object_del(wd->overlay);
250         wd->overlay = NULL;
251      }
252    if (overlay)
253      {
254         wd->overlay = overlay;
255         edje_object_part_swallow(wd->base, "elm.swallow.content", wd->overlay);
256         elm_widget_sub_object_add(obj, wd->overlay);
257      }
258
259    _custom_resize(wd, NULL, NULL, NULL);
260 }
261
262 EAPI Evas_Object *
263 elm_bg_overlay_get(const Evas_Object *obj)
264 {
265    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
266    Widget_Data *wd = elm_widget_data_get(obj);
267    if (!wd) return NULL;
268    return wd->overlay;
269 }
270
271 EAPI Evas_Object *
272 elm_bg_overlay_unset(Evas_Object *obj)
273 {
274    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
275    Widget_Data *wd = elm_widget_data_get(obj);
276    Evas_Object *overlay;
277    if (!wd) return NULL;
278    if (!wd->overlay) return NULL;
279    overlay = wd->overlay;
280    elm_widget_sub_object_del(obj, wd->overlay);
281    edje_object_part_unswallow(wd->base, wd->overlay);
282    wd->overlay = NULL;
283    _custom_resize(wd, NULL, NULL, NULL);
284    return overlay;
285 }
286
287 EAPI void
288 elm_bg_load_size_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
289 {
290    ELM_CHECK_WIDTYPE(obj, widtype);
291    Widget_Data *wd = elm_widget_data_get(obj);
292    const char *p;
293    if (!wd) return;
294    wd->load_opts.w = w;
295    wd->load_opts.h = h;
296    if (!wd->img) return;
297    if (!(((p = strrchr(wd->file, '.'))) && (!strcasecmp(p, ".edj"))))
298      evas_object_image_load_size_set(wd->img, w, h);
299 }
300