diff --git a/src/examples/edje/.gitignore b/src/examples/edje/.gitignore index 73b171ab35..027f4d35b8 100644 --- a/src/examples/edje/.gitignore +++ b/src/examples/edje/.gitignore @@ -15,6 +15,7 @@ /edje-focus /edje-multiseat /edje-multiseat-custom-names +/edje-multiseat-filter /edje-multisense /edje-perspective /edje-signals-messages diff --git a/src/examples/edje/Makefile.am b/src/examples/edje/Makefile.am index 2afacfc6fc..e34be1175c 100644 --- a/src/examples/edje/Makefile.am +++ b/src/examples/edje/Makefile.am @@ -47,6 +47,7 @@ lua_script.edc \ messages_echo.edc \ multiseat.edc \ multiseat_custom_names.edc \ +multiseat_filter.edc \ perspective.edc \ signals-messages.edc \ signalsBubble.edc \ @@ -148,6 +149,7 @@ edje-entry.c \ edje-focus.c \ edje-multiseat.c \ edje-multiseat-custom-names.c \ +edje-multiseat-filter.c \ edje-multisense.c \ edje-perspective.c \ edje-signals-messages.c \ @@ -225,6 +227,7 @@ edje-entry \ edje-focus \ edje-multiseat \ edje-multiseat-custom-names \ +edje-multiseat-filter \ edje-perspective \ edje-signals-messages \ edje-swallow \ diff --git a/src/examples/edje/edje-multiseat-filter.c b/src/examples/edje/edje-multiseat-filter.c new file mode 100644 index 0000000000..43ae82818f --- /dev/null +++ b/src/examples/edje/edje-multiseat-filter.c @@ -0,0 +1,130 @@ +/** + * Edje example demonstrating how to use multiseat filtering. + * + * It presents 4 widgets that can be controlled by: + * * seat1 only + * * seat2 only + * * seat1 + seat2 + * * any seat + * + * You'll need at least one Evas engine built for it (excluding the + * buffer one) that supports multiseat. It may be wayland or + * X11 with VNC support. Using other engines will lead you to a + * situation where all seats are reported as the same one ("default"). + * + * @verbatim + * edje_cc multiseat_filter.edc && gcc -o edje-multiseat-filter edje-multiseat-filter.c `pkg-config --libs --cflags evas ecore ecore-evas edje` + * @endverbatim + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#else +# define EINA_UNUSED +#endif + +#ifndef PACKAGE_DATA_DIR +#define PACKAGE_DATA_DIR "." +#endif + +#include +#include +#include + +#define WIDTH 400 +#define HEIGHT 400 + +static const char *GROUPNAME = "example/main"; +static const char *EDJE_FILE = PACKAGE_DATA_DIR"/multiseat_filter.edj"; + +static void +_on_destroy(Ecore_Evas *ee EINA_UNUSED) +{ + ecore_main_loop_quit(); +} + +static void +_on_canvas_resize(Ecore_Evas *ee) +{ + Evas_Object *edje_obj; + int w, h; + + edje_obj = ecore_evas_data_get(ee, "edje_obj"); + + ecore_evas_geometry_get(ee, NULL, NULL, &w, &h); + evas_object_resize(edje_obj, w, h); +} + +static void +_device_added(void *data, const Efl_Event *event) +{ + Efl_Input_Device *dev = event->info; + Evas_Object *edje_obj = data; + + if (efl_input_device_type_get(dev) != EFL_INPUT_DEVICE_CLASS_SEAT) + return; + + efl_canvas_object_seat_focus_add(edje_obj, dev); +} + +int +main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED) +{ + const Eina_List *devices, *l; + Efl_Input_Device *dev; + Evas_Object *edje_obj; + Ecore_Evas *ee; + Evas *evas; + + if (!ecore_evas_init()) + return EXIT_FAILURE; + + if (!edje_init()) + goto shutdown_ecore_evas; + + ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL); + if (!ee) goto shutdown_edje; + + ecore_evas_callback_destroy_set(ee, _on_destroy); + ecore_evas_callback_resize_set(ee, _on_canvas_resize); + ecore_evas_title_set(ee, "Edje Multiseat Filter Example"); + + evas = ecore_evas_get(ee); + + edje_obj = edje_object_add(evas); + + if (!edje_object_file_set(edje_obj, EDJE_FILE, GROUPNAME)) + printf("failed to set file %s.\n", EDJE_FILE); + + evas_object_move(edje_obj, 0, 0); + evas_object_resize(edje_obj, WIDTH, HEIGHT); + evas_object_show(edje_obj); + ecore_evas_data_set(ee, "edje_obj", edje_obj); + + devices = evas_device_list(evas, NULL); + EINA_LIST_FOREACH(devices, l, dev) + { + if (efl_input_device_type_get(dev) == EFL_INPUT_DEVICE_CLASS_SEAT) + efl_canvas_object_seat_focus_add(edje_obj, dev); + + } + efl_event_callback_add(evas, EFL_CANVAS_EVENT_DEVICE_ADDED, + _device_added, edje_obj); + + ecore_evas_show(ee); + + ecore_main_loop_begin(); + + ecore_evas_free(ee); + ecore_evas_shutdown(); + edje_shutdown(); + + return EXIT_SUCCESS; + +shutdown_edje: + edje_shutdown(); +shutdown_ecore_evas: + ecore_evas_shutdown(); + + return EXIT_FAILURE; +} diff --git a/src/examples/edje/multiseat_filter.edc b/src/examples/edje/multiseat_filter.edc new file mode 100644 index 0000000000..5a89503e27 --- /dev/null +++ b/src/examples/edje/multiseat_filter.edc @@ -0,0 +1,811 @@ +collections { + + styles { + style { + name: "entry_style"; + base: "font="sans" font_size=10 color=#000 wrap="word" left_margin=2 right_margin=2"; + } + } + + group { + name: "example/main"; + min: 400 400; + + parts { + part { + name: "bg"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + } + } + + part { + name: "title"; + type: TEXT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 0 0 0 255; + rel1 { + relative: 0.0 0.0; + offset: 0 0; + to: "bg"; + } + rel2 { + relative: 1.0 0.2; + offset: -1 -1; + to: "bg"; + } + text { + text: "Multiseat Filter Example"; + size: 16; + font: "sans"; + min: 1 1; + } + } + } + + // focus_bt is important to test if focus action are + // respecting allowed seats list + part { + name: "focus_bt"; + type: RECT; + mouse_events: 1; + description { + state: "default" 0.0; + rel1.relative: 0.3 0.2; + rel2.relative: 0.7 0.25; + color: 192 50 50 255; + } + description { + state: "over" 0.0; + inherit: "default" 0.0; + color: 142 30 30 255; + } + description { + state: "pressed" 0.0; + inherit: "default" 0.0; + color: 220 70 70 255; + } + } + + part { + name: "focus_bt,label"; + type: TEXT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 92 0 0 255; + rel1 { + relative: 0.5 0.5; + to: "focus_bt"; + } + rel2 { + relative: 0.5 0.5; + to: "focus_bt"; + } + text { + text: "Focus 'Seat 1 Only' Entry"; + size: 11; + font: "sans"; + min: 1 1; + } + } + } + + part { + name: "widget1"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + rel1.relative: 0.0 0.3; + rel2.relative: 0.5 0.65; + color: 255 255 0 255; + } + } + + part { + name: "widget2"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + rel1.relative: 0.0 0.65; + rel2.relative: 0.5 1.0; + color: 255 0 255 255; + } + } + + part { + name: "widget3"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + rel1.relative: 0.5 0.3; + rel2.relative: 1.0 0.65; + color: 0 255 255 255; + } + } + + part { + name: "widget4"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + rel1.relative: 0.5 0.65; + rel2.relative: 1.0 1.0; + color: 130 255 130 255; + } + } + + part { + name: "widget1,title"; + type: TEXT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 0 0 0 255; + rel1 { + relative: 0.0 0.02; + offset: 0 0; + to: "widget1"; + } + rel2 { + relative: 1.0 0.1; + offset: -1 -1; + to: "widget1"; + } + text { + text: "Seat1 Only"; + size: 10; + font: "sans"; + min: 1 1; + } + } + } + + part { + name: "widget1,drag_area"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 20 20 20 255; + rel1 { + relative: 0.1 0.2; + offset: -5 0; + to: "widget1"; + } + rel2 { + relative: 0.1 0.8; + offset: 4 0; + to: "widget1"; + } + } + } + + part { + name: "widget,knob,1"; + type: RECT; + mouse_events: 1; + allowed_seats: "seat1"; + dragable { + confine: "widget1,drag_area"; + x: 0 0 0; + y: 1 1 0; + } + description { + state: "default" 0.0; + min: 10 30; + color: 120 120 120 255; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + color: 200 200 200 255; + } + } + + part { + name: "widget,bg_text,1"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + min: 10 50; + rel1 { + to: "widget1"; + relative: 0.25 0.2; + } + rel2 { + to: "widget1"; + relative: 0.85 0.8; + } + color: 120 120 120 255; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + color: 200 200 200 255; + } + } + + part { + name: "widget,text,1"; + type: TEXTBLOCK; + scale: 1; + entry_mode: EDITABLE; + select_mode: DEFAULT; + cursor_mode: UNDER; + mouse_events: 1; + allowed_seats: "seat1"; + multiline: 1; + source: "example/selection"; + source4: "example/cursor"; + description { + state: "default" 0.0; + min: 12 50; + rel1 { + to: "widget,bg_text,1"; + offset: 2 2; + } + rel2 { + to: "widget,bg_text,1"; + offset: -3 -3; + } + text { + style: "entry_style"; + min: 0 1; + align: 0.0 0.0; + } + } + } + + part { + name: "widget2,title"; + type: TEXT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 0 0 0 255; + rel1 { + relative: 0.0 0.02; + offset: 0 0; + to: "widget2"; + } + rel2 { + relative: 1.0 0.1; + offset: -1 -1; + to: "widget2"; + } + text { + text: "Seat2 Only"; + size: 10; + font: "sans"; + min: 1 1; + } + } + } + + part { + name: "widget2,drag_area"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 20 20 20 255; + rel1 { + relative: 0.1 0.2; + offset: -5 0; + to: "widget2"; + } + rel2 { + relative: 0.1 0.8; + offset: 4 0; + to: "widget2"; + } + } + } + + part { + name: "widget,knob,2"; + type: RECT; + mouse_events: 1; + allowed_seats: "seat2"; + dragable { + confine: "widget2,drag_area"; + x: 0 0 0; + y: 1 1 0; + } + description { + state: "default" 0.0; + min: 10 30; + color: 120 120 120 255; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + color: 200 200 200 255; + } + } + + part { + name: "widget,bg_text,2"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + min: 10 50; + rel1 { + to: "widget2"; + relative: 0.25 0.2; + } + rel2 { + to: "widget2"; + relative: 0.85 0.8; + } + color: 120 120 120 255; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + color: 200 200 200 255; + } + } + + part { + name: "widget,text,2"; + type: TEXTBLOCK; + scale: 1; + entry_mode: EDITABLE; + select_mode: DEFAULT; + cursor_mode: UNDER; + mouse_events: 1; + allowed_seats: "seat2"; + multiline: 1; + source: "example/selection"; + source4: "example/cursor"; + description { + state: "default" 0.0; + min: 12 50; + rel1 { + to: "widget,bg_text,2"; + offset: 2 2; + } + rel2 { + to: "widget,bg_text,2"; + offset: -3 -3; + } + text { + style: "entry_style"; + min: 0 1; + align: 0.0 0.0; + } + } + } + + part { + name: "widget3,title"; + type: TEXT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 0 0 0 255; + rel1 { + relative: 0.0 0.02; + offset: 0 0; + to: "widget3"; + } + rel2 { + relative: 1.0 0.1; + offset: -1 -1; + to: "widget3"; + } + text { + text: "Seat 1 + Seat2"; + size: 10; + font: "sans"; + min: 1 1; + } + } + } + + part { + name: "widget3,drag_area"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 20 20 20 255; + rel1 { + relative: 0.1 0.2; + offset: -5 0; + to: "widget3"; + } + rel2 { + relative: 0.1 0.8; + offset: 4 0; + to: "widget3"; + } + } + } + + part { + name: "widget,knob,3"; + type: RECT; + mouse_events: 1; + allowed_seats: "seat1" "seat2"; + dragable { + confine: "widget3,drag_area"; + x: 0 0 0; + y: 1 1 0; + } + description { + state: "default" 0.0; + min: 10 30; + color: 120 120 120 255; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + color: 200 200 200 255; + } + } + + part { + name: "widget,bg_text,3"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + min: 10 50; + rel1 { + to: "widget3"; + relative: 0.25 0.2; + } + rel2 { + to: "widget3"; + relative: 0.85 0.8; + } + color: 120 120 120 255; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + color: 200 200 200 255; + } + } + + part { + name: "widget,text,3"; + type: TEXTBLOCK; + scale: 1; + entry_mode: EDITABLE; + select_mode: DEFAULT; + cursor_mode: UNDER; + mouse_events: 1; + allowed_seats: "seat1" "seat2"; + multiline: 1; + source: "example/selection"; + source4: "example/cursor"; + description { + state: "default" 0.0; + min: 12 50; + rel1 { + to: "widget,bg_text,3"; + offset: 2 2; + } + rel2 { + to: "widget,bg_text,3"; + offset: -3 -3; + } + text { + style: "entry_style"; + min: 0 1; + align: 0.0 0.0; + } + } + } + + part { + name: "widget4,title"; + type: TEXT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 0 0 0 255; + rel1 { + relative: 0.0 0.02; + offset: 0 0; + to: "widget4"; + } + rel2 { + relative: 1.0 0.1; + offset: -1 -1; + to: "widget4"; + } + text { + text: "Any seat"; + size: 10; + font: "sans"; + min: 1 1; + } + } + } + + part { + name: "widget4,drag_area"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 20 20 20 255; + rel1 { + relative: 0.1 0.2; + offset: -5 0; + to: "widget4"; + } + rel2 { + relative: 0.1 0.8; + offset: 4 0; + to: "widget4"; + } + } + } + + part { + name: "widget,knob,4"; + type: RECT; + mouse_events: 1; + dragable { + confine: "widget4,drag_area"; + x: 0 0 0; + y: 1 1 0; + } + description { + state: "default" 0.0; + min: 10 30; + color: 120 120 120 255; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + color: 200 200 200 255; + } + } + + part { + name: "widget,bg_text,4"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + min: 10 50; + rel1 { + to: "widget4"; + relative: 0.25 0.2; + } + rel2 { + to: "widget4"; + relative: 0.85 0.8; + } + color: 120 120 120 255; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + color: 200 200 200 255; + } + } + + part { + name: "widget,text,4"; + type: TEXTBLOCK; + scale: 1; + entry_mode: EDITABLE; + select_mode: DEFAULT; + cursor_mode: UNDER; + mouse_events: 1; + multiline: 1; + source: "example/selection"; + source4: "example/cursor"; + description { + state: "default" 0.0; + min: 12 50; + rel1 { + to: "widget,bg_text,4"; + offset: 2 2; + } + rel2 { + to: "widget,bg_text,4"; + offset: -3 -3; + } + text { + style: "entry_style"; + min: 0 1; + align: 0.0 0.0; + } + } + } + } + + programs { + program { + name: "clicked"; + signal: "mouse,clicked,1,*"; + source: "widget,text,*"; + script { + new partid; + partid = get_part_id(src); + set_focus(partid, sig[strlen("mouse,clicked,1,")]); + } + } + + program { + name: "focused"; + signal: "focus,part,in,*"; + source: "widget,text,*"; + script { + new buf[256]; + new partid; + + snprintf(buf, 128, "widget,bg_text,%s", + src[strlen("widget,text,")]); + partid = get_part_id(buf); + set_state(partid, "focused", 0.0); + } + } + + program { + name: "unfocused"; + signal: "focus,part,out,*"; + source: "widget,text,*"; + script { + new buf[256]; + new partid; + + snprintf(buf, 128, "widget,bg_text,%s", + src[strlen("widget,text,")]); + partid = get_part_id(buf); + set_state(partid, "default", 0.0); + } + } + + program { + name: "drag,start"; + signal: "drag,start,*"; + source: "widget,knob,*"; + script { + new partid; + partid = get_part_id(src); + set_state(partid, "focused", 0.0); + } + } + + program { + name: "drag,stop"; + signal: "drag,stop,*"; + source: "widget,knob,*"; + script { + new partid; + partid = get_part_id(src); + set_state(partid, "default", 0.0); + } + } + + program { + name: "focus_bt,in"; + signal: "mouse,in"; + source: "focus_bt"; + action: STATE_SET "over" 0.0; + target: "focus_bt"; + } + + program { + name: "focus_bt,out"; + signal: "mouse,out"; + source: "focus_bt"; + action: STATE_SET "default" 0.0; + target: "focus_bt"; + } + + program { + name: "focus_bt,down"; + signal: "mouse,down,1"; + source: "focus_bt"; + action: STATE_SET "pressed" 0.0; + target: "focus_bt"; + } + + program { + name: "focus_bt,up"; + signal: "mouse,up,1"; + source: "focus_bt"; + action: STATE_SET "default" 0.0; + target: "focus_bt"; + } + + program { + name: "focus_bt,clicked"; + signal: "mouse,clicked,1,*"; + source: "focus_bt"; + script { + set_focus(PART:"widget,text,1", + sig[strlen("mouse,clicked,1,")]); + } + } + } + } + + group { + name: "example/selection"; + + parts { + part { + name: "selection"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 180 180 180 255; + } + } + } + } + + group { + name: "example/cursor"; + min: 1 0; + + parts { + part { + name: "cursor"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + min: 2 12; + color: 0 0 0 255; + } + description { + state: "hidden" 0.0; + inherit: "default" 0.0; + color: 0 0 0 0; + } + } + } + + programs { + program { + name: "cursor_hide"; + signal: "load"; + source: ""; + action: STATE_SET "hidden" 0.0; + target: "cursor"; + transition: SINUSOIDAL 0.2; + after: "cursor_hide_timer"; + } + program { + name: "cursor_hide_timer"; + in: 0.2 0.0; + after: "cursor_show"; + } + program { + name: "cursor_show"; + action: STATE_SET "default" 0.0; + target: "cursor"; + after: "cursor_show_timer"; + } + program { + name: "cursor_show_timer"; + in: 0.5 0.0; + after: "cursor_hide"; + } + } + } +}