KTech 1.1.0
C++ 2D terminal game engine library
Loading...
Searching...
No Matches
stringfield.hpp
1/*
2 KTech, Kaup's C++ 2D terminal game engine library.
3 Copyright (C) 2023-2025 Ethan Kaufman (AKA Kaup)
4
5 This file is part of KTech.
6
7 KTech is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 any later version.
11
12 KTech is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with KTech. If not, see <https://www.gnu.org/licenses/>.
19*/
20
21#pragma once
22
23#include "../ktech.hpp"
24
29{
30public:
31 static constexpr std::pair<char, char> charRange_lower{'a', 'z'};
32 static constexpr std::pair<char, char> charRange_upper{'A', 'Z'};
33 static constexpr std::pair<char, char> charRange_numbers{'0', '9'};
34 static constexpr std::pair<char, char> charRange_all{' ', '~'};
35
36 std::string m_string;
37
38 std::function<void()> m_OnInsert;
39
57 std::function<void()> OnInsert = nullptr,
58 const std::vector<std::pair<char, char>>& allowedCharacters = {charRange_all},
59 KTech::Point position = { 0, 0 },
60 const std::string& text = "Value = ",
61 unsigned int maxChars = 8,
62 const std::string& defaultString = "String",
63 bool withFrame = false,
64 KTech::RGBA unselected = KTech::RGBAColors::gray,
65 KTech::RGBA selected = KTech::RGBAColors::white)
66 : Widget(engine, ui, position), m_OnInsert(std::move(OnInsert)), m_maxChars(maxChars), m_unselectedRGBA(unselected), m_selectedRGBA(selected), m_string(defaultString)
67 {
68 // Textures
69 SetText(text, withFrame);
70 SetValue(defaultString);
71 // Input handlers
72 for (const std::pair<char, char>& charRange : allowedCharacters)
73 {
74 m_callbackGroup.RegisterRangedCallback(charRange.first, charRange.second, [this]() -> bool { return this->Insert(); });
75 }
76 m_callbackGroup.RegisterCallback(KTech::Keys::delete_, [this]() -> bool { return this->Insert(); });
77 m_callbackGroup.RegisterCallback(KTech::Keys::backspace, [this]() -> bool { return this->Insert(); });
78 }
79
86 void SetText(const std::string& text, bool withFrame)
87 {
88 KTech::RGBA tempRGBA = (m_selected ? m_selectedRGBA : m_unselectedRGBA);
89 if (withFrame)
90 {
91 m_textures.resize(TEXTURES_SIZE_FRAMED);
92 m_textures[ti_topLeftCorner].Simple(KTech::UPoint(1, 1), KTech::CellA('#', tempRGBA), KTech::Point(0, 0));
93 m_textures[ti_topRightCorner].Simple(KTech::UPoint(1, 1), KTech::CellA('#', tempRGBA), KTech::Point(1 + text.length() + m_maxChars, 0));
94 m_textures[ti_bottomLeftCorner].Simple(KTech::UPoint(1, 1), KTech::CellA('#', tempRGBA), KTech::Point(0, 2));
95 m_textures[ti_bottomRightCorner].Simple(KTech::UPoint(1, 1), KTech::CellA('#', tempRGBA), KTech::Point(1 + text.length() + m_maxChars, 2));
96 m_textures[ti_topFrame].Simple(KTech::UPoint(text.length() + m_maxChars, 1), KTech::CellA('-', tempRGBA), KTech::Point(1, 0));
97 m_textures[ti_leftFrame].Simple(KTech::UPoint(1, 1), KTech::CellA('|', tempRGBA), KTech::Point(0, 1));
98 m_textures[ti_bottomFrame].Simple(KTech::UPoint(text.length() + m_maxChars, 1), KTech::CellA('-', tempRGBA), KTech::Point(1, 2));
99 m_textures[ti_rightFrame].Simple(KTech::UPoint(1, 1), KTech::CellA('|', tempRGBA), KTech::Point(1 + text.length() + m_maxChars, 1));
100 }
101 else
102 {
103 m_textures.resize(TEXTURES_SIZE_FRAMELESS);
104 }
105 // input position
106 m_textures[ti_input].m_rPos = KTech::Point(1 + text.length(), 1);
107 // text
108 m_textures[ti_text].Write({text}, tempRGBA, KTech::RGBA(0, 0, 0, 0), KTech::Point(1, 1));
109 }
110
115 void SetValue(const std::string& value)
116 {
117 m_string = value.substr(0, (m_string.size() > m_maxChars ? m_maxChars : m_string.size()));
118 m_textures[ti_input].Write({m_string}, (m_selected ? m_selectedRGBA : m_unselectedRGBA), KTech::RGBAColors::transparent);
119 m_currentChar = m_string.length();
120 }
121
122private:
123 enum TextureIndex : size_t
124 {
125 ti_input,
126 ti_text,
127 TEXTURES_SIZE_FRAMELESS,
128 ti_topLeftCorner = TEXTURES_SIZE_FRAMELESS,
129 ti_topRightCorner,
130 ti_bottomLeftCorner,
131 ti_bottomRightCorner,
132 ti_topFrame,
133 ti_leftFrame,
134 ti_bottomFrame,
135 ti_rightFrame,
136 TEXTURES_SIZE_FRAMED
137 };
138
139 KTech::RGBA m_unselectedRGBA, m_selectedRGBA;
140 uint16_t m_currentChar = 0;
141 uint16_t m_maxChars;
142
143 void OnSelect() override
144 {
145 RenderSelected();
146 }
147
148 void OnDeselect() override
149 {
150 RenderUnselected();
151 }
152
153 auto Insert() -> bool
154 {
155 if (engine.input.Is(KTech::Keys::backspace) || engine.input.Is(KTech::Keys::delete_))
156 {
157 if (m_currentChar == 0)
158 {
159 return false;
160 }
161
162 m_currentChar--;
163 m_string.pop_back();
164
165 m_textures[ti_input](m_currentChar, 0).c = ' ';
166 }
167 else if (m_currentChar == m_maxChars)
168 {
169 return false;
170 }
171 else
172 {
173 m_textures[ti_input](m_currentChar, 0).c = engine.input.input.at(0);
174 m_string.push_back(engine.input.input.at(0));
175 m_currentChar++;
176 }
177 if (m_OnInsert)
178 {
179 m_OnInsert();
180 }
181 return true;
182 }
183
184 void RenderSelected()
185 {
186 for (KTech::Texture& texture : m_textures)
187 {
188 texture.Transform([&](KTech::CellA& cell){ cell.f = m_selectedRGBA; });
189 }
190 }
191
192 void RenderUnselected()
193 {
194 for (KTech::Texture& texture : m_textures)
195 {
196 texture.Transform([&](KTech::CellA& cell){ cell.f = m_unselectedRGBA; });
197 }
198 }
199};
Complete engine containing all engine components.
Definition engine.hpp:41
Input input
Input engine component.
Definition engine.hpp:47
void RegisterCallback(const std::string &stringKey, const std::function< bool()> &callback)
Register a function to be called back when an input is received.
Definition callbackgroup.cpp:70
void RegisterRangedCallback(char start, char end, const std::function< bool()> &callback)
Register a function to be called back when an input within a characters range is received.
Definition callbackgroup.cpp:106
auto Is(const std::string &stringKey) const -> bool
Checks if input equals given string.
Definition input.cpp:54
std::string input
Input for the last-called callback function.
Definition input.hpp:48
World structure that comprises Textures, behaves as a user interface element, and exists within UI.
Definition widget.hpp:45
Engine & engine
Parent Engine.
Definition widget.hpp:57
std::vector< Texture > m_textures
Comprising Textures.
Definition widget.hpp:67
Input::CallbackGroup m_callbackGroup
Group of all input callbacks, which are enabled and disabled in correspondence to Widget::m_selected.
Definition widget.hpp:68
Widget(Engine &engine, Point position=Point(0, 0), std::string name="")
Construct a Widget.
Definition widget.cpp:34
bool m_selected
true: player input reaches the Widget. false: player input doesn't.
Definition widget.hpp:63
Widget for entering a string.
Definition stringfield.hpp:29
void SetText(const std::string &text, bool withFrame)
Change the displayed text.
Definition stringfield.hpp:86
static constexpr std::pair< char, char > charRange_lower
Range of all lower case letters.
Definition stringfield.hpp:31
static constexpr std::pair< char, char > charRange_numbers
Range of all digits.
Definition stringfield.hpp:33
StringField(KTech::Engine &engine, KTech::ID< KTech::UI > ui, std::function< void()> OnInsert=nullptr, const std::vector< std::pair< char, char > > &allowedCharacters={charRange_all}, KTech::Point position={ 0, 0 }, const std::string &text="Value = ", unsigned int maxChars=8, const std::string &defaultString="String", bool withFrame=false, KTech::RGBA unselected=KTech::RGBAColors::gray, KTech::RGBA selected=KTech::RGBAColors::white)
Construct a StringField.
Definition stringfield.hpp:55
static constexpr std::pair< char, char > charRange_upper
Range of all upper case letters.
Definition stringfield.hpp:32
std::function< void()> m_OnInsert
Function to call when the user inserts or removes a character.
Definition stringfield.hpp:38
std::string m_string
The entered string.
Definition stringfield.hpp:36
void SetValue(const std::string &value)
Change the entered string.
Definition stringfield.hpp:115
static constexpr std::pair< char, char > charRange_all
Range ofa all ASCII characters.
Definition stringfield.hpp:34
Like Cell, but with RGBA foreground and background colors, instead of RGB.
Definition cella.hpp:32
RGBA f
Foreground (character) color.
Definition cella.hpp:33
Serializable world structure identifier.
Definition id.hpp:38
2D vector, mostly used to store positions and directions.
Definition point.hpp:30
Like RGB, but also has an alpha channel representing transparency.
Definition rgba.hpp:30
A CellA-based sprite.
Definition texture.hpp:48
Unsigned 2D vector, mostly used to store sizes and 2D indexes.
Definition upoint.hpp:29