elm_win: add function client can start moving or resizing the window.
authorJi-Youn Park <jy0703.park@samsung.com>
Fri, 25 Nov 2016 02:35:20 +0000 (11:05 +0830)
committerTaehyub Kim <taehyub.kim@samsung.com>
Tue, 29 Nov 2016 12:32:35 +0000 (21:32 +0900)
        The result of this API can only guarantee that the request has been forwared to the server,
        In fact, there is no guarantee that the request can be processed by the server.

        In order to use this API correctly, avoid the following conditions.
        (The following situations will return a failure)

        1. Calling a function in the absence of a touch(mouse) down event.
        2. Calling the function twice more than once before the touch(mouse) up event.
        3. Calling the function when the elm win already resizing or moving the window.
        4. Calling the function using a combination of unsupported modes.

        Right usage
        1. touch(mouse) down event
        2. efl_ui_win_move_resize_start only once using the supported mode combination.
        3. touch(mouse) up event

        If a touch(mouse) up event occurs after calling the function, it automatically ends the window move and resize operation.

        Since there are some non-exclusive modes, you can use a combination of modes.(ELM_WIN_MOVE_RESIZE_MOVE is exclusive with others)
        However, Some combination of mode is limited for technical reasons.
        At present, only the following nine combinations are allowed.
        For more information, see the Elm.Win.Move_Resize_Mode.

        1. EFL_UI_WIN_MOVE_RESIZE_MOVE
        2. EFL_UI_WIN_MOVE_RESIZE_TOP
        3. EFL_UI_WIN_MOVE_RESIZE_BOTTOM
        4. EFL_UI_WIN_MOVE_RESIZE_LEFT
        5. EFL_UI_WIN_MOVE_RESIZE_RIGHT
        6. EFL_UI_WIN_MOVE_RESIZE_TOP | EFL_UI_WIN_MOVE_RESIZE_LEFT
        7. EFL_UI_WIN_MOVE_RESIZE_TOP | EFL_UI_WIN_MOVE_RESIZE_RIGHT
        8. EFL_UI_WIN_MOVE_RESIZE_BOTTOM | EFL_UI_WIN_MOVE_RESIZE_LEFT
        9. EFL_UI_WIN_MOVE_RESIZE_BOTTOM | EFL_UI_WIN_MOVE_RESIZE_RIGHT

Change-Id: I0a101af333212976f303754b679df8d3be85e1b5

src/bin/test_win_state.c
src/lib/elm_win.c
src/lib/elm_win.eo

index dadbbf38f4179ed67881342d779c7f9ebec6dfa0..357cea0d87fc7048c846dd2b5325a50425566f27 100644 (file)
@@ -11,6 +11,9 @@ typedef struct _Testitem
 
 static int rotate_with_resize = 0;
 static Eina_Bool fullscreen = EINA_FALSE;
+static Eina_Bool floating = EINA_FALSE;
+
+static Evas_Object *win1;
 
 static void
 my_bt_38_alpha_on(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
@@ -133,6 +136,15 @@ my_ck_38_borderless(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
    elm_win_borderless_set(win, borderless);
 }
 
+static void
+my_ck_38_floating(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   Evas_Object *win = data;
+   floating = elm_check_state_get(obj);
+   elm_win_floating_mode_set(win, floating);
+   evas_object_resize(win, 720, 800);
+}
+
 static void
 my_win_move(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
 {
@@ -310,12 +322,65 @@ _win_hide(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNU
    printf("win: hide\n");
 }
 
+static void
+_bt_pressed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   int param = (int)(uintptr_t)(data);
+   Eina_Bool res = EINA_FALSE;
+
+   printf("pressed event on Button:%d\n", param);
+
+   switch (param)
+     {
+      case 1:
+        printf("Top Left\n");
+        res = elm_win_move_resize_start(win1, ELM_WIN_MOVE_RESIZE_TOP | ELM_WIN_MOVE_RESIZE_LEFT);
+        break;
+      case 2:
+        printf("Top\n");
+        res = elm_win_move_resize_start(win1, ELM_WIN_MOVE_RESIZE_TOP);
+        break;
+      case 3:
+        printf("Top Right\n");
+        res = elm_win_move_resize_start(win1, ELM_WIN_MOVE_RESIZE_TOP | ELM_WIN_MOVE_RESIZE_RIGHT);
+        break;
+      case 4:
+        printf("Left\n");
+        res = elm_win_move_resize_start(win1, ELM_WIN_MOVE_RESIZE_LEFT);
+        break;
+      case 5:
+        printf("Move win\n");
+        res = elm_win_move_resize_start(win1, ELM_WIN_MOVE_RESIZE_MOVE);
+        break;
+      case 6:
+        printf("Right\n");
+        res = elm_win_move_resize_start(win1, ELM_WIN_MOVE_RESIZE_RIGHT);
+        break;
+      case 7:
+        printf("Bottom Left\n");
+        res = elm_win_move_resize_start(win1, ELM_WIN_MOVE_RESIZE_BOTTOM | ELM_WIN_MOVE_RESIZE_LEFT);
+        break;
+      case 8:
+        printf("Bottom\n");
+        res = elm_win_move_resize_start(win1, ELM_WIN_MOVE_RESIZE_BOTTOM);
+        break;
+      case 9:
+        printf("Bottom Right\n");
+        res = elm_win_move_resize_start(win1, ELM_WIN_MOVE_RESIZE_BOTTOM | ELM_WIN_MOVE_RESIZE_RIGHT);
+        break;
+      default:
+        printf("No action\n");
+   }
+   printf("result = %d\n", res);
+}
+
 void
 test_win_state(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
 {
-   Evas_Object *win, *bg, *sl, *bx, *bx2, *bt, *ck;
+   Evas_Object *bg, *sl, *bx, *bx2, *bt, *ck, *tb, *win;
 
    win = elm_win_add(NULL, "window-states", ELM_WIN_BASIC);
+   win1 = win;
    elm_win_title_set(win, "Window States");
    evas_object_smart_callback_add(win, "moved", my_win_move, NULL);
    evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, _win_resize, NULL);
@@ -526,6 +591,15 @@ test_win_state(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
    evas_object_show(ck);
    elm_box_pack_end(bx, ck);
 
+   ck = elm_check_add(win);
+   elm_object_text_set(ck, "floating");
+   elm_check_state_set(ck, floating);
+   evas_object_smart_callback_add(ck, "changed", my_ck_38_floating, win);
+   evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ck, 0.02, 0.99);
+   evas_object_show(ck);
+   elm_box_pack_end(bx, ck);
+
    bx2 = elm_box_add(win);
    elm_box_horizontal_set(bx2, EINA_TRUE);
    elm_box_homogeneous_set(bx2, EINA_TRUE);
@@ -575,6 +649,90 @@ test_win_state(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
    elm_box_pack_end(bx, bx2);
    evas_object_show(bx2);
 
+   tb = elm_table_add(win);
+   evas_object_size_hint_weight_set(tb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_fill_set(tb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   evas_object_show(tb);
+
+#define INTPTR(i) (void *)(intptr_t)(i)
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Top Left");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(bt, "pressed", _bt_pressed, INTPTR(1));
+   elm_table_pack(tb, bt, 0, 0, 1, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Top");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(bt, "pressed", _bt_pressed, INTPTR(2));
+   elm_table_pack(tb, bt, 1, 0, 1, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Top Right");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(bt, "pressed", _bt_pressed, INTPTR(3));
+   elm_table_pack(tb, bt, 2, 0, 1, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Left");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(bt, "pressed", _bt_pressed, INTPTR(4));
+   elm_table_pack(tb, bt, 0, 1, 1, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Move");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(bt, "pressed", _bt_pressed, INTPTR(5));
+   elm_table_pack(tb, bt, 1, 1, 1, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Right");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(bt, "pressed", _bt_pressed, INTPTR(6));
+   elm_table_pack(tb, bt, 2, 1, 1, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Bot Left");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(bt, "pressed", _bt_pressed, INTPTR(7));
+   elm_table_pack(tb, bt, 0, 2, 1, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Bottom");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(bt, "pressed", _bt_pressed, INTPTR(8));
+   elm_table_pack(tb, bt, 1, 2, 1, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Bot Right");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(bt, "pressed", _bt_pressed, INTPTR(9));
+   elm_table_pack(tb, bt, 2, 2, 1, 1);
+   evas_object_show(bt);
+
+#undef I
+
+   elm_box_pack_end(bx, tb);
+
    evas_object_resize(win, 280, 400);
    evas_object_show(win);
 }
index 7a60aba6c63e8473cf1042316796258d9e798734..d36d67a7ab7e40ed79de6c2fa93e50db9073c962 100644 (file)
@@ -137,6 +137,7 @@ struct _Elm_Win_Data
 
    Ecore_Job                     *deferred_resize_job;
    Ecore_Job                     *deferred_child_eval_job;
+   Ecore_Event_Handler           *mouse_up_handler;//TIZEN_ONLY(20161121) tizen don't have canvas mouse up event like opensource now.
 
    Elm_Win_Type                   type;
    Elm_Win_Keyboard_Mode          kbdmode;
@@ -2246,6 +2247,7 @@ _elm_win_evas_object_smart_del(Eo *obj, Elm_Win_Data *sd)
    ecore_event_handler_del(sd->wl.indicator_flick_handler); // TIZEN_ONLY(20160801): indicator implementation
    ecore_event_handler_del(sd->wl.aux_msg_handler);
 #endif
+   ecore_event_handler_del(sd->mouse_up_handler);//TIZEN_ONLY(20161121) tizen don't have canvas mouse up event like opensource now.
 
    if (sd->img_obj)
      {
@@ -2536,6 +2538,16 @@ _elm_win_wl_effect_end(void *data, int type EINA_UNUSED, void *event)
    return ECORE_CALLBACK_PASS_ON;
 }
 
+static Eina_Bool
+_elm_win_mouse_up(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
+{
+   ELM_WIN_DATA_GET(data, sd);
+
+   if (sd->resizing) sd->resizing = EINA_FALSE;
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+
 static Eina_Bool
 _elm_win_wl_aux_message(void *data, int type EINA_UNUSED, void *event)
 {
@@ -4466,6 +4478,10 @@ _elm_win_finalize_internal(Eo *obj, Elm_Win_Data *sd, const char *name, Elm_Win_
 #endif
    else if ((engine) && (!strncmp(engine, "shot:", 5)))
      _shot_init(sd);
+   //TIZEN_ONLY(20161121) tizen don't have canvas mouse up event like opensource now.
+   //window should deal with mouse up event related with move resize.
+   sd->mouse_up_handler = ecore_event_handler_add
+      (ECORE_EVENT_MOUSE_BUTTON_UP, _elm_win_mouse_up, obj);
 
    sd->kbdmode = ELM_WIN_KEYBOARD_UNKNOWN;
    sd->indmode = ELM_WIN_INDICATOR_UNKNOWN;
@@ -6356,6 +6372,62 @@ _elm_win_socket_listen(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *svcnam
    return EINA_TRUE;
 }
 
+EOLIAN static Eina_Bool
+_elm_win_move_resize_start(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Elm_Win_Move_Resize_Mode mode)
+{
+   Eina_Bool res = EINA_FALSE;
+
+#ifdef HAVE_ELEMENTARY_WAYLAND
+   int i;
+   //1. move_resize can be start after mouse down event
+   i = evas_event_down_count_get(sd->evas);
+   if (i <= 0) return res;
+
+   //2. check move_resize start already .
+   if (sd->resizing) return res;
+
+   i = sd->rot / 90;
+   if (mode == ELM_WIN_MOVE_RESIZE_MOVE)
+     {
+        int ox, oy;
+        sd->resizing = EINA_TRUE;
+        edje_object_part_geometry_get(sd->frame_obj, "elm.spacer.opaque",
+                                  &ox, &oy, NULL, NULL);
+        ecore_evas_wayland_move(sd->ee, ox, oy);
+        res = EINA_TRUE;
+     }
+   else
+     {
+        if(mode == ELM_WIN_MOVE_RESIZE_TOP)
+          sd->resize_location = _border_side[(0 + i) % 4].location;
+        else if (mode == ELM_WIN_MOVE_RESIZE_BOTTOM)
+          sd->resize_location = _border_side[(2 + i) % 4].location;
+        else if (mode == ELM_WIN_MOVE_RESIZE_LEFT)
+          sd->resize_location = _border_side[(1 + i) % 4].location;
+        else if (mode == ELM_WIN_MOVE_RESIZE_RIGHT)
+          sd->resize_location = _border_side[(3 + i) % 4].location;
+        else if (mode == (ELM_WIN_MOVE_RESIZE_TOP | ELM_WIN_MOVE_RESIZE_LEFT))
+          sd->resize_location = _border_corner[(0 + i) % 4].location;
+        else if (mode == (ELM_WIN_MOVE_RESIZE_TOP | ELM_WIN_MOVE_RESIZE_RIGHT))
+          sd->resize_location = _border_corner[(3 + i) % 4].location;
+        else if (mode == (ELM_WIN_MOVE_RESIZE_BOTTOM | ELM_WIN_MOVE_RESIZE_LEFT))
+          sd->resize_location = _border_corner[(1 + i) % 4].location;
+        else if (mode == (ELM_WIN_MOVE_RESIZE_BOTTOM | ELM_WIN_MOVE_RESIZE_RIGHT))
+          sd->resize_location = _border_corner[(2 + i) % 4].location;
+        else
+          sd->resize_location = 0;
+
+        if (sd->resize_location > 0)
+          {
+             sd->resizing = EINA_TRUE;
+             ecore_evas_wayland_resize(sd->ee, sd->resize_location);
+             res = EINA_TRUE;
+          }
+     }
+#endif
+   return res;
+}
+
 /* windowing specific calls - shall we do this differently? */
 
 EOLIAN static Ecore_X_Window
index 2f6de2b01f95b0b769ee7d57502de460be7d8771..302cddec62bfc0797b866d6e0d7590c4f0f88272 100644 (file)
@@ -171,6 +171,35 @@ enum Elm.Illume_Command
    close [[Closes the currently active window]]
 }
 
+enum Elm.Win.Move_Resize_Mode
+{
+   [[Define the move or resize mode of window.
+
+     The user can request the display server to start moving or resizing
+     the window by combining these modes. However, only limited combinations
+     are allowed.
+
+     Currently, only the following 9 combinations are allowed, and possibly
+     more combinations may be added in the future:
+     1. move,
+     2. top,
+     3. bottom,
+     4. left,
+     5. right,
+     6. top | left,
+     7. top | right,
+     8. bottom | left,
+     9. bottom | right.
+   ]]
+   legacy: elm_win_move_resize;
+
+   move = 1,           [[Start moving window]]
+   top = (1 << 1),     [[Start resizing window to the top]]
+   bottom = (1 << 2),  [[Start resizing window to the bottom]]
+   left = (1 << 3),    [[Start resizing window to the left]]
+   right = (1 << 4)    [[Start resizing window to the right]]
+}
+
 class Elm.Win (Elm.Widget, Elm_Interface_Atspi_Window,
                Elm_Interface_Atspi_Widget_Action)
 {
@@ -1770,6 +1799,53 @@ class Elm.Win (Elm.Widget, Elm_Interface_Atspi_Window,
             @in not_modifiers: Evas_Modifier_Mask; [[This is for the keymask feature. Currently this feature is not supported.]]
          }
       }
+      move_resize_start @internal {
+         [[Start moving or resizing the window.
+           
+           The user can request the display server to start moving or resizing
+           the window by combining modes from Elm.Win.Move_Resize_Mode.
+           This API can only be called if none of the following conditions is
+           true:
+
+           1. Called in the absence of a pointer down event,
+           2. Called more than once before a pointer up event,
+           3. Called when the window is already being resized or moved,
+           4. Called with an unsupported combination of modes.
+
+           Right usage:
+           1. Pointer (mouse or touch) down event,
+           2. elm_win_move_resize_start called only once with a supported mode,
+           3. Pointer (mouse or touch) up event.
+   
+           If a pointer up event occurs after calling the function, it
+           automatically ends the window move and resize operation.
+
+           Currently, only the following 9 combinations are allowed, and
+           possibly more combinations may be added in the future:
+
+           1. ELM_WIN_MOVE_RESIZE_MOVE
+           2. ELM_WIN_MOVE_RESIZE_TOP
+           3. ELM_WIN_MOVE_RESIZE_BOTTOM
+           4. ELM_WIN_MOVE_RESIZE_LEFT
+           5. ELM_WIN_MOVE_RESIZE_RIGHT
+           6. ELM_WIN_MOVE_RESIZE_TOP | ELM_WIN_MOVE_RESIZE_LEFT
+           7. ELM_WIN_MOVE_RESIZE_TOP | ELM_WIN_MOVE_RESIZE_RIGHT
+           8. ELM_WIN_MOVE_RESIZE_BOTTOM | ELM_WIN_MOVE_RESIZE_LEFT
+           9. ELM_WIN_MOVE_RESIZE_BOTTOM | ELM_WIN_MOVE_RESIZE_RIGHT
+
+           In particular move and resize can not happen simultaneously.
+
+           Note: the result of this API can only guarantee that the request has
+           been forwarded to the server, but there is no guarantee that the
+           request can be processed by the display server.
+         ]]
+         return: bool; [[$true if the request was successfully sent to the
+                         display server, $false in case of error.]]
+         params {
+            @in mode: Elm.Win.Move_Resize_Mode; [[The requested move or
+                                                     resize mode.]]
+         }
+      }
    }
    implements {
       class.constructor;