/* * This file explores the effects of redefining Box::Reconfig. The goal of * this exploration is to make Box::Reconfig public, since it is defined as * protected in the InterViews library version of Box. In so doing, we could * then use Box::Reconfig to notify a particular Box instance that something * has changed within it, and the box should therefore be redrawn on the * screen. * * The moral of the exploration is that specializaing Box::Reconfig to be * public doesnt do anything useful. Rather, the simple (and proper) way to * tell a box that it should redraw itself is with the already public function * Box::Change. * * So why did we do this exploration in the first place? To boldy go where no * Box has gone before! (Actually, we were a little confused. We saw the * description of Interactor::Reconfig and figured that's the way to tell any * interactor to change itself. We then went off on the specialization tangent * when we noticed that Box::Reconfig was protected. When this didn't do what * we wanted, we read the documentation for Box a little more carefully and * discovered the Change function. Hence, the further moral of this * exploration is: Read library documentation carefully before running off on a * specialization excursion.) */ #include #include "441/include/std-macros.h" #include "441/include/quitbutton.h" #include #include #include #include #include /* * To add a button to an interface, first declare a new class that is a * subclass of InterViews' PushButton class. */ class HelloButton : public PushButton { public: HelloButton(const char* label, ButtonState* bs, int flag) : PushButton(label, bs, flag) {}; protected: void Press(); }; class LocalBox : public VBox { public: LocalBox(Interactor *a, Interactor *b,Interactor *c); /* * Speicializing Reconfig here make wierd things happen. Specifically, * it make LocalBox, which is a subclass of VBox, act more like an HBox. * The cause of the problem is not know at this time. */ virtual void Reconfig(); /**/ }; LocalBox::LocalBox(Interactor *a, Interactor *b,Interactor *c) : VBox(a,b,c) {} /* * See comment above in class def */ virtual void LocalBox::Reconfig() { VBox::Reconfig(); } /* */ /* * To make something happen when the button is pressed, implement the virtual * Press function. */ void HelloButton::Press() { printf("Hello world.\n"); } /* * Now build a standard InterViews application program. In order to build a * new button, the constructor must be supplied its name, a button state * object, and an initial state value. The name is the string that will appear * inside the button. For now, we don't need to worry about the button state * and initial value, so we'll just supply dummy values for these. */ main() { World* world = new World; ButtonState* dummyState = new ButtonState; LocalBox *vb; /* * Insert a couple buttons in a VBox, thence in a Tray, thence in the * world. */ world->InsertApplication(new Tray(vb = new LocalBox( new HelloButton("Hello Button", dummyState, true), new VGlue(10, 1000, 1000), new QuitButton()))); /* * Here, the alignment is performed after the box has been constructed and * stuck in its scene. Given this, we must call Change in order for the * change in alignment to be reflected in the initial screen display. */ vb->Align(Center); /* * This is the inert call to our specialized version of Reconfig, that does * not give us the desired behavior. I.e., calling Reconfig does not cause * centering alignment to take effect. */ vb->Reconfig(); /* * This does the change we want. I.e., it ensures that the initial display * reflects the call to vb->Align(Center). */ vb->Change(); if (!catch(QuitButtonPressed)) world->Run(); delete world; return 0; }