scl/scldebug.cpp
scl/sclutils.cpp
scl/sclcontroller.cpp
+ scl/sclcontroller_button.cpp
+ scl/sclcontroller_mouse.cpp
scl/sclgwes.cpp
scl/sclevents.cpp
scl/sclwindows-efl.cpp
#include <vector>
#include "sclcontroller.h"
+#include "sclcontroller_button.h"
#include "scldebug.h"
#include "sclresourcecache.h"
#include "sclactionstate.h"
return ret;
}
-sclboolean
-CSCLController::process_button_pressed_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
- scltouchdevice touch_id, sclboolean actual_event)
-{
- SCL_DEBUG();
-
- sclboolean ret = FALSE;
- sclboolean redraw = FALSE;
-
- CSCLContext *context = CSCLContext::get_instance();
- CSCLResourceCache *cache = CSCLResourceCache::get_instance();
- CSCLWindows *windows = CSCLWindows::get_instance();
- CSCLEvents *events = CSCLEvents::get_instance();
- CSCLUtils *utils = CSCLUtils::get_instance();
- CSCLFeedback *feedback = CSCLFeedback::get_instance();
- CSCLEventHandler *handler = CSCLEventHandler::get_instance();
- SclResParserManager *sclres_manager = SclResParserManager::get_instance();
-
- if (!sclres_manager) return FALSE;
-
- PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
- PSclLayout sclres_layout = sclres_manager->get_layout_table();
- if (!sclres_input_mode_configure || !sclres_layout) return FALSE;
-
- SclButtonContext *button_context = NULL;
- const SclLayoutKeyCoordinate *coordinate = NULL;
-
- if (context && cache) {
- button_context = cache->get_cur_button_context(window, key_index);
- coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
- }
-
- if (context && cache && windows && events && utils && feedback && handler && button_context && coordinate) {
- /* First check if this button is enabled in current active sublayout */
- sclboolean sub_layout_match = TRUE;
- if (coordinate->sub_layout && context->get_cur_sublayout()) {
- if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
- sub_layout_match = FALSE;
- }
- }
-
- /* If this button is pressed */
- if ( x >= coordinate->x - coordinate->add_hit_left &&
- x < coordinate->x + coordinate->width + coordinate->add_hit_right &&
- y >= coordinate->y - coordinate->add_hit_top &&
- y < coordinate->y + coordinate->height + coordinate->add_hit_bottom &&
- /* Process the event only if the this item's sublayout id is active one */
- sub_layout_match ) {
- /* If currently shift mode is ON, and the last key was multitap, this means the shift did not
- turned off because of multitap button. So we need to turn it off here forcibly */
- sclwindow last_win = context->get_last_event_fired_window();
- scl8 last_key = context->get_last_event_fired_key();
- LOGD("last_win : %p last_key : :%d", last_win, last_key);
- const SclLayoutKeyCoordinate *last_coordinate = cache->get_cur_layout_key_coordinate(last_win, last_key);
- if (last_coordinate) {
- LOGD("last_coordinate->button_type : %d", last_coordinate->button_type);
- if (last_coordinate->button_type == BUTTON_TYPE_MULTITAP && context->get_shift_state() == SCL_SHIFT_STATE_ON) {
- /* And if the multitap button was different from the one we are dealing with... */
- LOGD("last_win %p window %p last_key %d key_index %d", last_win, window, last_key, key_index);
- if (last_win != window || last_key != key_index) {
- SclNotiShiftStateChangeDesc desc;
- desc.ui_event_desc = NULL;
- desc.shift_state = SCL_SHIFT_STATE_OFF;
-
- SCLEventReturnType ret = handler->on_event_notification(SCL_UINOTITYPE_SHIFT_STATE_CHANGE, &desc);
- if (ret == SCL_EVENT_PASS_ON) {
- context->set_shift_state(SCL_SHIFT_STATE_OFF);
- windows->update_window(windows->get_base_window());
- }
- }
- }
- }
-
- /* If newly pressed key has type MULTI_TOUCH_TYPE_EXCLUSIVE, release all existing pressed events */
- if (actual_event) {
- if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_EXCLUSIVE) {
- /* When calling mouse_release, the seq order of current multitouch events will be changed,
- so we put all the multitouch events into a vector and use them afterwards forreleasing */
- sclint loop = 0;
- sclint multi_touch_context_num = context->get_multi_touch_context_num();
- std::vector<SclUIEventDesc> multi_touch_events;
- for (loop = 0;loop < multi_touch_context_num;loop++) {
- SclUIEventDesc desc;
- context->get_multi_touch_event(loop, &desc);
- multi_touch_events.push_back(desc);
- }
- for (loop = 0;loop < multi_touch_context_num;loop++) {
- SclUIEventDesc desc = multi_touch_events[loop];
- if (desc.touch_id != touch_id) {
- mouse_release(context->get_cur_moving_window(desc.touch_id),
- context->get_cur_moving_point(desc.touch_id).x,
- context->get_cur_moving_point(desc.touch_id).y,
- desc.touch_id, FALSE);
- }
- }
- }
- }
-
- /* Make an unique ID for timer */
- const scl16 uniqId = utils->get_unique_id();
-
- context->set_cur_pressed_event_id(touch_id, uniqId);
- context->set_cur_pressed_key(touch_id, key_index);
- context->set_cur_pressed_window(touch_id, window);
-
- button_context->state = BUTTON_STATE_PRESSED;
-
- if (context->get_highlight_ui_enabled()) {
- CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
- if (focus_handler) {
- sclwindow prev_window = focus_handler->get_current_focus_window();
- scl8 prev_key = focus_handler->get_current_focus_key();
- const SclLayoutKeyCoordinate *prev_coordinate =
- cache->get_cur_layout_key_coordinate(prev_window, prev_key);
-
- focus_handler->set_current_focus(window, key_index);
-
- if (prev_coordinate) {
- windows->update_window(prev_window,
- prev_coordinate->x, prev_coordinate->y, prev_coordinate->width, prev_coordinate->height);
- }
- }
- }
-
- redraw = TRUE;
- ret = TRUE;
-
-#ifndef DIRECTLY_DRAW_ON_EVENTS
- /* If the window doesn't get exposed before corresponding release event,
- * the inverted state of a button will never be drawn onto screen.
- * To prevent such a case, we draw the inverted state of button forcefully and directly,
- * without waiting for expose event */
- /*CSCLGraphics *grps = CSCLGraphics::get_instance();
- CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
- scldrawctx draw_ctx = grps->begin_paint(window, TRUE);
- builder->draw_button(window, draw_ctx, key_index, button_context->state, TRUE);
- grps->end_paint(window, draw_ctx);*/
-#endif
-
- /* for feedback */
- feedback->button_pressed(window, key_index);
-
- /* Special routine for autopopup */
- if (coordinate->popup_type == POPUP_TYPE_AUTO_POPUP) {
- events->create_timer(SCL_TIMER_AUTOPOPUP, m_autopopup_key_duration, uniqId);
- } else {
- /* for long key & repeat key */
- events->create_timer(SCL_TIMER_LONGKEY, m_long_key_duration, uniqId);
- }
-
- SCLShiftState shift_index = context->get_shift_state();
- if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
- if (context->get_caps_lock_mode()) {
- shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
- }
-
- SclUIEventDesc key_event_desc;
- key_event_desc.key_value = coordinate->key_value[shift_index][0];
- key_event_desc.key_event = coordinate->key_event[shift_index][0];
- key_event_desc.key_type = coordinate->key_type;
- key_event_desc.key_modifier = KEY_MODIFIER_NONE;
- key_event_desc.event_type = EVENT_TYPE_PRESS;
-
- SclPoint curpoint = {x, y};
- key_event_desc.touch_id = touch_id;
- key_event_desc.mouse_pressed_point = curpoint;
- key_event_desc.mouse_current_point = curpoint;
- key_event_desc.mouse_farthest_point = curpoint;
-
- key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
- SCLEventReturnType processed = handler->on_event_drag_state_changed(key_event_desc);
-
- /* Only if the handler didn't return SCL_EVENT_DONE */
- if (processed == SCL_EVENT_PASS_ON) {
- /* Now process normal behaviours of each button type */
- switch (coordinate->button_type) {
- case BUTTON_TYPE_NORMAL:
- case BUTTON_TYPE_GRAB:
- case BUTTON_TYPE_SELFISH:
- case BUTTON_TYPE_DIRECTION:
- case BUTTON_TYPE_RELATIVE_DIRECTION: {
- /* Send click event right away if this button uses repeat key */
- if (coordinate->use_repeat_key) {
- handler->on_event_key_clicked(key_event_desc);
- }
- }
- break;
- case BUTTON_TYPE_MULTITAP: {
- }
- break;
- case BUTTON_TYPE_ROTATION: {
- }
- break;
- case BUTTON_TYPE_DRAG: {
- /* Drag buttons fires click event immediately when they are pressed */
- handler->on_event_key_clicked(key_event_desc);
- }
- break;
- case BUTTON_TYPE_UIITEM: break;
- case MAX_BUTTON_TYPE: break;
- default: break;
- }
- switch (coordinate->popup_type) {
- case POPUP_TYPE_BTN_PRESS_POPUP_DRAG: {
- SclNotiPopupOpeningDesc desc;
- desc.ui_event_desc = &key_event_desc;
- desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
- if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
- sclint popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
- SCLDisplayMode display_mode = context->get_display_mode();
- /* FIXME */
- //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
- if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
- scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
- sclshort popupLayoutId =
- sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
- SclRectangle popupRect;
- SclRectangle baseWndRect;
- SclLayout *layout = NULL;
- /* FIXME */
- //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
- if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
- layout = &sclres_layout[popupLayoutId];
- }
- if (layout) {
- windows->get_window_rect(windows->get_base_window(), &baseWndRect);
- popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
- popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
- //popupRect.width = utils->get_scale_x(layout->width);
- //popupRect.height= utils->get_scale_y(layout->height);
- if (!(sclres_manager->loaded(popupLayoutId))) {
- sclres_manager->load(popupLayoutId);
- }
- popupRect.width = layout->width;
- popupRect.height = layout->height;
- windows->close_all_popups();
-
- SclWindowOpener opener;
- opener.window = window;
- opener.key = key_index;
-
- sclwindow popup_window = windows->open_popup(opener,
- popupRect,
- popup_input_mode,
- popupLayoutId,
- coordinate->popup_type,
- sclres_input_mode_configure[popup_input_mode].use_virtual_window,
- sclres_input_mode_configure[popup_input_mode].use_dim_window,
- coordinate->extract_offset_x,
- coordinate->extract_offset_y,
- sclres_input_mode_configure[popup_input_mode].timeout);
-
- SclNotiPopupOpenedDesc opened_desc;
- opened_desc.ui_event_desc = &key_event_desc;
- opened_desc.input_mode = desc.input_mode;
- opened_desc.window = popup_window;
- handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
-
- windows->hide_window(windows->get_magnifier_window());
- /* FIXME : The parent key should be turned back to NORMAL state when RELEASED,
- in case of POPUP_TYPE_BTN_PRESS_POPUP_DRAG type. Temporarily setting NORMAL here. */
- button_context->state = BUTTON_STATE_NORMAL;
- _play_tts_for_input_mode_name(popup_input_mode);
- }
- }
- }
- }
- break;
- case POPUP_TYPE_BTN_RELEASE_POPUP:
- case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE:
- case POPUP_TYPE_BTN_LONGPRESS_POPUP:
- case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE:
- case POPUP_TYPE_AUTO_POPUP:
- case POPUP_TYPE_NONE:
- case MAX_POPUP_TYPE:
- default:
- /* Nothing to do in here */
- break;
- }
- }
-
- /* Shows the magnifier window(the magnifier window will display when a kind of button type is character) */
- //if (windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP) == windows->get_base_window()) {
- if (coordinate->use_magnifier) {
- sclboolean showMagnifier = check_magnifier_available(window, key_index, touch_id);
-
- PSclMagnifierWndConfigure magnifier_configure = NULL;
- if (sclres_manager) {
- magnifier_configure = sclres_manager->get_magnifier_configure();
- }
- if (showMagnifier && magnifier_configure) {
- SclPoint pos = {0, 0};
- /* calculates x position to be set */
- pos.x = (coordinate->x + (coordinate->width / 2)) -
- (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
-
- /* calculates y position to be set */
- sclint scnWidth, scnHeight;
- utils->get_screen_resolution(&scnWidth, &scnHeight);
-
- pos.y = coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
-
- /* FIXME : Temporary way of clearing magnifier window */
- /*SclWindowContext *window_context = windows->get_window_context(windows->get_magnifier_window(), FALSE);
- sclboolean clearmagwin = FALSE;
- if (window_context) {
- clearmagwin = !(window_context->hidden);
- }
- static int clearnum = 0;
- if (key_index == prevkey && window == prevwin) {
- clearmagwin = FALSE;
- }
- if (clearmagwin) {
- if (++clearnum > 1) {
- clearmagwin = FALSE;
- }
- } else {
- clearnum = 0;
- }
-
- if (clearmagwin) {
- CSCLGraphics *graphics = CSCLGraphics::get_instance();
- CSCLUtils *utils = CSCLUtils::get_instance();
- sclchar composed_path[_POSIX_PATH_MAX] = {0,};
- scldrawctx draw_ctx = graphics->begin_paint(windows->get_magnifier_window());
- utils->get_composed_path(composed_path, scl_magnifier_configure.bg_image_path);
- graphics->draw_image(windows->get_magnifier_window(), draw_ctx, composed_path, 0, 0);
- graphics->end_paint(windows->get_magnifier_window(), draw_ctx);
- }
- */
- windows->hide_window(windows->get_magnifier_window());
-
- SclWindowContext *window_context = windows->get_window_context(window);
- if (window_context) {
- pos.x += window_context->geometry.x;
- pos.y += window_context->geometry.y;
- }
-
- if (pos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
- pos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
- }
- if (pos.x > scnWidth +
- magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
- magnifier_configure->width * utils->get_custom_scale_rate_x()) {
- pos.x = scnWidth + magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
- magnifier_configure->width * utils->get_custom_scale_rate_x();
- }
- pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
- pos.x += coordinate->magnifier_offset_x;
- pos.y += coordinate->magnifier_offset_y;
- windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
- //windows->resize_window(windows->get_magnifier_window(), utils->get_scale_x(scl_magnifier_configure.width), utils->get_scale_y(scl_magnifier_configure.height));
- /*If we use transient_for them the ISE will occur some crash. It needs to check X11 */
- /*windows->set_parent(windows->get_base_window(), windows->get_magnifier_window());*/
-
- windows->show_window(windows->get_magnifier_window(), TRUE);
- //windows->update_window(windows->get_magnifier_window());
- }
-#if 0
- static int fFirst = true;
- if (fFirst) {
- windows->show_window(windows->get_magnifier_window());
- fFirst = false;
- } else {
- windows->update_window(windows->get_magnifier_window());
- }
-#endif
- /* We cannot use move_resize_window. It had occured some wrong behavior */
- /*windows->move_resize_window(windows->get_magnifier_window(), pos.x, pos.y, scl_magnifier_configure.width, scl_magnifier_configure.height);*/
- if (!showMagnifier) {
- windows->hide_window(windows->get_magnifier_window());
- }
- }
- } else {
- /* COMMENTED OUT FOR TESTING MULTITOUCH!! */
- ///* In case the current button is not the given key index */
- //if (button_context->state == BUTTON_STATE_PRESSED) {
- // /* Even if the press event occurs outside of this button's physical area, reset its context */
- // button_context->state = BUTTON_STATE_NORMAL;
- // redraw = TRUE;
- //}
- /* BUTTON_TYPE_MULTITAP type button should restore its multikey index when another button is clicked */
- if (coordinate->button_type & BUTTON_TYPE_MULTITAP) {
- button_context->multitap_index = 0;
- }
- }
-
- /* If there is any need for redrawing */
- if (redraw) {
-#ifdef DIRECTLY_DRAW_ON_EVENTS
- CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
- if (builder) {
- builder->draw_button(window, NULL, key_index, button_context->state, TRUE);
- }
-#else
- if (windows) {
- windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
- }
-#endif
- }
- }
-
- return ret;
-}
-
-sclboolean
-CSCLController::process_button_long_pressed_event(sclwindow window, sclbyte key_index,
- scltouchdevice touch_id, sclboolean actual_event)
-{
- SCL_DEBUG();
-
- sclboolean ret = FALSE;
-
- CSCLContext *context = CSCLContext::get_instance();
- CSCLWindows *windows = CSCLWindows::get_instance();
- CSCLActionState *state = CSCLActionState::get_instance();
- CSCLResourceCache *cache = CSCLResourceCache::get_instance();
- CSCLEventHandler *handler = CSCLEventHandler::get_instance();
- SclResParserManager *sclres_manager = SclResParserManager::get_instance();
-
- if (!sclres_manager) return FALSE;
-
- PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
- PSclLayout sclres_layout = sclres_manager->get_layout_table();
-
- if (!sclres_input_mode_configure || !sclres_layout) return FALSE;
-
- if (context && cache && handler && windows && state) {
- const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
- SclButtonContext *button_context = cache->get_cur_button_context(window, key_index);
-
- /* Should return FALSE if this key does not have any longkey related property */
- if (coordinate) {
- if (actual_event) {
- if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
- /* When calling mouse_release, the seq order of current multitouch events will be changed,
- so we put all the multitouch events into a vector and use them afterwards for releasing */
- sclboolean finished = FALSE;
- sclint loop = 0;
- sclint multi_touch_context_num = context->get_multi_touch_context_num();
- std::vector<SclUIEventDesc> multitouch_events;
- for (loop = 0;loop < multi_touch_context_num;loop++) {
- SclUIEventDesc desc;
- context->get_multi_touch_event(loop, &desc);
- multitouch_events.push_back(desc);
- }
- for (loop = 0;loop < multi_touch_context_num && !finished;loop++) {
- SclUIEventDesc desc = multitouch_events[loop];
- if (desc.touch_id != touch_id) {
- sclwindow cur_pressed_window = context->get_cur_pressed_window(desc.touch_id);
- scl8 cur_pressed_key = context->get_cur_pressed_key(desc.touch_id);
- const SclLayoutKeyCoordinate *cur_pressed_coordinate =
- cache->get_cur_layout_key_coordinate(cur_pressed_window, cur_pressed_key);
- if (cur_pressed_coordinate) {
- if (cur_pressed_coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
- mouse_release(context->get_cur_moving_window(desc.touch_id),
- context->get_cur_moving_point(desc.touch_id).x,
- context->get_cur_moving_point(desc.touch_id).y,
- desc.touch_id, FALSE);
- }
- }
- } else {
- finished = TRUE;
- }
- }
- }
- }
- }
-
- /* Should return FALSE if this key does not have any longkey related property */
- if (coordinate) {
- if (coordinate->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP ||
- coordinate->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE ) {
- SclUIEventDesc key_event_desc;
- key_event_desc.key_type = coordinate->long_key_type;
- if (coordinate->long_key_value == NULL && coordinate->long_key_event == 0) {
- SCLShiftState shift_index = context->get_shift_state();
- if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
- if (context->get_caps_lock_mode()) {
- shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
- }
-
- key_event_desc.key_value = coordinate->key_value[shift_index][0];
- key_event_desc.key_event = coordinate->key_event[shift_index][0];
- } else {
- key_event_desc.key_value = coordinate->long_key_value;
- key_event_desc.key_event = coordinate->long_key_event;
- }
- key_event_desc.key_modifier = KEY_MODIFIER_LONGKEY;
-
- key_event_desc.event_type = EVENT_TYPE_LONGPRESS;
- key_event_desc.touch_id = touch_id;
- key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
- key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
- key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
- key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
- SCLEventReturnType processed = handler->on_event_drag_state_changed(key_event_desc);
-
- /* Only if the handler didn't return SCL_EVENT_DONE */
- if (processed == SCL_EVENT_PASS_ON) {
- SclRectangle popupRect;
- SclRectangle baseWndRect;
- windows->get_window_rect(windows->get_base_window(), &baseWndRect);
- popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
- popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
-
- SclNotiPopupOpeningDesc desc;
- desc.ui_event_desc = &key_event_desc;
- desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
- if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
- sclint popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
- SCLDisplayMode display_mode = context->get_display_mode();
- /* FIXME */
- //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
- if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
- scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
- SclLayout *layout = NULL;
- sclshort popupLayoutId =
- sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
- /* FIXME */
- //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
- if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
- layout = &sclres_layout[popupLayoutId];
- }
- if (layout) {
- //popupRect.width = utils->get_scale_x(layout->width);
- //popupRect.height= utils->get_scale_y(layout->height);
- if (!(sclres_manager->loaded(popupLayoutId))) {
- sclres_manager->load(popupLayoutId);
- }
- popupRect.width = layout->width;
- popupRect.height = layout->height;
-
- SclWindowOpener opener;
- opener.window = window;
- opener.key = key_index;
-
- sclwindow popup_window = windows->open_popup(
- opener,
- popupRect,
- popup_input_mode,
- popupLayoutId,
- coordinate->popup_type,
- sclres_input_mode_configure[popup_input_mode].use_virtual_window,
- sclres_input_mode_configure[popup_input_mode].use_dim_window,
- coordinate->extract_offset_x,
- coordinate->extract_offset_y,
- sclres_input_mode_configure[popup_input_mode].timeout);
-
- SclNotiPopupOpenedDesc opened_desc;
- opened_desc.ui_event_desc = &key_event_desc;
- opened_desc.input_mode = desc.input_mode;
- opened_desc.window = popup_window;
- handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
-
- windows->hide_window(windows->get_magnifier_window());
- _play_tts_for_input_mode_name(popup_input_mode);
- ret = TRUE;
- }
- }
- }
- }
- } else if (coordinate->long_key_value) {
- if (strlen(coordinate->long_key_value) > 0) {
- if (windows->is_base_window(window)) {
- state->set_cur_action_state(ACTION_STATE_BASE_LONGKEY);
- } else {
- state->set_cur_action_state(ACTION_STATE_POPUP_LONGKEY);
- }
- ret = TRUE;
-
- PSclMagnifierWndConfigure magnifier_configure = NULL;
- if (sclres_manager) {
- magnifier_configure = sclres_manager->get_magnifier_configure();
- }
- if (coordinate->use_long_key_magnifier && magnifier_configure) {
- CSCLUtils *utils = CSCLUtils::get_instance();
- SclPoint pos = {0, 0};
-
- const SclLayout* layout = cache->get_cur_layout(window);
- if (utils && layout) {
- sclint scnWidth, scnHeight;
- utils->get_screen_resolution(&scnWidth, &scnHeight);
-
- //SclWindowContext *window_context = windows->get_window_context(window, TRUE);
- SclWindowContext *window_context = windows->get_window_context(window);
- if (window_context) {
- pos.x = window_context->geometry.x + (coordinate->x + (coordinate->width / 2)) -
- (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
- pos.y = window_context->geometry.y + coordinate->y -
- magnifier_configure->height * utils->get_custom_scale_rate_y();
- }
- if (pos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
- pos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
- }
- if (pos.x > scnWidth +
- magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
- magnifier_configure->width * utils->get_custom_scale_rate_x()) {
- pos.x = scnWidth +
- magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
- magnifier_configure->width * utils->get_custom_scale_rate_x();
- }
- pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
- pos.x += coordinate->magnifier_offset_x;
- pos.y += coordinate->magnifier_offset_y;
- windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
- windows->update_window(windows->get_magnifier_window());
- windows->show_window(windows->get_magnifier_window(), TRUE);
- }
- }
-
- SclUIEventDesc key_event_desc;
- key_event_desc.key_type = coordinate->long_key_type;
- key_event_desc.key_value = coordinate->long_key_value;
- key_event_desc.key_event = coordinate->long_key_event;
- key_event_desc.key_modifier = KEY_MODIFIER_LONGKEY;
-
- key_event_desc.event_type = EVENT_TYPE_LONGPRESS;
- key_event_desc.touch_id = touch_id;
- key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
- key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
- key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
- key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
- handler->on_event_key_clicked(key_event_desc);
- //}
- }
- }
- }
- if (ret) {
- context->set_cur_key_modifier(touch_id, KEY_MODIFIER_LONGKEY);
- if (coordinate && button_context) {
- if (coordinate->button_type & BUTTON_TYPE_MULTITAP) {
- button_context->multitap_index = 0;
- }
- }
- }
- }
- /* Longkey processing in here */
- return ret;
-}
-
-sclboolean
-CSCLController::process_button_repeat_pressed_event(sclwindow window, sclbyte key_index,
- scltouchdevice touch_id, sclboolean actual_event)
-{
- SCL_DEBUG();
- CSCLContext *context = CSCLContext::get_instance();
- CSCLResourceCache *cache = CSCLResourceCache::get_instance();
- CSCLWindows *windows = CSCLWindows::get_instance();
- CSCLEventHandler *handler = CSCLEventHandler::get_instance();
-
- if (context && cache && windows && handler) {
- const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
-
- SCLShiftState shift_index = context->get_shift_state();
- if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
- if (context->get_caps_lock_mode()) {
- shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
- }
-
- if (coordinate) {
- switch (coordinate->button_type) {
- case BUTTON_TYPE_NORMAL:
- case BUTTON_TYPE_GRAB:
- case BUTTON_TYPE_SELFISH:
- case BUTTON_TYPE_DIRECTION:
- case BUTTON_TYPE_RELATIVE_DIRECTION: {
- /* This is for enabling backspace key in search layout*/
- //if (coordinate->key_type != KEY_TYPE_MODECHANGE && coordinate->key_type != KEY_TYPE_COMPOSITION) {
- //if (coordinate->key_type != KEY_TYPE_MODECHANGE || coordinate->key_event[0][0] == MVK_BackSpace) {
- if (coordinate->key_type != KEY_TYPE_MODECHANGE) {
- sclulong repeatKeyEvent = coordinate->key_event[shift_index][0];
-
- /* In case of Delete key, Change from Char deletion to Word deletion
- when the input acceleration speed is reached to Max */
- SclResParserManager *sclres_manager = SclResParserManager::get_instance();
- PSclDefaultConfigure default_configure = NULL;
- if (sclres_manager) {
- default_configure = sclres_manager->get_default_configure();
- }
- if (default_configure) {
- if (default_configure->use_word_deletion) {
- scllong interval = m_repeat_key_duration - (m_key_repeated_num * SCL_REPEATKEY_ACCELERATION);
- if (repeatKeyEvent == MVK_BackSpace &&
- interval <= SCL_REPEATKEY_WORD_DELETION_START_DURATION) {
- repeatKeyEvent = MVK_3270_DeleteWord;
- }
- }
- }
-
- SclUIEventDesc key_event_desc;
- key_event_desc.key_value = coordinate->key_value[shift_index][0];
- key_event_desc.key_event = repeatKeyEvent;
- key_event_desc.key_type = coordinate->key_type;
- key_event_desc.key_modifier = KEY_MODIFIER_NONE;
-
- key_event_desc.event_type = EVENT_TYPE_REPEAT;
- key_event_desc.touch_id = touch_id;
- key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
- key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
- key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
- key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
- handler->on_event_key_clicked(key_event_desc);
- }
- }
- break;
- case BUTTON_TYPE_UIITEM: break;
- case MAX_BUTTON_TYPE: break;
- default: break;
- }
- }
- }
-
- /* Longkey processing in here */
- return TRUE;
-}
-
-sclboolean
-CSCLController::process_button_move_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
- scltouchdevice touch_id, sclboolean actual_event)
-{
- SCL_DEBUG();
-
- sclboolean ret = FALSE;
-
- CSCLUtils *utils = CSCLUtils::get_instance();
- CSCLEvents *events = CSCLEvents::get_instance();
- CSCLContext *context = CSCLContext::get_instance();
- CSCLWindows *windows = CSCLWindows::get_instance();
- CSCLFeedback *feedback = CSCLFeedback::get_instance();
- CSCLEventHandler *handler = CSCLEventHandler::get_instance();
- CSCLResourceCache *cache = CSCLResourceCache::get_instance();
-
- SclButtonContext *button_context = NULL;
-
- const SclLayoutKeyCoordinate *coordinate = NULL;
-
- if (cache) {
- coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
- button_context = cache->get_cur_button_context(window, key_index);
- }
-
- if (button_context && coordinate && feedback && utils && context && handler && cache && events && windows) {
- /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
- sclint thresholdX = 0;
- sclint thresholdY = 0;
- if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
- thresholdX = utils->get_scaled_x(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_X);
- thresholdY = utils->get_scaled_y(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_Y);
- }
-
- /* First check if this button is enabled in current active sublayout */
- sclboolean subLayoutMatch = TRUE;
- if (coordinate->sub_layout && context->get_cur_sublayout()) {
- if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
- subLayoutMatch = FALSE;
- }
- }
- if ( x >= coordinate->x - coordinate->add_hit_left - thresholdX &&
- x < coordinate->x + coordinate->width + coordinate->add_hit_right + thresholdX&&
- y >= coordinate->y - coordinate->add_hit_top - thresholdY &&
- y < coordinate->y + coordinate->height + coordinate->add_hit_bottom + thresholdY &&
- subLayoutMatch ) {
- ret = TRUE;
-
- SCLShiftState shift_index = context->get_shift_state();
- if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
- if (context->get_caps_lock_mode()) {
- shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
- }
-
- const SclLayout* layout = cache->get_cur_layout(windows->get_base_window());
-
- sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
- scl8 pressed_key = context->get_cur_pressed_key(touch_id);
- SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
- const SclLayoutKeyCoordinate *pressed_coordinate =
- cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
-
- if (pressed_context == NULL || pressed_coordinate == NULL) {
- return FALSE;
- }
-
- if (key_index != pressed_key || window != pressed_window) {
- /* When the focus has moved to another button, destroy all the timers */
- events->destroy_all_timer();
-
- if (check_event_transition_enabled(pressed_coordinate, coordinate)) {
- if (layout) {
- const scl16 uniqId = utils->get_unique_id();
- context->set_cur_pressed_event_id(touch_id, uniqId);
- /* Special routine for autopopup */
- if (coordinate->popup_type == POPUP_TYPE_AUTO_POPUP) {
- events->create_timer(SCL_TIMER_AUTOPOPUP, m_autopopup_key_duration, uniqId);
- } else {
- /* for long key & repeat key */
- events->create_timer(SCL_TIMER_LONGKEY, m_long_key_duration, uniqId);
- }
-
- context->set_cur_pressed_window(touch_id, window);
- context->set_cur_pressed_key(touch_id, key_index);
-
- sclboolean showMagnifier = check_magnifier_available(window, key_index, touch_id);
-
- SclResParserManager *sclres_manager = SclResParserManager::get_instance();
- PSclMagnifierWndConfigure magnifier_configure = NULL;
- if (sclres_manager) {
- magnifier_configure = sclres_manager->get_magnifier_configure();
- }
-
- SclWindowContext *window_context = windows->get_window_context(window);
- if (showMagnifier && magnifier_configure && window_context) {
- SclPoint pos = {0, 0};
- /* calculates x position to be set */
- pos.x = window_context->geometry.x;
- pos.x += (coordinate->x + (coordinate->width / 2)) -
- (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
-
- /* calculates y position to be set */
- pos.y = window_context->geometry.y;
- pos.y += coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
-
- if (pos.x < window_context->geometry.x - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
- pos.x = window_context->geometry.x - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
- }
- if (pos.x > window_context->geometry.x + window_context->geometry.width +
- magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
- magnifier_configure->width * utils->get_custom_scale_rate_x()) {
- pos.x = window_context->geometry.x + window_context->geometry.width +
- magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
- magnifier_configure->width * utils->get_custom_scale_rate_x();
- }
- pos.x += coordinate->magnifier_offset_x;
- pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
- pos.y += coordinate->magnifier_offset_y;
- if (windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP) == windows->get_base_window()) {
- windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
- windows->update_window(windows->get_magnifier_window());
- }
- }
-
- /* for feedback */
- feedback->button_moved(window, key_index);
-
- button_context->state = BUTTON_STATE_PRESSED;
- if (pressed_context) {
- /* But, if this button should be in pressed state in other multitouch id, do not initialize it */
- sclboolean found = FALSE;
- for (sclint loop = 0;loop < context->get_multi_touch_context_num() && !found;loop++) {
- SclUIEventDesc desc;
- context->get_multi_touch_event(loop, &desc);
- if (desc.touch_id != touch_id) {
- MultiTouchContext *multi_touch_context =
- context->find_multi_touch_context(desc.touch_id);
- if (multi_touch_context) {
- if (multi_touch_context->cur_pressed_window == pressed_window &&
- multi_touch_context->cur_pressed_key == pressed_key) {
- found = TRUE;
- }
- }
- }
- }
- if (!found) {
- pressed_context->state = BUTTON_STATE_NORMAL;
- }
- }
- /* If the window doesn't get exposed before corresponding release event,
- * the inverted state of a button will never be drawn onto screen.
- * To prevent such a case, we draw the inverted state of button forcefully and directly,
- * without waiting for expose event */
- /* Redrawing pressed button does not work properly, commented out */
- /*
- CSCLGraphics *grps = CSCLGraphics::get_instance();
- CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
- scldrawctx draw_ctx;
- if (pressed_window != SCLWINDOW_INVALID && pressed_key != NOT_USED) {
- draw_ctx = grps->begin_paint(pressed_window, TRUE);
- builder->draw_button(pressed_window, draw_ctx, pressed_key, FALSE);
- grps->end_paint(pressed_window, draw_ctx);
- }
- draw_ctx = grps->begin_paint(window, TRUE);
- builder->draw_button(window, draw_ctx, key_index, TRUE);
- grps->end_paint(window, draw_ctx);
- */
-
- switch (coordinate->button_type) {
- case BUTTON_TYPE_DRAG: {
- SclUIEventDesc key_event_desc;
- key_event_desc.key_value = coordinate->key_value[shift_index][0];
- key_event_desc.key_event = coordinate->key_event[shift_index][0];
- key_event_desc.key_type = coordinate->key_type;
- key_event_desc.key_modifier = KEY_MODIFIER_NONE;
-
- key_event_desc.event_type = EVENT_TYPE_MOVE;
- key_event_desc.touch_id = touch_id;
- key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
- key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
- key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
- key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
- if (sclres_manager) {
- magnifier_configure = sclres_manager->get_magnifier_configure();
- }
- sclboolean processed = handler->on_event_drag_state_changed(key_event_desc);
- if (processed && context->get_magnifier_enabled() && magnifier_configure) {
- SclPoint zoomwinpos = {0, 0};
- /* calculates x position to be set */
- zoomwinpos.x = (coordinate->x + (coordinate->width / 2)) -
- (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
-
- /* calculates y position to be set */
- sclint scnWidth, scnHeight;
- utils->get_screen_resolution(&scnWidth, &scnHeight);
-
- zoomwinpos.y = coordinate->y -
- magnifier_configure->height * utils->get_custom_scale_rate_y();
- SclWindowContext *window_context = windows->get_window_context(window);
- if (window_context) {
- zoomwinpos.x += window_context->geometry.x;
- zoomwinpos.y += window_context->geometry.y;
- }
- if (zoomwinpos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
- zoomwinpos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
- }
- if (zoomwinpos.x > scnWidth +
- magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
- magnifier_configure->width * utils->get_custom_scale_rate_x()) {
- zoomwinpos.x = scnWidth +
- magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
- magnifier_configure->width * utils->get_custom_scale_rate_x();
- }
- zoomwinpos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
- zoomwinpos.x += coordinate->magnifier_offset_x;
- zoomwinpos.y += coordinate->magnifier_offset_y;
- windows->move_window(windows->get_magnifier_window(), zoomwinpos.x, zoomwinpos.y);
- windows->show_window(windows->get_magnifier_window(), 0);
- }
-
- handler->on_event_key_clicked(key_event_desc);
- if (!(windows->is_base_window(window))) {
- /* When press event occured in popup window, reset POPUP_TIMEOUT timer */
- //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
- SclWindowContext *window_context = windows->get_window_context(window);
- if (window_context) {
- if (window_context->timeout > 0) {
- events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
- events->create_timer(SCL_TIMER_POPUP_TIMEOUT, window_context->timeout, 0, TRUE);
- }
- }
- }
- }
- break;
- case BUTTON_TYPE_NORMAL: break;
- case BUTTON_TYPE_GRAB: break;
- case BUTTON_TYPE_SELFISH: break;
- case BUTTON_TYPE_MULTITAP: break;
- case BUTTON_TYPE_ROTATION: break;
- case BUTTON_TYPE_DIRECTION: break;
- case BUTTON_TYPE_RELATIVE_DIRECTION: break;
- case BUTTON_TYPE_UIITEM: break;
- case MAX_BUTTON_TYPE: break;
- default:
- break;
- }
-
-#ifdef DIRECTLY_DRAW_ON_EVENTS
- CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
- if (builder) {
- if (button_context) {
- builder->draw_button(window, NULL, key_index, button_context->state);
- }
- if (pressedContext) {
- builder->draw_button(pressed_window, NULL, pressed_key, pressedContext->state, TRUE);
- }
- }
-#else
- windows->update_window(window,
- coordinate->x, coordinate->y, coordinate->width, coordinate->height);
- if (pressed_coordinate) {
- windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
- pressed_coordinate->width, pressed_coordinate->height);
- }
-#endif
- }
-
- //utils->log("Now Moving : %d %d\n", pos.x, pos.y);
- } else {
- /* If the focus went out from our SELFISH button */
- if (pressed_coordinate->button_type == BUTTON_TYPE_SELFISH) {
- pressed_context->state = BUTTON_STATE_NORMAL;
- windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
- pressed_coordinate->width, pressed_coordinate->height);
- /* And if this SELFISH button was the last button pressed */
- if (touch_id == context->get_last_touch_device_id()) {
- windows->hide_window(windows->get_magnifier_window());
- }
- }
- }
- } else {
- /* If the focus came back into our SELFISH button */
- if (pressed_coordinate->button_type == BUTTON_TYPE_SELFISH && pressed_context->state != BUTTON_STATE_PRESSED) {
- pressed_context->state = BUTTON_STATE_PRESSED;
- windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
- pressed_coordinate->width, pressed_coordinate->height);
- /* And if this SELFISH button was the last button pressed */
- if (touch_id == context->get_last_touch_device_id()) {
- sclboolean showMagnifier = check_magnifier_available(pressed_window, pressed_key, touch_id);
-
- if (showMagnifier) {
- windows->show_window(windows->get_magnifier_window());
- }
- }
- }
- }
- }
- }
-
- return ret;
-}
-
-sclboolean
-CSCLController::process_button_over_event(sclwindow window, sclint x, sclint y, sclbyte key_index)
-{
- SCL_DEBUG();
-
- sclboolean ret = FALSE;
-
- CSCLUtils *utils = CSCLUtils::get_instance();
- CSCLEvents *events = CSCLEvents::get_instance();
- CSCLContext *context = CSCLContext::get_instance();
- CSCLWindows *windows = CSCLWindows::get_instance();
- CSCLFeedback *feedback = CSCLFeedback::get_instance();
- CSCLResourceCache *cache = CSCLResourceCache::get_instance();
-
- SclButtonContext *button_context = NULL;
-
- const SclLayoutKeyCoordinate *coordinate = NULL;
- if (cache) {
- coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
- button_context = cache->get_cur_button_context(window, key_index);
- }
-
- if (button_context && coordinate && feedback && utils && context && cache && events && windows) {
- /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
- sclboolean subLayoutMatch = TRUE;
- if (coordinate->sub_layout && context->get_cur_sublayout()) {
- if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
- subLayoutMatch = FALSE;
- }
- }
- if ( x >= coordinate->x - coordinate->add_hit_left &&
- x < coordinate->x + coordinate->width + coordinate->add_hit_right &&
- y >= coordinate->y - coordinate->add_hit_top &&
- y < coordinate->y + coordinate->height + coordinate->add_hit_bottom &&
- subLayoutMatch ) {
- ret = TRUE;
-
- SCLShiftState shift_index = context->get_shift_state();
- if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
- if (context->get_caps_lock_mode()) {
- shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
- }
-
- const SclLayout* layout = cache->get_cur_layout(windows->get_base_window());
-
- sclwindow highlighted_window = context->get_cur_highlighted_window();
- scl8 highlighted_key = context->get_cur_highlighted_key();
- SclButtonContext *cur_context = cache->get_cur_button_context(window, key_index);
-
- if (cur_context == NULL) {
- return FALSE;
- }
- if (key_index != highlighted_key || window != highlighted_window) {
- SECURE_LOGD("%d != %d || %p != %p", key_index, highlighted_key, window, highlighted_window);
- if (layout) {
- if (coordinate->key_type != KEY_TYPE_NONE) {
- if (context->get_tts_enabled()) {
- const sclchar *targetstr = coordinate->hint_string[shift_index][button_context->multitap_index];
- if (targetstr == NULL) {
- targetstr = coordinate->label[shift_index][0];
- }
- if (targetstr == NULL) {
- targetstr = coordinate->key_value[shift_index][button_context->multitap_index];
- }
- /*if(state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY ) {
- targetstr = coordinate->long_key_value;
- }*/
- const sclchar *sayit = cache->find_substituted_string(targetstr);
- utils->play_tts(sayit);
- }
- }
- }
-
- context->set_cur_highlighted_window(window);
- context->set_cur_highlighted_key(key_index);
- }
- }
- }
-
- return ret;
-}
-SCLKeyModifier
-CSCLController::get_drag_key_modifier(sclint deltax, sclint deltay, sclfloat dist, sclboolean check_farthest,
- scltouchdevice touch_id, sclbyte extra_option) {
- typedef struct {
- double lowerbound;
- double upperbound;
- SCLKeyModifier modifier;
- } DIRECTIONINFO;
-
- CSCLContext *context = CSCLContext::get_instance();
- SCLKeyModifier key_modifier = KEY_MODIFIER_NONE;
-
- if (context) {
- double theta = atan2(deltay , (deltax ? deltax : 1)); /* Avoid divide by 0 exception */
- sclfloat ratio = fabs((sclfloat)deltay / (deltax ? deltax : 1));
- SCLDragState cur_drag_state = context->get_cur_drag_state(touch_id);
- if (extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS ||
- extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG ||
- extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN) { /* 8 directions */
- /* If the theta is below 0, the direction is upward since the y coordinate grows downward */
- /* The below angle values are customized for MoAKey, need to provide customizing API */
- DIRECTIONINFO info[] = {
- {-8 * (M_PI / 8), -7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_LEFT},
- {-7 * (M_PI / 8), -5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP_LEFT},
- {-5 * (M_PI / 8), -2.7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP},
- {-2.7 * (M_PI / 8), -1.5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP_RIGHT},
- {-1.5 * (M_PI / 8), 1 * (M_PI / 8), KEY_MODIFIER_DIRECTION_RIGHT},
- { 1 * (M_PI / 8), 3 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN_RIGHT},
- { 3 * (M_PI / 8), 5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN},
- { 5 * (M_PI / 8), 7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN_LEFT},
- { 7 * (M_PI / 8), 8 * (M_PI / 8), KEY_MODIFIER_DIRECTION_LEFT},
- };
- for (size_t loop = 0; loop < sizeof(info) / sizeof(DIRECTIONINFO); loop++) {
- if (theta >= info[loop].lowerbound && theta <= info[loop].upperbound) {
- key_modifier = info[loop].modifier;
- }
- }
- } else { /* 4 directions */
- /* If the state was dragging to one of 4 directions and the final release point is
- * far enough from inital press point, and the angle is in between out predefined angle value */
- if (extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE &&
- cur_drag_state != SCL_DRAG_STATE_NONE && cur_drag_state != SCL_DRAG_STATE_INVALID &&
- dist > SCL_DRAG_CURVE_RECOG_DIST &&
- ratio > (1 / SCL_DRAG_CURVE_FINAL_ANGLE_VALUE) &&
- ratio < SCL_DRAG_CURVE_FINAL_ANGLE_VALUE) {
- if (cur_drag_state == SCL_DRAG_STATE_DOWN) {
- if (deltax > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_DOWN_RIGHT;
- else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_DOWN_LEFT;
- }
- if (cur_drag_state == SCL_DRAG_STATE_UP) {
- if (deltax > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_UP_RIGHT;
- else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_UP_LEFT;
- }
- if (cur_drag_state == SCL_DRAG_STATE_LEFT) {
- if (deltay > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_LEFT_DOWN;
- else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_LEFT_UP;
- }
- if (cur_drag_state == SCL_DRAG_STATE_RIGHT) {
- if (deltay > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_RIGHT_DOWN;
- else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_RIGHT_UP;
- }
- } else {
- DIRECTIONINFO info[] = {
- {-4 * (M_PI / 4), -3 * (M_PI / 4), KEY_MODIFIER_DIRECTION_LEFT},
- {-3 * (M_PI / 4), -1 * (M_PI / 4), KEY_MODIFIER_DIRECTION_UP},
- {-1 * (M_PI / 4), 1 * (M_PI / 4), KEY_MODIFIER_DIRECTION_RIGHT},
- { 1 * (M_PI / 4), 3 * (M_PI / 4), KEY_MODIFIER_DIRECTION_DOWN},
- { 3 * (M_PI / 4), 4 * (M_PI / 4), KEY_MODIFIER_DIRECTION_LEFT},
- };
- for (size_t loop = 0; loop < sizeof(info) / sizeof(DIRECTIONINFO); loop++) {
- if (theta >= info[loop].lowerbound && theta <= info[loop].upperbound) {
- key_modifier = info[loop].modifier;
- }
- }
- }
- }
-
- if (extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG ||
- extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_LONG) {
- if (key_modifier >= KEY_MODIFIER_DIRECTION_LEFT &&
- key_modifier <= KEY_MODIFIER_DIRECTION_DOWN_RIGHT) {
- key_modifier = (SCLKeyModifier)(key_modifier + 8); // Add LONG attribute;
- }
- }
- if (check_farthest || context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN) {
- if (key_modifier >= KEY_MODIFIER_DIRECTION_LEFT &&
- key_modifier <= KEY_MODIFIER_DIRECTION_DOWN_RIGHT) {
- key_modifier = (SCLKeyModifier)(key_modifier + 16); // Add RETURN attribute;
- }
- }
- }
-
- return key_modifier;
-}
-
-sclboolean
-CSCLController::process_button_release_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
- scltouchdevice touch_id, sclboolean actual_event)
-{
- SCL_DEBUG();
-
- sclboolean ret = FALSE;
- sclboolean redraw = FALSE;
- sclboolean fire_event = FALSE;
- SCLKeyModifier key_modifier = KEY_MODIFIER_NONE;
-
- CSCLUtils *utils = CSCLUtils::get_instance();
- CSCLFeedback *feedback = CSCLFeedback::get_instance();
- CSCLWindows *windows = CSCLWindows::get_instance();
- CSCLContext *context = CSCLContext::get_instance();
- CSCLActionState *state = CSCLActionState::get_instance();
- CSCLEventHandler *handler = CSCLEventHandler::get_instance();
- CSCLResourceCache *cache = CSCLResourceCache::get_instance();
-
- SclResParserManager *sclres_manager = SclResParserManager::get_instance();
- if (!sclres_manager) return FALSE;
-
- PSclLayout sclres_layout = sclres_manager->get_layout_table();
- PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
- if (!sclres_layout || !sclres_input_mode_configure) return FALSE;
-
- SclButtonContext *button_context = NULL;
- const SclLayoutKeyCoordinate *coordinate = NULL;
-
- if (cache) {
- button_context = cache->get_cur_button_context(window, key_index);
- coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
- }
-
- const SclLayoutKeyCoordinate *targetCoordinate = NULL;
-
- if (utils && feedback && windows && context && state && handler && cache && button_context && coordinate) {
- scl8 savedInputMode = context->get_input_mode();
-
- sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
- scl8 pressed_key = context->get_cur_pressed_key(touch_id);
-
- if (actual_event) {
- if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
- /* When calling mouse_release, the seq order of current multitouch events will be changed,
- so we put all the multitouch events into a vector and use them afterwards for releasing */
- sclboolean finished = FALSE;
- sclint loop = 0;
- sclint multi_touch_context_num = context->get_multi_touch_context_num();
- std::vector<SclUIEventDesc> multi_touch_events;
- for (loop = 0;loop < multi_touch_context_num;loop++) {
- SclUIEventDesc desc;
- context->get_multi_touch_event(loop, &desc);
- multi_touch_events.push_back(desc);
- }
- for (loop = 0;loop < multi_touch_context_num && !finished;loop++) {
- SclUIEventDesc desc = multi_touch_events[loop];
- if (desc.touch_id != touch_id) {
- sclwindow cur_pressed_window = context->get_cur_pressed_window(desc.touch_id);
- scl8 cur_pressed_key = context->get_cur_pressed_key(desc.touch_id);
- const SclLayoutKeyCoordinate *cur_pressed_coordinate =
- cache->get_cur_layout_key_coordinate(cur_pressed_window, cur_pressed_key);
- if (cur_pressed_coordinate) {
- if (cur_pressed_coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
- mouse_release(context->get_cur_moving_window(desc.touch_id),
- context->get_cur_moving_point(desc.touch_id).x,
- context->get_cur_moving_point(desc.touch_id).y,
- desc.touch_id, FALSE);
- }
- }
- } else {
- finished = TRUE;
- }
- }
- }
- }
-
- /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
- sclint thresholdX = 0;
- sclint thresholdY = 0;
- if (context) {
- if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
- thresholdX = utils->get_scaled_x(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_X);
- thresholdY = utils->get_scaled_y(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_Y);
- }
- }
-
- /* Check if the pressed button's type is directional button */
- if (coordinate->button_type == BUTTON_TYPE_DIRECTION || coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
- if (context) {
- if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
- ret = TRUE;
- sclboolean check_farthest = FALSE;
-
- sclint startx = x;
- sclint starty = y;
-
- /* If the buttontype is RELATIVE_DIRECTION, get the distance from last move point */
- if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
- startx = context->get_prev_moving_point(touch_id).x;
- starty = context->get_prev_moving_point(touch_id).y;
- } else {
- startx = context->get_cur_pressed_point(touch_id).x;
- starty = context->get_cur_pressed_point(touch_id).y;
- }
-
- sclint deltax = x - startx;
- sclint deltay = y - starty;
-
- sclfloat dist = utils->get_distance(x, y, startx, starty);
- sclfloat direction_recog_dist = SCL_DIRECTION_RECOG_DIST * utils->get_smallest_scale_rate();
- if (coordinate->is_side_button) {
- direction_recog_dist = SCL_DIRECTION_RECOG_DIST_SIDE * utils->get_smallest_scale_rate();
- };
- if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
- direction_recog_dist = SCL_DIRECTION_RELATIVE_RECOG_DIST * utils->get_smallest_scale_rate();
- }
- if (context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN &&
- coordinate->button_type != BUTTON_TYPE_RELATIVE_DIRECTION) {
- if (coordinate->extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN ||
- coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN ||
- coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE) {
- deltax = context->get_farthest_move_point(touch_id).x - context->get_cur_pressed_point(touch_id).x;
- deltay = context->get_farthest_move_point(touch_id).y - context->get_cur_pressed_point(touch_id).y;
- dist = utils->get_distance(context->get_farthest_move_point(touch_id), context->get_cur_pressed_point(touch_id));
- check_farthest = TRUE;
- }
- }
- if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
- key_modifier = context->get_cur_key_modifier(touch_id);
- } else if (dist > direction_recog_dist) {
- key_modifier = get_drag_key_modifier(deltax, deltay, dist, check_farthest, touch_id, coordinate->extra_option);
- }
- }
- }
- }
-
- /* First check if this button is enabled in current active sublayout */
- sclboolean subLayoutMatch = TRUE;
- if (coordinate->sub_layout && context->get_cur_sublayout()) {
- if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
- subLayoutMatch = FALSE;
- }
- }
- /* Check if the event occured inside this button's rectangle */
- if ( x >= coordinate->x - coordinate->add_hit_left - thresholdX &&
- x < coordinate->x + coordinate->width + coordinate->add_hit_right + thresholdX &&
- y >= coordinate->y - coordinate->add_hit_top - thresholdY &&
- y < coordinate->y + coordinate->height + coordinate->add_hit_bottom + thresholdY &&
- subLayoutMatch ) {
- ret = TRUE;
- }
-
- if (ret) {
- /* for feedback */
- feedback->button_released(window, key_index);
-
- /* If this button's index is the same as the one initially pressed */
- if (pressed_window == window && pressed_key == key_index) {
- fire_event = TRUE;
- targetCoordinate = coordinate;
- } else {
- const SclLayoutKeyCoordinate *pressed_coordinate =
- cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
-
- if (pressed_coordinate) {
- if (check_event_transition_enabled(pressed_coordinate, coordinate)) {
- fire_event = TRUE;
- targetCoordinate = pressed_coordinate;
- } else {
- ret = FALSE;
- }
- }
- }
- }
-
- /* In case of mode change buttons, event should be fired only when it was pressed lastly */
- if (fire_event) {
- if (coordinate->key_type == KEY_TYPE_MODECHANGE) {
- if (touch_id != context->get_last_touch_device_id()) {
- fire_event = FALSE;
- }
- }
- }
-
- /* If this key's modifier is LONGKEY, this means the event is already fired so skip this one */
- if (context->get_cur_key_modifier(touch_id) == KEY_MODIFIER_LONGKEY) {
- fire_event = FALSE;
- }
-
- /* Don't fire any events if we're in longkey state */
- if (state->get_cur_action_state() != ACTION_STATE_BASE_LONGKEY &&
- state->get_cur_action_state() != ACTION_STATE_BASE_REPEATKEY &&
- state->get_cur_action_state() != ACTION_STATE_POPUP_LONGKEY &&
- state->get_cur_action_state() != ACTION_STATE_POPUP_REPEATKEY) {
- if (ret) {
- SCLShiftState shift_index = context->get_shift_state();
- if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
- if (context->get_caps_lock_mode()) {
- shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
- }
-
- SclUIEventDesc key_event_desc;
- if (targetCoordinate) {
- key_event_desc.key_type = targetCoordinate->key_type;
-
- key_event_desc.key_value = targetCoordinate->key_value[shift_index][button_context->multitap_index];
- key_event_desc.key_event = targetCoordinate->key_event[shift_index][button_context->multitap_index];
- }
- key_event_desc.key_modifier = key_modifier;
-
- key_event_desc.event_type = EVENT_TYPE_RELEASE;
- key_event_desc.touch_id = touch_id;
- key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
- key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
- key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
- key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
- if (handler->on_event_drag_state_changed(key_event_desc) != SCL_EVENT_PASS_ON) {
- fire_event = FALSE;
- }
- }
- if (fire_event) {
- if (targetCoordinate) {
- SCLShiftState shift_index = context->get_shift_state();
- if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
- if (context->get_caps_lock_mode()) {
- shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
- }
-
- SclUIEventDesc key_event_desc;
- key_event_desc.key_type = targetCoordinate->key_type;
-
- key_event_desc.event_type = EVENT_TYPE_RELEASE;
- key_event_desc.touch_id = touch_id;
- key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
- key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
- key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
- key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
- switch (targetCoordinate->button_type) {
- case BUTTON_TYPE_NORMAL:
- case BUTTON_TYPE_GRAB :
- case BUTTON_TYPE_SELFISH:
- case BUTTON_TYPE_DIRECTION :
- case BUTTON_TYPE_RELATIVE_DIRECTION: {
- SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
- if (pressed_context) {
- if (!(targetCoordinate->use_repeat_key) && pressed_context->state == BUTTON_STATE_PRESSED) {
- key_event_desc.key_value = targetCoordinate->key_value[shift_index][0];
- key_event_desc.key_event = targetCoordinate->key_event[shift_index][0];
- key_event_desc.key_modifier = key_modifier;
- handler->on_event_key_clicked(key_event_desc);
- }
- }
- }
- break;
- case BUTTON_TYPE_MULTITAP:
- case BUTTON_TYPE_ROTATION: {
- if (targetCoordinate->button_type == BUTTON_TYPE_MULTITAP) {
- if (window == context->get_last_event_fired_window() &&
- key_index == context->get_last_event_fired_key()) {
- key_modifier = KEY_MODIFIER_MULTITAP_REPEAT;
- } else {
- key_modifier = KEY_MODIFIER_MULTITAP_START;
- }
- } else {
- key_modifier = KEY_MODIFIER_NONE;
- }
- if (button_context->multitap_index < MAX_SIZE_OF_MULTITAP_CHAR) {
- key_event_desc.key_value = coordinate->key_value[shift_index][button_context->multitap_index];
- key_event_desc.key_event = coordinate->key_event[shift_index][button_context->multitap_index];
- key_event_desc.key_modifier = key_modifier;
- if (SCL_EVENT_PASS_ON == handler->on_event_key_clicked(key_event_desc)) {
- CSCLEvents *events = CSCLEvents::get_instance();
- events->destroy_timer(SCL_TIMER_MULTITAP);
- events->create_timer(SCL_TIMER_MULTITAP, m_multitap_delay_duration, 0);
- }
- }
- /* Check if the multikey index is in valid range, and increase by one */
- if (button_context->multitap_index >= MAX_SIZE_OF_MULTITAP_CHAR - 1) {
- button_context->multitap_index = 0;
- } else {
- sclbyte orgindex = button_context->multitap_index;
- button_context->multitap_index = 0;
- if (targetCoordinate->key_value[shift_index][orgindex + 1]) {
- if (strlen(targetCoordinate->key_value[shift_index][orgindex + 1]) > 0) {
- button_context->multitap_index = orgindex + 1;
- }
- }
- }
- }
- break;
- case BUTTON_TYPE_DRAG : {
- }
- break;
- case BUTTON_TYPE_TOGGLE : {
- SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
- if (pressed_context) {
- if (!(targetCoordinate->use_repeat_key) && pressed_context->state == BUTTON_STATE_PRESSED) {
- key_event_desc.key_value = targetCoordinate->key_value[shift_index][0];
- key_event_desc.key_event = targetCoordinate->key_event[shift_index][0];
- if (pressed_context->toggled) {
- key_event_desc.key_modifier = KEY_MODIFIER_NONE;
- } else {
- key_event_desc.key_modifier = KEY_MODIFIER_TOGGLED;
- }
- if (SCL_EVENT_PASS_ON == handler->on_event_key_clicked(key_event_desc)) {
- pressed_context->toggled = !(pressed_context->toggled);
- }
- }
- }
- }
- case BUTTON_TYPE_UIITEM: break;
- case MAX_BUTTON_TYPE: break;
- default: break;
- }
- switch (coordinate->popup_type) {
- case POPUP_TYPE_BTN_RELEASE_POPUP:
- case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE: {
- SCLDragState dragstate = context->get_cur_drag_state(touch_id);
- sclint popup_input_mode = NOT_USED;
-
- SclNotiPopupOpeningDesc desc;
- desc.ui_event_desc = &key_event_desc;
-
- if (scl_check_arrindex(dragstate, SCL_DRAG_STATE_MAX)) {
- desc.input_mode = coordinate->popup_input_mode[dragstate];
- popup_input_mode = sclres_manager->get_inputmode_id(coordinate->popup_input_mode[dragstate]);
- /* FIXME */
- //if (!scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP)) {
- if (!scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE)) {
- desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
- }
- }
- if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
- popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
- SCLDisplayMode display_mode = context->get_display_mode();
- /* FIXME */
- //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
- if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
- scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
- sclshort popupLayoutId =
- sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
- if (popupLayoutId == NOT_USED) {
- // deal with NOT_USED
- LOGD("popupLayoutID is not used.");
- }
- SclLayout *layout = NULL;
- /* FIXME */
- //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
- if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
- layout = &sclres_layout[popupLayoutId];
- }
- if (layout) {
- SclRectangle popupRect;
- SclRectangle baseWndRect;
- windows->get_window_rect(windows->get_base_window(), &baseWndRect);
- popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
- popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
-
- //popupRect.width = utils->get_scale_x(layout->width);
- //popupRect.height= utils->get_scale_y(layout->height);
- if (!(sclres_manager->loaded(popupLayoutId))) {
- sclres_manager->load(popupLayoutId);
- }
- popupRect.width = layout->width;
- popupRect.height = layout->height;
-
- /* Let's make sure this popup window does not go beyond the screen area */
- sclint scr_w, scr_h;
- utils->get_screen_resolution(&scr_w, &scr_h);
-
- if (popupRect.x + popupRect.width > scr_w) {
- popupRect.x = scr_w - popupRect.width;
- }
- if (popupRect.y + popupRect.height > scr_h) {
- popupRect.y = scr_h - popupRect.height;
- }
-
- SclWindowOpener opener;
- opener.window = window;
- opener.key = key_index;
-
- sclwindow popup_window = windows->open_popup(
- opener,
- popupRect,
- popup_input_mode,
- popupLayoutId,
- coordinate->popup_type,
- sclres_input_mode_configure[popup_input_mode].use_virtual_window,
- sclres_input_mode_configure[popup_input_mode].use_dim_window,
- coordinate->extract_offset_x,
- coordinate->extract_offset_y,
- sclres_input_mode_configure[popup_input_mode].timeout);
-
- SclNotiPopupOpenedDesc opened_desc;
- opened_desc.ui_event_desc = &key_event_desc;
- opened_desc.input_mode = desc.input_mode;
- opened_desc.window = popup_window;
- handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
-
- windows->hide_window(windows->get_magnifier_window());
- _play_tts_for_input_mode_name(popup_input_mode);
- }
- }
- }
- }
- break;
- case POPUP_TYPE_AUTO_POPUP:
- case POPUP_TYPE_BTN_PRESS_POPUP_DRAG:
- case POPUP_TYPE_NONE:
- /* Nothing to do in here */
- break;
- case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE: break;
- case POPUP_TYPE_BTN_LONGPRESS_POPUP: break;
- case MAX_POPUP_TYPE: break;
- default: break;
- }
- }
-
- context->set_last_event_fired_window(window);
- context->set_last_event_fired_key(key_index);
- }
- } else {
- if (targetCoordinate) {
- SCLShiftState shift_index = context->get_shift_state();
- if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
- if (context->get_caps_lock_mode()) {
- shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
- }
-
- SclUIEventDesc key_event_desc;
- key_event_desc.key_type = targetCoordinate->key_type;
-
- key_event_desc.key_value = targetCoordinate->key_value[shift_index][button_context->multitap_index];
- key_event_desc.key_event = targetCoordinate->key_event[shift_index][button_context->multitap_index];
- key_event_desc.key_modifier = key_modifier;
-
- key_event_desc.event_type = EVENT_TYPE_RELEASE;
- key_event_desc.touch_id = touch_id;
- key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
- key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
- key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
- key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
- handler->on_event_drag_state_changed(key_event_desc);
- }
- }
-
- /* If this button was pressed, initialize the button context regardless of event */
- if (button_context->state == BUTTON_STATE_PRESSED) {
- /* But, if this button should be in pressed state in other multitouch id, do not initialize */
- sclboolean found = FALSE;
- for (sclint loop = 0;loop < context->get_multi_touch_context_num() && !found;loop++) {
- SclUIEventDesc desc;
- context->get_multi_touch_event(loop, &desc);
- if (desc.touch_id != touch_id) {
- MultiTouchContext *multi_touch_context = context->find_multi_touch_context(desc.touch_id);
- if (multi_touch_context) {
- if (multi_touch_context->cur_pressed_window == window &&
- multi_touch_context->cur_pressed_key == key_index) {
- found = TRUE;
- }
- }
- }
- }
- if (!found) {
- button_context->state = BUTTON_STATE_NORMAL;
- redraw = TRUE;
- }
- }
-
- /* If this button needs to be redrawn */
- if (redraw) {
-#ifdef DIRECTLY_DRAW_ON_EVENTS
- CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
- if (builder) {
- builder->draw_button(window, NULL, key_index, button_context->state, TRUE);
- }
-#else
- if (savedInputMode == context->get_input_mode()) {
- windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
- }
-
-#endif
- }
- }
-
- return ret;
-}
-
-sclboolean
-CSCLController::mouse_press(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
-{
- SCL_DEBUG();
- sclboolean ret = FALSE;
-
- if (m_input_events_disabled) return FALSE;
-
- //utils->log("Controller::mouse_press : %d %d\n", x, y);
-
- /* Adjust x,y coordinate by touch offset */
- CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
-
- CSCLContext *context = CSCLContext::get_instance();
- CSCLResourceCache *cache = CSCLResourceCache::get_instance();
- CSCLActionState *state = CSCLActionState::get_instance();
- CSCLWindows *windows = CSCLWindows::get_instance();
- CSCLUtils *utils = CSCLUtils::get_instance();
-
- sclint button_index = NOT_USED;
- SclWindowContext *window_context = NULL;
- if (windows && cache) {
- const SclLayout *layout = cache->get_cur_layout(window);
- if (layout) {
- x += layout->mouse_manipulate_x;
- y += layout->mouse_manipulate_y;
- }
- window_context = windows->get_window_context(window);
- /* If the dim window is virtual and currently active, let's just skip this event */
- if (windows->is_base_window(window)) {
- SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
- if (dim_window_context) {
- LOGD("dim window is_virtual:%d, hidden:%d", dim_window_context->is_virtual, dim_window_context->hidden);
- if (/*dim_window_context->is_virtual &&*/ !(dim_window_context->hidden)) {
- window = windows->get_dim_window();
- window_context = dim_window_context;
- }
- }
- }
- }
-
- if (cache && state && windows && context && window_context) {
- SCLDisplayMode display_mode = context->get_display_mode();
- SclResParserManager *sclres_manager = SclResParserManager::get_instance();
- PSclDefaultConfigure default_configure = NULL;
- if (sclres_manager) {
- default_configure = sclres_manager->get_default_configure();
- }
- if (default_configure) {
- adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
- }
-
- sclboolean isSubEvent = FALSE;
- if (context->get_multi_touch_context_num() > 0) {
- SclUIEventDesc desc;
- context->get_multi_touch_event(0, &desc);
- sclwindow pressed_window = context->get_cur_pressed_window(desc.touch_id);
- scl8 pressed_key = context->get_cur_pressed_key(desc.touch_id);
- SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
- if (coordinate) {
- if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_GRAB_SUB_EVENTS) {
- isSubEvent = TRUE;
- if (utils)
- utils->play_vibration(DEFAULT_VIBRATION_STYLE, DEFAULT_VIBRATION_DURATION);
- }
- }
- }
- context->create_multi_touch_context(touch_id, isSubEvent);
- context->set_cur_pressed_window(touch_id, window);
- context->set_cur_pressed_point(touch_id, x, y);
- context->set_cur_pressed_time(touch_id);
- context->set_cur_moving_window(touch_id, window);
- context->set_cur_moving_point(touch_id, x, y);
- context->set_last_touch_device_id(touch_id);
- context->set_cur_drag_state(touch_id, SCL_DRAG_STATE_NONE);
- context->set_cur_key_modifier(touch_id, KEY_MODIFIER_NONE);
- for (sclint labelidx = 0;labelidx < MAX_SIZE_OF_LABEL_FOR_ONE;labelidx++) {
- context->set_custom_magnifier_label(touch_id, labelidx, NULL);
- }
-
- /* If there is postponed update of button, update it now */
- CSCLEvents *events = CSCLEvents::get_instance();
- sclwindow last_win = context->get_last_pressed_window();
- scl8 last_key = context->get_last_pressed_key();
- if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
- const SclLayoutKeyCoordinate* coords = cache->get_cur_layout_key_coordinate(last_win, last_key);
- if (coords) {
- windows->update_window(last_win, coords->x, coords->y, coords->width, coords->height);
- }
- }
- context->set_prev_pressed_window(touch_id, SCLWINDOW_INVALID);
- context->set_prev_pressed_key(touch_id, NOT_USED);
- context->set_prev_drag_state(touch_id, SCL_DRAG_STATE_NONE);
- context->set_prev_moving_point(touch_id, x, y);
-
- /* Destroy key related timers */
- events->destroy_timer(SCL_TIMER_BUTTON_DELAY);
- events->destroy_timer(SCL_TIMER_AUTOPOPUP);
- events->destroy_timer(SCL_TIMER_SHORT_LONGKEY);
- events->destroy_timer(SCL_TIMER_LONGKEY);
- events->destroy_timer(SCL_TIMER_REPEATKEY);
- events->destroy_timer(SCL_TIMER_MULTITAP);
-
- /* Do what has to be done when mouse gets pressed */
- handle_engine_signal(SCL_SIG_MOUSE_PRESS, window);
-
- /* Adjust event x and y positions as relative position to the virtual window */
- if (window_context) {
- /*if (window_context->isVirtual) {
- SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
- if (base_window_context) {
- x -= (window_context->x - base_window_context->x);
- y -= (window_context->y - base_window_context->y);
- }
- }*/
- }
-
- if (!isSubEvent) {
- sclboolean process_finished = FALSE;
- do {
- /* Iterate all the buttons and inform the event */
- sclboolean ended = FALSE;
- for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
- SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
- const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, loop);
- if (button_context && coordinate) {
- if (!(button_context->used)) {
- ended = TRUE;
- } else if (button_context->state != BUTTON_STATE_DISABLED &&
- coordinate->button_type != BUTTON_TYPE_UIITEM) {
- if (process_button_pressed_event(window, x, y, loop, touch_id, actual_event)) {
- if (windows->is_base_window(window)) {
- state->set_cur_action_state(ACTION_STATE_BASE_PRESS);
- } else {
- state->set_cur_action_state(ACTION_STATE_POPUP_PRESS);
- }
- button_index = loop;
- ret = TRUE;
- }
- }
- }
- }
-
- /* For covering a missing area about 1 pixel */
- if (!ret) {
- for (int loop = 0;loop < MAX_KEY;loop++) {
- SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
- const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, loop);
- if (button_context && coordinate) {
- if (!(button_context->used)) {
- break;
- } else if (button_context->state != BUTTON_STATE_DISABLED &&
- coordinate->button_type != BUTTON_TYPE_UIITEM) {
- if (process_button_pressed_event(window, x+1, y+1, loop, touch_id, actual_event)) {
- if (windows->is_base_window(window)) {
- state->set_cur_action_state(ACTION_STATE_BASE_PRESS);
- } else {
- state->set_cur_action_state(ACTION_STATE_POPUP_PRESS);
- }
- button_index = loop;
- break;
- }
- }
- } else {
- break;
- }
- }
- }
-
- if (windows->is_base_window(window)) {
- process_finished = TRUE;
- } else if (button_index != NOT_USED) {
- process_finished = TRUE;
- } else {
- const SclLayout *layout = cache->get_cur_layout(window);
- if (layout) {
- if (layout->use_sw_background && layout->bg_color.a == 0) {
- /* If we could not find appropriate button in this popup window and the popup is transparent */
- SclWindowContext *base_window_context =
- windows->get_window_context(windows->get_base_window());
- if (base_window_context) {
- x = (window_context->geometry.x + x - base_window_context->geometry.x);
- y = (window_context->geometry.y + y - base_window_context->geometry.y);
- }
- window = windows->get_base_window();
- } else {
- process_finished = TRUE;
- }
- } else {
- process_finished = TRUE;
- }
- }
- } while (!process_finished);
- }
-
- sclwindow skip_window = window;
- if (ret && button_index != NOT_USED) {
- const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, button_index);
- if (coordinate) {
- sclboolean dont_close_popup = FALSE;
- if (coordinate->dont_close_popup) {
- dont_close_popup = TRUE;
- }
- /* If the button's popup type is drag type, the opened popup could be the one opened by this press event */
- if (coordinate->popup_type == POPUP_TYPE_BTN_PRESS_POPUP_DRAG) {
- /* Check the opened popup was opened by this button */
- sclwindow popupwin = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
- SclWindowContext *popup_window_context = windows->get_window_context(popupwin);
- if (popup_window_context) {
- SclWindowOpener opener = popup_window_context->opener;
- if (opener.window == window && opener.key == button_index) {
- dont_close_popup = TRUE;
- }
- }
- }
- if (dont_close_popup) {
- skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
- }
- }
- } else {
- SclUIEventDesc key_event_desc;
- key_event_desc.event_type = EVENT_TYPE_PRESS;
-
- SclPoint curpoint = {x, y};
- key_event_desc.touch_id = touch_id;
- key_event_desc.mouse_pressed_point = curpoint;
- key_event_desc.mouse_current_point = curpoint;
- key_event_desc.mouse_farthest_point = curpoint;
-
- key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
- CSCLEventHandler *handler = CSCLEventHandler::get_instance();
- if (handler) {
- handler->on_event_drag_state_changed(key_event_desc);
- }
- }
- windows->close_all_popups(skip_window);
-
- /* When press event occured in popup window, reset POPUP_TIMEOUT timer */
- if (!(windows->is_base_window(window))) {
- if (window_context->timeout > 0) {
- events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
- events->create_timer(SCL_TIMER_POPUP_TIMEOUT, window_context->timeout, 0, TRUE);
- }
- } else if (skip_window != window) { /* Or the pressed button has dont_close_popup property, reset POPUP_TIMEOUT timer */
- //SclWindowContext *skip_window_context = windows->get_window_context(skip_window, FALSE);
- SclWindowContext *skip_window_context = windows->get_window_context(skip_window);
- if (skip_window_context) {
- if (skip_window_context->timeout > 0) {
- events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
- events->create_timer(SCL_TIMER_POPUP_TIMEOUT, skip_window_context->timeout, 0, TRUE);
- }
- }
- }
- }
-
- return TRUE;
-}
-
-sclboolean
-CSCLController::mouse_release(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
-{
- SCL_DEBUG();
- sclboolean ret = FALSE;
-
- //if (m_input_events_disabled) return FALSE;
-
- //utils->log("Controller::mouse_release : %d %d\n", x, y);
- /* Adjust x,y coordinate by touch offset */
- CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
-
- CSCLContext *context = CSCLContext::get_instance();
- CSCLResourceCache *cache = CSCLResourceCache::get_instance();
- CSCLActionState *state = CSCLActionState::get_instance();
- CSCLWindows *windows = CSCLWindows::get_instance();
- CSCLUtils *utils = CSCLUtils::get_instance();
- CSCLEventHandler *handler = CSCLEventHandler::get_instance();
- CSCLEvents *events = CSCLEvents::get_instance();
-
- sclint button_index = NOT_USED;
-
- if (cache && state && windows && context && utils && handler && events &&
- context->find_multi_touch_context(touch_id)) {
- const SclLayout *layout = cache->get_cur_layout(window);
- if (layout) {
- x += layout->mouse_manipulate_x;
- y += layout->mouse_manipulate_y;
- }
-
- sclwindow skip_window = SCLWINDOW_INVALID;
- SCLDisplayMode display_mode = context->get_display_mode();
-
- SclResParserManager *sclres_manager = SclResParserManager::get_instance();
- PSclDefaultConfigure default_configure = NULL;
- if (sclres_manager) {
- default_configure = sclres_manager->get_default_configure();
- }
- if (default_configure) {
- adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
- }
-
- context->set_cur_moving_window(touch_id, SCLWINDOW_INVALID);
-
- sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
- scl8 pressed_key = context->get_cur_pressed_key(touch_id);
- //SclWindowContext *window_context = windows->get_window_context(window, TRUE);
- SclWindowContext *window_context = windows->get_window_context(window);
- /* Adjust event x and y positions as relative position to the virtual window */
- if (window_context) {
- /*if (window_context->isVirtual) {
- SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
- if (base_window_context) {
- x -= (window_context->x - base_window_context->x);
- y -= (window_context->y - base_window_context->y);
- }
- }*/
- /* If the dim window is virtual and currently active, consider base window's event is occured in dim window */
- if (windows->is_base_window(window)) {
- SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
- if (dim_window_context) {
- if (dim_window_context->is_virtual && !(dim_window_context->hidden)) {
- window = windows->get_dim_window();
- window_context = dim_window_context;
- }
- }
- }
- }
-
- /* Iterate all the buttons and inform the event */
- sclboolean ended = FALSE;
-
- /* FIXME : The routine below seems to be removed, which was originally requested by Vodafone,
- * to slow down the speed of repeat key right before stopping repeatkey event */
- /* if (state->get_cur_action_state() == ACTION_STATE_BASE_REPEATKEY) {
- if (m_key_repeated_num > 10) {
- utils->sleep(100);
- process_button_repeat_pressed_event(pressed_window, pressed_key, touch_id);
- }
- ended = TRUE;
- }*/
-
- if (context->get_cur_pressed_window(touch_id) == window) {
- if (abs(context->get_cur_pressed_point(touch_id).x - x) > utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD) ||
- abs(context->get_cur_pressed_point(touch_id).y - y) > utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD) )
- {
- struct timeval t0 = context->get_cur_pressed_time(touch_id);
- struct timeval t1;
- gettimeofday(&t1, NULL);
- float etime;
- etime = ((t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec))/1000.0;
- if (etime < SCL_FLICK_GESTURE_RECOG_TIME) {
- SCLDragType drag_type = DRAG_NONE;
- if (x > context->get_cur_pressed_point(touch_id).x + utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
- drag_type = DRAG_RIGHT;
- }
- if (x < context->get_cur_pressed_point(touch_id).x - utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
- drag_type = DRAG_LEFT;
- }
- if (y > context->get_cur_pressed_point(touch_id).y + utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
- drag_type = DRAG_DOWN;
- }
- if (y < context->get_cur_pressed_point(touch_id).y - utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
- drag_type = DRAG_UP;
- }
- SclNotiGestureFlickDesc desc;
- SclUIEventDesc ui_event_desc;
- ui_event_desc.key_value = NULL;
- ui_event_desc.key_event = NOT_USED;
- ui_event_desc.key_modifier = KEY_MODIFIER_NONE;
- ui_event_desc.event_type = EVENT_TYPE_RELEASE;
- ui_event_desc.touch_id = touch_id;
- ui_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
- ui_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
- ui_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
- ui_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
- desc.ui_event_desc = &ui_event_desc;
- desc.drag_type = drag_type;
- if (handler->on_event_notification(SCL_UINOTITYPE_GESTURE_FLICK, &desc)) {
- ended = TRUE;
- }
- }
- }
- }
-
- /* FIXME : We should consider this kind of action in general manner, not only specific to autopopup */
- /* And also, this kind of implementation only selects button that was highlighted at least once. */
- // {
- //SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window, FALSE);
- SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window);
- if (pressed_window_context) {
- utils->log("PRESSED CTX : %p %d %d\n", pressed_window,
- pressed_window_context->geometry.x, pressed_window_context->geometry.y);
- //if (pressedCtx->popuptype == POPUP_TYPE_AUTO_POPUP) {
- sclboolean grab_event = FALSE;
- const SclLayout *pressed_layout = cache->get_cur_layout(pressed_window);
- if (pressed_layout) {
- if (pressed_layout->style == LAYOUT_STYLE_POPUP_GRAB) {
- grab_event = TRUE;
- }
- /* If the topmost window has the POPUP_GRAB style, find the nearest button to the mouse pointer */
- if (grab_event) {
- /* If the layout's addGrab* values are defined, process this event only if the event occured inside grab area */
- sclboolean in_grab_area = TRUE;
- if (pressed_layout->add_grab_left != NOT_USED &&
- x < (pressed_window_context->geometry.x - pressed_layout->add_grab_left)) {
- in_grab_area = FALSE;
- }
- if (pressed_layout->add_grab_right != NOT_USED &&
- x > (pressed_window_context->geometry.x + pressed_window_context->geometry.width
- + pressed_layout->add_grab_right)) {
- in_grab_area = FALSE;
- }
- if (pressed_layout->add_grab_top != NOT_USED &&
- y < (pressed_window_context->geometry.y - pressed_layout->add_grab_top)) {
- in_grab_area = FALSE;
- }
- if (pressed_layout->add_grab_bottom != NOT_USED &&
- y > (pressed_window_context->geometry.y + pressed_window_context->geometry.height
- + pressed_layout->add_grab_bottom)) {
- in_grab_area = FALSE;
- }
- if (in_grab_area) {
- SclLayoutKeyCoordinate *coord = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
- if (coord) {
- x = coord->x + (coord->width / 2);
- y = coord->y + (coord->height / 2);
-
- for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
- SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, loop);
- const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, loop);
- if (button_context && coordinate) {
- if (!(button_context->used)) {
- ended = TRUE;
- } else if (button_context->state != BUTTON_STATE_DISABLED &&
- coordinate->button_type != BUTTON_TYPE_UIITEM) {
- if (process_button_release_event(pressed_window, x, y, loop, touch_id, actual_event)) {
- ret = TRUE;
- ended = TRUE;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- // }
-
- SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
- const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
-
- /* FIXME : The rule below would not be a general requirement. A policy is needed regarding this. */
- /* Ignore base window's release event if a popup window is opened */
- if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
- if (windows->is_base_window(window)) {
- ended = TRUE;
- /* In case of direction button, the release event on other window should be processed */
- if (coordinate && window_context && pressed_window_context) {
- if (coordinate->button_type == BUTTON_TYPE_DIRECTION || coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
- sclint relx = (window_context->geometry.x + x) - pressed_window_context->geometry.x;
- sclint rely = (window_context->geometry.y + y) - pressed_window_context->geometry.y;
- if (process_button_release_event(pressed_window, relx, rely, pressed_key, touch_id, actual_event)) {
- button_index = pressed_key;
- ret = TRUE;
- x = coordinate->x + (coordinate->width / 2);
- y = coordinate->y + (coordinate->height / 2);
- skip_window = pressed_window;
- }
- }
- }
- }
- }
-
- sclboolean process_finished = FALSE;
- do {
- MultiTouchContext *multi_touch_context = context->find_multi_touch_context(touch_id);
- if (multi_touch_context) {
- if (!(multi_touch_context->is_sub_event)) {
- /* First check if the event occured in pressed key's threshold area */
- if (button_context && coordinate && !ended) {
- if (button_context->used && button_context->state != BUTTON_STATE_DISABLED) {
- if (process_button_release_event(pressed_window, x, y, pressed_key, touch_id, actual_event)) {
- button_index = pressed_key;
- ret = TRUE;
- x = coordinate->x + (coordinate->width / 2);
- y = coordinate->y + (coordinate->height / 2);
- }
- }
- }
- for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
- SclButtonContext *cur_context = cache->get_cur_button_context(window, loop);
- const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, loop);
- if (cur_context && cur_coordinate) {
- if (!(cur_context->used)) {
- ended = TRUE;
- } else if (cur_context->state != BUTTON_STATE_DISABLED &&
- cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
- if (window != pressed_window || loop != pressed_key) {
- if (process_button_release_event(window, x, y, loop, touch_id, actual_event)) {
- button_index = loop;
- ret = TRUE;
- }
- }
- }
- }
- }
- } else {
- process_finished = TRUE;
-
- SclUIEventDesc key_event_desc;
- key_event_desc.key_value = NULL;
- key_event_desc.key_event = NOT_USED;
- key_event_desc.key_modifier = KEY_MODIFIER_NONE;
- key_event_desc.event_type = EVENT_TYPE_NONE;
- key_event_desc.touch_id = touch_id;
- key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
- key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
- key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
- key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
- handler->on_event_key_clicked(key_event_desc);
- }
- }
-
- /* For covering a missing area about 1 pixel */
- if (!ret) {
- ended = FALSE;
-
- if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
- if (windows->is_base_window(window)) {
- ended = TRUE;
- }
- }
-
- for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
- SclButtonContext *cur_context = cache->get_cur_button_context(window, loop);
- if (cur_context && coordinate) {
- if (!(cur_context->used)) {
- ended = TRUE;
- break;
- } else if (cur_context->state != BUTTON_STATE_DISABLED &&
- coordinate->button_type != BUTTON_TYPE_UIITEM) {
- if (process_button_release_event(window, x+1, y+1, loop, touch_id)) {
- button_index = loop;
- ret = TRUE;
- break;
- }
- }
- }
- }
- }
- if (windows->is_base_window(window)) {
- process_finished = TRUE;
- } else if (button_index != NOT_USED) {
- process_finished = TRUE;
- } else {
- if (layout && layout->use_sw_background && layout->bg_color.a == 0) {
- /* If we could not find appropriate button in this popup window and the popup is transparent */
- SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
- if (base_window_context && window_context) {
- x = (window_context->geometry.x + x - base_window_context->geometry.x);
- y = (window_context->geometry.y + y - base_window_context->geometry.y);
- }
- window = windows->get_base_window();
- } else {
- process_finished = TRUE;
- }
- }
- } while (!process_finished);
-
- if (!ret) {
- SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
- const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
-
- SCLShiftState shift_index = context->get_shift_state();
- if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
- if (context->get_caps_lock_mode()) {
- shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
- }
-
- SclUIEventDesc key_event_desc;
- if (coordinate && button_context) {
- key_event_desc.key_type = coordinate->key_type;
-
- key_event_desc.key_value = coordinate->key_value[shift_index][button_context->multitap_index];
- key_event_desc.key_event = coordinate->key_event[shift_index][button_context->multitap_index];
- }
- key_event_desc.key_modifier = context->get_cur_key_modifier(touch_id);;
-
- key_event_desc.event_type = EVENT_TYPE_RELEASE;
- key_event_desc.touch_id = touch_id;
- key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
- key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
- key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
- key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
- handler->on_event_drag_state_changed(key_event_desc);
- }
-
- if (windows->is_base_window(window)) {
- state->set_cur_action_state(ACTION_STATE_BASE_INIT);
- } else {
- state->set_cur_action_state(ACTION_STATE_POPUP_INIT);
- }
-
- /* Restore previously pressed button's context and redraw it */
- if (button_context && coordinate) {
- button_context->state = BUTTON_STATE_NORMAL;
- /* Commented below line to postpone some of the feedback for releasing */
- //windows->update_window(pressed_window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
- }
-
- /* If there is postponed update of button, update it now */
- sclwindow last_win = context->get_last_pressed_window();
- scl8 last_key = context->get_last_pressed_key();
- if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
- const SclLayoutKeyCoordinate* coords = cache->get_cur_layout_key_coordinate(last_win, last_key);
- if (coords) {
- windows->update_window(last_win, coords->x, coords->y, coords->width, coords->height);
- }
- }
-
- /* To postpone some of the feedback for releasing */
- context->set_last_pressed_key(context->get_cur_pressed_key(touch_id));
- context->set_last_pressed_window(context->get_cur_pressed_window(touch_id));
-
- /* Do what has to be done when mouse gets released */
- sclboolean signaled = FALSE;
- if (coordinate) {
- switch (coordinate->popup_type) {
- case POPUP_TYPE_BTN_RELEASE_POPUP:
- case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE:
- case POPUP_TYPE_BTN_LONGPRESS_POPUP:
- case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE:
- {
- /* Fix me : We should consider z-order */
- skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
- handle_engine_signal(SCL_SIG_MOUSE_RELEASE, skip_window);
- signaled = TRUE;
- }
- break;
- case POPUP_TYPE_NONE: break;
- case POPUP_TYPE_BTN_PRESS_POPUP_DRAG: break;
- case POPUP_TYPE_AUTO_POPUP: break;
- case MAX_POPUP_TYPE: break;
- default: break;
- }
- }
- if (!signaled) {
- //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
- window_context = windows->get_window_context(window);
- if (window_context) {
- if (window_context->popup_type == POPUP_TYPE_BTN_RELEASE_POPUP ||
- window_context->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP) {
- /* Don't close window if the clicked button is a child of ReleasePopup window */
- skip_window = window;
- handle_engine_signal(SCL_SIG_MOUSE_RELEASE, window);
- signaled = TRUE;
- }
- }
- if (!signaled) {
- handle_engine_signal(SCL_SIG_MOUSE_RELEASE);
- }
- }
-
- context->set_cur_pressed_key(touch_id, NOT_USED);
- context->set_cur_pressed_window(touch_id, SCLWINDOW_INVALID);
-
- if (ret && button_index != NOT_USED) {
- const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, button_index);
- if (cur_coordinate) {
- if (cur_coordinate->dont_close_popup) {
- skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
- }
- }
- } else {
- if (pressed_window == windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP)) {
- if (pressed_window_context) {
- if (pressed_window_context->popup_type != POPUP_TYPE_BTN_RELEASE_POPUP_ONCE &&
- pressed_window_context->popup_type != POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE &&
- pressed_window_context->popup_type != POPUP_TYPE_AUTO_POPUP &&
- pressed_window_context->popup_type != POPUP_TYPE_BTN_PRESS_POPUP_DRAG)
- {
- skip_window = pressed_window;
- }
- }
- }
- }
- windows->close_all_popups(skip_window);
-
- /* Destroy key related timers */
- events->destroy_timer(SCL_TIMER_AUTOPOPUP);
- events->destroy_timer(SCL_TIMER_SHORT_LONGKEY);
- events->destroy_timer(SCL_TIMER_LONGKEY);
- events->destroy_timer(SCL_TIMER_REPEATKEY);
-
- /* If there are more than 1 active multitouch ids, don't play button_delay trick */
- if (context->get_multi_touch_context_num() == 1) {
- /* To postpone some of the feedback for releasing */
- events->create_timer(SCL_TIMER_BUTTON_DELAY, m_button_delay_duration, 0);
- } else {
- last_win = context->get_last_pressed_window();
- last_key = context->get_last_pressed_key();
-
- if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
- const SclLayoutKeyCoordinate* last_coordinate = cache->get_cur_layout_key_coordinate(last_win, last_key);
- if (last_coordinate) {
- windows->update_window(last_win,
- last_coordinate->x, last_coordinate->y, last_coordinate->width, last_coordinate->height);
- }
- }
-
- windows->hide_window(windows->get_magnifier_window());
- context->set_last_pressed_window(SCLWINDOW_INVALID);
- context->set_last_pressed_key(NOT_USED);
- }
- }
-
- if (context) {
- if (touch_id == context->get_last_touch_device_id()) {
- context->set_last_touch_device_id(SCLTOUCHDEVICE_INVALID);
- }
- context->destroy_multi_touch_context(touch_id);
- }
-
- return ret;
-}
-
-SCLDragState get_drag_state(sclint deltax, sclint deltay)
-{
- SCLDragState ret = SCL_DRAG_STATE_MAX;
-
- sclfloat ratio = fabs((sclfloat)deltay / (deltax ? deltax : 1));
- /* If tan(theta) is smaller than our predefined value */
- if (ratio <= (1 / SCL_DRAG_CURVE_4_DIRECTION_ANGLE_VALUE)) {
- if (deltax > 0) {
- ret = SCL_DRAG_STATE_RIGHT;
- } else {
- ret = SCL_DRAG_STATE_LEFT;
- }
- } else if (ratio >= SCL_DRAG_CURVE_4_DIRECTION_ANGLE_VALUE) {
- /* If tan(theta) is bigger than our predefined value */
- if (deltay > 0) {
- ret = SCL_DRAG_STATE_DOWN;
- } else {
- ret = SCL_DRAG_STATE_UP;
- }
- } else {
- ret = SCL_DRAG_STATE_INVALID;
- }
-
- return ret;
-}
-
-sclboolean
-CSCLController::mouse_move(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
-{
- SCL_DEBUG();
- sclboolean ret = FALSE;
-
- if (m_input_events_disabled) return FALSE;
-
- //utils->log("Controller::mouse_move : %d %d\n", x, y);
-
- /* Adjust x,y coordinate by touch offset */
- CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
-
- CSCLContext *context = CSCLContext::get_instance();
- CSCLResourceCache *cache = CSCLResourceCache::get_instance();
- CSCLActionState *state = CSCLActionState::get_instance();
- CSCLWindows *windows = CSCLWindows::get_instance();
- CSCLEvents *events = CSCLEvents::get_instance();
- CSCLUtils *utils = CSCLUtils::get_instance();
- CSCLEventHandler *handler = CSCLEventHandler::get_instance();
- SclResParserManager *sclres_manager = SclResParserManager::get_instance();
-
- if (!sclres_manager) return FALSE;
-
- PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
- if (!sclres_modifier_decoration) return FALSE;
-
- if (cache && state && windows && context && utils && adjustment && sclres_manager) {
- const SclLayout *layout = cache->get_cur_layout(window);
- if (layout) {
- x += layout->mouse_manipulate_x;
- y += layout->mouse_manipulate_y;
- }
-
- if (!(context->find_multi_touch_context(touch_id))) return FALSE;
-
- PSclDefaultConfigure default_configure = sclres_manager->get_default_configure();
- if (default_configure) {
- SCLDisplayMode display_mode = context->get_display_mode();
- adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
- }
-
- //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
- SclWindowContext *window_context = windows->get_window_context(window);
- /* Adjust event x and y positions as relative position to the virtual window */
- if (window_context) {
- /*if (window_context->isVirtual) {
- SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
- if (base_window_context) {
- x -= (window_context->x - base_window_context->x);
- y -= (window_context->y - base_window_context->y);
- }
- }*/
- /* If the dim window is virtual and currently active, let's just skip this event */
- if (windows->is_base_window(window)) {
- SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
- if (dim_window_context) {
- if (dim_window_context->is_virtual && !(dim_window_context->hidden)) {
- return FALSE;
- }
- }
- }
- /* If the pressed event was occured in dim window, let's just skip this move event */
- if (context->get_last_pressed_window() == windows->get_dim_window()) {
- return FALSE;
- }
- }
-
- sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
- scl8 pressed_key = context->get_cur_pressed_key(touch_id);
- SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
- const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
-
- /* If the multitouch type is SETTLE_PREVIOUS and is not the last touch device, let's ignore move events */
- if (coordinate) {
- if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
- if (context->get_last_touch_device_id() != touch_id) {
- return FALSE;
- }
- }
- }
-
- context->set_cur_moving_point(touch_id, x, y);
- context->set_cur_moving_window(touch_id, window);
-
- /* If in longkey state, do not process, just return */
- if (state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
- state->get_cur_action_state() == ACTION_STATE_BASE_REPEATKEY ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY) {
- return FALSE;
- }
- /* FIXME : The rule below would not be a general requirement. A policy is needed regarding this. */
- /* And if the event occured in popup window, don't come back to base window */
- if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
- state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
- if (windows->is_base_window(window)) {
- return FALSE;
- }
- }
-
- SclUIEventDesc desc;
- SCLShiftState shift_index = context->get_shift_state();
- if (context->get_caps_lock_mode()) {
- shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
- }
- if (coordinate) {
- desc.key_type = coordinate->key_type;
- desc.key_value = coordinate->key_value[shift_index][0];
- desc.key_event = coordinate->key_event[shift_index][0];
- }
- desc.event_type = EVENT_TYPE_MOVE;
- desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
- desc.mouse_current_point = context->get_cur_moving_point(touch_id);
- desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
- if (handler && handler->on_event_drag_state_changed(desc) != SCL_EVENT_PASS_ON) {
- return FALSE;
- }
-
- /* FIXME : Add a condition to skip this code if longkey timer is not active */
- /* If the mouse has moved out of threshold value of longkey keypress area, destroy longkey timer */
- if (m_long_key_cancel_distance > 0) {
- sclfloat dist = utils->get_distance(x, y,
- context->get_cur_pressed_point(touch_id).x, context->get_cur_pressed_point(touch_id).y);
- if (m_long_key_cancel_distance < dist) {
- events->destroy_timer(SCL_TIMER_LONGKEY);
- }
- }
-
- if (windows->is_base_window(window)) {
- state->set_cur_action_state(ACTION_STATE_BASE_MOVING);
- } else {
- state->set_cur_action_state(ACTION_STATE_POPUP_MOVING);
- }
-
- /* Iterate all the buttons and inform the event */
- sclboolean ended = FALSE;
-
- /* Check farthest move point and update it */
- sclint originx = x;
- sclint originy = y;
- if (pressed_window != window) {
- //SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window, FALSE);
- SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window);
- if (window_context && pressed_window_context) {
- originx = (window_context->geometry.x - pressed_window_context->geometry.x) + x;
- originy = (window_context->geometry.y - pressed_window_context->geometry.y) + y;
- }
- }
- sclint startx = originx;
- sclint starty = originy;
-
- /* Check if we should recognize drag curve */
- if (coordinate) {
- startx = context->get_cur_pressed_point(touch_id).x;
- starty = context->get_cur_pressed_point(touch_id).y;
- sclint deltax = originx - startx;
- sclint deltay = originy - starty;
- sclfloat approximate_dist = utils->get_approximate_distance(originx, originy, startx, starty);
-
- sclboolean update_magnifier = FALSE;
- sclboolean drag_state_changed = FALSE;
- SCLDragState cur_drag_state = context->get_cur_drag_state(touch_id);
- SCLDragState next_drag_state = SCL_DRAG_STATE_NONE;
- sclfloat direction_recog_dist = SCL_DIRECTION_RECOG_DIST * utils->get_smallest_scale_rate();
- if (coordinate->is_side_button) {
- direction_recog_dist = SCL_DIRECTION_RECOG_DIST_SIDE * utils->get_smallest_scale_rate();
- };
-
- if (coordinate->button_type == BUTTON_TYPE_DIRECTION) {
- /* Do not check farthest move point if current drag state is SCL_DRAG_STATE_RETURN */
- if (context->get_cur_drag_state(touch_id) != SCL_DRAG_STATE_RETURN) {
- if (approximate_dist > context->get_farthest_move_dist(touch_id)) {
- context->set_farthest_move_point(touch_id, originx, originy);
- }
- }
-
- if (cur_drag_state == SCL_DRAG_STATE_RETURN) {
- direction_recog_dist *= SCL_DRAG_RETURN_RECOG_THRESHOLD_RETURN;
- } else if (cur_drag_state != SCL_DRAG_STATE_NONE) {
- direction_recog_dist *= SCL_DRAG_RETURN_RECOG_THRESHOLD_OTHER;
- }
- if (approximate_dist > direction_recog_dist) {
- next_drag_state = get_drag_state(deltax, deltay);
- /* Disable longkey if dragging is recognized */
- events->destroy_timer(SCL_TIMER_LONGKEY);
- }
- if (cur_drag_state != next_drag_state) {
- drag_state_changed = TRUE;
- }
- if (cur_drag_state == SCL_DRAG_STATE_NONE) {
- //if (nextDragState != SCL_DRAG_STATE_INVALID) {
- cur_drag_state = next_drag_state;
- //}
- } else if (cur_drag_state != next_drag_state) {
- if (next_drag_state == SCL_DRAG_STATE_NONE) {
- cur_drag_state = SCL_DRAG_STATE_RETURN;
- } else {
- cur_drag_state = next_drag_state;
- }
- }
-
- context->set_cur_drag_state(touch_id, cur_drag_state);
- sclboolean check_farthest = FALSE;
- sclshort display = context->get_display_mode();
- if (!scl_check_arrindex(display, DISPLAYMODE_MAX)) display = 0;
- sclfloat dist = utils->get_distance(originx, originy,
- context->get_cur_pressed_point(touch_id).x, context->get_cur_pressed_point(touch_id).y);
- if (dist < direction_recog_dist && context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN) {
- if (coordinate->extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN ||
- coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN ||
- coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE) {
- deltax = context->get_farthest_move_point(touch_id).x -
- context->get_cur_pressed_point(touch_id).x;
- deltay = context->get_farthest_move_point(touch_id).y -
- context->get_cur_pressed_point(touch_id).y;
- dist = utils->get_distance(context->get_farthest_move_point(touch_id),
- context->get_cur_pressed_point(touch_id));
- check_farthest = TRUE;
- }
- }
- SCLKeyModifier key_modifier = get_drag_key_modifier(deltax, deltay, dist,
- check_farthest, touch_id, coordinate->extra_option);
- if (dist > direction_recog_dist) {
- context->set_cur_key_modifier(touch_id, key_modifier);
- }
- /* If this button needs to be decorated when dragged */
- if (coordinate->modifier_decorator) {
- const SclModifierDecoration *decoration = NULL;
- /* FIXME */
- /*if (scl_check_arrindex(coordinate->modifier_decorator,
- sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
- scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
- if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
- if (sclres_modifier_decoration[decoration_id].valid) {
- decoration = &(sclres_modifier_decoration[decoration_id]);
- }
- }
- /* Check if the button really needs to be redrawn (whether it has non-null bg_image_path information */
- if (decoration) {
- if (decoration->bg_image_path[display][key_modifier]) {
- windows->update_window(window,
- coordinate->x, coordinate->y, coordinate->width, coordinate->height);
- }
- }
- }
- if (dist > direction_recog_dist) {
- if (context->get_magnifier_enabled()) {
- update_magnifier = TRUE;
- }
- }
- } else if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
- if (cur_drag_state != SCL_DRAG_STATE_NONE) {
- startx = context->get_prev_moving_point(touch_id).x;
- starty = context->get_prev_moving_point(touch_id).y;
- approximate_dist = utils->get_approximate_distance(originx, originy, startx, starty);
- direction_recog_dist = SCL_DIRECTION_RELATIVE_RECOG_DIST * utils->get_smallest_scale_rate();
- }
- deltax = originx - startx;
- deltay = originy - starty;
- //printf("DIST : %f, RECOG : %f\n", dist, direction_recog_dist);
- if (approximate_dist > direction_recog_dist) {
- next_drag_state = get_drag_state(deltax, deltay);
- /* Disable longkey if dragging is recognized */
- events->destroy_timer(SCL_TIMER_LONGKEY);
-
- if (cur_drag_state != next_drag_state) {
- drag_state_changed = TRUE;
- }
- if (next_drag_state != SCL_DRAG_STATE_NONE) {
- cur_drag_state = next_drag_state;
- }
- context->set_cur_drag_state(touch_id, cur_drag_state);
-
- startx = context->get_farthest_move_point(touch_id).x;
- starty = context->get_farthest_move_point(touch_id).y;
- deltax = originx - startx;
- deltay = originy - starty;
- sclfloat dist_farthest = utils->get_approximate_distance(originx, originy, startx, starty);
- //printf("%d %d %d %d %f, %d %d\n", originx, originy, startx, starty, dist_farthest, cur_drag_state, next_drag_state);
- /* Let's see how much we are away from the last farthest point */
- sclfloat diffdir_recog_dist = SCL_DIRECTION_RELATIVE_DIFFDIR_RECOG_DIST * utils->get_smallest_scale_rate();
- /* If we moved certain amount from the point where direction changed, process drag state change routine */
- if (dist_farthest > diffdir_recog_dist || context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_NONE) {
- sclshort display = context->get_display_mode();
- SCLKeyModifier key_modifier = get_drag_key_modifier(deltax, deltay, dist_farthest,
- FALSE, touch_id, coordinate->extra_option);
- context->set_cur_key_modifier(touch_id, key_modifier);
- /* If this button needs to be decorated when dragged */
- if (coordinate->modifier_decorator) {
- const SclModifierDecoration *decoration = NULL;
- /* FIXME */
- /*if (scl_check_arrindex(coordinate->modifier_decorator,
- sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
- scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
- if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
- if (sclres_modifier_decoration[decoration_id].valid) {
- decoration = &(sclres_modifier_decoration[decoration_id]);
- }
- }
- /* Check if the button really needs to be redrawn (whether it has non-null bg_image_path information */
- if (decoration) {
- if (decoration->bg_image_path[display][key_modifier]) {
- windows->update_window(window,
- coordinate->x, coordinate->y, coordinate->width, coordinate->height);
- }
- }
- }
-
- if (context->get_magnifier_enabled()) {
- update_magnifier = TRUE;
- }
- }
- context->set_prev_moving_point(touch_id, originx, originy);
- }
- if (drag_state_changed) {
- /* When the dragging direction changes, save the current position as farthest point for future comparison */
- context->set_farthest_move_point(touch_id, originx, originy);
- LOGD("SET_FARTHEST : %d %d %d", originx, originy, context->get_cur_drag_state(touch_id));
- }
- }
-
- if (update_magnifier) {
- PSclMagnifierWndConfigure magnifier_configure = NULL;
- if (sclres_manager) {
- magnifier_configure = sclres_manager->get_magnifier_configure();
- }
-
- const SclLayout *base_layout = cache->get_cur_layout(windows->get_base_window());
- if (base_layout && magnifier_configure) {
- SclPoint zoomwinpos = {0, 0};
- /* calculates x position to be set */
- zoomwinpos.x = (coordinate->x + (coordinate->width / 2)) -
- (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
-
- /* calculates y position to be set */
- sclint scnWidth, scnHeight;
- utils->get_screen_resolution(&scnWidth, &scnHeight);
-
- zoomwinpos.y = coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
- if (window_context) {
- zoomwinpos.x += window_context->geometry.x;
- zoomwinpos.y += window_context->geometry.y;
- }
- if (zoomwinpos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
- zoomwinpos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
- }
- if (zoomwinpos.x > scnWidth +
- magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
- magnifier_configure->width * utils->get_custom_scale_rate_x()) {
- zoomwinpos.x = scnWidth +
- magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
- magnifier_configure->width * utils->get_custom_scale_rate_x();
- }
- zoomwinpos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
-
- zoomwinpos.x += coordinate->magnifier_offset_x;
- zoomwinpos.y += coordinate->magnifier_offset_y;
- windows->move_window(windows->get_magnifier_window(), zoomwinpos.x, zoomwinpos.y);
- windows->show_window(windows->get_magnifier_window(), 0);
- }
- }
- }
-
- sclboolean grab_event = FALSE;
- if (layout) {
- if (layout->style == LAYOUT_STYLE_POPUP_GRAB) {
- grab_event = TRUE;
- }
- /* If the topmost window has the POPUP_GRAB style, find the nearest button to the mouse pointer */
- if (grab_event && window_context) {
- /* If the layout's addGrab* values are defined, process this event only if the event occured inside grab area */
- sclboolean in_grab_area = TRUE;
- if (layout->add_grab_left != NOT_USED && x < -(layout->add_grab_left)) {
- in_grab_area = FALSE;
- }
- if (layout->add_grab_right != NOT_USED && x >
- (window_context->geometry.width + layout->add_grab_right)) {
- in_grab_area = FALSE;
- }
- if (layout->add_grab_top != NOT_USED && y < -(layout->add_grab_top)) {
- in_grab_area = FALSE;
- }
- if (layout->add_grab_bottom != NOT_USED && y >
- (window_context->geometry.height + layout->add_grab_bottom)) {
- in_grab_area = FALSE;
- }
- if (in_grab_area) {
- float min_dist = (float)((unsigned int)(-1));
- int min_dist_index = NOT_USED;
- for (int loop = 0;loop < MAX_KEY && !ended && !ret;loop++) {
- button_context = cache->get_cur_button_context(window, loop);
- const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, loop);
- if (button_context && cur_coordinate) {
- if (!(button_context->used)) {
- ended = TRUE;
- } else if (button_context->state != BUTTON_STATE_DISABLED &&
- cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
- float dist = utils->get_approximate_distance(x, y,
- cur_coordinate->x + (cur_coordinate->width / 2),
- cur_coordinate->y + (cur_coordinate->height / 2));
- if (dist < min_dist) {
- min_dist_index = loop;
- min_dist = dist;
- }
- }
- }
- }
- /* When we found the nearest button, generate this event on the button */
- if (min_dist_index != NOT_USED) {
- const SclLayoutKeyCoordinate *min_coordinate =
- cache->get_cur_layout_key_coordinate(window, min_dist_index);
- if (min_coordinate) {
- x = min_coordinate->x + (min_coordinate->width / 2);
- y = min_coordinate->y + (min_coordinate->height / 2);
- if (process_button_move_event(window, x, y, min_dist_index, touch_id, actual_event)) {
- ret = TRUE;
- }
- }
- }
- }
- } else {
- MultiTouchContext *multi_touch_context = context->find_multi_touch_context(touch_id);
- if (multi_touch_context) {
- sclint button_index = NOT_USED;
- if (!(multi_touch_context->is_sub_event)) {
- sclboolean process_finished = FALSE;
- do {
- /* First check if the event occured in pressed key's threshold area */
- if (button_context && coordinate) {
- if (pressed_window == window) { // Check only when the window is the one initally pressed
- if (button_context->used && button_context->state != BUTTON_STATE_DISABLED) {
- if (process_button_move_event(pressed_window, x, y, pressed_key, touch_id, actual_event)) {
- ret = TRUE;
- x = coordinate->x + (coordinate->width / 2);
- y = coordinate->y + (coordinate->height / 2);
- button_index = pressed_key;
- }
- }
- }
- }
- for (int loop = 0;loop < MAX_KEY && !ended && !ret;loop++) {
- button_context = cache->get_cur_button_context(window, loop);
- const SclLayoutKeyCoordinate *cur_coordinate =
- cache->get_cur_layout_key_coordinate(window, loop);
- if (button_context && cur_coordinate) {
- if (!(button_context->used)) {
- ended = TRUE;
- } else if (button_context->state != BUTTON_STATE_DISABLED &&
- cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
- if (window != pressed_window || loop != pressed_key) {
- if (process_button_move_event(window, x, y, loop, touch_id, actual_event)) {
- ret = TRUE;
- button_index = loop;
- }
- }
- }
- }
- }
-
- if (windows->is_base_window(window)) {
- process_finished = TRUE;
- } else if (button_index != NOT_USED) {
- process_finished = TRUE;
- } else {
- const SclLayout *cur_layout = cache->get_cur_layout(window);
- if (cur_layout && cur_layout->use_sw_background && cur_layout->bg_color.a == 0) {
- /* If we could not find appropriate button in this popup window and the popup is transparent */
- SclWindowContext *base_window_context =
- windows->get_window_context(windows->get_base_window());
- if (base_window_context && window_context) {
- x = (window_context->geometry.x + x - base_window_context->geometry.x);
- y = (window_context->geometry.y + y - base_window_context->geometry.y);
- }
- window = windows->get_base_window();
- } else {
- process_finished = TRUE;
- }
- }
- } while (!process_finished);
- }
- }
- }
- }
- }
-
- return ret;
-}
-
-sclboolean
-CSCLController::mouse_over(sclwindow window, sclint x, sclint y)
-{
- SCL_DEBUG();
- sclboolean ret = FALSE;
-
- if (m_input_events_disabled)
- return FALSE;
-
- /* Adjust x,y coordinate by touch offset */
- CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
- /* Iterate all the buttons and inform the event */
-
- CSCLContext *context = CSCLContext::get_instance();
- CSCLResourceCache *cache = CSCLResourceCache::get_instance();
- CSCLActionState *state = CSCLActionState::get_instance();
- CSCLWindows *windows = CSCLWindows::get_instance();
- CSCLUtils *utils = CSCLUtils::get_instance();
- SclResParserManager *sclres_manager = SclResParserManager::get_instance();
-
- if (cache && state && windows && context && utils && adjustment && sclres_manager) {
- const SclLayout *layout = cache->get_cur_layout(window);
- if (layout) {
- x += layout->mouse_manipulate_x;
- y += layout->mouse_manipulate_y;
- }
-
- SCLDisplayMode cur_display_mode = context->get_display_mode();
-
- const SclDefaultConfigure *default_configure = sclres_manager->get_default_configure();
- if (default_configure) {
- adjustment->apply_touch_offset(default_configure->touch_offset_level[cur_display_mode], &x, &y);
- }
-
- /* Iterate all the buttons and inform the event */
- sclboolean ended = FALSE;
-
- for (int loop = 0; loop < MAX_KEY && !ended && !ret; loop++) {
- SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
- const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, loop);
- if (button_context && coordinate) {
- if (!(button_context->used)) {
- ended = TRUE;
- } else if (button_context->state != BUTTON_STATE_DISABLED &&
- coordinate->button_type != BUTTON_TYPE_UIITEM) {
- if (process_button_over_event(window, x, y, loop)) {
- ret = TRUE;
- }
- }
- }
- }
- }
-
- return ret;
-}
-
-
/**
* Processes a timer event
* If return FALSE, the current timer will be stop
/* Ignores if the event id is different */
sclwindow window = context->get_cur_pressed_window(context->get_last_touch_device_id());
sclbyte key_index = context->get_cur_pressed_key(context->get_last_touch_device_id());
- if (process_button_long_pressed_event(window, key_index, context->get_last_touch_device_id())) {
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ if (controller_button->process_button_long_pressed_event(window, key_index, context->get_last_touch_device_id())) {
/* The button processed long key event, now enter longkey mode not to fire any events before releasing */
handle_engine_signal(SCL_SIG_MOUSE_LONG_PRESS, window);
windows->update_window(windows->get_magnifier_window());
if (interval < SCL_REPEATKEY_MIN_DURATION) {
interval = SCL_REPEATKEY_MIN_DURATION;
}
- process_button_repeat_pressed_event(window, key_index, context->get_last_touch_device_id());
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ controller_button->process_button_repeat_pressed_event(window, key_index, context->get_last_touch_device_id());
events->destroy_timer(id);
events->create_timer(SCL_TIMER_REPEATKEY, interval, value);
m_key_repeated_num++;
return ret;
}
+scllong
+CSCLController::get_longkey_duration()
+{
+ return m_long_key_duration;
+}
+
/**
* Sets the distance value for cancel longkey
* If not set, it will use default longkey duration. see sclconfig
return ret;
}
+sclshort
+CSCLController::get_longkey_cancel_dist()
+{
+ return m_long_key_cancel_distance;
+}
+
/**
* Sets the duration value for repeatkey
* If not set, it will use default repeatkey duration. see sclconfig
return ret;
}
+scllong
+CSCLController::get_repeatkey_duration()
+{
+ return m_repeat_key_duration;
+}
+
/**
* Sets the duration value for autopopup key
* If not set, it will use default short longkey duration. see sclconfig
return ret;
}
+scllong
+CSCLController::get_autopopup_key_duration()
+{
+ return m_autopopup_key_duration;
+}
+
/**
* Sets the amount value for button delay
* If not set, it will use default button delay amount. see sclconfig
return ret;
}
+scllong
+CSCLController::get_button_delay_duration()
+{
+ return m_button_delay_duration;
+}
+
+sclint
+CSCLController::get_key_repeated_num()
+{
+ return m_key_repeated_num;
+}
+
+scllong
+CSCLController::get_multitap_delay_duration()
+{
+ return m_multitap_delay_duration;
+}
+
/**
* Configures the variables for auto-popup window
* It will return rectangle area
{
m_input_events_disabled = disabled;
}
+
+sclboolean
+CSCLController::get_input_events_disabled()
+{
+ return m_input_events_disabled;
+}
static CSCLController* get_instance();
void init();
-private:
- sclboolean process_button_pressed_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
- scltouchdevice touch_id, sclboolean actual_event = TRUE);
- sclboolean process_button_long_pressed_event(sclwindow window, sclbyte key_index,
- scltouchdevice touch_id, sclboolean actual_event = TRUE);
- sclboolean process_button_repeat_pressed_event(sclwindow window, sclbyte key_index,
- scltouchdevice touch_id, sclboolean actual_event = TRUE);
- sclboolean process_button_move_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
- scltouchdevice touch_id, sclboolean actual_event = TRUE);
- sclboolean process_button_over_event(sclwindow window, sclint x, sclint y, sclbyte key_index);
- sclboolean process_button_release_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
- scltouchdevice touch_id, sclboolean actual_event = TRUE);
-
+public:
sclboolean configure_autopopup_window(sclwindow window, sclbyte key_index, SclRectangle* rect);
sclboolean check_event_transition_enabled(const SclLayoutKeyCoordinate *btnFrom, const SclLayoutKeyCoordinate *btnTo);
sclboolean check_magnifier_available(sclwindow window, sclbyte key_index, scltouchdevice touch_id);
- SCLKeyModifier get_drag_key_modifier(sclint deltax, sclint deltay, sclfloat dist,
- sclboolean check_farthest, scltouchdevice touch_id, sclbyte extra_option);
-
-public:
void handle_engine_signal(SclInternalSignal signal, sclwindow skip_window = SCLWINDOW_INVALID);
sclboolean process_input_mode_change(const sclbyte mode);
sclboolean process_rotation_change(const SCLRotation rotation);
- sclboolean mouse_press(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
- sclboolean mouse_release(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
- sclboolean mouse_move(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
- sclboolean mouse_over(sclwindow window, sclint x, sclint y);
sclboolean timer_event(const scl32 id);
sclboolean set_longkey_duration(scllong msc);
+ scllong get_longkey_duration();
sclboolean set_longkey_cancel_dist(sclshort dist);
+ sclshort get_longkey_cancel_dist();
sclboolean set_repeatkey_duration(scllong msc);
+ scllong get_repeatkey_duration();
sclboolean set_autopopup_key_duration(scllong msc);
+ scllong get_autopopup_key_duration();
sclboolean set_button_delay_duration(scllong msc);
+ scllong get_button_delay_duration();
+
+ sclint get_key_repeated_num();
+ scllong get_multitap_delay_duration();
SCLDebugMode get_debug_mode();
void set_debug_mode(SCLDebugMode mode);
void disable_input_events(sclboolean disabled);
+ sclboolean get_input_events_disabled();
protected:
/* Interval time(msc) for checking long key event */
--- /dev/null
+/*
+ * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 <time.h>
+#include <math.h>
+#include <assert.h>
+#include <vector>
+
+#include "sclcontroller.h"
+#include "sclcontroller_button.h"
+#include "sclcontroller_mouse.h"
+#include "scldebug.h"
+#include "sclresourcecache.h"
+#include "sclactionstate.h"
+#include "scluibuilder.h"
+#include "sclkeydefines.h"
+#include "sclfeedback.h"
+#include "sclerroradjustment.h"
+#include "sclimageproxy.h"
+#include "sclres_manager.h"
+#include "scleventhandler.h"
+#include "sclanimator.h"
+#include "sclkeyfocushandler.h"
+#include <dlog.h>
+
+//#define DIRECTLY_DRAW_ON_EVENTS
+
+using namespace scl;
+
+static sclboolean
+_play_tts_for_input_mode_name(int mode) {
+ SCL_DEBUG();
+
+ CSCLContext *context = CSCLContext::get_instance();
+ if (context && context->get_tts_enabled() == FALSE) {
+ return FALSE;
+ }
+
+ SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+ if (!sclres_manager) return FALSE;
+
+ const SclInputModeConfigure *pinput_mode_table = sclres_manager->get_input_mode_configure_table();
+ if (NULL == pinput_mode_table) {
+ return FALSE;
+ }
+
+ const char* name = pinput_mode_table[mode].name;
+ if (NULL == name) {
+ return FALSE;
+ }
+
+ CSCLUtils *utils = CSCLUtils::get_instance();
+ if (utils)
+ utils->play_tts(name);
+ return TRUE;
+}
+
+CSCLControllerButton*
+CSCLControllerButton::get_instance()
+{
+ static CSCLControllerButton instance;
+ return &instance;
+}
+
+sclboolean
+CSCLControllerButton::process_button_pressed_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+ scltouchdevice touch_id, sclboolean actual_event)
+{
+ SCL_DEBUG();
+
+ sclboolean ret = FALSE;
+ sclboolean redraw = FALSE;
+
+ CSCLContext *context = CSCLContext::get_instance();
+ CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+ CSCLWindows *windows = CSCLWindows::get_instance();
+ CSCLEvents *events = CSCLEvents::get_instance();
+ CSCLUtils *utils = CSCLUtils::get_instance();
+ CSCLFeedback *feedback = CSCLFeedback::get_instance();
+ CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+ SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+ if (!sclres_manager) return FALSE;
+
+ PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+ PSclLayout sclres_layout = sclres_manager->get_layout_table();
+ if (!sclres_input_mode_configure || !sclres_layout) return FALSE;
+
+ SclButtonContext *button_context = NULL;
+ const SclLayoutKeyCoordinate *coordinate = NULL;
+
+ if (context && cache) {
+ button_context = cache->get_cur_button_context(window, key_index);
+ coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+ }
+
+ if (context && cache && windows && events && utils && feedback && handler && button_context && coordinate) {
+ /* First check if this button is enabled in current active sublayout */
+ sclboolean sub_layout_match = TRUE;
+ if (coordinate->sub_layout && context->get_cur_sublayout()) {
+ if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
+ sub_layout_match = FALSE;
+ }
+ }
+
+ /* If this button is pressed */
+ if ( x >= coordinate->x - coordinate->add_hit_left &&
+ x < coordinate->x + coordinate->width + coordinate->add_hit_right &&
+ y >= coordinate->y - coordinate->add_hit_top &&
+ y < coordinate->y + coordinate->height + coordinate->add_hit_bottom &&
+ /* Process the event only if the this item's sublayout id is active one */
+ sub_layout_match ) {
+ /* If currently shift mode is ON, and the last key was multitap, this means the shift did not
+ turned off because of multitap button. So we need to turn it off here forcibly */
+ sclwindow last_win = context->get_last_event_fired_window();
+ scl8 last_key = context->get_last_event_fired_key();
+ LOGD("last_win : %p last_key : :%d", last_win, last_key);
+ const SclLayoutKeyCoordinate *last_coordinate = cache->get_cur_layout_key_coordinate(last_win, last_key);
+ if (last_coordinate) {
+ LOGD("last_coordinate->button_type : %d", last_coordinate->button_type);
+ if (last_coordinate->button_type == BUTTON_TYPE_MULTITAP && context->get_shift_state() == SCL_SHIFT_STATE_ON) {
+ /* And if the multitap button was different from the one we are dealing with... */
+ LOGD("last_win %p window %p last_key %d key_index %d", last_win, window, last_key, key_index);
+ if (last_win != window || last_key != key_index) {
+ SclNotiShiftStateChangeDesc desc;
+ desc.ui_event_desc = NULL;
+ desc.shift_state = SCL_SHIFT_STATE_OFF;
+
+ SCLEventReturnType ret = handler->on_event_notification(SCL_UINOTITYPE_SHIFT_STATE_CHANGE, &desc);
+ if (ret == SCL_EVENT_PASS_ON) {
+ context->set_shift_state(SCL_SHIFT_STATE_OFF);
+ windows->update_window(windows->get_base_window());
+ }
+ }
+ }
+ }
+
+ /* If newly pressed key has type MULTI_TOUCH_TYPE_EXCLUSIVE, release all existing pressed events */
+ if (actual_event) {
+ if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_EXCLUSIVE) {
+ /* When calling mouse_release, the seq order of current multitouch events will be changed,
+ so we put all the multitouch events into a vector and use them afterwards forreleasing */
+ sclint loop = 0;
+ sclint multi_touch_context_num = context->get_multi_touch_context_num();
+ std::vector<SclUIEventDesc> multi_touch_events;
+ for (loop = 0;loop < multi_touch_context_num;loop++) {
+ SclUIEventDesc desc;
+ context->get_multi_touch_event(loop, &desc);
+ multi_touch_events.push_back(desc);
+ }
+ for (loop = 0;loop < multi_touch_context_num;loop++) {
+ SclUIEventDesc desc = multi_touch_events[loop];
+ if (desc.touch_id != touch_id) {
+ CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
+ controller_mouse->mouse_release(context->get_cur_moving_window(desc.touch_id),
+ context->get_cur_moving_point(desc.touch_id).x,
+ context->get_cur_moving_point(desc.touch_id).y,
+ desc.touch_id, FALSE);
+ }
+ }
+ }
+ }
+
+ /* Make an unique ID for timer */
+ const scl16 uniqId = utils->get_unique_id();
+
+ context->set_cur_pressed_event_id(touch_id, uniqId);
+ context->set_cur_pressed_key(touch_id, key_index);
+ context->set_cur_pressed_window(touch_id, window);
+
+ button_context->state = BUTTON_STATE_PRESSED;
+
+ if (context->get_highlight_ui_enabled()) {
+ CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
+ if (focus_handler) {
+ sclwindow prev_window = focus_handler->get_current_focus_window();
+ scl8 prev_key = focus_handler->get_current_focus_key();
+ const SclLayoutKeyCoordinate *prev_coordinate =
+ cache->get_cur_layout_key_coordinate(prev_window, prev_key);
+
+ focus_handler->set_current_focus(window, key_index);
+
+ if (prev_coordinate) {
+ windows->update_window(prev_window,
+ prev_coordinate->x, prev_coordinate->y, prev_coordinate->width, prev_coordinate->height);
+ }
+ }
+ }
+
+ redraw = TRUE;
+ ret = TRUE;
+
+#ifndef DIRECTLY_DRAW_ON_EVENTS
+ /* If the window doesn't get exposed before corresponding release event,
+ * the inverted state of a button will never be drawn onto screen.
+ * To prevent such a case, we draw the inverted state of button forcefully and directly,
+ * without waiting for expose event */
+ /*CSCLGraphics *grps = CSCLGraphics::get_instance();
+ CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+ scldrawctx draw_ctx = grps->begin_paint(window, TRUE);
+ builder->draw_button(window, draw_ctx, key_index, button_context->state, TRUE);
+ grps->end_paint(window, draw_ctx);*/
+#endif
+
+ /* for feedback */
+ feedback->button_pressed(window, key_index);
+
+ /* Special routine for autopopup */
+ if (coordinate->popup_type == POPUP_TYPE_AUTO_POPUP) {
+ CSCLController *controller = CSCLController::get_instance();
+ events->create_timer(SCL_TIMER_AUTOPOPUP, controller->get_autopopup_key_duration(), uniqId);
+ } else {
+ /* for long key & repeat key */
+ CSCLController *controller = CSCLController::get_instance();
+ events->create_timer(SCL_TIMER_LONGKEY, controller->get_longkey_duration(), uniqId);
+ }
+
+ SCLShiftState shift_index = context->get_shift_state();
+ if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+ if (context->get_caps_lock_mode()) {
+ shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+ }
+
+ SclUIEventDesc key_event_desc;
+ key_event_desc.key_value = coordinate->key_value[shift_index][0];
+ key_event_desc.key_event = coordinate->key_event[shift_index][0];
+ key_event_desc.key_type = coordinate->key_type;
+ key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+ key_event_desc.event_type = EVENT_TYPE_PRESS;
+
+ SclPoint curpoint = {x, y};
+ key_event_desc.touch_id = touch_id;
+ key_event_desc.mouse_pressed_point = curpoint;
+ key_event_desc.mouse_current_point = curpoint;
+ key_event_desc.mouse_farthest_point = curpoint;
+
+ key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+ SCLEventReturnType processed = handler->on_event_drag_state_changed(key_event_desc);
+
+ /* Only if the handler didn't return SCL_EVENT_DONE */
+ if (processed == SCL_EVENT_PASS_ON) {
+ /* Now process normal behaviours of each button type */
+ switch (coordinate->button_type) {
+ case BUTTON_TYPE_NORMAL:
+ case BUTTON_TYPE_GRAB:
+ case BUTTON_TYPE_SELFISH:
+ case BUTTON_TYPE_DIRECTION:
+ case BUTTON_TYPE_RELATIVE_DIRECTION: {
+ /* Send click event right away if this button uses repeat key */
+ if (coordinate->use_repeat_key) {
+ handler->on_event_key_clicked(key_event_desc);
+ }
+ }
+ break;
+ case BUTTON_TYPE_MULTITAP: {
+ }
+ break;
+ case BUTTON_TYPE_ROTATION: {
+ }
+ break;
+ case BUTTON_TYPE_DRAG: {
+ /* Drag buttons fires click event immediately when they are pressed */
+ handler->on_event_key_clicked(key_event_desc);
+ }
+ break;
+ case BUTTON_TYPE_UIITEM: break;
+ case MAX_BUTTON_TYPE: break;
+ default: break;
+ }
+ switch (coordinate->popup_type) {
+ case POPUP_TYPE_BTN_PRESS_POPUP_DRAG: {
+ SclNotiPopupOpeningDesc desc;
+ desc.ui_event_desc = &key_event_desc;
+ desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
+ if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
+ sclint popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
+ SCLDisplayMode display_mode = context->get_display_mode();
+ /* FIXME */
+ //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
+ if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
+ scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+ sclshort popupLayoutId =
+ sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
+ SclRectangle popupRect;
+ SclRectangle baseWndRect;
+ SclLayout *layout = NULL;
+ /* FIXME */
+ //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
+ if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
+ layout = &sclres_layout[popupLayoutId];
+ }
+ if (layout) {
+ windows->get_window_rect(windows->get_base_window(), &baseWndRect);
+ popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
+ popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
+ //popupRect.width = utils->get_scale_x(layout->width);
+ //popupRect.height= utils->get_scale_y(layout->height);
+ if (!(sclres_manager->loaded(popupLayoutId))) {
+ sclres_manager->load(popupLayoutId);
+ }
+ popupRect.width = layout->width;
+ popupRect.height = layout->height;
+ windows->close_all_popups();
+
+ SclWindowOpener opener;
+ opener.window = window;
+ opener.key = key_index;
+
+ sclwindow popup_window = windows->open_popup(opener,
+ popupRect,
+ popup_input_mode,
+ popupLayoutId,
+ coordinate->popup_type,
+ sclres_input_mode_configure[popup_input_mode].use_virtual_window,
+ sclres_input_mode_configure[popup_input_mode].use_dim_window,
+ coordinate->extract_offset_x,
+ coordinate->extract_offset_y,
+ sclres_input_mode_configure[popup_input_mode].timeout);
+
+ SclNotiPopupOpenedDesc opened_desc;
+ opened_desc.ui_event_desc = &key_event_desc;
+ opened_desc.input_mode = desc.input_mode;
+ opened_desc.window = popup_window;
+ handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
+
+ windows->hide_window(windows->get_magnifier_window());
+ /* FIXME : The parent key should be turned back to NORMAL state when RELEASED,
+ in case of POPUP_TYPE_BTN_PRESS_POPUP_DRAG type. Temporarily setting NORMAL here. */
+ button_context->state = BUTTON_STATE_NORMAL;
+ _play_tts_for_input_mode_name(popup_input_mode);
+ }
+ }
+ }
+ }
+ break;
+ case POPUP_TYPE_BTN_RELEASE_POPUP:
+ case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE:
+ case POPUP_TYPE_BTN_LONGPRESS_POPUP:
+ case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE:
+ case POPUP_TYPE_AUTO_POPUP:
+ case POPUP_TYPE_NONE:
+ case MAX_POPUP_TYPE:
+ default:
+ /* Nothing to do in here */
+ break;
+ }
+ }
+
+ /* Shows the magnifier window(the magnifier window will display when a kind of button type is character) */
+ //if (windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP) == windows->get_base_window()) {
+ if (coordinate->use_magnifier) {
+ CSCLController *controller = CSCLController::get_instance();
+ sclboolean showMagnifier = controller->check_magnifier_available(window, key_index, touch_id);
+
+ PSclMagnifierWndConfigure magnifier_configure = NULL;
+ if (sclres_manager) {
+ magnifier_configure = sclres_manager->get_magnifier_configure();
+ }
+ if (showMagnifier && magnifier_configure) {
+ SclPoint pos = {0, 0};
+ /* calculates x position to be set */
+ pos.x = (coordinate->x + (coordinate->width / 2)) -
+ (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+
+ /* calculates y position to be set */
+ sclint scnWidth, scnHeight;
+ utils->get_screen_resolution(&scnWidth, &scnHeight);
+
+ pos.y = coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
+
+ /* FIXME : Temporary way of clearing magnifier window */
+ /*SclWindowContext *window_context = windows->get_window_context(windows->get_magnifier_window(), FALSE);
+ sclboolean clearmagwin = FALSE;
+ if (window_context) {
+ clearmagwin = !(window_context->hidden);
+ }
+ static int clearnum = 0;
+ if (key_index == prevkey && window == prevwin) {
+ clearmagwin = FALSE;
+ }
+ if (clearmagwin) {
+ if (++clearnum > 1) {
+ clearmagwin = FALSE;
+ }
+ } else {
+ clearnum = 0;
+ }
+
+ if (clearmagwin) {
+ CSCLGraphics *graphics = CSCLGraphics::get_instance();
+ CSCLUtils *utils = CSCLUtils::get_instance();
+ sclchar composed_path[_POSIX_PATH_MAX] = {0,};
+ scldrawctx draw_ctx = graphics->begin_paint(windows->get_magnifier_window());
+ utils->get_composed_path(composed_path, scl_magnifier_configure.bg_image_path);
+ graphics->draw_image(windows->get_magnifier_window(), draw_ctx, composed_path, 0, 0);
+ graphics->end_paint(windows->get_magnifier_window(), draw_ctx);
+ }
+ */
+ windows->hide_window(windows->get_magnifier_window());
+
+ SclWindowContext *window_context = windows->get_window_context(window);
+ if (window_context) {
+ pos.x += window_context->geometry.x;
+ pos.y += window_context->geometry.y;
+ }
+
+ if (pos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+ pos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+ }
+ if (pos.x > scnWidth +
+ magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+ magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+ pos.x = scnWidth + magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+ magnifier_configure->width * utils->get_custom_scale_rate_x();
+ }
+ pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+ pos.x += coordinate->magnifier_offset_x;
+ pos.y += coordinate->magnifier_offset_y;
+ windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
+ //windows->resize_window(windows->get_magnifier_window(), utils->get_scale_x(scl_magnifier_configure.width), utils->get_scale_y(scl_magnifier_configure.height));
+ /*If we use transient_for them the ISE will occur some crash. It needs to check X11 */
+ /*windows->set_parent(windows->get_base_window(), windows->get_magnifier_window());*/
+
+ windows->show_window(windows->get_magnifier_window(), TRUE);
+ //windows->update_window(windows->get_magnifier_window());
+ }
+#if 0
+ static int fFirst = true;
+ if (fFirst) {
+ windows->show_window(windows->get_magnifier_window());
+ fFirst = false;
+ } else {
+ windows->update_window(windows->get_magnifier_window());
+ }
+#endif
+ /* We cannot use move_resize_window. It had occured some wrong behavior */
+ /*windows->move_resize_window(windows->get_magnifier_window(), pos.x, pos.y, scl_magnifier_configure.width, scl_magnifier_configure.height);*/
+ if (!showMagnifier) {
+ windows->hide_window(windows->get_magnifier_window());
+ }
+ }
+ } else {
+ /* COMMENTED OUT FOR TESTING MULTITOUCH!! */
+ ///* In case the current button is not the given key index */
+ //if (button_context->state == BUTTON_STATE_PRESSED) {
+ // /* Even if the press event occurs outside of this button's physical area, reset its context */
+ // button_context->state = BUTTON_STATE_NORMAL;
+ // redraw = TRUE;
+ //}
+ /* BUTTON_TYPE_MULTITAP type button should restore its multikey index when another button is clicked */
+ if (coordinate->button_type & BUTTON_TYPE_MULTITAP) {
+ button_context->multitap_index = 0;
+ }
+ }
+
+ /* If there is any need for redrawing */
+ if (redraw) {
+#ifdef DIRECTLY_DRAW_ON_EVENTS
+ CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+ if (builder) {
+ builder->draw_button(window, NULL, key_index, button_context->state, TRUE);
+ }
+#else
+ if (windows) {
+ windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+ }
+#endif
+ }
+ }
+
+ return ret;
+}
+
+sclboolean
+CSCLControllerButton::process_button_long_pressed_event(sclwindow window, sclbyte key_index,
+ scltouchdevice touch_id, sclboolean actual_event)
+{
+ SCL_DEBUG();
+
+ sclboolean ret = FALSE;
+
+ CSCLContext *context = CSCLContext::get_instance();
+ CSCLWindows *windows = CSCLWindows::get_instance();
+ CSCLActionState *state = CSCLActionState::get_instance();
+ CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+ CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+ SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+ if (!sclres_manager) return FALSE;
+
+ PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+ PSclLayout sclres_layout = sclres_manager->get_layout_table();
+
+ if (!sclres_input_mode_configure || !sclres_layout) return FALSE;
+
+ if (context && cache && handler && windows && state) {
+ const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+ SclButtonContext *button_context = cache->get_cur_button_context(window, key_index);
+
+ /* Should return FALSE if this key does not have any longkey related property */
+ if (coordinate) {
+ if (actual_event) {
+ if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+ /* When calling mouse_release, the seq order of current multitouch events will be changed,
+ so we put all the multitouch events into a vector and use them afterwards for releasing */
+ sclboolean finished = FALSE;
+ sclint loop = 0;
+ sclint multi_touch_context_num = context->get_multi_touch_context_num();
+ std::vector<SclUIEventDesc> multitouch_events;
+ for (loop = 0;loop < multi_touch_context_num;loop++) {
+ SclUIEventDesc desc;
+ context->get_multi_touch_event(loop, &desc);
+ multitouch_events.push_back(desc);
+ }
+ for (loop = 0;loop < multi_touch_context_num && !finished;loop++) {
+ SclUIEventDesc desc = multitouch_events[loop];
+ if (desc.touch_id != touch_id) {
+ sclwindow cur_pressed_window = context->get_cur_pressed_window(desc.touch_id);
+ scl8 cur_pressed_key = context->get_cur_pressed_key(desc.touch_id);
+ const SclLayoutKeyCoordinate *cur_pressed_coordinate =
+ cache->get_cur_layout_key_coordinate(cur_pressed_window, cur_pressed_key);
+ if (cur_pressed_coordinate) {
+ if (cur_pressed_coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+ CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
+ controller_mouse->mouse_release(context->get_cur_moving_window(desc.touch_id),
+ context->get_cur_moving_point(desc.touch_id).x,
+ context->get_cur_moving_point(desc.touch_id).y,
+ desc.touch_id, FALSE);
+ }
+ }
+ } else {
+ finished = TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ /* Should return FALSE if this key does not have any longkey related property */
+ if (coordinate) {
+ if (coordinate->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP ||
+ coordinate->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE ) {
+ SclUIEventDesc key_event_desc;
+ key_event_desc.key_type = coordinate->long_key_type;
+ if (coordinate->long_key_value == NULL && coordinate->long_key_event == 0) {
+ SCLShiftState shift_index = context->get_shift_state();
+ if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+ if (context->get_caps_lock_mode()) {
+ shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+ }
+
+ key_event_desc.key_value = coordinate->key_value[shift_index][0];
+ key_event_desc.key_event = coordinate->key_event[shift_index][0];
+ } else {
+ key_event_desc.key_value = coordinate->long_key_value;
+ key_event_desc.key_event = coordinate->long_key_event;
+ }
+ key_event_desc.key_modifier = KEY_MODIFIER_LONGKEY;
+
+ key_event_desc.event_type = EVENT_TYPE_LONGPRESS;
+ key_event_desc.touch_id = touch_id;
+ key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+ key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+ key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+ key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+ SCLEventReturnType processed = handler->on_event_drag_state_changed(key_event_desc);
+
+ /* Only if the handler didn't return SCL_EVENT_DONE */
+ if (processed == SCL_EVENT_PASS_ON) {
+ SclRectangle popupRect;
+ SclRectangle baseWndRect;
+ windows->get_window_rect(windows->get_base_window(), &baseWndRect);
+ popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
+ popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
+
+ SclNotiPopupOpeningDesc desc;
+ desc.ui_event_desc = &key_event_desc;
+ desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
+ if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
+ sclint popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
+ SCLDisplayMode display_mode = context->get_display_mode();
+ /* FIXME */
+ //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
+ if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
+ scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+ SclLayout *layout = NULL;
+ sclshort popupLayoutId =
+ sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
+ /* FIXME */
+ //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
+ if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
+ layout = &sclres_layout[popupLayoutId];
+ }
+ if (layout) {
+ //popupRect.width = utils->get_scale_x(layout->width);
+ //popupRect.height= utils->get_scale_y(layout->height);
+ if (!(sclres_manager->loaded(popupLayoutId))) {
+ sclres_manager->load(popupLayoutId);
+ }
+ popupRect.width = layout->width;
+ popupRect.height = layout->height;
+
+ SclWindowOpener opener;
+ opener.window = window;
+ opener.key = key_index;
+
+ sclwindow popup_window = windows->open_popup(
+ opener,
+ popupRect,
+ popup_input_mode,
+ popupLayoutId,
+ coordinate->popup_type,
+ sclres_input_mode_configure[popup_input_mode].use_virtual_window,
+ sclres_input_mode_configure[popup_input_mode].use_dim_window,
+ coordinate->extract_offset_x,
+ coordinate->extract_offset_y,
+ sclres_input_mode_configure[popup_input_mode].timeout);
+
+ SclNotiPopupOpenedDesc opened_desc;
+ opened_desc.ui_event_desc = &key_event_desc;
+ opened_desc.input_mode = desc.input_mode;
+ opened_desc.window = popup_window;
+ handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
+
+ windows->hide_window(windows->get_magnifier_window());
+ _play_tts_for_input_mode_name(popup_input_mode);
+ ret = TRUE;
+ }
+ }
+ }
+ }
+ } else if (coordinate->long_key_value) {
+ if (strlen(coordinate->long_key_value) > 0) {
+ if (windows->is_base_window(window)) {
+ state->set_cur_action_state(ACTION_STATE_BASE_LONGKEY);
+ } else {
+ state->set_cur_action_state(ACTION_STATE_POPUP_LONGKEY);
+ }
+ ret = TRUE;
+
+ PSclMagnifierWndConfigure magnifier_configure = NULL;
+ if (sclres_manager) {
+ magnifier_configure = sclres_manager->get_magnifier_configure();
+ }
+ if (coordinate->use_long_key_magnifier && magnifier_configure) {
+ CSCLUtils *utils = CSCLUtils::get_instance();
+ SclPoint pos = {0, 0};
+
+ const SclLayout* layout = cache->get_cur_layout(window);
+ if (utils && layout) {
+ sclint scnWidth, scnHeight;
+ utils->get_screen_resolution(&scnWidth, &scnHeight);
+
+ //SclWindowContext *window_context = windows->get_window_context(window, TRUE);
+ SclWindowContext *window_context = windows->get_window_context(window);
+ if (window_context) {
+ pos.x = window_context->geometry.x + (coordinate->x + (coordinate->width / 2)) -
+ (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+ pos.y = window_context->geometry.y + coordinate->y -
+ magnifier_configure->height * utils->get_custom_scale_rate_y();
+ }
+ if (pos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+ pos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+ }
+ if (pos.x > scnWidth +
+ magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+ magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+ pos.x = scnWidth +
+ magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+ magnifier_configure->width * utils->get_custom_scale_rate_x();
+ }
+ pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+ pos.x += coordinate->magnifier_offset_x;
+ pos.y += coordinate->magnifier_offset_y;
+ windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
+ windows->update_window(windows->get_magnifier_window());
+ windows->show_window(windows->get_magnifier_window(), TRUE);
+ }
+ }
+
+ SclUIEventDesc key_event_desc;
+ key_event_desc.key_type = coordinate->long_key_type;
+ key_event_desc.key_value = coordinate->long_key_value;
+ key_event_desc.key_event = coordinate->long_key_event;
+ key_event_desc.key_modifier = KEY_MODIFIER_LONGKEY;
+
+ key_event_desc.event_type = EVENT_TYPE_LONGPRESS;
+ key_event_desc.touch_id = touch_id;
+ key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+ key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+ key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+ key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+ handler->on_event_key_clicked(key_event_desc);
+ //}
+ }
+ }
+ }
+ if (ret) {
+ context->set_cur_key_modifier(touch_id, KEY_MODIFIER_LONGKEY);
+ if (coordinate && button_context) {
+ if (coordinate->button_type & BUTTON_TYPE_MULTITAP) {
+ button_context->multitap_index = 0;
+ }
+ }
+ }
+ }
+ /* Longkey processing in here */
+ return ret;
+}
+
+sclboolean
+CSCLControllerButton::process_button_repeat_pressed_event(sclwindow window, sclbyte key_index,
+ scltouchdevice touch_id, sclboolean actual_event)
+{
+ SCL_DEBUG();
+ CSCLContext *context = CSCLContext::get_instance();
+ CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+ CSCLWindows *windows = CSCLWindows::get_instance();
+ CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+
+ if (context && cache && windows && handler) {
+ const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+
+ SCLShiftState shift_index = context->get_shift_state();
+ if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+ if (context->get_caps_lock_mode()) {
+ shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+ }
+
+ if (coordinate) {
+ switch (coordinate->button_type) {
+ case BUTTON_TYPE_NORMAL:
+ case BUTTON_TYPE_GRAB:
+ case BUTTON_TYPE_SELFISH:
+ case BUTTON_TYPE_DIRECTION:
+ case BUTTON_TYPE_RELATIVE_DIRECTION: {
+ /* This is for enabling backspace key in search layout*/
+ //if (coordinate->key_type != KEY_TYPE_MODECHANGE && coordinate->key_type != KEY_TYPE_COMPOSITION) {
+ //if (coordinate->key_type != KEY_TYPE_MODECHANGE || coordinate->key_event[0][0] == MVK_BackSpace) {
+ if (coordinate->key_type != KEY_TYPE_MODECHANGE) {
+ sclulong repeatKeyEvent = coordinate->key_event[shift_index][0];
+
+ /* In case of Delete key, Change from Char deletion to Word deletion
+ when the input acceleration speed is reached to Max */
+ SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+ PSclDefaultConfigure default_configure = NULL;
+ if (sclres_manager) {
+ default_configure = sclres_manager->get_default_configure();
+ }
+ if (default_configure) {
+ if (default_configure->use_word_deletion) {
+ CSCLController *controller = CSCLController::get_instance();
+ scllong interval = controller->get_repeatkey_duration() -
+ (controller->get_key_repeated_num() * SCL_REPEATKEY_ACCELERATION);
+ if (repeatKeyEvent == MVK_BackSpace &&
+ interval <= SCL_REPEATKEY_WORD_DELETION_START_DURATION) {
+ repeatKeyEvent = MVK_3270_DeleteWord;
+ }
+ }
+ }
+
+ SclUIEventDesc key_event_desc;
+ key_event_desc.key_value = coordinate->key_value[shift_index][0];
+ key_event_desc.key_event = repeatKeyEvent;
+ key_event_desc.key_type = coordinate->key_type;
+ key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+
+ key_event_desc.event_type = EVENT_TYPE_REPEAT;
+ key_event_desc.touch_id = touch_id;
+ key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+ key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+ key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+ key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+ handler->on_event_key_clicked(key_event_desc);
+ }
+ }
+ break;
+ case BUTTON_TYPE_UIITEM: break;
+ case MAX_BUTTON_TYPE: break;
+ default: break;
+ }
+ }
+ }
+
+ /* Longkey processing in here */
+ return TRUE;
+}
+
+sclboolean
+CSCLControllerButton::process_button_move_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+ scltouchdevice touch_id, sclboolean actual_event)
+{
+ SCL_DEBUG();
+
+ sclboolean ret = FALSE;
+
+ CSCLUtils *utils = CSCLUtils::get_instance();
+ CSCLEvents *events = CSCLEvents::get_instance();
+ CSCLContext *context = CSCLContext::get_instance();
+ CSCLWindows *windows = CSCLWindows::get_instance();
+ CSCLFeedback *feedback = CSCLFeedback::get_instance();
+ CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+ CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+ SclButtonContext *button_context = NULL;
+
+ const SclLayoutKeyCoordinate *coordinate = NULL;
+
+ if (cache) {
+ coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+ button_context = cache->get_cur_button_context(window, key_index);
+ }
+
+ if (button_context && coordinate && feedback && utils && context && handler && cache && events && windows) {
+ /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
+ sclint thresholdX = 0;
+ sclint thresholdY = 0;
+ if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
+ thresholdX = utils->get_scaled_x(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_X);
+ thresholdY = utils->get_scaled_y(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_Y);
+ }
+
+ /* First check if this button is enabled in current active sublayout */
+ sclboolean subLayoutMatch = TRUE;
+ if (coordinate->sub_layout && context->get_cur_sublayout()) {
+ if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
+ subLayoutMatch = FALSE;
+ }
+ }
+ if ( x >= coordinate->x - coordinate->add_hit_left - thresholdX &&
+ x < coordinate->x + coordinate->width + coordinate->add_hit_right + thresholdX&&
+ y >= coordinate->y - coordinate->add_hit_top - thresholdY &&
+ y < coordinate->y + coordinate->height + coordinate->add_hit_bottom + thresholdY &&
+ subLayoutMatch ) {
+ ret = TRUE;
+
+ SCLShiftState shift_index = context->get_shift_state();
+ if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+ if (context->get_caps_lock_mode()) {
+ shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+ }
+
+ const SclLayout* layout = cache->get_cur_layout(windows->get_base_window());
+
+ sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
+ scl8 pressed_key = context->get_cur_pressed_key(touch_id);
+ SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
+ const SclLayoutKeyCoordinate *pressed_coordinate =
+ cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+ if (pressed_context == NULL || pressed_coordinate == NULL) {
+ return FALSE;
+ }
+
+ if (key_index != pressed_key || window != pressed_window) {
+ /* When the focus has moved to another button, destroy all the timers */
+ events->destroy_all_timer();
+
+ CSCLController *controller = CSCLController::get_instance();
+ if (controller->check_event_transition_enabled(pressed_coordinate, coordinate)) {
+ if (layout) {
+ const scl16 uniqId = utils->get_unique_id();
+ context->set_cur_pressed_event_id(touch_id, uniqId);
+ /* Special routine for autopopup */
+ if (coordinate->popup_type == POPUP_TYPE_AUTO_POPUP) {
+ CSCLController *controller = CSCLController::get_instance();
+ events->create_timer(SCL_TIMER_AUTOPOPUP, controller->get_autopopup_key_duration(), uniqId);
+ } else {
+ /* for long key & repeat key */
+ CSCLController *controller = CSCLController::get_instance();
+ events->create_timer(SCL_TIMER_LONGKEY, controller->get_longkey_duration(), uniqId);
+ }
+
+ context->set_cur_pressed_window(touch_id, window);
+ context->set_cur_pressed_key(touch_id, key_index);
+
+ CSCLController *controller = CSCLController::get_instance();
+ sclboolean showMagnifier = controller->check_magnifier_available(window, key_index, touch_id);
+
+ SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+ PSclMagnifierWndConfigure magnifier_configure = NULL;
+ if (sclres_manager) {
+ magnifier_configure = sclres_manager->get_magnifier_configure();
+ }
+
+ SclWindowContext *window_context = windows->get_window_context(window);
+ if (showMagnifier && magnifier_configure && window_context) {
+ SclPoint pos = {0, 0};
+ /* calculates x position to be set */
+ pos.x = window_context->geometry.x;
+ pos.x += (coordinate->x + (coordinate->width / 2)) -
+ (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+
+ /* calculates y position to be set */
+ pos.y = window_context->geometry.y;
+ pos.y += coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
+
+ if (pos.x < window_context->geometry.x - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+ pos.x = window_context->geometry.x - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+ }
+ if (pos.x > window_context->geometry.x + window_context->geometry.width +
+ magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+ magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+ pos.x = window_context->geometry.x + window_context->geometry.width +
+ magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+ magnifier_configure->width * utils->get_custom_scale_rate_x();
+ }
+ pos.x += coordinate->magnifier_offset_x;
+ pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+ pos.y += coordinate->magnifier_offset_y;
+ if (windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP) == windows->get_base_window()) {
+ windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
+ windows->update_window(windows->get_magnifier_window());
+ }
+ }
+
+ /* for feedback */
+ feedback->button_moved(window, key_index);
+
+ button_context->state = BUTTON_STATE_PRESSED;
+ if (pressed_context) {
+ /* But, if this button should be in pressed state in other multitouch id, do not initialize it */
+ sclboolean found = FALSE;
+ for (sclint loop = 0;loop < context->get_multi_touch_context_num() && !found;loop++) {
+ SclUIEventDesc desc;
+ context->get_multi_touch_event(loop, &desc);
+ if (desc.touch_id != touch_id) {
+ MultiTouchContext *multi_touch_context =
+ context->find_multi_touch_context(desc.touch_id);
+ if (multi_touch_context) {
+ if (multi_touch_context->cur_pressed_window == pressed_window &&
+ multi_touch_context->cur_pressed_key == pressed_key) {
+ found = TRUE;
+ }
+ }
+ }
+ }
+ if (!found) {
+ pressed_context->state = BUTTON_STATE_NORMAL;
+ }
+ }
+ /* If the window doesn't get exposed before corresponding release event,
+ * the inverted state of a button will never be drawn onto screen.
+ * To prevent such a case, we draw the inverted state of button forcefully and directly,
+ * without waiting for expose event */
+ /* Redrawing pressed button does not work properly, commented out */
+ /*
+ CSCLGraphics *grps = CSCLGraphics::get_instance();
+ CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+ scldrawctx draw_ctx;
+ if (pressed_window != SCLWINDOW_INVALID && pressed_key != NOT_USED) {
+ draw_ctx = grps->begin_paint(pressed_window, TRUE);
+ builder->draw_button(pressed_window, draw_ctx, pressed_key, FALSE);
+ grps->end_paint(pressed_window, draw_ctx);
+ }
+ draw_ctx = grps->begin_paint(window, TRUE);
+ builder->draw_button(window, draw_ctx, key_index, TRUE);
+ grps->end_paint(window, draw_ctx);
+ */
+
+ switch (coordinate->button_type) {
+ case BUTTON_TYPE_DRAG: {
+ SclUIEventDesc key_event_desc;
+ key_event_desc.key_value = coordinate->key_value[shift_index][0];
+ key_event_desc.key_event = coordinate->key_event[shift_index][0];
+ key_event_desc.key_type = coordinate->key_type;
+ key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+
+ key_event_desc.event_type = EVENT_TYPE_MOVE;
+ key_event_desc.touch_id = touch_id;
+ key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+ key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+ key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+ key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+ if (sclres_manager) {
+ magnifier_configure = sclres_manager->get_magnifier_configure();
+ }
+ sclboolean processed = handler->on_event_drag_state_changed(key_event_desc);
+ if (processed && context->get_magnifier_enabled() && magnifier_configure) {
+ SclPoint zoomwinpos = {0, 0};
+ /* calculates x position to be set */
+ zoomwinpos.x = (coordinate->x + (coordinate->width / 2)) -
+ (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+
+ /* calculates y position to be set */
+ sclint scnWidth, scnHeight;
+ utils->get_screen_resolution(&scnWidth, &scnHeight);
+
+ zoomwinpos.y = coordinate->y -
+ magnifier_configure->height * utils->get_custom_scale_rate_y();
+ SclWindowContext *window_context = windows->get_window_context(window);
+ if (window_context) {
+ zoomwinpos.x += window_context->geometry.x;
+ zoomwinpos.y += window_context->geometry.y;
+ }
+ if (zoomwinpos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+ zoomwinpos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+ }
+ if (zoomwinpos.x > scnWidth +
+ magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+ magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+ zoomwinpos.x = scnWidth +
+ magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+ magnifier_configure->width * utils->get_custom_scale_rate_x();
+ }
+ zoomwinpos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+ zoomwinpos.x += coordinate->magnifier_offset_x;
+ zoomwinpos.y += coordinate->magnifier_offset_y;
+ windows->move_window(windows->get_magnifier_window(), zoomwinpos.x, zoomwinpos.y);
+ windows->show_window(windows->get_magnifier_window(), 0);
+ }
+
+ handler->on_event_key_clicked(key_event_desc);
+ if (!(windows->is_base_window(window))) {
+ /* When press event occured in popup window, reset POPUP_TIMEOUT timer */
+ //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+ SclWindowContext *window_context = windows->get_window_context(window);
+ if (window_context) {
+ if (window_context->timeout > 0) {
+ events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
+ events->create_timer(SCL_TIMER_POPUP_TIMEOUT, window_context->timeout, 0, TRUE);
+ }
+ }
+ }
+ }
+ break;
+ case BUTTON_TYPE_NORMAL: break;
+ case BUTTON_TYPE_GRAB: break;
+ case BUTTON_TYPE_SELFISH: break;
+ case BUTTON_TYPE_MULTITAP: break;
+ case BUTTON_TYPE_ROTATION: break;
+ case BUTTON_TYPE_DIRECTION: break;
+ case BUTTON_TYPE_RELATIVE_DIRECTION: break;
+ case BUTTON_TYPE_UIITEM: break;
+ case MAX_BUTTON_TYPE: break;
+ default:
+ break;
+ }
+
+#ifdef DIRECTLY_DRAW_ON_EVENTS
+ CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+ if (builder) {
+ if (button_context) {
+ builder->draw_button(window, NULL, key_index, button_context->state);
+ }
+ if (pressedContext) {
+ builder->draw_button(pressed_window, NULL, pressed_key, pressedContext->state, TRUE);
+ }
+ }
+#else
+ windows->update_window(window,
+ coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+ if (pressed_coordinate) {
+ windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
+ pressed_coordinate->width, pressed_coordinate->height);
+ }
+#endif
+ }
+
+ //utils->log("Now Moving : %d %d\n", pos.x, pos.y);
+ } else {
+ /* If the focus went out from our SELFISH button */
+ if (pressed_coordinate->button_type == BUTTON_TYPE_SELFISH) {
+ pressed_context->state = BUTTON_STATE_NORMAL;
+ windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
+ pressed_coordinate->width, pressed_coordinate->height);
+ /* And if this SELFISH button was the last button pressed */
+ if (touch_id == context->get_last_touch_device_id()) {
+ windows->hide_window(windows->get_magnifier_window());
+ }
+ }
+ }
+ } else {
+ /* If the focus came back into our SELFISH button */
+ if (pressed_coordinate->button_type == BUTTON_TYPE_SELFISH && pressed_context->state != BUTTON_STATE_PRESSED) {
+ pressed_context->state = BUTTON_STATE_PRESSED;
+ windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
+ pressed_coordinate->width, pressed_coordinate->height);
+ /* And if this SELFISH button was the last button pressed */
+ if (touch_id == context->get_last_touch_device_id()) {
+ CSCLController *controller = CSCLController::get_instance();
+ sclboolean showMagnifier = controller->check_magnifier_available(pressed_window, pressed_key, touch_id);
+
+ if (showMagnifier) {
+ windows->show_window(windows->get_magnifier_window());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+sclboolean
+CSCLControllerButton::process_button_over_event(sclwindow window, sclint x, sclint y, sclbyte key_index)
+{
+ SCL_DEBUG();
+
+ sclboolean ret = FALSE;
+
+ CSCLUtils *utils = CSCLUtils::get_instance();
+ CSCLEvents *events = CSCLEvents::get_instance();
+ CSCLContext *context = CSCLContext::get_instance();
+ CSCLWindows *windows = CSCLWindows::get_instance();
+ CSCLFeedback *feedback = CSCLFeedback::get_instance();
+ CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+ SclButtonContext *button_context = NULL;
+
+ const SclLayoutKeyCoordinate *coordinate = NULL;
+ if (cache) {
+ coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+ button_context = cache->get_cur_button_context(window, key_index);
+ }
+
+ if (button_context && coordinate && feedback && utils && context && cache && events && windows) {
+ /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
+ sclboolean subLayoutMatch = TRUE;
+ if (coordinate->sub_layout && context->get_cur_sublayout()) {
+ if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
+ subLayoutMatch = FALSE;
+ }
+ }
+ if ( x >= coordinate->x - coordinate->add_hit_left &&
+ x < coordinate->x + coordinate->width + coordinate->add_hit_right &&
+ y >= coordinate->y - coordinate->add_hit_top &&
+ y < coordinate->y + coordinate->height + coordinate->add_hit_bottom &&
+ subLayoutMatch ) {
+ ret = TRUE;
+
+ SCLShiftState shift_index = context->get_shift_state();
+ if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+ if (context->get_caps_lock_mode()) {
+ shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+ }
+
+ const SclLayout* layout = cache->get_cur_layout(windows->get_base_window());
+
+ sclwindow highlighted_window = context->get_cur_highlighted_window();
+ scl8 highlighted_key = context->get_cur_highlighted_key();
+ SclButtonContext *cur_context = cache->get_cur_button_context(window, key_index);
+
+ if (cur_context == NULL) {
+ return FALSE;
+ }
+ if (key_index != highlighted_key || window != highlighted_window) {
+ SECURE_LOGD("%d != %d || %p != %p", key_index, highlighted_key, window, highlighted_window);
+ if (layout) {
+ if (coordinate->key_type != KEY_TYPE_NONE) {
+ if (context->get_tts_enabled()) {
+ const sclchar *targetstr = coordinate->hint_string[shift_index][button_context->multitap_index];
+ if (targetstr == NULL) {
+ targetstr = coordinate->label[shift_index][0];
+ }
+ if (targetstr == NULL) {
+ targetstr = coordinate->key_value[shift_index][button_context->multitap_index];
+ }
+ /*if(state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY ) {
+ targetstr = coordinate->long_key_value;
+ }*/
+ const sclchar *sayit = cache->find_substituted_string(targetstr);
+ utils->play_tts(sayit);
+ }
+ }
+ }
+
+ context->set_cur_highlighted_window(window);
+ context->set_cur_highlighted_key(key_index);
+ }
+ }
+ }
+
+ return ret;
+}
+
+sclboolean
+CSCLControllerButton::process_button_release_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+ scltouchdevice touch_id, sclboolean actual_event)
+{
+ SCL_DEBUG();
+
+ sclboolean ret = FALSE;
+ sclboolean redraw = FALSE;
+ sclboolean fire_event = FALSE;
+ SCLKeyModifier key_modifier = KEY_MODIFIER_NONE;
+
+ CSCLUtils *utils = CSCLUtils::get_instance();
+ CSCLFeedback *feedback = CSCLFeedback::get_instance();
+ CSCLWindows *windows = CSCLWindows::get_instance();
+ CSCLContext *context = CSCLContext::get_instance();
+ CSCLActionState *state = CSCLActionState::get_instance();
+ CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+ CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+ SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+ if (!sclres_manager) return FALSE;
+
+ PSclLayout sclres_layout = sclres_manager->get_layout_table();
+ PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+ if (!sclres_layout || !sclres_input_mode_configure) return FALSE;
+
+ SclButtonContext *button_context = NULL;
+ const SclLayoutKeyCoordinate *coordinate = NULL;
+
+ if (cache) {
+ button_context = cache->get_cur_button_context(window, key_index);
+ coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+ }
+
+ const SclLayoutKeyCoordinate *targetCoordinate = NULL;
+
+ if (utils && feedback && windows && context && state && handler && cache && button_context && coordinate) {
+ scl8 savedInputMode = context->get_input_mode();
+
+ sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
+ scl8 pressed_key = context->get_cur_pressed_key(touch_id);
+
+ if (actual_event) {
+ if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+ /* When calling mouse_release, the seq order of current multitouch events will be changed,
+ so we put all the multitouch events into a vector and use them afterwards for releasing */
+ sclboolean finished = FALSE;
+ sclint loop = 0;
+ sclint multi_touch_context_num = context->get_multi_touch_context_num();
+ std::vector<SclUIEventDesc> multi_touch_events;
+ for (loop = 0;loop < multi_touch_context_num;loop++) {
+ SclUIEventDesc desc;
+ context->get_multi_touch_event(loop, &desc);
+ multi_touch_events.push_back(desc);
+ }
+ for (loop = 0;loop < multi_touch_context_num && !finished;loop++) {
+ SclUIEventDesc desc = multi_touch_events[loop];
+ if (desc.touch_id != touch_id) {
+ sclwindow cur_pressed_window = context->get_cur_pressed_window(desc.touch_id);
+ scl8 cur_pressed_key = context->get_cur_pressed_key(desc.touch_id);
+ const SclLayoutKeyCoordinate *cur_pressed_coordinate =
+ cache->get_cur_layout_key_coordinate(cur_pressed_window, cur_pressed_key);
+ if (cur_pressed_coordinate) {
+ if (cur_pressed_coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+ CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
+ controller_mouse->mouse_release(context->get_cur_moving_window(desc.touch_id),
+ context->get_cur_moving_point(desc.touch_id).x,
+ context->get_cur_moving_point(desc.touch_id).y,
+ desc.touch_id, FALSE);
+ }
+ }
+ } else {
+ finished = TRUE;
+ }
+ }
+ }
+ }
+
+ /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
+ sclint thresholdX = 0;
+ sclint thresholdY = 0;
+ if (context) {
+ if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
+ thresholdX = utils->get_scaled_x(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_X);
+ thresholdY = utils->get_scaled_y(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_Y);
+ }
+ }
+
+ /* Check if the pressed button's type is directional button */
+ if (coordinate->button_type == BUTTON_TYPE_DIRECTION || coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+ if (context) {
+ if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
+ ret = TRUE;
+ sclboolean check_farthest = FALSE;
+
+ sclint startx = x;
+ sclint starty = y;
+
+ /* If the buttontype is RELATIVE_DIRECTION, get the distance from last move point */
+ if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+ startx = context->get_prev_moving_point(touch_id).x;
+ starty = context->get_prev_moving_point(touch_id).y;
+ } else {
+ startx = context->get_cur_pressed_point(touch_id).x;
+ starty = context->get_cur_pressed_point(touch_id).y;
+ }
+
+ sclint deltax = x - startx;
+ sclint deltay = y - starty;
+
+ sclfloat dist = utils->get_distance(x, y, startx, starty);
+ sclfloat direction_recog_dist = SCL_DIRECTION_RECOG_DIST * utils->get_smallest_scale_rate();
+ if (coordinate->is_side_button) {
+ direction_recog_dist = SCL_DIRECTION_RECOG_DIST_SIDE * utils->get_smallest_scale_rate();
+ };
+ if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+ direction_recog_dist = SCL_DIRECTION_RELATIVE_RECOG_DIST * utils->get_smallest_scale_rate();
+ }
+ if (context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN &&
+ coordinate->button_type != BUTTON_TYPE_RELATIVE_DIRECTION) {
+ if (coordinate->extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN ||
+ coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN ||
+ coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE) {
+ deltax = context->get_farthest_move_point(touch_id).x - context->get_cur_pressed_point(touch_id).x;
+ deltay = context->get_farthest_move_point(touch_id).y - context->get_cur_pressed_point(touch_id).y;
+ dist = utils->get_distance(context->get_farthest_move_point(touch_id), context->get_cur_pressed_point(touch_id));
+ check_farthest = TRUE;
+ }
+ }
+ if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+ key_modifier = context->get_cur_key_modifier(touch_id);
+ } else if (dist > direction_recog_dist) {
+ CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
+ key_modifier = controller_mouse->get_drag_key_modifier(deltax, deltay, dist, check_farthest, touch_id, coordinate->extra_option);
+ }
+ }
+ }
+ }
+
+ /* First check if this button is enabled in current active sublayout */
+ sclboolean subLayoutMatch = TRUE;
+ if (coordinate->sub_layout && context->get_cur_sublayout()) {
+ if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
+ subLayoutMatch = FALSE;
+ }
+ }
+ /* Check if the event occured inside this button's rectangle */
+ if ( x >= coordinate->x - coordinate->add_hit_left - thresholdX &&
+ x < coordinate->x + coordinate->width + coordinate->add_hit_right + thresholdX &&
+ y >= coordinate->y - coordinate->add_hit_top - thresholdY &&
+ y < coordinate->y + coordinate->height + coordinate->add_hit_bottom + thresholdY &&
+ subLayoutMatch ) {
+ ret = TRUE;
+ }
+
+ if (ret) {
+ /* for feedback */
+ feedback->button_released(window, key_index);
+
+ /* If this button's index is the same as the one initially pressed */
+ if (pressed_window == window && pressed_key == key_index) {
+ fire_event = TRUE;
+ targetCoordinate = coordinate;
+ } else {
+ const SclLayoutKeyCoordinate *pressed_coordinate =
+ cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+ if (pressed_coordinate) {
+ CSCLController *controller = CSCLController::get_instance();
+ if (controller->check_event_transition_enabled(pressed_coordinate, coordinate)) {
+ fire_event = TRUE;
+ targetCoordinate = pressed_coordinate;
+ } else {
+ ret = FALSE;
+ }
+ }
+ }
+ }
+
+ /* In case of mode change buttons, event should be fired only when it was pressed lastly */
+ if (fire_event) {
+ if (coordinate->key_type == KEY_TYPE_MODECHANGE) {
+ if (touch_id != context->get_last_touch_device_id()) {
+ fire_event = FALSE;
+ }
+ }
+ }
+
+ /* If this key's modifier is LONGKEY, this means the event is already fired so skip this one */
+ if (context->get_cur_key_modifier(touch_id) == KEY_MODIFIER_LONGKEY) {
+ fire_event = FALSE;
+ }
+
+ /* Don't fire any events if we're in longkey state */
+ if (state->get_cur_action_state() != ACTION_STATE_BASE_LONGKEY &&
+ state->get_cur_action_state() != ACTION_STATE_BASE_REPEATKEY &&
+ state->get_cur_action_state() != ACTION_STATE_POPUP_LONGKEY &&
+ state->get_cur_action_state() != ACTION_STATE_POPUP_REPEATKEY) {
+ if (ret) {
+ SCLShiftState shift_index = context->get_shift_state();
+ if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+ if (context->get_caps_lock_mode()) {
+ shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+ }
+
+ SclUIEventDesc key_event_desc;
+ if (targetCoordinate) {
+ key_event_desc.key_type = targetCoordinate->key_type;
+
+ key_event_desc.key_value = targetCoordinate->key_value[shift_index][button_context->multitap_index];
+ key_event_desc.key_event = targetCoordinate->key_event[shift_index][button_context->multitap_index];
+ }
+ key_event_desc.key_modifier = key_modifier;
+
+ key_event_desc.event_type = EVENT_TYPE_RELEASE;
+ key_event_desc.touch_id = touch_id;
+ key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+ key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+ key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+ key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+ if (handler->on_event_drag_state_changed(key_event_desc) != SCL_EVENT_PASS_ON) {
+ fire_event = FALSE;
+ }
+ }
+ if (fire_event) {
+ if (targetCoordinate) {
+ SCLShiftState shift_index = context->get_shift_state();
+ if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+ if (context->get_caps_lock_mode()) {
+ shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+ }
+
+ SclUIEventDesc key_event_desc;
+ key_event_desc.key_type = targetCoordinate->key_type;
+
+ key_event_desc.event_type = EVENT_TYPE_RELEASE;
+ key_event_desc.touch_id = touch_id;
+ key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+ key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+ key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+ key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+ switch (targetCoordinate->button_type) {
+ case BUTTON_TYPE_NORMAL:
+ case BUTTON_TYPE_GRAB :
+ case BUTTON_TYPE_SELFISH:
+ case BUTTON_TYPE_DIRECTION :
+ case BUTTON_TYPE_RELATIVE_DIRECTION: {
+ SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
+ if (pressed_context) {
+ if (!(targetCoordinate->use_repeat_key) && pressed_context->state == BUTTON_STATE_PRESSED) {
+ key_event_desc.key_value = targetCoordinate->key_value[shift_index][0];
+ key_event_desc.key_event = targetCoordinate->key_event[shift_index][0];
+ key_event_desc.key_modifier = key_modifier;
+ handler->on_event_key_clicked(key_event_desc);
+ }
+ }
+ }
+ break;
+ case BUTTON_TYPE_MULTITAP:
+ case BUTTON_TYPE_ROTATION: {
+ if (targetCoordinate->button_type == BUTTON_TYPE_MULTITAP) {
+ if (window == context->get_last_event_fired_window() &&
+ key_index == context->get_last_event_fired_key()) {
+ key_modifier = KEY_MODIFIER_MULTITAP_REPEAT;
+ } else {
+ key_modifier = KEY_MODIFIER_MULTITAP_START;
+ }
+ } else {
+ key_modifier = KEY_MODIFIER_NONE;
+ }
+ if (button_context->multitap_index < MAX_SIZE_OF_MULTITAP_CHAR) {
+ key_event_desc.key_value = coordinate->key_value[shift_index][button_context->multitap_index];
+ key_event_desc.key_event = coordinate->key_event[shift_index][button_context->multitap_index];
+ key_event_desc.key_modifier = key_modifier;
+ if (SCL_EVENT_PASS_ON == handler->on_event_key_clicked(key_event_desc)) {
+ CSCLEvents *events = CSCLEvents::get_instance();
+ events->destroy_timer(SCL_TIMER_MULTITAP);
+ CSCLController *controller = CSCLController::get_instance();
+ events->create_timer(SCL_TIMER_MULTITAP, controller->get_multitap_delay_duration(), 0);
+ }
+ }
+ /* Check if the multikey index is in valid range, and increase by one */
+ if (button_context->multitap_index >= MAX_SIZE_OF_MULTITAP_CHAR - 1) {
+ button_context->multitap_index = 0;
+ } else {
+ sclbyte orgindex = button_context->multitap_index;
+ button_context->multitap_index = 0;
+ if (targetCoordinate->key_value[shift_index][orgindex + 1]) {
+ if (strlen(targetCoordinate->key_value[shift_index][orgindex + 1]) > 0) {
+ button_context->multitap_index = orgindex + 1;
+ }
+ }
+ }
+ }
+ break;
+ case BUTTON_TYPE_DRAG : {
+ }
+ break;
+ case BUTTON_TYPE_TOGGLE : {
+ SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
+ if (pressed_context) {
+ if (!(targetCoordinate->use_repeat_key) && pressed_context->state == BUTTON_STATE_PRESSED) {
+ key_event_desc.key_value = targetCoordinate->key_value[shift_index][0];
+ key_event_desc.key_event = targetCoordinate->key_event[shift_index][0];
+ if (pressed_context->toggled) {
+ key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+ } else {
+ key_event_desc.key_modifier = KEY_MODIFIER_TOGGLED;
+ }
+ if (SCL_EVENT_PASS_ON == handler->on_event_key_clicked(key_event_desc)) {
+ pressed_context->toggled = !(pressed_context->toggled);
+ }
+ }
+ }
+ }
+ case BUTTON_TYPE_UIITEM: break;
+ case MAX_BUTTON_TYPE: break;
+ default: break;
+ }
+ switch (coordinate->popup_type) {
+ case POPUP_TYPE_BTN_RELEASE_POPUP:
+ case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE: {
+ SCLDragState dragstate = context->get_cur_drag_state(touch_id);
+ sclint popup_input_mode = NOT_USED;
+
+ SclNotiPopupOpeningDesc desc;
+ desc.ui_event_desc = &key_event_desc;
+
+ if (scl_check_arrindex(dragstate, SCL_DRAG_STATE_MAX)) {
+ desc.input_mode = coordinate->popup_input_mode[dragstate];
+ popup_input_mode = sclres_manager->get_inputmode_id(coordinate->popup_input_mode[dragstate]);
+ /* FIXME */
+ //if (!scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP)) {
+ if (!scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE)) {
+ desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
+ }
+ }
+ if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
+ popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
+ SCLDisplayMode display_mode = context->get_display_mode();
+ /* FIXME */
+ //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
+ if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
+ scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+ sclshort popupLayoutId =
+ sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
+ if (popupLayoutId == NOT_USED) {
+ // deal with NOT_USED
+ LOGD("popupLayoutID is not used.");
+ }
+ SclLayout *layout = NULL;
+ /* FIXME */
+ //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
+ if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
+ layout = &sclres_layout[popupLayoutId];
+ }
+ if (layout) {
+ SclRectangle popupRect;
+ SclRectangle baseWndRect;
+ windows->get_window_rect(windows->get_base_window(), &baseWndRect);
+ popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
+ popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
+
+ //popupRect.width = utils->get_scale_x(layout->width);
+ //popupRect.height= utils->get_scale_y(layout->height);
+ if (!(sclres_manager->loaded(popupLayoutId))) {
+ sclres_manager->load(popupLayoutId);
+ }
+ popupRect.width = layout->width;
+ popupRect.height = layout->height;
+
+ /* Let's make sure this popup window does not go beyond the screen area */
+ sclint scr_w, scr_h;
+ utils->get_screen_resolution(&scr_w, &scr_h);
+
+ if (popupRect.x + popupRect.width > scr_w) {
+ popupRect.x = scr_w - popupRect.width;
+ }
+ if (popupRect.y + popupRect.height > scr_h) {
+ popupRect.y = scr_h - popupRect.height;
+ }
+
+ SclWindowOpener opener;
+ opener.window = window;
+ opener.key = key_index;
+
+ sclwindow popup_window = windows->open_popup(
+ opener,
+ popupRect,
+ popup_input_mode,
+ popupLayoutId,
+ coordinate->popup_type,
+ sclres_input_mode_configure[popup_input_mode].use_virtual_window,
+ sclres_input_mode_configure[popup_input_mode].use_dim_window,
+ coordinate->extract_offset_x,
+ coordinate->extract_offset_y,
+ sclres_input_mode_configure[popup_input_mode].timeout);
+
+ SclNotiPopupOpenedDesc opened_desc;
+ opened_desc.ui_event_desc = &key_event_desc;
+ opened_desc.input_mode = desc.input_mode;
+ opened_desc.window = popup_window;
+ handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
+
+ windows->hide_window(windows->get_magnifier_window());
+ _play_tts_for_input_mode_name(popup_input_mode);
+ }
+ }
+ }
+ }
+ break;
+ case POPUP_TYPE_AUTO_POPUP:
+ case POPUP_TYPE_BTN_PRESS_POPUP_DRAG:
+ case POPUP_TYPE_NONE:
+ /* Nothing to do in here */
+ break;
+ case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE: break;
+ case POPUP_TYPE_BTN_LONGPRESS_POPUP: break;
+ case MAX_POPUP_TYPE: break;
+ default: break;
+ }
+ }
+
+ context->set_last_event_fired_window(window);
+ context->set_last_event_fired_key(key_index);
+ }
+ } else {
+ if (targetCoordinate) {
+ SCLShiftState shift_index = context->get_shift_state();
+ if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+ if (context->get_caps_lock_mode()) {
+ shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+ }
+
+ SclUIEventDesc key_event_desc;
+ key_event_desc.key_type = targetCoordinate->key_type;
+
+ key_event_desc.key_value = targetCoordinate->key_value[shift_index][button_context->multitap_index];
+ key_event_desc.key_event = targetCoordinate->key_event[shift_index][button_context->multitap_index];
+ key_event_desc.key_modifier = key_modifier;
+
+ key_event_desc.event_type = EVENT_TYPE_RELEASE;
+ key_event_desc.touch_id = touch_id;
+ key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+ key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+ key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+ key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+ handler->on_event_drag_state_changed(key_event_desc);
+ }
+ }
+
+ /* If this button was pressed, initialize the button context regardless of event */
+ if (button_context->state == BUTTON_STATE_PRESSED) {
+ /* But, if this button should be in pressed state in other multitouch id, do not initialize */
+ sclboolean found = FALSE;
+ for (sclint loop = 0;loop < context->get_multi_touch_context_num() && !found;loop++) {
+ SclUIEventDesc desc;
+ context->get_multi_touch_event(loop, &desc);
+ if (desc.touch_id != touch_id) {
+ MultiTouchContext *multi_touch_context = context->find_multi_touch_context(desc.touch_id);
+ if (multi_touch_context) {
+ if (multi_touch_context->cur_pressed_window == window &&
+ multi_touch_context->cur_pressed_key == key_index) {
+ found = TRUE;
+ }
+ }
+ }
+ }
+ if (!found) {
+ button_context->state = BUTTON_STATE_NORMAL;
+ redraw = TRUE;
+ }
+ }
+
+ /* If this button needs to be redrawn */
+ if (redraw) {
+#ifdef DIRECTLY_DRAW_ON_EVENTS
+ CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+ if (builder) {
+ builder->draw_button(window, NULL, key_index, button_context->state, TRUE);
+ }
+#else
+ if (savedInputMode == context->get_input_mode()) {
+ windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+ }
+
+#endif
+ }
+ }
+
+ return ret;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "sclgwes.h"
+#include "sclutils.h"
+#include "sclcontext.h"
+
+#ifndef __SCL_CONTROLLER_BUTTON_H__
+#define __SCL_CONTROLLER_BUTTON_H__
+
+//SCL_BEGIN_DECLS
+
+namespace scl
+{
+
+class CSCLControllerButton
+{
+private:
+ CSCLControllerButton() {}
+public:
+ virtual ~CSCLControllerButton() {}
+
+ static CSCLControllerButton* get_instance();
+
+public:
+ sclboolean process_button_pressed_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+ scltouchdevice touch_id, sclboolean actual_event = TRUE);
+ sclboolean process_button_long_pressed_event(sclwindow window, sclbyte key_index,
+ scltouchdevice touch_id, sclboolean actual_event = TRUE);
+ sclboolean process_button_repeat_pressed_event(sclwindow window, sclbyte key_index,
+ scltouchdevice touch_id, sclboolean actual_event = TRUE);
+ sclboolean process_button_move_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+ scltouchdevice touch_id, sclboolean actual_event = TRUE);
+ sclboolean process_button_over_event(sclwindow window, sclint x, sclint y, sclbyte key_index);
+ sclboolean process_button_release_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+ scltouchdevice touch_id, sclboolean actual_event = TRUE);
+
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_CONTROLLER_BUTTON_H__
--- /dev/null
+/*
+ * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 <time.h>
+#include <math.h>
+#include <assert.h>
+#include <vector>
+
+#include "sclcontroller_mouse.h"
+#include "sclcontroller.h"
+#include "sclcontroller_button.h"
+#include "scldebug.h"
+#include "sclresourcecache.h"
+#include "sclactionstate.h"
+#include "scluibuilder.h"
+#include "sclkeydefines.h"
+#include "sclfeedback.h"
+#include "sclerroradjustment.h"
+#include "sclimageproxy.h"
+#include "sclres_manager.h"
+#include "scleventhandler.h"
+#include "sclanimator.h"
+#include "sclkeyfocushandler.h"
+#include <dlog.h>
+
+//#define DIRECTLY_DRAW_ON_EVENTS
+
+using namespace scl;
+
+CSCLControllerMouse*
+CSCLControllerMouse::get_instance()
+{
+ static CSCLControllerMouse instance;
+ return &instance;
+}
+
+sclboolean
+CSCLControllerMouse::mouse_press(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
+{
+ SCL_DEBUG();
+ sclboolean ret = FALSE;
+
+ CSCLController *controller = CSCLController::get_instance();
+ if (controller->get_input_events_disabled()) return FALSE;
+
+ //utils->log("Controller::mouse_press : %d %d\n", x, y);
+
+ /* Adjust x,y coordinate by touch offset */
+ CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+
+ CSCLContext *context = CSCLContext::get_instance();
+ CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+ CSCLActionState *state = CSCLActionState::get_instance();
+ CSCLWindows *windows = CSCLWindows::get_instance();
+ CSCLUtils *utils = CSCLUtils::get_instance();
+
+ sclint button_index = NOT_USED;
+ SclWindowContext *window_context = NULL;
+ if (windows && cache) {
+ const SclLayout *layout = cache->get_cur_layout(window);
+ if (layout) {
+ x += layout->mouse_manipulate_x;
+ y += layout->mouse_manipulate_y;
+ }
+ window_context = windows->get_window_context(window);
+ /* If the dim window is virtual and currently active, let's just skip this event */
+ if (windows->is_base_window(window)) {
+ SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
+ if (dim_window_context) {
+ LOGD("dim window is_virtual:%d, hidden:%d", dim_window_context->is_virtual, dim_window_context->hidden);
+ if (/*dim_window_context->is_virtual &&*/ !(dim_window_context->hidden)) {
+ window = windows->get_dim_window();
+ window_context = dim_window_context;
+ }
+ }
+ }
+ }
+
+ if (cache && state && windows && context && window_context) {
+ SCLDisplayMode display_mode = context->get_display_mode();
+ SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+ PSclDefaultConfigure default_configure = NULL;
+ if (sclres_manager) {
+ default_configure = sclres_manager->get_default_configure();
+ }
+ if (default_configure) {
+ adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
+ }
+
+ sclboolean isSubEvent = FALSE;
+ if (context->get_multi_touch_context_num() > 0) {
+ SclUIEventDesc desc;
+ context->get_multi_touch_event(0, &desc);
+ sclwindow pressed_window = context->get_cur_pressed_window(desc.touch_id);
+ scl8 pressed_key = context->get_cur_pressed_key(desc.touch_id);
+ SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+ if (coordinate) {
+ if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_GRAB_SUB_EVENTS) {
+ isSubEvent = TRUE;
+ if (utils)
+ utils->play_vibration(DEFAULT_VIBRATION_STYLE, DEFAULT_VIBRATION_DURATION);
+ }
+ }
+ }
+ context->create_multi_touch_context(touch_id, isSubEvent);
+ context->set_cur_pressed_window(touch_id, window);
+ context->set_cur_pressed_point(touch_id, x, y);
+ context->set_cur_pressed_time(touch_id);
+ context->set_cur_moving_window(touch_id, window);
+ context->set_cur_moving_point(touch_id, x, y);
+ context->set_last_touch_device_id(touch_id);
+ context->set_cur_drag_state(touch_id, SCL_DRAG_STATE_NONE);
+ context->set_cur_key_modifier(touch_id, KEY_MODIFIER_NONE);
+ for (sclint labelidx = 0;labelidx < MAX_SIZE_OF_LABEL_FOR_ONE;labelidx++) {
+ context->set_custom_magnifier_label(touch_id, labelidx, NULL);
+ }
+
+ /* If there is postponed update of button, update it now */
+ CSCLEvents *events = CSCLEvents::get_instance();
+ sclwindow last_win = context->get_last_pressed_window();
+ scl8 last_key = context->get_last_pressed_key();
+ if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
+ const SclLayoutKeyCoordinate* coords = cache->get_cur_layout_key_coordinate(last_win, last_key);
+ if (coords) {
+ windows->update_window(last_win, coords->x, coords->y, coords->width, coords->height);
+ }
+ }
+ context->set_prev_pressed_window(touch_id, SCLWINDOW_INVALID);
+ context->set_prev_pressed_key(touch_id, NOT_USED);
+ context->set_prev_drag_state(touch_id, SCL_DRAG_STATE_NONE);
+ context->set_prev_moving_point(touch_id, x, y);
+
+ /* Destroy key related timers */
+ events->destroy_timer(SCL_TIMER_BUTTON_DELAY);
+ events->destroy_timer(SCL_TIMER_AUTOPOPUP);
+ events->destroy_timer(SCL_TIMER_SHORT_LONGKEY);
+ events->destroy_timer(SCL_TIMER_LONGKEY);
+ events->destroy_timer(SCL_TIMER_REPEATKEY);
+ events->destroy_timer(SCL_TIMER_MULTITAP);
+
+ /* Do what has to be done when mouse gets pressed */
+ CSCLController *controller = CSCLController::get_instance();
+ controller->handle_engine_signal(SCL_SIG_MOUSE_PRESS, window);
+
+ /* Adjust event x and y positions as relative position to the virtual window */
+ if (window_context) {
+ /*if (window_context->isVirtual) {
+ SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+ if (base_window_context) {
+ x -= (window_context->x - base_window_context->x);
+ y -= (window_context->y - base_window_context->y);
+ }
+ }*/
+ }
+
+ if (!isSubEvent) {
+ sclboolean process_finished = FALSE;
+ do {
+ /* Iterate all the buttons and inform the event */
+ sclboolean ended = FALSE;
+ for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
+ SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
+ const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+ if (button_context && coordinate) {
+ if (!(button_context->used)) {
+ ended = TRUE;
+ } else if (button_context->state != BUTTON_STATE_DISABLED &&
+ coordinate->button_type != BUTTON_TYPE_UIITEM) {
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ if (controller_button->process_button_pressed_event(window, x, y, loop, touch_id, actual_event)) {
+ if (windows->is_base_window(window)) {
+ state->set_cur_action_state(ACTION_STATE_BASE_PRESS);
+ } else {
+ state->set_cur_action_state(ACTION_STATE_POPUP_PRESS);
+ }
+ button_index = loop;
+ ret = TRUE;
+ }
+ }
+ }
+ }
+
+ /* For covering a missing area about 1 pixel */
+ if (!ret) {
+ for (int loop = 0;loop < MAX_KEY;loop++) {
+ SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
+ const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+ if (button_context && coordinate) {
+ if (!(button_context->used)) {
+ break;
+ } else if (button_context->state != BUTTON_STATE_DISABLED &&
+ coordinate->button_type != BUTTON_TYPE_UIITEM) {
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ if (controller_button->process_button_pressed_event(window, x+1, y+1, loop, touch_id, actual_event)) {
+ if (windows->is_base_window(window)) {
+ state->set_cur_action_state(ACTION_STATE_BASE_PRESS);
+ } else {
+ state->set_cur_action_state(ACTION_STATE_POPUP_PRESS);
+ }
+ button_index = loop;
+ break;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ if (windows->is_base_window(window)) {
+ process_finished = TRUE;
+ } else if (button_index != NOT_USED) {
+ process_finished = TRUE;
+ } else {
+ const SclLayout *layout = cache->get_cur_layout(window);
+ if (layout) {
+ if (layout->use_sw_background && layout->bg_color.a == 0) {
+ /* If we could not find appropriate button in this popup window and the popup is transparent */
+ SclWindowContext *base_window_context =
+ windows->get_window_context(windows->get_base_window());
+ if (base_window_context) {
+ x = (window_context->geometry.x + x - base_window_context->geometry.x);
+ y = (window_context->geometry.y + y - base_window_context->geometry.y);
+ }
+ window = windows->get_base_window();
+ } else {
+ process_finished = TRUE;
+ }
+ } else {
+ process_finished = TRUE;
+ }
+ }
+ } while (!process_finished);
+ }
+
+ sclwindow skip_window = window;
+ if (ret && button_index != NOT_USED) {
+ const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, button_index);
+ if (coordinate) {
+ sclboolean dont_close_popup = FALSE;
+ if (coordinate->dont_close_popup) {
+ dont_close_popup = TRUE;
+ }
+ /* If the button's popup type is drag type, the opened popup could be the one opened by this press event */
+ if (coordinate->popup_type == POPUP_TYPE_BTN_PRESS_POPUP_DRAG) {
+ /* Check the opened popup was opened by this button */
+ sclwindow popupwin = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+ SclWindowContext *popup_window_context = windows->get_window_context(popupwin);
+ if (popup_window_context) {
+ SclWindowOpener opener = popup_window_context->opener;
+ if (opener.window == window && opener.key == button_index) {
+ dont_close_popup = TRUE;
+ }
+ }
+ }
+ if (dont_close_popup) {
+ skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+ }
+ }
+ } else {
+ SclUIEventDesc key_event_desc;
+ key_event_desc.event_type = EVENT_TYPE_PRESS;
+
+ SclPoint curpoint = {x, y};
+ key_event_desc.touch_id = touch_id;
+ key_event_desc.mouse_pressed_point = curpoint;
+ key_event_desc.mouse_current_point = curpoint;
+ key_event_desc.mouse_farthest_point = curpoint;
+
+ key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+ CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+ if (handler) {
+ handler->on_event_drag_state_changed(key_event_desc);
+ }
+ }
+ windows->close_all_popups(skip_window);
+
+ /* When press event occured in popup window, reset POPUP_TIMEOUT timer */
+ if (!(windows->is_base_window(window))) {
+ if (window_context->timeout > 0) {
+ events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
+ events->create_timer(SCL_TIMER_POPUP_TIMEOUT, window_context->timeout, 0, TRUE);
+ }
+ } else if (skip_window != window) { /* Or the pressed button has dont_close_popup property, reset POPUP_TIMEOUT timer */
+ //SclWindowContext *skip_window_context = windows->get_window_context(skip_window, FALSE);
+ SclWindowContext *skip_window_context = windows->get_window_context(skip_window);
+ if (skip_window_context) {
+ if (skip_window_context->timeout > 0) {
+ events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
+ events->create_timer(SCL_TIMER_POPUP_TIMEOUT, skip_window_context->timeout, 0, TRUE);
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+sclboolean
+CSCLControllerMouse::mouse_release(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
+{
+ SCL_DEBUG();
+ sclboolean ret = FALSE;
+
+ //if (m_input_events_disabled) return FALSE;
+
+ //utils->log("Controller::mouse_release : %d %d\n", x, y);
+ /* Adjust x,y coordinate by touch offset */
+ CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+
+ CSCLContext *context = CSCLContext::get_instance();
+ CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+ CSCLActionState *state = CSCLActionState::get_instance();
+ CSCLWindows *windows = CSCLWindows::get_instance();
+ CSCLUtils *utils = CSCLUtils::get_instance();
+ CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+ CSCLEvents *events = CSCLEvents::get_instance();
+ CSCLController *controller = CSCLController::get_instance();
+
+ sclint button_index = NOT_USED;
+
+ if (cache && state && windows && context && utils && handler && events &&
+ context->find_multi_touch_context(touch_id)) {
+ const SclLayout *layout = cache->get_cur_layout(window);
+ if (layout) {
+ x += layout->mouse_manipulate_x;
+ y += layout->mouse_manipulate_y;
+ }
+
+ sclwindow skip_window = SCLWINDOW_INVALID;
+ SCLDisplayMode display_mode = context->get_display_mode();
+
+ SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+ PSclDefaultConfigure default_configure = NULL;
+ if (sclres_manager) {
+ default_configure = sclres_manager->get_default_configure();
+ }
+ if (default_configure) {
+ adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
+ }
+
+ context->set_cur_moving_window(touch_id, SCLWINDOW_INVALID);
+
+ sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
+ scl8 pressed_key = context->get_cur_pressed_key(touch_id);
+ //SclWindowContext *window_context = windows->get_window_context(window, TRUE);
+ SclWindowContext *window_context = windows->get_window_context(window);
+ /* Adjust event x and y positions as relative position to the virtual window */
+ if (window_context) {
+ /*if (window_context->isVirtual) {
+ SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+ if (base_window_context) {
+ x -= (window_context->x - base_window_context->x);
+ y -= (window_context->y - base_window_context->y);
+ }
+ }*/
+ /* If the dim window is virtual and currently active, consider base window's event is occured in dim window */
+ if (windows->is_base_window(window)) {
+ SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
+ if (dim_window_context) {
+ if (dim_window_context->is_virtual && !(dim_window_context->hidden)) {
+ window = windows->get_dim_window();
+ window_context = dim_window_context;
+ }
+ }
+ }
+ }
+
+ /* Iterate all the buttons and inform the event */
+ sclboolean ended = FALSE;
+
+ /* FIXME : The routine below seems to be removed, which was originally requested by Vodafone,
+ * to slow down the speed of repeat key right before stopping repeatkey event */
+ /* if (state->get_cur_action_state() == ACTION_STATE_BASE_REPEATKEY) {
+ if (m_key_repeated_num > 10) {
+ utils->sleep(100);
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ controller_button->process_button_repeat_pressed_event(pressed_window, pressed_key, touch_id);
+ }
+ ended = TRUE;
+ }*/
+
+ if (context->get_cur_pressed_window(touch_id) == window) {
+ if (abs(context->get_cur_pressed_point(touch_id).x - x) > utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD) ||
+ abs(context->get_cur_pressed_point(touch_id).y - y) > utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD) )
+ {
+ struct timeval t0 = context->get_cur_pressed_time(touch_id);
+ struct timeval t1;
+ gettimeofday(&t1, NULL);
+ float etime;
+ etime = ((t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec))/1000.0;
+ if (etime < SCL_FLICK_GESTURE_RECOG_TIME) {
+ SCLDragType drag_type = DRAG_NONE;
+ if (x > context->get_cur_pressed_point(touch_id).x + utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
+ drag_type = DRAG_RIGHT;
+ }
+ if (x < context->get_cur_pressed_point(touch_id).x - utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
+ drag_type = DRAG_LEFT;
+ }
+ if (y > context->get_cur_pressed_point(touch_id).y + utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
+ drag_type = DRAG_DOWN;
+ }
+ if (y < context->get_cur_pressed_point(touch_id).y - utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
+ drag_type = DRAG_UP;
+ }
+ SclNotiGestureFlickDesc desc;
+ SclUIEventDesc ui_event_desc;
+ ui_event_desc.key_value = NULL;
+ ui_event_desc.key_event = NOT_USED;
+ ui_event_desc.key_modifier = KEY_MODIFIER_NONE;
+ ui_event_desc.event_type = EVENT_TYPE_RELEASE;
+ ui_event_desc.touch_id = touch_id;
+ ui_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+ ui_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+ ui_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+ ui_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+ desc.ui_event_desc = &ui_event_desc;
+ desc.drag_type = drag_type;
+ if (handler->on_event_notification(SCL_UINOTITYPE_GESTURE_FLICK, &desc)) {
+ ended = TRUE;
+ }
+ }
+ }
+ }
+
+ /* FIXME : We should consider this kind of action in general manner, not only specific to autopopup */
+ /* And also, this kind of implementation only selects button that was highlighted at least once. */
+ // {
+ //SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window, FALSE);
+ SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window);
+ if (pressed_window_context) {
+ utils->log("PRESSED CTX : %p %d %d\n", pressed_window,
+ pressed_window_context->geometry.x, pressed_window_context->geometry.y);
+ //if (pressedCtx->popuptype == POPUP_TYPE_AUTO_POPUP) {
+ sclboolean grab_event = FALSE;
+ const SclLayout *pressed_layout = cache->get_cur_layout(pressed_window);
+ if (pressed_layout) {
+ if (pressed_layout->style == LAYOUT_STYLE_POPUP_GRAB) {
+ grab_event = TRUE;
+ }
+ /* If the topmost window has the POPUP_GRAB style, find the nearest button to the mouse pointer */
+ if (grab_event) {
+ /* If the layout's addGrab* values are defined, process this event only if the event occured inside grab area */
+ sclboolean in_grab_area = TRUE;
+ if (pressed_layout->add_grab_left != NOT_USED &&
+ x < (pressed_window_context->geometry.x - pressed_layout->add_grab_left)) {
+ in_grab_area = FALSE;
+ }
+ if (pressed_layout->add_grab_right != NOT_USED &&
+ x > (pressed_window_context->geometry.x + pressed_window_context->geometry.width
+ + pressed_layout->add_grab_right)) {
+ in_grab_area = FALSE;
+ }
+ if (pressed_layout->add_grab_top != NOT_USED &&
+ y < (pressed_window_context->geometry.y - pressed_layout->add_grab_top)) {
+ in_grab_area = FALSE;
+ }
+ if (pressed_layout->add_grab_bottom != NOT_USED &&
+ y > (pressed_window_context->geometry.y + pressed_window_context->geometry.height
+ + pressed_layout->add_grab_bottom)) {
+ in_grab_area = FALSE;
+ }
+ if (in_grab_area) {
+ SclLayoutKeyCoordinate *coord = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+ if (coord) {
+ x = coord->x + (coord->width / 2);
+ y = coord->y + (coord->height / 2);
+
+ for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
+ SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, loop);
+ const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, loop);
+ if (button_context && coordinate) {
+ if (!(button_context->used)) {
+ ended = TRUE;
+ } else if (button_context->state != BUTTON_STATE_DISABLED &&
+ coordinate->button_type != BUTTON_TYPE_UIITEM) {
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ if (controller_button->process_button_release_event(pressed_window, x, y, loop, touch_id, actual_event)) {
+ ret = TRUE;
+ ended = TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ // }
+
+ SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
+ const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+ /* FIXME : The rule below would not be a general requirement. A policy is needed regarding this. */
+ /* Ignore base window's release event if a popup window is opened */
+ if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
+ if (windows->is_base_window(window)) {
+ ended = TRUE;
+ /* In case of direction button, the release event on other window should be processed */
+ if (coordinate && window_context && pressed_window_context) {
+ if (coordinate->button_type == BUTTON_TYPE_DIRECTION || coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+ sclint relx = (window_context->geometry.x + x) - pressed_window_context->geometry.x;
+ sclint rely = (window_context->geometry.y + y) - pressed_window_context->geometry.y;
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ if (controller_button->process_button_release_event(pressed_window, relx, rely, pressed_key, touch_id, actual_event)) {
+ button_index = pressed_key;
+ ret = TRUE;
+ x = coordinate->x + (coordinate->width / 2);
+ y = coordinate->y + (coordinate->height / 2);
+ skip_window = pressed_window;
+ }
+ }
+ }
+ }
+ }
+
+ sclboolean process_finished = FALSE;
+ do {
+ MultiTouchContext *multi_touch_context = context->find_multi_touch_context(touch_id);
+ if (multi_touch_context) {
+ if (!(multi_touch_context->is_sub_event)) {
+ /* First check if the event occured in pressed key's threshold area */
+ if (button_context && coordinate && !ended) {
+ if (button_context->used && button_context->state != BUTTON_STATE_DISABLED) {
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ if (controller_button->process_button_release_event(pressed_window, x, y, pressed_key, touch_id, actual_event)) {
+ button_index = pressed_key;
+ ret = TRUE;
+ x = coordinate->x + (coordinate->width / 2);
+ y = coordinate->y + (coordinate->height / 2);
+ }
+ }
+ }
+ for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
+ SclButtonContext *cur_context = cache->get_cur_button_context(window, loop);
+ const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+ if (cur_context && cur_coordinate) {
+ if (!(cur_context->used)) {
+ ended = TRUE;
+ } else if (cur_context->state != BUTTON_STATE_DISABLED &&
+ cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
+ if (window != pressed_window || loop != pressed_key) {
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ if (controller_button->process_button_release_event(window, x, y, loop, touch_id, actual_event)) {
+ button_index = loop;
+ ret = TRUE;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ process_finished = TRUE;
+
+ SclUIEventDesc key_event_desc;
+ key_event_desc.key_value = NULL;
+ key_event_desc.key_event = NOT_USED;
+ key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+ key_event_desc.event_type = EVENT_TYPE_NONE;
+ key_event_desc.touch_id = touch_id;
+ key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+ key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+ key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+ key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+ handler->on_event_key_clicked(key_event_desc);
+ }
+ }
+
+ /* For covering a missing area about 1 pixel */
+ if (!ret) {
+ ended = FALSE;
+
+ if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
+ if (windows->is_base_window(window)) {
+ ended = TRUE;
+ }
+ }
+
+ for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
+ SclButtonContext *cur_context = cache->get_cur_button_context(window, loop);
+ if (cur_context && coordinate) {
+ if (!(cur_context->used)) {
+ ended = TRUE;
+ break;
+ } else if (cur_context->state != BUTTON_STATE_DISABLED &&
+ coordinate->button_type != BUTTON_TYPE_UIITEM) {
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ if (controller_button->process_button_release_event(window, x+1, y+1, loop, touch_id)) {
+ button_index = loop;
+ ret = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (windows->is_base_window(window)) {
+ process_finished = TRUE;
+ } else if (button_index != NOT_USED) {
+ process_finished = TRUE;
+ } else {
+ if (layout && layout->use_sw_background && layout->bg_color.a == 0) {
+ /* If we could not find appropriate button in this popup window and the popup is transparent */
+ SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+ if (base_window_context && window_context) {
+ x = (window_context->geometry.x + x - base_window_context->geometry.x);
+ y = (window_context->geometry.y + y - base_window_context->geometry.y);
+ }
+ window = windows->get_base_window();
+ } else {
+ process_finished = TRUE;
+ }
+ }
+ } while (!process_finished);
+
+ if (!ret) {
+ SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
+ const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+ SCLShiftState shift_index = context->get_shift_state();
+ if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+ if (context->get_caps_lock_mode()) {
+ shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+ }
+
+ SclUIEventDesc key_event_desc;
+ if (coordinate && button_context) {
+ key_event_desc.key_type = coordinate->key_type;
+
+ key_event_desc.key_value = coordinate->key_value[shift_index][button_context->multitap_index];
+ key_event_desc.key_event = coordinate->key_event[shift_index][button_context->multitap_index];
+ }
+ key_event_desc.key_modifier = context->get_cur_key_modifier(touch_id);;
+
+ key_event_desc.event_type = EVENT_TYPE_RELEASE;
+ key_event_desc.touch_id = touch_id;
+ key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+ key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+ key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+ key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+ handler->on_event_drag_state_changed(key_event_desc);
+ }
+
+ if (windows->is_base_window(window)) {
+ state->set_cur_action_state(ACTION_STATE_BASE_INIT);
+ } else {
+ state->set_cur_action_state(ACTION_STATE_POPUP_INIT);
+ }
+
+ /* Restore previously pressed button's context and redraw it */
+ if (button_context && coordinate) {
+ button_context->state = BUTTON_STATE_NORMAL;
+ /* Commented below line to postpone some of the feedback for releasing */
+ //windows->update_window(pressed_window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+ }
+
+ /* If there is postponed update of button, update it now */
+ sclwindow last_win = context->get_last_pressed_window();
+ scl8 last_key = context->get_last_pressed_key();
+ if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
+ const SclLayoutKeyCoordinate* coords = cache->get_cur_layout_key_coordinate(last_win, last_key);
+ if (coords) {
+ windows->update_window(last_win, coords->x, coords->y, coords->width, coords->height);
+ }
+ }
+
+ /* To postpone some of the feedback for releasing */
+ context->set_last_pressed_key(context->get_cur_pressed_key(touch_id));
+ context->set_last_pressed_window(context->get_cur_pressed_window(touch_id));
+
+ /* Do what has to be done when mouse gets released */
+ sclboolean signaled = FALSE;
+ if (coordinate) {
+ switch (coordinate->popup_type) {
+ case POPUP_TYPE_BTN_RELEASE_POPUP:
+ case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE:
+ case POPUP_TYPE_BTN_LONGPRESS_POPUP:
+ case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE:
+ {
+ /* Fix me : We should consider z-order */
+ skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+ controller->handle_engine_signal(SCL_SIG_MOUSE_RELEASE, skip_window);
+ signaled = TRUE;
+ }
+ break;
+ case POPUP_TYPE_NONE: break;
+ case POPUP_TYPE_BTN_PRESS_POPUP_DRAG: break;
+ case POPUP_TYPE_AUTO_POPUP: break;
+ case MAX_POPUP_TYPE: break;
+ default: break;
+ }
+ }
+ if (!signaled) {
+ //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+ window_context = windows->get_window_context(window);
+ if (window_context) {
+ if (window_context->popup_type == POPUP_TYPE_BTN_RELEASE_POPUP ||
+ window_context->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP) {
+ /* Don't close window if the clicked button is a child of ReleasePopup window */
+ skip_window = window;
+ controller->handle_engine_signal(SCL_SIG_MOUSE_RELEASE, window);
+ signaled = TRUE;
+ }
+ }
+ if (!signaled) {
+ controller->handle_engine_signal(SCL_SIG_MOUSE_RELEASE);
+ }
+ }
+
+ context->set_cur_pressed_key(touch_id, NOT_USED);
+ context->set_cur_pressed_window(touch_id, SCLWINDOW_INVALID);
+
+ if (ret && button_index != NOT_USED) {
+ const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, button_index);
+ if (cur_coordinate) {
+ if (cur_coordinate->dont_close_popup) {
+ skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+ }
+ }
+ } else {
+ if (pressed_window == windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP)) {
+ if (pressed_window_context) {
+ if (pressed_window_context->popup_type != POPUP_TYPE_BTN_RELEASE_POPUP_ONCE &&
+ pressed_window_context->popup_type != POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE &&
+ pressed_window_context->popup_type != POPUP_TYPE_AUTO_POPUP &&
+ pressed_window_context->popup_type != POPUP_TYPE_BTN_PRESS_POPUP_DRAG)
+ {
+ skip_window = pressed_window;
+ }
+ }
+ }
+ }
+ windows->close_all_popups(skip_window);
+
+ /* Destroy key related timers */
+ events->destroy_timer(SCL_TIMER_AUTOPOPUP);
+ events->destroy_timer(SCL_TIMER_SHORT_LONGKEY);
+ events->destroy_timer(SCL_TIMER_LONGKEY);
+ events->destroy_timer(SCL_TIMER_REPEATKEY);
+
+ /* If there are more than 1 active multitouch ids, don't play button_delay trick */
+ if (context->get_multi_touch_context_num() == 1) {
+ /* To postpone some of the feedback for releasing */
+ CSCLController *controller = CSCLController::get_instance();
+ events->create_timer(SCL_TIMER_BUTTON_DELAY, controller->get_button_delay_duration(), 0);
+ } else {
+ last_win = context->get_last_pressed_window();
+ last_key = context->get_last_pressed_key();
+
+ if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
+ const SclLayoutKeyCoordinate* last_coordinate = cache->get_cur_layout_key_coordinate(last_win, last_key);
+ if (last_coordinate) {
+ windows->update_window(last_win,
+ last_coordinate->x, last_coordinate->y, last_coordinate->width, last_coordinate->height);
+ }
+ }
+
+ windows->hide_window(windows->get_magnifier_window());
+ context->set_last_pressed_window(SCLWINDOW_INVALID);
+ context->set_last_pressed_key(NOT_USED);
+ }
+ }
+
+ if (context) {
+ if (touch_id == context->get_last_touch_device_id()) {
+ context->set_last_touch_device_id(SCLTOUCHDEVICE_INVALID);
+ }
+ context->destroy_multi_touch_context(touch_id);
+ }
+
+ return ret;
+}
+
+SCLKeyModifier
+CSCLControllerMouse::get_drag_key_modifier(sclint deltax, sclint deltay, sclfloat dist, sclboolean check_farthest,
+ scltouchdevice touch_id, sclbyte extra_option) {
+ typedef struct {
+ double lowerbound;
+ double upperbound;
+ SCLKeyModifier modifier;
+ } DIRECTIONINFO;
+
+ CSCLContext *context = CSCLContext::get_instance();
+ SCLKeyModifier key_modifier = KEY_MODIFIER_NONE;
+
+ if (context) {
+ double theta = atan2(deltay , (deltax ? deltax : 1)); /* Avoid divide by 0 exception */
+ sclfloat ratio = fabs((sclfloat)deltay / (deltax ? deltax : 1));
+ SCLDragState cur_drag_state = context->get_cur_drag_state(touch_id);
+ if (extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS ||
+ extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG ||
+ extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN) { /* 8 directions */
+ /* If the theta is below 0, the direction is upward since the y coordinate grows downward */
+ /* The below angle values are customized for MoAKey, need to provide customizing API */
+ DIRECTIONINFO info[] = {
+ {-8 * (M_PI / 8), -7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_LEFT},
+ {-7 * (M_PI / 8), -5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP_LEFT},
+ {-5 * (M_PI / 8), -2.7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP},
+ {-2.7 * (M_PI / 8), -1.5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP_RIGHT},
+ {-1.5 * (M_PI / 8), 1 * (M_PI / 8), KEY_MODIFIER_DIRECTION_RIGHT},
+ { 1 * (M_PI / 8), 3 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN_RIGHT},
+ { 3 * (M_PI / 8), 5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN},
+ { 5 * (M_PI / 8), 7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN_LEFT},
+ { 7 * (M_PI / 8), 8 * (M_PI / 8), KEY_MODIFIER_DIRECTION_LEFT},
+ };
+ for (size_t loop = 0; loop < sizeof(info) / sizeof(DIRECTIONINFO); loop++) {
+ if (theta >= info[loop].lowerbound && theta <= info[loop].upperbound) {
+ key_modifier = info[loop].modifier;
+ }
+ }
+ } else { /* 4 directions */
+ /* If the state was dragging to one of 4 directions and the final release point is
+ * far enough from inital press point, and the angle is in between out predefined angle value */
+ if (extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE &&
+ cur_drag_state != SCL_DRAG_STATE_NONE && cur_drag_state != SCL_DRAG_STATE_INVALID &&
+ dist > SCL_DRAG_CURVE_RECOG_DIST &&
+ ratio > (1 / SCL_DRAG_CURVE_FINAL_ANGLE_VALUE) &&
+ ratio < SCL_DRAG_CURVE_FINAL_ANGLE_VALUE) {
+ if (cur_drag_state == SCL_DRAG_STATE_DOWN) {
+ if (deltax > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_DOWN_RIGHT;
+ else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_DOWN_LEFT;
+ }
+ if (cur_drag_state == SCL_DRAG_STATE_UP) {
+ if (deltax > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_UP_RIGHT;
+ else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_UP_LEFT;
+ }
+ if (cur_drag_state == SCL_DRAG_STATE_LEFT) {
+ if (deltay > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_LEFT_DOWN;
+ else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_LEFT_UP;
+ }
+ if (cur_drag_state == SCL_DRAG_STATE_RIGHT) {
+ if (deltay > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_RIGHT_DOWN;
+ else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_RIGHT_UP;
+ }
+ } else {
+ DIRECTIONINFO info[] = {
+ {-4 * (M_PI / 4), -3 * (M_PI / 4), KEY_MODIFIER_DIRECTION_LEFT},
+ {-3 * (M_PI / 4), -1 * (M_PI / 4), KEY_MODIFIER_DIRECTION_UP},
+ {-1 * (M_PI / 4), 1 * (M_PI / 4), KEY_MODIFIER_DIRECTION_RIGHT},
+ { 1 * (M_PI / 4), 3 * (M_PI / 4), KEY_MODIFIER_DIRECTION_DOWN},
+ { 3 * (M_PI / 4), 4 * (M_PI / 4), KEY_MODIFIER_DIRECTION_LEFT},
+ };
+ for (size_t loop = 0; loop < sizeof(info) / sizeof(DIRECTIONINFO); loop++) {
+ if (theta >= info[loop].lowerbound && theta <= info[loop].upperbound) {
+ key_modifier = info[loop].modifier;
+ }
+ }
+ }
+ }
+
+ if (extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG ||
+ extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_LONG) {
+ if (key_modifier >= KEY_MODIFIER_DIRECTION_LEFT &&
+ key_modifier <= KEY_MODIFIER_DIRECTION_DOWN_RIGHT) {
+ key_modifier = (SCLKeyModifier)(key_modifier + 8); // Add LONG attribute;
+ }
+ }
+ if (check_farthest || context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN) {
+ if (key_modifier >= KEY_MODIFIER_DIRECTION_LEFT &&
+ key_modifier <= KEY_MODIFIER_DIRECTION_DOWN_RIGHT) {
+ key_modifier = (SCLKeyModifier)(key_modifier + 16); // Add RETURN attribute;
+ }
+ }
+ }
+
+ return key_modifier;
+}
+
+SCLDragState get_drag_state(sclint deltax, sclint deltay)
+{
+ SCLDragState ret = SCL_DRAG_STATE_INVALID;
+
+ sclfloat ratio = fabs((sclfloat)deltay / (deltax ? deltax : 1));
+ /* If tan(theta) is smaller than our predefined value */
+ if (ratio <= (1 / SCL_DRAG_CURVE_4_DIRECTION_ANGLE_VALUE)) {
+ if (deltax > 0) {
+ ret = SCL_DRAG_STATE_RIGHT;
+ } else {
+ ret = SCL_DRAG_STATE_LEFT;
+ }
+ } else if (ratio >= SCL_DRAG_CURVE_4_DIRECTION_ANGLE_VALUE) {
+ /* If tan(theta) is bigger than our predefined value */
+ if (deltay > 0) {
+ ret = SCL_DRAG_STATE_DOWN;
+ } else {
+ ret = SCL_DRAG_STATE_UP;
+ }
+ }
+
+ return ret;
+}
+
+sclboolean
+CSCLControllerMouse::mouse_move(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
+{
+ SCL_DEBUG();
+ sclboolean ret = FALSE;
+
+ CSCLController *controller = CSCLController::get_instance();
+ if (controller->get_input_events_disabled()) return FALSE;
+
+ //utils->log("Controller::mouse_move : %d %d\n", x, y);
+
+ /* Adjust x,y coordinate by touch offset */
+ CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+
+ CSCLContext *context = CSCLContext::get_instance();
+ CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+ CSCLActionState *state = CSCLActionState::get_instance();
+ CSCLWindows *windows = CSCLWindows::get_instance();
+ CSCLEvents *events = CSCLEvents::get_instance();
+ CSCLUtils *utils = CSCLUtils::get_instance();
+ CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+ SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+ if (!sclres_manager) return FALSE;
+
+ PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
+ if (!sclres_modifier_decoration) return FALSE;
+
+ if (cache && state && windows && context && utils && adjustment && sclres_manager) {
+ const SclLayout *layout = cache->get_cur_layout(window);
+ if (layout) {
+ x += layout->mouse_manipulate_x;
+ y += layout->mouse_manipulate_y;
+ }
+
+ if (!(context->find_multi_touch_context(touch_id))) return FALSE;
+
+ PSclDefaultConfigure default_configure = sclres_manager->get_default_configure();
+ if (default_configure) {
+ SCLDisplayMode display_mode = context->get_display_mode();
+ adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
+ }
+
+ //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+ SclWindowContext *window_context = windows->get_window_context(window);
+ /* Adjust event x and y positions as relative position to the virtual window */
+ if (window_context) {
+ /*if (window_context->isVirtual) {
+ SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+ if (base_window_context) {
+ x -= (window_context->x - base_window_context->x);
+ y -= (window_context->y - base_window_context->y);
+ }
+ }*/
+ /* If the dim window is virtual and currently active, let's just skip this event */
+ if (windows->is_base_window(window)) {
+ SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
+ if (dim_window_context) {
+ if (dim_window_context->is_virtual && !(dim_window_context->hidden)) {
+ return FALSE;
+ }
+ }
+ }
+ /* If the pressed event was occured in dim window, let's just skip this move event */
+ if (context->get_last_pressed_window() == windows->get_dim_window()) {
+ return FALSE;
+ }
+ }
+
+ sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
+ scl8 pressed_key = context->get_cur_pressed_key(touch_id);
+ SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
+ const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+ /* If the multitouch type is SETTLE_PREVIOUS and is not the last touch device, let's ignore move events */
+ if (coordinate) {
+ if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+ if (context->get_last_touch_device_id() != touch_id) {
+ return FALSE;
+ }
+ }
+ }
+
+ context->set_cur_moving_point(touch_id, x, y);
+ context->set_cur_moving_window(touch_id, window);
+
+ /* If in longkey state, do not process, just return */
+ if (state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
+ state->get_cur_action_state() == ACTION_STATE_BASE_REPEATKEY ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY) {
+ return FALSE;
+ }
+ /* FIXME : The rule below would not be a general requirement. A policy is needed regarding this. */
+ /* And if the event occured in popup window, don't come back to base window */
+ if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
+ state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
+ if (windows->is_base_window(window)) {
+ return FALSE;
+ }
+ }
+
+ SclUIEventDesc desc;
+ SCLShiftState shift_index = context->get_shift_state();
+ if (context->get_caps_lock_mode()) {
+ shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+ }
+ if (coordinate) {
+ desc.key_type = coordinate->key_type;
+ desc.key_value = coordinate->key_value[shift_index][0];
+ desc.key_event = coordinate->key_event[shift_index][0];
+ }
+ desc.event_type = EVENT_TYPE_MOVE;
+ desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+ desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+ desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+ if (handler && handler->on_event_drag_state_changed(desc) != SCL_EVENT_PASS_ON) {
+ return FALSE;
+ }
+
+ /* FIXME : Add a condition to skip this code if longkey timer is not active */
+ /* If the mouse has moved out of threshold value of longkey keypress area, destroy longkey timer */
+ CSCLController *controller = CSCLController::get_instance();
+ if (controller->get_longkey_cancel_dist() > 0) {
+ sclfloat dist = utils->get_distance(x, y,
+ context->get_cur_pressed_point(touch_id).x, context->get_cur_pressed_point(touch_id).y);
+ if (controller->get_longkey_cancel_dist() < dist) {
+ events->destroy_timer(SCL_TIMER_LONGKEY);
+ }
+ }
+
+ if (windows->is_base_window(window)) {
+ state->set_cur_action_state(ACTION_STATE_BASE_MOVING);
+ } else {
+ state->set_cur_action_state(ACTION_STATE_POPUP_MOVING);
+ }
+
+ /* Iterate all the buttons and inform the event */
+ sclboolean ended = FALSE;
+
+ /* Check farthest move point and update it */
+ sclint originx = x;
+ sclint originy = y;
+ if (pressed_window != window) {
+ //SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window, FALSE);
+ SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window);
+ if (window_context && pressed_window_context) {
+ originx = (window_context->geometry.x - pressed_window_context->geometry.x) + x;
+ originy = (window_context->geometry.y - pressed_window_context->geometry.y) + y;
+ }
+ }
+ sclint startx = originx;
+ sclint starty = originy;
+
+ /* Check if we should recognize drag curve */
+ if (coordinate) {
+ startx = context->get_cur_pressed_point(touch_id).x;
+ starty = context->get_cur_pressed_point(touch_id).y;
+ sclint deltax = originx - startx;
+ sclint deltay = originy - starty;
+ sclfloat approximate_dist = utils->get_approximate_distance(originx, originy, startx, starty);
+
+ sclboolean update_magnifier = FALSE;
+ sclboolean drag_state_changed = FALSE;
+ SCLDragState cur_drag_state = context->get_cur_drag_state(touch_id);
+ SCLDragState next_drag_state = SCL_DRAG_STATE_NONE;
+ sclfloat direction_recog_dist = SCL_DIRECTION_RECOG_DIST * utils->get_smallest_scale_rate();
+ if (coordinate->is_side_button) {
+ direction_recog_dist = SCL_DIRECTION_RECOG_DIST_SIDE * utils->get_smallest_scale_rate();
+ };
+
+ if (coordinate->button_type == BUTTON_TYPE_DIRECTION) {
+ /* Do not check farthest move point if current drag state is SCL_DRAG_STATE_RETURN */
+ if (context->get_cur_drag_state(touch_id) != SCL_DRAG_STATE_RETURN) {
+ if (approximate_dist > context->get_farthest_move_dist(touch_id)) {
+ context->set_farthest_move_point(touch_id, originx, originy);
+ }
+ }
+
+ if (cur_drag_state == SCL_DRAG_STATE_RETURN) {
+ direction_recog_dist *= SCL_DRAG_RETURN_RECOG_THRESHOLD_RETURN;
+ } else if (cur_drag_state != SCL_DRAG_STATE_NONE) {
+ direction_recog_dist *= SCL_DRAG_RETURN_RECOG_THRESHOLD_OTHER;
+ }
+ if (approximate_dist > direction_recog_dist) {
+ next_drag_state = get_drag_state(deltax, deltay);
+ /* Disable longkey if dragging is recognized */
+ events->destroy_timer(SCL_TIMER_LONGKEY);
+ }
+ if (cur_drag_state != next_drag_state) {
+ drag_state_changed = TRUE;
+ }
+ if (cur_drag_state == SCL_DRAG_STATE_NONE) {
+ //if (nextDragState != SCL_DRAG_STATE_INVALID) {
+ cur_drag_state = next_drag_state;
+ //}
+ } else if (cur_drag_state != next_drag_state) {
+ if (next_drag_state == SCL_DRAG_STATE_NONE) {
+ cur_drag_state = SCL_DRAG_STATE_RETURN;
+ } else {
+ cur_drag_state = next_drag_state;
+ }
+ }
+
+ context->set_cur_drag_state(touch_id, cur_drag_state);
+ sclboolean check_farthest = FALSE;
+ sclshort display = context->get_display_mode();
+ if (!scl_check_arrindex(display, DISPLAYMODE_MAX)) display = 0;
+ sclfloat dist = utils->get_distance(originx, originy,
+ context->get_cur_pressed_point(touch_id).x, context->get_cur_pressed_point(touch_id).y);
+ if (dist < direction_recog_dist && context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN) {
+ if (coordinate->extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN ||
+ coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN ||
+ coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE) {
+ deltax = context->get_farthest_move_point(touch_id).x -
+ context->get_cur_pressed_point(touch_id).x;
+ deltay = context->get_farthest_move_point(touch_id).y -
+ context->get_cur_pressed_point(touch_id).y;
+ dist = utils->get_distance(context->get_farthest_move_point(touch_id),
+ context->get_cur_pressed_point(touch_id));
+ check_farthest = TRUE;
+ }
+ }
+ SCLKeyModifier key_modifier = get_drag_key_modifier(deltax, deltay, dist,
+ check_farthest, touch_id, coordinate->extra_option);
+ if (dist > direction_recog_dist) {
+ context->set_cur_key_modifier(touch_id, key_modifier);
+ }
+ /* If this button needs to be decorated when dragged */
+ if (coordinate->modifier_decorator) {
+ const SclModifierDecoration *decoration = NULL;
+ /* FIXME */
+ /*if (scl_check_arrindex(coordinate->modifier_decorator,
+ sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
+ scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
+ if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
+ if (sclres_modifier_decoration[decoration_id].valid) {
+ decoration = &(sclres_modifier_decoration[decoration_id]);
+ }
+ }
+ /* Check if the button really needs to be redrawn (whether it has non-null bg_image_path information */
+ if (decoration) {
+ if (decoration->bg_image_path[display][key_modifier]) {
+ windows->update_window(window,
+ coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+ }
+ }
+ }
+ if (dist > direction_recog_dist) {
+ if (context->get_magnifier_enabled()) {
+ update_magnifier = TRUE;
+ }
+ }
+ } else if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+ if (cur_drag_state != SCL_DRAG_STATE_NONE) {
+ startx = context->get_prev_moving_point(touch_id).x;
+ starty = context->get_prev_moving_point(touch_id).y;
+ approximate_dist = utils->get_approximate_distance(originx, originy, startx, starty);
+ direction_recog_dist = SCL_DIRECTION_RELATIVE_RECOG_DIST * utils->get_smallest_scale_rate();
+ }
+ deltax = originx - startx;
+ deltay = originy - starty;
+ //printf("DIST : %f, RECOG : %f\n", dist, direction_recog_dist);
+ if (approximate_dist > direction_recog_dist) {
+ next_drag_state = get_drag_state(deltax, deltay);
+ /* Disable longkey if dragging is recognized */
+ events->destroy_timer(SCL_TIMER_LONGKEY);
+
+ if (cur_drag_state != next_drag_state) {
+ drag_state_changed = TRUE;
+ }
+ if (next_drag_state != SCL_DRAG_STATE_NONE) {
+ cur_drag_state = next_drag_state;
+ }
+ context->set_cur_drag_state(touch_id, cur_drag_state);
+
+ startx = context->get_farthest_move_point(touch_id).x;
+ starty = context->get_farthest_move_point(touch_id).y;
+ deltax = originx - startx;
+ deltay = originy - starty;
+ sclfloat dist_farthest = utils->get_approximate_distance(originx, originy, startx, starty);
+ //printf("%d %d %d %d %f, %d %d\n", originx, originy, startx, starty, dist_farthest, cur_drag_state, next_drag_state);
+ /* Let's see how much we are away from the last farthest point */
+ sclfloat diffdir_recog_dist = SCL_DIRECTION_RELATIVE_DIFFDIR_RECOG_DIST * utils->get_smallest_scale_rate();
+ /* If we moved certain amount from the point where direction changed, process drag state change routine */
+ if (dist_farthest > diffdir_recog_dist || context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_NONE) {
+ sclshort display = context->get_display_mode();
+ SCLKeyModifier key_modifier = get_drag_key_modifier(deltax, deltay, dist_farthest,
+ FALSE, touch_id, coordinate->extra_option);
+ context->set_cur_key_modifier(touch_id, key_modifier);
+ /* If this button needs to be decorated when dragged */
+ if (coordinate->modifier_decorator) {
+ const SclModifierDecoration *decoration = NULL;
+ /* FIXME */
+ /*if (scl_check_arrindex(coordinate->modifier_decorator,
+ sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
+ scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
+ if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
+ if (sclres_modifier_decoration[decoration_id].valid) {
+ decoration = &(sclres_modifier_decoration[decoration_id]);
+ }
+ }
+ /* Check if the button really needs to be redrawn (whether it has non-null bg_image_path information */
+ if (decoration) {
+ if (decoration->bg_image_path[display][key_modifier]) {
+ windows->update_window(window,
+ coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+ }
+ }
+ }
+
+ if (context->get_magnifier_enabled()) {
+ update_magnifier = TRUE;
+ }
+ }
+ context->set_prev_moving_point(touch_id, originx, originy);
+ }
+ if (drag_state_changed) {
+ /* When the dragging direction changes, save the current position as farthest point for future comparison */
+ context->set_farthest_move_point(touch_id, originx, originy);
+ LOGD("SET_FARTHEST : %d %d %d", originx, originy, context->get_cur_drag_state(touch_id));
+ }
+ }
+
+ if (update_magnifier) {
+ PSclMagnifierWndConfigure magnifier_configure = NULL;
+ if (sclres_manager) {
+ magnifier_configure = sclres_manager->get_magnifier_configure();
+ }
+
+ const SclLayout *base_layout = cache->get_cur_layout(windows->get_base_window());
+ if (base_layout && magnifier_configure) {
+ SclPoint zoomwinpos = {0, 0};
+ /* calculates x position to be set */
+ zoomwinpos.x = (coordinate->x + (coordinate->width / 2)) -
+ (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+
+ /* calculates y position to be set */
+ sclint scnWidth, scnHeight;
+ utils->get_screen_resolution(&scnWidth, &scnHeight);
+
+ zoomwinpos.y = coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
+ if (window_context) {
+ zoomwinpos.x += window_context->geometry.x;
+ zoomwinpos.y += window_context->geometry.y;
+ }
+ if (zoomwinpos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+ zoomwinpos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+ }
+ if (zoomwinpos.x > scnWidth +
+ magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+ magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+ zoomwinpos.x = scnWidth +
+ magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+ magnifier_configure->width * utils->get_custom_scale_rate_x();
+ }
+ zoomwinpos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+
+ zoomwinpos.x += coordinate->magnifier_offset_x;
+ zoomwinpos.y += coordinate->magnifier_offset_y;
+ windows->move_window(windows->get_magnifier_window(), zoomwinpos.x, zoomwinpos.y);
+ windows->show_window(windows->get_magnifier_window(), 0);
+ }
+ }
+ }
+
+ sclboolean grab_event = FALSE;
+ if (layout) {
+ if (layout->style == LAYOUT_STYLE_POPUP_GRAB) {
+ grab_event = TRUE;
+ }
+ /* If the topmost window has the POPUP_GRAB style, find the nearest button to the mouse pointer */
+ if (grab_event && window_context) {
+ /* If the layout's addGrab* values are defined, process this event only if the event occured inside grab area */
+ sclboolean in_grab_area = TRUE;
+ if (layout->add_grab_left != NOT_USED && x < -(layout->add_grab_left)) {
+ in_grab_area = FALSE;
+ }
+ if (layout->add_grab_right != NOT_USED && x >
+ (window_context->geometry.width + layout->add_grab_right)) {
+ in_grab_area = FALSE;
+ }
+ if (layout->add_grab_top != NOT_USED && y < -(layout->add_grab_top)) {
+ in_grab_area = FALSE;
+ }
+ if (layout->add_grab_bottom != NOT_USED && y >
+ (window_context->geometry.height + layout->add_grab_bottom)) {
+ in_grab_area = FALSE;
+ }
+ if (in_grab_area) {
+ float min_dist = (float)((unsigned int)(-1));
+ int min_dist_index = NOT_USED;
+ for (int loop = 0;loop < MAX_KEY && !ended && !ret;loop++) {
+ button_context = cache->get_cur_button_context(window, loop);
+ const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+ if (button_context && cur_coordinate) {
+ if (!(button_context->used)) {
+ ended = TRUE;
+ } else if (button_context->state != BUTTON_STATE_DISABLED &&
+ cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
+ float dist = utils->get_approximate_distance(x, y,
+ cur_coordinate->x + (cur_coordinate->width / 2),
+ cur_coordinate->y + (cur_coordinate->height / 2));
+ if (dist < min_dist) {
+ min_dist_index = loop;
+ min_dist = dist;
+ }
+ }
+ }
+ }
+ /* When we found the nearest button, generate this event on the button */
+ if (min_dist_index != NOT_USED) {
+ const SclLayoutKeyCoordinate *min_coordinate =
+ cache->get_cur_layout_key_coordinate(window, min_dist_index);
+ if (min_coordinate) {
+ x = min_coordinate->x + (min_coordinate->width / 2);
+ y = min_coordinate->y + (min_coordinate->height / 2);
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ if (controller_button->process_button_move_event(window, x, y, min_dist_index, touch_id, actual_event)) {
+ ret = TRUE;
+ }
+ }
+ }
+ }
+ } else {
+ MultiTouchContext *multi_touch_context = context->find_multi_touch_context(touch_id);
+ if (multi_touch_context) {
+ sclint button_index = NOT_USED;
+ if (!(multi_touch_context->is_sub_event)) {
+ sclboolean process_finished = FALSE;
+ do {
+ /* First check if the event occured in pressed key's threshold area */
+ if (button_context && coordinate) {
+ if (pressed_window == window) { // Check only when the window is the one initally pressed
+ if (button_context->used && button_context->state != BUTTON_STATE_DISABLED) {
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ if (controller_button->process_button_move_event(pressed_window, x, y, pressed_key, touch_id, actual_event)) {
+ ret = TRUE;
+ x = coordinate->x + (coordinate->width / 2);
+ y = coordinate->y + (coordinate->height / 2);
+ button_index = pressed_key;
+ }
+ }
+ }
+ }
+ for (int loop = 0;loop < MAX_KEY && !ended && !ret;loop++) {
+ button_context = cache->get_cur_button_context(window, loop);
+ const SclLayoutKeyCoordinate *cur_coordinate =
+ cache->get_cur_layout_key_coordinate(window, loop);
+ if (button_context && cur_coordinate) {
+ if (!(button_context->used)) {
+ ended = TRUE;
+ } else if (button_context->state != BUTTON_STATE_DISABLED &&
+ cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
+ if (window != pressed_window || loop != pressed_key) {
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ if (controller_button->process_button_move_event(window, x, y, loop, touch_id, actual_event)) {
+ ret = TRUE;
+ button_index = loop;
+ }
+ }
+ }
+ }
+ }
+
+ if (windows->is_base_window(window)) {
+ process_finished = TRUE;
+ } else if (button_index != NOT_USED) {
+ process_finished = TRUE;
+ } else {
+ const SclLayout *cur_layout = cache->get_cur_layout(window);
+ if (cur_layout && cur_layout->use_sw_background && cur_layout->bg_color.a == 0) {
+ /* If we could not find appropriate button in this popup window and the popup is transparent */
+ SclWindowContext *base_window_context =
+ windows->get_window_context(windows->get_base_window());
+ if (base_window_context && window_context) {
+ x = (window_context->geometry.x + x - base_window_context->geometry.x);
+ y = (window_context->geometry.y + y - base_window_context->geometry.y);
+ }
+ window = windows->get_base_window();
+ } else {
+ process_finished = TRUE;
+ }
+ }
+ } while (!process_finished);
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+sclboolean
+CSCLControllerMouse::mouse_over(sclwindow window, sclint x, sclint y)
+{
+ SCL_DEBUG();
+ sclboolean ret = FALSE;
+
+ CSCLController *controller = CSCLController::get_instance();
+ if (controller->get_input_events_disabled())
+ return FALSE;
+
+ /* Adjust x,y coordinate by touch offset */
+ CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+ /* Iterate all the buttons and inform the event */
+
+ CSCLContext *context = CSCLContext::get_instance();
+ CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+ CSCLActionState *state = CSCLActionState::get_instance();
+ CSCLWindows *windows = CSCLWindows::get_instance();
+ CSCLUtils *utils = CSCLUtils::get_instance();
+ SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+ if (cache && state && windows && context && utils && adjustment && sclres_manager) {
+ const SclLayout *layout = cache->get_cur_layout(window);
+ if (layout) {
+ x += layout->mouse_manipulate_x;
+ y += layout->mouse_manipulate_y;
+ }
+
+ SCLDisplayMode cur_display_mode = context->get_display_mode();
+
+ const SclDefaultConfigure *default_configure = sclres_manager->get_default_configure();
+ if (default_configure) {
+ adjustment->apply_touch_offset(default_configure->touch_offset_level[cur_display_mode], &x, &y);
+ }
+
+ /* Iterate all the buttons and inform the event */
+ sclboolean ended = FALSE;
+
+ for (int loop = 0; loop < MAX_KEY && !ended && !ret; loop++) {
+ SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
+ const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+ if (button_context && coordinate) {
+ if (!(button_context->used)) {
+ ended = TRUE;
+ } else if (button_context->state != BUTTON_STATE_DISABLED &&
+ coordinate->button_type != BUTTON_TYPE_UIITEM) {
+ CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+ if (controller_button->process_button_over_event(window, x, y, loop)) {
+ ret = TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "sclgwes.h"
+#include "sclutils.h"
+#include "sclcontext.h"
+
+#ifndef __SCL_CONTROLLER_MOUSE_H__
+#define __SCL_CONTROLLER_MOUSE_H__
+
+//SCL_BEGIN_DECLS
+
+namespace scl
+{
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class CSCLControllerMouse
+{
+private:
+ CSCLControllerMouse() {}
+public:
+ virtual ~CSCLControllerMouse() {}
+
+ static CSCLControllerMouse* get_instance();
+
+ sclboolean mouse_press(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
+ sclboolean mouse_release(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
+ sclboolean mouse_move(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
+ sclboolean mouse_over(sclwindow window, sclint x, sclint y);
+
+ SCLKeyModifier get_drag_key_modifier(sclint deltax, sclint deltay, sclfloat dist,
+ sclboolean check_farthest, scltouchdevice touch_id, sclbyte extra_option);
+
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_CONTROLLER_MOUSE_H__
#include "sclevents-efl.h"
#include "scldebug.h"
#include "sclcontroller.h"
+#include "sclcontroller_mouse.h"
#include "sclgraphics.h"
#include "scluibuilder.h"
#include "sclerroradjustment.h"
LOGD("Incoming message is empty");
return;
}
- CSCLController *controller = CSCLController::get_instance();
+ CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
CSCLWindows *windows = CSCLWindows::get_instance();
- if (!windows || !controller) return;
+ if (!windows || !controller_mouse) return;
sclwindow base_window = windows->get_base_window();
SclWindowContext *window_context = windows->get_window_context(base_window);
last_pos_x = info->x;
last_pos_y = info->y - window_context->geometry.y;
LOGD("hover last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y);
- controller->mouse_over(base_window, last_pos_x, last_pos_y);
+ controller_mouse->mouse_over(base_window, last_pos_x, last_pos_y);
}
} else if (info->type == ONE_FINGER_DOUBLE_TAP) {
if (info->y >= window_context->geometry.y) {
last_pos_x = info->x;
last_pos_y = info->y - window_context->geometry.y;
LOGD("double last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y);
- controller->mouse_press(base_window, last_pos_x, last_pos_y);
- controller->mouse_release(base_window, last_pos_x, last_pos_y);
+ controller_mouse->mouse_press(base_window, last_pos_x, last_pos_y);
+ controller_mouse->mouse_release(base_window, last_pos_x, last_pos_y);
}
}
free(info);
Ecore_Wl2_Window *wl_window;
#endif
- CSCLController *controller = CSCLController::get_instance();
+ CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
CSCLWindows *windows = CSCLWindows::get_instance();
CSCLContext *context = CSCLContext::get_instance();
CSCLUtils *utils = CSCLUtils::get_instance();
return TRUE;
}
- if (controller && windows && context && utils && adjustment && ev) {
+ if (controller_mouse && windows && context && utils && adjustment && ev) {
LOGD("mouse_press : %d %d, %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y,
g_timestamp_last_base_window_resized, ev->timestamp);
/* Now convert the global coordinate to appropriate local coordinate */
SclPoint coords = get_rotated_local_coords(
root_x, root_y, context->get_rotation(), &rect);
- controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
+ controller_mouse->mouse_press(window, coords.x, coords.y, ev->multi.device);
mouse_pressed = TRUE;
processed = TRUE;
pressed_window = window;
#endif
SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
- controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
+ controller_mouse->mouse_press(window, coords.x, coords.y, ev->multi.device);
mouse_pressed = TRUE;
processed = TRUE;
}
return TRUE;
/*CSCLContext *context = CSCLContext::get_instance();
- controller->mouse_press((sclwindow)data, ev->output.x, ev->output.y);
+ controller_mouse->mouse_press((sclwindow)data, ev->output.x, ev->output.y);
mouse_pressed = TRUE;*/
//LOGD("=-=-=-=- mouse_press : %p %d %d\n", data, ev->output.x, ev->output.y);
{
SCL_DEBUG();
- CSCLController *controller = CSCLController::get_instance();
+ CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
CSCLWindows *windows = CSCLWindows::get_instance();
CSCLContext *context = CSCLContext::get_instance();
return TRUE;
}
- if (controller && windows && context && ev) {
+ if (controller_mouse && windows && context && ev) {
LOGD("mouse_release : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y);
sclbyte index = 0;
}
}
if (dimwinevent) {
- controller->mouse_press(windows->get_dim_window(), ev->root.x, ev->root.y, ev->multi.device);
+ controller_mouse->mouse_press(windows->get_dim_window(), ev->root.x, ev->root.y, ev->multi.device);
} else {
do {
window = windows->get_nth_window_in_Z_order_list(index);
/* Now convert the global coordinate to appropriate local coordinate */
SclPoint coords = get_rotated_local_coords(
root_x, root_y, context->get_rotation(), &rect);
- controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
+ controller_mouse->mouse_release(window, coords.x, coords.y, ev->multi.device);
processed = TRUE;
}
}
#endif
SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
- controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
+ controller_mouse->mouse_release(window, coords.x, coords.y, ev->multi.device);
processed = TRUE;
}
}
}
return TRUE;
- //CSCLController *controller = CSCLController::get_instance();
+ //CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
//CSCLWindows *windows = CSCLWindows::get_instance();
- //controller->mouse_release((sclwindow)data, (int)ev->output.x, (int)ev->output.y);
- //controller->mouse_release((sclwindow)data, (int)ev->x, (int)ev->y);
+ //controller_mouse->mouse_release((sclwindow)data, (int)ev->output.x, (int)ev->output.y);
+ //controller_mouse->mouse_release((sclwindow)data, (int)ev->x, (int)ev->y);
}
#ifdef HANDLE_KEY_EVENTS
static Eina_Bool key_pressed(void *data, int type, void *event_info)
{
LOGD("=-=-=-=- key_pressed \n");
- CSCLController *controller = CSCLController::get_instance();
+ CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
Ecore_Event_Key *ev = (Ecore_Event_Key *)event_info;
const char *ckey_val = ev->key;
LOGD("=-=-=-=- ev->key(char) = %c \n", ev->key);
button_context = cache->get_cur_button_context(window, current_key_index);
coordinate = cache->get_cur_layout_key_coordinate(window, current_key_index);
button_context->state = BUTTON_STATE_NORMAL;
- controller->mouse_press(window, coordinate->x, coordinate->y, TRUE);
- controller->mouse_release(window, coordinate->x, coordinate->y, TRUE);
+ controller_mouse->mouse_press(window, coordinate->x, coordinate->y, TRUE);
+ controller_mouse->mouse_release(window, coordinate->x, coordinate->y, TRUE);
if (KEY_TYPE_MODECHANGE != coordinate->key_type) {
button_context->state = BUTTON_STATE_PRESSED;
windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
{
SCL_DEBUG();
- CSCLController *controller = CSCLController::get_instance();
+ CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
CSCLWindows *windows = CSCLWindows::get_instance();
CSCLContext *context = CSCLContext::get_instance();
CSCLResourceCache *cache = CSCLResourceCache::get_instance();
return TRUE;
}
- if (controller && windows && context && cache && ev) {
+ if (controller_mouse && windows && context && cache && ev) {
sclbyte index = 0;
sclboolean processed = FALSE;
sclwindow window = SCLWINDOW_INVALID;
SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
- controller->mouse_move(context->get_cur_pressed_window(ev->multi.device), coords.x, coords.y, ev->multi.device);
+ controller_mouse->mouse_move(context->get_cur_pressed_window(ev->multi.device), coords.x, coords.y, ev->multi.device);
processed = TRUE;
} else {
do {
/* Now convert the global coordinate to appropriate local coordinate */
SclPoint coords = get_rotated_local_coords(
root_x, root_y, context->get_rotation(), &rect);
- controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
+ controller_mouse->mouse_move(window, coords.x, coords.y, ev->multi.device);
processed = TRUE;
}
}
#endif
SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
- controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
+ controller_mouse->mouse_move(window, coords.x, coords.y, ev->multi.device);
processed = TRUE;
}
}
}
- //CSCLController *controller = CSCLController::get_instance();
+ //CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
//CSCLWindows *windows = CSCLWindows::get_instance();
- //controller->mouse_move((sclwindow)data, (int)ev->cur.output.x, (int)ev->cur.output.y);
- //controller->mouse_move((sclwindow)data, (int)ev->x, (int)ev->y);
+ //controller_mouse->mouse_move((sclwindow)data, (int)ev->cur.output.x, (int)ev->cur.output.y);
+ //controller_mouse->mouse_move((sclwindow)data, (int)ev->x, (int)ev->y);
return TRUE;
}
/**
* Registers a event callback func to given window.
- * In this function, it should call several event functions of CSCLController class whenever an event has occurred
+ * In this function, it should call several event functions of CSCLControllerMouse class whenever an event has occurred
* The below list shows what event function should be called.
* - mouse_press (when the user presses mouse button)
* - mouse_release (when the user releases mouse button)
Ecore_X_Event_Client_Message *ev = (Ecore_X_Event_Client_Message *)event;
if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL) {
CSCLWindows *windows = CSCLWindows::get_instance();
- CSCLController *controller = CSCLController::get_instance();
+ CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
static int last_pos_x = -10000;
static int last_pos_y = -10000;
- if (windows && controller) {
+ if (windows && controller_mouse) {
Evas_Object *base_win = (Evas_Object *)windows->get_base_window();
if (base_win == NULL) return FALSE;
if ((unsigned int)ev->data.l[0] == elm_win_xwindow_get(base_win)) {
if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE) {
// 1 finger double tap
- controller->mouse_press(base_win, last_pos_x, last_pos_y);
- controller->mouse_release(base_win, last_pos_x, last_pos_y);
+ controller_mouse->mouse_press(base_win, last_pos_x, last_pos_y);
+ controller_mouse->mouse_release(base_win, last_pos_x, last_pos_y);
} else if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ) {
// 1 finger tap
// 1 finger touch & move
last_pos_x = ev->data.l[2];
last_pos_y = ev->data.l[3];
- controller->mouse_over(base_win, last_pos_x, last_pos_y);
+ controller_mouse->mouse_over(base_win, last_pos_x, last_pos_y);
}
}
}
#include "scldebug.h"
#include "sclwindows.h"
-#include "sclcontroller.h"
+#include "sclcontroller_mouse.h"
#include "sclresourcecache.h"
#include "sclkeyfocushandler.h"
#include <dlog.h>
const char *keyname = key;
LOGD("=-=-=-=- key_pressed \n");
- CSCLController *controller = CSCLController::get_instance();
+ CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
LOGD("=-=-=-=- keyname(char) = %s \n", keyname);
CSCLResourceCache *cache = CSCLResourceCache::get_instance();
CSCLWindows *windows = CSCLWindows::get_instance();
CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
- if (!windows || !focus_handler || !cache || !controller) return FALSE;
+ if (!windows || !focus_handler || !cache || !controller_mouse) return FALSE;
sclwindow current_focus_window = focus_handler->get_current_focus_window();
scl8 current_key_index = focus_handler->get_current_focus_key();
if (cache)
coordinate = cache->get_cur_layout_key_coordinate(current_focus_window, current_key_index);
//button_context->state = BUTTON_STATE_NORMAL;
- if (coordinate && controller) {
- controller->mouse_press(current_focus_window, coordinate->x, coordinate->y, TRUE);
- controller->mouse_release(current_focus_window, coordinate->x, coordinate->y, TRUE);
+ if (coordinate && controller_mouse) {
+ controller_mouse->mouse_press(current_focus_window, coordinate->x, coordinate->y, TRUE);
+ controller_mouse->mouse_release(current_focus_window, coordinate->x, coordinate->y, TRUE);
if (KEY_TYPE_MODECHANGE != coordinate->key_type) {
//button_context->state = BUTTON_STATE_PRESSED;
//windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
#include "sclevents.h"
#include "sclresourcecache.h"
#include "sclcontroller.h"
+#include "sclcontroller_mouse.h"
#include "sclactionstate.h"
#include "sclres_manager.h"
#include "sclkeyfocushandler.h"
cur_layout->mouse_manipulate_x;
sclint y = popup_coordinate->y + (popup_coordinate->height / 2) -
cur_layout->mouse_manipulate_y;
- controller->mouse_press(window, x, y, context->get_last_touch_device_id());
+ CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
+ controller_mouse->mouse_press(window, x, y, context->get_last_touch_device_id());
}
}