home *** CD-ROM | disk | FTP | other *** search
- /////////////////////////////////////////////////////////////////////////////
- //
- // example
- //
- // This file demonstrates many of the features of the gem++ library.
- //
- /////////////////////////////////////////////////////////////////////////////
- //
- // This file is Copyright 1992 by Warwick W. Allison,
- // and is freely distributable providing no charge is made.
- //
- /////////////////////////////////////////////////////////////////////////////
-
- #include "gem++.h"
- #include "example.h"
- #include <time.h>
- #include <string.h>
-
-
-
- //
- // Demonstrates a simple derived class of GEMobject
- //
- // Objects of this class will become Checked when clicked upon.
- //
- class MenuItemToggle : public GEMobject {
- public:
- GEMfeedback Touch(int x, int y, const GEMevent& e)
- {
- Checked(bool(!Checked()));
- Deselect();
- Redraw();
- return ContinueInteraction;
- }
- };
-
-
- static char* monthtext[12]={"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"};
-
- //
- // Demonstrates GEMtimer and GEMhotform used for popup menus.
- //
- // This class encapsulates all the RSCindices required to setup
- // the clock, so only of of these objects could be created, since
- // they use the single graphics in the GEMrsc. See the GEMringfiw
- // below for a more complex example that allows duplicates.
- //
- // This class has quite a few components...
- //
- // - it is a GEMformwindow with no window-parts, so it is a form
- // in a window.
- // - it is a GEMtimer, so its Expire() method is called at the intervals
- // requested with Interval().
- // - it is a GEMobject based on the GRABBER object, so its Touch() method
- // is called when the GRABBER is touched.
- // - it has two GEMtextobjects, timetext and datetext, which we can just
- // treat as if they are char*'s since they have conversion operators.
- // - it has a GEMhotform, popup, used for a pop-up menu.
- // - it has a MenuItemToggle (defined above), gmt, which is in the popup
- // menu, and which we test the Checked() state of when deciding to
- // use local or Greenwich time.
- // - it has a GEMalert, gmjoke, which makes the whole GMT thing worthwhile.
- //
- // The member functions are described within.
- //
- class Clock : public GEMformwindow, GEMtimer, GEMobject {
- public:
- Clock(GEMactivity& act, const GEMrsc& rsc) :
- GEMformwindow(act,rsc,CLOCK,0),
- GEMtimer(act,0), // Initially interval==0, ie. Expire() immediately.
- GEMobject(*this,GRABBER),
- timetext(*this,TIME),
- datetext(*this,DATE),
- popup(rsc,POPUP),
- gmt(popup,GMT),
- gmjoke(rsc,GMJOKE)
- {
- strcpy(timetext," ");
- strcpy(datetext," ");
- }
-
- private:
-
- // The Update() method gets the local time or Greenwich time, according
- // to whether the gmt GEMobject is Checked. It then sets the timetext
- // and datetext strings (they are actually GEMtextobjects). It then
- // Redraws those strings. Update() is a local member, called by the
- // methods below it.
- //
- void Update()
- {
- time_t ti=time(0);
- tm* T;
- if (gmt.Checked())
- T=gmtime(&ti);
- else
- T=localtime(&ti);
- timetext[0]=T->tm_hour/10 ? T->tm_hour/10+'0' : ' ';
- timetext[1]=T->tm_hour%10+'0';
- timetext[2]=T->tm_min/10+'0';
- timetext[3]=T->tm_min%10+'0';
- strncpy(datetext,monthtext[T->tm_mon],3);
- datetext[3]=T->tm_mday/10 ? T->tm_mday/10+'0' : ' ';
- datetext[4]=T->tm_mday%10+'0';
- if (IsOpen()) {
- timetext.Redraw();
- datetext.Redraw();
- }
- }
-
- protected:
-
- // The Expire() method overrides that inherited from GEMtimer.
- // It is called when the interval expires. Its action it
- // to merely Update the time and wait set the interval to
- // be 60000 milliseconds. We only need to reset the interval
- // because when we created the object, we requested the interval
- // to be 0 so that the Expire (and hence Update) would be
- // immediate.
- //
- virtual GEMfeedback Expire(const GEMevent&)
- {
- Update();
- Interval(60000); // Every minute, approx.
- return ContinueInteraction;
- }
-
- // The Touch() method overrides that inheritted from GEMobject.
- // It is called whenever the user touches the GRABBER object
- // on which the object was defined.
- //
- // If the touch is made using the right button (button 1), the
- // popup menu is displayed. If the exitor of the popup is
- // the "close" menuitem, the Close() method inheritted from
- // GEMformwindow is called. If the exitor is the smiley-face
- // icon (DOGMJOKE, that's Do-GM-joke), the gmjoke alert is
- // popped up. If the exitor is the "quit" menuitem, EndInteraction
- // is returned, ending the GEMactivity.Do() loop. Note that
- // the "GMT" menuitem is handled by using the Touch() method of
- // MenuItemToggle as described above.
- //
- // If the touch is not made by the right button, we employ a bit
- // of AES code (hmm, maybe that ugly stuff needs a class) to drag
- // a box the size of the BorderRect of this window, then we
- // GEMformwindow::Move this window to that dragged location.
- //
- virtual GEMfeedback Touch(int x, int y, const GEMevent& e)
- {
- if (e.Button(1)) {
- switch (popup.Do(e.X(),e.Y())) {
- case QCLOCK:
- Close();
- break; case DOGMJOKE:
- gmjoke.Alert();
- break; case QPROG:
- return EndInteraction;
- }
- Update();
- return ContinueInteraction;
- } else {
- int bx,by,bw,bh;
- int nx,ny;
- wind_get(0,WF_WORKXYWH,&bx,&by,&bw,&bh);
- GRect w=BorderRect();
- graf_dragbox(w.g_w,w.g_h,w.g_x,w.g_y,bx,by,bw,bh,&nx,&ny);
-
- GEMformwindow::Move(nx,ny);
-
- return ContinueInteraction;
- }
- }
-
- private:
- GEMtextobject timetext,datetext;
- GEMhotform popup;
- MenuItemToggle gmt;
- GEMalert gmjoke;
- };
-
- //
- // Demonstrates GEMvdiobject
- //
- class GEMliney : public GEMvdiobject {
- protected:
- virtual void Draw(int x, int y)
- {
- int j=Width() < Height() ? Width() : Height();
- for (int i=0; i<j; i+=3) {
- vdi.line(x,y+j-i,x+i,y);
- }
- }
- };
-
- //
- // Demonstrates GEMvdiobject, with special "Selected" state display.
- //
- class GEMellipse : public GEMvdiobject {
- protected:
- virtual void Draw(int x, int y)
- {
- vdi.sf_interior(2); // Patterned
- if (Selected()) vdi.sf_style(20);
- else vdi.sf_style(10);
- vdi.ellipse(x+Width()/2,y+Height()/2,Width()/2,Height()/2);
- }
- };
-
- //
- // Demonstrates that GEMuserobjects (and GEMvdiobjects) retain
- // the features of the object that is having its display representation
- // redefined.
- //
- class GEMroundbutton : public GEMvdiobject {
- private:
- int texth;
-
- public:
- GEMroundbutton(GEMform& f, int RSCindex, VDI& v) :
- GEMvdiobject(f,RSCindex,v)
- {
- int j;
- graf_handle(&j,&texth,&j,&j);
- }
-
- protected:
- virtual void Draw(int x, int y)
- {
- if (Selected()) vdi.sf_interior(1);
- else vdi.sf_interior(0);
- vdi.rfbox(x,y,x+Width()-1,y+Height()-1);
- vdi.swr_mode(MD_XOR);
- int j;
- vdi.st_alignment(1,3,&j,&j); // Centre-Bottom aligned
- vdi.gtext(x+Width()/2,y+(Height()+texth)/2-1,Text());
- vdi.swr_mode(MD_REPLACE);
- }
- };
-
-
- //
- // Demonstrates various GEMobjects, and the GEMformiconwindow
- //
- class Various : public GEMformiconwindow {
- public:
- Various(GEMactivity& in, const GEMrsc& rsc) :
- GEMformiconwindow(in,rsc,VARIOUS,VARIOUSI),
- image("example.img"),
- picture(*this,PIC,image),
- SimpleSlider(*this,SIMPKNOB,SIMPSLID),
- VertSlider(*this,VKNOB,VRACK,UP,DOWN),
- HorzSlider(*this,HKNOB,HRACK,LEFT,RIGHT),
- vdi(),
- Ellipse(*this,ELLIPSE,vdi),
- Liney(*this,LINEY,vdi),
- R1(*this,RBUT1,vdi),
- R2(*this,RBUT2,vdi)
- {
- SetName(" Various GEM++ objects ");
- }
-
- private:
- IMG image;
- GEMimageobject picture;
- GEMslider SimpleSlider;
- GEMslider VertSlider;
- GEMslider HorzSlider;
- VDI vdi;
- GEMellipse Ellipse;
- GEMliney Liney;
- GEMroundbutton R1;
- GEMroundbutton R2;
- };
-
-
- //
- // Demonstrates a sophisticated duplicatable window with shared objects
- //
- class GEMringfiw : public GEMformiconwindow {
- private:
- GEMringfiw*& head;
- GEMringfiw* next;
- GEMringfiw* prev;
-
- protected:
- virtual GEMfeedback UserClosed() {
- GEMformwindow::Close();
- delete this;
- return ContinueInteraction;
- }
-
- GEMringfiw(GEMactivity& in, const GEMrsc& rsc, int RSCform, int RSCicon, GEMringfiw*& h) :
- GEMformiconwindow(in,rsc,RSCform,RSCicon),
- head(h)
- {
- next=prev=this;
- }
-
- GEMringfiw(GEMringfiw& copy, GEMringfiw*& h) :
- GEMformiconwindow(copy),
- next(©), prev(copy.prev),
- head(h)
- {
- next->prev=this;
- prev->next=this;
- }
-
- ~GEMringfiw()
- {
- if (next==this) {
- head=0;
- } else {
- if (head==this) head=next;
- prev->next=next;
- next->prev=prev;
- }
- }
-
- public:
- static bool OpenNew(GEMactivity& act, const GEMrsc& rsc, int RSCform, int RSCicon, GEMringfiw*& head)
- {
- GEMringfiw* newhead;
-
- if (head)
- newhead=new GEMringfiw(*head,head);
- else
- newhead=new GEMringfiw(act,rsc,RSCform,RSCicon,head);
-
- head=newhead;
- head->Open();
- if (head->IsOpen()) {
- return TRUE;
- } else {
- delete newhead;
- return FALSE;
- }
- }
- };
-
-
- //
- // Demonstrates GEMmenu as central to the interaction.
- //
- class Menu : GEMmenu {
- public:
- Menu(GEMactivity& in, const GEMrsc& r) :
- GEMmenu(in,r,MENU),
- act(in),
- rsc(r),
- about(rsc,ABOUT),
- itisfree(rsc,FREE),
- authors(rsc,AUTHORS),
- gnu(rsc,GNU),
- errwin(rsc,ERRWIN),
- clocknote(rsc,CLOCKNOTE),
- various(in,rsc),
- clock(in,rsc),
- windows(0),
- bigform(in,rsc,BIGFORM,BIGFORMI,CLOSER|MOVER|NAME|FULLER|SIZER|UPARROW|DNARROW|LFARROW|RTARROW|VSLIDE|HSLIDE)
- {
- bigform.Resize(200,100);
- }
-
- protected:
- virtual GEMfeedback DoItem(int item, const GEMevent& e)
- {
- switch (item) {
- case DOABOUT:
- about.Do();
- break; case DOFREE:
- itisfree.Do();
- break; case DOAUTHORS:
- authors.Do();
- break; case DOGNU:
- gnu.Do();
- break; case DOQUIT:
- return EndInteraction;
- break; case DOVARIOUS:
- various.Open();
- break; case DOBIGFORM:
- bigform.Open();
- break; case DOSHARING:
- if (!GEMringfiw::OpenNew(act,rsc,SHARING,SHARINGI,windows))
- switch (errwin.Alert()) {
- case 1: return DoItem(item,e);
- break; case 2: about.Do();
- }
- break; case DOCLOCK:
- clocknote.Alert();
- clock.Open();
- }
-
- return ContinueInteraction;
- }
-
- private:
- Clock clock;
- GEMringfiw* windows;
- GEMactivity& act;
- GEMrsc& rsc;
- GEMform about,itisfree,authors,gnu;
- GEMformiconwindow bigform;
- Various various;
- GEMalert errwin;
- GEMalert clocknote;
- };
-
-
- //
- // Demonstrates GEMfileselector
- //
- class FileChooser : public GEMobject, public GEMfileselector {
- public:
- FileChooser(GEMform& f, int RSCibutn, GEMobject& disp, char* prmpt) :
- GEMobject(f,RSCibutn),
- GEMfileselector(disp.Text()),
- display(disp),
- prompt(prmpt)
- {
- display.Redraw();
- }
-
- virtual GEMfeedback Touch(int x, int y, const GEMevent& e)
- {
- if (Get(prompt)) display.Redraw();
-
- return ContinueInteraction;
- }
-
- private:
- GEMobject& display;
- char* prompt;
- };
-
- //
- // Demonstrates GEMdesktop
- //
- class Desktop : public GEMdesktop {
- public:
- Desktop(GEMactivity& in, const GEMrsc& rsc) :
- GEMdesktop(in,rsc,DESKTOP),
- display(*this,FILEDISPLAY),
- files(*this,FILES,display,rsc.String(FILEPROMPT))
- {
- }
-
- private:
- GEMobject display;
- FileChooser files;
- };
-
-
- main()
- {
- // Before we do ANYTHING with GEM, we must declare a GEMapplication.
- GEMapplication example;
-
- // Next, we declare a GEMrsc, which we then use to create other objects.
- GEMrsc rsc("example.rsc",8,16);
- // GEMrsc rsc("example.rsc");
-
- if (!rsc) {
- // If the GEMrsc file cannot be created, we have to resort to a
- // GEMalert constructed from strings rather than from the GEMrsc.
- GEMalert dammit("Could not load \"example.rsc\".","Quit");
- dammit.Alert();
- } else {
- // But if everything goes fine, we create a GEMactivity, and
- // our own Menu and Desktop (see definitions above) in that
- // GEMactivity.
-
- GEMactivity activity;
-
- Menu menu(activity,rsc);
-
- Desktop desktop(activity,rsc);
-
- // Then, conduct the GEMactivity - returns when all done.
- activity.Do();
- }
- }
-