• 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_picker.h"
17 #include "dock/vibrator_manager.h"
18 #include "draw/draw_line.h"
19 #include "draw/draw_rect.h"
20 #include "themes/theme_manager.h"
21 
22 namespace OHOS {
PickerListScrollListener(UIPicker * picker,UIList * list)23 PickerListScrollListener::PickerListScrollListener(UIPicker* picker, UIList* list)
24     : listView_(list),
25       pickerView_(picker),
26       selectView_(nullptr),
27       lastSelectView_(nullptr),
28       selectIndex_(0),
29       isInitted_(false) {}
30 
OnItemSelected(int16_t index,UIView * view)31 void PickerListScrollListener::OnItemSelected(int16_t index, UIView* view)
32 {
33     if (!isInitted_) {
34         return;
35     }
36 
37     if ((lastSelectView_ != nullptr) && (listView_ != nullptr) && (pickerView_ != nullptr) && (view != nullptr)) {
38         lastSelectView_->SetStyle(STYLE_TEXT_COLOR, pickerView_->GetBackgroundTextColor().full);
39         if (pickerView_->backgroundFontName_ == nullptr) {
40             static_cast<UILabel*>(lastSelectView_)->SetFontId(pickerView_->backgroundFontId_);
41         } else {
42             static_cast<UILabel*>(lastSelectView_)
43                 ->SetFont(pickerView_->backgroundFontName_, pickerView_->backgroundFontSize_);
44         }
45         view->SetStyle(STYLE_TEXT_COLOR, pickerView_->GetHighlightTextColor().full);
46         if (pickerView_->highlightFontName_ == nullptr) {
47             static_cast<UILabel*>(view)->SetFontId(pickerView_->highlightFontId_);
48         } else {
49             static_cast<UILabel*>(view)->SetFont(pickerView_->highlightFontName_, pickerView_->highlightFontSize_);
50         }
51         lastSelectView_ = view;
52         selectIndex_ = index;
53         listView_->Invalidate();
54         if (pickerView_->pickerListener_) {
55             pickerView_->pickerListener_->OnPickerChanged(*pickerView_);
56         }
57     }
58 }
59 
OnScrollEnd(int16_t index,UIView * view)60 void PickerListScrollListener::OnScrollEnd(int16_t index, UIView* view)
61 {
62     if ((view == nullptr) || (listView_ == nullptr) || (pickerView_ == nullptr)) {
63         return;
64     }
65 
66     if (lastSelectView_ != nullptr) {
67         lastSelectView_->SetStyle(STYLE_TEXT_COLOR, pickerView_->GetBackgroundTextColor().full);
68         if (pickerView_->backgroundFontName_ == nullptr) {
69             static_cast<UILabel*>(lastSelectView_)->SetFontId(pickerView_->backgroundFontId_);
70         } else {
71             static_cast<UILabel*>(lastSelectView_)
72                 ->SetFont(pickerView_->backgroundFontName_, pickerView_->backgroundFontSize_);
73         }
74         lastSelectView_ = view;
75     }
76 
77     view->SetStyle(STYLE_TEXT_COLOR, pickerView_->GetHighlightTextColor().full);
78     if (pickerView_->highlightFontName_ == nullptr) {
79         static_cast<UILabel*>(view)->SetFontId(pickerView_->highlightFontId_);
80     } else {
81         static_cast<UILabel*>(view)->SetFont(pickerView_->highlightFontName_, pickerView_->highlightFontSize_);
82     }
83 
84     listView_->Invalidate();
85     selectView_ = view;
86     selectIndex_ = index;
87 
88     if (pickerView_->pickerListener_) {
89         pickerView_->pickerListener_->OnPickerStoped(*pickerView_);
90     }
91 }
92 
UIPicker()93 UIPicker::UIPicker()
94     : isWidthSet_(false),
95       isHeightSet_(false),
96       textAdapter_(nullptr),
97       maxCount_(0),
98       isScrollBlankSizeSet_(false),
99       scrollBlankSize_(0),
100       backgroundFontSize_(0),
101       highlightFontSize_(0),
102       backgroundFontName_(nullptr),
103       highlightFontName_(nullptr),
104       itemsWidth_(0),
105       itemsHeight_(0),
106       rangeValue_(nullptr),
107       rangeValueCount_(0),
108       startValue_(0),
109       endValue_(0),
110       isSetAdaptered_(false),
111       pickerListener_(nullptr)
112 {
113     Theme* theme = ThemeManager::GetInstance().GetCurrent();
114     if (theme != nullptr) {
115         style_ = &(theme->GetPickerBackgroundStyle());
116     } else {
117         style_ = &(StyleDefault::GetPickerBackgroundStyle());
118     }
119     backgroundFontId_ = style_->font_;
120     backgroundColor_ = style_->textColor_;
121     direct_ = UITextLanguageDirect::TEXT_DIRECT_LTR;
122 
123     if (theme != nullptr) {
124         style_ = &(theme->GetPickerHighlightStyle());
125     } else {
126         style_ = &(StyleDefault::GetPickerHighlightStyle());
127     }
128     highlightFontId_ = style_->font_;
129     highlightColor_ = style_->textColor_;
130 
131     list_.SetThrowDrag(true);
132     list_.SetStyle(StyleDefault::GetBackgroundTransparentStyle());
133 #if ENABLE_ROTATE_INPUT
134     list_.rotateFactor_ = DEFAULT_PICKER_ROTATE_FACTOR;
135     list_.rotateThrowthreshold_ = PICKERVIEW_ROTATE_THROW_THRESHOLD;
136     list_.rotateAccCoefficient_ = PICKERVIEW_ROTATE_DISTANCE_COEFF;
137 #endif
138 #if ENABLE_FOCUS_MANAGER
139     focusable_ = true;
140 #endif
141     list_.SetLoopState(false);
142     list_.EnableAutoAlign(true);
143     listListener_ = new PickerListScrollListener(this, &list_);
144     list_.SetScrollStateListener(listListener_);
145     Add(&list_);
146 }
147 
~UIPicker()148 UIPicker::~UIPicker()
149 {
150     ClearValues();
151     Remove(&list_);
152     if (listListener_ != nullptr) {
153         delete listListener_;
154         listListener_ = nullptr;
155     }
156 
157     if (backgroundFontName_ != nullptr) {
158         UIFree(backgroundFontName_);
159         backgroundFontName_ = nullptr;
160     }
161 
162     if (highlightFontName_ != nullptr) {
163         UIFree(highlightFontName_);
164         highlightFontName_ = nullptr;
165     }
166 
167     if (textAdapter_ != nullptr) {
168         delete textAdapter_;
169         textAdapter_ = nullptr;
170     }
171 }
172 
SetValues(int16_t start,int16_t end)173 bool UIPicker::SetValues(int16_t start, int16_t end)
174 {
175     if (start > end) {
176         return false;
177     }
178 
179     startValue_ = start;
180     endValue_ = end;
181     return RefreshValues(start, end);
182 }
183 
SetValues(const char * value[],uint16_t count)184 bool UIPicker::SetValues(const char* value[], uint16_t count)
185 {
186     if (value == nullptr) {
187         return false;
188     }
189 
190     rangeValue_ = value;
191     rangeValueCount_ = count;
192     return RefreshValues(value, count);
193 }
194 
Refresh()195 void UIPicker::Refresh()
196 {
197     if (rangeValue_) {
198         RefreshValues(rangeValue_, rangeValueCount_);
199     } else if ((startValue_ != 0) || (endValue_ != 0)) {
200         RefreshValues(startValue_, endValue_);
201     }
202 }
203 
RefreshValues(int16_t start,int16_t end)204 bool UIPicker::RefreshValues(int16_t start, int16_t end)
205 {
206     if ((start == 0) && (end == 0)) {
207         return false;
208     }
209     maxCount_ = end - start + 1;
210     if (!isWidthSet_ || !isHeightSet_ || !itemsHeight_) {
211         return false;
212     }
213     uint16_t userSelectIndex = listListener_->GetSelectIndex();
214     ClearList();
215     InitTextAdapter();
216     if (textAdapter_ == nullptr) {
217         return false;
218     }
219     textAdapter_->SetData(start, end);
220     RefreshList();
221     RefreshSelected(userSelectIndex);
222     return true;
223 }
224 
RefreshValues(const char * value[],uint16_t count)225 bool UIPicker::RefreshValues(const char* value[], uint16_t count)
226 {
227     if (value == nullptr) {
228         return false;
229     }
230     maxCount_ = count;
231     if (!isWidthSet_ || !isHeightSet_ || !itemsHeight_) {
232         return false;
233     }
234     uint16_t userSelectIndex = listListener_->GetSelectIndex();
235     ClearList();
236     for (uint16_t i = 0; i < count; i++) {
237         dataList_.PushBack(value[i]);
238     }
239     InitTextAdapter();
240     textAdapter_->SetData(&dataList_);
241     RefreshList();
242     RefreshSelected(userSelectIndex);
243 
244     return true;
245 }
246 
RefreshList()247 void UIPicker::RefreshList()
248 {
249     int16_t height = GetHeight();
250     itemsWidth_ = GetWidth();
251     textAdapter_->SetWidth(itemsWidth_);
252     textAdapter_->SetHeight(itemsHeight_);
253     textAdapter_->SetLineBreakMode(UILabel::LINE_BREAK_CLIP);
254     if (backgroundFontName_ == nullptr) {
255         textAdapter_->SetFontId(backgroundFontId_);
256     } else {
257         textAdapter_->SetFont(backgroundFontName_, backgroundFontSize_);
258     }
259     textAdapter_->GetStyle().textColor_ = backgroundColor_;
260     textAdapter_->SetDirect(direct_);
261     list_.SetHeight(height);
262     list_.SetWidth(itemsWidth_);
263     list_.LayoutCenterOfParent();
264     list_.SetSelectPosition(height / 2);                   // 2: half
265     if (isScrollBlankSizeSet_) {
266         list_.SetScrollBlankSize(scrollBlankSize_);
267     } else {
268         list_.SetScrollBlankSize((height - itemsHeight_) / 2); // 2: half
269     }
270     if (!isSetAdaptered_) {
271         list_.SetAdapter(textAdapter_);
272         isSetAdaptered_ = true;
273     }
274 
275     list_.RefreshList();
276     RefreshSelected(0);
277 }
278 
ClearValues()279 void UIPicker::ClearValues()
280 {
281     rangeValue_ = nullptr;
282     rangeValueCount_ = 0;
283     maxCount_ = 0;
284     ClearList();
285     ClearTextAdapter();
286 }
287 
ClearList()288 void UIPicker::ClearList()
289 {
290     itemsWidth_ = 0;
291     if (listListener_) {
292         listListener_->SetSelectView(nullptr);
293         listListener_->SetSelectIndex(0);
294         listListener_->SetInitStatus(false);
295     }
296     dataList_.Clear();
297 }
298 
ClearTextAdapter()299 void UIPicker::ClearTextAdapter()
300 {
301     if (textAdapter_ != nullptr) {
302         delete textAdapter_;
303         textAdapter_ = nullptr;
304     }
305     list_.SetAdapter(textAdapter_);
306     list_.RefreshList();
307     isSetAdaptered_ = false;
308 }
309 
SetSelected(uint16_t index)310 bool UIPicker::SetSelected(uint16_t index)
311 {
312     return RefreshSelected(index);
313 }
314 
RefreshSelected(uint16_t index)315 bool UIPicker::RefreshSelected(uint16_t index)
316 {
317     if (maxCount_ <= index) {
318         GRAPHIC_LOGW("Failed to refresh selected since index is beyond range!");
319         return false;
320     }
321     if (itemsHeight_ && (list_.GetChildrenHead() != nullptr) && isWidthSet_ && isHeightSet_) {
322         listListener_->SetInitStatus(false);
323         // 2: half
324         int16_t yOffset = (list_.GetHeight() - itemsHeight_) / 2 -
325                           itemsHeight_ * (index - list_.GetChildrenHead()->GetViewIndex());
326         list_.SetScrollStateListener(nullptr);
327         list_.ScrollBy(yOffset - list_.GetChildrenHead()->GetY());
328         list_.SetScrollStateListener(listListener_);
329         listListener_->SetScrollState(ListScrollListener::SCROLL_STATE_STOP);
330         UIView* childView = static_cast<UIView*>(list_.GetChildrenHead());
331         uint16_t lastSelectIndex = listListener_->GetSelectIndex();
332 
333         while (childView != nullptr) {
334             int16_t viewIndex = childView->GetViewIndex();
335             if (viewIndex == lastSelectIndex) {
336                 childView->SetStyle(STYLE_TEXT_COLOR, GetBackgroundTextColor().full);
337                 if (backgroundFontName_ == nullptr) {
338                     static_cast<UILabel*>(childView)->SetFontId(backgroundFontId_);
339                 } else {
340                     static_cast<UILabel*>(childView)->SetFont(backgroundFontName_, backgroundFontSize_);
341                 }
342             }
343             if (viewIndex == index) {
344                 childView->SetStyle(STYLE_TEXT_COLOR, GetHighlightTextColor().full);
345                 if (highlightFontName_ == nullptr) {
346                     static_cast<UILabel*>(childView)->SetFontId(highlightFontId_);
347                 } else {
348                     static_cast<UILabel*>(childView)->SetFont(highlightFontName_, highlightFontSize_);
349                 }
350                 listListener_->SetSelectView(childView);
351                 listListener_->SetInitStatus(true);
352             }
353             childView = childView->GetNextSibling();
354         }
355         listListener_->SetSelectIndex(index);
356         list_.Invalidate();
357         return true;
358     }
359     listListener_->SetSelectIndex(index);
360     return false;
361 }
362 
GetSelected() const363 uint16_t UIPicker::GetSelected() const
364 {
365     return listListener_->GetSelectIndex();
366 }
367 
SetFontId(uint16_t backgroundFontId,uint16_t highlightFontId)368 void UIPicker::SetFontId(uint16_t backgroundFontId, uint16_t highlightFontId)
369 {
370     if ((backgroundFontId == backgroundFontId_) && (highlightFontId == highlightFontId_)) {
371         return;
372     }
373     backgroundFontId_ = backgroundFontId;
374     if (backgroundFontName_ != nullptr) {
375         UIFree(backgroundFontName_);
376         backgroundFontName_ = nullptr;
377     }
378 
379     highlightFontId_ = highlightFontId;
380     if (highlightFontName_ != nullptr) {
381         UIFree(highlightFontName_);
382         highlightFontName_ = nullptr;
383     }
384 
385     Refresh();
386 }
387 
SetBackgroundFont(const char * name,uint8_t size)388 void UIPicker::SetBackgroundFont(const char* name, uint8_t size)
389 {
390     if ((name != nullptr) && (backgroundFontName_ != nullptr)) {
391         if (strcmp(name, backgroundFontName_) == 0 && size == backgroundFontSize_) {
392             return;
393         }
394     }
395     Text::SetFont(name, size, backgroundFontName_, backgroundFontSize_);
396     Refresh();
397 }
398 
SetHighlightFont(const char * name,uint8_t size)399 void UIPicker::SetHighlightFont(const char* name, uint8_t size)
400 {
401     if ((name != nullptr) && (highlightFontName_ != nullptr)) {
402         if (strcmp(name, highlightFontName_) == 0 && size == highlightFontSize_) {
403             return;
404         }
405     }
406     Text::SetFont(name, size, highlightFontName_, highlightFontSize_);
407     Refresh();
408 }
409 
SetTextColor(ColorType backgroundColor,ColorType highlightColor)410 void UIPicker::SetTextColor(ColorType backgroundColor, ColorType highlightColor)
411 {
412     if ((backgroundColor.full == backgroundColor_.full) && (highlightColor.full == highlightColor_.full)) {
413         return;
414     }
415     backgroundColor_ = backgroundColor;
416     highlightColor_ = highlightColor;
417     Refresh();
418 }
419 
SetItemHeight(int16_t height)420 void UIPicker::SetItemHeight(int16_t height)
421 {
422     if (height == itemsHeight_) {
423         return;
424     }
425     if (height > 0) {
426         itemsHeight_ = height;
427         Refresh();
428     }
429 }
430 
SetWidth(int16_t width)431 void UIPicker::SetWidth(int16_t width)
432 {
433     if (width == UIView::GetWidth()) {
434         return;
435     }
436     if (width > 0) {
437         UIView::SetWidth(width);
438         isWidthSet_ = true;
439         Refresh();
440     }
441 }
442 
SetHeight(int16_t height)443 void UIPicker::SetHeight(int16_t height)
444 {
445     if (height == UIView::GetHeight()) {
446         return;
447     }
448     if (height > 0) {
449         UIView::SetHeight(height);
450         isHeightSet_ = true;
451         Refresh();
452     }
453 }
454 
SetLoopState(bool state)455 void UIPicker::SetLoopState(bool state)
456 {
457     if (state == list_.GetLoopState()) {
458         return;
459     }
460     list_.SetLoopState(state);
461     Refresh();
462 }
463 
SetDirect(UITextLanguageDirect direct)464 void UIPicker::SetDirect(UITextLanguageDirect direct)
465 {
466     if (direct == direct_) {
467         return;
468     }
469     direct_ = direct;
470     Refresh();
471 }
472 
SetTextFormatter(TextFormatter * formatter)473 void UIPicker::SetTextFormatter(TextFormatter* formatter)
474 {
475     InitTextAdapter();
476     textAdapter_->SetTextFormatter(formatter);
477     Refresh();
478 }
479 } // namespace OHOS
480