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