1 #include <Elementary.h>
5 * @defgroup Conformant Conformant
7 * The aim is to provide a widget that can be used in elementary apps to
8 * account for space taken up by the indicator & softkey windows when running
9 * the illume2 module of E17.
12 typedef struct _Widget_Data Widget_Data;
16 Evas_Object *shelf, *panel;
18 Ecore_Event_Handler *prop_hdl;
21 Ecore_Animator *animator; // animaton timer
22 double start; // time started
23 Evas_Coord auto_x, auto_y; // desired delta
24 Evas_Coord x, y; // current delta
28 /* local function prototypes */
29 static const char *widtype = NULL;
30 static void _del_hook(Evas_Object *obj);
31 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
32 static void _theme_hook(Evas_Object *obj);
33 static void _sizing_eval(Evas_Object *obj);
34 static Eina_Bool _prop_change(void *data, int type, void *event);
38 _del_hook(Evas_Object *obj)
40 Widget_Data *wd = elm_widget_data_get(obj);
43 if (wd->prop_hdl) ecore_event_handler_del(wd->prop_hdl);
48 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
50 Widget_Data *wd = elm_widget_data_get(obj);
53 edje_object_mirrored_set(wd->base, rtl);
57 _theme_hook(Evas_Object *obj)
59 Widget_Data *wd = elm_widget_data_get(obj);
62 _elm_widget_mirrored_reload(obj);
63 _mirrored_set(obj, elm_widget_mirrored_get(obj));
64 _elm_theme_object_set(obj, wd->base, "conformant", "base",
65 elm_widget_style_get(obj));
68 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->content);
69 edje_object_scale_set(wd->base, elm_widget_scale_get(obj)
70 * _elm_config->scale);
75 _sizing_eval(Evas_Object *obj)
77 Widget_Data *wd = elm_widget_data_get(obj);
78 Evas_Coord mw = -1, mh = -1;
81 edje_object_size_min_calc(wd->base, &mw, &mh);
82 evas_object_size_hint_min_set(obj, mw, mh);
83 evas_object_size_hint_max_set(obj, -1, -1);
87 _changed_size_hints(void *data, Evas *e __UNUSED__,
88 Evas_Object *obj __UNUSED__,
89 void *event_info __UNUSED__)
91 Widget_Data *wd = elm_widget_data_get(data);
98 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
100 Widget_Data *wd = elm_widget_data_get(obj);
101 Evas_Object *sub = event_info;
104 if (sub == wd->content)
106 evas_object_event_callback_del_full(sub,
107 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
108 _changed_size_hints, obj);
114 /* unused now - but meant to be for making sure the focused widget is always
115 * visible when the vkbd comes and goes by moving the conformant obj (and thus
116 * its children) to show the focused widget (and if focus changes follow)
119 _focus_object_get(const Evas_Object *obj)
121 Evas_Object *win, *foc;
123 win = elm_widget_top_get(obj);
124 if (!win) return NULL;
125 foc = elm_widget_top_get(win);
129 _focus_object_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
131 evas_object_geometry_get(obj, x, y, w, h);
135 _focus_change_del(void *data, Evas_Object *obj, void *event_info)
137 // called from toplevel when the focused window shanges
141 _autoscroll_move(Evas_Object *obj)
143 // move conformant edje by delta to show focused widget
147 _autoscroll_mode_enable(Evas_Object *obj)
149 // called when autoscroll mode should be on - content area smaller than
151 // 1. get focused object
152 // 2. if not in visible conformant area calculate delta needed to
154 // 3. store delta and call _autoscroll_move() which either asanimates
155 // or jumps right there
159 _autoscroll_mode_disable(Evas_Object *obj)
161 // called when autoscroll mode should be off - set delta to 0 and
162 // call _autoscroll_move()
167 _prop_change(void *data, int type __UNUSED__, void *event)
169 #ifdef HAVE_ELEMENTARY_X
170 Ecore_X_Event_Window_Property *ev;
171 Widget_Data *wd = elm_widget_data_get(data);
173 if (!wd) return ECORE_CALLBACK_PASS_ON;
175 if (ev->atom == ECORE_X_ATOM_E_ILLUME_ZONE)
180 zone = ecore_x_e_illume_zone_get(ev->win);
181 ecore_x_e_illume_indicator_geometry_get(zone, NULL, NULL, NULL, &sh);
183 evas_object_size_hint_min_set(wd->shelf, -1, sh);
184 evas_object_size_hint_max_set(wd->shelf, -1, sh);
186 ecore_x_e_illume_softkey_geometry_get(zone, NULL, NULL, NULL, &sh);
188 evas_object_size_hint_min_set(wd->panel, -1, sh);
189 evas_object_size_hint_max_set(wd->panel, -1, sh);
191 else if (ev->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY)
196 zone = ecore_x_e_illume_zone_get(ev->win);
197 ecore_x_e_illume_indicator_geometry_get(zone, NULL, NULL, NULL, &sh);
199 evas_object_size_hint_min_set(wd->shelf, -1, sh);
200 evas_object_size_hint_max_set(wd->shelf, -1, sh);
202 else if (ev->atom == ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY)
207 zone = ecore_x_e_illume_zone_get(ev->win);
208 ecore_x_e_illume_softkey_geometry_get(zone, NULL, NULL, NULL, &sh);
210 evas_object_size_hint_min_set(wd->panel, -1, sh);
211 evas_object_size_hint_max_set(wd->panel, -1, sh);
213 else if (ev->atom == ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY)
218 printf("Keyboard Geometry Changed\n");
219 zone = ecore_x_e_illume_zone_get(ev->win);
220 ecore_x_e_illume_keyboard_geometry_get(zone, NULL, &ky, NULL, NULL);
221 printf("\tGeom: %d\n", ky);
225 return ECORE_CALLBACK_PASS_ON;
229 * Add a new Conformant object
231 * @param parent The parent object
232 * @return The new conformant object or NULL if it cannot be created
234 * @ingroup Conformant
237 elm_conformant_add(Evas_Object *parent)
243 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
245 ELM_SET_WIDTYPE(widtype, "conformant");
246 elm_widget_type_set(obj, "conformant");
247 elm_widget_sub_object_add(parent, obj);
248 elm_widget_data_set(obj, wd);
249 elm_widget_del_hook_set(obj, _del_hook);
250 elm_widget_theme_hook_set(obj, _theme_hook);
251 elm_widget_can_focus_set(obj, EINA_FALSE);
253 wd->base = edje_object_add(e);
254 _elm_theme_object_set(obj, wd->base, "conformant", "base", "default");
255 elm_widget_resize_object_set(obj, wd->base);
257 #ifdef HAVE_ELEMENTARY_X
258 Evas_Object *top = elm_widget_top_get(obj);
259 Ecore_X_Window zone, xwin = elm_win_xwindow_get(top);
261 if ((xwin) && (!elm_win_inlined_image_object_get(top)))
265 zone = ecore_x_e_illume_zone_get(xwin);
267 ecore_x_e_illume_indicator_geometry_get(zone, NULL, NULL, NULL, &sh);
269 wd->shelf = evas_object_rectangle_add(e);
270 evas_object_color_set(wd->shelf, 0, 0, 0, 0);
271 evas_object_size_hint_min_set(wd->shelf, -1, sh);
272 evas_object_size_hint_max_set(wd->shelf, -1, sh);
273 edje_object_part_swallow(wd->base, "elm.swallow.shelf", wd->shelf);
276 ecore_x_e_illume_softkey_geometry_get(zone, NULL, NULL, NULL, &sh);
278 wd->panel = evas_object_rectangle_add(e);
279 evas_object_color_set(wd->panel, 0, 0, 0, 0);
280 evas_object_size_hint_min_set(wd->panel, -1, sh);
281 evas_object_size_hint_max_set(wd->panel, -1, sh);
282 edje_object_part_swallow(wd->base, "elm.swallow.panel", wd->panel);
284 wd->prop_hdl = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY,
287 // FIXME: get kbd region prop
290 evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
292 _mirrored_set(obj, elm_widget_mirrored_get(obj));
298 * Set the content of the conformant widget
300 * Once the content object is set, a previously set one will be deleted.
301 * If you want to keep that old content object, use the
302 * elm_conformat_content_unset() function.
304 * @param obj The conformant object
305 * @return The content that was being used
307 * @ingroup Conformant
310 elm_conformant_content_set(Evas_Object *obj, Evas_Object *content)
312 ELM_CHECK_WIDTYPE(obj, widtype);
313 Widget_Data *wd = elm_widget_data_get(obj);
316 if (wd->content == content) return;
317 if (wd->content) evas_object_del(wd->content);
318 wd->content = content;
321 elm_widget_sub_object_add(obj, content);
322 evas_object_event_callback_add(content,
323 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
324 _changed_size_hints, obj);
325 edje_object_part_swallow(wd->base, "elm.swallow.content", content);
331 * Get the content of the conformant widget
333 * Return the content object which is set for this widget;
335 * @param obj The conformant object
336 * @return The content that is being used
338 * @ingroup Conformant
341 elm_conformant_content_get(const Evas_Object *obj)
343 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
344 Widget_Data *wd = elm_widget_data_get(obj);
346 if (!wd) return NULL;
351 * Unset the content of the conformant widget
353 * Unparent and return the content object which was set for this widget;
355 * @param obj The conformant object
356 * @return The content that was being used
358 * @ingroup Conformant
361 elm_conformant_content_unset(Evas_Object *obj)
363 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
364 Widget_Data *wd = elm_widget_data_get(obj);
365 Evas_Object *content;
367 if (!wd) return NULL;
368 if (!wd->content) return NULL;
369 content = wd->content;
370 elm_widget_sub_object_del(obj, wd->content);
371 edje_object_part_unswallow(wd->base, wd->content);