neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
i_item_selection_model.hpp
Go to the documentation of this file.
1// i_item_selection_model.hpp
2/*
3 neogfx C++ App/Game Engine
4 Copyright (c) 2015, 2020 Leigh Johnston. All Rights Reserved.
5
6 This program is free software: you can redistribute it and / or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#pragma once
21
22#include <neogfx/neogfx.hpp>
23#include <neolib/core/i_map.hpp>
27
28namespace neogfx
29{
30 class i_item_presentation_model;
31
39
41 {
42 None = 0x0000,
43 Select = 0x0001,
44 Deselect = 0x0002,
45 Toggle = 0x0004,
46 Clear = 0x0008,
47 Row = 0x0100,
48 Column = 0x0200,
49 CurrentIndex = 0x1000,
50 Queued = 0x4000,
51 Internal = 0x8000,
52
66 };
67
84
86 {
87 aLhs = static_cast<item_selection_operation>(static_cast<uint32_t>(aLhs) | static_cast<uint32_t>(aRhs));
88 return aLhs;
89 }
90
92 {
93 aLhs = static_cast<item_selection_operation>(static_cast<uint32_t>(aLhs) & static_cast<uint32_t>(aRhs));
94 return aLhs;
95 }
96
98 {
99 aLhs |= aRhs;
100 return aLhs;
101 }
102
104 {
105 aLhs &= aRhs;
106 return aLhs;
107 }
108
110 {
111 return static_cast<item_selection_operation>(~static_cast<uint32_t>(aLhs));
112 }
113
115 {
116 typedef selection_area abstract_type; // todo: create abstract interface
117 item_presentation_model_index topLeft;
118 item_presentation_model_index bottomRight;
119 };
120
122
123 inline bool contains(item_selection const& aSelection, item_presentation_model_index aIndex)
124 {
125 for (auto const& part : aSelection)
126 {
127 auto const& area = part.second();
128 if (aIndex.row() >= area.topLeft.row() && aIndex.row() <= area.bottomRight.row() &&
129 aIndex.column() >= area.topLeft.column() && aIndex.column() <= area.bottomRight.column())
130 return true;
131 }
132 return false;
133 }
134
135 // todo: column
136 struct row {};
137 struct cell {};
138
139 template <typename Type>
141 {
143 public:
144 using value_type = item_presentation_model_index;
145 using pointer = value_type const*;
146 using reference = value_type const&;
147 using difference_type = std::ptrdiff_t;
148 using iterator_catagory = std::forward_iterator_tag;
149 public:
151 iSelection{ nullptr }, iIterator {}
152 {
153 }
155 iSelection{ &aSelection }, iIterator{ aPosition }
156 {
157 }
158 public:
159 bool operator==(const selection_iterator& aRhs) const
160 {
161 if (singular() || aRhs.singular())
162 return false;
163 else if (&selection() != &aRhs.selection())
164 return false;
165 else if (is_end() || aRhs.is_end())
166 return is_end() == aRhs.is_end();
167 else if (iterator() != aRhs.iterator())
168 return false;
169 else
170 return index() == aRhs.index();
171 }
172 bool operator!=(const selection_iterator& aRhs) const
173 {
174 return !(*this == aRhs);
175 }
176 public:
178 {
179 return index();
180 }
182 {
183 return &index();
184 }
185 public:
187 {
188 if constexpr (std::is_same_v<Type, row>)
189 {
190 index() += item_presentation_model_index{ 1, 0 };
191 if (index().row() > iIterator->second().bottomRight.row())
192 {
193 ++iterator();
194 iIndex = std::nullopt;
195 }
196 }
197 else if constexpr (std::is_same_v<Type, cell>)
198 {
199 index() += item_presentation_model_index{ 0, 1 };
200 if (index().column() > iIterator->second().bottomRight.column())
201 {
202 index().set_column(iIterator->second().topLeft.column());
203 index() += item_presentation_model_index{ 1, 0 };
204 if (index().row() > iIterator->second().bottomRight.row())
205 {
206 ++iterator();
207 iIndex = std::nullopt;
208 }
209 }
210 }
211 return *this;
212 }
213 private:
214 bool singular() const
215 {
216 return iSelection == nullptr;
217 }
218 bool is_end() const
219 {
220 return !singular() && iterator() == selection().end();
221 }
222 item_selection const& selection() const
223 {
224 return *iSelection;
225 }
226 item_selection::const_iterator const& iterator() const
227 {
228 return iIterator;
229 }
231 {
232 return iIterator;
233 }
234 item_presentation_model_index const& index() const
235 {
236 if (iIndex == std::nullopt)
237 iIndex = iterator()->first();
238 return *iIndex;
239 }
240 item_presentation_model_index& index()
241 {
242 return const_cast<item_presentation_model_index&>(const_cast<selection_iterator const&>(*this).index());
243 }
244 private:
245 item_selection const* iSelection;
247 mutable std::optional<item_presentation_model_index> iIndex;
248 };
249
252
254 {
255 return row_selection_iterator{ aSelection, aSelection.begin() };
256 }
257
259 {
260 return row_selection_iterator{ aSelection, aSelection.end() };
261 }
262
264 {
265 return cell_selection_iterator{ aSelection, aSelection.begin() };
266 }
267
269 {
270 return cell_selection_iterator{ aSelection, aSelection.end() };
271 }
272
274 {
275 public:
276 declare_event(current_index_changed, const optional_item_presentation_model_index& /* aCurrentIndex */, const optional_item_presentation_model_index& /* aPreviousIndex */)
277 declare_event(selection_changed, const item_selection&, const item_selection&)
278 declare_event(presentation_model_added, i_item_presentation_model&)
279 declare_event(presentation_model_changed, i_item_presentation_model&, i_item_presentation_model&)
280 declare_event(presentation_model_removed, i_item_presentation_model&)
282 public:
283 struct no_presentation_model : std::logic_error { no_presentation_model() : std::logic_error("neogfx::i_item_selection_model::no_presentation_model") {} };
284 struct no_current_index : std::logic_error { no_current_index() : std::logic_error("neogfx::i_item_selection_model::no_current_index") {} };
285 public:
287 public:
288 virtual ~i_item_selection_model() = default;
289 public:
290 virtual bool has_presentation_model() const = 0;
291 virtual i_item_presentation_model& presentation_model() const = 0;
292 virtual void set_presentation_model(i_item_presentation_model& aModel) = 0;
293 public:
294 virtual item_selection_mode mode() const = 0;
295 virtual void set_mode(item_selection_mode aType) = 0;
296 public:
297 virtual bool has_current_index() const = 0;
298 virtual item_presentation_model_index const& current_index() const = 0;
299 virtual void set_current_index(item_presentation_model_index const& aIndex) = 0;
300 virtual void clear_current_index() = 0;
301 virtual item_presentation_model_index relative_to_current_index(index_location aRelativeLocation, bool aSelectable = true, bool aEditable = false) const = 0;
302 virtual item_presentation_model_index relative_to_index(item_presentation_model_index const& aIndex, index_location aRelativeLocation, bool aSelectable = true, bool aEditable = false) const = 0;
303 virtual item_presentation_model_index next_cell() const = 0;
304 virtual item_presentation_model_index next_cell(item_presentation_model_index const& aIndex) const = 0;
305 virtual item_presentation_model_index previous_cell() const = 0;
306 virtual item_presentation_model_index previous_cell(item_presentation_model_index const& aIndex) const = 0;
307 public:
308 virtual const item_selection& selection() const = 0;
309 virtual bool is_selected(item_presentation_model_index const& aIndex) const = 0;
310 virtual bool is_selectable(item_presentation_model_index const& aIndex) const = 0;
311 virtual void clear_selection() = 0;
312 virtual void select(item_presentation_model_index const& aIndex, item_selection_operation aOperation) = 0;
313 virtual void select(item_model_index const& aIndex, item_selection_operation aOperation) = 0;
314 public:
315 virtual bool sorting() const = 0;
316 virtual bool filtering() const = 0;
317 public:
318 virtual bool is_editable(item_presentation_model_index const& aIndex) const = 0;
319 // helpers
320 public:
321 optional_item_presentation_model_index current_index_maybe() const
322 {
323 if (has_current_index())
324 return current_index();
325 return {};
326 }
327 void select(item_presentation_model_index const& aIndex)
328 {
329 switch (mode())
330 {
332 break;
335 break;
338 break;
341 break;
342 }
343 }
361 void clear(item_presentation_model_index const& aIndex)
362 {
364 }
365 void clear(item_model_index const& aIndex)
366 {
368 }
386 {
387 return cell_begin();
388 }
390 {
391 return cell_end();
392 }
393 };
394}
virtual item_presentation_model_index previous_cell(item_presentation_model_index const &aIndex) const =0
virtual bool has_presentation_model() const =0
virtual void set_mode(item_selection_mode aType)=0
void clear(item_presentation_model_index const &aIndex)
virtual void set_current_index(item_presentation_model_index const &aIndex)=0
virtual item_presentation_model_index relative_to_index(item_presentation_model_index const &aIndex, index_location aRelativeLocation, bool aSelectable=true, bool aEditable=false) const =0
virtual i_item_presentation_model & presentation_model() const =0
virtual ~i_item_selection_model()=default
virtual bool is_selected(item_presentation_model_index const &aIndex) const =0
virtual void select(item_model_index const &aIndex, item_selection_operation aOperation)=0
void select(item_model_index const &aIndex)
row_selection_iterator row_begin() const
cell_selection_iterator cell_begin() const
virtual item_presentation_model_index relative_to_current_index(index_location aRelativeLocation, bool aSelectable=true, bool aEditable=false) const =0
virtual item_selection_mode mode() const =0
virtual bool is_editable(item_presentation_model_index const &aIndex) const =0
void clear(item_model_index const &aIndex)
virtual bool is_selectable(item_presentation_model_index const &aIndex) const =0
virtual void select(item_presentation_model_index const &aIndex, item_selection_operation aOperation)=0
virtual bool sorting() const =0
virtual void clear_selection()=0
void select(item_presentation_model_index const &aIndex)
virtual void clear_current_index()=0
virtual item_presentation_model_index next_cell(item_presentation_model_index const &aIndex) const =0
row_selection_iterator row_end() const
cell_selection_iterator begin() const
cell_selection_iterator cell_end() const
optional_item_presentation_model_index current_index_maybe() const
virtual void set_presentation_model(i_item_presentation_model &aModel)=0
virtual bool filtering() const =0
virtual bool has_current_index() const =0
virtual item_presentation_model_index next_cell() const =0
declare_event(current_index_changed, const optional_item_presentation_model_index &, const optional_item_presentation_model_index &) declare_event(selection_changed
virtual const item_selection & selection() const =0
virtual item_presentation_model_index previous_cell() const =0
virtual item_presentation_model_index const & current_index() const =0
cell_selection_iterator end() const
item_presentation_model_index value_type
std::forward_iterator_tag iterator_catagory
selection_iterator(item_selection const &aSelection, item_selection::const_iterator aPosition)
bool operator!=(const selection_iterator &aRhs) const
bool operator==(const selection_iterator &aRhs) const
const_iterator begin() const
const_iterator end() const
base_type::const_iterator const_iterator
Definition i_map.hpp:58
row_selection_iterator row_end(item_selection const &aSelection)
bool contains(item_selection const &aSelection, item_presentation_model_index aIndex)
row_selection_iterator row_begin(item_selection const &aSelection)
constexpr font_style & operator&=(font_style &aLhs, font_style aRhs)
Definition font.hpp:81
constexpr style_aspect operator&(style_aspect aLhs, style_aspect aRhs)
Definition i_style.hpp:60
audio_channel operator~(audio_channel lhs)
selection_iterator< row > row_selection_iterator
cell_selection_iterator cell_end(item_selection const &aSelection)
constexpr font_style & operator|=(font_style &aLhs, font_style aRhs)
Definition font.hpp:76
selection_iterator< cell > cell_selection_iterator
cell_selection_iterator cell_begin(item_selection const &aSelection)
constexpr style_aspect operator|(style_aspect aLhs, style_aspect aRhs)
Definition i_style.hpp:55
neolib::i_map< item_presentation_model_index, selection_area > item_selection
Definition plf_hive.h:79
#define declare_event(declName,...)
Definition i_event.hpp:305
item_presentation_model_index bottomRight
item_presentation_model_index topLeft