• 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     textAdapter_->SetData(start, end);
217     RefreshList();
218     RefreshSelected(userSelectIndex);
219     return true;
220 }
221 
RefreshValues(const char * value[],uint16_t count)222 bool UIPicker::RefreshValues(const char* value[], uint16_t count)
223 {
224     if (value == nullptr) {
225         return false;
226     }
227     maxCount_ = count;
228     if (!isWidthSet_ || !isHeightSet_ || !itemsHeight_) {
229         return false;
230     }
231     uint16_t userSelectIndex = listListener_->GetSelectIndex();
232     ClearList();
233     for (uint16_t i = 0; i < count; i++) {
234         dataList_.PushBack(value[i]);
235     }
236     InitTextAdapter();
237     textAdapter_->SetData(&dataList_);
238     RefreshList();
239     RefreshSelected(userSelectIndex);
240 
241     return true;
242 }
243 
RefreshList()244 void UIPicker::RefreshList()
245 {
246     int16_t height = GetHeight();
247     itemsWidth_ = GetWidth();
248     textAdapter_->SetWidth(itemsWidth_);
249     textAdapter_->SetHeight(itemsHeight_);
250     textAdapter_->SetLineBreakMode(UILabel::LINE_BREAK_CLIP);
251     if (backgroundFontName_ == nullptr) {
252         textAdapter_->SetFontId(backgroundFontId_);
253     } else {
254         textAdapter_->SetFont(backgroundFontName_, backgroundFontSize_);
255     }
256     textAdapter_->GetStyle().textColor_ = backgroundColor_;
257     textAdapter_->SetDirect(direct_);
258     list_.SetHeight(height);
259     list_.SetWidth(itemsWidth_);
260     list_.LayoutCenterOfParent();
261     list_.SetSelectPosition(height / 2);                   // 2: half
262     if (isScrollBlankSizeSet_) {
263         list_.SetScrollBlankSize(scrollBlankSize_);
264     } else {
265         list_.SetScrollBlankSize((height - itemsHeight_) / 2); // 2: half
266     }
267     if (!isSetAdaptered_) {
268         list_.SetAdapter(textAdapter_);
269         isSetAdaptered_ = true;
270     }
271 
272     list_.RefreshList();
273     RefreshSelected(0);
274 }
275 
ClearValues()276 void UIPicker::ClearValues()
277 {
278     rangeValue_ = nullptr;
279     rangeValueCount_ = 0;
280     maxCount_ = 0;
281     ClearList();
282     ClearTextAdapter();
283 }
284 
ClearList()285 void UIPicker::ClearList()
286 {
287     itemsWidth_ = 0;
288     if (listListener_) {
289         listListener_->SetSelectView(nullptr);
290         listListener_->SetSelectIndex(0);
291         listListener_->SetInitStatus(false);
292     }
293     dataList_.Clear();
294 }
295 
ClearTextAdapter()296 void UIPicker::ClearTextAdapter()
297 {
298     if (textAdapter_ != nullptr) {
299         delete textAdapter_;
300         textAdapter_ = nullptr;
301     }
302     list_.SetAdapter(textAdapter_);
303     list_.RefreshList();
304     isSetAdaptered_ = false;
305 }
306 
SetSelected(uint16_t index)307 bool UIPicker::SetSelected(uint16_t index)
308 {
309     return RefreshSelected(index);
310 }
311 
RefreshSelected(uint16_t index)312 bool UIPicker::RefreshSelected(uint16_t index)
313 {
314     if (maxCount_ <= index) {
315         GRAPHIC_LOGW("Failed to refresh selected since index is beyond range!");
316         return false;
317     }
318     if (itemsHeight_ && (list_.GetChildrenHead() != nullptr) && isWidthSet_ && isHeightSet_) {
319         listListener_->SetInitStatus(false);
320         // 2: half
321         int16_t yOffset = (list_.GetHeight() - itemsHeight_) / 2 -
322                           itemsHeight_ * (index - list_.GetChildrenHead()->GetViewIndex());
323         list_.SetScrollStateListener(nullptr);
324         list_.ScrollBy(yOffset - list_.GetChildrenHead()->GetY());
325         list_.SetScrollStateListener(listListener_);
326         listListener_->SetScrollState(ListScrollListener::SCROLL_STATE_STOP);
327         UIView* childView = static_cast<UIView*>(list_.GetChildrenHead());
328         uint16_t lastSelectIndex = listListener_->GetSelectIndex();
329 
330         while (childView != nullptr) {
331             int16_t viewIndex = childView->GetViewIndex();
332             if (viewIndex == lastSelectIndex) {
333                 childView->SetStyle(STYLE_TEXT_COLOR, GetBackgroundTextColor().full);
334                 if (backgroundFontName_ == nullptr) {
335                     static_cast<UILabel*>(childView)->SetFontId(backgroundFontId_);
336                 } else {
337                     static_cast<UILabel*>(childView)->SetFont(backgroundFontName_, backgroundFontSize_);
338                 }
339             }
340             if (viewIndex == index) {
341                 childView->SetStyle(STYLE_TEXT_COLOR, GetHighlightTextColor().full);
342                 if (highlightFontName_ == nullptr) {
343                     static_cast<UILabel*>(childView)->SetFontId(highlightFontId_);
344                 } else {
345                     static_cast<UILabel*>(childView)->SetFont(highlightFontName_, highlightFontSize_);
346                 }
347                 listListener_->SetSelectView(childView);
348                 listListener_->SetInitStatus(true);
349             }
350             childView = childView->GetNextSibling();
351         }
352         listListener_->SetSelectIndex(index);
353         list_.Invalidate();
354         return true;
355     }
356     listListener_->SetSelectIndex(index);
357     return false;
358 }
359 
GetSelected() const360 uint16_t UIPicker::GetSelected() const
361 {
362     return listListener_->GetSelectIndex();
363 }
364 
SetFontId(uint16_t backgroundFontId,uint16_t highlightFontId)365 void UIPicker::SetFontId(uint16_t backgroundFontId, uint16_t highlightFontId)
366 {
367     backgroundFontId_ = backgroundFontId;
368     if (backgroundFontName_ != nullptr) {
369         UIFree(backgroundFontName_);
370         backgroundFontName_ = nullptr;
371     }
372 
373     highlightFontId_ = highlightFontId;
374     if (highlightFontName_ != nullptr) {
375         UIFree(highlightFontName_);
376         highlightFontName_ = nullptr;
377     }
378 
379     Refresh();
380 }
381 
SetBackgroundFont(const char * name,uint8_t size)382 void UIPicker::SetBackgroundFont(const char* name, uint8_t size)
383 {
384     Text::SetFont(name, size, backgroundFontName_, backgroundFontSize_);
385     Refresh();
386 }
387 
SetHighlightFont(const char * name,uint8_t size)388 void UIPicker::SetHighlightFont(const char* name, uint8_t size)
389 {
390     Text::SetFont(name, size, highlightFontName_, highlightFontSize_);
391     Refresh();
392 }
393 
SetTextColor(ColorType backgroundColor,ColorType highlightColor)394 void UIPicker::SetTextColor(ColorType backgroundColor, ColorType highlightColor)
395 {
396     backgroundColor_ = backgroundColor;
397     highlightColor_ = highlightColor;
398     Refresh();
399 }
400 
SetItemHeight(int16_t height)401 void UIPicker::SetItemHeight(int16_t height)
402 {
403     if (height > 0) {
404         itemsHeight_ = height;
405         Refresh();
406     }
407 }
408 
SetWidth(int16_t width)409 void UIPicker::SetWidth(int16_t width)
410 {
411     if (width > 0) {
412         UIView::SetWidth(width);
413         isWidthSet_ = true;
414         Refresh();
415     }
416 }
417 
SetHeight(int16_t height)418 void UIPicker::SetHeight(int16_t height)
419 {
420     if (height > 0) {
421         UIView::SetHeight(height);
422         isHeightSet_ = true;
423         Refresh();
424     }
425 }
426 
SetLoopState(bool state)427 void UIPicker::SetLoopState(bool state)
428 {
429     list_.SetLoopState(state);
430     Refresh();
431 }
432 
SetDirect(UITextLanguageDirect direct)433 void UIPicker::SetDirect(UITextLanguageDirect direct)
434 {
435     direct_ = direct;
436     Refresh();
437 }
438 
SetTextFormatter(TextFormatter * formatter)439 void UIPicker::SetTextFormatter(TextFormatter* formatter)
440 {
441     InitTextAdapter();
442     textAdapter_->SetTextFormatter(formatter);
443     Refresh();
444 }
445 } // namespace OHOS
446