SGL
gcanvas.h
1 /*
2  * File: gcanvas.h
3  * ---------------
4  *
5  * @author Marty Stepp
6  * @version 2021/04/09
7  * - added sgl namespace
8  * - converted Grid functionality to 2D array/vector
9  * @version 2019/05/01
10  * - added createArgbPixel
11  * - bug fixes related to save / setPixels with alpha transparency
12  * @version 2019/03/07
13  * - added support for loading canvas directly from istream (htiek)
14  * @version 2018/09/10
15  * - added doc comments for new documentation generation
16  * @version 2018/09/04
17  * - added double-click event support
18  * @version 2018/08/23
19  * - renamed to gcanvas.h to replace Java version
20  * @version 2018/06/30
21  * - initial version
22  */
23 
24 
25 #ifndef _gcanvas_h
26 #define _gcanvas_h
27 
28 #include <string>
29 #include <vector>
30 #include <QtEvents>
31 #include <QPainter>
32 #include "gdrawingsurface.h"
33 #include "gevent.h"
34 #include "ginteractor.h"
35 #include "gobjects.h"
36 
37 // default color used to highlight pixels that do not match between two images
38 #define GCANVAS_DEFAULT_DIFF_PIXEL_COLOR 0xdd00dd
39 
40 namespace sgl {
41 
42 class _Internal_QCanvas;
43 
75 class GCanvas : public virtual GInteractor, public virtual GDrawingSurface {
76 public:
81  static const int WIDTH_HEIGHT_MAX;
82 
87  static int createArgbPixel(int alpha, int red, int green, int blue);
88 
93  static int createRgbPixel(int red, int green, int blue);
94 
99  static int getAlpha(int argb);
100 
105  static int getBlue(int rgb);
106 
111  static int getGreen(int rgb);
112 
117  static int getRed(int rgb);
118 
123  static void getRedGreenBlue(int rgb, int& red, int& green, int& blue);
124 
129  GCanvas(QWidget* parent = nullptr);
130 
137  GCanvas(const string& filename, QWidget* parent = nullptr);
138 
144  GCanvas(std::istream& filename, QWidget* parent = nullptr);
145 
152  GCanvas(double width, double height, int rgbBackground, QWidget* parent = nullptr);
153 
160  GCanvas(double width, double height, const string& rgbBackground = "#00000000", QWidget* parent = nullptr);
161 
165  ~GCanvas() override;
166 
171  virtual void add(GObject* gobj);
172 
178  virtual void add(GObject* gobj, double x, double y);
179 
183  virtual void add(GObject& gobj);
184 
189  virtual void add(GObject& gobj, double x, double y);
190 
195  void clear() override;
196 
205  virtual void clearObjects();
206 
216  virtual void clearPixels();
217 
222  virtual bool contains(double x, double y) const;
223 
231  virtual int countDiffPixels(const GCanvas& image) const;
232 
240  virtual int countDiffPixels(const GCanvas& image, int xmin, int ymin, int xmax, int ymax) const;
241 
250  virtual int countDiffPixels(const GCanvas* image) const;
251 
260  virtual int countDiffPixels(const GCanvas* image, int xmin, int ymin, int xmax, int ymax) const;
261 
267  virtual GCanvas* diff(const GCanvas& image, int diffPixelColor = GCANVAS_DEFAULT_DIFF_PIXEL_COLOR) const;
268 
275  virtual GCanvas* diff(const GCanvas* image, int diffPixelColor = GCANVAS_DEFAULT_DIFF_PIXEL_COLOR) const;
276 
286  void draw(GObject* gobj) override;
287 
288  /* @private */
289  /* @inherit */
290  void draw(QPainter* painter) override;
291 
295  virtual bool equals(const GCanvas& other) const;
296 
302  virtual void fill(int rgb);
303 
308  virtual void fill(const string& rgb);
309 
319  virtual void fillRegion(double x, double y, double width, double height, int rgb);
320 
329  virtual void fillRegion(double x, double y, double width, double height,
330  const string& rgb);
331 
337  virtual void flatten();
338 
339  /* @inherit */
340  string getBackground() const override;
341 
342  /* @inherit */
343  int getBackgroundInt() const override;
344 
351  virtual GObject* getElement(int index) const;
352 
358  virtual GObject* getElementAt(double x, double y) const;
359 
364  virtual int getElementCount() const;
365 
371  virtual string getFilename() const;
372 
373  /* @inherit */
374  string getFont() const override;
375 
376  /* @inherit */
377  _Internal_QWidget* getInternalWidget() const override;
378 
390  int getPixel(double x, double y) const override;
391 
406  int getPixelARGB(double x, double y) const override;
407 
413  virtual std::vector<std::vector<int>> getPixels() const override;
414 
422  int** getPixelsArray() const override;
423 
432  virtual std::vector<std::vector<int>> getPixelsARGB() const override;
433 
444  int** getPixelsArrayARGB() const override;
445 
446  /* @inherit */
447  string getType() const override;
448 
449  /* @inherit */
450  QWidget* getWidget() const override;
451 
452  /* @inherit */
453  bool isAutoRepaint() const override;
454 
460  virtual void load(const string& filename);
461 
473  virtual void remove(GObject* gobj);
474 
479  virtual void remove(GObject& gobj);
480 
484  virtual void removeAll();
485 
494  void repaint() override;
495 
500  void repaintRegion(int x, int y, int width, int height) override;
501 
512  void resize(double width, double height, bool retain = true);
513 
518  virtual void save(const string& filename);
519 
528  void setAutoRepaint(bool autoRepaint) override;
529 
530  /* @inherit */
531  void setBackground(int color) override;
532 
533  /* @inherit */
534  void setBackground(const string& color) override;
535 
536  /* @inherit */
537  void setColor(int color) override;
538 
539  /* @inherit */
540  void setColor(const string& color) override;
541 
542  /* @inherit */
543  void setFont(const QFont& font) override;
544 
545  /* @inherit */
546  void setFont(const string& font) override;
547 
548  /* @inherit */
549  void setForeground(int rgb) override;
550 
551  /* @inherit */
552  void setForeground(const string& color) override;
553 
559  void setKeyListener(GEventListener func) override;
560 
566  void setKeyListener(GEventListenerVoid func) override;
567 
579  void setPixel(double x, double y, int rgb) override;
580 
592  void setPixel(double x, double y, int r, int g, int b) override;
593 
605  void setPixelARGB(double x, double y, int argb) override;
606 
618  void setPixelARGB(double x, double y, int a, int r, int g, int b) override;
619 
628  void setPixels(int** pixels, int width = -1, int height = -1) override;
629 
638  virtual void setPixels(const std::vector<std::vector<int>>& pixels) override;
639 
648  void setPixelsARGB(int** pixelsARGB, int width = -1, int height = -1) override;
649 
658  virtual void setPixelsARGB(const std::vector<std::vector<int>>& pixelsARGB) override;
659 
663  virtual GImage* toGImage() const;
664 
665 private:
666  Q_DISABLE_COPY(GCanvas)
667 
668  _Internal_QCanvas* _iqcanvas;
669  GCompound _gcompound;
670  QImage* _backgroundImage;
671  string _filename; // file canvas was loaded from; "" if not loaded from a file
672 
673  friend class _Internal_QCanvas;
674 
675  void ensureBackgroundImage();
676 
677  void ensureBackgroundImageConstHack() const;
678 
679  void init(double width, double height, int rgbBackground, QWidget* parent);
680 
685  virtual bool loadFromStream(std::istream& input);
686 
687  void notifyOfResize(double width, double height);
688 };
689 
690 
695 class _Internal_QCanvas : public QWidget, public _Internal_QWidget {
696  Q_OBJECT
697 
698 public:
699  _Internal_QCanvas(GCanvas* gcanvas, QWidget* parent = nullptr);
700  void detach() override;
701  void enterEvent(QEvent* event) override;
702  void keyPressEvent(QKeyEvent* event) override;
703  void keyReleaseEvent(QKeyEvent* event) override;
704  void leaveEvent(QEvent* event) override;
705  void mouseMoveEvent(QMouseEvent* event) override;
706  void mousePressEvent(QMouseEvent* event) override;
707  void mouseReleaseEvent(QMouseEvent* event) override;
708  void paintEvent(QPaintEvent *event) override;
709  void resizeEvent(QResizeEvent* event) override;
710  virtual void setCanvasSize(double width, double height);
711  QSize sizeHint() const override;
712  void wheelEvent(QWheelEvent* event) override;
713 
714 signals:
715  void doubleClicked();
716 
717 protected:
718  void mouseDoubleClickEvent(QMouseEvent* e) override;
719 
720 private:
721  GCanvas* _gcanvas;
722 
723  friend class GCanvas;
724 };
725 
726 } // namespace sgl
727 
728 #endif // _gcanvas_h
virtual bool equals(const GCanvas &other) const
Returns true if the two given canvases contain exactly the same pixel data.
Definition: gcanvas.cpp:392
_Internal_QWidget* getInternalWidget() const override
Returns a direct pointer to the internal Qt widget being wrapped by this interactor.
Definition: gcanvas.cpp:489
int ** getPixelsArrayARGB() const override
Returns all pixels of the background layer of the canvas as a heap-allocated 2D array, where the first index represents the x value and the second index represents the y value.
Definition: gcanvas.cpp:559
virtual void load(string filename)
Reads the canvas&#39;s pixel contents from the given image file.
Definition: gcanvas.cpp:587
virtual void clearObjects()
Removes all graphical objects from the foreground layer of the canvas.
Definition: gcanvas.cpp:193
void setPixelsARGB(int **pixelsARGB, int width=-1, int height=-1) override
Sets the color of the all pixels in the background layer of the canvas to the given ARGB values...
Definition: gcanvas.cpp:920
static int getGreen(int rgb)
Extracts the green component from 0-255 of the given RGB integer.
Definition: gcanvas.cpp:68
string getBackground() const override
Returns the current background color of the interactor as a string.
Definition: gcanvas.cpp:452
virtual void clearPixels()
Resets the background layer of pixels in the canvas to the current background color.
Definition: gcanvas.cpp:201
static int getRed(int rgb)
Extracts the red component from 0-255 of the given RGB integer.
Definition: gcanvas.cpp:72
This graphical object subclass represents an image from a file.
Definition: gobjects.h:957
void setColor(int color) override
Sets the current foreground outline color of the interactor as as RGB integer.
Definition: gcanvas.cpp:782
void setBackground(int color) override
Sets the current background color of the interactor as an RGB integer.
Definition: gcanvas.cpp:760
bool isAutoRepaint() const override
Returns true if the interactor should repaint itself automatically whenever any change is made to its...
Definition: gcanvas.cpp:583
virtual void fillRegion(double x, double y, double width, double height, int rgb)
Sets the color of every pixel in the given rectangular range of the canvas pixel data to the given co...
Definition: gcanvas.cpp:413
virtual void add(GObject *gobj)
Adds the given interactor to canvas.
Definition: gcanvas.cpp:156
virtual std::vector< std::vector< int > > getPixels() const override
Returns all pixels of the surface as a nested STL vector of vectors, where the first index represents...
Definition: gcanvas.cpp:511
GDrawingSurface is an abstract superclass for types that allow drawing shapes and pixels onto themsel...
Definition: gdrawingsurface.h:35
virtual GObject * getElementAt(double x, double y) const
Returns a pointer to the first graphical object in the foreground layer of the canvas that contains t...
Definition: gcanvas.cpp:467
void setPixels(int **pixels, int width=-1, int height=-1) override
Sets the color of the all pixels in the background layer of the canvas to the given RGB values...
Definition: gcanvas.cpp:866
This class is the common superclass of all graphical objects that can be displayed on a graphical win...
Definition: gobjects.h:66
void setKeyListener(GEventListener func) override
Sets a key listener on this canvas so that it will be called when any key is pressed or released on t...
Definition: gcanvas.cpp:806
void setAutoRepaint(bool autoRepaint) override
Sets whether the canvas will automatically repaint itself whenever you make a change to either the ba...
Definition: gcanvas.cpp:752
virtual GObject * getElement(int index) const
Returns a pointer to the graphical object in the foreground layer of the canvas at the specified inde...
Definition: gcanvas.cpp:460
std::function< void(GEvent)> GEventListener
Types for the event listener functions to be passed to various interactors.
Definition: gevent.h:38
void clear() override
Removes all graphical objects from the canvas foreground layer and wipes the background layer to show...
Definition: gcanvas.cpp:188
Definition: console.h:45
void setPixelARGB(double x, double y, int argb) override
Sets the color of the given x/y pixel in the background layer of the canvas to the given ARGB value...
Definition: gcanvas.cpp:850
This abstract class is the superclass for all graphical interactors.
Definition: ginteractor.h:52
virtual int countDiffPixels(const GCanvas &image) const
Returns the total number of pixels that are not the same color between this image and the given other...
Definition: gcanvas.cpp:228
string getFont() const override
Returns the current text font of the interactor as a font string.
Definition: gcanvas.cpp:485
A GCanvas is a graphical drawing surface on which you can draw shapes, lines, and colors...
Definition: gcanvas.h:75
void repaintRegion(int x, int y, int width, int height) override
Instructs the canvas to redraw the given region of pixels within both of its layers.
Definition: gcanvas.cpp:704
string getType() const override
Returns a string representing the class name of this interactor, such as "GButton" or "GCheckBox"...
Definition: gcanvas.cpp:575
virtual string getFilename() const
Returns the name of the image file from which this canvas was loaded or to which it was saved most re...
Definition: gcanvas.cpp:481
virtual bool contains(double x, double y) const
Returns true if any of the graphical objects in the foreground layer of the canvas touch the given x/...
Definition: gcanvas.cpp:221
virtual std::vector< std::vector< int > > getPixelsARGB() const override
Returns all pixels of the background layer of the canvas as a nested STL vector of vectors...
Definition: gcanvas.cpp:543
std::function< void()> GEventListenerVoid
Types for the event listener functions to be passed to various interactors.
Definition: gevent.h:44
~GCanvas() override
Frees memory allocated internally by the canvas.
Definition: gcanvas.cpp:150
void setFont(const QFont &font) override
Returns the current text font of the interactor using a Qt font object.
Definition: gcanvas.cpp:790
static int createArgbPixel(int alpha, int red, int green, int blue)
Creates a single ARGB integer from the given A-R-G-B components from 0-255.
Definition: gcanvas.cpp:45
virtual int getElementCount() const
Returns the number of graphical objects stored in the foreground layer of the canvas.
Definition: gcanvas.cpp:474
void repaint() override
Instructs the canvas to redraw its layers.
Definition: gcanvas.cpp:695
static void getRedGreenBlue(int rgb, int &red, int &green, int &blue)
Extracts the red, green, and blue components from 0-255 of the given RGB integer, filling by referenc...
Definition: gcanvas.cpp:76
This graphical object subclass consists of a collection of other graphical objects.
Definition: gobjects.h:769
static int getAlpha(int argb)
Extracts the alpha component from 0-255 of the given ARGB integer.
Definition: gcanvas.cpp:59
int getPixelARGB(double x, double y) const override
Returns the color of the pixel at the given x/y coordinates of the background layer of the canvas as ...
Definition: gcanvas.cpp:502
virtual void removeAll()
Removes all graphical objects from the foreground layer of the canvas.
Definition: gcanvas.cpp:687
void setPixel(double x, double y, int rgb) override
Sets the color of the given x/y pixel in the background layer of the canvas to the given RGB value...
Definition: gcanvas.cpp:824
virtual void save(string filename)
Saves the canvas&#39;s contents to the given image file.
Definition: gcanvas.cpp:721
QWidget* getWidget() const override
Returns a direct pointer to the internal Qt widget being wrapped by this interactor.
Definition: gcanvas.cpp:579
int getPixel(double x, double y) const override
Returns the color of the pixel at the given x/y coordinates of the background layer of the canvas as ...
Definition: gcanvas.cpp:493
static const int WIDTH_HEIGHT_MAX
Largest value that an image&#39;s width and/or height can have.
Definition: gcanvas.h:81
virtual GImage * toGImage() const
Converts the pixels of the canvas into a GImage object.
Definition: gcanvas.cpp:972
static int createRgbPixel(int red, int green, int blue)
Creates a single RGB integer from the given R-G-B components from 0-255.
Definition: gcanvas.cpp:52
virtual GCanvas * diff(const GCanvas &image, int diffPixelColor=GCANVAS_DEFAULT_DIFF_PIXEL_COLOR) const
Generates a new canvas whose content is equal to that of this canvas but with any pixels that don&#39;t m...
Definition: gcanvas.cpp:287
virtual void flatten()
Moves all graphical objects from the foreground layer to the background layer.
Definition: gcanvas.cpp:438
int ** getPixelsArray() const override
Returns all pixels of the background layer of the canvas as a heap-allocated 2D array, where the first index represents the x value and the second index represents the y value.
Definition: gcanvas.cpp:527
int getBackgroundInt() const override
Returns the current background color of the interactor as an RGB integer.
Definition: gcanvas.cpp:456
void setForeground(int rgb) override
Sets the current foreground outline color of the interactor as an RGB integer.
Definition: gcanvas.cpp:798
void draw(GObject *gobj) override
Draws the given graphical object onto the background layer of the canvas.
Definition: gcanvas.cpp:344
static int getBlue(int rgb)
Extracts the blue component from 0-255 of the given RGB integer.
Definition: gcanvas.cpp:64
virtual void fill(int rgb)
Sets the color of every pixel in the canvas to the given color value.
Definition: gcanvas.cpp:400
void resize(double width, double height, bool retain=true)
Changes this image&#39;s bounds to be the given size.
Definition: gcanvas.cpp:712
GCanvas(QWidget* parent=nullptr)
Creates an empty canvas with a default size of 0x0 pixels and a default background and foreground col...
Definition: gcanvas.cpp:83