]> Shamusworld >> Repos - architektonas/blob - src/base/grid.cpp
In the middle of chasing down MDI not activating bug, renaming of Graphic to
[architektonas] / src / base / grid.cpp
1 // grid.cpp
2 //
3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
9 //
10 // JLH = James L. Hammons <jlhamm@acm.org>
11 //
12 // Who  When        What
13 // ---  ----------  -----------------------------------------------------------
14 // JLH  05/21/2010  Added this text. :-)
15 //
16
17 #include "grid.h"
18
19 #include "drawing.h"
20 #include "graphicview.h"
21 #include "settings.h"
22 #include "units.h"
23 #include "vector.h"
24
25 #warning "!!! Clean out all references to RS_GraphicView here and in header !!!"
26 /**
27  * Constructor.
28  */
29 Grid::Grid(GraphicView * gv): graphicView(gv), pt(NULL), number(0),
30         metaX(NULL), numMetaX(0), metaY(NULL), numMetaY(0)
31 {
32 }
33
34 /**
35  * Destructor.
36  */
37 Grid::~Grid()
38 {
39         if (pt != NULL)
40                 delete[] pt;
41
42         if (metaX != NULL)
43                 delete[] metaX;
44
45         if (metaY != NULL)
46                 delete[] metaY;
47 }
48
49 /**
50  * Updates the grid point array.
51  */
52 void Grid::update()
53 {
54         DEBUG->print("Grid::update");
55
56         if (!graphicView->isGridOn())
57                 return;
58
59         Drawing * drawing = graphicView->GetDrawing();
60
61         // auto scale grid?
62         settings.beginGroup("Appearance");
63         bool scaleGrid = settings.value("ScaleGrid", true).toBool();
64         int minGridSpacing = settings.value("MinGridSpacing", 10).toInt();
65         settings.endGroup();
66
67         // get grid setting
68         Vector userGrid;
69
70         if (drawing != NULL)
71                 userGrid = drawing->getVariableVector("$GRIDUNIT", Vector(-1.0, -1.0));
72
73         // delete old grid:
74         if (pt != NULL)
75         {
76                 delete[] pt;
77                 pt = NULL;
78         }
79
80         if (metaX != NULL)
81         {
82                 delete[] metaX;
83                 metaX = NULL;
84         }
85
86         if (metaY != NULL)
87         {
88                 delete[] metaY;
89                 metaY = NULL;
90         }
91
92         number = 0;
93         numMetaX = 0;
94         numMetaY = 0;
95
96         DEBUG->print("Grid::update: 001");
97
98         // find out unit:
99         RS2::Unit unit = RS2::None;
100         RS2::LinearFormat format = RS2::Decimal;
101
102         if (drawing != NULL)
103         {
104                 unit = drawing->getUnit();
105                 format = drawing->getLinearFormat();
106         }
107
108         Vector gridWidth;
109         Vector metaGridWidth;
110
111         DEBUG->print("Grid::update: 002");
112
113         // init grid spacing:
114         // metric grid:
115         if (Units::isMetric(unit) || unit == RS2::None
116                 || format == RS2::Decimal || format == RS2::Engineering)
117         {
118                 if (userGrid.x > 0.0)
119                         gridWidth.x = userGrid.x;
120                 else
121                         gridWidth.x = 0.000001;
122
123                 if (userGrid.y > 0.0)
124                         gridWidth.y = userGrid.y;
125                 else
126                         gridWidth.y = 0.000001;
127
128                 DEBUG->print("Grid::update: 003");
129
130                 // auto scale grid
131                 if (scaleGrid)
132                 {
133                         while (graphicView->toGuiDX(gridWidth.x) < minGridSpacing)
134                                 gridWidth.x *= 10;
135
136                         while (graphicView->toGuiDY(gridWidth.y) < minGridSpacing)
137                                 gridWidth.y *= 10;
138                 }
139
140                 metaGridWidth.x = gridWidth.x * 10;
141                 metaGridWidth.y = gridWidth.y * 10;
142
143                 DEBUG->print("Grid::update: 004");
144         }
145         // imperial grid:
146         else
147         {
148                 DEBUG->print("Grid::update: 005");
149
150                 if (userGrid.x > 0.0)
151                         gridWidth.x = userGrid.x;
152                 else
153                         gridWidth.x = 1.0 / 1024.0;
154
155                 if (userGrid.y > 0.0)
156                         gridWidth.y = userGrid.y;
157                 else
158                         gridWidth.y = 1.0 / 1024.0;
159
160                 DEBUG->print("Grid::update: 006");
161
162                 if (unit == RS2::Inch)
163                 {
164                         DEBUG->print("Grid::update: 007");
165
166                         // auto scale grid
167                         if (scaleGrid)
168                         {
169                                 while (graphicView->toGuiDX(gridWidth.x) < minGridSpacing)
170                                 {
171                                         if (Math::round(gridWidth.x) >= 36)
172                                         {
173                                                 gridWidth.x *= 2;
174                                         }
175                                         else if (Math::round(gridWidth.x) >= 12)
176                                         {
177                                                 gridWidth.x *= 3;
178                                         }
179                                         else if (Math::round(gridWidth.x) >= 4)
180                                         {
181                                                 gridWidth.x *= 3;
182                                         }
183                                         else if (Math::round(gridWidth.x) >= 1)
184                                         {
185                                                 gridWidth.x *= 2;
186                                         }
187                                         else
188                                         {
189                                                 gridWidth.x*=2;
190                                         }
191                                 }
192
193                                 while (graphicView->toGuiDY(gridWidth.y) < minGridSpacing)
194                                 {
195                                         if (Math::round(gridWidth.y) >= 36)
196                                         {
197                                                 gridWidth.y *= 2;
198                                         }
199                                         else if (Math::round(gridWidth.y) >= 12)
200                                         {
201                                                 gridWidth.y *= 3;
202                                         }
203                                         else if (Math::round(gridWidth.y) >= 4)
204                                         {
205                                                 gridWidth.y *= 3;
206                                         }
207                                         else if (Math::round(gridWidth.y) >= 1)
208                                         {
209                                                 gridWidth.y *= 2;
210                                         }
211                                         else
212                                         {
213                                                 gridWidth.y *= 2;
214                                         }
215                                 }
216                         }
217
218                         DEBUG->print("Grid::update: 008");
219
220                         // metagrid X shows inches..
221                         metaGridWidth.x = 1.0;
222
223                         if (graphicView->toGuiDX(metaGridWidth.x) < minGridSpacing * 2)
224                         {
225                                 // .. or feet
226                                 metaGridWidth.x = 12.0;
227
228                                 // .. or yards
229                                 if (graphicView->toGuiDX(metaGridWidth.x) < minGridSpacing * 2)
230                                 {
231                                         metaGridWidth.x = 36.0;
232
233                                         // .. or miles (not really..)
234                                         //if (graphicView->toGuiDX(metaGridWidth.x)<20) {
235                                         //    metaGridWidth.x = 63360.0;
236                                         //}
237
238                                         // .. or nothing
239                                         if (graphicView->toGuiDX(metaGridWidth.x) < minGridSpacing * 2)
240                                                 metaGridWidth.x = -1.0;
241
242                                 }
243                         }
244
245                         DEBUG->print("Grid::update: 009");
246
247                         // metagrid Y shows inches..
248                         metaGridWidth.y = 1.0;
249
250                         if (graphicView->toGuiDY(metaGridWidth.y) < minGridSpacing * 2)
251                         {
252                                 // .. or feet
253                                 metaGridWidth.y = 12.0;
254
255                                 // .. or yards
256                                 if (graphicView->toGuiDY(metaGridWidth.y) < minGridSpacing * 2)
257                                 {
258                                         metaGridWidth.y = 36.0;
259
260                                         // .. or miles (not really..)
261                                         //if (graphicView->toGuiDY(metaGridWidth.y)<20) {
262                                         //    metaGridWidth.y = 63360.0;
263                                         //}
264
265                                         // .. or nothing
266                                         if (graphicView->toGuiDY(metaGridWidth.y) < minGridSpacing * 2)
267                                         {
268                                                 metaGridWidth.y = -1.0;
269                                         }
270
271                                 }
272                         }
273
274                         DEBUG->print("Grid::update: 010");
275                 }
276                 else
277                 {
278                         DEBUG->print("Grid::update: 011");
279
280                         if (scaleGrid)
281                         {
282                                 while (graphicView->toGuiDX(gridWidth.x) < minGridSpacing)
283                                 {
284                                         gridWidth.x *= 2;
285                                 }
286
287                                 metaGridWidth.x = -1.0;
288
289                                 while (graphicView->toGuiDY(gridWidth.y) < minGridSpacing)
290                                 {
291                                         gridWidth.y *= 2;
292                                 }
293
294                                 metaGridWidth.y = -1.0;
295                         }
296                         DEBUG->print("Grid::update: 012");
297                 }
298                 //gridWidth.y = gridWidth.x;
299                 //metaGridWidth.y = metaGridWidth.x;
300         }
301
302         DEBUG->print("Grid::update: 013");
303
304         // for grid info:
305         spacing = gridWidth.x;
306         metaSpacing = metaGridWidth.x;
307
308         if (gridWidth.x > 1.0e-6 && gridWidth.y > 1.0e-6
309                 && graphicView->toGuiDX(gridWidth.x) > 2
310                 && graphicView->toGuiDY(gridWidth.y) > 2)
311         {
312                 // find grid boundaries
313                 double left = (int)(graphicView->toGraphX(0) / gridWidth.x) * gridWidth.x;
314                 double right = (int)(graphicView->toGraphX(graphicView->getWidth())
315                         / gridWidth.x) * gridWidth.x;
316                 double top = (int)(graphicView->toGraphY(0) / gridWidth.y) * gridWidth.y;
317                 double bottom = (int)(graphicView->toGraphY(graphicView->getHeight())
318                         / gridWidth.y) * gridWidth.y;
319
320                 left -= gridWidth.x;
321                 right += gridWidth.x;
322                 top += gridWidth.y;
323                 bottom -= gridWidth.y;
324
325                 // calculate number of visible grid points
326                 int numberX = (Math::round((right-left) / gridWidth.x) + 1);
327                 int numberY = (Math::round((top-bottom) / gridWidth.y) + 1);
328                 number = numberX * numberY;
329
330                 DEBUG->print("Grid::update: 014");
331
332                 // create grid array:
333                 if (number > 0 && number < 1000000)
334                 {
335                         pt = new Vector[number];
336
337                         int i=0;
338                         for(int y=0; y<numberY; ++y)
339                         {
340                                 for(int x=0; x<numberX; ++x)
341                                 {
342                                         pt[i++] = Vector(left + x * gridWidth.x, bottom + y * gridWidth.y);
343                                 }
344                         }
345                 }
346                 else
347                 {
348                         number = 0;
349                         pt = NULL;
350                 }
351
352                 DEBUG->print("Grid::update: 015");
353         }
354
355         // find meta grid boundaries
356         if (metaGridWidth.x > 1.0e-6 && metaGridWidth.y > 1.0e-6
357                 && graphicView->toGuiDX(metaGridWidth.x) > 2
358                 && graphicView->toGuiDY(metaGridWidth.y) > 2)
359         {
360                 double mleft = (int)(graphicView->toGraphX(0)
361                         / metaGridWidth.x) * metaGridWidth.x;
362                 double mright = (int)(graphicView->toGraphX(graphicView->getWidth())
363                         / metaGridWidth.x) * metaGridWidth.x;
364                 double mtop = (int)(graphicView->toGraphY(0)
365                         / metaGridWidth.y) * metaGridWidth.y;
366                 double mbottom = (int)(graphicView->toGraphY(graphicView->getHeight())
367                         / metaGridWidth.y) * metaGridWidth.y;
368
369                 mleft -= metaGridWidth.x;
370                 mright += metaGridWidth.x;
371                 mtop += metaGridWidth.y;
372                 mbottom -= metaGridWidth.y;
373
374                 // calculate number of visible meta grid lines:
375                 numMetaX = (Math::round((mright - mleft) / metaGridWidth.x) + 1);
376                 numMetaY = (Math::round((mtop - mbottom) / metaGridWidth.y) + 1);
377
378                 if (numMetaX > 0 && numMetaY > 0)
379                 {
380                         // create meta grid arrays:
381                         metaX = new double[numMetaX];
382                         metaY = new double[numMetaY];
383
384                         int i = 0;
385
386                         for(int x=0; x<numMetaX; ++x)
387                                 metaX[i++] = mleft + x * metaGridWidth.x;
388
389                         i = 0;
390
391                         for(int y=0; y<numMetaY; ++y)
392                                 metaY[i++] = mbottom + y * metaGridWidth.y;
393                 }
394                 else
395                 {
396                         numMetaX = 0;
397                         metaX = NULL;
398                         numMetaY = 0;
399                         metaY = NULL;
400                 }
401         }
402
403         DEBUG->print("Grid::update: OK");
404 }
405
406 /**
407  * @return Array of all visible grid points.
408  */
409 Vector * Grid::getPoints()
410 {
411         return pt;
412 }
413
414 /**
415  * @return Number of visible grid points.
416  */
417 int Grid::count()
418 {
419         return number;
420 }
421
422 /**
423  * @return Grid info for status widget.
424  */
425 QString Grid::getInfo()
426 {
427         return QString("%1 / %2").arg(spacing).arg(metaSpacing);
428 }
429
430 /**
431  * @return Meta grid positions in X.
432  */
433 double * Grid::getMetaX()
434 {
435         return metaX;
436 }
437
438 /**
439  * @return Number of visible meta grid lines in X.
440  */
441 int Grid::countMetaX()
442 {
443         return numMetaX;
444 }
445
446 /**
447 * @return Meta grid positions in Y.
448 */
449 double * Grid::getMetaY()
450 {
451         return metaY;
452 }
453
454 /**
455 * @return Number of visible meta grid lines in Y.
456 */
457 int Grid::countMetaY()
458 {
459         return numMetaY;
460 }