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-2024 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  // Inquiry
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  // Inquiry
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  void replaceControlCodes();
132  auto getVisibleLines() -> std::size_t;
133  void resetVisibleLineCounter();
134 
135  // Data members
136  FStringList column_list{};
137  FDataAccessPtr data_pointer{};
138  iterator root{};
139  std::size_t visible_lines{1};
140  bool expandable{false};
141  bool is_expand{false};
142  bool checkable{false};
143  bool is_checked{false};
144 
145  // Friend class
146  friend class FListView;
147  friend class FListViewIterator;
148 };
149 
150 
151 // FListViewItem inline functions
152 //----------------------------------------------------------------------
153 template <typename DT>
154 inline FListViewItem::FListViewItem ( const FStringList& cols
155  , DT&& data
156  , iterator parent_iter )
157  : FObject{nullptr}
158  , column_list{cols}
159  , data_pointer{makeFData(std::forward<DT>(data))}
160 {
161  if ( cols.empty() )
162  return;
163 
164  replaceControlCodes();
165  insert (this, parent_iter);
166 }
167 
168 //----------------------------------------------------------------------
169 inline auto FListViewItem::getClassName() const -> FString
170 { return "FListViewItem"; }
171 
172 //----------------------------------------------------------------------
173 inline auto FListViewItem::getColumnCount() const -> uInt
174 { return static_cast<uInt>(column_list.size()); }
175 
176 //----------------------------------------------------------------------
177 template <typename DT>
178 inline auto FListViewItem::getData() const -> clean_fdata_t<DT>&
179 {
180  return static_cast<FData<clean_fdata_t<DT>>&>(*data_pointer).get();
181 }
182 
183 //----------------------------------------------------------------------
184 template <typename DT>
185 inline void FListViewItem::setData (DT&& data)
186 {
187  const auto data_obj = makeFData(std::forward<DT>(data));
188  data_pointer = data_obj;
189 }
190 
191 //----------------------------------------------------------------------
192 inline void FListViewItem::setChecked (bool checked)
193 { is_checked = checked; }
194 
195 //----------------------------------------------------------------------
196 inline auto FListViewItem::isChecked() const -> bool
197 { return is_checked; }
198 
199 //----------------------------------------------------------------------
200 inline auto FListViewItem::isExpand() const -> bool
201 { return is_expand; }
202 
203 //----------------------------------------------------------------------
204 inline auto FListViewItem::isExpandable() const -> bool
205 { return expandable; }
206 
207 //----------------------------------------------------------------------
208 inline auto FListViewItem::isCheckable() const -> bool
209 { return checkable; }
210 
211 
212 //----------------------------------------------------------------------
213 // class FListViewIterator
214 //----------------------------------------------------------------------
215 
217 {
218  public:
219  // Using-declarations
220  using FObjectList = std::vector<FObject*>;
221  using Iterator = FObjectList::iterator;
222  using IteratorStack = std::stack<Iterator>;
223 
224  // Constructor
225  FListViewIterator () = default;
226  ~FListViewIterator () = default;
227  explicit FListViewIterator (Iterator);
228  FListViewIterator (const FListViewIterator&) = default;
229  FListViewIterator (FListViewIterator&& i) noexcept
230  : iter_path{std::move(i.iter_path)}
231  , node{i.node}
232  , position{i.position}
233  { }
234 
235  // Overloaded operators
236  auto operator = (const FListViewIterator&) -> FListViewIterator& = default;
237  auto operator = (FListViewIterator&&) noexcept -> FListViewIterator& = default;
238  auto operator = (Iterator iter) -> FListViewIterator&;
239  auto operator ++ () -> FListViewIterator&; // prefix
240  auto operator ++ (int) -> FListViewIterator; // postfix
241  auto operator -- () -> FListViewIterator&; // prefix
242  auto operator -- (int) -> FListViewIterator; // postfix
243  auto operator += (int) -> FListViewIterator&;
244  auto operator -= (int) -> FListViewIterator&;
245  auto operator * () const -> FObject*&;
246  auto operator -> () const -> FObject*;
247 
248  friend inline auto operator == ( const FListViewIterator& lhs
249  , const FListViewIterator& rhs ) -> bool
250  {
251  return lhs.node == rhs.node;
252  }
253 
254  friend inline auto operator != ( const FListViewIterator& lhs
255  , const FListViewIterator& rhs ) -> bool
256  {
257  return lhs.node != rhs.node;
258  }
259 
260  friend inline auto operator == ( const FListViewIterator& listview_iter
261  , const Iterator& iter) -> bool
262  {
263  return listview_iter.node == iter;
264  }
265 
266  friend inline auto operator != ( const FListViewIterator& listview_iter
267  , const Iterator& iter) -> bool
268  {
269  return listview_iter.node != iter;
270  }
271 
272  // Accessor
273  auto getClassName() const -> FString;
274  auto getPosition() -> int&;
275 
276  // Methods
277  void parentElement();
278 
279  // Friend Non-member operator functions
280  friend auto operator + (const FListViewIterator& lhs, int n) -> FListViewIterator
281  {
282  auto tmp = lhs;
283 
284  for (int i = n; i > 0 ; i--)
285  tmp.nextElement(tmp.node);
286 
287  return tmp;
288  }
289 
290  friend auto operator - (const FListViewIterator& lhs, int n) -> FListViewIterator
291  {
292  auto tmp = lhs;
293 
294  for (int i = n; i > 0 ; i--)
295  tmp.prevElement(tmp.node);
296 
297  return tmp;
298  }
299 
300  private:
301  // Methods
302  void nextElement (Iterator&);
303  void prevElement (Iterator&);
304 
305  // Data members
306  IteratorStack iter_path{};
307  Iterator node{};
308  int position{0};
309 };
310 
311 
312 // FListViewIterator inline functions
313 //----------------------------------------------------------------------
314 inline auto FListViewIterator::operator * () const -> FObject*&
315 { return *node; }
316 
317 //----------------------------------------------------------------------
318 inline auto FListViewIterator::operator -> () const -> FObject*
319 { return *node; }
320 
321 //----------------------------------------------------------------------
322 inline auto FListViewIterator::getClassName() const -> FString
323 { return "FListViewIterator"; }
324 
325 //----------------------------------------------------------------------
326 inline auto FListViewIterator::getPosition() -> int&
327 { return position; }
328 
329 
330 //----------------------------------------------------------------------
331 // class FListView
332 //----------------------------------------------------------------------
333 
334 class FListView : public FWidget
335 {
336  public:
337  // Using-declaration
338  using FWidget::setGeometry;
339  using FListViewItems = std::vector<FListViewItem*>;
340 
341  // Disable copy constructor
342  FListView (const FListView&) = delete;
343 
344  // Disable move constructor
345  FListView (FListView&&) noexcept = delete;
346 
347  // Constructor
348  explicit FListView (FWidget* = nullptr);
349 
350  // Destructor
351  ~FListView() override;
352 
353  // Disable copy assignment operator (=)
354  auto operator = (const FListView&) -> FListView& = delete;
355 
356  // Disable move assignment operator (=)
357  auto operator = (FListView&&) noexcept -> FListView& = delete;
358 
359  // Accessors
360  auto getClassName() const -> FString override;
361  auto getCount() const -> std::size_t;
362  auto getColumnCount() const -> std::size_t;
363  auto getColumnAlignment (int) const -> Align;
364  auto getColumnText (int) const -> FString;
365  auto getColumnSortType (int) const -> SortType;
366  auto getSortOrder() const -> SortOrder;
367  auto getSortColumn() const -> int;
368  auto getCurrentItem() -> FListViewItem*;
369 
370  // Mutators
371  void setSize (const FSize&, bool = true) override;
372  void setGeometry ( const FPoint&, const FSize&
373  , bool = true ) override;
374  void setColumnAlignment (int, Align);
375  void setColumnText (int, const FString&);
376  void setColumnSortType (int, SortType = SortType::Name);
377  void setColumnSort (int, SortOrder = SortOrder::Ascending);
378  template <typename Compare>
379  void setUserAscendingCompare (Compare);
380  template <typename Compare>
381  void setUserDescendingCompare (Compare);
382  void hideSortIndicator (bool = true);
383  void showColumn (int);
384  void hideColumn (int);
385  void setTreeView (bool = true);
386  void unsetTreeView();
387 
388  // Inquiries
389  auto isColumnHidden (int) const -> bool;
390 
391  // Methods
392  virtual auto addColumn (const FString&, int = USE_MAX_SIZE) -> int;
393  virtual auto removeColumn (int) -> int;
394  void removeAllColumns();
395  void hide() override;
396  auto insert (FListViewItem*) -> iterator;
397  auto insert (FListViewItem*, iterator) -> iterator;
398  template <typename DT = std::nullptr_t>
399  auto insert (const FStringList&, DT&& = DT()) -> iterator;
400  auto insert (const FStringList&, iterator) -> iterator;
401  template <typename DT>
402  auto insert (const FStringList&, DT&&, iterator) -> iterator;
403  template <typename T
404  , typename DT = std::nullptr_t>
405  auto insert (const std::initializer_list<T>&, DT&& = DT()) -> iterator;
406  template <typename T>
407  auto insert (const std::initializer_list<T>&, iterator) -> iterator;
408  template <typename T
409  , typename DT>
410  auto insert (const std::initializer_list<T>&, DT&&, iterator) -> iterator;
411  template <typename ColT
412  , typename DT = std::nullptr_t>
413  auto insert (const std::vector<ColT>&, DT&& = DT()) -> iterator;
414  template <typename ColT>
415  auto insert (const std::vector<ColT>&, iterator) -> iterator;
416  template <typename ColT
417  , typename DT>
418  auto insert (const std::vector<ColT>&, DT&&, iterator) -> iterator;
419  void remove (FListViewItem*);
420  void clear();
421  auto getData() & -> FListViewItems&;
422  auto getData() const & -> const FListViewItems&;
423 
424  virtual void sort();
425 
426  // Event handlers
427  void onKeyPress (FKeyEvent*) override;
428  void onMouseDown (FMouseEvent*) override;
429  void onMouseUp (FMouseEvent*) override;
430  void onMouseMove (FMouseEvent*) override;
431  void onMouseDoubleClick (FMouseEvent*) override;
432  void onWheel (FWheelEvent*) override;
433  void onTimer (FTimerEvent*) override;
434  void onFocusOut (FFocusEvent*) override;
435 
436  protected:
437  // Methods
438  void initLayout() override;
439  void adjustViewport (const int);
440  void adjustScrollbars (const std::size_t) const;
441  void adjustSize() override;
442 
443  private:
444  struct Header; // forward declaration
445 
446  // Using-declaration
447  using KeyMap = std::unordered_map<FKey, std::function<void()>, EnumHash<FKey>>;
448  using KeyMapResult = std::unordered_map<FKey, std::function<bool()>, EnumHash<FKey>>;
449  using HeaderItems = std::vector<Header>;
450  using SortTypes = std::vector<SortType>;
451 
452  struct ListViewData
453  {
454  iterator root{};
455  FObjectList selflist{};
456  FObjectList itemlist{};
457  HeaderItems header; // GitHub issues #122
458  FVTermBuffer headerline{};
459  KeyMap key_map{};
460  KeyMapResult key_map_result{};
461  };
462 
463  struct SelectionState
464  {
465  FListViewIterator current_iter{};
466  const FListViewItem* clicked_checkbox_item{nullptr};
467  FPoint clicked_expander_pos{-1, -1};
468  FPoint clicked_header_pos{-1, -1};
469  };
470 
471  struct SortState
472  {
473  int column{-1};
474  SortTypes type{};
475  SortOrder order{SortOrder::Unsorted};
476  bool hide_sort_indicator{false};
477  };
478 
479  struct ScrollingState
480  {
481  FScrollbarPtr vbar{nullptr};
482  FScrollbarPtr hbar{nullptr};
483  FListViewIterator first_visible_line{};
484  FListViewIterator last_visible_line{};
485  int first_line_position_before{-1};
486  int xoffset{0};
487  bool timer{false};
488  int repeat{100};
489  int distance{1};
490  };
491 
492  // Constants
493  static constexpr std::size_t checkbox_space = 4;
494 
495  // Constants
496  static constexpr int USE_MAX_SIZE = -1;
497 
498  // Accessors
499  static auto getNullIterator() -> iterator&;
500 
501  // Mutators
502  static void setNullIterator (const iterator&);
503 
504  // Inquiry
505  auto isHorizontallyScrollable() const -> bool;
506  auto isVerticallyScrollable() const -> bool;
507  auto canSkipListDrawing() const -> bool;
508  auto canSkipDragScrolling() -> bool;
509 
510  // Methods
511  void init();
512  void mapKeyFunctions();
513  void processKeyAction (FKeyEvent*);
514  template <typename Compare>
515  void sort (Compare);
516  auto getAlignOffset ( const Align
517  , const std::size_t
518  , const std::size_t ) const -> std::size_t;
519  auto getListEnd (const FListViewItem*) -> iterator;
520  void draw() override;
521  void drawBorder() override;
522  void drawScrollbars() const;
523  void drawHeadlines();
524  void drawList();
525  void setInputCursor (const FListViewItem*, int, bool);
526  void finalizeListDrawing (int);
527  void adjustWidthForTreeView (std::size_t&, std::size_t, bool) const;
528  void drawListLine (const FListViewItem*, bool, bool);
529  auto createColumnsString (const FListViewItem*) -> FString;
530  void printColumnsString (FString&);
531  void clearList();
532  void setLineAttributes (bool, bool) const;
533  auto getCheckBox (const FListViewItem* item) const -> FString;
534  auto getLinePrefix (const FListViewItem*, std::size_t) const -> FString;
535  void drawSortIndicator (std::size_t&, std::size_t);
536  void drawHeadlineLabel (const HeaderItems::const_iterator&);
537  void drawHeaderBorder (std::size_t);
538  auto findHeaderStartPos (bool&) -> FVTermBuffer::iterator;
539  auto findHeaderEndPos (FVTermBuffer::iterator, bool, bool&) -> FVTermBuffer::iterator;
540  void drawBufferedHeadline();
541  void drawColumnEllipsis ( const HeaderItems::const_iterator&
542  , const FString& );
543  void updateLayout();
544  void updateDrawing (bool, bool);
545  auto determineLineWidth (FListViewItem*) -> std::size_t;
546  void beforeInsertion (FListViewItem*);
547  void afterInsertion();
548  void adjustListBeforeRemoval (const FListViewItem*);
549  void removeItemFromParent (FListViewItem*);
550  void updateListAfterRemoval();
551  void recalculateHorizontalBar (std::size_t);
552  void recalculateVerticalBar (std::size_t) const;
553  void mouseHeaderClicked();
554  void handleTreeExpanderClick (const FMouseEvent*);
555  void handleCheckboxClick (const FMouseEvent*);
556  void wheelUp (int);
557  void wheelDown (int);
558  void wheelLeft (int);
559  void wheelRight (int);
560  auto dragScrollUp (int) -> bool;
561  auto dragScrollDown (int) -> bool;
562  void dragUp (MouseButton);
563  void dragDown (MouseButton);
564  void stopDragScroll();
565  void toggleItemExpandState (FListViewItem*) const;
566  void toggleItemCheckState (FListViewItem*) const;
567  auto isCheckboxClicked (int, int) const -> bool;
568  void resetClickedPositions();
569  auto isWithinHeaderBounds (const FPoint&) const -> bool;
570  auto isWithinListBounds (const FPoint&) const -> bool;
571  auto appendItem (FListViewItem*) -> iterator;
572  void handleListEvent (const FMouseEvent*);
573  void processClick() const;
574  void processRowChanged() const;
575  void processChanged() const;
576  void changeOnResize() const;
577  void toggleCheckbox();
578  void collapseAndScrollLeft();
579  void jumpToParentElement (const FListViewItem*);
580  void expandAndScrollRight();
581  void firstPos();
582  void lastPos();
583  auto expandSubtree() -> bool;
584  auto collapseSubtree() -> bool;
585  void setRelativePosition (int);
586  void stepForward();
587  void stepBackward();
588  void stepForward (int);
589  void stepBackward (int);
590  void scrollToX (int);
591  void scrollToY (int);
592  void scrollTo (const FPoint&);
593  void scrollTo (int, int);
594  void scrollBy (int, int);
595  auto isItemListEmpty() const -> bool;
596  auto isTreeView() const -> bool;
597  auto isColumnIndexInvalid (int) const -> bool;
598  auto hasCheckableItems() const -> bool;
599  auto getScrollBarMaxHorizontal() const noexcept -> int;
600  auto getScrollBarMaxVertical (const std::size_t) const noexcept -> int;
601  void updateViewAfterVBarChange (const FScrollbar::ScrollType);
602  void updateViewAfterHBarChange (const FScrollbar::ScrollType, const int);
603  auto getVerticalScrollDistance (const FScrollbar::ScrollType) const -> int;
604  auto getHorizontalScrollDistance (const FScrollbar::ScrollType) const -> int;
605 
606  // Callback methods
607  void cb_vbarChange (const FWidget*);
608  void cb_hbarChange (const FWidget*);
609 
610  // Data members
611  std::size_t nf_offset{0};
612  std::size_t max_line_width{1};
613  bool tree_view{false};
614  bool has_checkable_items{false};
615  ListViewData data{};
616  SortState sorting{};
617  ScrollingState scroll{};
618  SelectionState selection{};
619  DragScrollMode drag_scroll{DragScrollMode::None};
620 
621  // Function Pointer
622  bool (*user_defined_ascending) (const FObject*, const FObject*){nullptr};
623  bool (*user_defined_descending) (const FObject*, const FObject*){nullptr};
624 
625  // Friend class
626  friend class FListViewItem;
627 };
628 
629 
630 //----------------------------------------------------------------------
631 // struct FListView::Header
632 //----------------------------------------------------------------------
633 
635 {
636  public:
637  Header() = default;
638 
639  FString name{};
640  Align alignment{Align::Left};
641  int width{0};
642  bool fixed_width{false};
643  bool visible{true};
644 };
645 
646 
647 // FListView inline functions
648 //----------------------------------------------------------------------
649 inline auto FListView::getClassName() const -> FString
650 { return "FListView"; }
651 
652 //----------------------------------------------------------------------
653 inline auto FListView::getSortOrder() const -> SortOrder
654 { return sorting.order; }
655 
656 //----------------------------------------------------------------------
657 inline auto FListView::getSortColumn() const -> int
658 { return sorting.column; }
659 
660 //----------------------------------------------------------------------
661 inline auto FListView::getCurrentItem() -> FListViewItem*
662 { return static_cast<FListViewItem*>(*selection.current_iter); }
663 
664 //----------------------------------------------------------------------
665 template <typename Compare>
666 inline void FListView::setUserAscendingCompare (Compare cmp)
667 { user_defined_ascending = cmp; }
668 
669 //----------------------------------------------------------------------
670 template <typename Compare>
671 inline void FListView::setUserDescendingCompare (Compare cmp)
672 { user_defined_descending = cmp; }
673 
674 //----------------------------------------------------------------------
675 inline void FListView::hideSortIndicator (bool hide)
676 { sorting.hide_sort_indicator = hide; }
677 
678 //----------------------------------------------------------------------
679 inline void FListView::setTreeView (bool enable)
680 { tree_view = enable; }
681 
682 //----------------------------------------------------------------------
683 inline void FListView::unsetTreeView()
684 { setTreeView(false); }
685 
686 //----------------------------------------------------------------------
687 inline auto FListView::insert (FListViewItem* item) -> FObject::iterator
688 { return insert (item, data.root); }
689 
690 //----------------------------------------------------------------------
691 template <typename DT>
692 inline auto
693  FListView::insert (const FStringList& cols, DT&& d) -> FObject::iterator
694 { return insert (cols, std::forward<DT>(d), data.root); }
695 
696 //----------------------------------------------------------------------
697 inline auto
698  FListView::insert ( const FStringList& cols
699  , iterator parent_iter ) -> FObject::iterator
700 { return insert (cols, nullptr, parent_iter); }
701 
702 //----------------------------------------------------------------------
703 template <typename DT>
704 inline auto FListView::insert ( const FStringList& cols
705  , DT&& d
706  , iterator parent_iter ) -> FObject::iterator
707 {
708  FListViewItem* item;
709 
710  if ( cols.empty() || parent_iter == getNullIterator() )
711  return getNullIterator();
712 
713  if ( ! *parent_iter )
714  parent_iter = data.root;
715 
716  try
717  {
718  item = new FListViewItem (cols, std::forward<DT>(d), getNullIterator());
719  }
720  catch (const std::bad_alloc&)
721  {
722  badAllocOutput ("FListViewItem");
723  return getNullIterator();
724  }
725 
726  item->replaceControlCodes();
727  return insert(item, parent_iter);
728 }
729 
730 //----------------------------------------------------------------------
731 template <typename T
732  , typename DT>
733 inline auto
734  FListView::insert (const std::initializer_list<T>& list, DT&& d) -> FObject::iterator
735 { return insert (list, std::forward<DT>(d), data.root); }
736 
737 //----------------------------------------------------------------------
738 template <typename T>
739 inline auto
740  FListView::insert ( const std::initializer_list<T>& list
741  , iterator parent_iter ) -> FObject::iterator
742 { return insert (list, 0, parent_iter); }
743 
744 //----------------------------------------------------------------------
745 template <typename T
746  , typename DT>
747 auto FListView::insert ( const std::initializer_list<T>& list
748  , DT&& d
749  , iterator parent_iter ) -> FObject::iterator
750 {
751  FStringList str_cols;
752 
753  std::transform ( std::begin(list)
754  , std::end(list)
755  , std::back_inserter(str_cols)
756  , [] (const auto& col)
757  {
758  const FString s(FString() << col);
759  return s;
760  }
761  );
762 
763  auto item_iter = insert (str_cols, std::forward<DT>(d), parent_iter);
764  return item_iter;
765 }
766 
767 //----------------------------------------------------------------------
768 template <typename ColT
769  , typename DT>
770 inline auto
771  FListView::insert (const std::vector<ColT>& cols, DT&& d) -> FObject::iterator
772 { return insert (cols, std::forward<DT>(d), data.root); }
773 
774 //----------------------------------------------------------------------
775 template <typename ColT>
776 inline auto
777  FListView::insert ( const std::vector<ColT>& cols
778  , iterator parent_iter ) -> FObject::iterator
779 { return insert (cols, 0, parent_iter); }
780 
781 //----------------------------------------------------------------------
782 template <typename ColT
783  , typename DT>
784 auto
785  FListView::insert ( const std::vector<ColT>& cols
786  , DT&& d
787  , iterator parent_iter ) -> FObject::iterator
788 {
789  FStringList str_cols;
790 
791  std::transform ( std::begin(cols)
792  , std::end(cols)
793  , std::back_inserter(str_cols)
794  , [] (const auto& col)
795  {
796  const FString s(FString() << col);
797  return s;
798  }
799  );
800 
801  auto item_iter = insert (str_cols, std::forward<DT>(d), parent_iter);
802  return item_iter;
803 }
804 
805 //----------------------------------------------------------------------
806 inline auto FListView::getData() & -> FListViewItems&
807 {
808  FObjectList* ptr = &data.itemlist;
809  return *static_cast<FListViewItems*>(static_cast<void*>(ptr));
810 }
811 
812 //----------------------------------------------------------------------
813 inline auto FListView::getData() const & -> const FListViewItems&
814 {
815  const FObjectList* ptr = &data.itemlist;
816  return *static_cast<const FListViewItems*>(static_cast<const void*>(ptr));
817 }
818 
819 //----------------------------------------------------------------------
820 inline auto FListView::isHorizontallyScrollable() const -> bool
821 { return max_line_width > getClientWidth(); }
822 
823 //----------------------------------------------------------------------
824 inline auto FListView::isVerticallyScrollable() const -> bool
825 { return getCount() > getClientHeight(); }
826 
827 //----------------------------------------------------------------------
828 inline auto FListView::canSkipListDrawing() const -> bool
829 { return isItemListEmpty() || getHeight() <= 2 || getWidth() <= 4; }
830 
831 //----------------------------------------------------------------------
832 inline auto FListView::getColumnCount() const -> std::size_t
833 { return data.header.size(); }
834 
835 //----------------------------------------------------------------------
836 inline void FListView::toggleItemCheckState (FListViewItem* item) const
837 { item->setChecked(! item->isChecked()); }
838 
839 //----------------------------------------------------------------------
840 inline void FListView::scrollTo (const FPoint& pos)
841 { scrollTo(pos.getX(), pos.getY()); }
842 
843 //----------------------------------------------------------------------
844 inline auto FListView::isItemListEmpty() const -> bool
845 { return data.itemlist.empty(); }
846 
847 //----------------------------------------------------------------------
848 inline auto FListView::isTreeView() const -> bool
849 { return tree_view; }
850 
851 //----------------------------------------------------------------------
852 inline auto FListView::isColumnIndexInvalid (int column) const -> bool
853 {
854  return column < 1 || data.header.empty() || column > int(data.header.size());
855 }
856 
857 //----------------------------------------------------------------------
858 inline auto FListView::hasCheckableItems() const -> bool
859 { return has_checkable_items; }
860 
861 } // namespace finalcut
862 
863 #endif // FLISTVIEW_H
Definition: fevent.h:196
Definition: fevent.h:144
Definition: flistview.h:216
Definition: fevent.h:300
Definition: flistview.h:334
Definition: fvtermbuffer.h:56
Definition: fevent.h:171
Definition: class_template.cpp:25
Definition: fpoint.h:50
Definition: fsize.h:55
Definition: fobject.h:79
Definition: flistview.h:634
Definition: fstring.h:79
Definition: fdata.h:51
Definition: fwidget.h:129
Definition: fevent.h:124
Definition: flistview.h:75
Definition: ftypes.h:160