neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
text_edit.hpp
Go to the documentation of this file.
1// text_edit.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 <functional>
24#include <boost/pool/pool_alloc.hpp>
37
38namespace neogfx
39{
40 enum class text_edit_caps : uint32_t
41 {
42 None = 0x00000000,
43
44 SingleLine = 0x00000001,
45 MultiLine = 0x00000002,
47
48 Password = 0x00000100,
49 ShowPassword = 0x00000200,
50
51 ParseURIs = 0x00001000,
52
53 OnlyAccept = 0x00010000,
54
56 };
57}
58
67
68namespace neogfx
69{
71 {
72 return static_cast<text_edit_caps>(~static_cast<uint32_t>(aLhs));
73 }
74
76 {
77 return static_cast<text_edit_caps>(static_cast<uint32_t>(aLhs) & static_cast<uint32_t>(aRhs));
78 }
79
81 {
82 return static_cast<text_edit_caps>(static_cast<uint32_t>(aLhs) | static_cast<uint32_t>(aRhs));
83 }
84
85 class text_edit : public framed_scrollable_widget, public i_clipboard_sink, public i_text_document
86 {
87 meta_object(framed_scrollable_widget)
88 // events
89 public:
90 define_event(CanAcceptText, can_accept_text, i_string const&, bool&)
91 define_event(AcceptText, accept_text, i_string const&)
92 define_event(TextFilter, text_filter, i_string const&, bool&)
93 define_event(TextChanged, text_changed)
94 define_event(DefaultStyleChanged, default_style_changed)
95 define_event(ContextMenu, context_menu, i_menu&)
96 define_event(UriClicked, uri_clicked, i_string const&)
97
98 // types
99 private:
100 typedef text_edit property_context_type;
101
102 struct password_bits
103 {
104 text_edit& parent;
105 neogfx::padding previousPadding;
106 button<> showPassword;
107
108 password_bits(text_edit& aParent);
109 ~password_bits();
110 };
111
112 public:
113 typedef std::optional<string> optional_password_mask;
114
115 class character_style
116 {
117 public:
118 character_style();
119 character_style(character_style const& aOther);
120 character_style(
121 optional_font const& aFont,
122 const color_or_gradient& aTextColor = color_or_gradient{},
123 const color_or_gradient& aPaperColor = color_or_gradient{},
124 const optional_text_effect& aTextEffect = optional_text_effect{});
125 public:
126 optional_font const& font() const;
127 const color_or_gradient& glyph_color() const;
128 const color_or_gradient& text_color() const;
129 const color_or_gradient& paper_color() const;
130 bool smart_underline() const;
131 bool ignore_emoji() const;
132 const optional_text_effect& text_effect() const;
133 text_format as_text_format() const;
134 character_style& set_font(optional_font const& aFont = optional_font{});
135 character_style& set_font_if_none(neogfx::font const& aFont);
136 character_style& set_glyph_color(const color_or_gradient& aColor = color_or_gradient{});
137 character_style& set_text_color(const color_or_gradient& aColor = color_or_gradient{});
138 character_style& set_paper_color(const color_or_gradient& aColor = color_or_gradient{});
139 character_style& set_text_effect(const optional_text_effect& aEffect = optional_text_effect{});
140 character_style& set_from_text_format(const text_format& aTextFormat);
141 public:
142 character_style& merge(const character_style& aRhs);
143 public:
144 bool operator==(const character_style& aRhs) const;
145 bool operator!=(const character_style& aRhs) const;
146 bool operator<(const character_style& aRhs) const;
147 private:
148 optional_font iFont;
149 color_or_gradient iGlyphColor;
150 color_or_gradient iTextColor;
151 color_or_gradient iPaperColor;
152 bool iSmartUnderline;
153 bool iIgnoreEmoji;
154 optional_text_effect iTextEffect;
155 };
156
157 class paragraph_style
158 {
159 public:
160 paragraph_style();
161 paragraph_style(paragraph_style const& aOther);
162 paragraph_style(optional_alignment const& aAlignment, optional_padding const& aPadding = {}, optional<double> const& aLineSpacing = {});
163 public:
164 optional_alignment const& alignment() const;
165 paragraph_style& set_alignment(optional_alignment const& aALignment = {});
166 optional_padding const& padding() const;
167 paragraph_style& set_padding(optional_padding const& aPadding = {});
168 optional<double> const& line_spacing() const;
169 paragraph_style& set_line_spacing(optional<double> const& aLineSpacing = {});
170 public:
171 paragraph_style& merge(const paragraph_style& aRhs);
172 public:
173 bool operator==(const paragraph_style& aRhs) const;
174 bool operator!=(const paragraph_style& aRhs) const;
175 bool operator<(const paragraph_style& aRhs) const;
176 public:
177 optional_alignment iAlignment;
178 optional_padding iPadding;
179 optional<double> iLineSpacing;
180 };
181
182 class style
183 {
184 public:
185 style();
186 style(character_style const& aCharacter);
187 style(character_style const& aCharacter, paragraph_style const& aParagraph);
188 style(paragraph_style const& aParagraph);
189 style(text_edit& aParent, const style& aOther);
190 public:
191 void add_ref() const;
192 void release() const;
193 public:
194 style& merge(const style& aOverridingStyle);
195 public:
196 bool operator==(const style& aRhs) const;
197 bool operator!=(const style& aRhs) const;
198 bool operator<(const style& aRhs) const;
199 public:
200 character_style const& character() const;
201 character_style& character();
202 paragraph_style const& paragraph() const;
203 paragraph_style& paragraph();
204 private:
205 text_edit* iParent;
206 mutable uint32_t iUseCount;
207 character_style iCharacter;
208 paragraph_style iParagraph;
209 };
210
211 typedef std::set<style> style_list;
212
213 typedef std::function<std::tuple<const style&, std::ptrdiff_t> (std::ptrdiff_t)> style_callback;
214 struct ansi {};
215 typedef std::variant<std::monostate, style, style_callback, ansi> format;
216
217 class column_info
218 {
219 public:
220 column_info();
221
222 public:
223 char32_t delimiter() const;
224 void set_delimiter(char32_t aDelimiter);
225 const optional_dimension& min_width() const;
226 void set_min_width(const optional_dimension& aMinWidth);
227 const optional_dimension& max_width() const;
228 void set_max_width(const optional_dimension& aMaxWidth);
229 const neogfx::padding& padding() const;
230 void set_padding(const neogfx::padding& aPadding);
231 const std::optional<text_edit::style>& style() const;
232 void set_style(const std::optional<text_edit::style>& aStyle);
233
234 public:
235 bool operator==(const column_info& aRhs) const;
236 bool operator!=(const column_info& aRhs) const;
237
238 private:
239 char32_t iDelimiter;
240 optional_dimension iMinWidth;
241 optional_dimension iMaxWidth;
242 neogfx::padding iPadding;
243 std::optional<text_edit::style> iStyle;
244 };
245
246 private:
247 class multiple_text_changes;
248
249 struct unknown_node {};
250
251 template <typename Node = unknown_node>
252 class tag
253 {
254 private:
255 static constexpr std::size_t SMALL_OPTIMIZATION_FONT_COUNT = 4;
256 private:
257 typedef std::variant<std::monostate, style_list::const_iterator, nullptr_t> tag_style;
258 public:
259 struct tag_data
260 {
261 tag_style style;
262 bool operator==(const tag_data& rhs) const
263 {
264 return style == rhs.style;
265 }
266 };
267 public:
268 template <typename Node2>
269 struct rebind { typedef tag<Node2> type; };
270 private:
271 typedef Node node_type;
272 public:
273 tag(const tag_data& aContents) :
274 iNode(nullptr), iContents(aContents)
275 {
276 if (std::holds_alternative<style_list::const_iterator>(style()))
277 static_variant_cast<style_list::const_iterator>(style())->add_ref();
278 }
279 template <typename Node2>
280 tag(node_type& aNode, const tag<Node2>& aTag) :
281 iNode(&aNode), iContents(aTag.iContents)
282 {
283 if (std::holds_alternative<style_list::const_iterator>(style()))
284 static_variant_cast<style_list::const_iterator>(style())->add_ref();
285 }
286 tag(const tag& aOther) :
287 iNode(aOther.iNode), iContents(aOther.iContents)
288 {
289 if (std::holds_alternative<style_list::const_iterator>(style()))
290 static_variant_cast<style_list::const_iterator>(style())->add_ref();
291 }
292 ~tag()
293 {
294 if (std::holds_alternative<style_list::const_iterator>(style()))
295 static_variant_cast<style_list::const_iterator>(style())->release();
296 }
297 public:
298 bool operator==(const tag& aOther) const
299 {
300 return contents() == aOther.contents();
301 }
302 bool operator!=(const tag& aOther) const
303 {
304 return !(*this == aOther);
305 }
306 public:
307 const tag_style& style() const
308 {
309 return contents().style;
310 }
311 private:
312 const tag_data& contents() const
313 {
314 return iContents;
315 }
316 tag_data& contents()
317 {
318 return iContents;
319 }
320 private:
321 node_type* iNode;
322 tag_data iContents;
323 };
324
325 typedef neolib::tag_array<tag<>, char32_t, 16, 256> document_text;
326
327 typedef neolib::segmented_array<glyph_char, 256> glyph_container_type;
328
329 typedef basic_glyph_text_content<glyph_container_type> document_glyphs;
330
331 class glyph_paragraph;
332 class glyph_paragraph_index;
333 typedef neolib::indexitor<
334 glyph_paragraph,
335 glyph_paragraph_index,
336 boost::fast_pool_allocator<std::pair<glyph_paragraph, const glyph_paragraph_index>, boost::default_user_allocator_new_delete, boost::details::pool::null_mutex>> glyph_paragraphs;
337
338 struct glyph_line;
339 typedef std::vector<glyph_line> glyph_lines;
340
341 class glyph_column;
342 typedef std::vector<glyph_column> glyph_columns;
343
344 struct position_info;
345
346 private:
347 class dragger;
348
349 public:
350 typedef document_text::size_type position_type;
351
352 // exceptions
353 public:
354 struct not_implemented : std::logic_error { not_implemented() : std::logic_error("neogfx::text_edit::not_implemented") {} };
355 struct bad_column_index : std::logic_error { bad_column_index() : std::logic_error("neogfx::text_edit::bad_column_index") {} };
356
357 // text_edit
358 public:
359 text_edit(text_edit_caps aType = text_edit_caps::MultiLine, frame_style aFrameStyle = frame_style::SolidFrame);
360 text_edit(i_widget& aParent, text_edit_caps aType = text_edit_caps::MultiLine, frame_style aFrameStyle = frame_style::SolidFrame);
361 text_edit(i_layout& aLayout, text_edit_caps aType = text_edit_caps::MultiLine, frame_style aFrameStyle = frame_style::SolidFrame);
362 ~text_edit();
363 // scrollable_widget
364 public:
365 void moved() override;
366 void resized() override;
367 void layout_items(bool aDefer) override;
368 public:
369 size minimum_size(optional_size const& aAvailableSpace = optional_size{}) const override;
370 size maximum_size(optional_size const& aAvailableSpace = optional_size{}) const override;
371 neogfx::padding padding() const override;
372 public:
373 void paint(i_graphics_context& aGc) const override;
374 public:
375 color palette_color(color_role aColorRole) const override;
376 public:
377 const neogfx::font& font() const override;
378 void set_font(optional_font const& aFont) override;
379 public:
380 void focus_gained(focus_reason aFocusReason) override;
381 void focus_lost(focus_reason aFocusReason) override;
382 public:
383 void mouse_button_pressed(mouse_button aButton, const point& aPosition, key_modifiers_e aKeyModifiers) override;
384 void mouse_button_double_clicked(mouse_button aButton, const point& aPosition, key_modifiers_e aKeyModifiers) override;
385 void mouse_button_released(mouse_button aButton, const point& aPosition) override;
386 void mouse_moved(const point& aPosition, key_modifiers_e aKeyModifiers) override;
387 void mouse_entered(const point& aPosition) override;
388 void mouse_left() override;
389 neogfx::mouse_cursor mouse_cursor() const override;
390 public:
391 bool key_pressed(scan_code_e aScanCode, key_code_e aKeyCode, key_modifiers_e aKeyModifiers) override;
392 bool key_released(scan_code_e aScanCode, key_code_e aKeyCode, key_modifiers_e aKeyModifiers) override;
393 bool text_input(i_string const& aText) override;
394 public:
396 neogfx::scrolling_disposition scrolling_disposition(const i_widget&) const override;
397 public:
398 rect scroll_area() const override;
399 size scroll_page() const override;
400 public:
401 bool use_scrollbar_container_updater() const override;
402 using framed_scrollable_widget::update_scrollbar_visibility;
403 bool update_scrollbar_visibility(usv_stage_e aStage) override;
404 void scroll_page_updated() override;
405 public:
406 color frame_color() const override;
407 // i_clipboard
408 public:
409 bool can_undo() const override;
410 bool can_redo() const override;
411 bool can_cut() const override;
412 bool can_copy() const override;
413 bool can_paste() const override;
414 bool can_delete_selected() const override;
415 bool can_select_all() const override;
416 void undo(i_clipboard& aClipboard) override;
417 void redo(i_clipboard& aClipboard) override;
418 void cut(i_clipboard& aClipboard) override;
419 void copy(i_clipboard& aClipboard) override;
420 void paste(i_clipboard& aClipboard) override;
421 void delete_selected() override;
422 void select_all() override;
423 // i_text_document
424 public:
425 std::size_t document_length() const override;
426 void move_cursor(cursor::move_operation_e aMoveOperation, bool aMoveAnchor = true) override;
427 public:
428 i_string const& plain_text() const override;
429 bool set_plain_text(i_string const& aPlainText) override;
430 i_string const& rich_text(rich_text_format aFormat = rich_text_format::Html) const override;
431 bool set_rich_text(i_string const& aRichText, rich_text_format aFormat = rich_text_format::Html) override;
432 public:
433 void paste_plain_text() override;
434 void paste_rich_text(rich_text_format aFormat = rich_text_format::Html) override;
435 public:
436 void begin_update() override;
437 void end_update() override;
438 // text_edit
439 public:
440 bool read_only() const;
441 void set_read_only(bool aReadOnly = true);
442 bool word_wrap() const;
443 void set_word_wrap(bool aWordWrap = true);
444 uint32_t grow_lines() const;
445 void set_grow_lines(uint32_t aGrowLines = 5u);
446 bool password() const;
447 i_string const& password_mask() const;
448 void set_password(bool aPassword, i_string const& aMask = string{ "\xE2\x97\x8F" });
449 const style& default_style() const;
450 void set_default_style(style const& aDefaultStyle, bool aPersist = false);
451 color default_text_color() const;
453 void set_alignment(neogfx::alignment aAlignment);
454 public:
455 style current_style() const;
456 void apply_style(style const& aStyle);
457 void apply_style(position_type aStart, position_type aEnd, style const& aStyle);
458 style next_style() const;
459 public:
460 void clear();
461 std::size_t paragraph_count() const;
462 void delete_paragraph(std::size_t aParagraphIndex);
463 i_string const& text() const;
464 std::size_t set_text(i_string const& aText);
465 std::size_t set_text(i_string const& aText, format const& aFormat);
466 std::size_t append_text(i_string const& aText, bool aMoveCursor = false);
467 std::size_t append_text(i_string const& aText, format const& aFormat, bool aMoveCursor = false);
468 std::size_t insert_text(i_string const& aText, bool aMoveCursor = false);
469 std::size_t insert_text(i_string const& aText, format const& aFormat, bool aMoveCursor = false);
470 std::size_t insert_text(position_type aPosition, i_string const& aText, bool aMoveCursor = false);
471 std::size_t insert_text(position_type aPosition, i_string const& aText, format const& aFormat, bool aMoveCursor = false);
472 std::size_t set_text(std::string const& aText) { return set_text(string{ aText }); }
473 std::size_t set_text(std::string const& aText, format const& aFormat) { return set_text(string{ aText }, aFormat); }
474 std::size_t append_text(std::string const& aText, bool aMoveCursor = false) { return append_text(string{ aText }, aMoveCursor); }
475 std::size_t append_text(std::string const& aText, format const& aFormat, bool aMoveCursor = false) { return append_text(string{ aText }, aFormat, aMoveCursor); }
476 std::size_t insert_text(std::string const& aText, bool aMoveCursor = false) { return insert_text(string{ aText }, aMoveCursor); }
477 std::size_t insert_text(std::string const& aText, format const& aFormat, bool aMoveCursor = false) { return insert_text(string{ aText }, aFormat, aMoveCursor); }
478 std::size_t insert_text(position_type aPosition, std::string const& aText, bool aMoveCursor = false) { return insert_text(aPosition, string{ aText }, aMoveCursor); }
479 std::size_t insert_text(position_type aPosition, std::string const& aText, format const& aFormat, bool aMoveCursor = false) { return insert_text(aPosition, string{ aText }, aFormat, aMoveCursor); }
480 void delete_text(position_type aStart, position_type aEnd);
481 std::size_t columns() const;
482 void set_columns(std::size_t aColumnCount);
483 void remove_columns();
484 const column_info& column(std::size_t aColumnIndex) const;
485 void set_column(std::size_t aColumnIndex, const column_info& aColumn);
486 const style& column_style(std::size_t aColumnIndex) const;
487 const style& column_style(const column_info& aColumn) const;
488 public:
489 const neogfx::size_hint& size_hint() const;
490 void set_size_hint(const neogfx::size_hint& aSizeHint);
491 void set_tab_stop_hint(i_string const& aTabStopHint = string{ "0000" });
492 neogfx::tab_stops const& tab_stops() const;
493 void set_tab_stops(std::optional<neogfx::tab_stops> const& aTabStops);
494 public:
495 position_type document_hit_test(const point& aPosition, bool aAdjustForScrollPosition = true) const;
496 virtual bool same_word(position_type aTextPositionLeft, position_type aTextPositionRight) const;
497 virtual std::pair<position_type, position_type> word_at(position_type aTextPosition, bool aWordBreakIsWhitespace = false) const;
498 public:
499 neogfx::cursor& cursor() const;
500 void set_cursor_position(const point& aPosition, bool aMoveAnchor = true, bool aEnableDragger = false);
501 protected:
502 std::size_t column_index(const column_info& aColumn) const;
503 rect column_rect(std::size_t aColumnIndex, bool aExtendIntoPadding = false) const;
504 std::size_t column_hit_test(const point& aPosition, bool aAdjustForScrollPosition = true) const;
505 private:
506 std::pair<glyph_columns::const_iterator, glyph_lines::const_iterator> glyph_column_line(position_type aGlyphPosition) const;
507 position_info glyph_position(position_type aGlyphPosition, bool aForCursor = false) const;
508 position_type cursor_glyph_position() const;
509 position_type cursor_glyph_anchor() const;
510 void set_cursor_glyph_position(position_type aGlyphPosition, bool aMoveAnchor = true);
511 private:
512 void init();
513 document_glyphs const& glyphs() const;
514 document_glyphs& glyphs();
515 std::size_t do_insert_text(position_type aPosition, i_string const& aText, format const& aFormat, bool aMoveCursor, bool aClearFirst);
516 void delete_any_selection();
517 void notify_text_changed();
518 std::pair<position_type, position_type> related_glyphs(position_type aGlyphPosition) const;
519 bool same_paragraph(position_type aFirstGlyphPos, position_type aSecondGlyphPos) const;
520 glyph_paragraphs::const_iterator character_to_paragraph(position_type aCharacterPos) const;
521 glyph_paragraphs::const_iterator glyph_to_paragraph(position_type aGlyphPos) const;
522 document_glyphs::const_iterator to_glyph(document_text::const_iterator aWhere) const;
523 std::pair<document_text::size_type, document_text::size_type> from_glyph(document_glyphs::const_iterator aWhere) const;
524 void refresh_paragraph(document_text::const_iterator aWhere, ptrdiff_t aDelta);
525 void refresh_columns();
526 void refresh_lines();
527 void animate();
528 void update_cursor();
529 void make_cursor_visible(bool aForcePreviewScroll = false);
530 void make_visible(position_info const& aGlyphPosition, point const& aPreview = {});
531 style glyph_style(document_glyphs::const_iterator aGlyphChar, const glyph_column& aColumn) const;
532 void draw_glyphs(i_graphics_context const& aGc, const point& aPosition, const glyph_column& aColumn, glyph_lines::const_iterator aLine) const;
533 void draw_cursor(i_graphics_context const& aGc) const;
534 rect cursor_rect() const;
535 double calc_padding_adjust(style const& aStyle) const;
536 double padding_adjust() const;
537 static std::pair<document_glyphs::iterator, document_glyphs::iterator> word_break(document_glyphs::iterator aBegin, document_glyphs::iterator aFrom, document_glyphs::iterator aEnd);
538 static std::pair<document_glyphs::reverse_iterator, document_glyphs::reverse_iterator> word_break(document_glyphs::reverse_iterator aBegin, document_glyphs::reverse_iterator aFrom, document_glyphs::reverse_iterator aEnd);
539 private:
540 sink iSink;
541 text_edit_caps iCaps;
542 style iDefaultStyle;
543 mutable std::optional<style> iNextStyle;
544 bool iPersistDefaultStyle;
545 font_info iDefaultFont;
546 mutable neogfx::cursor iCursor;
547 style_list iStyles;
548 bool iUpdatingDocument;
549 document_text iPreviousText;
550 document_text iText;
551 mutable std::optional<string> iUtf8TextCache;
552 mutable std::optional<document_glyphs> iGlyphs;
553 glyph_paragraphs iGlyphParagraphs;
554 glyph_columns iGlyphColumns;
555 optional_size iTextExtents;
556 uint64_t iCursorAnimationStartTime;
557 typedef std::pair<position_type, position_type> find_span;
558 typedef std::map<
559 find_span,
560 glyph_paragraphs::const_iterator,
561 std::less<find_span>,
562 boost::fast_pool_allocator<std::pair<const find_span, glyph_paragraphs::const_iterator>, boost::default_user_allocator_new_delete, boost::details::pool::null_mutex>> find_in_paragraph_cache;
563 mutable find_in_paragraph_cache iCharacterToParagraphCache;
564 mutable std::optional<find_in_paragraph_cache::iterator> iCharacterToParagraphCacheLastAccess;
565 mutable find_in_paragraph_cache iGlyphToParagraphCache;
566 mutable std::optional<find_in_paragraph_cache::iterator> iGlyphToParagraphCacheLastAccess;
567 neogfx::size_hint iSizeHint;
568 mutable std::optional<std::pair<neogfx::font, size>> iHintedSize;
569 std::optional<neogfx::tab_stops> iTabStops;
570 string iTabStopHint;
571 mutable std::optional<std::pair<neogfx::font, neogfx::tab_stops>> iCalculatedTabStops;
572 basic_point<std::optional<dimension>> iCursorHint;
573 widget_timer iAnimator;
574 std::unique_ptr<dragger> iDragger;
575 std::unique_ptr<neogfx::context_menu> iMenu;
576 uint32_t iSuppressTextChangedNotification;
577 uint32_t iWantedToNotfiyTextChanged;
578 std::optional<std::pair<text_edit::position_type, text_edit::position_type>> iSelectedUri;
579 std::optional<password_bits> iPasswordBits;
580 bool iOutOfMemory;
581 public:
582 define_property(property_category::other, bool, ReadOnly, read_only, false)
583 define_property(property_category::other, bool, WordWrap, word_wrap, (iCaps & text_edit_caps::MultiLine) == text_edit_caps::MultiLine)
584 define_property(property_category::other, uint32_t, GrowLines, grow_lines, 5u)
585 define_property(property_category::other, bool, Password, password, false)
586 define_property(property_category::other, string, PasswordMask, password_mask)
587 };
588
589 extern template class basic_glyph_text_content<text_edit::glyph_container_type>;
590}
#define end_declare_enum(enumName)
Definition i_enum.hpp:62
#define declare_enum_string(enumName, enumEnumerator)
Definition i_enum.hpp:59
#define begin_declare_enum(enumName)
Definition i_enum.hpp:52
constexpr style_aspect operator&(style_aspect aLhs, style_aspect aRhs)
Definition i_style.hpp:60
bool operator!=(color_or_gradient const &lhs, color const &rhs) noexcept
audio_channel operator~(audio_channel lhs)
optional< padding > optional_padding
basic_padding< dimension > padding
bool operator<(const basic_rect< CoordinateType, CoordinateSystem > &left, const basic_rect< CoordinateType, CoordinateSystem > &right)
neolib::variant< color, gradient > color_or_gradient
Definition gradient.hpp:149
gui_rect rect
bool operator==(const basic_rect< CoordinateType, CoordinateSystem > &left, const basic_rect< CoordinateType, CoordinateSystem > &right)
optional< dimension > optional_dimension
constexpr style_aspect operator|(style_aspect aLhs, style_aspect aRhs)
Definition i_style.hpp:55
sRGB_color color
Definition color.hpp:1067
optional< size > optional_size
optional< alignment > optional_alignment
Definition alignment.hpp:43
scrollable_widget< framed_widget< widget<> > > framed_scrollable_widget
basic_size< coordinate > size
format_result format(std::string_view const &aFormat, Args &&... aArgs)
Definition plf_hive.h:79
#define meta_object(...)
Definition i_object.hpp:28
#define define_event(name, declName,...)
Definition event.hpp:200
#define define_property(category, type, name, calculator,...)
Definition property.hpp:536