No Description

grid.cpp 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. /***************************************************************************
  2. ** Initial code taken from: http://www.labsquare.org (Sacha Schutz) **
  3. ** Where can be drawn a grid and that object could paint the desired cell **
  4. ****************************************************************************
  5. ** **
  6. ** GridView, a simple GridView made with Qt4 **
  7. ** Copyright (C) 2013 Sacha Schutz **
  8. ** **
  9. ** This program is free software: you can redistribute it and/or modify **
  10. ** it under the terms of the GNU General Public License as published by **
  11. ** the Free Software Foundation, either version 3 of the License, or **
  12. ** (at your option) any later version. **
  13. ** **
  14. ** This program is distributed in the hope that it will be useful, **
  15. ** but WITHOUT ANY WARRANTY; without even the implied warranty of **
  16. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
  17. ** GNU General Public License for more details. **
  18. ** **
  19. ** You should have received a copy of the GNU General Public License **
  20. ** along with this program. If not, see http://www.gnu.org/licenses/. **
  21. ** **
  22. ****************************************************************************/
  23. //The rest of the code was implemented by Ramon Collazo for the project
  24. //TUES at UPRRP.
  25. #include "grid.h"
  26. #include <QVBoxLayout>
  27. #include <QToolBar>
  28. #include <QtGlobal>
  29. #include <QDebug>
  30. #include <QtCore>
  31. /// \fn GridWidget::GridWidget(QWidget *parent)
  32. /// \~English
  33. /// \brief Default constructor. The properties of the grid are set as follows:
  34. ///* mCellSize: Sets the size of the cell to 10px
  35. ///* mRowCount: Sets the number of rows in the grid to 39
  36. ///* mColumnCount: Sets the number of columns in the grid to 27
  37. ///* Tool and ToolSize: Sets the Tool which is going to be used to draw the grid
  38. ///* frontColor: The color which will be used to paint to black
  39. ///* backColor: Current clicked square
  40. ///* background: Sets the background color to white
  41. /// \~English
  42. /// \brief Constructor por defecto. Las propiedades de el grid se ajustan como sigue:
  43. /// * mCellSize: Ajusta el tamano de la celda a 10px
  44. /// * mRowCount: Ajusta el numero de filas en la cuadricula a 39
  45. /// * ColumnCount: Ajusta el numero de columnas en el grid a 27
  46. /// * Tool and ToolSize: Ajusta la herramiento que se va a utilizar para dibujar
  47. /// el grid.
  48. /// * frontColor: El color que se utilizara para pintar a negro
  49. /// * backColor: Cuadrado marcado actualmente
  50. /// * background: El color del fondo en blanco
  51. GridWidget::GridWidget(QWidget *parent):
  52. QWidget(parent)
  53. {
  54. mCellSize = 10;
  55. mRowCount = 39;
  56. mColumnCount = 27;
  57. Tool = "dot";
  58. ToolSize = 1;
  59. frontColor = Qt::black;
  60. /* QColor::Invalid is used to identify when the color is not selected*/
  61. /* QColor::Invalid es usado para identificar cuando el color no esta seleccionado*/
  62. backColor = QColor::Invalid;
  63. background = Qt::white;
  64. emit canUndo(false);
  65. emit canRedo(false);
  66. }
  67. /// \fn GridWidget::GridWidget(int rowCount, int columnCount, QWidget *parent):
  68. /// \~English
  69. /// \brief Constructor which receives the number of rows and columns in the grid
  70. /// \param rowCount number of rows in the grid
  71. /// \param columnCount number of columns in the grid
  72. /// \param parent parent window
  73. /// \~Spanish
  74. /// \brief Constructor que recibe el numero de filas y columnas en la cuadricula
  75. /// \param rowCount numero de filas en la cuadricula
  76. /// \param columnCount numero de columnas en la cuadricula
  77. /// \param parent ventana padre
  78. GridWidget::GridWidget(int rowCount, int columnCount, QWidget *parent):
  79. QWidget(parent)
  80. {
  81. mCellSize = 10;
  82. mRowCount = rowCount;
  83. mColumnCount = columnCount;
  84. Tool = "dot";
  85. ToolSize = 1;
  86. frontColor = Qt::black;
  87. backColor = QColor::Invalid;
  88. background = Qt::white;
  89. emit canUndo(false);
  90. emit canRedo(false);
  91. }
  92. /// \fn void GridWidget::setTool(QString tool)
  93. /// \~English
  94. /// \param tool choosen tool
  95. /// \brief Sets the tool
  96. /// \~Spanish
  97. /// \param tool herramienta escogida
  98. /// \brief Ajusta la herramienta
  99. void GridWidget::setTool(QString tool){
  100. Tool = tool;
  101. }
  102. /// \fn void GridWidget::setFront(QString front)
  103. /// \~English
  104. /// \brief Sets the color of the brush
  105. /// \param front brush color
  106. /// \~Spanish
  107. /// \brief Ajusta el color de la brocha
  108. /// \param front color de la brocha
  109. void GridWidget::setFront(QString front){
  110. frontColor = front;
  111. }
  112. /// \fn void GridWidget::setBack(QString back)
  113. /// \~English
  114. /// \brief Sets the color of the background
  115. /// \param back background color
  116. /// \~Spanish
  117. /// \brief Ajusta el color del fondo
  118. /// \param back color para el fondo
  119. void GridWidget::setBack(QString back){
  120. background=back;
  121. }
  122. /// \fn void GridWidget::setToolSize(int size)
  123. /// \~English
  124. /// \brief Sets the size of the tool
  125. /// \param size tool size
  126. /// \~Spanish
  127. /// \brief Ajusta el tamano de la herramienta
  128. /// \param size tamano de la herramienta
  129. void GridWidget::setToolSize(int size){
  130. ToolSize = size;
  131. }
  132. /// \fn void GridWidget::setGridSize(int rowCount, int columnCount)
  133. /// \~English
  134. /// \brief Sets the number of columns and rows of the grid
  135. /// \param rowCount number of rows
  136. /// \param columnCount number of columns
  137. /// \~Spanish
  138. /// \brief Ajusta el numero de columnas y fileas de la cuadricula
  139. /// \param rowCount numero de filas
  140. /// \param columnCount numero de columnas
  141. void GridWidget::setGridSize(int rowCount, int columnCount)
  142. {
  143. mRowCount = rowCount;
  144. mColumnCount = columnCount;
  145. }
  146. /// \fn void GridWidget::paintEvent(QPaintEvent *event)
  147. /// \~English
  148. /// \brief This function is automatically invoked each time the widget or
  149. /// its parent receives a repaint signal.
  150. /// \param event received event reference
  151. /// \~Spanish
  152. /// \brief Esta funcion es invocada automaticmente cada ves que el widget o
  153. /// el padre recibe una senal de repintar.
  154. /// \param event referencia a un evento recibido
  155. void GridWidget::paintEvent(QPaintEvent *event)
  156. {
  157. Q_UNUSED(event)
  158. drawGrid(this);
  159. }
  160. /// \fn void GridWidget::mousePressEvent(QMouseEvent * event)
  161. /// \~English
  162. /// \brief When the mouse is clicked on a cell of the grid it gets the x,y
  163. /// coordinates of the mouse and uses them to paint the tool at that
  164. /// location.
  165. /// \param event received event reference
  166. /// \~Spanish
  167. /// \brief Cuando el raton (mouse) is marcada en una celda de la cuadricula
  168. /// obtiene las coordenadas x, y del raton y los usa para pintar la herramienta en
  169. /// ese lugar.
  170. void GridWidget::mousePressEvent(QMouseEvent * event)
  171. {
  172. if (!newStates.empty()) newStates.clear();
  173. if (oldStates.size() == 5) oldStates.pop_front();
  174. oldStates.push_back(mColors);
  175. emit canUndo(true);
  176. emit canRedo(false);
  177. int X = event->x() / mCellSize;
  178. int Y = event->y() / mCellSize;
  179. backColor = mColors[mColumnCount * Y + X];
  180. identifyTool(Tool, X, Y);
  181. emit cellClicked(QPoint(X,Y));
  182. QWidget::mousePressEvent(event);
  183. }
  184. /// \fn void GridWidget::undo()
  185. /// \~English
  186. /// \brief When the undo button is pressed the current state is pushed into
  187. /// the redo vector(newStates) and the last state in the undo vector(oldStates)
  188. /// is painted on the grid.
  189. /// \~Spanish
  190. /// \brief Cuando el boton de deshacer (undo) es presionado el estado actual es empujado
  191. /// al vector(newStates) de rehacer (redo) y el ultimo estado del vector(oldStates) de
  192. /// deshacer (undo) es pintado en la cuadricula
  193. void GridWidget::undo(){
  194. /* When the undo button is pressed the current state is pushed into
  195. * the redo vector and the last state in the undo vector is painted
  196. * on the grid.
  197. * Cuando el boton de deshacer (undo) es presionado el estado corriente es empujado
  198. * al vector de rehacer (redo) y el ultimo estado del vector de deshacer (undo) es
  199. * pintado en la cuadricula
  200. */
  201. if (!oldStates.empty()){
  202. newStates.push_back(mColors);
  203. canRedo(true);
  204. mColors.clear();
  205. mColors = oldStates.back();
  206. oldStates.pop_back();
  207. if (oldStates.empty()) canUndo(false);
  208. repaint();
  209. }
  210. }
  211. /// \fn void GridWidget::redo()
  212. /// \~English
  213. /// \brief When the redo button is pressed the current state is pushed into
  214. /// the undo vector(oldStates) and the last state in the redo vector(newStates)
  215. /// is painted on the grid.
  216. /// \~Spanish Cuando el boton de rehacer (redo) es presionado el estado actual es empujado
  217. /// al vector(oldStates) de deshacer (undo) y el último estado del vector (newStates) de
  218. /// de rehacer (redo) es pintado en la cuadrícula.
  219. ///
  220. void GridWidget::redo(){
  221. if (!newStates.empty()){
  222. oldStates.push_back(mColors);
  223. canUndo(true);
  224. mColors.clear();
  225. mColors = newStates.back();
  226. newStates.pop_back();
  227. if (newStates.empty()) canRedo(false);
  228. repaint();
  229. }
  230. }
  231. /// \fn void GridWidget::switchOn(int x, int y, const QColor &color)
  232. /// \~English
  233. /// \brief Saves the given color and position in the vector
  234. /// that represents the painted cells of the grid
  235. /// \param x coordinate x of the cell in the grid
  236. /// \param y coordinate y of the cell in the grid
  237. /// \param color color to paint cell
  238. /// \~Spanish
  239. /// \brief Guarda el color y la posicion dados en el vector que
  240. /// representa las celdas pintadas en la cuadricula
  241. /// \param x coordenada x de la celda en el cuadricula
  242. /// \param y coordenada y de la celda en la cuadricula
  243. /// \param color color to paint cell
  244. void GridWidget::switchOn(int x, int y, const QColor &color)
  245. {
  246. int index = mColumnCount * y + x;
  247. mColors[index] = color;
  248. }
  249. /// \fn QColor GridWidget::getCellColor(int x, int y) ;
  250. /// \~English
  251. /// \brief Returns the color of the cell in position (x,y)
  252. /// \param x coordinate x of the cell in the grid
  253. /// \param y coordinate y of the cell in the grid
  254. /// \return the color of the cell
  255. /// \~Spanish
  256. /// \brief Devuelve el color de la celda en la posicion (x,y)
  257. /// \param x coordenada x de la celda en el cuadricula
  258. /// \param y coordenada y de la celda en la cuadricula
  259. /// \return el color de la celda
  260. QColor GridWidget::getCellColor(int x, int y){
  261. return mColors[mColumnCount * y + x] ;
  262. }
  263. /// \fn int GridWidget::getGridColumns() ;
  264. /// \~English
  265. /// \brief Returns the number of columns in the grid
  266. /// \return number of columns in the grid
  267. /// \~Spanish
  268. /// \brief Devuelve el numero de columnas en la cuadricula
  269. /// \return el numero de columnas en la cuadricula
  270. int GridWidget::getGridColumns() {
  271. return mColumnCount ;
  272. }
  273. /// \fn int GridWidget::getGridRows() ;
  274. /// \~English
  275. /// \brief Returns the number of rows in the grid
  276. /// \return number of rows in the grid
  277. /// \~Spanish
  278. /// \brief Devuelve el numero de filas en la cuadricula
  279. /// \return el numero de filas en la cuadricula
  280. int GridWidget::getGridRows(){
  281. return mRowCount ;
  282. }
  283. /// \fn void GridWidget::switchOff(int x, int y)
  284. /// \~English
  285. /// \brief Removes the given position from the vector that
  286. /// represents the painted cells of the grid
  287. /// \param x coordinate x of the cell in the grid
  288. /// \param y coordinate y of the cell in the grid
  289. /// \~Spanish
  290. /// \brief Remueve la posicion dada del vector que representa
  291. /// las celdas pintadas en la cuadricula
  292. /// \param x coordenada x de la celda en el cuadricula
  293. /// \param y coordenada y de la celda en la cuadricula
  294. void GridWidget::switchOff(int x, int y)
  295. {
  296. int index = mColumnCount * y + x;
  297. mColors.remove(index);
  298. }
  299. /// \fn void GridWidget::clear()
  300. /// \~English
  301. /// \brief Clears the grid and sets it to its initial state
  302. /// \~Spanish
  303. /// \brief Limpia la cuadricula y la pone en su estado inicial.
  304. void GridWidget::clear()
  305. {
  306. oldStates.push_back(mColors);
  307. mColors.clear();
  308. canRedo(false);
  309. if (!newStates.empty()) newStates.clear();
  310. }
  311. /// \fn void GridWidget::setCellSize(int size)
  312. /// \~English
  313. /// \brief Sets the size of the cells in the grid
  314. /// \param size cell size
  315. /// \~Spanish
  316. /// \brief Ajusta el tamano de las celdas de la cuadricula
  317. /// \param size tamano de la celda
  318. void GridWidget::setCellSize(int size)
  319. {
  320. mCellSize = size;
  321. }
  322. /// \fn void GridWidget::drawGrid(QPaintDevice *device)
  323. /// \~English
  324. /// \brief Function that first sets the size of the GridWidget, then paints the cells
  325. /// with the color selected for the background and finally paints
  326. /// the lines to form the grid.
  327. /// \param device the panel to paint the grid
  328. /// \~Spanish
  329. /// \brief Funcion que primero ajusta el tamano del widget de la cuadricula, luego pinta
  330. /// las celdas con el color seleccionado en el background y finalmente pinta las lineas
  331. /// para formar el grid.
  332. /// \param device el panel para pintar la cuadricula
  333. void GridWidget::drawGrid(QPaintDevice *device)
  334. {
  335. mGridPix = QPixmap(size());
  336. QPainter paint;
  337. paint.begin(device);
  338. mGridPix.fill(background);
  339. paint.drawPixmap(0,0,mGridPix);
  340. paint.setPen(QPen(Qt::lightGray));
  341. //Draws vertical lines
  342. //Dibuja las lineas verticales
  343. for ( int x=0;x<width(); x+=mCellSize )
  344. paint.drawLine(x,rect().top(), x, rect().bottom());
  345. //Draws horizontal lines
  346. // Dibuja las lineas horizontales
  347. for ( int y=0;y<height(); y+=mCellSize )
  348. paint.drawLine(rect().left(),y,rect().right(),y);
  349. // Draw Cells
  350. // Dibuja las celdas
  351. foreach (int index , mColors.keys())
  352. {
  353. int y = qFloor(index/mColumnCount);
  354. int x = index % mColumnCount;
  355. if (mColors[index] != QColor::Invalid){
  356. paint.setBrush(mColors[index]);
  357. paint.drawRect(x*mCellSize, y*mCellSize, mCellSize, mCellSize);
  358. }
  359. }
  360. paint.end();
  361. }
  362. /// \fn void GridWidget::identifyTool(QString tool, int x, int y)
  363. /// \~English
  364. /// \brief This function is called on each mousePressEvent inside the grid.
  365. /// It identifies the way the grid will be painted calling the function of the
  366. /// tool received in the parameters (dot, rowfill, column fill, diagonal, square,
  367. /// triangles and circles).
  368. /// \param tool the tool to be called by the funtion
  369. /// \param x coordinate x of the cell in the grid.
  370. /// \param y coordinate y of the cell in the grid.
  371. /// \~Spanish
  372. /// \brief Esta funcion es llamada en cada evento del mouse presionado dentro
  373. /// de la cuadricula. Identifica la forma en que el grid va a ser pintado llamando
  374. /// la funcion del tool recibido en los parametros (dot, rowfill, column fill, diagonal, square,
  375. /// triangles and circles).
  376. /// \param tool la herramienta a llamar por la funcion
  377. /// \param x coordenada x de la celda en la cuadricula
  378. /// \param y coordenada y de la celde en la cuadricula
  379. void GridWidget::identifyTool(QString tool, int x, int y){
  380. if (tool == "dot") Dot(x, y, frontColor);
  381. else if (tool == "row") RowMajorFill(x, y, backColor, frontColor);
  382. else if (tool == "column") ColMajorFill(x, y, backColor, frontColor);
  383. else if (tool == "diagonal left") DiagonalLeft(x, y, backColor, frontColor);
  384. else if (tool == "diagonal right") DiagonalRight(x, y, backColor, frontColor);
  385. else if (tool == "square") square(x, y, frontColor, ToolSize);
  386. else if (tool == "triangle") triangle(x, y, frontColor, ToolSize);
  387. else if (tool == "circle") circle(x, y, frontColor, ToolSize);
  388. else if (tool == "flood") flood_fill(x,y,frontColor, backColor);
  389. else qDebug() << "Tool Selection Error!";
  390. repaint();
  391. }