Rewrote how input text box focus is decided
This commit is contained in:
parent
1585e0aa67
commit
8b3e321ab5
41 changed files with 317 additions and 490 deletions
|
|
@ -21,6 +21,7 @@ namespace GUIStuff {
|
|||
input_mouse_motion_callback(InputManager::convert_finger_motion_to_mouse_motion(motion));
|
||||
}
|
||||
void Element::input_key_callback(const InputManager::KeyCallbackArgs& key) {}
|
||||
std::optional<InputManager::TextBoxStartInfo> Element::get_text_box_start_info() { return std::nullopt; }
|
||||
|
||||
void Element::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ namespace GUIStuff {
|
|||
virtual void input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch);
|
||||
virtual void input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion);
|
||||
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
virtual std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info();
|
||||
protected:
|
||||
static SCollision::AABB<float> get_bb_from_command(Clay_RenderCommand* command);
|
||||
std::optional<SCollision::AABB<float>> boundingBox;
|
||||
|
|
|
|||
|
|
@ -23,16 +23,6 @@ template <typename T> struct TextBoxData {
|
|||
std::function<void()> onDeselect;
|
||||
};
|
||||
|
||||
|
||||
struct TextEditData {
|
||||
TextEditData(unsigned initTextboxInputID, const std::shared_ptr<RichText::TextBox>& initTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& initCursor):
|
||||
textboxInputID(initTextboxInputID),
|
||||
userInput(initTextBox, initCursor, nullptr)
|
||||
{}
|
||||
unsigned textboxInputID;
|
||||
RichTextUserInput userInput;
|
||||
};
|
||||
|
||||
template <typename T> class TextBox : public Element {
|
||||
public:
|
||||
TextBox(GUIManager& gui);
|
||||
|
|
@ -47,6 +37,7 @@ template <typename T> class TextBox : public Element {
|
|||
virtual void input_text_callback(const InputManager::TextCallbackArgs& text) override;
|
||||
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
|
||||
virtual std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info() override;
|
||||
~TextBox();
|
||||
private:
|
||||
void populate_empty_textbox();
|
||||
|
|
@ -64,7 +55,8 @@ template <typename T> class TextBox : public Element {
|
|||
|
||||
bool isEmptyText = false;
|
||||
bool isHeld = false;
|
||||
std::optional<TextEditData> edit;
|
||||
|
||||
std::unique_ptr<RichTextUserInput> edit;
|
||||
|
||||
std::optional<T> oldData;
|
||||
std::string oldEmptyText;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "TextBox.decl.hpp"
|
||||
#include "../GUIManager.hpp"
|
||||
#include <SDL3/SDL_keyboard.h>
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
|
|
@ -15,6 +16,11 @@ template <typename T> void TextBox<T>::layout(const Clay_ElementId& id, const Te
|
|||
gui.invalidate_draw_element(this);
|
||||
}
|
||||
|
||||
if(edit) {
|
||||
SCollision::AABB<float> rect = {boundingBox.value().min * gui.io.guiScaleMultiplier, boundingBox.value().max * gui.io.guiScaleMultiplier};
|
||||
gui.io.input->update_textbox_rectangle(edit->id, rect);
|
||||
}
|
||||
|
||||
CLAY(id, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(static_cast<float>(io.fontSize * 2)), .height = CLAY_SIZING_FIXED(static_cast<float>(io.fontSize * 1.25f))}
|
||||
|
|
@ -32,10 +38,6 @@ template <typename T> void TextBox<T>::update() {
|
|||
oldDD.cur = *cur;
|
||||
gui.invalidate_draw_element(this);
|
||||
}
|
||||
if(edit.has_value()) {
|
||||
SCollision::AABB<float> rect = {boundingBox.value().min * gui.io.guiScaleMultiplier, boundingBox.value().max * gui.io.guiScaleMultiplier};
|
||||
gui.io.input->update_textbox_rectangle(edit.value().textboxInputID, rect);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void TextBox<T>::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) {
|
||||
|
|
@ -80,30 +82,29 @@ template <typename T> void TextBox<T>::clay_draw(SkCanvas* canvas, UpdateInputDa
|
|||
|
||||
template <typename T> void TextBox<T>::select() {
|
||||
if(!is_selected()) {
|
||||
SCollision::AABB<float> rect = {boundingBox.value().min * gui.io.guiScaleMultiplier, boundingBox.value().max * gui.io.guiScaleMultiplier};
|
||||
unsigned id = gui.io.input->set_text_box_front(rect, userInfo.textInputProps);
|
||||
if(isEmptyText)
|
||||
textbox->clear_text();
|
||||
edit = TextEditData(id, textbox, cur);
|
||||
edit = std::make_unique<RichTextUserInput>(gui.io.input->text_box_get_new_id(), textbox, cur, nullptr);
|
||||
CustomEvents::emit_event(CustomEvents::RefreshTextBoxInputEvent{});
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void TextBox<T>::deselect() {
|
||||
if(is_selected()) {
|
||||
gui.io.input->remove_text_box(edit.value().textboxInputID);
|
||||
edit = nullptr;
|
||||
if(userInfo.onDeselect) userInfo.onDeselect();
|
||||
CustomEvents::emit_event(CustomEvents::RefreshTextBoxInputEvent{});
|
||||
reset_textbox_text();
|
||||
edit = std::nullopt;
|
||||
populate_empty_textbox();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> bool TextBox<T>::is_selected() const {
|
||||
return edit.has_value();
|
||||
return edit != nullptr;
|
||||
}
|
||||
|
||||
template <typename T> void TextBox<T>::input_paste_callback(const CustomEvents::PasteEvent& paste) {
|
||||
if(is_selected() && edit.value().userInput.input_paste_callback(paste))
|
||||
if(is_selected() && edit->input_paste_callback(paste))
|
||||
after_text_input_callback();
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +119,7 @@ template <typename T> void TextBox<T>::input_text_key_callback(const InputManage
|
|||
});
|
||||
}
|
||||
else {
|
||||
if(edit.value().userInput.input_key_callback(*gui.io.input, key).textEdited)
|
||||
if(edit->input_key_callback(*gui.io.input, key).textEdited)
|
||||
after_text_input_callback();
|
||||
}
|
||||
}
|
||||
|
|
@ -150,7 +151,7 @@ template <typename T> void TextBox<T>::after_text_input_callback() {
|
|||
|
||||
template <typename T> void TextBox<T>::input_text_callback(const InputManager::TextCallbackArgs& text) {
|
||||
if(is_selected()) {
|
||||
edit.value().userInput.add_text_to_textbox(text.str);
|
||||
edit->add_text_to_textbox(text.str);
|
||||
after_text_input_callback();
|
||||
}
|
||||
}
|
||||
|
|
@ -181,6 +182,18 @@ template <typename T> void TextBox<T>::input_mouse_motion_callback(const InputMa
|
|||
textbox->process_mouse_left_button(*cur, motion.pos - boundingBox.value().min, 0, isHeld, gui.io.input->key(InputManager::KEY_GENERIC_LSHIFT).held);
|
||||
}
|
||||
|
||||
template <typename T> std::optional<InputManager::TextBoxStartInfo> TextBox<T>::get_text_box_start_info() {
|
||||
if(edit) {
|
||||
SCollision::AABB<float> rect = {boundingBox.value().min * gui.io.guiScaleMultiplier, boundingBox.value().max * gui.io.guiScaleMultiplier};
|
||||
return InputManager::TextBoxStartInfo{
|
||||
.id = edit->id,
|
||||
.rect = rect,
|
||||
.inputProperties = userInfo.textInputProps
|
||||
};
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <typename T> void TextBox<T>::init_textbox(UpdateInputData& io) {
|
||||
if(!textbox) {
|
||||
textbox = std::make_shared<RichText::TextBox>();
|
||||
|
|
@ -212,7 +225,7 @@ template <typename T> bool TextBox<T>::update_data() {
|
|||
|
||||
template <typename T> TextBox<T>::~TextBox() {
|
||||
if(is_selected())
|
||||
gui.io.input->remove_text_box(edit.value().textboxInputID);
|
||||
CustomEvents::emit_event(CustomEvents::RefreshTextBoxInputEvent{});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue