Add screens

This commit is contained in:
Yousef Khadadeh 2026-04-12 12:36:00 +03:00
parent 4e352ec832
commit 919e41db22
60 changed files with 538 additions and 385 deletions

View file

@ -341,13 +341,12 @@ void DrawingProgram::send_transforms_for(const std::vector<CanvasComponentContai
}
}
void DrawingProgram::toolbar_gui() {
void DrawingProgram::toolbar_gui(Toolbar& t) {
using namespace GUIStuff;
using namespace ElementHelpers;
GUIManager& gui = world.main.g.gui;
auto& io = gui.io;
auto& t = world.main.toolbar;
gui.new_id("Drawing Program Toolbar GUI", [&] {
gui.element<LayoutElement>("Drawing Program Toolbar GUI", [&] (LayoutElement*, const Clay_ElementId& lId) {
@ -399,9 +398,9 @@ void DrawingProgram::toolbar_gui() {
});
}
void DrawingProgram::right_click_popup_gui() {
void DrawingProgram::right_click_popup_gui(Toolbar& t) {
if(rightClickPopupLocation.has_value())
drawTool->right_click_popup_gui(rightClickPopupLocation.value());
drawTool->right_click_popup_gui(t, rightClickPopupLocation.value());
}
void DrawingProgram::set_right_click_popup_location(const Vector2f& newLoc) {
@ -479,15 +478,7 @@ void DrawingProgram::selection_action_menu(Vector2f popupPos) {
});
}
void DrawingProgram::right_click_popup_gui(Vector2f popupPos) {
GUIStuff::GUIManager& gui = world.main.g.gui;
gui.new_id("Drawing Program right click GUI", [&] {
drawTool->right_click_popup_gui(popupPos);
});
}
void DrawingProgram::tool_options_gui() {
void DrawingProgram::tool_options_gui(Toolbar& t) {
using namespace GUIStuff;
GUIStuff::GUIManager& gui = world.main.g.gui;
@ -506,7 +497,7 @@ void DrawingProgram::tool_options_gui() {
.backgroundColor = convert_vec4<Clay_Color>(io.theme->backColor1),
.cornerRadius = CLAY_CORNER_RADIUS(io.theme->windowCorners1)
}) {
drawTool->gui_toolbox();
drawTool->gui_toolbox(t);
}
});
}

View file

@ -25,10 +25,9 @@ class DrawingProgram {
public:
DrawingProgram(World& initWorld);
void server_init_no_file();
void toolbar_gui();
void right_click_popup_gui();
void tool_options_gui();
void right_click_popup_gui(Vector2f popupPos);
void toolbar_gui(Toolbar& t);
void tool_options_gui(Toolbar& t);
void right_click_popup_gui(Toolbar& t);
void update();
void scale_up(const WorldScalar& scaleUpAmount);
void draw(SkCanvas* canvas, const DrawData& drawData);

View file

@ -30,12 +30,11 @@ DrawingProgramSelection::DrawingProgramSelection(DrawingProgram& initDrawP):
drawP(initDrawP)
{}
void DrawingProgramSelection::selection_gui() {
void DrawingProgramSelection::selection_gui(Toolbar& t) {
using namespace GUIStuff;
using namespace ElementHelpers;
auto& gui = drawP.world.main.g.gui;
auto& t = drawP.world.main.toolbar;
gui.new_id("general selection gui", [&] {
text_label(gui, "Select from:");
@ -129,10 +128,6 @@ void DrawingProgramSelection::check_add_stroke_color_change_undo() {
drawP.world.undo.push(std::make_unique<EditCanvasComponentsStrokeColorWorldUndoAction>(std::move(undoIDs), std::move(oldColors)));
strokeColorChangeData.oldColorData.clear();
auto& t = drawP.world.main.toolbar;
if(&strokeColorChangeData.newColor == t.colorRight)
t.colorRight = nullptr; // Just making sure that the color selector doesn't leak
}
}

View file

@ -9,7 +9,7 @@ class DrawingProgram;
class DrawingProgramSelection {
public:
DrawingProgramSelection(DrawingProgram& initDrawP);
void selection_gui();
void selection_gui(Toolbar& t);
void add_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection<float>& cC, DrawingProgramLayerManager::LayerSelector layerSelector, bool frontObjectOnly);
void remove_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection<float>& cC, DrawingProgramLayerManager::LayerSelector layerSelector, bool frontObjectOnly);
void erase_component(CanvasComponentContainer::ObjInfo* objToCheck);

View file

@ -170,7 +170,7 @@ void BrushTool::commit_stroke() {
}
}
void BrushTool::gui_toolbox() {
void BrushTool::gui_toolbox(Toolbar& t) {
using namespace GUIStuff;
using namespace ElementHelpers;
@ -183,8 +183,7 @@ void BrushTool::gui_toolbox() {
});
}
void BrushTool::right_click_popup_gui(Vector2f popupPos) {
Toolbar& t = drawP.world.main.toolbar;
void BrushTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
t.paint_popup(popupPos);
}

View file

@ -16,9 +16,9 @@ class BrushTool : public DrawingProgramToolBase {
public:
BrushTool(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void tool_update() override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void switch_tool(DrawingProgramToolType newTool) override;
virtual void draw(SkCanvas* canvas, const DrawData& drawData) override;

View file

@ -29,9 +29,9 @@ class DrawingProgramToolBase {
public:
DrawingProgramToolBase(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() = 0;
virtual void gui_toolbox() = 0;
virtual void gui_toolbox(Toolbar& t) = 0;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) = 0;
virtual void right_click_popup_gui(Vector2f popupPos) = 0;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) = 0;
virtual void tool_update() = 0;
virtual void draw(SkCanvas* canvas, const DrawData& drawData) = 0;
virtual void switch_tool(DrawingProgramToolType newTool) = 0;

View file

@ -24,14 +24,14 @@ DrawingProgramToolType EditTool::get_type() {
return DrawingProgramToolType::EDIT;
}
void EditTool::gui_toolbox() {
void EditTool::gui_toolbox(Toolbar& t) {
using namespace GUIStuff;
using namespace ElementHelpers;
auto& gui = drawP.world.main.g.gui;
if(objInfoBeingEdited)
compEditTool->edit_gui();
compEditTool->edit_gui(t);
else {
gui.new_id("edit tool", [&] {
text_label_centered(gui, "Edit");
@ -165,9 +165,9 @@ void EditTool::input_mouse_motion_callback(const InputManager::MouseMotionCallba
drawP.selection.input_mouse_motion_callback_modify_selection(motion);
}
void EditTool::right_click_popup_gui(Vector2f popupPos) {
void EditTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
if(objInfoBeingEdited)
return compEditTool->right_click_popup_gui(popupPos);
return compEditTool->right_click_popup_gui(t, popupPos);
else
return drawP.selection_action_menu(popupPos);
}

View file

@ -19,8 +19,8 @@ class EditTool : public DrawingProgramToolBase {
EditTool(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void tool_update() override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void switch_tool(DrawingProgramToolType newTool) override;

View file

@ -12,13 +12,12 @@ BrushEditTool::BrushEditTool(DrawingProgram& initDrawP, CanvasComponentContainer
DrawingProgramEditToolBase(initDrawP, initComp)
{}
void BrushEditTool::edit_gui() {
void BrushEditTool::edit_gui(Toolbar& t) {
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->obj->commit_update(drawP); };
gui.new_id("edit tool brush", [&] {

View file

@ -11,7 +11,7 @@ class BrushEditTool : public DrawingProgramEditToolBase {
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 edit_gui(Toolbar& t) override;
private:
Vector4f oldColor;
};

View file

@ -6,8 +6,7 @@ DrawingProgramEditToolBase::DrawingProgramEditToolBase(DrawingProgram& initDrawP
comp(initComp)
{}
void DrawingProgramEditToolBase::right_click_popup_gui(Vector2f popupPos) {
Toolbar& t = drawP.world.main.toolbar;
void DrawingProgramEditToolBase::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
t.paint_popup(popupPos);
}

View file

@ -12,8 +12,8 @@ class DrawingProgramEditToolBase {
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 edit_gui(Toolbar& t) = 0;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos);
virtual void input_paste_callback(const CustomEvents::PasteEvent& paste);
virtual void input_text_key_callback(const InputManager::KeyCallbackArgs& key);
virtual void input_text_callback(const InputManager::TextCallbackArgs& text);

View file

@ -15,13 +15,12 @@ EllipseDrawEditTool::EllipseDrawEditTool(DrawingProgram& initDrawP, CanvasCompon
DrawingProgramEditToolBase(initDrawP, initComp)
{}
void EllipseDrawEditTool::edit_gui() {
void EllipseDrawEditTool::edit_gui(Toolbar& t) {
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->obj->commit_update(drawP); };
auto commit_update_and_layout_func = [&] {
comp->obj->commit_update(drawP);

View file

@ -13,7 +13,7 @@ class EllipseDrawEditTool : public DrawingProgramEditToolBase {
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 edit_gui(Toolbar& t) override;
private:
void commit();

View file

@ -45,12 +45,11 @@ bool ImageEditTool::edit_update() {
return true;
}
void ImageEditTool::edit_gui() {
void ImageEditTool::edit_gui(Toolbar& t) {
using namespace GUIStuff;
using namespace ElementHelpers;
ImageCanvasComponent& a = static_cast<ImageCanvasComponent&>(comp->obj->get_comp());
Toolbar& t = drawP.world.main.toolbar;
auto& gui = drawP.world.main.g.gui;
gui.new_id("edit tool image", [&] {
text_label_centered(gui, "File Properties");

View file

@ -10,5 +10,5 @@ class ImageEditTool : public DrawingProgramEditToolBase {
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 edit_gui(Toolbar& t) override;
};

View file

@ -12,7 +12,7 @@ RectDrawEditTool::RectDrawEditTool(DrawingProgram& initDrawP, CanvasComponentCon
DrawingProgramEditToolBase(initDrawP, initComp)
{}
void RectDrawEditTool::edit_gui() {
void RectDrawEditTool::edit_gui(Toolbar& t) {
using namespace GUIStuff;
using namespace ElementHelpers;
@ -23,7 +23,6 @@ void RectDrawEditTool::edit_gui() {
};
auto commit_update_func = [&] { comp->obj->commit_update(drawP); };
Toolbar& t = drawP.world.main.toolbar;
auto& gui = drawP.world.main.g.gui;
gui.new_id("edit tool rectangle", [&] {
text_label_centered(gui, "Edit Rectangle");

View file

@ -12,7 +12,7 @@ class RectDrawEditTool : public DrawingProgramEditToolBase {
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 edit_gui(Toolbar& t) override;
private:
std::optional<RectangleCanvasComponent::Data> oldData;
};

View file

@ -35,12 +35,11 @@ void TextBoxEditTool::commit_update_and_layout_func() {
drawP.world.main.g.gui.set_to_layout();
}
void TextBoxEditTool::edit_gui() {
void TextBoxEditTool::edit_gui(Toolbar& t) {
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;
@ -276,7 +275,7 @@ void TextBoxEditTool::input_mouse_motion_callback(const InputManager::MouseMotio
}
}
void TextBoxEditTool::right_click_popup_gui(Vector2f popupPos) {
void TextBoxEditTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
using namespace GUIStuff;
using namespace ElementHelpers;

View file

@ -14,8 +14,8 @@ class TextBoxEditTool : public DrawingProgramEditToolBase {
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 edit_gui(Toolbar& t) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void input_paste_callback(const CustomEvents::PasteEvent& paste) override;
virtual void input_text_key_callback(const InputManager::KeyCallbackArgs& key) override;

View file

@ -20,7 +20,7 @@ DrawingProgramToolType EllipseDrawTool::get_type() {
return DrawingProgramToolType::ELLIPSE;
}
void EllipseDrawTool::gui_toolbox() {
void EllipseDrawTool::gui_toolbox(Toolbar& t) {
using namespace GUIStuff;
using namespace ElementHelpers;
@ -93,8 +93,7 @@ void EllipseDrawTool::erase_component(CanvasComponentContainer::ObjInfo* erasedC
objInfoBeingEdited = nullptr;
}
void EllipseDrawTool::right_click_popup_gui(Vector2f popupPos) {
Toolbar& t = drawP.world.main.toolbar;
void EllipseDrawTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
t.paint_popup(popupPos);
}

View file

@ -10,8 +10,8 @@ class EllipseDrawTool : public DrawingProgramToolBase {
public:
EllipseDrawTool(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void tool_update() override;
virtual void switch_tool(DrawingProgramToolType newTool) override;

View file

@ -16,7 +16,7 @@ DrawingProgramToolType EraserTool::get_type() {
return DrawingProgramToolType::ERASER;
}
void EraserTool::gui_toolbox() {
void EraserTool::gui_toolbox(Toolbar& t) {
using namespace GUIStuff;
using namespace ElementHelpers;
@ -32,8 +32,7 @@ void EraserTool::gui_toolbox() {
});
}
void EraserTool::right_click_popup_gui(Vector2f popupPos) {
Toolbar& t = drawP.world.main.toolbar;
void EraserTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
t.paint_popup(popupPos);
}

View file

@ -9,8 +9,8 @@ class EraserTool : public DrawingProgramToolBase {
public:
EraserTool(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void tool_update() override;
virtual void switch_tool(DrawingProgramToolType newTool) override;

View file

@ -26,7 +26,7 @@ DrawingProgramToolType EyeDropperTool::get_type() {
return DrawingProgramToolType::EYEDROPPER;
}
void EyeDropperTool::gui_toolbox() {
void EyeDropperTool::gui_toolbox(Toolbar& t) {
using namespace GUIStuff;
using namespace ElementHelpers;
@ -42,8 +42,7 @@ void EyeDropperTool::gui_toolbox() {
});
}
void EyeDropperTool::right_click_popup_gui(Vector2f popupPos) {
Toolbar& t = drawP.world.main.toolbar;
void EyeDropperTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
t.paint_popup(popupPos);
}

View file

@ -7,8 +7,8 @@ class EyeDropperTool : public DrawingProgramToolBase {
public:
EyeDropperTool(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void tool_update() override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void draw(SkCanvas* canvas, const DrawData& drawData) override;

View file

@ -111,11 +111,10 @@ void GridModifyTool::input_mouse_motion_callback(const InputManager::MouseMotion
}
}
void GridModifyTool::gui_toolbox() {
void GridModifyTool::gui_toolbox(Toolbar& t) {
using namespace GUIStuff;
using namespace ElementHelpers;
Toolbar& t = drawP.world.main.toolbar;
auto& gui = drawP.world.main.g.gui;
gui.new_id("Grid modify tool", [&] {
@ -162,8 +161,7 @@ void GridModifyTool::gui_toolbox() {
});
}
void GridModifyTool::right_click_popup_gui(Vector2f popupPos) {
Toolbar& t = drawP.world.main.toolbar;
void GridModifyTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
t.paint_popup(popupPos);
}

View file

@ -10,8 +10,8 @@ class GridModifyTool : public DrawingProgramToolBase {
GridModifyTool(DrawingProgram& initDrawP);
void set_grid(const NetworkingObjects::NetObjWeakPtr<WorldGrid>& newGrid);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void tool_update() override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void draw(SkCanvas* canvas, const DrawData& drawData) override;

View file

@ -39,15 +39,15 @@ DrawingProgramToolType LassoSelectTool::get_type() {
return DrawingProgramToolType::LASSOSELECT;
}
void LassoSelectTool::gui_toolbox() {
void LassoSelectTool::gui_toolbox(Toolbar& t) {
auto& gui = drawP.world.main.g.gui;
gui.new_id("lasso select tool", [&] {
GUIStuff::ElementHelpers::text_label_centered(gui, "Lasso Select");
drawP.selection.selection_gui();
drawP.selection.selection_gui(t);
});
}
void LassoSelectTool::right_click_popup_gui(Vector2f popupPos) {
void LassoSelectTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
drawP.selection_action_menu(popupPos);
}

View file

@ -11,8 +11,8 @@ class LassoSelectTool : public DrawingProgramToolBase {
public:
LassoSelectTool(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void tool_update() override;
virtual void draw(SkCanvas* canvas, const DrawData& drawData) override;

View file

@ -18,7 +18,7 @@ DrawingProgramToolType LineDrawTool::get_type() {
return DrawingProgramToolType::LINE;
}
void LineDrawTool::gui_toolbox() {
void LineDrawTool::gui_toolbox(Toolbar& t) {
using namespace GUIStuff;
using namespace ElementHelpers;
auto& gui = drawP.world.main.g.gui;
@ -87,8 +87,7 @@ void LineDrawTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp
objInfoBeingEdited = nullptr;
}
void LineDrawTool::right_click_popup_gui(Vector2f popupPos) {
Toolbar& t = drawP.world.main.toolbar;
void LineDrawTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
t.paint_popup(popupPos);
}

View file

@ -9,8 +9,8 @@ class LineDrawTool : public DrawingProgramToolBase {
public:
LineDrawTool(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void tool_update() override;
virtual void switch_tool(DrawingProgramToolType newTool) override;

View file

@ -16,14 +16,14 @@ DrawingProgramToolType PanCanvasTool::get_type() {
return DrawingProgramToolType::PAN;
}
void PanCanvasTool::gui_toolbox() {
void PanCanvasTool::gui_toolbox(Toolbar& t) {
auto& gui = drawP.world.main.g.gui;
gui.new_id("Pan canvas tool", [&] {
GUIStuff::ElementHelpers::text_label_centered(gui, "Pan tool");
});
}
void PanCanvasTool::right_click_popup_gui(Vector2f popupPos) {
void PanCanvasTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
drawP.selection_action_menu(popupPos);
}

View file

@ -7,8 +7,8 @@ class PanCanvasTool : public DrawingProgramToolBase {
public:
PanCanvasTool(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void tool_update() override;
virtual void draw(SkCanvas* canvas, const DrawData& drawData) override;

View file

@ -18,7 +18,7 @@ DrawingProgramToolType RectDrawTool::get_type() {
return DrawingProgramToolType::RECTANGLE;
}
void RectDrawTool::gui_toolbox() {
void RectDrawTool::gui_toolbox(Toolbar& t) {
using namespace GUIStuff;
using namespace ElementHelpers;
@ -97,8 +97,7 @@ void RectDrawTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp
objInfoBeingEdited = nullptr;
}
void RectDrawTool::right_click_popup_gui(Vector2f popupPos) {
Toolbar& t = drawP.world.main.toolbar;
void RectDrawTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
t.paint_popup(popupPos);
}

View file

@ -9,8 +9,8 @@ class RectDrawTool : public DrawingProgramToolBase {
public:
RectDrawTool(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void tool_update() override;
virtual void switch_tool(DrawingProgramToolType newTool) override;

View file

@ -18,11 +18,11 @@ DrawingProgramToolType RectSelectTool::get_type() {
return DrawingProgramToolType::RECTSELECT;
}
void RectSelectTool::gui_toolbox() {
void RectSelectTool::gui_toolbox(Toolbar& t) {
auto& gui = drawP.world.main.g.gui;
gui.new_id("rectangle select tool", [&] {
GUIStuff::ElementHelpers::text_label_centered(gui, "Rectangle Select");
drawP.selection.selection_gui();
drawP.selection.selection_gui(t);
});
}
@ -73,7 +73,7 @@ void RectSelectTool::input_mouse_motion_callback(const InputManager::MouseMotion
void RectSelectTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp) {
}
void RectSelectTool::right_click_popup_gui(Vector2f popupPos) {
void RectSelectTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
drawP.selection_action_menu(popupPos);
}

View file

@ -9,9 +9,9 @@ class RectSelectTool : public DrawingProgramToolBase {
public:
RectSelectTool(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void tool_update() override;
virtual void draw(SkCanvas* canvas, const DrawData& drawData) override;
virtual void switch_tool(DrawingProgramToolType newTool) override;

View file

@ -50,11 +50,10 @@ DrawingProgramToolType ScreenshotTool::get_type() {
return DrawingProgramToolType::SCREENSHOT;
}
void ScreenshotTool::gui_toolbox() {
void ScreenshotTool::gui_toolbox(Toolbar& t) {
using namespace GUIStuff;
using namespace ElementHelpers;
Toolbar& t = drawP.world.main.toolbar;
auto& gui = drawP.world.main.g.gui;
auto& screenshotConfig = drawP.world.main.toolConfig.screenshot;
gui.new_id("screenshot tool", [&] {
@ -128,8 +127,7 @@ void ScreenshotTool::gui_toolbox() {
});
}
void ScreenshotTool::right_click_popup_gui(Vector2f popupPos) {
Toolbar& t = drawP.world.main.toolbar;
void ScreenshotTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
t.paint_popup(popupPos);
}

View file

@ -11,8 +11,8 @@ class ScreenshotTool : public DrawingProgramToolBase {
public:
ScreenshotTool(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void tool_update() override;
virtual void draw(SkCanvas* canvas, const DrawData& drawData) override;

View file

@ -19,7 +19,7 @@ DrawingProgramToolType TextBoxTool::get_type() {
return DrawingProgramToolType::TEXTBOX;
}
void TextBoxTool::gui_toolbox() {
void TextBoxTool::gui_toolbox(Toolbar& t) {
auto& gui = drawP.world.main.g.gui;
gui.new_id("textbox tool", [&] {
GUIStuff::ElementHelpers::text_label_centered(gui, "Place textbox");
@ -74,8 +74,7 @@ void TextBoxTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp)
objInfoBeingEdited = nullptr;
}
void TextBoxTool::right_click_popup_gui(Vector2f popupPos) {
Toolbar& t = drawP.world.main.toolbar;
void TextBoxTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
t.paint_popup(popupPos);
}

View file

@ -9,8 +9,8 @@ class TextBoxTool : public DrawingProgramToolBase {
public:
TextBoxTool(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void tool_update() override;
virtual void draw(SkCanvas* canvas, const DrawData& drawData) override;

View file

@ -16,14 +16,14 @@ DrawingProgramToolType ZoomCanvasTool::get_type() {
return DrawingProgramToolType::ZOOM;
}
void ZoomCanvasTool::gui_toolbox() {
void ZoomCanvasTool::gui_toolbox(Toolbar& t) {
auto& gui = drawP.world.main.g.gui;
gui.new_id("Zoom canvas tool", [&] {
GUIStuff::ElementHelpers::text_label_centered(gui, "Zoom tool");
});
}
void ZoomCanvasTool::right_click_popup_gui(Vector2f popupPos) {
void ZoomCanvasTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
drawP.selection_action_menu(popupPos);
}

View file

@ -7,8 +7,8 @@ class ZoomCanvasTool : public DrawingProgramToolBase {
public:
ZoomCanvasTool(DrawingProgram& initDrawP);
virtual DrawingProgramToolType get_type() override;
virtual void gui_toolbox() override;
virtual void right_click_popup_gui(Vector2f popupPos) override;
virtual void gui_toolbox(Toolbar& t) override;
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
virtual void tool_update() override;
virtual void draw(SkCanvas* canvas, const DrawData& drawData) override;

View file

@ -11,7 +11,7 @@ GUIHolder::GUIHolder(MainProgram& m):
gui.io.textTypeface = main.fonts->map["Roboto"];
gui.io.fonts = main.fonts;
gui.io.layoutRun = [&] {
main.toolbar.layout_run();
main.screen->gui_layout_run();
};
gui.io.input = &main.input;

View file

@ -2,8 +2,10 @@
#include <Helpers/Random.hpp>
#include "ResourceDisplay/ImageResourceDisplay.hpp"
#include "DrawingProgram/DrawingProgramCache.hpp"
#include <fstream>
GlobalConfig::GlobalConfig() {
load_default_palette();
displayName = Random::get().alphanumeric_str(10);
}
@ -126,3 +128,75 @@ void GlobalConfig::set_config_json(InputManager& input, const nlohmann::json& j,
try{j.at("debug").at("maximumFrameTimeToForceCacheRebuild").get_to(DrawingProgramCache::MILLISECOND_FRAME_TIME_TO_FORCE_CACHE_REFRESH);} catch(...) {}
try{j.at("debug").at("millisecondMinimumTimeToCheckForCacheRebuild").get_to(DrawingProgramCache::MILLISECOND_MINIMUM_TIME_TO_CHECK_FORCE_REFRESH);} catch(...) {}
}
void GlobalConfig::save_palettes() {
std::ofstream f(configPath / "palettes.json");
if(f.is_open()) {
using json = nlohmann::json;
json j;
auto palettesToSave = palettes;
palettesToSave.erase(palettesToSave.begin());
j = palettesToSave;
f << j;
f.close();
}
}
void GlobalConfig::load_palettes() {
std::ifstream f(configPath / "palettes.json");
load_default_palette();
if(f.is_open()) {
using json = nlohmann::json;
try {
json j;
f >> j;
std::vector<Palette> palettes;
j.get_to(palettes);
palettes.insert(palettes.end(), palettes.begin(), palettes.end());
} catch(...) {}
f.close();
}
}
void GlobalConfig::load_default_palette() {
palettes.clear();
palettes.emplace_back();
auto& palette = palettes.back().colors;
palettes.back().name = "Default";
palette = {{1.0,1.0,1.0},{0.0,0.0,0.0},{1.0,0.0,0.0},{1.0,0.529411792755127,0.0},{1.0,0.8274509906768799,0.0},{0.8705882430076599,1.0,0.03921568766236305},{0.6313725709915161,1.0,0.03921568766236305},{0.03921568766236305,1.0,0.6000000238418579},{0.03921568766236305,0.9372549057006836,1.0},{0.0784313753247261,0.4901960790157318,0.9607843160629272},{0.3450980484485626,0.03921568766236305,1.0},{0.7450980544090271,0.03921568766236305,1.0}};
}
void GlobalConfig::load_licenses() {
{
int globCount;
std::filesystem::path third_party_license_path("data/third_party_licenses");
char** filesInPath = SDL_GlobDirectory(third_party_license_path.string().c_str(), nullptr, 0, &globCount);
if(filesInPath) {
for(int i = 0; i < globCount; i++) {
std::filesystem::path filePath = third_party_license_path / std::filesystem::path(filesInPath[i]);
SDL_PathInfo fileInfo;
if(SDL_GetPathInfo(filePath.string().c_str(), &fileInfo) && fileInfo.type == SDL_PATHTYPE_FILE) {
thirdPartyLicenses.emplace_back(filePath.filename().string(), read_file_to_string(filePath));
}
}
SDL_free(filesInPath);
}
}
std::sort(thirdPartyLicenses.begin(), thirdPartyLicenses.end(), [](const auto& a1, const auto& a2) {
return std::lexicographical_compare(a1.first.begin(), a1.first.end(), a2.first.begin(), a2.first.end());
});
ownLicenseText = "InfiniPaint v" + VersionConstants::CURRENT_VERSION_STRING;
ownLicenseText +=
R"(
Copyright © 2026 Yousef Khadadeh
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
)";
}

View file

@ -9,6 +9,21 @@ class GlobalConfig {
public:
GlobalConfig();
std::filesystem::path currentSearchPath;
std::string ownLicenseText;
std::vector<std::pair<std::string, std::string>> thirdPartyLicenses;
struct Palette {
std::string name;
std::vector<Vector3f> colors;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Palette, name, colors)
};
std::vector<Palette> palettes;
std::filesystem::path configPath;
float guiScale = 1.0f;
double dragZoomSpeed = 0.02;
@ -32,6 +47,10 @@ class GlobalConfig {
nlohmann::json get_config_json(const InputManager& input) const;
void set_config_json(InputManager& input, const nlohmann::json& j, VersionNumber version);
void save_palettes();
void load_palettes();
void load_licenses();
bool showPerformance = false;
bool checkForUpdates = false;
bool useNativeFilePicker = true;
@ -53,6 +72,8 @@ class GlobalConfig {
#ifndef __EMSCRIPTEN__
bool applyDisplayScale = true;
#endif
private:
void load_default_palette();
};
NLOHMANN_JSON_SERIALIZE_ENUM(GlobalConfig::AntiAliasing, {

View file

@ -3,7 +3,6 @@
#include "VersionConstants.hpp"
#include <SDL3/SDL_render.h>
#include <SDL3/SDL_video.h>
#include <chrono>
#include <include/core/SkAlphaType.h>
#include <include/core/SkColor.h>
#include <include/core/SkPaint.h>
@ -20,6 +19,7 @@
#include <cereal/archives/json.hpp>
#include <Helpers/Serializers.hpp>
#include <nlohmann/json.hpp>
#include "Screens/DrawingProgramScreen.hpp"
#include <include/core/SkSurface.h>
#ifdef USE_SKIA_BACKEND_GRAPHITE
@ -34,18 +34,17 @@
#endif
#include <Helpers/Logger.hpp>
#include "DrawCollision.hpp"
MainProgram::MainProgram():
input(*this),
fonts(std::make_shared<FontData>()),
toolbar(*this),
g(*this)
{
screen = std::make_unique<DrawingProgramScreen>(*this);
Logger::get().add_log("WORLDFATAL", [&](const std::string& text) {
*logFile << "[WORLDFATAL] " << text << std::endl;
std::cout << "[WORLDFATAL] " << text << std::endl;
logMessages.emplace_front(Toolbar::LogMessage{text, Toolbar::LogMessage::COLOR_ERROR});
logMessages.emplace_front(UserLogMessage{text, UserLogMessage::COLOR_ERROR});
if(logMessages.size() == LOG_SIZE)
logMessages.pop_back();
g.gui.set_to_layout();
@ -54,7 +53,7 @@ MainProgram::MainProgram():
Logger::get().add_log("USERINFO", [&](const std::string& text) {
*logFile << "[USERINFO] " << text << std::endl;
std::cout << "[USERINFO] " << text << std::endl;
logMessages.emplace_front(Toolbar::LogMessage{text, Toolbar::LogMessage::COLOR_NORMAL});
logMessages.emplace_front(UserLogMessage{text, UserLogMessage::COLOR_NORMAL});
if(logMessages.size() == LOG_SIZE)
logMessages.pop_back();
g.gui.set_to_layout();
@ -69,26 +68,17 @@ MainProgram::MainProgram():
void MainProgram::update() {
deltaTime.update_time_since();
deltaTime.update_time_point();
input.update();
g.update();
toolbar.update();
for(auto& w : worlds) {
if(w == world)
w->focus_update();
else
w->unfocus_update();
}
screen->update();
for(auto& w : worlds)
w->update();
NetLibrary::update();
post_callback();
}
bool MainProgram::app_close_requested() {
return toolbar.app_close_requested();
return screen->app_close_requested();
}
void MainProgram::update_display_names() {
@ -99,11 +89,11 @@ void MainProgram::update_display_names() {
}
void MainProgram::init_net_library() {
NetLibrary::init(configPath / "p2p.json");
NetLibrary::init(conf.configPath / "p2p.json");
}
void MainProgram::save_config() {
std::ofstream f(configPath / "config.json");
std::ofstream f(conf.configPath / "config.json");
if(f.is_open()) {
using json = nlohmann::json;
json j;
@ -114,13 +104,13 @@ void MainProgram::save_config() {
j["window"]["size"] = window.writtenSize;
j["window"]["maximized"] = window.maximized;
j["window"]["fullscreen"] = window.fullscreen;
j["fileselectorpath"] = toolbar.file_selector_path();
j["fileselectorpath"] = conf.currentSearchPath;
j["toolConfig"] = toolConfig;
f << std::setw(4) << j;
f.close();
}
toolbar.save_palettes();
conf.save_palettes();
#ifdef __EMSCRIPTEN__
EM_ASM(
@ -135,8 +125,8 @@ void MainProgram::save_config() {
}
void MainProgram::load_config() {
std::ifstream f(configPath / "config.json");
toolbar.file_selector_path() = homePath;
std::ifstream f(conf.configPath / "config.json");
conf.currentSearchPath = homePath;
if(f.is_open()) {
using json = nlohmann::json;
@ -169,10 +159,10 @@ void MainProgram::load_config() {
}
catch(...) {}
try {
j.at("fileselectorpath").get_to(toolbar.file_selector_path());
j.at("fileselectorpath").get_to(conf.currentSearchPath);
}
catch(...) {
toolbar.file_selector_path() = homePath;
conf.currentSearchPath = homePath;
}
#endif
try {
@ -186,11 +176,11 @@ void MainProgram::load_config() {
else
toolbar.viewWebVersionWelcome = true;
#endif
toolbar.load_palettes();
g.load_theme(configPath, conf.themeCurrentlyLoaded);
toolbar.load_licenses();
conf.load_palettes();
g.load_theme(conf.configPath, conf.themeCurrentlyLoaded);
conf.load_licenses();
NetLibrary::copy_default_p2p_config_to_path(configPath / "p2p.json");
NetLibrary::copy_default_p2p_config_to_path(conf.configPath / "p2p.json");
update_display_names();
set_vsync_value(conf.vsyncValue);
@ -293,20 +283,18 @@ void MainProgram::post_callback() {
}
void MainProgram::input_add_file_to_canvas_callback(const CustomEvents::AddFileToCanvasEvent& addFile) {
if(world)
world->input_add_file_to_canvas_callback(addFile);
screen->input_add_file_to_canvas_callback(addFile);
post_callback();
}
void MainProgram::input_open_infinipaint_file_callback(const CustomEvents::OpenInfiniPaintFileEvent& openFile) {
create_new_tab(openFile);
screen->input_open_infinipaint_file_callback(openFile);
post_callback();
}
void MainProgram::input_paste_callback(const CustomEvents::PasteEvent& paste) {
g.input_paste_callback(paste);
if(world)
world->input_paste_callback(paste);
screen->input_paste_callback(paste);
post_callback();
}
@ -330,148 +318,106 @@ bool MainProgram::input_keybind_callback(const Vector2ui32& newKey) {
}
void MainProgram::input_drop_file_callback(const InputManager::DropCallbackArgs& drop) {
if(std::filesystem::is_regular_file(drop.data)) {
std::filesystem::path droppedFilePath(drop.data);
if(droppedFilePath.has_extension() && droppedFilePath.extension().string() == std::string("." + World::FILE_EXTENSION)) {
CustomEvents::emit_event<CustomEvents::OpenInfiniPaintFileEvent>({
.isClient = false,
.filePathSource = droppedFilePath
});
return;
}
}
if(world)
world->input_drop_file_callback(drop);
screen->input_drop_file_callback(drop);
post_callback();
}
void MainProgram::input_drop_text_callback(const InputManager::DropCallbackArgs& drop) {
if(world)
world->input_drop_text_callback(drop);
screen->input_drop_text_callback(drop);
post_callback();
}
void MainProgram::input_key_callback(const InputManager::KeyCallbackArgs& key) {
switch(key.key) {
case InputManager::KEY_NOGUI: {
if(key.down && !key.repeat) {
drawGui = !drawGui;
g.gui.set_to_layout();
}
break;
}
case InputManager::KEY_FULLSCREEN: {
if(key.down && !key.repeat)
toggle_full_screen();
break;
}
case InputManager::KEY_SAVE: {
if(key.down && !key.repeat)
toolbar.save_func();
break;
}
case InputManager::KEY_SAVE_AS: {
if(key.down && !key.repeat)
toolbar.save_as_func();
break;
}
case InputManager::KEY_OPEN_CHAT: {
if(key.down && !key.repeat)
toolbar.open_chatbox();
break;
}
if(key.key == InputManager::KEY_FULLSCREEN) {
if(key.down && !key.repeat)
toggle_full_screen();
}
g.input_key_callback(key);
if(world)
world->input_key_callback(key);
screen->input_key_callback(key);
post_callback();
}
void MainProgram::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {
switch(key.key) {
case InputManager::KEY_GENERIC_ESCAPE: {
if(key.down && !key.repeat)
toolbar.close_chatbox();
break;
}
}
g.input_text_key_callback(key);
if(world)
world->input_text_key_callback(key);
screen->input_text_key_callback(key);
post_callback();
}
void MainProgram::input_text_callback(const InputManager::TextCallbackArgs& text) {
g.input_text_callback(text);
if(world)
world->input_text_callback(text);
screen->input_text_callback(text);
post_callback();
}
void MainProgram::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
g.input_mouse_button_callback(button);
if(world)
world->input_mouse_button_callback(button);
screen->input_mouse_button_callback(button);
post_callback();
}
void MainProgram::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
g.input_mouse_motion_callback(motion);
if(world)
world->input_mouse_motion_callback(motion);
screen->input_mouse_motion_callback(motion);
post_callback();
}
void MainProgram::input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) {
g.input_mouse_wheel_callback(wheel);
if(world)
world->input_mouse_wheel_callback(wheel);
screen->input_mouse_wheel_callback(wheel);
post_callback();
}
void MainProgram::input_pen_button_callback(const InputManager::PenButtonCallbackArgs& button) {
if(world)
world->input_pen_button_callback(button);
screen->input_pen_button_callback(button);
post_callback();
}
void MainProgram::input_pen_touch_callback(const InputManager::PenTouchCallbackArgs& touch) {
if(world)
world->input_pen_touch_callback(touch);
screen->input_pen_touch_callback(touch);
post_callback();
}
void MainProgram::input_pen_motion_callback(const InputManager::PenMotionCallbackArgs& motion) {
if(world)
world->input_pen_motion_callback(motion);
screen->input_pen_motion_callback(motion);
post_callback();
}
void MainProgram::input_pen_axis_callback(const InputManager::PenAxisCallbackArgs& axis) {
if(world)
world->input_pen_axis_callback(axis);
screen->input_pen_axis_callback(axis);
post_callback();
}
void MainProgram::input_multi_finger_touch_callback(const InputManager::MultiFingerTouchCallbackArgs& touch) {
if(world)
world->input_multi_finger_touch_callback(touch);
screen->input_multi_finger_touch_callback(touch);
post_callback();
}
void MainProgram::input_multi_finger_motion_callback(const InputManager::MultiFingerMotionCallbackArgs& motion) {
if(world)
world->input_multi_finger_motion_callback(motion);
screen->input_multi_finger_motion_callback(motion);
post_callback();
}
void MainProgram::input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch) {
screen->input_finger_touch_callback(touch);
post_callback();
}
void MainProgram::input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion) {
screen->input_finger_motion_callback(motion);
post_callback();
}
void MainProgram::input_window_resize_callback(const InputManager::WindowResizeCallbackArgs& w) {
for(auto& wor : worlds)
wor->drawData.cam.set_viewing_area(window.size.cast<float>());
g.window_update();
screen->input_window_resize_callback(w);
post_callback();
}
void MainProgram::input_window_scale_callback(const InputManager::WindowScaleCallbackArgs& w) {
g.window_update();
screen->input_window_scale_callback(w);
post_callback();
}

View file

@ -16,6 +16,7 @@
#include "DrawingProgram/ToolConfiguration.hpp"
#include "GUIHolder.hpp"
#include "GlobalConfig.hpp"
#include "Screens/Screen.hpp"
#ifdef USE_SKIA_BACKEND_GRAPHITE
#include "include/gpu/graphite/Recorder.h"
@ -25,14 +26,23 @@
using namespace Eigen;
struct UserLogMessage {
static constexpr float DISPLAY_TIME = 8.0f;
static constexpr float FADE_START_TIME = 7.0f;
std::string text;
enum {
COLOR_NORMAL = 0,
COLOR_ERROR
} color;
TimePoint time;
};
class MainProgram {
public:
static constexpr size_t LOG_SIZE = 30;
InputManager input;
Vector3f userColor;
struct Window {
std::chrono::steady_clock::duration lastFrameTime = std::chrono::milliseconds(16);
Vector2i size = {-1, -1};
@ -72,12 +82,13 @@ class MainProgram {
std::shared_ptr<FontData> fonts;
TimePoint deltaTime;
Toolbar toolbar;
GUIHolder g;
ToolConfiguration toolConfig;
std::ofstream* logFile;
std::deque<Toolbar::LogMessage> logMessages;
std::deque<UserLogMessage> logMessages;
std::unique_ptr<Screen> screen;
MainProgram();
void update();
@ -105,7 +116,6 @@ class MainProgram {
void refresh_draw_surfaces();
std::filesystem::path homePath;
std::filesystem::path configPath;
std::filesystem::path documentsPath;
bool drawGui = true;

View file

@ -0,0 +1,141 @@
#include "DrawingProgramScreen.hpp"
#include "../MainProgram.hpp"
DrawingProgramScreen::DrawingProgramScreen(MainProgram& m):
Screen(m),
toolbar(m)
{}
void DrawingProgramScreen::update() {
toolbar.update();
main.world->focus_update();
}
void DrawingProgramScreen::gui_layout_run() {
toolbar.layout_run();
}
bool DrawingProgramScreen::app_close_requested() {
return toolbar.app_close_requested();
}
void DrawingProgramScreen::input_add_file_to_canvas_callback(const CustomEvents::AddFileToCanvasEvent& addFile) {
main.world->input_add_file_to_canvas_callback(addFile);
}
void DrawingProgramScreen::input_open_infinipaint_file_callback(const CustomEvents::OpenInfiniPaintFileEvent& openFile) {
main.create_new_tab(openFile);
}
void DrawingProgramScreen::input_paste_callback(const CustomEvents::PasteEvent& paste) {
main.world->input_paste_callback(paste);
}
void DrawingProgramScreen::input_drop_file_callback(const InputManager::DropCallbackArgs& drop) {
if(std::filesystem::is_regular_file(drop.data)) {
std::filesystem::path droppedFilePath(drop.data);
if(droppedFilePath.has_extension() && droppedFilePath.extension().string() == std::string("." + World::FILE_EXTENSION)) {
CustomEvents::emit_event<CustomEvents::OpenInfiniPaintFileEvent>({
.isClient = false,
.filePathSource = droppedFilePath
});
return;
}
}
main.world->input_drop_file_callback(drop);
}
void DrawingProgramScreen::input_drop_text_callback(const InputManager::DropCallbackArgs& drop) {
main.world->input_drop_text_callback(drop);
}
void DrawingProgramScreen::input_key_callback(const InputManager::KeyCallbackArgs& key) {
switch(key.key) {
case InputManager::KEY_NOGUI: {
if(key.down && !key.repeat) {
toolbar.drawGui = !toolbar.drawGui;
main.g.gui.set_to_layout();
}
break;
}
case InputManager::KEY_SAVE: {
if(key.down && !key.repeat)
toolbar.save_func();
break;
}
case InputManager::KEY_SAVE_AS: {
if(key.down && !key.repeat)
toolbar.save_as_func();
break;
}
case InputManager::KEY_OPEN_CHAT: {
if(key.down && !key.repeat)
toolbar.open_chatbox();
break;
}
}
main.world->input_key_callback(key);
}
void DrawingProgramScreen::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {
switch(key.key) {
case InputManager::KEY_GENERIC_ESCAPE: {
if(key.down && !key.repeat)
toolbar.close_chatbox();
break;
}
}
main.world->input_text_key_callback(key);
}
void DrawingProgramScreen::input_text_callback(const InputManager::TextCallbackArgs& text) {
main.world->input_text_callback(text);
}
void DrawingProgramScreen::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
main.world->input_mouse_button_callback(button);
}
void DrawingProgramScreen::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
main.world->input_mouse_motion_callback(motion);
}
void DrawingProgramScreen::input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) {
main.world->input_mouse_wheel_callback(wheel);
}
void DrawingProgramScreen::input_pen_button_callback(const InputManager::PenButtonCallbackArgs& button) {
main.world->input_pen_button_callback(button);
}
void DrawingProgramScreen::input_pen_touch_callback(const InputManager::PenTouchCallbackArgs& touch) {
main.world->input_pen_touch_callback(touch);
}
void DrawingProgramScreen::input_pen_motion_callback(const InputManager::PenMotionCallbackArgs& motion) {
main.world->input_pen_motion_callback(motion);
}
void DrawingProgramScreen::input_pen_axis_callback(const InputManager::PenAxisCallbackArgs& axis) {
main.world->input_pen_axis_callback(axis);
}
void DrawingProgramScreen::input_multi_finger_touch_callback(const InputManager::MultiFingerTouchCallbackArgs& touch) {
main.world->input_multi_finger_touch_callback(touch);
}
void DrawingProgramScreen::input_multi_finger_motion_callback(const InputManager::MultiFingerMotionCallbackArgs& motion) {
main.world->input_multi_finger_motion_callback(motion);
}
void DrawingProgramScreen::input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch) {
}
void DrawingProgramScreen::input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion) {
}
void DrawingProgramScreen::input_window_resize_callback(const InputManager::WindowResizeCallbackArgs& w) {
}
void DrawingProgramScreen::input_window_scale_callback(const InputManager::WindowScaleCallbackArgs& w) {
}

View file

@ -0,0 +1,34 @@
#pragma once
#include "Screen.hpp"
#include "../Toolbar.hpp"
class DrawingProgramScreen : public Screen {
public:
DrawingProgramScreen(MainProgram& m);
virtual void update() override;
virtual void gui_layout_run() override;
virtual bool app_close_requested() override;
virtual void input_add_file_to_canvas_callback(const CustomEvents::AddFileToCanvasEvent& addFile) override;
virtual void input_open_infinipaint_file_callback(const CustomEvents::OpenInfiniPaintFileEvent& openFile) override;
virtual void input_paste_callback(const CustomEvents::PasteEvent& paste) override;
virtual void input_drop_file_callback(const InputManager::DropCallbackArgs& drop) override;
virtual void input_drop_text_callback(const InputManager::DropCallbackArgs& drop) override;
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key) 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_callback(const InputManager::MouseButtonCallbackArgs& button) override;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
virtual void input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) override;
virtual void input_pen_button_callback(const InputManager::PenButtonCallbackArgs& button) override;
virtual void input_pen_touch_callback(const InputManager::PenTouchCallbackArgs& touch) override;
virtual void input_pen_motion_callback(const InputManager::PenMotionCallbackArgs& motion) override;
virtual void input_pen_axis_callback(const InputManager::PenAxisCallbackArgs& axis) override;
virtual void input_multi_finger_touch_callback(const InputManager::MultiFingerTouchCallbackArgs& touch) override;
virtual void input_multi_finger_motion_callback(const InputManager::MultiFingerMotionCallbackArgs& motion) override;
virtual void input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch) override;
virtual void input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion) override;
virtual void input_window_resize_callback(const InputManager::WindowResizeCallbackArgs& w) override;
virtual void input_window_scale_callback(const InputManager::WindowScaleCallbackArgs& w) override;
private:
Toolbar toolbar;
};

32
src/Screens/Screen.cpp Normal file
View file

@ -0,0 +1,32 @@
#include "Screen.hpp"
Screen::Screen(MainProgram& m):
main(m)
{}
void Screen::update() {}
void Screen::gui_layout_run() {}
bool Screen::app_close_requested() { return false; }
void Screen::input_add_file_to_canvas_callback(const CustomEvents::AddFileToCanvasEvent& addFile) {}
void Screen::input_open_infinipaint_file_callback(const CustomEvents::OpenInfiniPaintFileEvent& openFile) {}
void Screen::input_paste_callback(const CustomEvents::PasteEvent& paste) {}
void Screen::input_drop_file_callback(const InputManager::DropCallbackArgs& drop) {}
void Screen::input_drop_text_callback(const InputManager::DropCallbackArgs& drop) {}
void Screen::input_key_callback(const InputManager::KeyCallbackArgs& key) {}
void Screen::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {}
void Screen::input_text_callback(const InputManager::TextCallbackArgs& text) {}
void Screen::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {}
void Screen::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {}
void Screen::input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) {}
void Screen::input_pen_button_callback(const InputManager::PenButtonCallbackArgs& button) {}
void Screen::input_pen_touch_callback(const InputManager::PenTouchCallbackArgs& touch) {}
void Screen::input_pen_motion_callback(const InputManager::PenMotionCallbackArgs& motion) {}
void Screen::input_pen_axis_callback(const InputManager::PenAxisCallbackArgs& axis) {}
void Screen::input_multi_finger_touch_callback(const InputManager::MultiFingerTouchCallbackArgs& touch) {}
void Screen::input_multi_finger_motion_callback(const InputManager::MultiFingerMotionCallbackArgs& motion) {}
void Screen::input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch) {}
void Screen::input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion) {}
void Screen::input_window_resize_callback(const InputManager::WindowResizeCallbackArgs& w) {}
void Screen::input_window_scale_callback(const InputManager::WindowScaleCallbackArgs& w) {}
Screen::~Screen() {}

36
src/Screens/Screen.hpp Normal file
View file

@ -0,0 +1,36 @@
#pragma once
#include "../InputManager.hpp"
class Screen {
public:
Screen(MainProgram& m);
virtual void update();
virtual void gui_layout_run();
virtual bool app_close_requested();
virtual void input_add_file_to_canvas_callback(const CustomEvents::AddFileToCanvasEvent& addFile);
virtual void input_open_infinipaint_file_callback(const CustomEvents::OpenInfiniPaintFileEvent& openFile);
virtual void input_paste_callback(const CustomEvents::PasteEvent& paste);
virtual void input_drop_file_callback(const InputManager::DropCallbackArgs& drop);
virtual void input_drop_text_callback(const InputManager::DropCallbackArgs& drop);
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key);
virtual void input_text_key_callback(const InputManager::KeyCallbackArgs& key);
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);
virtual void input_pen_button_callback(const InputManager::PenButtonCallbackArgs& button);
virtual void input_pen_touch_callback(const InputManager::PenTouchCallbackArgs& touch);
virtual void input_pen_motion_callback(const InputManager::PenMotionCallbackArgs& motion);
virtual void input_pen_axis_callback(const InputManager::PenAxisCallbackArgs& axis);
virtual void input_multi_finger_touch_callback(const InputManager::MultiFingerTouchCallbackArgs& touch);
virtual void input_multi_finger_motion_callback(const InputManager::MultiFingerMotionCallbackArgs& motion);
virtual void input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch);
virtual void input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion);
virtual void input_window_resize_callback(const InputManager::WindowResizeCallbackArgs& w);
virtual void input_window_scale_callback(const InputManager::WindowScaleCallbackArgs& w);
virtual ~Screen();
protected:
MainProgram& main;
};

View file

@ -26,7 +26,6 @@
#include <filesystem>
#include <optional>
#include <Helpers/Logger.hpp>
#include <fstream>
#include <Helpers/StringHelpers.hpp>
#include <Helpers/VersionNumber.hpp>
@ -69,49 +68,7 @@ using namespace ElementHelpers;
Toolbar::Toolbar(MainProgram& initMain):
main(initMain)
{
load_default_palette();
}
void Toolbar::load_default_palette() {
paletteData.palettes.clear();
paletteData.palettes.emplace_back();
auto& palette = paletteData.palettes.back().colors;
paletteData.palettes.back().name = "Default";
palette = {{1.0,1.0,1.0},{0.0,0.0,0.0},{1.0,0.0,0.0},{1.0,0.529411792755127,0.0},{1.0,0.8274509906768799,0.0},{0.8705882430076599,1.0,0.03921568766236305},{0.6313725709915161,1.0,0.03921568766236305},{0.03921568766236305,1.0,0.6000000238418579},{0.03921568766236305,0.9372549057006836,1.0},{0.0784313753247261,0.4901960790157318,0.9607843160629272},{0.3450980484485626,0.03921568766236305,1.0},{0.7450980544090271,0.03921568766236305,1.0}};
paletteData.selectedPalette = 0;
}
void Toolbar::save_palettes() {
std::ofstream f(main.configPath / "palettes.json");
if(f.is_open()) {
using json = nlohmann::json;
json j;
auto palettesToSave = paletteData.palettes;
palettesToSave.erase(palettesToSave.begin());
j = palettesToSave;
f << j;
f.close();
}
}
void Toolbar::load_palettes() {
std::ifstream f(main.configPath / "palettes.json");
load_default_palette();
if(f.is_open()) {
using json = nlohmann::json;
try {
json j;
f >> j;
std::vector<PaletteData::Palette> palettes;
j.get_to(palettes);
paletteData.palettes.insert(paletteData.palettes.end(), palettes.begin(), palettes.end());
} catch(...) {}
f.close();
}
}
{}
// You can't trust that filter wont be -1 on the platform youre on, so dont use the extension from the callback
void Toolbar::sdl_open_file_dialog_callback(void* userData, const char * const * fileList, int filter) {
@ -160,10 +117,6 @@ void Toolbar::open_file_selector(const std::string& filePickerName, const std::v
}
}
std::filesystem::path& Toolbar::file_selector_path() {
return filePicker.currentSearchPath;
}
void Toolbar::color_button_left(const char* id, Vector4f* color, const ColorSelectorButtonData& colorSelectorData) {
auto& gui = main.g.gui;
color_button(gui, id, color, {
@ -216,46 +169,12 @@ void Toolbar::color_selector_right(Element* button, Vector4f* color, const Color
main.g.gui.set_to_layout();
}
void Toolbar::load_licenses() {
{
int globCount;
std::filesystem::path third_party_license_path("data/third_party_licenses");
char** filesInPath = SDL_GlobDirectory(third_party_license_path.string().c_str(), nullptr, 0, &globCount);
if(filesInPath) {
for(int i = 0; i < globCount; i++) {
std::filesystem::path filePath = third_party_license_path / std::filesystem::path(filesInPath[i]);
SDL_PathInfo fileInfo;
if(SDL_GetPathInfo(filePath.string().c_str(), &fileInfo) && fileInfo.type == SDL_PATHTYPE_FILE) {
thirdPartyLicenses.emplace_back(filePath.filename().string(), read_file_to_string(filePath));
}
}
SDL_free(filesInPath);
}
}
std::sort(thirdPartyLicenses.begin(), thirdPartyLicenses.end(), [](const auto& a1, const auto& a2) {
return std::lexicographical_compare(a1.first.begin(), a1.first.end(), a2.first.begin(), a2.first.end());
});
ownLicenseText = "InfiniPaint v" + VersionConstants::CURRENT_VERSION_STRING;
ownLicenseText +=
R"(
Copyright © 2026 Yousef Khadadeh
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
)";
}
void Toolbar::update() {
std::erase_if(main.logMessages, [&](auto& logM) {
logM.time.update_time_since();
if(logM.time > LogMessage::FADE_START_TIME) {
if(logM.time > UserLogMessage::FADE_START_TIME) {
main.g.gui.set_to_layout();
return logM.time >= LogMessage::DISPLAY_TIME;
return logM.time >= UserLogMessage::DISPLAY_TIME;
}
return false;
});
@ -294,7 +213,7 @@ void Toolbar::layout_run() {
update_notification_check();
#endif
if(main.drawGui) {
if(drawGui) {
CLAY_AUTO_ID({
.layout = {
.sizing = {.width = CLAY_SIZING_FIT(gui.io.windowSize.x()), .height = CLAY_SIZING_FIT(gui.io.windowSize.y())},
@ -338,7 +257,7 @@ void Toolbar::layout_run() {
}
if(!main.world->clientStillConnecting)
main.world->drawProg.right_click_popup_gui();
main.world->drawProg.right_click_popup_gui(*this);
}
bool Toolbar::app_close_requested() {
@ -486,7 +405,7 @@ void Toolbar::paint_popup(Vector2f popupPos) {
paint_circle_popup_menu(gui, "paint circle popup", popupPos, {
.rotationAngle = newRotationAngle.get(),
.selectedColor = main.world->drawProg.get_foreground_color_ptr(),
.palette = paletteData.palettes[paletteData.selectedPalette].colors,
.palette = main.conf.palettes[paletteData.selectedPalette].colors,
.onRotate = [&, newRotationAngle] {
main.world->drawData.cam.c.rotate_about(main.world->drawData.cam.c.from_space(main.window.size.cast<float>() * 0.5f), *newRotationAngle - main.world->drawData.cam.c.rotation);
*newRotationAngle = main.world->drawData.cam.c.rotation;
@ -1199,8 +1118,8 @@ void Toolbar::global_log() {
for(size_t i = 0; i < main.logMessages.size(); i++) {
auto& logM = main.logMessages[i];
logM.time.update_time_since();
if(logM.time < LogMessage::DISPLAY_TIME) {
float a = 1.0f - lerp_time<float>(logM.time, LogMessage::DISPLAY_TIME, LogMessage::FADE_START_TIME);
if(logM.time < UserLogMessage::DISPLAY_TIME) {
float a = 1.0f - lerp_time<float>(logM.time, UserLogMessage::DISPLAY_TIME, UserLogMessage::FADE_START_TIME);
gui.new_id(i, [&] {
gui.element<LayoutElement>("Global log message", [&] (LayoutElement*, const Clay_ElementId& lId) {
CLAY(lId, {
@ -1216,10 +1135,10 @@ void Toolbar::global_log() {
}) {
SkColor4f c{0, 0, 0, 0};
switch(logM.color) {
case LogMessage::COLOR_NORMAL:
case UserLogMessage::COLOR_NORMAL:
c = io.theme->frontColor1;
break;
case LogMessage::COLOR_ERROR:
case UserLogMessage::COLOR_ERROR:
c = io.theme->errorColor;
break;
}
@ -1247,7 +1166,7 @@ void Toolbar::drawing_program_gui() {
.layoutDirection = CLAY_LEFT_TO_RIGHT
},
}) {
main.world->drawProg.toolbar_gui();
main.world->drawProg.toolbar_gui(*this);
if(colorLeft)
color_picker_window("Drawing program gui color picker left", &colorLeft, colorLeftButton, colorLeftData);
@ -1259,7 +1178,7 @@ void Toolbar::drawing_program_gui() {
if(colorRight)
color_picker_window("Drawing program gui color picker right", &colorRight, colorRightButton, colorRightData);
main.world->drawProg.tool_options_gui();
main.world->drawProg.tool_options_gui(*this);
}
}
@ -1310,7 +1229,7 @@ void Toolbar::color_palette(const char* id, Vector4f* color, const std::function
auto& io = gui.io;
gui.new_id(id, [&] {
auto& palette = paletteData.palettes[paletteData.selectedPalette].colors;
auto& palette = main.conf.palettes[paletteData.selectedPalette].colors;
gui.element<ScrollArea>("color palette scroll area", ScrollArea::Options{
.scrollVertical = true,
@ -1400,7 +1319,7 @@ void Toolbar::color_palette(const char* id, Vector4f* color, const std::function
}
}) {
std::vector<std::string> paletteNames;
for(auto& p : paletteData.palettes)
for(auto& p : main.conf.palettes)
paletteNames.emplace_back(p.name);
gui.element<DropDown<size_t>>("paletteselector", &paletteData.selectedPalette, paletteNames, DropdownOptions{
.onClick = [&] { gui.set_to_layout(); }
@ -1414,7 +1333,7 @@ void Toolbar::color_palette(const char* id, Vector4f* color, const std::function
svg_icon_button(gui, "paletteremove", "data/icons/close.svg", {
.size = 25.0f,
.onClick = [&] {
paletteData.palettes.erase(paletteData.palettes.begin() + paletteData.selectedPalette);
main.conf.palettes.erase(main.conf.palettes.begin() + paletteData.selectedPalette);
paletteData.selectedPalette = 0;
}
});
@ -1423,9 +1342,9 @@ void Toolbar::color_palette(const char* id, Vector4f* color, const std::function
input_text_field(gui, "paletteinputname", "Name", &paletteData.newPaletteStr);
text_button_wide("addpalettebutton", "Create", [&] {
if(!paletteData.newPaletteStr.empty()) {
paletteData.palettes.emplace_back();
paletteData.palettes.back().name = paletteData.newPaletteStr;
paletteData.selectedPalette = paletteData.palettes.size() - 1;
main.conf.palettes.emplace_back();
main.conf.palettes.back().name = paletteData.newPaletteStr;
paletteData.selectedPalette = main.conf.palettes.size() - 1;
paletteData.addingPalette = false;
}
});
@ -1738,7 +1657,7 @@ void Toolbar::general_settings_inner_gui() {
.wide = true,
.centered = false,
.onClick = [&, opt] {
main.g.load_theme(main.configPath, main.conf.themeCurrentlyLoaded);
main.g.load_theme(main.conf.configPath, main.conf.themeCurrentlyLoaded);
themeData.selectedThemeIndex = std::nullopt;
generalSettingsOptions = opt;
main.keybindWaiting = std::nullopt;
@ -1860,7 +1779,7 @@ void Toolbar::general_settings_inner_gui() {
if(themeData.selectedThemeIndex != 0) {
text_button_wide("savethemebutton", "Save", [&] {
main.conf.themeCurrentlyLoaded = themeData.themeDirList[themeData.selectedThemeIndex.value()];
main.g.save_theme(main.configPath, main.conf.themeCurrentlyLoaded);
main.g.save_theme(main.conf.configPath, main.conf.themeCurrentlyLoaded);
reload_theme_list();
});
}
@ -1873,7 +1792,7 @@ void Toolbar::general_settings_inner_gui() {
});
if(themeData.selectedThemeIndex != 0) {
text_button_wide("deletethemebutton", "Delete", [&] {
try { std::filesystem::remove(main.configPath / "themes" / (themeData.themeDirList[themeData.selectedThemeIndex.value()] + ".json")); } catch(...) { }
try { std::filesystem::remove(main.conf.configPath / "themes" / (themeData.themeDirList[themeData.selectedThemeIndex.value()] + ".json")); } catch(...) { }
main.conf.themeCurrentlyLoaded = "Default";
reload_theme_list();
});
@ -1883,7 +1802,7 @@ void Toolbar::general_settings_inner_gui() {
input_text_field(gui, "Theme name:", "Theme name: ", &main.conf.themeCurrentlyLoaded);
left_to_right_line_layout(gui, [&]() {
text_button_wide("saveasdone", "Done", [&] {
main.g.save_theme(main.configPath, main.conf.themeCurrentlyLoaded);
main.g.save_theme(main.conf.configPath, main.conf.themeCurrentlyLoaded);
reload_theme_list();
});
text_button_wide("saveascancel", "Cancel", [&] {
@ -1964,7 +1883,7 @@ void Toolbar::general_settings_inner_gui() {
}
text_button_wide("done menu", "Done", [&] {
main.save_config();
main.g.load_theme(main.configPath, main.conf.themeCurrentlyLoaded);
main.g.load_theme(main.conf.configPath, main.conf.themeCurrentlyLoaded);
themeData.selectedThemeIndex = std::nullopt;
main.keybindWaiting = std::nullopt;
optionsMenuOpen = false;
@ -2006,7 +1925,7 @@ void Toolbar::about_menu_inner_gui() {
});
}
text_label_light_centered(gui, "Third Party Components");
for(int i = 0; i < static_cast<int>(thirdPartyLicenses.size()); i++) {
for(int i = 0; i < static_cast<int>(main.conf.thirdPartyLicenses.size()); i++) {
CLAY_AUTO_ID({
.layout = {
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0) },
@ -2014,7 +1933,7 @@ void Toolbar::about_menu_inner_gui() {
}
}) {
gui.new_id(i, [&] {
text_button(gui, "noticebutton", thirdPartyLicenses[i].first, {
text_button(gui, "noticebutton", main.conf.thirdPartyLicenses[i].first, {
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
.isSelected = selectedLicense == i,
.wide = true,
@ -2034,7 +1953,7 @@ void Toolbar::about_menu_inner_gui() {
.clipVertical = true,
.showScrollbarY = true,
.innerContent = [&](const ScrollArea::InnerContentParameters&) {
text_label_size(gui, (selectedLicense == -1) ? ownLicenseText : thirdPartyLicenses[selectedLicense].second, 0.8f);
text_label_size(gui, (selectedLicense == -1) ? main.conf.ownLicenseText : main.conf.thirdPartyLicenses[selectedLicense].second, 0.8f);
}
});
});
@ -2048,7 +1967,7 @@ void Toolbar::reload_theme_list() {
themeData.themeDirList.clear();
themeData.themeDirList.emplace_back("Default");
std::filesystem::path themeDir = main.configPath / "themes";
std::filesystem::path themeDir = main.conf.configPath / "themes";
if(std::filesystem::exists(themeDir) && std::filesystem::is_directory(themeDir)) {
for(auto& theme : std::filesystem::recursive_directory_iterator(themeDir)) {
std::string name = theme.path().stem().string();
@ -2059,7 +1978,7 @@ void Toolbar::reload_theme_list() {
}
}
}
if(!main.g.load_theme(main.configPath, main.conf.themeCurrentlyLoaded))
if(!main.g.load_theme(main.conf.configPath, main.conf.themeCurrentlyLoaded))
themeData.selectedThemeIndex = 0;
themeData.openedSaveAsMenu = false;
@ -2071,15 +1990,15 @@ void Toolbar::file_picker_gui_refresh_entries() {
filePicker.entries.clear();
for(;;) {
try {
for(const std::filesystem::path& entry : std::filesystem::directory_iterator(filePicker.currentSearchPath))
for(const std::filesystem::path& entry : std::filesystem::directory_iterator(main.conf.currentSearchPath))
filePicker.entries.emplace_back(entry);
break;
}
catch(const std::exception& e) {
Logger::get().log("INFO", e.what());
if(filePicker.currentSearchPath == main.homePath) // The home path must exist. If we get errors on the home path, we have a real problem
if(main.conf.currentSearchPath == main.homePath) // The home path must exist. If we get errors on the home path, we have a real problem
throw e;
filePicker.currentSearchPath = main.homePath;
main.conf.currentSearchPath = main.homePath;
}
}
@ -2122,7 +2041,7 @@ void Toolbar::file_picker_gui_refresh_entries() {
void Toolbar::file_picker_gui_done() {
if(!filePicker.fileName.empty()) {
std::filesystem::path pathToRet = filePicker.currentSearchPath / filePicker.fileName;
std::filesystem::path pathToRet = main.conf.currentSearchPath / filePicker.fileName;
if(filePicker.isSaving)
pathToRet = force_extension_on_path(pathToRet, filePicker.extensionFiltersComplete[filePicker.extensionSelected].extensions);
filePicker.postSelectionFunc(pathToRet, filePicker.extensionFiltersComplete[filePicker.extensionSelected]);
@ -2140,11 +2059,11 @@ void Toolbar::file_picker_gui() {
left_to_right_line_layout(gui, [&]() {
svg_icon_button(gui, "file picker back button", "data/icons/backarrow.svg", {
.onClick = [&] {
filePicker.currentSearchPath = filePicker.currentSearchPath.parent_path();
main.conf.currentSearchPath = main.conf.currentSearchPath.parent_path();
file_picker_gui_refresh_entries();
}
});
input_path_field(gui, "file picker path", "Path", &filePicker.currentSearchPath, {
input_path_field(gui, "file picker path", "Path", &main.conf.currentSearchPath, {
.fileTypeRestriction = std::filesystem::file_type::directory,
.onEdit = [&] {
file_picker_gui_refresh_entries();
@ -2195,7 +2114,7 @@ void Toolbar::file_picker_gui() {
gui.set_post_callback_func([&, button, selectedEntry, entry] {
if(selectedEntry && button.clicks >= 2) {
if(std::filesystem::is_directory(entry)) {
filePicker.currentSearchPath = entry;
main.conf.currentSearchPath = entry;
file_picker_gui_refresh_entries();
}
else if(std::filesystem::is_regular_file(entry))

View file

@ -1,7 +1,5 @@
#pragma once
#include "GUIStuff/Elements/ScrollArea.hpp"
#include "GUIStuff/Elements/TextParagraph.hpp"
#include "GUIStuff/GUIManager.hpp"
#include "DrawData.hpp"
#include "Helpers/FileDownloader.hpp"
#include <filesystem>
@ -15,17 +13,6 @@ class MainProgram;
class Toolbar {
public:
struct LogMessage {
static constexpr float DISPLAY_TIME = 8.0f;
static constexpr float FADE_START_TIME = 7.0f;
std::string text;
enum {
COLOR_NORMAL = 0,
COLOR_ERROR
} color;
TimePoint time;
};
struct ChatMessage {
static constexpr float DISPLAY_TIME = 8.0f;
static constexpr float FADE_START_TIME = 7.0f;
@ -70,11 +57,6 @@ class Toolbar {
void open_file_selector(const std::string& filePickerName, const std::vector<ExtensionFilter>& extensionFilters, OpenFileSelectorCallback postSelectionFunc, const std::string& fileName = "", bool isSaving = false);
void save_func();
void save_as_func();
std::filesystem::path& file_selector_path();
void save_palettes();
void load_palettes();
void load_licenses();
void open_chatbox();
void close_chatbox();
@ -87,6 +69,8 @@ class Toolbar {
Vector4f* colorRight = nullptr;
ColorSelectorData colorRightData;
bool drawGui = true;
bool app_close_requested();
private:
static void sdl_open_file_dialog_callback(void* userData, const char * const * fileList, int filter);
@ -113,7 +97,6 @@ class Toolbar {
void color_picker_window(const char* id, Vector4f** color, GUIStuff::Element* b, const ColorSelectorData& colorSelectorData);
void color_palette(const char* id, Vector4f* color, const std::function<void()>& onChange);
void open_world_file(bool isClient, const std::string& netSource, const std::string& serverLocalID);
void load_default_palette();
void load_default_theme();
void about_menu_inner_gui();
void web_version_welcome();
@ -144,21 +127,12 @@ class Toolbar {
} updateCheckerData;
#endif
std::string ownLicenseText;
std::vector<std::pair<std::string, std::string>> thirdPartyLicenses;
int selectedLicense = -1;
std::string downloadNameSet;
struct PaletteData {
struct Palette {
std::string name;
std::vector<Vector3f> colors;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Palette, name, colors)
};
size_t selectedPalette = 0;
std::vector<Palette> palettes;
bool addingPalette = false;
std::string newPaletteStr;
} paletteData;
@ -211,7 +185,6 @@ class Toolbar {
std::vector<ExtensionFilter> extensionFiltersComplete;
std::vector<std::string> extensionFilters;
std::vector<std::filesystem::path> entries;
std::filesystem::path currentSearchPath;
std::filesystem::path currentSelectedPath;
std::string fileName = "";
bool isSaving = false;

View file

@ -167,9 +167,6 @@ void World::init_client(const std::string& serverFullID) {
}
void World::focus_update() {
if(!connection_update())
return;
if(!clientStillConnecting) {
delayedUpdateObjectManager.update(netObjMan);
constexpr float SECONDS_TO_SEND_CAMERA_DATA = 0.5f;
@ -242,7 +239,7 @@ void World::redo_with_checks() {
undo.redo();
}
void World::unfocus_update() {
void World::update() {
connection_update();
}

View file

@ -53,7 +53,7 @@ class World {
WorldScalar calculate_zoom_from_uniform_zoom(WorldScalar uniformZoom, WorldVec oldWindowSize);
void focus_update();
void unfocus_update();
void update();
void on_tab_out();
void draw(SkCanvas* canvas, const DrawData& calledDrawData);

View file

@ -441,14 +441,14 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
mS.m = std::make_unique<MainProgram>();
mS.m->logFile = &mS.logFile;
mS.m->configPath = mS.configPath;
mS.m->conf.configPath = mS.configPath;
mS.m->homePath = mS.homePath;
#ifndef __EMSCRIPTEN__
const char* documentsPathSDL = SDL_GetUserFolder(SDL_FOLDER_DOCUMENTS);
if(!documentsPathSDL) {
documentsPathSDL = SDL_GetUserFolder(SDL_FOLDER_DESKTOP);
if(!documentsPathSDL)
mS.m->documentsPath = mS.m->configPath;
mS.m->documentsPath = mS.m->conf.configPath;
else
mS.m->documentsPath = std::filesystem::path(documentsPathSDL);
}