Readded chat box

This commit is contained in:
Yousef Khadadeh 2026-04-09 16:30:28 +03:00
parent 99c2657434
commit 60af55d4db
19 changed files with 307 additions and 249 deletions

View file

@ -12,6 +12,7 @@ template <typename OptT> SelectableButton::Data selectable_button_options_to_dat
SelectableButton::Data toRet;
toRet.onClick = options.onClick;
toRet.isSelected = options.isSelected;
toRet.instantResponse = options.instantResponse;
toRet.drawType = options.drawType;
toRet.onClickButton = options.onClickButton;
return toRet;
@ -20,6 +21,7 @@ template <typename OptT> SelectableButton::Data selectable_button_options_to_dat
struct TextButtonOptions {
SelectableButton::DrawType drawType = SelectableButton::DrawType::FILLED;
bool isSelected = false;
bool instantResponse = false;
bool wide = false;
bool centered = true;
@ -30,6 +32,7 @@ struct TextButtonOptions {
struct SVGButtonOptions {
SelectableButton::DrawType drawType = SelectableButton::DrawType::FILLED;
bool isSelected = false;
bool instantResponse = false;
float size = BIG_BUTTON_SIZE;
std::function<void()> onClick;
@ -39,6 +42,7 @@ struct SVGButtonOptions {
struct FixedSizeColorButtonOptions {
SelectableButton::DrawType drawType = SelectableButton::DrawType::FILLED;
bool isSelected = false;
bool instantResponse = false;
bool hasAlpha = true;
float size = BIG_BUTTON_SIZE;

View file

@ -8,7 +8,6 @@ namespace GUIStuff { namespace ElementHelpers {
template <typename T, typename OptT> TextBoxData<T> textbox_options_to_data(const OptT& options) {
TextBoxData<T> toRet;
toRet.updateEveryEdit = options.updateEveryEdit;
toRet.onEnter = options.onEnter;
toRet.onEdit = options.onEdit;
toRet.immutable = options.immutable;
@ -18,7 +17,6 @@ template <typename T, typename OptT> TextBoxData<T> textbox_options_to_data(cons
}
struct TextBoxOptions {
bool updateEveryEdit = true;
bool immutable = false;
std::function<void()> onEnter;
std::function<void()> onEdit;
@ -28,7 +26,6 @@ struct TextBoxOptions {
struct TextBoxScalarOptions {
int decimalPrecision = 0;
bool updateEveryEdit = true;
bool immutable = false;
std::function<void()> onEnter;
std::function<void()> onEdit;
@ -38,7 +35,6 @@ struct TextBoxScalarOptions {
struct TextBoxScalarsOptions {
int decimalPrecision = 0;
bool updateEveryEdit = true;
bool immutable = false;
std::function<void(size_t)> onEnter;
std::function<void(size_t)> onEdit;
@ -48,7 +44,6 @@ struct TextBoxScalarsOptions {
struct TextBoxPathOptions {
std::filesystem::file_type fileTypeRestriction;
bool updateEveryEdit = true;
bool immutable = false;
std::function<void()> onEnter;
std::function<void()> onEdit;
@ -58,7 +53,6 @@ struct TextBoxPathOptions {
struct TextBoxHexColorOptions {
bool hasAlpha = true;
bool updateEveryEdit = true;
bool immutable = false;
std::function<void()> onEnter;
std::function<void()> onEdit;
@ -122,7 +116,6 @@ template <typename TContainer, typename T> void input_scalars_field(GUIManager&
for(size_t i = 0; i < elemCount; i++) {
gui.new_id(i, [&] { input_scalar<T>(gui, "field", &(*val)[i], minVal, maxVal, TextBoxScalarOptions {
.decimalPrecision = options.decimalPrecision,
.updateEveryEdit = options.updateEveryEdit,
.immutable = options.immutable,
.onEnter = [f = options.onEnter, i] { if(f) f(i); },
.onEdit = [f = options.onEdit, i] { if(f) f(i); },

View file

@ -6,6 +6,7 @@ namespace GUIStuff {
gui(initGUI) {}
void Element::update() {}
void Element::deselect() {}
void Element::input_paste_callback(const CustomEvents::PasteEventData& paste) { }
void Element::input_text_key_callback(const InputManager::KeyCallbackArgs& key) { }

View file

@ -23,6 +23,7 @@ namespace GUIStuff {
Element* parent = nullptr;
virtual void update();
virtual void deselect();
virtual void input_paste_callback(const CustomEvents::PasteEventData& paste);
virtual void input_text_key_callback(const InputManager::KeyCallbackArgs& key);

View file

@ -14,6 +14,7 @@ void SelectableButton::layout(const Clay_ElementId& id, const Data& d) {
SkColor4f backgroundColorHighlight;
SkColor4f backgroundColor;
instantResponse = d.instantResponse;
onClick = [&, this, d] {
if(d.onClickButton)
d.onClickButton(this);
@ -70,10 +71,16 @@ void SelectableButton::layout(const Clay_ElementId& id, const Data& d) {
void SelectableButton::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
bool oldIsHeld = isHeld;
isHeld = mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down;
if(isHeld)
if(isHeld) {
if(instantResponse) {
std::cout << "INSTANT" << std::endl;
gui.set_post_callback_func(onClick);
}
gui.set_to_layout();
}
else if(mouseHovering && oldIsHeld && button.button == InputManager::MouseButton::LEFT && !button.down) {
gui.set_post_callback_func(onClick);
if(!instantResponse)
gui.set_post_callback_func(onClick);
gui.set_to_layout();
}
else if(mouseHovering != oldIsHovering || isHeld != oldIsHeld)

View file

@ -21,6 +21,7 @@ class SelectableButton : public Element {
struct Data {
DrawType drawType = DrawType::TRANSPARENT_ALL;
bool isSelected = false;
bool instantResponse = false;
std::function<void()> onClick;
std::function<void(SelectableButton*)> onClickButton;
std::function<void(const InnerContentCallbackParameters&)> innerContent;
@ -32,6 +33,7 @@ class SelectableButton : public Element {
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
private:
bool instantResponse = false;
bool isHeld = false;
bool oldIsHovering = false;
std::function<void()> onClick;

View file

@ -14,7 +14,6 @@ template <typename T> struct TextBoxData {
std::function<std::optional<T>(const std::string&)> fromStr;
std::function<std::string(const T&)> toStr;
bool singleLine = true;
bool updateEveryEdit = true;
bool immutable = false;
InputManager::TextInputProperties textInputProps;
std::function<void()> onEdit;
@ -38,7 +37,9 @@ template <typename T> class TextBox : public Element {
TextBox(GUIManager& gui);
void layout(const Clay_ElementId& id, const TextBoxData<T>& userInfo);
virtual void update();
void select();
virtual void update() override;
virtual void deselect() override;
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;

View file

@ -71,6 +71,23 @@ template <typename T> void TextBox<T>::clay_draw(SkCanvas* canvas, UpdateInputDa
canvas->restore();
}
template <typename T> void TextBox<T>::select() {
if(!is_selected()) {
SCollision::AABB<float> rect = {(boundingBox.value().min + gui.io.windowPos) * gui.io.guiScaleMultiplier, (boundingBox.value().max + gui.io.windowPos) * gui.io.guiScaleMultiplier};
unsigned id = gui.io.input->set_text_box_front(rect, userInfo.textInputProps);
edit = TextEditData(id, textbox, cur);
}
}
template <typename T> void TextBox<T>::deselect() {
if(is_selected()) {
gui.io.input->remove_text_box(edit.value().textboxInputID);
if(userInfo.onDeselect) userInfo.onDeselect();
reset_textbox_text();
edit = std::nullopt;
}
}
template <typename T> bool TextBox<T>::is_selected() const {
return edit.has_value();
}
@ -101,7 +118,7 @@ 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(userInfo.updateEveryEdit && update_data() && userInfo.onEdit)
if(update_data() && userInfo.onEdit)
gui.set_post_callback_func_high_priority(userInfo.onEdit);
}
}
@ -114,37 +131,22 @@ template <typename T> void TextBox<T>::input_text_callback(const InputManager::T
}
template <typename T> void TextBox<T>::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
auto& io = gui.io;
isHeld = false;
if(button.button == InputManager::MouseButton::LEFT && boundingBox.has_value()) {
if(button.down) {
if(mouseHovering) {
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);
select();
gui.set_post_callback_func_high_priority([&] {
if(userInfo.onSelect) userInfo.onSelect();
});
}
isHeld = true;
textbox->process_mouse_left_button(*cur, button.pos - boundingBox.value().min, button.clicks, isHeld, gui.io.input->key(InputManager::KEY_GENERIC_LSHIFT).held);
}
else if(is_selected()) {
gui.io.input->remove_text_box(edit.value().textboxInputID);
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;
textbox->process_mouse_left_button(*cur, button.pos - boundingBox.value().min, button.clicks, true, gui.io.input->key(InputManager::KEY_GENERIC_LSHIFT).held);
}
else if(is_selected())
deselect();
}
else {
textbox->process_mouse_left_button(*cur, button.pos - boundingBox.value().min, 0, isHeld, gui.io.input->key(InputManager::KEY_GENERIC_LSHIFT).held);
textbox->process_mouse_left_button(*cur, button.pos - boundingBox.value().min, 0, false, gui.io.input->key(InputManager::KEY_GENERIC_LSHIFT).held);
}
}
}

View file

@ -482,6 +482,11 @@ bool GUIManager::cursor_obstructed() const {
return cursorObstructed;
}
void GUIManager::deselect_all() {
for(ElementContainer* e : orderedElements)
e->elem->deselect();
}
void GUIManager::input_paste_callback(const CustomEvents::PasteEventData& paste) {
for(ElementContainer* e : orderedElements)
e->elem->input_paste_callback(paste);

View file

@ -43,8 +43,8 @@ class GUIManager {
template <typename ElementType, typename... Args> ElementType* element(const char* id, const Args&... a) {
push_id(id);
Element* oldParent = parentElement;
ElementType* elem = insert_element<ElementType>();
Element* oldParent = parentElement;
elem->parent = parentElement;
parentElement = elem;
@ -61,9 +61,8 @@ class GUIManager {
template <typename ElementType, typename... Args> ElementType* clipping_element(const char* id, const Args&... a) {
push_id(id);
Element* oldParent = parentElement;
ElementType* elem = insert_element<ElementType>();
Element* oldParent = parentElement;
elem->parent = parentElement;
parentElement = elem;
@ -83,11 +82,12 @@ class GUIManager {
clippingRegion = oldClippingRegion;
parentElement = oldParent;
pop_id();
return elem;
}
void deselect_all();
DefaultStringArena strArena;
void input_paste_callback(const CustomEvents::PasteEventData& paste);