1 #include <Elementary.h>
5 * @defgroup Hover Hover
8 * A Hover object will over its @p parent object at the @p target
9 * location. Anything in the background will be given a darker
10 * coloring to indicate that the hover object is on top (at the
13 * @note The hover object will take up the entire space of @p target
17 typedef struct _Widget_Data Widget_Data;
18 typedef struct _Content_Info Content_Info;
21 # define MAX(a, b) (((a) > (b)) ? (a) : (b))
24 #define ELM_HOVER_PARTS_FOREACH unsigned int i = 0; \
25 for (i = 0; i < sizeof(wd->subs) / sizeof(wd->subs[0]); i++)
27 static const char *_directions[] = {
39 #define _HOV_LEFT (_directions[0])
40 #define _HOV_TOP_LEFT (_directions[1])
41 #define _HOV_TOP (_directions[2])
42 #define _HOV_TOP_RIGHT (_directions[2])
43 #define _HOV_RIGHT (_directions[4])
44 #define _HOV_BOTTOM_RIGHT (_directions[5])
45 #define _HOV_BOTTOM (_directions[6])
46 #define _HOV_BOTTOM_LEFT (_directions[7])
47 #define _HOV_MIDDLE (_directions[8])
57 Evas_Object *hov, *cov;
58 Evas_Object *offset, *size;
59 Evas_Object *parent, *target;
61 Content_Info subs[sizeof(_directions)/sizeof(_directions[0])];
64 static const char *widtype = NULL;
65 static void _del_pre_hook(Evas_Object *obj);
66 static void _del_hook(Evas_Object *obj);
67 static void _theme_hook(Evas_Object *obj);
68 static void _sizing_eval(Evas_Object *obj);
69 static void _reval_content(Evas_Object *obj);
70 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
71 static void _hov_show_do(Evas_Object *obj);
72 static void _hov_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
73 static void _hov_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
74 static void _hov_show(void *data, Evas *e, Evas_Object *obj, void *event_info);
75 static void _hov_hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
76 static void _on_focus_hook(void *data, Evas_Object *obj);
77 static void _elm_hover_sub_obj_placement_eval_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
78 static void _elm_hover_sub_obj_placement_eval(Evas_Object *obj);
80 static const char SIG_CLICKED[] = "clicked";
81 static const char SIG_SMART_LOCATION_CHANGED[] = "smart,changed";
82 static const Evas_Smart_Cb_Description _signals[] = {
84 {SIG_SMART_LOCATION_CHANGED, ""},
89 _del_pre_hook(Evas_Object *obj)
91 Widget_Data *wd = elm_widget_data_get(obj);
95 if (evas_object_visible_get(obj))
96 evas_object_smart_callback_call(obj, SIG_CLICKED, NULL);
97 elm_hover_target_set(obj, NULL);
98 elm_hover_parent_set(obj, NULL);
99 evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_MOVE, _hov_move, obj);
100 evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_RESIZE, _hov_resize, obj);
101 evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_SHOW, _hov_show, obj);
102 evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_HIDE, _hov_hide, obj);
106 _del_hook(Evas_Object *obj)
108 Widget_Data *wd = elm_widget_data_get(obj);
114 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
116 Widget_Data *wd = elm_widget_data_get(obj);
118 if (elm_widget_focus_get(obj))
120 edje_object_signal_emit(wd->cov, "elm,action,focus", "elm");
121 evas_object_focus_set(wd->cov, EINA_TRUE);
125 edje_object_signal_emit(wd->cov, "elm,action,unfocus", "elm");
126 evas_object_focus_set(wd->cov, EINA_FALSE);
131 _theme_hook(Evas_Object *obj)
133 Widget_Data *wd = elm_widget_data_get(obj);
135 // FIXME: hover contents doesn't seem to propagate resizes properly
136 _elm_theme_object_set(obj, wd->cov, "hover", "base", elm_widget_style_get(obj));
137 edje_object_scale_set(wd->cov, elm_widget_scale_get(obj) *
141 _elm_hover_sub_obj_placement_eval(obj);
145 if (evas_object_visible_get(wd->cov)) _hov_show_do(obj);
149 _signal_emit_hook(Evas_Object *obj, const char *emission, const char *source)
153 wd = elm_widget_data_get(obj);
157 edje_object_signal_emit(wd->cov, emission, source);
161 _signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
165 wd = elm_widget_data_get(obj);
169 edje_object_signal_callback_add(wd->hov, emission, source, func_cb, data);
173 _signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
177 wd = elm_widget_data_get(obj);
179 edje_object_signal_callback_del_full(wd->hov, emission, source, func_cb,
184 _elm_hover_left_space_calc(Widget_Data *wd, Evas_Coord *spc_l, Evas_Coord *spc_t, Evas_Coord *spc_r, Evas_Coord *spc_b)
186 Evas_Coord x = 0, y = 0, w = 0, h = 0, x2 = 0, y2 = 0, w2 = 0, h2 = 0;
189 evas_object_geometry_get(wd->parent, &x, &y, &w, &h);
191 evas_object_geometry_get(wd->target, &x2, &y2, &w2, &h2);
194 *spc_r = (x + w) - (x2 + w2);
201 *spc_b = (y + h) - (y2 + h2);
209 _sizing_eval(Evas_Object *obj)
211 Widget_Data *wd = elm_widget_data_get(obj);
212 Evas_Coord x = 0, y = 0, w = 0, h = 0, x2 = 0, y2 = 0, w2 = 0, h2 = 0;
214 if (wd->parent) evas_object_geometry_get(wd->parent, &x, &y, &w, &h);
215 if (wd->hov) evas_object_geometry_get(wd->hov, &x2, &y2, &w2, &h2);
216 evas_object_move(wd->cov, x, y);
217 evas_object_resize(wd->cov, w, h);
218 evas_object_size_hint_min_set(wd->offset, x2 - x, y2 - y);
219 evas_object_size_hint_min_set(wd->size, w2, h2);
220 edje_object_part_swallow(wd->cov, "elm.swallow.offset", wd->offset);
221 edje_object_part_swallow(wd->cov, "elm.swallow.size", wd->size);
225 _reval_content(Evas_Object *obj)
227 Widget_Data *wd = elm_widget_data_get(obj);
231 ELM_HOVER_PARTS_FOREACH
234 snprintf(buf, sizeof(buf), "elm.swallow.slot.%s", wd->subs[i].swallow);
235 edje_object_part_swallow(wd->cov, buf, wd->subs[i].obj);
240 _elm_hover_smart_content_location_get(Widget_Data *wd, Evas_Coord spc_l, Evas_Coord spc_t, Evas_Coord spc_r, Evas_Coord spc_b)
242 Evas_Coord c_w = 0, c_h = 0, mid_w, mid_h;
245 evas_object_size_hint_min_get(wd->smt_sub, &c_w, &c_h);
252 max = MAX(spc_t, spc_r);
253 max = MAX(max, spc_b);
258 return _HOV_TOP_RIGHT;
266 return _HOV_BOTTOM_RIGHT;
267 else if (mid_h > spc_b)
268 return _HOV_TOP_RIGHT;
274 return _HOV_BOTTOM_RIGHT;
279 max = MAX(spc_t, spc_l);
280 max = MAX(max, spc_b);
285 return _HOV_TOP_LEFT;
293 return _HOV_BOTTOM_LEFT;
294 else if (mid_h > spc_b)
295 return _HOV_TOP_LEFT;
301 return _HOV_BOTTOM_LEFT;
307 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
313 wd = elm_widget_data_get(obj);
319 if (wd->smt_sub == sub)
324 ELM_HOVER_PARTS_FOREACH
326 if (wd->subs[i].obj == sub)
328 wd->subs[i].obj = NULL;
336 _hov_show_do(Evas_Object *obj)
338 Widget_Data *wd = elm_widget_data_get(obj);
344 evas_object_show(wd->cov);
345 edje_object_signal_emit(wd->cov, "elm,action,show", "elm");
348 ELM_HOVER_PARTS_FOREACH
354 snprintf(buf, sizeof(buf), "elm,action,slot,%s,show",
355 wd->subs[i].swallow);
356 edje_object_signal_emit(wd->cov, buf, "elm");
362 _hov_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
368 _hov_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
374 _hov_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
380 _hov_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
382 Widget_Data *wd = elm_widget_data_get(data);
386 edje_object_signal_emit(wd->cov, "elm,action,hide", "elm");
387 evas_object_hide(wd->cov);
390 ELM_HOVER_PARTS_FOREACH
396 snprintf(buf, sizeof(buf), "elm,action,slot,%s,hide",
397 wd->subs[i].swallow);
398 edje_object_signal_emit(wd->cov, buf, "elm");
404 _target_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
406 Widget_Data *wd = elm_widget_data_get(data);
412 _target_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
414 Widget_Data *wd = elm_widget_data_get(data);
419 _elm_hover_sub_obj_placement_eval(data);
423 _signal_dismiss(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
425 Widget_Data *wd = elm_widget_data_get(data);
427 evas_object_hide(data);
428 evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
432 _parent_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
438 _parent_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
444 _parent_show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
449 _parent_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
451 Widget_Data *wd = elm_widget_data_get(data);
453 evas_object_hide(wd->cov);
457 _parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
459 Widget_Data *wd = elm_widget_data_get(data);
461 elm_hover_parent_set(data, NULL);
466 * Adds a hover object to @p parent
468 * @param parent The parent object
469 * @return The hover object or NULL if one could not be created
474 elm_hover_add(Evas_Object *parent)
480 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
482 wd = ELM_NEW(Widget_Data);
484 ELM_HOVER_PARTS_FOREACH
485 wd->subs[i].swallow = _directions[i];
487 e = evas_object_evas_get(parent);
489 obj = elm_widget_add(e);
490 ELM_SET_WIDTYPE(widtype, "hover");
491 elm_widget_type_set(obj, "hover");
492 elm_widget_sub_object_add(parent, obj);
493 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
494 elm_widget_data_set(obj, wd);
495 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
496 elm_widget_theme_hook_set(obj, _theme_hook);
497 elm_widget_del_hook_set(obj, _del_hook);
498 elm_widget_can_focus_set(obj, EINA_TRUE);
499 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
500 elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook);
501 elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook);
503 wd->hov = evas_object_rectangle_add(e);
504 evas_object_pass_events_set(wd->hov, EINA_TRUE);
505 evas_object_color_set(wd->hov, 0, 0, 0, 0);
506 elm_widget_resize_object_set(obj, wd->hov);
507 evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_MOVE, _hov_move, obj);
508 evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_RESIZE, _hov_resize, obj);
509 evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_SHOW, _hov_show, obj);
510 evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_HIDE, _hov_hide, obj);
512 wd->cov = edje_object_add(e);
513 _elm_theme_object_set(obj, wd->cov, "hover", "base", "default");
514 elm_widget_sub_object_add(obj, wd->cov);
515 edje_object_signal_callback_add(wd->cov, "elm,action,dismiss", "",
516 _signal_dismiss, obj);
518 wd->offset = evas_object_rectangle_add(e);
519 evas_object_pass_events_set(wd->offset, EINA_TRUE);
520 evas_object_color_set(wd->offset, 0, 0, 0, 0);
521 elm_widget_sub_object_add(obj, wd->offset);
523 wd->size = evas_object_rectangle_add(e);
524 evas_object_pass_events_set(wd->size, EINA_TRUE);
525 evas_object_color_set(wd->size, 0, 0, 0, 0);
526 elm_widget_sub_object_add(obj, wd->size);
528 edje_object_part_swallow(wd->cov, "elm.swallow.offset", wd->offset);
529 edje_object_part_swallow(wd->cov, "elm.swallow.size", wd->size);
531 evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
533 elm_hover_parent_set(obj, parent);
534 evas_object_smart_callbacks_descriptions_set(obj, _signals);
541 * Sets the target object for the hover.
543 * @param obj The hover object
544 * @param target The object to center the hover onto. The hover
545 * will take up the entire space that the target object fills.
550 elm_hover_target_set(Evas_Object *obj, Evas_Object *target)
552 ELM_CHECK_WIDTYPE(obj, widtype);
553 Widget_Data *wd = elm_widget_data_get(obj);
557 evas_object_event_callback_del_full(wd->target, EVAS_CALLBACK_DEL,
559 evas_object_event_callback_del_full(wd->target, EVAS_CALLBACK_MOVE,
565 evas_object_event_callback_add(wd->target, EVAS_CALLBACK_DEL,
567 evas_object_event_callback_add(wd->target, EVAS_CALLBACK_MOVE,
569 elm_widget_hover_object_set(target, obj);
576 * Sets the parent object for the hover.
578 * @param obj The hover object
579 * @param parent The object to locate the hover over.
584 elm_hover_parent_set(Evas_Object *obj, Evas_Object *parent)
586 ELM_CHECK_WIDTYPE(obj, widtype);
587 Widget_Data *wd = elm_widget_data_get(obj);
591 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_MOVE,
593 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE,
594 _parent_resize, obj);
595 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_SHOW,
597 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_HIDE,
599 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_DEL,
605 evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_MOVE,
607 evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_RESIZE,
608 _parent_resize, obj);
609 evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_SHOW,
611 evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_HIDE,
613 evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_DEL,
615 // elm_widget_sub_object_add(parent, obj);
621 * Gets the target object for the hover.
623 * @param obj The hover object
624 * @return The target object of the hover.
629 elm_hover_target_get(const Evas_Object *obj)
631 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
632 Widget_Data *wd = elm_widget_data_get(obj);
633 if (!wd) return NULL;
639 * Gets the parent object for the hover.
641 * @param obj The hover object
642 * @return The parent object to locate the hover over.
647 elm_hover_parent_get(const Evas_Object *obj)
649 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
650 Widget_Data *wd = elm_widget_data_get(obj);
651 if (!wd) return NULL;
657 _elm_hover_subs_del(Widget_Data *wd)
659 ELM_HOVER_PARTS_FOREACH
663 evas_object_del(wd->subs[i].obj);
664 wd->subs[i].obj = NULL;
670 _elm_hover_sub_obj_placement_eval(Evas_Object *obj)
672 Evas_Coord spc_l, spc_r, spc_t, spc_b;
673 const char *smart_dir;
677 wd = elm_widget_data_get(obj);
681 _elm_hover_left_space_calc(wd, &spc_l, &spc_t, &spc_r, &spc_b);
683 edje_object_part_unswallow(wd->cov, wd->smt_sub);
685 smart_dir = _elm_hover_smart_content_location_get(wd, spc_l, spc_t, spc_r,
687 evas_object_smart_callback_call(obj, SIG_SMART_LOCATION_CHANGED,
690 snprintf(buf, sizeof(buf), "elm.swallow.slot.%s", smart_dir);
691 edje_object_part_swallow(wd->cov, buf, wd->smt_sub);
695 _elm_hover_sub_obj_placement_eval_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
697 _elm_hover_sub_obj_placement_eval(data);
701 * Sets the content of the hover object and the direction in which
704 * Once the content object is set for a given direction, a previously
705 * set one (on the same direction) will be deleted. If you want to
706 * keep that old content object, use the elm_hover_content_unset()
709 * @param obj The hover object
710 * @param swallow The direction that the object will be displayed
711 * at. Accepted values are "left", "top-left", "top", "top-right",
712 * "right", "bottom-right", "bottom", "bottom-left", "middle" and
714 * @param content The content to place at @p swallow
716 * All directions may have contents at the same time, except for
717 * "smart". This is a special placement hint and its use case
718 * independs of the calculations coming from
719 * elm_hover_best_content_location_get(). Its use is for cases when
720 * one desires only one hover content, but with a dinamic special
721 * placement within the hover area. The content's geometry, whenever
722 * it changes, will be used to decide on a best location not
723 * extrapolating the hover's parent object view to show it in (still
724 * being the hover's target determinant of its medium part -- move and
725 * resize it to simulate finger sizes, for example). If one of the
726 * directions other than "smart" are used, a previously content set
727 * using it will be deleted, and vice-versa.
732 elm_hover_content_set(Evas_Object *obj, const char *swallow, Evas_Object *content)
734 ELM_CHECK_WIDTYPE(obj, widtype);
738 wd = elm_widget_data_get(obj);
742 if (!strcmp(swallow, "smart"))
744 if (wd->smt_sub != content)
746 _elm_hover_subs_del(wd);
747 wd->smt_sub = content;
752 elm_widget_sub_object_add(obj, content);
753 evas_object_event_callback_add(wd->smt_sub,
754 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
755 _elm_hover_sub_obj_placement_eval_cb,
758 _elm_hover_sub_obj_placement_eval(obj);
766 evas_object_del(wd->smt_sub);
770 ELM_HOVER_PARTS_FOREACH
772 if (!strcmp(swallow, wd->subs[i].swallow))
774 if (content == wd->subs[i].obj)
776 evas_object_del(wd->subs[i].obj);
777 wd->subs[i].obj = NULL;
783 snprintf(buf, sizeof(buf), "elm.swallow.slot.%s", swallow);
784 elm_widget_sub_object_add(obj, content);
785 edje_object_part_swallow(wd->cov, buf, content);
786 wd->subs[i].obj = content;
797 * Get the content of the hover object, in a given direction.
799 * Return the content object which was set for this widget in the
802 * @param obj The hover object
803 * @param swallow The direction that the object was display at.
804 * @return The content that was being used
806 * @note See elm_hover_content_set() for more information.
811 elm_hover_content_get(const Evas_Object *obj, const char *swallow)
813 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
817 wd = elm_widget_data_get(obj);
821 if (!strcmp(swallow, "smart"))
824 ELM_HOVER_PARTS_FOREACH
825 if (!strcmp(swallow, wd->subs[i].swallow))
826 return wd->subs[i].obj;
832 _elm_hover_sub_obj_unparent(Evas_Object *obj)
836 wd = elm_widget_data_get(obj);
838 elm_widget_sub_object_del(obj, wd->smt_sub);
839 evas_object_event_callback_del_full(wd->smt_sub,
840 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
841 _elm_hover_sub_obj_placement_eval_cb,
843 edje_object_part_unswallow(wd->cov, wd->smt_sub);
848 * Unset the content of the hover object, in a given direction.
850 * Unparent and return the content object set at that direction.
852 * @param obj The hover object
853 * @param swallow The direction that the object was display at.
854 * @return The content that was being used.
856 * @note See elm_hover_content_set() for more information.
861 elm_hover_content_unset(Evas_Object *obj, const char *swallow)
863 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
867 wd = elm_widget_data_get(obj);
871 if (!strcmp(swallow, "smart"))
873 Evas_Object *content;
878 content = wd->smt_sub;
879 _elm_hover_sub_obj_unparent(obj);
883 ELM_HOVER_PARTS_FOREACH
885 if (!strcmp(swallow, wd->subs[i].swallow))
887 Evas_Object *content;
889 if (!wd->subs[i].obj)
892 content = wd->subs[i].obj;
893 elm_widget_sub_object_del(obj, wd->subs[i].obj);
894 edje_object_part_unswallow(wd->cov, wd->subs[i].obj);
895 wd->subs[i].obj = NULL;
905 * Returns the best swallow location for content in the hover.
907 * @param obj The hover object
908 * @param pref_axis The preferred orientation axis for the hover object to use
909 * @return The edje location to place content into the hover or @c
912 * @p pref_axis may be one of
914 * - @c ELM_HOVER_AXIS_NONE -- no prefered orientation
915 * - @c ELM_HOVER_AXIS_HORIZONTAL -- horizontal
916 * - @c ELM_HOVER_AXIS_VERTICAL -- vertical
917 * - @c ELM_HOVER_AXIS_BOTH -- both
920 * See also elm_hover_content_set().
925 elm_hover_best_content_location_get(const Evas_Object *obj, Elm_Hover_Axis pref_axis)
927 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
929 Evas_Coord spc_l, spc_r, spc_t, spc_b;
932 wd = elm_widget_data_get(obj);
936 _elm_hover_left_space_calc(wd, &spc_l, &spc_t, &spc_r, &spc_b);
938 if (pref_axis == ELM_HOVER_AXIS_HORIZONTAL)
940 if (spc_l < spc_r) return _HOV_RIGHT;
941 else return _HOV_LEFT;
943 else if (pref_axis == ELM_HOVER_AXIS_VERTICAL)
945 if (spc_t < spc_b) return _HOV_BOTTOM;
946 else return _HOV_TOP;
951 if (spc_t > spc_r) return _HOV_TOP;
952 else if (spc_b > spc_r) return _HOV_BOTTOM;
955 if (spc_t > spc_r) return _HOV_TOP;
956 else if (spc_b > spc_r) return _HOV_BOTTOM;