summaryrefslogtreecommitdiff
path: root/main/src/view/ivug-slider-mouse.c
diff options
context:
space:
mode:
authorKim Kibum <kb0929.kim@samsung.com>2012-06-08 14:54:16 +0900
committerKim Kibum <kb0929.kim@samsung.com>2012-06-08 14:54:16 +0900
commit8b42d4bb33943903b7160bb963bf7e7c6824e9ef (patch)
tree021a596daee9f7e379b8914aad343a2342528e47 /main/src/view/ivug-slider-mouse.c
parent7164c202e81bc53033dce636367d92b93265b915 (diff)
downloadug-image-viewer-efl-8b42d4bb33943903b7160bb963bf7e7c6824e9ef.tar.gz
ug-image-viewer-efl-8b42d4bb33943903b7160bb963bf7e7c6824e9ef.tar.bz2
ug-image-viewer-efl-8b42d4bb33943903b7160bb963bf7e7c6824e9ef.zip
apply FSL(Flora Software License)
Diffstat (limited to 'main/src/view/ivug-slider-mouse.c')
-rwxr-xr-xmain/src/view/ivug-slider-mouse.c439
1 files changed, 439 insertions, 0 deletions
diff --git a/main/src/view/ivug-slider-mouse.c b/main/src/view/ivug-slider-mouse.c
new file mode 100755
index 0000000..2f3f190
--- /dev/null
+++ b/main/src/view/ivug-slider-mouse.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.tizenopensource.org/license
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "ivug-common.h"
+#include "ivug-mouse-event.h"
+#include "ivug-anim.h"
+#include "ivug-slider-item.h"
+#include "ivug-slider.h"
+#include "ivug-effect.h"
+
+#include "ivug-slider-priv.h"
+
+#define SIG_CLICKED "slider,clicked"
+#define SIG_LONGPRESSED "slider,longpressed"
+
+#define SHIFT_THRESHOLD (0.0f) // 52%
+
+
+static bool _ivug_slider_check_flick(MouseEvent *down, MouseEvent *up)
+{
+#define FLICK_TIME_MAX (200) //flick time value.
+#define FLICK_WIDTH_MIN (elm_config_finger_size_get() >> 2)
+
+ if ( up->event_flags & EVAS_EVENT_FLAG_ON_HOLD )
+ {
+ MSG_SLIDER_HIGH("On hold detected");
+ return false;
+ }
+
+// Check pinch zoom right before zoom
+ if ( (up->timestamp - down->timestamp) > FLICK_TIME_MAX )
+ {
+ MSG_SLIDER_HIGH("Not flick opertion. TimeGap=%d", up->timestamp - down->timestamp);
+ return false;
+ }
+
+// TODO : Consider Y axis flick.
+ int delta_x = up->x - down->x;
+ int delta_y = up->y - down->y;
+
+ if (abs(delta_x) < FLICK_WIDTH_MIN)
+ {
+ MSG_SLIDER_HIGH("Not flick opertion. Delta X=%d Delta Y=%d", delta_x, delta_y);
+ return false;
+ }
+
+ return true;
+
+}
+
+
+static bool _ivug_slider_check_click(MouseEvent *down, MouseEvent *up)
+{
+#define CLICK_TIME_MIN (7)
+#define CLICK_TIME_MAX (500) /* 500 < long press */
+
+#define CLICK_WIDTH_MAX (elm_config_finger_size_get() >> 2)
+
+ if ( down->device != up->device )
+ {
+ MSG_SLIDER_HIGH("Not click. Device=%d %d", down->device , up->device);
+ return false;
+ }
+
+ if (up->button_flags & EVAS_BUTTON_DOUBLE_CLICK)
+ {
+ MSG_SLIDER_HIGH("Up.. Double clicked!!");
+ return false;
+ }
+
+ int dTS = (up->timestamp - down->timestamp);
+ if ( (dTS < CLICK_TIME_MIN) || (dTS > CLICK_TIME_MAX) )
+ {
+ MSG_SLIDER_HIGH("Not click. TS=%d", (up->timestamp - down->timestamp));
+ return false;
+ }
+
+ unsigned int dist = get_distance(down->x, down->y, up->x, up->y);
+
+ if ( dist < (unsigned int)CLICK_WIDTH_MAX)
+ {
+ MSG_SLIDER_HIGH("Detect Clicked event. TS=%d, Dist=%d", dTS, dist);
+ return true;
+ }
+
+ MSG_SLIDER_HIGH("Not Click : TS=%dms Dis=%d", dTS, dist);
+
+ return false;
+}
+
+static Eina_Bool _long_pressed(void *data)
+{
+ struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(data);
+
+ if (!sd) return ECORE_CALLBACK_CANCEL;
+
+ sd->long_timer = NULL;
+
+ Evas_Coord_Point down;
+
+ down.x = sd->down.x;
+ down.y = sd->down.y;
+
+ evas_object_smart_callback_call(data, SIG_LONGPRESSED, &down);
+
+ MSG_SLIDER_HIGH("Long pressed!!!!!");
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool _clicked(void *data)
+{
+ struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(data);
+
+ if (!sd) return ECORE_CALLBACK_CANCEL;
+
+ sd->click_timer = NULL;
+
+ Evas_Coord_Point down;
+
+ down.x = sd->down.x;
+ down.y = sd->down.y;
+
+ // Check video icon clicked or not/
+ Slide_Item *si = sd->slide[CENTER_SLIDE];
+
+ if ( ivug_slider_item_icon_click_check(si, down.x, down.y) == true ) // Video icon clicked.
+ {
+ MSG_SLIDER_HIGH("Video icon clicked!!!!!");
+
+ evas_object_smart_callback_call(data, "slider,clicked,icon", &down);
+
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ if(sd->ss_state == SLIDE_SHOW_RUNNING)/* this click is for stop slide show */
+ {
+ ivug_slider_stop_slide_show(sd->obj);
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ evas_object_smart_callback_call(data, SIG_CLICKED, &down); // For change menu visibility
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+
+void _ivug_on_mouse_down(Evas_Object *obj, MouseEvent *down, void *data)
+{
+ struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(data);
+ Slide_Item* si = sd->slide[CENTER_SLIDE];
+
+ MSG_SLIDER_HIGH("%s. down->XY(%d,%d)", __func__, down->x, down->y);
+
+//save down position.
+ sd->down = *down;
+
+// End animation
+ if(sd->animator)
+ {
+ ecore_animator_del(sd->animator);
+ sd->animator = NULL;
+
+ MSG_SLIDER_HIGH("Animation is working. stopping animation. Current SI->XY(%d,%d)", si->x, si->y);
+ }
+
+ sd->edge = _ivug_slider_edge_state_get(si);
+
+ if (down->button_flags & EVAS_BUTTON_DOUBLE_CLICK)
+ {
+ MSG_SLIDER_HIGH("Double clicked!!");
+ }
+
+ if (sd->long_timer)
+ {
+ ecore_timer_del(sd->long_timer);
+ sd->long_timer = NULL;
+ }
+
+ if (sd->click_timer)
+ {
+ ecore_timer_del(sd->click_timer);
+ sd->click_timer = NULL;
+ }
+
+ if ( sd->ss_state == SLIDE_SHOW_RUNNING)
+ {
+// Stop slide show if running. BUG : When user click , menu bar is not visible.
+// Evas_Object *slider = (Evas_Object *)data;
+ //ivug_slider_stop_slide_show(slider); // data is Evas_Object
+
+ return;
+ }
+
+ if ( abs(si->x) < IMAGE_MOVE_MARGIN)
+ {
+ MSG_SLIDER_HIGH("Creating long pressed timer");
+ sd->long_timer = ecore_timer_add(elm_config_longpress_timeout_get(), _long_pressed, data);
+ }
+}
+
+
+void _ivug_on_mouse_up(Evas_Object *obj, MouseEvent *up, void *data)
+{
+ struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(data);
+
+ sd->up = *up;
+
+ Slide_Item *si = sd->slide[CENTER_SLIDE];
+
+ MSG_SLIDER_HIGH("Mouse Up : si->XYWH(%d,%d,%d,%d)", si->x, si->y, si->w, si->h);
+
+ if (sd->long_timer)
+ {
+ ecore_timer_del(sd->long_timer);
+ sd->long_timer = NULL;
+ }
+
+// Find Scroll Direction
+ shift_direction_t dir = SLIDE_SHIFT_NONE;
+
+// TODO How to make simpler below routine???
+ if ( _ivug_slider_check_flick(&sd->down, up) == true) // If flick
+ {
+ int delta_x = up->x - sd->down.x;
+// int delta_y = up->y - sd->down.y;
+
+ {
+ if ( (sd->edge & SLIDE_RIGHT_EDGE) && (delta_x < 0)) // Mouse : <--
+ {
+ // <---------
+ if ( sd->slide[NEXT_SLIDE]->state != SLIDE_STATE_NONE )
+ {
+ dir = SLIDE_SHIFT_TO_RIGHT;
+ }
+ }
+ else if ( (sd->edge & SLIDE_LEFT_EDGE) && (delta_x > 0) ) // Mouse : -->
+ {
+ // ------>
+ if ( sd->slide[PREV_SLIDE]->state != SLIDE_STATE_NONE )
+ {
+ dir = SLIDE_SHIFT_TO_LEFT;
+ }
+ }
+ }
+ }
+ else
+ {
+ MSG_SLIDER_HIGH("Si->x=%d", si->x);
+// if ( si->x == 0 ) // If not moving state
+// {
+ if ( _ivug_slider_check_click(&sd->down, up) == true )
+ {
+ sd->click_timer = ecore_timer_add(0.2f, _clicked, data);
+ // Clicked event
+// evas_object_smart_callback_call(data, SIG_CLICKED, &sd->down.x);
+ }
+
+// }
+
+ // Not flick. check up position.
+ if ( si->x > sd->w * (SHIFT_THRESHOLD) )
+ {
+ // Scroll to --->
+ if ( sd->slide[PREV_SLIDE]->state != SLIDE_STATE_NONE ) // Check left end
+ {
+ dir = SLIDE_SHIFT_TO_LEFT;
+ }
+ }
+ else if (si->x + si->w < sd->w * (1.0f - SHIFT_THRESHOLD) )
+ {
+ // Scroll to <---
+ if ( sd->slide[NEXT_SLIDE]->state != SLIDE_STATE_NONE ) // Check left end
+ {
+ dir = SLIDE_SHIFT_TO_RIGHT;
+ }
+ }
+ }
+
+ switch(dir)
+ {
+ case SLIDE_SHIFT_TO_LEFT:
+ MSG_SLIDER_HIGH("Scroll --->");
+
+ _ivug_slider_slide_update(sd, sd->slide[CENTER_SLIDE]->x,
+ sd->slide[CENTER_SLIDE]->w + IMAGE_BETWEEN_MARGIN);
+ if(sd->ss_state == SLIDE_SHOW_RUNNING)
+ {
+ sd->bSS_SlideFlag = EINA_TRUE;
+ ivug_slider_stop_slide_show(sd->obj);
+ }
+ break;
+
+ case SLIDE_SHIFT_TO_RIGHT:
+ MSG_SLIDER_HIGH("Scroll <---");
+
+ _ivug_slider_slide_update(sd, sd->slide[CENTER_SLIDE]->x,
+ -sd->slide[CENTER_SLIDE]->w - IMAGE_BETWEEN_MARGIN);
+ if(sd->ss_state == SLIDE_SHOW_RUNNING)
+ {
+ sd->bSS_SlideFlag = EINA_TRUE;
+ ivug_slider_stop_slide_show(sd->obj);
+ }
+ break;
+
+ case SLIDE_SHIFT_NONE:
+
+ MSG_SLIDER_HIGH("Scroll to center");
+
+ if ( sd->slide[CENTER_SLIDE]->x == 0 )
+ {
+ MSG_SLIDER_WARN("No need to animation");
+ return;
+ }
+
+ _ivug_slider_slide_update(sd,sd->slide[CENTER_SLIDE]->x , 0);
+
+ break;
+
+ }
+
+
+
+}
+
+
+void _ivug_on_mouse_move(Evas_Object *obj, MouseEvent *prev, MouseEvent *cur, void *data)
+{
+ struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(data);
+ Slide_Item* si = sd->slide[CENTER_SLIDE];
+
+ if (sd->long_timer)
+ {
+ Evas_Coord dx, dy;
+ dx = sd->down.x - cur->x;
+ dx *= dx;
+ dy =sd->down.y - cur->y;
+ dy *= dy;
+
+ if ((dx + dy) > LONG_PRESS_MARGIN * LONG_PRESS_MARGIN)
+ {
+ MSG_SLIDER_HIGH("%s delete long timer. Move:%d Margin:%d", __func__, (dx + dy), LONG_PRESS_MARGIN * LONG_PRESS_MARGIN );
+ ecore_timer_del(sd->long_timer); //delete long press.
+ sd->long_timer = NULL;
+ }
+ }
+// MSG_SLIDER_HIGH("%s. XY(%d,%d)", __func__, cur->x, cur->y);
+// TODO : check slide move threshhold
+ if ( sd->edge == SLIDE_NO_EDGE )
+ {
+ MSG_SLIDER_MED("Photocam handle this event");
+ return;
+ }
+
+ int dst_x, dst_y;
+
+ dst_x = si->x + (cur->x - prev->x);
+ dst_y = si->y + (cur->y - prev->y);
+
+ MSG_SLIDER_MED("%s. Edge=%d Cur XY(%d,%d) Prev XY(%d,%d) SI->XY(%d,%d) Dest(%d,%d)", __func__,sd->edge,
+ cur->x, cur->y, prev->x, prev->y, si->x, si->y, dst_x, dst_y);
+
+// If left-most or right-most image, do not scroll.
+ if ( ivug_slider_item_data_get(sd->slide[NEXT_SLIDE]) == NULL ) // Is left-most image?
+ {
+ MSG_SLIDER_MED("Next item is NULL. dst_x=%d", dst_x);
+
+ if ( dst_x < 0 )
+ {
+ MSG_SLIDER_MED("No allowed scroll to right");
+ _ivug_slider_pass_event_to_item(sd, EINA_FALSE);
+ return;
+ }
+ }
+
+ if ( ivug_slider_item_data_get(sd->slide[PREV_SLIDE]) == NULL ) // Is right-most image?
+ {
+ MSG_SLIDER_MED("Prev item is NULL. dst_x=%d", dst_x);
+ if ( dst_x > 0 )
+ {
+ MSG_SLIDER_MED("No allowed scroll to left");
+ _ivug_slider_pass_event_to_item(sd, EINA_FALSE);
+ return;
+ }
+ }
+ if ( (sd->edge & SLIDE_LEFT_EDGE) && (dst_x > IMAGE_SCROLL_MARGIN))
+ {
+ MSG_SLIDER_MED("Case 1. edge=%d, X=%d", sd->edge, dst_x);
+
+ _ivug_slider_pass_event_to_item(sd, EINA_FALSE);
+
+ _ivug_slider_slide_update_pos(sd, dst_x , si->y); //update
+ _ivug_slider_slide_update_shift(sd);
+
+ return;
+ }
+
+ if ( (sd->edge & SLIDE_RIGHT_EDGE) && (dst_x < -IMAGE_SCROLL_MARGIN))
+ {
+ MSG_SLIDER_MED("Case 2. edge=%d, X=%d", sd->edge, dst_x);
+ _ivug_slider_pass_event_to_item(sd, EINA_FALSE);
+
+ _ivug_slider_slide_update_pos(sd, dst_x , si->y); //update
+ _ivug_slider_slide_update_shift(sd);
+
+ return;
+ }
+
+ if ( (sd->edge & SLIDE_FIT) != SLIDE_FIT)
+ {
+ MSG_SLIDER_MED("Case 3. edge=%d", sd->edge);
+ _ivug_slider_pass_event_to_item(sd, EINA_TRUE); // Send event to phtocam
+ sd->edge = SLIDE_NO_EDGE;
+ }
+
+ if (dst_x >= -IMAGE_SCROLL_MARGIN && dst_x <= IMAGE_SCROLL_MARGIN)
+ {
+ MSG_SLIDER_MED("Case 4. It isn't over IMAGE_SCROLL_MARGIN");
+ return ;
+ }
+
+ MSG_SLIDER_ERROR("Debug Me NEw edge=%d delta_x=%d si->x=%d", sd->edge, dst_x, si->x);
+ return;
+
+}
+