IntelliPhoto  0.4
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"
13 #include "Tool/IntelliToolPen.h"
14 #include "Tool/IntelliToolPlain.h"
15 #include "Tool/IntelliToolLine.h"
16 #include "Tool/IntelliToolCircle.h"
20 
21 PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent)
22  :QWidget(parent){
23  // Testing Area
24  // test yout tool here and reset after accomplished test
25  this->Tool = new IntelliToolFloodFill(this, &colorPicker);
26  this->setUp(maxWidth, maxHeight);
27  this->addLayer(200,200,0,0,ImageType::Shaped_Image);
28  layerBundle[0].image->drawPlain(QColor(0,0,255,255));
29  std::vector<QPoint> polygon;
30  polygon.push_back(QPoint(100,000));
31  polygon.push_back(QPoint(200,100));
32  polygon.push_back(QPoint(100,200));
33  polygon.push_back(QPoint(000,100));
34  layerBundle[0].image->setPolygon(polygon);
35 
36  this->addLayer(200,200,150,150);
37  layerBundle[1].image->drawPlain(QColor(0,255,0,255));
38  layerBundle[1].alpha=200;
39 
40  activeLayer=0;
41 }
42 
44  delete Tool;
45 }
46 
47 void PaintingArea::setUp(int maxWidth, int maxHeight){
48  //set standart parameter
49  this->maxWidth = maxWidth;
50  this->maxHeight = maxHeight;
51  Canvas = new QImage(maxWidth,maxHeight, QImage::Format_ARGB32);
52 
53  // Roots the widget to the top left even if resized
54  setAttribute(Qt::WA_StaticContents);
55 
56 }
57 
58 int PaintingArea::addLayer(int width, int height, int widthOffset, int heightOffset, ImageType type){
59  LayerObject newLayer;
60  newLayer.width = width;
61  newLayer.hight = height;
62  newLayer.widthOffset = widthOffset;
63  newLayer.hightOffset = heightOffset;
64  if(type==ImageType::Raster_Image){
65  newLayer.image = new IntelliRasterImage(width,height);
66  }else if(type==ImageType::Shaped_Image){
67  newLayer.image = new IntelliShapedImage(width, height);
68  }
69  newLayer.alpha = 255;
70  this->layerBundle.push_back(newLayer);
71  return static_cast<int>(layerBundle.size())-1;
72 }
73 
74 
75 void PaintingArea::deleteLayer(int index){
76  if(index<static_cast<int>(layerBundle.size())){
77  this->layerBundle.erase(layerBundle.begin()+index);
78  if(activeLayer>=index){
79  activeLayer--;
80  }
81  }
82 }
83 
85  if(activeLayer>=0 && activeLayer < static_cast<int>(layerBundle.size())){
86  this->layerBundle.erase(layerBundle.begin()+activeLayer);
87  activeLayer--;
88  }
89 }
90 
92  if(index>=0&&index<static_cast<int>(layerBundle.size())){
93  this->activeLayer=index;
94  }
95 }
96 
97 void PaintingArea::setAlphaOfLayer(int index, int alpha){
98  if(index>=0&&index<static_cast<int>(layerBundle.size())){
99  layerBundle[static_cast<size_t>(index)].alpha=alpha;
100  }
101 }
102 
103 // Used to load the image and place it in the widget
104 bool PaintingArea::open(const QString &fileName){
105  if(this->activeLayer==-1){
106  return false;
107  }
108  IntelliImage* active = layerBundle[static_cast<size_t>(activeLayer)].image;
109  bool open = active->loadImage(fileName);
110  active->calculateVisiblity();
111  update();
112  return open;
113 }
114 
115 // Save the current image
116 bool PaintingArea::save(const QString &fileName, const char *fileFormat){
117  if(layerBundle.size()==0){
118  return false;
119  }
120  this->assembleLayers(true);
121 
122  if(!strcmp(fileFormat,"PNG")){
123  QImage visibleImage = Canvas->convertToFormat(QImage::Format_Indexed8);
124  fileFormat = "png";
125  if (visibleImage.save(fileName, fileFormat)) {
126  return true;
127  } else {
128  return false;
129  }
130  }
131 
132  if (Canvas->save(fileName, fileFormat)) {
133  return true;
134  } else {
135  return false;
136  }
137 }
138 
139 // Color the image area with white
140 void PaintingArea::floodFill(int r, int g, int b, int a){
141  if(this->activeLayer==-1){
142  return;
143  }
144  IntelliImage* active = layerBundle[static_cast<size_t>(activeLayer)].image;
145  active->drawPlain(QColor(r, g, b, a));
146  update();
147 }
148 
150  layerBundle[static_cast<size_t>(activeLayer)].widthOffset += x;
151  layerBundle[static_cast<size_t>(activeLayer)].hightOffset += y;
152 }
153 
155  if(idx==1){
156  this->activateUpperLayer();
157  }else if(idx==-1){
158  this->activateLowerLayer();
159  }
160 }
161 
163  if(a>=0 && a < static_cast<int>(layerBundle.size())){
164  this->setLayerToActive(a);
165  }
166 }
167 
169  QColor clr = QColorDialog::getColor(colorPicker.getFirstColor(), nullptr, "Main Color", QColorDialog::DontUseNativeDialog);
170  this->colorPicker.setFirstColor(clr);
171 }
172 
174  QColor clr = QColorDialog::getColor(colorPicker.getSecondColor(), nullptr, "Secondary Color", QColorDialog::DontUseNativeDialog);
175  this->colorPicker.setSecondColor(clr);
176 }
177 
179  this->colorPicker.switchColors();
180 }
181 
183  delete this->Tool;
184  Tool = new IntelliToolPen(this, &colorPicker);
185 }
186 
188  delete this->Tool;
189  Tool = new IntelliToolPlainTool(this, &colorPicker);
190 }
191 
193  delete this->Tool;
194  Tool = new IntelliToolLine(this, &colorPicker);
195 }
196 
198  return layerBundle.operator[](activeLayer).width;
199 }
200 
202  return layerBundle.operator[](activeLayer).hight;
203 }
204 
205 // If a mouse button is pressed check if it was the
206 // left button and if so store the current position
207 // Set that we are currently drawing
208 void PaintingArea::mousePressEvent(QMouseEvent *event){
209  if(Tool == nullptr)
210  return;
211  int x = event->x()-layerBundle[activeLayer].widthOffset;
212  int y = event->y()-layerBundle[activeLayer].hightOffset;
213  if(event->button() == Qt::LeftButton){
214  Tool->onMouseLeftPressed(x, y);
215  }else if(event->button() == Qt::RightButton){
216  Tool->onMouseRightPressed(x, y);
217  }
218  update();
219 }
220 
221 // When the mouse moves if the left button is clicked
222 // we call the drawline function which draws a line
223 // from the last position to the current
224 void PaintingArea::mouseMoveEvent(QMouseEvent *event){
225  if(Tool == nullptr)
226  return;
227  int x = event->x()-layerBundle[activeLayer].widthOffset;
228  int y = event->y()-layerBundle[activeLayer].hightOffset;
229  Tool->onMouseMoved(x, y);
230  update();
231 }
232 
233 // If the button is released we set variables to stop drawing
234 void PaintingArea::mouseReleaseEvent(QMouseEvent *event){
235  if(Tool == nullptr)
236  return;
237  int x = event->x()-layerBundle[activeLayer].widthOffset;
238  int y = event->y()-layerBundle[activeLayer].hightOffset;
239  if(event->button() == Qt::LeftButton){
240  Tool->onMouseLeftReleased(x, y);
241  }else if(event->button() == Qt::RightButton){
242  Tool->onMouseRightReleased(x, y);
243  }
244  update();
245 }
246 
247 void PaintingArea::wheelEvent(QWheelEvent *event){
248  QPoint numDegrees = event->angleDelta() / 8;
249  if(!numDegrees.isNull()){
250  QPoint numSteps = numDegrees / 15;
251  Tool->onWheelScrolled(numSteps.y()*-1);
252  }
253 }
254 
255 // QPainter provides functions to draw on the widget
256 // The QPaintEvent is sent to widgets that need to
257 // update themselves
258 void PaintingArea::paintEvent(QPaintEvent *event){
259  this->assembleLayers();
260 
261  QPainter painter(this);
262  QRect dirtyRec = event->rect();
263  painter.drawImage(dirtyRec, *Canvas, dirtyRec);
264  update();
265 }
266 
267 // Resize the image to slightly larger then the main window
268 // to cut down on the need to resize the image
269 void PaintingArea::resizeEvent(QResizeEvent *event){
270  //TODO wait till tool works
271  update();
272 }
273 
274 void PaintingArea::resizeImage(QImage *image_res, const QSize &newSize){
275  //TODO implement
276 }
277 
278 void PaintingArea::activateUpperLayer(){
279  if(activeLayer!=-1 && activeLayer<layerBundle.size()-1){
280  std::swap(layerBundle[activeLayer], layerBundle[activeLayer+1]);
281  activeLayer++;
282  }
283 }
284 
285 void PaintingArea::activateLowerLayer(){
286  if(activeLayer!=-1 && activeLayer>0){
287  std::swap(layerBundle[activeLayer], layerBundle[activeLayer-1]);
288  activeLayer--;
289  }
290 }
291 
292 void PaintingArea::assembleLayers(bool forSaving){
293  if(forSaving){
294  Canvas->fill(Qt::GlobalColor::transparent);
295  }else{
296  Canvas->fill(Qt::GlobalColor::black);
297  }
298  for(size_t i=0; i<layerBundle.size(); i++){
299  LayerObject layer = layerBundle[i];
300  QImage cpy = layer.image->getDisplayable(layer.alpha);
301  QColor clr_0;
302  QColor clr_1;
303  for(int y=0; y<layer.hight; y++){
304  if(layer.hightOffset+y<0) continue;
305  if(layer.hightOffset+y>=maxHeight) break;
306  for(int x=0; x<layer.width; x++){
307  if(layer.widthOffset+x<0) continue;
308  if(layer.widthOffset+x>=maxWidth) break;
309  clr_0=Canvas->pixelColor(layer.widthOffset+x, layer.hightOffset+y);
310  clr_1=cpy.pixelColor(x,y);
311  float t = static_cast<float>(clr_1.alpha())/255.f;
312  int r =static_cast<int>(static_cast<float>(clr_1.red())*(t)+static_cast<float>(clr_0.red())*(1.f-t)+0.5f);
313  int g =static_cast<int>(static_cast<float>(clr_1.green())*(t)+static_cast<float>(clr_0.green())*(1.f-t)+0.5f);
314  int b =static_cast<int>(static_cast<float>(clr_1.blue())*(t)+static_cast<float>(clr_0.blue()*(1.f-t))+0.5f);
315  int a =std::min(clr_0.alpha()+clr_1.alpha(), 255);
316  clr_0.setRed(r);
317  clr_0.setGreen(g);
318  clr_0.setBlue(b);
319  clr_0.setAlpha(a);
320 
321  Canvas->setPixelColor(layer.widthOffset+x, layer.hightOffset+y, clr_0);
322  }
323  }
324  }
325 }
326 
327 void PaintingArea::createTempLayerAfter(int idx){
328  if(idx>=0){
329  LayerObject newLayer;
330  newLayer.alpha = 255;
331  newLayer.hight = layerBundle[idx].hight;
332  newLayer.width = layerBundle[idx].width;
333  newLayer.hightOffset = layerBundle[idx].hightOffset;
334  newLayer.widthOffset = layerBundle[idx].widthOffset;
335  newLayer.image = layerBundle[idx].image->getDeepCopy();
336  layerBundle.insert(layerBundle.begin()+idx+1,newLayer);
337  }
338 }
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)
Definition: PaintingArea.cpp:58
PaintingArea::getWidthActiveLayer
int getWidthActiveLayer()
Definition: PaintingArea.cpp:197
PaintingArea::mouseReleaseEvent
void mouseReleaseEvent(QMouseEvent *event) override
Definition: PaintingArea.cpp:234
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)
Definition: PaintingArea.cpp:104
LayerObject::widthOffset
int widthOffset
Definition: PaintingArea.h:20
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)
Definition: PaintingArea.cpp:91
PaintingArea::getHeightActiveLayer
int getHeightActiveLayer()
Definition: PaintingArea.cpp:201
PaintingArea::floodFill
void floodFill(int r, int g, int b, int a)
Definition: PaintingArea.cpp:140
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
PaintingArea::save
bool save(const QString &fileName, const char *fileFormat)
Definition: PaintingArea.cpp:116
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:187
PaintingArea::wheelEvent
void wheelEvent(QWheelEvent *event) override
Definition: PaintingArea.cpp:247
LayerObject
Definition: PaintingArea.h:16
PaintingArea::deleteLayer
void deleteLayer(int index)
Definition: PaintingArea.cpp:75
PaintingArea::createPenTool
void createPenTool()
Definition: PaintingArea.cpp:182
IntelliToolPlain.h
PaintingArea::mousePressEvent
void mousePressEvent(QMouseEvent *event) override
Definition: PaintingArea.cpp:208
ImageType::Raster_Image
IntelliRasterImage.h
LayerObject::alpha
int alpha
Definition: PaintingArea.h:22
PaintingArea::createLineTool
void createLineTool()
Definition: PaintingArea.cpp:192
IntelliToolLine.h
IntelliToolPen
The IntelliToolPen class represents a tool to draw a line.
Definition: IntelliToolPen.h:10
PaintingArea::colorPickerSetSecondColor
void colorPickerSetSecondColor()
Definition: PaintingArea.cpp:173
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()
Definition: PaintingArea.cpp:168
PaintingArea::colorPickerSwitchColor
void colorPickerSwitchColor()
Definition: PaintingArea.cpp:178
LayerObject::width
int width
Definition: PaintingArea.h:18
IntelliToolRectangle.h
PaintingArea::~PaintingArea
~PaintingArea() override
Definition: PaintingArea.cpp:43
PaintingArea::mouseMoveEvent
void mouseMoveEvent(QMouseEvent *event) override
Definition: PaintingArea.cpp:224
IntelliColorPicker::setFirstColor
void setFirstColor(QColor Color)
A function to set the primary color.
Definition: IntelliColorPicker.cpp:24
PaintingArea::slotDeleteActiveLayer
void slotDeleteActiveLayer()
Definition: PaintingArea.cpp:84
ImageType::Shaped_Image
PaintingArea::moveActiveLayer
void moveActiveLayer(int idx)
Definition: PaintingArea.cpp:154
PaintingArea::PaintingArea
PaintingArea(int maxWidth=600, int maxHeight=600, QWidget *parent=nullptr)
Definition: PaintingArea.cpp:21
PaintingArea.h
IntelliColorPicker::getFirstColor
QColor getFirstColor()
A function to read the primary selected color.
Definition: IntelliColorPicker.cpp:16
LayerObject::hight
int hight
Definition: PaintingArea.h:19
PaintingArea::slotActivateLayer
void slotActivateLayer(int a)
Definition: PaintingArea.cpp:162
PaintingArea::paintEvent
void paintEvent(QPaintEvent *event) override
Definition: PaintingArea.cpp:258
PaintingArea::setAlphaOfLayer
void setAlphaOfLayer(int index, int alpha)
Definition: PaintingArea.cpp:97
LayerObject::image
IntelliImage * image
Definition: PaintingArea.h:17
PaintingArea::resizeEvent
void resizeEvent(QResizeEvent *event) override
Definition: PaintingArea.cpp:269
IntelliToolFloodFill
The IntelliToolFloodFill class represents a tool to flood FIll a certian area.
Definition: IntelliToolFloodFill.h:10
IntelliToolPen.h
PaintingArea::movePositionActive
void movePositionActive(int x, int y)
Definition: PaintingArea.cpp:149
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
LayerObject::hightOffset
int hightOffset
Definition: PaintingArea.h:21
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