23#include <boost/format.hpp>
36 class i_drag_drop_item;
37 class i_drag_drop_target;
83 return static_cast<item_cell_flags>(
static_cast<uint32_t
>(lhs) |
static_cast<uint32_t
>(rhs));
88 return static_cast<item_cell_flags>(
static_cast<uint32_t
>(lhs)&
static_cast<uint32_t
>(rhs));
146 struct item_presentation_model_index : item_index<item_presentation_model_index>
148 typedef item_presentation_model_index abstract_type;
149 using item_index::item_index;
151 typedef std::optional<item_presentation_model_index> optional_item_presentation_model_index;
153 class i_item_sort_predicate
156 virtual ~i_item_sort_predicate() =
default;
158 virtual bool compare(item_model_index aLhs, item_model_index aRhs)
const noexcept = 0;
161 class item_sort_predicate :
public i_item_sort_predicate
164 item_sort_predicate(std::function<
bool(item_model_index aLhs, item_model_index aRhs)>
const& aPredicate) :
165 iPredicate{ aPredicate }
169 bool compare(item_model_index aLhs, item_model_index aRhs)
const noexcept override
171 return iPredicate(aLhs, aRhs);
174 std::function<bool(item_model_index aLhs, item_model_index aRhs)> iPredicate;
177 class i_item_presentation_model :
public i_reference_counted,
public i_property_owner
181 declare_event(column_info_changed, item_presentation_model_index::column_type)
183 declare_event(item_added, item_presentation_model_index
const&)
184 declare_event(item_changed, item_presentation_model_index
const&)
185 declare_event(item_removing, item_presentation_model_index
const&)
186 declare_event(item_removed, item_presentation_model_index
const&)
187 declare_event(item_expanding, item_presentation_model_index
const&)
188 declare_event(item_collapsing, item_presentation_model_index
const&)
189 declare_event(item_expanded, item_presentation_model_index
const&)
190 declare_event(item_collapsed, item_presentation_model_index
const&)
191 declare_event(item_toggled, item_presentation_model_index
const&)
192 declare_event(item_checked, item_presentation_model_index
const&)
193 declare_event(item_unchecked, item_presentation_model_index
const&)
194 declare_event(item_indeterminate, item_presentation_model_index
const&)
202 declare_event(dragging_item_render_info, i_drag_drop_item
const&,
bool&, size&)
203 declare_event(dragging_item_render, i_drag_drop_item
const&, i_graphics_context&, point
const&)
204 declare_event(dragging_item_cancelled, i_drag_drop_item
const&)
205 declare_event(item_dropped, i_drag_drop_item
const&, i_drag_drop_target&)
207 typedef i_item_presentation_model abstract_type;
208 struct cell_meta_type
212 button_checked_state checked =
false;
213 bool expanded =
false;
220 virtual void visit(cell_meta_type& aMeta) = 0;
222 enum class sort_direction
227 typedef std::optional<sort_direction> optional_sort_direction;
228 typedef std::pair<item_presentation_model_index::column_type, sort_direction> sort_by_param;
229 typedef std::optional<sort_by_param> optional_sort_by_param;
230 typedef std::string filter_search_key;
231 enum class filter_search_type
237 enum class case_sensitivity
242 typedef std::tuple<item_presentation_model_index::column_type, filter_search_key, filter_search_type, case_sensitivity> filter;
243 typedef std::optional<filter> optional_filter;
245 struct no_item_model : std::logic_error { no_item_model() :
std::logic_error(
"neogfx::i_item_presentation_model::no_item_model") {} };
246 struct bad_index : std::logic_error { bad_index() :
std::logic_error(
"neogfx::i_item_presentation_model::bad_index") {} };
247 struct no_mapped_row : std::logic_error { no_mapped_row() :
std::logic_error(
"neogfx::i_item_presentation_model::no_mapped_row") {} };
248 struct already_attached : std::logic_error { already_attached() :
std::logic_error(
"neogfx::i_item_presentation_model::already_attached") {} };
249 struct not_attached : std::logic_error { not_attached() :
std::logic_error(
"neogfx::i_item_presentation_model::not_attached") {} };
251 virtual ~i_item_presentation_model() =
default;
253 virtual bool attached()
const = 0;
254 virtual i_widget& attachment()
const = 0;
255 virtual void attach(i_ref_ptr<i_widget>
const& aWidget) = 0;
256 virtual void detach() = 0;
258 virtual bool updating()
const = 0;
259 virtual void begin_update() = 0;
260 virtual void end_update() = 0;
261 virtual bool has_item_model()
const = 0;
263 virtual void set_item_model(i_item_model& aItemModel) = 0;
264 virtual item_model_index to_item_model_index(item_presentation_model_index
const& aIndex)
const = 0;
265 virtual bool has_item_model_index(item_model_index
const& aIndex)
const = 0;
266 virtual item_presentation_model_index from_item_model_index(item_model_index
const& aIndex,
bool aIgnoreColumn =
false)
const = 0;
268 virtual uint32_t rows()
const = 0;
269 virtual uint32_t columns()
const = 0;
270 virtual uint32_t columns(item_presentation_model_index
const& aIndex)
const = 0;
272 virtual void accept(i_meta_visitor& aVisitor,
bool aIgnoreCollapsedState =
false) = 0;
274 virtual dimension column_width(item_presentation_model_index::column_type aColumnIndex, i_units_context
const& aUnitsContext,
bool aExtendIntoPadding =
true)
const = 0;
275 virtual std::string
const& column_heading_text(item_presentation_model_index::column_type aColumnIndex)
const = 0;
276 virtual size column_heading_extents(item_presentation_model_index::column_type aColumnIndex, i_units_context
const& aUnitsContext)
const = 0;
277 virtual void set_column_heading_text(item_presentation_model_index::column_type aColumnIndex, std::string
const& aHeadingText) = 0;
278 virtual item_cell_flags column_flags(item_presentation_model_index::column_type aColumnIndex)
const = 0;
279 virtual void set_column_flags(item_presentation_model_index::column_type aColumnIndex, item_cell_flags aFlags) = 0;
280 virtual optional_size column_image_size(item_presentation_model_index::column_type aColumnIndex)
const = 0;
281 virtual void set_column_image_size(item_presentation_model_index::column_type aColumnIndex, optional_size
const& aImageSize) = 0;
283 virtual bool expand(item_presentation_model_index
const& aIndex) = 0;
284 virtual bool collapse(item_presentation_model_index
const& aIndex) = 0;
285 virtual bool toggle_expanded(item_presentation_model_index
const& aIndex) = 0;
286 virtual bool expand_to(item_model_index
const& aIndex) = 0;
288 virtual button_checked_state
const& checked_state(item_presentation_model_index
const& aIndex) = 0;
289 virtual bool is_checked(item_presentation_model_index
const& aIndex)
const = 0;
290 virtual bool is_unchecked(item_presentation_model_index
const& aIndex)
const = 0;
291 virtual bool is_indeterminate(item_presentation_model_index
const& aIndex)
const = 0;
292 virtual void set_checked_state(item_presentation_model_index
const& aIndex, button_checked_state
const& aState) = 0;
293 virtual void check(item_presentation_model_index
const& aIndex) = 0;
294 virtual void uncheck(item_presentation_model_index
const& aIndex) = 0;
295 virtual void set_indeterminate(item_presentation_model_index
const& aIndex) = 0;
296 virtual void set_checked(item_presentation_model_index
const& aIndex,
bool aChecked) = 0;
297 virtual void toggle_check(item_presentation_model_index
const& aIndex) = 0;
299 virtual font
const& default_font()
const = 0;
300 virtual void set_default_font(optional_font
const& aDefaultFont) = 0;
301 virtual size cell_spacing(i_units_context
const& aUnitsContext)
const = 0;
302 virtual void set_cell_spacing(optional_size
const& aSpacing, i_units_context
const& aUnitsContext) = 0;
303 virtual neogfx::padding cell_padding(i_units_context
const& aUnitsContext)
const = 0;
304 virtual void set_cell_padding(optional_padding
const& aPadding, i_units_context
const& aUnitsContext) = 0;
305 virtual bool alternating_row_color()
const = 0;
306 virtual void set_alternating_row_color(
bool aAlternatingColor) = 0;
308 virtual dimension item_height(item_presentation_model_index
const& aIndex, i_units_context
const& aUnitsContext)
const = 0;
309 virtual double total_height(i_units_context
const& aUnitsContext)
const = 0;
310 virtual double item_position(item_presentation_model_index
const& aIndex, i_units_context
const& aUnitsContext)
const = 0;
311 virtual std::pair<item_presentation_model_index::value_type, coordinate> item_at(
double aPosition, i_units_context
const& aUnitsContext)
const = 0;
313 virtual item_cell_flags cell_flags(item_presentation_model_index
const& aIndex)
const = 0;
314 virtual void set_cell_flags(item_presentation_model_index
const& aIndex, item_cell_flags aFlags) = 0;
315 virtual cell_meta_type& cell_meta(item_presentation_model_index
const& aIndex)
const = 0;
317 virtual std::string cell_to_string(item_presentation_model_index
const& aIndex)
const = 0;
318 virtual item_cell_data string_to_cell_data(item_presentation_model_index
const& aIndex, std::string
const& aString)
const = 0;
319 virtual item_cell_data string_to_cell_data(item_presentation_model_index
const& aIndex, std::string
const& aString,
bool& aError)
const = 0;
320 virtual boost::basic_format<char> cell_format(item_presentation_model_index
const& aIndex)
const = 0;
321 virtual optional_color cell_color(item_presentation_model_index
const& aIndex, color_role aColorRole)
const = 0;
322 virtual optional_font cell_font(item_presentation_model_index
const& aIndex)
const = 0;
323 virtual optional_size cell_image_size(item_presentation_model_index
const& aIndex)
const = 0;
324 virtual optional_size cell_check_box_size(item_presentation_model_index
const& aIndex, i_units_context
const& aUnitsContext)
const = 0;
325 virtual optional_size cell_tree_expander_size(item_presentation_model_index
const& aIndex, i_units_context
const& aUnitsContext)
const = 0;
326 virtual optional_texture cell_image(item_presentation_model_index
const& aIndex)
const = 0;
327 virtual neogfx::glyph_text& cell_glyph_text(item_presentation_model_index
const& aIndex)
const = 0;
328 virtual size cell_extents(item_presentation_model_index
const& aIndex, i_units_context
const& aUnitsContext)
const = 0;
329 virtual dimension indent(item_presentation_model_index
const& aIndex, i_units_context
const& aUnitsContext)
const = 0;
331 virtual void sort(i_item_sort_predicate
const& aPredicate) = 0;
332 virtual bool sortable()
const = 0;
333 virtual void set_sortable(
bool aSortable) = 0;
334 virtual optional_sort_by_param sorting_by()
const = 0;
335 virtual void sort_by(item_presentation_model_index::column_type aColumnIndex, optional_sort_direction
const& aSortDirection = optional_sort_direction{}) = 0;
336 virtual void reset_sort() = 0;
338 virtual optional_item_presentation_model_index find_item(filter_search_key
const& aFilterSearchKey, item_presentation_model_index::column_type aColumnIndex = 0, filter_search_type aFilterSearchType = filter_search_type::Prefix, case_sensitivity aCaseSensitivity = case_sensitivity::CaseInsensitive)
const = 0;
340 virtual bool filtering()
const = 0;
341 virtual optional_filter filtering_by()
const = 0;
342 virtual void filter_by(item_presentation_model_index::column_type aColumnIndex, filter_search_key
const& aFilterSearchKey, filter_search_type aFilterSearchType = filter_search_type::Prefix, case_sensitivity aCaseSensitivity = case_sensitivity::CaseInsensitive) = 0;
343 virtual void reset_filter() = 0;
346 bool column_editable(item_presentation_model_index::column_type aColumnIndex)
const
348 return (column_flags(aColumnIndex) & item_cell_flags::Editable) == item_cell_flags::Editable;
350 void set_column_editable(item_presentation_model_index::column_type aColumnIndex,
bool aEditable =
true)
354 set_column_flags(aColumnIndex, column_flags(aColumnIndex) | item_cell_flags::Editable);
355 if ((column_flags(aColumnIndex) & (item_cell_flags::EditableWhenFocused | item_cell_flags::EditableOnInputEvent)) == item_cell_flags::Invalid)
356 set_column_flags(aColumnIndex, column_flags(aColumnIndex) | item_cell_flags::EditableWhenFocused);
359 set_column_flags(aColumnIndex, column_flags(aColumnIndex) & ~item_cell_flags::Editable);
361 bool column_editable_when_focused(item_presentation_model_index::column_type aColumnIndex)
const
363 return column_editable(aColumnIndex) && (column_flags(aColumnIndex) & item_cell_flags::EditableWhenFocused) == item_cell_flags::EditableWhenFocused;
365 void set_column_editable_when_focused(item_presentation_model_index::column_type aColumnIndex,
bool aEditableWhenFocused =
true)
367 if (aEditableWhenFocused)
368 set_column_flags(aColumnIndex, (column_flags(aColumnIndex) | item_cell_flags::Editable | item_cell_flags::EditableWhenFocused) & ~item_cell_flags::EditableOnInputEvent);
370 set_column_flags(aColumnIndex, column_flags(aColumnIndex) & ~(item_cell_flags::Editable | item_cell_flags::EditableWhenFocused));
372 bool column_editable_on_input_event(item_presentation_model_index::column_type aColumnIndex)
const
374 return column_editable(aColumnIndex) && (column_flags(aColumnIndex) & item_cell_flags::EditableOnInputEvent) == item_cell_flags::EditableOnInputEvent;
376 void set_column_editable_on_input_event(item_presentation_model_index::column_type aColumnIndex,
bool aEditableOnInputEvent =
true)
378 if (aEditableOnInputEvent)
379 set_column_flags(aColumnIndex, (column_flags(aColumnIndex) | item_cell_flags::Editable | item_cell_flags::EditableOnInputEvent) & ~item_cell_flags::EditableWhenFocused);
381 set_column_flags(aColumnIndex, column_flags(aColumnIndex) & ~(item_cell_flags::Editable | item_cell_flags::EditableOnInputEvent));
383 bool column_selectable(item_model_index::column_type aColumnIndex)
const
385 return (column_flags(aColumnIndex) & item_cell_flags::Selectable) == item_cell_flags::Selectable;
387 void set_column_selectable(item_model_index::column_type aColumnIndex,
bool aSelectable =
true)
390 set_column_flags(aColumnIndex, column_flags(aColumnIndex) | item_cell_flags::Selectable);
392 set_column_flags(aColumnIndex, column_flags(aColumnIndex) & ~item_cell_flags::Selectable);
394 bool column_read_only(item_model_index::column_type aColumnIndex)
const
396 return (column_flags(aColumnIndex) & item_cell_flags::Editable) != item_cell_flags::Editable;
398 void set_column_read_only(item_model_index::column_type aColumnIndex,
bool aReadOnly =
true)
401 set_column_flags(aColumnIndex, column_flags(aColumnIndex) & ~item_cell_flags::Editable);
403 set_column_flags(aColumnIndex, column_flags(aColumnIndex) | item_cell_flags::Editable);
405 bool column_checkable(item_model_index::column_type aColumnIndex)
const
407 return (column_flags(aColumnIndex) & item_cell_flags::Checkable) == item_cell_flags::Checkable;
409 void set_column_checkable(item_model_index::column_type aColumnIndex,
bool aCheckable =
true)
413 set_column_flags(aColumnIndex, column_flags(aColumnIndex) | item_cell_flags::Checkable);
414 if ((column_flags(aColumnIndex) & (item_cell_flags::CheckableBiState | item_cell_flags::CheckableTriState)) == item_cell_flags::Invalid)
415 set_column_flags(aColumnIndex, column_flags(aColumnIndex) | item_cell_flags::CheckableBiState);
418 set_column_flags(aColumnIndex, column_flags(aColumnIndex) & ~item_cell_flags::Checkable);
420 bool column_bi_state_checkable(item_model_index::column_type aColumnIndex)
const
422 return column_checkable(aColumnIndex) && (column_flags(aColumnIndex) & item_cell_flags::CheckableBiState) == item_cell_flags::CheckableBiState;
424 void set_column_bi_state_checkable(item_model_index::column_type aColumnIndex,
bool aCheckableBiState =
true)
426 if (aCheckableBiState)
427 set_column_flags(aColumnIndex, (column_flags(aColumnIndex) | item_cell_flags::Checkable | item_cell_flags::CheckableBiState) & ~item_cell_flags::CheckableTriState);
429 set_column_flags(aColumnIndex, column_flags(aColumnIndex) & ~(item_cell_flags::Checkable | item_cell_flags::CheckableBiState));
431 bool column_tri_state_checkable(item_model_index::column_type aColumnIndex)
const
433 return column_checkable(aColumnIndex) && (column_flags(aColumnIndex) & item_cell_flags::CheckableTriState) == item_cell_flags::CheckableTriState;
435 void set_column_tri_state_checkable(item_model_index::column_type aColumnIndex,
bool aCheckableTriState =
true)
437 if (aCheckableTriState)
438 set_column_flags(aColumnIndex, (column_flags(aColumnIndex) | item_cell_flags::Checkable | item_cell_flags::CheckableTriState) & ~item_cell_flags::CheckableBiState);
440 set_column_flags(aColumnIndex, column_flags(aColumnIndex) & ~(item_cell_flags::Checkable | item_cell_flags::CheckableTriState));
442 bool cell_editable(item_presentation_model_index
const& aIndex)
const
444 return (cell_flags(aIndex) & item_cell_flags::Editable) == item_cell_flags::Editable;
446 void set_cell_editable(item_presentation_model_index
const& aIndex,
bool aEditable =
true)
450 set_cell_flags(aIndex, cell_flags(aIndex) | item_cell_flags::Editable);
451 if ((cell_flags(aIndex) & (item_cell_flags::EditableWhenFocused | item_cell_flags::EditableOnInputEvent)) == item_cell_flags::Invalid)
452 set_cell_flags(aIndex, cell_flags(aIndex) | item_cell_flags::EditableWhenFocused);
455 set_cell_flags(aIndex, cell_flags(aIndex) & ~item_cell_flags::Editable);
457 bool cell_editable_when_focused(item_presentation_model_index
const& aIndex)
const
459 return cell_editable(aIndex) && (cell_flags(aIndex) & item_cell_flags::EditableWhenFocused) == item_cell_flags::EditableWhenFocused;
461 void set_cell_editable_when_focused(item_presentation_model_index
const& aIndex,
bool aEditableWhenFocused =
true)
463 if (aEditableWhenFocused)
464 set_cell_flags(aIndex, (cell_flags(aIndex) | item_cell_flags::Editable | item_cell_flags::EditableWhenFocused) & ~item_cell_flags::EditableOnInputEvent);
466 set_cell_flags(aIndex, cell_flags(aIndex) & ~(item_cell_flags::Editable | item_cell_flags::EditableWhenFocused));
468 bool cell_editable_on_input_event(item_presentation_model_index
const& aIndex)
const
470 return cell_editable(aIndex) && (cell_flags(aIndex) & item_cell_flags::EditableOnInputEvent) == item_cell_flags::EditableOnInputEvent;
472 void set_cell_editable_on_input_event(item_presentation_model_index
const& aIndex,
bool aEditableOnInputEvent =
true)
474 if (aEditableOnInputEvent)
475 set_cell_flags(aIndex, (cell_flags(aIndex) | item_cell_flags::Editable | item_cell_flags::EditableOnInputEvent) & ~item_cell_flags::EditableWhenFocused);
477 set_cell_flags(aIndex, cell_flags(aIndex) & ~(item_cell_flags::Editable | item_cell_flags::EditableOnInputEvent));
479 bool cell_selectable(item_presentation_model_index
const& aIndex)
const
481 return (cell_flags(aIndex) & item_cell_flags::Selectable) == item_cell_flags::Selectable;
483 void set_cell_selectable(item_presentation_model_index
const& aIndex,
bool aSelectable =
true)
486 set_cell_flags(aIndex, cell_flags(aIndex) | item_cell_flags::Selectable);
488 set_cell_flags(aIndex, cell_flags(aIndex) & ~item_cell_flags::Selectable);
490 bool cell_read_only(item_presentation_model_index
const& aIndex)
const
492 return (cell_flags(aIndex) & item_cell_flags::Editable) != item_cell_flags::Editable;
494 void set_cell_read_only(item_presentation_model_index
const& aIndex,
bool aReadOnly =
true)
497 set_cell_flags(aIndex, cell_flags(aIndex) & ~item_cell_flags::Editable);
499 set_cell_flags(aIndex, cell_flags(aIndex) | item_cell_flags::Editable);
501 bool cell_checkable(item_presentation_model_index
const& aIndex)
const
503 return (cell_flags(aIndex) & item_cell_flags::Checkable) == item_cell_flags::Checkable;
505 void set_cell_checkable(item_presentation_model_index
const& aIndex,
bool aCheckable =
true)
509 set_cell_flags(aIndex, cell_flags(aIndex) | item_cell_flags::Checkable);
510 if ((cell_flags(aIndex) & (item_cell_flags::CheckableBiState | item_cell_flags::CheckableTriState)) == item_cell_flags::Invalid)
511 set_cell_flags(aIndex, cell_flags(aIndex) | item_cell_flags::CheckableBiState);
514 set_cell_flags(aIndex, cell_flags(aIndex) & ~item_cell_flags::Checkable);
516 bool cell_bi_state_checkable(item_presentation_model_index
const& aIndex)
const
518 return cell_checkable(aIndex) && (cell_flags(aIndex) & item_cell_flags::CheckableBiState) == item_cell_flags::CheckableBiState;
520 void set_cell_bi_state_checkable(item_presentation_model_index
const& aIndex,
bool aCheckableBiState =
true)
522 if (aCheckableBiState)
523 set_cell_flags(aIndex, (cell_flags(aIndex) | item_cell_flags::Checkable | item_cell_flags::CheckableBiState) & ~item_cell_flags::CheckableTriState);
525 set_cell_flags(aIndex, cell_flags(aIndex) & ~(item_cell_flags::Checkable | item_cell_flags::CheckableBiState));
527 bool cell_tri_state_checkable(item_presentation_model_index
const& aIndex)
const
529 return cell_checkable(aIndex) && (cell_flags(aIndex) & item_cell_flags::CheckableTriState) == item_cell_flags::CheckableTriState;
531 void set_cell_tri_state_checkable(item_presentation_model_index
const& aIndex,
bool aCheckableTriState =
true)
533 if (aCheckableTriState)
534 set_cell_flags(aIndex, (cell_flags(aIndex) | item_cell_flags::Checkable | item_cell_flags::CheckableTriState) & ~item_cell_flags::CheckableBiState);
536 set_cell_flags(aIndex, cell_flags(aIndex) & ~(item_cell_flags::Checkable | item_cell_flags::CheckableTriState));
540 class scoped_item_update
543 scoped_item_update(i_item_presentation_model& aPresentationModel) :
544 iPresentationModel{ aPresentationModel }
546 iPresentationModel.begin_update();
548 ~scoped_item_update()
550 iPresentationModel.end_update();
553 i_item_presentation_model& iPresentationModel;
#define end_declare_enum(enumName)
#define declare_enum_string(enumName, enumEnumerator)
#define begin_declare_enum(enumName)
constexpr font_style & operator&=(font_style &aLhs, font_style aRhs)
constexpr style_aspect operator&(style_aspect aLhs, style_aspect aRhs)
audio_channel operator^(audio_channel lhs, audio_channel rhs)
optional< color > optional_color
audio_channel operator~(audio_channel lhs)
default_geometry_value_type dimension
std::optional< glyph_text > optional_glyph_text
std::optional< item_cell_flags > optional_item_cell_flags
std::optional< texture > optional_texture
basic_item_model< void * > item_model
constexpr font_style & operator|=(font_style &aLhs, font_style aRhs)
item_cell_selection_flags
constexpr style_aspect operator|(style_aspect aLhs, style_aspect aRhs)
optional< size > optional_size
constexpr font_style & operator^=(font_style &aLhs, font_style aRhs)
basic_size< coordinate > size
constexpr decltype(auto) visit(Visitor &&vis, neolib::variant< Types... > &&var)
#define declare_event(declName,...)