Mercurial > ~dholland > hg > ag > index.cgi
comparison anagram/vaclgui/vaclgui.cpp @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:13d2b8934445 |
---|---|
1 /* | |
2 * AnaGram, A System for Syntax Directed Programming | |
3 * Copyright 1997-2002 Parsifal Software. All Rights Reserved. | |
4 * See the file COPYING for license and usage terms. | |
5 * | |
6 * vaclgui.cpp | |
7 */ | |
8 | |
9 //#include <iaccel.hpp> | |
10 #include <iapp.hpp> | |
11 #include <icoordsy.hpp> | |
12 #include <iexcept.hpp> | |
13 #include <ifont.hpp> | |
14 //#include <igroupbx.hpp> | |
15 #include <iiconctl.hpp> | |
16 //#include <iinfoa.hpp> | |
17 #include <imsgbox.hpp> | |
18 #include <ipainevt.hpp> | |
19 #include <ipainhdr.hpp> | |
20 //#include <iprofile.hpp> | |
21 #include <irefcnt.hpp> | |
22 | |
23 #include "action.h" | |
24 #include "agcstack.h" | |
25 #include "aglib.h" | |
26 #include "agrect.hpp" | |
27 #include "agstring.h" | |
28 #include "assert.h" | |
29 #include "engdef.h" | |
30 #include "ctrlpanel.hpp" | |
31 #include "base.h" | |
32 #include "bpu.h" | |
33 #include "help.h" | |
34 #include "multiline.hpp" | |
35 #include "operations.h" | |
36 #include "textfile.h" | |
37 #include "sums-defs.h" | |
38 #include "vaclgui-res.h" | |
39 #include "vaclgui.hpp" | |
40 #include "version.h" | |
41 | |
42 //#define INCLUDE_LOGGING | |
43 #include "log.h" | |
44 | |
45 | |
46 #define DLL | |
47 | |
48 | |
49 ActionWindow *pActionWindow = 0; | |
50 | |
51 IPoint cascadeIncrement; | |
52 IPoint cascadeOffset(0,0); | |
53 IPoint cascadeOrigin(0,0); | |
54 AgString commandLineFile; | |
55 IPointerHandle iconHandle; | |
56 AgAction idAction; | |
57 text_file inputFile; | |
58 IFont menuFont; | |
59 int messageBoxShowing = 0; | |
60 | |
61 | |
62 // declared in base.h | |
63 int nextChildId(void) { | |
64 //LOGSECTION("nextChildId"); | |
65 static int next = 0x1000; | |
66 //LOGV(next); | |
67 return next++; | |
68 } | |
69 | |
70 void messageBeep() { | |
71 LOGSECTION("messageBeep"); | |
72 MessageBeep(MB_ICONEXCLAMATION); | |
73 } | |
74 | |
75 AgQuadrant findQuadrant(IWindow *w) { | |
76 RECT r; | |
77 SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); | |
78 AgRectangle desktop(r); | |
79 cint sz = desktop.size()/2; | |
80 AgQuadrant quad = upperLeft; | |
81 AgRectangle wRect(w); | |
82 int i; | |
83 int area[4] = {0, 0, 0, 0}; | |
84 for (i = 0; i < 4; i++) { | |
85 AgQuadrant corner = (AgQuadrant) i; | |
86 AgQuadrant quadrant = (AgQuadrant) (i^3); | |
87 AgRectangle test(desktop.position(corner), sz, quadrant); | |
88 area[i] = test.intersection(wRect).area(); | |
89 if (area[i] > area[quad]) { | |
90 quad = (AgQuadrant) i; | |
91 } | |
92 } | |
93 return quad; | |
94 } | |
95 | |
96 static const struct { | |
97 AgQuadrant corner, quadrant; | |
98 } placement[8] = { | |
99 { lowerLeft, lowerRight }, | |
100 { lowerRight, lowerLeft }, | |
101 { upperLeft, upperRight }, | |
102 { upperRight, upperLeft }, | |
103 { upperRight, lowerRight }, | |
104 { lowerRight, upperRight }, | |
105 { upperLeft, lowerLeft }, | |
106 { lowerLeft, upperLeft } | |
107 }; | |
108 | |
109 static cint positionWindow(cint measure, LayoutRef reference, cint sz) { | |
110 LOGSECTION("positionWindow"); | |
111 int i; | |
112 int area[8]; | |
113 AgRectangle test[8]; | |
114 for (i = 0; i < 8; i++) { | |
115 AgQuadrant corner = placement[i].corner; | |
116 AgQuadrant quadrant = placement[i].quadrant; | |
117 LOGV(i) LCV(corner) LCV(quadrant); | |
118 | |
119 test[i] = AgRectangle(reference.position(corner), sz, quadrant); | |
120 LOGV(reference.position(corner)); | |
121 LOGV(test[i].position()); | |
122 test[i].limit(measure); | |
123 LOGV(test[i].position()); | |
124 area[i] = reference.overlap(test[i]); | |
125 LOGV(test[i].position()) LCV(test[i].size()) LCV(area[i]); | |
126 } | |
127 int minArea = area[0]; | |
128 int optimalPlacement = 0; | |
129 for (i = 1; i < 8; i++) { | |
130 if (area[i] >= minArea) { | |
131 continue; | |
132 } | |
133 minArea = area[i]; | |
134 optimalPlacement = i; | |
135 } | |
136 LOGV(minArea) LCV(optimalPlacement); | |
137 return test[optimalPlacement].position(upperLeft); | |
138 } | |
139 | |
140 IRectangle adjustPos(IRectangle &r) { | |
141 RECT rd; | |
142 SystemParametersInfo(SPI_GETWORKAREA, 0, &rd, 0); | |
143 IRectangle desktop(rd.left, rd.top, rd.right, rd.bottom); | |
144 ISize newSize = r.size().minimum(desktop.size()); | |
145 newSize = newSize.maximum(ISize(100, 100)); | |
146 r.sizeTo(newSize); | |
147 IPoint where = r.maxXMaxY().minimum(desktop.maxXMaxY()); | |
148 where -= newSize; | |
149 r.moveTo(where); | |
150 where = r.minXMinY().maximum(IPoint(0, 0)); | |
151 r.moveTo(where); | |
152 return r; | |
153 } | |
154 | |
155 class Damaged : public AgFrame { | |
156 private: | |
157 MultiLineText message; | |
158 | |
159 public: | |
160 Damaged(const char *failure); | |
161 ~Damaged(); | |
162 void showme(); | |
163 }; | |
164 | |
165 Damaged::Damaged(const char *failure) | |
166 : AgFrame(IFrameWindow::border | |
167 | dialogBackground | |
168 | IFrameWindow::windowList | |
169 | IFrameWindow::systemMenu) | |
170 , message(this) | |
171 { | |
172 LOGSECTION("Damaged"); | |
173 AgString f1 = "Initialization failure: "; | |
174 AgString f2 = failure; | |
175 AgString f3 = code_segment("broken"); | |
176 AgString msg = f1.concat(f2).concat("\n\v").concat(f3); | |
177 LOGV(msg); | |
178 message.setText(msg.pointer()); | |
179 IFont textFont = IFont("Arial", 9); | |
180 message.setFont(textFont); | |
181 int leading = textFont.maxSize().height() + textFont.externalLeading(); | |
182 LOGV(leading); | |
183 message.setVTab(leading/2); | |
184 } | |
185 | |
186 Damaged::~Damaged() { | |
187 pActionWindow->close(); | |
188 } | |
189 | |
190 void Damaged::showme() { | |
191 LOGSECTION("Damaged::show"); | |
192 ISize frameSize = frameRectFor(IRectangle(message.minimumSize())).size(); | |
193 LOGV(frameSize.asString()); | |
194 setClient(&message); | |
195 sizeTo(frameSize); | |
196 IPoint where = (IPair) place(IWindow::desktopWindow()->size(), | |
197 frameSize, 11); | |
198 LOGV(where.asString()); | |
199 moveTo(where); | |
200 show().setFocus(); | |
201 } | |
202 | |
203 class SplashTimer : public ITimerFn { | |
204 private: | |
205 IFrameWindow *window; | |
206 ITimer &timer; | |
207 AgAction finish; | |
208 | |
209 public: | |
210 SplashTimer(IFrameWindow *, ITimer &); | |
211 SplashTimer(IFrameWindow *, ITimer &, AgAction); | |
212 void timerExpired(unsigned long timerId); | |
213 }; | |
214 | |
215 SplashTimer::SplashTimer(IFrameWindow *window_, | |
216 ITimer &timer_) | |
217 : window(window_) | |
218 , timer(timer_) | |
219 {} | |
220 | |
221 SplashTimer::SplashTimer(IFrameWindow *window_, | |
222 ITimer &timer_, | |
223 AgAction f) | |
224 : window(window_) | |
225 , timer(timer_) | |
226 , finish(f) | |
227 {} | |
228 | |
229 void SplashTimer::timerExpired(unsigned long) { | |
230 LOGSECTION("SplashTimer::timerExpired"); | |
231 timer.stop(); | |
232 window->close(); | |
233 LOGS("splash window closed"); | |
234 finish.performDeferred(); | |
235 } | |
236 | |
237 class ReleaseSplash | |
238 : public IFrameWindow | |
239 , public IPaintHandler | |
240 { | |
241 private: | |
242 ISetCanvas canvas; | |
243 ISetCanvas top; | |
244 IIconControl myicon; | |
245 IStaticText logo; | |
246 ICanvas balance; | |
247 IStaticText progName; | |
248 MultiLineText copyright; | |
249 //IStaticText licenseBox; | |
250 //MultiLineText licensee; | |
251 static ITimer timer; | |
252 | |
253 public: | |
254 ReleaseSplash(); | |
255 ~ReleaseSplash(); | |
256 Boolean paintWindow(IPaintEvent &event); | |
257 static void makeReleaseSplash(); | |
258 }; | |
259 | |
260 ReleaseSplash::~ReleaseSplash() { | |
261 IPaintHandler::stopHandlingEventsFor(&canvas); | |
262 IPaintHandler::stopHandlingEventsFor(&top); | |
263 IPaintHandler::stopHandlingEventsFor(&balance); | |
264 } | |
265 | |
266 Boolean ReleaseSplash::paintWindow(IPaintEvent &event) { | |
267 LOGSECTION("ReleaseSplash::paintWindow"); | |
268 LOGV(event.rect().asString()); | |
269 event.clearBackground(IGUIColor::dialogBgnd); | |
270 return false; | |
271 } | |
272 | |
273 ITimer ReleaseSplash::timer; | |
274 | |
275 ReleaseSplash::ReleaseSplash() | |
276 : IFrameWindow(nextChildId(), | |
277 AgFrame::frameParent, | |
278 AgFrame::frameOwner, | |
279 IRectangle(), | |
280 dialogBackground | dialogBorder) | |
281 , canvas(nextChildId(),this, this, IRectangle(), | |
282 ISetCanvas::verticalDecks | |
283 | ISetCanvas::packTight | |
284 | ISetCanvas::centerAlign | |
285 | IWindow::clipChildren | |
286 | IWindow::visible) | |
287 , top(nextChildId(), &canvas, &canvas, IRectangle(), | |
288 ISetCanvas::horizontalDecks | |
289 | ISetCanvas::packTight | |
290 | ISetCanvas::centerVerticalAlign | |
291 | IWindow::clipChildren | |
292 | IWindow::visible | |
293 ) | |
294 , myicon(nextChildId(), &top, &top, iconHandle,IRectangle(), | |
295 IIconControl::classDefaultStyle | IIconControl::fillBackground) | |
296 , logo(nextChildId(), &top, &top) | |
297 , balance(nextChildId(), &top, &top) | |
298 , progName(nextChildId(), &canvas, &canvas) | |
299 , copyright(&canvas) | |
300 //, licenseBox(nextChildId(), &canvas, &canvas) | |
301 //, licensee(&canvas, IRectangle(), | |
302 // IStaticText::classDefaultStyle | |
303 // | IStaticText::border3D) | |
304 { | |
305 IPaintHandler::handleEventsFor(&canvas); | |
306 IPaintHandler::handleEventsFor(&top); | |
307 IPaintHandler::handleEventsFor(&balance); | |
308 //myicon.setBackgroundColor(IGUIColor::dialogBgnd); | |
309 logo.setFont(IFont("Arial", 20)); | |
310 logo.font().setBold(); | |
311 logo.setText("AnaGram"); | |
312 IFont textFont("Arial",8); | |
313 progName.setFont(IFont("Arial",12)); | |
314 progName.font().setBold(); | |
315 progName.setText(BASEVERSIONSTRING); | |
316 copyright.setFont(IFont("Arial", 8)); | |
317 // | |
318 // This used to have a literal iso-latin-1 copyright char in it. | |
319 // However, I've been compelled to remove it, including even from | |
320 // this comment, not because any compiler rejects it (though they | |
321 // would technically be within their rights) but because Red Hat's | |
322 // foolish and reckless default locale settings and/or Red Hat's | |
323 // custom patch set seem to render Red Hat-based versions of Emacs | |
324 // incapable of touching the file without mangling it. | |
325 // | |
326 // I am not terribly surprised to discover this. RH seems to do a | |
327 // lot of work to make sure they can put the 'sux' in 'linsux'. | |
328 // | |
329 // (i18n is a fine thing, but it has to *work*, especially since | |
330 // non-English speakers can't just shut it all off and do without.) | |
331 // | |
332 // Fortunately, the copyright character is not legally necessary. | |
333 // | |
334 copyright.setText("Copyright 1993-2002 Parsifal Software. " | |
335 "All Rights Reserved.\n" | |
336 "Copyright 2006, 2007 David A. Holland. " | |
337 "All Rights Reserved.\n" | |
338 "\n" | |
339 "This version of AnaGram is free software.\n" | |
340 "There is NO WARRANTY.\n" | |
341 "See \"license\" in the help system for details.\n"); | |
342 copyright.setMinimumSize(copyright.calcMinimumSize()); | |
343 | |
344 //licenseBox.setFont(textFont); | |
345 //licenseBox.setText("This copy of AnaGram is registered to:"); | |
346 | |
347 //licensee.setFont(textFont); | |
348 //licensee.setText(licenseeText().pointer()); | |
349 //LOGV(licenseBox.font().name()) LCV(licenseBox.font().pointSize()); | |
350 //LOGV(licensee.font().name()) LCV(licensee.font().pointSize()); | |
351 //int leading = textFont.maxSize().height() + textFont.externalLeading(); | |
352 //licensee.setMargin(leading, leading); | |
353 //licensee.setVTab(leading/2); | |
354 | |
355 canvas.setDeckCount(1); | |
356 top.setDeckCount(1); | |
357 setClient(&canvas); | |
358 //myicon.sizeTo(myicon.minimumSize()); | |
359 //balance.sizeTo(myicon.minimumSize()); | |
360 balance.setMinimumSize(myicon.minimumSize()); | |
361 //logo.sizeTo(logo.minimumSize()); | |
362 //top.sizeTo(top.minimumSize()); | |
363 //licenseBox.sizeTo(licenseBox.minimumSize()); | |
364 | |
365 //ISize minSize = licenseBox.minimumSize(); | |
366 //ISize licenseeSize = licensee.calcMinimumSize(); | |
367 //if (licenseeSize.width() < minSize.width()) { | |
368 // licenseeSize.setWidth(minSize.width()); | |
369 //} | |
370 //licensee.setMinimumSize(licenseeSize); | |
371 | |
372 ISize size = canvas.minimumSize(); | |
373 canvas.sizeTo(size); | |
374 IRectangle r = frameRectFor(IRectangle(size)); | |
375 ISize windowSize = r.size(); | |
376 sizeTo(windowSize); | |
377 ISize desktopSize = IWindow::desktopWindow()->size(); | |
378 ISize margin = (desktopSize - windowSize)/2; | |
379 moveTo((IPoint) margin); | |
380 } | |
381 | |
382 void ReleaseSplash::makeReleaseSplash() { | |
383 LOGSECTION("Splash::makeReleaseSplash"); | |
384 ReleaseSplash *window = new ReleaseSplash; | |
385 window->setAutoDeleteObject(); | |
386 window->show().refresh(IWindow::immediate); | |
387 #ifdef INCLUDE_LOGGING | |
388 int posFlag = | |
389 #endif | |
390 SetWindowPos(window->handle(), | |
391 HWND_TOPMOST, | |
392 0,0,0,0, | |
393 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); | |
394 #ifdef INCLUDE_LOGGING | |
395 if (posFlag == 0) { | |
396 LOGV(GetLastError()); | |
397 } | |
398 #endif | |
399 | |
400 IReference<ITimerFn> timerFn(new SplashTimer(window, timer)); | |
401 window->timer.start(timerFn, 4000); | |
402 } | |
403 | |
404 void bailOut(const char *problem) { | |
405 LOGSECTION("bailOut"); | |
406 LOGV(problem); | |
407 LOGSTACK; | |
408 if (controlPanel->timer.isStarted()) { | |
409 controlPanel->timer.stop(); | |
410 } | |
411 IMessageBox messageBox(0); | |
412 messageBox.setTitle("AnaGram"); | |
413 char msg[200]; | |
414 sprintf(msg, "%s\nUnexpected program termination", problem); | |
415 messageBoxShowing++; | |
416 messageBox.show(msg, IMessageBox::catastrophic); | |
417 messageBoxShowing--; | |
418 abort(); | |
419 } | |
420 | |
421 //void abortProgram() { | |
422 // pActionWindow->close(); | |
423 //} | |
424 | |
425 static void setup() { | |
426 LOGSECTION("setup"); | |
427 | |
428 init_parser(); | |
429 | |
430 const char *failure = checksums_ok(); | |
431 LOGS("checksums_ok call returned"); | |
432 LOGV(failure); | |
433 | |
434 if (failure) { | |
435 Damaged *failwindow = new Damaged(failure); | |
436 failwindow->setAutoDeleteObject(); | |
437 | |
438 idAction = actionObject(failwindow, Damaged::showme); | |
439 } | |
440 else { | |
441 idAction = actionObject(ControlPanel::makeControlPanel); | |
442 } | |
443 | |
444 idAction.performDeferred(); | |
445 } | |
446 | |
447 void agGui(char *f) { | |
448 LOGSECTION("agGui"); | |
449 LOGV((void *) agGui); | |
450 | |
451 AgString file(f); | |
452 try { | |
453 commandLineFile = file; | |
454 LOGV(commandLineFile); | |
455 ICoordinateSystem::setApplicationOrientation( | |
456 ICoordinateSystem::originUpperLeft); | |
457 | |
458 iconHandle = IResourceLibrary().loadIcon(IDI_ICON, 0); | |
459 ActionWindow actionWindow; | |
460 pActionWindow = &actionWindow; | |
461 AgAction::startup(); | |
462 AgFrame::frameOwner = pActionWindow; | |
463 AgFrame::frameParent = IWindow::desktopWindow(); | |
464 engdef_init(); | |
465 help_init(); | |
466 defer(ReleaseSplash::makeReleaseSplash); | |
467 defer(setup); | |
468 | |
469 LOGS("Starting program"); | |
470 IApplication::current().run(); | |
471 LOGS("Program complete"); | |
472 } | |
473 catch(IException & IFLOG(ie)) { | |
474 AgFrame::windowRegistry.clearActive(); | |
475 LOGSECTION_ON("catch(IException)"); | |
476 LOGSTACK; | |
477 LOGEXCEPTION(ie); | |
478 LOGS("Returned from logging exception"); | |
479 assert(0); | |
480 /* | |
481 IMessageBox messageBox(0); | |
482 LOGS("Created message box"); | |
483 messageBox.setTitle("AnaGram"); | |
484 LOGS("title set"); | |
485 messageBox.show( | |
486 "AnaGram: Unexpected program termination", | |
487 IMessageBox::catastrophic); | |
488 LOGS("Returned from showing message"); | |
489 */ | |
490 } | |
491 catch(Problem p) { | |
492 AgFrame::windowRegistry.clearActive(); | |
493 LOGSECTION("catch(Problem)"); | |
494 LOGV(p.msg); | |
495 LOGSTACK; | |
496 assert(0); | |
497 /* | |
498 IMessageBox messageBox(0); | |
499 messageBox.setTitle("AnaGram"); | |
500 char msg[200]; | |
501 sprintf(msg, "Unexpected program termination\n%s", p.msg); | |
502 messageBoxShowing++; | |
503 messageBox.show(msg, IMessageBox::catastrophic); | |
504 messageBoxShowing--; | |
505 */ | |
506 } | |
507 catch(...) { | |
508 AgFrame::windowRegistry.clearActive(); | |
509 LOGSECTION_ON("catch(...)"); | |
510 LOGSTACK; | |
511 assert(0); | |
512 /* | |
513 IMessageBox messageBox(0); | |
514 messageBox.setTitle("AnaGram..."); | |
515 messageBoxShowing++; | |
516 messageBox.show( | |
517 "AnaGram: Unexpected program termination", | |
518 IMessageBox::catastrophic); | |
519 messageBoxShowing--; | |
520 */ | |
521 } | |
522 } | |
523 | |
524 #if 0 /* was: ifndef DLL */ | |
525 | |
526 /**************************************************************/ | |
527 /* historic main() program entry point */ | |
528 /**************************************************************/ | |
529 int main(int argc, char *argv[]) { | |
530 init(argv[0]); | |
531 | |
532 int buildSwitch = 0; | |
533 int i; | |
534 AgString file; | |
535 for (i = 1; i < argc; i++) { | |
536 switch (argv[i][0]) { | |
537 case '/': | |
538 case '-': | |
539 switch (argv[i][1]) { | |
540 case 'b': | |
541 case 'B': | |
542 buildSwitch = 1; | |
543 LOGS("set buildSwitch"); | |
544 break; | |
545 } | |
546 break; | |
547 default: | |
548 file = argv[i]; | |
549 break; | |
550 } | |
551 } | |
552 if (buildSwitch) { | |
553 return commandLineBuild(file.pointer()); | |
554 } | |
555 agGui(file.pointer()); | |
556 return 0; | |
557 } | |
558 | |
559 #endif /* 0 */ | |
560 | |
561 IPoint placeOnDesktop(ISize s, int ij) { | |
562 RECT r; | |
563 SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); | |
564 ISize desktopSize(r.right - r.left, r.bottom - r.top); | |
565 return (IPair) place(desktopSize, s, ij); | |
566 } | |
567 | |
568 IPoint placeRelative(ISize s, IWindow *window) { | |
569 RECT r; | |
570 SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); | |
571 ISize desktopSize(r.right - r.left, r.bottom - r.top); | |
572 | |
573 AgRectangle ref(window->position(), window->size()); | |
574 return (IPair) positionWindow(desktopSize, ref, s); | |
575 } | |
576 | |
577 IPoint placeWindow(ISize s, LayoutRef ref) { | |
578 RECT r; | |
579 SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); | |
580 ISize desktopSize(r.right - r.left, r.bottom - r.top); | |
581 return (IPair) positionWindow(desktopSize, ref, s); | |
582 } | |
583 |