1 /*
2 * Copyright (c) 2020-2021 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 "components/ui_time_picker.h"
17 #include <cstdio>
18 #include <ctime>
19 #include "draw/draw_rect.h"
20 #include "gfx_utils/graphic_log.h"
21 #include "securec.h"
22 #include "themes/theme_manager.h"
23
24 namespace OHOS {
UITimePicker()25 UITimePicker::UITimePicker()
26 : selectedValue_{0},
27 selectedHour_{0},
28 selectedMinute_{0},
29 selectedSecond_{0},
30 secVisible_(false),
31 loopState_{false},
32 pickerWidth_(0),
33 itemsHeight_(0),
34 xPos_(0),
35 backgroundFontSize_(0),
36 highlightFontSize_(0),
37 backgroundFontName_(nullptr),
38 highlightFontName_(nullptr),
39 pickerListener_(this),
40 timePickerListener_(nullptr)
41 {
42 Theme* theme = ThemeManager::GetInstance().GetCurrent();
43 if (theme != nullptr) {
44 style_ = &(theme->GetPickerBackgroundStyle());
45 } else {
46 style_ = &(StyleDefault::GetPickerBackgroundStyle());
47 }
48 backgroundFontId_ = style_->font_;
49 backgroundColor_ = style_->textColor_;
50 if (theme != nullptr) {
51 style_ = &(theme->GetPickerHighlightStyle());
52 } else {
53 style_ = &(StyleDefault::GetPickerHighlightStyle());
54 }
55 #if ENABLE_FOCUS_MANAGER
56 focusable_ = true;
57 #endif
58 highlightFontId_ = style_->font_;
59 highlightColor_ = style_->textColor_;
60
61 hourPicker_ = nullptr;
62 minutePicker_ = nullptr;
63 secondPicker_ = nullptr;
64 }
65
~UITimePicker()66 UITimePicker::~UITimePicker()
67 {
68 DeInitTimePicker();
69 if (backgroundFontName_ != nullptr) {
70 UIFree(backgroundFontName_);
71 backgroundFontName_ = nullptr;
72 }
73
74 if (highlightFontName_ != nullptr) {
75 UIFree(highlightFontName_);
76 highlightFontName_ = nullptr;
77 }
78 }
79
InitTimePicker()80 void UITimePicker::InitTimePicker()
81 {
82 xPos_ = 0;
83 if (secVisible_) {
84 pickerWidth_ = GetWidth() / SEC_VISIBLE_COUNT;
85 InitPicker(hourPicker_, TIME_START, HOUR_END);
86 xPos_ = pickerWidth_;
87 InitPicker(minutePicker_, TIME_START, MIN_END);
88 xPos_ *= (SEC_VISIBLE_COUNT - 1);
89 InitPicker(secondPicker_, TIME_START, SEC_END);
90 if (secondPicker_ != nullptr) {
91 secondPicker_->SetLoopState(loopState_[PICKER_SEC]);
92 }
93 } else {
94 pickerWidth_ = GetWidth() / SEC_INVISIBLE_COUNT;
95 InitPicker(hourPicker_, TIME_START, HOUR_END);
96 xPos_ = pickerWidth_;
97 InitPicker(minutePicker_, TIME_START, MIN_END);
98 }
99 if (hourPicker_ != nullptr) {
100 hourPicker_->SetLoopState(loopState_[PICKER_HOUR]);
101 }
102 if (minutePicker_ != nullptr) {
103 minutePicker_->SetLoopState(loopState_[PICKER_MIN]);
104 }
105
106 RefreshSelected(selectedValue_);
107 }
108
DeInitTimePicker()109 void UITimePicker::DeInitTimePicker()
110 {
111 DeInitPicker(secondPicker_);
112 DeInitPicker(minutePicker_);
113 DeInitPicker(hourPicker_);
114 }
115
RefreshTimePicker()116 void UITimePicker::RefreshTimePicker()
117 {
118 DeInitTimePicker();
119 InitTimePicker();
120 }
121
InitPicker(UIPicker * & picker,int16_t start,int16_t end)122 void UITimePicker::InitPicker(UIPicker*& picker, int16_t start, int16_t end)
123 {
124 picker = new UIPicker();
125 if (picker == nullptr) {
126 GRAPHIC_LOGE("new UIPicker fail");
127 return;
128 }
129 picker->SetPosition(xPos_, 0, pickerWidth_, GetHeight());
130 picker->SetItemHeight(itemsHeight_);
131 picker->SetFontId(backgroundFontId_, highlightFontId_);
132 if ((backgroundFontName_ == nullptr) || (highlightFontName_ == nullptr)) {
133 picker->SetFontId(backgroundFontId_, highlightFontId_);
134 } else {
135 picker->SetBackgroundFont(backgroundFontName_, backgroundFontSize_);
136 picker->SetHighlightFont(highlightFontName_, highlightFontSize_);
137 }
138 picker->SetTextColor(backgroundColor_, highlightColor_);
139 picker->SetValues(start, end);
140 picker->RegisterSelectedListener(&pickerListener_);
141 Add(picker);
142
143 #if ENABLE_ROTATE_INPUT
144 if (end == HOUR_END) {
145 picker->GetChildrenHead()->SetViewId(HOUR_LIST_NAME);
146 } else if (end == MIN_END && secondPicker_ == nullptr) {
147 picker->GetChildrenHead()->SetViewId(MIN_LIST_NAME);
148 } else if (end == SEC_END) {
149 picker->GetChildrenHead()->SetViewId(SEC_LIST_NAME);
150 }
151 #endif
152 }
153
DeInitPicker(UIPicker * & picker)154 void UITimePicker::DeInitPicker(UIPicker*& picker)
155 {
156 if (picker != nullptr) {
157 Remove(picker);
158 picker->ClearValues();
159 delete picker;
160 picker = nullptr;
161 }
162 }
163
TimeSelectedCallback()164 void UITimePicker::TimeSelectedCallback()
165 {
166 uint16_t hourSelect = hourPicker_->GetSelected();
167 uint16_t minSelect = minutePicker_->GetSelected();
168 GetValueByIndex(selectedHour_, BUF_SIZE, hourSelect, TIME_START, HOUR_END);
169 GetValueByIndex(selectedMinute_, BUF_SIZE, minSelect, TIME_START, MIN_END);
170
171 if (memset_s(selectedValue_, SELECTED_VALUE_SIZE, 0, SELECTED_VALUE_SIZE) != EOK) {
172 return;
173 }
174
175 if (secVisible_) {
176 uint16_t secSelect = secondPicker_->GetSelected();
177 GetValueByIndex(selectedSecond_, BUF_SIZE, secSelect, TIME_START, SEC_END);
178 if (sprintf_s(selectedValue_, SELECTED_VALUE_SIZE, "%s:%s:%s",
179 selectedHour_, selectedMinute_, selectedSecond_) < 0) {
180 return;
181 }
182 } else {
183 if (sprintf_s(selectedValue_, SELECTED_VALUE_SIZE, "%s:%s", selectedHour_, selectedMinute_) < 0) {
184 return;
185 }
186 }
187
188 if (timePickerListener_ != nullptr) {
189 timePickerListener_->OnTimePickerStoped(*this);
190 }
191 }
192
GetValueByIndex(char * value,uint8_t len,uint16_t index,int16_t start,int16_t end)193 void UITimePicker::GetValueByIndex(char* value, uint8_t len, uint16_t index, int16_t start, int16_t end)
194 {
195 if ((value != nullptr) && (index < end - start + 1)) {
196 if (sprintf_s(value, len, "%02u", index) < 0) {
197 return;
198 }
199 }
200 }
201
SetSelected(const char * value)202 bool UITimePicker::SetSelected(const char* value)
203 {
204 if (value == nullptr) {
205 return false;
206 }
207
208 if (memset_s(selectedValue_, SELECTED_VALUE_SIZE, 0, SELECTED_VALUE_SIZE) != EOK) {
209 return false;
210 }
211
212 if (strcpy_s(selectedValue_, SELECTED_VALUE_SIZE, value) != EOK) {
213 return false;
214 }
215 if (secVisible_) {
216 if (sscanf_s(value, "%[^:]%*c%[^:]%*c%[^\n]", selectedHour_, BUF_SIZE,
217 selectedMinute_, BUF_SIZE, selectedSecond_, BUF_SIZE) < 3) { // 3: three variables
218 return false;
219 }
220 } else {
221 if (sscanf_s(value, "%[^:]%*c%[^\n]", selectedHour_, BUF_SIZE,
222 selectedMinute_, BUF_SIZE) < 2) { // 2: two variables
223 return false;
224 }
225 }
226 return RefreshSelected(selectedValue_);
227 }
228
RefreshSelected(const char * value)229 bool UITimePicker::RefreshSelected(const char* value)
230 {
231 uint32_t hourSelect;
232 uint32_t minSelect;
233
234 if (value == nullptr) {
235 return false;
236 }
237
238 if (secVisible_) {
239 uint32_t secSelect;
240 // 3: three variables
241 if (sscanf_s(value, "%u:%u:%u", &hourSelect, &minSelect, &secSelect) < 3) {
242 return false;
243 }
244 secondPicker_->SetSelected(secSelect);
245 } else {
246 if (sscanf_s(value, "%u:%u", &hourSelect, &minSelect) < 2) { // 2: two variables
247 return false;
248 }
249 }
250
251 hourPicker_->SetSelected(hourSelect);
252 minutePicker_->SetSelected(minSelect);
253 return true;
254 }
255
OnPressEvent(const PressEvent & event)256 bool UITimePicker::OnPressEvent(const PressEvent& event)
257 {
258 if (event.GetCurrentPos().x < (GetX() + hourPicker_->GetX() + hourPicker_->GetWidth())) {
259 hourPicker_->RequestFocus();
260 } else if (event.GetCurrentPos().x < (GetX() + minutePicker_->GetX() + minutePicker_->GetWidth())) {
261 minutePicker_->RequestFocus();
262 } else if (event.GetCurrentPos().x < (GetX() + secondPicker_->GetX() + secondPicker_->GetWidth())) {
263 secondPicker_->RequestFocus();
264 }
265 return UIView::OnPressEvent(event);
266 }
267
SetItemHeight(int16_t height)268 void UITimePicker::SetItemHeight(int16_t height)
269 {
270 itemsHeight_ = height;
271 RefreshTimePicker();
272 }
273
EnableSecond(bool state)274 void UITimePicker::EnableSecond(bool state)
275 {
276 secVisible_ = state;
277 RefreshTimePicker();
278 }
279
SetTextStyle(uint16_t backgroundFontId,uint16_t highlightFontId,ColorType backgroundColor,ColorType highlightColor)280 void UITimePicker::SetTextStyle(uint16_t backgroundFontId,
281 uint16_t highlightFontId,
282 ColorType backgroundColor,
283 ColorType highlightColor)
284 {
285 highlightFontId_ = highlightFontId;
286 if (highlightFontName_ != nullptr) {
287 UIFree(highlightFontName_);
288 highlightFontName_ = nullptr;
289 }
290
291 backgroundFontId_ = backgroundFontId;
292 if (backgroundFontName_ != nullptr) {
293 UIFree(backgroundFontName_);
294 backgroundFontName_ = nullptr;
295 }
296
297 highlightColor_ = highlightColor;
298 backgroundColor_ = backgroundColor;
299 RefreshTimePicker();
300 }
301
SetTextColor(ColorType backgroundColor,ColorType highlightColor)302 void UITimePicker::SetTextColor(ColorType backgroundColor, ColorType highlightColor)
303 {
304 backgroundColor_ = backgroundColor;
305 highlightColor_ = highlightColor;
306 RefreshTimePicker();
307 }
308
SetBackgroundFont(const char * name,uint8_t size)309 void UITimePicker::SetBackgroundFont(const char* name, uint8_t size)
310 {
311 Text::SetFont(name, size, backgroundFontName_, backgroundFontSize_);
312 RefreshTimePicker();
313 }
314
SetHighlightFont(const char * name,uint8_t size)315 void UITimePicker::SetHighlightFont(const char* name, uint8_t size)
316 {
317 Text::SetFont(name, size, highlightFontName_, highlightFontSize_);
318 RefreshTimePicker();
319 }
320
SetWidth(int16_t width)321 void UITimePicker::SetWidth(int16_t width)
322 {
323 UIView::SetWidth(width);
324 RefreshTimePicker();
325 }
326
SetHeight(int16_t height)327 void UITimePicker::SetHeight(int16_t height)
328 {
329 UIView::SetHeight(height);
330 RefreshTimePicker();
331 }
332
SetLoopState(const uint8_t pickerType,bool state)333 void UITimePicker::SetLoopState(const uint8_t pickerType, bool state)
334 {
335 switch (pickerType) {
336 case PICKER_HOUR:
337 loopState_[PICKER_HOUR] = state;
338 break;
339 case PICKER_MIN:
340 loopState_[PICKER_MIN] = state;
341 break;
342 case PICKER_SEC:
343 loopState_[PICKER_SEC] = state;
344 break;
345 default:
346 return;
347 }
348 RefreshTimePicker();
349 }
350 }
351