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, uint16_t highlightFontId,
281 ColorType backgroundColor, ColorType highlightColor)
282 {
283 highlightFontId_ = highlightFontId;
284 if (highlightFontName_ != nullptr) {
285 UIFree(highlightFontName_);
286 highlightFontName_ = nullptr;
287 }
288
289 backgroundFontId_ = backgroundFontId;
290 if (backgroundFontName_ != nullptr) {
291 UIFree(backgroundFontName_);
292 backgroundFontName_ = nullptr;
293 }
294
295 highlightColor_ = highlightColor;
296 backgroundColor_ = backgroundColor;
297 RefreshTimePicker();
298 }
299
SetTextColor(ColorType backgroundColor,ColorType highlightColor)300 void UITimePicker::SetTextColor(ColorType backgroundColor, ColorType highlightColor)
301 {
302 backgroundColor_ = backgroundColor;
303 highlightColor_ = highlightColor;
304 RefreshTimePicker();
305 }
306
SetBackgroundFont(const char * name,uint8_t size)307 void UITimePicker::SetBackgroundFont(const char* name, uint8_t size)
308 {
309 Text::SetFont(name, size, backgroundFontName_, backgroundFontSize_);
310 RefreshTimePicker();
311 }
312
SetHighlightFont(const char * name,uint8_t size)313 void UITimePicker::SetHighlightFont(const char* name, uint8_t size)
314 {
315 Text::SetFont(name, size, highlightFontName_, highlightFontSize_);
316 RefreshTimePicker();
317 }
318
SetWidth(int16_t width)319 void UITimePicker::SetWidth(int16_t width)
320 {
321 UIView::SetWidth(width);
322 RefreshTimePicker();
323 }
324
SetHeight(int16_t height)325 void UITimePicker::SetHeight(int16_t height)
326 {
327 UIView::SetHeight(height);
328 RefreshTimePicker();
329 }
330
SetLoopState(const uint8_t pickerType,bool state)331 void UITimePicker::SetLoopState(const uint8_t pickerType, bool state)
332 {
333 switch (pickerType) {
334 case PICKER_HOUR:
335 loopState_[PICKER_HOUR] = state;
336 break;
337 case PICKER_MIN:
338 loopState_[PICKER_MIN] = state;
339 break;
340 case PICKER_SEC:
341 loopState_[PICKER_SEC] = state;
342 break;
343 default:
344 return;
345 }
346 RefreshTimePicker();
347 }
348 }
349