From 36113024fb01bc0808d02bc23322f4769b269cb1 Mon Sep 17 00:00:00 2001 From: Shaohua Tong Date: Fri, 29 Nov 2019 17:54:09 +0100 Subject: [PATCH] painting circle,square and rectangle with mouse! --- main/main.cpp | 86 +++++++++++++++---- src/DrawRender.cpp | 206 ++++++++++++++++++++++++++++++++++----------- src/DrawRender.hpp | 54 +++++++++--- 3 files changed, 271 insertions(+), 75 deletions(-) diff --git a/main/main.cpp b/main/main.cpp index fa07588..37f6532 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1,5 +1,4 @@ #include -#include "../src/demo.h" #include "internal.hpp" #include "vkvm.hpp" #include "../src/DrawRender.hpp" @@ -8,28 +7,81 @@ /** * @author: Shaohua Tong * @since: v0.0.1 - * Circle and Square and Mouse brush can show in GUI + * draw circle, square, rectangle and mouse drawing */ void outPutPixel(int windowHeight, int windowWidth, vkvm::Color brushColor); int main() { vkvm::initialize(0); - vkvm::registerEvent(vkvm::EventType::MouseDrag, [](){ - std::cout << "drag" << std::endl; - vkvm::Color backgroundColor = vkvm::getBackgroundColor(); - vkvm::Color penColor(160,180,123); - int penWidth = 10; - DrawRender drawRender(vkvm::getWidth(), vkvm::getHeight(), backgroundColor, penColor, penWidth); - drawRender.update(vkvm::getMousePosition(), BRUSH); + vkvm::Color penColor(250,102,0); + int penWidth = 5; + DrawRender drawRender(vkvm::getWidth(), vkvm::getHeight(), vkvm::getBackgroundColor(), penColor, penWidth); + + vkvm::registerEvent(vkvm::EventType::MouseMove, [&drawRender]() { + if(drawRender.getMouseDown() == true) { + vkvm::Coordinates mousePosition = vkvm::getMousePosition(); + mousePosition.y = mousePosition.y - 30; + drawRender.setMousePostion(mousePosition); + + if (drawRender.getTurnOnBrush() == true ) { + drawRender.brushUpdate(mousePosition); + vkvm::callEvent(vkvm::EventType::Redraw); + } + + else if((drawRender.getKeyCode() - 65536) == vkvm::KeyCode::S) { + drawRender.graphicsUpdate(SQUARE); + vkvm::callEvent(vkvm::EventType::Redraw); + } + + else if((drawRender.getKeyCode() - 65536) == vkvm::KeyCode::C) { + drawRender.graphicsUpdate(CIRCLE); + vkvm::callEvent(vkvm::EventType::Redraw); + } + + else if((drawRender.getKeyCode() - 65536) == vkvm::KeyCode::R) { + drawRender.graphicsUpdate(RECTANGLE); + vkvm::callEvent(vkvm::EventType::Redraw); + } + } }); - vkvm::registerEvent(vkvm::EventType::MouseButton, [](){ - vkvm::Color backgroundColor = vkvm::getBackgroundColor(); - vkvm::Color penColor(160,180,123); - int penWidth = 10; - DrawRender drawRender(vkvm::getWidth(), vkvm::getHeight(), backgroundColor, penColor, penWidth); - drawRender.update(vkvm::getMousePosition(), CIRCLE); + vkvm::registerEvent(vkvm::EventType::MouseLeftDown, [&drawRender]() { + if(drawRender.getMouseDown() == false) { + drawRender.setMouseDown(true); + + vkvm::Coordinates mousePosition = vkvm::getMousePosition(); + mousePosition.y = mousePosition.y - 30; + drawRender.setMouseLeftDownPostion(mousePosition); + } + + if((drawRender.getTurnOnBrush() == false) && ((drawRender.getKeyCode() - 65536) == vkvm::KeyCode::B)) { + drawRender.setTurnOnBrush(true); + } + }); + + vkvm::registerEvent(vkvm::EventType::MouseLeftUp, [&drawRender]() { + drawRender.setTurnOnBrush(false); + drawRender.setMouseDown(false); + drawRender.setPainting(false); + }); + + vkvm::registerEvent(vkvm::EventType::KeyDown, [&drawRender]() { + drawRender.setKeyCode(vkvm::getLastPressedKey()); + + if((drawRender.getKeyCode() - 65536) == vkvm::KeyCode::D) { + drawRender.clear(); + vkvm::callEvent(vkvm::EventType::Redraw); + } + }); + + vkvm::registerEvent(vkvm::EventType::KeyUp, [&drawRender]() { + drawRender.setKeyCode(vkvm::getLastPressedKey()); + + if((drawRender.getKeyCode() - 65536) == vkvm::KeyCode::D) { + drawRender.clear(); + vkvm::callEvent(vkvm::EventType::Redraw); + } }); while(1){ @@ -51,6 +103,4 @@ void outPutPixel(int windowHeight, int windowWidth, vkvm::Color penColor) { } std::cout << "\n"; } -} - - +} \ No newline at end of file diff --git a/src/DrawRender.cpp b/src/DrawRender.cpp index 93fa6a4..fbb4c3c 100644 --- a/src/DrawRender.cpp +++ b/src/DrawRender.cpp @@ -1,27 +1,32 @@ // -// Created by shaohuatong on 21.11.19. +// Created by shaohuatong on 28.11.19. // #include "DrawRender.hpp" #include -DrawRender::DrawRender(int windowWidth, int windowHeight, vkvm::Color backgroundColor, vkvm::Color penColor, int penWidth) - : backgroundColor(backgroundColor), penColor(penColor) { +DrawRender::DrawRender(int windowWidth, int windowHeight, vkvm::Color defaultBackgroundColor, vkvm::Color penColor, int penWidth) + : backgroundColor(defaultBackgroundColor), penColor(penColor) { this-> windowWidth = windowWidth; this-> windowHeight = windowHeight; this-> penWidth = penWidth; } -void DrawRender::update(vkvm::Coordinates mousePostion, int type) { - if(type == BRUSH) { - std::vector> circleBrush = brushCreator(mousePostion); - translateToSharedMemory(circleBrush, startX, startY, type); +void DrawRender::graphicsUpdate(int type) { + if(type == CIRCLE || type == SQUARE) { + std::vector> graphics = circleAndSquareCreator(type); + translateToSharedMemory(graphics, startX, startY); + } + else if(type == RECTANGLE) { + std::vector> graphics = rectangleCreator(); + translateToSharedMemory(graphics, startX, startY); + } - } - else if(type == CIRCLE || type == SQUARE) { - std::vector> graphics = circleAndSquareCreator(mousePostion, type); - translateToSharedMemory(graphics, startX, startY, type); - } +} + +void DrawRender::brushUpdate(vkvm::Coordinates mousePosition) { + std::vector> brush = brushCreator(mousePosition); + translateToSharedMemory(brush, startX, startY); } void DrawRender::clear() { @@ -32,20 +37,65 @@ void DrawRender::clear() { } } } +std::vector> DrawRender::rectangleCreator() { + if(painting == true) + clearToSharedMemory(oldGraphics, startX, startY); -std::vector> DrawRender::circleAndSquareCreator(vkvm::Coordinates mousePosition, int type) { + int x_draw = 0; + int y_draw = 0; + std::vector> rectangle; + length = abs(mouseLeftDownPosition.x - mousePosition.x); + width = abs(mouseLeftDownPosition.y - mousePosition.y); + vkvm::Coordinates uperLeft; + vkvm::Coordinates bottomRight; + uperLeft.x = min(mouseLeftDownPosition.x, mousePosition.x); + uperLeft.y = min(mouseLeftDownPosition.y, mousePosition.y); + bottomRight.x = max(mouseLeftDownPosition.x, mousePosition.x); + bottomRight.y = max(mouseLeftDownPosition.y, mousePosition.y); + + rectangle.resize(width); + for(y_draw = 0; y_draw < width; y_draw++) { + rectangle[y_draw].resize(length); + for(x_draw = 0; x_draw < length; x_draw++) { + if((x_draw >= 0 && x_draw <= penWidth) || (y_draw >= 0 && y_draw <= penWidth) + || (x_draw <= length && x_draw >= length - penWidth) + || (y_draw <= width && y_draw >= width - penWidth)) { + rectangle[y_draw][x_draw] = true; + } + } + } + + oldGraphics.resize(width); + for(y_draw = 0; y_draw < width; y_draw++) { + oldGraphics[y_draw].resize(length); + for(x_draw = 0; x_draw < length; x_draw++) { + oldGraphics[y_draw][x_draw] = true; + } + } + + painting = true; + startX = uperLeft.x; + startY = uperLeft.y; + return rectangle; +} +std::vector> DrawRender::circleAndSquareCreator(int type) { + if(painting == true) + clearToSharedMemory(oldGraphics, startX, startY); std::vector> circle; int x_draw = 0; int y_draw = 0; int distance = 0; - radius = std::min(std::min(mousePosition.x, mousePosition.y), - std::min(windowWidth - mousePosition.x, windowHeight - mousePosition.y)) * 0.8; + radius = getDistance(getMouseLeftDownPosition(), getMousePostion()) / 2; + vkvm::Coordinates middlePosition; + middlePosition.x = (mousePosition.x + mouseLeftDownPosition.x) / 2; + middlePosition.y = (mousePosition.y + mouseLeftDownPosition.y) / 2; + vkvm::Coordinates uperLeft; vkvm::Coordinates bottomRight; - uperLeft.x = mousePosition.x - radius; - uperLeft.y = mousePosition.y - radius; - bottomRight.x = mousePosition.x + radius; - bottomRight.y = mousePosition.y + radius; + uperLeft.x = middlePosition.x - radius; + uperLeft.y = middlePosition.y - radius; + bottomRight.x = middlePosition.x + radius; + bottomRight.y = middlePosition.y + radius; vkvm::Coordinates temp; circle.resize(2 * radius); @@ -55,7 +105,7 @@ std::vector> DrawRender::circleAndSquareCreator(vkvm::Coordina if(type == CIRCLE) { temp.x = uperLeft.x + x_draw; temp.y = uperLeft.y + y_draw; - distance = squareOfDistance(temp, mousePosition); + distance = squareOfDistance(temp, middlePosition); if( distance < (radius * radius) && distance > ((radius - penWidth) * (radius - penWidth))) { circle[y_draw][x_draw] = true; @@ -63,14 +113,23 @@ std::vector> DrawRender::circleAndSquareCreator(vkvm::Coordina } if(type == SQUARE) { if((x_draw >= 0 && x_draw <= penWidth) || (y_draw >= 0 && y_draw <= penWidth) - || (x_draw <= 2 * radius && x_draw >= 2 * radius - penWidth) - || (y_draw <= 2 * radius && y_draw >= 2 * radius - penWidth)) { + || (x_draw <= 2 * radius && x_draw >= 2 * radius - penWidth) + || (y_draw <= 2 * radius && y_draw >= 2 * radius - penWidth)) { circle[y_draw][x_draw] = true; } } } } + oldGraphics.resize(2 * radius); + for(y_draw = 0; y_draw < 2 * radius; y_draw++) { + oldGraphics[y_draw].resize(2 * radius); + for(x_draw = 0; x_draw < 2 * radius; x_draw++) { + oldGraphics[y_draw][x_draw] = true; + } + } + + painting = true; startX = uperLeft.x; startY = uperLeft.y; return circle; @@ -109,21 +168,37 @@ std::vector> DrawRender::brushCreator(vkvm::Coordinates mouseP } -void DrawRender::translateToSharedMemory(std::vector> graphics, int startX, int startY, int type) { +void DrawRender::translateToSharedMemory(std::vector> graphics, int startX, int startY) { int x, y; int currentX = startX; int currentY = startY; - if(type == CIRCLE || type == SQUARE || type == BRUSH) { - for(y = 0; y < 2 * radius; y++) { - for(x = 0; x < 2 * radius; x++) { - if(graphics[y][x]) { - vkvm::setPixel(currentX, currentY, penColor); - } - currentX++; + + for(y = 0; y < graphics.size(); y++) { + for(x = 0; x < graphics[y].size(); x++) { + if(graphics[y][x]) { + vkvm::setPixel(currentX, currentY, penColor); } - currentX = startX; - currentY++; + currentX++; } + currentX = startX; + currentY++; + } +} + +void DrawRender::clearToSharedMemory(std::vector> graphics, int startX, int startY) { + int x, y; + int currentX = startX; + int currentY = startY; + + for(y = 0; y < graphics.size(); y++) { + for(x = 0; x < graphics[y].size(); x++) { + if(graphics[y][x]) { + vkvm::setPixel(currentX, currentY, backgroundColor); + } + currentX++; + } + currentX = startX; + currentY++; } } @@ -131,33 +206,70 @@ int DrawRender::squareOfDistance(vkvm::Coordinates x, vkvm::Coordinates y) { return (x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y); } +int DrawRender::getDistance(vkvm::Coordinates x, vkvm::Coordinates y) { + return (int)floor(sqrt(squareOfDistance(x, y))); +} +int DrawRender::min(int x, int y) { + if(x <= y) + return x; + return y; +} +int DrawRender::max(int x, int y) { + if(x<=y) + return y; + return x; +} +vkvm::Coordinates DrawRender::getMouseLeftDownPosition() { + return mouseLeftDownPosition; +} +void DrawRender::setMouseLeftDownPostion(vkvm::Coordinates newMousePosition) { + mouseLeftDownPosition = newMousePosition; +} +vkvm::Coordinates DrawRender::getMousePostion() { + return mousePosition; +} +void DrawRender::setMousePostion(vkvm::Coordinates newMousePosition) { + mousePosition = newMousePosition; +} +void DrawRender::setKeyCode(vkvm::KeyCode newKeyCode) { + keyCode = newKeyCode; +} +vkvm::KeyCode DrawRender::getKeyCode() { + return keyCode; +} +void DrawRender::setTurnOnBrush(bool newTurnOnBrush) { + turnOnBrush = newTurnOnBrush; +} +bool DrawRender::getTurnOnBrush() { + return turnOnBrush; +} +int DrawRender::getRadius() { + return radius; +} +bool DrawRender::getMouseDown() { + return mouseDown; +} +void DrawRender::setMouseDown(bool isMouseDown) { + mouseDown = isMouseDown; +} +bool DrawRender::getPainting() { + return painting; +} - - - - - - - - - - - - - - - +void DrawRender::setPainting(bool isPainting) { + painting = isPainting; +} \ No newline at end of file diff --git a/src/DrawRender.hpp b/src/DrawRender.hpp index 543d238..4b84d95 100644 --- a/src/DrawRender.hpp +++ b/src/DrawRender.hpp @@ -10,39 +10,73 @@ #include #include "Font.h" #include "vector" +#include #define CIRCLE 0 #define SQUARE 1 -#define BRUSH 2 +#define RECTANGLE 2 +#define BRUSH 3 class DrawRender { public: DrawRender(int windowWidth, int windowHeight, vkvm::Color defaultBackgroundColor, vkvm::Color penColor, int penWidth); + void brushUpdate(vkvm::Coordinates mousePosition); + void graphicsUpdate(int type); + + void setMouseLeftDownPostion(vkvm::Coordinates newMousePosition); + vkvm::Coordinates getMouseLeftDownPosition(); + void setMousePostion(vkvm::Coordinates newMousePosition); + vkvm::Coordinates getMousePostion(); + void setKeyCode(vkvm::KeyCode newKeyCode); + void setTurnOnBrush(bool turnOnBrush); + bool getTurnOnBrush(); + vkvm::KeyCode getKeyCode(); + void setKeyCode(); + void setMouseDown(bool isMouseDown); + bool getMouseDown(); + void setPainting(bool isOneFinish); + bool getPainting(); + int getRadius(); - void setType(); - void update(vkvm::Coordinates mousePosition, int type); void clear(); private: + std::vector> oldGraphics; + vkvm::Coordinates mouseLeftDownPosition; vkvm::Coordinates mousePosition; vkvm::Color backgroundColor; vkvm::Color penColor; - int type; + vkvm::KeyCode keyCode; int penWidth; int windowWidth; int windowHeight; - int graphicsHeight; - int graphicsWidth; int radius; + int length; + int width; int startX; int startY; - bool turnOnBrush; + bool painting = true; + bool mouseDown = false; + bool turnOnBrush = false; - std::vector> circleAndSquareCreator(vkvm::Coordinates mousePosition, int type); + std::vector> rectangleCreator(); + std::vector> circleAndSquareCreator(int type); std::vector> brushCreator(vkvm::Coordinates mousePosition); - int squareOfDistance(vkvm::Coordinates x, vkvm::Coordinates y); - void translateToSharedMemory(std::vector> graphics, int startX, int startY, int Type); + int getDistance(vkvm::Coordinates x, vkvm::Coordinates y); + int min(int x, int y); + int max(int x, int y); + void translateToSharedMemory(std::vector> graphics, int startX, int startY); + void clearToSharedMemory(std::vector> graphics, int startX, int startY); }; #endif //SIMPLE_DRAW_DRAWRENDER_HPP + + + + + + + + +