ASW Lib
A.D.S. Games SDL Wrapper Library. A library targeted at Allegro4 users who want to switch to SDL3 and use modern c++.
Loading...
Searching...
No Matches
input_box.cpp
Go to the documentation of this file.
2
3#include <SDL3/SDL.h>
4#include <algorithm>
5
9
11{
12 focused_ = focused;
13 (void)ctx;
14
15 if (focused) {
16 SDL_StartTextInput(asw::display::window);
17 cursor_pos_ = value.size();
18 } else {
19 SDL_StopTextInput(asw::display::window);
20 }
21}
22
24{
25 if (!enabled) {
26 return false;
27 }
28
29 switch (e.type) {
31 hovered_ = true;
32 return false;
33 }
35 hovered_ = false;
36 return false;
37 }
39 if (transform.contains(e.pointer_pos)) {
40 ctx.pointer_capture = this;
41 ctx.focus.set_focus(ctx, this);
42 cursor_pos_ = value.size();
43 return true;
44 }
45 return false;
46 }
48 if (ctx.pointer_capture == this) {
49 ctx.pointer_capture = nullptr;
50 }
51 return false;
52 }
54 value.insert(cursor_pos_, e.text);
55 cursor_pos_ += e.text.size();
56 if (on_change) {
57 on_change(value);
58 }
59 return true;
60 }
63 if (cursor_pos_ > 0) {
64 value.erase(cursor_pos_ - 1, 1);
65 cursor_pos_--;
66 if (on_change) {
67 on_change(value);
68 }
69 }
70 return true;
71 }
73 if (cursor_pos_ < value.size()) {
74 value.erase(cursor_pos_, 1);
75 if (on_change) {
76 on_change(value);
77 }
78 }
79 return true;
80 }
81 if (e.key == asw::input::Key::Left) {
82 if (cursor_pos_ > 0) {
83 cursor_pos_--;
84 }
85 return true;
86 }
87 if (e.key == asw::input::Key::Right) {
88 if (cursor_pos_ < value.size()) {
89 cursor_pos_++;
90 }
91 return true;
92 }
93 if (e.key == asw::input::Key::Home) {
94 cursor_pos_ = 0;
95 return true;
96 }
97 if (e.key == asw::input::Key::End) {
98 cursor_pos_ = value.size();
99 return true;
100 }
101 return false;
102 }
104 // Consume activate to prevent Space from triggering other actions
105 return true;
106 }
107 default:
108 break;
109 }
110 return false;
111}
112
114{
115 constexpr float text_padding = 4.0F;
116
117 // Background
118 asw::Color bg = ctx.theme.input_bg;
119 if (!enabled) {
120 bg = ctx.theme.panel_bg;
121 }
122 asw::draw::rect_fill(transform, bg);
123
124 // Border
125 asw::Color border = ctx.theme.btn_bg;
126 if (hovered_ && enabled) {
127 border = ctx.theme.btn_hover;
128 }
129 asw::draw::rect(transform, border);
130
131 // Clip text to input bounds
132 const SDL_Rect clip {
133 static_cast<int>(transform.position.x + text_padding),
134 static_cast<int>(transform.position.y),
135 static_cast<int>(transform.size.x - (text_padding * 2)),
136 static_cast<int>(transform.size.y),
137 };
138 SDL_SetRenderClipRect(asw::display::renderer, &clip);
139
140 // Text position (vertically centered)
141 const auto display_text = value.empty() ? placeholder : value;
142 const auto display_color = value.empty() ? ctx.theme.text_dim : ctx.theme.text;
143
144 if (!display_text.empty() && font != nullptr) {
145 const auto text_size = asw::util::get_text_size(font, display_text);
146 const float text_y = transform.position.y + ((transform.size.y - text_size.y) / 2.0F);
147 const asw::Vec2 text_pos { transform.position.x + text_padding, text_y };
148
149 asw::draw::text(font, display_text, text_pos, display_color);
150 }
151
152 // Cursor
153 if (focused_ && font != nullptr) {
154 const auto before_cursor = value.substr(0, cursor_pos_);
155 float cursor_x = transform.position.x + text_padding;
156
157 if (!before_cursor.empty()) {
158 const auto size = asw::util::get_text_size(font, before_cursor);
159 cursor_x += static_cast<float>(size.x);
160 }
161
162 const auto text_height = asw::util::get_text_size(font, "|");
163 const float cursor_y = transform.position.y
164 + ((transform.size.y - static_cast<float>(text_height.y)) / 2.0F);
165
166 asw::draw::line({ cursor_x, cursor_y },
167 { cursor_x, cursor_y + static_cast<float>(text_height.y) }, ctx.theme.text);
168 }
169
170 // Reset clip
171 SDL_SetRenderClipRect(asw::display::renderer, nullptr);
172
173 // Focus ring
174 if (focused_ && ctx.theme.show_focus) {
175 auto ring = asw::Quad<float>(transform);
176 ring.position.x -= 2;
177 ring.position.y -= 2;
178 ring.size.x += 4;
179 ring.size.y += 4;
181 }
182
183 Widget::draw(ctx);
184}
A 2D rectangle in space.
Definition geometry.h:388
A 2D vector in space.
Definition geometry.h:21
Shared state for the UI system.
Definition context.h:75
Widget * pointer_capture
The widget that has captured pointer input.
Definition context.h:88
FocusManager focus
The focus manager.
Definition context.h:85
Theme theme
The current UI theme.
Definition context.h:82
void set_focus(Context &ctx, Widget *w)
Set focus to a specific widget.
Definition context.cpp:22
void draw(Context &ctx) override
Draw the input box.
void on_focus_changed(Context &ctx, bool focused) override
Called when focus state changes.
Definition input_box.cpp:10
std::size_t cursor_pos_
Definition input_box.h:68
bool on_event(Context &ctx, const UIEvent &e) override
Handle a UI event.
Definition input_box.cpp:23
std::string value
The current text value.
Definition input_box.h:60
virtual void draw(Context &ctx)
Draw this widget and its children.
Definition widget.cpp:26
Display and window routines for the ASW library.
Routines for drawing sprites and primitives to the screen.
Input box widget for the ASW UI module.
asw::Renderer * renderer
The renderer for the display module.
Definition display.cpp:9
asw::Window * window
The window for the display module.
Definition display.cpp:10
void line(const asw::Vec2< float > &position1, const asw::Vec2< float > &position2, asw::Color color)
Draw a line.
Definition draw.cpp:193
void text(const asw::Font &font, const std::string &text, const asw::Vec2< float > &position, asw::Color color, asw::TextJustify justify=asw::TextJustify::Left)
Draw text.
Definition draw.cpp:151
void rect(const asw::Quad< float > &position, asw::Color color)
Draw a rectangle.
Definition draw.cpp:204
void rect_fill(const asw::Quad< float > &position, asw::Color color)
Draw a filled rectangle.
Definition draw.cpp:220
asw::Vec2< int > get_text_size(const asw::Font &font, const std::string &text)
Get text size.
Definition util.cpp:22
RGBA color struct with 8-bit channels.
Definition color.h:11
asw::Color text
Default text color.
Definition theme.h:20
bool show_focus
Show focus rings around focused widgets. Enabled by default when using keyboard navigation.
Definition theme.h:51
asw::Color panel_bg
Panel background color.
Definition theme.h:26
asw::Color input_bg
Input box background color.
Definition theme.h:41
asw::Color text_dim
Dimmed text color.
Definition theme.h:23
asw::Color btn_focus_ring
Button focus ring color.
Definition theme.h:38
asw::Color btn_hover
Button hover color.
Definition theme.h:32
asw::Color btn_bg
Button background color.
Definition theme.h:29
Event structure for UI interactions.
Definition event.h:21
asw::Vec2< float > pointer_pos
The pointer position.
Definition event.h:49
std::string text
The text associated with a TextInput event.
Definition event.h:55
asw::input::Key key
The key associated with the event.
Definition event.h:40
Type type
The type of the event.
Definition event.h:37
General utility functions.