summaryrefslogtreecommitdiff
path: root/src/lib/elementary/efl_ui_spotlight_icon_indicator.c
blob: 731a9a9429e3460cdee3713a265fb65314453aa2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif

#define EFL_PACK_LAYOUT_PROTECTED

#include <Elementary.h>
#include "elm_priv.h"

typedef struct {
   Efl_Ui_Box *indicator;
   Efl_Ui_Spotlight_Container *container;
   Efl_Canvas_Layout *layout;
   double last_position;
   Eina_Size2D min, max;
} Efl_Ui_Spotlight_Icon_Indicator_Data;

static void
_flush_state(Eo *item, double val)
{
   Eina_Value v = eina_value_double_init(val);

    efl_layout_signal_message_send(item, 1, v);
}

static void
_add_item(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Icon_Indicator_Data *pd)
{
   Efl_Canvas_Layout *item;

   item = efl_add(EFL_CANVAS_LAYOUT_CLASS, pd->indicator);
   elm_widget_theme_object_set(pd->indicator, item,
                               "spotlight", "indicator", "default");
   efl_gfx_hint_align_set(item, 0.5, 0.5);
   efl_gfx_hint_weight_set(item, 0, 0);
   efl_gfx_hint_fill_set(item, 0, 0);
   efl_gfx_hint_size_min_set(item,  efl_layout_calc_size_min(item, EINA_SIZE2D(0, 0)));
   efl_pack_end(pd->indicator, item);
   _flush_state(item, 0.0);
}

static void
_flush_position(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Icon_Indicator_Data *pd)
{
   int next = -1, closer;
   double closer_val;

   for (int i = 0; i < efl_content_count(pd->indicator); ++i)
     {
        _flush_state(efl_pack_content_get(pd->indicator, i), 0.0f);
     }

   closer = MIN(MAX(round(pd->last_position), 0), efl_content_count(pd->container) - 1);
   closer_val = fabs(1.0f - fabs(closer - pd->last_position));

   _flush_state(efl_pack_content_get(pd->indicator, closer), closer_val);

   if (pd->last_position > closer)
     next = closer + 1;
   else if (pd->last_position < closer)
     next = closer - 1;
   else
     {
        next = closer + 1;
        if (next < efl_content_count(pd->container))
          _flush_state(efl_pack_content_get(pd->indicator, next), fabs(1.0f - fabs((next - pd->last_position))));
        next = closer - 1;
        if (next >= 0)
          _flush_state(efl_pack_content_get(pd->indicator, next), fabs(1.0f - fabs((next - pd->last_position))));
     }

   if (next >= 0 && next < efl_content_count(pd->container))
     _flush_state(efl_pack_content_get(pd->indicator, next), fabs(1.0f - fabs((next - pd->last_position))));
}

static void
_resize_cb(void *data, const Efl_Event *ev)
{
   efl_gfx_entity_size_set(data, efl_gfx_entity_size_get(ev->object));
}

static void
_position_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
   efl_gfx_entity_position_set(data, efl_gfx_entity_position_get(ev->object));
}

EFL_CALLBACKS_ARRAY_DEFINE(spotlight_resized,
  {EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb},
  {EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _position_cb},
)

EOLIAN static void
_efl_ui_spotlight_icon_indicator_efl_ui_spotlight_indicator_bind(Eo *obj, Efl_Ui_Spotlight_Icon_Indicator_Data *pd, Efl_Ui_Spotlight_Container *spotlight)
{
   if (spotlight)
     {
        pd->container = spotlight;
        efl_event_callback_array_add(pd->container, spotlight_resized(), pd->layout);
        pd->layout = efl_add(EFL_CANVAS_LAYOUT_CLASS, pd->container);

        if (elm_widget_theme_object_set(pd->container, pd->layout,
                                       "spotlight",
                                       "indicator_holder",
                                       elm_widget_theme_style_get(pd->container)) == EFL_UI_THEME_APPLY_ERROR_GENERIC)
          CRI("Failed to set layout!");
        efl_canvas_group_member_add(pd->container, pd->layout);
        efl_gfx_entity_geometry_set(pd->layout, efl_gfx_entity_geometry_get(pd->container));

        pd->indicator = efl_add(EFL_UI_BOX_CLASS, pd->container);
        efl_ui_widget_internal_set(pd->indicator, EINA_TRUE);
        efl_ui_layout_orientation_set(pd->indicator, EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL);
        efl_content_set(efl_part(pd->layout, "efl.indicator"), pd->indicator);

        for (int i = 0; i < efl_content_count(pd->container); ++i)
          {
             Eo *subobj = efl_pack_content_get(pd->container, i);
             _add_item(obj, pd);
             efl_gfx_stack_above(pd->layout, subobj);
          }
     }
}

EOLIAN static void
_efl_ui_spotlight_icon_indicator_efl_ui_spotlight_indicator_content_add(Eo *obj, Efl_Ui_Spotlight_Icon_Indicator_Data *pd, Efl_Gfx_Entity *subobj EINA_UNUSED, int index EINA_UNUSED)
{
   _add_item(obj, pd);
   _flush_position(obj, pd);
   efl_gfx_stack_above(pd->layout, subobj);
}

EOLIAN static void
_efl_ui_spotlight_icon_indicator_efl_ui_spotlight_indicator_content_del(Eo *obj, Efl_Ui_Spotlight_Icon_Indicator_Data *pd, Efl_Gfx_Entity *subobj EINA_UNUSED, int index EINA_UNUSED)
{
   efl_del(efl_pack_content_get(pd->indicator, 0));
   _flush_position(obj, pd);
}

EOLIAN static void
_efl_ui_spotlight_icon_indicator_efl_ui_spotlight_indicator_position_update(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Icon_Indicator_Data *pd, double position)
{
   pd->last_position = position;
   _flush_position(obj, pd);
}

EOLIAN static void
_efl_ui_spotlight_icon_indicator_efl_object_destructor(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Icon_Indicator_Data *pd)
{
   if (pd->layout)
     efl_del(pd->layout);
   if (pd->indicator)
     efl_del(pd->indicator);

   efl_destructor(efl_super(obj, EFL_UI_SPOTLIGHT_ICON_INDICATOR_CLASS));
}


#include "efl_ui_spotlight_icon_indicator.eo.c"