• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "custom_input_method.h"
17 
18 #include <string>
19 
20 #include "common/input_method_manager.h"
21 #include "components/root_view.h"
22 #include "components/ui_checkbox.h"
23 #include "components/ui_edit_text.h"
24 #include "components/ui_label.h"
25 #include "font/ui_font.h"
26 #include "ui_test.h"
27 
28 namespace OHOS {
29 namespace {
30 struct KeyInfo {
31     uint8_t keyCount;
32     uint8_t row1Count;
33     uint8_t row2Count;
34     uint8_t row3Count;
35     uint8_t row4Count;
36     const char* keyName[32]; // 32: max count of keys
37 };
38 
39 const KeyInfo LOW_CASE_KEY_IOFO = {
40     32, 10, 19, 28, 32,
41     {
42         "q",     "w",     "e", "r",     "t", "y", "u", "i", "o",   "p", // 10
43         "a",     "s",     "d", "f",     "g", "h", "j", "k", "l",        // 9
44         "shift", "z",     "x", "c",     "v", "b", "n", "m", "del",      // 9
45         "123",   "space", ".", "return"                                 // 4
46     }
47 };
48 
49 const KeyInfo UPPER_CASE_KEY_IOFO = {
50     32, 10, 19, 28, 32,
51     {
52         "Q",     "W",     "E", "R",     "T", "Y", "U", "I", "O",   "P", // 10
53         "A",     "S",     "D", "F",     "G", "H", "J", "K", "L",        // 9
54         "shift", "Z",     "X", "C",     "V", "B", "N", "M", "del",      // 9
55         "123",   "space", ".", "return"                                 // 4
56     }
57 };
58 
59 const KeyInfo NUM_KEY_IOFO = {
60     31, 10, 20, 27, 31,
61     {
62         "1",   "2",     "3", "4",     "5", "6", "7",   "8", "9", "0",  // 10
63         "-",   "/",     ":", ";",     "(", ")", "$",   "&", "@", "\"", // 10
64         "#+=", ".",     ",", "?",     "!", "'", "del",                 // 7
65         "ABC", "space", ".", "return"                                  // 4
66     }
67 };
68 
69 const KeyInfo SYMBOL_KEY_IOFO = {
70     31, 10, 20, 27, 31,
71     {
72         "[",   "]",     "{", "}",     "#", "%", "^",   "*", "+", "=", // 10
73         "_",   "\\",    "|", "~",     "<", ">", "¥",  "€", "£", "•", // 10
74         "123", ".",     ",", "?",     "!", "'", "del",                // 7
75         "ABC", "space", ".", "return"                                 // 4
76     }
77 };
78 
79 const int16_t KEYBOARD_WIDTH = 580;
80 const int16_t KEYBOARD_HEIGHT = 320;
81 const int16_t KEY_WIDTH = 50;
82 const int16_t KEY_HEIGHT = 65;
83 const int16_t FUNC_KEY_WIDTH = 65;
84 const int16_t SPACE_KEY_WIDTH = 260;
85 const int16_t RETURN_KEY_WIDTH = 120;
86 const int16_t KEY_BORDER_RADIUS = 10;
87 const int16_t KEY_MARGIN_LEFT = 7;
88 
GetKeyInfo(KeyboardType type)89 KeyInfo GetKeyInfo(KeyboardType type)
90 {
91     KeyInfo keyInfo;
92     switch (type) {
93         case KeyboardType::LOW_CASE:
94             keyInfo = LOW_CASE_KEY_IOFO;
95             break;
96         case KeyboardType::UPPER_CASE:
97             keyInfo = UPPER_CASE_KEY_IOFO;
98             break;
99         case KeyboardType::NUMBER:
100             keyInfo = NUM_KEY_IOFO;
101             break;
102         case KeyboardType::SYMBOL:
103             keyInfo = SYMBOL_KEY_IOFO;
104             break;
105         default:
106             keyInfo = LOW_CASE_KEY_IOFO;
107             break;
108     }
109 
110     return keyInfo;
111 }
112 } // namespace
113 
OnShow(InputMethodManager::InputMethodParam & param)114 void CustomInputMethod::OnShow(InputMethodManager::InputMethodParam& param)
115 {
116     // init method
117     SetupView(keyboardType_);
118 
119     // update value
120     editView_->SetText(param.text.c_str());
121     editView_->SetInputType(param.inputType);
122     if (param.view != nullptr) {
123         UIEditText* paramView = reinterpret_cast<UIEditText*>(param.view);
124         editView_->SetPlaceholder(paramView->GetPlaceholder());
125         editView_->SetPlaceholderColor(paramView->GetPlaceholderColor());
126         editView_->SetCursorColor(paramView->GetCursorColor());
127         editView_->SetTextColor(paramView->GetTextColor());
128         editView_->SetMaxLength(paramView->GetMaxLength());
129     }
130     editView_->Focus();
131     container_->Invalidate();
132 
133     // keyboard show callback
134     InputMethodManager::GetInstance().OnKeyboardShow();
135 }
136 
OnHide()137 void CustomInputMethod::OnHide()
138 {
139     editView_->Blur();
140     TearDownView();
141 
142     // keyboard show callback
143     InputMethodManager::GetInstance().OnKeyboardHide();
144 }
145 
SetupView(KeyboardType type)146 void CustomInputMethod::SetupView(KeyboardType type)
147 {
148     if (container_ == nullptr) {
149         container_ = new UIViewGroup();
150         container_->Resize(KEYBOARD_WIDTH, 650); // 650: height
151         container_->SetPosition(350, 100);       // 350: position x, 100: position y
152         container_->SetStyle(STYLE_BORDER_COLOR, Color::White().full);
153         // add on rootview
154         RootView::GetInstance()->Add(container_);
155     }
156 
157     if (editView_ != nullptr) {
158         container_->Remove(editView_);
159         delete editView_;
160     }
161     editView_ = new UIEditTextEx();
162     container_->Add(editView_);
163     editView_->Resize(250, 40); // 250: width, 40: height
164     editView_->SetPosition(0, 0);
165     editView_->SetViewId("Input_edit_text_view");
166 
167     if (inputTypeBtn_ == nullptr) {
168         inputTypeBtn_ = new UILabelButton();
169         container_->Add(inputTypeBtn_);
170         inputTypeBtn_->Resize(100, 40); // 100: width, 40: height
171         inputTypeBtn_->SetText("toggle");
172         inputTypeBtn_->LayoutRightToSibling("Input_edit_text_view", 10); // 10: offset
173         inputTypeBtn_->SetOnClickListener(this);
174         inputTypeBtn_->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE,
175                                         UIButton::RELEASED);
176         inputTypeBtn_->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED);
177     }
178 
179     SetupKeyboard(type);
180 }
181 
SetupKeyboard(KeyboardType type)182 void CustomInputMethod::SetupKeyboard(KeyboardType type)
183 {
184     UIViewGroup* keyboard = new UIViewGroup();
185     int16_t rowHeight = KEYBOARD_HEIGHT / 4; // 4: row number
186     keyboard->Resize(KEYBOARD_WIDTH, KEYBOARD_HEIGHT);
187     keyboard->SetPosition(0, 45); // 45: position y
188     keyboard->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full);
189     keyboard->SetViewId("keyboard");
190     container_->Add(keyboard);
191     FlexLayout* row1 = SetupKeyRow("row1", KEYBOARD_WIDTH, rowHeight);
192     row1->SetPosition(0, 0);
193     keyboard->Add(row1);
194 
195     FlexLayout* row2 = SetupKeyRow("row2", KEYBOARD_WIDTH, rowHeight);
196     keyboard->Add(row2);
197     row2->LayoutBottomToSibling("row1");
198 
199     FlexLayout* row3 = SetupKeyRow("row3", KEYBOARD_WIDTH, rowHeight);
200     keyboard->Add(row3);
201     row3->LayoutBottomToSibling("row2");
202 
203     FlexLayout* row4 = SetupKeyRow("row4", KEYBOARD_WIDTH, rowHeight);
204     keyboard->Add(row4);
205     row4->LayoutBottomToSibling("row3");
206 
207     KeyInfo keyInfo = GetKeyInfo(type);
208     for (int16_t i = 0; i < keyInfo.keyCount; i++) {
209         UILabelButton* key = SetupButton(keyInfo.keyName[i]);
210         if (i < keyInfo.row1Count) {
211             row1->Add(key);
212         } else if (i < keyInfo.row2Count) {
213             row2->Add(key);
214         } else if (i < keyInfo.row3Count) {
215             row3->Add(key);
216         } else if (i < keyInfo.row4Count) {
217             row4->Add(key);
218         }
219     }
220 
221     row1->LayoutChildren();
222     row2->LayoutChildren();
223     row3->LayoutChildren();
224     row4->LayoutChildren();
225     keyboard->Invalidate();
226 }
227 
SetupKeyRow(const char * name,int16_t width,int16_t height)228 FlexLayout* CustomInputMethod::SetupKeyRow(const char* name, int16_t width, int16_t height)
229 {
230     FlexLayout* row = new FlexLayout();
231     row->Resize(width, height);
232     row->SetViewId(name);
233     row->SetMajorAxisAlign(ALIGN_CENTER);
234     row->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
235     return row;
236 }
237 
SetupButton(const char * title)238 UILabelButton* CustomInputMethod::SetupButton(const char* title)
239 {
240     UILabelButton* keyBtn = new UILabelButton();
241     keyBtn->SetText(title);
242     keyBtn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE);
243     keyBtn->SetStyle(STYLE_MARGIN_LEFT, KEY_MARGIN_LEFT);
244     keyBtn->SetOnClickListener(this);
245     int16_t radius = KEY_BORDER_RADIUS;
246     keyBtn->SetStyleForState(STYLE_BORDER_RADIUS, radius, UIButton::RELEASED);
247     keyBtn->SetStyleForState(STYLE_BORDER_RADIUS, radius, UIButton::PRESSED);
248     keyBtn->SetStyleForState(STYLE_BORDER_RADIUS, radius, UIButton::INACTIVE);
249     keyBtn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED);
250     keyBtn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED);
251     keyBtn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE);
252     keyBtn->Resize(KEY_WIDTH, KEY_HEIGHT);
253 
254     if ((strcmp(title, "shift") == 0) || (strcmp(title, "del") == 0) || (strcmp(title, "123") == 0) ||
255         (strcmp(title, "ABC") == 0) || (strcmp(title, "#+=") == 0)) {
256         keyBtn->Resize(FUNC_KEY_WIDTH, KEY_HEIGHT);
257     } else if (strcmp(title, "space") == 0) {
258         keyBtn->Resize(SPACE_KEY_WIDTH, KEY_HEIGHT);
259     } else if (strcmp(title, "return") == 0) {
260         keyBtn->Resize(RETURN_KEY_WIDTH, KEY_HEIGHT);
261     }
262     return keyBtn;
263 }
264 
TearDownView()265 void CustomInputMethod::TearDownView()
266 {
267     UITest::DeleteChildren(container_);
268     container_ = nullptr;
269     editView_ = nullptr;
270 }
271 
OnClick(UIView & view,const ClickEvent & event)272 bool CustomInputMethod::OnClick(UIView& view, const ClickEvent& event)
273 {
274     if (inputTypeBtn_ == &view) {
275         InputType type = editView_->GetInputType();
276         if (type == InputType::TEXT_TYPE) {
277             editView_->SetInputType(InputType::PASSWORD_TYPE);
278             InputMethodManager::GetInstance().SetInputType(InputType::PASSWORD_TYPE);
279         } else {
280             editView_->SetInputType(InputType::TEXT_TYPE);
281             InputMethodManager::GetInstance().SetInputType(InputType::TEXT_TYPE);
282         }
283     } else {
284         DealKeyEvent(view);
285     }
286 
287     return true;
288 }
289 
DealKeyEvent(UIView & view)290 void CustomInputMethod::DealKeyEvent(UIView& view)
291 {
292     const char* key = reinterpret_cast<UILabelButton*>(&view)->GetText();
293     if (key == nullptr) {
294         return;
295     }
296 
297     if (strcmp(key, "shift") == 0) {
298         if (keyboardType_ == KeyboardType::LOW_CASE) {
299             keyboardType_ = KeyboardType::UPPER_CASE;
300         } else {
301             keyboardType_ = KeyboardType::LOW_CASE;
302         }
303         ChangeKeyboard(keyboardType_);
304     } else if (strcmp(key, "123") == 0) {
305         keyboardType_ = KeyboardType::NUMBER;
306         ChangeKeyboard(keyboardType_);
307     } else if (strcmp(key, "ABC") == 0) {
308         keyboardType_ = KeyboardType::LOW_CASE;
309         ChangeKeyboard(keyboardType_);
310     } else if (strcmp(key, "#+=") == 0) {
311         keyboardType_ = KeyboardType::SYMBOL;
312         ChangeKeyboard(keyboardType_);
313     } else if (strcmp(key, "del") == 0) {
314         InputMethodManager::GetInstance().DeleteBackward(1);
315         editView_->DeleteBackward(1);
316     } else if (strcmp(key, "space") == 0) {
317         InputMethodManager::GetInstance().InsertText(" ");
318         editView_->InsertText(" ");
319     } else if (strcmp(key, "return") == 0) {
320         // do nothing
321     } else {
322         InputMethodManager::GetInstance().InsertText(key);
323         editView_->InsertText(key);
324     }
325 }
326 
ChangeKeyboard(KeyboardType type)327 void CustomInputMethod::ChangeKeyboard(KeyboardType type)
328 {
329     UIView* keyboardTmp = container_->GetChildById("keyboard");
330     SetupKeyboard(type);
331     container_->Remove(keyboardTmp);
332     UITest::DeleteChildren(keyboardTmp);
333 }
334 } // namespace OHOS
335