1 /*
2 Copyright (C) 2019-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5
6 /*
7 WARNING: This file was generated by the dkct program (see
8 http://dktools.sourceforge.net/ for details).
9 Changes you make here will be lost if dkct is run again!
10 You should modify the original source and run dkct on it.
11 Original source: WxdkdrawFrameTools.cpt
12 */
13
14 /** @file WxdkdrawFrameTools.cpp The WxdkdrawFrameTools module.
15 */
16
17
18 #include <wxdkdraw/wxdkdraw.h>
19
20 #ifndef WXDKDRAWAPPH_INCLUDED
21 #include <wxdkdraw/WxdkdrawApp.h>
22 #endif
23 #ifndef WXDKDRAWFRAME_H_INCLUDED
24 #include <wxdkdraw/WxdkdrawFrame.h>
25 #endif
26
27
28
29
30
31
32 /* IMPORTANT: Number and order of entries here must match the order in the
33 m_iv member array and the iv_keys array below!
34 */
35 /** Default values for the integer array.
36 */
37 static const int default_values[] = {
38 /* IVI_BORDER_RED */ 236 ,
39 /* IVI_BORDER_GREEN */ 236 ,
40 /* IVI_BORDER_BLUE */ 255 ,
41 /* IVI_BG_RED */ 242 ,
42 /* IVI_BG_GREEN */ 242 ,
43 /* IVI_BG_BLUE */ 242 ,
44 /* IVI_GRID_RED */ 202 ,
45 /* IVI_GRID_GREEN */ 202 ,
46 /* IVI_GRID_BLUE */ 230 ,
47 /* IVI_PH_RED */ 255 ,
48 /* IVI_PH_GREEN */ 214 ,
49 /* IVI_PH_BLUE */ 0 ,
50 /* IVI_M_COPY_RED */ 0 ,
51 /* IVI_M_COPY_GREEN */ 143 ,
52 /* IVI_M_COPY_BLUE */ 0 ,
53 /* IVI_M_MOVE_RED */ 0 ,
54 /* IVI_M_MOVE_GREEN */ 0 ,
55 /* IVI_M_MOVE_BLUE */ 204 ,
56 /* IVI_M_DEL_RED */ 204 ,
57 /* IVI_M_DEL_GREEN */ 0 ,
58 /* IVI_M_DEL_BLUE */ 0 ,
59 /* IVI_M_GROUP_RED */ 0 ,
60 /* IVI_M_GROUP_GREEN */ 0 ,
61 /* IVI_M_GROUP_BLUE */ 0 ,
62 /* IVI_MISSIMG_RED */ 204 ,
63 /* IVI_MISSIMG_GREEN */ 0 ,
64 /* IVI_MISSIMG_BLUE */ 0 ,
65 /* IVI_XS_SUBSEGS */ 4 ,
66 /* IVI_FONT_EXACT */ 0 ,
67 /* IVI_DOT_DIAMETER_FILLED */ 8 ,
68 /* IVI_DOT_DIAMETER_WHITE */ 10 ,
69 /* IVI_ARROWHEAD_LENGTH */ 16 ,
70 /* IVI_ARROWHEAD_WIDTH */ 8 ,
71 /* IVI_STYLE_VALUE */ 4 ,
72 /* IVI_MITER_LIMIT */ 8 ,
73 /* IVI_REDUCE_MARKUP_POINTS */ 1 ,
74 /* IVI_D_LAYER */ 0 ,
75 /* IVI_D_LINE_COL_RED */ 0 ,
76 /* IVI_D_LINE_COL_GREEN */ 0 ,
77 /* IVI_D_LINE_COL_BLUE */ 0 ,
78 /* IVI_D_LINEWIDTH */ 2 ,
79 /* IVI_D_LINESTYLE */ WXD_LS_SOLID ,
80 /* IVI_D_STYLE_VALUE */ 4 ,
81 /* IVI_D_JOIN_STYLE */ WXD_LJ_MITERED ,
82 /* IVI_D_MITER_LIMIT */ 8 ,
83 /* IVI_D_CAP_STYLE */ WXD_LC_BUTTED ,
84 /* IVI_D_AHF_TYPE */ 0 ,
85 /* IVI_D_AHF_LENGTH */ 16 ,
86 /* IVI_D_AHF_WIDTH */ 8 ,
87 /* IVI_D_AHB_TYPE */ 0 ,
88 /* IVI_D_AHB_LENGTH */ 16 ,
89 /* IVI_D_AHB_WIDTH */ 8 ,
90 /* IVI_D_FILL_COL_RED */ 255 ,
91 /* IVI_D_FILL_COL_GREEN */ 255 ,
92 /* IVI_D_FILL_COL_BLUE */ 255 ,
93 /* IVI_D_FILL_STYLE */ WXD_FS_NONE ,
94 /* IVI_D_TEXT_LATEX */ 1 ,
95 /* IVI_D_TEXT_ALIGN */ WXD_TEXT_ALIGN_LEFT ,
96 /* IVI_D_TEXT_FONT */ 0 ,
97 /* IVI_D_TEXT_SIZE */ 12 ,
98 /* IVI_C_GRID */ 1 ,
99 /* IVI_C_PH */ 0 ,
100 /* IVI_C_COR_POSITION */ 1 ,
101 };
102 /* IMPORTANT: Number and order of entries here must match the order in the
103 m_iv member array and the iv_keys array below!
104 */
105
106
107
108 /* IMPORTANT: Number and order of entries here must match the
109 order in the default_values and m_iv arrays!
110 */
111 /** Keys to save and restore the int values.
112 */
113 static const wxChar * const iv_keys[] = {
114 /* 0 */
115 wxT("colour.border.red"),
116
117 /* 1 */
118 wxT("colour.border.green"),
119
120 /* 2 */
121 wxT("colour.border.blue"),
122
123 /* 3 */
124 wxT("colour.background.red"),
125
126 /* 4 */
127 wxT("colour.background.blue"),
128
129 /* 5 */
130 wxT("colour.background.green"),
131
132 /* 6 */
133 wxT("colour.grid.red"),
134
135 /* 7 */
136 wxT("colour.grid.green"),
137
138 /* 8 */
139 wxT("colour.grid.blue"),
140
141 /* 9 */
142 wxT("colour.placement-help.red"),
143
144 /* 10 */
145 wxT("colour.placement-help.green"),
146
147 /* 11 */
148 wxT("colour.placement-help.blue"),
149
150 /* 12 */
151 wxT("colour.modify.copy.red"),
152
153 /* 13 */
154 wxT("colour.modify.copy.green"),
155
156 /* 14 */
157 wxT("colour.modify.copy.blue"),
158
159 /* 15 */
160 wxT("colour.modify.move.red"),
161
162 /* 16 */
163 wxT("colour.modify.move.green"),
164
165 /* 17 */
166 wxT("colour.modify.move.blue"),
167
168 /* 18 */
169 wxT("colour.modify.delete.red"),
170
171 /* 19 */
172 wxT("colour.modify.delete.green"),
173
174 /* 20 */
175 wxT("colour.modify.delete.blue"),
176
177 /* 21 */
178 wxT("colour.modify.group.red"),
179
180 /* 22 */
181 wxT("colour.modify.group.green"),
182
183 /* 23 */
184 wxT("colour.modify.group.blue"),
185
186 /* 24 */
187 wxT("colour.markup.missing-image.red"),
188
189 /* 25 */
190 wxT("colour.markup.missing-image.green"),
191
192 /* 26 */
193 wxT("colour.markup.missing-image.blue"),
194
195 /* 27 */
196 wxT("config.x-spline.sub-segments"),
197
198 /* 28 */
199 wxT("config.text.font.exact"),
200
201 /* 29 */
202 wxT("config.dot.filled.diameter"),
203
204 /* 30 */
205 wxT("config.dot.white.diameter"),
206
207 /* 31 */
208 wxT("config.arrowhead.length"),
209
210 /* 32 */
211 wxT("config.arrowhead.width"),
212
213 /* 33 */
214 wxT("config.line.dash.length"),
215
216 /* 34 */
217 wxT("config.join.miter-limit"),
218
219 /* 35 */
220 wxT("config.markup-point.reduce-size"),
221
222 /* 36 */
223 wxT("default.layer"),
224
225 /* 37 */
226 wxT("default.colour.stroke.red"),
227
228 /* 38 */
229 wxT("default.colour.stroke.green"),
230
231 /* 39 */
232 wxT("default.colour.stroke.blue"),
233
234 /* 40 */
235 wxT("default.line.width"),
236
237 /* 41 */
238 wxT("default.line.style"),
239
240 /* 42 */
241 wxT("default.line.dash.length"),
242
243 /* 43 */
244 wxT("default.join.style"),
245
246 /* 44 */
247 wxT("default.join.miter-limit"),
248
249 /* 45 */
250 wxT("default.cap.style"),
251
252 /* 46 */
253 wxT("default.arrowhead.forward.type"),
254
255 /* 47 */
256 wxT("default.arrowhead.forward.length"),
257
258 /* 48 */
259 wxT("default.arrowhead.forward.width"),
260
261 /* 49 */
262 wxT("default.arrowhead.backward.type"),
263
264 /* 50 */
265 wxT("default.arrowhead.backward.length"),
266
267 /* 51 */
268 wxT("default.arrowhead.backward.width"),
269
270 /* 52 */
271 wxT("default.colour.fill.red"),
272
273 /* 53 */
274 wxT("default.colour.fill.green"),
275
276 /* 54 */
277 wxT("default.colour.fill.blue"),
278
279 /* 55 */
280 wxT("default.fill.style"),
281
282 /* 56 */
283 wxT("default.text.latex"),
284
285 /* 57 */
286 wxT("default.text.align"),
287
288 /* 58 */
289 wxT("default.text.font"),
290
291 /* 59 */
292 wxT("default.text.size"),
293
294 /* 60 */
295 wxT("config.grid.enable"),
296
297 /* 61 */
298 wxT("config.placement-help.enable"),
299
300 /* 62 */
301 wxT("config.zoom-out.correct-position"),
302
303 NULL
304
305 };
306 /* IMPORTANT: Number and order of entries here must match the
307 order in the default_values and m_iv arrays!
308 */
309
310
311
312 /** Correct given int value v to a range specified by minimum and maximum.
313 @param min Range minimum.
314 @param max Range maximum.
315 @param v Value to correct if necessary.
316 @return Corrected value.
317 */
318 static
319 int
i_to_range(int min,int max,int v)320 i_to_range(int min, int max, int v)
321 {
322 if (min > v) { v = min; }
323 if (max < v) { v = max; }
324 return v;
325 }
326
327
328
329 /** Correct given int value v to an unsigned range specified by minimum
330 and maximum.
331 @param min Range minimum.
332 @param max Range maximum.
333 @param v Value to correct if necessary.
334 @return Corrected value.
335 */
336 static
337 unsigned
u_to_range(unsigned min,unsigned max,int v)338 u_to_range(unsigned min, unsigned max, int v)
339 {
340 unsigned back;
341
342 if (0 <= v) {
343 back = (unsigned)v;
344 }
345 else {
346 back = 0U;
347 }
348 if (min > back) { back = min; }
349 if (max < back) { back = max; }
350 return back;
351 }
352
353
354
355 void
DefaultStyleToArray(void)356 WxdkdrawFrame::DefaultStyleToArray(void)
357 {
358
359 m_iv[IVI_D_LAYER] = m_oStyle.lay;
360 m_iv[IVI_D_LINE_COL_RED] = m_oStyle.sc[0] ;
361 m_iv[IVI_D_LINE_COL_GREEN] = m_oStyle.sc[1] ;
362 m_iv[IVI_D_LINE_COL_BLUE] = m_oStyle.sc[2] ;
363 m_iv[IVI_D_LINEWIDTH] = m_oStyle.lw ;
364 m_iv[IVI_D_LINESTYLE] = m_oStyle.ls ;
365 m_iv[IVI_D_STYLE_VALUE] = m_oStyle.sl ;
366 m_iv[IVI_D_JOIN_STYLE] = m_oStyle.js ;
367 m_iv[IVI_D_MITER_LIMIT] = m_oStyle.ml ;
368 m_iv[IVI_D_CAP_STYLE] = m_oStyle.cs ;
369 m_iv[IVI_D_AHF_TYPE] = m_oStyle.aft ;
370 m_iv[IVI_D_AHF_LENGTH] = m_oStyle.afl ;
371 m_iv[IVI_D_AHF_WIDTH] = m_oStyle.afw ;
372 m_iv[IVI_D_AHB_TYPE] = m_oStyle.abt ;
373 m_iv[IVI_D_AHB_LENGTH] = m_oStyle.abl ;
374 m_iv[IVI_D_AHB_WIDTH] = m_oStyle.abw ;
375 m_iv[IVI_D_FILL_COL_RED] = m_oStyle.fc[0] ;
376 m_iv[IVI_D_FILL_COL_GREEN] = m_oStyle.fc[1] ;
377 m_iv[IVI_D_FILL_COL_BLUE] = m_oStyle.fc[2] ;
378 m_iv[IVI_D_FILL_STYLE] = m_oStyle.fs ;
379 m_iv[IVI_D_TEXT_LATEX] = m_oStyle.det.t.fl ;
380 m_iv[IVI_D_TEXT_ALIGN] = m_oStyle.det.t.al ;
381 m_iv[IVI_D_TEXT_FONT] = m_oStyle.det.t.find ;
382 m_iv[IVI_D_TEXT_SIZE] = m_oStyle.det.t.fsz ;
383
384 }
385
386
387
388 void
DefaultStyleFromArray(void)389 WxdkdrawFrame::DefaultStyleFromArray(void)
390 {
391
392 m_oStyle.lay = (int16_t)i_to_range(
393 DK4_I16_MIN, DK4_I16_MAX, m_iv[IVI_D_LAYER]
394 );
395 m_oStyle.sc[0] = (uint8_t)u_to_range(
396 0U, 255U, m_iv[IVI_D_LINE_COL_RED]
397 );
398 m_oStyle.sc[1] = (uint8_t)u_to_range(
399 0U, 255U, m_iv[IVI_D_LINE_COL_GREEN]
400 );
401 m_oStyle.sc[2] = (uint8_t)u_to_range(
402 0U, 255U, m_iv[IVI_D_LINE_COL_BLUE]
403 );
404 m_oStyle.lw = (uint16_t)u_to_range(
405 0U, DK4_U16_MAX, m_iv[IVI_D_LINEWIDTH]
406 );
407 m_oStyle.ls = (uint8_t)u_to_range(
408 WXD_LS_SOLID, WXD_LS_DASH_DOT_DOT_DOT, m_iv[IVI_D_LINESTYLE]
409 );
410 m_oStyle.sl = (uint8_t)u_to_range(
411 1U, 255U, m_iv[IVI_D_STYLE_VALUE]
412 );
413 m_oStyle.js = (uint8_t)u_to_range(
414 WXD_LJ_MITERED, WXD_LJ_BEVELED, m_iv[IVI_D_JOIN_STYLE]
415 );
416 m_oStyle.ml = (uint8_t)u_to_range(
417 1U, 255U, m_iv[IVI_D_MITER_LIMIT]
418 );
419 m_oStyle.cs = (uint8_t)u_to_range(
420 WXD_LC_BUTTED, WXD_LC_PROJECTING, m_iv[IVI_D_CAP_STYLE]
421 );
422 m_oStyle.aft = (uint8_t)u_to_range(
423 0U, 29U, m_iv[IVI_D_AHF_TYPE]
424 );
425 m_oStyle.afl = (uint8_t)u_to_range(
426 2U, 255U, m_iv[IVI_D_AHF_LENGTH]
427 );
428 m_oStyle.afw = (uint8_t)u_to_range(
429 2U, 255U, m_iv[IVI_D_AHF_WIDTH]
430 );
431 m_oStyle.abt = (uint8_t)u_to_range(
432 0U, 29U, m_iv[IVI_D_AHB_TYPE]
433 );
434 m_oStyle.abl = (uint8_t)u_to_range(
435 2U, 255U, m_iv[IVI_D_AHB_LENGTH]
436 );
437 m_oStyle.abw = (uint8_t)u_to_range(
438 2U, 255U, m_iv[IVI_D_AHB_WIDTH]
439 );
440 m_oStyle.fc[0] = (uint8_t)u_to_range(
441 0U, 255U, m_iv[IVI_D_FILL_COL_RED]
442 );
443 m_oStyle.fc[1] = (uint8_t)u_to_range(
444 0U, 255U, m_iv[IVI_D_FILL_COL_GREEN]
445 );
446 m_oStyle.fc[2] = (uint8_t)u_to_range(
447 0U, 255U, m_iv[IVI_D_FILL_COL_BLUE]
448 );
449 m_oStyle.fs = (uint8_t)u_to_range(
450 WXD_FS_NONE, WXD_FS_VERTICAL_TIRES, m_iv[IVI_D_FILL_STYLE]
451 );
452 m_oStyle.det.t.fl = (uint8_t)u_to_range(
453 0U, 1U, m_iv[IVI_D_TEXT_LATEX]
454 );
455 m_oStyle.det.t.al = (uint8_t)u_to_range(
456 WXD_TA_LEFT, WXD_TA_RIGHT, m_iv[IVI_D_TEXT_ALIGN]
457 );
458 m_oStyle.det.t.find = (uint8_t)u_to_range(
459 0U, 34U, m_iv[IVI_D_TEXT_FONT]
460 );
461 m_oStyle.det.t.fsz = (uint16_t)u_to_range(
462 1U, DK4_U16_MAX, m_iv[IVI_D_TEXT_SIZE]
463 );
464
465 }
466
467
468
469 void
LoadDefaults(void)470 WxdkdrawFrame::LoadDefaults(void)
471 {
472 DK4_MEMCPY(m_iv,default_values,((size_t)(IVI_MAX)*sizeof(int)));
473 }
474
475
476
477 void
LoadConfiguration(void)478 WxdkdrawFrame::LoadConfiguration(void)
479 {
480 LoadDefaults();
481 DefaultStyleToArray();
482 pAppHelp->GetMultiple(iv_keys ,m_iv, IVI_MAX);
483 DefaultStyleFromArray();
484 cbGridOnOff->SetValue((0 != m_iv[IVI_C_GRID]));
485 cbPH->SetValue((0 != m_iv[IVI_C_PH]));
486 }
487
488
489
490 void
SaveConfiguration(void)491 WxdkdrawFrame::SaveConfiguration(void)
492 {
493 DefaultStyleToArray();
494 m_iv[IVI_C_GRID] = ((cbGridOnOff->GetValue()) ? 1 : 0);
495 m_iv[IVI_C_PH] = ((cbPH->GetValue()) ? 1 : 0);
496 pAppHelp->SetMultiple(iv_keys ,m_iv, IVI_MAX);
497 }
498
499
500
501 void
ResetConfiguration(void)502 WxdkdrawFrame::ResetConfiguration(void)
503 {
504 LoadDefaults();
505 wxdobj_obj_init(&m_oStyle, WXD_OT_TEXT, NULL);
506 }
507
508
509
510 void
ColorModify(size_t ivi,int rdl)511 WxdkdrawFrame::ColorModify(size_t ivi, int rdl)
512 {
513 wxColour curcol(
514 (unsigned char)(m_iv[ivi]),
515 (unsigned char)(m_iv[ivi + 1]),
516 (unsigned char)(m_iv[ivi + 2])
517 );
518 wxColourData wxcd;
519
520 wxcd.SetColour(curcol);
521 wxColourDialog dlg(this, &wxcd);
522
523 if (wxID_OK == dlg.ShowModal()) {
524 wxColour col = dlg.GetColourData().GetColour();
525 m_iv[ivi ] = col.Red();
526 m_iv[ivi + 1] = col.Green();
527 m_iv[ivi + 2] = col.Blue();
528 wxdobj_drw_require_redraw(m_pDrw, rdl);
529 }
530
531 }
532
533
534
535 void
ColorReset(size_t ivi,int rdl)536 WxdkdrawFrame::ColorReset(size_t ivi, int rdl)
537 {
538
539 DK4_MEMCPY(&(m_iv[ivi]),&(default_values[ivi]),(3*sizeof(int)));
540 wxdobj_drw_require_redraw(m_pDrw, rdl);
541
542 }
543
544
545
546 bool
FindDirectoryForFile(wxChar * dnb,size_t dnsz,wxString & fn)547 WxdkdrawFrame::FindDirectoryForFile(wxChar *dnb, size_t dnsz, wxString & fn)
548 {
549 wxChar const *fnstr = NULL;
550 wxChar const *cwdstr = NULL;
551 wxChar *ptr = NULL;
552 size_t lgt = (size_t)0U;
553 bool back = false;
554
555 if ((NULL != dnb) && ((size_t)0U < dnsz)) {
556 dnb[0] = wxT('\0');
557 wxCStrData strd = fn.c_str();
558 fnstr = (wxChar const *)strd;
559 if (NULL != fnstr) {
560 lgt = dk4strx_len(fnstr);
561 if ((size_t)0U < lgt) {
562 if (lgt < dnsz) {
563 dk4strx_cpy_s(dnb, dnsz, fnstr, NULL);
564 #if DK4_HAVE_BACKSLASH_AS_SEP
565 ptr = dk4strx_rchr(dnb, wxT('\\'));
566 #else
567 ptr = dk4strx_rchr(dnb, wxT('/'));
568 #endif
569 if (NULL != ptr) {
570 *ptr = wxT('\0');
571 back = true;
572
573 }
574 else {
575 wxString cwd = ::wxGetCwd();
576 {
577 wxCStrData strwcd = cwd.c_str();
578 {
579 cwdstr = (wxChar const *)strwcd;
580 if (NULL != cwdstr) {
581 lgt = dk4strx_len(cwdstr);
582 if ((size_t)0U < lgt) {
583 if (lgt < dnsz) {
584 dk4strx_cpy_s(dnb,dnsz,cwdstr,NULL);
585 back = true;
586
587 }
588 else {
589 /* ERROR: CWD too long */
590 dk4error_set_simple_error_code(
591 &m_oErrorReport,
592 WXD_E_CWD_TOO_LONG
593 );
594 }
595 }
596 else {
597 /* ERROR: No current dir */
598 dk4error_set_simple_error_code(
599 &m_oErrorReport,
600 WXD_E_NO_CWD
601 );
602 }
603 }
604 else {
605 /* ERROR: No current dir */
606 dk4error_set_simple_error_code(
607 &m_oErrorReport, WXD_E_NO_CWD
608 );
609 }
610 }
611 }
612 }
613 }
614 else {
615 /* ERROR: Output file name too long */
616 dk4error_set_simple_error_code(
617 &m_oErrorReport, WXD_E_OUTPUT_FN_TOO_LONG
618 );
619 }
620 }
621 else {
622 /* ERROR: Failed to find directory for file */
623 dk4error_set_simple_error_code(
624 &m_oErrorReport, WXD_E_OUTPUT_DIRNAME
625 );
626 }
627 }
628 else {
629 /* ERROR: Failed to find directory for file */
630 dk4error_set_simple_error_code(
631 &m_oErrorReport, WXD_E_OUTPUT_DIRNAME
632 );
633 }
634 }
635 else {
636 }
637 return back;
638 }
639
640
641
642 bool
SaveToFile(void)643 WxdkdrawFrame::SaveToFile(void)
644 {
645 wxChar fnbuf[DK4_MAX_PATH]; /* File name current dir */
646 wxdwr_status_t wrst; /* Writer status */
647 wxString sNewTitle = wxEmptyString; /* New program window title */
648 wxString sDlgTitle(sTexts[171]); /* Dialog title */
649 wxString sDlgTypes(sTexts[172]); /* File type suffixes */
650 FILE *fipo; /* File for output */
651 int res; /* Save operation result */
652 bool cc = true; /* Flag: Can continue */
653 bool back = false;
654
655 if (!(m_bHaveName)) {
656 #if wxCHECK_VERSION(2, 9, 0)
657 wxFileDialog dlg(
658 this, sDlgTitle, m_sFileDir, m_sFileShort,
659 sDlgTypes, (wxFD_SAVE | wxFD_OVERWRITE_PROMPT)
660 );
661 #else
662 wxFileDialog dlg(
663 this, sDlgTitle, m_sFileDir, m_sFileShort,
664 sDlgTypes, wxSAVE
665 );
666 #endif
667 if(wxID_OK == dlg.ShowModal()) {
668 m_sFileFull = dlg.GetPath();
669 m_sFileDir = dlg.GetDirectory();
670 m_sFileShort = dlg.GetFilename();
671 m_bHaveName = true;
672 if (m_bModified) {
673 sNewTitle.Append(sTexts[170]);
674 sNewTitle.Append(m_sFileShort);
675 SetTitle(sNewTitle);
676 }
677 else {
678 SetTitle(m_sFileShort);
679 }
680 m_bUpdate = true;
681 }
682 else {
683 cc = false;
684 }
685 }
686 if (m_bHaveName && cc) {
687 cc = FindDirectoryForFile(fnbuf, DK4_SIZEOF(fnbuf,wxChar), m_sFileFull);
688 if (!(cc)) {
689 /* ##### ERROR: Failed to find directory */
690 }
691 }
692 if (m_bHaveName && cc) {
693 wxFFile wxff(m_sFileFull, wxT("w"));
694 if (wxff.IsOpened()) {
695 fipo = wxff.Detach();
696 if (NULL != fipo) {
697 back = true;
698 wxdwr_status_init(&wrst, pAppHelp->GetWxEncoding());
699 wrst.dirn = fnbuf;
700 res = wxdwr_write_file(fipo, m_pDrw, &wrst);
701 wrst.dirn = NULL;
702 if (0 == res) {
703 back = false;
704 switch (wrst.ec) {
705 case WXDWR_E_WRITE : {
706 /* ERROR: Write operation failed */
707 wxMessageBox(
708 sTexts[204], sTexts[202],
709 (wxOK | wxCENTRE | wxICON_ERROR)
710 );
711 } break;
712 case WXDWR_E_STRING_TOO_LONG : {
713 /* ERROR: String too long */
714 if (NULL != wrst.str) {
715 wxString msg = wxString(sTexts[205]);
716 msg.Append(wxString(wrst.str));
717 msg.Append(wxString(sTexts[206]));
718 wxMessageBox(
719 msg, sTexts[202],
720 (wxOK | wxCENTRE | wxICON_ERROR)
721 );
722 }
723 else {
724 wxMessageBox(
725 sTexts[207], sTexts[202],
726 (wxOK | wxCENTRE | wxICON_ERROR)
727 );
728 }
729 } break;
730 case WXDWR_E_RECODE_TEXT : {
731 /* ERROR: Failed to recode text */
732 if (NULL != wrst.str) {
733 wxString msg = wxString(sTexts[208]);
734 msg.Append(wxString(wrst.str));
735 msg.Append(wxString(sTexts[209]));
736 wxMessageBox(
737 msg, sTexts[202],
738 (wxOK | wxCENTRE | wxICON_ERROR)
739 );
740 }
741 else {
742 wxMessageBox(
743 sTexts[210], sTexts[202],
744 (wxOK | wxCENTRE | wxICON_ERROR)
745 );
746 }
747
748 } break;
749 case WXDWR_E_RECODE_FILENAME : {
750 /* ERROR: Failed to recode file name */
751 if (NULL != wrst.str) {
752 wxString msg = wxString(sTexts[211]);
753 msg.Append(wxString(wrst.str));
754 msg.Append(wxString(sTexts[212]));
755 wxMessageBox(
756 msg, sTexts[202],
757 (wxOK | wxCENTRE | wxICON_ERROR)
758 );
759 }
760 else {
761 wxMessageBox(
762 sTexts[213], sTexts[202],
763 (wxOK | wxCENTRE | wxICON_ERROR)
764 );
765 }
766 } break;
767 case WXDWR_E_STRING_EMPTY : {
768 /* ERROR: Empty string not expected */
769 wxMessageBox(
770 sTexts[214], sTexts[202],
771 (wxOK | wxCENTRE | wxICON_ERROR)
772 );
773 } break;
774 default : {
775 /* ERROR: Unknown reason */
776 wxMessageBox(
777 sTexts[215], sTexts[202],
778 (wxOK | wxCENTRE | wxICON_ERROR)
779 );
780 } break;
781 }
782 }
783 #if TRACE_DEBUG
784 else {
785 }
786 #endif
787 if (0 != fclose(fipo)) {
788 if (back) {
789 /* ERROR: Failed to write to file */
790 wxMessageBox(
791 sTexts[204], sTexts[202],
792 (wxOK | wxCENTRE | wxICON_ERROR)
793 );
794 }
795 back = false;
796 }
797 #if TRACE_DEBUG
798 else {
799 }
800 #endif
801 }
802 else {
803 /* ERROR: Failed to open file */
804 wxMessageBox(
805 sTexts[203], sTexts[202], (wxOK | wxCENTRE | wxICON_ERROR)
806 );
807 }
808 }
809 else {
810 /* ERROR: Failed to open file */
811 wxMessageBox(
812 sTexts[203], sTexts[202], (wxOK | wxCENTRE | wxICON_ERROR)
813 );
814 }
815 if (back) {
816 SetTitle(m_sFileShort);
817 SetModified(false);
818 }
819 }
820 #if TRACE_DEBUG
821 else {
822 }
823 #endif
824
825 return back;
826 }
827
828
829
830 void
SetModified(bool f)831 WxdkdrawFrame::SetModified(bool f)
832 {
833
834 if (f != m_bModified) {
835 if (f) {
836 wxString s = wxEmptyString;
837 s.Append(sTexts[170]);
838 if (m_bHaveName) {
839 s.Append(m_sFileShort);
840 }
841 else {
842 s.Append(sTexts[18]);
843 }
844 SetTitle(s);
845 }
846 else {
847 if (m_bHaveName) {
848 SetTitle(m_sFileShort);
849 }
850 else {
851 SetTitle(sTexts[18]);
852 }
853 }
854 m_bModified = f;
855 m_bUpdate = true;
856 }
857
858 }
859
860
861
862
863 wxSize
ColourViewSize(void)864 WxdkdrawFrame::ColourViewSize(void)
865 {
866 int sl = 20;
867 if (NULL != bFileOpen) {
868 sl = (bFileOpen->GetClientSize()).GetHeight();
869 }
870
871 return(wxSize(sl,sl));
872 }
873
874
875
876 Wxd_drawing_t *
ReadDrawingFromFile(wxString & fn)877 WxdkdrawFrame::ReadDrawingFromFile(wxString & fn)
878 {
879 wxChar dirnb[DK4_MAX_PATH];
880 Wxd_drawing_t *back = NULL; /* Function result */
881 FILE *fp = NULL; /* File to read from */
882 bool haved = false; /* Have directory name */
883
884 wxFFile wxff(fn);
885 haved = FindDirectoryForFile(dirnb, DK4_SIZEOF(dirnb,wxChar), fn);
886 if (wxff.IsOpened()) {
887 fp = wxff.Detach();
888 if (NULL != fp) {
889
890 wxdrd_status_init(&m_oStatusReader);
891 if (haved) {
892 m_oStatusReader.dirn = dirnb;
893 }
894 else {
895 m_oStatusReader.dirn = NULL;
896 }
897 back = wxdrd_read_file(fp, &m_oStatusReader);
898 m_oStatusReader.dirn = NULL;
899 fclose(fp);
900 if (NULL != back) {
901 wxdobj_drw_set_xsubs(back, (size_t)(m_iv[IVI_XS_SUBSEGS]));
902 wxdobj_bb_for_drawing(back);
903 }
904 else {
905 /* ERROR: Failed to read file */
906 dk4error_set_simple_error_code(
907 &m_oErrorReport, WXD_E_FAILED_TO_READ_FILE
908 );
909 }
910 }
911 else {
912 /* ERROR: Failed to open file */
913 dk4error_set_simple_error_code(
914 &m_oErrorReport, WXD_E_FAILED_TO_OPEN_FILE
915 );
916 }
917 }
918 else {
919 /* ERROR: Failed to open file */
920 dk4error_set_simple_error_code(
921 &m_oErrorReport, WXD_E_FAILED_TO_OPEN_FILE
922 );
923 }
924
925 return back;
926 }
927
928
929
930 void
UpdateImages(void)931 WxdkdrawFrame::UpdateImages(void)
932 {
933 Wxd_object_t *pobj;
934 dk4sto_it_reset(m_pDrw->i_flat);
935 do {
936 pobj = (Wxd_object_t *)dk4sto_it_next(m_pDrw->i_flat);
937 if (NULL != pobj) {
938 if (WXD_OT_IMAGE == pobj->ot) {
939 if (NULL != (pobj->det).i.fn) {
940 if (NULL == (pobj->det).i.bm) {
941 wxdobj_load_image(
942 pobj,
943 pAppHelp->GetDkEncoding(),
944 pAppHelp->GetWxEncoding()
945 );
946 }
947 }
948 }
949 }
950 } while (NULL != pobj);
951 }
952
953
954
955 void
DrawingLoaded(void)956 WxdkdrawFrame::DrawingLoaded(void)
957 {
958 /* No operation started on new drawing yet
959 */
960 m_iState = S_NOOP;
961 m_iWheelControl = 0;
962 m_iWheelShift = 0;
963 m_iWheelNormal = 0;
964 m_pStyle = NULL;
965 m_pCurrent = NULL;
966 /* Zoom factor and grid distances
967 */
968 drawco->CalculateZoomFactor();
969 {
970 wxString s;
971 s.Printf("%g", drawco->m_dZoom);
972 lZoomPercent->SetLabel(s);
973 lZoomPercent->Refresh();
974 m_bUpdate = true;
975 }
976 /* Update coefficients for fill patterns
977 */
978 UpdateStipples();
979 UpdateFonts();
980 szTopBar->Layout();
981 lZoomPercent->Refresh();
982 UpdateImages();
983 /* Coordinates conversion coefficients
984 */
985 drawco->CalculateConversionCoefficients();
986
987 /* Grid setup to GUI
988 */
989 if (NULL != m_pDrw) {
990 if ((uint8_t)0U != m_pDrw->gridunit) {
991 cbGridUnit->SetSelection(1);
992 }
993 else {
994 cbGridUnit->SetSelection(0);
995 }
996 if ((uint8_t)0U != m_pDrw->gridbase) {
997 cbGridBase->SetSelection(1);
998 }
999 else {
1000 cbGridBase->SetSelection(0);
1001 }
1002 cbGridUnit->Refresh();
1003 cbGridBase->Refresh();
1004 m_bUpdate = true;
1005 }
1006
1007 /* Calculate grid
1008 */
1009 drawco->CalculateGridDistances();
1010
1011 /* Required width and height
1012 */
1013
1014 /* Scrollbar positions
1015 */
1016 AdjustScrollbars();
1017
1018 /* GUI attributes object
1019 */
1020 m_pStyle = NULL;
1021 m_pCurrent = NULL;
1022 m_iState = S_NOOP;
1023 m_iWheelControl = 0;
1024 m_iWheelShift = 0;
1025 m_iWheelNormal = 0;
1026 m_uCurrent = 0;
1027 m_iObjToCreate = -1;
1028 m_bSplineInterpolated = false;
1029 m_bModified = false;
1030 m_bMouseDiff = false;
1031
1032 drawco->Refresh();
1033 m_bUpdate = true;
1034 }
1035
1036
1037
1038 void
ModificationReportingAtEventEnd(void)1039 WxdkdrawFrame::ModificationReportingAtEventEnd(void)
1040 {
1041 if (DK4_E_NONE == m_oErrorReport.ec) {
1042 if (0 != m_oStatusReader.mod) {
1043 SetModified();
1044 wxMessageBox(
1045 sTexts[600], sTexts[599],
1046 (wxOK | wxCENTRE | wxICON_INFORMATION)
1047 );
1048 }
1049 }
1050 }
1051
1052
1053
1054 void
OnFirstIdle(void)1055 WxdkdrawFrame::OnFirstIdle(void)
1056 {
1057 Wxd_drawing_t *pDrw;
1058
1059
1060 wxdrd_status_init(&m_oStatusReader);
1061 dk4error_init(&m_oErrorReport);
1062 m_pDrw = wxdobj_drw_new();
1063 if (m_bHaveName) {
1064 wxFileName wxfn(m_sFileFull);
1065 SetTitle(m_sFileShort);
1066 if (wxfn.IsFileReadable()) {
1067 pDrw = ReadDrawingFromFile(m_sFileFull);
1068 if (NULL != pDrw) {
1069 wxdobj_drw_delete(m_pDrw);
1070 m_pDrw = pDrw;
1071 m_bHaveName = true;
1072 m_bUpdate = true;
1073 }
1074 else {
1075 /* ERROR: Failed to read file, already reported */
1076 }
1077 }
1078 else {
1079 dk4error_set_simple_error_code(
1080 &m_oErrorReport, WXD_E_FAILED_TO_OPEN_FILE
1081 );
1082 }
1083 }
1084 #if TRACE_DEBUG
1085 else {
1086 }
1087 #endif
1088 /* If drawing was read, set frame as active (ready for events).
1089 Otherwise show error message and exit application.
1090 */
1091 if (NULL != m_pDrw) {
1092 m_bActive = true;
1093 DrawingLoaded();
1094 szTopBar->Layout();
1095 SetStatusText(sTexts[531]);
1096 Refresh();
1097 Update();
1098 }
1099 else {
1100 Close();
1101 }
1102 ModificationReportingAtEventEnd();
1103 ErrorReportingAtEventEnd();
1104 dk4error_init(&m_oErrorReport);
1105
1106 wxdrd_status_init(&m_oStatusReader);
1107
1108 }
1109
1110
1111
1112 static
i32_avg(int32_t a,int32_t b,dk4_er_t * erp)1113 int32_t i32_avg(int32_t a, int32_t b, dk4_er_t *erp)
1114 {
1115 dk4_er_t er;
1116 int32_t back = (int32_t)0L;
1117
1118 dk4error_init(&er);
1119 back = dk4ma_int32_t_add(a, b, &er) / ((int32_t)2L);
1120 if (DK4_E_NONE != er.ec) {
1121 dk4error_init(&er);
1122 back = dk4ma_int32_t_add(
1123 a,
1124 (dk4ma_int32_t_sub(b, a, &er) / ((int32_t)2L)),
1125 &er
1126 );
1127 if (DK4_E_NONE != er.ec) {
1128 dk4error_copy(erp, &er);
1129 }
1130 }
1131 return back;
1132 }
1133
1134
1135
1136 void
CorrectCenterPointIfNecessary(void)1137 WxdkdrawFrame::CorrectCenterPointIfNecessary(void)
1138 {
1139 dk4_er_t er;
1140 int32_t xcmin; /* Minimum value for center x position */
1141 int32_t xcmax; /* Maximum value for center x position */
1142 int32_t ycmin; /* Minimum value for center y position */
1143 int32_t ycmax; /* Maximum value for center y position */
1144 int32_t deltax; /* X difference border to center */
1145 int32_t deltay; /* Y difference border to center */
1146
1147 dk4error_init(&er);
1148 deltax = dk4ma_int32_from_double(
1149 (
1150 (16256000.0 * (double)((drawco->m_szDrawco).GetWidth()))
1151 / (2.0 * drawco->m_dZoom * (drawco->m_ptRes).x)
1152 ), &er
1153 );
1154 deltay = dk4ma_int32_from_double(
1155 (
1156 (16256000.0 * (double)((drawco->m_szDrawco).GetHeight()))
1157 / (2.0 * drawco->m_dZoom * (drawco->m_ptRes).y)
1158 ), &er
1159 );
1160 xcmin = dk4ma_int32_t_add(
1161 dk4ma_int32_t_sub(
1162 (m_pDrw->bb).xl,
1163 dk4ma_int32_from_double((double)(m_pDrw->bleft), &er),
1164 &er
1165 ), deltax, &er
1166 );
1167 xcmax = dk4ma_int32_t_sub(
1168 dk4ma_int32_t_add(
1169 (m_pDrw->bb).xr,
1170 dk4ma_int32_from_double((double)(m_pDrw->bright), &er),
1171 &er
1172 ), deltax, &er
1173 );
1174 ycmin = dk4ma_int32_t_add(
1175 dk4ma_int32_t_sub(
1176 (m_pDrw->bb).yb,
1177 dk4ma_int32_from_double((double)(m_pDrw->bbottom), &er),
1178 &er
1179 ), deltay, &er
1180 );
1181 ycmax = dk4ma_int32_t_sub(
1182 dk4ma_int32_t_add(
1183 (m_pDrw->bb).yt,
1184 dk4ma_int32_from_double((double)(m_pDrw->btop), &er),
1185 &er
1186 ), deltay, &er
1187 );
1188 if (DK4_E_NONE == er.ec) {
1189 /*
1190 X correction
1191 */
1192 if (xcmax > xcmin) {
1193 if (m_pDrw->cx < xcmin) {
1194 m_pDrw->cx = xcmin;
1195 }
1196 else {
1197 if (m_pDrw->cx > xcmax) {
1198 m_pDrw->cx = xcmax;
1199 }
1200 }
1201 }
1202 else {
1203 if (xcmax == xcmin) {
1204 m_pDrw->cx = xcmin;
1205 }
1206 else {
1207 xcmin = i32_avg((m_pDrw->bb).xl, (m_pDrw->bb).xr, &er);
1208 if (DK4_E_NONE == er.ec) {
1209 m_pDrw->cx = xcmin;
1210 }
1211 }
1212 }
1213 /*
1214 Y correction
1215 */
1216 if (ycmax > ycmin) {
1217 if (m_pDrw->cy < ycmin) {
1218 m_pDrw->cy = ycmin;
1219 }
1220 else {
1221 if (m_pDrw->cy > ycmax) {
1222 m_pDrw->cy = ycmax;
1223 }
1224 }
1225 }
1226 else {
1227 if (ycmax == ycmin) {
1228 m_pDrw->cy = ycmin;
1229 }
1230 else {
1231 dk4error_init(&er);
1232 ycmin = i32_avg((m_pDrw->bb).yb, (m_pDrw->bb).yt, &er);
1233 if (DK4_E_NONE == er.ec) {
1234 m_pDrw->cy = ycmin;
1235 }
1236 }
1237 }
1238 }
1239 else {
1240 }
1241
1242 }
1243
1244
1245
1246 void
ZoomChanged(bool bZoomOut)1247 WxdkdrawFrame::ZoomChanged(bool bZoomOut)
1248 {
1249 drawco->CalculateZoomFactor();
1250 {
1251 wxString s;
1252 s.Printf("%g", drawco->m_dZoom);
1253 lZoomPercent->SetLabel(s);
1254 }
1255 UpdateStipples();
1256 UpdateFonts();
1257 szTopBar->Layout();
1258 lZoomPercent->Refresh();
1259 if (bZoomOut && (0 != m_iv[IVI_C_COR_POSITION])) {
1260 CorrectCenterPointIfNecessary();
1261 }
1262 drawco->CalculateConversionCoefficients();
1263 AdjustScrollbars();
1264 wxdobj_drw_require_redraw(m_pDrw, WXD_REFRESH_GRID);
1265 drawco->Refresh();
1266 m_bUpdate = true;
1267 }
1268
1269
1270
1271 void
AdjustScrollbars(void)1272 WxdkdrawFrame::AdjustScrollbars(void)
1273 {
1274 dk4_er_t er; /* Error report */
1275 int xPos; /* Horizontal scrolblar position */
1276 int yPos; /* Vertical scrollbar position */
1277 int xThumb; /* Thumb size width (control width) */
1278 int yThumb; /* Thumb size height (control height) */
1279 int xRange; /* Range (required pixels) */
1280 int yRange; /* Range (required pixels) */
1281 int xPageSize; /* Pixels to scroll for page */
1282 int yPageSize; /* Pixels to scroll for page */
1283 bool bEnableX = false; /* Enable horizontal scrollbar */
1284 bool bEnableY = false; /* Enable vertical scrollbar */
1285
1286 dk4error_init(&er);
1287 xThumb = (drawco->m_szDrawco).GetWidth();
1288 yThumb = (drawco->m_szDrawco).GetHeight();
1289 xRange = dk4ma_int_from_double(
1290 ceil(
1291 (
1292 (
1293 (double)((m_pDrw->bb).xr) - (double)((m_pDrw->bb).xl)
1294 + (double)(m_pDrw->bleft) + (double)(m_pDrw->bright)
1295 ) * (drawco->m_ptRes).x * drawco->m_dZoom
1296 ) / RESWXD
1297 ), &er
1298 );
1299 yRange = dk4ma_int_from_double(
1300 ceil(
1301 (
1302 (
1303 (double)((m_pDrw->bb).yt) - (double)((m_pDrw->bb).yb)
1304 + (double)(m_pDrw->bbottom) + (double)(m_pDrw->btop)
1305 ) * (drawco->m_ptRes).y * drawco->m_dZoom
1306 ) / RESWXD
1307 ), &er
1308 );
1309 xPageSize = dk4ma_int_mul(xThumb, 4, &er) / 5;
1310 yPageSize = dk4ma_int_mul(yThumb, 4, &er) / 5;
1311 xPos = dk4ma_int_from_double(
1312 dk4ma_rint(
1313 (
1314 (
1315 (
1316 (double)(m_pDrw->cx) - (double)((m_pDrw->bb).xl)
1317 + (double)(m_pDrw->bleft)
1318 ) * (drawco->m_ptRes).x * drawco->m_dZoom
1319 ) / RESWXD
1320 ) - ((double)xThumb / 2.0)
1321 ), &er
1322 );
1323 yPos = dk4ma_int_from_double(
1324 dk4ma_rint(
1325 (
1326 (
1327 (
1328 (double)((m_pDrw->bb).yt) - (double)(m_pDrw->cy)
1329 + (double)(m_pDrw->btop)
1330 ) * (drawco->m_ptRes).y * drawco->m_dZoom
1331 ) / RESWXD
1332 ) - ((double)yThumb / 2.0)
1333 ), &er
1334 );
1335 if (0 > xPos) { xPos = 0; }
1336 if (0 > yPos) { yPos = 0; }
1337 if ((xRange - xThumb) < xPos) { xPos = xRange - xThumb; }
1338 if ((yRange - yThumb) < yPos) { yPos = yRange - yThumb; }
1339 if (DK4_E_NONE == er.ec) {
1340 if (xRange > xThumb) {
1341 bEnableX = true;
1342 }
1343 if (yRange > yThumb) {
1344 bEnableY = true;
1345 }
1346 }
1347 /* Set up horizontal scrollbar
1348 */
1349 if (bEnableX) {
1350 if (!(sbHori->IsEnabled())) {
1351 sbHori->Enable();
1352 }
1353
1354
1355
1356
1357 sbHori->SetScrollbar(xPos, xThumb, xRange, xPageSize, true);
1358 sbHori->SetThumbPosition(xPos);
1359 sbHori->Refresh();
1360 }
1361 else {
1362 if (sbHori->IsEnabled()) {
1363 sbHori->Enable(false);
1364 sbHori->Refresh();
1365 }
1366 }
1367 /* Set up vertical scrollbar
1368 */
1369 if (bEnableY) {
1370 if (!(sbVert->IsEnabled())) {
1371 sbVert->Enable();
1372 }
1373
1374
1375
1376
1377 sbVert->SetScrollbar(yPos, yThumb, yRange, yPageSize, true);
1378 sbVert->SetThumbPosition(yPos);
1379 sbVert->Refresh();
1380 }
1381 else {
1382 if (sbVert->IsEnabled()) {
1383 sbVert->Enable(false);
1384 sbVert->Refresh();
1385 }
1386 }
1387 }
1388
1389
1390
1391 void
StartEventHandling(void)1392 WxdkdrawFrame::StartEventHandling(void)
1393 {
1394 dk4error_init(&m_oErrorReport);
1395 m_bUpdate = false;
1396 }
1397
1398
1399
1400 void
MoveScrollbar(wxScrollBar * sb,int lines,bool vert)1401 WxdkdrawFrame::MoveScrollbar(wxScrollBar *sb, int lines, bool vert)
1402 {
1403 int range; /* Scrollbar range (maximum) */
1404 #if 0
1405 int ps; /* Page size */
1406 #endif
1407 int pos; /* Position */
1408 int ts; /* Thumb size */
1409
1410 range = sb->GetRange();
1411 #if 0
1412 ps = sb->GetPageSize();
1413 #endif
1414 pos = sb->GetThumbPosition();
1415 ts = sb->GetThumbSize();
1416
1417 if (range > ts) {
1418 pos -= (lines * ts) / 10;
1419 if (0 > pos) { pos = 0; }
1420 if ((range - ts) <= pos) { pos = range - ts - 1; }
1421 sb->SetThumbPosition(pos);
1422 if (vert) {
1423 UseScrollV();
1424 }
1425 else {
1426 UseScrollH();
1427 }
1428 sb->Refresh();
1429 sb->Update();
1430 }
1431
1432 }
1433
1434
1435
1436 void
ControlMouseWheel(wxMouseEvent & event)1437 WxdkdrawFrame::ControlMouseWheel(wxMouseEvent & event)
1438 {
1439 int modifiers; /* Modifier keys */
1440 int rotation; /* Rotation of wheel */
1441 int delta; /* Required rotation for line */
1442 int lines; /* Number of lines */
1443 int8_t ozl;
1444
1445 StartEventHandling();
1446 if (UpdateMousePosition(event)) {
1447 wxdobj_drw_require_redraw(m_pDrw, WXD_REFRESH_MARKUP);
1448 }
1449 modifiers = event.GetModifiers();
1450 rotation = event.GetWheelRotation();
1451 delta = event.GetWheelDelta();
1452 switch (modifiers) {
1453 case wxMOD_CONTROL : {
1454 m_iWheelControl += rotation;
1455 lines = m_iWheelControl / delta;
1456 m_iWheelControl -= (lines * delta);
1457 ozl = m_pDrw->zl;
1458 if (0 < lines) {
1459 while (0 < lines--) {
1460 if ((int8_t)(-14) < m_pDrw->zl) {
1461 m_pDrw->zl = (int8_t)(m_pDrw->zl - 1);
1462 }
1463 }
1464 }
1465 else {
1466 if (0 > lines) {
1467 while (0 > lines++) {
1468 if ((int8_t)14 > m_pDrw->zl) {
1469 m_pDrw->zl = (int8_t)(m_pDrw->zl + 1);
1470 }
1471 }
1472 }
1473 }
1474 if (ozl != m_pDrw->zl) {
1475 ZoomChanged((ozl > m_pDrw->zl));
1476 UpdateGridPosition();
1477 }
1478 } break;
1479 case wxMOD_SHIFT : {
1480 m_iWheelShift += rotation;
1481 lines = m_iWheelShift /delta;
1482 m_iWheelShift -= (lines * delta);
1483 if (sbHori->IsEnabled()) {
1484 MoveScrollbar(sbHori, lines, false);
1485 drawco->CalculateConversionCoefficients();
1486 UpdateGridPosition();
1487 wxdobj_drw_require_redraw(m_pDrw, WXD_REFRESH_GRID);
1488 }
1489 } break;
1490 case wxMOD_NONE : {
1491 m_iWheelNormal += rotation;
1492 lines = m_iWheelNormal / delta;
1493 m_iWheelNormal -= (lines * delta);
1494 if (sbVert->IsEnabled()) {
1495 MoveScrollbar(sbVert, lines, true);
1496 drawco->CalculateConversionCoefficients();
1497 UpdateGridPosition();
1498 wxdobj_drw_require_redraw(m_pDrw, WXD_REFRESH_GRID);
1499 }
1500 } break;
1501 }
1502
1503 EndEventHandling();
1504 }
1505
1506
1507
1508 void
UseScrollH(void)1509 WxdkdrawFrame::UseScrollH(void)
1510 {
1511 dk4_er_t er; /* Error report */
1512 int32_t cx; /* Center x */
1513 int tp; /* Thumb position */
1514 int ts; /* Thumb size */
1515 #if 0
1516 int r;
1517 int p;
1518 #endif
1519
1520 #if 0
1521 r = sbHori->GetRange();
1522 p = sbHori->GetPageSize();
1523 #endif
1524 tp = sbHori->GetThumbPosition();
1525 ts = sbHori->GetThumbSize();
1526 dk4error_init(&er);
1527 cx = dk4ma_int32_from_double(
1528 dk4ma_rint(
1529 (
1530 ((double)tp + (double)ts / 2.0) * RESWXD
1531 ) / ((drawco->m_ptRes).x * drawco->m_dZoom)
1532 ), &er
1533 );
1534 cx = dk4ma_int32_t_add(cx, (m_pDrw->bb).xl, &er);
1535 cx = dk4ma_int32_t_sub(cx, m_pDrw->bleft, &er);
1536 if (DK4_E_NONE == er.ec) {
1537 m_pDrw->cx = cx;
1538 wxdobj_drw_require_redraw(m_pDrw, WXD_REFRESH_GRID);
1539 drawco->Refresh();
1540 m_bUpdate = true;
1541 }
1542
1543 }
1544
1545
1546
1547 void
UseScrollV(void)1548 WxdkdrawFrame::UseScrollV(void)
1549 {
1550 dk4_er_t er; /* Error report */
1551 int32_t cy; /* Center y */
1552 int tp; /* Thumb position */
1553 int ts; /* Thumb size */
1554 #if 0
1555 int r;
1556 int p;
1557 #endif
1558
1559 #if 0
1560 r = sbVert->GetRange();
1561 p = sbVert->GetPageSize();
1562 #endif
1563 tp = sbVert->GetThumbPosition();
1564 ts = sbVert->GetThumbSize();
1565 dk4error_init(&er);
1566 cy = dk4ma_int32_from_double(
1567 dk4ma_rint(
1568 (
1569 ((double)tp + (double)ts / 2.0) * RESWXD
1570 ) / ((drawco->m_ptRes).x * drawco->m_dZoom)
1571 ), &er
1572 );
1573 cy = dk4ma_int32_t_sub((m_pDrw->bb).yt, cy, &er);
1574 cy = dk4ma_int32_t_add(cy, m_pDrw->btop, &er);
1575 if (DK4_E_NONE == er.ec) {
1576 m_pDrw->cy = cy;
1577 wxdobj_drw_require_redraw(m_pDrw, WXD_REFRESH_GRID);
1578 drawco->Refresh();
1579 m_bUpdate = true;
1580 }
1581
1582 }
1583
1584
1585
1586 #if 0
1587
1588 static
1589 bool
1590 ColourChooserDiffersFromColour(Dk4WxColourView *pcc, int *pcol)
1591 {
1592 bool back = false;
1593 if (pcc->Red() != pcol[0]) {
1594 back = true;
1595 }
1596 else {
1597 if (pcc->Green() != pcol[1]) {
1598 back = true;
1599 }
1600 else {
1601 if (pcc->Blue() != pcol[2]) {
1602 back = true;
1603 }
1604 }
1605 }
1606 return back;
1607 }
1608
1609 #endif
1610
1611
1612
1613 void
StyleToGUI(bool refresh)1614 WxdkdrawFrame::StyleToGUI(bool refresh)
1615 {
1616 int valrotation = 0; /* Rotation value */
1617 bool enalayer = true; /* Enable layer spin control */
1618 bool enalinecolour = false; /* Enable line colour chooser */
1619 bool enalinewidth = false; /* Enable line width spin control */
1620 bool enalinestyle = false; /* Enable line style button */
1621 bool enajoinstyle = false; /* Enable join style button */
1622 bool enacapstyle = false; /* Enable cap style button */
1623 bool enafwarrow = false; /* Enable forward arrow button */
1624 bool enabwarrow = false; /* Enable backward arrow button */
1625 bool enafillcolour = false; /* Enable fill colour chooser */
1626 bool enafillstyle = false; /* Enable fill style button */
1627 bool enalatex = false; /* Enable LaTeX checkbox */
1628 bool enatextalign = false; /* Enable text align button */
1629 bool enatextfont = false; /* Enable text font button */
1630 bool enatextsize = false; /* Enable text size spin control */
1631 bool enarotation = false; /* Enable rotation spin control */
1632
1633 if (NULL != m_pStyle) {
1634 /*
1635 Check which style elements to enable
1636 */
1637 switch ( (int)(m_pStyle->ot) ) {
1638 case WXD_OT_TEXT : {
1639 enalinecolour = true;
1640 enalatex = true;
1641 enatextalign = true;
1642 enatextfont = true;
1643 enatextsize = true;
1644 enarotation = true;
1645 valrotation = (m_pStyle->det).t.a;
1646 } break;
1647 case WXD_OT_POLYLINE : case WXD_OT_O_SPLINE : {
1648 enalinecolour = true;
1649 enalinewidth = true;
1650 enalinestyle = true;
1651 enajoinstyle = true;
1652 enacapstyle = true;
1653 enafwarrow = true;
1654 enabwarrow = true;
1655 } break;
1656 case WXD_OT_O_ARC : {
1657 enalinecolour = true;
1658 enalinewidth = true;
1659 enalinestyle = true;
1660 enacapstyle = true;
1661 enafwarrow = true;
1662 enabwarrow = true;
1663 } break;
1664 case WXD_OT_POLYGON : case WXD_OT_C_SPLINE : case WXD_OT_C_ARC : {
1665
1666 enalinecolour = true;
1667 enalinewidth = true;
1668 enalinestyle = true;
1669 enajoinstyle = true;
1670 enafillcolour = true;
1671 enafillstyle = true;
1672 } break;
1673 case WXD_OT_CIRCLE : case WXD_OT_ELLIPSE : {
1674 enalinecolour = true;
1675 enalinewidth = true;
1676 enalinestyle = true;
1677 enafillcolour = true;
1678 enafillstyle = true;
1679 if (WXD_OT_ELLIPSE == m_pStyle->ot) {
1680 enarotation = true;
1681 valrotation = (m_pStyle->det).e.a;
1682 }
1683 } break;
1684 case WXD_OT_BOX : {
1685 enalinecolour = true;
1686 enalinewidth = true;
1687 enalinestyle = true;
1688 enajoinstyle = true;
1689 enafillcolour = true;
1690 enafillstyle = true;
1691 } break;
1692 case WXD_OT_IMAGE : {
1693 enafillcolour = true;
1694 } break;
1695 case WXD_OT_DOT_FILLED : {
1696 enalinecolour = true;
1697 } break;
1698 case WXD_OT_DOT_WHITE : {
1699 enalinecolour = true;
1700 enalinewidth = true;
1701 } break;
1702 default : {
1703 } break;
1704 }
1705
1706 /*
1707 Prepare to change style for selected object.
1708 */
1709
1710 /* Layer */
1711 spLayerNumber->SetValue( (int)(m_pStyle->lay) );
1712 spLayerNumber->Enable(enalayer);
1713 if (refresh) { spLayerNumber->Refresh(); m_bUpdate = true; }
1714
1715
1716 /* Line colour */
1717 ccLineColour->SetRGB(m_pStyle->sc[0], m_pStyle->sc[1], m_pStyle->sc[2]);
1718
1719 ccLineColour->Enable(enalinecolour);
1720 if (refresh) { ccLineColour->Refresh(); m_bUpdate = true; }
1721
1722
1723 /* Line width */
1724 spLineWidth->SetValue( (int)(m_pStyle->lw) );
1725
1726 spLineWidth->Enable(enalinewidth);
1727 if (refresh) { spLineWidth->Refresh(); m_bUpdate = true; }
1728
1729
1730 /* Line style */
1731 bStyleLineStyle->SetBitmap(WxdkdrawFrame::ms_ls_images[m_pStyle->ls]);
1732
1733 bStyleLineStyle->Enable(enalinestyle);
1734 if (refresh) { bStyleLineStyle->Refresh(); m_bUpdate = true; }
1735
1736
1737 /* Join style */
1738 bStyleLineJoins->SetBitmap(WxdkdrawFrame::ms_lj_images[m_pStyle->js]);
1739 bStyleLineJoins->Enable(enajoinstyle);
1740 if (refresh) { bStyleLineJoins->Refresh(); m_bUpdate = true; }
1741
1742
1743 /* Cap style */
1744 bStyleLineEnds->SetBitmap(WxdkdrawFrame::ms_lc_images[m_pStyle->cs]);
1745 bStyleLineEnds->Enable(enacapstyle);
1746 if (refresh) { bStyleLineEnds->Refresh(); m_bUpdate = true; }
1747
1748
1749 /* Forward arrow */
1750 bStyleArrowForward->SetBitmap(
1751 WxdkdrawFrame::ms_arrow_images[m_pStyle->aft]
1752 );
1753 bStyleArrowForward->Enable(enafwarrow);
1754 if (refresh) { bStyleArrowForward->Refresh(); m_bUpdate = true; }
1755
1756
1757 /* Backward arrow */
1758 bStyleArrowBackward->SetBitmap(
1759 WxdkdrawFrame::ms_arrow_images[m_pStyle->abt]
1760 );
1761 bStyleArrowBackward->Enable(enabwarrow);
1762 if (refresh) { bStyleArrowBackward->Refresh(); m_bUpdate = true; }
1763
1764
1765 /* Fill colour */
1766 ccFillColour->SetRGB(
1767 m_pStyle->fc[0], m_pStyle->fc[1], m_pStyle->fc[2]
1768 );
1769 ccFillColour->Enable(enafillcolour);
1770 if (refresh) { ccFillColour->Refresh(); m_bUpdate = true; }
1771
1772
1773 /* Fill style */
1774 bStyleFillPattern->SetBitmap(WxdkdrawFrame::ms_fs_images[m_pStyle->fs]);
1775 bStyleFillPattern->Enable(enafillstyle);
1776 if (refresh) { bStyleFillPattern->Refresh(); m_bUpdate = true; }
1777
1778
1779 if (WXD_OT_TEXT == m_pStyle->ot) {
1780
1781 /* LaTeX text flag */
1782 cbStyleTextLaTeX->SetValue(
1783 WXD_TEXT_FLAG_NONE
1784 != (WXD_TEXT_FLAG_LATEX & (m_pStyle->det).t.fl)
1785 );
1786 cbStyleTextLaTeX->Enable(enalatex);
1787 if (refresh) { cbStyleTextLaTeX->Refresh(); m_bUpdate = true; }
1788
1789
1790
1791 bStyleTextAlign->SetBitmap(
1792 WxdkdrawFrame::ms_ta_images[(m_pStyle->det).t.al]
1793 );
1794 bStyleTextAlign->Enable(enatextalign);
1795 if (refresh) { bStyleTextAlign->Refresh(); m_bUpdate = true; }
1796
1797
1798 /* Text font */
1799 bStyleFontName->SetBitmap(
1800 WxdkdrawFrame::ms_fn_images[(m_pStyle->det).t.find]
1801 );
1802 bStyleFontName->Enable(enatextfont);
1803 if (refresh) { bStyleFontName->Refresh(); m_bUpdate = true; }
1804
1805
1806 /* Text size */
1807 spFontSize->SetValue((m_pStyle->det).t.fsz);
1808 spFontSize->Enable(enatextsize);
1809 if (refresh) { spFontSize->Refresh(); m_bUpdate = true; }
1810
1811
1812 }
1813 else {
1814 cbStyleTextLaTeX->Enable(false);
1815 bStyleTextAlign->Enable(false);
1816 bStyleFontName->Enable(false);
1817 spFontSize->Enable(false);
1818 }
1819 spRotation->SetValue(valrotation);
1820 spRotation->Enable(enarotation);
1821 if (refresh) { spRotation->Refresh(); m_bUpdate = true; }
1822 }
1823 else {
1824 /*
1825 Prepare to change default styles.
1826 */
1827
1828 /* Layer number */
1829 spLayerNumber->SetValue( (int)(m_oStyle.lay) );
1830 spLayerNumber->Enable();
1831 if (refresh) { spLayerNumber->Refresh(); m_bUpdate = true; }
1832
1833 /* Line colour */
1834 ccLineColour->SetRGB( m_oStyle.sc[0], m_oStyle.sc[1], m_oStyle.sc[2] );
1835 ccLineColour->Enable();
1836 if (refresh) { ccLineColour->Refresh(); m_bUpdate = true; }
1837
1838 /* Line width */
1839 spLineWidth->SetValue( (int)(m_oStyle.lw) );
1840 spLineWidth->Enable();
1841 if (refresh) { spLineWidth->Refresh(); m_bUpdate = true; }
1842
1843 /* Line style */
1844 bStyleLineStyle->SetBitmap(WxdkdrawFrame::ms_ls_images[m_oStyle.ls]);
1845 bStyleLineStyle->Enable();
1846 if (refresh) { bStyleLineStyle->Refresh(); m_bUpdate = true; }
1847
1848 /* Join style */
1849 bStyleLineJoins->SetBitmap(WxdkdrawFrame::ms_lj_images[m_oStyle.js]);
1850 bStyleLineJoins->Enable();
1851 if (refresh) { bStyleLineJoins->Refresh(); m_bUpdate = true; }
1852
1853 /* Cap style */
1854 bStyleLineEnds->SetBitmap(WxdkdrawFrame::ms_lc_images[m_oStyle.cs]);
1855 bStyleLineEnds->Enable();
1856 if (refresh) { bStyleLineEnds->Refresh(); m_bUpdate = true; }
1857
1858 /* Forward arrow */
1859 bStyleArrowForward->SetBitmap(
1860 WxdkdrawFrame::ms_arrow_images[m_oStyle.aft]
1861 );
1862 bStyleArrowForward->Enable();
1863 if (refresh) { bStyleArrowForward->Refresh(); m_bUpdate = true; }
1864
1865 /* Backward arrow */
1866 bStyleArrowBackward->SetBitmap(
1867 WxdkdrawFrame::ms_arrow_images[m_oStyle.abt]
1868 );
1869 bStyleArrowBackward->Enable();
1870 if (refresh) { bStyleArrowBackward->Refresh(); m_bUpdate = true; }
1871
1872 /* Fill colour */
1873 ccFillColour->SetRGB( m_oStyle.fc[0], m_oStyle.fc[1], m_oStyle.fc[2] );
1874 ccFillColour->Enable();
1875 if (refresh) { ccFillColour->Refresh(); m_bUpdate = true; }
1876
1877 /* Fill style */
1878 bStyleFillPattern->SetBitmap(WxdkdrawFrame::ms_fs_images[m_oStyle.fs]);
1879 bStyleFillPattern->Enable();
1880 if (refresh) { bStyleFillPattern->Refresh(); m_bUpdate = true; }
1881
1882 /* LaTeX text flag */
1883 cbStyleTextLaTeX->SetValue(
1884 WXD_TEXT_FLAG_NONE != (WXD_TEXT_FLAG_LATEX & m_oStyle.det.t.fl)
1885 );
1886 cbStyleTextLaTeX->Enable();
1887 if (refresh) { cbStyleTextLaTeX->Refresh(); m_bUpdate = true; }
1888
1889 /* Text align */
1890 bStyleTextAlign->SetBitmap(
1891 WxdkdrawFrame::ms_ta_images[m_oStyle.det.t.al]
1892 );
1893 bStyleTextAlign->Enable();
1894 if (refresh) { bStyleTextAlign->Refresh(); m_bUpdate = true; }
1895
1896 /* Text font */
1897 bStyleFontName->SetBitmap(
1898 WxdkdrawFrame::ms_fn_images[m_oStyle.det.t.find]
1899 );
1900 bStyleFontName->Enable();
1901 if (refresh) { bStyleFontName->Refresh(); m_bUpdate = true; }
1902
1903 /* Text size */
1904 spFontSize->SetValue(m_oStyle.det.t.fsz);
1905 spFontSize->Enable();
1906 if (refresh) { spFontSize->Refresh(); m_bUpdate = true; }
1907
1908 /* Rotation */
1909 spRotation->SetValue(0);
1910 spRotation->Enable(false);
1911 if (refresh) { spRotation->Refresh(); m_bUpdate = true; }
1912 }
1913
1914 }
1915
1916
1917
1918 void
SetStyleObject(Wxd_object_t * pObj,bool bUpdate)1919 WxdkdrawFrame::SetStyleObject(Wxd_object_t *pObj, bool bUpdate)
1920 {
1921 if (m_pStyle != pObj) {
1922 m_pStyle = pObj;
1923 StyleToGUI(bUpdate);
1924 }
1925 }
1926
1927
1928
1929 void
UpdateOneFont(Wxd_font_t * pfont)1930 WxdkdrawFrame::UpdateOneFont(
1931 Wxd_font_t *pfont
1932 )
1933 {
1934 pfont->attempted = false;
1935 if (NULL != pfont->font) {
1936 delete (pfont->font);
1937 pfont->font = NULL;
1938 }
1939 wxdfont_find_font(
1940 pfont, drawco->m_dZoom, (drawco->m_ptRes).y,
1941 (0 != m_iv[IVI_FONT_EXACT])
1942 );
1943 }
1944
1945
1946
1947 void
UpdateFonts(void)1948 WxdkdrawFrame::UpdateFonts(void)
1949 {
1950 Wxd_font_t *pfont;
1951 Wxd_object_t *pobj;
1952
1953 /* Connect text details to fonts.
1954 */
1955
1956 dk4sto_it_reset(m_pDrw->i_flat);
1957 do {
1958 pobj = (Wxd_object_t *)dk4sto_it_next(m_pDrw->i_flat);
1959 if (NULL != pobj) {
1960 if (WXD_OT_TEXT == pobj->ot) {
1961 if (NULL == (pobj->det).t.font) {
1962 (pobj->det).t.font = FindFont(
1963 (pobj->det).t.find, (pobj->det).t.fsz
1964 );
1965 }
1966 }
1967 }
1968 } while (NULL != pobj);
1969
1970 /* Clear and renew all fonts
1971 */
1972
1973 dk4sto_it_reset(m_pDrw->i_fonts);
1974 do {
1975 pfont = (Wxd_font_t *)dk4sto_it_next(m_pDrw->i_fonts);
1976 if (NULL != pfont) {
1977 UpdateOneFont(pfont);
1978 }
1979 } while (NULL != pfont);
1980
1981
1982 }
1983
1984
1985
1986 Wxd_font_t *
FindFont(uint8_t find,uint16_t fsz)1987 WxdkdrawFrame::FindFont(uint8_t find, uint16_t fsz)
1988 {
1989 Wxd_font_t tf;
1990 Wxd_font_t *back = NULL;
1991
1992 tf.find = find; tf.fsz = fsz;
1993 back = (Wxd_font_t *)dk4sto_it_find_like(m_pDrw->i_fonts, &tf, 0);
1994 if (NULL == back) {
1995 back = wxdfont_new(find, fsz);
1996 if (NULL != back) {
1997 if (0 != dk4sto_add(m_pDrw->s_fonts, back, NULL)) {
1998 wxdfont_find_font(
1999 back, drawco->m_dZoom, (drawco->m_ptRes).y,
2000 (0 != m_iv[IVI_FONT_EXACT])
2001 );
2002 }
2003 else {
2004 wxdfont_delete(back);
2005 back = NULL;
2006 }
2007 }
2008 }
2009 return back;
2010 }
2011
2012
2013
2014 bool
ObjectSelectableInState(Wxd_object_t const * pobj)2015 WxdkdrawFrame::ObjectSelectableInState(Wxd_object_t const *pobj)
2016 {
2017 bool back = false;
2018 if (NULL != pobj) {
2019 back = true;
2020 /*
2021 _STATE_
2022 In some states we want to select objects of certain
2023 types only
2024 */
2025 switch (m_iState) {
2026 case S_MOD_SPLINE : {
2027 back = false;
2028 switch ( (int)(pobj->ot) ) {
2029 case WXD_OT_O_SPLINE :
2030 case WXD_OT_C_SPLINE :
2031 {
2032 back = true;
2033 } break;
2034 }
2035 } break;
2036 case S_ROTATE : {
2037 switch ( (int)(pobj->ot) ) {
2038 case WXD_OT_CIRCLE :
2039 case WXD_OT_DOT_FILLED :
2040 case WXD_OT_DOT_WHITE :
2041 {
2042 if (NULL == pobj->pa) {
2043 back = false;
2044 }
2045 } break;
2046 }
2047 } break;
2048 case S_CONVERT : {
2049 back = wxdobj_can_convert(m_iObjToCreate, pobj);
2050 } break;
2051 case S_FLIP : {
2052 /*
2053 For some object types flipping would result
2054 in no change
2055 */
2056 switch ( (int)(pobj->ot) ) {
2057 case WXD_OT_CIRCLE :
2058 case WXD_OT_BOX :
2059 case WXD_OT_IMAGE :
2060 case WXD_OT_DOT_FILLED :
2061 case WXD_OT_DOT_WHITE : {
2062 if (NULL == pobj->pa) {
2063 back = false;
2064 }
2065 } break;
2066 }
2067 } break;
2068 case S_UNGROUP : {
2069 /*
2070 Only members of groups are of interest, from the member
2071 we go upwards to find the top level group object
2072 */
2073 if (NULL == pobj->pa) {
2074 back = false;
2075 }
2076 } break;
2077 case S_DETAILS : {
2078 /*
2079 The details to modify - if any - depend on the object type:
2080 */
2081 switch ( (int)(pobj->ot) ) {
2082 case WXD_OT_TEXT : /* Texts */
2083 case WXD_OT_BOX : /* Rounded corner radius */
2084 case WXD_OT_IMAGE : /* Image file and flags */
2085 case WXD_OT_DOT_FILLED : /* Diameter */
2086 case WXD_OT_DOT_WHITE : /* Diameter */
2087 {
2088 back = true;
2089 } break;
2090 default : {
2091 back = false;
2092 } break;
2093 }
2094 } break;
2095 }
2096 }
2097 return back;
2098 }
2099
2100
2101
2102 Wxd_object_t *
FindNearestObject(bool gr)2103 WxdkdrawFrame::FindNearestObject(bool gr)
2104 {
2105 Wxd_object_t *back = NULL; /* Object with minimum distance */
2106 Wxd_object_t *pobj; /* Current object */
2107 double min = -1.0; /* Minimum distance found so far */
2108 double d; /* Distance to current object */
2109
2110 dk4sto_it_reset(m_pDrw->i_flat);
2111 do {
2112 pobj = (Wxd_object_t *)dk4sto_it_next(m_pDrw->i_flat);
2113 if (NULL != pobj) {
2114 if ((wxdobj_is_active(pobj)) && (ObjectSelectableInState(pobj))) {
2115 d = wxdobj_distance_to_point(pobj, &m_ptMousePosRaw);
2116 if (
2117 (0.0 < d)
2118 && ((0.0 > min) || (d < min))
2119 && (d < 2.0 * (double)(drawco->m_uGridSnap))
2120 ) {
2121 min = d;
2122 back = pobj;
2123 }
2124 }
2125 }
2126 } while (NULL != pobj);
2127 if ((gr) && (NULL != back)) {
2128 while (NULL != back->pa) { back = back->pa; }
2129 }
2130 return back;
2131 }
2132
2133
2134
2135 void
RequireRedraw(int level)2136 WxdkdrawFrame::RequireRedraw(int level)
2137 {
2138 wxdobj_drw_require_redraw(m_pDrw, level);
2139 drawco->Refresh();
2140 Update();
2141 }
2142
2143
2144
2145 void
UpdateTextForFont(Wxd_object_t * pobj,bool bRedraw)2146 WxdkdrawFrame::UpdateTextForFont(Wxd_object_t *pobj, bool bRedraw)
2147 {
2148 Wxd_font_t *pfont;
2149 bool hasf;
2150
2151 hasf = (NULL != (pobj->det).t.font);
2152 (pobj->det).t.font = pfont = FindFont((pobj->det).t.find,(pobj->det).t.fsz);
2153 if (NULL != pfont) {
2154 UpdateOneFont(pfont);
2155 }
2156 if (hasf) {
2157 wxdobj_remove_unused_fonts(m_pDrw);
2158 }
2159 if (bRedraw) {
2160 RequireRedraw(WXD_REFRESH_DRAWING);
2161 }
2162
2163 }
2164
2165
2166
2167 void
SetMouseAndStatusTexts(int st)2168 WxdkdrawFrame::SetMouseAndStatusTexts(int st)
2169 {
2170
2171 /* Defaults
2172 */
2173
2174 msgMouseL->SetLabel(sNlWx[7]);
2175 msgMouseM->SetLabel(sNlWx[7]);
2176 msgMouseR->SetLabel(sNlWx[7]);
2177 SetStatusText(sNlWx[7]);
2178 /*
2179 _STATE_ Messages depending on state to enter.
2180 */
2181 switch (st) {
2182 case S_NOOP : {
2183 } break;
2184 case S_DELETE : {
2185 msgMouseR->SetLabel(sTexts[341]);
2186 msgMouseM->SetLabel(sTexts[534]);
2187 } break;
2188 case S_REGION_DELETE : {
2189 msgMouseL->SetLabel(sTexts[532]);
2190 msgMouseR->SetLabel(sTexts[533]);
2191 } break;
2192 case S_MOVE_SELECT : {
2193 msgMouseL->SetLabel(sNlWx[7]);
2194 msgMouseR->SetLabel(sTexts[344]);
2195 } break;
2196 case S_MOVE_PLACE : {
2197 } break;
2198 case S_COPY_SELECT : {
2199 msgMouseL->SetLabel(sNlWx[7]);
2200 msgMouseR->SetLabel(sTexts[372]);
2201 } break;
2202 case S_COPY_PLACE : {
2203 } break;
2204 case S_POLY_FIRST : {
2205 msgMouseL->SetLabel(sTexts[373]);
2206 msgMouseR->SetLabel(sTexts[375]);
2207 SetStatusText(
2208 sTexts[(WXD_OT_POLYLINE == m_iObjToCreate) ? 30 : 32]
2209 );
2210 } break;
2211 case S_POLY_FURTHER : {
2212 msgMouseL->SetLabel(
2213 (IsAcceptablePoint()) ? (sTexts[374]) : (sNlWx[7])
2214 );
2215 msgMouseR->SetLabel(sTexts[376]);
2216 SetStatusText(
2217 sTexts[(WXD_OT_POLYLINE == m_iObjToCreate) ? 30 : 32]
2218 );
2219 } break;
2220 case S_SPLINE_FIRST : {
2221 msgMouseL->SetLabel(sTexts[373]);
2222 msgMouseR->SetLabel(sTexts[375]);
2223 if (WXD_OT_C_SPLINE == m_iObjToCreate) {
2224 SetStatusText(sTexts[m_bSplineInterpolated ? 48 : 44]);
2225 }
2226 else {
2227 SetStatusText(sTexts[m_bSplineInterpolated ? 46 : 42]);
2228 }
2229 } break;
2230 case S_SPLINE_FURTHER : {
2231 msgMouseL->SetLabel(
2232 (IsAcceptablePoint()) ? (sTexts[374]) : (sNlWx[7])
2233 );
2234 msgMouseR->SetLabel(sTexts[376]);
2235 if (WXD_OT_C_SPLINE == m_iObjToCreate) {
2236 SetStatusText(sTexts[m_bSplineInterpolated ? 48 : 44]);
2237 }
2238 else {
2239 SetStatusText(sTexts[m_bSplineInterpolated ? 46 : 42]);
2240 }
2241 } break;
2242 case S_BOX_FIRST : {
2243 msgMouseL->SetLabel(sTexts[377]);
2244 msgMouseR->SetLabel(sTexts[379]);
2245 SetStatusText(sTexts[m_bSplineInterpolated ? 36 : 34]);
2246 } break;
2247 case S_BOX_OPPOSITE : {
2248 msgMouseL->SetLabel(
2249 (IsAcceptablePoint()) ? (sTexts[378]) : (sNlWx[7])
2250 );
2251 msgMouseR->SetLabel(sTexts[379]);
2252 SetStatusText(sTexts[m_bSplineInterpolated ? 36 : 34]);
2253 } break;
2254 case S_CIRCLE_CENTER : {
2255 msgMouseL->SetLabel(sTexts[380]);
2256 msgMouseR->SetLabel(sTexts[383]);
2257 SetStatusText(sTexts[38]);
2258 } break;
2259 case S_CIRCLE_RADIUS : {
2260 msgMouseL->SetLabel(
2261 (IsAcceptablePoint()) ? (sTexts[381]) : (sNlWx[7])
2262 );
2263 msgMouseR->SetLabel(sTexts[382]);
2264 SetStatusText(sTexts[38]);
2265 } break;
2266 case S_ELLIPSE_CENTER : {
2267 msgMouseL->SetLabel(sTexts[380]);
2268 msgMouseR->SetLabel(sTexts[383]);
2269 SetStatusText(sTexts[40]);
2270 } break;
2271 case S_ELLIPSE_CORNER : {
2272 msgMouseL->SetLabel(
2273 (IsAcceptablePoint()) ? (sTexts[384]) : (sNlWx[7])
2274 );
2275 msgMouseR->SetLabel(sTexts[382]);
2276 SetStatusText(sTexts[40]);
2277 } break;
2278 case S_ARC_1 : {
2279 msgMouseL->SetLabel(sTexts[389]);
2280 msgMouseR->SetLabel(sTexts[393]);
2281 SetStatusText(sTexts[(WXD_OT_C_ARC == m_iObjToCreate) ? 388 : 386]);
2282 } break;
2283 case S_ARC_2 : {
2284 msgMouseL->SetLabel(
2285 (IsAcceptablePoint()) ? (sTexts[390]) : (sNlWx[7])
2286 );
2287 msgMouseR->SetLabel(sTexts[392]);
2288 SetStatusText(sTexts[(WXD_OT_C_ARC == m_iObjToCreate) ? 388 : 386]);
2289 } break;
2290 case S_ARC_3 : {
2291 msgMouseL->SetLabel(
2292 (IsAcceptablePoint()) ? (sTexts[391]) : (sNlWx[7])
2293 );
2294 msgMouseR->SetLabel(sTexts[392]);
2295 SetStatusText(sTexts[(WXD_OT_C_ARC == m_iObjToCreate) ? 388 : 386]);
2296 } break;
2297 case S_DOT : {
2298 msgMouseL->SetLabel(sTexts[394]);
2299 msgMouseR->SetLabel(sTexts[395]);
2300 SetStatusText(
2301 sTexts[(WXD_OT_DOT_WHITE == m_iObjToCreate) ? 52 : 50]
2302 );
2303 } break;
2304 case S_TEXT : {
2305 msgMouseL->SetLabel(sTexts[403]);
2306 msgMouseR->SetLabel(sTexts[404]);
2307 SetStatusText(sTexts[54]);
2308 } break;
2309 case S_IMG_1 : {
2310 msgMouseL->SetLabel(sTexts[405]);
2311 msgMouseR->SetLabel(sTexts[408]);
2312 SetStatusText(sTexts[56]);
2313 } break;
2314 case S_IMG_2 : {
2315 msgMouseL->SetLabel(
2316 (IsAcceptablePoint()) ? (sTexts[406]) : (sNlWx[7])
2317 );
2318 msgMouseR->SetLabel(sTexts[407]);
2319 SetStatusText(sTexts[56]);
2320 } break;
2321 case S_LIBELEM_PLACE : {
2322 msgMouseL->SetLabel(sTexts[411]);
2323 msgMouseR->SetLabel(sTexts[412]);
2324 SetStatusText(sTexts[58]);
2325 } break;
2326 case S_MOVEPT_SELECT : {
2327 msgMouseL->SetLabel(
2328 (NULL != m_pCurrent) ? (sTexts[418]) : (sNlWx[7])
2329 );
2330 msgMouseR->SetLabel(sTexts[420]);
2331 SetStatusText(sTexts[421]);
2332 } break;
2333 case S_MOVEPT_PLACE : {
2334 msgMouseL->SetLabel(sTexts[419]);
2335 msgMouseR->SetLabel(sTexts[420]);
2336 SetStatusText(sTexts[421]);
2337 } break;
2338 case S_DELPT : {
2339 msgMouseL->SetLabel(
2340 (NULL != m_pCurrent) ? (sTexts[431]) : (sNlWx[7])
2341 );
2342 msgMouseR->SetLabel(sTexts[432]);
2343 SetStatusText(sTexts[433]);
2344 } break;
2345 case S_ADDPT_SELECT : {
2346 msgMouseL->SetLabel(
2347 (NULL != m_pCurrent) ? (sTexts[435]) : (sNlWx[7])
2348 );
2349 msgMouseR->SetLabel(sTexts[437]);
2350 SetStatusText(sTexts[434]);
2351 } break;
2352 case S_ADDPT_PLACE : {
2353 msgMouseL->SetLabel(
2354 (NULL != m_pCurrent) ? (sTexts[436]) : (sNlWx[7])
2355 );
2356 msgMouseR->SetLabel(sTexts[438]);
2357 SetStatusText(sTexts[434]);
2358 } break;
2359 case S_DRWSZ_SELECT : {
2360 msgMouseL->SetLabel(
2361 (m_bHaveCornerPoint) ? (sTexts[439]) : (sNlWx[7])
2362 );
2363 msgMouseR->SetLabel(sTexts[440]);
2364 SetStatusText(sTexts[441]);
2365 } break;
2366 case S_DRWSZ_PLACE : {
2367 msgMouseL->SetLabel(sTexts[442]);
2368 msgMouseR->SetLabel(sTexts[443]);
2369 SetStatusText(sTexts[441]);
2370 } break;
2371 case S_FLIP : {
2372 msgMouseL->SetLabel(
2373 (NULL != m_pCurrent) ? (sTexts[445]) : (sNlWx[7])
2374 );
2375 msgMouseR->SetLabel(sTexts[446]);
2376 SetStatusText(sTexts[444]);
2377 } break;
2378 case S_GROUP_ONE : {
2379 int num_marked_2 = wxdobj_num_marked_2(m_pDrw);
2380 if (NULL != m_pCurrent) {
2381 msgMouseL->SetLabel(sTexts[
2382 ((wxdobj_is_marked(m_pCurrent,OBJ_MARKER_2))
2383 ? (448) : (447))
2384 ]);
2385 }
2386 else {
2387 msgMouseL->SetLabel(
2388 (2 <= num_marked_2) ? (sTexts[449]) : (sNlWx[7])
2389 );
2390 }
2391 msgMouseR->SetLabel(sTexts[(2<= num_marked_2) ? (450) : (451)]);
2392 SetStatusText(sTexts[452]);
2393 } break;
2394 case S_UNGROUP : {
2395 msgMouseL->SetLabel(
2396 ((NULL != m_pCurrent) ? (sTexts[454]) : (sNlWx[7]))
2397 );
2398 msgMouseR->SetLabel(sTexts[455]);
2399 SetStatusText(sTexts[453]);
2400 } break;
2401 case S_GROUP_RECT_1 : {
2402 msgMouseL->SetLabel(sTexts[456]);
2403 msgMouseR->SetLabel(sTexts[451]);
2404 SetStatusText(sTexts[457]);
2405 } break;
2406 case S_GROUP_RECT_2 : {
2407 msgMouseL->SetLabel(sTexts[449]);
2408 msgMouseR->SetLabel(sTexts[450]);
2409 SetStatusText(sTexts[457]);
2410 } break;
2411 case S_DETAILS : case S_DETAILS_2 : {
2412 msgMouseL->SetLabel(
2413 (NULL != m_pCurrent) ? (sTexts[459]) : (sNlWx[7])
2414 );
2415 msgMouseR->SetLabel(sTexts[460]);
2416 SetStatusText(sTexts[458]);
2417 } break;
2418 case S_CONVERT : {
2419 switch ( (int)m_iObjToCreate ) {
2420 case WXD_OT_POLYLINE : {
2421 SetStatusText(sTexts[546]);
2422 } break;
2423 case WXD_OT_POLYGON : {
2424 SetStatusText(sTexts[545]);
2425 } break;
2426 case WXD_OT_C_SPLINE: {
2427 if (m_bSplineInterpolated) {
2428 SetStatusText(sTexts[547]);
2429 }
2430 else {
2431 SetStatusText(sTexts[550]);
2432 }
2433 } break;
2434 case WXD_OT_O_SPLINE : {
2435 if (m_bSplineInterpolated) {
2436 SetStatusText(sTexts[166]);
2437 }
2438 else {
2439 SetStatusText(sTexts[551]);
2440 }
2441 } break;
2442 case WXD_OT_C_ARC : {
2443 SetStatusText(sTexts[548]);
2444 } break;
2445 case WXD_OT_O_ARC : {
2446 SetStatusText(sTexts[549]);
2447 } break;
2448 case WXD_OT_DOT_FILLED : {
2449 SetStatusText(sTexts[553]);
2450 } break;
2451 case WXD_OT_DOT_WHITE : {
2452 SetStatusText(sTexts[552]);
2453 } break;
2454 }
2455 msgMouseL->SetLabel(
2456 (NULL != m_pCurrent) ? (sTexts[554]) : (sNlWx[7])
2457 );
2458 msgMouseR->SetLabel(sTexts[555]);
2459 } break;
2460 case S_ROTATE : {
2461 msgMouseL->SetLabel(
2462 (NULL != m_pCurrent) ? (sTexts[572]) : (sNlWx[7])
2463 );
2464 msgMouseR->SetLabel(sTexts[573]);
2465 SetStatusText(sTexts[(m_bSplineInterpolated) ? 571 : 570]);
2466 } break;
2467 case S_MOD_SPLINE : {
2468 msgMouseL->SetLabel(
2469 (NULL != m_pCurrent) ? (sTexts[622]) : (sNlWx[7])
2470 );
2471 msgMouseR->SetLabel(sTexts[623]);
2472 SetStatusText(sTexts[624]);
2473 } break;
2474 default : {
2475 } break;
2476 }
2477 /*
2478 Refresh widgets and update window
2479 */
2480 msgMouseL->Refresh();
2481 msgMouseM->Refresh();
2482 msgMouseR->Refresh();
2483 m_bUpdate = true;
2484
2485 }
2486
2487
2488
2489
2490 /* vim: set ai sw=4 ts=4 : */
2491
2492