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