Mercurial > ~dholland > hg > ag > index.cgi
view anagram/vaclgui/vaclgui.cpp @ 14:a02e9434072e
Fix friend declaration for gcc10.
XXX: did not check it against the IBM compiler, might end up needing
XXX: to be conditional.
author | David A. Holland |
---|---|
date | Tue, 31 May 2022 00:59:42 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
/* * AnaGram, A System for Syntax Directed Programming * Copyright 1997-2002 Parsifal Software. All Rights Reserved. * See the file COPYING for license and usage terms. * * vaclgui.cpp */ //#include <iaccel.hpp> #include <iapp.hpp> #include <icoordsy.hpp> #include <iexcept.hpp> #include <ifont.hpp> //#include <igroupbx.hpp> #include <iiconctl.hpp> //#include <iinfoa.hpp> #include <imsgbox.hpp> #include <ipainevt.hpp> #include <ipainhdr.hpp> //#include <iprofile.hpp> #include <irefcnt.hpp> #include "action.h" #include "agcstack.h" #include "aglib.h" #include "agrect.hpp" #include "agstring.h" #include "assert.h" #include "engdef.h" #include "ctrlpanel.hpp" #include "base.h" #include "bpu.h" #include "help.h" #include "multiline.hpp" #include "operations.h" #include "textfile.h" #include "sums-defs.h" #include "vaclgui-res.h" #include "vaclgui.hpp" #include "version.h" //#define INCLUDE_LOGGING #include "log.h" #define DLL ActionWindow *pActionWindow = 0; IPoint cascadeIncrement; IPoint cascadeOffset(0,0); IPoint cascadeOrigin(0,0); AgString commandLineFile; IPointerHandle iconHandle; AgAction idAction; text_file inputFile; IFont menuFont; int messageBoxShowing = 0; // declared in base.h int nextChildId(void) { //LOGSECTION("nextChildId"); static int next = 0x1000; //LOGV(next); return next++; } void messageBeep() { LOGSECTION("messageBeep"); MessageBeep(MB_ICONEXCLAMATION); } AgQuadrant findQuadrant(IWindow *w) { RECT r; SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); AgRectangle desktop(r); cint sz = desktop.size()/2; AgQuadrant quad = upperLeft; AgRectangle wRect(w); int i; int area[4] = {0, 0, 0, 0}; for (i = 0; i < 4; i++) { AgQuadrant corner = (AgQuadrant) i; AgQuadrant quadrant = (AgQuadrant) (i^3); AgRectangle test(desktop.position(corner), sz, quadrant); area[i] = test.intersection(wRect).area(); if (area[i] > area[quad]) { quad = (AgQuadrant) i; } } return quad; } static const struct { AgQuadrant corner, quadrant; } placement[8] = { { lowerLeft, lowerRight }, { lowerRight, lowerLeft }, { upperLeft, upperRight }, { upperRight, upperLeft }, { upperRight, lowerRight }, { lowerRight, upperRight }, { upperLeft, lowerLeft }, { lowerLeft, upperLeft } }; static cint positionWindow(cint measure, LayoutRef reference, cint sz) { LOGSECTION("positionWindow"); int i; int area[8]; AgRectangle test[8]; for (i = 0; i < 8; i++) { AgQuadrant corner = placement[i].corner; AgQuadrant quadrant = placement[i].quadrant; LOGV(i) LCV(corner) LCV(quadrant); test[i] = AgRectangle(reference.position(corner), sz, quadrant); LOGV(reference.position(corner)); LOGV(test[i].position()); test[i].limit(measure); LOGV(test[i].position()); area[i] = reference.overlap(test[i]); LOGV(test[i].position()) LCV(test[i].size()) LCV(area[i]); } int minArea = area[0]; int optimalPlacement = 0; for (i = 1; i < 8; i++) { if (area[i] >= minArea) { continue; } minArea = area[i]; optimalPlacement = i; } LOGV(minArea) LCV(optimalPlacement); return test[optimalPlacement].position(upperLeft); } IRectangle adjustPos(IRectangle &r) { RECT rd; SystemParametersInfo(SPI_GETWORKAREA, 0, &rd, 0); IRectangle desktop(rd.left, rd.top, rd.right, rd.bottom); ISize newSize = r.size().minimum(desktop.size()); newSize = newSize.maximum(ISize(100, 100)); r.sizeTo(newSize); IPoint where = r.maxXMaxY().minimum(desktop.maxXMaxY()); where -= newSize; r.moveTo(where); where = r.minXMinY().maximum(IPoint(0, 0)); r.moveTo(where); return r; } class Damaged : public AgFrame { private: MultiLineText message; public: Damaged(const char *failure); ~Damaged(); void showme(); }; Damaged::Damaged(const char *failure) : AgFrame(IFrameWindow::border | dialogBackground | IFrameWindow::windowList | IFrameWindow::systemMenu) , message(this) { LOGSECTION("Damaged"); AgString f1 = "Initialization failure: "; AgString f2 = failure; AgString f3 = code_segment("broken"); AgString msg = f1.concat(f2).concat("\n\v").concat(f3); LOGV(msg); message.setText(msg.pointer()); IFont textFont = IFont("Arial", 9); message.setFont(textFont); int leading = textFont.maxSize().height() + textFont.externalLeading(); LOGV(leading); message.setVTab(leading/2); } Damaged::~Damaged() { pActionWindow->close(); } void Damaged::showme() { LOGSECTION("Damaged::show"); ISize frameSize = frameRectFor(IRectangle(message.minimumSize())).size(); LOGV(frameSize.asString()); setClient(&message); sizeTo(frameSize); IPoint where = (IPair) place(IWindow::desktopWindow()->size(), frameSize, 11); LOGV(where.asString()); moveTo(where); show().setFocus(); } class SplashTimer : public ITimerFn { private: IFrameWindow *window; ITimer &timer; AgAction finish; public: SplashTimer(IFrameWindow *, ITimer &); SplashTimer(IFrameWindow *, ITimer &, AgAction); void timerExpired(unsigned long timerId); }; SplashTimer::SplashTimer(IFrameWindow *window_, ITimer &timer_) : window(window_) , timer(timer_) {} SplashTimer::SplashTimer(IFrameWindow *window_, ITimer &timer_, AgAction f) : window(window_) , timer(timer_) , finish(f) {} void SplashTimer::timerExpired(unsigned long) { LOGSECTION("SplashTimer::timerExpired"); timer.stop(); window->close(); LOGS("splash window closed"); finish.performDeferred(); } class ReleaseSplash : public IFrameWindow , public IPaintHandler { private: ISetCanvas canvas; ISetCanvas top; IIconControl myicon; IStaticText logo; ICanvas balance; IStaticText progName; MultiLineText copyright; //IStaticText licenseBox; //MultiLineText licensee; static ITimer timer; public: ReleaseSplash(); ~ReleaseSplash(); Boolean paintWindow(IPaintEvent &event); static void makeReleaseSplash(); }; ReleaseSplash::~ReleaseSplash() { IPaintHandler::stopHandlingEventsFor(&canvas); IPaintHandler::stopHandlingEventsFor(&top); IPaintHandler::stopHandlingEventsFor(&balance); } Boolean ReleaseSplash::paintWindow(IPaintEvent &event) { LOGSECTION("ReleaseSplash::paintWindow"); LOGV(event.rect().asString()); event.clearBackground(IGUIColor::dialogBgnd); return false; } ITimer ReleaseSplash::timer; ReleaseSplash::ReleaseSplash() : IFrameWindow(nextChildId(), AgFrame::frameParent, AgFrame::frameOwner, IRectangle(), dialogBackground | dialogBorder) , canvas(nextChildId(),this, this, IRectangle(), ISetCanvas::verticalDecks | ISetCanvas::packTight | ISetCanvas::centerAlign | IWindow::clipChildren | IWindow::visible) , top(nextChildId(), &canvas, &canvas, IRectangle(), ISetCanvas::horizontalDecks | ISetCanvas::packTight | ISetCanvas::centerVerticalAlign | IWindow::clipChildren | IWindow::visible ) , myicon(nextChildId(), &top, &top, iconHandle,IRectangle(), IIconControl::classDefaultStyle | IIconControl::fillBackground) , logo(nextChildId(), &top, &top) , balance(nextChildId(), &top, &top) , progName(nextChildId(), &canvas, &canvas) , copyright(&canvas) //, licenseBox(nextChildId(), &canvas, &canvas) //, licensee(&canvas, IRectangle(), // IStaticText::classDefaultStyle // | IStaticText::border3D) { IPaintHandler::handleEventsFor(&canvas); IPaintHandler::handleEventsFor(&top); IPaintHandler::handleEventsFor(&balance); //myicon.setBackgroundColor(IGUIColor::dialogBgnd); logo.setFont(IFont("Arial", 20)); logo.font().setBold(); logo.setText("AnaGram"); IFont textFont("Arial",8); progName.setFont(IFont("Arial",12)); progName.font().setBold(); progName.setText(BASEVERSIONSTRING); copyright.setFont(IFont("Arial", 8)); // // This used to have a literal iso-latin-1 copyright char in it. // However, I've been compelled to remove it, including even from // this comment, not because any compiler rejects it (though they // would technically be within their rights) but because Red Hat's // foolish and reckless default locale settings and/or Red Hat's // custom patch set seem to render Red Hat-based versions of Emacs // incapable of touching the file without mangling it. // // I am not terribly surprised to discover this. RH seems to do a // lot of work to make sure they can put the 'sux' in 'linsux'. // // (i18n is a fine thing, but it has to *work*, especially since // non-English speakers can't just shut it all off and do without.) // // Fortunately, the copyright character is not legally necessary. // copyright.setText("Copyright 1993-2002 Parsifal Software. " "All Rights Reserved.\n" "Copyright 2006, 2007 David A. Holland. " "All Rights Reserved.\n" "\n" "This version of AnaGram is free software.\n" "There is NO WARRANTY.\n" "See \"license\" in the help system for details.\n"); copyright.setMinimumSize(copyright.calcMinimumSize()); //licenseBox.setFont(textFont); //licenseBox.setText("This copy of AnaGram is registered to:"); //licensee.setFont(textFont); //licensee.setText(licenseeText().pointer()); //LOGV(licenseBox.font().name()) LCV(licenseBox.font().pointSize()); //LOGV(licensee.font().name()) LCV(licensee.font().pointSize()); //int leading = textFont.maxSize().height() + textFont.externalLeading(); //licensee.setMargin(leading, leading); //licensee.setVTab(leading/2); canvas.setDeckCount(1); top.setDeckCount(1); setClient(&canvas); //myicon.sizeTo(myicon.minimumSize()); //balance.sizeTo(myicon.minimumSize()); balance.setMinimumSize(myicon.minimumSize()); //logo.sizeTo(logo.minimumSize()); //top.sizeTo(top.minimumSize()); //licenseBox.sizeTo(licenseBox.minimumSize()); //ISize minSize = licenseBox.minimumSize(); //ISize licenseeSize = licensee.calcMinimumSize(); //if (licenseeSize.width() < minSize.width()) { // licenseeSize.setWidth(minSize.width()); //} //licensee.setMinimumSize(licenseeSize); ISize size = canvas.minimumSize(); canvas.sizeTo(size); IRectangle r = frameRectFor(IRectangle(size)); ISize windowSize = r.size(); sizeTo(windowSize); ISize desktopSize = IWindow::desktopWindow()->size(); ISize margin = (desktopSize - windowSize)/2; moveTo((IPoint) margin); } void ReleaseSplash::makeReleaseSplash() { LOGSECTION("Splash::makeReleaseSplash"); ReleaseSplash *window = new ReleaseSplash; window->setAutoDeleteObject(); window->show().refresh(IWindow::immediate); #ifdef INCLUDE_LOGGING int posFlag = #endif SetWindowPos(window->handle(), HWND_TOPMOST, 0,0,0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); #ifdef INCLUDE_LOGGING if (posFlag == 0) { LOGV(GetLastError()); } #endif IReference<ITimerFn> timerFn(new SplashTimer(window, timer)); window->timer.start(timerFn, 4000); } void bailOut(const char *problem) { LOGSECTION("bailOut"); LOGV(problem); LOGSTACK; if (controlPanel->timer.isStarted()) { controlPanel->timer.stop(); } IMessageBox messageBox(0); messageBox.setTitle("AnaGram"); char msg[200]; sprintf(msg, "%s\nUnexpected program termination", problem); messageBoxShowing++; messageBox.show(msg, IMessageBox::catastrophic); messageBoxShowing--; abort(); } //void abortProgram() { // pActionWindow->close(); //} static void setup() { LOGSECTION("setup"); init_parser(); const char *failure = checksums_ok(); LOGS("checksums_ok call returned"); LOGV(failure); if (failure) { Damaged *failwindow = new Damaged(failure); failwindow->setAutoDeleteObject(); idAction = actionObject(failwindow, Damaged::showme); } else { idAction = actionObject(ControlPanel::makeControlPanel); } idAction.performDeferred(); } void agGui(char *f) { LOGSECTION("agGui"); LOGV((void *) agGui); AgString file(f); try { commandLineFile = file; LOGV(commandLineFile); ICoordinateSystem::setApplicationOrientation( ICoordinateSystem::originUpperLeft); iconHandle = IResourceLibrary().loadIcon(IDI_ICON, 0); ActionWindow actionWindow; pActionWindow = &actionWindow; AgAction::startup(); AgFrame::frameOwner = pActionWindow; AgFrame::frameParent = IWindow::desktopWindow(); engdef_init(); help_init(); defer(ReleaseSplash::makeReleaseSplash); defer(setup); LOGS("Starting program"); IApplication::current().run(); LOGS("Program complete"); } catch(IException & IFLOG(ie)) { AgFrame::windowRegistry.clearActive(); LOGSECTION_ON("catch(IException)"); LOGSTACK; LOGEXCEPTION(ie); LOGS("Returned from logging exception"); assert(0); /* IMessageBox messageBox(0); LOGS("Created message box"); messageBox.setTitle("AnaGram"); LOGS("title set"); messageBox.show( "AnaGram: Unexpected program termination", IMessageBox::catastrophic); LOGS("Returned from showing message"); */ } catch(Problem p) { AgFrame::windowRegistry.clearActive(); LOGSECTION("catch(Problem)"); LOGV(p.msg); LOGSTACK; assert(0); /* IMessageBox messageBox(0); messageBox.setTitle("AnaGram"); char msg[200]; sprintf(msg, "Unexpected program termination\n%s", p.msg); messageBoxShowing++; messageBox.show(msg, IMessageBox::catastrophic); messageBoxShowing--; */ } catch(...) { AgFrame::windowRegistry.clearActive(); LOGSECTION_ON("catch(...)"); LOGSTACK; assert(0); /* IMessageBox messageBox(0); messageBox.setTitle("AnaGram..."); messageBoxShowing++; messageBox.show( "AnaGram: Unexpected program termination", IMessageBox::catastrophic); messageBoxShowing--; */ } } #if 0 /* was: ifndef DLL */ /**************************************************************/ /* historic main() program entry point */ /**************************************************************/ int main(int argc, char *argv[]) { init(argv[0]); int buildSwitch = 0; int i; AgString file; for (i = 1; i < argc; i++) { switch (argv[i][0]) { case '/': case '-': switch (argv[i][1]) { case 'b': case 'B': buildSwitch = 1; LOGS("set buildSwitch"); break; } break; default: file = argv[i]; break; } } if (buildSwitch) { return commandLineBuild(file.pointer()); } agGui(file.pointer()); return 0; } #endif /* 0 */ IPoint placeOnDesktop(ISize s, int ij) { RECT r; SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); ISize desktopSize(r.right - r.left, r.bottom - r.top); return (IPair) place(desktopSize, s, ij); } IPoint placeRelative(ISize s, IWindow *window) { RECT r; SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); ISize desktopSize(r.right - r.left, r.bottom - r.top); AgRectangle ref(window->position(), window->size()); return (IPair) positionWindow(desktopSize, ref, s); } IPoint placeWindow(ISize s, LayoutRef ref) { RECT r; SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); ISize desktopSize(r.right - r.left, r.bottom - r.top); return (IPair) positionWindow(desktopSize, ref, s); }