Implemented animation for highlight ui 02/22502/1
authorJi-hoon Lee <dalton.lee@samsung.com>
Thu, 27 Feb 2014 11:17:26 +0000 (20:17 +0900)
committershoum.chen@samsung.com <shoum.chen@samsung.com>
Wed, 4 Jun 2014 22:00:18 +0000 (18:00 -0400)
Change-Id: I38d31c0ee4893bac5b57577508dc4fe78030fa20

14 files changed:
CMakeLists.txt
scl/include/sclanimator.h [new file with mode: 0644]
scl/include/sclconfig.h
scl/include/sclcontext.h
scl/include/sclevents.h
scl/include/sclui.h
scl/include/scluiimpl.h
scl/sclanimator.cpp [new file with mode: 0644]
scl/sclcontext.cpp
scl/sclcontroller.cpp
scl/sclkeyfocushandler.cpp
scl/sclui.cpp
scl/scluibuilder.cpp
scl/scluiimpl.cpp

index 88758f9..2c6989a 100644 (file)
@@ -40,6 +40,7 @@ SET(SRCS
     scl/gwes/win32/sclgraphics-win32.cpp
     scl/gwes/efl/sclwindows-efl.cpp
     scl/gwes/efl/sclgraphics-efl.cpp
+    scl/gwes/efl/sclanimator-efl.cpp
     scl/gwes/efl/sclevents-efl.cpp
     scl/gwes/win32/sclevents-win32.cpp
     scl/sclfeedback.cpp
@@ -56,6 +57,7 @@ SET(SRCS
     scl/sclactionstate.cpp
     scl/sclresourcecache.cpp
     scl/sclkeyfocushandler.cpp
+    scl/sclanimator.cpp
     res/sclresource.cpp
     res/simple_debug.cpp
 )
diff --git a/scl/include/sclanimator.h b/scl/include/sclanimator.h
new file mode 100644 (file)
index 0000000..33bec13
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "scltypes.h"
+#include "sclconfig.h"
+#include "sclstructs.h"
+
+#include <map>
+
+#ifndef __SCL_ANIMATOR_H__
+#define __SCL_ANIMATOR_H__
+
+#ifdef __cplusplus
+//SCL_BEGIN_DECLS
+#endif
+
+namespace scl
+{
+
+/* Currently this SCL Animation class is not designed for specific animtions, not for general use.
+   Should refine later to provide general animation behavior */
+typedef enum {
+    ANIMATION_TYPE_NONE,
+    ANIMATION_TYPE_HIGHLIGHT_UI,
+
+    ANIMATION_TYPE_MAX
+}SCLAnimationType;
+
+typedef struct {
+    SCLAnimationType type;
+    sclint length;
+
+    sclwindow window_from;
+    sclwindow window_to;
+
+    SclRectangle rect_from;
+    SclRectangle rect_to;
+}SclAnimationDesc;
+
+typedef struct {
+    sclboolean active;
+
+    SclAnimationDesc desc;
+    sclint step;
+
+    SclRectangle rect_cur;
+}SclAnimationState;
+
+
+class CSCLAnimatorImpl
+{
+    virtual void init() = 0;
+    virtual void fini() = 0;
+
+    /* By default, animation is not supported */
+    virtual sclboolean check_animation_supported() { return FALSE; }
+    virtual void animator_timer(SclAnimationState *state) = 0;
+
+    friend class CSCLAnimator;
+private:
+
+};
+
+class CSCLAnimator
+{
+private:
+    CSCLAnimator();
+public :
+    ~CSCLAnimator();
+
+    static CSCLAnimator* get_instance();
+
+    void init();
+    void fini();
+
+    /* Some backends may not provide animation feature */
+    sclboolean check_animation_supported();
+
+    sclint create_animator(SclAnimationDesc *desc);
+    sclboolean destroy_animator(sclint id);
+
+    sclint find_animator_by_type(SCLAnimationType type);
+
+    SclAnimationState* get_animation_state(sclint id);
+
+    sclboolean start_animator(sclint id);
+    sclboolean stop_animator(sclint id);
+
+    sclboolean animator_timer();
+
+protected :
+    CSCLAnimatorImpl* get_scl_animator_impl();
+
+private :
+    CSCLAnimatorImpl* m_impl;
+
+    std::map<sclint, SclAnimationState> m_animators;
+};
+
+
+} /* End of scl namespace */
+
+#ifdef __cplusplus
+//SCL_END_DECLS
+#endif
+
+#endif //__SCL_ANIMATOR_H__
index a3f08a2..9460fa7 100644 (file)
@@ -277,6 +277,7 @@ typedef enum _SCLTimer {
     SCL_TIMER_USERAREA,
     SCL_TIMER_BUTTON_DELAY,
     SCL_TIMER_POPUP_TIMEOUT,
+    SCL_TIMER_ANIMATION,
     SCL_TIMER_AUTOTEST,
 }SCLTimer;
 
@@ -442,6 +443,9 @@ typedef enum _SCLParserType {
 /* FIXME : This should be configurable also */
 #define SCL_HIGHLIGHT_UI_IMAGE "B09_icon_cue.png"
 
+#define SCL_ANIMATION_TIMER_INTERVAL (1000 / 30) // 30 frames per second
+#define SCL_ANIMATION_TIME 300 // Animation for 1 second
+
 typedef enum _SCLDebugMode {
     DEBUGMODE_DISABLED,
     DEBUGMODE_DISPLAY_INTERNAL,
index 498fdeb..2ddec47 100644 (file)
@@ -168,6 +168,18 @@ public:
     sclboolean get_shift_multi_touch_enabled() {
         return m_shift_multi_touch_enabled;
     }
+    void set_highlight_ui_enabled(sclboolean enabled) {
+        m_highlight_ui_enabled = enabled;
+    }
+    sclboolean get_highlight_ui_enabled() {
+        return m_highlight_ui_enabled;
+    }
+    void set_highlight_ui_animation_enabled(sclboolean enabled) {
+        m_highlight_ui_animation_enabled = enabled;
+    }
+    sclboolean get_highlight_ui_animation_enabled() {
+        return m_highlight_ui_animation_enabled;
+    }
 
     scl8 get_last_pressed_key() {
         return m_last_pressed_key;
@@ -282,6 +294,8 @@ protected:
     sclboolean m_sounce_enabled;
     sclboolean m_vibration_enabled;
     sclboolean m_shift_multi_touch_enabled;
+    sclboolean m_highlight_ui_enabled;
+    sclboolean m_highlight_ui_animation_enabled;
 
     sclwindow m_last_pressed_window;
     scl8 m_last_pressed_key;
index e742203..82e0b6b 100644 (file)
@@ -80,6 +80,7 @@ public :
     void connect_window_events(sclwindow wnd, const sclint evt);
 
     void create_timer(const scl16 id, const scl32 interval, scl16 value, sclboolean addToMap = TRUE) {
+        get_scl_events_impl()->destroy_timer(id);
         get_scl_events_impl()->create_timer(id, interval, value, addToMap);
     }
 
index 9acad65..fe325fe 100644 (file)
@@ -349,6 +349,18 @@ public:
     void enable_shift_multi_touch(sclboolean enabled);
 
     /**
+     * @brief This API requests SCL library to enable/disable highlight ui
+     * @param[in] enabled indicates whether to show highlight ui
+     */
+    void enable_highlight_ui(sclboolean enabled);
+
+    /**
+     * @brief This API requests SCL library to enable/disable animation effect for highlight ui
+     * @param[in] enabled indicates whether to display animation effect when moving highlight ui
+     */
+    void enable_highlight_ui_animation(sclboolean enabled);
+
+    /**
      * @brief This API requests SCL library to apply the touch offset adjustment
      * @param[in] enabled indicates whether the touch offset adjustment should applied or not
      */
index 72e77ce..74c91a3 100644 (file)
@@ -107,6 +107,8 @@ public:
     void enable_vibration(sclboolean enabled);
     void enable_tts(sclboolean enabled);
     void enable_shift_multi_touch(sclboolean enabled);
+    void enable_highlight_ui(sclboolean enabled);
+    void enable_highlight_ui_animation(sclboolean enabled);
 
     void enable_touch_offset(sclboolean enabled);
     void disable_input_events(sclboolean disabled);
diff --git a/scl/sclanimator.cpp b/scl/sclanimator.cpp
new file mode 100644 (file)
index 0000000..9f1d3e2
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sclanimator.h"
+#ifdef  __WIN32__
+#include "sclanimator-win32.h"
+#elif defined(__EFL__)
+#include "sclanimator-efl.h"
+#elif __GTK__
+#include "sclanimator-gtk.h"
+#else
+#include "sclanimator-cairo.h"
+#endif
+#include "scldebug.h"
+
+#include "sclevents.h"
+#include "sclwindows.h"
+
+using namespace scl;
+
+CSCLAnimator::CSCLAnimator()
+{
+    SCL_DEBUG();
+    m_impl = NULL;
+}
+
+CSCLAnimator::~CSCLAnimator()
+{
+    SCL_DEBUG();
+
+    if (m_impl) {
+        delete m_impl;
+        m_impl = NULL;
+    }
+}
+
+void CSCLAnimator::init()
+{
+    CSCLAnimatorImpl *impl = get_scl_animator_impl();
+    if (impl) {
+        impl->init();
+    }
+}
+
+void CSCLAnimator::fini()
+{
+    CSCLAnimatorImpl *impl = get_scl_animator_impl();
+    if (impl) {
+        impl->fini();
+    }
+}
+
+sclboolean CSCLAnimator::check_animation_supported()
+{
+    sclboolean ret = FALSE;
+
+    CSCLAnimatorImpl *impl = get_scl_animator_impl();
+    if (impl) {
+        ret = impl->check_animation_supported();
+    }
+    return ret;
+}
+
+CSCLAnimatorImpl* CSCLAnimator::get_scl_animator_impl()
+{
+    SCL_DEBUG();
+    if (m_impl == 0) {
+#ifdef  __WIN32__
+        m_impl = new CSCLAnimatorImplWin32;
+#elif defined(__EFL__)
+        m_impl = new CSCLAnimatorImplEfl;
+#elif __GTK__
+        m_impl = new CSCLAnimatorImplGtk;
+#else
+        m_impl = new CSCLAnimatorImplCairo;
+#endif
+    }
+    return m_impl;
+}
+
+CSCLAnimator* CSCLAnimator::get_instance()
+{
+    static CSCLAnimator instance;
+    return &instance;
+}
+
+sclint
+CSCLAnimator::create_animator(SclAnimationDesc *desc)
+{
+    static sclint animator_id = 0;
+
+    if (desc) {
+        animator_id++;
+        /* Just in case for overflow */
+        if (animator_id < 0) animator_id = 0;
+
+        SclAnimationState state;
+        state.active = FALSE;
+        state.rect_cur = desc->rect_from;
+        state.step = 0;
+
+        state.desc = *desc;
+
+        destroy_animator(animator_id);
+        m_animators[animator_id] = state;
+    } else {
+        return NOT_USED;
+    }
+
+    return animator_id;
+}
+
+sclboolean
+CSCLAnimator::destroy_animator(sclint id)
+{
+    sclboolean ret = TRUE;
+
+    std::map<sclint, SclAnimationState>::iterator iter = m_animators.find(id);
+    if (iter != m_animators.end()) {
+        SclAnimationState *state = &(iter->second);
+        state->active = FALSE;
+        m_animators.erase(iter->first);
+    } else {
+        ret = FALSE;
+    }
+
+    sclboolean destroy_timer = TRUE;
+    for(std::map<sclint, SclAnimationState>::iterator iter = m_animators.begin();
+        iter != m_animators.end();std::advance(iter, 1)) {
+            if (iter != m_animators.end()) {
+                SclAnimationState *state = &(iter->second);
+                if (state->active) {
+                    destroy_timer = FALSE;
+                }
+            }
+    }
+
+    if (destroy_timer) {
+        CSCLEvents *events = CSCLEvents::get_instance();
+        if (events) {
+            events->destroy_timer(SCL_TIMER_ANIMATION);
+        }
+    }
+
+    return ret;
+}
+
+sclint
+CSCLAnimator::find_animator_by_type(SCLAnimationType type)
+{
+    sclint ret = NOT_USED;
+
+    for(std::map<sclint, SclAnimationState>::iterator iter = m_animators.begin();
+        iter != m_animators.end();std::advance(iter, 1)) {
+            if (iter != m_animators.end()) {
+                SclAnimationState *state = &(iter->second);
+                if (state->desc.type == type) {
+                    ret = iter->first;
+                }
+            }
+    }
+
+    return ret;
+}
+
+
+SclAnimationState*
+CSCLAnimator::get_animation_state(sclint id)
+{
+    SclAnimationState *ret = NULL;
+
+    std::map<sclint, SclAnimationState>::iterator iter = m_animators.find(id);
+    if (iter != m_animators.end()) {
+        ret = &(iter->second);
+    } else {
+        ret = NULL;
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLAnimator::start_animator(sclint id)
+{
+    sclboolean ret = TRUE;
+
+    std::map<sclint, SclAnimationState>::iterator iter = m_animators.find(id);
+    if (iter != m_animators.end()) {
+        SclAnimationState *state = &(iter->second);
+        state->active = TRUE;
+    } else {
+        ret = FALSE;
+    }
+
+    /*
+    sclboolean start_timer = TRUE;
+    for(std::map<sclint, SclAnimationState>::iterator iter = m_animators.begin();
+        iter != m_animators.end();std::advance(iter, 1)) {
+            if (iter != m_animators.end()) {
+                SclAnimationState *state = &(iter->second);
+                if (state->active) {
+                    start_timer = FALSE;
+                }
+            }
+    }
+
+    if (start_timer) {
+        CSCLEvents *events = CSCLEvents::get_instance();
+        if (events) {
+            events->create_timer(SCL_TIMER_ANIMATION, SCL_ANIMATION_TIMER_INTERVAL, 0);
+        }
+    }
+    */
+    CSCLEvents *events = CSCLEvents::get_instance();
+    if (events) {
+        events->destroy_timer(SCL_TIMER_ANIMATION);
+        events->create_timer(SCL_TIMER_ANIMATION, SCL_ANIMATION_TIMER_INTERVAL, 0);
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLAnimator::stop_animator(sclint id)
+{
+    sclboolean ret = TRUE;
+
+    std::map<sclint, SclAnimationState>::iterator iter = m_animators.find(id);
+    if (iter != m_animators.end()) {
+        SclAnimationState *state = &(iter->second);
+        state->active = FALSE;
+        m_animators.erase(iter->first);
+    } else {
+        ret = FALSE;
+    }
+
+    sclboolean destroy_timer = TRUE;
+    for(std::map<sclint, SclAnimationState>::iterator iter = m_animators.begin();
+        iter != m_animators.end();std::advance(iter, 1)) {
+            if (iter != m_animators.end()) {
+                SclAnimationState *state = &(iter->second);
+                if (state->active) {
+                    destroy_timer = FALSE;
+                }
+            }
+    }
+
+    if (destroy_timer) {
+        CSCLEvents *events = CSCLEvents::get_instance();
+        if (events) {
+            events->destroy_timer(SCL_TIMER_ANIMATION);
+        }
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLAnimator::animator_timer()
+{
+    sclboolean destroy_timer = TRUE;
+    SclAnimationState* cur = NULL;
+    for(std::map<sclint, SclAnimationState>::iterator iter = m_animators.begin();
+        iter != m_animators.end();std::advance(iter, 1)) {
+            if (iter != m_animators.end()) {
+                CSCLWindows *windows = CSCLWindows::get_instance();
+                SclAnimationState *state = &(iter->second);
+                if (state && state->active && windows) {
+                    state->step++;
+                    if (SCL_ANIMATION_TIMER_INTERVAL * state->step >= state->desc.length) {
+                        state->active = FALSE;
+                    } else {
+                        SclRectangle rect_from = state->desc.rect_from;
+                        SclRectangle rect_to = state->desc.rect_to;
+
+                        /* Convert popup window coordinates relative to base window */
+                        if (!(windows->is_base_window(state->desc.window_from))) {
+                            SclWindowContext *base_winctx = windows->get_window_context(windows->get_base_window());
+                            SclWindowContext *prev_winctx = windows->get_window_context(state->desc.window_from);
+                            if (base_winctx && prev_winctx) {
+                                rect_from.x += (prev_winctx->geometry.x - base_winctx->geometry.x);
+                                rect_from.y += (prev_winctx->geometry.y - base_winctx->geometry.y);
+                            }
+                        }
+                        if (!(windows->is_base_window(state->desc.window_to))) {
+                            SclWindowContext *base_winctx = windows->get_window_context(windows->get_base_window());
+                            SclWindowContext *next_winctx = windows->get_window_context(state->desc.window_to);
+                            if (base_winctx && next_winctx) {
+                                rect_to.x += (next_winctx->geometry.x - base_winctx->geometry.x);
+                                rect_to.y += (next_winctx->geometry.y - base_winctx->geometry.y);
+                            }
+                        }
+
+                        sclint delta_x = rect_to.x - rect_from.x;
+                        sclint delta_y = rect_to.y - rect_from.y;
+                        sclint delta_width = rect_to.width - rect_from.width;
+                        sclint delta_height = rect_to.height - rect_from.height;
+                        state->rect_cur.x = rect_from.x +
+                            ((delta_x) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
+                        state->rect_cur.y = rect_from.y +
+                            ((delta_y) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
+                        state->rect_cur.width = rect_from.width +
+                            ((delta_width) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
+                        state->rect_cur.height = rect_from.height +
+                            ((delta_height) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
+                    }
+
+                    CSCLAnimatorImpl *impl = get_scl_animator_impl();
+                    if (impl) {
+                        impl->animator_timer(state);
+                    }
+
+                    if (state->active == FALSE) {
+                        CSCLWindows *windows = CSCLWindows::get_instance();
+                        if (windows) {
+                            windows->update_window(state->desc.window_to,
+                                state->desc.rect_to.x, state->desc.rect_to.y,
+                                state->desc.rect_to.width, state->desc.rect_to.height);
+                        }
+                    } else {
+                        destroy_timer = FALSE;
+                    }
+                }
+            }
+    }
+    return !(destroy_timer);
+}
+
index 8b8a0ef..3c1fda5 100644 (file)
@@ -68,6 +68,8 @@ CSCLContext::reset()
     m_sounce_enabled = TRUE;
     m_vibration_enabled = TRUE;
     m_shift_multi_touch_enabled = TRUE;
+    m_highlight_ui_enabled = FALSE;
+    m_highlight_ui_animation_enabled = FALSE;
 
     m_tts_enabled = FALSE;
 
index 77e9762..7e97a4b 100644 (file)
@@ -31,6 +31,7 @@
 #include "sclimageproxy.h"
 #include "sclres_manager.h"
 #include "scleventhandler.h"
+#include "sclanimator.h"
 
 //#define DIRECTLY_DRAW_ON_EVENTS
 
@@ -3511,6 +3512,13 @@ CSCLController::timer_event(const scl32 data)
         return FALSE;
     }
     break;
+    case SCL_TIMER_ANIMATION: {
+        CSCLAnimator *animator = CSCLAnimator::get_instance();
+        if (animator) {
+            return animator->animator_timer();
+        }
+        return TRUE;
+    }
 
     default: {
         events->destroy_timer(id);
index 81ca5d2..392c48f 100644 (file)
@@ -27,6 +27,7 @@
 #include "sclwindows.h"
 #include "scleventhandler.h"
 #include "sclres_manager.h"
+#include "sclanimator.h"
 
 using namespace scl;
 
@@ -391,6 +392,16 @@ CSCLKeyFocusHandler::get_next_candidate_key(SCLHighlightNavigationDirection dire
     return ret;
 }
 
+static void copy_rectangle(SclLayoutKeyCoordinatePointer src, SclRectangle *dest)
+{
+    if (src && dest) {
+        (dest)->x = (src)->x;
+        (dest)->y = (src)->y;
+        (dest)->width = (src)->width;
+        (dest)->height = (src)->height;
+    }
+}
+
 void
 CSCLKeyFocusHandler::process_navigation(SCLHighlightNavigationDirection direction)
 {
@@ -417,7 +428,7 @@ CSCLKeyFocusHandler::process_navigation(SCLHighlightNavigationDirection directio
         }
     }
 
-    if (sclres_layout_key_coordinate_pointer_frame &&
+    if (sclres_layout_key_coordinate_pointer_frame && context->get_highlight_ui_enabled() &&
         scl_check_arrindex(layout, MAX_SCL_LAYOUT) && scl_check_arrindex(m_focus_key, MAX_KEY)) {
         SclLayoutKeyCoordinatePointer cur = sclres_layout_key_coordinate_pointer_frame[layout][m_focus_key];
 
@@ -578,17 +589,90 @@ CSCLKeyFocusHandler::process_navigation(SCLHighlightNavigationDirection directio
                 }
             }
         }
-    }
 
-    SclNotiHighlighNavigateDesc desc;
-    desc.direction = direction;
-    desc.window_from = prev_window;
-    desc.key_from = prev_key;
-    desc.window_to = next_window;
-    desc.key_to = next_key;
-    if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_HIGHLIGHT_NAVIGATE, &desc)) {
-        m_focus_window = desc.window_to;
-        m_focus_key = desc.key_to;
+        SclNotiHighlighNavigateDesc desc;
+        desc.direction = direction;
+        desc.window_from = prev_window;
+        desc.key_from = prev_key;
+        desc.window_to = next_window;
+        desc.key_to = next_key;
+        if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_HIGHLIGHT_NAVIGATE, &desc)) {
+            CSCLAnimator *animator = CSCLAnimator::get_instance();
+            if (animator) {
+                sclboolean start_animation = FALSE;
+                if (windows->is_base_window(desc.window_to) && windows->is_base_window(desc.window_from)) {
+                    if(desc.key_to != desc.key_from) {
+                        start_animation = TRUE;
+                    }
+                } else {
+                    SclWindowContext *winctx_from = windows->get_window_context(desc.window_from);
+                    SclWindowContext *winctx_to = windows->get_window_context(desc.window_to);
+                    if (winctx_from && winctx_to) {
+                        if ((windows->is_base_window(desc.window_from) || winctx_from->is_virtual) &&
+                            (windows->is_base_window(desc.window_to) || winctx_to->is_virtual)) {
+                                start_animation = TRUE;
+                        }
+                    }
+                }
+                if (start_animation &&
+                    context->get_highlight_ui_enabled() &&
+                    context->get_highlight_ui_animation_enabled() &&
+                    animator->check_animation_supported()) {
+                        sclshort layout_from = NOT_USED;
+                        sclshort layout_to = NOT_USED;
+                        if (windows->is_base_window(desc.window_from)) {
+                            layout_from = context->get_base_layout();
+                        } else {
+                            layout_from = context->get_popup_layout(desc.window_from);
+                        }
+                        if (windows->is_base_window(desc.window_to)) {
+                            layout_to = context->get_base_layout();
+                        } else {
+                            layout_to = context->get_popup_layout(desc.window_to);
+                        }
+
+                        SclLayoutKeyCoordinatePointer prev_coordinate =
+                            sclres_layout_key_coordinate_pointer_frame[layout_from][desc.key_from];
+                        SclLayoutKeyCoordinatePointer next_coordinate =
+                            sclres_layout_key_coordinate_pointer_frame[layout_to][desc.key_to];
+
+                        sclint id = animator->find_animator_by_type(ANIMATION_TYPE_HIGHLIGHT_UI);
+                        if (id == NOT_USED) {
+                            SclAnimationDesc animdesc;
+                            animdesc.type = ANIMATION_TYPE_HIGHLIGHT_UI;
+                            animdesc.length = SCL_ANIMATION_TIME;
+
+                            copy_rectangle( prev_coordinate, &(animdesc.rect_from) );
+                            copy_rectangle( next_coordinate, &(animdesc.rect_to) );
+
+                            animdesc.window_from = desc.window_from;
+                            animdesc.window_to = desc.window_to;
+
+                            id = animator->create_animator(&animdesc);
+                            animator->start_animator(id);
+                        } else {
+                            SclAnimationState *state = animator->get_animation_state(id);
+                            if (state) {
+                                if (state->active) {
+                                    state->desc.rect_from = state->rect_cur;
+                                } else {
+                                    state->active = TRUE;
+                                    copy_rectangle( prev_coordinate, &(state->desc.rect_from) );
+                                }
+                                state->step = 0;
+
+                                copy_rectangle( next_coordinate, &(state->desc.rect_to) );
+
+                                state->desc.window_from = desc.window_from;
+                                state->desc.window_to = desc.window_to;
+                            }
+                            animator->start_animator(id);
+                        }
+                }
+            }
+            m_focus_window = desc.window_to;
+            m_focus_key = desc.key_to;
+        }
     }
 }
 
index 526adde..7cdfe8c 100644 (file)
@@ -537,6 +537,22 @@ CSCLUI::enable_shift_multi_touch(sclboolean enabled)
 }
 
 void
+CSCLUI::enable_highlight_ui(sclboolean enabled)
+{
+    if (m_impl) {
+        m_impl->enable_highlight_ui(enabled);
+    }
+}
+
+void
+CSCLUI::enable_highlight_ui_animation(sclboolean enabled)
+{
+    if (m_impl) {
+        m_impl->enable_highlight_ui_animation(enabled);
+    }
+}
+
+void
 CSCLUI::enable_touch_offset(sclboolean enabled)
 {
     if (m_impl) {
index 27125d9..632f926 100644 (file)
@@ -26,6 +26,7 @@
 #include "sclimageproxy.h"
 #include "sclactionstate.h"
 #include "sclkeyfocushandler.h"
+#include "sclanimator.h"
 
 //#include "sclresource.h"
 #include <assert.h>
@@ -260,8 +261,21 @@ CSCLUIBuilder::show_layout(const sclwindow window, const scl16 x, const scl16 y,
                         }
                     }
 
-                    // if (highlight_animation_enabled)
-                    // else {
+                    sclboolean draw_highlight_ui = TRUE;
+                    SclAnimationState *state = NULL;
+                    CSCLAnimator *animator = CSCLAnimator::get_instance();
+                    if (animator) {
+                        sclint id = animator->find_animator_by_type(ANIMATION_TYPE_HIGHLIGHT_UI);
+                        state = animator->get_animation_state(id);
+                    }
+                    if (state) {
+                        // If currently the highlight UI is being animated, don't draw it here
+                        if (state->active) {
+                            draw_highlight_ui = FALSE;
+                        }
+                    }
+
+                    if (draw_highlight_ui && context->get_highlight_ui_enabled()) {
                         sclchar composed_path[_POSIX_PATH_MAX] = {0,};
                         const SclLayoutKeyCoordinate *coordinate = NULL;
                         scl8 current_key_index = focus_handler->get_current_focus_key();
@@ -273,7 +287,7 @@ CSCLUIBuilder::show_layout(const sclwindow window, const scl16 x, const scl16 y,
                             graphics->draw_image(window, draw_ctx, composed_path, NULL,
                                 startx + coordinate->x, starty + coordinate->y, coordinate->width, coordinate->height);
                         }
-                    //}
+                    }
                 }
             }
         }
index 2621e66..7e242f3 100644 (file)
@@ -27,6 +27,7 @@
 #include "sclres_manager.h"
 #include "scleventhandler.h"
 #include "sclkeyfocushandler.h"
+#include "sclanimator.h"
 
 using namespace scl;
 
@@ -882,6 +883,43 @@ CSCLUIImpl::enable_shift_multi_touch(sclboolean enabled)
 }
 
 void
+CSCLUIImpl::enable_highlight_ui(sclboolean enabled)
+{
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        if (context) {
+            context->set_highlight_ui_enabled(enabled);
+
+            sclwindow window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+            windows->update_window(window);
+            if (!(windows->is_base_window(window))) {
+                windows->update_window(windows->get_base_window());
+            }
+        }
+    }
+}
+
+void
+CSCLUIImpl::enable_highlight_ui_animation(sclboolean enabled)
+{
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        CSCLAnimator *animator = CSCLAnimator::get_instance();
+        if (context && animator) {
+            context->set_highlight_ui_animation_enabled(enabled);
+
+            if (!enabled) {
+                sclint id = animator->find_animator_by_type(ANIMATION_TYPE_HIGHLIGHT_UI);
+                if (id != NOT_USED) {
+                    animator->destroy_animator(id);
+                }
+            }
+        }
+    }
+}
+
+void
 CSCLUIImpl::enable_touch_offset(sclboolean enabled)
 {
     CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();