Tizen 2.1 release
[platform/core/uifw/e17.git] / src / bin / e_resist.c
1 #include "e.h"
2
3 typedef struct _E_Resist_Rect E_Resist_Rect;
4
5 struct _E_Resist_Rect
6 {
7    int x, y, w, h;
8    int v1;
9    int resist_out;
10 };
11
12 static void _e_resist_rects(Eina_List *rects, int px, int py, int pw, int ph, int x, int y, int w, int h, int *rx, int *ry, int *rw, int *rh);
13
14 EAPI int
15 e_resist_container_border_position(E_Container *con, Eina_List *skiplist,
16                                    int px, int py, int pw, int ph,
17                                    int x, int y, int w, int h,
18                                    int *rx, int *ry, int *rw, int *rh)
19 {
20    Eina_List *l, *ll, *rects = NULL;
21    E_Resist_Rect *r;
22    E_Border_List *bl;
23    E_Border *bd, *bd2;
24    E_Desk *desk;
25    E_Shelf *es;
26    E_Zone *zone;
27
28    if (!e_config->use_resist)
29      {
30         *rx = x;
31         *ry = y;
32         *rw = w;
33         *rh = h;
34         return 0;
35      }
36
37    /* edges of screen */
38 #define OBSTACLE(_x, _y, _w, _h, _resist) \
39    { \
40       r = E_NEW(E_Resist_Rect, 1); \
41       r->x = _x; r->y = _y; r->w = _w; r->h = _h; r->v1 = _resist; \
42       r->resist_out = 0; \
43       rects = eina_list_append(rects, r); \
44    }
45 #define HOLDER(_x, _y, _w, _h, _resist) \
46    { \
47       r = E_NEW(E_Resist_Rect, 1); \
48       r->x = _x; r->y = _y; r->w = _w; r->h = _h; r->v1 = _resist; \
49       r->resist_out = 1; \
50       rects = eina_list_append(rects, r); \
51    }
52
53    EINA_LIST_FOREACH(con->zones, l, zone)
54      {
55         HOLDER(zone->x, zone->y, zone->w, zone->h, e_config->desk_resist);
56      }
57    /* FIXME: need to add resist or complete BLOCKS for things like ibar */
58    /* can add code here to add more fake obstacles with custom resist values */
59    /* here if need be - ie xinerama middle between screens and panels etc. */
60
61    bl = e_container_border_list_first(con);
62    while ((bd = e_container_border_list_next(bl)))
63      {
64         if (bd->visible)
65           {
66              int ok;
67
68              ok = 1;
69              EINA_LIST_FOREACH(skiplist, ll, bd2)
70                {
71                   if (bd2 == bd)
72                     {
73                        ok = 0;
74                        break;
75                     }
76                }
77              if (ok && bd->offer_resistance)
78                {
79                   OBSTACLE(bd->x, bd->y, bd->w, bd->h, e_config->window_resist);
80                }
81           }
82      }
83    e_container_border_list_free(bl);
84
85    desk = e_desk_current_get(e_zone_current_get(con));
86    EINA_LIST_FOREACH(e_shelf_list(), l, es)
87      {
88         Eina_List *ll2;
89         E_Config_Shelf_Desk *sd;
90
91         if (es->zone->container == con)
92           {
93              if (es->cfg->desk_show_mode)
94                {
95                   EINA_LIST_FOREACH(es->cfg->desk_list, ll2, sd)
96                     {
97                        if (!sd) continue;
98                        if ((sd->x == desk->x) && (sd->y == desk->y))
99                          {
100                             OBSTACLE(es->x + es->zone->x, es->y + es->zone->y, es->w, es->h,
101                                      e_config->gadget_resist);
102                             break;
103                          }
104                     }
105                }
106              else
107                {
108                   OBSTACLE(es->x + es->zone->x, es->y + es->zone->y, es->w, es->h,
109                            e_config->gadget_resist);
110                }
111           }
112      }
113    if (rects)
114      {
115         _e_resist_rects(rects,
116                         px, py, pw, ph,
117                         x, y, w, h,
118                         rx, ry, rw, rh);
119
120         E_FREE_LIST(rects, E_FREE);
121      }
122    return 1;
123 }
124
125 EAPI int
126 e_resist_container_gadman_position(E_Container *con, Eina_List *skiplist __UNUSED__,
127                                    int px, int py, int pw, int ph,
128                                    int x, int y, int w, int h,
129                                    int *rx, int *ry)
130 {
131    Eina_List *l, *rects = NULL;
132    E_Resist_Rect *r;
133    E_Shelf *es;
134
135    if (!e_config->use_resist)
136      {
137         *rx = x;
138         *ry = y;
139         return 0;
140      }
141
142    EINA_LIST_FOREACH(e_shelf_list(), l, es)
143      {
144         if (es->zone->container == con)
145           {
146              OBSTACLE(es->x + es->zone->x, es->y + es->zone->y, es->w, es->h,
147                       e_config->gadget_resist);
148           }
149      }
150
151    if (rects)
152      {
153         _e_resist_rects(rects,
154                         px, py, pw, ph,
155                         x, y, w, h,
156                         rx, ry, NULL, NULL);
157
158         E_FREE_LIST(rects, E_FREE);
159      }
160    return 1;
161 }
162
163 static void
164 _e_resist_rects(Eina_List *rects,
165                 int px, int py, int pw, int ph,
166                 int x, int y, int w, int h,
167                 int *rx, int *ry, int *rw, int *rh)
168 {
169    int dx, dy, dw, dh, d, pd;
170    int resist_x = 0, resist_y = 0;
171    int resist_w = 0, resist_h = 0;
172    Eina_List *l;
173    E_Resist_Rect *r;
174
175 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
176    const int magnet_eff_margin = 30;
177    int gap = 0;
178    int magnet_gain_x = 0;
179    int magnet_gain_y = 0;
180 #endif
181
182    dx = x - px;
183    dy = y - py;
184    dw = w - pw;
185    dh = h - ph;
186
187    EINA_LIST_FOREACH(rects, l, r)
188      {
189         if (E_SPANS_COMMON(r->y, r->h, y, h))
190           {
191 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
192              if (r->resist_out)
193                {
194                   gap = (r->x + r->w) - (x + w);
195                   if (gap >= 0 && gap <= magnet_eff_margin)
196                     {
197                        if (magnet_gain_x == 0 || magnet_gain_x > gap)
198                          magnet_gain_x = gap;
199                     }
200
201                   gap = x - r->x;
202                   if (gap >= 0 && gap <= magnet_eff_margin)
203                     {
204                        if (magnet_gain_x == 0 || magnet_gain_x > gap)
205                          magnet_gain_x = -gap;
206                     }
207                }
208              else
209                {
210                   gap = r->x - (x + w);
211                   if (gap >= 0 && gap <= magnet_eff_margin)
212                     {
213                        if (magnet_gain_x == 0 || magnet_gain_x > gap)
214                          magnet_gain_x = gap;
215                     }
216
217                   gap = x - (r->x + r->w);
218                   if (gap >= 0 && gap <= magnet_eff_margin)
219                     {
220                        if (magnet_gain_x == 0 || magnet_gain_x > gap)
221                          magnet_gain_x = -gap;
222                     }
223                }
224 #endif
225              if (dx > 0)
226                {
227                   /* moving right */
228                   if (r->resist_out)
229                     {
230                        /* check right edge of windows against left */
231                        d = x + w - (r->x + r->w);
232                        pd = px + pw - (r->x + r->w);
233                        if ((d > 0) && (pd <= 0) && (d <= r->v1))
234                          {
235                             if (-resist_x < d)
236                               resist_x = -d;
237                          }
238                     }
239                   else
240                     {
241                        /* check left edge of windows against right */
242                        d = r->x - (x + w);
243                        pd = r->x - (px + pw);
244                        if ((d < 0) && (pd >= 0) && (d >= -r->v1))
245                          {
246                             if (resist_x > d)
247                               resist_x = d;
248                          }
249                     }
250                }
251              else if (dx < 0)
252                {
253                   /* moving left */
254                   if (r->resist_out)
255                     {
256                        /* check left edge of windows against right */
257                        d = r->x - x;
258                        pd = r->x - px;
259                        if ((d > 0) && (pd <= 0) && (d <= r->v1))
260                          {
261                             if (resist_x < d)
262                               {
263                                  resist_x = d;
264                                  resist_w = -d;
265                               }
266                          }
267                     }
268                   else
269                     {
270                        /* check right edge of windows against left */
271                        d = x - (r->x + r->w);
272                        pd = px - (r->x + r->w);
273                        if ((d < 0) && (pd >= 0) && (d >= -r->v1))
274                          {
275                             if (-resist_x > d)
276                             {
277                                resist_x = -d;
278                                resist_w = d;
279                             }
280                          }
281                     }
282                }
283              if ((dw > 0) && (dx == 0))
284                {
285                   /* enlarging window by moving lower corner */
286                   if (r->resist_out)
287                     {
288                        /* check right edge of windows against left */
289                        d = x + w - (r->x + r->w);
290                        pd = px + pw - (r->x + r->w);
291                        if ((d > 0) && (pd <= 0) && (d <= r->v1))
292                          {
293                             if (-resist_w < d)
294                               resist_w = -d;
295                          }
296                     }
297                   else
298                     {
299                        /* check left edge of windows against right */
300                        d = r->x - (x + w);
301                        pd = r->x - (px + pw);
302                        if ((d < 0) && (pd >= 0) && (d >= -r->v1))
303                          {
304                             if (resist_w > d)
305                               resist_w = d;
306                          }
307                     }
308                }
309           }
310         if (E_SPANS_COMMON(r->x, r->w, x, w))
311           {
312 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
313              if (r->resist_out)
314                {
315                   gap = (r->y + r->h) - (y + h);
316                   if (gap >= 0 && gap <= magnet_eff_margin)
317                     {
318                        if (magnet_gain_y == 0 || magnet_gain_y > gap)
319                          magnet_gain_y = gap;
320                     }
321
322                   gap = y - r->y;
323                   if (gap >= 0 && gap <= magnet_eff_margin)
324                     {
325                        if (magnet_gain_y == 0 || magnet_gain_y > gap)
326                          magnet_gain_y = -gap;
327                     }
328                }
329              else
330                {
331                   gap = r->y - (y + h);
332                   if (gap >= 0 && gap <= magnet_eff_margin)
333                     {
334                        if (magnet_gain_y == 0 || magnet_gain_y > gap)
335                          magnet_gain_y = gap;
336                     }
337
338                   gap = y - (r->y + r->h);
339                   if (gap >= 0 && gap <= magnet_eff_margin)
340                     {
341                        if (magnet_gain_y == 0 || magnet_gain_y >gap)
342                          magnet_gain_y = -gap;
343                     }
344                }
345 #endif
346              if (dy > 0)
347                {
348                   /* moving down */
349                   if (r->resist_out)
350                     {
351                        /* check bottom edge of windows against top */
352                        d = y + h - (r->y + r->h);
353                        pd = py + ph - (r->y + r->h);
354                        if ((d > 0) && (pd <= 0) && (d <= r->v1))
355                          {
356                             if (-resist_y < d)
357                               resist_y = -d;
358                          }
359                     }
360                   else
361                     {
362                        /* check top edge of windows against bottom */
363                        d = r->y - (y + h);
364                        pd = r->y - (py + ph);
365                        if ((d < 0) && (pd >= 0) && (d >= -r->v1))
366                          {
367                             if (resist_y > d)
368                               resist_y = d;
369                          }
370                     }
371                }
372              else if (dy < 0)
373                {
374                   /* moving up */
375                   if (r->resist_out)
376                     {
377                        /* check top edge of windows against bottom */
378                        d = r->y - y;
379                        pd = r->y - py;
380                        if ((d > 0) && (pd <= 0) && (d <= r->v1))
381                          {
382                             if (resist_y < d)
383                               {
384                                  resist_y = d;
385                                  resist_h = -d;
386                               }
387                          }
388                     }
389                   else
390                     {
391                        /* moving up - check bottom edge of windows against top */
392                        d = y - (r->y + r->h);
393                        pd = py - (r->y + r->h);
394                        if ((d < 0) && (pd >= 0) && (d >= -r->v1))
395                          {
396                             if (-resist_y > d)
397                               {
398                                  resist_y = -d;
399                                  resist_h = d;
400                               }
401                          }
402                     }
403                }
404              if ((dh > 0) && (dy == 0))
405                {
406                   /* enlarging window by moving lower corner */
407                   if (r->resist_out)
408                     {
409                        /* check bottom edge of windows against top */
410                        d = y + h - (r->y + r->h);
411                        pd = py + ph - (r->y + r->h);
412                        if ((d > 0) && (pd <= 0) && (d <= r->v1))
413                          {
414                             if (-resist_h < d)
415                               resist_h = -d;
416                          }
417                     }
418                   else
419                     {
420                        /* check top edge of windows against bottom */
421                        d = r->y - (y + h);
422                        pd = r->y - (py + ph);
423                        if ((d < 0) && (pd >= 0) && (d >= -r->v1))
424                          {
425                             if (resist_h > d)
426                               resist_h = d;
427                          }
428                     }
429                }
430           }
431      }
432    if (rx)
433      {
434         if (dx != 0)
435 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
436           *rx = x + (abs(resist_x) > abs(magnet_gain_x) ?
437                      resist_x : magnet_gain_x);
438 #else
439           *rx = x + resist_x;
440 #endif
441         else
442           *rx = x;
443      }
444    if (ry)
445      {
446         if (dy != 0)
447 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
448           *ry = y + (abs(resist_y) > abs(magnet_gain_y) ?
449                      resist_y : magnet_gain_y);
450 #else
451           *ry = y + resist_y;
452 #endif
453         else
454           *ry = y;
455      }
456    if (rw)
457      {
458         if (dw != 0)
459           *rw = w + resist_w;
460         else
461           *rw = w;
462      }
463    if (rh)
464      {
465         if (dh != 0)
466           *rh = h + resist_h;
467         else
468           *rh = h;
469      }
470 }