Support floating keyboard 62/136262/20
authorInHong Han <inhong1.han@samsung.com>
Mon, 26 Jun 2017 01:27:34 +0000 (10:27 +0900)
committerInHong Han <inhong1.han@samsung.com>
Tue, 8 Aug 2017 06:48:17 +0000 (15:48 +0900)
Change-Id: I42bff8858ea6b7ee311dde95e2b280704f0b76c7

src/candidate/efl/candidate-multiline-efl.cpp
src/candidate/efl/candidate-multiline-efl.h
src/candidate/include/candidate.h
src/include/ise-emoticon-mode.h
src/include/ise-floating-mode.h [new file with mode: 0644]
src/include/ise-stt-mode.h
src/include/ise.h
src/ise-emoticon-mode.cpp
src/ise-stt-mode.cpp
src/ise.cpp

index f2fd06f..9b4d304 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "candidate-multiline-efl.h"
+#include "config.h"
 #include <vector>
 #include <string>
 #include <assert.h>
@@ -44,6 +45,8 @@ using namespace std;
 #define IME_UI_RESOLUTION_H           1280
 #endif
 
+extern CONFIG_VALUES g_config_values;
+
 static void
 _mouse_down(void *data, Evas *e,
     Evas_Object *button, void *event_info)
@@ -283,13 +286,19 @@ EflMultiLineCandidate::make_more_view()
     edje_object_file_set(m_candidateMoreScrollerBg, CANDIDATE_EDJ_FILE_PATH, "scroller_bg");
     evas_object_size_hint_weight_set(m_candidateMoreScrollerBg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
     evas_object_resize(m_candidateMoreScrollerBg, m_screenWidth, m_screenHeight-CANDIDATE_WINDOW_HEIGHT*m_screenRatio);
-    evas_object_move(m_candidateMoreScrollerBg, 0, CANDIDATE_WINDOW_HEIGHT*m_screenRatio);
+    if (m_floating_mode)
+        evas_object_move(m_candidateMoreScrollerBg, 0, (CANDIDATE_WINDOW_HEIGHT*m_screenRatio)+FLOATING_TITLE_BAR_HEIGHT);
+    else
+        evas_object_move(m_candidateMoreScrollerBg, 0, CANDIDATE_WINDOW_HEIGHT*m_screenRatio);
 
     m_candidateMoreScroller = elm_scroller_add((Evas_Object*)m_window);
     elm_scroller_bounce_set(m_candidateMoreScroller, EINA_FALSE, EINA_TRUE);
     elm_scroller_policy_set(m_candidateMoreScroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
     evas_object_resize(m_candidateMoreScroller, m_screenWidth, m_screenHeight-CANDIDATE_WINDOW_HEIGHT*m_screenRatio);
-    evas_object_move(m_candidateMoreScroller, 0, CANDIDATE_WINDOW_HEIGHT*m_screenRatio);
+    if (m_floating_mode)
+        evas_object_move(m_candidateMoreScroller, 0, (CANDIDATE_WINDOW_HEIGHT*m_screenRatio)+FLOATING_TITLE_BAR_HEIGHT);
+    else
+        evas_object_move(m_candidateMoreScroller, 0, CANDIDATE_WINDOW_HEIGHT*m_screenRatio);
 
     m_candidateMoreTable = elm_table_add((Evas_Object*)m_window);
     evas_object_size_hint_weight_set(m_candidateMoreTable, 0.0, 0.0);
@@ -311,19 +320,34 @@ EflMultiLineCandidate::make_view()
     m_screenHeight = scr_h;
     double screenRatio_w = (double)scr_w/IME_UI_RESOLUTION_W;
     double screenRatio_h = (double)scr_h/IME_UI_RESOLUTION_H;
-    m_screenRatio = MAX(screenRatio_w, screenRatio_h);
+
+    read_ise_config_values();
+    m_floating_mode = g_config_values.floating_mode;
+
+    if (m_floating_mode) {
+        m_screenRatio = FLOATING_SCALE_RATE;
+        m_screenWidth *= m_screenRatio;
+    } else {
+        m_screenRatio = MAX(screenRatio_w, screenRatio_h);
+    }
 
     m_candidateScrollerBg = edje_object_add(evas_object_evas_get((Evas_Object*)m_window));
     edje_object_file_set(m_candidateScrollerBg, CANDIDATE_EDJ_FILE_PATH, "candidate_bg");
     evas_object_size_hint_weight_set(m_candidateScrollerBg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-    evas_object_resize(m_candidateScrollerBg, scr_w, CANDIDATE_WINDOW_HEIGHT*m_screenRatio);
-    evas_object_move(m_candidateScrollerBg, 0, 0);
+    evas_object_resize(m_candidateScrollerBg, m_screenWidth, CANDIDATE_WINDOW_HEIGHT*m_screenRatio);
+    if (m_floating_mode)
+        evas_object_move(m_candidateScrollerBg, 0, FLOATING_TITLE_BAR_HEIGHT);
+    else
+        evas_object_move(m_candidateScrollerBg, 0, 0);
 
     m_candidateScroller = elm_scroller_add(m_window);
     elm_scroller_bounce_set(m_candidateScroller, EINA_TRUE, EINA_FALSE);
     elm_scroller_policy_set(m_candidateScroller, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
-    evas_object_resize(m_candidateScroller, scr_w, CANDIDATE_WINDOW_HEIGHT*m_screenRatio);
-    evas_object_move(m_candidateScroller, 0, 0);
+    evas_object_resize(m_candidateScroller, m_screenWidth, CANDIDATE_WINDOW_HEIGHT*m_screenRatio);
+    if (m_floating_mode)
+        evas_object_move(m_candidateScroller, 0, FLOATING_TITLE_BAR_HEIGHT);
+    else
+        evas_object_move(m_candidateScroller, 0, 0);
 
     m_candidateTable = elm_table_add(m_window);
     evas_object_size_hint_weight_set(m_candidateTable, 0.0, 0.0);
@@ -335,8 +359,12 @@ EflMultiLineCandidate::make_view()
     edje_object_file_set(m_candidateMoreBtn, CANDIDATE_EDJ_FILE_PATH, "more_button");
     evas_object_size_hint_min_set(m_candidateMoreBtn, MORE_BUTTON_WIDTH*m_screenRatio, MORE_BUTTON_HEIGHT*m_screenRatio);
     evas_object_resize(m_candidateMoreBtn, MORE_BUTTON_WIDTH*m_screenRatio, MORE_BUTTON_HEIGHT*m_screenRatio);
-    evas_object_move(m_candidateMoreBtn, m_screenWidth-MORE_BUTTON_WIDTH*m_screenRatio,
-                     (CANDIDATE_WINDOW_HEIGHT-MORE_BUTTON_HEIGHT)*m_screenRatio/2);
+    if (m_floating_mode)
+        evas_object_move(m_candidateMoreBtn, m_screenWidth-MORE_BUTTON_WIDTH*m_screenRatio,
+                         ((CANDIDATE_WINDOW_HEIGHT-MORE_BUTTON_HEIGHT)*m_screenRatio/2) + FLOATING_TITLE_BAR_HEIGHT);
+    else
+        evas_object_move(m_candidateMoreBtn, m_screenWidth-MORE_BUTTON_WIDTH*m_screenRatio,
+                         (CANDIDATE_WINDOW_HEIGHT-MORE_BUTTON_HEIGHT)*m_screenRatio/2);
     evas_object_event_callback_add(m_candidateMoreBtn, EVAS_CALLBACK_MOUSE_DOWN,
                                    ui_candidate_window_more_button_down_cb, this);
 
@@ -344,8 +372,12 @@ EflMultiLineCandidate::make_view()
     edje_object_file_set(m_candidateCloseBtn, CANDIDATE_EDJ_FILE_PATH, "close_button");
     evas_object_size_hint_min_set(m_candidateCloseBtn, MORE_BUTTON_WIDTH*m_screenRatio, MORE_BUTTON_HEIGHT*m_screenRatio);
     evas_object_resize(m_candidateCloseBtn, MORE_BUTTON_WIDTH*m_screenRatio, MORE_BUTTON_HEIGHT*m_screenRatio);
-    evas_object_move(m_candidateCloseBtn, m_screenWidth-MORE_BUTTON_WIDTH*m_screenRatio,
-                     (CANDIDATE_WINDOW_HEIGHT-MORE_BUTTON_HEIGHT)*m_screenRatio/2);
+    if (m_floating_mode)
+        evas_object_move(m_candidateCloseBtn, m_screenWidth-MORE_BUTTON_WIDTH*m_screenRatio,
+                         ((CANDIDATE_WINDOW_HEIGHT-MORE_BUTTON_HEIGHT)*m_screenRatio/2) + FLOATING_TITLE_BAR_HEIGHT);
+    else
+        evas_object_move(m_candidateCloseBtn, m_screenWidth-MORE_BUTTON_WIDTH*m_screenRatio,
+                         (CANDIDATE_WINDOW_HEIGHT-MORE_BUTTON_HEIGHT)*m_screenRatio/2);
     evas_object_event_callback_add(m_candidateCloseBtn, EVAS_CALLBACK_MOUSE_DOWN,
                                    ui_candidate_window_close_button_down_cb, this);
 
@@ -361,6 +393,7 @@ EflMultiLineCandidate::EflMultiLineCandidate(Evas_Object *window)
     m_screenWidth = 0;
     m_screenHeight = 0;
     m_screenRatio = 1.0;
+    m_floating_mode = false;
     m_window = window;
     m_candidateScrollerBg = NULL;
     m_candidateScroller = NULL;
@@ -563,6 +596,9 @@ EflMultiLineCandidate::rotate(int degree)
             break;
     }
 
+    if (m_floating_mode)
+        m_screenWidth *= m_screenRatio;
+
 #ifdef _TV
     int temp = m_screenWidth;
     m_screenWidth = m_screenHeight;
@@ -573,10 +609,17 @@ EflMultiLineCandidate::rotate(int degree)
     evas_object_resize(m_candidateScroller, m_screenWidth, CANDIDATE_WINDOW_HEIGHT*m_screenRatio);
     evas_object_resize(m_candidateMoreScrollerBg, m_screenWidth, m_screenHeight-CANDIDATE_WINDOW_HEIGHT*m_screenRatio);
     evas_object_resize(m_candidateMoreScroller, m_screenWidth, m_screenHeight-CANDIDATE_WINDOW_HEIGHT*m_screenRatio);
-    evas_object_move(m_candidateMoreBtn, m_screenWidth-MORE_BUTTON_WIDTH*m_screenRatio,
-                     (CANDIDATE_WINDOW_HEIGHT-MORE_BUTTON_HEIGHT)*m_screenRatio/2);
-    evas_object_move(m_candidateCloseBtn, m_screenWidth-MORE_BUTTON_WIDTH*m_screenRatio,
-                     (CANDIDATE_WINDOW_HEIGHT-MORE_BUTTON_HEIGHT)*m_screenRatio/2);
+    if (m_floating_mode) {
+        evas_object_move(m_candidateMoreBtn, m_screenWidth-MORE_BUTTON_WIDTH*m_screenRatio,
+                         ((CANDIDATE_WINDOW_HEIGHT-MORE_BUTTON_HEIGHT)*m_screenRatio/2) + FLOATING_TITLE_BAR_HEIGHT);
+        evas_object_move(m_candidateCloseBtn, m_screenWidth-MORE_BUTTON_WIDTH*m_screenRatio,
+                         ((CANDIDATE_WINDOW_HEIGHT-MORE_BUTTON_HEIGHT)*m_screenRatio/2) + FLOATING_TITLE_BAR_HEIGHT);
+    } else {
+        evas_object_move(m_candidateMoreBtn, m_screenWidth-MORE_BUTTON_WIDTH*m_screenRatio,
+                         (CANDIDATE_WINDOW_HEIGHT-MORE_BUTTON_HEIGHT)*m_screenRatio/2);
+        evas_object_move(m_candidateCloseBtn, m_screenWidth-MORE_BUTTON_WIDTH*m_screenRatio,
+                         (CANDIDATE_WINDOW_HEIGHT-MORE_BUTTON_HEIGHT)*m_screenRatio/2);
+    }
 }
 
 int
@@ -584,3 +627,9 @@ EflMultiLineCandidate::get_height()
 {
     return CANDIDATE_WINDOW_HEIGHT*m_screenRatio;
 }
+
+bool
+EflMultiLineCandidate::get_floating_mode()
+{
+    return m_floating_mode;
+}
index 35ec8d1..11cff39 100644 (file)
@@ -39,6 +39,7 @@ class EflMultiLineCandidate: public Candidate
         void update(const std::vector<std::string> &candidates);
         void rotate(int degree);
         int get_height();
+        bool get_floating_mode();
         void more_btn_clicked();
         void more_btn_released();
         void close_btn_clicked();
@@ -67,6 +68,7 @@ class EflMultiLineCandidate: public Candidate
         double m_screenRatio;
         std::string m_candidateFontName;
         int m_candidateFontSize;
+        bool m_floating_mode;
         Evas_Object * m_stringWidthCalObj;
         Evas_Object * m_candidateScrollerBg;
         Evas_Object * m_candidateScroller;
index 8fb58a0..f28aca7 100644 (file)
@@ -19,6 +19,7 @@
 #define __CANDIDATE_H__
 #include <vector>
 #include <string>
+#include "ise-floating-mode.h"
 
 class EventDesc
 {
@@ -73,6 +74,7 @@ class Candidate
         virtual void rotate(int degree) { }
         virtual int get_height() { return 0; }
         virtual bool get_visible() { return m_visible; }
+        virtual bool get_floating_mode() { return false; }
         void add_event_listener(EventListener *l);
     protected:
         void notify_listeners(const EventDesc &desc);
index f9e58b5..f47cc0c 100644 (file)
@@ -18,6 +18,8 @@
 #ifndef ISE_EMOTICON_MODE_H_
 #define ISE_EMOTICON_MODE_H_
 
+#include "ise-floating-mode.h"
+
 #ifdef SUPPORTS_EMOTICONS
 
 #ifdef _WEARABLE
@@ -59,6 +61,7 @@ enum emoticon_group_t
 };
 #endif
 
+
 void ise_show_emoticon_layout(emoticon_group_t emoticon_group, const int screen_degree, const bool is_candidate_on, void *main_window);
 void ise_change_emoticon_mode(emoticon_group_t emoticon_group);
 void ise_destroy_emoticon_layout(void);
diff --git a/src/include/ise-floating-mode.h b/src/include/ise-floating-mode.h
new file mode 100644 (file)
index 0000000..e2b3e0f
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef _ISE_FLOATING_MODE_H_
+#define _ISE_FLOATING_MODE_H_
+
+#define FLOATING_SCALE_RATE 0.75
+#define FLOATING_TITLE_BAR_HEIGHT 80
+
+#endif
\ No newline at end of file
index fdf439b..3280e0f 100644 (file)
@@ -30,6 +30,7 @@
 #include "SttManager.h"
 #include "MicEffector.h"
 #include "WInputSttMicEffect.h"
+#include "ise-floating-mode.h"
 
 #ifdef EAPI
 # undef EAPI
index 9543402..52ad2fe 100644 (file)
@@ -72,6 +72,12 @@ enum ISE_LAYOUT{
     ISE_LAYOUT_STYLE_MAX
 };
 
+enum ISE_CANDIDATE_REQUEST {
+    ISE_CANDIDATE_REQ_NONE,
+    ISE_CANDIDATE_REQ_SHOW,
+    ISE_CANDIDATE_REQ_HIDE,
+};
+
 typedef struct {
     const sclchar *input_mode;
     const sclchar *sublayout_name;
index d1aba4b..0d6eac5 100644 (file)
@@ -235,7 +235,11 @@ void ise_show_emoticon_layout(emoticon_group_t emoticon_group, const int screen_
     if (g_candidate && g_candidate->get_visible())
         y = g_candidate->get_height();
 
-    evas_object_move(layout, 0, y);
+    read_ise_config_values();
+    if (g_config_values.floating_mode)
+        evas_object_move(layout, 0, y + FLOATING_TITLE_BAR_HEIGHT);
+    else
+        evas_object_move(layout, 0, y);
 
     if (is_candidate_on) {
         if (screen_degree == 0 || screen_degree == 180)
@@ -249,20 +253,36 @@ void ise_show_emoticon_layout(emoticon_group_t emoticon_group, const int screen_
         LOGD("screen width:%d, height:%d\n", width, height);
         if (screen_degree == 0 || screen_degree == 180) {
             elm_layout_file_set(layout, EMOTICON_EDJ_FILE_PATH, EMOTICON_EDJ_GROUP_PORT_CANDIDATE_OFF);
-            evas_object_resize(layout, width, g_ui->get_scaled_y(ISE_HEIGHT_PORT));
+            if (g_config_values.floating_mode)
+                evas_object_resize(layout, width * FLOATING_SCALE_RATE, g_ui->get_scaled_y(ISE_HEIGHT_PORT) * FLOATING_SCALE_RATE);
+            else
+                evas_object_resize(layout, width, g_ui->get_scaled_y(ISE_HEIGHT_PORT));
         } else {
             elm_layout_file_set(layout, EMOTICON_EDJ_FILE_PATH, EMOTICON_EDJ_GROUP_LAND_CANDIDATE_OFF);
-            evas_object_resize(layout, width, g_ui->get_scaled_y(ISE_HEIGHT_LAND));
+            if (g_config_values.floating_mode)
+                evas_object_resize(layout, width * FLOATING_SCALE_RATE, g_ui->get_scaled_y(ISE_HEIGHT_LAND) * FLOATING_SCALE_RATE);
+            else
+                evas_object_resize(layout, width, g_ui->get_scaled_y(ISE_HEIGHT_LAND));
         }
 #ifdef _WEARABLE
-        evas_object_resize(layout, 260, 240);
-        evas_object_move(layout, 10, y);
+        if (g_config_values.floating_mode) {
+            evas_object_resize(layout, 260 * FLOATING_SCALE_RATE, 240 * FLOATING_SCALE_RATE);
+            evas_object_move(layout, 10, y + FLOATING_TITLE_BAR_HEIGHT);
+        } else {
+            evas_object_resize(layout, 260, 240);
+            evas_object_move(layout, 10, y);
+        }
 #else
         if (screen_degree == 0 || screen_degree == 180) {
             ;
         } else {
-            evas_object_resize(layout, width - g_ui->get_scaled_y(88*2), g_ui->get_scaled_y(ISE_HEIGHT_LAND));
-            evas_object_move(layout, g_ui->get_scaled_y(88), y);
+            if (g_config_values.floating_mode) {
+                evas_object_resize(layout, (width - g_ui->get_scaled_y(88*2)) * FLOATING_SCALE_RATE, (g_ui->get_scaled_y(ISE_HEIGHT_LAND)) * FLOATING_SCALE_RATE);
+                evas_object_move(layout, g_ui->get_scaled_y(88), y + FLOATING_TITLE_BAR_HEIGHT);
+            } else {
+                evas_object_resize(layout, width - g_ui->get_scaled_y(88*2), g_ui->get_scaled_y(ISE_HEIGHT_LAND));
+                evas_object_move(layout, g_ui->get_scaled_y(88), y);
+            }
         }
 #endif
     }
index 7a915a1..3b2ebd0 100644 (file)
@@ -25,6 +25,8 @@
 
 #include "ise.h"
 #include "utils.h"
+#include "config.h"
+#include "candidate-factory.h"
 #include "ise-stt-mode.h"
 #include "ise-stt-option.h"
 
@@ -41,6 +43,8 @@
 VoiceData *my_voicedata = NULL;
 static Evas_Object *win_main = NULL;
 extern CSCLUI *g_ui;
+extern Candidate    *g_candidate;
+extern CONFIG_VALUES g_config_values;
 
 static void set_guide_text(VoiceData *vd, const char* text, bool translatable = false);
 
@@ -603,8 +607,14 @@ Evas_Object *create_fullview(Evas_Object *win, VoiceData *r_voicedata)
     evas_object_image_alpha_set(canvas, EINA_TRUE);
     evas_object_size_hint_align_set(canvas, EVAS_HINT_FILL, EVAS_HINT_FILL);
     evas_object_size_hint_weight_set(canvas, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-    evas_object_move(canvas, 0, 0);
 
+    int y = 0;
+    if (g_candidate && g_candidate->get_visible())
+        y = g_candidate->get_height();
+    read_ise_config_values();
+    if (g_config_values.floating_mode)
+        y += FLOATING_TITLE_BAR_HEIGHT;
+    evas_object_move(canvas, 0, y);
     elm_object_part_content_set(layout_main, "EFFECT_BG", canvas);
     elm_object_content_set(win, layout_main);
 
@@ -637,7 +647,10 @@ Evas_Object *create_fullview(Evas_Object *win, VoiceData *r_voicedata)
     SCLDisplayMode display_mode = g_ui->get_display_mode();
     if (display_mode >= 0 && display_mode < DISPLAYMODE_MAX) {
         SclSize rect = g_ui->get_input_mode_size(g_ui->get_input_mode(), display_mode);
-        evas_object_resize(layout_main, rect.width, rect.height);
+        if (g_config_values.floating_mode)
+            evas_object_resize(layout_main, rect.width * FLOATING_SCALE_RATE, rect.height * FLOATING_SCALE_RATE);
+        else
+            evas_object_resize(layout_main, rect.width, rect.height);
     }
 
     evas_object_layer_set(layout_main, 32000);
index cd4187d..73d42eb 100644 (file)
@@ -44,6 +44,7 @@
 #include "ise-language-change.h"
 #include "modeindicator.h"
 #include "w-input-smartreply.h"
+#include "ise-floating-mode.h"
 
 #define EDJ_FILE                        RESDIR"/edje/mobile/customised_ctxpopup.edj"
 
@@ -71,6 +72,7 @@ static sclboolean g_need_send_shift_event = FALSE;
 extern void set_ise_imdata(const char * buf, size_t &len);
 static void init_recent_used_punctuation();
 static void update_recent_used_punctuation(const char *key_value);
+static void set_ime_size(bool floating_mode, ISE_CANDIDATE_REQUEST candidate_req);
 static sclboolean g_punctuation_popup_opened = FALSE;
 static sclboolean g_popup_opened = FALSE;
 static vector<string> g_recent_used_punctuation;
@@ -83,6 +85,8 @@ static bool g_input_panel_show = false;
 static bool g_smartreply_reply_exist = false;
 static unsigned int g_smartreply_size = 0;
 static bool g_caps_mode_pending = false;
+static bool g_floating_mode = false;
+static bool g_candidate_more_view = false;
 #ifdef _MOBILE
 static Ecore_Timer *guideline_timer = NULL;
 #endif
@@ -140,10 +144,16 @@ class CandidateEventListener: public EventListener
                 case MultiEventDesc::CANDIDATE_MORE_VIEW_SHOW:
                     // when more parts shows, click on the candidate will
                     // not affect the key click event
+                    g_candidate_more_view = true;
+                    if (!g_input_panel_show)
+                        set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_SHOW);
                     if (g_ui)
                         g_ui->disable_input_events(TRUE);
                     break;
                 case MultiEventDesc::CANDIDATE_MORE_VIEW_HIDE:
+                    g_candidate_more_view = false;
+                    if (!g_input_panel_show)
+                        set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_SHOW);
                     if (g_ui)
                         g_ui->disable_input_events(FALSE);
                     break;
@@ -367,15 +377,9 @@ static bool ise_is_emoticons_disabled(void)
 
 static Eina_Bool softcandidate_hide_timer_callback(void *data)
 {
-    if (g_ui) {
-        g_ui->set_custom_starting_coordinates(0, 0);
-        SclSize size_portrait = g_ui->get_input_mode_size(g_ui->get_input_mode(), DISPLAYMODE_PORTRAIT);
-        SclSize size_landscape = g_ui->get_input_mode_size(g_ui->get_input_mode(), DISPLAYMODE_LANDSCAPE);
-        ime_set_size(size_portrait.width, size_portrait.height, size_landscape.width, size_landscape.height);
+    if (g_ui)
+        set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_HIDE);
 
-        LOGD("Hiding candidate , position [%d %d] size [%d %d] [%d %d]", 0, 0,
-            size_portrait.width, size_portrait.height, size_landscape.width, size_landscape.height);
-    }
     if (g_candidate) {
         g_candidate->hide();
         g_softcandidate_show = false;
@@ -648,13 +652,7 @@ SCLEventReturnType CUIEventCallback::on_event_notification(SCLUINotiType noti_ty
     } else if (noti_type == SCL_UINOTITYPE_INPUT_MODE_CHANGE) {
         SclNotiInputModeChangeDesc *desc = static_cast<SclNotiInputModeChangeDesc*>(etc_info);
         if (desc && g_ui) {
-            SclSize size_portrait = g_ui->get_input_mode_size(desc->input_mode, DISPLAYMODE_PORTRAIT);
-            SclSize size_landscape = g_ui->get_input_mode_size(desc->input_mode, DISPLAYMODE_LANDSCAPE);
-            if (g_candidate && g_candidate->get_visible()) {
-                size_portrait.height += g_candidate->get_height();
-                size_landscape.height += g_candidate->get_height();
-            }
-            ime_set_size(size_portrait.width, size_portrait.height, size_landscape.width, size_landscape.height);
+            set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_NONE);
 
             if (strcmp(g_ui->get_input_mode(), "STT_3X4") == 0 &&
                 strcmp(desc->input_mode, "STT_3X4") != 0) {
@@ -807,6 +805,13 @@ SCLEventReturnType CUIEventCallback::on_event_drag_state_changed(SclUIEventDesc
         if (event_desc.key_event == MVK_space) {
             ise_destroy_space_flick_language_change_popup();
         }
+
+        if (g_floating_mode)
+            ime_set_floating_drag_end();
+    } else if (event_desc.event_type == EVENT_TYPE_PRESS) {
+        if (g_floating_mode && event_desc.mouse_current_point.y <= FLOATING_TITLE_BAR_HEIGHT
+            && event_desc.mouse_current_point.y >= 0)
+            ime_set_floating_drag_start();
     }
     return SCL_EVENT_PASS_ON;
 }
@@ -1295,6 +1300,7 @@ ise_show(int ic)
                 /* If this layout requires specific input mode, set it */
                 if (strlen(g_ise_default_values[layout_index].input_mode) > 0) {
                     g_ui->set_input_mode(g_ise_default_values[layout_index].input_mode);
+                    set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_NONE);
                 } else {
                     if (force_primary_latin) {
                         _language_manager.select_language(PRIMARY_LATIN_LANGUAGE, TRUE);
@@ -1373,13 +1379,13 @@ ise_show(int ic)
 #endif
 
         // Update IME size
-        SclSize size_portrait = g_ui->get_input_mode_size(g_ui->get_input_mode(), DISPLAYMODE_PORTRAIT);
-        SclSize size_landscape = g_ui->get_input_mode_size(g_ui->get_input_mode(), DISPLAYMODE_LANDSCAPE);
-        if (g_candidate && g_candidate->get_visible()) {
-            size_portrait.height += g_candidate->get_height();
-            size_landscape.height += g_candidate->get_height();
-        }
-        ime_set_size(size_portrait.width, size_portrait.height, size_landscape.width, size_landscape.height);
+        if (g_config_values.floating_mode != g_floating_mode)
+            g_floating_mode = g_config_values.floating_mode;
+
+        if (g_candidate && g_candidate->get_visible())
+            set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_SHOW);
+        else
+            set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_NONE);
     }
 
     g_keyboard_state.visible_state = TRUE;
@@ -1511,13 +1517,8 @@ ise_hide()
     }
 
     g_input_panel_show = false;
-    if (g_softcandidate_show && g_ui && g_candidate) {
-        SclSize size_portrait = g_ui->get_input_mode_size(g_ui->get_input_mode(), DISPLAYMODE_PORTRAIT);
-        SclSize size_landscape = g_ui->get_input_mode_size(g_ui->get_input_mode(), DISPLAYMODE_LANDSCAPE);
-        size_portrait.height = g_candidate->get_height();
-        size_landscape.height = g_candidate->get_height();
-        ime_set_size(size_portrait.width, size_portrait.height, size_landscape.width, size_landscape.height);
-    }
+    if (g_softcandidate_show && g_ui && g_candidate)
+        set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_SHOW);
 #ifdef _WEARABLE
     hide_indicator_window();
 #endif
@@ -1582,7 +1583,26 @@ static void ise_language_guide_popup_changed_cb(const char *key, void *user_data
 static void ise_floating_mode_changed_cb(const char *key, void *user_data)
 {
     read_ise_floating_mode();
-    ime_set_floating_mode(g_config_values.floating_mode);
+    g_floating_mode = g_config_values.floating_mode;
+
+    ime_set_floating_mode(g_floating_mode);
+    if (g_candidate && g_floating_mode != g_candidate->get_floating_mode()) {
+        delete_softcandidate_hide_timer();
+        delete g_candidate;
+        g_candidate = NULL;
+
+        create_softcandidate();
+        if (g_candidate->get_visible()) {
+            g_softcandidate_show = true;
+            if (g_candidate) {
+                g_candidate->show();
+                if (g_ui)
+                    set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_SHOW);
+            }
+            return;
+        }
+    }
+    set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_NONE);
 }
 
 void
@@ -1661,17 +1681,11 @@ ise_create()
 #ifdef _TV
             g_ui->enable_highlight_ui(TRUE);
 #endif
-            ime_set_floating_mode(g_config_values.floating_mode);
-        }
-
-        SclSize size_portrait = g_ui->get_input_mode_size(g_ui->get_input_mode(), DISPLAYMODE_PORTRAIT);
-        SclSize size_landscape = g_ui->get_input_mode_size(g_ui->get_input_mode(), DISPLAYMODE_LANDSCAPE);
-        if (g_candidate && g_candidate->get_visible()) {
-            size_portrait.height += g_candidate->get_height();
-            size_landscape.height += g_candidate->get_height();
+            g_floating_mode = g_config_values.floating_mode;
+            ime_set_floating_mode(g_floating_mode);
         }
-        ime_set_size(size_portrait.width, size_portrait.height, size_landscape.width, size_landscape.height);
 
+        set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_NONE);
         preference_set_changed_cb(ISE_CONFIG_KEYPAD_MODE, ise_keypad_mode_changed_cb, NULL);
         preference_set_changed_cb(ISE_CONFIG_ENABLED_LANGUAGES, ise_enabled_languages_changed_cb, NULL);
         preference_set_changed_cb(ISE_CONFIG_SELECTED_LANGUAGE, ise_selected_language_changed_cb, NULL);
@@ -1724,22 +1738,8 @@ ise_app_candidate_show()
     g_softcandidate_show = true;
     if (g_candidate) {
         g_candidate->show();
-        if (g_ui) {
-            g_ui->set_custom_starting_coordinates(0, g_candidate->get_height());
-            SclSize size_portrait = g_ui->get_input_mode_size(g_ui->get_input_mode(), DISPLAYMODE_PORTRAIT);
-            SclSize size_landscape = g_ui->get_input_mode_size(g_ui->get_input_mode(), DISPLAYMODE_LANDSCAPE);
-            if (g_input_panel_show) {
-                size_portrait.height += g_candidate->get_height();
-                size_landscape.height += g_candidate->get_height();
-            } else {
-                size_portrait.height = g_candidate->get_height();
-                size_landscape.height = g_candidate->get_height();
-            }
-            ime_set_size(size_portrait.width, size_portrait.height, size_landscape.width, size_landscape.height);
-
-            LOGD("Showing candidate , position [%d %d] size [%d %d] [%d %d]", 0, g_candidate->get_height(),
-                size_portrait.width, size_portrait.height, size_landscape.width, size_landscape.height);
-        }
+        if (g_ui)
+            set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_SHOW);
     }
 }
 
@@ -2012,6 +2012,81 @@ static void update_recent_used_punctuation(const char * key_value)
     }
 }
 
+static void set_ime_size(bool floating_mode, ISE_CANDIDATE_REQUEST candidate_req)
+{
+    SclSize size_portrait = g_ui->get_input_mode_size(g_ui->get_input_mode(), DISPLAYMODE_PORTRAIT);
+    SclSize size_landscape = g_ui->get_input_mode_size(g_ui->get_input_mode(), DISPLAYMODE_LANDSCAPE);
+
+    if (floating_mode) {
+        size_portrait.width *= FLOATING_SCALE_RATE;
+        size_portrait.height *= FLOATING_SCALE_RATE;
+        size_landscape.width *= FLOATING_SCALE_RATE;
+        size_landscape.height *= FLOATING_SCALE_RATE;
+        switch (candidate_req) {
+            case ISE_CANDIDATE_REQ_NONE:
+                if (g_candidate && g_candidate->get_visible()) {
+                    g_ui->set_custom_starting_coordinates(0, FLOATING_TITLE_BAR_HEIGHT + g_candidate->get_height());
+                    size_portrait.height += g_candidate->get_height();
+                    size_landscape.height += g_candidate->get_height();
+                } else {
+                    g_ui->set_custom_starting_coordinates(0, FLOATING_TITLE_BAR_HEIGHT);
+                }
+                break;
+            case ISE_CANDIDATE_REQ_SHOW:
+                g_ui->set_custom_starting_coordinates(0, FLOATING_TITLE_BAR_HEIGHT + g_candidate->get_height());
+                if (g_input_panel_show || g_candidate_more_view) {
+                    size_portrait.height += g_candidate->get_height();
+                    size_landscape.height += g_candidate->get_height();
+                } else {
+                    size_portrait.height = g_candidate->get_height();
+                    size_landscape.height = g_candidate->get_height();
+                }
+                break;
+            case ISE_CANDIDATE_REQ_HIDE:
+                g_ui->set_custom_starting_coordinates(0, FLOATING_TITLE_BAR_HEIGHT);
+                break;
+            default: break;
+        }
+
+        if (g_ui->get_custom_scale_rate_x() != FLOATING_SCALE_RATE || g_ui->get_custom_scale_rate_y() != FLOATING_SCALE_RATE)
+            g_ui->set_custom_scale_rate(FLOATING_SCALE_RATE, FLOATING_SCALE_RATE);
+
+        ime_set_size(size_portrait.width, size_portrait.height + FLOATING_TITLE_BAR_HEIGHT,
+            size_landscape.width, size_landscape.height + FLOATING_TITLE_BAR_HEIGHT);
+    } else {
+        switch (candidate_req) {
+            case ISE_CANDIDATE_REQ_NONE:
+                if (g_candidate && g_candidate->get_visible()) {
+                    g_ui->set_custom_starting_coordinates(0, g_candidate->get_height());
+                    size_portrait.height += g_candidate->get_height();
+                    size_landscape.height += g_candidate->get_height();
+                } else {
+                    g_ui->set_custom_starting_coordinates(0, 0);
+                }
+                break;
+            case ISE_CANDIDATE_REQ_SHOW:
+                g_ui->set_custom_starting_coordinates(0, g_candidate->get_height());
+                if (g_input_panel_show || g_candidate_more_view) {
+                    size_portrait.height += g_candidate->get_height();
+                    size_landscape.height += g_candidate->get_height();
+                } else {
+                    size_portrait.height = g_candidate->get_height();
+                    size_landscape.height = g_candidate->get_height();
+                }
+                break;
+            case ISE_CANDIDATE_REQ_HIDE:
+                g_ui->set_custom_starting_coordinates(0, 0);
+                break;
+            default: break;
+        }
+
+        if (g_ui->get_custom_scale_rate_x() != 1.0 || g_ui->get_custom_scale_rate_y() != 1.0)
+            g_ui->set_custom_scale_rate(1.0, 1.0);
+
+        ime_set_size(size_portrait.width, size_portrait.height, size_landscape.width, size_landscape.height);
+    }
+}
+
 static void ime_app_create_cb(void *user_data)
 {
     ise_create();