/* * Copyright (c) 1987, 1988, 1989 Stanford University * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Stanford not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Stanford makes no representations about * the suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Implementation of the frame around a squares view. */ #if defined(__cplusplus) #include "sframe.h" #include "squares.h" #include "metaview.h" #include "view.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class SquaresFrame; typedef void (SquaresFrame::*MenuFunc)(); class Command : public MenuItem { public: Command(const char*, Alignment, SquaresFrame*, MenuFunc); virtual void Do(); private: SquaresFrame* frame; MenuFunc func; }; Command::Command( const char* str, Alignment al, SquaresFrame* s, MenuFunc f ) : (str, al) { frame = s; func = f; } void Command::Do() { (frame->*func)(); } struct MenuInfo { const char* str; MenuFunc func; }; #if !defined(__cplusplus) #include "sframe.h" #include "squares.h" #include "metaview.h" #include "view.h" #endif static MenuInfo mainmenu[] = { { "add square", &SquaresFrame::AddSquare }, { "new view", &SquaresFrame::NewView }, { "view setup", &SquaresFrame::ViewSetup }, { "close", &SquaresFrame::Close }, { "quit", &SquaresFrame::Quit }, { nil } }; static MenuInfo adjustmenu[] = { { "zoom in", &SquaresFrame::ZoomIn }, { "zoom out", &SquaresFrame::ZoomOut }, { "normal size", &SquaresFrame::NormalSize }, { "center view", &SquaresFrame::CenterView }, { nil } }; static MenuInfo quitmenu[] = { { "yes, quit", &SquaresFrame::YesQuit }, { "no, don't quit", &SquaresFrame::NoQuit }, { nil } }; SquaresFrame::SquaresFrame (SquaresFrame* f) { view = new SquaresView(f->view->subject); Init(); style = new SquaresMetaView(f->style); MakeFrame(); } SquaresFrame::SquaresFrame (SquaresView* v) { const char* a; view = v; Init(); style = new SquaresMetaView; a = GetAttribute("panner"); style->type = (a == nil) ? AdjustByScrollers : AdjustByPanner; a = GetAttribute("adjustersize"); if (*a == 'm') { style->size = Medium; } else if (*a == 'l') { style->size = Large; } else { style->size = Small; } style->right = (GetAttribute("left") == nil); style->below = (GetAttribute("above") == nil); style->hscroll = (GetAttribute("!hscroll") == nil); style->vscroll = (GetAttribute("!vscroll") == nil); MakeFrame(); } void SquaresFrame::Init () { SetClassName("SquaresFrame"); menu = MakeMenu(new PopupMenu, mainmenu); adjust = MakeMenu(new PopupMenu, adjustmenu); quit = MakeMenu(new PopupMenu, quitmenu); Unref(input); input = updownEvents; input->Reference(); viewport = new Viewport(new Frame(view)); Propagate(false); ++nviews; } SquaresFrame::~SquaresFrame () { delete menu; delete quit; delete style; } Menu* SquaresFrame::MakeMenu(Menu* menu, MenuInfo* item) { for (MenuInfo* i = item; i->str != nil; i++) { menu->Include(new Command(i->str, Center, this, i->func)); } return menu; } void SquaresFrame::MakeFrame () { Scene* p = viewport->Parent(); Interactor* interior; if (p != nil) { p->Remove(viewport); } if (style->type == AdjustByPanner) { interior = PannerFrameInterior(); } else if (style->type == AdjustByScrollers) { interior = ScrollerFrameInterior(); } Insert(interior); } Interactor* SquaresFrame::ScrollerFrameInterior () { Interactor* v = viewport; Tray* t = new Tray; Interactor* hs, *vs; Border* hb, *vb; int size; if (style->size == Small) { size = round(0.15*inches); } else if (style->size == Medium) { size = round(0.20*inches); } else if (style->size == Large) { size = round(0.25*inches); } if (style->vscroll) { vs = new VScroller(viewport, size); vb = new VBorder; if (style->right) { t->HBox(t, v, vb, vs, t); } else { t->HBox(t, vs, vb, v, t); } t->VBox(t, vb, t); } else { t->HBox(t, v, t); } if (style->hscroll) { hs = new HScroller(viewport, size); hb = new HBorder; if (style->below) { t->VBox(t, v, hb, hs, t); } else { t->VBox(t, hs, hb, v, t); } t->HBox(t, hb, t); } else { t->VBox(t, v, t); } if (style->vscroll && style->hscroll) { if (style->below) { t->VBox(t, vs, hb); } else { t->VBox(hb, vs, t); } if (style->right) { t->HBox(t, hs, vb); } else { t->HBox(vb, hs, t); } } else if (style->vscroll) { t->VBox(t, vs, t); } else if (style->hscroll) { t->HBox(t, hs, t); } return t; } Interactor* SquaresFrame::PannerFrameInterior () { Interactor* v = viewport; Tray* t = new Tray(v); int size; if (style->size == Small) { size = 0; } else if (style->size == Medium) { size = round(0.75*inches); } else if (style->size == Large) { size = round(1.0*inches); } t->Align(style->align, new Frame(new Panner(v, size))); t->Propagate(false); return t; } void SquaresFrame::Handle (Event& e) { if (e.eventType == DownEvent) { if (e.button == RIGHTMOUSE) { adjust->Popup(e); } else { menu->Popup(e); } } } void SquaresFrame::AddSquare() { view->subject->Add(); } void SquaresFrame::NewView() { GetWorld()->InsertToplevel(new SquaresFrame(this), this); } void SquaresFrame::ViewSetup() { Event e; Poll(e); e.target = this; if (style->Popup(e)) { MakeFrame(); Change(); } } void SquaresFrame::Close() { if (nviews == 1) { Event e; Poll(e); quit->Popup(e); } else { --nviews; delete this; } } void SquaresFrame::Quit() { Event e; Poll(e); quit->Popup(e); } void SquaresFrame::ZoomIn() { viewport->ZoomBy(2.0, 2.0); } void SquaresFrame::ZoomOut() { viewport->ZoomBy(0.5, 0.5); } void SquaresFrame::NormalSize() { viewport->ZoomTo(1.0, 1.0); } void SquaresFrame::CenterView() { viewport->ScrollTo(0.5, 0.5); } void SquaresFrame::YesQuit() { exit(0); } void SquaresFrame::NoQuit() { /* nop */ }