Working on getting textbox edit tool functional
This commit is contained in:
parent
262bf23bce
commit
0087048a02
43 changed files with 605 additions and 295 deletions
|
|
@ -6,8 +6,9 @@ namespace GUIStuff {
|
|||
|
||||
void Element::tick_update() {}
|
||||
|
||||
void Element::input_paste_callback(const CustomEvents::PasteEventData& paste) { }
|
||||
void Element::input_text_key_callback(const InputManager::KeyCallbackArgs& key) { }
|
||||
void Element::input_text_callback(const std::string& str) { }
|
||||
void Element::input_text_callback(const InputManager::TextCallbackArgs& text) { }
|
||||
void Element::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) { }
|
||||
void Element::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) { }
|
||||
void Element::input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) { }
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ namespace GUIStuff {
|
|||
|
||||
virtual void tick_update();
|
||||
|
||||
// Return true when mouse obstructs what's behind it
|
||||
virtual void input_paste_callback(const CustomEvents::PasteEventData& paste);
|
||||
virtual void input_text_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
virtual void input_text_callback(const std::string& str);
|
||||
virtual void input_text_callback(const InputManager::TextCallbackArgs& text);
|
||||
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button);
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion);
|
||||
virtual void input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel);
|
||||
|
|
|
|||
|
|
@ -4,16 +4,23 @@
|
|||
|
||||
namespace GUIStuff {
|
||||
|
||||
struct NumberSliderData {
|
||||
std::function<void()> onChange;
|
||||
std::function<void()> onHold;
|
||||
std::function<void()> onRelease;
|
||||
};
|
||||
|
||||
template <typename T> class NumberSlider : public Element {
|
||||
public:
|
||||
NumberSlider(GUIManager& gui):
|
||||
Element(gui) {}
|
||||
|
||||
void layout(const Clay_ElementId& id, T* data, T minData, T maxData, const std::function<void()>& onChange) {
|
||||
|
||||
void layout(const Clay_ElementId& id, T* data, T minData, T maxData, const NumberSliderData& config) {
|
||||
this->data = data;
|
||||
this->minData = minData;
|
||||
this->maxData = maxData;
|
||||
this->onChange = onChange;
|
||||
this->config = config;
|
||||
|
||||
CLAY(id, {
|
||||
.layout = {
|
||||
|
|
@ -74,22 +81,29 @@ template <typename T> class NumberSlider : public Element {
|
|||
canvas->restore();
|
||||
}
|
||||
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override {
|
||||
bool oldIsHeld = isHeld;
|
||||
isHeld = mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down;
|
||||
if(isHeld && boundingBox.has_value())
|
||||
update_slider_pos(button.pos);
|
||||
if(oldIsHeld && !isHeld) {
|
||||
gui.set_post_callback_func([&] {
|
||||
if(config.onRelease) config.onRelease();
|
||||
});
|
||||
}
|
||||
else if(isHeld && boundingBox.has_value())
|
||||
update_slider_pos(button.pos, true);
|
||||
}
|
||||
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override {
|
||||
if(isHeld && boundingBox.has_value())
|
||||
update_slider_pos(motion.pos);
|
||||
update_slider_pos(motion.pos, false);
|
||||
}
|
||||
|
||||
private:
|
||||
void update_slider_pos(const Vector2f& p) {
|
||||
gui.set_post_callback_func([&, p] {
|
||||
void update_slider_pos(const Vector2f& p, bool justHeld) {
|
||||
gui.set_post_callback_func([&, p, justHeld] {
|
||||
float fracPosOnSlider = (p.x() - boundingBox.value().min.x()) / boundingBox.value().width();
|
||||
*data = static_cast<T>(std::clamp<double>(std::lerp<double>(minData, maxData, fracPosOnSlider), minData, maxData)); // Clamp as double then cast so that unsigned types dont wrap on clamp
|
||||
if(onChange) onChange();
|
||||
if(justHeld && config.onHold) config.onHold();
|
||||
if(config.onChange) config.onChange();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +111,7 @@ template <typename T> class NumberSlider : public Element {
|
|||
T* data = nullptr;
|
||||
T minData = 0.0;
|
||||
T maxData = 1.0;
|
||||
std::function<void()> onChange;
|
||||
NumberSliderData config;
|
||||
|
||||
float hoverAnimation = 0.0;
|
||||
float holdAnimation = 0.0;
|
||||
|
|
|
|||
|
|
@ -19,13 +19,15 @@ template <typename T> struct TextBoxData {
|
|||
InputManager::TextInputProperties textInputProps;
|
||||
std::function<void()> onEdit;
|
||||
std::function<void()> onEnter;
|
||||
std::function<void()> onSelect;
|
||||
std::function<void()> onDeselect;
|
||||
};
|
||||
|
||||
|
||||
struct TextEditData {
|
||||
TextEditData(unsigned initTextboxInputID, const std::shared_ptr<RichText::TextBox>& initTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& initCursor, const std::function<void()>& onTextEdit):
|
||||
TextEditData(unsigned initTextboxInputID, const std::shared_ptr<RichText::TextBox>& initTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& initCursor):
|
||||
textboxInputID(initTextboxInputID),
|
||||
userInput(initTextBox, initCursor, nullptr, onTextEdit)
|
||||
userInput(initTextBox, initCursor, nullptr)
|
||||
{}
|
||||
unsigned textboxInputID;
|
||||
RichTextUserInput userInput;
|
||||
|
|
@ -37,12 +39,14 @@ template <typename T> class TextBox : public Element {
|
|||
|
||||
void layout(const Clay_ElementId& id, const TextBoxData<T>& userInfo);
|
||||
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override;
|
||||
virtual void input_paste_callback(const CustomEvents::PasteEventData& paste) override;
|
||||
virtual void input_text_key_callback(const InputManager::KeyCallbackArgs& key) override;
|
||||
virtual void input_text_callback(const std::string& str) override;
|
||||
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;
|
||||
~TextBox();
|
||||
private:
|
||||
void after_text_input_callback();
|
||||
void init_textbox(UpdateInputData& io);
|
||||
void reset_textbox_text();
|
||||
bool update_data();
|
||||
|
|
|
|||
|
|
@ -65,6 +65,11 @@ template <typename T> bool TextBox<T>::is_selected() const {
|
|||
return edit.has_value();
|
||||
}
|
||||
|
||||
template <typename T> void TextBox<T>::input_paste_callback(const CustomEvents::PasteEventData& paste) {
|
||||
if(is_selected() && edit.value().userInput.input_paste_callback(paste))
|
||||
after_text_input_callback();
|
||||
}
|
||||
|
||||
template <typename T> void TextBox<T>::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {
|
||||
if(is_selected()) {
|
||||
if(key.key == InputManager::KEY_GENERIC_ENTER && key.down) {
|
||||
|
|
@ -75,14 +80,27 @@ template <typename T> void TextBox<T>::input_text_key_callback(const InputManage
|
|||
reset_textbox_text();
|
||||
});
|
||||
}
|
||||
else
|
||||
edit.value().userInput.input_key_callback(*gui.io.input, key);
|
||||
else {
|
||||
if(edit.value().userInput.input_key_callback(*gui.io.input, key).textEdited)
|
||||
after_text_input_callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void TextBox<T>::input_text_callback(const std::string& str) {
|
||||
if(is_selected())
|
||||
edit.value().userInput.add_text_to_textbox(str);
|
||||
template <typename T> void TextBox<T>::after_text_input_callback() {
|
||||
if(userInfo.immutable)
|
||||
cur->pos = cur->selectionBeginPos = cur->selectionEndPos = textbox->insert({0, 0}, userInfo.toStr(*userInfo.data));
|
||||
else {
|
||||
if(update_data() && userInfo.onEdit)
|
||||
gui.set_post_callback_func_high_priority(userInfo.onEdit);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
after_text_input_callback();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void TextBox<T>::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
|
||||
|
|
@ -91,22 +109,23 @@ template <typename T> void TextBox<T>::input_mouse_button_callback(const InputMa
|
|||
if(button.button == InputManager::MouseButton::LEFT && boundingBox.has_value()) {
|
||||
if(button.down) {
|
||||
if(mouseHovering) {
|
||||
SCollision::AABB<float> rect = {(boundingBox.value().min + io.windowPos) * io.guiScaleMultiplier, (boundingBox.value().max + io.windowPos) * io.guiScaleMultiplier};
|
||||
unsigned id = gui.io.input->set_text_box_front(rect, userInfo.textInputProps);
|
||||
if(!is_selected()) {
|
||||
SCollision::AABB<float> rect = {(boundingBox.value().min + io.windowPos) * io.guiScaleMultiplier, (boundingBox.value().max + io.windowPos) * io.guiScaleMultiplier};
|
||||
unsigned id = gui.io.input->set_text_box_front(rect, userInfo.textInputProps);
|
||||
edit = TextEditData(id, textbox, cur);
|
||||
gui.set_post_callback_func_high_priority([&] {
|
||||
if(userInfo.onSelect) userInfo.onSelect();
|
||||
});
|
||||
}
|
||||
textbox->process_mouse_left_button(*cur, button.pos - boundingBox.value().min, button.clicks, true, gui.io.input->key(InputManager::KEY_GENERIC_LSHIFT).held);
|
||||
edit = TextEditData(id, textbox, cur, [&] {
|
||||
if(userInfo.immutable)
|
||||
cur->pos = cur->selectionBeginPos = cur->selectionEndPos = textbox->insert({0, 0}, userInfo.toStr(*userInfo.data));
|
||||
else {
|
||||
if(update_data() && userInfo.onEdit)
|
||||
gui.set_post_callback_func_high_priority(userInfo.onEdit);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if(is_selected()) {
|
||||
gui.io.input->remove_text_box(edit.value().textboxInputID);
|
||||
if(update_data())
|
||||
gui.set_post_callback_func_high_priority(userInfo.onEdit);
|
||||
gui.set_post_callback_func_high_priority([&] {
|
||||
if(update_data())
|
||||
if(userInfo.onEdit) userInfo.onEdit();
|
||||
if(userInfo.onDeselect) userInfo.onDeselect();
|
||||
});
|
||||
reset_textbox_text();
|
||||
edit = std::nullopt;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue