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 /** 17 * @addtogroup UI_Components 18 * @{ 19 * 20 * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. 21 * 22 * @since 1.0 23 * @version 1.0 24 */ 25 26 /** 27 * @file ui_list.h 28 * 29 * @brief Declares a scrollable list in the vertical or horizontal direction. * This scrollable list can be used with 30 * the adapter {@link AbstractAdapter} to implement scrolling, inertial scrolling, automatic alignment, and 31 * invoking of a callback when a child view at the preset position is selected as this list scrolls. It is used 32 * when there is a large number of child views with a fixed format. 33 * 34 * @since 1.0 35 * @version 1.0 36 */ 37 38 #ifndef GRAPHIC_LITE_UI_LIST_H 39 #define GRAPHIC_LITE_UI_LIST_H 40 41 #include "components/abstract_adapter.h" 42 #include "components/ui_abstract_scroll.h" 43 #include "dock/focus_manager.h" 44 #include "dock/vibrator_manager.h" 45 #include "gfx_utils/list.h" 46 47 namespace OHOS { 48 /** 49 * @brief Represents a listener that contains a callback to be invoked when the scroll state changes or when a new child 50 * view is selected at the preset position as this list scrolls. The scroll state can be {@link 51 * SCROLL_STATE_STOP} or {@link SCROLL_STATE_MOVE}. 52 * @since 1.0 53 * @version 1.0 54 */ 55 class ListScrollListener : public HeapBase { 56 public: 57 /** 58 * @brief A constructor used to create a <b>ListScrollListener</b> instance with the default state 59 * {@link SCROLL_STATE_STOP}. 60 * @since 1.0 61 * @version 1.0 62 */ ListScrollListener()63 ListScrollListener() : state_(SCROLL_STATE_STOP) {} 64 65 /** 66 * @brief A destructor used to delete the <b>ListScrollListener</b> instance. 67 * @since 1.0 68 * @version 1.0 69 */ ~ListScrollListener()70 virtual ~ListScrollListener() {} 71 72 /** 73 * @brief Called when a scroll starts. 74 * @param index Indicates the index of the child view being selected at the preset position. This parameter should 75 * be set to {@link NULL_SELECT_INDEX} if no child view is selected or no position is preset. 76 * @param view Indicates the child view being selected at the preset position. This parameter should be set to 77 * <b>NULL</b> if no child view is selected or no position is preset. 78 * @since 1.0 79 * @version 1.0 80 */ OnScrollStart(int16_t index,UIView * view)81 virtual void OnScrollStart(int16_t index, UIView* view) {} 82 83 /** 84 * @brief Called when a scroll ends. 85 * 86 * @param index Indicates the index of the child view being selected at the preset position. This parameter should 87 * be set to {@link NULL_SELECT_INDEX} if no child view is selected or no position is preset. 88 * @param view Indicates the child view being selected at the preset position. This parameter should be set to 89 * <b>NULL</b> if no child view is selected or no position is preset. 90 * @since 1.0 91 * @version 1.0 92 * 93 */ OnScrollEnd(int16_t index,UIView * view)94 virtual void OnScrollEnd(int16_t index, UIView* view) {} 95 96 /** 97 * @brief Called when move to the top of scroll. 98 * 99 * @param index Indicates the index of the child view being selected at the preset position. This parameter should 100 * be set to {@link NULL_SELECT_INDEX} if no child view is selected or no position is preset. 101 * @param view Indicates the child view being selected at the preset position. This parameter should be set to 102 * <b>NULL</b> if no child view is selected or no position is preset. 103 * @since 8 104 * @version 8 105 * 106 */ OnScrollTop(int16_t index,UIView * view)107 virtual void OnScrollTop(int16_t index, UIView* view) {} 108 109 /** 110 * @brief Called when move to the bottom of scroll. 111 * 112 * @param index Indicates the index of the child view being selected at the preset position. This parameter should 113 * be set to {@link NULL_SELECT_INDEX} if no child view is selected or no position is preset. 114 * @param view Indicates the child view being selected at the preset position. This parameter should be set to 115 * <b>NULL</b> if no child view is selected or no position is preset. 116 * @since 8 117 * @version 8 118 * 119 */ OnScrollBottom(int16_t index,UIView * view)120 virtual void OnScrollBottom(int16_t index, UIView* view) {} 121 122 /** 123 * @brief Called when a new child view is selected at the preset position as this list scrolls. For details about 124 * how to set the position, see {@link SetSelectPosition}. 125 * 126 * @param index Indicates the index of the child view being selected at the preset position. This parameter should 127 * be set to {@link NULL_SELECT_INDEX} if no child view is selected or no position is preset. 128 * @param view Indicates the child view being selected at the preset position. This parameter should be set to 129 * <b>NULL</b> if no child view is selected or no position is preset. 130 * @since 1.0 131 * @version 1.0 132 * 133 */ OnItemSelected(int16_t index,UIView * view)134 virtual void OnItemSelected(int16_t index, UIView* view) {} 135 136 /** 137 * @brief Obtains the scroll state of this list. 138 * 139 * @return Returns the scroll state, either {@link SCROLL_STATE_STOP} or {@link SCROLL_STATE_MOVE}. 140 * @since 1.0 141 * @version 1.0 142 */ GetScrollState()143 uint8_t GetScrollState() const 144 { 145 return state_; 146 } 147 SetScrollState(uint8_t state)148 void SetScrollState(uint8_t state) 149 { 150 state_ = state; 151 } 152 153 static constexpr uint8_t SCROLL_STATE_STOP = 0; 154 static constexpr uint8_t SCROLL_STATE_MOVE = 1; 155 156 private: 157 friend class UIList; 158 uint8_t state_; 159 }; 160 161 /** 162 * @brief Represents a scrollable list which is used with the adapter {@link AbstractAdapter} to implement scrolling, 163 * inertial scrolling, automatic alignment, and invoking of a callback when a child view is selected at the 164 * preset position as this list scrolls. 165 * 166 * You need to override {@link AbstractAdapter} to implement functions for setting and saving data, obtaining data 167 * quantity, and creating child views. <b>UIList</b> is used when there is a large number of child views with a fixed 168 * format. This list automatically reclaims the child views removed out of the current view as it scrolls so that as 169 * many as child views can be displayed with a lower memory consumption. 170 * 171 * @since 1.0 172 * @version 1.0 173 */ 174 class UIList : public UIAbstractScroll { 175 public: 176 /** 177 * @brief A constructor used to create a <b>UIList</b> instance in the vertical direction. 178 * @since 1.0 179 * @version 1.0 180 */ 181 UIList(); 182 183 /** 184 * @brief A constructor used to create a <b>UIList</b> instance in the specified direction. 185 * 186 * @param direction Indicates the <b>UIList</b> direction, either {@link HORIZONTAL} or {@link VERTICAL}. 187 * @since 1.0 188 * @version 1.0 189 */ 190 explicit UIList(uint8_t direction); 191 192 /** 193 * @brief A destructor used to delete the <b>UIList</b> instance. 194 * @since 1.0 195 * @version 1.0 196 */ 197 virtual ~UIList(); 198 199 /** 200 * @brief Obtains the view type. 201 * @return Returns the view type, as defined in {@link UIViewType}. 202 * @since 1.0 203 * @version 1.0 204 */ GetViewType()205 UIViewType GetViewType() const override 206 { 207 return UI_LIST; 208 } 209 210 bool OnDragEvent(const DragEvent& event) override; 211 212 bool OnDragEndEvent(const DragEvent& event) override; 213 214 bool OnPressEvent(const PressEvent& event) override; 215 216 #if ENABLE_ROTATE_INPUT 217 bool OnRotateStartEvent(const RotateEvent& event) override; 218 219 bool OnRotateEndEvent(const RotateEvent& event) override; 220 #endif 221 222 /** 223 * @brief Sets the adapter for this list. The content of this list is initialized when the adapter is set. 224 * 225 * @param adapter Indicates the adapter to set. For details, see {@link AbstractAdapter}. 226 * @since 1.0 227 * @version 1.0 228 */ 229 void SetAdapter(AbstractAdapter* adapter); 230 231 /** 232 * @brief Moves the position of all child views. 233 * 234 * @param offsetX Indicates the offset distance by which a child view is moved on the x-axis. 235 * @param offsetY Indicates the offset distance by which a child view is moved on the y-axis. 236 * @since 1.0 237 * @version 1.0 238 */ 239 void MoveChildByOffset(int16_t x, int16_t y) override; 240 241 /** 242 * @brief Scrolls to change the index of the first row or column of the current view. 243 * 244 * @param index Indicates the new index of the first row or column of the current view. 245 * @since 1.0 246 * @version 1.0 247 */ 248 void ScrollTo(uint16_t index); 249 250 /** 251 * @brief Scrolls the content in this list. 252 * 253 * @param distance Indicates the distance by which the content is scrolled. 254 * @since 1.0 255 * @version 1.0 256 */ 257 void ScrollBy(int16_t distance); 258 259 /** 260 * @brief Sets the start index for this list. 261 * 262 * @param index Indicates the start index to set. The default value is <b>0</b>. 263 * @since 1.0 264 * @version 1.0 265 * 266 */ SetStartIndex(uint16_t index)267 void SetStartIndex(uint16_t index) 268 { 269 startIndex_ = index; 270 } 271 272 /** 273 * @brief Obtains the start index of this list. The default value is <b>0</b>. 274 * 275 * @return Returns the start index. 276 * @since 1.0 277 * @version 1.0 278 */ GetStartIndex()279 uint16_t GetStartIndex() const 280 { 281 return startIndex_; 282 } 283 284 /** 285 * @brief Sets the loop state for this list, in which a loop scroll is possible since the top and bottom of the list 286 * are connected together. 287 * 288 * @param state Indicates the loop state to set. 289 * @since 1.0 290 * @version 1.0 291 */ SetLoopState(bool state)292 void SetLoopState(bool state) 293 { 294 isLoopList_ = state; 295 } 296 297 /** 298 * @brief Checks whether this list is in a loop state. 299 * 300 * @return Returns if the list is in the loop state; returns <b>false</b> if the list is in the common state. 301 * @since 1.0 302 * @version 1.0 303 */ GetLoopState()304 bool GetLoopState() const 305 { 306 return isLoopList_; 307 } 308 309 /** 310 * @brief Sets the position where a child view is selected as this list scrolls. 311 * 312 * When a child view is selected at the specified position, the callback {@link ListScrollListener} is invoked. 313 * You can implement the zoom-in and color-change effects in the callback. 314 * 315 * @param position Indicates the position to set. The default value is <b>0</b>, indicating that no position is 316 * set. 317 * @since 1.0 318 * @version 1.0 319 */ SetSelectPosition(uint16_t position)320 void SetSelectPosition(uint16_t position) 321 { 322 selectPosition_ = position; 323 } 324 325 /** 326 * @brief Obtains the child view being selected at the preset position. 327 * 328 * @return Returns the child view if available; returns <b>NULL</b> if no child view is selected or no position is 329 * set. 330 * @since 1.0 331 * @version 1.0 332 */ 333 UIView* GetSelectView(); 334 335 /** 336 * @brief Sets the listener that contains a callback to be invoked when a child view is selected as this list 337 * scrolls. 338 * 339 * @param scrollListener Indicates the listener to set. 340 * @since 1.0 341 * @version 1.0 342 */ SetScrollStateListener(ListScrollListener * scrollListener)343 void SetScrollStateListener(ListScrollListener* scrollListener) 344 { 345 scrollListener_ = scrollListener; 346 } 347 348 /** 349 * @brief Refreshes this list. The number of child views in the current view is fixed and the positions of those 350 * reserved child views as this list scrolls remain unchanged. 351 * @since 1.0 352 * @version 1.0 353 */ 354 void RefreshList(); 355 356 /** 357 * @brief Sets the automatic alignment state for this list. When a scroll stops, a child view is selected and its 358 * position is automatically aligned with the preset position. 359 * 360 * @param state Indicates the automatic alignment state. <b>true</b> indicates this state is enabled, and 361 * <b>false</b> indicates the opposite case. 362 * @since 1.0 363 * @version 1.0 364 */ EnableAutoAlign(bool state)365 void EnableAutoAlign(bool state) 366 { 367 autoAlign_ = state; 368 } 369 370 /** 371 * @brief 372 * 设置自动对齐动画时长,单位为毫秒,默认为100毫秒。该功能依赖EnableAutoAlign()方法,自动对齐设置为true情况下才生效。 373 * 374 * @param value 自动对齐动画时长,0表示无动画。 375 * @since 3.0 376 * @version 3.0 377 */ SetAutoAlignTime(uint16_t time)378 void SetAutoAlignTime(uint16_t time) 379 { 380 alignTime_ = time; 381 } 382 383 /** 384 * @brief Sets the automatic alignment mode for this list when auto align state is enabled. 385 * 386 * @param dragBack mode of alignment. 387 * true means list item will move back when its position crosses the line of select 388 * position partly (but not all of it). 389 * false means list item will move front when its position crosses the line of select 390 * position (no matter how many it crosses). 391 * 392 * @since 3.0 393 * @version 3.0 394 */ EnableCrossDragBack(bool dragBack)395 void EnableCrossDragBack(bool dragBack) 396 { 397 dragBack_ = dragBack; 398 } 399 400 /** 401 * @brief 获取自动对齐动画时长。 402 * 403 * @return 自动对齐动画时长。 404 * @since 3.0 405 * @version 3.0 406 */ GetAutoAlignTime()407 uint16_t GetAutoAlignTime() const 408 { 409 return alignTime_; 410 } 411 412 void SetXScrollBarVisible(bool visible); 413 414 void SetYScrollBarVisible(bool visible); 415 416 void RemoveAll() override; 417 418 static constexpr int8_t NULL_SELECT_INDEX = -1; 419 420 UIView* onSelectedView_; 421 422 protected: 423 static constexpr int16_t RECALCULATE_DRAG_DISTANCE = 10; 424 static constexpr int16_t RECALCULATE_DRAG_TIMES = 10; 425 static constexpr int16_t DEFAULT_ALIGN_TIMES = 100; 426 void StopAnimator() override; 427 bool DragXInner(int16_t distance) override; 428 bool DragYInner(int16_t distance) override; 429 430 private: 431 friend class UIPicker; 432 friend class Recycle; 433 class Recycle : public HeapBase { 434 public: Recycle(UIList * list)435 explicit Recycle(UIList* list) : adapter_(nullptr), listView_(list), hasInitialiszed_(false) {} 436 virtual ~Recycle(); 437 void InitRecycle(); 438 UIView* GetView(int16_t index); SetAdapter(AbstractAdapter * adapter)439 void SetAdapter(AbstractAdapter* adapter) 440 { 441 hasInitialiszed_ = false; 442 adapter_ = adapter; 443 } 444 HasInitialiszed()445 bool HasInitialiszed() 446 { 447 return hasInitialiszed_; 448 } 449 AddScrapView(UIView * view)450 void AddScrapView(UIView* view) 451 { 452 scrapView_.PushBack(view); 453 } 454 GetAdapterItemCount()455 uint16_t GetAdapterItemCount() 456 { 457 return (adapter_ == nullptr) ? 0 : adapter_->GetCount(); 458 } 459 ClearScrapView()460 void ClearScrapView() 461 { 462 scrapView_.Clear(); 463 } 464 465 Rect32 GetAdapterItemsReletiveRect(); 466 void MoveAdapterItemsRelativeRect(int16_t x, int16_t y); 467 void MeasureAdapterRelativeRect(); 468 469 private: 470 friend class UIList; 471 void FillActiveView(); 472 473 List<UIView*> scrapView_; 474 AbstractAdapter* adapter_; 475 UIList* listView_; 476 Rect32 adapterRelativeRect_; 477 bool hasInitialiszed_; 478 }; 479 480 void PushBack(UIView* view); 481 void PopItem(UIView* view); 482 void PushFront(UIView* view); 483 void SetHead(UIView* view); 484 bool MoveChildStep(int16_t distance); 485 bool MoveChildStepVertical(int16_t distance); 486 bool MoveChildStepHorizontal(int16_t distance); 487 uint16_t GetIndexInc(uint16_t index); 488 uint16_t GetIndexDec(uint16_t index); 489 490 bool MoveOffset(int16_t x, int16_t y); 491 void UpdateScrollBar(); 492 bool IsNeedReCalculateDragEnd(); 493 bool ReCalculateDragEnd(); 494 void CalculateReboundDistance(int16_t& dragDistanceX, int16_t& dragDistanceY) override; 495 void FixDistance(int16_t& distanceX, int16_t& distanceY) override; 496 void FixHorDistance(int16_t& distanceX); 497 void FixVerDistance(int16_t& distanceY); 498 bool isLoopList_; 499 bool isReCalculateDragEnd_; 500 bool autoAlign_; 501 uint16_t alignTime_; 502 uint16_t startIndex_; 503 uint16_t topIndex_; 504 uint16_t bottomIndex_; 505 uint16_t selectPosition_; 506 int16_t onSelectedIndex_; 507 Recycle recycle_; 508 ListScrollListener* scrollListener_; 509 }; 510 } // namespace OHOS 511 #endif // GRAPHIC_LITE_UI_LIST_H 512