HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
text_selection.hpp
1// Copyright Take Vos 2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "text_cursor.hpp"
8#include "../utility/module.hpp"
9#include <tuple>
10#include <cstdlib>
11#include <algorithm>
12
13namespace hi::inline v1 {
14
16public:
17 constexpr text_selection() noexcept = default;
18 constexpr text_selection(text_selection const&) noexcept = default;
19 constexpr text_selection(text_selection&&) noexcept = default;
20 constexpr text_selection& operator=(text_selection const&) noexcept = default;
21 constexpr text_selection& operator=(text_selection&&) noexcept = default;
22
23 constexpr text_selection& resize(size_t size) noexcept
24 {
25 _cursor.resize(size);
26 _start_first.resize(size);
27 _start_last.resize(size);
28 _finish_first.resize(size);
29 _finish_last.resize(size);
30 return *this;
31 }
32
33 constexpr text_cursor cursor() const noexcept
34 {
35 return _cursor;
36 }
37
43 constexpr std::pair<text_cursor, text_cursor> selection(size_t size) const noexcept
44 {
45 auto first = std::min(_start_first, _finish_first);
46 auto last = std::max(_start_last, _finish_last);
47
48 first = first.before_neighbor(size);
49 last = last.after_neighbor(size);
50 return {first, last};
51 }
52
57 {
58 auto first = std::min(_start_first, _finish_first);
59 auto last = std::max(_start_last, _finish_last);
60
61 auto first_index = first.after() ? first.index() + 1 : first.index();
62 auto last_index = last.after() ? last.index() + 1 : last.index();
63 return {first_index, last_index};
64 }
65
66 [[nodiscard]] constexpr bool empty() const noexcept
67 {
68 hilet[first_index, last_index] = selection_indices();
69 return first_index >= last_index;
70 }
71
72 constexpr explicit operator bool() const noexcept
73 {
74 return not empty();
75 }
76
77 constexpr text_selection& clear_selection(size_t size) noexcept
78 {
79 return set_cursor(_cursor.resize(size));
80 }
81
82 constexpr text_selection& set_cursor(text_cursor new_cursor) noexcept
83 {
84 _cursor = _start_first = _start_last = _finish_first = _finish_last = new_cursor;
85 hi_axiom(holds_invariant());
86 return *this;
87 }
88
89 constexpr text_selection& operator=(text_cursor const& rhs) noexcept
90 {
91 return set_cursor(rhs);
92 }
93
94 constexpr void start_selection(text_cursor new_cursor, text_cursor first, text_cursor last) noexcept
95 {
96 _start_first = _finish_first = first;
97 _start_last = _finish_last = last;
98 _cursor = new_cursor == first ? first : last;
99 hi_axiom(holds_invariant());
100 }
101
102 constexpr void start_selection(text_cursor new_cursor, std::pair<text_cursor, text_cursor> selection) noexcept
103 {
104 return start_selection(new_cursor, selection.first, selection.second);
105 }
106
107 constexpr void drag_selection(text_cursor drag_cursor) noexcept
108 {
109 _finish_first = _finish_last = drag_cursor;
110 _cursor = drag_cursor;
111 }
112
113 constexpr void drag_selection(text_cursor drag_cursor, text_cursor first, text_cursor last) noexcept
114 {
115 _finish_first = first;
116 _finish_last = last;
117 _cursor = first < _start_first ? first : last > _start_last ? last : drag_cursor == first ? first : last;
118 hi_axiom(holds_invariant());
119 }
120
121 constexpr void drag_selection(text_cursor drag_cursor, std::pair<text_cursor, text_cursor> selection) noexcept
122 {
123 return drag_selection(drag_cursor, selection.first, selection.second);
124 }
125
126 [[nodiscard]] constexpr friend bool operator==(text_selection const&, text_selection const&) noexcept = default;
127
128private:
129 [[nodiscard]] constexpr bool holds_invariant() const noexcept
130 {
131 return _start_first <= _start_last and _finish_first <= _finish_last and
132 (_cursor == _start_first or _cursor == _start_last or _cursor == _finish_first or _cursor == _finish_last);
133 }
134
140 text_cursor _cursor;
141
144 text_cursor _start_first;
145
148 text_cursor _start_last;
149
152 text_cursor _finish_first;
153
156 text_cursor _finish_last;
157};
158
159} // namespace hi::inline v1
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:238
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
A cursor-position in text.
Definition text_cursor.hpp:22
Definition text_selection.hpp:15
constexpr std::pair< size_t, size_t > selection_indices() const noexcept
Get the text indices for the selection.
Definition text_selection.hpp:56
constexpr std::pair< text_cursor, text_cursor > selection(size_t size) const noexcept
Return the selection of characters.
Definition text_selection.hpp:43
T max(T... args)
T min(T... args)