• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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