YCLIMP
Yandex Command Line Interface Music Player
Loading...
Searching...
No Matches
ElementSelector.hpp
1#pragma once
2
3#include "DatabaseIdentifiers.hpp"
4#include "FileManager.hpp"
5#include "Primitives.hpp"
6#include "Utility.hpp"
7
8#include <concepts>
9#include <memory>
10#include <optional>
11#include <random>
12#include <unordered_set>
13
19struct ElementSelectorState
20{
21 ElementSelectorState(size_t firstVisible, size_t selected);
22
23 size_t firstVisibleElementIndx;
24 size_t selectedElementIndx;
25};
26
27template <typename Element>
28concept PtrAndNameIsString = requires(Element el) {
29 {
30 el->name + "a"
31 } -> std::same_as<std::string>;
32 };
33template <typename Element>
34concept NameIsString = std::is_same<decltype(Element::name), std::string>::value;
35
36template <typename Element>
37concept ElementIsDBPlaylistPtr = std::is_same<Element, DBPlaylist_Ptr>::value;
38
39template <typename Element>
40concept ElementIsFilePtr = std::is_same<Element, File_Ptr>::value;
41
52template <typename ElementPtr>
54class ElementSelector
55{
56public:
57 template <typename Element>
59 static std::vector<ElementPtr> CrutchConverter(std::vector<Element> elements);
60
61public:
62 ElementSelector(const Recti& bounds);
63
64 void Load(std::vector<ElementPtr> element, bool overwrite);
65 void Load(ElementPtr element, bool overwrite);
66
67 void Update();
68 void HandleResize(const Recti& bounds);
69
70 void SelectUp();
71 void SelectDown();
72 void SelectByIndx(std::size_t indx);
73 void SelectByName(const std::string& filename);
74
75 void ClearAllLastingSelections();
76 void LastingSelectOnCurrent();
77
78 ElementSelectorState GetState() const;
79 void RestoreState(const ElementSelectorState& state);
80
81 std::vector<std::size_t> GetLastingSelectedElementsIndices() const;
82 std::vector<ElementPtr> GetLastingSelectedElements() const;
83 std::vector<ElementPtr> GetElements() const;
84
85 const std::optional<ElementPtr> GetSelected() const;
86 std::size_t GetSelectedPosition() const;
87 std::size_t GetElementsSize() const;
88
93 template <typename U = ElementPtr>
95 void Draw() const
96 {
97 int x = mBounds.left + 1;
98 int y = mBounds.top;
99 int xSpace = mBounds.width - 1;
100
101 int iBound =
102 std::min((int) mFirstVisibleIndx + mBounds.height, (int) mFiles.size());
103 for (int i = mFirstVisibleIndx; i < iBound; ++i)
104 {
105 if (i == mSelectedIndx)
106 {
107 attron(A_REVERSE);
108 }
109 if (mLastingSelectIndxs.contains(i))
110 {
111 attron(COLOR_PAIR(3));
112 }
113
114 PrintwInLimitedX(Vector2i{x, y}, mFiles[i]->name, x + xSpace);
115 attroff(A_REVERSE | COLOR_PAIR(0));
116 ++y;
117
118 attroff(COLOR_PAIR(2));
119 }
120
121 if (mFiles.empty())
122 {
124 "Wow such empty, Can you pleeeeease open another directory?", mBounds);
125 }
126 }
127
132 template <typename U = ElementPtr>
133 requires ElementIsFilePtr<U>
134 void Draw() const
135 {
136 int x = mBounds.left + 1;
137 int y = mBounds.top;
138 int xSpace = mBounds.width - 1;
139
140 int iBound =
141 std::min((int) mFirstVisibleIndx + mBounds.height, (int) mFiles.size());
142 for (int i = mFirstVisibleIndx; i < iBound; ++i)
143 {
144 if (i == mSelectedIndx)
145 {
146 attron(A_REVERSE);
147 }
148 if (mFiles[i]->type == File::Type::Directory)
149 {
150 attron(COLOR_PAIR(2));
151 }
152 if (mLastingSelectIndxs.contains(i))
153 {
154 attron(COLOR_PAIR(3));
155 }
156
157 PrintwInLimitedX(Vector2i{x, y}, mFiles[i]->name, x + xSpace);
158 attroff(A_REVERSE | COLOR_PAIR(0));
159 ++y;
160
161 attroff(COLOR_PAIR(2));
162 }
163
164 if (mFiles.empty())
165 {
167 "Wow such empty, Can you pleeeeease open another directory?", mBounds);
168 }
169 }
170
171 void ShuffleElements();
172
176 template <typename U = ElementPtr,
177 std::enable_if_t<std::is_same<U, File_Ptr>::value, bool> = true>
179 {
180 if (mFiles.empty())
181 return;
182
183 bool parentDirExist = false;
184 File_Ptr parent_dir = nullptr;
185 for (auto iter{begin(mFiles)}; iter != end(mFiles); ++iter)
186 {
187 if ((*iter)->name == "..")
188 {
189 parent_dir = *iter;
190 parentDirExist = true;
191 mFiles.erase(iter);
192 break;
193 }
194 }
195 // parent_dir goes first
196 std::vector<File_Ptr> sortedFiles;
197 if (parentDirExist)
198 sortedFiles.push_back(parent_dir);
199
200 for (auto& file : mFiles)
201 {
202 if (file->type == File::Type::Directory)
203 {
204 sortedFiles.push_back(file);
205 }
206 }
207
208 for (auto& file : mFiles)
209 {
210 if (file->type == File::Type::Directory)
211 continue;
212
213 sortedFiles.push_back(std::move(file));
214 }
215 mFiles = std::move(sortedFiles);
216 }
217
218private:
219 Recti mBounds;
220 std::size_t mSelectedIndx;
221 std::size_t mFirstVisibleIndx;
222 std::vector<ElementPtr> mFiles;
223 std::unordered_set<size_t> mLastingSelectIndxs;
224 std::default_random_engine mShuffleRandomEngine;
225};
226
227#include "ElementSelector.tpp"
228
229// Don't know where it will be better to place it, for now will place it there
230using FileSelector = ElementSelector<File_Ptr>;
Utility function list.
void printwMsgBox(const std::string &msg, const Recti &availableSpace)
Definition Utility.cpp:106
bool PrintwInLimitedX(const Vector2i &startPos, const std::string &text, int xLimit, int startIndx=0, bool truncIfNotFit=true)
Printw line in specified x boundary. if line is larger than x boundary. then truncate the line.
Definition Utility.cpp:23
The ElementSelector class - class to select & draw list of elements.
Definition ElementSelector.hpp:55
void Load(std::vector< ElementPtr > element, bool overwrite)
Definition ElementSelector.tpp:70
void Load(ElementPtr element, bool overwrite)
Definition ElementSelector.tpp:50
void SortDirsFirst()
SortDirsFirst - defined for File_Ptr to sort dirs first.
Definition ElementSelector.hpp:178
static std::vector< ElementPtr > CrutchConverter(std::vector< Element > elements)
ElementSelector::CrutchConverter - convert vector of Element to vector of Element_Ptr;.
Definition ElementSelector.tpp:29
void Draw() const
Draw method defined twice: this one is for DBPlaylistPtr. Required in NewElementsDialogBundle,...
Definition ElementSelector.hpp:95
void Draw() const
Draw method defined twice: this one is for all other elements (File_Ptr for now all the other elemenr...
Definition ElementSelector.hpp:134
Definition ElementSelector.hpp:37
Definition ElementSelector.hpp:40
Definition ElementSelector.hpp:34
Definition ElementSelector.hpp:28
The ElementSelectorState - struct to store element selector state .
Definition ElementSelector.hpp:20