FINAL CUT
flistview.h
1 /***********************************************************************
2 * flistview.h - Widget FListView and FListViewItem *
3 * *
4 * This file is part of the FINAL CUT widget toolkit *
5 * *
6 * Copyright 2017-2026 Markus Gans *
7 * *
8 * FINAL CUT is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as *
10 * published by the Free Software Foundation; either version 3 of *
11 * the License, or (at your option) any later version. *
12 * *
13 * FINAL CUT is distributed in the hope that it will be useful, but *
14 * WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this program. If not, see *
20 * <http://www.gnu.org/licenses/>. *
21 ***********************************************************************/
22 
23 /* Inheritance diagram
24  * ═══════════════════
25  *
26  * ▕▔▔▔▔▔▔▔▔▔▏ ▕▔▔▔▔▔▔▔▔▔▏
27  * ▕ FVTerm ▏ ▕ FObject ▏
28  * ▕▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▏
29  * ▲ ▲
30  * │ │
31  * └─────┬─────┘
32  * │
33  * ▕▔▔▔▔▔▔▔▔▔▏ ▕▔▔▔▔▔▔▔▔▔▏
34  * ▕ FWidget ▏ ▕ FObject ▏
35  * ▕▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▏
36  * ▲ ▲
37  * │ │
38  * ▕▔▔▔▔▔▔▔▔▔▔▔▏1 *▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏1 1▕▔▔▔▔▔▔▔▏
39  * ▕ FListView ▏- - - -▕ FListViewItem ▏- - - -▕ FData ▏
40  * ▕▁▁▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▏
41  */
42 
43 #ifndef FLISTVIEW_H
44 #define FLISTVIEW_H
45 
46 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
47  #error "Only <final/final.h> can be included directly."
48 #endif
49 
50 #include <iterator>
51 #include <memory>
52 #include <stack>
53 #include <unordered_map>
54 #include <utility>
55 #include <vector>
56 
57 #include "final/ftypes.h"
58 #include "final/fwidget.h"
59 #include "final/util/fdata.h"
60 #include "final/vterm/fvtermbuffer.h"
61 #include "final/widget/fscrollbar.h"
62 
63 namespace finalcut
64 {
65 
66 // class forward declaration
67 class FListView;
68 class FScrollBar;
69 class FString;
70 
71 //----------------------------------------------------------------------
72 // class FListViewItem
73 //----------------------------------------------------------------------
74 
75 class FListViewItem : public FObject
76 {
77  public:
78  // Constructor
79  explicit FListViewItem (iterator);
80  template <typename DT>
81  FListViewItem (const FStringList&, DT&&, iterator);
82 
83  // copy constructor
85 
86  // Destructor
87  ~FListViewItem() override;
88 
89  // copy assignment operator (=)
90  auto operator = (const FListViewItem&) -> FListViewItem&;
91 
92  // Accessors
93  auto getClassName() const -> FString override;
94  auto getColumnCount() const -> uInt;
95  auto getSortColumn() const -> int;
96  auto getText (int) const -> FString;
97  template <typename DT>
98  auto getData() const -> clean_fdata_t<DT>&;
99  auto getDepth() const -> uInt;
100 
101  // Mutators
102  void setText (int, const FString&);
103  template <typename DT>
104  void setData (DT&&);
105  void setCheckable (bool = true);
106  void setChecked (bool = true);
107 
108  // Predicate
109  auto isChecked() const -> bool;
110  auto isExpand() const -> bool;
111 
112  // Methods
113  auto insert (FListViewItem*) -> iterator;
114  auto insert (FListViewItem*, iterator) const -> iterator;
115  void remove (FListViewItem*) const;
116  void expand();
117  void collapse();
118 
119  private:
120  // Using-declaration
121  using FDataAccessPtr = std::shared_ptr<FDataAccess>;
122 
123  // Predicate
124  auto isExpandable() const -> bool;
125  auto isCheckable() const -> bool;
126 
127  // Methods
128  template <typename Compare>
129  void sort (Compare);
130  auto appendItem (FListViewItem*) -> iterator;
131  auto getFListViewOwner() const -> FListView*;
132  void replaceControlCodes();
133  auto getVisibleLines() -> std::size_t;
134  void resetVisibleLineCounter();
135 
136  // Data members
137  FStringList column_list{};
138  FDataAccessPtr data_pointer{};
139  iterator root{};
140  std::size_t visible_lines{1};
141  bool expandable{false};
142  bool is_expand{false};
143  bool checkable{false};
144  bool is_checked{false};
145 
146  // Friend class
147  friend class FListView;
148  friend class FListViewIterator;
149 };
150 
151 
152 // FListViewItem inline functions
153 //----------------------------------------------------------------------
154 template <typename DT>
155 inline FListViewItem::FListViewItem ( const FStringList& cols
156  , DT&& data
157  , iterator parent_iter )
158  : FObject{nullptr}
159  , column_list{cols}
160  , data_pointer{makeFData(std::forward<DT>(data))}
161 {
162  if ( cols.empty() )
163  return;
164 
165  replaceControlCodes();
166  insert (this, parent_iter);
167 }
168 
169 //----------------------------------------------------------------------
170 inline auto FListViewItem::getClassName() const -> FString
171 { return "FListViewItem"; }
172 
173 //----------------------------------------------------------------------
174 inline auto FListViewItem::getColumnCount() const -> uInt
175 { return static_cast<uInt>(column_list.size()); }
176 
177 //----------------------------------------------------------------------
178 template <typename DT>
179 inline auto FListViewItem::getData() const -> clean_fdata_t<DT>&
180 {
181  return static_cast<FData<clean_fdata_t<DT>>&>(*data_pointer).get();
182 }
183 
184 //----------------------------------------------------------------------
185 template <typename DT>
186 inline void FListViewItem::setData (DT&& data)
187 {
188  auto data_obj = makeFData(std::forward<DT>(data));
189  data_pointer = std::move(data_obj);
190 }
191 
192 //----------------------------------------------------------------------
193 inline void FListViewItem::setChecked (bool checked)
194 { is_checked = checked; }
195 
196 //----------------------------------------------------------------------
197 inline auto FListViewItem::isChecked() const -> bool
198 { return is_checked; }
199 
200 //----------------------------------------------------------------------
201 inline auto FListViewItem::isExpand() const -> bool
202 { return is_expand; }
203 
204 //----------------------------------------------------------------------
205 inline auto FListViewItem::isExpandable() const -> bool
206 { return expandable; }
207 
208 //----------------------------------------------------------------------
209 inline auto FListViewItem::isCheckable() const -> bool
210 { return checkable; }
211 
212 
213 //----------------------------------------------------------------------
214 // class FListViewIterator
215 //----------------------------------------------------------------------
216 
218 {
219  public:
220  // Using-declarations
221  using FObjectList = std::vector<FObject*>;
222  using Iterator = FObjectList::iterator;
223  using IteratorStack = std::stack<Iterator>;
224 
225  // Constructor
226  FListViewIterator () = default;
227  ~FListViewIterator () = default;
228  explicit FListViewIterator (Iterator);
229  FListViewIterator (const FListViewIterator&) = default;
230  FListViewIterator (FListViewIterator&& i) noexcept
231  : iter_path{std::move(i.iter_path)}
232  , node{i.node}
233  , position{i.position}
234  { }
235 
236  // Overloaded operators
237  auto operator = (const FListViewIterator&) -> FListViewIterator& = default;
238  auto operator = (FListViewIterator&&) noexcept -> FListViewIterator& = default;
239  auto operator = (Iterator iter) -> FListViewIterator&;
240  auto operator ++ () -> FListViewIterator&; // prefix
241  auto operator ++ (int) -> FListViewIterator; // postfix
242  auto operator -- () -> FListViewIterator&; // prefix
243  auto operator -- (int) -> FListViewIterator; // postfix
244  auto operator += (int) -> FListViewIterator&;
245  auto operator -= (int) -> FListViewIterator&;
246  auto operator * () const -> FObject*&;
247  auto operator -> () const -> FObject*;
248 
249  friend inline auto operator == ( const FListViewIterator& lhs
250  , const FListViewIterator& rhs ) -> bool
251  {
252  return lhs.node == rhs.node;
253  }
254 
255  friend inline auto operator != ( const FListViewIterator& lhs
256  , const FListViewIterator& rhs ) -> bool
257  {
258  return lhs.node != rhs.node;
259  }
260 
261  friend inline auto operator == ( const FListViewIterator& listview_iter
262  , const Iterator& iter) -> bool
263  {
264  return listview_iter.node == iter;
265  }
266 
267  friend inline auto operator != ( const FListViewIterator& listview_iter
268  , const Iterator& iter) -> bool
269  {
270  return listview_iter.node != iter;
271  }
272 
273  // Accessor
274  auto getClassName() const -> FString;
275  auto getPosition() -> int&;
276 
277  // Methods
278  void parentElement();
279 
280  // Friend Non-member operator functions
281  friend auto operator + (const FListViewIterator& lhs, int n) -> FListViewIterator
282  {
283  auto tmp = lhs;
284 
285  for (int i = n; i > 0 ; i--)
286  tmp.nextElement(tmp.node);
287 
288  return tmp;
289  }
290 
291  friend auto operator - (const FListViewIterator& lhs, int n) -> FListViewIterator
292  {
293  auto tmp = lhs;
294 
295  for (int i = n; i > 0 ; i--)
296  tmp.prevElement(tmp.node);
297 
298  return tmp;
299  }
300 
301  private:
302  // Predicate
303  auto isRootLevel() const noexcept -> bool
304  {
305  return iter_path.empty();
306  }
307 
308  // Methods
309  void nextElement (Iterator&);
310  void prevElement (Iterator&);
311 
312  // Data members
313  IteratorStack iter_path{};
314  Iterator node{};
315  int position{0};
316 };
317 
318 
319 // FListViewIterator inline functions
320 //----------------------------------------------------------------------
321 inline auto FListViewIterator::operator * () const -> FObject*&
322 { return *node; }
323 
324 //----------------------------------------------------------------------
325 inline auto FListViewIterator::operator -> () const -> FObject*
326 { return *node; }
327 
328 //----------------------------------------------------------------------
329 inline auto FListViewIterator::getClassName() const -> FString
330 { return "FListViewIterator"; }
331 
332 //----------------------------------------------------------------------
333 inline auto FListViewIterator::getPosition() -> int&
334 { return position; }
335 
336 
337 //----------------------------------------------------------------------
338 // class FListView
339 //----------------------------------------------------------------------
340 
341 class FListView : public FWidget
342 {
343  public:
344  // Using-declaration
345  using FWidget::setGeometry;
346  using FListViewItems = std::vector<FListViewItem*>;
347 
348  // Disable copy constructor
349  FListView (const FListView&) = delete;
350 
351  // Disable move constructor
352  FListView (FListView&&) noexcept = delete;
353 
354  // Constructor
355  explicit FListView (FWidget* = nullptr);
356 
357  // Destructor
358  ~FListView() override;
359 
360  // Disable copy assignment operator (=)
361  auto operator = (const FListView&) -> FListView& = delete;
362 
363  // Disable move assignment operator (=)
364  auto operator = (FListView&&) noexcept -> FListView& = delete;
365 
366  // Accessors
367  auto getClassName() const -> FString override;
368  auto getCount() const -> std::size_t;
369  auto getColumnCount() const -> std::size_t;
370  auto getColumnAlignment (int) const -> Align;
371  auto getColumnText (int) const -> FString;
372  auto getColumnSortType (int) const -> SortType;
373  auto getSortOrder() const -> SortOrder;
374  auto getSortColumn() const -> int;
375  auto getCurrentItem() -> FListViewItem*;
376 
377  // Mutators
378  void setSize (const FSize&, bool = true) override;
379  void setGeometry ( const FPoint&, const FSize&
380  , bool = true ) override;
381  void setColumnAlignment (int, Align);
382  void setColumnText (int, const FString&);
383  void setColumnSortType (int, SortType = SortType::Name);
384  void setColumnSort (int, SortOrder = SortOrder::Ascending);
385  template <typename Compare>
386  void setUserAscendingCompare (Compare);
387  template <typename Compare>
388  void setUserDescendingCompare (Compare);
389  void hideSortIndicator (bool = true);
390  void showColumn (int);
391  void hideColumn (int);
392  void setTreeView (bool = true);
393  void unsetTreeView();
394 
395  // Predicate
396  auto isColumnHidden (int) const -> bool;
397 
398  // Methods
399  virtual auto addColumn (const FString&, int = USE_MAX_SIZE) -> int;
400  virtual auto removeColumn (int) -> int;
401  void removeAllColumns();
402  void hide() override;
403  void firstPos();
404  void lastPos();
405  void stepForward();
406  void stepBackward();
407  void stepForward (int);
408  void stepBackward (int);
409  auto insert (FListViewItem*) -> iterator;
410  auto insert (FListViewItem*, iterator) -> iterator;
411  template <typename DT = std::nullptr_t>
412  auto insert (const FStringList&, DT&& = DT()) -> iterator;
413  auto insert (const FStringList&, iterator) -> iterator;
414  template <typename DT>
415  auto insert (const FStringList&, DT&&, iterator) -> iterator;
416  template <typename T
417  , typename DT = std::nullptr_t>
418  auto insert (const std::initializer_list<T>&, DT&& = DT()) -> iterator;
419  template <typename T>
420  auto insert (const std::initializer_list<T>&, iterator) -> iterator;
421  template <typename T
422  , typename DT>
423  auto insert (const std::initializer_list<T>&, DT&&, iterator) -> iterator;
424  template <typename ColT
425  , typename DT = std::nullptr_t>
426  auto insert (const std::vector<ColT>&, DT&& = DT()) -> iterator;
427  template <typename ColT>
428  auto insert (const std::vector<ColT>&, iterator) -> iterator;
429  template <typename ColT
430  , typename DT>
431  auto insert (const std::vector<ColT>&, DT&&, iterator) -> iterator;
432  void remove (FListViewItem*);
433  void clear();
434  auto getData() & -> FListViewItems&;
435  auto getData() const & -> const FListViewItems&;
436 
437  virtual void sort();
438 
439  // Event handlers
440  void onKeyPress (FKeyEvent*) override;
441  void onMouseDown (FMouseEvent*) override;
442  void onMouseUp (FMouseEvent*) override;
443  void onMouseMove (FMouseEvent*) override;
444  void onMouseDoubleClick (FMouseEvent*) override;
445  void onWheel (FWheelEvent*) override;
446  void onTimer (FTimerEvent*) override;
447  void onFocusOut (FFocusEvent*) override;
448 
449  protected:
450  // Methods
451  void initLayout() override;
452  void adjustViewport (const int);
453  void adjustScrollBars (const std::size_t) const;
454  void adjustSize() override;
455 
456  private:
457  struct Header; // forward declaration
458 
459  // Using-declaration
460  using KeyMap = std::unordered_map<FKey, std::function<void()>, EnumHash<FKey>>;
461  using KeyMapResult = std::unordered_map<FKey, std::function<bool()>, EnumHash<FKey>>;
462  using HeaderItems = std::vector<Header>;
463  using SortTypes = std::vector<SortType>;
464 
465  struct ListViewData
466  {
467  iterator root{};
468  FObjectList selflist{};
469  FObjectList itemlist{};
470  HeaderItems header; // GitHub issues #122
471  FVTermBuffer headerline{};
472  KeyMap key_map{};
473  KeyMapResult key_map_result{};
474  };
475 
476  struct SelectionState
477  {
478  FListViewIterator current_iter{};
479  const FListViewItem* clicked_checkbox_item{nullptr};
480  FPoint clicked_expander_pos{-1, -1};
481  FPoint clicked_header_pos{-1, -1};
482  };
483 
484  struct SortState
485  {
486  int column{-1};
487  SortTypes type{};
488  SortOrder order{SortOrder::Unsorted};
489  bool hide_sort_indicator{false};
490  };
491 
492  struct ScrollingState
493  {
494  FScrollBarPtr vbar{nullptr};
495  FScrollBarPtr hbar{nullptr};
496  FListViewIterator first_visible_line{};
497  FListViewIterator last_visible_line{};
498  int first_line_position_before{-1};
499  int xoffset{0};
500  bool timer{false};
501  int repeat{100};
502  int distance{1};
503  };
504 
505  // Constants
506  static constexpr std::size_t checkbox_space = 4;
507 
508  // Constants
509  static constexpr int USE_MAX_SIZE = -1;
510 
511  // Accessors
512  auto getNullIterator() -> iterator;
513 
514  // Mutators
515  static void setNullIterator (const iterator&);
516 
517  // Predicate
518  auto isHorizontallyScrollable() const -> bool;
519  auto isVerticallyScrollable() const -> bool;
520  auto canSkipListDrawing() const -> bool;
521  auto canSkipDragScrolling() -> bool;
522  auto isLayoutInitialized() const -> bool;
523 
524  // Methods
525  void init();
526  void mapKeyFunctions();
527  void processKeyAction (FKeyEvent*);
528  template <typename Compare>
529  void sort (Compare);
530  auto getAlignOffset ( const Align
531  , const std::size_t
532  , const std::size_t ) const -> std::size_t;
533  auto getListEnd (const FListViewItem*) -> iterator;
534  void draw() override;
535  void drawBorder() override;
536  void drawScrollBars() const;
537  void drawHeadlines();
538  void drawList();
539  void setInputCursor (const FListViewItem*, int, bool);
540  void finalizeListDrawing (volatile int);
541  void adjustWidthForTreeView (std::size_t&, std::size_t, bool) const;
542  void drawListLine (const FListViewItem*, bool, bool);
543  auto createColumnsString (const FListViewItem*) -> FString;
544  void printColumnsString (FString&);
545  void clearList();
546  void setLineAttributes (bool, bool) const;
547  auto getCheckBox (const FListViewItem* item) const -> FString;
548  auto getLinePrefix (const FListViewItem*, std::size_t) const -> FString;
549  void drawSortIndicator (std::size_t&, std::size_t);
550  void drawHeadlineLabel (const HeaderItems::const_iterator&);
551  void drawHeaderBorder (std::size_t);
552  auto findHeaderStartPos (bool&) -> FVTermBuffer::iterator;
553  auto findHeaderEndPos (FVTermBuffer::iterator, bool, bool&) -> FVTermBuffer::iterator;
554  void drawBufferedHeadline();
555  void drawColumnEllipsis ( const HeaderItems::const_iterator&
556  , const FString& );
557  void updateLayout();
558  void updateDrawing (bool, bool);
559  auto determineLineWidth (FListViewItem*) -> std::size_t;
560  void beforeInsertion (FListViewItem*);
561  void afterInsertion();
562  void adjustListBeforeRemoval (const FListViewItem*);
563  void removeItemFromParent (FListViewItem*);
564  void updateListAfterRemoval();
565  void recalculateHorizontalBar (std::size_t);
566  void recalculateVerticalBar (std::size_t) const;
567  void mouseHeaderClicked();
568  auto getHeaderClickWidth (const Header&, int) const -> int;
569  auto isPositionWithinHeader (int, int, int) const -> bool;
570  void handleColumnSort (int);
571  void handleTreeExpanderClick (const FMouseEvent*);
572  void handleCheckboxClick (const FMouseEvent*);
573  void wheelUp (int);
574  void wheelDown (int);
575  void wheelLeft (int);
576  void wheelRight (int);
577  auto dragScrollUp (int) -> bool;
578  auto dragScrollDown (int) -> bool;
579  void dragUp (MouseButton);
580  void dragDown (MouseButton);
581  void stopDragScroll();
582  void toggleItemExpandState (FListViewItem*) const;
583  void toggleItemCheckState (FListViewItem*) const;
584  auto isCheckboxClicked (int, int) const -> bool;
585  void resetClickedPositions();
586  auto isWithinHeaderBounds (const FPoint&) const -> bool;
587  auto isWithinListBounds (const FPoint&) const -> bool;
588  auto appendItem (FListViewItem*) -> iterator;
589  void handleListEvent (const FMouseEvent*);
590  void handleTreeViewEvents (const FMouseEvent*, const FListViewItem*);
591  void handleCheckableItemsEvents (const FMouseEvent*, const FListViewItem*);
592  void processClick() const;
593  void processRowChanged() const;
594  void processChanged() const;
595  void changeOnResize() const;
596  void toggleCheckbox();
597  void collapseAndScrollLeft();
598  void jumpToParentElement (const FListViewItem*);
599  void expandAndScrollRight();
600  void firstPos_impl();
601  void lastPos_impl();
602  auto expandSubtree() -> bool;
603  auto collapseSubtree() -> bool;
604  void setRelativePosition (int);
605  void stepForward_impl();
606  void stepBackward_impl();
607  void stepForward_impl (int);
608  void stepBackward_impl (int);
609  void scrollToX (int);
610  void scrollToY (int);
611  void scrollTo (const FPoint&);
612  void scrollTo (int, int);
613  void scrollBy (int, int);
614  auto isItemListEmpty() const -> bool;
615  auto isTreeView() const -> bool;
616  auto isColumnIndexInvalid (int) const -> bool;
617  auto hasCheckableItems() const -> bool;
618  auto getScrollBarMaxHorizontal() const noexcept -> int;
619  auto getScrollBarMaxVertical (const std::size_t) const noexcept -> int;
620  void updateViewAfterVBarChange (const FScrollBar::ScrollType);
621  void updateViewAfterHBarChange (const FScrollBar::ScrollType, const int);
622  auto getVerticalScrollDistance (const FScrollBar::ScrollType) const -> int;
623  auto getHorizontalScrollDistance (const FScrollBar::ScrollType) const -> int;
624 
625  // Callback methods
626  void cb_vbarChange (const FWidget*);
627  void cb_hbarChange (const FWidget*);
628 
629  // Data members
630  std::size_t nf_offset{0};
631  std::size_t max_line_width{1};
632  bool tree_view{false};
633  bool has_checkable_items{false};
634  ListViewData data{};
635  SortState sorting{};
636  ScrollingState scroll{};
637  SelectionState selection{};
638  DragScrollMode drag_scroll{DragScrollMode::None};
639 
640  // Function Pointer
641  bool (*user_defined_ascending) (const FObject*, const FObject*){nullptr};
642  bool (*user_defined_descending) (const FObject*, const FObject*){nullptr};
643 
644  // Friend class
645  friend class FListViewItem;
646  friend class FListViewIterator;
647 };
648 
649 
650 //----------------------------------------------------------------------
651 // struct FListView::Header
652 //----------------------------------------------------------------------
653 
655 {
656  public:
657  Header() = default;
658 
659  FString name{};
660  Align alignment{Align::Left};
661  int width{0};
662  bool fixed_width{false};
663  bool visible{true};
664 };
665 
666 
667 // FListView inline functions
668 //----------------------------------------------------------------------
669 inline auto FListView::getClassName() const -> FString
670 { return "FListView"; }
671 
672 //----------------------------------------------------------------------
673 inline auto FListView::getSortOrder() const -> SortOrder
674 { return sorting.order; }
675 
676 //----------------------------------------------------------------------
677 inline auto FListView::getSortColumn() const -> int
678 { return sorting.column; }
679 
680 //----------------------------------------------------------------------
681 inline auto FListView::getCurrentItem() -> FListViewItem*
682 { return static_cast<FListViewItem*>(*selection.current_iter); }
683 
684 //----------------------------------------------------------------------
685 template <typename Compare>
686 inline void FListView::setUserAscendingCompare (Compare cmp)
687 { user_defined_ascending = cmp; }
688 
689 //----------------------------------------------------------------------
690 template <typename Compare>
691 inline void FListView::setUserDescendingCompare (Compare cmp)
692 { user_defined_descending = cmp; }
693 
694 //----------------------------------------------------------------------
695 inline void FListView::hideSortIndicator (bool hide)
696 { sorting.hide_sort_indicator = hide; }
697 
698 //----------------------------------------------------------------------
699 inline void FListView::setTreeView (bool enable)
700 { tree_view = enable; }
701 
702 //----------------------------------------------------------------------
703 inline void FListView::unsetTreeView()
704 { setTreeView(false); }
705 
706 //----------------------------------------------------------------------
707 inline auto FListView::insert (FListViewItem* item) -> FObject::iterator
708 { return insert (item, data.root); }
709 
710 //----------------------------------------------------------------------
711 template <typename DT>
712 inline auto
713  FListView::insert (const FStringList& cols, DT&& d) -> FObject::iterator
714 { return insert (cols, std::forward<DT>(d), data.root); }
715 
716 //----------------------------------------------------------------------
717 inline auto
718  FListView::insert ( const FStringList& cols
719  , iterator parent_iter ) -> FObject::iterator
720 { return insert (cols, nullptr, parent_iter); }
721 
722 //----------------------------------------------------------------------
723 template <typename DT>
724 inline auto FListView::insert ( const FStringList& cols
725  , DT&& d
726  , iterator parent_iter ) -> FObject::iterator
727 {
728  FListViewItem* item;
729 
730  if ( cols.empty() || parent_iter == getNullIterator() )
731  return getNullIterator();
732 
733  if ( ! *parent_iter )
734  parent_iter = data.root;
735 
736  try
737  {
738  item = new FListViewItem (cols, std::forward<DT>(d), getNullIterator());
739  }
740  catch (const std::bad_alloc&)
741  {
742  badAllocOutput ("FListViewItem");
743  return getNullIterator();
744  }
745 
746  item->replaceControlCodes();
747  return insert(item, parent_iter);
748 }
749 
750 //----------------------------------------------------------------------
751 template <typename T
752  , typename DT>
753 inline auto
754  FListView::insert (const std::initializer_list<T>& list, DT&& d) -> FObject::iterator
755 { return insert (list, std::forward<DT>(d), data.root); }
756 
757 //----------------------------------------------------------------------
758 template <typename T>
759 inline auto
760  FListView::insert ( const std::initializer_list<T>& list
761  , iterator parent_iter ) -> FObject::iterator
762 { return insert (list, 0, parent_iter); }
763 
764 //----------------------------------------------------------------------
765 template <typename T
766  , typename DT>
767 auto FListView::insert ( const std::initializer_list<T>& list
768  , DT&& d
769  , iterator parent_iter ) -> FObject::iterator
770 {
771  FStringList str_cols;
772 
773  std::transform ( std::begin(list)
774  , std::end(list)
775  , std::back_inserter(str_cols)
776  , [] (const auto& col)
777  {
778  const FString s(FString() << col);
779  return s;
780  }
781  );
782 
783  auto item_iter = insert (str_cols, std::forward<DT>(d), parent_iter);
784  return item_iter;
785 }
786 
787 //----------------------------------------------------------------------
788 template <typename ColT
789  , typename DT>
790 inline auto
791  FListView::insert (const std::vector<ColT>& cols, DT&& d) -> FObject::iterator
792 { return insert (cols, std::forward<DT>(d), data.root); }
793 
794 //----------------------------------------------------------------------
795 template <typename ColT>
796 inline auto
797  FListView::insert ( const std::vector<ColT>& cols
798  , iterator parent_iter ) -> FObject::iterator
799 { return insert (cols, 0, parent_iter); }
800 
801 //----------------------------------------------------------------------
802 template <typename ColT
803  , typename DT>
804 auto
805  FListView::insert ( const std::vector<ColT>& cols
806  , DT&& d
807  , iterator parent_iter ) -> FObject::iterator
808 {
809  FStringList str_cols;
810 
811  std::transform ( std::begin(cols)
812  , std::end(cols)
813  , std::back_inserter(str_cols)
814  , [] (const auto& col)
815  {
816  const FString s(FString() << col);
817  return s;
818  }
819  );
820 
821  auto item_iter = insert (str_cols, std::forward<DT>(d), parent_iter);
822  return item_iter;
823 }
824 
825 //----------------------------------------------------------------------
826 inline auto FListView::getData() & -> FListViewItems&
827 {
828  FObjectList* ptr = &data.itemlist;
829  return *static_cast<FListViewItems*>(static_cast<void*>(ptr));
830 }
831 
832 //----------------------------------------------------------------------
833 inline auto FListView::getData() const & -> const FListViewItems&
834 {
835  const FObjectList* ptr = &data.itemlist;
836  return *static_cast<const FListViewItems*>(static_cast<const void*>(ptr));
837 }
838 
839 //----------------------------------------------------------------------
840 inline auto FListView::isHorizontallyScrollable() const -> bool
841 { return max_line_width > getClientWidth(); }
842 
843 //----------------------------------------------------------------------
844 inline auto FListView::isVerticallyScrollable() const -> bool
845 { return getCount() > getClientHeight(); }
846 
847 //----------------------------------------------------------------------
848 inline auto FListView::canSkipListDrawing() const -> bool
849 {
850  const auto height = getHeight();
851  const auto width = getWidth();
852  return isItemListEmpty()
853  || height <= 2
854  || width <= 4;
855 }
856 
857 //----------------------------------------------------------------------
858 inline auto FListView::isLayoutInitialized() const -> bool
859 { return getFlags().visibility.initialize_layout; }
860 
861 //----------------------------------------------------------------------
862 inline auto FListView::getColumnCount() const -> std::size_t
863 { return data.header.size(); }
864 
865 //----------------------------------------------------------------------
866 inline void FListView::toggleItemCheckState (FListViewItem* item) const
867 {
868  item->setChecked(! item->isChecked());
869  processChanged();
870 }
871 
872 //----------------------------------------------------------------------
873 inline void FListView::scrollTo (const FPoint& pos)
874 { scrollTo(pos.getX(), pos.getY()); }
875 
876 //----------------------------------------------------------------------
877 inline auto FListView::isItemListEmpty() const -> bool
878 { return data.itemlist.empty(); }
879 
880 //----------------------------------------------------------------------
881 inline auto FListView::isTreeView() const -> bool
882 { return tree_view; }
883 
884 //----------------------------------------------------------------------
885 inline auto FListView::isColumnIndexInvalid (int column) const -> bool
886 {
887  return column < 1 || data.header.empty() || column > int(data.header.size());
888 }
889 
890 //----------------------------------------------------------------------
891 inline auto FListView::hasCheckableItems() const -> bool
892 { return has_checkable_items; }
893 
894 } // namespace finalcut
895 
896 #endif // FLISTVIEW_H
Definition: fevent.h:207
Definition: fevent.h:144
Definition: flistview.h:217
Definition: fevent.h:311
Definition: flistview.h:341
Definition: fvtermbuffer.h:56
Definition: fevent.h:182
Definition: class_template.cpp:25
Definition: fpoint.h:50
Definition: fsize.h:55
Definition: fobject.h:79
Definition: flistview.h:654
Definition: fstring.h:82
Definition: fdata.h:55
Definition: fwidget.h:129
Definition: fevent.h:124
Definition: flistview.h:75
Definition: ftypes.h:161