From 00232fe39031e5faac99d3f69ed21fa7384b371f Mon Sep 17 00:00:00 2001 From: Conrad Date: Fri, 6 Dec 2019 09:31:52 +0100 Subject: [PATCH 01/19] Minor CQ Update --- src/Painting/IntelliPhoto.pro | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Painting/IntelliPhoto.pro b/src/Painting/IntelliPhoto.pro index d1dc823..9cb20dc 100644 --- a/src/Painting/IntelliPhoto.pro +++ b/src/Painting/IntelliPhoto.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -36,7 +36,6 @@ HEADERS += \ FORMS += \ widget.ui - QMAKE_CXXFLAGS QMAKE_LFLAGS From b2c3448e28570b8daf6fe37d245df4344d2cf7eb Mon Sep 17 00:00:00 2001 From: Conrad Date: Fri, 6 Dec 2019 09:34:15 +0100 Subject: [PATCH 02/19] Removed -hopefully- last user files --- .gitignore | 4 + src/Painting/IntelliPhoto.87de10b | 337 ------------------------------ src/Painting/IntelliPhoto.user | 337 ------------------------------ 3 files changed, 4 insertions(+), 674 deletions(-) delete mode 100644 src/Painting/IntelliPhoto.87de10b delete mode 100644 src/Painting/IntelliPhoto.user diff --git a/.gitignore b/.gitignore index 0ec0492..7eacc1b 100644 --- a/.gitignore +++ b/.gitignore @@ -17,5 +17,9 @@ CMakeLists.txt.user* app_version.h phony.c +# Ignore User Files except for the pro file +IntelliPhoto.* +!IntelliPhoto.pro + # macOS Environment Files .DS_STORE diff --git a/src/Painting/IntelliPhoto.87de10b b/src/Painting/IntelliPhoto.87de10b deleted file mode 100644 index 934c6c1..0000000 --- a/src/Painting/IntelliPhoto.87de10b +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - EnvironmentId - {87de10b7-9dd6-4379-8674-fd04613e186e} - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - 80 - true - true - 1 - true - false - 0 - true - true - 0 - 8 - true - 1 - true - true - true - false - - - - ProjectExplorer.Project.PluginSettings - - - -fno-delayed-template-parsing - - true - - - - ProjectExplorer.Project.Target.0 - - Desktop Qt 5.12.5 MinGW 64-bit - Desktop Qt 5.12.5 MinGW 64-bit - qt.qt5.5125.win64_mingw73_kit - 0 - 0 - 0 - - C:/Users/Jonas/Documents/QML/build-Scribble-Desktop_Qt_5_12_5_MinGW_64_bit-Debug - - - true - qmake - - QtProjectManager.QMakeBuildStep - true - - false - false - false - - - true - Make - - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Erstellen - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Bereinigen - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Debug - Debug - Qt4ProjectManager.Qt4BuildConfiguration - 2 - true - - - C:/Users/Jonas/Documents/QML/build-Scribble-Desktop_Qt_5_12_5_MinGW_64_bit-Release - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - - false - false - true - - - true - Make - - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Erstellen - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Bereinigen - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Release - Release - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - - C:/Users/Jonas/Documents/QML/build-Scribble-Desktop_Qt_5_12_5_MinGW_64_bit-Profile - - - true - qmake - - QtProjectManager.QMakeBuildStep - true - - false - true - true - - - true - Make - - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Erstellen - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Bereinigen - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Profile - Profile - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - 3 - - - 0 - Deployment - - ProjectExplorer.BuildSteps.Deploy - - 1 - Deployment-Konfiguration - - ProjectExplorer.DefaultDeployConfiguration - - 1 - - - dwarf - - cpu-cycles - - - 250 - -F - true - 4096 - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - kcachegrind - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - 2 - - Scribble - - Qt4ProjectManager.Qt4RunConfiguration:C:/Users/Jonas/Documents/QML/Scribble/Scribble.pro - - 3768 - false - true - true - false - false - true - - C:/Users/Jonas/Documents/QML/build-Scribble-Desktop_Qt_5_12_5_MinGW_64_bit-Debug - - 1 - - - - ProjectExplorer.Project.TargetCount - 1 - - - ProjectExplorer.Project.Updater.FileVersion - 22 - - - Version - 22 - - diff --git a/src/Painting/IntelliPhoto.user b/src/Painting/IntelliPhoto.user deleted file mode 100644 index 574e287..0000000 --- a/src/Painting/IntelliPhoto.user +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - EnvironmentId - {39e188fc-db7d-4dae-b6b7-f93e7e62e580} - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - 80 - true - true - 1 - true - false - 0 - true - true - 0 - 8 - true - 1 - true - true - true - false - - - - ProjectExplorer.Project.PluginSettings - - - -fno-delayed-template-parsing - - true - - - - ProjectExplorer.Project.Target.0 - - Desktop Qt 5.12.6 MinGW 32-bit - Desktop Qt 5.12.6 MinGW 32-bit - qt.qt5.5126.win32_mingw73_kit - 0 - 0 - 0 - - E:/Users/pauln/Documents/intelliphoto/IntelliPhoto/build-Scribble-Desktop_Qt_5_12_6_MinGW_32_bit-Debug - - - true - qmake - - QtProjectManager.QMakeBuildStep - true - - false - false - false - - - true - Make - - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Erstellen - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Bereinigen - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Debug - Debug - Qt4ProjectManager.Qt4BuildConfiguration - 2 - true - - - E:/Users/pauln/Documents/intelliphoto/IntelliPhoto/build-Scribble-Desktop_Qt_5_12_6_MinGW_32_bit-Release - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - - false - false - true - - - true - Make - - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Erstellen - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Bereinigen - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Release - Release - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - - E:/Users/pauln/Documents/intelliphoto/IntelliPhoto/build-Scribble-Desktop_Qt_5_12_6_MinGW_32_bit-Profile - - - true - qmake - - QtProjectManager.QMakeBuildStep - true - - false - true - true - - - true - Make - - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Erstellen - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Bereinigen - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Profile - Profile - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - 3 - - - 0 - Deployment - - ProjectExplorer.BuildSteps.Deploy - - 1 - Deployment-Konfiguration - - ProjectExplorer.DefaultDeployConfiguration - - 1 - - - dwarf - - cpu-cycles - - - 250 - -F - true - 4096 - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - kcachegrind - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - 2 - - Scribble - - Qt4ProjectManager.Qt4RunConfiguration:E:/Users/pauln/Documents/intelliphoto/IntelliPhoto/Scribble/Scribble.pro - - 3768 - false - true - true - false - false - true - - E:/Users/pauln/Documents/intelliphoto/IntelliPhoto/build-Scribble-Desktop_Qt_5_12_6_MinGW_32_bit-Debug - - 1 - - - - ProjectExplorer.Project.TargetCount - 1 - - - ProjectExplorer.Project.Updater.FileVersion - 22 - - - Version - 22 - - From 2840c8767e93a9e4fa784c5865256becdbc49358 Mon Sep 17 00:00:00 2001 From: Conrad Date: Fri, 6 Dec 2019 09:43:41 +0100 Subject: [PATCH 03/19] Changed Build Exception Rule --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 7eacc1b..f4c35fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ # Build folders -src/*-debug/ -src/*-release/ +src/build-*/ # QT Creator Files *.creator.user* From dc1d42fc9f46dbe26dfb13dc636804f44643364c Mon Sep 17 00:00:00 2001 From: Sonaion Date: Mon, 9 Dec 2019 15:42:57 +0100 Subject: [PATCH 04/19] =?UTF-8?q?Refactroting,=20Performence=20and=20Cover?= =?UTF-8?q?age=20ver=C3=A4nderung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Painting/GUI/IntelliPhotoGui.h | 3 +- src/Painting/Image/IntelliImage.cpp | 8 -- src/Painting/Image/IntelliImage.h | 19 ++- src/Painting/Image/IntelliRasterImage.cpp | 4 + src/Painting/Image/IntelliRasterImage.h | 3 +- src/Painting/Image/IntelliShapedImage.cpp | 89 ++++++------ src/Painting/Image/IntelliShapedImage.h | 1 + src/Painting/IntelliHelper/IntelliHelper.cpp | 35 ----- src/Painting/IntelliHelper/IntelliHelper.h | 27 ++-- src/Painting/Layer/PaintingArea.cpp | 136 ++++++------------- src/Painting/Layer/PaintingArea.h | 1 - 11 files changed, 126 insertions(+), 200 deletions(-) diff --git a/src/Painting/GUI/IntelliPhotoGui.h b/src/Painting/GUI/IntelliPhotoGui.h index fa36326..c872ab8 100644 --- a/src/Painting/GUI/IntelliPhotoGui.h +++ b/src/Painting/GUI/IntelliPhotoGui.h @@ -73,7 +73,8 @@ private: bool saveFile(const QByteArray &fileFormat); // What we'll draw on - PaintingArea *paintingArea; + PaintingArea* paintingArea; + // The menu widgets QMenu *saveAsMenu; diff --git a/src/Painting/Image/IntelliImage.cpp b/src/Painting/Image/IntelliImage.cpp index 879e8c7..814aa36 100644 --- a/src/Painting/Image/IntelliImage.cpp +++ b/src/Painting/Image/IntelliImage.cpp @@ -71,11 +71,3 @@ void IntelliImage::floodFill(const QColor& color){ imageData.fill(color); } - -int IntelliImage::x(){ - return imageData.size().width(); -} - -int IntelliImage::y(){ - return imageData.size().height(); -} diff --git a/src/Painting/Image/IntelliImage.h b/src/Painting/Image/IntelliImage.h index a2fb3c0..894093c 100644 --- a/src/Painting/Image/IntelliImage.h +++ b/src/Painting/Image/IntelliImage.h @@ -13,20 +13,26 @@ enum class ImageType{ Shaped_Image }; -class IntelliImage{ +class IntelliTool; +class IntelliImage{ + friend IntelliTool; protected: void resizeImage(QImage *image, const QSize &newSize); + virtual void calculateVisiblity()=0; QImage imageData; + + //calculate with polygon public: IntelliImage(int weight, int height); virtual ~IntelliImage() = 0; //start on top left - virtual void drawPixel(const QPoint &p1, const QColor& color); - virtual void drawLine(const QPoint &p1, const QPoint& p2, const QColor& color, const int& penWidth); - virtual void floodFill(const QColor& color); + //TODO give tool refrence of image, -> funtkions will not be needed + virtual void drawPixel(const QPoint &p1, const QColor& color); + virtual void drawLine(const QPoint &p1, const QPoint& p2, const QColor& color, const int& penWidth); + virtual void floodFill(const QColor& color); //returns the filtered output virtual QImage getDisplayable(const QSize& displaySize, int alpha)=0; @@ -37,10 +43,9 @@ public: //sets the data for the visible image virtual void setPolygon(const std::vector& polygonData)=0; - virtual bool loadImage(const QString &fileName); - int x(); - int y(); + //loads an image to the ColorBuffer + virtual bool loadImage(const QString &fileName); }; #endif diff --git a/src/Painting/Image/IntelliRasterImage.cpp b/src/Painting/Image/IntelliRasterImage.cpp index b73c264..3cedbeb 100644 --- a/src/Painting/Image/IntelliRasterImage.cpp +++ b/src/Painting/Image/IntelliRasterImage.cpp @@ -12,6 +12,10 @@ IntelliRasterImage::~IntelliRasterImage(){ } +void IntelliRasterImage::calculateVisiblity(){ + +} + QImage IntelliRasterImage::getDisplayable(int alpha){ return getDisplayable(imageData.size(), alpha); } diff --git a/src/Painting/Image/IntelliRasterImage.h b/src/Painting/Image/IntelliRasterImage.h index 3b3e600..2d6d809 100644 --- a/src/Painting/Image/IntelliRasterImage.h +++ b/src/Painting/Image/IntelliRasterImage.h @@ -4,7 +4,8 @@ #include"Image/IntelliImage.h" class IntelliRasterImage : public IntelliImage{ - +protected: + virtual void calculateVisiblity() override; public: IntelliRasterImage(int weight, int height); virtual ~IntelliRasterImage() override; diff --git a/src/Painting/Image/IntelliShapedImage.cpp b/src/Painting/Image/IntelliShapedImage.cpp index 6b7a829..7baf81c 100644 --- a/src/Painting/Image/IntelliShapedImage.cpp +++ b/src/Painting/Image/IntelliShapedImage.cpp @@ -13,59 +13,66 @@ IntelliShapedImage::~IntelliShapedImage(){ } QImage IntelliShapedImage::getDisplayable(int alpha){ - return getDisplayable(imageData.size()); + return getDisplayable(imageData.size(),alpha); +} + +void IntelliShapedImage::calculateVisiblity(){ + if(polygonData.size()<=2){ + QColor clr; + for(int y=0; y(polygonData.size()-1); i++){ + QPoint B = polygonData[static_cast(i)]; + QPoint C = polygonData[static_cast(i+1)]; + QPoint P(x,y); + cutNumeber+=IntelliHelper::isInTriangle(A,B,C,P); + } + if(cutNumeber%2==0){ + clr = imageData.pixelColor(x,y); + clr.setAlpha(0); + imageData.setPixelColor(x,y,clr); + }else{ + clr = imageData.pixelColor(x,y); + clr.setAlpha(255); + imageData.setPixelColor(x,y,clr); + } + } + } } QImage IntelliShapedImage::getDisplayable(const QSize& displaySize, int alpha){ - if(polygonData.size()==0){ - QImage copy = imageData; - for(int y = 0; y not in Polygon - if(!(cutNumberX&1)){ - QColor tmpColor(0,0,0); - tmpColor.setAlpha(0); - copy.setPixelColor(startPoint,tmpColor); - }else{ - QColor clr = copy.pixelColor(x,y); - clr.setAlpha(alpha); - copy.setPixelColor(x,y,clr); - } + for(int x = 0; x& polygonData){ if(polygonData.size()<3){ - return; - } - for(auto element:polygonData){ - this->polygonData.push_back(QPoint(element.x(), element.y())); + this->polygonData.clear(); + }else{ + this->polygonData.clear(); + for(auto element:polygonData){ + this->polygonData.push_back(QPoint(element.x(), element.y())); + } } + calculateVisiblity(); return; } diff --git a/src/Painting/Image/IntelliShapedImage.h b/src/Painting/Image/IntelliShapedImage.h index 6c38366..0039c3b 100644 --- a/src/Painting/Image/IntelliShapedImage.h +++ b/src/Painting/Image/IntelliShapedImage.h @@ -6,6 +6,7 @@ class IntelliShapedImage : public IntelliImage{ protected: + virtual void calculateVisiblity() override; std::vector polygonData; public: IntelliShapedImage(int weight, int height); diff --git a/src/Painting/IntelliHelper/IntelliHelper.cpp b/src/Painting/IntelliHelper/IntelliHelper.cpp index ef0e8fb..0cd9460 100644 --- a/src/Painting/IntelliHelper/IntelliHelper.cpp +++ b/src/Painting/IntelliHelper/IntelliHelper.cpp @@ -1,39 +1,4 @@ #include"IntelliHelper.h" #include -int IntelliHelper::orientation(QPoint& p, QPoint& q, QPoint& r){ - int value = (q.y()-p.y())*(r.x()-q.x())- - (q.x()-p.x())*(r.y()-q.y()); - if(value==0) return 0; - return (value>0)?1:2; -} -bool IntelliHelper::onSegment(QPoint& p1, QPoint& q, QPoint& p2){ - return (q.x() >= std::min(p1.x(),p2.x()) && q.x() <= std::max(p1.x(), p2.x()) && - q.y() >= std::min(p1.y(),p2.y()) && q.y() <= std::max(p1.y(), p2.y())); -} - -bool IntelliHelper::hasIntersection(QPoint& p1, QPoint& q1, QPoint& p2, QPoint& q2){ - int o1 = IntelliHelper::orientation(p1,q1,p2); - int o2 = IntelliHelper::orientation(p1,q1,q2); - int o3 = IntelliHelper::orientation(p2,q2,p1); - int o4 = IntelliHelper::orientation(p2,q2,q1); - - // General case - if (o1 != o2 && o3 != o4) - return true; - - // p1, q1 and p2 are colinear and p2 lies on segment p1q1 - if (o1 == 0 && onSegment(p1, p2, q1)) return true; - - // p1, q1 and q2 are colinear and q2 lies on segment p1q1 - if (o2 == 0 && onSegment(p1, q2, q1)) return true; - - // p2, q2 and p1 are colinear and p1 lies on segment p2q2 - if (o3 == 0 && onSegment(p2, p1, q2)) return true; - - // p2, q2 and q1 are colinear and q1 lies on segment p2q2 - if (o4 == 0 && onSegment(p2, q1, q2)) return true; - - return false; // Doesn't fall in any of the above cases -} diff --git a/src/Painting/IntelliHelper/IntelliHelper.h b/src/Painting/IntelliHelper/IntelliHelper.h index 9e273f6..ef6b32a 100644 --- a/src/Painting/IntelliHelper/IntelliHelper.h +++ b/src/Painting/IntelliHelper/IntelliHelper.h @@ -5,18 +5,27 @@ class IntelliHelper{ + public: - //checks for orientation: - // 0 - colinear - // 1 - clockwise - // 2 - counter clockwise - static int orientation(QPoint& p1, QPoint& p2, QPoint& p3); - //checks if q is on segment p1-p2 - static bool onSegment(QPoint& p1, QPoint& q, QPoint& p2); + static inline float sign(QPoint& p1, QPoint& p2, QPoint& p3){ + return (p1.x()-p3.x())*(p2.y()-p3.y())-(p2.x()-p3.x())*(p1.y()-p3.y()); + } - //cheks if p1-q1 intersects with p2-q2 - static bool hasIntersection(QPoint& p1, QPoint& q1, QPoint& p2, QPoint& q2); + + static inline bool isInTriangle(QPoint& A, QPoint& B, QPoint& C, QPoint& P){ + float val1, val2, val3; + bool neg, pos; + + val1 = IntelliHelper::sign(P,A,B); + val2 = IntelliHelper::sign(P,B,C); + val3 = IntelliHelper::sign(P,C,A); + + neg = (val1<0.f) || (val2<0.f) || (val3<0.f); + pos = (val1>0.f) || (val2>0.f) || (val3>0.f); + + return !(neg && pos); + } }; #endif diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index 58fc159..ac898f1 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -10,26 +10,18 @@ #include #include -#define EXPORT PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) :QWidget(parent){ this->setUp(maxWidth, maxHeight); - -#ifdef EXPORT - this->addLayer(maxWidth, maxHeight); - layerStructure[0].image->floodFill(QColor(255,255,255,255)); - activeLayer=0; -#endif -#ifndef EXPORT //tetsing this->addLayer(200,200,0,0,ImageType::Shaped_Image); layerStructure[0].image->floodFill(QColor(255,0,0,255)); std::vector polygon; - polygon.push_back(QPoint(100,0)); - polygon.push_back(QPoint(200,200)); - polygon.push_back(QPoint(0,200)); - polygon.push_back(QPoint(100,0)); + polygon.push_back(QPoint(100,000)); + polygon.push_back(QPoint(200,100)); + polygon.push_back(QPoint(100,200)); + polygon.push_back(QPoint(000,100)); layerStructure[0].image->setPolygon(polygon); this->addLayer(200,200,150,150); @@ -37,7 +29,6 @@ PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) layerStructure[1].alpha=200; activeLayer=1; -#endif } void PaintingArea::setUp(int maxWidth, int maxHeight){ @@ -45,7 +36,6 @@ void PaintingArea::setUp(int maxWidth, int maxHeight){ this->maxWidth = maxWidth; this->maxHeight = maxHeight; Canvas = new QImage(maxWidth,maxHeight, QImage::Format_ARGB32); - Canvas->fill(Qt::GlobalColor::white); // Roots the widget to the top left even if resized setAttribute(Qt::WA_StaticContents); @@ -69,11 +59,11 @@ int PaintingArea::addLayer(int width, int height, int widthOffset, int heightOff } newLayer.alpha = 255; this->layerStructure.push_back(newLayer); - return layerStructure.size()-1; + return static_cast(layerStructure.size())-1; } void PaintingArea::deleteLayer(int index){ - if(index(layerStructure.size())){ this->layerStructure.erase(layerStructure.begin()+index); if(activeLayer>=index){ activeLayer--; @@ -82,26 +72,24 @@ void PaintingArea::deleteLayer(int index){ } void PaintingArea::deleteActiveLayer(){ + if(activeLayer>=0 && activeLayer < static_cast(layerStructure.size())){ this->layerStructure.erase(layerStructure.begin()+activeLayer); activeLayer--; + } } void PaintingArea::setLayerToActive(int index) { - if(index=0&&index(layerStructure.size())){ this->activeLayer=index; } } void PaintingArea::setAlphaToLayer(int index, int alpha){ - if(index=0&&index(layerStructure.size())){ + layerStructure[static_cast(index)].alpha=alpha; } } -QPixmap PaintingArea::getAsPixmap(){ - assembleLayers(); - return QPixmap::fromImage(*Canvas); -} // Used to load the image and place it in the widget bool PaintingArea::openImage(const QString &fileName) @@ -109,7 +97,7 @@ bool PaintingArea::openImage(const QString &fileName) if(this->activeLayer==-1){ return false; } - IntelliImage* active = layerStructure[activeLayer].image; + IntelliImage* active = layerStructure[static_cast(activeLayer)].image; bool open = active->loadImage(fileName); update(); return open; @@ -133,7 +121,6 @@ bool PaintingArea::saveImage(const QString &fileName, const char *fileFormat) } } - if (Canvas->save(fileName, fileFormat)) { return true; } else { @@ -144,13 +131,13 @@ bool PaintingArea::saveImage(const QString &fileName, const char *fileFormat) // Used to change the pen color void PaintingArea::setPenColor(const QColor &newColor) { - myPenColor = newColor; + //TODO give to Tool } // Used to change the pen width void PaintingArea::setPenWidth(int newWidth) { - myPenWidth = newWidth; + //TODO give to Tool } // Color the image area with white @@ -158,48 +145,50 @@ void PaintingArea::clearImage(int r, int g, int b){ if(this->activeLayer==-1){ return; } - IntelliImage* active = layerStructure[activeLayer].image; + IntelliImage* active = layerStructure[static_cast(activeLayer)].image; active->floodFill(QColor(r, g, b, 255)); update(); } void PaintingArea::activate(int a){ - this->setLayerToActive(a); + if(a>=0 && a < static_cast(layerStructure.size())){ + this->setLayerToActive(a); + } } void PaintingArea::setAlpha(int a){ if(activeLayer>=0){ - layerStructure[activeLayer].alpha=a; + layerStructure[static_cast(activeLayer)].alpha=a; } } void PaintingArea::getMoveUp(int a){ - layerStructure[activeLayer].heightOffset-=a; + layerStructure[static_cast(activeLayer)].heightOffset-=a; } void PaintingArea::getMoveDown(int a){ - layerStructure[activeLayer].heightOffset+=a; + layerStructure[static_cast(activeLayer)].heightOffset+=a; } void PaintingArea::getMoveRight(int a){ - layerStructure[activeLayer].widthOffset+=a; + layerStructure[static_cast(activeLayer)].widthOffset+=a; } void PaintingArea::getMoveLeft(int a){ - layerStructure[activeLayer].widthOffset-=a; + layerStructure[static_cast(activeLayer)].widthOffset-=a; } void PaintingArea::getMoveLayerUp(){ - if(activeLayer=0){ - std::swap(layerStructure[activeLayer], layerStructure[activeLayer+1]); + if(activeLayer(layerStructure.size()-1) && activeLayer>=0){ + std::swap(layerStructure[static_cast(activeLayer)], layerStructure[static_cast(activeLayer+1)]); activeLayer++; } } void PaintingArea::getMoveLayerDown(){ if(activeLayer>0){ - std::swap(layerStructure[activeLayer], layerStructure[activeLayer-1]); + std::swap(layerStructure[static_cast(activeLayer)], layerStructure[static_cast(activeLayer-1)]); activeLayer--; } } @@ -209,18 +198,7 @@ void PaintingArea::getMoveLayerDown(){ // Set that we are currently drawing void PaintingArea::mousePressEvent(QMouseEvent *event) { - if (event->button() == Qt::LeftButton) { - if(this->activeLayer==-1){ - return; - } - LayerObject& active = layerStructure[activeLayer]; - - int x = event->x()-active.widthOffset; - int y = event->y()-active.heightOffset; - //TODO CALCULATE LAST POINT - lastPoint=QPoint(x,y); - scribbling = true; - } + //TODO implement in tool } @@ -229,38 +207,13 @@ void PaintingArea::mousePressEvent(QMouseEvent *event) // from the last position to the current void PaintingArea::mouseMoveEvent(QMouseEvent *event) { - if ((event->buttons() & Qt::LeftButton) && scribbling){ - if(this->activeLayer==-1){ - return; - } - LayerObject& active = layerStructure[activeLayer]; - - int x = event->x()-active.widthOffset; - int y = event->y()-active.heightOffset; - - //TODO CALCULATE NEW POINT - drawLineTo(QPoint(x,y)); - update(); - } + //TODO implement in Tool } // If the button is released we set variables to stop drawing void PaintingArea::mouseReleaseEvent(QMouseEvent *event) { - if (event->button() == Qt::LeftButton && scribbling) { - if(this->activeLayer==-1){ - return; - } - LayerObject& active = layerStructure[activeLayer]; - - int x = event->x()-active.widthOffset; - int y = event->y()-active.heightOffset; - - //TODO CALCULATE NEW POINT - drawLineTo(QPoint(x,y)); - update(); - scribbling = false; - } + //TODO implement in tool } // QPainter provides functions to draw on the widget @@ -280,32 +233,17 @@ void PaintingArea::paintEvent(QPaintEvent *event) // to cut down on the need to resize the image void PaintingArea::resizeEvent(QResizeEvent *event) { - if(this->activeLayer==-1){ - return; - } - LayerObject active = layerStructure[activeLayer]; - - QPainter painter(this); - QRect dirtyRec(QPoint(0,0), event->size()); - painter.drawImage(dirtyRec, active.image->getDisplayable(event->size(), active.alpha), dirtyRec); + //TODO Doesnt quit work update(); } void PaintingArea::drawLineTo(const QPoint &endPoint) { - //// Used to draw on the widget - if(this->activeLayer==-1){ - return; - } - LayerObject active = layerStructure[activeLayer]; - active.image->drawLine(lastPoint, endPoint,myPenColor, myPenWidth); - lastPoint = endPoint; - update(); } void PaintingArea::resizeImage(QImage *image_res, const QSize &newSize){ - image_res->scaled(newSize,Qt::IgnoreAspectRatio); + //TODO implement } void PaintingArea::assembleLayers(bool forSaving){ @@ -321,13 +259,17 @@ void PaintingArea::assembleLayers(bool forSaving){ QColor clr_0; QColor clr_1; for(int y=0; y=maxHeight) break; for(int x=0; x=maxWidth) break; clr_0=Canvas->pixelColor(layer.widthOffset+x, layer.heightOffset+y); clr_1=cpy.pixelColor(x,y); - float t = (float)clr_1.alpha()/255.f; - int r =(float)clr_1.red()*(t)+(float)clr_0.red()*(1.-t); - int g =(float)clr_1.green()*(t)+(float)clr_0.green()*(1.-t); - int b =(float)clr_1.blue()*(t)+(float)clr_0.blue()*(1.-t); + float t = static_cast(clr_1.alpha())/255.f; + int r =static_cast(static_cast(clr_1.red())*(t)+static_cast(clr_0.red())*(1.f-t)+0.5f); + int g =static_cast(static_cast(clr_1.green())*(t)+static_cast(clr_0.green())*(1.f-t)+0.5f); + int b =static_cast(static_cast(clr_1.blue())*(t)+static_cast(clr_0.blue()*(1.f-t))+0.5f); int a =std::min(clr_0.alpha()+clr_1.alpha(), 255); clr_0.setRed(r); clr_0.setGreen(g); diff --git a/src/Painting/Layer/PaintingArea.h b/src/Painting/Layer/PaintingArea.h index febf33b..b8e172d 100644 --- a/src/Painting/Layer/PaintingArea.h +++ b/src/Painting/Layer/PaintingArea.h @@ -47,7 +47,6 @@ public: int penWidth() const { return myPenWidth; } - QPixmap getAsPixmap(); public slots: // Events to handle From f26bd13fa592b48ecaaaa42f81a60a0c4da186e0 Mon Sep 17 00:00:00 2001 From: Sonaion Date: Mon, 9 Dec 2019 15:45:05 +0100 Subject: [PATCH 05/19] Documentation -Update --- src/Painting/Layer/PaintingArea.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index ac898f1..e68498a 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -233,7 +233,7 @@ void PaintingArea::paintEvent(QPaintEvent *event) // to cut down on the need to resize the image void PaintingArea::resizeEvent(QResizeEvent *event) { - //TODO Doesnt quit work + //TODO wait till tool works update(); } @@ -252,7 +252,6 @@ void PaintingArea::assembleLayers(bool forSaving){ }else{ Canvas->fill(Qt::GlobalColor::black); } - //TODO interpolation of alpha for saving for(size_t i=0; igetDisplayable(layer.alpha); From 4c61bae14b9103cdfa10422ec6686d2c3014df4d Mon Sep 17 00:00:00 2001 From: Sonaion Date: Mon, 9 Dec 2019 18:58:38 +0100 Subject: [PATCH 06/19] Gui Update --- src/Painting/GUI/IntelliPhotoGui.cpp | 357 ++++++++++++--------------- src/Painting/GUI/IntelliPhotoGui.h | 66 ++--- src/Painting/Layer/PaintingArea.cpp | 83 +++---- src/Painting/Layer/PaintingArea.h | 22 +- 4 files changed, 209 insertions(+), 319 deletions(-) diff --git a/src/Painting/GUI/IntelliPhotoGui.cpp b/src/Painting/GUI/IntelliPhotoGui.cpp index 65a03d5..075e3ac 100644 --- a/src/Painting/GUI/IntelliPhotoGui.cpp +++ b/src/Painting/GUI/IntelliPhotoGui.cpp @@ -71,53 +71,23 @@ void IntelliPhotoGui::save() saveFile(fileFormat); } -// Opens a dialog to change the pen color -void IntelliPhotoGui::penColor() -{ - // Store the chosen color from the dialog - QColor newColor = QColorDialog::getColor(paintingArea->penColor()); - - // If a valid color set it - if (newColor.isValid()) - paintingArea->setPenColor(newColor); -} - -// Opens a dialog that allows the user to change the pen width -void IntelliPhotoGui::penWidth() -{ - // Stores button value - bool ok; - - // tr("Painting") is the title - // the next tr is the text to display - // Get the current pen width - // Define the min, max, step and ok button - int newWidth = QInputDialog::getInt(this, tr("Painting"), - tr("Select pen width:"), - paintingArea->penWidth(), - 1, 500, 1, &ok); - // Change the pen width - if (ok) - paintingArea->setPenWidth(newWidth); -} - // Opens a dialog that allows the user to create a New Layer void IntelliPhotoGui::newLayer() { // Stores button value - bool ok; + bool ok1, ok2; // tr("New Layer") is the title // the next tr is the text to display // Define the standard Value, min, max, step and ok button int width = QInputDialog::getInt(this, tr("New Layer"), tr("Width:"), - 200,1, 500, 1, &ok); + 200,1, 500, 1, &ok1); int height = QInputDialog::getInt(this, tr("New Layer"), tr("Height:"), - 200,1, 500, 1, &ok); + 200,1, 500, 1, &ok2); // Create New Layer - if (ok) + if (ok1&&ok2) { int layer = paintingArea->addLayer(width,height,100,100); paintingArea->activate(layer); @@ -135,12 +105,108 @@ void IntelliPhotoGui::deleteLayer() // Define the standard Value, min, max, step and ok button int layerNumber = QInputDialog::getInt(this, tr("delete Layer"), tr("Number:"), - 1,1, 500, 1, &ok); + 1,0, 500, 1, &ok); // Create New Layer if (ok) - paintingArea->deleteLayer(layerNumber-1); + paintingArea->deleteLayer(layerNumber); } + +void IntelliPhotoGui::onSetAlpha(){ + // Stores button value + bool ok1, ok2; + + // tr("Layer to set on") is the title + // the next tr is the text to display + // Define the standard Value, min, max, step and ok button + int layer = QInputDialog::getInt(this, tr("Layer to set on"), + tr("Layer:"), + -1,-1,100,1, &ok1); + // tr("New Alpha") is the title + int alpha = QInputDialog::getInt(this, tr("New Alpha"), + tr("Alpha:"), + 255,0, 255, 1, &ok2); + if (ok1&&ok2) + { + paintingArea->setAlphaToLayer(layer,alpha); + } +} + +void IntelliPhotoGui::onMoveUp(){ + paintingArea->moveActive(0,-2); + update(); +} + +void IntelliPhotoGui::onMoveDown(){ + paintingArea->moveActive(0,2); + update(); +} + +void IntelliPhotoGui::onMoveLeft(){ + paintingArea->moveActive(-2,0); + update(); +} + +void IntelliPhotoGui::onMoveRight(){ + paintingArea->moveActive(2,0); + update(); +} + +void IntelliPhotoGui::onMoveLayerUp(){ + paintingArea->moveActiveLayer(1); + update(); +} + +void IntelliPhotoGui::onMoveLayerDown(){ + paintingArea->moveActiveLayer(-1); + update(); +} + +void IntelliPhotoGui::onClearedPressed(){ + // Stores button value + bool ok1, ok2, ok3, ok4; + + // tr("Red Input") is the title + // the next tr is the text to display + // Define the standard Value, min, max, step and ok button + int red = QInputDialog::getInt(this, tr("Red Input"), + tr("Red:"), + 255,0, 255,1, &ok1); + // tr("Green Input") is the title + int green = QInputDialog::getInt(this, tr("Green Input"), + tr("Green:"), + 255,0, 255, 1, &ok2); + // tr("Blue Input") is the title + int blue = QInputDialog::getInt(this, tr("Blue Input"), + tr("Blue:"), + 255,0, 255, 1, &ok3); + // tr("Alpha Input") is the title + int alpha = QInputDialog::getInt(this, tr("Alpha Input"), + tr("Alpha:"), + 255,0, 255, 1, &ok4); + if (ok1&&ok2&&ok3&&ok4) + { + paintingArea->clearImage(red, green, blue, alpha); + } +} + +void IntelliPhotoGui::onActivePressed(){ + // Stores button value + bool ok1; + + // tr("Layer to set on") is the title + // the next tr is the text to display + // Define the standard Value, min, max, step and ok button + int layer = QInputDialog::getInt(this, tr("Layer to set on"), + tr("Layer:"), + -1,0,255,1, &ok1); + if (ok1) + { + paintingArea->setLayerToActive(layer); + } +}; + + // Open an about dialog void IntelliPhotoGui::about() { @@ -149,88 +215,9 @@ void IntelliPhotoGui::about() tr("

IntelliPhoto Some nice ass looking software

")); } -void IntelliPhotoGui::onSetAlpha(){ - int a = this->setAlphaEdit->text().toInt(); - if (a >= 0 && a < 256) - emit this->sendAlpha(a); -} - -void IntelliPhotoGui::onMoveUp(){ - int a = 5; - emit this->moveUp(a); -} - -void IntelliPhotoGui::onMoveDown(){ - int a = 5; - emit this->moveDown(a); -} - -void IntelliPhotoGui::onMoveLeft(){ - int a = 5; - emit this->moveLeft(a); -} - -void IntelliPhotoGui::onMoveRight(){ - int a = 5; - emit this->moveRight(a); -} - -void IntelliPhotoGui::onMoveLayerUp(){ - emit this->moveLayerUp(); -} - -void IntelliPhotoGui::onMoveLayerDown(){ - emit this->moveLayerDown(); -} - -void IntelliPhotoGui::onClearedPressed(){ - int r = this->RedEdit->text().toInt(); - int g = this->GreenEdit->text().toInt(); - int b = this->BlueEdit->text().toInt(); - if(r < 256 && r >= 0 && g < 256 && g >= 0 && b < 256 && b >= 0) - emit this->sendClearColor(r,g,b); -} - -void IntelliPhotoGui::onActivePressed(){ - int a = this->selectActiveEdit->text().toInt(); - emit this->sendActiveLayer(a-1); -}; - - - // Define menu actions that call functions void IntelliPhotoGui::createActions() { - //connect signal and slots of gui element - connect(this->clearButton, SIGNAL(clicked()), this, SLOT(onClearedPressed())); - connect(this, SIGNAL(sendClearColor(int,int,int)), paintingArea, SLOT(clearImage(int, int, int))); - - connect(this->selectActiveButton, SIGNAL(clicked()), this, SLOT(onActivePressed())); - connect(this, SIGNAL(sendActiveLayer(int)),paintingArea, SLOT(activate(int))); - - connect(this->setAlphaButton, SIGNAL(clicked()), this, SLOT(onSetAlpha())); - connect(this, SIGNAL(sendAlpha(int)), paintingArea, SLOT(setAlpha(int))); - - connect(this->moveActiveUpButton, SIGNAL(clicked()), this, SLOT(onMoveUp())); - connect(this, SIGNAL(moveUp(int)), paintingArea, SLOT(getMoveUp(int))); - - connect(this->moveActiveDownButton, SIGNAL(clicked()), this, SLOT(onMoveDown())); - connect(this, SIGNAL(moveDown(int)), paintingArea, SLOT(getMoveDown(int))); - - connect(this->moveActiveLeftButton, SIGNAL(clicked()), this, SLOT(onMoveLeft())); - connect(this, SIGNAL(moveLeft(int)), paintingArea, SLOT(getMoveLeft(int))); - - connect(this->moveActiveRightButton, SIGNAL(clicked()), this, SLOT(onMoveRight())); - connect(this, SIGNAL(moveRight(int)), paintingArea, SLOT(getMoveRight(int))); - - connect(this->layerMoveActiveDownButton, SIGNAL(clicked()), this, SLOT(onMoveLayerDown())); - connect(this, SIGNAL(moveLayerDown()), paintingArea, SLOT(getMoveLayerDown())); - - connect(this->layerMoveActiveUpButton, SIGNAL(clicked()), this, SLOT(onMoveLayerUp())); - connect(this, SIGNAL(moveLayerUp()), paintingArea, SLOT(getMoveLayerUp())); - - - // Create the action tied to the menu openAct = new QAction(tr("&Open..."), this); @@ -258,16 +245,14 @@ void IntelliPhotoGui::createActions() saveAsActs.append(action); } - QAction *action = new QAction("PNG-8", this); - - // Set an action for each file format - action->setData("PNG"); - + //set exporter to actions + QAction *pngSaveAction = new QAction("PNG-8", this); + pngSaveAction->setData("PNG"); // When clicked call IntelliPhotoGui::save() - connect(action, SIGNAL(triggered()), this, SLOT(save())); + connect(pngSaveAction, SIGNAL(triggered()), this, SLOT(save())); + // Attach each PNG in save Menu + saveAsActs.append(pngSaveAction); - // Attach each file format option menu item to Save As - saveAsActs.append(action); // Create exit action and tie to IntelliPhotoGui::close() @@ -275,24 +260,11 @@ void IntelliPhotoGui::createActions() exitAct->setShortcuts(QKeySequence::Quit); connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); - // Create pen color action and tie to IntelliPhotoGui::penColor() - penColorAct = new QAction(tr("&Pen Color..."), this); - connect(penColorAct, SIGNAL(triggered()), this, SLOT(penColor())); - - // Create pen width action and tie to IntelliPhotoGui::penWidth() - penWidthAct = new QAction(tr("Pen &Width..."), this); - connect(penWidthAct, SIGNAL(triggered()), this, SLOT(penWidth())); - - // Create clear screen action and tie to IntelliPhotoGui::clearImage() - clearScreenAct = new QAction(tr("&Clear Screen"), this); - clearScreenAct->setShortcut(tr("Ctrl+L")); - connect(clearScreenAct, SIGNAL(triggered()), - this, SLOT(onClearedPressed())); - // Create New Layer action and tie to IntelliPhotoGui::newLayer() newLayerAct = new QAction(tr("&New Layer..."), this); connect(newLayerAct, SIGNAL(triggered()), this, SLOT(newLayer())); + // Delete New Layer action and tie to IntelliPhotoGui::deleteLayer() deleteLayerAct = new QAction(tr("&Delete Layer..."), this); connect(deleteLayerAct, SIGNAL(triggered()), this, SLOT(deleteLayer())); @@ -301,6 +273,39 @@ void IntelliPhotoGui::createActions() deleteActiveLayerAct = new QAction(tr("&Delete active Layer"), this); connect(deleteActiveLayerAct, SIGNAL(triggered()), paintingArea, SLOT(deleteActiveLayer())); + clearedActions = new QAction(tr("&clear Image"), this); + connect(clearedActions, SIGNAL(triggered()), this, SLOT(onClearedPressed())); + + setActiveAction = new QAction(tr("&set Active"), this); + connect(setActiveAction, SIGNAL(triggered()), this, SLOT(onActivePressed())); + + setAlphaAction = new QAction(tr("&set Alpha"), this); + connect(setAlphaAction, SIGNAL(triggered()), this, SLOT(onSetAlpha())); + + moveUpAction = new QAction(tr("&move Up"), this); + moveUpAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Up)); + connect(moveUpAction, SIGNAL(triggered()), this, SLOT(onMoveUp())); + + moveDownAction = new QAction(tr("&move Down"), this); + moveDownAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Down)); + connect(moveDownAction, SIGNAL(triggered()), this, SLOT(onMoveDown())); + + moveLeftAction = new QAction(tr("&move Left"), this); + moveLeftAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Left)); + connect(moveLeftAction, SIGNAL(triggered()), this, SLOT(onMoveLeft())); + + moveRightAction = new QAction(tr("&move Right"), this); + moveRightAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Right)); + connect(moveRightAction, SIGNAL(triggered()), this, SLOT(onMoveRight())); + + moveLayerUpAction = new QAction(tr("&move Layer Up"), this); + moveLayerUpAction->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Up)); + connect(moveLayerUpAction, SIGNAL(triggered()), this, SLOT(onMoveLayerUp())); + + moveLayerDownAction= new QAction(tr("&move Layer Down"), this); + moveLayerDownAction->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Down)); + connect(moveLayerDownAction, SIGNAL(triggered()), this, SLOT(onMoveLayerDown())); + // Create about action and tie to IntelliPhotoGui::about() aboutAct = new QAction(tr("&About"), this); connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); @@ -328,10 +333,15 @@ void IntelliPhotoGui::createMenus() // Attach all actions to Options optionMenu = new QMenu(tr("&Options"), this); - optionMenu->addAction(penColorAct); - optionMenu->addAction(penWidthAct); - optionMenu->addSeparator(); - optionMenu->addAction(clearScreenAct); + optionMenu->addAction(clearedActions); + optionMenu->addAction(setActiveAction); + optionMenu->addAction(setAlphaAction); + optionMenu->addAction(moveUpAction); + optionMenu->addAction(moveDownAction); + optionMenu->addAction(moveLeftAction); + optionMenu->addAction(moveRightAction); + optionMenu->addAction(moveLayerUpAction); + optionMenu->addAction(moveLayerDownAction); // Attach all actions to Layer layerMenu = new QMenu(tr("&Layer"), this); @@ -339,6 +349,9 @@ void IntelliPhotoGui::createMenus() layerMenu->addAction(deleteLayerAct); layerMenu->addAction(deleteActiveLayerAct); + //Attach all Tool Options + toolMenu = new QMenu(tr("&Tools"), this); + // Attach all actions to Help helpMenu = new QMenu(tr("&Help"), this); helpMenu->addAction(aboutAct); @@ -348,6 +361,7 @@ void IntelliPhotoGui::createMenus() menuBar()->addMenu(fileMenu); menuBar()->addMenu(optionMenu); menuBar()->addMenu(layerMenu); + menuBar()->addMenu(toolMenu); menuBar()->addMenu(helpMenu); } @@ -361,67 +375,10 @@ void IntelliPhotoGui::createGui(){ centralGuiWidget->setLayout(mainLayout); //create Gui elements - clearButton = new QPushButton("set Color"); paintingArea = new PaintingArea(); - - RedLabel = new QLabel("Red:"); - GreenLabel = new QLabel("Green"); - BlueLabel = new QLabel("Blue:"); - RedEdit = new QLineEdit("255"); - GreenEdit = new QLineEdit("255"); - BlueEdit = new QLineEdit("255"); - RedEdit->setMaximumSize(150,20); - GreenEdit->setMaximumSize(150,20); - BlueEdit->setMaximumSize(150,20); - - selectActiveButton = new QPushButton("select Active"); - selectActiveLabel = new QLabel("Active:"); - selectActiveEdit = new QLineEdit("1"); - selectActiveLabel->setMaximumSize(150,20); - selectActiveEdit->setMaximumSize(150,20); - - setAlphaButton = new QPushButton("set Alpha"); - setAlphaLabel = new QLabel("Alpha:"); - setAlphaEdit = new QLineEdit("255"); - setAlphaEdit->setMaximumSize(150,20); - - moveActiveUpButton = new QPushButton("move 5 Up"); - moveActiveDownButton = new QPushButton("move 5 Down"); - moveActiveLeftButton = new QPushButton("move 5 Left"); - moveActiveRightButton = new QPushButton("move 5 Right"); - - layerMoveActiveDownButton = new QPushButton("Active Layer Down"); - layerMoveActiveUpButton = new QPushButton("Active Layer Up"); - - //set gui elemtns position - mainLayout->addWidget(clearButton,0,25,1,1); - mainLayout->addWidget(paintingArea,0,0,25,25); - - mainLayout->addWidget(RedLabel,1,25,1,1); - mainLayout->addWidget(RedEdit,2,25,1,1); - mainLayout->addWidget(GreenLabel,3,25,1,1); - mainLayout->addWidget(GreenEdit,4,25,1,1); - mainLayout->addWidget(BlueLabel,5,25,1,1); - mainLayout->addWidget(BlueEdit,6,25,1,1); - - mainLayout->addWidget(selectActiveButton,7,25,1,1); - mainLayout->addWidget(selectActiveLabel,8,25,1,1); - mainLayout->addWidget(selectActiveEdit,9,25,1,1); - - mainLayout->addWidget(setAlphaButton,10,25,1,1); - mainLayout->addWidget(setAlphaLabel,11,25,1,1); - mainLayout->addWidget(setAlphaEdit,12,25,1,1); - - mainLayout->addWidget(moveActiveUpButton,13,25,1,1); - mainLayout->addWidget(moveActiveDownButton,14,25,1,1); - mainLayout->addWidget(moveActiveLeftButton,15,25,1,1); - mainLayout->addWidget(moveActiveRightButton,16,25,1,1); - - mainLayout->addWidget(layerMoveActiveDownButton,17,25,1,1); - mainLayout->addWidget(layerMoveActiveUpButton,18,25,1,1); - - + //set gui elements + mainLayout->addWidget(paintingArea); } void IntelliPhotoGui::setIntelliStyle(){ diff --git a/src/Painting/GUI/IntelliPhotoGui.h b/src/Painting/GUI/IntelliPhotoGui.h index c872ab8..ac2c2f9 100644 --- a/src/Painting/GUI/IntelliPhotoGui.h +++ b/src/Painting/GUI/IntelliPhotoGui.h @@ -18,19 +18,9 @@ class IntelliPhotoGui : public QMainWindow // for all Qt objects // QObjects handle events Q_OBJECT -signals: - void sendClearColor(int r, int g, int b); - void sendActiveLayer(int a); - void sendAlpha(int a); - void moveUp(int a); - void moveDown(int a); - void moveRight(int a); - void moveLeft(int a); - void moveLayerUp(); - void moveLayerDown(); - public: IntelliPhotoGui(); + protected: // Function used to close an event void closeEvent(QCloseEvent *event) override; @@ -39,8 +29,6 @@ protected: private slots: void open(); void save(); - void penColor(); - void penWidth(); void newLayer(); void deleteLayer(); void about(); @@ -59,73 +47,55 @@ private: // Will tie user actions to functions void createActions(); void createMenus(); - //setup GUI elements void createGui(); - //set style of the GUI void setIntelliStyle(); + // Will check if changes have occurred since last save bool maybeSave(); - // Opens the Save dialog and saves bool saveFile(const QByteArray &fileFormat); // What we'll draw on PaintingArea* paintingArea; - // The menu widgets QMenu *saveAsMenu; QMenu *fileMenu; QMenu *optionMenu; QMenu *layerMenu; + QMenu *toolMenu; QMenu *helpMenu; - // All the actions that can occur QAction *openAct; - - // Actions tied to specific file formats - QList saveAsActs; QAction *exitAct; - QAction *penColorAct; - QAction *penWidthAct; - QAction *clearScreenAct; + QAction *newLayerAct; QAction *deleteLayerAct; QAction *deleteActiveLayerAct; + QAction *aboutAct; QAction *aboutQtAct; + QAction* clearedActions; + QAction* setActiveAction; + QAction* setAlphaAction; + QAction* moveUpAction; + QAction* moveDownAction; + QAction* moveLeftAction; + QAction* moveRightAction; + QAction* moveLayerUpAction; + QAction* moveLayerDownAction; + + // Actions tied to specific file formats + QList saveAsActs; + //main GUI elements QWidget* centralGuiWidget; QGridLayout *mainLayout; - QPushButton *clearButton; - - QLabel *RedLabel; - QLabel *GreenLabel; - QLabel *BlueLabel; - QLineEdit *RedEdit; - QLineEdit *GreenEdit; - QLineEdit *BlueEdit; - - QPushButton *selectActiveButton; - QLabel *selectActiveLabel; - QLineEdit *selectActiveEdit; - - QPushButton *setAlphaButton; - QLabel *setAlphaLabel; - QLineEdit *setAlphaEdit; - - QPushButton *moveActiveUpButton; - QPushButton *moveActiveDownButton; - QPushButton *moveActiveLeftButton; - QPushButton *moveActiveRightButton; - - QPushButton *layerMoveActiveDownButton; - QPushButton *layerMoveActiveUpButton; }; diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index e68498a..1a7b9c1 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -128,71 +128,36 @@ bool PaintingArea::saveImage(const QString &fileName, const char *fileFormat) } } -// Used to change the pen color -void PaintingArea::setPenColor(const QColor &newColor) -{ - //TODO give to Tool -} - -// Used to change the pen width -void PaintingArea::setPenWidth(int newWidth) -{ - //TODO give to Tool -} // Color the image area with white -void PaintingArea::clearImage(int r, int g, int b){ +void PaintingArea::clearImage(int r, int g, int b, int a){ if(this->activeLayer==-1){ return; } IntelliImage* active = layerStructure[static_cast(activeLayer)].image; - active->floodFill(QColor(r, g, b, 255)); - + active->floodFill(QColor(r, g, b, a)); update(); } +void PaintingArea::moveActive(int x, int y){ + layerStructure[static_cast(activeLayer)].widthOffset += x; + layerStructure[static_cast(activeLayer)].heightOffset += y; +} + +void PaintingArea::moveActiveLayer(int idx){ + if(idx==1){ + this->activeLayerUp(); + }else if(idx==-1){ + this->activeLayerDown(); + } +} + void PaintingArea::activate(int a){ if(a>=0 && a < static_cast(layerStructure.size())){ this->setLayerToActive(a); } } -void PaintingArea::setAlpha(int a){ - if(activeLayer>=0){ - layerStructure[static_cast(activeLayer)].alpha=a; - } -} - -void PaintingArea::getMoveUp(int a){ - layerStructure[static_cast(activeLayer)].heightOffset-=a; -} - -void PaintingArea::getMoveDown(int a){ - layerStructure[static_cast(activeLayer)].heightOffset+=a; -} - -void PaintingArea::getMoveRight(int a){ - layerStructure[static_cast(activeLayer)].widthOffset+=a; -} - -void PaintingArea::getMoveLeft(int a){ - layerStructure[static_cast(activeLayer)].widthOffset-=a; -} - -void PaintingArea::getMoveLayerUp(){ - if(activeLayer(layerStructure.size()-1) && activeLayer>=0){ - std::swap(layerStructure[static_cast(activeLayer)], layerStructure[static_cast(activeLayer+1)]); - activeLayer++; - } -} - -void PaintingArea::getMoveLayerDown(){ - if(activeLayer>0){ - std::swap(layerStructure[static_cast(activeLayer)], layerStructure[static_cast(activeLayer-1)]); - activeLayer--; - } -} - // If a mouse button is pressed check if it was the // left button and if so store the current position // Set that we are currently drawing @@ -237,15 +202,25 @@ void PaintingArea::resizeEvent(QResizeEvent *event) update(); } -void PaintingArea::drawLineTo(const QPoint &endPoint) -{ - -} void PaintingArea::resizeImage(QImage *image_res, const QSize &newSize){ //TODO implement } +void PaintingArea::activeLayerUp(){ + if(activeLayer!=-1 && activeLayer0){ + std::swap(layerStructure[activeLayer], layerStructure[activeLayer-1]); + activeLayer--; + } +} + void PaintingArea::assembleLayers(bool forSaving){ if(forSaving){ Canvas->fill(Qt::GlobalColor::transparent); diff --git a/src/Painting/Layer/PaintingArea.h b/src/Painting/Layer/PaintingArea.h index b8e172d..f164cae 100644 --- a/src/Painting/Layer/PaintingArea.h +++ b/src/Painting/Layer/PaintingArea.h @@ -36,31 +36,19 @@ public: void deleteLayer(int index); void setLayerToActive(int index); void setAlphaToLayer(int index, int alpha); + void clearImage(int r, int g, int b, int a); + void moveActive(int x, int y); + void moveActiveLayer(int idx); // Has the image been modified since last save bool isModified() const { return modified; } - void setPenColor(const QColor &newColor); - QColor penColor() const { return myPenColor; } - - void setPenWidth(int newWidth); - int penWidth() const { return myPenWidth; } - - public slots: // Events to handle - void clearImage(int r, int g, int b); void activate(int a); void deleteActiveLayer(); - void setAlpha(int a); - void getMoveUp(int a); - void getMoveDown(int a); - void getMoveRight(int a); - void getMoveLeft(int a); - void getMoveLayerUp(); - void getMoveLayerDown(); //void setUp helper for konstruktor void setUp(int maxWidth, int maxHeight); protected: @@ -76,7 +64,8 @@ protected: void resizeEvent(QResizeEvent *event) override; private: - + void activeLayerUp(); + void activeLayerDown(); QImage* Canvas; int maxWidth; @@ -87,7 +76,6 @@ private: void assembleLayers(bool forSaving=false); - void drawLineTo(const QPoint &endPoint); void resizeImage(QImage *image_res, const QSize &newSize); // Will be marked true or false depending on if From 62e144abd45c642104b0b2793045b2e67e4e9c97 Mon Sep 17 00:00:00 2001 From: Sonaion Date: Mon, 9 Dec 2019 19:38:32 +0100 Subject: [PATCH 07/19] Naming Convention and clean-up dead code --- src/Painting/GUI/IntelliPhotoGui.cpp | 168 +++++++++++++-------------- src/Painting/GUI/IntelliPhotoGui.h | 62 +++++----- src/Painting/Layer/PaintingArea.cpp | 90 +++++++------- src/Painting/Layer/PaintingArea.h | 40 +++---- 4 files changed, 171 insertions(+), 189 deletions(-) diff --git a/src/Painting/GUI/IntelliPhotoGui.cpp b/src/Painting/GUI/IntelliPhotoGui.cpp index 075e3ac..350293d 100644 --- a/src/Painting/GUI/IntelliPhotoGui.cpp +++ b/src/Painting/GUI/IntelliPhotoGui.cpp @@ -39,7 +39,7 @@ void IntelliPhotoGui::closeEvent(QCloseEvent *event) // Check if the current image has been changed and then // open a dialog to open a file -void IntelliPhotoGui::open() +void IntelliPhotoGui::slotOpen() { // Check if changes have been made since last save // maybeSave() returns true if no changes have been made @@ -54,12 +54,12 @@ void IntelliPhotoGui::open() // If we have a file name load the image and place // it in the paintingArea if (!fileName.isEmpty()) - paintingArea->openImage(fileName); + paintingArea->open(fileName); } } // Called when the user clicks Save As in the menu -void IntelliPhotoGui::save() +void IntelliPhotoGui::slotSave() { // A QAction represents the action of the user clicking QAction *action = qobject_cast(sender()); @@ -72,7 +72,7 @@ void IntelliPhotoGui::save() } // Opens a dialog that allows the user to create a New Layer -void IntelliPhotoGui::newLayer() +void IntelliPhotoGui::slotCreateNewLayer() { // Stores button value bool ok1, ok2; @@ -90,12 +90,12 @@ void IntelliPhotoGui::newLayer() if (ok1&&ok2) { int layer = paintingArea->addLayer(width,height,100,100); - paintingArea->activate(layer); + paintingArea->slotActivateLayer(layer); } } // Opens a dialog that allows the user to delete a Layer -void IntelliPhotoGui::deleteLayer() +void IntelliPhotoGui::slotDeleteLayer() { // Stores button value bool ok; @@ -112,7 +112,7 @@ void IntelliPhotoGui::deleteLayer() } -void IntelliPhotoGui::onSetAlpha(){ +void IntelliPhotoGui::slotSetActiveAlpha(){ // Stores button value bool ok1, ok2; @@ -128,41 +128,41 @@ void IntelliPhotoGui::onSetAlpha(){ 255,0, 255, 1, &ok2); if (ok1&&ok2) { - paintingArea->setAlphaToLayer(layer,alpha); + paintingArea->setAlphaOfLayer(layer,alpha); } } -void IntelliPhotoGui::onMoveUp(){ - paintingArea->moveActive(0,-2); +void IntelliPhotoGui::slotPositionMoveUp(){ + paintingArea->movePositionActive(0,-2); update(); } -void IntelliPhotoGui::onMoveDown(){ - paintingArea->moveActive(0,2); +void IntelliPhotoGui::slotPositionMoveDown(){ + paintingArea->movePositionActive(0,2); update(); } -void IntelliPhotoGui::onMoveLeft(){ - paintingArea->moveActive(-2,0); +void IntelliPhotoGui::slotPositionMoveLeft(){ + paintingArea->movePositionActive(-2,0); update(); } -void IntelliPhotoGui::onMoveRight(){ - paintingArea->moveActive(2,0); +void IntelliPhotoGui::slotPositionMoveRight(){ + paintingArea->movePositionActive(2,0); update(); } -void IntelliPhotoGui::onMoveLayerUp(){ +void IntelliPhotoGui::slotMoveLayerUp(){ paintingArea->moveActiveLayer(1); update(); } -void IntelliPhotoGui::onMoveLayerDown(){ +void IntelliPhotoGui::slotMoveLayerDown(){ paintingArea->moveActiveLayer(-1); update(); } -void IntelliPhotoGui::onClearedPressed(){ +void IntelliPhotoGui::slotClearActiveLayer(){ // Stores button value bool ok1, ok2, ok3, ok4; @@ -186,11 +186,11 @@ void IntelliPhotoGui::onClearedPressed(){ 255,0, 255, 1, &ok4); if (ok1&&ok2&&ok3&&ok4) { - paintingArea->clearImage(red, green, blue, alpha); + paintingArea->floodFill(red, green, blue, alpha); } } -void IntelliPhotoGui::onActivePressed(){ +void IntelliPhotoGui::slotSetActiveLayer(){ // Stores button value bool ok1; @@ -208,7 +208,7 @@ void IntelliPhotoGui::onActivePressed(){ // Open an about dialog -void IntelliPhotoGui::about() +void IntelliPhotoGui::slotAboutDialog() { // Window title and text to display QMessageBox::about(this, tr("About Painting"), @@ -219,13 +219,13 @@ void IntelliPhotoGui::about() void IntelliPhotoGui::createActions() { // Create the action tied to the menu - openAct = new QAction(tr("&Open..."), this); + actionOpen = new QAction(tr("&Open..."), this); // Define the associated shortcut key - openAct->setShortcuts(QKeySequence::Open); + actionOpen->setShortcuts(QKeySequence::Open); // Tie the action to IntelliPhotoGui::open() - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(actionOpen, SIGNAL(triggered()), this, SLOT(slotOpen())); // Get a list of the supported file formats // QImageWriter is used to write images to files @@ -239,80 +239,80 @@ void IntelliPhotoGui::createActions() action->setData(format); // When clicked call IntelliPhotoGui::save() - connect(action, SIGNAL(triggered()), this, SLOT(save())); + connect(action, SIGNAL(triggered()), this, SLOT(slotSave())); // Attach each file format option menu item to Save As - saveAsActs.append(action); + actionSaveAs.append(action); } //set exporter to actions QAction *pngSaveAction = new QAction("PNG-8", this); pngSaveAction->setData("PNG"); // When clicked call IntelliPhotoGui::save() - connect(pngSaveAction, SIGNAL(triggered()), this, SLOT(save())); + connect(pngSaveAction, SIGNAL(triggered()), this, SLOT(slotSave())); // Attach each PNG in save Menu - saveAsActs.append(pngSaveAction); + actionSaveAs.append(pngSaveAction); // Create exit action and tie to IntelliPhotoGui::close() - exitAct = new QAction(tr("&Exit"), this); - exitAct->setShortcuts(QKeySequence::Quit); - connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); + actionOpen = new QAction(tr("&Exit"), this); + actionOpen->setShortcuts(QKeySequence::Quit); + connect(actionOpen, SIGNAL(triggered()), this, SLOT(close())); // Create New Layer action and tie to IntelliPhotoGui::newLayer() - newLayerAct = new QAction(tr("&New Layer..."), this); - connect(newLayerAct, SIGNAL(triggered()), this, SLOT(newLayer())); + actionCreateNewLayer = new QAction(tr("&New Layer..."), this); + connect(actionCreateNewLayer, SIGNAL(triggered()), this, SLOT(slotCreateNewLayer())); // Delete New Layer action and tie to IntelliPhotoGui::deleteLayer() - deleteLayerAct = new QAction(tr("&Delete Layer..."), this); - connect(deleteLayerAct, SIGNAL(triggered()), this, SLOT(deleteLayer())); + actionDeleteLayer = new QAction(tr("&Delete Layer..."), this); + connect(actionDeleteLayer, SIGNAL(triggered()), this, SLOT(slotDeleteLayer())); // Delete Active Layer action and tie to paintingArea::deleteActiveLayerLayer() - deleteActiveLayerAct = new QAction(tr("&Delete active Layer"), this); - connect(deleteActiveLayerAct, SIGNAL(triggered()), paintingArea, SLOT(deleteActiveLayer())); + actionDeleteActiveLayer = new QAction(tr("&Delete active Layer"), this); + connect(actionDeleteActiveLayer, SIGNAL(triggered()), paintingArea, SLOT(deleteActiveLayer())); - clearedActions = new QAction(tr("&clear Image"), this); - connect(clearedActions, SIGNAL(triggered()), this, SLOT(onClearedPressed())); + actionFloodFill = new QAction(tr("&clear Image"), this); + connect(actionFloodFill, SIGNAL(triggered()), this, SLOT(slotClearActiveLayer())); - setActiveAction = new QAction(tr("&set Active"), this); - connect(setActiveAction, SIGNAL(triggered()), this, SLOT(onActivePressed())); + actionSetActiveLayer = new QAction(tr("&set Active"), this); + connect(actionSetActiveLayer, SIGNAL(triggered()), this, SLOT(slotSetActiveLayer())); - setAlphaAction = new QAction(tr("&set Alpha"), this); - connect(setAlphaAction, SIGNAL(triggered()), this, SLOT(onSetAlpha())); + actionSetActiveAlpha = new QAction(tr("&set Alpha"), this); + connect(actionSetActiveAlpha, SIGNAL(triggered()), this, SLOT(slotSetActiveAlpha())); - moveUpAction = new QAction(tr("&move Up"), this); - moveUpAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Up)); - connect(moveUpAction, SIGNAL(triggered()), this, SLOT(onMoveUp())); + actionMovePositionUp = new QAction(tr("&move Up"), this); + actionMovePositionUp->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Up)); + connect(actionMovePositionUp, SIGNAL(triggered()), this, SLOT(slotPositionMoveUp())); - moveDownAction = new QAction(tr("&move Down"), this); - moveDownAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Down)); - connect(moveDownAction, SIGNAL(triggered()), this, SLOT(onMoveDown())); + actionMovePositionDown = new QAction(tr("&move Down"), this); + actionMovePositionDown->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Down)); + connect(actionMovePositionDown, SIGNAL(triggered()), this, SLOT(slotPositionMoveDown())); - moveLeftAction = new QAction(tr("&move Left"), this); - moveLeftAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Left)); - connect(moveLeftAction, SIGNAL(triggered()), this, SLOT(onMoveLeft())); + actionMovePositionLeft = new QAction(tr("&move Left"), this); + actionMovePositionLeft->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Left)); + connect(actionMovePositionLeft, SIGNAL(triggered()), this, SLOT(slotPositionMoveLeft())); - moveRightAction = new QAction(tr("&move Right"), this); - moveRightAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Right)); - connect(moveRightAction, SIGNAL(triggered()), this, SLOT(onMoveRight())); + actionMovePositionRight = new QAction(tr("&move Right"), this); + actionMovePositionRight->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Right)); + connect(actionMovePositionRight, SIGNAL(triggered()), this, SLOT(slotPositionMoveRight())); - moveLayerUpAction = new QAction(tr("&move Layer Up"), this); - moveLayerUpAction->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Up)); - connect(moveLayerUpAction, SIGNAL(triggered()), this, SLOT(onMoveLayerUp())); + actionMoveLayerUp = new QAction(tr("&move Layer Up"), this); + actionMoveLayerUp->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Up)); + connect(actionMoveLayerUp, SIGNAL(triggered()), this, SLOT(slotMoveLayerUp())); - moveLayerDownAction= new QAction(tr("&move Layer Down"), this); - moveLayerDownAction->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Down)); - connect(moveLayerDownAction, SIGNAL(triggered()), this, SLOT(onMoveLayerDown())); + actionMoveLayerDown= new QAction(tr("&move Layer Down"), this); + actionMoveLayerDown->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Down)); + connect(actionMoveLayerDown, SIGNAL(triggered()), this, SLOT(slotMoveLayerDown())); // Create about action and tie to IntelliPhotoGui::about() - aboutAct = new QAction(tr("&About"), this); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); + actionAboutDialog = new QAction(tr("&About"), this); + connect(actionAboutDialog, SIGNAL(triggered()), this, SLOT(slotAboutDialog())); // Create about Qt action and tie to IntelliPhotoGui::aboutQt() - aboutQtAct = new QAction(tr("About &Qt"), this); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + actionAboutQtDialog = new QAction(tr("About &Qt"), this); + connect(actionAboutQtDialog, SIGNAL(triggered()), qApp, SLOT(aboutQt())); } // Create the menubar @@ -320,42 +320,42 @@ void IntelliPhotoGui::createMenus() { // Create Save As option and the list of file types saveAsMenu = new QMenu(tr("&Save As"), this); - foreach (QAction *action, saveAsActs) + foreach (QAction *action, actionSaveAs) saveAsMenu->addAction(action); // Attach all actions to File fileMenu = new QMenu(tr("&File"), this); - fileMenu->addAction(openAct); + fileMenu->addAction(actionOpen); fileMenu->addMenu(saveAsMenu); fileMenu->addSeparator(); - fileMenu->addAction(exitAct); + fileMenu->addAction(actionOpen); // Attach all actions to Options optionMenu = new QMenu(tr("&Options"), this); - optionMenu->addAction(clearedActions); - optionMenu->addAction(setActiveAction); - optionMenu->addAction(setAlphaAction); - optionMenu->addAction(moveUpAction); - optionMenu->addAction(moveDownAction); - optionMenu->addAction(moveLeftAction); - optionMenu->addAction(moveRightAction); - optionMenu->addAction(moveLayerUpAction); - optionMenu->addAction(moveLayerDownAction); + optionMenu->addAction(actionFloodFill); + optionMenu->addAction(actionSetActiveLayer); + optionMenu->addAction(actionSetActiveAlpha); + optionMenu->addAction(actionMovePositionUp); + optionMenu->addAction(actionMovePositionDown); + optionMenu->addAction(actionMovePositionLeft); + optionMenu->addAction(actionMovePositionRight); + optionMenu->addAction(actionMoveLayerUp); + optionMenu->addAction(actionMoveLayerDown); // Attach all actions to Layer layerMenu = new QMenu(tr("&Layer"), this); - layerMenu->addAction(newLayerAct); - layerMenu->addAction(deleteLayerAct); - layerMenu->addAction(deleteActiveLayerAct); + layerMenu->addAction(actionCreateNewLayer); + layerMenu->addAction(actionDeleteLayer); + layerMenu->addAction(actionDeleteActiveLayer); //Attach all Tool Options toolMenu = new QMenu(tr("&Tools"), this); // Attach all actions to Help helpMenu = new QMenu(tr("&Help"), this); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); + helpMenu->addAction(actionAboutDialog); + helpMenu->addAction(actionAboutQtDialog); // Add menu items to the menubar menuBar()->addMenu(fileMenu); @@ -435,7 +435,7 @@ bool IntelliPhotoGui::saveFile(const QByteArray &fileFormat) } else { // Call for the file to be saved - return paintingArea->saveImage(fileName, fileFormat.constData()); + return paintingArea->save(fileName, fileFormat.constData()); } } diff --git a/src/Painting/GUI/IntelliPhotoGui.h b/src/Painting/GUI/IntelliPhotoGui.h index ac2c2f9..87b529f 100644 --- a/src/Painting/GUI/IntelliPhotoGui.h +++ b/src/Painting/GUI/IntelliPhotoGui.h @@ -27,21 +27,21 @@ protected: // The events that can be triggered private slots: - void open(); - void save(); - void newLayer(); - void deleteLayer(); - void about(); + void slotOpen(); + void slotSave(); + void slotCreateNewLayer(); + void slotDeleteLayer(); + void slotAboutDialog(); - void onClearedPressed(); - void onActivePressed(); - void onSetAlpha(); - void onMoveUp(); - void onMoveDown(); - void onMoveLeft(); - void onMoveRight(); - void onMoveLayerUp(); - void onMoveLayerDown(); + void slotClearActiveLayer(); + void slotSetActiveLayer(); + void slotSetActiveAlpha(); + void slotPositionMoveUp(); + void slotPositionMoveDown(); + void slotPositionMoveLeft(); + void slotPositionMoveRight(); + void slotMoveLayerUp(); + void slotMoveLayerDown(); private: // Will tie user actions to functions @@ -70,28 +70,28 @@ private: QMenu *helpMenu; // All the actions that can occur - QAction *openAct; - QAction *exitAct; + QAction *actionOpen; + QAction *actionExit; - QAction *newLayerAct; - QAction *deleteLayerAct; - QAction *deleteActiveLayerAct; + QAction *actionCreateNewLayer; + QAction *actionDeleteLayer; + QAction *actionDeleteActiveLayer; - QAction *aboutAct; - QAction *aboutQtAct; + QAction *actionAboutDialog; + QAction *actionAboutQtDialog; - QAction* clearedActions; - QAction* setActiveAction; - QAction* setAlphaAction; - QAction* moveUpAction; - QAction* moveDownAction; - QAction* moveLeftAction; - QAction* moveRightAction; - QAction* moveLayerUpAction; - QAction* moveLayerDownAction; + QAction* actionFloodFill; + QAction* actionSetActiveLayer; + QAction* actionSetActiveAlpha; + QAction* actionMovePositionUp; + QAction* actionMovePositionDown; + QAction* actionMovePositionLeft; + QAction* actionMovePositionRight; + QAction* actionMoveLayerUp; + QAction* actionMoveLayerDown; // Actions tied to specific file formats - QList saveAsActs; + QList actionSaveAs; //main GUI elements QWidget* centralGuiWidget; diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index 1a7b9c1..044820a 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -16,17 +16,17 @@ PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) this->setUp(maxWidth, maxHeight); //tetsing this->addLayer(200,200,0,0,ImageType::Shaped_Image); - layerStructure[0].image->floodFill(QColor(255,0,0,255)); + layerBundle[0].image->floodFill(QColor(255,0,0,255)); std::vector polygon; polygon.push_back(QPoint(100,000)); polygon.push_back(QPoint(200,100)); polygon.push_back(QPoint(100,200)); polygon.push_back(QPoint(000,100)); - layerStructure[0].image->setPolygon(polygon); + layerBundle[0].image->setPolygon(polygon); this->addLayer(200,200,150,150); - layerStructure[1].image->floodFill(QColor(0,255,0,255)); - layerStructure[1].alpha=200; + layerBundle[1].image->floodFill(QColor(0,255,0,255)); + layerBundle[1].alpha=200; activeLayer=1; } @@ -40,73 +40,69 @@ void PaintingArea::setUp(int maxWidth, int maxHeight){ // Roots the widget to the top left even if resized setAttribute(Qt::WA_StaticContents); - // Set defaults for the monitored variables - scribbling = false; - myPenWidth = 1; - myPenColor = Qt::blue; } int PaintingArea::addLayer(int width, int height, int widthOffset, int heightOffset, ImageType type){ LayerObject newLayer; newLayer.width = width; - newLayer.height = height; + newLayer.hight = height; newLayer.widthOffset = widthOffset; - newLayer.heightOffset = heightOffset; + newLayer.hightOffset = heightOffset; if(type==ImageType::Raster_Image){ newLayer.image = new IntelliRasterImage(width,height); }else if(type==ImageType::Shaped_Image){ newLayer.image = new IntelliShapedImage(width, height); } newLayer.alpha = 255; - this->layerStructure.push_back(newLayer); - return static_cast(layerStructure.size())-1; + this->layerBundle.push_back(newLayer); + return static_cast(layerBundle.size())-1; } void PaintingArea::deleteLayer(int index){ - if(index(layerStructure.size())){ - this->layerStructure.erase(layerStructure.begin()+index); + if(index(layerBundle.size())){ + this->layerBundle.erase(layerBundle.begin()+index); if(activeLayer>=index){ activeLayer--; } } } -void PaintingArea::deleteActiveLayer(){ - if(activeLayer>=0 && activeLayer < static_cast(layerStructure.size())){ - this->layerStructure.erase(layerStructure.begin()+activeLayer); +void PaintingArea::slotDeleteActiveLayer(){ + if(activeLayer>=0 && activeLayer < static_cast(layerBundle.size())){ + this->layerBundle.erase(layerBundle.begin()+activeLayer); activeLayer--; } } void PaintingArea::setLayerToActive(int index) { - if(index>=0&&index(layerStructure.size())){ + if(index>=0&&index(layerBundle.size())){ this->activeLayer=index; } } -void PaintingArea::setAlphaToLayer(int index, int alpha){ - if(index>=0&&index(layerStructure.size())){ - layerStructure[static_cast(index)].alpha=alpha; +void PaintingArea::setAlphaOfLayer(int index, int alpha){ + if(index>=0&&index(layerBundle.size())){ + layerBundle[static_cast(index)].alpha=alpha; } } // Used to load the image and place it in the widget -bool PaintingArea::openImage(const QString &fileName) +bool PaintingArea::open(const QString &fileName) { if(this->activeLayer==-1){ return false; } - IntelliImage* active = layerStructure[static_cast(activeLayer)].image; + IntelliImage* active = layerBundle[static_cast(activeLayer)].image; bool open = active->loadImage(fileName); update(); return open; } // Save the current image -bool PaintingArea::saveImage(const QString &fileName, const char *fileFormat) +bool PaintingArea::save(const QString &fileName, const char *fileFormat) { - if(layerStructure.size()==0){ + if(layerBundle.size()==0){ return false; } this->assembleLayers(true); @@ -130,30 +126,30 @@ bool PaintingArea::saveImage(const QString &fileName, const char *fileFormat) // Color the image area with white -void PaintingArea::clearImage(int r, int g, int b, int a){ +void PaintingArea::floodFill(int r, int g, int b, int a){ if(this->activeLayer==-1){ return; } - IntelliImage* active = layerStructure[static_cast(activeLayer)].image; + IntelliImage* active = layerBundle[static_cast(activeLayer)].image; active->floodFill(QColor(r, g, b, a)); update(); } -void PaintingArea::moveActive(int x, int y){ - layerStructure[static_cast(activeLayer)].widthOffset += x; - layerStructure[static_cast(activeLayer)].heightOffset += y; +void PaintingArea::movePositionActive(int x, int y){ + layerBundle[static_cast(activeLayer)].widthOffset += x; + layerBundle[static_cast(activeLayer)].hightOffset += y; } void PaintingArea::moveActiveLayer(int idx){ if(idx==1){ - this->activeLayerUp(); + this->activateUpperLayer(); }else if(idx==-1){ - this->activeLayerDown(); + this->activateLowerLayer(); } } -void PaintingArea::activate(int a){ - if(a>=0 && a < static_cast(layerStructure.size())){ +void PaintingArea::slotActivateLayer(int a){ + if(a>=0 && a < static_cast(layerBundle.size())){ this->setLayerToActive(a); } } @@ -207,16 +203,16 @@ void PaintingArea::resizeImage(QImage *image_res, const QSize &newSize){ //TODO implement } -void PaintingArea::activeLayerUp(){ - if(activeLayer!=-1 && activeLayer0){ - std::swap(layerStructure[activeLayer], layerStructure[activeLayer-1]); + std::swap(layerBundle[activeLayer], layerBundle[activeLayer-1]); activeLayer--; } } @@ -227,18 +223,18 @@ void PaintingArea::assembleLayers(bool forSaving){ }else{ Canvas->fill(Qt::GlobalColor::black); } - for(size_t i=0; igetDisplayable(layer.alpha); QColor clr_0; QColor clr_1; - for(int y=0; y=maxHeight) break; + for(int y=0; y=maxHeight) break; for(int x=0; x=maxWidth) break; - clr_0=Canvas->pixelColor(layer.widthOffset+x, layer.heightOffset+y); + if(layer.hightOffset+y>=maxWidth) break; + clr_0=Canvas->pixelColor(layer.widthOffset+x, layer.hightOffset+y); clr_1=cpy.pixelColor(x,y); float t = static_cast(clr_1.alpha())/255.f; int r =static_cast(static_cast(clr_1.red())*(t)+static_cast(clr_0.red())*(1.f-t)+0.5f); @@ -250,7 +246,7 @@ void PaintingArea::assembleLayers(bool forSaving){ clr_0.setBlue(b); clr_0.setAlpha(a); - Canvas->setPixelColor(layer.widthOffset+x, layer.heightOffset+y, clr_0); + Canvas->setPixelColor(layer.widthOffset+x, layer.hightOffset+y, clr_0); } } } diff --git a/src/Painting/Layer/PaintingArea.h b/src/Painting/Layer/PaintingArea.h index f164cae..7ebec54 100644 --- a/src/Painting/Layer/PaintingArea.h +++ b/src/Painting/Layer/PaintingArea.h @@ -12,9 +12,9 @@ struct LayerObject{ IntelliImage* image; int width; - int height; + int hight; int widthOffset; - int heightOffset; + int hightOffset; int alpha=255; }; @@ -29,15 +29,15 @@ public: PaintingArea(int maxWidth=600, int maxHeight=600, QWidget *parent = nullptr); // Handles all events - bool openImage(const QString &fileName); - bool saveImage(const QString &fileName, const char *fileFormat); + bool open(const QString &fileName); + bool save(const QString &fileName, const char *fileFormat); int addLayer(int width, int height, int widthOffset=0, int heightOffset=0, ImageType type = ImageType::Raster_Image); void deleteLayer(int index); void setLayerToActive(int index); - void setAlphaToLayer(int index, int alpha); - void clearImage(int r, int g, int b, int a); - void moveActive(int x, int y); + void setAlphaOfLayer(int index, int alpha); + void floodFill(int r, int g, int b, int a); + void movePositionActive(int x, int y); void moveActiveLayer(int idx); // Has the image been modified since last save @@ -46,11 +46,9 @@ public: public slots: // Events to handle - void activate(int a); - void deleteActiveLayer(); + void slotActivateLayer(int a); + void slotDeleteActiveLayer(); - //void setUp helper for konstruktor - void setUp(int maxWidth, int maxHeight); protected: void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; @@ -64,14 +62,15 @@ protected: void resizeEvent(QResizeEvent *event) override; private: - void activeLayerUp(); - void activeLayerDown(); + void setUp(int maxWidth, int maxHeight); + void activateUpperLayer(); + void activateLowerLayer(); QImage* Canvas; int maxWidth; int maxHeight; - std::vector layerStructure; + std::vector layerBundle; int activeLayer=-1; void assembleLayers(bool forSaving=false); @@ -81,19 +80,6 @@ private: // Will be marked true or false depending on if // we have saved after a change bool modified=false; - - // Marked true or false depending on if the user - // is drawing - bool scribbling; - - // Holds the current pen width & color - int myPenWidth; - QColor myPenColor; - - // Stores the image being drawn - - // Stores the location at the current mouse event - QPoint lastPoint; }; #endif From 0aa3b17b8a500eeae454d9cabd95afac8e7cf547 Mon Sep 17 00:00:00 2001 From: Sonaion Date: Tue, 10 Dec 2019 12:20:15 +0100 Subject: [PATCH 08/19] =?UTF-8?q?Recht=20unsch=C3=B6ne=20Modularit=C3=A4t?= =?UTF-8?q?=20der=20Tools?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Painting/Image/IntelliImage.h | 10 +-- src/Painting/Image/IntelliRasterImage.cpp | 8 ++- src/Painting/Image/IntelliRasterImage.h | 3 + src/Painting/Image/IntelliShapedImage.cpp | 7 +++ src/Painting/Image/IntelliShapedImage.h | 5 +- src/Painting/IntelliPhoto.pro | 1 + src/Painting/Layer/PaintingArea.cpp | 15 +++++ src/Painting/Layer/PaintingArea.h | 12 +++- src/Painting/Tool/IntelliTool.cpp | 74 +++++++++++++++++++++++ src/Painting/Tool/IntelliTool.h | 26 +++++--- 10 files changed, 147 insertions(+), 14 deletions(-) create mode 100644 src/Painting/Tool/IntelliTool.cpp diff --git a/src/Painting/Image/IntelliImage.h b/src/Painting/Image/IntelliImage.h index 894093c..55ea479 100644 --- a/src/Painting/Image/IntelliImage.h +++ b/src/Painting/Image/IntelliImage.h @@ -29,15 +29,17 @@ public: virtual ~IntelliImage() = 0; //start on top left - //TODO give tool refrence of image, -> funtkions will not be needed - virtual void drawPixel(const QPoint &p1, const QColor& color); - virtual void drawLine(const QPoint &p1, const QPoint& p2, const QColor& color, const int& penWidth); - virtual void floodFill(const QColor& color); + virtual void drawPixel(const QPoint &p1, const QColor& color); + virtual void drawLine(const QPoint &p1, const QPoint& p2, const QColor& color, const int& penWidth); + virtual void floodFill(const QColor& color); //returns the filtered output virtual QImage getDisplayable(const QSize& displaySize, int alpha)=0; virtual QImage getDisplayable(int alpha=255)=0; + //gets a copy of the image !allocated + virtual IntelliImage* getDeepCopy()=0; + //returns the filtered output //sets the data for the visible image diff --git a/src/Painting/Image/IntelliRasterImage.cpp b/src/Painting/Image/IntelliRasterImage.cpp index 3cedbeb..6e4bc15 100644 --- a/src/Painting/Image/IntelliRasterImage.cpp +++ b/src/Painting/Image/IntelliRasterImage.cpp @@ -12,8 +12,14 @@ IntelliRasterImage::~IntelliRasterImage(){ } -void IntelliRasterImage::calculateVisiblity(){ +IntelliImage* IntelliRasterImage::getDeepCopy(){ + IntelliRasterImage* raster = new IntelliRasterImage(imageData.width(), imageData.height()); + raster->imageData.fill(Qt::transparent); + return raster; +} +void IntelliRasterImage::calculateVisiblity(){ + //not used in raster image } QImage IntelliRasterImage::getDisplayable(int alpha){ diff --git a/src/Painting/Image/IntelliRasterImage.h b/src/Painting/Image/IntelliRasterImage.h index 2d6d809..bf709e6 100644 --- a/src/Painting/Image/IntelliRasterImage.h +++ b/src/Painting/Image/IntelliRasterImage.h @@ -4,6 +4,7 @@ #include"Image/IntelliImage.h" class IntelliRasterImage : public IntelliImage{ + friend IntelliTool; protected: virtual void calculateVisiblity() override; public: @@ -14,6 +15,8 @@ public: virtual QImage getDisplayable(const QSize& displaySize,int alpha) override; virtual QImage getDisplayable(int alpha=255) override; + //gets a copy of the image !allocated + virtual IntelliImage* getDeepCopy() override; //sets the data for the visible image virtual void setPolygon(const std::vector& polygonData) override; diff --git a/src/Painting/Image/IntelliShapedImage.cpp b/src/Painting/Image/IntelliShapedImage.cpp index 7baf81c..72480f6 100644 --- a/src/Painting/Image/IntelliShapedImage.cpp +++ b/src/Painting/Image/IntelliShapedImage.cpp @@ -16,6 +16,13 @@ QImage IntelliShapedImage::getDisplayable(int alpha){ return getDisplayable(imageData.size(),alpha); } +IntelliImage* IntelliShapedImage::getDeepCopy(){ + IntelliShapedImage* shaped = new IntelliShapedImage(imageData.width(), imageData.height()); + shaped->setPolygon(this->polygonData); + shaped->imageData.fill(Qt::transparent); + return shaped; +} + void IntelliShapedImage::calculateVisiblity(){ if(polygonData.size()<=2){ QColor clr; diff --git a/src/Painting/Image/IntelliShapedImage.h b/src/Painting/Image/IntelliShapedImage.h index 0039c3b..e3ef5bc 100644 --- a/src/Painting/Image/IntelliShapedImage.h +++ b/src/Painting/Image/IntelliShapedImage.h @@ -4,7 +4,7 @@ #include"Image/IntelliImage.h" class IntelliShapedImage : public IntelliImage{ - + friend IntelliTool; protected: virtual void calculateVisiblity() override; std::vector polygonData; @@ -16,6 +16,9 @@ public: virtual QImage getDisplayable(const QSize& displaySize, int alpha=255) override; virtual QImage getDisplayable(int alpha=255) override; + //gets a copy of the image !allocated + virtual IntelliImage* getDeepCopy() override; + //sets the data for the visible image virtual void setPolygon(const std::vector& polygonData) override; }; diff --git a/src/Painting/IntelliPhoto.pro b/src/Painting/IntelliPhoto.pro index 9cb20dc..cddc449 100644 --- a/src/Painting/IntelliPhoto.pro +++ b/src/Painting/IntelliPhoto.pro @@ -22,6 +22,7 @@ SOURCES += \ Image/IntelliShapedImage.cpp \ IntelliHelper/IntelliHelper.cpp \ Layer/PaintingArea.cpp \ + Tool/IntelliTool.cpp \ main.cpp HEADERS += \ diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index 044820a..e8b7a94 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -58,6 +58,7 @@ int PaintingArea::addLayer(int width, int height, int widthOffset, int heightOff return static_cast(layerBundle.size())-1; } + void PaintingArea::deleteLayer(int index){ if(index(layerBundle.size())){ this->layerBundle.erase(layerBundle.begin()+index); @@ -217,6 +218,7 @@ void PaintingArea::activateLowerLayer(){ } } + void PaintingArea::assembleLayers(bool forSaving){ if(forSaving){ Canvas->fill(Qt::GlobalColor::transparent); @@ -251,3 +253,16 @@ void PaintingArea::assembleLayers(bool forSaving){ } } } + +void PaintingArea::createTempLayerAfter(int idx){ + if(idx>=0){ + LayerObject newLayer; + newLayer.alpha = layerBundle[idx].alpha; + newLayer.hight = layerBundle[idx].hight; + newLayer.width = layerBundle[idx].width; + newLayer.hightOffset = layerBundle[idx].hightOffset; + newLayer.widthOffset = layerBundle[idx].widthOffset; + newLayer.image = layerBundle[idx].image->getDeepCopy(); + layerBundle.insert(layerBundle.begin()+idx+1,newLayer); + } +} diff --git a/src/Painting/Layer/PaintingArea.h b/src/Painting/Layer/PaintingArea.h index 7ebec54..ead05da 100644 --- a/src/Painting/Layer/PaintingArea.h +++ b/src/Painting/Layer/PaintingArea.h @@ -5,10 +5,12 @@ #include #include #include"Image/IntelliImage.h" +#include"Tool/IntelliTool.h" #include #include #include + struct LayerObject{ IntelliImage* image; int width; @@ -16,6 +18,8 @@ struct LayerObject{ int widthOffset; int hightOffset; int alpha=255; + + }; class PaintingArea : public QWidget @@ -24,7 +28,7 @@ class PaintingArea : public QWidget // for all Qt objects // QObjects handle events Q_OBJECT - + friend IntelliTool; public: PaintingArea(int maxWidth=600, int maxHeight=600, QWidget *parent = nullptr); @@ -33,6 +37,7 @@ public: bool save(const QString &fileName, const char *fileFormat); int addLayer(int width, int height, int widthOffset=0, int heightOffset=0, ImageType type = ImageType::Raster_Image); + int addLayerAt(int idx, int width, int height, int widthOffset=0, int heightOffset=0, ImageType type = ImageType::Raster_Image); void deleteLayer(int index); void setLayerToActive(int index); void setAlphaOfLayer(int index, int alpha); @@ -43,6 +48,7 @@ public: // Has the image been modified since last save bool isModified() const { return modified; } + public slots: // Events to handle @@ -66,6 +72,7 @@ private: void activateUpperLayer(); void activateLowerLayer(); + QImage* Canvas; int maxWidth; int maxHeight; @@ -80,6 +87,9 @@ private: // Will be marked true or false depending on if // we have saved after a change bool modified=false; + + //Helper for Tool + void createTempLayerAfter(int idx); }; #endif diff --git a/src/Painting/Tool/IntelliTool.cpp b/src/Painting/Tool/IntelliTool.cpp new file mode 100644 index 0000000..046e7be --- /dev/null +++ b/src/Painting/Tool/IntelliTool.cpp @@ -0,0 +1,74 @@ +#include"IntelliTool.h" +#include"Layer/PaintingArea.h" + +IntelliTool::IntelliTool(PaintingArea* Area){ + this->Area=Area; +} + + +IntelliTool::~IntelliTool(){ + +} + + +void IntelliTool::onMouseRightPressed(int x, int y){ + this->drawing=true; + //create drawing layer + this->createToolLayer(); +} + +void IntelliTool::onMouseRightReleased(int x, int y){ + if(drawing){ + drawing=false; + this->mergeToolLayer(); + this->deleteToolLayer(); + } +} + +void IntelliTool::onMouseLeftPressed(int x, int y){ + if(drawing){ + drawing=false; + this->deleteToolLayer(); + } +} + +void IntelliTool::onMouseLeftReleased(int x, int y){ + //optional for tool +} + +void IntelliTool::onMouseMoved(int x, int y){ + //optional for tool +} + +void IntelliTool::createToolLayer(){ + Area->createTempLayerAfter(Area->activeLayer); + this->Active=&Area->layerBundle[Area->activeLayer]; + this->Canvas=&Area->layerBundle[Area->activeLayer+1]; +} + +void IntelliTool::mergeToolLayer(){ + QColor clr_0; + QColor clr_1; + for(int y=0; yhight; y++){ + for(int x=0; xwidth; x++){ + clr_0=Active->image->imageData.pixelColor(x,y); + clr_1=Canvas->image->imageData.pixelColor(x,y); + float t = static_cast(clr_1.alpha())/255.f; + int r =static_cast(static_cast(clr_1.red())*(t)+static_cast(clr_0.red())*(1.f-t)+0.5f); + int g =static_cast(static_cast(clr_1.green())*(t)+static_cast(clr_0.green())*(1.f-t)+0.5f); + int b =static_cast(static_cast(clr_1.blue())*(t)+static_cast(clr_0.blue()*(1.f-t))+0.5f); + int a =std::min(clr_0.alpha()+clr_1.alpha(), 255); + clr_0.setRed(r); + clr_0.setGreen(g); + clr_0.setBlue(b); + clr_0.setAlpha(a); + + Active->image->imageData.setPixelColor(x, y, clr_0); + } + } +} + +void IntelliTool::deleteToolLayer(){ + Area->deleteLayer(Area->activeLayer+1); + this->Canvas=nullptr; +} diff --git a/src/Painting/Tool/IntelliTool.h b/src/Painting/Tool/IntelliTool.h index b30b007..7c17366 100644 --- a/src/Painting/Tool/IntelliTool.h +++ b/src/Painting/Tool/IntelliTool.h @@ -1,18 +1,30 @@ #ifndef Intelli_Tool_H #define Intelli_Tool_H -#include"Layer/PaintingArea.h" +#include + +class LayerObject; +class PaintingArea; class IntelliTool{ private: - LayerObject* DataValue; - LayerObject* Preview; + void createToolLayer(); + void mergeToolLayer(); + void deleteToolLayer(); +protected: + PaintingArea* Area; + LayerObject* Active; + LayerObject* Canvas; + bool drawing = false; public: - IntelliTool(LayerObject* DataValue, LayerObject* Preview); + IntelliTool(PaintingArea* Area); virtual ~IntelliTool() = 0; - virtual void onMousePressed(QMouseEvent *event) = 0; - virtual void onMouseMoved(QMouseEvent* event)=0; - virtual void onMouseReleased(QMouseEvent* event)=0; + virtual void onMouseRightPressed(int x, int y); + virtual void onMouseRightReleased(int x, int y); + virtual void onMouseLeftPressed(int x, int y); + virtual void onMouseLeftReleased(int x, int y); + + virtual void onMouseMoved(int x, int y); }; #endif From 30d6781e7f724d4037ceaaa922d412d63fe79353 Mon Sep 17 00:00:00 2001 From: Sonaion Date: Tue, 10 Dec 2019 15:32:22 +0100 Subject: [PATCH 09/19] Tool structure- input bug --- src/Painting/GUI/IntelliPhotoGui.cpp | 13 +++---- src/Painting/GUI/IntelliPhotoGui.h | 1 - src/Painting/Image/IntelliImage.cpp | 4 --- src/Painting/Image/IntelliRasterImage.cpp | 2 +- src/Painting/IntelliPhoto.pro | 4 ++- src/Painting/Layer/PaintingArea.cpp | 35 ++++++++++++++----- src/Painting/Layer/PaintingArea.h | 6 ++-- src/Painting/Tool/IntelliTool.cpp | 29 ++++++++-------- src/Painting/Tool/IntelliToolPen.cpp | 42 +++++++++++++++++++++++ src/Painting/Tool/IntelliToolPen.h | 23 +++++++++++++ 10 files changed, 118 insertions(+), 41 deletions(-) create mode 100644 src/Painting/Tool/IntelliToolPen.cpp create mode 100644 src/Painting/Tool/IntelliToolPen.h diff --git a/src/Painting/GUI/IntelliPhotoGui.cpp b/src/Painting/GUI/IntelliPhotoGui.cpp index 350293d..4a96e0e 100644 --- a/src/Painting/GUI/IntelliPhotoGui.cpp +++ b/src/Painting/GUI/IntelliPhotoGui.cpp @@ -133,22 +133,22 @@ void IntelliPhotoGui::slotSetActiveAlpha(){ } void IntelliPhotoGui::slotPositionMoveUp(){ - paintingArea->movePositionActive(0,-2); + paintingArea->movePositionActive(0,-20); update(); } void IntelliPhotoGui::slotPositionMoveDown(){ - paintingArea->movePositionActive(0,2); + paintingArea->movePositionActive(0,20); update(); } void IntelliPhotoGui::slotPositionMoveLeft(){ - paintingArea->movePositionActive(-2,0); + paintingArea->movePositionActive(-20,0); update(); } void IntelliPhotoGui::slotPositionMoveRight(){ - paintingArea->movePositionActive(2,0); + paintingArea->movePositionActive(20,0); update(); } @@ -269,10 +269,6 @@ void IntelliPhotoGui::createActions() actionDeleteLayer = new QAction(tr("&Delete Layer..."), this); connect(actionDeleteLayer, SIGNAL(triggered()), this, SLOT(slotDeleteLayer())); - // Delete Active Layer action and tie to paintingArea::deleteActiveLayerLayer() - actionDeleteActiveLayer = new QAction(tr("&Delete active Layer"), this); - connect(actionDeleteActiveLayer, SIGNAL(triggered()), paintingArea, SLOT(deleteActiveLayer())); - actionFloodFill = new QAction(tr("&clear Image"), this); connect(actionFloodFill, SIGNAL(triggered()), this, SLOT(slotClearActiveLayer())); @@ -347,7 +343,6 @@ void IntelliPhotoGui::createMenus() layerMenu = new QMenu(tr("&Layer"), this); layerMenu->addAction(actionCreateNewLayer); layerMenu->addAction(actionDeleteLayer); - layerMenu->addAction(actionDeleteActiveLayer); //Attach all Tool Options toolMenu = new QMenu(tr("&Tools"), this); diff --git a/src/Painting/GUI/IntelliPhotoGui.h b/src/Painting/GUI/IntelliPhotoGui.h index 87b529f..9a8241c 100644 --- a/src/Painting/GUI/IntelliPhotoGui.h +++ b/src/Painting/GUI/IntelliPhotoGui.h @@ -75,7 +75,6 @@ private: QAction *actionCreateNewLayer; QAction *actionDeleteLayer; - QAction *actionDeleteActiveLayer; QAction *actionAboutDialog; QAction *actionAboutQtDialog; diff --git a/src/Painting/Image/IntelliImage.cpp b/src/Painting/Image/IntelliImage.cpp index 814aa36..d9f5a48 100644 --- a/src/Painting/Image/IntelliImage.cpp +++ b/src/Painting/Image/IntelliImage.cpp @@ -50,9 +50,6 @@ void IntelliImage::drawPixel(const QPoint &p1, const QColor& color){ // Draw a line from the last registered point to the current painter.drawPoint(p1); - - // Call to update the rectangular space where we drew - //update(QRect(p1, p2)); } void IntelliImage::drawLine(const QPoint &p1, const QPoint& p2, const QColor& color, const int& penWidth){ @@ -69,5 +66,4 @@ void IntelliImage::drawLine(const QPoint &p1, const QPoint& p2, const QColor& co void IntelliImage::floodFill(const QColor& color){ imageData.fill(color); - } diff --git a/src/Painting/Image/IntelliRasterImage.cpp b/src/Painting/Image/IntelliRasterImage.cpp index 6e4bc15..d92260f 100644 --- a/src/Painting/Image/IntelliRasterImage.cpp +++ b/src/Painting/Image/IntelliRasterImage.cpp @@ -31,7 +31,7 @@ QImage IntelliRasterImage::getDisplayable(const QSize& displaySize, int alpha){ for(int y = 0; y #include +#include #include -#include "string.h" + #include "PaintingArea.h" #include "Image/IntelliRasterImage.h" #include "Image/IntelliShapedImage.h" - -#include -#include +#include "Tool/IntelliToolPen.h" PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) :QWidget(parent){ + this->Tool = new IntelliToolPen(this); this->setUp(maxWidth, maxHeight); //tetsing this->addLayer(200,200,0,0,ImageType::Shaped_Image); @@ -160,7 +163,13 @@ void PaintingArea::slotActivateLayer(int a){ // Set that we are currently drawing void PaintingArea::mousePressEvent(QMouseEvent *event) { - //TODO implement in tool + int x = (float)layerBundle[activeLayer].width/(float)width()*event->x()+layerBundle[activeLayer].widthOffset; + int y = (float)layerBundle[activeLayer].hight/(float)height()*event->y()+layerBundle[activeLayer].hightOffset; + if(event->button() == Qt::LeftButton){ + Tool->onMouseLeftPressed(x, y); + }else if(event->button() == Qt::RightButton){ + Tool->onMouseRightPressed(x, y); + } } @@ -169,13 +178,21 @@ void PaintingArea::mousePressEvent(QMouseEvent *event) // from the last position to the current void PaintingArea::mouseMoveEvent(QMouseEvent *event) { - //TODO implement in Tool + int x = (float)layerBundle[activeLayer].width/(float)width()*event->x()+layerBundle[activeLayer].widthOffset; + int y = (float)layerBundle[activeLayer].hight/(float)height()*event->y()+layerBundle[activeLayer].hightOffset; + Tool->onMouseMoved(x, y); } // If the button is released we set variables to stop drawing void PaintingArea::mouseReleaseEvent(QMouseEvent *event) { - //TODO implement in tool + int x = (float)layerBundle[activeLayer].width/(float)width()*event->x()+layerBundle[activeLayer].widthOffset; + int y = (float)layerBundle[activeLayer].hight/(float)height()*event->y()+layerBundle[activeLayer].hightOffset; + if(event->button() == Qt::LeftButton){ + Tool->onMouseLeftReleased(x, y); + }else if(event->button() == Qt::RightButton){ + Tool->onMouseRightReleased(x, y); + } } // QPainter provides functions to draw on the widget @@ -235,7 +252,7 @@ void PaintingArea::assembleLayers(bool forSaving){ if(layer.hightOffset+y>=maxHeight) break; for(int x=0; x=maxWidth) break; + if(layer.widthOffset+x>=maxWidth) break; clr_0=Canvas->pixelColor(layer.widthOffset+x, layer.hightOffset+y); clr_1=cpy.pixelColor(x,y); float t = static_cast(clr_1.alpha())/255.f; @@ -257,7 +274,7 @@ void PaintingArea::assembleLayers(bool forSaving){ void PaintingArea::createTempLayerAfter(int idx){ if(idx>=0){ LayerObject newLayer; - newLayer.alpha = layerBundle[idx].alpha; + newLayer.alpha = 255; newLayer.hight = layerBundle[idx].hight; newLayer.width = layerBundle[idx].width; newLayer.hightOffset = layerBundle[idx].hightOffset; diff --git a/src/Painting/Layer/PaintingArea.h b/src/Painting/Layer/PaintingArea.h index ead05da..7623551 100644 --- a/src/Painting/Layer/PaintingArea.h +++ b/src/Painting/Layer/PaintingArea.h @@ -4,11 +4,11 @@ #include #include -#include"Image/IntelliImage.h" -#include"Tool/IntelliTool.h" #include #include #include +#include"Image/IntelliImage.h" +#include"Tool/IntelliTool.h" struct LayerObject{ @@ -77,6 +77,8 @@ private: int maxWidth; int maxHeight; + IntelliTool* Tool; + std::vector layerBundle; int activeLayer=-1; diff --git a/src/Painting/Tool/IntelliTool.cpp b/src/Painting/Tool/IntelliTool.cpp index 046e7be..404250d 100644 --- a/src/Painting/Tool/IntelliTool.cpp +++ b/src/Painting/Tool/IntelliTool.cpp @@ -12,12 +12,24 @@ IntelliTool::~IntelliTool(){ void IntelliTool::onMouseRightPressed(int x, int y){ - this->drawing=true; - //create drawing layer - this->createToolLayer(); + if(drawing){ + drawing=false; + this->deleteToolLayer(); + } } void IntelliTool::onMouseRightReleased(int x, int y){ + //optional for tool +} + +void IntelliTool::onMouseLeftPressed(int x, int y){ + this->drawing=true; + //create drawing layer + this->createToolLayer(); + +} + +void IntelliTool::onMouseLeftReleased(int x, int y){ if(drawing){ drawing=false; this->mergeToolLayer(); @@ -25,17 +37,6 @@ void IntelliTool::onMouseRightReleased(int x, int y){ } } -void IntelliTool::onMouseLeftPressed(int x, int y){ - if(drawing){ - drawing=false; - this->deleteToolLayer(); - } -} - -void IntelliTool::onMouseLeftReleased(int x, int y){ - //optional for tool -} - void IntelliTool::onMouseMoved(int x, int y){ //optional for tool } diff --git a/src/Painting/Tool/IntelliToolPen.cpp b/src/Painting/Tool/IntelliToolPen.cpp new file mode 100644 index 0000000..ca66584 --- /dev/null +++ b/src/Painting/Tool/IntelliToolPen.cpp @@ -0,0 +1,42 @@ +#include"IntelliToolPen.h" +#include"Layer/PaintingArea.h" +#include"QDebug" + +IntelliToolPen::IntelliToolPen(PaintingArea* Area) + :IntelliTool(Area){ + +} + +IntelliToolPen::~IntelliToolPen(){ + +} + +void IntelliToolPen::onMouseRightPressed(int x, int y){ + IntelliTool::onMouseRightPressed(x,y); + //implement in here + this->point=QPoint(x,y); + this->Canvas->image->drawPixel(point, QColor(255,0,0,255)); +} + +void IntelliToolPen::onMouseRightReleased(int x, int y){ + IntelliTool::onMouseRightReleased(x,y); + //implemnt in here +} + +void IntelliToolPen::onMouseLeftPressed(int x, int y){ + //implement in here + IntelliTool::onMouseLeftPressed(x,y); +} + +void IntelliToolPen::onMouseLeftReleased(int x, int y){ + //implement in here + IntelliTool::onMouseLeftReleased(x,y); +} + +void IntelliToolPen::onMouseMoved(int x, int y){ + if(this->drawing){ + QPoint newPoint(x,y); + this->Canvas->image->drawLine(this->point, newPoint, QColor(255,0,0,255), 2); + this->point=newPoint; + } +} diff --git a/src/Painting/Tool/IntelliToolPen.h b/src/Painting/Tool/IntelliToolPen.h new file mode 100644 index 0000000..a08ecc6 --- /dev/null +++ b/src/Painting/Tool/IntelliToolPen.h @@ -0,0 +1,23 @@ +#ifndef INTELLITOOLPEN_H +#define INTELLITOOLPEN_H + +#include"IntelliTool.h" +#include"QColor" +#include"QPoint" + +class IntelliToolPen : public IntelliTool{ + QColor clr; + QPoint point; +public: + IntelliToolPen(PaintingArea* Area); + virtual ~IntelliToolPen() override; + + virtual void onMouseRightPressed(int x, int y) override; + virtual void onMouseRightReleased(int x, int y) override; + virtual void onMouseLeftPressed(int x, int y) override; + virtual void onMouseLeftReleased(int x, int y) override; + + virtual void onMouseMoved(int x, int y) override; +}; + +#endif // INTELLITOOLPEN_H From 10fba8c454af2b18dc72074fc3d41effb5591794 Mon Sep 17 00:00:00 2001 From: Sonaion Date: Tue, 10 Dec 2019 15:44:22 +0100 Subject: [PATCH 10/19] Tool structure implemented --- src/Painting/GUI/IntelliPhotoGui.cpp | 2 +- src/Painting/Layer/PaintingArea.cpp | 12 ++++++------ src/Painting/Tool/IntelliToolPen.cpp | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Painting/GUI/IntelliPhotoGui.cpp b/src/Painting/GUI/IntelliPhotoGui.cpp index 4a96e0e..d51a8bb 100644 --- a/src/Painting/GUI/IntelliPhotoGui.cpp +++ b/src/Painting/GUI/IntelliPhotoGui.cpp @@ -89,7 +89,7 @@ void IntelliPhotoGui::slotCreateNewLayer() // Create New Layer if (ok1&&ok2) { - int layer = paintingArea->addLayer(width,height,100,100); + int layer = paintingArea->addLayer(width,height,0,0); paintingArea->slotActivateLayer(layer); } } diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index eb23d1d..6177989 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -163,8 +163,8 @@ void PaintingArea::slotActivateLayer(int a){ // Set that we are currently drawing void PaintingArea::mousePressEvent(QMouseEvent *event) { - int x = (float)layerBundle[activeLayer].width/(float)width()*event->x()+layerBundle[activeLayer].widthOffset; - int y = (float)layerBundle[activeLayer].hight/(float)height()*event->y()+layerBundle[activeLayer].hightOffset; + int x = event->x()-layerBundle[activeLayer].widthOffset; + int y = event->y()-layerBundle[activeLayer].hightOffset; if(event->button() == Qt::LeftButton){ Tool->onMouseLeftPressed(x, y); }else if(event->button() == Qt::RightButton){ @@ -178,16 +178,16 @@ void PaintingArea::mousePressEvent(QMouseEvent *event) // from the last position to the current void PaintingArea::mouseMoveEvent(QMouseEvent *event) { - int x = (float)layerBundle[activeLayer].width/(float)width()*event->x()+layerBundle[activeLayer].widthOffset; - int y = (float)layerBundle[activeLayer].hight/(float)height()*event->y()+layerBundle[activeLayer].hightOffset; + int x = event->x()-layerBundle[activeLayer].widthOffset; + int y = event->y()-layerBundle[activeLayer].hightOffset; Tool->onMouseMoved(x, y); } // If the button is released we set variables to stop drawing void PaintingArea::mouseReleaseEvent(QMouseEvent *event) { - int x = (float)layerBundle[activeLayer].width/(float)width()*event->x()+layerBundle[activeLayer].widthOffset; - int y = (float)layerBundle[activeLayer].hight/(float)height()*event->y()+layerBundle[activeLayer].hightOffset; + int x = event->x()-layerBundle[activeLayer].widthOffset; + int y = event->y()-layerBundle[activeLayer].hightOffset; if(event->button() == Qt::LeftButton){ Tool->onMouseLeftReleased(x, y); }else if(event->button() == Qt::RightButton){ diff --git a/src/Painting/Tool/IntelliToolPen.cpp b/src/Painting/Tool/IntelliToolPen.cpp index ca66584..36ae08d 100644 --- a/src/Painting/Tool/IntelliToolPen.cpp +++ b/src/Painting/Tool/IntelliToolPen.cpp @@ -14,8 +14,6 @@ IntelliToolPen::~IntelliToolPen(){ void IntelliToolPen::onMouseRightPressed(int x, int y){ IntelliTool::onMouseRightPressed(x,y); //implement in here - this->point=QPoint(x,y); - this->Canvas->image->drawPixel(point, QColor(255,0,0,255)); } void IntelliToolPen::onMouseRightReleased(int x, int y){ @@ -26,6 +24,7 @@ void IntelliToolPen::onMouseRightReleased(int x, int y){ void IntelliToolPen::onMouseLeftPressed(int x, int y){ //implement in here IntelliTool::onMouseLeftPressed(x,y); + this->point=QPoint(x,y); } void IntelliToolPen::onMouseLeftReleased(int x, int y){ From 282f85bd73f73a59a6b0e7a78ea8d091aa9755c1 Mon Sep 17 00:00:00 2001 From: Conrad Date: Wed, 11 Dec 2019 14:01:45 +0100 Subject: [PATCH 11/19] Added Icon for macOS --- src/Painting/IntelliPhoto.pro | 1 + src/Painting/icon.icns | Bin 0 -> 107524 bytes 2 files changed, 1 insertion(+) create mode 100644 src/Painting/icon.icns diff --git a/src/Painting/IntelliPhoto.pro b/src/Painting/IntelliPhoto.pro index 95e3aac..b61b9b8 100644 --- a/src/Painting/IntelliPhoto.pro +++ b/src/Painting/IntelliPhoto.pro @@ -43,6 +43,7 @@ QMAKE_CXXFLAGS QMAKE_LFLAGS RC_ICONS = icon.ico +ICON = icon.icns # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin diff --git a/src/Painting/icon.icns b/src/Painting/icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..791b4ae867c9dc3b5e1db96cb29479cfb9a21ba8 GIT binary patch literal 107524 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�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 literal 0 HcmV?d00001 From 72bde027ed4e1ac3a60beea6ce54f9207370a926 Mon Sep 17 00:00:00 2001 From: AshBastian Date: Wed, 11 Dec 2019 16:29:11 +0100 Subject: [PATCH 12/19] SetColorTool, PenTool und FloodFillTool LoL --- src/Painting/GUI/IntelliPhotoGui.cpp | 15 +++++++ src/Painting/GUI/IntelliPhotoGui.h | 8 ++++ src/Painting/IntelliPhoto.pro | 6 ++- src/Painting/Layer/PaintingArea.cpp | 9 +++- src/Painting/Layer/PaintingArea.h | 8 +++- src/Painting/Tool/IntelliTool.cpp | 3 ++ src/Painting/Tool/IntelliTool.h | 5 ++- .../Tool/IntelliToolFloodFillTool.cpp | 41 +++++++++++++++++++ src/Painting/Tool/IntelliToolFloodFillTool.h | 22 ++++++++++ src/Painting/Tool/IntelliToolPen.cpp | 12 +++--- src/Painting/Tool/IntelliToolPen.h | 8 ++-- src/Painting/Tool/IntelliToolSetColorTool.cpp | 36 ++++++++++++++++ src/Painting/Tool/IntelliToolSetColorTool.h | 24 +++++++++++ 13 files changed, 184 insertions(+), 13 deletions(-) create mode 100644 src/Painting/Tool/IntelliToolFloodFillTool.cpp create mode 100644 src/Painting/Tool/IntelliToolFloodFillTool.h create mode 100644 src/Painting/Tool/IntelliToolSetColorTool.cpp create mode 100644 src/Painting/Tool/IntelliToolSetColorTool.h diff --git a/src/Painting/GUI/IntelliPhotoGui.cpp b/src/Painting/GUI/IntelliPhotoGui.cpp index d51a8bb..ca123d4 100644 --- a/src/Painting/GUI/IntelliPhotoGui.cpp +++ b/src/Painting/GUI/IntelliPhotoGui.cpp @@ -111,6 +111,17 @@ void IntelliPhotoGui::slotDeleteLayer() paintingArea->deleteLayer(layerNumber); } +void IntelliPhotoGui::slotGetColorbar(){ + + bool ok1; + + int firstOrSecondColor = QInputDialog::getInt(this, tr("Which Color"), + tr("Number:"), + 1,1, 2, 1, &ok1); + + Tool = paintingArea->getTool(); + Tool->getColorbar(firstOrSecondColor); +} void IntelliPhotoGui::slotSetActiveAlpha(){ // Stores button value @@ -269,6 +280,9 @@ void IntelliPhotoGui::createActions() actionDeleteLayer = new QAction(tr("&Delete Layer..."), this); connect(actionDeleteLayer, SIGNAL(triggered()), this, SLOT(slotDeleteLayer())); + actionGetColorbar = new QAction(tr("&Set Color"),this); + connect(actionGetColorbar, SIGNAL(triggered()), this, SLOT(slotGetColorbar())); + actionFloodFill = new QAction(tr("&clear Image"), this); connect(actionFloodFill, SIGNAL(triggered()), this, SLOT(slotClearActiveLayer())); @@ -346,6 +360,7 @@ void IntelliPhotoGui::createMenus() //Attach all Tool Options toolMenu = new QMenu(tr("&Tools"), this); + toolMenu->addAction(actionGetColorbar); // Attach all actions to Help helpMenu = new QMenu(tr("&Help"), this); diff --git a/src/Painting/GUI/IntelliPhotoGui.h b/src/Painting/GUI/IntelliPhotoGui.h index 9a8241c..10b0e1d 100644 --- a/src/Painting/GUI/IntelliPhotoGui.h +++ b/src/Painting/GUI/IntelliPhotoGui.h @@ -12,6 +12,8 @@ // PaintingArea used to paint the image class PaintingArea; +class IntelliTool; + class IntelliPhotoGui : public QMainWindow { // Declares our class as a QObject which is the base class @@ -31,6 +33,9 @@ private slots: void slotSave(); void slotCreateNewLayer(); void slotDeleteLayer(); + + void slotGetColorbar(); + void slotAboutDialog(); void slotClearActiveLayer(); @@ -60,6 +65,7 @@ private: // What we'll draw on PaintingArea* paintingArea; + IntelliTool* Tool; // The menu widgets QMenu *saveAsMenu; @@ -76,6 +82,8 @@ private: QAction *actionCreateNewLayer; QAction *actionDeleteLayer; + QAction *actionGetColorbar; + QAction *actionAboutDialog; QAction *actionAboutQtDialog; diff --git a/src/Painting/IntelliPhoto.pro b/src/Painting/IntelliPhoto.pro index 95e3aac..9e0d263 100644 --- a/src/Painting/IntelliPhoto.pro +++ b/src/Painting/IntelliPhoto.pro @@ -23,7 +23,9 @@ SOURCES += \ IntelliHelper/IntelliHelper.cpp \ Layer/PaintingArea.cpp \ Tool/IntelliTool.cpp \ + Tool/IntelliToolFloodFillTool.cpp \ Tool/IntelliToolPen.cpp \ + Tool/IntelliToolSetColorTool.cpp \ main.cpp HEADERS += \ @@ -34,7 +36,9 @@ HEADERS += \ IntelliHelper/IntelliHelper.h \ Layer/PaintingArea.h \ Tool/IntelliTool.h \ - Tool/IntelliToolPen.h + Tool/IntelliToolFloodFillTool.h \ + Tool/IntelliToolPen.h \ + Tool/IntelliToolSetColorTool.h FORMS += \ widget.ui diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index 6177989..7186907 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -11,11 +11,14 @@ #include "Image/IntelliRasterImage.h" #include "Image/IntelliShapedImage.h" #include "Tool/IntelliToolPen.h" +#include "Tool/IntelliToolSetColorTool.h" +#include "Tool/IntelliToolFloodFillTool.h" PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) :QWidget(parent){ - this->Tool = new IntelliToolPen(this); + this->Tool = new IntelliToolFloodFillTool(this); + this->ColorTool = new IntelliToolSetColorTool(this); this->setUp(maxWidth, maxHeight); //tetsing this->addLayer(200,200,0,0,ImageType::Shaped_Image); @@ -34,6 +37,10 @@ PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) activeLayer=1; } +IntelliToolSetColorTool* PaintingArea::getTool(){ + return ColorTool; +} + void PaintingArea::setUp(int maxWidth, int maxHeight){ //set standart parameter this->maxWidth = maxWidth; diff --git a/src/Painting/Layer/PaintingArea.h b/src/Painting/Layer/PaintingArea.h index 7623551..abdc990 100644 --- a/src/Painting/Layer/PaintingArea.h +++ b/src/Painting/Layer/PaintingArea.h @@ -7,8 +7,9 @@ #include #include #include -#include"Image/IntelliImage.h" -#include"Tool/IntelliTool.h" +#include "Image/IntelliImage.h" +#include "Tool/IntelliTool.h" +#include "Tool/IntelliToolSetColorTool.h" struct LayerObject{ @@ -32,6 +33,8 @@ class PaintingArea : public QWidget public: PaintingArea(int maxWidth=600, int maxHeight=600, QWidget *parent = nullptr); + IntelliToolSetColorTool* getTool(); //TODO: rename function, when there are more Tools + // Handles all events bool open(const QString &fileName); bool save(const QString &fileName, const char *fileFormat); @@ -78,6 +81,7 @@ private: int maxHeight; IntelliTool* Tool; + IntelliToolSetColorTool* ColorTool; std::vector layerBundle; int activeLayer=-1; diff --git a/src/Painting/Tool/IntelliTool.cpp b/src/Painting/Tool/IntelliTool.cpp index 404250d..4aa4403 100644 --- a/src/Painting/Tool/IntelliTool.cpp +++ b/src/Painting/Tool/IntelliTool.cpp @@ -10,6 +10,9 @@ IntelliTool::~IntelliTool(){ } +void IntelliTool::getColorbar(int firstOrSecondColor){ + //optional for tool +} void IntelliTool::onMouseRightPressed(int x, int y){ if(drawing){ diff --git a/src/Painting/Tool/IntelliTool.h b/src/Painting/Tool/IntelliTool.h index 7c17366..75343ce 100644 --- a/src/Painting/Tool/IntelliTool.h +++ b/src/Painting/Tool/IntelliTool.h @@ -1,7 +1,7 @@ #ifndef Intelli_Tool_H #define Intelli_Tool_H -#include +#include class LayerObject; class PaintingArea; @@ -16,10 +16,13 @@ protected: LayerObject* Active; LayerObject* Canvas; bool drawing = false; + public: IntelliTool(PaintingArea* Area); virtual ~IntelliTool() = 0; + virtual void getColorbar(int firstOrSecondColor); + virtual void onMouseRightPressed(int x, int y); virtual void onMouseRightReleased(int x, int y); virtual void onMouseLeftPressed(int x, int y); diff --git a/src/Painting/Tool/IntelliToolFloodFillTool.cpp b/src/Painting/Tool/IntelliToolFloodFillTool.cpp new file mode 100644 index 0000000..c7c476e --- /dev/null +++ b/src/Painting/Tool/IntelliToolFloodFillTool.cpp @@ -0,0 +1,41 @@ +#include "IntelliToolFloodFillTool.h" +#include "Layer/PaintingArea.h" + +IntelliToolFloodFillTool::IntelliToolFloodFillTool(PaintingArea* Area) + :IntelliToolSetColorTool(Area) +{ + Tool = Area->getTool(); + isPressed = false; +} + +void IntelliToolFloodFillTool::onMouseLeftPressed(int x, int y){ + if(!isPressed){ + isPressed = true; + IntelliTool::onMouseLeftPressed(x,y); + Tool = Area->getTool(); + this->Canvas->image->floodFill(Tool->getFirstColor()); + } +} + +void IntelliToolFloodFillTool::onMouseRightPressed(int x, int y){ + if(!isPressed){ + isPressed = true; + IntelliTool::onMouseLeftPressed(x,y); + Tool = Area->getTool(); + this->Canvas->image->floodFill(Tool->getSecondColor()); + } +} + +void IntelliToolFloodFillTool::onMouseRightReleased(int x, int y){ + IntelliTool::onMouseLeftReleased(x,y); + if(isPressed) isPressed = false; +} + +void IntelliToolFloodFillTool::onMouseLeftReleased(int x, int y){ + IntelliTool::onMouseLeftReleased(x,y); + if(isPressed) isPressed = false; +} + +void IntelliToolFloodFillTool::onMouseMoved(int x, int y){ + IntelliTool::onMouseRightPressed(x,y); +} diff --git a/src/Painting/Tool/IntelliToolFloodFillTool.h b/src/Painting/Tool/IntelliToolFloodFillTool.h new file mode 100644 index 0000000..30b1e95 --- /dev/null +++ b/src/Painting/Tool/IntelliToolFloodFillTool.h @@ -0,0 +1,22 @@ +#ifndef INTELLITOOLFLOODFILLTOOL_H +#define INTELLITOOLFLOODFILLTOOL_H + +#include "IntelliToolSetColorTool.h" + +class IntelliToolFloodFillTool : public IntelliToolSetColorTool +{ +public: + IntelliToolFloodFillTool(PaintingArea *Area); + + void IntelliToolFloodFillTool::onMouseLeftPressed(int x, int y) override; + void IntelliToolFloodFillTool::onMouseLeftReleased(int x, int y) override; + void IntelliToolFloodFillTool::onMouseRightPressed(int x, int y) override; + void IntelliToolFloodFillTool::onMouseRightReleased(int x, int y) override; + void IntelliToolFloodFillTool::onMouseMoved(int x, int y) override; + +private: + IntelliToolSetColorTool* Tool; + bool isPressed; +}; + +#endif // INTELLITOOLFLOODFILLTOOL_H diff --git a/src/Painting/Tool/IntelliToolPen.cpp b/src/Painting/Tool/IntelliToolPen.cpp index 36ae08d..a858908 100644 --- a/src/Painting/Tool/IntelliToolPen.cpp +++ b/src/Painting/Tool/IntelliToolPen.cpp @@ -1,9 +1,9 @@ -#include"IntelliToolPen.h" -#include"Layer/PaintingArea.h" -#include"QDebug" +#include "IntelliToolPen.h" +#include "Layer/PaintingArea.h" +#include "QDebug" IntelliToolPen::IntelliToolPen(PaintingArea* Area) - :IntelliTool(Area){ + :IntelliToolSetColorTool(Area){ } @@ -35,7 +35,9 @@ void IntelliToolPen::onMouseLeftReleased(int x, int y){ void IntelliToolPen::onMouseMoved(int x, int y){ if(this->drawing){ QPoint newPoint(x,y); - this->Canvas->image->drawLine(this->point, newPoint, QColor(255,0,0,255), 2); + Tool = Area->getTool(); + qDebug() << Tool->getFirstColor(); + this->Canvas->image->drawLine(this->point, newPoint, Tool->getFirstColor(), 2); this->point=newPoint; } } diff --git a/src/Painting/Tool/IntelliToolPen.h b/src/Painting/Tool/IntelliToolPen.h index a08ecc6..a54d80d 100644 --- a/src/Painting/Tool/IntelliToolPen.h +++ b/src/Painting/Tool/IntelliToolPen.h @@ -1,12 +1,11 @@ #ifndef INTELLITOOLPEN_H #define INTELLITOOLPEN_H -#include"IntelliTool.h" +#include"IntelliToolSetColorTool.h" #include"QColor" #include"QPoint" -class IntelliToolPen : public IntelliTool{ - QColor clr; +class IntelliToolPen : public IntelliToolSetColorTool{ QPoint point; public: IntelliToolPen(PaintingArea* Area); @@ -18,6 +17,9 @@ public: virtual void onMouseLeftReleased(int x, int y) override; virtual void onMouseMoved(int x, int y) override; + +private: + IntelliToolSetColorTool* Tool; }; #endif // INTELLITOOLPEN_H diff --git a/src/Painting/Tool/IntelliToolSetColorTool.cpp b/src/Painting/Tool/IntelliToolSetColorTool.cpp new file mode 100644 index 0000000..549e0e7 --- /dev/null +++ b/src/Painting/Tool/IntelliToolSetColorTool.cpp @@ -0,0 +1,36 @@ +#include "IntelliToolSetColorTool.h" +#include "QDebug" + +IntelliToolSetColorTool::IntelliToolSetColorTool(PaintingArea* Area) + :IntelliTool(Area){ + firstColor = {255,0,0,255}; + secondColor = {0,0,255,255}; +} + +IntelliToolSetColorTool::~IntelliToolSetColorTool(){ + +} + +void IntelliToolSetColorTool::getColorbar(int firstOrSecondColor = 1){ + QString Titel; + QColor newColor; + if(firstOrSecondColor == 1){ + Titel = "Choose first Color"; + newColor = QColorDialog::getColor(this->firstColor,nullptr,Titel); + this->firstColor = newColor; + qDebug() << "Firstcolor" << this->firstColor; + } + else{ + Titel = "Choose second Color"; + newColor = QColorDialog::getColor(this->secondColor,nullptr,Titel); + this->secondColor = newColor; + } +} + +QColor IntelliToolSetColorTool::getFirstColor(){ + return firstColor; +} + +QColor IntelliToolSetColorTool::getSecondColor(){ + return secondColor; +} diff --git a/src/Painting/Tool/IntelliToolSetColorTool.h b/src/Painting/Tool/IntelliToolSetColorTool.h new file mode 100644 index 0000000..c8c0c1a --- /dev/null +++ b/src/Painting/Tool/IntelliToolSetColorTool.h @@ -0,0 +1,24 @@ +#ifndef INTELLITOOLSETCOLORTOOL_H +#define INTELLITOOLSETCOLORTOOL_H + +#include"IntelliTool.h" +#include"QColor" +#include"QPoint" +#include"QColorDialog" + +class IntelliToolSetColorTool: public IntelliTool{ +public: + IntelliToolSetColorTool(PaintingArea *Area); + virtual ~IntelliToolSetColorTool() override; + + void getColorbar(int firstOrSecondColor) override; + + QColor IntelliToolSetColorTool::getFirstColor(); + QColor IntelliToolSetColorTool::getSecondColor(); + +protected: + QColor firstColor; + QColor secondColor; +}; + +#endif // INTELLITOOLSETCOLORTOOL_H From b1895b0c049909799a713e3adb36475e16c15ecc Mon Sep 17 00:00:00 2001 From: Sonaion Date: Wed, 11 Dec 2019 18:54:04 +0100 Subject: [PATCH 13/19] Modularisation --- src/Painting/GUI/IntelliPhotoGui.cpp | 42 +++++++++++-------- src/Painting/GUI/IntelliPhotoGui.h | 14 +++---- src/Painting/IntelliPhoto.pro | 4 +- src/Painting/Layer/PaintingArea.cpp | 23 +++++++--- src/Painting/Layer/PaintingArea.h | 7 ++-- .../Tool/IntelliToolFloodFillTool.cpp | 29 ++++--------- src/Painting/Tool/IntelliToolFloodFillTool.h | 19 ++++----- src/Painting/Tool/IntelliToolPen.cpp | 11 +++-- src/Painting/Tool/IntelliToolPen.h | 9 ++-- src/Painting/Tool/IntelliToolSetColorTool.cpp | 36 ---------------- src/Painting/Tool/IntelliToolSetColorTool.h | 24 ----------- 11 files changed, 81 insertions(+), 137 deletions(-) delete mode 100644 src/Painting/Tool/IntelliToolSetColorTool.cpp delete mode 100644 src/Painting/Tool/IntelliToolSetColorTool.h diff --git a/src/Painting/GUI/IntelliPhotoGui.cpp b/src/Painting/GUI/IntelliPhotoGui.cpp index ca123d4..51d5731 100644 --- a/src/Painting/GUI/IntelliPhotoGui.cpp +++ b/src/Painting/GUI/IntelliPhotoGui.cpp @@ -111,18 +111,15 @@ void IntelliPhotoGui::slotDeleteLayer() paintingArea->deleteLayer(layerNumber); } -void IntelliPhotoGui::slotGetColorbar(){ +void slotCreatePenTool(){ - bool ok1; - - int firstOrSecondColor = QInputDialog::getInt(this, tr("Which Color"), - tr("Number:"), - 1,1, 2, 1, &ok1); - - Tool = paintingArea->getTool(); - Tool->getColorbar(firstOrSecondColor); } +void slotCreateFloodFillTool(){ + +} + + void IntelliPhotoGui::slotSetActiveAlpha(){ // Stores button value bool ok1, ok2; @@ -218,6 +215,14 @@ void IntelliPhotoGui::slotSetActiveLayer(){ }; +void IntelliPhotoGui::slotCreatePenTool(){ + paintingArea->createPenTool(); +} + +void IntelliPhotoGui::slotCreateFloodFillTool(){ + paintingArea->createFloodFillTool(); +} + // Open an about dialog void IntelliPhotoGui::slotAboutDialog() { @@ -275,17 +280,10 @@ void IntelliPhotoGui::createActions() actionCreateNewLayer = new QAction(tr("&New Layer..."), this); connect(actionCreateNewLayer, SIGNAL(triggered()), this, SLOT(slotCreateNewLayer())); - // Delete New Layer action and tie to IntelliPhotoGui::deleteLayer() actionDeleteLayer = new QAction(tr("&Delete Layer..."), this); connect(actionDeleteLayer, SIGNAL(triggered()), this, SLOT(slotDeleteLayer())); - actionGetColorbar = new QAction(tr("&Set Color"),this); - connect(actionGetColorbar, SIGNAL(triggered()), this, SLOT(slotGetColorbar())); - - actionFloodFill = new QAction(tr("&clear Image"), this); - connect(actionFloodFill, SIGNAL(triggered()), this, SLOT(slotClearActiveLayer())); - actionSetActiveLayer = new QAction(tr("&set Active"), this); connect(actionSetActiveLayer, SIGNAL(triggered()), this, SLOT(slotSetActiveLayer())); @@ -316,6 +314,14 @@ void IntelliPhotoGui::createActions() actionMoveLayerDown->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Down)); connect(actionMoveLayerDown, SIGNAL(triggered()), this, SLOT(slotMoveLayerDown())); + //Create Tool actions down here + actionCreateFloodFillTool = new QAction(tr("&Flood Fill"), this); + connect(actionCreateFloodFillTool, SIGNAL(triggered()), this, SLOT(slotCreateFloodFillTool())); + + actionCreatePenTool = new QAction(tr("&Pen"),this); + connect(actionCreatePenTool, SIGNAL(triggered()), this, SLOT(slotCreatePenTool())); + + // Create about action and tie to IntelliPhotoGui::about() actionAboutDialog = new QAction(tr("&About"), this); connect(actionAboutDialog, SIGNAL(triggered()), this, SLOT(slotAboutDialog())); @@ -343,7 +349,6 @@ void IntelliPhotoGui::createMenus() // Attach all actions to Options optionMenu = new QMenu(tr("&Options"), this); - optionMenu->addAction(actionFloodFill); optionMenu->addAction(actionSetActiveLayer); optionMenu->addAction(actionSetActiveAlpha); optionMenu->addAction(actionMovePositionUp); @@ -360,7 +365,8 @@ void IntelliPhotoGui::createMenus() //Attach all Tool Options toolMenu = new QMenu(tr("&Tools"), this); - toolMenu->addAction(actionGetColorbar); + toolMenu->addAction(actionCreatePenTool); + toolMenu->addAction(actionCreateFloodFillTool); // Attach all actions to Help helpMenu = new QMenu(tr("&Help"), this); diff --git a/src/Painting/GUI/IntelliPhotoGui.h b/src/Painting/GUI/IntelliPhotoGui.h index 10b0e1d..994c0c7 100644 --- a/src/Painting/GUI/IntelliPhotoGui.h +++ b/src/Painting/GUI/IntelliPhotoGui.h @@ -33,11 +33,6 @@ private slots: void slotSave(); void slotCreateNewLayer(); void slotDeleteLayer(); - - void slotGetColorbar(); - - void slotAboutDialog(); - void slotClearActiveLayer(); void slotSetActiveLayer(); void slotSetActiveAlpha(); @@ -48,6 +43,11 @@ private slots: void slotMoveLayerUp(); void slotMoveLayerDown(); + void slotCreatePenTool(); + void slotCreateFloodFillTool(); + + void slotAboutDialog(); + private: // Will tie user actions to functions void createActions(); @@ -82,12 +82,12 @@ private: QAction *actionCreateNewLayer; QAction *actionDeleteLayer; - QAction *actionGetColorbar; + QAction *actionCreatePenTool; + QAction *actionCreateFloodFillTool; QAction *actionAboutDialog; QAction *actionAboutQtDialog; - QAction* actionFloodFill; QAction* actionSetActiveLayer; QAction* actionSetActiveAlpha; QAction* actionMovePositionUp; diff --git a/src/Painting/IntelliPhoto.pro b/src/Painting/IntelliPhoto.pro index 45e293d..e83f1d7 100644 --- a/src/Painting/IntelliPhoto.pro +++ b/src/Painting/IntelliPhoto.pro @@ -25,7 +25,6 @@ SOURCES += \ Tool/IntelliTool.cpp \ Tool/IntelliToolFloodFillTool.cpp \ Tool/IntelliToolPen.cpp \ - Tool/IntelliToolSetColorTool.cpp \ main.cpp HEADERS += \ @@ -37,8 +36,7 @@ HEADERS += \ Layer/PaintingArea.h \ Tool/IntelliTool.h \ Tool/IntelliToolFloodFillTool.h \ - Tool/IntelliToolPen.h \ - Tool/IntelliToolSetColorTool.h + Tool/IntelliToolPen.h FORMS += \ widget.ui diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index 7186907..2c3ec59 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -11,14 +11,12 @@ #include "Image/IntelliRasterImage.h" #include "Image/IntelliShapedImage.h" #include "Tool/IntelliToolPen.h" -#include "Tool/IntelliToolSetColorTool.h" #include "Tool/IntelliToolFloodFillTool.h" PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) :QWidget(parent){ - this->Tool = new IntelliToolFloodFillTool(this); - this->ColorTool = new IntelliToolSetColorTool(this); + this->Tool = nullptr; this->setUp(maxWidth, maxHeight); //tetsing this->addLayer(200,200,0,0,ImageType::Shaped_Image); @@ -37,9 +35,6 @@ PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) activeLayer=1; } -IntelliToolSetColorTool* PaintingArea::getTool(){ - return ColorTool; -} void PaintingArea::setUp(int maxWidth, int maxHeight){ //set standart parameter @@ -165,11 +160,23 @@ void PaintingArea::slotActivateLayer(int a){ } } +void PaintingArea::createPenTool(){ + delete this->Tool; + Tool = new IntelliToolPen(this); +} + +void PaintingArea::createFloodFillTool(){ + delete this->Tool; + Tool = new IntelliToolFloodFillTool(this); +} + // If a mouse button is pressed check if it was the // left button and if so store the current position // Set that we are currently drawing void PaintingArea::mousePressEvent(QMouseEvent *event) { + if(Tool == nullptr) + return; int x = event->x()-layerBundle[activeLayer].widthOffset; int y = event->y()-layerBundle[activeLayer].hightOffset; if(event->button() == Qt::LeftButton){ @@ -185,6 +192,8 @@ void PaintingArea::mousePressEvent(QMouseEvent *event) // from the last position to the current void PaintingArea::mouseMoveEvent(QMouseEvent *event) { + if(Tool == nullptr) + return; int x = event->x()-layerBundle[activeLayer].widthOffset; int y = event->y()-layerBundle[activeLayer].hightOffset; Tool->onMouseMoved(x, y); @@ -193,6 +202,8 @@ void PaintingArea::mouseMoveEvent(QMouseEvent *event) // If the button is released we set variables to stop drawing void PaintingArea::mouseReleaseEvent(QMouseEvent *event) { + if(Tool == nullptr) + return; int x = event->x()-layerBundle[activeLayer].widthOffset; int y = event->y()-layerBundle[activeLayer].hightOffset; if(event->button() == Qt::LeftButton){ diff --git a/src/Painting/Layer/PaintingArea.h b/src/Painting/Layer/PaintingArea.h index abdc990..6c5e208 100644 --- a/src/Painting/Layer/PaintingArea.h +++ b/src/Painting/Layer/PaintingArea.h @@ -9,7 +9,6 @@ #include #include "Image/IntelliImage.h" #include "Tool/IntelliTool.h" -#include "Tool/IntelliToolSetColorTool.h" struct LayerObject{ @@ -33,8 +32,6 @@ class PaintingArea : public QWidget public: PaintingArea(int maxWidth=600, int maxHeight=600, QWidget *parent = nullptr); - IntelliToolSetColorTool* getTool(); //TODO: rename function, when there are more Tools - // Handles all events bool open(const QString &fileName); bool save(const QString &fileName, const char *fileFormat); @@ -51,6 +48,9 @@ public: // Has the image been modified since last save bool isModified() const { return modified; } + //create tools + void createPenTool(); + void createFloodFillTool(); public slots: @@ -81,7 +81,6 @@ private: int maxHeight; IntelliTool* Tool; - IntelliToolSetColorTool* ColorTool; std::vector layerBundle; int activeLayer=-1; diff --git a/src/Painting/Tool/IntelliToolFloodFillTool.cpp b/src/Painting/Tool/IntelliToolFloodFillTool.cpp index c7c476e..5bc163d 100644 --- a/src/Painting/Tool/IntelliToolFloodFillTool.cpp +++ b/src/Painting/Tool/IntelliToolFloodFillTool.cpp @@ -1,41 +1,30 @@ #include "IntelliToolFloodFillTool.h" #include "Layer/PaintingArea.h" +#include "QColorDialog" IntelliToolFloodFillTool::IntelliToolFloodFillTool(PaintingArea* Area) - :IntelliToolSetColorTool(Area) -{ - Tool = Area->getTool(); - isPressed = false; + :IntelliTool(Area){ + + this->color = QColorDialog::getColor(Qt::blue,nullptr,"Flood Fill Color"); } void IntelliToolFloodFillTool::onMouseLeftPressed(int x, int y){ - if(!isPressed){ - isPressed = true; - IntelliTool::onMouseLeftPressed(x,y); - Tool = Area->getTool(); - this->Canvas->image->floodFill(Tool->getFirstColor()); - } + IntelliTool::onMouseLeftPressed(x,y); + this->Canvas->image->floodFill(color); } void IntelliToolFloodFillTool::onMouseRightPressed(int x, int y){ - if(!isPressed){ - isPressed = true; - IntelliTool::onMouseLeftPressed(x,y); - Tool = Area->getTool(); - this->Canvas->image->floodFill(Tool->getSecondColor()); - } + IntelliTool::onMouseRightPressed(x,y); } void IntelliToolFloodFillTool::onMouseRightReleased(int x, int y){ - IntelliTool::onMouseLeftReleased(x,y); - if(isPressed) isPressed = false; + IntelliTool::onMouseRightReleased(x,y); } void IntelliToolFloodFillTool::onMouseLeftReleased(int x, int y){ IntelliTool::onMouseLeftReleased(x,y); - if(isPressed) isPressed = false; } void IntelliToolFloodFillTool::onMouseMoved(int x, int y){ - IntelliTool::onMouseRightPressed(x,y); + IntelliTool::onMouseMoved(x,y); } diff --git a/src/Painting/Tool/IntelliToolFloodFillTool.h b/src/Painting/Tool/IntelliToolFloodFillTool.h index 30b1e95..b1ea02c 100644 --- a/src/Painting/Tool/IntelliToolFloodFillTool.h +++ b/src/Painting/Tool/IntelliToolFloodFillTool.h @@ -1,22 +1,21 @@ #ifndef INTELLITOOLFLOODFILLTOOL_H #define INTELLITOOLFLOODFILLTOOL_H -#include "IntelliToolSetColorTool.h" +#include "IntelliTool.h" +#include "QColor" -class IntelliToolFloodFillTool : public IntelliToolSetColorTool +class IntelliToolFloodFillTool : public IntelliTool { + QColor color; public: IntelliToolFloodFillTool(PaintingArea *Area); - void IntelliToolFloodFillTool::onMouseLeftPressed(int x, int y) override; - void IntelliToolFloodFillTool::onMouseLeftReleased(int x, int y) override; - void IntelliToolFloodFillTool::onMouseRightPressed(int x, int y) override; - void IntelliToolFloodFillTool::onMouseRightReleased(int x, int y) override; - void IntelliToolFloodFillTool::onMouseMoved(int x, int y) override; + void onMouseLeftPressed(int x, int y) override; + void onMouseLeftReleased(int x, int y) override; + void onMouseRightPressed(int x, int y) override; + void onMouseRightReleased(int x, int y) override; + void onMouseMoved(int x, int y) override; -private: - IntelliToolSetColorTool* Tool; - bool isPressed; }; #endif // INTELLITOOLFLOODFILLTOOL_H diff --git a/src/Painting/Tool/IntelliToolPen.cpp b/src/Painting/Tool/IntelliToolPen.cpp index a858908..4da6754 100644 --- a/src/Painting/Tool/IntelliToolPen.cpp +++ b/src/Painting/Tool/IntelliToolPen.cpp @@ -1,10 +1,15 @@ #include "IntelliToolPen.h" #include "Layer/PaintingArea.h" #include "QDebug" +#include "QColorDialog" +#include "QInputDialog" IntelliToolPen::IntelliToolPen(PaintingArea* Area) - :IntelliToolSetColorTool(Area){ + :IntelliTool(Area){ + this->color = QColorDialog::getColor(Qt::blue,nullptr,"Flood Fill Color"); + bool ok; + this->penWidth = QInputDialog::getInt(nullptr, "Pen width", "Number:", 1,0, 50, 1, &ok); } IntelliToolPen::~IntelliToolPen(){ @@ -35,9 +40,7 @@ void IntelliToolPen::onMouseLeftReleased(int x, int y){ void IntelliToolPen::onMouseMoved(int x, int y){ if(this->drawing){ QPoint newPoint(x,y); - Tool = Area->getTool(); - qDebug() << Tool->getFirstColor(); - this->Canvas->image->drawLine(this->point, newPoint, Tool->getFirstColor(), 2); + this->Canvas->image->drawLine(this->point, newPoint, color, penWidth); this->point=newPoint; } } diff --git a/src/Painting/Tool/IntelliToolPen.h b/src/Painting/Tool/IntelliToolPen.h index a54d80d..2728348 100644 --- a/src/Painting/Tool/IntelliToolPen.h +++ b/src/Painting/Tool/IntelliToolPen.h @@ -1,11 +1,13 @@ #ifndef INTELLITOOLPEN_H #define INTELLITOOLPEN_H -#include"IntelliToolSetColorTool.h" +#include"IntelliTool.h" #include"QColor" #include"QPoint" -class IntelliToolPen : public IntelliToolSetColorTool{ +class IntelliToolPen : public IntelliTool{ + QColor color; + int penWidth; QPoint point; public: IntelliToolPen(PaintingArea* Area); @@ -17,9 +19,6 @@ public: virtual void onMouseLeftReleased(int x, int y) override; virtual void onMouseMoved(int x, int y) override; - -private: - IntelliToolSetColorTool* Tool; }; #endif // INTELLITOOLPEN_H diff --git a/src/Painting/Tool/IntelliToolSetColorTool.cpp b/src/Painting/Tool/IntelliToolSetColorTool.cpp deleted file mode 100644 index 549e0e7..0000000 --- a/src/Painting/Tool/IntelliToolSetColorTool.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "IntelliToolSetColorTool.h" -#include "QDebug" - -IntelliToolSetColorTool::IntelliToolSetColorTool(PaintingArea* Area) - :IntelliTool(Area){ - firstColor = {255,0,0,255}; - secondColor = {0,0,255,255}; -} - -IntelliToolSetColorTool::~IntelliToolSetColorTool(){ - -} - -void IntelliToolSetColorTool::getColorbar(int firstOrSecondColor = 1){ - QString Titel; - QColor newColor; - if(firstOrSecondColor == 1){ - Titel = "Choose first Color"; - newColor = QColorDialog::getColor(this->firstColor,nullptr,Titel); - this->firstColor = newColor; - qDebug() << "Firstcolor" << this->firstColor; - } - else{ - Titel = "Choose second Color"; - newColor = QColorDialog::getColor(this->secondColor,nullptr,Titel); - this->secondColor = newColor; - } -} - -QColor IntelliToolSetColorTool::getFirstColor(){ - return firstColor; -} - -QColor IntelliToolSetColorTool::getSecondColor(){ - return secondColor; -} diff --git a/src/Painting/Tool/IntelliToolSetColorTool.h b/src/Painting/Tool/IntelliToolSetColorTool.h deleted file mode 100644 index c8c0c1a..0000000 --- a/src/Painting/Tool/IntelliToolSetColorTool.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef INTELLITOOLSETCOLORTOOL_H -#define INTELLITOOLSETCOLORTOOL_H - -#include"IntelliTool.h" -#include"QColor" -#include"QPoint" -#include"QColorDialog" - -class IntelliToolSetColorTool: public IntelliTool{ -public: - IntelliToolSetColorTool(PaintingArea *Area); - virtual ~IntelliToolSetColorTool() override; - - void getColorbar(int firstOrSecondColor) override; - - QColor IntelliToolSetColorTool::getFirstColor(); - QColor IntelliToolSetColorTool::getSecondColor(); - -protected: - QColor firstColor; - QColor secondColor; -}; - -#endif // INTELLITOOLSETCOLORTOOL_H From e8d8223cc2c4776bc22e3a1e5ac64555a60cbda1 Mon Sep 17 00:00:00 2001 From: AshBastian Date: Thu, 12 Dec 2019 10:22:20 +0100 Subject: [PATCH 14/19] =?UTF-8?q?=C3=84nderung=20der=20Vererbung=20der=20T?= =?UTF-8?q?ools=20und=20einf=C3=BCgen=20des=20ColorPickers=20(Farbmanager)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Painting/GUI/IntelliPhotoGui.cpp | 35 ++++++++++++-- src/Painting/GUI/IntelliPhotoGui.h | 9 +++- .../IntelliHelper/IntelliColorPicker.cpp | 47 +++++++++++++++++++ .../IntelliHelper/IntelliColorPicker.h | 28 +++++++++++ src/Painting/IntelliPhoto.pro | 6 +-- src/Painting/Layer/PaintingArea.cpp | 32 +++++++++---- src/Painting/Layer/PaintingArea.h | 18 +++++-- ...etColorTool.cpp => IntelliColorPicker.cpp} | 12 ++--- src/Painting/Tool/IntelliTool.cpp | 4 -- src/Painting/Tool/IntelliTool.h | 2 - .../Tool/IntelliToolFloodFillTool.cpp | 8 ++-- src/Painting/Tool/IntelliToolFloodFillTool.h | 16 +++---- src/Painting/Tool/IntelliToolPen.cpp | 8 ++-- src/Painting/Tool/IntelliToolPen.h | 8 ++-- src/Painting/Tool/IntelliToolSetColorTool.h | 24 ---------- 15 files changed, 180 insertions(+), 77 deletions(-) create mode 100644 src/Painting/IntelliHelper/IntelliColorPicker.cpp create mode 100644 src/Painting/IntelliHelper/IntelliColorPicker.h rename src/Painting/Tool/{IntelliToolSetColorTool.cpp => IntelliColorPicker.cpp} (65%) delete mode 100644 src/Painting/Tool/IntelliToolSetColorTool.h diff --git a/src/Painting/GUI/IntelliPhotoGui.cpp b/src/Painting/GUI/IntelliPhotoGui.cpp index ca123d4..b624f5a 100644 --- a/src/Painting/GUI/IntelliPhotoGui.cpp +++ b/src/Painting/GUI/IntelliPhotoGui.cpp @@ -119,8 +119,19 @@ void IntelliPhotoGui::slotGetColorbar(){ tr("Number:"), 1,1, 2, 1, &ok1); - Tool = paintingArea->getTool(); - Tool->getColorbar(firstOrSecondColor); + paintingArea->getColorbar(firstOrSecondColor); +} + +void IntelliPhotoGui::slotSwitchColors(){ + paintingArea->switchColors(); +} + +void IntelliPhotoGui::slotCreatePenTool(){ + paintingArea->createPenTool(); +} + +void IntelliPhotoGui::slotCreateFloodFillTool(){ + paintingArea->createFloodFillTool(); } void IntelliPhotoGui::slotSetActiveAlpha(){ @@ -280,9 +291,6 @@ void IntelliPhotoGui::createActions() actionDeleteLayer = new QAction(tr("&Delete Layer..."), this); connect(actionDeleteLayer, SIGNAL(triggered()), this, SLOT(slotDeleteLayer())); - actionGetColorbar = new QAction(tr("&Set Color"),this); - connect(actionGetColorbar, SIGNAL(triggered()), this, SLOT(slotGetColorbar())); - actionFloodFill = new QAction(tr("&clear Image"), this); connect(actionFloodFill, SIGNAL(triggered()), this, SLOT(slotClearActiveLayer())); @@ -316,6 +324,20 @@ void IntelliPhotoGui::createActions() actionMoveLayerDown->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Down)); connect(actionMoveLayerDown, SIGNAL(triggered()), this, SLOT(slotMoveLayerDown())); + //Create Tool actions down here + actionGetColorbar = new QAction(tr("&Set Color"),this); + connect(actionGetColorbar, SIGNAL(triggered()), this, SLOT(slotGetColorbar())); + + actionSwitchColors = new QAction(tr("&Switch Color"),this); + actionSwitchColors->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_C)); + connect(actionSwitchColors, SIGNAL(triggered()),this, SLOT(slotSwitchColors())); + + actionCreateFloodFillTool = new QAction(tr("&Flood Fill"), this); + connect(actionCreateFloodFillTool, SIGNAL(triggered()), this, SLOT(slotCreateFloodFillTool())); + + actionCreatePenTool = new QAction(tr("&Pen"),this); + connect(actionCreatePenTool, SIGNAL(triggered()), this, SLOT(slotCreatePenTool())); + // Create about action and tie to IntelliPhotoGui::about() actionAboutDialog = new QAction(tr("&About"), this); connect(actionAboutDialog, SIGNAL(triggered()), this, SLOT(slotAboutDialog())); @@ -361,6 +383,9 @@ void IntelliPhotoGui::createMenus() //Attach all Tool Options toolMenu = new QMenu(tr("&Tools"), this); toolMenu->addAction(actionGetColorbar); + toolMenu->addAction(actionSwitchColors); + toolMenu->addAction(actionCreatePenTool); + toolMenu->addAction(actionCreateFloodFillTool); // Attach all actions to Help helpMenu = new QMenu(tr("&Help"), this); diff --git a/src/Painting/GUI/IntelliPhotoGui.h b/src/Painting/GUI/IntelliPhotoGui.h index 10b0e1d..b9c7ffd 100644 --- a/src/Painting/GUI/IntelliPhotoGui.h +++ b/src/Painting/GUI/IntelliPhotoGui.h @@ -14,6 +14,8 @@ class PaintingArea; class IntelliTool; +class IntelliColorPicker; + class IntelliPhotoGui : public QMainWindow { // Declares our class as a QObject which is the base class @@ -35,6 +37,9 @@ private slots: void slotDeleteLayer(); void slotGetColorbar(); + void slotSwitchColors(); + void slotCreatePenTool(); + void slotCreateFloodFillTool(); void slotAboutDialog(); @@ -65,7 +70,6 @@ private: // What we'll draw on PaintingArea* paintingArea; - IntelliTool* Tool; // The menu widgets QMenu *saveAsMenu; @@ -83,6 +87,9 @@ private: QAction *actionDeleteLayer; QAction *actionGetColorbar; + QAction *actionSwitchColors; + QAction *actionCreatePenTool; + QAction *actionCreateFloodFillTool; QAction *actionAboutDialog; QAction *actionAboutQtDialog; diff --git a/src/Painting/IntelliHelper/IntelliColorPicker.cpp b/src/Painting/IntelliHelper/IntelliColorPicker.cpp new file mode 100644 index 0000000..cfd951f --- /dev/null +++ b/src/Painting/IntelliHelper/IntelliColorPicker.cpp @@ -0,0 +1,47 @@ +#include "IntelliColorPicker.h" + +IntelliColorPicker::IntelliColorPicker(PaintingArea* Area){ + firstColor = {255,0,0,255}; + secondColor = {0,0,255,255}; +} + +IntelliColorPicker::~IntelliColorPicker(){ + +} + +void IntelliColorPicker::getColorbar(int firstOrSecondColor = 1){ + QString Titel; + QColor newColor; + if(firstOrSecondColor == 1){ + Titel = "Choose first Color"; + newColor = QColorDialog::getColor(this->firstColor,nullptr,Titel); + setFirstColor(newColor); + } + else{ + Titel = "Choose second Color"; + newColor = QColorDialog::getColor(this->secondColor,nullptr,Titel); + setFirstColor(newColor); + } +} + +void IntelliColorPicker::switchColors(){ + QColor temp = this->firstColor; + this->firstColor = this->secondColor; + this->secondColor = temp; +} + +QColor IntelliColorPicker::getFirstColor(){ + return this->firstColor; +} + +QColor IntelliColorPicker::getSecondColor(){ + return this->secondColor; +} + +void IntelliColorPicker::setFirstColor(QColor Color){ + this->firstColor = Color; +} + +void IntelliColorPicker::setSecondColor(QColor Color){ + this->secondColor = Color; +} diff --git a/src/Painting/IntelliHelper/IntelliColorPicker.h b/src/Painting/IntelliHelper/IntelliColorPicker.h new file mode 100644 index 0000000..1eeb28e --- /dev/null +++ b/src/Painting/IntelliHelper/IntelliColorPicker.h @@ -0,0 +1,28 @@ +#ifndef INTELLITOOLSETCOLORTOOL_H +#define INTELLITOOLSETCOLORTOOL_H + +#include"Layer/PaintingArea.h" +#include"QColor" +#include"QPoint" +#include"QColorDialog" + +class IntelliColorPicker{ +public: + IntelliColorPicker(PaintingArea *Area); + virtual ~IntelliColorPicker(); + + void getColorbar(int firstOrSecondColor); + void switchColors(); + + QColor getFirstColor(); + QColor getSecondColor(); + + void setFirstColor(QColor Color); + void setSecondColor(QColor Color); + +private: + QColor firstColor; + QColor secondColor; +}; + +#endif // INTELLITOOLSETCOLORTOOL_H diff --git a/src/Painting/IntelliPhoto.pro b/src/Painting/IntelliPhoto.pro index 9e0d263..5dbb70d 100644 --- a/src/Painting/IntelliPhoto.pro +++ b/src/Painting/IntelliPhoto.pro @@ -20,12 +20,12 @@ SOURCES += \ Image/IntelliImage.cpp \ Image/IntelliRasterImage.cpp \ Image/IntelliShapedImage.cpp \ + IntelliHelper/IntelliColorPicker.cpp \ IntelliHelper/IntelliHelper.cpp \ Layer/PaintingArea.cpp \ Tool/IntelliTool.cpp \ Tool/IntelliToolFloodFillTool.cpp \ Tool/IntelliToolPen.cpp \ - Tool/IntelliToolSetColorTool.cpp \ main.cpp HEADERS += \ @@ -33,12 +33,12 @@ HEADERS += \ Image/IntelliImage.h \ Image/IntelliRasterImage.h \ Image/IntelliShapedImage.h \ + IntelliHelper/IntelliColorPicker.h \ IntelliHelper/IntelliHelper.h \ Layer/PaintingArea.h \ Tool/IntelliTool.h \ Tool/IntelliToolFloodFillTool.h \ - Tool/IntelliToolPen.h \ - Tool/IntelliToolSetColorTool.h + Tool/IntelliToolPen.h FORMS += \ widget.ui diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index 7186907..1f2cd18 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -8,17 +8,11 @@ #include #include "PaintingArea.h" -#include "Image/IntelliRasterImage.h" -#include "Image/IntelliShapedImage.h" -#include "Tool/IntelliToolPen.h" -#include "Tool/IntelliToolSetColorTool.h" -#include "Tool/IntelliToolFloodFillTool.h" - PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) :QWidget(parent){ - this->Tool = new IntelliToolFloodFillTool(this); - this->ColorTool = new IntelliToolSetColorTool(this); + this->Tool = new IntelliToolPen(this); + this->ColorTool = new IntelliColorPicker(this); this->setUp(maxWidth, maxHeight); //tetsing this->addLayer(200,200,0,0,ImageType::Shaped_Image); @@ -37,10 +31,30 @@ PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) activeLayer=1; } -IntelliToolSetColorTool* PaintingArea::getTool(){ +void PaintingArea::getColorbar(int firstOrSecondColor){ + ColorTool->getColorbar(firstOrSecondColor); +} + +IntelliColorPicker* PaintingArea::getColorTool(){ return ColorTool; } +void PaintingArea::switchColors(){ + ColorTool->switchColors(); +} + +void PaintingArea::createPenTool(){ + IntelliTool *temp = this->Tool; + this->Tool = new IntelliToolPen(this); + delete temp; +} + +void PaintingArea::createFloodFillTool(){ + IntelliTool *temp = this->Tool; + this->Tool = new IntelliToolFloodFillTool(this); + delete temp; +} + void PaintingArea::setUp(int maxWidth, int maxHeight){ //set standart parameter this->maxWidth = maxWidth; diff --git a/src/Painting/Layer/PaintingArea.h b/src/Painting/Layer/PaintingArea.h index abdc990..2fa317a 100644 --- a/src/Painting/Layer/PaintingArea.h +++ b/src/Painting/Layer/PaintingArea.h @@ -8,8 +8,11 @@ #include #include #include "Image/IntelliImage.h" +#include "Image/IntelliRasterImage.h" +#include "Image/IntelliShapedImage.h" #include "Tool/IntelliTool.h" -#include "Tool/IntelliToolSetColorTool.h" +#include "Tool/IntelliToolPen.h" +#include "Tool/IntelliToolFloodFillTool.h" struct LayerObject{ @@ -23,6 +26,8 @@ struct LayerObject{ }; +class IntelliColorPicker; + class PaintingArea : public QWidget { // Declares our class as a QObject which is the base class @@ -33,7 +38,14 @@ class PaintingArea : public QWidget public: PaintingArea(int maxWidth=600, int maxHeight=600, QWidget *parent = nullptr); - IntelliToolSetColorTool* getTool(); //TODO: rename function, when there are more Tools + IntelliColorPicker* getColorTool(); + + void getColorbar(int firstOrSecondColor); + void switchColors(); + + //Create Tools + void createPenTool(); + void createFloodFillTool(); // Handles all events bool open(const QString &fileName); @@ -81,7 +93,7 @@ private: int maxHeight; IntelliTool* Tool; - IntelliToolSetColorTool* ColorTool; + IntelliColorPicker* ColorTool; std::vector layerBundle; int activeLayer=-1; diff --git a/src/Painting/Tool/IntelliToolSetColorTool.cpp b/src/Painting/Tool/IntelliColorPicker.cpp similarity index 65% rename from src/Painting/Tool/IntelliToolSetColorTool.cpp rename to src/Painting/Tool/IntelliColorPicker.cpp index 549e0e7..55af5b9 100644 --- a/src/Painting/Tool/IntelliToolSetColorTool.cpp +++ b/src/Painting/Tool/IntelliColorPicker.cpp @@ -1,17 +1,17 @@ -#include "IntelliToolSetColorTool.h" +#include "IntelliColorPicker.h" #include "QDebug" -IntelliToolSetColorTool::IntelliToolSetColorTool(PaintingArea* Area) +IntelliColorPicker::IntelliColorPicker(PaintingArea* Area) :IntelliTool(Area){ firstColor = {255,0,0,255}; secondColor = {0,0,255,255}; } -IntelliToolSetColorTool::~IntelliToolSetColorTool(){ +IntelliColorPicker::~IntelliColorPicker(){ } -void IntelliToolSetColorTool::getColorbar(int firstOrSecondColor = 1){ +void IntelliColorPicker::getColorbar(int firstOrSecondColor = 1){ QString Titel; QColor newColor; if(firstOrSecondColor == 1){ @@ -27,10 +27,10 @@ void IntelliToolSetColorTool::getColorbar(int firstOrSecondColor = 1){ } } -QColor IntelliToolSetColorTool::getFirstColor(){ +QColor IntelliColorPicker::getFirstColor(){ return firstColor; } -QColor IntelliToolSetColorTool::getSecondColor(){ +QColor IntelliColorPicker::getSecondColor(){ return secondColor; } diff --git a/src/Painting/Tool/IntelliTool.cpp b/src/Painting/Tool/IntelliTool.cpp index 4aa4403..e2f11ff 100644 --- a/src/Painting/Tool/IntelliTool.cpp +++ b/src/Painting/Tool/IntelliTool.cpp @@ -10,10 +10,6 @@ IntelliTool::~IntelliTool(){ } -void IntelliTool::getColorbar(int firstOrSecondColor){ - //optional for tool -} - void IntelliTool::onMouseRightPressed(int x, int y){ if(drawing){ drawing=false; diff --git a/src/Painting/Tool/IntelliTool.h b/src/Painting/Tool/IntelliTool.h index 75343ce..a519616 100644 --- a/src/Painting/Tool/IntelliTool.h +++ b/src/Painting/Tool/IntelliTool.h @@ -21,8 +21,6 @@ public: IntelliTool(PaintingArea* Area); virtual ~IntelliTool() = 0; - virtual void getColorbar(int firstOrSecondColor); - virtual void onMouseRightPressed(int x, int y); virtual void onMouseRightReleased(int x, int y); virtual void onMouseLeftPressed(int x, int y); diff --git a/src/Painting/Tool/IntelliToolFloodFillTool.cpp b/src/Painting/Tool/IntelliToolFloodFillTool.cpp index c7c476e..4a7c34a 100644 --- a/src/Painting/Tool/IntelliToolFloodFillTool.cpp +++ b/src/Painting/Tool/IntelliToolFloodFillTool.cpp @@ -2,9 +2,9 @@ #include "Layer/PaintingArea.h" IntelliToolFloodFillTool::IntelliToolFloodFillTool(PaintingArea* Area) - :IntelliToolSetColorTool(Area) + :IntelliTool(Area) { - Tool = Area->getTool(); + Tool = Area->getColorTool(); isPressed = false; } @@ -12,7 +12,7 @@ void IntelliToolFloodFillTool::onMouseLeftPressed(int x, int y){ if(!isPressed){ isPressed = true; IntelliTool::onMouseLeftPressed(x,y); - Tool = Area->getTool(); + Tool = Area->getColorTool(); this->Canvas->image->floodFill(Tool->getFirstColor()); } } @@ -21,7 +21,7 @@ void IntelliToolFloodFillTool::onMouseRightPressed(int x, int y){ if(!isPressed){ isPressed = true; IntelliTool::onMouseLeftPressed(x,y); - Tool = Area->getTool(); + Tool = Area->getColorTool(); this->Canvas->image->floodFill(Tool->getSecondColor()); } } diff --git a/src/Painting/Tool/IntelliToolFloodFillTool.h b/src/Painting/Tool/IntelliToolFloodFillTool.h index 30b1e95..b706a99 100644 --- a/src/Painting/Tool/IntelliToolFloodFillTool.h +++ b/src/Painting/Tool/IntelliToolFloodFillTool.h @@ -1,21 +1,21 @@ #ifndef INTELLITOOLFLOODFILLTOOL_H #define INTELLITOOLFLOODFILLTOOL_H -#include "IntelliToolSetColorTool.h" +#include "IntelliHelper/IntelliColorPicker.h" -class IntelliToolFloodFillTool : public IntelliToolSetColorTool +class IntelliToolFloodFillTool : public IntelliTool { public: IntelliToolFloodFillTool(PaintingArea *Area); - void IntelliToolFloodFillTool::onMouseLeftPressed(int x, int y) override; - void IntelliToolFloodFillTool::onMouseLeftReleased(int x, int y) override; - void IntelliToolFloodFillTool::onMouseRightPressed(int x, int y) override; - void IntelliToolFloodFillTool::onMouseRightReleased(int x, int y) override; - void IntelliToolFloodFillTool::onMouseMoved(int x, int y) override; + void onMouseLeftPressed(int x, int y) override; + void onMouseLeftReleased(int x, int y) override; + void onMouseRightPressed(int x, int y) override; + void onMouseRightReleased(int x, int y) override; + void onMouseMoved(int x, int y) override; private: - IntelliToolSetColorTool* Tool; + IntelliColorPicker* Tool; bool isPressed; }; diff --git a/src/Painting/Tool/IntelliToolPen.cpp b/src/Painting/Tool/IntelliToolPen.cpp index a858908..bbd188f 100644 --- a/src/Painting/Tool/IntelliToolPen.cpp +++ b/src/Painting/Tool/IntelliToolPen.cpp @@ -1,10 +1,9 @@ #include "IntelliToolPen.h" #include "Layer/PaintingArea.h" -#include "QDebug" IntelliToolPen::IntelliToolPen(PaintingArea* Area) - :IntelliToolSetColorTool(Area){ - + :IntelliTool(Area){ + Tool = new IntelliColorPicker(Area); } IntelliToolPen::~IntelliToolPen(){ @@ -35,8 +34,7 @@ void IntelliToolPen::onMouseLeftReleased(int x, int y){ void IntelliToolPen::onMouseMoved(int x, int y){ if(this->drawing){ QPoint newPoint(x,y); - Tool = Area->getTool(); - qDebug() << Tool->getFirstColor(); + Tool = Area->getColorTool(); this->Canvas->image->drawLine(this->point, newPoint, Tool->getFirstColor(), 2); this->point=newPoint; } diff --git a/src/Painting/Tool/IntelliToolPen.h b/src/Painting/Tool/IntelliToolPen.h index a54d80d..d1d2266 100644 --- a/src/Painting/Tool/IntelliToolPen.h +++ b/src/Painting/Tool/IntelliToolPen.h @@ -1,11 +1,13 @@ #ifndef INTELLITOOLPEN_H #define INTELLITOOLPEN_H -#include"IntelliToolSetColorTool.h" +#include"IntelliTool.h" #include"QColor" #include"QPoint" -class IntelliToolPen : public IntelliToolSetColorTool{ +class IntelliColorPicker; + +class IntelliToolPen : public IntelliTool{ QPoint point; public: IntelliToolPen(PaintingArea* Area); @@ -19,7 +21,7 @@ public: virtual void onMouseMoved(int x, int y) override; private: - IntelliToolSetColorTool* Tool; + IntelliColorPicker* Tool; }; #endif // INTELLITOOLPEN_H diff --git a/src/Painting/Tool/IntelliToolSetColorTool.h b/src/Painting/Tool/IntelliToolSetColorTool.h deleted file mode 100644 index c8c0c1a..0000000 --- a/src/Painting/Tool/IntelliToolSetColorTool.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef INTELLITOOLSETCOLORTOOL_H -#define INTELLITOOLSETCOLORTOOL_H - -#include"IntelliTool.h" -#include"QColor" -#include"QPoint" -#include"QColorDialog" - -class IntelliToolSetColorTool: public IntelliTool{ -public: - IntelliToolSetColorTool(PaintingArea *Area); - virtual ~IntelliToolSetColorTool() override; - - void getColorbar(int firstOrSecondColor) override; - - QColor IntelliToolSetColorTool::getFirstColor(); - QColor IntelliToolSetColorTool::getSecondColor(); - -protected: - QColor firstColor; - QColor secondColor; -}; - -#endif // INTELLITOOLSETCOLORTOOL_H From 5ec4f9f8f9e672052326de4a4483732fecce4647 Mon Sep 17 00:00:00 2001 From: Sonaion Date: Thu, 12 Dec 2019 11:18:37 +0100 Subject: [PATCH 15/19] new tools --- src/Painting/GUI/IntelliPhotoGui.cpp | 17 +++++-- src/Painting/GUI/IntelliPhotoGui.h | 6 ++- src/Painting/Image/IntelliImage.h | 5 +- src/Painting/Image/IntelliShapedImage.cpp | 2 +- src/Painting/Image/IntelliShapedImage.h | 5 +- src/Painting/IntelliPhoto.pro | 8 +-- src/Painting/Layer/PaintingArea.cpp | 14 ++++-- src/Painting/Layer/PaintingArea.h | 3 +- src/Painting/Tool/IntelliTool.cpp | 5 +- src/Painting/Tool/IntelliTool.h | 1 - src/Painting/Tool/IntelliToolLine.cpp | 49 +++++++++++++++++++ src/Painting/Tool/IntelliToolLine.h | 31 ++++++++++++ src/Painting/Tool/IntelliToolPen.cpp | 8 +-- ...FloodFillTool.cpp => IntelliToolPlain.cpp} | 30 ++++++------ ...ToolFloodFillTool.h => IntelliToolPlain.h} | 4 +- 15 files changed, 141 insertions(+), 47 deletions(-) create mode 100644 src/Painting/Tool/IntelliToolLine.cpp create mode 100644 src/Painting/Tool/IntelliToolLine.h rename src/Painting/Tool/{IntelliToolFloodFillTool.cpp => IntelliToolPlain.cpp} (50%) rename src/Painting/Tool/{IntelliToolFloodFillTool.h => IntelliToolPlain.h} (81%) diff --git a/src/Painting/GUI/IntelliPhotoGui.cpp b/src/Painting/GUI/IntelliPhotoGui.cpp index 51d5731..aa2970e 100644 --- a/src/Painting/GUI/IntelliPhotoGui.cpp +++ b/src/Painting/GUI/IntelliPhotoGui.cpp @@ -219,8 +219,12 @@ void IntelliPhotoGui::slotCreatePenTool(){ paintingArea->createPenTool(); } -void IntelliPhotoGui::slotCreateFloodFillTool(){ - paintingArea->createFloodFillTool(); +void IntelliPhotoGui::slotCreatePlainTool(){ + paintingArea->createPlainTool(); +} + +void IntelliPhotoGui::slotCreateLineTool(){ + paintingArea->createLineTool(); } // Open an about dialog @@ -315,12 +319,14 @@ void IntelliPhotoGui::createActions() connect(actionMoveLayerDown, SIGNAL(triggered()), this, SLOT(slotMoveLayerDown())); //Create Tool actions down here - actionCreateFloodFillTool = new QAction(tr("&Flood Fill"), this); - connect(actionCreateFloodFillTool, SIGNAL(triggered()), this, SLOT(slotCreateFloodFillTool())); + actionCreatePlainTool = new QAction(tr("&Plain"), this); + connect(actionCreatePlainTool, SIGNAL(triggered()), this, SLOT(slotCreatePlainTool())); actionCreatePenTool = new QAction(tr("&Pen"),this); connect(actionCreatePenTool, SIGNAL(triggered()), this, SLOT(slotCreatePenTool())); + actionCreateLineTool = new QAction(tr("&Line"), this); + connect(actionCreateLineTool, SIGNAL(triggered()), this, SLOT(slotCreateLineTool())); // Create about action and tie to IntelliPhotoGui::about() actionAboutDialog = new QAction(tr("&About"), this); @@ -366,7 +372,8 @@ void IntelliPhotoGui::createMenus() //Attach all Tool Options toolMenu = new QMenu(tr("&Tools"), this); toolMenu->addAction(actionCreatePenTool); - toolMenu->addAction(actionCreateFloodFillTool); + toolMenu->addAction(actionCreatePlainTool); + toolMenu->addAction(actionCreateLineTool); // Attach all actions to Help helpMenu = new QMenu(tr("&Help"), this); diff --git a/src/Painting/GUI/IntelliPhotoGui.h b/src/Painting/GUI/IntelliPhotoGui.h index 994c0c7..7639383 100644 --- a/src/Painting/GUI/IntelliPhotoGui.h +++ b/src/Painting/GUI/IntelliPhotoGui.h @@ -44,7 +44,8 @@ private slots: void slotMoveLayerDown(); void slotCreatePenTool(); - void slotCreateFloodFillTool(); + void slotCreatePlainTool(); + void slotCreateLineTool(); void slotAboutDialog(); @@ -83,7 +84,8 @@ private: QAction *actionDeleteLayer; QAction *actionCreatePenTool; - QAction *actionCreateFloodFillTool; + QAction *actionCreatePlainTool; + QAction *actionCreateLineTool; QAction *actionAboutDialog; QAction *actionAboutQtDialog; diff --git a/src/Painting/Image/IntelliImage.h b/src/Painting/Image/IntelliImage.h index 55ea479..72a7310 100644 --- a/src/Painting/Image/IntelliImage.h +++ b/src/Painting/Image/IntelliImage.h @@ -19,7 +19,6 @@ class IntelliImage{ friend IntelliTool; protected: void resizeImage(QImage *image, const QSize &newSize); - virtual void calculateVisiblity()=0; QImage imageData; @@ -28,6 +27,7 @@ public: IntelliImage(int weight, int height); virtual ~IntelliImage() = 0; + //start on top left virtual void drawPixel(const QPoint &p1, const QColor& color); virtual void drawLine(const QPoint &p1, const QPoint& p2, const QColor& color, const int& penWidth); @@ -39,12 +39,13 @@ public: //gets a copy of the image !allocated virtual IntelliImage* getDeepCopy()=0; + virtual void calculateVisiblity()=0; //returns the filtered output //sets the data for the visible image virtual void setPolygon(const std::vector& polygonData)=0; - + virtual std::vector getPolygonData(){ return std::vector();} //loads an image to the ColorBuffer virtual bool loadImage(const QString &fileName); diff --git a/src/Painting/Image/IntelliShapedImage.cpp b/src/Painting/Image/IntelliShapedImage.cpp index 72480f6..4257847 100644 --- a/src/Painting/Image/IntelliShapedImage.cpp +++ b/src/Painting/Image/IntelliShapedImage.cpp @@ -18,8 +18,8 @@ QImage IntelliShapedImage::getDisplayable(int alpha){ IntelliImage* IntelliShapedImage::getDeepCopy(){ IntelliShapedImage* shaped = new IntelliShapedImage(imageData.width(), imageData.height()); - shaped->setPolygon(this->polygonData); shaped->imageData.fill(Qt::transparent); + shaped->setPolygon(this->polygonData); return shaped; } diff --git a/src/Painting/Image/IntelliShapedImage.h b/src/Painting/Image/IntelliShapedImage.h index e3ef5bc..2c8c3a3 100644 --- a/src/Painting/Image/IntelliShapedImage.h +++ b/src/Painting/Image/IntelliShapedImage.h @@ -6,18 +6,21 @@ class IntelliShapedImage : public IntelliImage{ friend IntelliTool; protected: - virtual void calculateVisiblity() override; + std::vector polygonData; public: IntelliShapedImage(int weight, int height); virtual ~IntelliShapedImage() override; + virtual void calculateVisiblity() override; + //returns the filtered output virtual QImage getDisplayable(const QSize& displaySize, int alpha=255) override; virtual QImage getDisplayable(int alpha=255) override; //gets a copy of the image !allocated virtual IntelliImage* getDeepCopy() override; + virtual std::vector getPolygonData() override{return polygonData;} //sets the data for the visible image virtual void setPolygon(const std::vector& polygonData) override; diff --git a/src/Painting/IntelliPhoto.pro b/src/Painting/IntelliPhoto.pro index e83f1d7..e4c4ce5 100644 --- a/src/Painting/IntelliPhoto.pro +++ b/src/Painting/IntelliPhoto.pro @@ -23,8 +23,9 @@ SOURCES += \ IntelliHelper/IntelliHelper.cpp \ Layer/PaintingArea.cpp \ Tool/IntelliTool.cpp \ - Tool/IntelliToolFloodFillTool.cpp \ + Tool/IntelliToolLine.cpp \ Tool/IntelliToolPen.cpp \ + Tool/IntelliToolPlain.cpp \ main.cpp HEADERS += \ @@ -35,8 +36,9 @@ HEADERS += \ IntelliHelper/IntelliHelper.h \ Layer/PaintingArea.h \ Tool/IntelliTool.h \ - Tool/IntelliToolFloodFillTool.h \ - Tool/IntelliToolPen.h + Tool/IntelliToolLine.h \ + Tool/IntelliToolPen.h \ + Tool/IntelliToolPlain.h FORMS += \ widget.ui diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index 2c3ec59..4b7f450 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -11,7 +11,8 @@ #include "Image/IntelliRasterImage.h" #include "Image/IntelliShapedImage.h" #include "Tool/IntelliToolPen.h" -#include "Tool/IntelliToolFloodFillTool.h" +#include "Tool/IntelliToolPlain.h" +#include "Tool/IntelliToolLine.h" PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) @@ -32,7 +33,7 @@ PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) layerBundle[1].image->floodFill(QColor(0,255,0,255)); layerBundle[1].alpha=200; - activeLayer=1; + activeLayer=0; } @@ -165,9 +166,14 @@ void PaintingArea::createPenTool(){ Tool = new IntelliToolPen(this); } -void PaintingArea::createFloodFillTool(){ +void PaintingArea::createPlainTool(){ delete this->Tool; - Tool = new IntelliToolFloodFillTool(this); + Tool = new IntelliToolPlainTool(this); +} + +void PaintingArea::createLineTool(){ + delete this->Tool; + Tool = new IntelliToolLine(this); } // If a mouse button is pressed check if it was the diff --git a/src/Painting/Layer/PaintingArea.h b/src/Painting/Layer/PaintingArea.h index 6c5e208..2a0ab76 100644 --- a/src/Painting/Layer/PaintingArea.h +++ b/src/Painting/Layer/PaintingArea.h @@ -50,7 +50,8 @@ public: //create tools void createPenTool(); - void createFloodFillTool(); + void createPlainTool(); + void createLineTool(); public slots: diff --git a/src/Painting/Tool/IntelliTool.cpp b/src/Painting/Tool/IntelliTool.cpp index 4aa4403..f10b872 100644 --- a/src/Painting/Tool/IntelliTool.cpp +++ b/src/Painting/Tool/IntelliTool.cpp @@ -10,10 +10,6 @@ IntelliTool::~IntelliTool(){ } -void IntelliTool::getColorbar(int firstOrSecondColor){ - //optional for tool -} - void IntelliTool::onMouseRightPressed(int x, int y){ if(drawing){ drawing=false; @@ -69,6 +65,7 @@ void IntelliTool::mergeToolLayer(){ Active->image->imageData.setPixelColor(x, y, clr_0); } + Active->image->calculateVisiblity(); } } diff --git a/src/Painting/Tool/IntelliTool.h b/src/Painting/Tool/IntelliTool.h index 75343ce..466e03c 100644 --- a/src/Painting/Tool/IntelliTool.h +++ b/src/Painting/Tool/IntelliTool.h @@ -21,7 +21,6 @@ public: IntelliTool(PaintingArea* Area); virtual ~IntelliTool() = 0; - virtual void getColorbar(int firstOrSecondColor); virtual void onMouseRightPressed(int x, int y); virtual void onMouseRightReleased(int x, int y); diff --git a/src/Painting/Tool/IntelliToolLine.cpp b/src/Painting/Tool/IntelliToolLine.cpp new file mode 100644 index 0000000..ff94a6b --- /dev/null +++ b/src/Painting/Tool/IntelliToolLine.cpp @@ -0,0 +1,49 @@ +#include "IntelliToolLine.h" +#include "Layer/PaintingArea.h" +#include "QColorDialog" +#include "QInputDialog" + +IntelliToolLine::IntelliToolLine(PaintingArea* Area) + :IntelliTool(Area){ + this->color = QColorDialog::getColor(Qt::blue, nullptr, "Line Color"); + this->lineWidth = QInputDialog::getInt(nullptr,"Line Width Input", "Width",1,1,50,1); + //create checkbox or scroll dialog to get line style + this->lineStyle = LineStyle::SOLID_LINE; +} + +IntelliToolLine::~IntelliToolLine(){ + +} + + +void IntelliToolLine::onMouseRightPressed(int x, int y){ + IntelliTool::onMouseRightPressed(x,y); +} + +void IntelliToolLine::onMouseRightReleased(int x, int y){ + IntelliTool::onMouseRightReleased(x,y); +} + +void IntelliToolLine::onMouseLeftPressed(int x, int y){ + IntelliTool::onMouseLeftPressed(x,y); + this->start=QPoint(x,y); + this->Canvas->image->drawLine(start, start, this->color, this->lineWidth); +} + +void IntelliToolLine::onMouseLeftReleased(int x, int y){ + IntelliTool::onMouseLeftReleased(x,y); +} + +void IntelliToolLine::onMouseMoved(int x, int y){ + IntelliTool::onMouseMoved(x,y); + if(this->drawing){ + this->Canvas->image->floodFill(Qt::transparent); + QPoint next(x,y); + switch(lineStyle){ + case LineStyle::SOLID_LINE : + this->Canvas->image->drawLine(start,next,color,lineWidth); + break; + } + } + +} diff --git a/src/Painting/Tool/IntelliToolLine.h b/src/Painting/Tool/IntelliToolLine.h new file mode 100644 index 0000000..37faace --- /dev/null +++ b/src/Painting/Tool/IntelliToolLine.h @@ -0,0 +1,31 @@ +#ifndef INTELLITOOLLINE_H +#define INTELLITOOLLINE_H +#include "IntelliTool.h" + +#include "QColor" +#include "QPoint" + +enum class LineStyle{ + SOLID_LINE +}; + +class IntelliToolLine : public IntelliTool +{ + QPoint start; + QColor color; + int lineWidth; + LineStyle lineStyle; +public: + IntelliToolLine(PaintingArea* Area); + virtual ~IntelliToolLine() override; + + + virtual void onMouseRightPressed(int x, int y) override; + virtual void onMouseRightReleased(int x, int y) override; + virtual void onMouseLeftPressed(int x, int y) override; + virtual void onMouseLeftReleased(int x, int y) override; + + virtual void onMouseMoved(int x, int y) override; +}; + +#endif // INTELLITOOLLINE_H diff --git a/src/Painting/Tool/IntelliToolPen.cpp b/src/Painting/Tool/IntelliToolPen.cpp index 4da6754..19b6f0e 100644 --- a/src/Painting/Tool/IntelliToolPen.cpp +++ b/src/Painting/Tool/IntelliToolPen.cpp @@ -7,9 +7,7 @@ IntelliToolPen::IntelliToolPen(PaintingArea* Area) :IntelliTool(Area){ this->color = QColorDialog::getColor(Qt::blue,nullptr,"Flood Fill Color"); - - bool ok; - this->penWidth = QInputDialog::getInt(nullptr, "Pen width", "Number:", 1,0, 50, 1, &ok); + this->penWidth = QInputDialog::getInt(nullptr, "Pen width", "Number:", 1,0, 50, 1); } IntelliToolPen::~IntelliToolPen(){ @@ -18,22 +16,18 @@ IntelliToolPen::~IntelliToolPen(){ void IntelliToolPen::onMouseRightPressed(int x, int y){ IntelliTool::onMouseRightPressed(x,y); - //implement in here } void IntelliToolPen::onMouseRightReleased(int x, int y){ IntelliTool::onMouseRightReleased(x,y); - //implemnt in here } void IntelliToolPen::onMouseLeftPressed(int x, int y){ - //implement in here IntelliTool::onMouseLeftPressed(x,y); this->point=QPoint(x,y); } void IntelliToolPen::onMouseLeftReleased(int x, int y){ - //implement in here IntelliTool::onMouseLeftReleased(x,y); } diff --git a/src/Painting/Tool/IntelliToolFloodFillTool.cpp b/src/Painting/Tool/IntelliToolPlain.cpp similarity index 50% rename from src/Painting/Tool/IntelliToolFloodFillTool.cpp rename to src/Painting/Tool/IntelliToolPlain.cpp index 5bc163d..d344eff 100644 --- a/src/Painting/Tool/IntelliToolFloodFillTool.cpp +++ b/src/Painting/Tool/IntelliToolPlain.cpp @@ -1,30 +1,32 @@ -#include "IntelliToolFloodFillTool.h" +#include "IntelliToolPlain.h" #include "Layer/PaintingArea.h" #include "QColorDialog" -IntelliToolFloodFillTool::IntelliToolFloodFillTool(PaintingArea* Area) +IntelliToolPlainTool::IntelliToolPlainTool(PaintingArea* Area) :IntelliTool(Area){ this->color = QColorDialog::getColor(Qt::blue,nullptr,"Flood Fill Color"); } -void IntelliToolFloodFillTool::onMouseLeftPressed(int x, int y){ +void IntelliToolPlainTool::onMouseLeftPressed(int x, int y){ IntelliTool::onMouseLeftPressed(x,y); this->Canvas->image->floodFill(color); } -void IntelliToolFloodFillTool::onMouseRightPressed(int x, int y){ - IntelliTool::onMouseRightPressed(x,y); -} - -void IntelliToolFloodFillTool::onMouseRightReleased(int x, int y){ - IntelliTool::onMouseRightReleased(x,y); -} - -void IntelliToolFloodFillTool::onMouseLeftReleased(int x, int y){ +void IntelliToolPlainTool::onMouseLeftReleased(int x, int y){ IntelliTool::onMouseLeftReleased(x,y); } -void IntelliToolFloodFillTool::onMouseMoved(int x, int y){ - IntelliTool::onMouseMoved(x,y); +void IntelliToolPlainTool::onMouseRightPressed(int x, int y){ + IntelliTool::onMouseRightPressed(x,y); +} + +void IntelliToolPlainTool::onMouseRightReleased(int x, int y){ + IntelliTool::onMouseRightReleased(x,y); +} + + +void IntelliToolPlainTool::onMouseMoved(int x, int y){ + IntelliTool::onMouseMoved(x,y); + } diff --git a/src/Painting/Tool/IntelliToolFloodFillTool.h b/src/Painting/Tool/IntelliToolPlain.h similarity index 81% rename from src/Painting/Tool/IntelliToolFloodFillTool.h rename to src/Painting/Tool/IntelliToolPlain.h index b1ea02c..418fccf 100644 --- a/src/Painting/Tool/IntelliToolFloodFillTool.h +++ b/src/Painting/Tool/IntelliToolPlain.h @@ -4,11 +4,11 @@ #include "IntelliTool.h" #include "QColor" -class IntelliToolFloodFillTool : public IntelliTool +class IntelliToolPlainTool : public IntelliTool { QColor color; public: - IntelliToolFloodFillTool(PaintingArea *Area); + IntelliToolPlainTool(PaintingArea *Area); void onMouseLeftPressed(int x, int y) override; void onMouseLeftReleased(int x, int y) override; From fdf90d4502f8a4de657638dc56b14d58e5119797 Mon Sep 17 00:00:00 2001 From: Sonaion Date: Thu, 12 Dec 2019 11:22:16 +0100 Subject: [PATCH 16/19] Update PaintingArea.cpp --- src/Painting/Layer/PaintingArea.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index 4b7f450..2650aaa 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -190,6 +190,7 @@ void PaintingArea::mousePressEvent(QMouseEvent *event) }else if(event->button() == Qt::RightButton){ Tool->onMouseRightPressed(x, y); } + update(); } @@ -203,6 +204,7 @@ void PaintingArea::mouseMoveEvent(QMouseEvent *event) int x = event->x()-layerBundle[activeLayer].widthOffset; int y = event->y()-layerBundle[activeLayer].hightOffset; Tool->onMouseMoved(x, y); + update(); } // If the button is released we set variables to stop drawing @@ -217,6 +219,7 @@ void PaintingArea::mouseReleaseEvent(QMouseEvent *event) }else if(event->button() == Qt::RightButton){ Tool->onMouseRightReleased(x, y); } + update(); } // QPainter provides functions to draw on the widget From 84ea429b2a444dc5f9652bdbbf75168b7d634c29 Mon Sep 17 00:00:00 2001 From: Sonaion Date: Thu, 12 Dec 2019 13:03:08 +0100 Subject: [PATCH 17/19] Bug free tool strucute - try me bitch --- src/Painting/GUI/IntelliPhotoGui.cpp | 30 ++++++++++++++++ src/Painting/GUI/IntelliPhotoGui.h | 25 +++++++++++-- src/Painting/Image/IntelliShapedImage.cpp | 4 +-- .../IntelliHelper/IntelliColorPicker.cpp | 21 ++--------- .../IntelliHelper/IntelliColorPicker.h | 4 +-- src/Painting/Layer/PaintingArea.cpp | 36 +++++++++---------- src/Painting/Layer/PaintingArea.h | 9 +++-- src/Painting/Tool/IntelliTool.cpp | 10 +++--- src/Painting/Tool/IntelliTool.h | 5 ++- src/Painting/Tool/IntelliToolLine.cpp | 12 +++---- src/Painting/Tool/IntelliToolLine.h | 3 +- src/Painting/Tool/IntelliToolPen.cpp | 12 ++++--- src/Painting/Tool/IntelliToolPen.h | 3 +- src/Painting/Tool/IntelliToolPlain.cpp | 10 +++--- src/Painting/Tool/IntelliToolPlain.h | 3 +- 15 files changed, 111 insertions(+), 76 deletions(-) diff --git a/src/Painting/GUI/IntelliPhotoGui.cpp b/src/Painting/GUI/IntelliPhotoGui.cpp index aa2970e..418cdaa 100644 --- a/src/Painting/GUI/IntelliPhotoGui.cpp +++ b/src/Painting/GUI/IntelliPhotoGui.cpp @@ -214,6 +214,17 @@ void IntelliPhotoGui::slotSetActiveLayer(){ } }; +void IntelliPhotoGui::slotSetFirstColor(){ + paintingArea->colorPickerSetFirstColor(); +} + +void IntelliPhotoGui::slotSetSecondColor(){ + paintingArea->colorPickerSetSecondColor(); +} + +void IntelliPhotoGui::slotSwitchColor(){ + paintingArea->colorPickerSwitchColor(); +} void IntelliPhotoGui::slotCreatePenTool(){ paintingArea->createPenTool(); @@ -318,6 +329,17 @@ void IntelliPhotoGui::createActions() actionMoveLayerDown->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Down)); connect(actionMoveLayerDown, SIGNAL(triggered()), this, SLOT(slotMoveLayerDown())); + //Create Color Actions here + actionColorPickerFirstColor = new QAction(tr("&Main"), this); + connect(actionColorPickerFirstColor, SIGNAL(triggered()), this, SLOT(slotSetFirstColor())); + + actionColorPickerSecondColor = new QAction(tr("&Secondary"), this); + connect(actionColorPickerSecondColor, SIGNAL(triggered()), this, SLOT(slotSetFirstColor())); + + actionColorSwitch = new QAction(tr("&Switch"), this); + actionColorSwitch->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_S)); + connect(actionColorSwitch, SIGNAL(triggered()), this, SLOT(slotSwitchColor())); + //Create Tool actions down here actionCreatePlainTool = new QAction(tr("&Plain"), this); connect(actionCreatePlainTool, SIGNAL(triggered()), this, SLOT(slotCreatePlainTool())); @@ -369,11 +391,19 @@ void IntelliPhotoGui::createMenus() layerMenu->addAction(actionCreateNewLayer); layerMenu->addAction(actionDeleteLayer); + //Attach all Color Options + colorMenu = new QMenu(tr("&Color"), this); + colorMenu->addAction(actionColorPickerFirstColor); + colorMenu->addAction(actionColorPickerSecondColor); + colorMenu->addAction(actionColorSwitch); + //Attach all Tool Options toolMenu = new QMenu(tr("&Tools"), this); toolMenu->addAction(actionCreatePenTool); toolMenu->addAction(actionCreatePlainTool); toolMenu->addAction(actionCreateLineTool); + toolMenu->addSeparator(); + toolMenu->addMenu(colorMenu); // Attach all actions to Help helpMenu = new QMenu(tr("&Help"), this); diff --git a/src/Painting/GUI/IntelliPhotoGui.h b/src/Painting/GUI/IntelliPhotoGui.h index 5559f71..c204cce 100644 --- a/src/Painting/GUI/IntelliPhotoGui.h +++ b/src/Painting/GUI/IntelliPhotoGui.h @@ -29,10 +29,12 @@ protected: // Function used to close an event void closeEvent(QCloseEvent *event) override; -// The events that can be triggered private slots: + //meta slots here (need further ) void slotOpen(); void slotSave(); + + //layer slots here void slotCreateNewLayer(); void slotDeleteLayer(); void slotClearActiveLayer(); @@ -45,10 +47,17 @@ private slots: void slotMoveLayerUp(); void slotMoveLayerDown(); + //color Picker slots here + void slotSetFirstColor(); + void slotSetSecondColor(); + void slotSwitchColor(); + + //tool slots here void slotCreatePenTool(); void slotCreatePlainTool(); void slotCreateLineTool(); + //slots for dialogs void slotAboutDialog(); private: @@ -74,23 +83,33 @@ private: QMenu *fileMenu; QMenu *optionMenu; QMenu *layerMenu; + QMenu *colorMenu; QMenu *toolMenu; QMenu *helpMenu; // All the actions that can occur + + //meta image actions (need further modularisation) QAction *actionOpen; QAction *actionExit; - QAction *actionCreateNewLayer; - QAction *actionDeleteLayer; + //color Picker actions + QAction *actionColorPickerFirstColor; + QAction *actionColorPickerSecondColor; + QAction *actionColorSwitch; + //tool actions QAction *actionCreatePenTool; QAction *actionCreatePlainTool; QAction *actionCreateLineTool; + //dialog actions QAction *actionAboutDialog; QAction *actionAboutQtDialog; + //layer change actions + QAction *actionCreateNewLayer; + QAction *actionDeleteLayer; QAction* actionSetActiveLayer; QAction* actionSetActiveAlpha; QAction* actionMovePositionUp; diff --git a/src/Painting/Image/IntelliShapedImage.cpp b/src/Painting/Image/IntelliShapedImage.cpp index 4257847..67df534 100644 --- a/src/Painting/Image/IntelliShapedImage.cpp +++ b/src/Painting/Image/IntelliShapedImage.cpp @@ -18,8 +18,8 @@ QImage IntelliShapedImage::getDisplayable(int alpha){ IntelliImage* IntelliShapedImage::getDeepCopy(){ IntelliShapedImage* shaped = new IntelliShapedImage(imageData.width(), imageData.height()); - shaped->imageData.fill(Qt::transparent); shaped->setPolygon(this->polygonData); + shaped->imageData.fill(Qt::transparent); return shaped; } @@ -52,7 +52,7 @@ void IntelliShapedImage::calculateVisiblity(){ imageData.setPixelColor(x,y,clr); }else{ clr = imageData.pixelColor(x,y); - clr.setAlpha(255); + clr.setAlpha(std::min(255, clr.alpha())); imageData.setPixelColor(x,y,clr); } } diff --git a/src/Painting/IntelliHelper/IntelliColorPicker.cpp b/src/Painting/IntelliHelper/IntelliColorPicker.cpp index cfd951f..76ba561 100644 --- a/src/Painting/IntelliHelper/IntelliColorPicker.cpp +++ b/src/Painting/IntelliHelper/IntelliColorPicker.cpp @@ -1,6 +1,6 @@ #include "IntelliColorPicker.h" -IntelliColorPicker::IntelliColorPicker(PaintingArea* Area){ +IntelliColorPicker::IntelliColorPicker(){ firstColor = {255,0,0,255}; secondColor = {0,0,255,255}; } @@ -9,25 +9,8 @@ IntelliColorPicker::~IntelliColorPicker(){ } -void IntelliColorPicker::getColorbar(int firstOrSecondColor = 1){ - QString Titel; - QColor newColor; - if(firstOrSecondColor == 1){ - Titel = "Choose first Color"; - newColor = QColorDialog::getColor(this->firstColor,nullptr,Titel); - setFirstColor(newColor); - } - else{ - Titel = "Choose second Color"; - newColor = QColorDialog::getColor(this->secondColor,nullptr,Titel); - setFirstColor(newColor); - } -} - void IntelliColorPicker::switchColors(){ - QColor temp = this->firstColor; - this->firstColor = this->secondColor; - this->secondColor = temp; + std::swap(firstColor, secondColor); } QColor IntelliColorPicker::getFirstColor(){ diff --git a/src/Painting/IntelliHelper/IntelliColorPicker.h b/src/Painting/IntelliHelper/IntelliColorPicker.h index 1eeb28e..64f23e5 100644 --- a/src/Painting/IntelliHelper/IntelliColorPicker.h +++ b/src/Painting/IntelliHelper/IntelliColorPicker.h @@ -1,17 +1,15 @@ #ifndef INTELLITOOLSETCOLORTOOL_H #define INTELLITOOLSETCOLORTOOL_H -#include"Layer/PaintingArea.h" #include"QColor" #include"QPoint" #include"QColorDialog" class IntelliColorPicker{ public: - IntelliColorPicker(PaintingArea *Area); + IntelliColorPicker(); virtual ~IntelliColorPicker(); - void getColorbar(int firstOrSecondColor); void switchColors(); QColor getFirstColor(); diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index 704b676..ecef2ee 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -37,22 +37,6 @@ PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) } -void PaintingArea::switchColors(){ - ColorTool->switchColors(); -} - -void PaintingArea::createPenTool(){ - IntelliTool *temp = this->Tool; - this->Tool = new IntelliToolPen(this); - delete temp; -} - -void PaintingArea::createFloodFillTool(){ - IntelliTool *temp = this->Tool; - this->Tool = new IntelliToolFloodFillTool(this); - delete temp; -} - void PaintingArea::setUp(int maxWidth, int maxHeight){ //set standart parameter this->maxWidth = maxWidth; @@ -177,19 +161,33 @@ void PaintingArea::slotActivateLayer(int a){ } } +void PaintingArea::colorPickerSetFirstColor(){ + QColor clr = QColorDialog::getColor(colorPicker.getFirstColor(), nullptr, "Main Color"); + this->colorPicker.setFirstColor(clr); +} + +void PaintingArea::colorPickerSetSecondColor(){ + QColor clr = QColorDialog::getColor(colorPicker.getSecondColor(), nullptr, "Secondary Color"); + this->colorPicker.setSecondColor(clr); +} + +void PaintingArea::colorPickerSwitchColor(){ + this->colorPicker.switchColors(); +} + void PaintingArea::createPenTool(){ delete this->Tool; - Tool = new IntelliToolPen(this); + Tool = new IntelliToolPen(this, &colorPicker); } void PaintingArea::createPlainTool(){ delete this->Tool; - Tool = new IntelliToolPlainTool(this); + Tool = new IntelliToolPlainTool(this, &colorPicker); } void PaintingArea::createLineTool(){ delete this->Tool; - Tool = new IntelliToolLine(this); + Tool = new IntelliToolLine(this, &colorPicker); } // If a mouse button is pressed check if it was the diff --git a/src/Painting/Layer/PaintingArea.h b/src/Painting/Layer/PaintingArea.h index a1571f6..71921c0 100644 --- a/src/Painting/Layer/PaintingArea.h +++ b/src/Painting/Layer/PaintingArea.h @@ -11,6 +11,7 @@ #include "Image/IntelliRasterImage.h" #include "Image/IntelliShapedImage.h" #include "Tool/IntelliTool.h" +#include "IntelliHelper/IntelliColorPicker.h" struct LayerObject{ @@ -24,8 +25,6 @@ struct LayerObject{ }; -class IntelliColorPicker; - class PaintingArea : public QWidget { // Declares our class as a QObject which is the base class @@ -52,6 +51,11 @@ public: // Has the image been modified since last save bool isModified() const { return modified; } + //change properties of colorPicker + void colorPickerSetFirstColor(); + void colorPickerSetSecondColor(); + void colorPickerSwitchColor(); + //create tools void createPenTool(); void createPlainTool(); @@ -86,6 +90,7 @@ private: int maxHeight; IntelliTool* Tool; + IntelliColorPicker colorPicker; std::vector layerBundle; int activeLayer=-1; diff --git a/src/Painting/Tool/IntelliTool.cpp b/src/Painting/Tool/IntelliTool.cpp index f10b872..606459c 100644 --- a/src/Painting/Tool/IntelliTool.cpp +++ b/src/Painting/Tool/IntelliTool.cpp @@ -1,8 +1,9 @@ #include"IntelliTool.h" #include"Layer/PaintingArea.h" -IntelliTool::IntelliTool(PaintingArea* Area){ +IntelliTool::IntelliTool(PaintingArea* Area, IntelliColorPicker* colorPicker){ this->Area=Area; + this->colorPicker=colorPicker; } @@ -25,7 +26,7 @@ void IntelliTool::onMouseLeftPressed(int x, int y){ this->drawing=true; //create drawing layer this->createToolLayer(); - + Canvas->image->calculateVisiblity(); } void IntelliTool::onMouseLeftReleased(int x, int y){ @@ -33,11 +34,13 @@ void IntelliTool::onMouseLeftReleased(int x, int y){ drawing=false; this->mergeToolLayer(); this->deleteToolLayer(); + Active->image->calculateVisiblity(); } } void IntelliTool::onMouseMoved(int x, int y){ - //optional for tool + if(drawing) + Canvas->image->calculateVisiblity(); } void IntelliTool::createToolLayer(){ @@ -65,7 +68,6 @@ void IntelliTool::mergeToolLayer(){ Active->image->imageData.setPixelColor(x, y, clr_0); } - Active->image->calculateVisiblity(); } } diff --git a/src/Painting/Tool/IntelliTool.h b/src/Painting/Tool/IntelliTool.h index a519616..b534257 100644 --- a/src/Painting/Tool/IntelliTool.h +++ b/src/Painting/Tool/IntelliTool.h @@ -1,6 +1,7 @@ #ifndef Intelli_Tool_H #define Intelli_Tool_H +#include "IntelliHelper/IntelliColorPicker.h" #include class LayerObject; @@ -13,12 +14,14 @@ private: void deleteToolLayer(); protected: PaintingArea* Area; + IntelliColorPicker* colorPicker; + LayerObject* Active; LayerObject* Canvas; bool drawing = false; public: - IntelliTool(PaintingArea* Area); + IntelliTool(PaintingArea* Area, IntelliColorPicker* colorPicker); virtual ~IntelliTool() = 0; virtual void onMouseRightPressed(int x, int y); diff --git a/src/Painting/Tool/IntelliToolLine.cpp b/src/Painting/Tool/IntelliToolLine.cpp index ff94a6b..1c9fc79 100644 --- a/src/Painting/Tool/IntelliToolLine.cpp +++ b/src/Painting/Tool/IntelliToolLine.cpp @@ -3,9 +3,8 @@ #include "QColorDialog" #include "QInputDialog" -IntelliToolLine::IntelliToolLine(PaintingArea* Area) - :IntelliTool(Area){ - this->color = QColorDialog::getColor(Qt::blue, nullptr, "Line Color"); +IntelliToolLine::IntelliToolLine(PaintingArea* Area, IntelliColorPicker* colorPicker) + :IntelliTool(Area, colorPicker){ this->lineWidth = QInputDialog::getInt(nullptr,"Line Width Input", "Width",1,1,50,1); //create checkbox or scroll dialog to get line style this->lineStyle = LineStyle::SOLID_LINE; @@ -27,7 +26,8 @@ void IntelliToolLine::onMouseRightReleased(int x, int y){ void IntelliToolLine::onMouseLeftPressed(int x, int y){ IntelliTool::onMouseLeftPressed(x,y); this->start=QPoint(x,y); - this->Canvas->image->drawLine(start, start, this->color, this->lineWidth); + this->Canvas->image->drawLine(start, start, colorPicker->getFirstColor(),lineWidth); + Canvas->image->calculateVisiblity(); } void IntelliToolLine::onMouseLeftReleased(int x, int y){ @@ -41,9 +41,9 @@ void IntelliToolLine::onMouseMoved(int x, int y){ QPoint next(x,y); switch(lineStyle){ case LineStyle::SOLID_LINE : - this->Canvas->image->drawLine(start,next,color,lineWidth); + this->Canvas->image->drawLine(start,next,colorPicker->getFirstColor(),lineWidth); break; } } - + IntelliTool::onMouseMoved(x,y); } diff --git a/src/Painting/Tool/IntelliToolLine.h b/src/Painting/Tool/IntelliToolLine.h index 37faace..2240dec 100644 --- a/src/Painting/Tool/IntelliToolLine.h +++ b/src/Painting/Tool/IntelliToolLine.h @@ -12,11 +12,10 @@ enum class LineStyle{ class IntelliToolLine : public IntelliTool { QPoint start; - QColor color; int lineWidth; LineStyle lineStyle; public: - IntelliToolLine(PaintingArea* Area); + IntelliToolLine(PaintingArea* Area, IntelliColorPicker* colorPicker); virtual ~IntelliToolLine() override; diff --git a/src/Painting/Tool/IntelliToolPen.cpp b/src/Painting/Tool/IntelliToolPen.cpp index 19b6f0e..14db6dd 100644 --- a/src/Painting/Tool/IntelliToolPen.cpp +++ b/src/Painting/Tool/IntelliToolPen.cpp @@ -4,10 +4,9 @@ #include "QColorDialog" #include "QInputDialog" -IntelliToolPen::IntelliToolPen(PaintingArea* Area) - :IntelliTool(Area){ - this->color = QColorDialog::getColor(Qt::blue,nullptr,"Flood Fill Color"); - this->penWidth = QInputDialog::getInt(nullptr, "Pen width", "Number:", 1,0, 50, 1); +IntelliToolPen::IntelliToolPen(PaintingArea* Area, IntelliColorPicker* colorPicker) + :IntelliTool(Area, colorPicker){ + this->penWidth = QInputDialog::getInt(nullptr, "Pen width", "Width:", 1,0, 50, 1); } IntelliToolPen::~IntelliToolPen(){ @@ -25,6 +24,8 @@ void IntelliToolPen::onMouseRightReleased(int x, int y){ void IntelliToolPen::onMouseLeftPressed(int x, int y){ IntelliTool::onMouseLeftPressed(x,y); this->point=QPoint(x,y); + this->Canvas->image->drawPixel(point, colorPicker->getFirstColor()); + Canvas->image->calculateVisiblity(); } void IntelliToolPen::onMouseLeftReleased(int x, int y){ @@ -34,7 +35,8 @@ void IntelliToolPen::onMouseLeftReleased(int x, int y){ void IntelliToolPen::onMouseMoved(int x, int y){ if(this->drawing){ QPoint newPoint(x,y); - this->Canvas->image->drawLine(this->point, newPoint, color, penWidth); + this->Canvas->image->drawLine(this->point, newPoint, colorPicker->getFirstColor(), penWidth); this->point=newPoint; } + IntelliTool::onMouseMoved(x,y); } diff --git a/src/Painting/Tool/IntelliToolPen.h b/src/Painting/Tool/IntelliToolPen.h index 2728348..a5acc49 100644 --- a/src/Painting/Tool/IntelliToolPen.h +++ b/src/Painting/Tool/IntelliToolPen.h @@ -6,11 +6,10 @@ #include"QPoint" class IntelliToolPen : public IntelliTool{ - QColor color; int penWidth; QPoint point; public: - IntelliToolPen(PaintingArea* Area); + IntelliToolPen(PaintingArea* Area, IntelliColorPicker* colorPicker); virtual ~IntelliToolPen() override; virtual void onMouseRightPressed(int x, int y) override; diff --git a/src/Painting/Tool/IntelliToolPlain.cpp b/src/Painting/Tool/IntelliToolPlain.cpp index d344eff..3302dd7 100644 --- a/src/Painting/Tool/IntelliToolPlain.cpp +++ b/src/Painting/Tool/IntelliToolPlain.cpp @@ -2,15 +2,14 @@ #include "Layer/PaintingArea.h" #include "QColorDialog" -IntelliToolPlainTool::IntelliToolPlainTool(PaintingArea* Area) - :IntelliTool(Area){ - - this->color = QColorDialog::getColor(Qt::blue,nullptr,"Flood Fill Color"); +IntelliToolPlainTool::IntelliToolPlainTool(PaintingArea* Area, IntelliColorPicker* colorPicker) + :IntelliTool(Area, colorPicker){ } void IntelliToolPlainTool::onMouseLeftPressed(int x, int y){ IntelliTool::onMouseLeftPressed(x,y); - this->Canvas->image->floodFill(color); + this->Canvas->image->floodFill(colorPicker->getFirstColor()); + Canvas->image->calculateVisiblity(); } void IntelliToolPlainTool::onMouseLeftReleased(int x, int y){ @@ -28,5 +27,4 @@ void IntelliToolPlainTool::onMouseRightReleased(int x, int y){ void IntelliToolPlainTool::onMouseMoved(int x, int y){ IntelliTool::onMouseMoved(x,y); - } diff --git a/src/Painting/Tool/IntelliToolPlain.h b/src/Painting/Tool/IntelliToolPlain.h index 418fccf..9e468f4 100644 --- a/src/Painting/Tool/IntelliToolPlain.h +++ b/src/Painting/Tool/IntelliToolPlain.h @@ -6,9 +6,8 @@ class IntelliToolPlainTool : public IntelliTool { - QColor color; public: - IntelliToolPlainTool(PaintingArea *Area); + IntelliToolPlainTool(PaintingArea *Area, IntelliColorPicker* colorPicker); void onMouseLeftPressed(int x, int y) override; void onMouseLeftReleased(int x, int y) override; From de30640a1a9746e6f83b908e8185af70e676e136 Mon Sep 17 00:00:00 2001 From: Sonaion Date: Thu, 12 Dec 2019 13:17:22 +0100 Subject: [PATCH 18/19] Open implemented again --- src/Painting/GUI/IntelliPhotoGui.cpp | 23 +++++++++++------------ src/Painting/Image/IntelliImage.cpp | 4 ++-- src/Painting/Image/IntelliImage.h | 2 +- src/Painting/Layer/PaintingArea.cpp | 11 ++++++++--- src/Painting/Layer/PaintingArea.h | 7 +------ src/Painting/Tool/IntelliToolLine.cpp | 2 +- src/Painting/Tool/IntelliToolPlain.cpp | 2 +- 7 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/Painting/GUI/IntelliPhotoGui.cpp b/src/Painting/GUI/IntelliPhotoGui.cpp index 418cdaa..1535408 100644 --- a/src/Painting/GUI/IntelliPhotoGui.cpp +++ b/src/Painting/GUI/IntelliPhotoGui.cpp @@ -249,14 +249,7 @@ void IntelliPhotoGui::slotAboutDialog() // Define menu actions that call functions void IntelliPhotoGui::createActions() { - // Create the action tied to the menu - actionOpen = new QAction(tr("&Open..."), this); - // Define the associated shortcut key - actionOpen->setShortcuts(QKeySequence::Open); - - // Tie the action to IntelliPhotoGui::open() - connect(actionOpen, SIGNAL(triggered()), this, SLOT(slotOpen())); // Get a list of the supported file formats // QImageWriter is used to write images to files @@ -287,9 +280,13 @@ void IntelliPhotoGui::createActions() // Create exit action and tie to IntelliPhotoGui::close() - actionOpen = new QAction(tr("&Exit"), this); - actionOpen->setShortcuts(QKeySequence::Quit); - connect(actionOpen, SIGNAL(triggered()), this, SLOT(close())); + actionExit = new QAction(tr("&Exit"), this); + actionExit->setShortcuts(QKeySequence::Quit); + connect(actionExit, SIGNAL(triggered()), this, SLOT(close())); + + actionOpen = new QAction(tr("&Open"), this); + actionOpen->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_O)); + connect(actionOpen, SIGNAL(triggered()), this, SLOT(slotOpen())); // Create New Layer action and tie to IntelliPhotoGui::newLayer() actionCreateNewLayer = new QAction(tr("&New Layer..."), this); @@ -373,7 +370,7 @@ void IntelliPhotoGui::createMenus() fileMenu->addAction(actionOpen); fileMenu->addMenu(saveAsMenu); fileMenu->addSeparator(); - fileMenu->addAction(actionOpen); + fileMenu->addAction(actionExit); // Attach all actions to Options optionMenu = new QMenu(tr("&Options"), this); @@ -446,7 +443,9 @@ void IntelliPhotoGui::setIntelliStyle(){ bool IntelliPhotoGui::maybeSave() { // Check for changes since last save - if (paintingArea->isModified()) { + + //TODO insert variable for modified status here to make an save exit message + if (false) { QMessageBox::StandardButton ret; // Painting is the title diff --git a/src/Painting/Image/IntelliImage.cpp b/src/Painting/Image/IntelliImage.cpp index d9f5a48..74b7891 100644 --- a/src/Painting/Image/IntelliImage.cpp +++ b/src/Painting/Image/IntelliImage.cpp @@ -20,7 +20,7 @@ bool IntelliImage::loadImage(const QString &fileName){ return false; // scaled Image to size of Layer - // loadedImage = loadedImage.scaled(imageData.size(),Qt::IgnoreAspectRatio); + loadedImage = loadedImage.scaled(imageData.size(),Qt::IgnoreAspectRatio); imageData = loadedImage.convertToFormat(QImage::Format_ARGB32); return true; @@ -64,6 +64,6 @@ void IntelliImage::drawLine(const QPoint &p1, const QPoint& p2, const QColor& co } -void IntelliImage::floodFill(const QColor& color){ +void IntelliImage::drawPlain(const QColor& color){ imageData.fill(color); } diff --git a/src/Painting/Image/IntelliImage.h b/src/Painting/Image/IntelliImage.h index 72a7310..14e9ec2 100644 --- a/src/Painting/Image/IntelliImage.h +++ b/src/Painting/Image/IntelliImage.h @@ -31,7 +31,7 @@ public: //start on top left virtual void drawPixel(const QPoint &p1, const QColor& color); virtual void drawLine(const QPoint &p1, const QPoint& p2, const QColor& color, const int& penWidth); - virtual void floodFill(const QColor& color); + virtual void drawPlain(const QColor& color); //returns the filtered output virtual QImage getDisplayable(const QSize& displaySize, int alpha)=0; diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index ecef2ee..7fff2a9 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -21,7 +21,7 @@ PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) this->setUp(maxWidth, maxHeight); //tetsing this->addLayer(200,200,0,0,ImageType::Shaped_Image); - layerBundle[0].image->floodFill(QColor(255,0,0,255)); + layerBundle[0].image->drawPlain(QColor(255,0,0,255)); std::vector polygon; polygon.push_back(QPoint(100,000)); polygon.push_back(QPoint(200,100)); @@ -30,12 +30,16 @@ PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) layerBundle[0].image->setPolygon(polygon); this->addLayer(200,200,150,150); - layerBundle[1].image->floodFill(QColor(0,255,0,255)); + layerBundle[1].image->drawPlain(QColor(0,255,0,255)); layerBundle[1].alpha=200; activeLayer=0; } +PaintingArea::~PaintingArea(){ + delete Tool; +} + void PaintingArea::setUp(int maxWidth, int maxHeight){ //set standart parameter @@ -102,6 +106,7 @@ bool PaintingArea::open(const QString &fileName) } IntelliImage* active = layerBundle[static_cast(activeLayer)].image; bool open = active->loadImage(fileName); + active->calculateVisiblity(); update(); return open; } @@ -138,7 +143,7 @@ void PaintingArea::floodFill(int r, int g, int b, int a){ return; } IntelliImage* active = layerBundle[static_cast(activeLayer)].image; - active->floodFill(QColor(r, g, b, a)); + active->drawPlain(QColor(r, g, b, a)); update(); } diff --git a/src/Painting/Layer/PaintingArea.h b/src/Painting/Layer/PaintingArea.h index 71921c0..a4ec3fa 100644 --- a/src/Painting/Layer/PaintingArea.h +++ b/src/Painting/Layer/PaintingArea.h @@ -34,6 +34,7 @@ class PaintingArea : public QWidget friend IntelliTool; public: PaintingArea(int maxWidth=600, int maxHeight=600, QWidget *parent = nullptr); + ~PaintingArea(); // Handles all events bool open(const QString &fileName); @@ -48,9 +49,6 @@ public: void movePositionActive(int x, int y); void moveActiveLayer(int idx); - // Has the image been modified since last save - bool isModified() const { return modified; } - //change properties of colorPicker void colorPickerSetFirstColor(); void colorPickerSetSecondColor(); @@ -99,9 +97,6 @@ private: void resizeImage(QImage *image_res, const QSize &newSize); - // Will be marked true or false depending on if - // we have saved after a change - bool modified=false; //Helper for Tool void createTempLayerAfter(int idx); diff --git a/src/Painting/Tool/IntelliToolLine.cpp b/src/Painting/Tool/IntelliToolLine.cpp index 1c9fc79..c1d571d 100644 --- a/src/Painting/Tool/IntelliToolLine.cpp +++ b/src/Painting/Tool/IntelliToolLine.cpp @@ -37,7 +37,7 @@ void IntelliToolLine::onMouseLeftReleased(int x, int y){ void IntelliToolLine::onMouseMoved(int x, int y){ IntelliTool::onMouseMoved(x,y); if(this->drawing){ - this->Canvas->image->floodFill(Qt::transparent); + this->Canvas->image->drawPlain(Qt::transparent); QPoint next(x,y); switch(lineStyle){ case LineStyle::SOLID_LINE : diff --git a/src/Painting/Tool/IntelliToolPlain.cpp b/src/Painting/Tool/IntelliToolPlain.cpp index 3302dd7..aaa2a02 100644 --- a/src/Painting/Tool/IntelliToolPlain.cpp +++ b/src/Painting/Tool/IntelliToolPlain.cpp @@ -8,7 +8,7 @@ IntelliToolPlainTool::IntelliToolPlainTool(PaintingArea* Area, IntelliColorPicke void IntelliToolPlainTool::onMouseLeftPressed(int x, int y){ IntelliTool::onMouseLeftPressed(x,y); - this->Canvas->image->floodFill(colorPicker->getFirstColor()); + this->Canvas->image->drawPlain(colorPicker->getFirstColor()); Canvas->image->calculateVisiblity(); } From c58e8fcb6fc1065ac05014d14c0ebb2e77898cf4 Mon Sep 17 00:00:00 2001 From: Sonaion Date: Thu, 12 Dec 2019 14:08:11 +0100 Subject: [PATCH 19/19] ui changes --- src/Painting/GUI/IntelliPhotoGui.cpp | 2 +- src/Painting/Image/IntelliShapedImage.cpp | 2 +- src/Painting/Image/IntelliShapedImage.h | 4 ++-- src/Painting/Tool/IntelliToolLine.cpp | 9 ++++++++- src/Painting/Tool/IntelliToolLine.h | 3 ++- src/Painting/widget.ui | 4 ++-- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Painting/GUI/IntelliPhotoGui.cpp b/src/Painting/GUI/IntelliPhotoGui.cpp index 1535408..119bbfd 100644 --- a/src/Painting/GUI/IntelliPhotoGui.cpp +++ b/src/Painting/GUI/IntelliPhotoGui.cpp @@ -19,7 +19,7 @@ IntelliPhotoGui::IntelliPhotoGui() setIntelliStyle(); // Size the app - resize(500, 500); + showMaximized(); } diff --git a/src/Painting/Image/IntelliShapedImage.cpp b/src/Painting/Image/IntelliShapedImage.cpp index 67df534..0dbc807 100644 --- a/src/Painting/Image/IntelliShapedImage.cpp +++ b/src/Painting/Image/IntelliShapedImage.cpp @@ -5,7 +5,7 @@ #include IntelliShapedImage::IntelliShapedImage(int weight, int height) - :IntelliImage(weight, height){ + :IntelliRasterImage(weight, height){ } IntelliShapedImage::~IntelliShapedImage(){ diff --git a/src/Painting/Image/IntelliShapedImage.h b/src/Painting/Image/IntelliShapedImage.h index 2c8c3a3..0a3598e 100644 --- a/src/Painting/Image/IntelliShapedImage.h +++ b/src/Painting/Image/IntelliShapedImage.h @@ -1,9 +1,9 @@ #ifndef INTELLISHAPE_H #define INTELLISHAPE_H -#include"Image/IntelliImage.h" +#include"Image/IntelliRasterImage.h" -class IntelliShapedImage : public IntelliImage{ +class IntelliShapedImage : public IntelliRasterImage{ friend IntelliTool; protected: diff --git a/src/Painting/Tool/IntelliToolLine.cpp b/src/Painting/Tool/IntelliToolLine.cpp index c1d571d..b3f1bf7 100644 --- a/src/Painting/Tool/IntelliToolLine.cpp +++ b/src/Painting/Tool/IntelliToolLine.cpp @@ -40,8 +40,15 @@ void IntelliToolLine::onMouseMoved(int x, int y){ this->Canvas->image->drawPlain(Qt::transparent); QPoint next(x,y); switch(lineStyle){ - case LineStyle::SOLID_LINE : + case LineStyle::SOLID_LINE: this->Canvas->image->drawLine(start,next,colorPicker->getFirstColor(),lineWidth); + break; + case LineStyle::DOTTED_LINE: + QPoint p1 =start.x() <= next.x() ? start : next; + QPoint p2 =start.x() < next.x() ? next : start; + int m = (float)(p2.y()-p1.y())/(float)(p2.x()-p1.x())+0.5f; + int c = start.y()-start.x()*m; + break; } } diff --git a/src/Painting/Tool/IntelliToolLine.h b/src/Painting/Tool/IntelliToolLine.h index 2240dec..637eb73 100644 --- a/src/Painting/Tool/IntelliToolLine.h +++ b/src/Painting/Tool/IntelliToolLine.h @@ -6,7 +6,8 @@ #include "QPoint" enum class LineStyle{ - SOLID_LINE + SOLID_LINE, + DOTTED_LINE }; class IntelliToolLine : public IntelliTool diff --git a/src/Painting/widget.ui b/src/Painting/widget.ui index b90248d..b1d4c7b 100644 --- a/src/Painting/widget.ui +++ b/src/Painting/widget.ui @@ -6,8 +6,8 @@ 0 0 - 800 - 600 + 360 + 206