summaryrefslogtreecommitdiff
path: root/src/lib/elementary/efl_ui_relative_container_private.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/elementary/efl_ui_relative_container_private.h')
-rw-r--r--src/lib/elementary/efl_ui_relative_container_private.h140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/lib/elementary/efl_ui_relative_container_private.h b/src/lib/elementary/efl_ui_relative_container_private.h
new file mode 100644
index 0000000..43ea3c2
--- /dev/null
+++ b/src/lib/elementary/efl_ui_relative_container_private.h
@@ -0,0 +1,140 @@
1#ifndef EFL_UI_RELATIVE_CONTAINER_PRIVATE_H
2#define EFL_UI_RELATIVE_CONTAINER_PRIVATE_H
3
4#ifdef HAVE_CONFIG_H
5# include "elementary_config.h"
6#endif
7
8#define EFL_PACK_LAYOUT_PROTECTED
9
10#include <Elementary.h>
11#include "elm_priv.h"
12
13typedef enum _Efl_Ui_Relative_Container_Calc_State
14{
15 RELATIVE_CALC_NONE,
16 RELATIVE_CALC_DONE,
17 RELATIVE_CALC_ON
18} Efl_Ui_Relative_Container_Calc_State;
19
20typedef struct _Efl_Ui_Relative_Container_Data Efl_Ui_Relative_Container_Data;
21typedef struct _Efl_Ui_Relative_Container_Child Efl_Ui_Relative_Container_Child;
22typedef struct _Efl_Ui_Relative_Container_Calc Efl_Ui_Relative_Container_Calc;
23typedef struct _Efl_Ui_Relative_Container_Relation Efl_Ui_Relative_Container_Relation;
24typedef struct _Efl_Ui_Relative_Container_Content_Iterator Efl_Ui_Relative_Container_Content_Iterator;
25
26struct _Efl_Ui_Relative_Container_Calc
27{
28 EINA_INLIST;
29
30 int max[2];
31 int min[2];
32 int aspect[2];
33 int margin[4];
34 Efl_Gfx_Hint_Aspect aspect_type;
35 Eina_Bool fill[2];
36 double weight[2];
37 double align[2];
38 double comp_factor;
39 /* m0 is static min size which is added to the other children min size.
40 * only if both (target, relative)[0] and (target, relative)[1] are same,
41 * it has non-zero value. it is calculated as (min * (align / relative)) if
42 * align is greater than relative, (min * ((1 - align) / (1 - relative))) otherwise.
43 * mi, mj are transformed relative based on layout min size. they are
44 * calculated as (target.mi + (relative * (target.mj - target.mi))). for example,
45 * there are two children of relative_container that has different target base.
46 * | | obj1 | obj2 |
47 * | min | 100 | 100 |
48 * |left.target | layout| obj1 |
49 * |left.relative | 0.0 | 0.5 |
50 * |right.target | layout| obj1 |
51 * |right.relative| 0.5 | 1.0 |
52 * | mi | 0.0 | 0.25 |
53 * | mj | 0.5 | 0.5 |
54 *
55 * obj1.mi = layout.mi(0.0) + (obj1.relative(0.0) * (LAyout.mj(1.0) - layout.mi(0.0))) = 0.0
56 * obj1.mj = layout.mi(0.0) + (obj1.relative(0.5) * (layout.mj(1.0) - layout.mi(0.0))) = 0.5
57 * obj2.mi = obj1.mi(0.0) + (obj2.relative(0.5) * (obj1.mj(0.5) - obj1.mi(0.0))) = 0.25
58 * obj2.mj = obj1.mi(0.0) + (obj2.relative(1.0) * (obj1.mj(0.5) - obj1.mi(0.0))) = 0.5
59 * layout min size is calculated as maximum of (child_min + m0) / (mj - mi).
60 * in the example, obj1 require layout min size as
61 * ((child_min(100) + m0(0)) / (mj(0.5) - mi(0.0))) = 200. obj2 require
62 * layout min size as ((100 + 0) / (0.5 - 0.25)) = 400. as a result, layout
63 * min size is max(200, 400) = 400.
64 */
65 double m0[2];
66 double mi[2], mj[2];
67
68 struct {
69 int position;
70 double length;
71 } space[2], want[2];
72
73 Efl_Ui_Relative_Container_Calc_State state[2];
74 Efl_Ui_Relative_Container_Calc_State chain_state[2];
75 Efl_Ui_Relative_Container_Child *to[4];
76};
77
78struct _Efl_Ui_Relative_Container_Data
79{
80 Eo *obj;
81 Eo *clipper;
82 Eina_Hash *children;
83 Efl_Ui_Relative_Container_Child *base;
84};
85
86struct _Efl_Ui_Relative_Container_Relation
87{
88 Efl_Object *to;
89 double relative_position;
90};
91
92struct _Efl_Ui_Relative_Container_Child
93{
94 Eo *obj;
95 Eo *layout;
96 Efl_Ui_Relative_Container_Relation rel[4];
97 Efl_Ui_Relative_Container_Calc calc;
98};
99
100struct _Efl_Ui_Relative_Container_Content_Iterator
101{
102 Eina_Iterator iterator;
103 Eina_Iterator *real_iterator;
104 Eo *relative_container;
105};
106
107#define EFL_UI_RELATIVE_CONTAINER_RELATION_SET_GET(direction, DIRECTION) \
108 EOLIAN static void \
109 _efl_ui_relative_container_relation_ ## direction ## _set(Eo *obj, Efl_Ui_Relative_Container_Data *pd, Eo *child, Eo *target, double relative_position) \
110 { \
111 Efl_Ui_Relative_Container_Child *rc; \
112 if (!child) return; \
113 rc = _relative_child_get(pd, child); \
114 if (!rc) return; \
115 if (target) rc->rel[DIRECTION].to = target; \
116 if (relative_position < 0) relative_position = 0; \
117 else if (relative_position > 1) relative_position = 1; \
118 rc->rel[DIRECTION].relative_position = relative_position; \
119 efl_pack_layout_request(obj); \
120 } \
121 \
122 EOLIAN static void \
123 _efl_ui_relative_container_relation_ ## direction ## _get(const Eo *obj EINA_UNUSED, Efl_Ui_Relative_Container_Data *pd, Eo *child, Eo **target, double *relative_position) \
124 { \
125 Efl_Ui_Relative_Container_Child *rc; \
126 Eo *rel_to = NULL; \
127 double rel_relative = 0.0; \
128 rc = eina_hash_find(pd->children, &child); \
129 if (rc) \
130 { \
131 rel_to = rc->rel[DIRECTION].to; \
132 rel_relative = rc->rel[DIRECTION].relative_position; \
133 } \
134 else \
135 ERR("child(%p(%s)) is not registered", child, efl_class_name_get(child)); \
136 if (target) *target = rel_to; \
137 if (relative_position) *relative_position = rel_relative; \
138 }
139
140#endif