2 * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "sclkeyfocushandler.h"
18 #include <Elementary.h>
24 #include "sclres_type.h"
26 #include "sclcontext.h"
27 #include "sclresourcecache.h"
28 #include "sclwindows.h"
29 #include "scleventhandler.h"
30 #include "sclres_manager.h"
31 #include "sclanimator.h"
38 CSCLKeyFocusHandler::CSCLKeyFocusHandler()
42 m_keyboard_grabbed = FALSE;
44 m_focus_key = NOT_USED;
45 m_focus_window = SCLWINDOW_INVALID;
47 #ifdef TARGET_EMULATOR
48 create_sniffer_window();
55 CSCLKeyFocusHandler::~CSCLKeyFocusHandler()
61 CSCLKeyFocusHandler::get_instance()
63 static CSCLKeyFocusHandler instance;
69 * Grabs the navigation and Return keys
72 CSCLKeyFocusHandler::grab_keyboard(const sclwindow parent)
75 Evas_Object *window = (Evas_Object *)parent;
76 Ecore_X_Window x_window = elm_win_xwindow_get(window);
78 Display *x_display = (Display *)ecore_x_display_get();
81 grab_result = utilx_grab_key(x_display, x_window, "Return", EXCLUSIVE_GRAB);
82 if (0 == grab_result) {
83 LOGD("Return Key Grabbed successfully\n");
84 } else if (EXCLUSIVE_GRABBED_ALREADY == grab_result) {
85 LOGD("Return Key already grabbed in Exclusiv mode\n");
87 LOGD("Failed to Grab Return key\n");
90 m_keyboard_grabbed = TRUE;
95 * UnGrabs the navigation and Return keys
98 CSCLKeyFocusHandler::ungrab_keyboard(const sclwindow parent)
101 Evas_Object *window = (Evas_Object *)parent;
102 Ecore_X_Window x_window = elm_win_xwindow_get(window);
103 Display *x_display = (Display *)ecore_x_display_get();
105 grab_result = utilx_ungrab_key(x_display, x_window, "Return");
106 if (0 == grab_result) {
107 LOGD("Return Key UnGrabbed successfully\n");
109 LOGD("Failed to UnGrab Return key\n");
112 m_keyboard_grabbed = FALSE;
115 #endif /*USING_KEY_GRAB*/
119 CSCLKeyFocusHandler::popup_opened(sclwindow window)
124 CSCLKeyFocusHandler::popup_closed(sclwindow window)
126 sclshort layout = NOT_USED;
127 CSCLContext *context = CSCLContext::get_instance();
128 CSCLWindows *windows = CSCLWindows::get_instance();
129 SclResParserManager *sclres_manager = SclResParserManager::get_instance();
130 PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = NULL;
132 if (context && windows && sclres_manager) {
133 sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
134 layout = context->get_popup_layout(m_focus_window);
136 if (windows && sclres_layout_key_coordinate_pointer_frame &&
137 scl_check_arrindex(layout, MAX_SCL_LAYOUT) && scl_check_arrindex(m_focus_key, MAX_KEY)) {
138 SclLayoutKeyCoordinatePointer cur = sclres_layout_key_coordinate_pointer_frame[layout][m_focus_key];
139 SclWindowContext *window_context = windows->get_window_context(m_focus_window);
140 SclRectangle cur_key_coordinate = {0, 0, 0, 0};
141 if (window_context) {
142 cur_key_coordinate.x = cur->x + window_context->geometry.x;
143 cur_key_coordinate.y = cur->y + window_context->geometry.y;
144 cur_key_coordinate.width = cur->width;
145 cur_key_coordinate.height = cur->height;
148 m_focus_window = windows->get_base_window();
149 m_focus_key = get_next_candidate_key(HIGHLIGHT_NAVIGATE_NONE, cur_key_coordinate, windows->get_base_window()).candidate;
154 * Resets the navigation info
157 CSCLKeyFocusHandler::reset_key_navigation_info(sclwindow window)
159 CSCLWindows *windows = CSCLWindows::get_instance();
161 if (windows->is_base_window(window)) {
162 m_focus_window = window;
169 * Compares the sub-layout values
172 CSCLKeyFocusHandler::sub_layout_match(sclchar *layout1, sclchar *layout2)
176 if (strcmp(layout1, layout2) == 0) {
180 } else if (layout2) {
189 * Builds the key navigation info
192 CSCLKeyFocusHandler::update_key_navigation_info(sclwindow window, scl8 index, SclLayoutKeyCoordinatePointer p_next_key)
197 * Finalize the navigation info
200 CSCLKeyFocusHandler::finalize_key_navigation_info(sclwindow window)
205 * Initializes the key index to first key of first row
208 CSCLKeyFocusHandler::init_key_index()
213 * Returns the currently focused key index
216 CSCLKeyFocusHandler::get_current_focus_key(void)
222 * Returns the currently focused window
225 CSCLKeyFocusHandler::get_current_focus_window(void)
227 return m_focus_window;
231 #define min(a, b) (((a) < (b)) ? (a) : (b))
234 #define max(a, b) (((a) > (b)) ? (a) : (b))
236 /* If 2 lines overlap, this will return minus value of overlapping length,
237 and return positive distance value otherwise */
238 int calculate_distance(int start_1, int end_1, int start_2, int end_2)
240 return -1 * (min(end_1, end_2) - max(start_1, start_2));
244 * Computes and Returns the key index for next focussed key depending upon the navigation direction
247 CSCLKeyFocusHandler::get_next_candidate_key(SCLHighlightNavigationDirection direction, SclRectangle cur, sclwindow window)
249 NEXT_CANDIDATE_INFO ret;
250 ret.candidate = NOT_USED;
251 ret.candidate_otherside = NOT_USED;
253 int candidate = NOT_USED;
254 int candidate_distance_x = INT_MAX;
255 int candidate_distance_y = INT_MAX;
256 int startpos_identical = FALSE;
258 int otherside_candidate = NOT_USED;
260 sclshort layout = NOT_USED;
262 CSCLContext *context = CSCLContext::get_instance();
263 CSCLWindows *windows = CSCLWindows::get_instance();
264 CSCLResourceCache *cache = CSCLResourceCache::get_instance();
266 SclResParserManager *sclres_manager = SclResParserManager::get_instance();
267 PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = NULL;
269 if (context && windows && sclres_manager) {
270 sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
272 if (windows->is_base_window(window)) {
273 layout = context->get_base_layout();
275 layout = context->get_popup_layout(window);
279 if (windows && cache && context &&
280 sclres_layout_key_coordinate_pointer_frame && scl_check_arrindex(layout, MAX_SCL_LAYOUT)) {
281 for (sclint loop = 0;loop < MAX_KEY; loop++) {
282 SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout][loop];
283 if (p && (loop != m_focus_key || window != m_focus_window)) {
284 if (p->sub_layout && context->get_cur_sublayout()) {
285 if (!sub_layout_match(p->sub_layout, context->get_cur_sublayout())) {
289 SclWindowContext *window_context = windows->get_window_context(window);
290 SclRectangle btn = {0, 0, 0, 0};
291 if (window_context) {
292 btn.x = p->x + window_context->geometry.x;
293 btn.y = p->y + window_context->geometry.y;
294 btn.width = p->width;
295 btn.height = p->height;
297 if (windows->is_base_window(window)) {
298 btn.x += cache->get_custom_starting_coordinates().x;
299 btn.y += cache->get_custom_starting_coordinates().y;
306 case HIGHLIGHT_NAVIGATE_LEFT:
307 temp_distance_y = calculate_distance(btn.y, btn.y + btn.height, cur.y, cur.y + cur.height);
308 //if (temp_distance_y <= candidate_distance_y) {
309 if (temp_distance_y <= candidate_distance_y && temp_distance_y < 0) {
310 /* If the button is closer in Y axis, consider this to be the closer regardless of X */
311 if (temp_distance_y < candidate_distance_y) {
312 /* Only if the ypos were not the same */
313 if (!startpos_identical) {
314 candidate_distance_x = INT_MAX;
317 /* Save for otherside */
318 otherside_candidate = loop;
319 temp_distance_x = calculate_distance(btn.x, btn.x + btn.width, cur.x, cur.x + cur.width);
320 if (temp_distance_x < candidate_distance_x) {
323 candidate_distance_x = temp_distance_x;
324 candidate_distance_y = temp_distance_y;
325 startpos_identical = (btn.y == cur.y);
330 case HIGHLIGHT_NAVIGATE_RIGHT:
331 temp_distance_y = calculate_distance(btn.y, btn.y + btn.height, cur.y, cur.y + cur.height);
332 //if (temp_distance_y <= candidate_distance_y) {
333 if (temp_distance_y <= candidate_distance_y && temp_distance_y < 0) {
334 /* If the button is closer in Y axis, consider this to be the closer regardless of X */
335 if (temp_distance_y < candidate_distance_y) {
336 /* Only if the ypos were not the same */
337 if (!startpos_identical) {
338 candidate_distance_x = INT_MAX;
341 /* Save for otherside */
342 if (otherside_candidate == NOT_USED) {
343 otherside_candidate = loop;
345 temp_distance_x = calculate_distance(btn.x, btn.x + btn.width, cur.x, cur.x + cur.width);
346 if (temp_distance_x < candidate_distance_x) {
349 candidate_distance_x = temp_distance_x;
350 candidate_distance_y = temp_distance_y;
351 startpos_identical = (btn.y == cur.y);
356 case HIGHLIGHT_NAVIGATE_UP:
357 temp_distance_x = calculate_distance(btn.x, btn.x + btn.width, cur.x, cur.x + cur.width);
358 if (temp_distance_x <= candidate_distance_x) {
359 /* If the button is closer in X axis, consider this to be the closer regardless of Y */
360 if (temp_distance_x < candidate_distance_x) {
361 /* Only if the xpos were not the same */
362 if (!startpos_identical) {
363 candidate_distance_y = INT_MAX;
366 temp_distance_y = calculate_distance(btn.y, btn.y + btn.height, cur.y, cur.y + cur.height);
367 if (temp_distance_y < candidate_distance_y) {
370 candidate_distance_x = temp_distance_x;
371 candidate_distance_y = temp_distance_y;
372 startpos_identical = (btn.x == cur.x);
377 case HIGHLIGHT_NAVIGATE_DOWN:
378 temp_distance_x = calculate_distance(btn.x, btn.x + btn.width, cur.x, cur.x + cur.width);
379 if (temp_distance_x <= candidate_distance_x) {
380 /* If the button is closer in X axis, consider this to be the closer regardless of Y */
381 if (temp_distance_x < candidate_distance_x) {
382 /* Only if the xpos were not the same */
383 if (!startpos_identical) {
384 candidate_distance_y = INT_MAX;
387 temp_distance_y = calculate_distance(btn.y, btn.y + btn.height, cur.y, cur.y + cur.height);
388 if (temp_distance_y < candidate_distance_y) {
391 candidate_distance_x = temp_distance_x;
392 candidate_distance_y = temp_distance_y;
393 startpos_identical = (btn.x == cur.x);
399 temp_distance_y = calculate_distance(btn.y, btn.y + btn.height, cur.y, cur.y + cur.height);
400 if (temp_distance_y <= candidate_distance_y) {
401 temp_distance_x = calculate_distance(btn.x, btn.x + btn.width, cur.x, cur.x + cur.width);
402 if (temp_distance_x <= candidate_distance_x) {
404 candidate_distance_x = temp_distance_x;
405 candidate_distance_y = temp_distance_y;
413 ret.candidate = candidate;
414 ret.candidate_otherside = otherside_candidate;
420 static void copy_rectangle(SclLayoutKeyCoordinatePointer src, SclRectangle *dest)
423 (dest)->x = (src)->x;
424 (dest)->y = (src)->y;
425 (dest)->width = (src)->width;
426 (dest)->height = (src)->height;
431 CSCLKeyFocusHandler::process_navigation(SCLHighlightNavigationDirection direction)
433 CSCLContext *context = CSCLContext::get_instance();
434 CSCLWindows *windows = CSCLWindows::get_instance();
435 CSCLEventHandler *handler = CSCLEventHandler::get_instance();
436 CSCLResourceCache *cache = CSCLResourceCache::get_instance();
437 SclResParserManager *sclres_manager = SclResParserManager::get_instance();
439 if (!context || !windows || !handler || !cache || !sclres_manager) return;
441 sclshort layout = NOT_USED;
443 sclwindow prev_window = m_focus_window;
444 scl8 prev_key = m_focus_key;
445 sclwindow next_window = m_focus_window;
446 scl8 next_key = m_focus_key;
448 PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = NULL;
450 if (context && windows && handler && sclres_manager) {
451 sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
453 if (windows->is_base_window(m_focus_window)) {
454 layout = context->get_base_layout();
456 layout = context->get_popup_layout(m_focus_window);
460 if (sclres_layout_key_coordinate_pointer_frame && context->get_highlight_ui_enabled() &&
461 scl_check_arrindex(layout, MAX_SCL_LAYOUT) && scl_check_arrindex(m_focus_key, MAX_KEY)) {
462 SclLayoutKeyCoordinatePointer cur = sclres_layout_key_coordinate_pointer_frame[layout][m_focus_key];
464 /* To compare with buttons in popup window, let's convert to global coordinates */
465 SclWindowContext *window_context = windows->get_window_context(m_focus_window);
466 SclRectangle cur_key_coordinate = {0, 0, 0, 0};
467 if (window_context && cur && cache) {
468 cur_key_coordinate.x = cur->x + window_context->geometry.x;
469 cur_key_coordinate.y = cur->y + window_context->geometry.y;
470 cur_key_coordinate.width = cur->width;
471 cur_key_coordinate.height = cur->height;
473 if (windows->is_base_window(m_focus_window)) {
474 cur_key_coordinate.x += cache->get_custom_starting_coordinates().x;
475 cur_key_coordinate.y += cache->get_custom_starting_coordinates().y;
479 NEXT_CANDIDATE_INFO base_candidate;
480 base_candidate.candidate = base_candidate.candidate_otherside = NOT_USED;
481 NEXT_CANDIDATE_INFO popup_candidate;
482 popup_candidate.candidate = popup_candidate.candidate_otherside = NOT_USED;
483 sclboolean search_in_base_window = TRUE;
484 sclboolean exclude_popup_covered_area = FALSE;
486 if (windows && !windows->is_base_window(windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP))) {
487 if (cache && window_context && scl_check_arrindex(window_context->inputmode, MAX_SCL_INPUT_MODE)) {
488 const SclLayout *cur_layout =
489 cache->get_cur_layout(windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP));
491 if (!(cur_layout->use_sw_background) || cur_layout->bg_color.a != 0) {
492 const PSclInputModeConfigure sclres_input_mode_configure =
493 sclres_manager->get_input_mode_configure_table();
494 if (sclres_input_mode_configure && sclres_input_mode_configure[window_context->inputmode].use_dim_window) {
495 search_in_base_window = FALSE;
497 exclude_popup_covered_area = TRUE;
502 popup_candidate = get_next_candidate_key(direction, cur_key_coordinate,
503 windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP));
505 /* Now search buttons in base window */
506 if (search_in_base_window && windows) {
507 base_candidate = get_next_candidate_key(direction, cur_key_coordinate, windows->get_base_window());
510 if (popup_candidate.candidate == NOT_USED && base_candidate.candidate != NOT_USED) {
511 next_window = windows->get_base_window();
512 next_key = base_candidate.candidate;
513 } else if (popup_candidate.candidate != NOT_USED && base_candidate.candidate == NOT_USED) {
514 next_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
515 next_key = popup_candidate.candidate;
516 } else if (popup_candidate.candidate == NOT_USED && base_candidate.candidate == NOT_USED) {
517 if (base_candidate.candidate_otherside != NOT_USED) {
518 next_window = windows->get_base_window();
519 next_key = base_candidate.candidate_otherside;
520 } else if (popup_candidate.candidate_otherside != NOT_USED) {
521 next_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
522 next_key = popup_candidate.candidate_otherside;
525 /* Compare those 2 candidates */
526 sclwindow popup_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
527 sclshort base_layout = context->get_base_layout();
528 sclshort popup_layout = context->get_popup_layout(popup_window);
530 SclLayoutKeyCoordinatePointer base_key = NULL;
531 SclLayoutKeyCoordinatePointer popup_key = NULL;
532 SclWindowContext *base_window_context = NULL;
533 SclWindowContext *popup_window_context = NULL;
535 if (scl_check_arrindex(base_layout, MAX_SCL_LAYOUT) && scl_check_arrindex(popup_layout, MAX_SCL_LAYOUT)) {
536 base_key = sclres_layout_key_coordinate_pointer_frame[base_layout][base_candidate.candidate];
537 popup_key = sclres_layout_key_coordinate_pointer_frame[popup_layout][popup_candidate.candidate];
538 base_window_context = windows->get_window_context(windows->get_base_window());
539 popup_window_context = windows->get_window_context(popup_window);
542 SclRectangle base_key_coordinate = {0, 0, 0, 0};
543 if (base_window_context) {
544 base_key_coordinate.x = base_key->x + base_window_context->geometry.x;
545 base_key_coordinate.y = base_key->y + base_window_context->geometry.y;
546 base_key_coordinate.width = base_key->width;
547 base_key_coordinate.height = base_key->height;
549 base_key_coordinate.x += cache->get_custom_starting_coordinates().x;
550 base_key_coordinate.y += cache->get_custom_starting_coordinates().y;
553 SclRectangle popup_key_coordinate = {0, 0, 0, 0};
554 if (popup_window_context) {
555 popup_key_coordinate.x = popup_key->x + popup_window_context->geometry.x;
556 popup_key_coordinate.y = popup_key->y + popup_window_context->geometry.y;
557 popup_key_coordinate.width = popup_key->width;
558 popup_key_coordinate.height = popup_key->height;
561 if (exclude_popup_covered_area) {
562 CSCLUtils *utils = CSCLUtils::get_instance();
563 if (utils && popup_window_context) {
564 /* If the base candidate key is covered by popup window, do not choose it */
565 if (utils->is_rect_overlap(base_key_coordinate, popup_window_context->geometry)) {
566 base_candidate.candidate = NOT_USED;
570 /* If the base candidate key wasn't excluded */
571 if (base_candidate.candidate != NOT_USED) {
572 int base_distance_x = INT_MAX;
573 int base_distance_y = INT_MAX;
574 int popup_distance_x = INT_MAX;
575 int popup_distance_y = INT_MAX;
577 base_distance_x = calculate_distance(
578 cur_key_coordinate.x, cur_key_coordinate.x + cur_key_coordinate.width,
579 base_key_coordinate.x, base_key_coordinate.x + base_key_coordinate.width);
580 base_distance_y = calculate_distance(
581 cur_key_coordinate.y, cur_key_coordinate.y + cur_key_coordinate.height,
582 base_key_coordinate.y, base_key_coordinate.y + base_key_coordinate.height);
584 popup_distance_x = calculate_distance(
585 cur_key_coordinate.x, cur_key_coordinate.x + cur_key_coordinate.width,
586 popup_key_coordinate.x, popup_key_coordinate.x + popup_key_coordinate.width);
587 popup_distance_y = calculate_distance(
588 cur_key_coordinate.y, cur_key_coordinate.y + cur_key_coordinate.height,
589 popup_key_coordinate.y, popup_key_coordinate.y + popup_key_coordinate.height);
591 if (direction == HIGHLIGHT_NAVIGATE_LEFT || direction == HIGHLIGHT_NAVIGATE_RIGHT) {
592 int minimum_distance = -1 * (cur_key_coordinate.height / 3);
593 if (base_distance_y > minimum_distance && popup_distance_y > minimum_distance) {
594 minimum_distance = 0;
596 if (base_distance_y < minimum_distance && popup_distance_y < minimum_distance) {
597 if (base_distance_x < popup_distance_x) {
598 next_window = windows->get_base_window();
599 next_key = base_candidate.candidate;
601 next_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
602 next_key = popup_candidate.candidate;
604 } else if (base_distance_y < minimum_distance) {
605 next_window = windows->get_base_window();
606 next_key = base_candidate.candidate;
608 next_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
609 next_key = popup_candidate.candidate;
611 } else if (direction == HIGHLIGHT_NAVIGATE_UP || direction == HIGHLIGHT_NAVIGATE_DOWN) {
612 int minimum_distance = -1 * (cur_key_coordinate.width / 3);
613 if (base_distance_x > minimum_distance && popup_distance_x > minimum_distance) {
614 minimum_distance = 0;
616 if (base_distance_x < minimum_distance && popup_distance_x < minimum_distance) {
617 if (base_distance_y < popup_distance_y) {
618 next_window = windows->get_base_window();
619 next_key = base_candidate.candidate;
621 next_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
622 next_key = popup_candidate.candidate;
624 } else if (base_distance_x < minimum_distance) {
625 next_window = windows->get_base_window();
626 next_key = base_candidate.candidate;
628 next_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
629 next_key = popup_candidate.candidate;
635 SclNotiHighlightNavigateDesc desc;
636 desc.direction = direction;
637 desc.window_from = prev_window;
638 desc.key_from = prev_key;
639 desc.window_to = next_window;
640 desc.key_to = next_key;
641 if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_HIGHLIGHT_NAVIGATE, &desc)) {
642 CSCLAnimator *animator = CSCLAnimator::get_instance();
644 sclboolean start_animation = FALSE;
645 if (windows->is_base_window(desc.window_to) && windows->is_base_window(desc.window_from)) {
646 if (desc.key_to != desc.key_from) {
647 start_animation = TRUE;
650 SclWindowContext *window_context_from = windows->get_window_context(desc.window_from);
651 SclWindowContext *window_context_to = windows->get_window_context(desc.window_to);
652 if (window_context_from && window_context_to) {
653 if ((windows->is_base_window(desc.window_from) || window_context_from->is_virtual) &&
654 (windows->is_base_window(desc.window_to) || window_context_to->is_virtual)) {
655 start_animation = TRUE;
659 sclshort layout_from = NOT_USED;
660 sclshort layout_to = NOT_USED;
661 if (windows->is_base_window(desc.window_from)) {
662 layout_from = context->get_base_layout();
664 layout_from = context->get_popup_layout(desc.window_from);
666 if (windows->is_base_window(desc.window_to)) {
667 layout_to = context->get_base_layout();
669 layout_to = context->get_popup_layout(desc.window_to);
671 if (!scl_check_arrindex(desc.key_from, MAX_KEY) || !scl_check_arrindex(desc.key_to, MAX_KEY) ||
672 !scl_check_arrindex(layout_from, MAX_SCL_LAYOUT) || !scl_check_arrindex(layout_to, MAX_SCL_LAYOUT)) {
673 start_animation = FALSE;
675 if (start_animation &&
676 context->get_highlight_ui_enabled() &&
677 context->get_highlight_ui_animation_enabled() &&
678 animator->check_animation_supported()) {
679 SclLayoutKeyCoordinatePointer prev_coordinate =
680 sclres_layout_key_coordinate_pointer_frame[layout_from][desc.key_from];
681 SclLayoutKeyCoordinatePointer next_coordinate =
682 sclres_layout_key_coordinate_pointer_frame[layout_to][desc.key_to];
684 SclRectangle prev_rect;
685 SclRectangle next_rect;
686 copy_rectangle(prev_coordinate, &(prev_rect));
687 copy_rectangle(next_coordinate, &(next_rect));
689 if (windows->is_base_window(desc.window_from)) {
690 prev_rect.x += cache->get_custom_starting_coordinates().x;
691 prev_rect.y += cache->get_custom_starting_coordinates().y;
693 /* Convert popup window coordinates relative to base window */
694 SclWindowContext *base_window_context =
695 windows->get_window_context(windows->get_base_window());
696 SclWindowContext *prev_window_context =
697 windows->get_window_context(desc.window_from);
698 if (base_window_context && prev_window_context) {
699 prev_rect.x += (prev_window_context->geometry.x - base_window_context->geometry.x);
700 prev_rect.y += (prev_window_context->geometry.y - base_window_context->geometry.y);
703 if (windows->is_base_window(desc.window_to)) {
704 next_rect.x += cache->get_custom_starting_coordinates().x;
705 next_rect.y += cache->get_custom_starting_coordinates().y;
707 /* Convert popup window coordinates relative to base window */
708 SclWindowContext *base_window_context =
709 windows->get_window_context(windows->get_base_window());
710 SclWindowContext *next_window_context =
711 windows->get_window_context(desc.window_to);
712 if (base_window_context && next_window_context) {
713 next_rect.x += (next_window_context->geometry.x - base_window_context->geometry.x);
714 next_rect.y += (next_window_context->geometry.y - base_window_context->geometry.y);
717 /* Let's check if the navigation animation should be in circular movement */
718 sclboolean circular = FALSE;
719 /* If our 2 buttons overlap in Y axis */
720 if (calculate_distance(
721 prev_rect.y, prev_rect.y + prev_rect.height,
722 next_rect.y, next_rect.y + next_rect.height) < 0) {
723 /* And if those 2 buttons are side buttons, let's run the animation in circular mode */
724 if (prev_coordinate->is_side_button && next_coordinate->is_side_button) {
729 sclint id = animator->find_animator_by_type(ANIMATION_TYPE_HIGHLIGHT_UI);
730 if (id == NOT_USED) {
731 SclAnimationDesc animdesc;
732 animdesc.type = ANIMATION_TYPE_HIGHLIGHT_UI;
733 animdesc.length = SCL_ANIMATION_TIME;
735 animdesc.rect_from = prev_rect;
736 animdesc.rect_to = next_rect;
738 animdesc.window_from = desc.window_from;
739 animdesc.window_to = desc.window_to;
740 animdesc.circular = circular;
742 id = animator->create_animator(&animdesc);
743 animator->start_animator(id);
745 SclAnimationState *state = animator->get_animation_state(id);
748 /* FIXME : When we have time later,
749 let's use the currect rect so that the animation starts from the current position,
750 considering the circular movement case */
751 //state->desc.rect_from = state->rect_cur;
752 state->desc.rect_from = prev_rect;
754 state->active = TRUE;
755 state->desc.rect_from = prev_rect;
758 state->desc.circular = circular;
760 state->desc.rect_to = next_rect;
762 state->desc.window_from = desc.window_from;
763 state->desc.window_to = desc.window_to;
765 animator->start_animator(id);
769 m_focus_window = desc.window_to;
770 m_focus_key = desc.key_to;
776 CSCLKeyFocusHandler::set_current_focus(sclwindow window, scl8 index)
778 m_focus_window = window;
782 #ifdef TARGET_EMULATOR
785 * callback for window show event (sniffer window)
787 static void sniffer_window_show_cb(void *data, Evas *e, Evas_Object *obj, void *event)
789 LOGD("INSIDE =-=-=-=- x_event_sniffer_window_show_cb, Trying to Grab Key Board : \n");
791 Eina_Bool ret = ecore_x_keyboard_grab(x_window);
793 if (EINA_TRUE == ret) {
794 LOGD("Keyboard Grabbed successfully by sniffer\n");
796 LOGD("Failed to Grab keyboard by sniffer\n");
802 * sniffer window creation function, the keyboard would be grabbed by this window in case of Tizen Emulator
805 CSCLKeyFocusHandler::create_sniffer_window(void)
807 LOGD("CSCLKeyFocusHandler : INSIDE =-=-=-=- create_sniffer_window : \n");
808 Evas_Object *win = NULL;
810 win = elm_win_add(NULL, "KEY_SNIFFER", ELM_WIN_UTILITY);
812 elm_win_borderless_set(win, EINA_TRUE);
813 elm_win_alpha_set(win, EINA_FALSE);
814 elm_win_title_set(win, "KEY_SNIFFER");
815 elm_win_fullscreen_set(win, EINA_FALSE);
816 set_window_accepts_focus(win, FALSE);
817 evas_object_show(win);
818 evas_object_resize(win, 100, 100);
821 evas_object_event_callback_add(win, EVAS_CALLBACK_SHOW, sniffer_window_show_cb, NULL);
825 CSCLKeyFocusHandler::set_window_accepts_focus(const sclwindow window, sclboolean acceptable)
827 elm_win_prop_focus_skip_set(static_cast<Evas_Object*>(window), !acceptable);