1 /* BurrTools
2 *
3 * BurrTools is the legal property of its developers, whose
4 * names are listed in the COPYRIGHT file, which is included
5 * within the source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21 #include "statuswindow.h"
22 #include "piececolor.h"
23
24 #include "../lib/voxel.h"
25 #include "../lib/puzzle.h"
26 #include "../lib/problem.h"
27 #include "../lib/millable.h"
28 #include "../lib/voxeltable.h"
29
30 #include <FL/Fl.H>
31
32 class LFl_Line : public Fl_Box, public layoutable_c {
33
34 private:
35
36 int thickness;
37
38 public:
39
LFl_Line(int x,int y,int w,int h,int thick=1,Fl_Color col=FL_BLACK)40 LFl_Line(int x, int y, int w, int h, int thick = 1, Fl_Color col = FL_BLACK) : Fl_Box(0, 0, 0, 0), layoutable_c(x, y, w, h), thickness(thick) {
41 color(col);
42 box(FL_FLAT_BOX);
43 }
44
getMinSize(int * width,int * height) const45 virtual void getMinSize(int *width, int *height) const {
46 *width = thickness;
47 *height = thickness;
48 }
49 };
50
cb_Close_stub(Fl_Widget *,void * v)51 static void cb_Close_stub(Fl_Widget*, void* v) { ((statusWindow_c*)v)->hide(); }
cb_RemoveSelected_stub(Fl_Widget *,void * v)52 static void cb_RemoveSelected_stub(Fl_Widget*, void* v) { ((statusWindow_c*)v)->cb_removeSelected(); }
53
54 class StatusProgress : public LFl_Double_Window {
55
56 private:
57
58 LFl_Progress * p;
59
60 public:
61
StatusProgress(void)62 StatusProgress(void) : LFl_Double_Window(false) {
63
64 label("Progress");
65
66 (new LFl_Box("Calculating Status information.\n"
67 "This might take some time...", 0, 0, 1, 1))->pitch(3);
68
69 p = new LFl_Progress(0, 1, 1, 1);
70 p->minimum(0);
71 p->maximum(1);
72 p->selection_color((Fl_Color)4);
73 p->pitch(3);
74
75 LFl_Button * btn = new LFl_Button("Cancel", 0, 2, 1, 1);
76 btn->pitch(3);
77 btn->callback(cb_Close_stub, this);
78
79 end();
80
81 set_modal();
82 }
83
setProgress(float value)84 void setProgress(float value) {
85 p->value(value);
86 }
87 };
88
cb_removeSelected(void)89 void statusWindow_c::cb_removeSelected(void) {
90
91 bt_assert(selection.size() <= puz->shapeNumber());
92
93 /* we have to go up from the bottom as otherwise the indixes may shift
94 *
95 * we hafe to use the selection size as starting point as
96 * the user may have pressed cancel during calculation leaving us
97 * with an incomplete list
98 */
99 for (unsigned int s = selection.size(); s > 0; s--)
100 {
101 if (selection[s-1]->value())
102 {
103 for (unsigned int i = 0; i < puz->problemNumber(); i++)
104 if (puz->getProblem(i)->usesShape(s-1))
105 puz->getProblem(i)->removeAllSolutions();
106
107 puz->removeShape(s-1);
108 }
109 }
110
111 again = true;
112 hide();
113 }
114
statusWindow_c(puzzle_c * p)115 statusWindow_c::statusWindow_c(puzzle_c * p) : LFl_Double_Window(true), puz(p), again(false) {
116
117 StatusProgress * stp = new StatusProgress;
118 stp->show();
119
120 begin();
121
122 char tmp[200];
123
124 label("Shape Information");
125
126 unsigned int lines = p->shapeNumber();
127 unsigned int head = 3;
128
129 layouter_c * fr = new layouter_c(0, 0, 1, 1);
130 fr->pitch(7);
131
132 (new LFl_Scroll(0, 0, 1, 1))->type(Fl_Scroll::VERTICAL_ALWAYS);
133
134 unsigned int cols = 27;
135
136 // 2 more columns for notchable and millable
137 if (p->getGridType()->getType() == gridType_c::GT_BRICKS)
138 cols += 4;
139
140 voxelTablePuzzle_c shapeTab(p);
141
142 for (unsigned int s = 0; s < p->shapeNumber(); s++) {
143
144 LFl_Box * b;
145
146 if (s & 1) {
147 b = new LFl_Box("", 0, s+head, cols, 1);
148 b->color(fl_rgb_color(150, 150, 150));
149 b->box(FL_FLAT_BOX);
150 }
151
152 const voxel_c * v = p->getShape(s);
153
154 unsigned int col = 0;
155
156 selection.push_back(new LFl_Check_Button(" ", col, s+head));
157 col+=2;
158
159 if (v->getName().length())
160 snprintf(tmp, 200, "S%i - %s", s+1, v->getName().c_str());
161 else
162 snprintf(tmp, 200, "S%i", s+1);
163
164 b = new LFl_Box("", col, s+head);
165 b->copy_label(tmp);
166 b->color(fltkPieceColor(s));
167 b->labelcolor(contrastPieceColor(s));
168 b->box(FL_FLAT_BOX);
169 col += 2;
170
171 snprintf(tmp, 200, "%i", v->countState(voxel_c::VX_FILLED));
172 (new LFl_Box("", col, s+head))->copy_label(tmp);
173 col += 2;
174
175 snprintf(tmp, 200, "%i", v->countState(voxel_c::VX_VARIABLE));
176 (new LFl_Box("", col, s+head))->copy_label(tmp);
177 col += 2;
178
179 snprintf(tmp, 200, "%i", v->countState(voxel_c::VX_VARIABLE) + v->countState(voxel_c::VX_FILLED));
180 (new LFl_Box("", col, s+head))->copy_label(tmp);
181 col += 2;
182 Fl::wait(0);
183
184 unsigned int shapeIdx;
185 unsigned char shapeTrans;
186 bool shapeKnown = shapeTab.getSpace(v, &shapeIdx, &shapeTrans, voxelTable_c::PAR_MIRROR);
187
188 if (shapeKnown)
189 {
190 snprintf(tmp, 200, "%i", shapeIdx+1);
191 b = new LFl_Box("", col, s+head);
192 b->copy_label(tmp);
193 b->color(fltkPieceColor(shapeIdx));
194 b->labelcolor(contrastPieceColor(shapeIdx));
195 b->box(FL_FLAT_BOX);
196 }
197 col += 2;
198 Fl::wait(0);
199
200 shapeKnown = shapeTab.getSpace(v, &shapeIdx, &shapeTrans, 0);
201
202 if (shapeKnown)
203 {
204 snprintf(tmp, 200, "%i", shapeIdx+1);
205 b = new LFl_Box("", col, s+head);
206 b->copy_label(tmp);
207 b->color(fltkPieceColor(shapeIdx));
208 b->labelcolor(contrastPieceColor(shapeIdx));
209 b->box(FL_FLAT_BOX);
210 }
211 col += 2;
212 Fl::wait(0);
213
214 shapeKnown = shapeTab.getSpace(v, &shapeIdx, &shapeTrans, voxelTable_c::PAR_COLOUR);
215
216 if (shapeKnown && shapeTrans < p->getGridType()->getSymmetries()->getNumTransformations())
217 {
218 snprintf(tmp, 200, "%i", shapeIdx+1);
219 b = new LFl_Box("", col, s+head);
220 b->copy_label(tmp);
221 b->color(fltkPieceColor(shapeIdx));
222 b->labelcolor(contrastPieceColor(shapeIdx));
223 b->box(FL_FLAT_BOX);
224 }
225 col +=2 ;
226 Fl::wait(0);
227
228 if (v->connected(0, true, 0)) {
229 new LFl_Box("X", col, s+head);
230 } else {
231 b = new LFl_Box("", col, s+head);
232 b->color(fl_rgb_color(pieceColorRi(s), pieceColorGi(s), pieceColorBi(s)));
233 b->box(FL_FLAT_BOX);
234 }
235 col += 2;
236 Fl::wait(0);
237
238 if (v->connected(1, true, 0)) {
239 new LFl_Box("X", col, s+head);
240 } else {
241 b = new LFl_Box("", col, s+head);
242 b->color(fl_rgb_color(pieceColorRi(s), pieceColorGi(s), pieceColorBi(s)));
243 b->box(FL_FLAT_BOX);
244 }
245 col += 2;
246 Fl::wait(0);
247
248 if (v->connected(2, true, 0)) {
249 new LFl_Box("X", col, s+head);
250 } else {
251 b = new LFl_Box("", col, s+head);
252 b->color(fl_rgb_color(pieceColorRi(s), pieceColorGi(s), pieceColorBi(s)));
253 b->box(FL_FLAT_BOX);
254 }
255 col += 2;
256 Fl::wait(0);
257
258 if (!v->connected(0, false, 0, false)) {
259 b = new LFl_Box("X", col, s+head);
260 b->color(fltkPieceColor(s));
261 b->labelcolor(contrastPieceColor(s));
262 b->box(FL_FLAT_BOX);
263 }
264 col += 2;
265 Fl::wait(0);
266
267 if (!v->connected(0, false, 0)) {
268 b = new LFl_Box("X", col, s+head);
269 b->color(fltkPieceColor(s));
270 b->labelcolor(contrastPieceColor(s));
271 b->box(FL_FLAT_BOX);
272 }
273 col += 2;
274 Fl::wait(0);
275
276 if (p->getGridType()->getType() == gridType_c::GT_BRICKS) {
277 if (isNotchable(v))
278 b = new LFl_Box("X", col, s+head);
279
280 col += 2;
281
282 if (isMillable(v))
283 b = new LFl_Box("X", col, s+head);
284
285 col += 2;
286 }
287
288 if (!p->getGridType()->getSymmetries()->symmetryKnown(v)) {
289 b = new LFl_Box("---", col, s+head);
290 b->color(fltkPieceColor(s));
291 b->labelcolor(contrastPieceColor(s));
292 b->box(FL_FLAT_BOX);
293 } else {
294 snprintf(tmp, 200, "%i", p->getGridType()->getSymmetries()->calculateSymmetry(v));
295 b = new LFl_Box("", col, s+head);
296 b->copy_label(tmp);
297 b->box(FL_NO_BOX);
298 }
299 col += 2;
300
301 stp->setProgress(1.0*s/p->shapeNumber());
302 Fl::wait(0);
303 if (!stp->visible())
304 break;
305
306 shapeTab.addSpace(s, voxelTable_c::PAR_MIRROR);
307 shapeTab.addSpace(s, voxelTable_c::PAR_MIRROR | voxelTable_c::PAR_COLOUR);
308 }
309
310 stp->hide();
311 delete stp;
312
313 unsigned int col = 1;
314
315 new LFl_Line(col++, 0, 1, lines+head, 2);
316
317 (new LFl_Box("Shape", col++, 0))->pitch(2);
318 new LFl_Line(col++, 0, 1, lines+head, 2);
319
320 (new LFl_Box("Units", col, 0, 5))->pitch(2);
321 (new LFl_Box("Normal", col++, 1))->pitch(2);
322 new LFl_Line(col++, 1, 1, lines+head-1, 1);
323 (new LFl_Box("Variable", col++, 1))->pitch(2);
324 new LFl_Line(col++, 1, 1, lines+head-1, 1);
325 (new LFl_Box("Total", col++, 1))->pitch(2);
326 new LFl_Line(col++, 0, 1, lines+head, 2);
327
328 (new LFl_Box("Identical", col, 0, 5))->pitch(2);
329 (new LFl_Box("Mirror", col++, 1))->pitch(2);
330 new LFl_Line(col++, 1, 1, lines+head-1, 1);
331 (new LFl_Box("Shape", col++, 1))->pitch(2);
332 new LFl_Line(col++, 1, 1, lines+head-1, 1);
333 (new LFl_Box("Complete", col++, 1))->pitch(2);
334 new LFl_Line(col++, 0, 1, lines+head, 2);
335
336 (new LFl_Box("Connectivity", col, 0, 5))->pitch(2);
337 (new LFl_Box("Face", col++, 1))->pitch(2);
338 new LFl_Line(col++, 1, 1, lines+head-1, 1);
339 (new LFl_Box("Edge", col++, 1))->pitch(2);
340 new LFl_Line(col++, 1, 1, lines+head-1, 1);
341 (new LFl_Box("Corner", col++, 1))->pitch(2);
342 new LFl_Line(col++, 0, 1, lines+head, 2);
343
344 (new LFl_Box("Holes", col, 0, 3))->pitch(2);
345 (new LFl_Box("2D", col++, 1))->pitch(2);
346 new LFl_Line(col++, 1, 1, lines+head-1, 1);
347 (new LFl_Box("3D", col++, 1))->pitch(2);
348 new LFl_Line(col++, 0, 1, lines+head, 2);
349
350 if (p->getGridType()->getType() == gridType_c::GT_BRICKS) {
351
352 (new LFl_Box("Tools", col, 0, 3))->pitch(2);
353 (new LFl_Box("Notch", col++, 1))->pitch(2);
354 new LFl_Line(col++, 1, 1, lines+head-1, 1);
355 (new LFl_Box("Mill", col++, 1))->pitch(2);
356 new LFl_Line(col++, 0, 1, lines+head, 2);
357 }
358
359 (new LFl_Box("Sym", col++, 0, 1))->pitch(2);
360
361 new LFl_Line(0, 2, cols, 1, 2);
362
363 fr->end();
364 fr->setMinimumSize(10, 200);
365 fr->weight(1, 1);
366
367 fr = new layouter_c(0, 1, 1, 1);
368 fr->pitch(7);
369
370 LFl_Button * btn = new LFl_Button("Close", 0, 1);
371 btn->callback(cb_Close_stub, this);
372 btn->weight(1, 0);
373
374 (new LFl_Box(1, 1))->setMinimumSize(5, 0);
375
376 btn = new LFl_Button("Remove selected", 2, 1);
377 btn->callback(cb_RemoveSelected_stub, this);
378 btn->weight(1, 0);
379
380 fr->end();
381
382
383 set_modal();
384 }
385