47 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT) 48 #error "Only <final/final.h> can be included directly." 52 #include <unordered_map> 56 #include "final/fwidget.h" 57 #include "final/util/fdata.h" 58 #include "final/widget/fscrollbar.h" 75 template <
typename DT = std::
nullptr_t>
79 auto getClassName()
const ->
FString;
80 auto getText()
const ->
FString;
81 template <
typename DT>
82 auto getData()
const -> clean_fdata_t<DT>&;
86 template <
typename DT>
90 auto isSelected()
const -> bool;
97 using FDataAccessPtr = std::shared_ptr<FDataAccess>;
104 FDataAccessPtr data_pointer{};
105 BracketType brackets{BracketType::None};
106 bool selected{
false};
115 template <
typename DT>
116 inline FListBoxItem::FListBoxItem (
const FString& txt, DT&& data)
117 : text{stringFilter(txt)}
118 , data_pointer{makeFData(std::forward<DT>(data))}
122 inline auto FListBoxItem::getClassName()
const ->
FString 123 {
return "FListBoxItem"; }
126 inline auto FListBoxItem::getText()
const ->
FString 130 template <
typename DT>
131 inline auto FListBoxItem::getData()
const -> clean_fdata_t<DT>&
137 inline void FListBoxItem::setText (
const FString& txt)
139 text.setString(stringFilter(txt));
143 template <
typename DT>
144 inline void FListBoxItem::setData (DT&& data)
146 const auto data_obj = makeFData(std::forward<DT>(data));
147 data_pointer.reset(data_obj);
151 inline auto FListBoxItem::isSelected()
const ->
bool 155 inline void FListBoxItem::clear()
159 inline auto FListBoxItem::stringFilter (
const FString& txt)
const ->
FString 162 .expandTabs(FVTerm::getFOutput()->getTabstop())
165 .replaceControlCodes();
177 using FWidget::setGeometry;
178 using FListBoxItems = std::vector<FListBoxItem>;
182 template <
typename Iterator
183 ,
typename InsertConverter>
185 template <
typename Container
186 ,
typename LazyConverter>
187 FListBox (Container, LazyConverter&&,
FWidget* =
nullptr);
190 FListBox (
const FListBox&) =
delete;
193 FListBox (FListBox&&) noexcept =
delete;
196 ~FListBox()
override;
199 auto operator = (
const FListBox&) -> FListBox& =
delete;
202 auto operator = (FListBox&&) noexcept -> FListBox& =
delete;
205 auto getClassName()
const ->
FString override;
206 auto getCount()
const -> std::size_t;
208 auto getItem (std::size_t)
const & ->
const FListBoxItem&;
209 auto getItem (FListBoxItems::iterator) & ->
FListBoxItem&;
210 auto getItem (FListBoxItems::const_iterator)
const & ->
const FListBoxItem&;
211 auto currentItem()
const noexcept -> std::size_t;
212 auto getData() & -> FListBoxItems&;
213 auto getData()
const & ->
const FListBoxItems&;
217 void setCurrentItem (std::size_t);
218 void setCurrentItem (FListBoxItems::iterator);
219 void selectItem (std::size_t);
220 void selectItem (FListBoxItems::iterator)
const;
221 void unselectItem (std::size_t);
222 void unselectItem (FListBoxItems::iterator)
const;
223 void showInsideBrackets (
const std::size_t, BracketType);
224 void showNoBrackets (std::size_t);
225 void showNoBrackets (FListBoxItems::iterator)
const;
226 void setSize (
const FSize&,
bool =
true)
override;
227 void setGeometry (
const FPoint&,
const FSize&,
bool =
true)
override;
228 void setMultiSelection (
bool =
true);
229 void unsetMultiSelection ();
230 void setDisable()
override;
234 auto isSelected (std::size_t)
const -> bool;
235 auto isSelected (FListBoxItems::iterator)
const -> bool;
236 auto isMultiSelection()
const -> bool;
237 auto hasBrackets (std::size_t)
const -> bool;
238 auto hasBrackets (FListBoxItems::iterator)
const -> bool;
241 void hide()
override;
242 template <
typename Iterator
243 ,
typename InsertConverter>
244 void insert (Iterator, Iterator,
const InsertConverter&);
245 template <
typename Container
246 ,
typename LazyConverter>
247 void insert (
const Container&, LazyConverter&&);
248 template <
typename Container
249 ,
typename LazyConverter>
250 void insert (Container*, LazyConverter&&);
253 ,
typename DT = std::nullptr_t>
254 void insert (
const std::initializer_list<T>& list
255 , BracketType = BracketType::None
258 template <
typename ItemT
259 ,
typename DT = std::nullptr_t>
260 void insert (
const ItemT&
261 , BracketType = BracketType::None
264 void remove (std::size_t);
265 auto findItem (
const FString&) -> FListBoxItems::iterator;
266 void reserve (std::size_t);
282 void initLayout()
override;
283 void adjustYOffset (std::size_t);
284 void adjustSize()
override;
288 using KeyMap = std::unordered_map<FKey, std::function<void()>,
EnumHash<FKey>>;
289 using KeyMapResult = std::unordered_map<FKey, std::function<bool()>, EnumHash<FKey>>;
290 using LazyInsert = std::function<void(FListBoxItem&, FDataAccess*, std::size_t)>;
294 FListBoxItems itemlist{};
299 KeyMapResult key_map_result{};
302 struct SelectionState
304 std::size_t current{0};
305 int last_current{-1};
306 int select_from_item{-1};
307 bool multi_select{
false};
308 bool mouse_select{
false};
309 bool click_on_list{
false};
312 struct ScrollingState
314 FScrollbarPtr vbar{
nullptr};
315 FScrollbarPtr hbar{
nullptr};
318 int last_yoffset{-1};
325 enum class ConvertType
333 static auto getString (FListBoxItems::iterator) ->
FString;
336 auto isHorizontallyScrollable()
const -> bool;
337 auto isVerticallyScrollable()
const -> bool;
338 auto isCurrentLine (
int)
const -> bool;
339 auto isDragSelect()
const -> bool;
340 auto canSkipDragScrolling() -> bool;
344 void mapKeyFunctions();
346 void draw()
override;
347 void drawBorder()
override;
348 void drawScrollbars()
const;
350 auto canSkipDrawing()
const -> bool;
351 auto calculateNumberItemsToDraw()
const -> std::size_t;
352 auto canRedrawPartialList()
const -> bool;
353 void updateRedrawParameters (std::size_t&, std::size_t&)
const;
354 void finalizeDrawing();
356 void drawListLine (
int, FListBoxItems::iterator,
bool);
357 void printLeftBracket (BracketType);
358 void printRightBracket (BracketType);
359 void drawListBracketsLine (
int, FListBoxItems::iterator,
bool);
360 auto getMaxWidth()
const -> std::size_t;
361 void printLeftCurrentLineArrow (
int);
362 void printRightCurrentLineArrow (
int);
363 void printRemainingSpacesFromPos (std::size_t);
364 void setInitialLineAttributes (
bool)
const;
365 void setCurrentLineAttributes (
int,
bool,
bool,
bool&);
366 void setSelectedCurrentLineAttributes (
int);
367 void setUnselectedCurrentLineAttributes (
int,
bool,
bool&);
368 void setLineAttributes (
int,
bool,
bool,
bool&);
369 void unsetAttributes()
const;
370 void updateDrawing (
bool,
bool);
371 void recalculateHorizontalBar (std::size_t,
bool);
372 void recalculateVerticalBar (std::size_t)
const;
373 void multiSelection (std::size_t);
374 void multiSelectionUpTo (std::size_t);
376 void wheelDown (
int);
377 void wheelLeft (
int);
378 void wheelRight (
int);
379 auto dragScrollUp() -> bool;
380 auto dragScrollDown() -> bool;
381 void dragUp (MouseButton);
382 void dragDown (MouseButton);
383 void stopDragScroll();
384 void prevListItem (
int);
385 void nextListItem (
int);
386 void scrollToX (
int);
387 void scrollToY (
int);
388 void scrollLeft (
int);
389 void scrollRight (
int);
398 auto isWithinListBounds (
const FPoint&)
const -> bool;
399 auto skipIncrementalSearch() -> bool;
400 auto isNonSelectMouseButtonPressed (
const FMouseEvent*)
const -> bool;
401 template <
typename MultiSelectionFunction>
402 void handleMouseWithinListBounds (
const FMouseEvent*,
const MultiSelectionFunction&);
404 void acceptSelection();
405 auto spacebarProcessing() -> bool;
406 auto changeSelectionAndPosition() -> bool;
407 auto deletePreviousCharacter() -> bool;
408 auto keyIncSearchInput (FKey) -> bool;
409 void processClick()
const;
410 void processSelect()
const;
411 void processRowChanged()
const;
412 void processChanged()
const;
413 void changeOnResize()
const;
414 void updateScrollBarAfterRemoval (std::size_t);
415 auto getScrollBarMaxHorizontal()
const noexcept -> int;
416 auto getScrollBarMaxVertical()
const noexcept -> int;
417 void recalculateMaximumLineWidth();
418 void lazyConvert (FListBoxItems::iterator, std::size_t);
419 auto index2iterator (std::size_t) -> FListBoxItems::iterator;
420 auto index2iterator (std::size_t index)
const -> FListBoxItems::const_iterator;
421 void handleSelectionChange (
const std::size_t);
422 void handleXOffsetChange (
const int);
423 void handleVerticalScrollBarUpdate (
const FScrollbar::ScrollType,
const int)
const;
424 void handleHorizontalScrollBarUpdate (
const FScrollbar::ScrollType,
const int)
const;
425 auto getVerticalScrollDistance (
const FScrollbar::ScrollType)
const -> int;
426 auto getHorizontalScrollDistance (
const FScrollbar::ScrollType)
const -> int;
429 void cb_vbarChange (
const FWidget*);
430 void cb_hbarChange (
const FWidget*);
433 LazyInsert lazy_inserter{};
436 std::size_t nf_offset{0};
437 std::size_t max_line_width{0};
439 ScrollingState scroll{};
440 SelectionState selection{};
441 ConvertType conv_type{ConvertType::None};
442 DragScrollMode drag_scroll{DragScrollMode::None};
447 namespace flistboxhelper
450 template <
typename Container>
451 constexpr
auto getContainer(
FDataAccess* container) -> clean_fdata_t<Container>&
460 template <
typename Iterator
461 ,
typename InsertConverter>
462 inline FListBox::FListBox ( Iterator first
464 , InsertConverter convert
470 while ( first != last )
472 insert(convert(first), BracketType::None,
false, &(*first));
478 template <
typename Container
479 ,
typename LazyConverter>
480 inline FListBox::FListBox ( Container container
481 , LazyConverter&& convert
486 insert (container, std::forward<LazyConverter>(convert));
490 inline auto FListBox::getClassName()
const ->
FString 491 {
return "FListBox"; }
494 inline auto FListBox::getCount()
const -> std::size_t
495 {
return data.itemlist.size(); }
498 inline auto FListBox::getItem (std::size_t index) & ->
FListBoxItem&
500 auto iter = index2iterator(index - 1);
505 inline auto FListBox::getItem (std::size_t index)
const & ->
const FListBoxItem&
507 auto iter = index2iterator(index - 1);
512 inline auto FListBox::getItem (FListBoxItems::iterator iter) & ->
FListBoxItem&
516 inline auto FListBox::getItem (FListBoxItems::const_iterator iter)
const & ->
const FListBoxItem&
520 inline auto FListBox::currentItem()
const noexcept -> std::size_t
521 {
return selection.current; }
524 inline auto FListBox::getData() & -> FListBoxItems&
525 {
return data.itemlist; }
528 inline auto FListBox::getData()
const & ->
const FListBoxItems&
529 {
return data.itemlist; }
532 inline auto FListBox::getText() & ->
FString&
533 {
return data.text; }
536 inline void FListBox::selectItem (std::size_t index)
537 { index2iterator(index - 1)->selected =
true; }
540 inline void FListBox::selectItem (FListBoxItems::iterator iter)
const 541 { iter->selected =
true; }
544 inline void FListBox::unselectItem (std::size_t index)
545 { index2iterator(index - 1)->selected =
false; }
548 inline void FListBox::unselectItem (FListBoxItems::iterator iter)
const 549 { iter->selected =
false; }
552 inline void FListBox::showNoBrackets (std::size_t index)
553 { index2iterator(index - 1)->brackets = BracketType::None; }
556 inline void FListBox::showNoBrackets (FListBoxItems::iterator iter)
const 557 { iter->brackets = BracketType::None; }
560 inline void FListBox::setMultiSelection (
bool enable)
561 { selection.multi_select = enable; }
564 inline void FListBox::unsetMultiSelection()
565 { setMultiSelection(
false); }
568 inline void FListBox::setDisable()
569 { setEnable(
false); }
572 inline auto FListBox::isSelected (std::size_t index)
const ->
bool 573 {
return index2iterator(index - 1)->selected; }
576 inline auto FListBox::isSelected (FListBoxItems::iterator iter)
const ->
bool 577 {
return iter->selected; }
580 inline auto FListBox::isMultiSelection()
const ->
bool 581 {
return selection.multi_select; }
584 inline auto FListBox::hasBrackets(std::size_t index)
const ->
bool 585 {
return index2iterator(index - 1)->brackets != BracketType::None; }
588 inline auto FListBox::hasBrackets(FListBoxItems::iterator iter)
const ->
bool 589 {
return iter->brackets != BracketType::None; }
592 inline void FListBox::reserve (std::size_t new_cap)
593 { data.itemlist.reserve(new_cap); }
596 template <
typename Iterator
597 ,
typename InsertConverter>
598 inline void FListBox::insert ( Iterator first
600 ,
const InsertConverter& convert )
602 conv_type = ConvertType::Direct;
604 while ( first != last )
606 insert (convert(first), BracketType::None,
false, &(*first));
612 template <
typename Container
613 ,
typename LazyConverter>
614 void FListBox::insert (
const Container& container, LazyConverter&& converter)
616 conv_type = ConvertType::Lazy;
617 data.source_container = makeFData(container);
618 lazy_inserter = std::forward<LazyConverter>(converter);
619 const std::size_t size = container.size();
622 data.itemlist.resize(size);
624 recalculateVerticalBar(size);
628 template <
typename Container
629 ,
typename LazyConverter>
630 void FListBox::insert (Container* container, LazyConverter&& converter)
632 insert (*container, std::forward<LazyConverter>(converter));
638 void FListBox::insert (
const std::initializer_list<T>& list
643 for (
const auto& item : list)
646 listItem.brackets = b;
647 listItem.selected = s;
653 template <
typename ItemT
655 void FListBox::insert (
const ItemT& item
661 listItem.brackets = b;
662 listItem.selected = s;
667 inline auto FListBox::isHorizontallyScrollable()
const ->
bool 668 {
return max_line_width + 1 >= getClientWidth(); }
671 inline auto FListBox::isVerticallyScrollable()
const ->
bool 672 {
return getCount() > getClientHeight(); }
675 inline auto FListBox::isCurrentLine (
int y)
const ->
bool 676 {
return y + scroll.yoffset + 1 == int(selection.current); }
679 inline auto FListBox::getMaxWidth()
const -> std::size_t
680 {
return getWidth() - nf_offset - 4; }
684 FListBox::index2iterator (std::size_t index) -> FListBoxItems::iterator
686 auto iter = data.itemlist.begin();
687 using distance_type = FListBoxItems::difference_type;
688 std::advance (iter, distance_type(index));
694 FListBox::index2iterator (std::size_t index)
const -> FListBoxItems::const_iterator
696 auto iter = data.itemlist.begin();
697 using distance_type = FListBoxItems::difference_type;
698 std::advance (iter, distance_type(index));
Definition: flistbox.h:173
Definition: class_template.cpp:25
Definition: flistbox.h:71