diff --git a/PaintTool/PaintWindow.cpp b/PaintTool/PaintWindow.cpp index 3f5afbd..589f4f9 100644 --- a/PaintTool/PaintWindow.cpp +++ b/PaintTool/PaintWindow.cpp @@ -18,16 +18,21 @@ PaintWindow::PaintWindow() { shape = new sf::CircleShape(freedrawSize); window = new sf::RenderWindow(sf::VideoMode(Width, Height), "Paint Tool v0.1"); + + view.setCenter(Width/2, Height/2); + view.setSize(Width, Height); window->setActive(); + ImGui::SFML::Init(*window); ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable; ImGuiIO testio = ImGui::GetIO(); io = &ImGui::GetIO(); - NewLayer(Width, Width)->GetRenderTexture()->clear(sf::Color::White); + RenderLayer* layer = NewLayer(Width, Height); + layer->GetRenderTexture()->clear(sf::Color::White); window->setFramerateLimit(60); WindowLoop(); @@ -55,6 +60,9 @@ void PaintWindow::WindowLoop() static_cast(circleColor[1] * 255), static_cast(circleColor[2] * 255), static_cast(opacity * 255)); + + window->setView(window->getDefaultView()); + window->setView(view); sf::Event event{}; while (window->pollEvent(event)) @@ -68,8 +76,16 @@ void PaintWindow::WindowLoop() if (event.type == sf::Event::MouseButtonPressed) { - if (io->WantCaptureMouse) break; - MouseDown = true; + if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) + { + if (io->WantCaptureMouse) break; + MouseDown = true; + } + if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Middle)) + { + panning = true; + } + } @@ -79,26 +95,40 @@ void PaintWindow::WindowLoop() while (!lineMouseLocations.empty()) lineMouseLocations.pop(); mouseDoOnce = false; - + panning = false; switch (CurrentTool) { case Tools::EFREEDRAW: break; case Tools::ECIRCLE: Layers[currentLayer]->GetRenderTexture()->draw(circle); break; - case Tools::ERECTANGLE: Layers[currentLayer]->GetRenderTexture()->draw(rectangle); break; + case Tools::ERECTANGLE: + { + //rectangle.setPosition(rectangle.getPosition().x, rectangle.getPosition().y); + Layers[currentLayer]->GetRenderTexture()->draw(rectangle); + break; + } case Tools::ELINE: if (!actionMouseLocations.empty())DrawBetweenPoints(actionMouseLocations.front(), actionMouseLocations.back()); break; default: ; } actionMouseLocations.clear(); } - if (event.type == sf::Event::MouseWheelMoved) + if (event.type == sf::Event::MouseWheelMoved && !io->WantCaptureMouse) { + if (sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt)) + { + int scale = event.mouseWheel.delta * -20; + float aratio = (float)window->getSize().y / (float)window->getSize().x ; + view.setSize(( (float)view.getSize().x + scale), ((float)view.getSize().y + aratio * scale)); + } + else + { freedrawSize += static_cast(event.mouseWheel.delta); if (freedrawSize < 1) freedrawSize = 1; - dynamic_cast(shape)->setRadius(freedrawSize); + } + } @@ -113,18 +143,18 @@ void PaintWindow::WindowLoop() if (event.type == sf::Event::Resized) { - // update the view to the new size of the window - sf::FloatRect visibleArea(0, 0, (float)(event.size.width), (float)(event.size.height)); - window->setView(sf::View(visibleArea)); + sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height); + view.reset(visibleArea); } } - + if (!io->WantCaptureMouse && sf::Mouse::getPosition(*window) != mousePos) { mouseMoved = true; - mousePos = sf::Mouse::getPosition(*window); + sf::Vector2i pixelPos = sf::Mouse::getPosition(*window); + mousePos = (sf::Vector2i)window->mapPixelToCoords(pixelPos, view); } else mouseMoved = false; @@ -137,7 +167,7 @@ void PaintWindow::WindowLoop() { case Tools::EFREEDRAW: { - if (mouseMoved) DrawToLayer(Layers[currentLayer]); + DrawToLayer(Layers[currentLayer]); break; } case Tools::ELINE: @@ -165,7 +195,7 @@ void PaintWindow::WindowLoop() rectangle.setSize(static_cast(scale)); fillShape ? rectangle.setFillColor(colour) :rectangle.setFillColor(sf::Color::Transparent); rectangle.setOutlineColor(colour); - rectangle.setOutlineThickness((freedrawSize * 2)); + fillShape ? rectangle.setOutlineThickness((0)) : rectangle.setOutlineThickness((freedrawSize * 2)); //rectangle.setOutlineThickness(1); rectangle.setPosition(actionMouseLocations.front().x, actionMouseLocations.front().y); break; @@ -177,7 +207,7 @@ void PaintWindow::WindowLoop() float scaleFactor = (sqrt(circle.getScale().x * circle.getScale().x + circle.getScale().y * circle.getScale().y)); fillShape ? circle.setFillColor(colour) : circle.setFillColor(sf::Color::Transparent); circle.setOutlineColor(colour); - circle.setOutlineThickness((freedrawSize * 2) / scaleFactor); + fillShape ? circle.setOutlineThickness(0) : circle.setOutlineThickness((freedrawSize * 2) / scaleFactor); circle.setPointCount(16 + (scaleFactor * 0.2)); circle.setPosition(actionMouseLocations.front().x, actionMouseLocations.front().y); @@ -187,6 +217,12 @@ void PaintWindow::WindowLoop() } mouseDoOnce = true; } + if (panning) + { + actionMouseLocations.push_back(mousePos); + sf::Vector2i deltaMove = actionMouseLocations.front() - actionMouseLocations.back(); + view.move(deltaMove.x, deltaMove.y); + } ImGui::SFML::Update(*window, deltaClock.restart()); @@ -194,33 +230,35 @@ void PaintWindow::WindowLoop() UI_ColorPicker(); UI_Tools(); UI_Debug(); + UI_Instructions(); shape->setFillColor(colour); - + dynamic_cast(shape)->setRadius(freedrawSize); window->clear(sf::Color(200, 200, 200, 255)); - + //window->setView(window->getDefaultView()); if ((CurrentTool == Tools::ELINE && !MouseDown) || CurrentTool != Tools::ELINE) shape->setPosition(static_cast(mousePos.x) - freedrawSize, static_cast(mousePos.y) - freedrawSize); - + + for (RenderLayer* rt : Layers) { rt->UpdateTexture(); rt->GetRenderTexture()->display(); - window->draw(*rt); + if (rt->visible) window->draw(*rt); } - + switch (CurrentTool) { case Tools::EFREEDRAW: {window->draw(*shape); break;} - case Tools::ECIRCLE: {window->draw(circle); break;} - case Tools::ERECTANGLE: {window->draw(rectangle); break;} - case Tools::ELINE: {window->draw(line); window->draw(*shape); break;} + case Tools::ECIRCLE: {if (MouseDown) window->draw(circle); break;} + case Tools::ERECTANGLE: { if (MouseDown) window->draw(rectangle); break;} + case Tools::ELINE: {if (MouseDown) window->draw(line); window->draw(*shape); break;} default: ; } - + ImGui::SFML::Render(*window); window->display(); } @@ -247,13 +285,6 @@ float PaintWindow::Det(sf::Vector2 a, sf::Vector2 b) return (a.x * b.y) - (a.y * b.x); } -/* -bool PaintWindow::Cross(sf::Vector2 a, sf::Vector2 b) -{ - int z = a.x * b.y - a.y * b.y; - -} -*/ std::string PaintWindow::GetDateAndTime() const { std::time_t t = std::time(0); @@ -368,7 +399,7 @@ bool PaintWindow::SaveImage() image.create(Width, Height); for (auto layer : Layers) { - image.draw(*layer); + if (layer->visible) image.draw(*layer); } image.display(); @@ -383,7 +414,7 @@ bool PaintWindow::SaveImage() void PaintWindow::UI_Debug() { - ImGui::Begin("Debug Window"); + ImGui::Begin("Info"); ImGui::Text("Mouse Position:"); ImGui::Text("X: %i Y: %i", mousePos.x, mousePos.y); @@ -411,14 +442,14 @@ void PaintWindow::UI_Debug() ImGui::EndCombo(); } - - + ImGui::Checkbox("Visible", &Layers[currentLayer]->visible); + if (ImGui::Button("New Layer")) { NewLayer(Width, Height); } + - ImGui::Text("Layer Count: %i", Layers.size()); ImGui::End(); } @@ -504,5 +535,29 @@ void PaintWindow::UI_Tools() if (update) ImGui::PopStyleColor(); ImGui::Checkbox("Fill Shape", &fillShape); + + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Spacing(); + + ImGui::SliderFloat("Thickness", &freedrawSize, 1, 60); + + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Spacing(); + + if (ImGui::Button("Save Image")) + { + SaveImage(); + } + ImGui::End(); +} + +void PaintWindow::UI_Instructions() +{ + ImGui::Begin("Instructions"); + ImGui::Text("Scroll to change Thickness"); + ImGui::Text("Alt + Scroll to zoom"); + ImGui::Text("Middle mouse to pan canvas"); ImGui::End(); } \ No newline at end of file diff --git a/PaintTool/PaintWindow.h b/PaintTool/PaintWindow.h index 37520c1..0528e5d 100644 --- a/PaintTool/PaintWindow.h +++ b/PaintTool/PaintWindow.h @@ -42,6 +42,7 @@ class PaintWindow std::vector> actionMouseLocations; sf::VertexArray line = sf::VertexArray(sf::Lines, 2); sf::Clock deltaClock; + ImGuiIO* io; Tools CurrentTool = Tools::EFREEDRAW; ImVec4 ActiveButtonColour = ImColor(27, 54, 74); @@ -68,12 +69,16 @@ class PaintWindow char AtlasInput[128] = "Saved/In"; char AtlasOutput[128] = "Saved/Out"; float AtlasResolutionScale = 1.f; - + bool panning = false; + + sf::View view; + sf::Color colour; void AtlasTextures(int rows, int columns, int imageWidth, int imageHeight); void UI_Debug(); void UI_Tools(); + void UI_Instructions(); void UI_ColorPicker(); void UI_Atlas(); void WindowLoop(); diff --git a/PaintTool/RenderLayer.h b/PaintTool/RenderLayer.h index c70073f..791f71e 100644 --- a/PaintTool/RenderLayer.h +++ b/PaintTool/RenderLayer.h @@ -14,5 +14,7 @@ class RenderLayer : public sf::Sprite sf::RenderTexture* GetRenderTexture() {return RT;} void UpdateTexture(); - + + bool visible = true; + void SetVisible(bool NewVisible) { visible = NewVisible; } }; diff --git a/PaintTool/imgui.ini b/PaintTool/imgui.ini index 9c76fa8..12a3ae2 100644 --- a/PaintTool/imgui.ini +++ b/PaintTool/imgui.ini @@ -24,13 +24,13 @@ Size=291,102 Collapsed=0 [Window][Colour Picker] -Pos=1247,286 -Size=288,295 +Pos=1295,15 +Size=288,309 Collapsed=0 DockId=0x00000004,0 [Window][Debug Window] -Pos=1247,687 +Pos=1308,482 Size=288,137 Collapsed=0 DockId=0x00000003,0 @@ -41,21 +41,34 @@ Size=398,345 Collapsed=0 [Window][Texture Atlas] -Pos=1247,286 -Size=288,295 +Pos=1295,15 +Size=288,309 Collapsed=0 DockId=0x00000004,1 [Window][Tools] -Pos=1247,583 -Size=288,102 +Pos=1295,326 +Size=288,177 Collapsed=0 DockId=0x00000005,0 +[Window][Info] +Pos=1295,505 +Size=288,172 +Collapsed=0 +DockId=0x00000007,0 + +[Window][Instructions] +Pos=6,6 +Size=254,88 +Collapsed=0 + [Docking][Data] -DockNode ID=0x00000001 Pos=1247,286 Size=288,538 Split=Y - DockNode ID=0x00000002 Parent=0x00000001 SizeRef=288,399 Split=Y - DockNode ID=0x00000004 Parent=0x00000002 SizeRef=288,299 Selected=0xA9845671 - DockNode ID=0x00000005 Parent=0x00000002 SizeRef=288,103 Selected=0xD44407B5 - DockNode ID=0x00000003 Parent=0x00000001 SizeRef=288,137 Selected=0x7C31ADA6 +DockNode ID=0x00000001 Pos=1295,15 Size=288,662 Split=Y + DockNode ID=0x00000006 Parent=0x00000001 SizeRef=288,491 Split=Y + DockNode ID=0x00000002 Parent=0x00000006 SizeRef=288,417 Split=Y + DockNode ID=0x00000004 Parent=0x00000002 SizeRef=288,311 Selected=0xA9845671 + DockNode ID=0x00000005 Parent=0x00000002 SizeRef=288,178 Selected=0xD44407B5 + DockNode ID=0x00000003 Parent=0x00000006 SizeRef=288,119 Selected=0x7C31ADA6 + DockNode ID=0x00000007 Parent=0x00000001 SizeRef=288,173 Selected=0xE534E588