#include #include #include #define RAYGUI_IMPLEMENTATION #include #include #include #include #include #include "src/gui/styleDark.hpp" #include "src/gui/Panel.hpp" #include "src/util.hpp" #include "src/UndoRedoManager.hpp" #include "src/Artboards.hpp" #include "src/gui/View.hpp" #include "src/gui/VStack.hpp" #include "src/gui/HStack.hpp" #include "src/gui/Button.hpp" #include "src/gui/Spacer.hpp" #include "src/gui/Icon.hpp" std::ostream& operator<<(std::ostream& os, const Color& c) { os << "Color(" << (int)c.r << ", " << (int)c.g << ", " << (int)c.b << ", " << (int)c.a << ")"; return os; } using namespace mcpaint; using namespace mcpaint::gui; int main() { Vector2 windowSize = {1080, 720}; SetTargetFPS(100); SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_MSAA_4X_HINT); InitWindow(windowSize.x, windowSize.y, "mcpaint"); HideCursor(); bool mouseDrag = false; Dispatch& dispatcher = Dispatch::Instance(); dispatcher.addListener(Event::Type::POINTER_REQUEST, [&mouseDrag](Event e) { mouseDrag = true; }); //SetExitKey(KEY_NULL); Artboards* artboards = new Artboards(); auto gui = View({ VStack({ HStack({ Button(Icon::BRUSH, [](Event e) { std::cout << "CLICK" << std::endl; }), Button("Load", [](Event e) { std::cout << "CLICK" << std::endl; }), Button("clear", [](Event e) { std::cout << "CLICK" << std::endl; }), Spacer(), Button("Tool", [](Event e) { std::cout << "CLICK" << std::endl; }), Button("erase", [](Event e) { std::cout << "CLICK" << std::endl; }), })->background(Theme::ELEMENT)->size({100.0f, 35})->padding(3)->border({.color = Theme::ELEMENT_BORDER, .width = 1}), HStack({ artboards, VStack({ Button("Test"), Spacer() })->background(Theme::ELEMENT)->size({200, 100.0f}) })->background(Theme::ARTBOARD), View()->background(RED)->size({100.0f, 50}), })->background(Theme::ELEMENT) }); UndoRedoManager undoStack; std::vector images; Panel toolBar = Panel({0, 0}, {100.0f, 50}); Panel inspector = Panel({70.0f, 50}, {30.0f, 100.0f}); Font roboto = LoadFontEx("resources/sf-pro.otf", 40, nullptr, 0); SetTextureFilter(roboto.texture, TEXTURE_FILTER_BILINEAR); SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI); //SetWindowSize(1920, 1080); RenderTexture2D canvas = LoadRenderTexture(1080, 720); SetTextureFilter(canvas.texture, TEXTURE_FILTER_TRILINEAR); GuiLoadStyleDark(); GuiSetFont(roboto); GuiSetStyle(DEFAULT, TEXT_SIZE, 15); GuiSetStyle(DEFAULT, BORDER_COLOR_NORMAL, 0x00000000); GuiSetStyle(DEFAULT, BORDER_COLOR_FOCUSED, 0x00000000); Color mainColor = ColorFromHex(0x000000FF); std::vector colors = { ColorFromHex(0x000000FF), ColorFromHex(0xFF0000FF), ColorFromHex(0x00FF00FF), ColorFromHex(0x0000FFFF), ColorFromHex(0xFFFF00FF), ColorFromHex(0xFF00FFFF), ColorFromHex(0x00FFFFFF), ColorFromHex(0xFFFFFFFF), }; BeginTextureMode(canvas); ClearBackground(WHITE); for (int x = 0; x < canvas.texture.width; x += 10) { for (int y = 0; y < canvas.texture.height; y += 10) { if (((x + y) / 10) % 2 == 0) DrawRectangle(x, y, 10, 10, ColorFromHex(0xCCCCCCFF)); } } EndTextureMode(); RenderTexture2D stackCopy = canvas; undoStack.push(canvas); Vector2 lastMouse = { 0, 0 }; bool stroke = false; float strokeWidth = 10; Rectangle canvasRect = {10, 50, canvas.texture.width, canvas.texture.height}; while (!WindowShouldClose()) { float deltaTime = GetFrameTime(); mouseDrag = false; gui->update(deltaTime); // GUI windowSize = {static_cast(GetScreenWidth()), static_cast(GetScreenHeight())}; toolBar.update(deltaTime); Vector2 mouse = GetMousePosition(); if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && CheckCollisionPointRec(mouse, canvasRect)) { mouse = {mouse.x - canvasRect.x, mouse.y - canvasRect.y}; BeginTextureMode(canvas); if (stroke) { Vector2 diff = lastMouse - mouse; float len = Vector2Length(diff); for (int i = 0; i < len / (strokeWidth/2); i++) { Vector2 lerp = Vector2Lerp(lastMouse, mouse, (float)i / (len / (strokeWidth/2))); DrawCircleV(lerp, strokeWidth, mainColor); } //DrawLineEx(lastMouse, mouse, 10, BLACK); } stroke = true; EndTextureMode(); } else { stroke = false; } Rectangle inspectorRect = {inspector.getPosition().x, inspector.getPosition().y, inspector.getSize().x, inspector.getSize().y}; if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON) && CheckCollisionPointRec(mouse, canvasRect) && !CheckCollisionPointRec(mouse, inspectorRect) && !IsFileDropped()) { undoStack.push(canvas); } if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) { BeginTextureMode(canvas); ClearBackground(WHITE); for (int x = 0; x < canvas.texture.width; x += 10) { for (int y = 0; y < canvas.texture.height; y += 10) { if (((x + y) / 10) % 2 == 0) DrawRectangle(x, y, 10, 10, ColorFromHex(0xCCCCCCFF)); } } EndTextureMode(); } if (IsFileDropped()) { FilePathList files = LoadDroppedFiles(); for (int i = 0; i < files.count; i++) { std::cout << files.paths[i] << std::endl; BeginTextureMode(canvas); DrawTexture(LoadTextureFromImage(LoadImage(files.paths[i])), 0, 0, WHITE); EndTextureMode(); } if (files.count > 0) undoStack.push(canvas); UnloadDroppedFiles(files); } BeginDrawing(); ClearBackground(ColorFromHex(0x222222FF)); gui->render(deltaTime); // GUI /* float x = 10; float y = 10; Vector2 pointer = GetMousePosition(); DrawTexturePro(canvas.texture, {0, 0, (float)canvas.texture.width, (float)-canvas.texture.height }, canvasRect, {0, 0}, 0, WHITE); if (CheckCollisionPointRec(pointer, canvasRect)) DrawCircleLinesV(pointer, strokeWidth, mainColor); toolBar.render(deltaTime); GuiButton({x, y, 25, 25}, "#02#"); x += 35; GuiButton({x, y, 25, 25}, "#24#"); x += 35; GuiSetState(STATE_DISABLED); if (undoStack.canUndo()) GuiSetState(STATE_NORMAL); if (GuiButton({x, y, 25, 25}, "#056#")) undoStack.undo(canvas); x += 35; GuiSetState(STATE_DISABLED); if (undoStack.canRedo()) GuiSetState(STATE_NORMAL); if (GuiButton({x, y, 25, 25}, "#057#")) undoStack.redo(canvas); x += 35; y += 50; GuiSetState(STATE_NORMAL); inspector.render(deltaTime); x = inspector.getPosition().x + 10; y = inspector.getPosition().y + 10; float pickerWidth = GuiGetStyle(COLORPICKER, HUEBAR_WIDTH) - GuiGetStyle(COLORPICKER, HUEBAR_PADDING); GuiColorPicker({inspector.getPosition().x + 10, inspector.getPosition().y + 10, inspector.getSize().x - 35 - pickerWidth, 300}, "color", &mainColor); y += 300 + 10; bool l = false; std::string val = std::to_string(strokeWidth); char* c = "ddd"; //GuiTextInputBox({x, y, 90, 25}, "brush size", "mess", nullptr_t, &c, 20, &l); std::string sliderLabel = "brush size"; float labelWidth = GetTextWidth(sliderLabel.c_str()); x += labelWidth + 10; GuiSliderBar({ x, y, inspector.getSize().x - labelWidth - 30, 15}, sliderLabel.c_str(), nullptr, &strokeWidth, 1, 20); x = inspector.getPosition().x + 10; y += 25; DrawCircle(x + 10 + strokeWidth, y + 10 + strokeWidth, strokeWidth, mainColor); DrawCircleLines(x + 10 + strokeWidth, y + 10 + strokeWidth, strokeWidth, WHITE); */ size_t cursorSize = 15; Vector2 cursorPosition = GetMousePosition(); int x = cursorPosition.x; int y = cursorPosition.y; Icon cursor = Icon::REGULAR;; Color cursorColor = BLACK; Color cursorOutline = WHITE; if (mouseDrag) { cursor = Icon::MOVE; cursorColor = WHITE; cursorOutline = BLACK; } // outline DrawIcon(cursor, x + 1, y + 1, cursorSize, cursorOutline); DrawIcon(cursor, x - 1, y - 1, cursorSize, cursorOutline); DrawIcon(cursor, x + 1, y - 1, cursorSize, cursorOutline); DrawIcon(cursor, x - 1, y + 1, cursorSize, cursorOutline); DrawIcon(cursor, x, y, cursorSize, cursorColor); EndDrawing(); lastMouse = mouse; } delete gui; CloseWindow(); return 0; }