aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBogdan Devichev <b.devichev@samsung.com>2014-04-09 19:04:55 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2014-04-09 19:04:55 +0900
commitaedef31eddf38567e27abcb4f753cf803c4f7b47 (patch)
tree820d3e39914e536ad001fb8831fc6e6736a76e82
parentgenlist event_block_rect needs a smart parent to reduce BITCH (diff)
downloadelementary-aedef31eddf38567e27abcb4f753cf803c4f7b47.tar.gz
elementary: when modal win appears another wins are blocked
Summary: In win.edc add blocker for its content and programs for it. Add Eina_Bool blocked and was_enabled to _Elm_Menu_Item for correctly blocking and unblocking of main_menu. They used for saving state which was before modal win was apeared. Add callbacks and private functions in menu.c for blocking and unblocking menu. Add integer modal_count to Elm_Win_Smart_Data for creating enum of modal wins. Add changes in win.c for blocking content, in_focus callback and menu while modal win is exist. Reviewers: cedric, seoz, raster Reviewed By: raster CC: reutskiy.v.v, raster Differential Revision: https://phab.enlightenment.org/D607
-rw-r--r--data/themes/edc/elm/win.edc24
-rw-r--r--src/lib/elm_menu.c31
-rw-r--r--src/lib/elm_widget_menu.h2
-rw-r--r--src/lib/elm_win.c83
4 files changed, 138 insertions, 2 deletions
diff --git a/data/themes/edc/elm/win.edc b/data/themes/edc/elm/win.edc
index 56af51fd1..343de6c6e 100644
--- a/data/themes/edc/elm/win.edc
+++ b/data/themes/edc/elm/win.edc
@@ -28,6 +28,18 @@ group { name: "elm/win/base/default";
}
}
}
+ part { name: "blocker"; type: RECT;
+ description { state: "default" 0.0;
+ rel1.relative : 0.0 0.0;
+ rel2.relative : 1.0 1.0;
+ color: 64 64 64 150;
+ visible: 0;
+ }
+ description { state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ }
+ }
}
programs {
program { name: "show_menu";
@@ -42,5 +54,17 @@ group { name: "elm/win/base/default";
action: STATE_SET "default" 0.0;
target: "elm.swallow.menu";
}
+ program { name: "hide_blocker";
+ signal: "elm,action,hide_blocker";
+ source: "elm";
+ action: STATE_SET "default" 0.0;
+ target: "blocker";
+ }
+ program { name: "show_blocker";
+ signal: "elm,action,show_blocker";
+ source: "elm";
+ action: STATE_SET "visible" 0.0;
+ target: "blocker";
+ }
}
}
diff --git a/src/lib/elm_menu.c b/src/lib/elm_menu.c
index d13f4422e..5e8a356fd 100644
--- a/src/lib/elm_menu.c
+++ b/src/lib/elm_menu.c
@@ -492,6 +492,33 @@ _menu_item_inactivate_cb(void *data,
if (item->submenu.open) _submenu_hide(item);
}
+static void
+_block_menu(Elm_Menu_Data * sd, Evas_Object *obj EINA_UNUSED, ...)
+{
+ const Eina_List *l;
+ Elm_Menu_Item *current;
+ Eina_List *items = sd->items;
+ EINA_LIST_FOREACH(items, l, current)
+ {
+ if (!current->blocked) current->was_enabled = !elm_widget_item_disabled_get(current);
+ current->blocked = EINA_TRUE;
+ elm_object_item_disabled_set(current, EINA_TRUE);
+ }
+}
+
+static void
+_unblock_menu(Elm_Menu_Data * sd, Evas_Object *obj EINA_UNUSED, ...)
+{
+ const Eina_List *l;
+ Elm_Menu_Item *current;
+ Eina_List *items = sd->items;
+ EINA_LIST_FOREACH(items, l, current)
+ {
+ elm_object_item_disabled_set(current, !current->was_enabled);
+ current->blocked = EINA_FALSE;
+ }
+}
+
EOLIAN static void
_elm_menu_evas_smart_show(Eo *obj EINA_UNUSED, Elm_Menu_Data *sd)
{
@@ -736,6 +763,10 @@ _elm_menu_eo_base_constructor(Eo *obj, Elm_Menu_Data *sd)
(sd->hv, ELM_HOVER_AXIS_VERTICAL), sd->bx);
_sizing_eval(obj);
+ evas_object_smart_callback_add(obj, "elm,action,block_menu",
+ _block_menu, sd);
+ evas_object_smart_callback_add(obj, "elm,action,unblock_menu",
+ _unblock_menu, sd);
}
EAPI void
diff --git a/src/lib/elm_widget_menu.h b/src/lib/elm_widget_menu.h
index 04fe2448b..0cede00d3 100644
--- a/src/lib/elm_widget_menu.h
+++ b/src/lib/elm_widget_menu.h
@@ -53,6 +53,8 @@ struct _Elm_Menu_Item
Eina_Bool separator : 1;
Eina_Bool selected : 1;
Eina_Bool object_item : 1;
+ Eina_Bool was_enabled : 1;
+ Eina_Bool blocked : 1;
};
/**
diff --git a/src/lib/elm_win.c b/src/lib/elm_win.c
index c3a1651c6..227f0519d 100644
--- a/src/lib/elm_win.c
+++ b/src/lib/elm_win.c
@@ -50,6 +50,40 @@ static const Elm_Win_Trap *trap = NULL;
if (!obj || !eo_isa(obj, MY_CLASS)) \
return
+#define DECREMENT_MODALITY() \
+ EINA_LIST_FOREACH(_elm_win_list, l, current) \
+ { \
+ ELM_WIN_DATA_GET_OR_RETURN(current, cursd); \
+ if ((obj != current) && (cursd->modal_count > 0)) \
+ { \
+ cursd->modal_count--; \
+ } \
+ if (cursd->modal_count == 0) \
+ { \
+ edje_object_signal_emit(cursd->layout, \
+ "elm,action,hide_blocker", "elm"); \
+ evas_object_smart_callback_call(cursd->main_menu, \
+ "elm,action,unblock_menu", NULL); \
+ } \
+ }
+
+#define INCREMENT_MODALITY() \
+ EINA_LIST_FOREACH(_elm_win_list, l, current) \
+ { \
+ ELM_WIN_DATA_GET_OR_RETURN(current, cursd); \
+ if (obj != current) \
+ { \
+ cursd->modal_count++; \
+ } \
+ if (cursd->modal_count > 0) \
+ { \
+ edje_object_signal_emit(cursd->layout, \
+ "elm,action,show_blocker", "elm"); \
+ evas_object_smart_callback_call(cursd->main_menu, \
+ "elm,action,block_menu", NULL); \
+ } \
+ }
+
#define ENGINE_GET() (_elm_preferred_engine ? _elm_preferred_engine : (_elm_config->engine ? _elm_config->engine : ""))
#define ENGINE_COMPARE(name) (!strcmp(ENGINE_GET(), name))
@@ -158,6 +192,7 @@ struct _Elm_Win_Data
int size_base_w, size_base_h;
int size_step_w, size_step_h;
int norender;
+ int modal_count;
Eina_Bool urgent : 1;
Eina_Bool modal : 1;
Eina_Bool demand_attention : 1;
@@ -858,7 +893,7 @@ _elm_win_focus_in(Ecore_Evas *ee)
Evas_Object *obj;
unsigned int order = 0;
- if (!sd) return;
+ if ((!sd) || (sd->modal_count)) return;
obj = sd->obj;
@@ -1249,10 +1284,19 @@ _deferred_ecore_evas_free(void *data)
EOLIAN static void
_elm_win_evas_smart_show(Eo *obj, Elm_Win_Data *sd)
{
+ if (sd->modal_count) return;
+ const Eina_List *l;
+ Evas_Object *current;
+
if (!evas_object_visible_get(obj))
_elm_win_state_eval_queue();
eo_do_super(obj, MY_CLASS, evas_obj_smart_show());
+ if ((sd->modal) && (!evas_object_visible_get(obj)))
+ {
+ INCREMENT_MODALITY()
+ }
+
TRAP(sd, show);
if (sd->shot.info) _shot_handle(sd);
@@ -1261,10 +1305,19 @@ _elm_win_evas_smart_show(Eo *obj, Elm_Win_Data *sd)
EOLIAN static void
_elm_win_evas_smart_hide(Eo *obj, Elm_Win_Data *sd)
{
+ if (sd->modal_count) return;
+ const Eina_List *l;
+ Evas_Object *current;
+
if (evas_object_visible_get(obj))
_elm_win_state_eval_queue();
eo_do_super(obj, MY_CLASS, evas_obj_smart_hide());
+ if ((sd->modal) && (evas_object_visible_get(obj)))
+ {
+ DECREMENT_MODALITY()
+ }
+
TRAP(sd, hide);
if (sd->frame_obj)
@@ -1512,6 +1565,17 @@ _elm_win_img_callbacks_del(Evas_Object *obj, Evas_Object *imgobj)
EOLIAN static void
_elm_win_evas_smart_del(Eo *obj, Elm_Win_Data *sd)
{
+ const Eina_List *l;
+ Evas_Object *current;
+
+ if ((sd->modal) && (evas_object_visible_get(obj)))
+ {
+ DECREMENT_MODALITY()
+ }
+
+ if ((sd->modal) && (sd->modal_count > 0))
+ ERR("Deleted modal win was blocked by another modal win which was created after creation of that win.");
+
evas_object_event_callback_del_full(sd->layout,
EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_elm_win_on_resize_obj_changed_size_hints,
@@ -3111,6 +3175,7 @@ _elm_win_constructor(Eo *obj, Elm_Win_Data *sd, const char *name, Elm_Win_Type t
sd->type = type;
sd->parent = parent;
+ sd->modal_count = 0;
if (sd->parent)
evas_object_event_callback_add
@@ -3834,8 +3899,22 @@ _elm_win_demand_attention_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
}
EOLIAN static void
-_elm_win_modal_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool modal)
+_elm_win_modal_set(Eo *obj, Elm_Win_Data *sd, Eina_Bool modal)
{
+ if (sd->modal_count) return;
+
+ const Eina_List *l;
+ Evas_Object *current;
+
+ if ((modal) && (!sd->modal) && (evas_object_visible_get(obj)))
+ {
+ INCREMENT_MODALITY()
+ }
+ else if ((!modal) && (sd->modal) && (evas_object_visible_get(obj)))
+ {
+ DECREMENT_MODALITY()
+ }
+
sd->modal = modal;
TRAP(sd, modal_set, modal);
#ifdef HAVE_ELEMENTARY_X