home *** CD-ROM | disk | FTP | other *** search
- /////////////////////////////////////////////////////////////////////////////
- //
- // This file is Copyright 1992,1993 by Warwick W. Allison.
- // This file is part of the gem++ library.
- // You are free to copy and modify these sources, provided you acknowledge
- // the origin by retaining this notice, and adhere to the conditions
- // described in the file COPYING.LIB.
- //
- /////////////////////////////////////////////////////////////////////////////
-
- #include <aesbind.h>
- #include <osbind.h>
- #include "gemfw.h"
- #include "gemo.h"
- #include "geme.h"
- #include "scancode.h"
-
- // The global int "StartObject" links the call to RedrawOverlaps
- // with RedrawOverlaps' calls to Redraw. An alternative solution
- // would be to have RedrawOverlaps accept a parameter which it
- // just blindly passed to Redraw, however this would involve a
- // void* pointer, and would delocalize the issue. When setting
- // the StartObject, be sure to reset it to ROOT, since redraw
- // events, etc. will also call RedrawOverlaps.
- static int StartObject=ROOT;
-
-
- static
- bool GetKey(int& Key)
- // Modal. Menu bar is not active while getting keys.
- // Returns FALSE if non-key event arrives.
- {
- int Pipe[32];
- int mx,my,button,meta,count;
-
- wind_update(BEG_MCTRL);
-
- int got=evnt_multi(MU_KEYBD|MU_BUTTON,
- 1,1,1,0,0,0,0,0,0,0,0,0,0,
- Pipe,0,&mx,&my,&button,&meta,&Key,&count
- );
-
- wind_update(END_MCTRL);
-
- if (got&MU_KEYBD) {
- return TRUE;
- }
-
- return FALSE;
- }
-
- void GEMformwindow::Redraw(const GRect& area)
- {
- if (IsOpen()) {
- objc_draw(Obj, StartObject, MAX_DEPTH, area.g_x, area.g_y, area.g_w, area.g_h);
- }
- }
-
- void GEMformwindow::SetWorkRect(const GRect& r)
- // Do the normal SetWorkRect, then adjust object tree position.
- {
- GEMwindow::SetWorkRect(r);
-
- Obj[ROOT].MoveTo(Pos.g_x-LeftColumn()*ColumnWidth(),
- Pos.g_y-TopLine()*LineHeight());
- }
-
- bool GEMformwindow::HAlignSlider()
- // Adjust object tree position.
- {
- Obj[ROOT].MoveTo(Pos.g_x-LeftColumn()*ColumnWidth(),
- Pos.g_y-TopLine()*LineHeight());
- return FALSE;
- }
-
- bool GEMformwindow::VAlignSlider()
- // Adjust object tree position.
- {
- Obj[ROOT].MoveTo(Pos.g_x-LeftColumn()*ColumnWidth(),
- Pos.g_y-TopLine()*LineHeight());
- return FALSE;
- }
-
- GEMformwindow::GEMformwindow(GEMactivity& act, const GEMrsc& in, int RSCindex) :
- GEMwindow(act,CLOSER|MOVER|NAME), GEMform(in, RSCindex)
- {
- GRect workArea(Obj[ROOT].X(), Obj[ROOT].Y(),
- Obj[ROOT].Width(), Obj[ROOT].Height());
- Max = Pos = workArea;
- initialized = TRUE;
- Align(0,0,2,2); // For simple shade patterns (complex ones require 4x4)
- }
-
- GEMformwindow::GEMformwindow(GEMactivity& act, const GEMrsc& in, int RSCindex, int Parts) :
- GEMwindow(act,Parts), GEMform(in, RSCindex)
- {
- GRect workArea(Obj[ROOT].X(), Obj[ROOT].Y(),
- Obj[ROOT].Width(), Obj[ROOT].Height());
- Max = Pos = workArea;
- initialized = TRUE;
- Align(0,0,2,2); // For simple shade patterns (complex ones require 4x4)
-
- // Assumes ColumnWidth() and LineHeight() are 1.
- SetTotalColumns(Obj[ROOT].Width());
- SetTotalLines(Obj[ROOT].Height());
- SetVisibleColumns(Obj[ROOT].Width());
- SetVisibleLines(Obj[ROOT].Height());
- }
-
- GEMformwindow::GEMformwindow(const GEMformwindow& copy) :
- GEMwindow(copy), GEMform(copy)
- {
- // GEMwindow is exactly the same, except position changes slightly.
- Obj[ROOT].MoveTo(Pos.g_x,Pos.g_y);
- }
-
- static
- void WaitForNoButton()
- {
- int X,Y,Buttons,Metas;
-
- do graf_mkstate(&X,&Y,&Buttons,&Metas); while (Buttons);
- }
-
-
- // Any point in making this a method of GEMobjects?
- static
- void WatchBox(GEMobject *O)
- {
- int X,Y,Buttons,Metas;
- bool OldOn=O->Selected();
- bool On=FALSE;
-
- do {
- graf_mkstate(&X,&Y,&Buttons,&Metas);
- On=O->ContainsPoint(X,Y);
- if (On!=OldOn) {
- OldOn=On;
- O->Selected(On);
- O->Redraw();
- }
- } while (Buttons);
- }
-
- static
- int FindEditable(GEMrawobject *Obj, int Object, int way)
- {
- int c=Object+way;
-
- while (1) {
- if (c<0) while (!(Obj[++c].LastObject()));
- else if (Obj[c].Editable() || c==Object) return c;
- else if (Obj[c].LastObject() && way>0) c=0;
- else c+=way;
- }
- }
-
- void GEMformwindow::Edit(int Object, int Index)
- {
- objc_edit(Obj,Object,0,Index,EDSTART,&Index);
- objc_edit(Obj,Object,0,Index,EDINIT,&Index);
-
- WaitForNoButton();
-
- while (1) {
- int Key;
-
- if (!GetKey(Key)) {
- objc_edit(Obj,Object,0,Index,EDEND,&Index);
- return;
- }
-
- switch (Key>>8) {
- case KEY_RETURN:
- objc_edit(Obj,Object,0,Index,EDEND,&Index);
- return;
- break; case KEY_UP:
- objc_edit(Obj,Object,0,Index,EDEND,&Index);
- Object=FindEditable(Obj,Object,-1);
- objc_edit(Obj,Object,0,Index,EDINIT,&Index);
- break; case KEY_DOWN:
- objc_edit(Obj,Object,0,Index,EDEND,&Index);
- Object=FindEditable(Obj,Object,+1);
- objc_edit(Obj,Object,0,Index,EDINIT,&Index);
- break; default:
- objc_edit(Obj,Object,Key,Index,EDCHAR,&Index);
- }
-
- }
- }
-
- static
- bool inside(int x, int y, const GRECT& pt)
- {
- return ( x>=pt.g_x && y>=pt.g_y && x<pt.g_x+pt.g_w && y<pt.g_y+pt.g_h );
- }
-
- void GEMformwindow::Top(const GEMevent& e)
- {
- GRECT R;
- wind_calc(1,parts,Pos.g_x,Pos.g_y,Pos.g_w,Pos.g_h,&R.g_x,&R.g_y,&R.g_w,&R.g_h);
- if (!inside(e.X(),e.Y(),R) || Click(e)==IgnoredClick) GEMwindow::Top(e);
- }
-
- GEMfeedback GEMformwindow::Click(const GEMevent& e)
- {
- int o=objc_find(Obj,ROOT,MAX_DEPTH,e.X(),e.Y());
-
- if (o<0) return IgnoredClick;
-
- while (o>=0 && !Obj[o].Disabled() && !Obj[o].RadioButton()
- && !Obj[o].TouchExit() && !Obj[o].Editable()
- && !Obj[o].Exit() && !Obj[o].Selectable()) {
- o=Parent(o);
- }
- if (o<0) o=0;
-
- GEMobject *O=operator[](o).Cook();
- int Dummy=O==0;
-
- if (Dummy) O=new GEMobject(*this,o);
-
- if (O->Disabled()) {
- if (Dummy) delete O;
- return IgnoredClick;
- }
-
- GEMfeedback result=IgnoredClick;
-
- int X,Y;
- objc_offset(Obj,o,&X,&Y);
-
- if (O->TouchExit())
- result=DoItem(o,e);
-
- if (O->RadioButton()) {
- if (!O->Selected()) {
- int p=Parent(o);
- int c=Obj[p].Head();
- while (c!=p) {
- GEMobject P(*this,c);
- if (P.Selected() && P.RadioButton()) {
- P.Deselect();
- P.Redraw();
- }
- c=Obj[c].Next();
- }
- O->Select();
- O->Redraw();
-
- result=DoItem(o,e);
- } else
- result=ContinueInteraction;
- } else {
- if (O->Selectable() && !O->Exit()) {
- if (O->Selected()) O->Deselect();
- else O->Select();
- O->Redraw();
-
- result=DoItem(o,e);
- WaitForNoButton();
- }
- }
-
- if (O->Editable()) {
- Edit(o,1/* Column */);
- result=DoItem(o,e);
- }
-
- if (O->Exit()) {
- result=ContinueInteraction;
- if (O->Selectable()) {
- WatchBox(O);
- if (O->Selected()) {
- result=DoItem(o,e);
- O->Deselect();
- O->Redraw();
- }
- } else {
- WaitForNoButton();
- }
- }
-
- if (Dummy) delete O;
-
- return result;
- }
-
- void GEMformwindow::RedrawObject(int RSCindex)
- {
- if (IsOpen()) {
- int x,y;
- objc_offset(Obj,RSCindex,&x,&y);
- GRect R(x,y,Obj[RSCindex].Width(),Obj[RSCindex].Height());
- StartObject=RSCindex;
- RedrawOverlaps(R);
- StartObject=ROOT;
- }
- }
-
- void GEMformwindow::RedrawObject(int RSCindex,int Cx,int Cy,int Cw,int Ch) // Clipped
- {
- if (IsOpen()) {
- int x,y;
- objc_offset(Obj,RSCindex,&x,&y);
- GRect R(x+Cx,y+Cy,Cw,Ch);
- StartObject=RSCindex;
- RedrawOverlaps(R);
- StartObject=ROOT;
- }
- }
-
- void GEMformwindow::AlignObject(int RSCindex, int xmlt=8, int ymlt=1)
- {
- GEMform::AlignObject(RSCindex,xmlt,ymlt);
-
- int j;
- int x,y;
- wind_calc(1,parts,xoffset,yoffset,50,50,&x,&y,&j,&j);
-
- Align(x,y,xmult,ymult);
- }
-
- bool GEMformwindow::IsOpen() const
- {
- return GEMwindow::IsOpen();
- }
-