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
|
|
@ -53,6 +53,7 @@ set(sources "src/main.cpp"
|
|||
"src/GUIHolder.cpp"
|
||||
"src/GlobalConfig.cpp"
|
||||
"src/RichTextUserInput.cpp"
|
||||
"src/CustomEvents.cpp"
|
||||
"src/Bookmarks/BookmarkListItem.cpp"
|
||||
"src/Bookmarks/BookmarkManager.cpp"
|
||||
"src/ResourceDisplay/ResourceDisplay.cpp"
|
||||
|
|
|
|||
38
src/CustomEvents.cpp
Normal file
38
src/CustomEvents.cpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#include "CustomEvents.hpp"
|
||||
#include <SDL3/SDL.h>
|
||||
#include <queue>
|
||||
|
||||
namespace CustomEvents {
|
||||
|
||||
bool alreadyInitialized = false;
|
||||
|
||||
uint32_t PASTE_EVENT;
|
||||
std::queue<PasteEventData> pasteEventData;
|
||||
|
||||
void init() {
|
||||
if(!alreadyInitialized) {
|
||||
PASTE_EVENT = SDL_RegisterEvents(1);
|
||||
alreadyInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool emit_paste_event(const PasteEventData& pasteData) {
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.type = PASTE_EVENT;
|
||||
if(SDL_PushEvent(&event)) {
|
||||
pasteEventData.push(pasteData);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const PasteEventData& get_paste_event_data() {
|
||||
return pasteEventData.front();
|
||||
}
|
||||
|
||||
void pop_paste_event_data() {
|
||||
pasteEventData.pop();
|
||||
}
|
||||
|
||||
}
|
||||
26
src/CustomEvents.hpp
Normal file
26
src/CustomEvents.hpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include "RichText/TextBox.hpp"
|
||||
|
||||
namespace CustomEvents {
|
||||
void init();
|
||||
|
||||
enum class PasteEventDataType {
|
||||
TEXT,
|
||||
IMAGE
|
||||
};
|
||||
struct PasteEventData {
|
||||
PasteEventDataType type;
|
||||
std::string data;
|
||||
std::optional<RichText::TextData> richText;
|
||||
std::optional<Vector2f> mousePos;
|
||||
};
|
||||
|
||||
bool emit_paste_event(const PasteEventData& pasteData);
|
||||
const PasteEventData& get_paste_event_data();
|
||||
void pop_paste_event_data();
|
||||
|
||||
extern uint32_t PASTE_EVENT;
|
||||
}
|
||||
|
|
@ -58,6 +58,10 @@ void DrawingProgram::on_tab_out() {
|
|||
controls.middleClickHeld = false;
|
||||
}
|
||||
|
||||
void DrawingProgram::input_paste_callback(const CustomEvents::PasteEventData& paste) {
|
||||
drawTool->input_paste_callback(paste);
|
||||
}
|
||||
|
||||
void DrawingProgram::input_drop_file_callback(const InputManager::DropCallbackArgs& drop) {
|
||||
if(std::filesystem::is_regular_file(drop.data)) {
|
||||
#ifdef __EMSCRIPTEN_
|
||||
|
|
@ -83,6 +87,14 @@ void DrawingProgram::input_drop_text_callback(const InputManager::DropCallbackAr
|
|||
}
|
||||
}
|
||||
|
||||
void DrawingProgram::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {
|
||||
drawTool->input_text_key_callback(key);
|
||||
}
|
||||
|
||||
void DrawingProgram::input_text_callback(const InputManager::TextCallbackArgs& text) {
|
||||
drawTool->input_text_callback(text);
|
||||
}
|
||||
|
||||
void DrawingProgram::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
|
||||
auto buttonCallbacks = [&](const InputManager::MouseButtonCallbackArgs& b) {
|
||||
drawTool->input_mouse_button_on_canvas_callback(b);
|
||||
|
|
|
|||
|
|
@ -59,8 +59,11 @@ class DrawingProgram {
|
|||
void send_transforms_for(const std::vector<CanvasComponentContainer::ObjInfo*>& objsToSendTransformsFor);
|
||||
|
||||
void on_tab_out();
|
||||
void input_paste_callback(const CustomEvents::PasteEventData& paste);
|
||||
void input_drop_text_callback(const InputManager::DropCallbackArgs& drop);
|
||||
void input_drop_file_callback(const InputManager::DropCallbackArgs& drop);
|
||||
void input_text_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
void input_text_callback(const InputManager::TextCallbackArgs& text);
|
||||
void input_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button);
|
||||
void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion);
|
||||
|
|
@ -131,7 +134,6 @@ class DrawingProgram {
|
|||
|
||||
std::optional<Vector2f> rightClickPopupLocation;
|
||||
|
||||
|
||||
uint32_t nextID = 0;
|
||||
|
||||
friend class EyeDropperTool;
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ std::unique_ptr<DrawingProgramToolBase> DrawingProgramToolBase::allocate_tool_ty
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void DrawingProgramToolBase::input_paste_callback(const CustomEvents::PasteEventData& paste) {}
|
||||
void DrawingProgramToolBase::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {}
|
||||
void DrawingProgramToolBase::input_text_callback(const InputManager::TextCallbackArgs& text) {}
|
||||
void DrawingProgramToolBase::input_key_callback(const InputManager::KeyCallbackArgs& key) {}
|
||||
void DrawingProgramToolBase::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) {}
|
||||
void DrawingProgramToolBase::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ class DrawingProgramToolBase {
|
|||
virtual void draw(SkCanvas* canvas, const DrawData& drawData) = 0;
|
||||
virtual void switch_tool(DrawingProgramToolType newTool) = 0;
|
||||
virtual bool prevent_undo_or_redo() = 0;
|
||||
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 InputManager::TextCallbackArgs& text);
|
||||
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
virtual void input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button);
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ void EditTool::gui_toolbox() {
|
|||
auto& gui = drawP.world.main.g.gui;
|
||||
|
||||
if(objInfoBeingEdited)
|
||||
compEditTool->edit_gui(objInfoBeingEdited);
|
||||
compEditTool->edit_gui();
|
||||
else {
|
||||
gui.new_id("edit tool", [&] {
|
||||
text_label_centered(gui, "Edit");
|
||||
|
|
@ -46,6 +46,21 @@ void EditTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp) {
|
|||
switch_tool(get_type());
|
||||
}
|
||||
|
||||
void EditTool::input_paste_callback(const CustomEvents::PasteEventData& paste) {
|
||||
if(objInfoBeingEdited)
|
||||
compEditTool->input_paste_callback(paste);
|
||||
}
|
||||
|
||||
void EditTool::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {
|
||||
if(objInfoBeingEdited)
|
||||
compEditTool->input_text_key_callback(key);
|
||||
}
|
||||
|
||||
void EditTool::input_text_callback(const InputManager::TextCallbackArgs& text) {
|
||||
if(objInfoBeingEdited)
|
||||
compEditTool->input_text_callback(text);
|
||||
}
|
||||
|
||||
void EditTool::input_key_callback(const InputManager::KeyCallbackArgs& key) {
|
||||
drawP.selection.input_key_callback_modify_selection(key);
|
||||
}
|
||||
|
|
@ -122,12 +137,12 @@ void EditTool::input_mouse_button_on_canvas_callback(const InputManager::MouseBu
|
|||
switch_tool(get_type());
|
||||
|
||||
if(objInfoBeingEdited)
|
||||
compEditTool->input_mouse_button_on_canvas_callback(objInfoBeingEdited, button, pointDragging);
|
||||
compEditTool->input_mouse_button_on_canvas_callback(button, pointDragging);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(objInfoBeingEdited)
|
||||
compEditTool->input_mouse_button_on_canvas_callback(objInfoBeingEdited, button, pointDragging);
|
||||
compEditTool->input_mouse_button_on_canvas_callback(button, pointDragging);
|
||||
if(pointDragging)
|
||||
pointDragging = nullptr;
|
||||
}
|
||||
|
|
@ -147,14 +162,14 @@ void EditTool::input_mouse_motion_callback(const InputManager::MouseMotionCallba
|
|||
objInfoBeingEdited->obj->commit_update(drawP);
|
||||
}
|
||||
}
|
||||
compEditTool->input_mouse_motion_callback(objInfoBeingEdited, motion, pointDragging);
|
||||
compEditTool->input_mouse_motion_callback(motion, pointDragging);
|
||||
}
|
||||
drawP.selection.input_mouse_motion_callback_modify_selection(motion);
|
||||
}
|
||||
|
||||
void EditTool::right_click_popup_gui(Vector2f popupPos) {
|
||||
if(objInfoBeingEdited)
|
||||
return compEditTool->right_click_popup_gui(objInfoBeingEdited, popupPos);
|
||||
return compEditTool->right_click_popup_gui(popupPos);
|
||||
else
|
||||
return drawP.selection_action_menu(popupPos);
|
||||
}
|
||||
|
|
@ -165,7 +180,7 @@ void EditTool::add_point_handle(const HandleData& handle) {
|
|||
|
||||
void EditTool::switch_tool(DrawingProgramToolType newTool) {
|
||||
if(objInfoBeingEdited) {
|
||||
compEditTool->commit_edit_updates(objInfoBeingEdited, prevData);
|
||||
compEditTool->commit_edit_updates(prevData);
|
||||
objInfoBeingEdited->obj->commit_update(drawP);
|
||||
objInfoBeingEdited->obj->send_comp_update(drawP, true);
|
||||
|
||||
|
|
@ -221,23 +236,23 @@ void EditTool::edit_start(CanvasComponentContainer::ObjInfo* comp, bool initUndo
|
|||
bool isEditing = true;
|
||||
switch(comp->obj->get_comp().get_type()) {
|
||||
case CanvasComponentType::TEXTBOX: {
|
||||
compEditTool = std::make_unique<TextBoxEditTool>(drawP);
|
||||
compEditTool = std::make_unique<TextBoxEditTool>(drawP, comp);
|
||||
break;
|
||||
}
|
||||
case CanvasComponentType::ELLIPSE: {
|
||||
compEditTool = std::make_unique<EllipseDrawEditTool>(drawP);
|
||||
compEditTool = std::make_unique<EllipseDrawEditTool>(drawP, comp);
|
||||
break;
|
||||
}
|
||||
case CanvasComponentType::RECTANGLE: {
|
||||
compEditTool = std::make_unique<RectDrawEditTool>(drawP);
|
||||
compEditTool = std::make_unique<RectDrawEditTool>(drawP, comp);
|
||||
break;
|
||||
}
|
||||
case CanvasComponentType::IMAGE: {
|
||||
compEditTool = std::make_unique<ImageEditTool>(drawP);
|
||||
compEditTool = std::make_unique<ImageEditTool>(drawP, comp);
|
||||
break;
|
||||
}
|
||||
case CanvasComponentType::BRUSHSTROKE: {
|
||||
compEditTool = std::make_unique<BrushEditTool>(drawP);
|
||||
compEditTool = std::make_unique<BrushEditTool>(drawP, comp);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
@ -249,7 +264,7 @@ void EditTool::edit_start(CanvasComponentContainer::ObjInfo* comp, bool initUndo
|
|||
objInfoBeingEdited = comp;
|
||||
oldData = comp->obj->get_comp().get_data_copy();
|
||||
undoAfterEditDone = initUndoAfterEditDone;
|
||||
compEditTool->edit_start(*this, objInfoBeingEdited, prevData);
|
||||
compEditTool->edit_start(*this, prevData);
|
||||
drawP.world.main.g.gui.set_to_layout();
|
||||
}
|
||||
}
|
||||
|
|
@ -261,7 +276,7 @@ bool EditTool::is_editable(CanvasComponentContainer::ObjInfo* comp) {
|
|||
void EditTool::tool_update() {
|
||||
if(objInfoBeingEdited) {
|
||||
objInfoBeingEdited->obj->send_comp_update(drawP, false);
|
||||
bool shouldNotReset = compEditTool->edit_update(objInfoBeingEdited);
|
||||
bool shouldNotReset = compEditTool->edit_update();
|
||||
if(!shouldNotReset)
|
||||
switch_tool(get_type());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ class EditTool : public DrawingProgramToolBase {
|
|||
virtual void switch_tool(DrawingProgramToolType newTool) override;
|
||||
virtual void draw(SkCanvas* canvas, const DrawData& drawData) override;
|
||||
virtual bool prevent_undo_or_redo() 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 InputManager::TextCallbackArgs& text) override;
|
||||
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key) override;
|
||||
virtual void input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) override;
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
|
||||
|
|
|
|||
|
|
@ -7,18 +7,18 @@
|
|||
#include "../../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp"
|
||||
#include "../../../GUIStuff/ElementHelpers/LayoutHelpers.hpp"
|
||||
|
||||
BrushEditTool::BrushEditTool(DrawingProgram& initDrawP):
|
||||
DrawingProgramEditToolBase(initDrawP)
|
||||
BrushEditTool::BrushEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp):
|
||||
DrawingProgramEditToolBase(initDrawP, initComp)
|
||||
{}
|
||||
|
||||
void BrushEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) {
|
||||
void BrushEditTool::edit_gui() {
|
||||
using namespace GUIStuff;
|
||||
using namespace ElementHelpers;
|
||||
|
||||
auto& a = static_cast<BrushStrokeCanvasComponent&>(comp->obj->get_comp());
|
||||
auto& gui = drawP.world.main.g.gui;
|
||||
Toolbar& t = drawP.world.main.toolbar;
|
||||
auto commit_update_func = [&, comp] { comp->obj->commit_update(drawP); };
|
||||
auto commit_update_func = [&] { comp->obj->commit_update(drawP); };
|
||||
|
||||
gui.new_id("edit tool brush", [&] {
|
||||
text_label_centered(gui, "Edit Brush Stroke");
|
||||
|
|
@ -29,14 +29,14 @@ void BrushEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) {
|
|||
});
|
||||
}
|
||||
|
||||
void BrushEditTool::edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) {
|
||||
void BrushEditTool::edit_start(EditTool& editTool, std::any& prevData) {
|
||||
auto& a = static_cast<BrushStrokeCanvasComponent&>(comp->obj->get_comp());
|
||||
oldColor = a.d.color;
|
||||
}
|
||||
|
||||
void BrushEditTool::commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) {
|
||||
void BrushEditTool::commit_edit_updates(std::any& prevData) {
|
||||
}
|
||||
|
||||
bool BrushEditTool::edit_update(CanvasComponentContainer::ObjInfo* comp) {
|
||||
bool BrushEditTool::edit_update() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ class DrawingProgram;
|
|||
|
||||
class BrushEditTool : public DrawingProgramEditToolBase {
|
||||
public:
|
||||
BrushEditTool(DrawingProgram& initDrawP);
|
||||
virtual void edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override;
|
||||
virtual void commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override;
|
||||
virtual bool edit_update(CanvasComponentContainer::ObjInfo* comp) override;
|
||||
virtual void edit_gui(CanvasComponentContainer::ObjInfo* comp) override;
|
||||
BrushEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp);
|
||||
virtual void edit_start(EditTool& editTool, std::any& prevData) override;
|
||||
virtual void commit_edit_updates(std::any& prevData) override;
|
||||
virtual bool edit_update() override;
|
||||
virtual void edit_gui() override;
|
||||
private:
|
||||
Vector4f oldColor;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,17 +1,21 @@
|
|||
#include "DrawingProgramEditToolBase.hpp"
|
||||
#include "../../../MainProgram.hpp"
|
||||
|
||||
DrawingProgramEditToolBase::DrawingProgramEditToolBase(DrawingProgram& initDrawP):
|
||||
drawP(initDrawP)
|
||||
DrawingProgramEditToolBase::DrawingProgramEditToolBase(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp):
|
||||
drawP(initDrawP),
|
||||
comp(initComp)
|
||||
{}
|
||||
|
||||
void DrawingProgramEditToolBase::right_click_popup_gui(CanvasComponentContainer::ObjInfo* comp, Vector2f popupPos) {
|
||||
void DrawingProgramEditToolBase::right_click_popup_gui(Vector2f popupPos) {
|
||||
Toolbar& t = drawP.world.main.toolbar;
|
||||
t.paint_popup(popupPos);
|
||||
}
|
||||
|
||||
void DrawingProgramEditToolBase::input_key_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::KeyCallbackArgs& key) {}
|
||||
void DrawingProgramEditToolBase::input_mouse_button_on_canvas_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::MouseButtonCallbackArgs& button, bool isDraggingPoint) {}
|
||||
void DrawingProgramEditToolBase::input_mouse_motion_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::MouseMotionCallbackArgs& motion, bool isDraggingPoint) {}
|
||||
void DrawingProgramEditToolBase::input_paste_callback(const CustomEvents::PasteEventData& paste) {}
|
||||
void DrawingProgramEditToolBase::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {}
|
||||
void DrawingProgramEditToolBase::input_text_callback(const InputManager::TextCallbackArgs& text) {}
|
||||
void DrawingProgramEditToolBase::input_key_callback(const InputManager::KeyCallbackArgs& key) {}
|
||||
void DrawingProgramEditToolBase::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button, bool isDraggingPoint) {}
|
||||
void DrawingProgramEditToolBase::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool isDraggingPoint) {}
|
||||
|
||||
DrawingProgramEditToolBase::~DrawingProgramEditToolBase() {}
|
||||
|
|
|
|||
|
|
@ -8,16 +8,20 @@ class EditTool;
|
|||
|
||||
class DrawingProgramEditToolBase {
|
||||
public:
|
||||
DrawingProgramEditToolBase(DrawingProgram& initDrawP);
|
||||
virtual void edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* compContainer, std::any& prevData) = 0;
|
||||
virtual void commit_edit_updates(CanvasComponentContainer::ObjInfo* compContainer, std::any& prevData) = 0;
|
||||
virtual bool edit_update(CanvasComponentContainer::ObjInfo* compContainer) = 0;
|
||||
virtual void edit_gui(CanvasComponentContainer::ObjInfo* compContainer) = 0;
|
||||
virtual void right_click_popup_gui(CanvasComponentContainer::ObjInfo* comp, Vector2f popupPos);
|
||||
virtual void input_key_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::KeyCallbackArgs& key);
|
||||
virtual void input_mouse_button_on_canvas_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::MouseButtonCallbackArgs& button, bool isDraggingPoint);
|
||||
virtual void input_mouse_motion_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::MouseMotionCallbackArgs& motion, bool isDraggingPoint);
|
||||
DrawingProgramEditToolBase(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp);
|
||||
virtual void edit_start(EditTool& editTool, std::any& prevData) = 0;
|
||||
virtual void commit_edit_updates(std::any& prevData) = 0;
|
||||
virtual bool edit_update() = 0;
|
||||
virtual void edit_gui() = 0;
|
||||
virtual void right_click_popup_gui(Vector2f popupPos);
|
||||
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 InputManager::TextCallbackArgs& text);
|
||||
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
virtual void input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button, bool isDraggingPoint);
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool isDraggingPoint);
|
||||
virtual ~DrawingProgramEditToolBase();
|
||||
protected:
|
||||
DrawingProgram& drawP;
|
||||
CanvasComponentContainer::ObjInfo* comp;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,19 +12,19 @@
|
|||
#include "../../../GUIStuff/ElementHelpers/LayoutHelpers.hpp"
|
||||
#include "../../../GUIStuff/ElementHelpers/NumberSliderHelpers.hpp"
|
||||
|
||||
EllipseDrawEditTool::EllipseDrawEditTool(DrawingProgram& initDrawP):
|
||||
DrawingProgramEditToolBase(initDrawP)
|
||||
EllipseDrawEditTool::EllipseDrawEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp):
|
||||
DrawingProgramEditToolBase(initDrawP, initComp)
|
||||
{}
|
||||
|
||||
void EllipseDrawEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) {
|
||||
void EllipseDrawEditTool::edit_gui() {
|
||||
using namespace GUIStuff;
|
||||
using namespace ElementHelpers;
|
||||
|
||||
auto& a = static_cast<EllipseCanvasComponent&>(comp->obj->get_comp());
|
||||
auto& gui = drawP.world.main.g.gui;
|
||||
Toolbar& t = drawP.world.main.toolbar;
|
||||
auto commit_update_func = [&, comp] { comp->obj->commit_update(drawP); };
|
||||
auto commit_update_and_layout_func = [&, comp] {
|
||||
auto commit_update_func = [&] { comp->obj->commit_update(drawP); };
|
||||
auto commit_update_and_layout_func = [&] {
|
||||
comp->obj->commit_update(drawP);
|
||||
drawP.world.main.g.gui.set_to_layout();
|
||||
};
|
||||
|
|
@ -52,7 +52,7 @@ void EllipseDrawEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) {
|
|||
});
|
||||
}
|
||||
|
||||
void EllipseDrawEditTool::edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) {
|
||||
void EllipseDrawEditTool::edit_start(EditTool& editTool, std::any& prevData) {
|
||||
auto& a = static_cast<EllipseCanvasComponent&>(comp->obj->get_comp());
|
||||
|
||||
prevData = a.d;
|
||||
|
|
@ -60,9 +60,9 @@ void EllipseDrawEditTool::edit_start(EditTool& editTool, CanvasComponentContaine
|
|||
editTool.add_point_handle({&a.d.p2, &a.d.p1, nullptr});
|
||||
}
|
||||
|
||||
void EllipseDrawEditTool::commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) {
|
||||
void EllipseDrawEditTool::commit_edit_updates(std::any& prevData) {
|
||||
}
|
||||
|
||||
bool EllipseDrawEditTool::edit_update(CanvasComponentContainer::ObjInfo* comp) {
|
||||
bool EllipseDrawEditTool::edit_update() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ class DrawingProgram;
|
|||
|
||||
class EllipseDrawEditTool : public DrawingProgramEditToolBase {
|
||||
public:
|
||||
EllipseDrawEditTool(DrawingProgram& initDrawP);
|
||||
virtual void edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override;
|
||||
virtual void commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override;
|
||||
virtual bool edit_update(CanvasComponentContainer::ObjInfo* comp) override;
|
||||
virtual void edit_gui(CanvasComponentContainer::ObjInfo* comp) override;
|
||||
EllipseDrawEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp);
|
||||
virtual void edit_start(EditTool& editTool, std::any& prevData) override;
|
||||
virtual void commit_edit_updates(std::any& prevData) override;
|
||||
virtual bool edit_update() override;
|
||||
virtual void edit_gui() override;
|
||||
private:
|
||||
void commit();
|
||||
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@
|
|||
#include <EmscriptenHelpers/emscripten_browser_file.h>
|
||||
#endif
|
||||
|
||||
ImageEditTool::ImageEditTool(DrawingProgram& initDrawP):
|
||||
DrawingProgramEditToolBase(initDrawP)
|
||||
ImageEditTool::ImageEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp):
|
||||
DrawingProgramEditToolBase(initDrawP, initComp)
|
||||
{}
|
||||
|
||||
void ImageEditTool::edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) {
|
||||
void ImageEditTool::edit_start(EditTool& editTool, std::any& prevData) {
|
||||
auto& a = static_cast<ImageCanvasComponent&>(comp->obj->get_comp());
|
||||
static Vector2f staticZero = {0.0f, 0.0f};
|
||||
static Vector2f staticOne = {1.0f, 1.0f};
|
||||
|
|
@ -36,17 +36,17 @@ void ImageEditTool::edit_start(EditTool& editTool, CanvasComponentContainer::Obj
|
|||
comp->obj->commit_update(drawP);
|
||||
}
|
||||
|
||||
void ImageEditTool::commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) {
|
||||
void ImageEditTool::commit_edit_updates(std::any& prevData) {
|
||||
auto& a = static_cast<ImageCanvasComponent&>(comp->obj->get_comp());
|
||||
a.d.editing = false;
|
||||
comp->obj->commit_update(drawP);
|
||||
}
|
||||
|
||||
bool ImageEditTool::edit_update(CanvasComponentContainer::ObjInfo* comp) {
|
||||
bool ImageEditTool::edit_update() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImageEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) {
|
||||
void ImageEditTool::edit_gui() {
|
||||
using namespace GUIStuff;
|
||||
using namespace ElementHelpers;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ class DrawingProgram;
|
|||
|
||||
class ImageEditTool : public DrawingProgramEditToolBase {
|
||||
public:
|
||||
ImageEditTool(DrawingProgram& initDrawP);
|
||||
virtual void edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override;
|
||||
virtual void commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override;
|
||||
virtual bool edit_update(CanvasComponentContainer::ObjInfo* comp) override;
|
||||
virtual void edit_gui(CanvasComponentContainer::ObjInfo* comp) override;
|
||||
ImageEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp);
|
||||
virtual void edit_start(EditTool& editTool, std::any& prevData) override;
|
||||
virtual void commit_edit_updates(std::any& prevData) override;
|
||||
virtual bool edit_update() override;
|
||||
virtual void edit_gui() override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,20 +9,20 @@
|
|||
#include "../../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp"
|
||||
#include "../../../GUIStuff/ElementHelpers/RadioButtonHelpers.hpp"
|
||||
|
||||
RectDrawEditTool::RectDrawEditTool(DrawingProgram& initDrawP):
|
||||
DrawingProgramEditToolBase(initDrawP)
|
||||
RectDrawEditTool::RectDrawEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp):
|
||||
DrawingProgramEditToolBase(initDrawP, initComp)
|
||||
{}
|
||||
|
||||
void RectDrawEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) {
|
||||
void RectDrawEditTool::edit_gui() {
|
||||
using namespace GUIStuff;
|
||||
using namespace ElementHelpers;
|
||||
|
||||
auto& a = static_cast<RectangleCanvasComponent&>(comp->obj->get_comp());
|
||||
auto commit_update_and_layout_func = [&, comp] {
|
||||
auto commit_update_and_layout_func = [&] {
|
||||
comp->obj->commit_update(drawP);
|
||||
drawP.world.main.g.gui.set_to_layout();
|
||||
};
|
||||
auto commit_update_func = [&, comp] { comp->obj->commit_update(drawP); };
|
||||
auto commit_update_func = [&] { comp->obj->commit_update(drawP); };
|
||||
|
||||
Toolbar& t = drawP.world.main.toolbar;
|
||||
auto& gui = drawP.world.main.g.gui;
|
||||
|
|
@ -50,16 +50,16 @@ void RectDrawEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) {
|
|||
});
|
||||
}
|
||||
|
||||
void RectDrawEditTool::edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) {
|
||||
void RectDrawEditTool::edit_start(EditTool& editTool, std::any& prevData) {
|
||||
auto& a = static_cast<RectangleCanvasComponent&>(comp->obj->get_comp());
|
||||
prevData = a.d;
|
||||
editTool.add_point_handle({&a.d.p1, nullptr, &a.d.p2});
|
||||
editTool.add_point_handle({&a.d.p2, &a.d.p1, nullptr});
|
||||
}
|
||||
|
||||
void RectDrawEditTool::commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) {
|
||||
void RectDrawEditTool::commit_edit_updates(std::any& prevData) {
|
||||
}
|
||||
|
||||
bool RectDrawEditTool::edit_update(CanvasComponentContainer::ObjInfo* comp) {
|
||||
bool RectDrawEditTool::edit_update() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ class DrawingProgram;
|
|||
|
||||
class RectDrawEditTool : public DrawingProgramEditToolBase {
|
||||
public:
|
||||
RectDrawEditTool(DrawingProgram& initDrawP);
|
||||
virtual void edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override;
|
||||
virtual void commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override;
|
||||
virtual bool edit_update(CanvasComponentContainer::ObjInfo* comp) override;
|
||||
virtual void edit_gui(CanvasComponentContainer::ObjInfo* comp) override;
|
||||
RectDrawEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp);
|
||||
virtual void edit_start(EditTool& editTool, std::any& prevData) override;
|
||||
virtual void commit_edit_updates(std::any& prevData) override;
|
||||
virtual bool edit_update() override;
|
||||
virtual void edit_gui() override;
|
||||
private:
|
||||
std::optional<RectangleCanvasComponent::Data> oldData;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,89 +16,137 @@
|
|||
|
||||
#include "../../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp"
|
||||
#include "../../../GUIStuff/ElementHelpers/LayoutHelpers.hpp"
|
||||
#include "../../../GUIStuff/ElementHelpers/ButtonHelpers.hpp"
|
||||
#include "../../../GUIStuff/ElementHelpers/NumberSliderHelpers.hpp"
|
||||
#include "../../../GUIStuff/Elements/PositionAdjustingPopupMenu.hpp"
|
||||
|
||||
using namespace RichText;
|
||||
|
||||
TextBoxEditTool::TextBoxEditTool(DrawingProgram& initDrawP):
|
||||
DrawingProgramEditToolBase(initDrawP)
|
||||
TextBoxEditTool::TextBoxEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp):
|
||||
DrawingProgramEditToolBase(initDrawP, initComp)
|
||||
{}
|
||||
|
||||
void TextBoxEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) {
|
||||
void TextBoxEditTool::commit_update_func() {
|
||||
comp->obj->commit_update(drawP);
|
||||
}
|
||||
|
||||
void TextBoxEditTool::commit_update_and_layout_func() {
|
||||
comp->obj->commit_update(drawP);
|
||||
drawP.world.main.g.gui.set_to_layout();
|
||||
}
|
||||
|
||||
void TextBoxEditTool::edit_gui() {
|
||||
using namespace GUIStuff;
|
||||
using namespace ElementHelpers;
|
||||
|
||||
auto& a = static_cast<TextBoxCanvasComponent&>(comp->obj->get_comp());
|
||||
Toolbar& t = drawP.world.main.toolbar;
|
||||
auto& gui = drawP.world.main.g.gui;
|
||||
|
||||
auto& currentMods = *currentModsPtr;
|
||||
|
||||
gui.new_id("edit tool text", [&] {
|
||||
text_label_centered(gui, "Edit Text");
|
||||
|
||||
left_to_right_line_layout(gui, [&] {
|
||||
text_label(gui, "Font");
|
||||
//if(gui.font_picker("font picker", &newFontName)) {
|
||||
// currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES] = std::make_shared<FontFamiliesTextStyleModifier>(std::vector<SkString>{SkString{newFontName.c_str(), newFontName.size()}});
|
||||
// add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES]);});
|
||||
//}
|
||||
});
|
||||
//left_to_right_line_layout(gui, [&] {
|
||||
// text_label(gui, "Font");
|
||||
// if(gui.font_picker("font picker", &newFontName)) {
|
||||
// currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES] = std::make_shared<FontFamiliesTextStyleModifier>(std::vector<SkString>{SkString{newFontName.c_str(), newFontName.size()}});
|
||||
// add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES]);});
|
||||
// }
|
||||
//});
|
||||
|
||||
//left_to_right_line_centered_layout(gui, [&] {
|
||||
// if(svg_icon_button("Bold button", "data/icons/RemixIcon/bold.svg", newIsBold)) {
|
||||
// newIsBold = !newIsBold;
|
||||
// currentMods[TextStyleModifier::ModifierType::WEIGHT] = std::make_shared<WeightTextStyleModifier>(newIsBold ? SkFontStyle::Weight::kBold_Weight : SkFontStyle::Weight::kNormal_Weight);
|
||||
// add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::WEIGHT]);});
|
||||
// }
|
||||
left_to_right_line_centered_layout(gui, [&] {
|
||||
svg_icon_button(gui, "Bold button", "data/icons/RemixIcon/bold.svg", {
|
||||
.isSelected = newIsBold,
|
||||
.onClick = [&] {
|
||||
newIsBold = !newIsBold;
|
||||
currentMods[TextStyleModifier::ModifierType::WEIGHT] = std::make_shared<WeightTextStyleModifier>(newIsBold ? SkFontStyle::Weight::kBold_Weight : SkFontStyle::Weight::kNormal_Weight);
|
||||
add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::WEIGHT]);});
|
||||
commit_update_func();
|
||||
}
|
||||
});
|
||||
|
||||
// if(gui.svg_icon_button("Italic button", "data/icons/RemixIcon/italic.svg", newIsItalic)) {
|
||||
// newIsItalic = !newIsItalic;
|
||||
// currentMods[TextStyleModifier::ModifierType::SLANT] = std::make_shared<SlantTextStyleModifier>(newIsItalic ? SkFontStyle::Slant::kItalic_Slant : SkFontStyle::Slant::kUpright_Slant);
|
||||
// add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::SLANT]);});
|
||||
// }
|
||||
svg_icon_button(gui, "Italic button", "data/icons/RemixIcon/italic.svg", {
|
||||
.isSelected = newIsItalic,
|
||||
.onClick = [&] {
|
||||
newIsItalic = !newIsItalic;
|
||||
currentMods[TextStyleModifier::ModifierType::SLANT] = std::make_shared<SlantTextStyleModifier>(newIsItalic ? SkFontStyle::Slant::kItalic_Slant : SkFontStyle::Slant::kUpright_Slant);
|
||||
add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::SLANT]);});
|
||||
commit_update_func();
|
||||
}
|
||||
});
|
||||
|
||||
// bool decorationEdited = false;
|
||||
// if(gui.svg_icon_button("Underline button", "data/icons/RemixIcon/underline.svg", newIsUnderlined)) {
|
||||
// newIsUnderlined = !newIsUnderlined;
|
||||
// decorationEdited = true;
|
||||
// }
|
||||
// if(gui.svg_icon_button("Strikethrough button", "data/icons/RemixIcon/strikethrough.svg", newIsLinethrough)) {
|
||||
// newIsLinethrough = !newIsLinethrough;
|
||||
// decorationEdited = true;
|
||||
// }
|
||||
// if(gui.svg_icon_button("Overline button", "data/icons/RemixIcon/overline.svg", newIsOverline)) {
|
||||
// newIsOverline = !newIsOverline;
|
||||
// decorationEdited = true;
|
||||
// }
|
||||
// if(decorationEdited) {
|
||||
// currentMods[TextStyleModifier::ModifierType::DECORATION] = std::make_shared<DecorationTextStyleModifier>(get_new_decoration_value());
|
||||
// add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::DECORATION]);});
|
||||
// }
|
||||
//});
|
||||
auto decorationChange = [&] {
|
||||
currentMods[TextStyleModifier::ModifierType::DECORATION] = std::make_shared<DecorationTextStyleModifier>(get_new_decoration_value());
|
||||
add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::DECORATION]);});
|
||||
commit_update_func();
|
||||
};
|
||||
|
||||
//gui.left_to_right_line_centered_layout([&]() {
|
||||
// if(gui.svg_icon_button("Align left button", "data/icons/RemixIcon/align-left.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kLeft))
|
||||
// add_undo([&](){a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kLeft);});
|
||||
// if(gui.svg_icon_button("Align center button", "data/icons/RemixIcon/align-center.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kCenter))
|
||||
// add_undo([&](){a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kCenter);});
|
||||
// if(gui.svg_icon_button("Align right button", "data/icons/RemixIcon/align-right.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kRight))
|
||||
// add_undo([&](){a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kRight);});
|
||||
// if(gui.svg_icon_button("Align justify button", "data/icons/RemixIcon/align-justify.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kJustify))
|
||||
// add_undo([&](){a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kJustify);});
|
||||
// if(gui.svg_icon_button("Text direction left", "data/icons/RemixIcon/text-direction-l.svg", currentPStyle.textDirection == skia::textlayout::TextDirection::kLtr))
|
||||
// add_undo([&](){a.textBox->set_text_direction_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextDirection::kLtr);});
|
||||
// if(gui.svg_icon_button("Text direction right", "data/icons/RemixIcon/text-direction-r.svg", currentPStyle.textDirection == skia::textlayout::TextDirection::kRtl))
|
||||
// add_undo([&](){a.textBox->set_text_direction_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextDirection::kRtl);});
|
||||
//});
|
||||
svg_icon_button(gui, "Underline button", "data/icons/RemixIcon/underline.svg", {
|
||||
.isSelected = newIsUnderlined,
|
||||
.onClick = [&, decorationChange] {
|
||||
newIsUnderlined = !newIsUnderlined;
|
||||
decorationChange();
|
||||
}
|
||||
});
|
||||
|
||||
//if(gui.slider_scalar_field<uint32_t>("Font Size Slider", "Font Size", &newFontSize, 3, 100)) {
|
||||
// hold_undo_data("Font Size", a);
|
||||
// currentMods[TextStyleModifier::ModifierType::SIZE] = std::make_shared<SizeTextStyleModifier>(newFontSize);
|
||||
// a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::SIZE]);
|
||||
//}
|
||||
//else
|
||||
// release_undo_data("Font Size");
|
||||
svg_icon_button(gui, "Strikethrough button", "data/icons/RemixIcon/strikethrough.svg", {
|
||||
.isSelected = newIsLinethrough,
|
||||
.onClick = [&, decorationChange] {
|
||||
newIsLinethrough = !newIsLinethrough;
|
||||
decorationChange();
|
||||
}
|
||||
});
|
||||
|
||||
svg_icon_button(gui, "Overline button", "data/icons/RemixIcon/overline.svg", {
|
||||
.isSelected = newIsOverline,
|
||||
.onClick = [&, decorationChange] {
|
||||
newIsOverline = !newIsOverline;
|
||||
decorationChange();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
left_to_right_line_centered_layout(gui, [&]() {
|
||||
auto paragraph_operation_button = [&](const char* id, const char* svgPath, bool isSelected, const std::function<void()>& func) {
|
||||
svg_icon_button(gui, id, svgPath, {
|
||||
.isSelected = isSelected,
|
||||
.onClick = [&, func] {
|
||||
add_undo(func);
|
||||
commit_update_func();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
paragraph_operation_button("Align left button", "data/icons/RemixIcon/align-left.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kLeft, [&] {
|
||||
a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kLeft);
|
||||
});
|
||||
paragraph_operation_button("Align center button", "data/icons/RemixIcon/align-center.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kCenter, [&] {
|
||||
a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kCenter);
|
||||
});
|
||||
paragraph_operation_button("Align right button", "data/icons/RemixIcon/align-right.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kRight, [&] {
|
||||
a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kRight);
|
||||
});
|
||||
paragraph_operation_button("Align justify button", "data/icons/RemixIcon/align-justify.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kJustify, [&] {
|
||||
a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kJustify);
|
||||
});
|
||||
paragraph_operation_button("Text direction left button", "data/icons/RemixIcon/text-direction-l.svg", currentPStyle.textDirection == skia::textlayout::TextDirection::kLtr, [&] {
|
||||
a.textBox->set_text_direction_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextDirection::kLtr);
|
||||
});
|
||||
paragraph_operation_button("Text direction right button", "data/icons/RemixIcon/text-direction-r.svg", currentPStyle.textDirection == skia::textlayout::TextDirection::kRtl, [&] {
|
||||
a.textBox->set_text_direction_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextDirection::kRtl);
|
||||
});
|
||||
});
|
||||
|
||||
slider_scalar_field<uint32_t>(gui, "Font Size Slider", "Font Size", &newFontSize, 3, 100, TextBoxScalarOptions{
|
||||
.onEdit = [&] {
|
||||
currentMods[TextStyleModifier::ModifierType::SIZE] = std::make_shared<SizeTextStyleModifier>(newFontSize);
|
||||
a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::SIZE]);
|
||||
commit_update_func();
|
||||
},
|
||||
.onSelect = [&] { hold_undo_data("Font Size", a); },
|
||||
.onDeselect = [&] { release_undo_data("Font Size"); }
|
||||
});
|
||||
|
||||
//// Text color
|
||||
//gui.left_to_right_line_layout([&]() {
|
||||
|
|
@ -117,8 +165,6 @@ void TextBoxEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) {
|
|||
// a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::COLOR]);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
//// Highlight color
|
||||
//gui.left_to_right_line_layout([&]() {
|
||||
// if(gui.color_button_big("Highlight Color", &newHighlightColor, &newHighlightColor == t.colorRight)) {
|
||||
|
|
@ -160,10 +206,37 @@ void TextBoxEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) {
|
|||
//return oldInputChangedTextBox;
|
||||
}
|
||||
|
||||
void TextBoxEditTool::input_key_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::KeyCallbackArgs& key) {
|
||||
void TextBoxEditTool::input_paste_callback(const CustomEvents::PasteEventData& paste) {
|
||||
if(textboxID.has_value() && textboxID.value() == drawP.world.main.input.text.current_textbox_editing_id()) {
|
||||
auto& a = static_cast<TextBoxCanvasComponent&>(comp->obj->get_comp());
|
||||
if(userInput->input_paste_callback(paste)) {
|
||||
commit_update_and_layout_func();
|
||||
set_styles_at_selection(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextBoxEditTool::input_mouse_button_on_canvas_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::MouseButtonCallbackArgs& button, bool isDraggingPoint) {
|
||||
void TextBoxEditTool::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {
|
||||
if(textboxID.has_value() && textboxID.value() == drawP.world.main.input.text.current_textbox_editing_id()) {
|
||||
auto& a = static_cast<TextBoxCanvasComponent&>(comp->obj->get_comp());
|
||||
auto changes = userInput->input_key_callback(drawP.world.main.input, key);
|
||||
if(changes.textEdited || changes.cursorChanged) {
|
||||
commit_update_and_layout_func();
|
||||
set_styles_at_selection(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextBoxEditTool::input_text_callback(const InputManager::TextCallbackArgs& text) {
|
||||
if(textboxID.has_value() && textboxID.value() == drawP.world.main.input.text.current_textbox_editing_id()) {
|
||||
auto& a = static_cast<TextBoxCanvasComponent&>(comp->obj->get_comp());
|
||||
userInput->add_text_to_textbox(text.str);
|
||||
commit_update_and_layout_func();
|
||||
set_styles_at_selection(a);
|
||||
}
|
||||
}
|
||||
|
||||
void TextBoxEditTool::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button, bool isDraggingPoint) {
|
||||
if(button.button == InputManager::MouseButton::LEFT && !isDraggingPoint) {
|
||||
auto& a = static_cast<TextBoxCanvasComponent&>(comp->obj->get_comp());
|
||||
|
||||
|
|
@ -175,11 +248,16 @@ void TextBoxEditTool::input_mouse_button_on_canvas_callback(CanvasComponentConta
|
|||
|
||||
bool collidesWithBox = comp->obj->collides_with_cam_coords(drawP.world.drawData.cam.c, mousePointCollection);
|
||||
|
||||
auto oldCursor = *a.cursor;
|
||||
a.textBox->process_mouse_left_button(*a.cursor, a.get_mouse_pos(drawP), (button.down && button.clicks && collidesWithBox) ? button.clicks : 0, button.down, input.key(InputManager::KEY_GENERIC_LSHIFT).held);
|
||||
if(oldCursor != *a.cursor) {
|
||||
set_styles_at_selection(a);
|
||||
commit_update_and_layout_func();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextBoxEditTool::input_mouse_motion_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::MouseMotionCallbackArgs& motion, bool isDraggingPoint) {
|
||||
void TextBoxEditTool::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool isDraggingPoint) {
|
||||
auto& a = static_cast<TextBoxCanvasComponent&>(comp->obj->get_comp());
|
||||
a.init_text_box(drawP);
|
||||
|
||||
|
|
@ -192,11 +270,16 @@ void TextBoxEditTool::input_mouse_motion_callback(CanvasComponentContainer::ObjI
|
|||
|
||||
InputManager& input = drawP.world.main.input;
|
||||
|
||||
auto oldCursor = *a.cursor;
|
||||
a.textBox->process_mouse_left_button(*a.cursor, a.get_mouse_pos(drawP), 0, drawP.controls.leftClickHeld, input.key(InputManager::KEY_GENERIC_LSHIFT).held);
|
||||
if(oldCursor != *a.cursor) {
|
||||
set_styles_at_selection(a);
|
||||
commit_update_and_layout_func();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextBoxEditTool::right_click_popup_gui(CanvasComponentContainer::ObjInfo* comp, Vector2f popupPos) {
|
||||
void TextBoxEditTool::right_click_popup_gui(Vector2f popupPos) {
|
||||
using namespace GUIStuff;
|
||||
using namespace ElementHelpers;
|
||||
|
||||
|
|
@ -241,8 +324,7 @@ void TextBoxEditTool::release_undo_data(const std::string& undoName) {
|
|||
auto it = undoHeldData.find(undoName);
|
||||
if(it != undoHeldData.end()) {
|
||||
std::pair<RichText::TextBox::Cursor, RichText::TextData>& undoData = it->second;
|
||||
InputManager& input = drawP.world.main.input;
|
||||
//input.text.add_textbox_undo(undoData.first, undoData.second);
|
||||
userInput->add_textbox_undo(undoData.first, undoData.second);
|
||||
undoHeldData.erase(it);
|
||||
}
|
||||
}
|
||||
|
|
@ -250,15 +332,12 @@ void TextBoxEditTool::release_undo_data(const std::string& undoName) {
|
|||
void TextBoxEditTool::add_undo_if_selecting_area(TextBoxCanvasComponent& a, const std::function<void()>& func) {
|
||||
if(a.cursor->selectionBeginPos == a.cursor->selectionEndPos)
|
||||
func();
|
||||
else {
|
||||
InputManager& input = drawP.world.main.input;
|
||||
//input.text.do_textbox_operation_with_undo(func);
|
||||
}
|
||||
else
|
||||
userInput->do_textbox_operation_with_undo(func);
|
||||
}
|
||||
|
||||
void TextBoxEditTool::add_undo(const std::function<void()>& func) {
|
||||
InputManager& input = drawP.world.main.input;
|
||||
//input.text.do_textbox_operation_with_undo(func);
|
||||
userInput->do_textbox_operation_with_undo(func);
|
||||
}
|
||||
|
||||
uint8_t TextBoxEditTool::get_new_decoration_value() {
|
||||
|
|
@ -295,11 +374,12 @@ void TextBoxEditTool::set_styles_at_selection(TextBoxCanvasComponent& a) {
|
|||
currentPStyle = a.textBox->get_paragraph_style_data_at(start.fParagraphIndex);
|
||||
}
|
||||
|
||||
void TextBoxEditTool::commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) {
|
||||
void TextBoxEditTool::commit_edit_updates(std::any& prevData) {
|
||||
auto& a = static_cast<TextBoxCanvasComponent&>(comp->obj->get_comp());
|
||||
a.d.editing = false;
|
||||
comp->obj->commit_update(drawP);
|
||||
//drawP.world.main.input.remove_rich_text_box_input(a.textBox);
|
||||
if(textboxID.has_value())
|
||||
drawP.world.main.input.remove_text_box(textboxID.value());
|
||||
}
|
||||
|
||||
TextBoxEditTool::TextBoxEditToolAllData TextBoxEditTool::get_all_data(const TextBoxCanvasComponent& a) {
|
||||
|
|
@ -309,7 +389,7 @@ TextBoxEditTool::TextBoxEditToolAllData TextBoxEditTool::get_all_data(const Text
|
|||
};
|
||||
}
|
||||
|
||||
void TextBoxEditTool::edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) {
|
||||
void TextBoxEditTool::edit_start(EditTool& editTool, std::any& prevData) {
|
||||
auto& a = static_cast<TextBoxCanvasComponent&>(comp->obj->get_comp());
|
||||
auto& cur = a.cursor;
|
||||
auto& textbox = a.textBox;
|
||||
|
|
@ -321,7 +401,6 @@ void TextBoxEditTool::edit_start(EditTool& editTool, CanvasComponentContainer::O
|
|||
textbox->process_mouse_left_button(*cur, textSelectPos, 1, false, false);
|
||||
prevData = get_all_data(a);
|
||||
a.d.editing = true;
|
||||
a.textBox->inputChangedTextBox = true;
|
||||
|
||||
set_styles_at_selection(a);
|
||||
|
||||
|
|
@ -330,15 +409,16 @@ void TextBoxEditTool::edit_start(EditTool& editTool, CanvasComponentContainer::O
|
|||
|
||||
comp->obj->commit_update(drawP);
|
||||
|
||||
//drawP.world.main.input.set_rich_text_box_input_back(a.textBox, a.cursor, true, nullptr, {
|
||||
// .inputType = SDL_TextInputType::SDL_TEXTINPUT_TYPE_TEXT,
|
||||
// .capitalization = SDL_Capitalization::SDL_CAPITALIZE_NONE,
|
||||
// .autocorrect = true,
|
||||
// .multiline = true,
|
||||
// .androidInputType = InputManager::AndroidInputType::ANDROIDTEXT_TYPE_CLASS_TEXT
|
||||
//}, currentModsPtr);
|
||||
userInput = std::make_unique<RichTextUserInput>(textbox, cur, currentModsPtr);
|
||||
textboxID = drawP.world.main.input.set_text_box_back(std::nullopt, {
|
||||
.inputType = SDL_TextInputType::SDL_TEXTINPUT_TYPE_TEXT,
|
||||
.capitalization = SDL_Capitalization::SDL_CAPITALIZE_NONE,
|
||||
.autocorrect = true,
|
||||
.multiline = true,
|
||||
.androidInputType = InputManager::AndroidInputType::ANDROIDTEXT_TYPE_CLASS_TEXT
|
||||
});
|
||||
}
|
||||
|
||||
bool TextBoxEditTool::edit_update(CanvasComponentContainer::ObjInfo* comp) {
|
||||
bool TextBoxEditTool::edit_update() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,23 +3,29 @@
|
|||
#include "DrawingProgramEditToolBase.hpp"
|
||||
#include <Helpers/SCollision.hpp>
|
||||
#include <any>
|
||||
#include "../../../RichTextUserInput.hpp"
|
||||
|
||||
class DrawingProgram;
|
||||
|
||||
class TextBoxEditTool : public DrawingProgramEditToolBase {
|
||||
public:
|
||||
TextBoxEditTool(DrawingProgram& initDrawP);
|
||||
TextBoxEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp);
|
||||
|
||||
virtual void edit_start(EditTool& editTool,CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override;
|
||||
virtual void commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override;
|
||||
virtual bool edit_update(CanvasComponentContainer::ObjInfo* comp) override;
|
||||
virtual void edit_gui(CanvasComponentContainer::ObjInfo* comp) override;
|
||||
virtual void right_click_popup_gui(CanvasComponentContainer::ObjInfo* comp, Vector2f popupPos) override;
|
||||
virtual void edit_start(EditTool& editTool, std::any& prevData) override;
|
||||
virtual void commit_edit_updates(std::any& prevData) override;
|
||||
virtual bool edit_update() override;
|
||||
virtual void edit_gui() override;
|
||||
virtual void right_click_popup_gui(Vector2f popupPos) override;
|
||||
|
||||
virtual void input_key_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::KeyCallbackArgs& key) override;
|
||||
virtual void input_mouse_button_on_canvas_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::MouseButtonCallbackArgs& button, bool isDraggingPoint) override;
|
||||
virtual void input_mouse_motion_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::MouseMotionCallbackArgs& motion, bool isDraggingPoint) 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 InputManager::TextCallbackArgs& text) override;
|
||||
virtual void input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button, bool isDraggingPoint) override;
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool isDraggingPoint) override;
|
||||
private:
|
||||
std::unique_ptr<RichTextUserInput> userInput;
|
||||
std::optional<unsigned> textboxID;
|
||||
|
||||
struct TextBoxEditToolAllData {
|
||||
TextBoxCanvasComponent::Data textboxData;
|
||||
RichText::TextData richText;
|
||||
|
|
@ -44,6 +50,9 @@ class TextBoxEditTool : public DrawingProgramEditToolBase {
|
|||
void hold_undo_data(const std::string& undoName, TextBoxCanvasComponent& a);
|
||||
void release_undo_data(const std::string& undoName);
|
||||
|
||||
void commit_update_func();
|
||||
void commit_update_and_layout_func();
|
||||
|
||||
std::unordered_map<std::string, std::pair<RichText::TextBox::Cursor, RichText::TextData>> undoHeldData;
|
||||
|
||||
std::shared_ptr<RichText::TextStyleModifier::ModifierMap> currentModsPtr = std::make_shared<RichText::TextStyleModifier::ModifierMap>();
|
||||
|
|
|
|||
|
|
@ -119,12 +119,16 @@ void GUIHolder::draw(SkCanvas* canvas, bool skiaAA) {
|
|||
canvas->restore();
|
||||
}
|
||||
|
||||
void GUIHolder::input_paste_callback(const CustomEvents::PasteEventData& paste) {
|
||||
gui.input_paste_callback(paste);
|
||||
}
|
||||
|
||||
void GUIHolder::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {
|
||||
gui.input_text_key_callback(key);
|
||||
}
|
||||
|
||||
void GUIHolder::input_text_callback(const std::string& str) {
|
||||
gui.input_text_callback(str);
|
||||
void GUIHolder::input_text_callback(const InputManager::TextCallbackArgs& text) {
|
||||
gui.input_text_callback(text);
|
||||
}
|
||||
|
||||
void GUIHolder::input_key_callback(const InputManager::KeyCallbackArgs& key) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "CustomEvents.hpp"
|
||||
#include "GUIStuff/GUIManager.hpp"
|
||||
|
||||
class MainProgram;
|
||||
|
|
@ -18,8 +19,9 @@ class GUIHolder {
|
|||
void update();
|
||||
void draw(SkCanvas* canvas, bool skiaAA);
|
||||
|
||||
void input_paste_callback(const CustomEvents::PasteEventData& paste);
|
||||
void input_text_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
void input_text_callback(const std::string& str);
|
||||
void input_text_callback(const InputManager::TextCallbackArgs& text);
|
||||
void input_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
void input_text_key_callback();
|
||||
void input_text_input_callback();
|
||||
|
|
|
|||
|
|
@ -14,7 +14,11 @@ namespace GUIStuff { namespace ElementHelpers {
|
|||
text_label(gui, name);
|
||||
input_scalar(gui, "textbox", val, min, max, options);
|
||||
});
|
||||
gui.element<NumberSlider<T>>("slider", val, min, max, options.onEdit);
|
||||
gui.element<NumberSlider<T>>("slider", val, min, max, NumberSliderData{
|
||||
.onChange = options.onEdit,
|
||||
.onHold = options.onSelect,
|
||||
.onRelease = options.onDeselect
|
||||
});
|
||||
});
|
||||
}
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ template <typename T, typename OptT> TextBoxData<T> textbox_options_to_data(cons
|
|||
toRet.onEnter = options.onEnter;
|
||||
toRet.onEdit = options.onEdit;
|
||||
toRet.immutable = options.immutable;
|
||||
toRet.onSelect = options.onSelect;
|
||||
toRet.onDeselect = options.onDeselect;
|
||||
return toRet;
|
||||
}
|
||||
|
||||
|
|
@ -20,6 +22,8 @@ struct TextBoxOptions {
|
|||
bool immutable = false;
|
||||
std::function<void()> onEnter;
|
||||
std::function<void()> onEdit;
|
||||
std::function<void()> onSelect;
|
||||
std::function<void()> onDeselect;
|
||||
};
|
||||
|
||||
struct TextBoxScalarOptions {
|
||||
|
|
@ -28,6 +32,8 @@ struct TextBoxScalarOptions {
|
|||
bool immutable = false;
|
||||
std::function<void()> onEnter;
|
||||
std::function<void()> onEdit;
|
||||
std::function<void()> onSelect;
|
||||
std::function<void()> onDeselect;
|
||||
};
|
||||
|
||||
struct TextBoxPathOptions {
|
||||
|
|
@ -36,6 +42,8 @@ struct TextBoxPathOptions {
|
|||
bool immutable = false;
|
||||
std::function<void()> onEnter;
|
||||
std::function<void()> onEdit;
|
||||
std::function<void()> onSelect;
|
||||
std::function<void()> onDeselect;
|
||||
};
|
||||
|
||||
struct TextBoxHexColorOptions {
|
||||
|
|
@ -44,6 +52,8 @@ struct TextBoxHexColorOptions {
|
|||
bool immutable = false;
|
||||
std::function<void()> onEnter;
|
||||
std::function<void()> onEdit;
|
||||
std::function<void()> onSelect;
|
||||
std::function<void()> onDeselect;
|
||||
};
|
||||
|
||||
void input_color_component_255(GUIManager& gui, const char* id, float* val, const TextBoxOptions& options = {});
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -344,6 +344,13 @@ bool GUIManager::cursor_obstructed() const {
|
|||
return cursorObstructed;
|
||||
}
|
||||
|
||||
void GUIManager::input_paste_callback(const CustomEvents::PasteEventData& paste) {
|
||||
for(ElementContainer* e : orderedElements)
|
||||
e->elem->input_paste_callback(paste);
|
||||
run_post_callback_func();
|
||||
layout_if_necessary();
|
||||
}
|
||||
|
||||
void GUIManager::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {
|
||||
for(ElementContainer* e : orderedElements)
|
||||
e->elem->input_text_key_callback(key);
|
||||
|
|
@ -351,9 +358,9 @@ void GUIManager::input_text_key_callback(const InputManager::KeyCallbackArgs& ke
|
|||
layout_if_necessary();
|
||||
}
|
||||
|
||||
void GUIManager::input_text_callback(const std::string& str) {
|
||||
void GUIManager::input_text_callback(const InputManager::TextCallbackArgs& text) {
|
||||
for(ElementContainer* e : orderedElements)
|
||||
e->elem->input_text_callback(str);
|
||||
e->elem->input_text_callback(text);
|
||||
run_post_callback_func();
|
||||
layout_if_necessary();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,8 +85,9 @@ class GUIManager {
|
|||
|
||||
DefaultStringArena strArena;
|
||||
|
||||
void input_paste_callback(const CustomEvents::PasteEventData& paste);
|
||||
void input_text_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
void input_text_callback(const std::string& str);
|
||||
void input_text_callback(const InputManager::TextCallbackArgs& text);
|
||||
void input_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
void input_mouse_button_callback(InputManager::MouseButtonCallbackArgs button);
|
||||
void input_mouse_motion_callback(InputManager::MouseMotionCallbackArgs motion);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "InputManager.hpp"
|
||||
#include "CustomEvents.hpp"
|
||||
|
||||
#include <SDL3/SDL_clipboard.h>
|
||||
#include <SDL3/SDL_keyboard.h>
|
||||
|
|
@ -11,6 +12,7 @@
|
|||
|
||||
#include <Helpers/Logger.hpp>
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <include/core/SkStream.h>
|
||||
#include <include/encode/SkPngEncoder.h>
|
||||
|
|
@ -126,6 +128,12 @@ bool InputManager::Text::is_accepting_input() {
|
|||
return !textBoxes.empty();
|
||||
}
|
||||
|
||||
std::optional<unsigned> InputManager::Text::current_textbox_editing_id() {
|
||||
if(textBoxes.empty())
|
||||
return std::nullopt;
|
||||
return textBoxes.front().id;
|
||||
}
|
||||
|
||||
void InputManager::Text::update_accepting_input(SDL_Window* window) {
|
||||
if(!textBoxes.empty()) {
|
||||
auto& textbox = textBoxes.front();
|
||||
|
|
@ -354,8 +362,13 @@ uint32_t InputManager::make_generic_key_mod(SDL_Keymod m) {
|
|||
return toRet;
|
||||
}
|
||||
|
||||
void InputManager::backend_paste_event() {
|
||||
main.input_paste_callback(CustomEvents::get_paste_event_data());
|
||||
CustomEvents::pop_paste_event_data();
|
||||
}
|
||||
|
||||
void InputManager::backend_input_text_event(const std::string& str) {
|
||||
main.input_text_callback(str);
|
||||
main.input_text_callback(TextCallbackArgs{ .str = str });
|
||||
}
|
||||
|
||||
void InputManager::backend_drop_file_event(const SDL_DropEvent& e) {
|
||||
|
|
@ -901,27 +914,35 @@ void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) {
|
|||
set_key_down(e, f->second);
|
||||
}
|
||||
|
||||
void InputManager::call_text_paste(const std::function<void(const TextPasteCallbackArgs&)>& pasteCallbackFunc) {
|
||||
void InputManager::call_paste(CustomEvents::PasteEventDataType type, const std::optional<Vector2f>& pastePosition) {
|
||||
// Workaround for not being able to copy richtext to system clipboard, this should at least work within the application itself
|
||||
pasteCallback = pasteCallbackFunc;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_browser_clipboard::paste_async([](std::string&& pasteData, void* callbackData){
|
||||
InputManager* inMan = (InputManager*)callbackData;
|
||||
std::string pData = pasteData;
|
||||
inMan->process_text_paste(pData);
|
||||
}, this);
|
||||
if(type == PasteDataType::TEXT) {
|
||||
emscripten_browser_clipboard::paste_async([](std::string&& pasteData, void* callbackData){
|
||||
InputManager* inMan = (InputManager*)callbackData;
|
||||
std::string pData = pasteData;
|
||||
inMan->process_text_paste(pData);
|
||||
}, this);
|
||||
}
|
||||
else {
|
||||
}
|
||||
#else
|
||||
process_text_paste(get_clipboard_str_SDL());
|
||||
switch(type) {
|
||||
case CustomEvents::PasteEventDataType::TEXT:
|
||||
process_text_paste(get_clipboard_str_SDL());
|
||||
break;
|
||||
case CustomEvents::PasteEventDataType::IMAGE:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void InputManager::process_text_paste(const std::string& pasteStr) {
|
||||
if(lastCopiedRichText.has_value() && lastCopiedRichText.value().get_plain_text() == remove_carriage_returns_from_str(pasteStr)) {
|
||||
pasteCallback({
|
||||
.text = pasteStr,
|
||||
.richText = lastCopiedRichText
|
||||
});
|
||||
}
|
||||
CustomEvents::emit_paste_event({
|
||||
.type = CustomEvents::PasteEventDataType::TEXT,
|
||||
.data = pasteStr,
|
||||
.richText = lastCopiedRichText.has_value() && lastCopiedRichText.value().get_plain_text() == remove_carriage_returns_from_str(pasteStr) ? lastCopiedRichText : std::nullopt
|
||||
});
|
||||
}
|
||||
|
||||
bool InputManager::ctrl_or_meta_held() {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include <Helpers/SCollision.hpp>
|
||||
|
||||
#include "CustomEvents.hpp"
|
||||
|
||||
using namespace Eigen;
|
||||
class MainProgram;
|
||||
|
||||
|
|
@ -155,6 +157,7 @@ struct InputManager {
|
|||
|
||||
struct Text {
|
||||
bool is_accepting_input();
|
||||
std::optional<unsigned> current_textbox_editing_id();
|
||||
|
||||
private:
|
||||
struct TextBoxInfo {
|
||||
|
|
@ -253,6 +256,7 @@ struct InputManager {
|
|||
void touch_finger_do_mouse_up(const SDL_TouchFingerEvent& f);
|
||||
void touch_finger_do_mouse_motion(const SDL_TouchFingerEvent& f);
|
||||
|
||||
void backend_paste_event();
|
||||
void backend_input_text_event(const std::string& str);
|
||||
void backend_drop_file_event(const SDL_DropEvent& e);
|
||||
void backend_drop_text_event(const SDL_DropEvent& e);
|
||||
|
|
@ -277,13 +281,9 @@ struct InputManager {
|
|||
std::string get_clipboard_str_SDL();
|
||||
void get_clipboard_image_data_SDL(const std::function<void(std::string_view data)>& callback);
|
||||
|
||||
struct TextPasteCallbackArgs {
|
||||
std::string text;
|
||||
std::optional<RichText::TextData> richText;
|
||||
};
|
||||
void call_text_paste(const std::function<void(const TextPasteCallbackArgs&)>& pasteCallbackFunc);
|
||||
void call_paste(CustomEvents::PasteEventDataType type, const std::optional<Vector2f>& pastePosition = std::nullopt);
|
||||
void process_text_paste(const std::string& pasteStr);
|
||||
std::function<void(const TextPasteCallbackArgs&)> pasteCallback;
|
||||
|
||||
std::optional<RichText::TextData> lastCopiedRichText;
|
||||
|
||||
std::string key_assignment_to_str(const Vector2ui32& k) const;
|
||||
|
|
@ -291,6 +291,10 @@ struct InputManager {
|
|||
|
||||
const KeyData& key(KeyCode kCode);
|
||||
|
||||
struct TextCallbackArgs {
|
||||
std::string str;
|
||||
};
|
||||
|
||||
struct KeyCallbackArgs {
|
||||
KeyCode key;
|
||||
bool down;
|
||||
|
|
|
|||
|
|
@ -317,6 +317,12 @@ sk_sp<SkSurface> MainProgram::create_native_surface(Vector2i resolution, bool is
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void MainProgram::input_paste_callback(const CustomEvents::PasteEventData& paste) {
|
||||
g.input_paste_callback(paste);
|
||||
if(world)
|
||||
world->input_paste_callback(paste);
|
||||
}
|
||||
|
||||
bool MainProgram::input_keybind_callback(const Vector2ui32& newKey) {
|
||||
if(keybindWaiting.has_value()) {
|
||||
unsigned v = keybindWaiting.value();
|
||||
|
|
@ -374,10 +380,14 @@ void MainProgram::input_key_callback(const InputManager::KeyCallbackArgs& key) {
|
|||
|
||||
void MainProgram::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {
|
||||
g.input_text_key_callback(key);
|
||||
if(world)
|
||||
world->input_text_key_callback(key);
|
||||
}
|
||||
|
||||
void MainProgram::input_text_callback(const std::string& str) {
|
||||
g.input_text_callback(str);
|
||||
void MainProgram::input_text_callback(const InputManager::TextCallbackArgs& text) {
|
||||
g.input_text_callback(text);
|
||||
if(world)
|
||||
world->input_text_callback(text);
|
||||
}
|
||||
|
||||
void MainProgram::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include "CustomEvents.hpp"
|
||||
#include "DrawData.hpp"
|
||||
#include <SDL3/SDL_render.h>
|
||||
#include <chrono>
|
||||
|
|
@ -121,13 +122,13 @@ class MainProgram {
|
|||
GlobalConfig conf;
|
||||
|
||||
std::optional<unsigned> keybindWaiting;
|
||||
void input_paste_callback(const CustomEvents::PasteEventData& paste);
|
||||
bool input_keybind_callback(const Vector2ui32& newKey);
|
||||
|
||||
void input_drop_file_callback(const InputManager::DropCallbackArgs& drop);
|
||||
void input_drop_text_callback(const InputManager::DropCallbackArgs& drop);
|
||||
void input_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
void input_text_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
void input_text_callback(const std::string& str);
|
||||
void input_text_callback(const InputManager::TextCallbackArgs& text);
|
||||
void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button);
|
||||
void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion);
|
||||
void input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel);
|
||||
|
|
|
|||
|
|
@ -169,9 +169,6 @@ void TextBox::process_key_input(Cursor& cur, InputKey in, bool ctrl, bool shift,
|
|||
|
||||
if(in != InputKey::UP && in != InputKey::DOWN)
|
||||
cur.previousX = std::nullopt;
|
||||
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
}
|
||||
|
||||
void TextBox::process_mouse_left_button(Cursor& cur, const Vector2f& pos, int clickCount, bool held, bool shift) {
|
||||
|
|
@ -224,9 +221,6 @@ void TextBox::process_mouse_left_button(Cursor& cur, const Vector2f& pos, int cl
|
|||
}
|
||||
|
||||
cur.previousX = std::nullopt;
|
||||
|
||||
if((oldCursor != cur) && onChange) onChange();
|
||||
inputChangedTextBox |= (oldCursor != cur);
|
||||
}
|
||||
else
|
||||
cur.selectionEndPosBeforeHeld = std::nullopt;
|
||||
|
|
@ -241,8 +235,6 @@ std::pair<std::string, TextData> TextBox::process_cut(Cursor& cur) {
|
|||
if(cur.selectionBeginPos != cur.selectionEndPos) {
|
||||
cur.selectionEndPos = cur.selectionBeginPos = cur.pos = remove(cur.selectionBeginPos, cur.selectionEndPos);
|
||||
cur.previousX = std::nullopt;
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
}
|
||||
return toRet;
|
||||
}
|
||||
|
|
@ -253,8 +245,6 @@ void TextBox::process_text_input(Cursor& cur, const std::string& in, const std::
|
|||
cur.selectionEndPos = cur.selectionBeginPos = cur.pos = remove(cur.selectionBeginPos, cur.selectionEndPos);
|
||||
cur.selectionEndPos = cur.selectionBeginPos = cur.pos = insert(cur.pos, in, inputModMap);
|
||||
cur.previousX = std::nullopt;
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -264,8 +254,6 @@ void TextBox::process_rich_text_input(Cursor& cur, const TextData& richText) {
|
|||
cur.selectionEndPos = cur.selectionBeginPos = cur.pos = remove(cur.selectionBeginPos, cur.selectionEndPos);
|
||||
cur.selectionEndPos = cur.selectionBeginPos = cur.pos = insert_rich_text(cur.pos, richText);
|
||||
cur.previousX = std::nullopt;
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -461,8 +449,6 @@ TextPosition TextBox::insert_rich_text(TextPosition p, const TextData& richText)
|
|||
paragraphs[pIndex].pStyleData = richText.paragraphs[pIndex - p.fParagraphIndex].pStyleData;
|
||||
}
|
||||
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
needsRebuild = true;
|
||||
|
||||
return toRet;
|
||||
|
|
@ -490,8 +476,6 @@ void TextBox::set_rich_text_data(const TextData& richText) {
|
|||
if(richText.paragraphs.empty())
|
||||
paragraphs.emplace_back();
|
||||
tStyleMods = richText.tStyleMods;
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
needsRebuild = true;
|
||||
}
|
||||
|
||||
|
|
@ -526,8 +510,6 @@ std::string TextBox::get_text_between(TextPosition p1, TextPosition p2) {
|
|||
void TextBox::set_initial_text_style(const skia::textlayout::TextStyle& tStyle) {
|
||||
if(!tStyle.equals(initialTStyle)) {
|
||||
initialTStyle = tStyle;
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
needsRebuild = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -598,8 +580,6 @@ void TextBox::set_text_style_modifier_between(TextPosition p1, TextPosition p2,
|
|||
insert_style_at_pos(start, modifier);
|
||||
insert_style_at_pos(end, lastModOfThisTypeBeforeEnd); // Even if the end is the literal end of the text (which wont be seen), the end style must still be placed at the end so that it can merge with and delete the start style when the styled text is erased
|
||||
remove_duplicate_text_style_mods();
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
needsRebuild = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -614,8 +594,6 @@ void TextBox::set_text_alignment_between(size_t paragraphIndex1, size_t paragrap
|
|||
}
|
||||
}
|
||||
if(anythingChanged) {
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
needsRebuild = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -630,8 +608,6 @@ void TextBox::set_text_direction_between(size_t paragraphIndex1, size_t paragrap
|
|||
}
|
||||
}
|
||||
if(anythingChanged) {
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
needsRebuild = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -867,8 +843,6 @@ int TextBox::get_line_number_at_from_byte_text_pos(TextPosition pos) {
|
|||
void TextBox::set_width(float newWidth) {
|
||||
if(width != newWidth) {
|
||||
width = std::max(newWidth, 4.0f);
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
needsRebuild = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -885,8 +859,6 @@ void TextBox::set_allow_newlines(bool allow) {
|
|||
void TextBox::set_font_data(const std::shared_ptr<FontData>& fD) {
|
||||
if(fontData != fD) {
|
||||
fontData = fD;
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
needsRebuild = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1055,8 +1027,6 @@ TextPosition TextBox::insert(TextPosition pos, std::string_view textToInsert, co
|
|||
for(const auto& [modType, modifier] : inputModMap.value())
|
||||
set_text_style_modifier_between(oldPos, pos, modifier);
|
||||
}
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
needsRebuild = true;
|
||||
}
|
||||
|
||||
|
|
@ -1105,8 +1075,6 @@ TextPosition TextBox::remove(TextPosition p1, TextPosition p2) {
|
|||
}
|
||||
|
||||
remove_duplicate_text_style_mods();
|
||||
if(onChange) onChange();
|
||||
inputChangedTextBox = true;
|
||||
needsRebuild = true;
|
||||
|
||||
return start;
|
||||
|
|
|
|||
|
|
@ -66,9 +66,6 @@ class TextBox {
|
|||
public:
|
||||
TextBox();
|
||||
|
||||
bool inputChangedTextBox = false;
|
||||
std::function<void()> onChange;
|
||||
|
||||
enum class Movement {
|
||||
NOWHERE,
|
||||
LEFT,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "RichTextUserInput.hpp"
|
||||
#include "CustomEvents.hpp"
|
||||
|
||||
template <typename T> std::optional<T> shared_ptr_to_opt(const std::shared_ptr<T> o) {
|
||||
if(o)
|
||||
|
|
@ -7,18 +8,29 @@ template <typename T> std::optional<T> shared_ptr_to_opt(const std::shared_ptr<T
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
RichTextUserInput::RichTextUserInput(const std::shared_ptr<RichText::TextBox>& initTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& initCursor, const std::shared_ptr<RichText::TextStyleModifier::ModifierMap>& initModMap, const std::function<void()>& initOnTextEdit):
|
||||
RichTextUserInput::RichTextUserInput(const std::shared_ptr<RichText::TextBox>& initTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& initCursor, const std::shared_ptr<RichText::TextStyleModifier::ModifierMap>& initModMap):
|
||||
textBox(initTextBox),
|
||||
cursor(initCursor),
|
||||
modMap(initModMap),
|
||||
onTextEdit(initOnTextEdit)
|
||||
modMap(initModMap)
|
||||
{}
|
||||
|
||||
bool RichTextUserInput::input_paste_callback(const CustomEvents::PasteEventData& paste) {
|
||||
if(paste.type == CustomEvents::PasteEventDataType::TEXT) {
|
||||
do_textbox_operation_with_undo([&]() {
|
||||
if(paste.richText.has_value())
|
||||
textBox->process_rich_text_input(*cursor, paste.richText.value());
|
||||
else
|
||||
textBox->process_text_input(*cursor, paste.data, shared_ptr_to_opt(modMap));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RichTextUserInput::add_text_to_textbox(const std::string& inputText) {
|
||||
do_textbox_operation_with_undo([&]() {
|
||||
textBox->process_text_input(*cursor, inputText, shared_ptr_to_opt(modMap));
|
||||
});
|
||||
onTextEdit();
|
||||
}
|
||||
|
||||
void RichTextUserInput::add_textbox_undo(const RichText::TextBox::Cursor& prevCursor, const RichText::TextData& prevRichText) {
|
||||
|
|
@ -26,14 +38,12 @@ void RichTextUserInput::add_textbox_undo(const RichText::TextBox::Cursor& prevCu
|
|||
textBox->set_rich_text_data_for_undo_redo(prevRichText);
|
||||
cursor->selectionBeginPos = cursor->selectionEndPos = cursor->pos = std::max(prevCursor.selectionEndPos, prevCursor.selectionBeginPos);
|
||||
cursor->previousX = std::nullopt;
|
||||
onTextEdit();
|
||||
return true;
|
||||
},
|
||||
[&, currentCursor = *cursor, currentRichText = textBox->get_rich_text_data()]() {
|
||||
textBox->set_rich_text_data_for_undo_redo(currentRichText);
|
||||
cursor->selectionBeginPos = cursor->selectionEndPos = cursor->pos = std::max(currentCursor.selectionEndPos, currentCursor.selectionBeginPos);
|
||||
cursor->previousX = std::nullopt;
|
||||
onTextEdit();
|
||||
return true;
|
||||
}});
|
||||
}
|
||||
|
|
@ -43,13 +53,16 @@ void RichTextUserInput::do_textbox_operation_with_undo(const std::function<void(
|
|||
auto prevCursor = *cursor;
|
||||
func();
|
||||
add_textbox_undo(prevCursor, prevRichText);
|
||||
onTextEdit();
|
||||
}
|
||||
|
||||
void RichTextUserInput::input_key_callback(InputManager& input, const InputManager::KeyCallbackArgs& key) {
|
||||
RichTextUserInput::Changes RichTextUserInput::input_key_callback(InputManager& input, const InputManager::KeyCallbackArgs& key) {
|
||||
std::optional<RichText::TextStyleModifier::ModifierMap> modMapOpt = shared_ptr_to_opt(modMap);
|
||||
|
||||
Changes toRet;
|
||||
|
||||
if(key.down) {
|
||||
auto oldCursor = *cursor;
|
||||
|
||||
switch(key.key) {
|
||||
case InputManager::KEY_GENERIC_UP:
|
||||
textBox->process_key_input(*cursor, RichText::TextBox::InputKey::UP, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt);
|
||||
|
|
@ -67,11 +80,13 @@ void RichTextUserInput::input_key_callback(InputManager& input, const InputManag
|
|||
do_textbox_operation_with_undo([&] {
|
||||
textBox->process_key_input(*cursor, RichText::TextBox::InputKey::BACKSPACE, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt);
|
||||
});
|
||||
toRet.textEdited = true;
|
||||
break;
|
||||
case InputManager::KEY_TEXT_DELETE:
|
||||
do_textbox_operation_with_undo([&] {
|
||||
textBox->process_key_input(*cursor, RichText::TextBox::InputKey::DEL, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt);
|
||||
});
|
||||
toRet.textEdited = true;
|
||||
break;
|
||||
case InputManager::KEY_TEXT_HOME:
|
||||
textBox->process_key_input(*cursor, RichText::TextBox::InputKey::HOME, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt);
|
||||
|
|
@ -86,38 +101,38 @@ void RichTextUserInput::input_key_callback(InputManager& input, const InputManag
|
|||
do_textbox_operation_with_undo([&] {
|
||||
input.set_clipboard_plain_and_richtext_pair(textBox->process_cut(*cursor));
|
||||
});
|
||||
toRet.textEdited = true;
|
||||
break;
|
||||
case InputManager::KEY_TEXT_PASTE:
|
||||
do_textbox_operation_with_undo([&]() {
|
||||
input.call_text_paste([textBox = textBox, cursor = cursor, modMapOpt] (const InputManager::TextPasteCallbackArgs& pasteArgs) {
|
||||
if(pasteArgs.richText.has_value())
|
||||
textBox->process_rich_text_input(*cursor, pasteArgs.richText.value());
|
||||
else
|
||||
textBox->process_text_input(*cursor, pasteArgs.text, modMapOpt);
|
||||
});
|
||||
});
|
||||
input.call_paste(CustomEvents::PasteEventDataType::TEXT);
|
||||
break;
|
||||
case InputManager::KEY_TEXT_SELECTALL:
|
||||
textBox->process_key_input(*cursor, RichText::TextBox::InputKey::SELECT_ALL, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt);
|
||||
break;
|
||||
case InputManager::KEY_TEXT_UNDO:
|
||||
textboxUndo.undo();
|
||||
toRet.textEdited = true;
|
||||
break;
|
||||
case InputManager::KEY_TEXT_REDO:
|
||||
textboxUndo.redo();
|
||||
toRet.textEdited = true;
|
||||
break;
|
||||
case InputManager::KEY_GENERIC_ENTER:
|
||||
do_textbox_operation_with_undo([&] {
|
||||
textBox->process_key_input(*cursor, RichText::TextBox::InputKey::ENTER, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt);
|
||||
});
|
||||
toRet.textEdited = true;
|
||||
break;
|
||||
case InputManager::KEY_TEXT_TAB:
|
||||
do_textbox_operation_with_undo([&] {
|
||||
textBox->process_key_input(*cursor, RichText::TextBox::InputKey::TAB, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt);
|
||||
});
|
||||
toRet.textEdited = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return toRet;
|
||||
}
|
||||
toRet.cursorChanged = oldCursor != *cursor;
|
||||
}
|
||||
return toRet;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,24 @@
|
|||
#pragma once
|
||||
#include "CustomEvents.hpp"
|
||||
#include "RichText/TextBox.hpp"
|
||||
#include "UndoManager.hpp"
|
||||
#include "InputManager.hpp"
|
||||
|
||||
class RichTextUserInput {
|
||||
public:
|
||||
RichTextUserInput(const std::shared_ptr<RichText::TextBox>& initTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& initCursor, const std::shared_ptr<RichText::TextStyleModifier::ModifierMap>& initModMap, const std::function<void()>& initOnTextEdit);
|
||||
void input_key_callback(InputManager& input, const InputManager::KeyCallbackArgs& key);
|
||||
RichTextUserInput(const std::shared_ptr<RichText::TextBox>& initTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& initCursor, const std::shared_ptr<RichText::TextStyleModifier::ModifierMap>& initModMap);
|
||||
struct Changes {
|
||||
bool textEdited = false;
|
||||
bool cursorChanged = false;
|
||||
};
|
||||
Changes input_key_callback(InputManager& input, const InputManager::KeyCallbackArgs& key);
|
||||
bool input_paste_callback(const CustomEvents::PasteEventData& paste);
|
||||
void add_text_to_textbox(const std::string& inputText);
|
||||
private:
|
||||
void do_textbox_operation_with_undo(const std::function<void()>& func);
|
||||
void add_textbox_undo(const RichText::TextBox::Cursor& prevCursor, const RichText::TextData& prevRichText);
|
||||
private:
|
||||
std::shared_ptr<RichText::TextBox> textBox;
|
||||
std::shared_ptr<RichText::TextBox::Cursor> cursor;
|
||||
std::shared_ptr<RichText::TextStyleModifier::ModifierMap> modMap;
|
||||
UndoManager textboxUndo;
|
||||
std::function<void()> onTextEdit;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -244,6 +244,21 @@ void World::on_tab_out() {
|
|||
rMan.clear_display_cache();
|
||||
}
|
||||
|
||||
void World::input_paste_callback(const CustomEvents::PasteEventData& paste) {
|
||||
if(!clientStillConnecting)
|
||||
drawProg.input_paste_callback(paste);
|
||||
}
|
||||
|
||||
void World::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {
|
||||
if(!clientStillConnecting)
|
||||
drawProg.input_text_key_callback(key);
|
||||
}
|
||||
|
||||
void World::input_text_callback(const InputManager::TextCallbackArgs& text) {
|
||||
if(!clientStillConnecting)
|
||||
drawProg.input_text_callback(text);
|
||||
}
|
||||
|
||||
void World::input_drop_file_callback(const InputManager::DropCallbackArgs& drop) {
|
||||
if(!clientStillConnecting)
|
||||
drawProg.input_drop_file_callback(drop);
|
||||
|
|
|
|||
|
|
@ -96,8 +96,11 @@ class World {
|
|||
std::shared_ptr<NetServer> netServer;
|
||||
std::shared_ptr<NetClient> netClient;
|
||||
|
||||
void input_paste_callback(const CustomEvents::PasteEventData& paste);
|
||||
void input_drop_file_callback(const InputManager::DropCallbackArgs& drop);
|
||||
void input_drop_text_callback(const InputManager::DropCallbackArgs& drop);
|
||||
void input_text_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
void input_text_callback(const InputManager::TextCallbackArgs& text);
|
||||
void input_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button);
|
||||
void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include "CustomEvents.hpp"
|
||||
#include "Helpers/SCollision.hpp"
|
||||
#include "Helpers/StringHelpers.hpp"
|
||||
#include "Helpers/FileDownloader.hpp"
|
||||
|
|
@ -94,6 +95,7 @@
|
|||
|
||||
#include <Helpers/Logger.hpp>
|
||||
#include "SwitchCWD.hpp"
|
||||
#include "CustomEvents.hpp"
|
||||
|
||||
// Use dedicated graphics card on Windows
|
||||
#ifdef _WIN32
|
||||
|
|
@ -832,8 +834,11 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) {
|
|||
break;
|
||||
case SDL_EVENT_SCREEN_KEYBOARD_HIDDEN:
|
||||
break;
|
||||
default:
|
||||
default: {
|
||||
if(event->type == CustomEvents::PASTE_EVENT)
|
||||
mS.m->input.backend_paste_event();
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef NDEBUG
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue