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
This commit is contained in:
Bogdan Devichev 2014-04-09 19:04:55 +09:00 committed by Carsten Haitzler (Rasterman)
parent 8fba6f77e9
commit ac038d7982
4 changed files with 138 additions and 2 deletions

View File

@ -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";
}
}
}

View File

@ -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

View File

@ -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;
};
/**

View File

@ -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