from efl import elementary from efl import evas from efl.elementary.window import Window, ELM_WIN_BASIC from efl.elementary.transit import Transit from efl.elementary.gesture_layer import GestureLayer, ELM_GESTURE_ZOOM, \ ELM_GESTURE_MOMENTUM, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_MOVE, \ ELM_GESTURE_STATE_END, ELM_GESTURE_STATE_ABORT, ELM_GESTURE_STATE_START from efl.elementary.background import Background from efl.elementary.layout import Layout from efl.elementary.entry import Entry, ELM_WRAP_MIXED from efl.elementary.icon import Icon from efl.evas import Map, EVAS_HINT_EXPAND, EVAS_EVENT_FLAG_NONE #We zoom out to this value so we'll be able to use map and have a nice #resolution when zooming in. BASE_ZOOM = 0.5 #The amount of zoom to do when "lifting" objects. LIFT_FACTOR = 1.3 #The base size of the shadow image. SHADOW_W = 118 SHADOW_H = 118 zoom_out_animation_duration = 0.4 class Photo_Object(object): ic = None shadow = None hit = None gl = None zoom_out = None # bx, by - current wanted coordinates of the photo object. # bw, bh - original size of the "ic" object. # dx, dy - Used to indicate the distance between the center point # where we put down our fingers (when started moving the item) to # the coords of the object, so we'll be able to calculate movement # correctly. bx, by, bw, bh, dx, dy = None, None, None, None, None, None # Because gesture layer only knows the amount of rotation/zoom we do # per gesture, we have to keep the current rotate/zoom factor and the # one that was before we started the gesture. base_rotate, rotate = None, None base_zoom, zoom = None, None shadow_zoom = None def apply_changes(po): """ This function applies the information from the Photo_Object to the actual evas objects. Zoom/rotate factors and etc. """ map = evas.Map(4) map.point_coord_set(0, po.bx, po.by, 0) map.point_coord_set(1, po.bx + po.bw, po.by, 0) map.point_coord_set(2, po.bx + po.bw, po.by + po.bh, 0) map.point_coord_set(3, po.bx, po.by + po.bh, 0) map.point_image_uv_set(0, 0, 0) map.point_image_uv_set(1, po.bw, 0) map.point_image_uv_set(2, po.bw, po.bh) map.point_image_uv_set(3, 0, po.bh) map.util_rotate(po.rotate, po.bx + po.bw / 2, po.by + po.bh /2) map.util_zoom(po.zoom, po.zoom, po.bx + po.bw / 2, po.by + po.bh /2) po.ic.map_enabled = True po.ic.map = map shadow_map = Map(4) shadow_map.point_coord_set(0, po.bx, po.by, 0) shadow_map.point_coord_set(1, po.bx + po.bw, po.by, 0) shadow_map.point_coord_set(2, po.bx + po.bw, po.by + po.bh, 0) shadow_map.point_coord_set(3, po.bx, po.by + po.bh, 0) shadow_map.point_image_uv_set(0, 0, 0) shadow_map.point_image_uv_set(1, SHADOW_W, 0) shadow_map.point_image_uv_set(2, SHADOW_W, SHADOW_H) shadow_map.point_image_uv_set(3, 0, SHADOW_H) shadow_map.util_rotate(po.rotate, po.bx + po.bw / 2, po.by + po.bh /2) shadow_map.util_zoom(po.zoom * po.shadow_zoom, po.zoom * po.shadow_zoom, po.bx + (po.bw / 2), po.by + (po.bh / 2)) po.shadow.map_enabled = True po.shadow.map = shadow_map #evas_map_free(shadow_map); # Update the position of the hit box po.hit.points_clear() minx, miny, minz = map.point_coord_get(0) maxx = minx maxy = miny po.hit.point_add(minx, miny) for i in range(1, 3): x, y, z = map.point_coord_get(i) po.hit.point_add(x, y) if x < minx: minx = x elif x > maxx: maxx = x if y < miny: miny = y elif y > maxy: maxy = y po.shadow.raise_() po.ic.raise_() po.hit.raise_() #evas_map_free(map); def zoom_out_animation_operation(transit, *args, **kwargs): """Zoom out animation""" po, progress = args po.zoom = BASE_ZOOM + ((po.base_zoom - BASE_ZOOM) * (1.0 - progress)) apply_changes(po) def zoom_out_animation_end(transit, *args, **kwargs): po = args[0] po.base_zoom = po.zoom = BASE_ZOOM apply_changes(po) po.zoom_out = None def rotate_move(event_info, *args, **kwargs): po = args[0] p = event_info print("rotate move <%d,%d> base=<%f> <%f>" % (p.x, p.y, p.base_angle, p.angle)) po.rotate = po.base_rotate + p.angle - p.base_angle if po.rotate < 0: po.rotate += 360 apply_changes(po) return EVAS_EVENT_FLAG_NONE def rotate_end(event_info, *args, **kwargs): po = args[0] p = event_info print("rotate end/abort <%d,%d> base=<%f> <%f>" % (p.x, p.y, p.base_angle, p.angle)) po.base_rotate += p.angle - p.base_angle if po.rotate < 0: po.rotate += 360 return EVAS_EVENT_FLAG_NONE def zoom_start(event_info, *args, **kwargs): po = args[0] p = event_info print("zoom start <%d,%d> <%f>" % (p.x, p.y, p.zoom)) # If there's an active animator, stop it if po.zoom_out: elm_transit_del(po.zoom_out) po.zoom_out = None # Give it a "lift" effect right from the start po.base_zoom = BASE_ZOOM * LIFT_FACTOR po.zoom = po.base_zoom po.shadow_zoom = 1.7 apply_changes(po) return EVAS_EVENT_FLAG_NONE def zoom_move(event_info, *args, **kwargs): po = args[0] p = event_info print("zoom move <%d,%d> <%f>" % (p.x, p.y, p.zoom)) po.zoom = po.base_zoom * p.zoom apply_changes(po); return EVAS_EVENT_FLAG_NONE def zoom_end(event_info, *args, **kwargs): po = args[0] p = event_info print("zoom end/abort <%d,%d> <%f>" % (p.x, p.y, p.zoom)) # Apply the zoom out animator po.shadow_zoom = 1.3 po.base_zoom = po.zoom po.zoom_out = Transit() po.zoom_out.duration = zoom_out_animation_duration po.zoom_out.effect_add(zoom_out_animation_operation, po, zoom_out_animation_end) po.zoom_out.go() return EVAS_EVENT_FLAG_NONE def momentum_start(event_info, *args, **kwargs): po = args[0] p = event_info print("momentum_start <%d,%d>" % (p.x2, p.y2)) po.dx = p.x2 - po.bx po.dy = p.y2 - po.by apply_changes(po) return EVAS_EVENT_FLAG_NONE def momentum_move(event_info, *args, **kwargs): po = args[0] p = event_info print("momentum move <%d,%d>" % (p.x2, p.y2)) po.bx = p.x2 - po.dx po.by = p.y2 - po.dy apply_changes(po) return EVAS_EVENT_FLAG_NONE def momentum_end(event_info, *args, **kwargs): po = args[0] p = event_info print("momentum end/abort <%d,%d> <%d,%d>" % (p.x2, p.y2, p.mx, p.my)) #(void) po; #(void) p; # Make sure middle is in the screen, if not, fix it. # FIXME: Use actual window sizes instead of the hardcoded # values mx = po.bx + (po.bw / 2) my = po.by + (po.bh / 2) if mx < 0: po.bx = 0 - (po.bw / 2) elif mx > 480: po.bx = 480 - (po.bw / 2) if my < 0: po.by = 0 - (po.bw / 2) elif my > 800: po.by = 800 - (po.bh / 2) apply_changes(po) return EVAS_EVENT_FLAG_NONE def photo_object_add(parent, ic, icon, x, y, w, h, angle): po = Photo_Object() po.base_zoom = po.zoom = BASE_ZOOM if ic: po.ic = ic else: po.ic = Icon(parent) po.ic.file = icon po.bx = x po.by = y po.bw = w po.bh = h # Add shadow po.shadow = Icon(po.ic) po.shadow.file = "images/pol_shadow.png" po.shadow.size = SHADOW_W, SHADOW_H po.shadow.show() po.hit = evas.Polygon(parent.evas) po.hit.precise_is_inside = True po.hit.repeat_events = True po.hit.color = 0, 0, 0, 0 po.ic.pos = 0, 0 po.ic.size = po.bw, po.bh po.ic.show() po.hit.show() po.gl = GestureLayer(po.ic) po.gl.hold_events = True po.gl.attach(po.hit) # FIXME: Add a po.rotate start so we take the first angle!!!! po.gl.cb_set(ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_MOVE, rotate_move, po) po.gl.cb_set(ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_END, rotate_end, po) po.gl.cb_set(ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_ABORT, rotate_end, po) po.gl.cb_set(ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START, zoom_start, po) po.gl.cb_set(ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE, zoom_move, po) po.gl.cb_set(ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_END, zoom_end, po) po.gl.cb_set(ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_ABORT, zoom_end, po) po.gl.cb_set(ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_START, momentum_start, po) po.gl.cb_set(ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_MOVE, momentum_move, po) po.gl.cb_set(ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_END, momentum_end, po) po.gl.cb_set(ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_ABORT, momentum_end, po) po.rotate = po.base_rotate = angle po.shadow_zoom = 1.3 apply_changes(po) return po def gesture_layer_clicked(obj): w = 480 h = 800 win = Window("gesture-layer", ELM_WIN_BASIC) win.title = "Gesture Layer" win.autodel = True win.size = w, h bg = Background(win) bg.file = "images/wood_01.jpg" bg.size_hint_weight = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND win.resize_object_add(bg) bg.show() photos = [] photos.append(photo_object_add(win, None, "images/pol_sky.png", 200, 200, 365, 400, 0)) photos.append(photo_object_add(win, None, "images/pol_twofish.png", 40, 300, 365, 400, 45)) en = Entry(win) en.text = "You can use whatever object you want, even entries like this." en.line_wrap = ELM_WRAP_MIXED postit = Layout(win) postit.file = "postit_ent.edj", "main" postit.part_content_set("ent", en) photos.append(photo_object_add(win, postit, None, 50, 50, 382, 400, 355)) win.callback_delete_request_add(lambda o: elementary.exit()) win.show() if __name__ == "__main__": elementary.init() gesture_layer_clicked(None) elementary.run() elementary.shutdown()