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.hpp"
9#include "../assert.hpp"
10#include "../math.hpp"
11#include <tuple>
12#include <cstdlib>
13#include <algorithm>
14
15namespace hi::inline v1 {
16
18public:
19 constexpr text_selection() noexcept = default;
20 constexpr text_selection(text_selection const&) noexcept = default;
21 constexpr text_selection(text_selection&&) noexcept = default;
22 constexpr text_selection& operator=(text_selection const&) noexcept = default;
23 constexpr text_selection& operator=(text_selection&&) noexcept = default;
24
25 constexpr text_selection& resize(size_t size) noexcept
26 {
27 _cursor.resize(size);
28 _start_first.resize(size);
29 _start_last.resize(size);
30 _finish_first.resize(size);
31 _finish_last.resize(size);
32 return *this;
33 }
34
35 constexpr text_cursor cursor() const noexcept
36 {
37 return _cursor;
38 }
39
45 constexpr std::pair<text_cursor, text_cursor> selection(size_t size) const noexcept
46 {
47 auto first = std::min(_start_first, _finish_first);
48 auto last = std::max(_start_last, _finish_last);
49
50 first = first.before_neighbor(size);
51 last = last.after_neighbor(size);
52 return {first, last};
53 }
54
59 {
60 auto first = std::min(_start_first, _finish_first);
61 auto last = std::max(_start_last, _finish_last);
62
63 auto first_index = first.after() ? first.index() + 1 : first.index();
64 auto last_index = last.after() ? last.index() + 1 : last.index();
65 return {first_index, last_index};
66 }
67
68 [[nodiscard]] constexpr bool empty() const noexcept
69 {
70 hilet[first_index, last_index] = selection_indices();
71 return first_index >= last_index;
72 }
73
74 constexpr explicit operator bool() const noexcept
75 {
76 return not empty();
77 }
78
79 constexpr text_selection& clear_selection(size_t size) noexcept
80 {
81 return set_cursor(_cursor.resize(size));
82 }
83
84 constexpr text_selection& set_cursor(text_cursor new_cursor) noexcept
85 {
86 _cursor = _start_first = _start_last = _finish_first = _finish_last = new_cursor;
87 hi_axiom(holds_invariant());
88 return *this;
89 }
90
91 constexpr text_selection& operator=(text_cursor const& rhs) noexcept
92 {
93 return set_cursor(rhs);
94 }
95
96 constexpr void start_selection(text_cursor new_cursor, text_cursor first, text_cursor last) noexcept
97 {
98 _start_first = _finish_first = first;
99 _start_last = _finish_last = last;
100 _cursor = new_cursor == first ? first : last;
101 hi_axiom(holds_invariant());
102 }
103
104 constexpr void start_selection(text_cursor new_cursor, std::pair<text_cursor, text_cursor> selection) noexcept
105 {
106 return start_selection(new_cursor, selection.first, selection.second);
107 }
108
109 constexpr void drag_selection(text_cursor drag_cursor) noexcept
110 {
111 _finish_first = _finish_last = drag_cursor;
112 _cursor = drag_cursor;
113 }
114
115 constexpr void drag_selection(text_cursor drag_cursor, text_cursor first, text_cursor last) noexcept
116 {
117 _finish_first = first;
118 _finish_last = last;
119 _cursor = first < _start_first ? first : last > _start_last ? last : drag_cursor == first ? first : last;
120 hi_axiom(holds_invariant());
121 }
122
123 constexpr void drag_selection(text_cursor drag_cursor, std::pair<text_cursor, text_cursor> selection) noexcept
124 {
125 return drag_selection(drag_cursor, selection.first, selection.second);
126 }
127
128 [[nodiscard]] constexpr friend bool operator==(text_selection const&, text_selection const&) noexcept = default;
129
130private:
131 [[nodiscard]] constexpr bool holds_invariant() const noexcept
132 {
133 return _start_first <= _start_last and _finish_first <= _finish_last and
134 (_cursor == _start_first or _cursor == _start_last or _cursor == _finish_first or _cursor == _finish_last);
135 }
136
142 text_cursor _cursor;
143
146 text_cursor _start_first;
147
150 text_cursor _start_last;
151
154 text_cursor _finish_first;
155
158 text_cursor _finish_last;
159};
160
161} // namespace hi::inline v1
Utilities to assert and bound check.
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:133
Miscellaneous math functions.
Utilities used by the HikoGUI library itself.
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:15
A cursor-position in text.
Definition text_cursor.hpp:25
Definition text_selection.hpp:17
constexpr std::pair< size_t, size_t > selection_indices() const noexcept
Get the text indices for the selection.
Definition text_selection.hpp:58
constexpr std::pair< text_cursor, text_cursor > selection(size_t size) const noexcept
Return the selection of characters.
Definition text_selection.hpp:45
T max(T... args)
T min(T... args)