IntelliPhoto 0.5

PaintingArea.cpp
Go to the documentation of this file.
1 // ---------- PaintingArea.cpp ----------
2 #include "string.h"
3
4 #include <vector>
5
6 #include <QtWidgets>
7 #include <QPoint>
8 #include <QRect>
9
10 #include "PaintingArea.h"
11 #include "Image/IntelliRasterImage.h"
12 #include "Image/IntelliShapedImage.h"
13 #include "Tool/IntelliToolPen.h"
14 #include "Tool/IntelliToolPlain.h"
15 #include "Tool/IntelliToolLine.h"
16 #include "Tool/IntelliToolCircle.h"
17 #include "Tool/IntelliToolRectangle.h"
18 #include "Tool/IntelliToolFloodFill.h"
19 #include "Tool/IntelliToolPolygon.h"
20
21 PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget*parent)
22 : QWidget(parent){
23 this->Tool = nullptr;
24 this->setUp(maxWidth, maxHeight);
25 this->addLayer(200,200,0,0,ImageType::Shaped_Image);
26 layerBundle[0].image->drawPlain(QColor(0,0,255,255));
27 std::vector<QPoint> polygon;
28 polygon.push_back(QPoint(100,000));
29 polygon.push_back(QPoint(200,100));
30 polygon.push_back(QPoint(100,200));
31 polygon.push_back(QPoint(000,100));
32 layerBundle[0].image->setPolygon(polygon);
33
34 this->addLayer(200,200,150,150);
35 layerBundle[1].image->drawPlain(QColor(0,255,0,255));
36 layerBundle[1].alpha=200;
37
38 activeLayer=0;
39 }
40
41 PaintingArea::~PaintingArea(){
42 delete Tool;
43 }
44
45 void PaintingArea::setUp(int maxWidth, int maxHeight){
46 //set standart parameter
47 this->maxWidth = maxWidth;
48 this->maxHeight = maxHeight;
49 Canvas = new QImage(maxWidth,maxHeight, QImage::Format_ARGB32);
50
51 // Roots the widget to the top left even if resized
52 setAttribute(Qt::WA_StaticContents);
53
54 }
55
56 int PaintingArea::addLayer(int width, int height, int widthOffset, int heightOffset, ImageType type){
57 LayerObject newLayer;
58 newLayer.width = width;
59 newLayer.height = height;
60 newLayer.widthOffset = widthOffset;
61 newLayer.heightOffset = heightOffset;
62 if(type==ImageType::Raster_Image) {
63 newLayer.image = new IntelliRasterImage(width,height);
64 }else if(type==ImageType::Shaped_Image) {
65 newLayer.image = new IntelliShapedImage(width, height);
66 }
67 newLayer.alpha = 255;
68 this->layerBundle.push_back(newLayer);
69 return static_cast<int>(layerBundle.size())-1;
70 }
71
72
73 void PaintingArea::deleteLayer(int index){
74 if(index<static_cast<int>(layerBundle.size())) {
75 this->layerBundle.erase(layerBundle.begin()+index);
76 if(activeLayer>=index) {
77 activeLayer--;
78 }
79 }
80 }
81
82 void PaintingArea::slotDeleteActiveLayer(){
83 if(activeLayer>=0 && activeLayer < static_cast<int>(layerBundle.size())) {
84 this->layerBundle.erase(layerBundle.begin()+activeLayer);
85 activeLayer--;
86 }
87 }
88
89 void PaintingArea::setLayerToActive(int index){
90 if(index>=0&&index<static_cast<int>(layerBundle.size())) {
91 this->activeLayer=index;
92 }
93 }
94
95 void PaintingArea::setAlphaOfLayer(int index, int alpha){
96 if(index>=0&&index<static_cast<int>(layerBundle.size())) {
97 layerBundle[static_cast<size_t>(index)].alpha=alpha;
98 }
99 }
100
101 // Used to load the image and place it in the widget
102 bool PaintingArea::open(const QString &fileName){
103 if(this->activeLayer==-1) {
104 return false;
105 }
106 IntelliImage* active = layerBundle[static_cast<size_t>(activeLayer)].image;
107 bool open = active->loadImage(fileName);
108 active->calculateVisiblity();
109 update();
110 return open;
111 }
112
113 // Save the current image
114 bool PaintingArea::save(const QString &fileName, const char*fileFormat){
115 if(layerBundle.size()==0) {
116 return false;
117 }
118 this->assembleLayers(true);
119
120 if(!strcmp(fileFormat,"PNG")) {
121 QImage visibleImage = Canvas->convertToFormat(QImage::Format_Indexed8);
122 fileFormat = "png";
123 if (visibleImage.save(fileName, fileFormat)) {
124 return true;
125 } else {
126 return false;
127 }
128 }
129
130 if (Canvas->save(fileName, fileFormat)) {
131 return true;
132 } else {
133 return false;
134 }
135 }
136
137 // Color the image area with white
138 void PaintingArea::floodFill(int r, int g, int b, int a){
139 if(this->activeLayer==-1) {
140 return;
141 }
142 IntelliImage* active = layerBundle[static_cast<size_t>(activeLayer)].image;
143 active->drawPlain(QColor(r, g, b, a));
144 update();
145 }
146
147 void PaintingArea::movePositionActive(int x, int y){
148 layerBundle[static_cast<size_t>(activeLayer)].widthOffset += x;
149 layerBundle[static_cast<size_t>(activeLayer)].heightOffset += y;
150 }
151
152 void PaintingArea::moveActiveLayer(int idx){
153 if(idx==1) {
154 this->activateUpperLayer();
155 }else if(idx==-1) {
156 this->activateLowerLayer();
157 }
158 }
159
160 void PaintingArea::slotActivateLayer(int a){
161 if(a>=0 && a < static_cast<int>(layerBundle.size())) {
162 this->setLayerToActive(a);
163 }
164 }
165
166 void PaintingArea::colorPickerSetFirstColor(){
167 QColor clr = QColorDialog::getColor(colorPicker.getFirstColor(), nullptr, "Main Color", QColorDialog::DontUseNativeDialog);
168 this->colorPicker.setFirstColor(clr);
169 }
170
171 void PaintingArea::colorPickerSetSecondColor(){
172 QColor clr = QColorDialog::getColor(colorPicker.getSecondColor(), nullptr, "Secondary Color", QColorDialog::DontUseNativeDialog);
173 this->colorPicker.setSecondColor(clr);
174 }
175
176 void PaintingArea::colorPickerSwitchColor(){
177 this->colorPicker.switchColors();
178 }
179
180 void PaintingArea::createPenTool(){
181 delete this->Tool;
182 Tool = new IntelliToolPen(this, &colorPicker);
183 }
184
185 void PaintingArea::createPlainTool(){
186 delete this->Tool;
187 Tool = new IntelliToolPlainTool(this, &colorPicker);
188 }
189
190 void PaintingArea::createLineTool(){
191 delete this->Tool;
192 Tool = new IntelliToolLine(this, &colorPicker);
193 }
194
195 void PaintingArea::createRectangleTool(){
196 delete this->Tool;
197 Tool = new IntelliToolRectangle(this, &colorPicker);
198 }
199
200 void PaintingArea::createCircleTool(){
201 delete this->Tool;
202 Tool = new IntelliToolCircle(this, &colorPicker);
203 }
204 void PaintingArea::createPolygonTool(){
205 delete this->Tool;
206 Tool = new IntelliToolPolygon(this, &colorPicker);
207 }
208
209 void PaintingArea::createFloodFillTool(){
210 delete this->Tool;
211 Tool = new IntelliToolFloodFill(this, &colorPicker);
212 }
213
214 int PaintingArea::getWidthOfActive(){
215 return this->layerBundle[activeLayer].width;
216 }
217
218 int PaintingArea::getHeightOfActive(){
219 return this->layerBundle[activeLayer].height;
220 }
221
222 // If a mouse button is pressed check if it was the
223 // left button and if so store the current position
224 // Set that we are currently drawing
225 void PaintingArea::mousePressEvent(QMouseEvent*event){
226 if(Tool == nullptr)
227 return;
228 int x = event->x()-layerBundle[activeLayer].widthOffset;
229 int y = event->y()-layerBundle[activeLayer].heightOffset;
230 if(event->button() == Qt::LeftButton) {
231 Tool->onMouseLeftPressed(x, y);
232 }else if(event->button() == Qt::RightButton) {
233 Tool->onMouseRightPressed(x, y);
234 }
235 update();
236 }
237
238 // When the mouse moves if the left button is clicked
239 // we call the drawline function which draws a line
240 // from the last position to the current
241 void PaintingArea::mouseMoveEvent(QMouseEvent*event){
242 if(Tool == nullptr)
243 return;
244 int x = event->x()-layerBundle[activeLayer].widthOffset;
245 int y = event->y()-layerBundle[activeLayer].heightOffset;
246 Tool->onMouseMoved(x, y);
247 update();
248 }
249
250 // If the button is released we set variables to stop drawing
251 void PaintingArea::mouseReleaseEvent(QMouseEvent*event){
252 if(Tool == nullptr)
253 return;
254 int x = event->x()-layerBundle[activeLayer].widthOffset;
255 int y = event->y()-layerBundle[activeLayer].heightOffset;
256 if(event->button() == Qt::LeftButton) {
257 Tool->onMouseLeftReleased(x, y);
258 }else if(event->button() == Qt::RightButton) {
259 Tool->onMouseRightReleased(x, y);
260 }
261 update();
262 }
263
264 void PaintingArea::wheelEvent(QWheelEvent*event){
265 QPoint numDegrees = event->angleDelta() / 8;
266 if(!numDegrees.isNull()) {
267 QPoint numSteps = numDegrees / 15;
268 Tool->onWheelScrolled(numSteps.y()* -1);
269 }
270 }
271
272 // QPainter provides functions to draw on the widget
273 // The QPaintEvent is sent to widgets that need to
274 // update themselves
275 void PaintingArea::paintEvent(QPaintEvent*event){
276 this->assembleLayers();
277
278 QPainter painter(this);
279 QRect dirtyRec = event->rect();
280 painter.drawImage(dirtyRec, *Canvas, dirtyRec);
281 update();
282 }
283
284 // Resize the image to slightly larger then the main window
285 // to cut down on the need to resize the image
286 void PaintingArea::resizeEvent(QResizeEvent*event){
287 //TODO wait till tool works
288 update();
289 }
290
291 void PaintingArea::resizeImage(QImage*image_res, const QSize &newSize){
292 //TODO implement
293 }
294
295 void PaintingArea::activateUpperLayer(){
296 if(activeLayer!=-1 && activeLayer<layerBundle.size()-1) {
297 std::swap(layerBundle[activeLayer], layerBundle[activeLayer+1]);
298 activeLayer++;
299 }
300 }
301
302 void PaintingArea::activateLowerLayer(){
303 if(activeLayer!=-1 && activeLayer>0) {
304 std::swap(layerBundle[activeLayer], layerBundle[activeLayer-1]);
305 activeLayer--;
306 }
307 }
308
309 void PaintingArea::assembleLayers(bool forSaving){
310 if(forSaving) {
311 Canvas->fill(Qt::GlobalColor::transparent);
312 }else{
313 Canvas->fill(Qt::GlobalColor::black);
314 }
315 for(size_t i=0; i<layerBundle.size(); i++) {
316 LayerObject layer = layerBundle[i];
317 QImage cpy = layer.image->getDisplayable(layer.alpha);
318 QColor clr_0;
319 QColor clr_1;
320 for(int y=0; y<layer.height; y++) {
321 if(layer.heightOffset+y<0) continue;
322 if(layer.heightOffset+y>=maxHeight) break;
323 for(int x=0; x<layer.width; x++) {
324 if(layer.widthOffset+x<0) continue;
325 if(layer.widthOffset+x>=maxWidth) break;
326 clr_0=Canvas->pixelColor(layer.widthOffset+x, layer.heightOffset+y);
327 clr_1=cpy.pixelColor(x,y);
328 float t = static_cast<float>(clr_1.alpha())/255.f;
329 int r =static_cast<int>(static_cast<float>(clr_1.red())*(t)+static_cast<float>(clr_0.red())*(1.f-t)+0.5f);
330 int g =static_cast<int>(static_cast<float>(clr_1.green())*(t)+static_cast<float>(clr_0.green())*(1.f-t)+0.5f);
331 int b =static_cast<int>(static_cast<float>(clr_1.blue())*(t)+static_cast<float>(clr_0.blue()*(1.f-t))+0.5f);
332 int a =std::min(clr_0.alpha()+clr_1.alpha(), 255);
333 clr_0.setRed(r);
334 clr_0.setGreen(g);
335 clr_0.setBlue(b);
336 clr_0.setAlpha(a);
337
338 Canvas->setPixelColor(layer.widthOffset+x, layer.heightOffset+y, clr_0);
339 }
340 }
341 }
342 }
343
344 void PaintingArea::createTempLayerAfter(int idx){
345 if(idx>=0) {
346 LayerObject newLayer;
347 newLayer.alpha = 255;
348 newLayer.height = layerBundle[idx].height;
349 newLayer.width = layerBundle[idx].width;
350 newLayer.heightOffset = layerBundle[idx].heightOffset;
351 newLayer.widthOffset = layerBundle[idx].widthOffset;
352 newLayer.image = layerBundle[idx].image->getDeepCopy();
353 layerBundle.insert(layerBundle.begin()+idx+1,newLayer);
354 }
355 }
PaintingArea::getWidthOfActive
int getWidthOfActive()
The getWidthOfActive gets the horizontal dimensions of the active layer.
Definition: PaintingArea.cpp:214
PaintingArea::createCircleTool
void createCircleTool()
Definition: PaintingArea.cpp:200
IntelliTool::onMouseRightPressed
virtual void onMouseRightPressed(int x, int y)
A function managing the right click Pressed of a Mouse. Constructing the Canvas to draw on....
Definition: IntelliTool.cpp:14
IntelliTool::onMouseLeftReleased
virtual void onMouseLeftReleased(int x, int y)
A function managing the left click Released of a Mouse. Call this in child classes!
Definition: IntelliTool.cpp:32
ImageType
ImageType
The Types, which an Image can be.
Definition: IntelliImage.h:14
PaintingArea::addLayer
int addLayer(int width, int height, int widthOffset=0, int heightOffset=0, ImageType type=ImageType::Raster_Image)
The addLayer adds a layer to the current project/ painting area.
Definition: PaintingArea.cpp:56
PaintingArea::mouseReleaseEvent
void mouseReleaseEvent(QMouseEvent *event) override
Definition: PaintingArea.cpp:251
PaintingArea::createRectangleTool
void createRectangleTool()
Definition: PaintingArea.cpp:195
IntelliToolPolygon.h
IntelliTool::onMouseLeftPressed
virtual void onMouseLeftPressed(int x, int y)
A function managing the left click Pressed of a Mouse. Resetting the current draw....
Definition: IntelliTool.cpp:25
IntelliShapedImage.h
PaintingArea::open
bool open(const QString &fileName)
The open method is used for loading a picture into the current layer.
Definition: PaintingArea.cpp:102
LayerObject::widthOffset
int widthOffset
Definition: PaintingArea.h:28
IntelliImage::loadImage
virtual bool loadImage(const QString &fileName)
A function that loads and sclaes an image to the fitting dimensions.
Definition: IntelliImage.cpp:14
PaintingArea::setLayerToActive
void setLayerToActive(int index)
The setLayerToActive method marks a specific layer as active.
Definition: PaintingArea.cpp:89
PaintingArea::floodFill
void floodFill(int r, int g, int b, int a)
The floodFill method fills a the active layer with a given color.
Definition: PaintingArea.cpp:138
IntelliToolPlainTool
The IntelliToolPlainTool class represents a tool to fill the whole canvas with one color.
Definition: IntelliToolPlain.h:9
IntelliColorPicker::setSecondColor
void setSecondColor(QColor Color)
A function to set the secondary color.
Definition: IntelliColorPicker.cpp:28
IntelliShapedImage
The IntelliShapedImage manages a Shapedimage.
Definition: IntelliShapedImage.h:11
IntelliColorPicker::getSecondColor
QColor getSecondColor()
A function to read the secondary selected color.
Definition: IntelliColorPicker.cpp:20
LayerObject::heightOffset
int heightOffset
Definition: PaintingArea.h:29
PaintingArea::save
bool save(const QString &fileName, const char *fileFormat)
The save method is used for exporting the current project as one picture.
Definition: PaintingArea.cpp:114
PaintingArea::getHeightOfActive
int getHeightOfActive()
The getHeightOfActive gets the vertical dimensions of the active layer.
Definition: PaintingArea.cpp:218
IntelliColorPicker::switchColors
void switchColors()
A function switching primary and secondary color.
Definition: IntelliColorPicker.cpp:12
IntelliToolFloodFill.h
IntelliImage::getDisplayable
virtual QImage getDisplayable(const QSize &displaySize, int alpha)=0
A function returning the displayable ImageData in a requested transparence and size.
PaintingArea::createPlainTool
void createPlainTool()
Definition: PaintingArea.cpp:185
PaintingArea::wheelEvent
void wheelEvent(QWheelEvent *event) override
Definition: PaintingArea.cpp:264
LayerObject
The LayerObject struct holds all the information needed to construct a layer.
Definition: PaintingArea.h:24
PaintingArea::deleteLayer
void deleteLayer(int index)
The deleteLayer method removes a layer at a given index.
Definition: PaintingArea.cpp:73
PaintingArea::createPenTool
void createPenTool()
Definition: PaintingArea.cpp:180
IntelliToolPlain.h
PaintingArea::mousePressEvent
void mousePressEvent(QMouseEvent *event) override
Definition: PaintingArea.cpp:225
ImageType::Raster_Image
IntelliRasterImage.h
LayerObject::alpha
int alpha
Definition: PaintingArea.h:30
IntelliToolRectangle
The IntelliToolRectangle class represents a tool to draw a rectangle.
Definition: IntelliToolRectangle.h:11
PaintingArea::createLineTool
void createLineTool()
Definition: PaintingArea.cpp:190
IntelliToolLine.h
IntelliToolPen
The IntelliToolPen class represents a tool to draw a line.
Definition: IntelliToolPen.h:10
PaintingArea::colorPickerSetSecondColor
void colorPickerSetSecondColor()
The colorPickerSetSecondColor calls the QTColorPicker to determine the secondary drawing color.
Definition: PaintingArea.cpp:171
IntelliTool::onMouseRightReleased
virtual void onMouseRightReleased(int x, int y)
A function managing the right click Released of a Mouse. Merging the Canvas to Active....
Definition: IntelliTool.cpp:21
PaintingArea::colorPickerSetFirstColor
void colorPickerSetFirstColor()
The colorPickerSetFirstColor calls the QTColorPicker to determine the primary drawing color.
Definition: PaintingArea.cpp:166
PaintingArea::colorPickerSwitchColor
void colorPickerSwitchColor()
The colorPickerSwitchColor swaps the primary color with the secondary drawing color.
Definition: PaintingArea.cpp:176
LayerObject::width
int width
Definition: PaintingArea.h:26
IntelliToolRectangle.h
PaintingArea::~PaintingArea
~PaintingArea() override
This deconstructor is used to clear up the memory and remove the currently active window.
Definition: PaintingArea.cpp:41
PaintingArea::mouseMoveEvent
void mouseMoveEvent(QMouseEvent *event) override
Definition: PaintingArea.cpp:241
IntelliColorPicker::setFirstColor
void setFirstColor(QColor Color)
A function to set the primary color.
Definition: IntelliColorPicker.cpp:24
PaintingArea::slotDeleteActiveLayer
void slotDeleteActiveLayer()
The slotDeleteActiveLayer method handles the deletion of the active layer.
Definition: PaintingArea.cpp:82
ImageType::Shaped_Image
PaintingArea::createPolygonTool
void createPolygonTool()
Definition: PaintingArea.cpp:204
PaintingArea::moveActiveLayer
void moveActiveLayer(int idx)
The moveActiveLayer moves the active layer to a specific position in the layer stack.
Definition: PaintingArea.cpp:152
PaintingArea::PaintingArea
PaintingArea(int maxWidth=600, int maxHeight=600, QWidget *parent=nullptr)
PaintingArea is the constructor of the PaintingArea class, which initiates the working environment.
Definition: PaintingArea.cpp:21
PaintingArea.h
IntelliColorPicker::getFirstColor
QColor getFirstColor()
A function to read the primary selected color.
Definition: IntelliColorPicker.cpp:16
LayerObject::height
int height
Definition: PaintingArea.h:27
PaintingArea::createFloodFillTool
void createFloodFillTool()
Definition: PaintingArea.cpp:209
PaintingArea::slotActivateLayer
void slotActivateLayer(int a)
The slotActivateLayer method handles the event of selecting one layer as active.
Definition: PaintingArea.cpp:160
PaintingArea::paintEvent
void paintEvent(QPaintEvent *event) override
Definition: PaintingArea.cpp:275
PaintingArea::setAlphaOfLayer
void setAlphaOfLayer(int index, int alpha)
The setAlphaOfLayer method sets the alpha value of a specific layer.
Definition: PaintingArea.cpp:95
LayerObject::image
IntelliImage * image
Definition: PaintingArea.h:25
PaintingArea::resizeEvent
void resizeEvent(QResizeEvent *event) override
Definition: PaintingArea.cpp:286
IntelliToolFloodFill
The IntelliToolFloodFill class represents a tool to flood FIll a certian area.
Definition: IntelliToolFloodFill.h:10
IntelliToolPen.h
IntelliToolCircle
The IntelliToolCircle class represents a tool to draw a circle.
Definition: IntelliToolCircle.h:10
PaintingArea::movePositionActive
void movePositionActive(int x, int y)
The movePositionActive method moves the active layer to certain position.
Definition: PaintingArea.cpp:147
IntelliImage
An abstract class which manages the basic IntelliImage operations.
Definition: IntelliImage.h:24
IntelliTool::onMouseMoved
virtual void onMouseMoved(int x, int y)
A function managing the mouse moved event. Call this in child classes!
Definition: IntelliTool.cpp:41
IntelliToolPolygon
The IntelliToolPolygon managed the Drawing of Polygonforms.
Definition: IntelliToolPolygon.h:11
IntelliImage::calculateVisiblity
virtual void calculateVisiblity()=0
An abstract function that calculates the visiblity of the Image data if needed.
IntelliTool::onWheelScrolled
virtual void onWheelScrolled(int value)
A function managing the scroll event. A positive value means scrolling outwards. Call this in child c...
Definition: IntelliTool.cpp:46
IntelliRasterImage
The IntelliRasterImage manages a Rasterimage.
Definition: IntelliRasterImage.h:9
IntelliToolCircle.h
IntelliImage::drawPlain
virtual void drawPlain(const QColor &color)
A function that clears the whole image in a given Color.
Definition: IntelliImage.cpp:76
IntelliToolLine
The IntelliToolFloodFill class represents a tool to draw a line.
Definition: IntelliToolLine.h:18