You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

279 lines
8.1 KiB

#include <memory>
#include <raylib.h>
#include <iostream>
#define RAYGUI_IMPLEMENTATION
#include <raygui.h>
#include <raymath.h>
#include <algorithm>
#include <vector>
#include <sstream>
#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<Texture2D> 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<Color> 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<float>(GetScreenWidth()), static_cast<float>(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;
}