home *** CD-ROM | disk | FTP | other *** search
/ Computer Club Elmshorn Atari PD / CCE_PD.iso / pc / 0400 / CCE_0423.ZIP / CCE_0423.PD / GEM.ZOO / gemfw.cc < prev    next >
C/C++ Source or Header  |  1992-04-26  |  6KB  |  299 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  This file is Copyright 1992 by Warwick W. Allison,
  4. //  and is freely distributable providing no charge is made.
  5. //
  6. /////////////////////////////////////////////////////////////////////////////
  7.  
  8. #include <aesbind.h>
  9. #include <osbind.h>
  10. #include "gemfw.h"
  11. #include "gemo.h"
  12. #include "scancode.h"
  13.  
  14. // The global int "StartObject" links the call to RedrawOverlaps
  15. // with RedrawOverlaps' calls to Redraw.  An alternative solution
  16. // would be to have RedrawOverlaps accept a parameter which it
  17. // just blindly passed to Redraw, however this would involve a
  18. // void* pointer, and would delocalize the issue.  When setting
  19. // the StartObject, be sure to reset it to ROOT, since redraw
  20. // events, etc. will also call RedrawOverlaps.
  21. int StartObject=ROOT;
  22.  
  23.  
  24. bool GetKey(int& Key)
  25. {
  26. /***** BIOS or GEMDOS based... but both lose characters!
  27.     int X,Y,Buttons,Metas;
  28.     do {
  29.         graf_mkstate(&X,&Y,&Buttons,&Metas);
  30.     } while (!Bconstat(2) && !Buttons);
  31.     if (Bconstat(2)) {
  32.         Key=Bconin(2);
  33.         Key=((Key>>8)&0xFF00)|(Key&0xFF);
  34.         return TRUE;
  35.     } else return FALSE;
  36. *************/
  37.  
  38.  
  39. //***** Event-based... but how do we recycle events?
  40.     int Pipe[32];
  41.     int mx,my,button,meta,count;
  42.     ClickResult r=ContinueInteraction;
  43.  
  44.     wind_update(BEG_MCTRL);  // So disable those events... POOR SOLUTION!
  45.  
  46.     int got=evnt_multi(MU_KEYBD|MU_BUTTON,
  47.                 1,1,1,0,0,0,0,0,0,0,0,0,0,
  48.                 Pipe,0,&mx,&my,&button,&meta,&Key,&count
  49.             );
  50.  
  51.     wind_update(END_MCTRL);
  52.  
  53.     if (got&MU_KEYBD) {
  54.         return TRUE;
  55.     }
  56.  
  57.     return FALSE;
  58. }
  59.  
  60. void GEMformwindow::Redraw(GRECT& area)
  61. {
  62.     objc_draw(Obj, StartObject, MAX_DEPTH, area.g_x, area.g_y, area.g_w, area.g_h);
  63. }
  64.  
  65. void GEMformwindow::move(int x, int y)
  66. {
  67.     // Snap, since forms use 2x2 shades
  68.     x=x&~1;
  69.     y=y&~1;
  70.  
  71.     GEMwindow::move(x,y);
  72.  
  73.     int X,Y,W,H;
  74.     wind_get(Handle,WF_WORKXYWH,&X,&Y,&W,&H);
  75.     Obj[0].ob_x=X;
  76.     Obj[0].ob_y=Y;
  77. }
  78.  
  79. GRECT WorkToBorder(int Parts, GEMrealobject& O)
  80. {
  81.     GRECT R;
  82.     if (Parts>0) {
  83.         wind_calc(0,Parts,O.ob_x,O.ob_y,O.ob_width,O.ob_height,&R.g_x,&R.g_y,&R.g_w,&R.g_h);
  84.     } else {
  85.         R.g_x=0;
  86.         R.g_y=0;
  87.         R.g_w=0;
  88.         R.g_h=0;
  89.     }
  90.     return R;
  91. }
  92.  
  93.  
  94.  
  95. GEMformwindow::GEMformwindow(int RSCindex, int Parts=NAME|CLOSER|MOVER) :
  96.     GEMform(RSCindex),
  97.     GEMwindow(Parts, WorkToBorder(Parts,Obj[0]))
  98. {
  99. }
  100.  
  101. int Parent(GEMrealobject* Form, int o)
  102. {
  103.     int n=o;
  104.  
  105.     do {
  106.         o=n;
  107.         n=Form[n].ob_next;
  108.     } while (n>=0 && Form[n].ob_tail!=o);
  109.  
  110.     return n;
  111. }
  112.  
  113. void WaitForNoButton()
  114. {
  115.     int X,Y,Buttons,Metas;
  116.  
  117.     do graf_mkstate(&X,&Y,&Buttons,&Metas); while (Buttons);
  118. }
  119.  
  120.  
  121. // Any point in making this a method of GEMrealobjects?
  122. void WatchBox(GEMobject *O)
  123. {
  124.     int X,Y,Buttons,Metas;
  125.     bool OldOn=O->Selected();
  126.     bool On=FALSE;
  127.  
  128.     do {
  129.         graf_mkstate(&X,&Y,&Buttons,&Metas);
  130.         On=O->ContainsPoint(X,Y);
  131.         if (On!=OldOn) {
  132.             OldOn=On;
  133.             O->Selected(On);
  134.             O->Redraw();
  135.         }
  136.     } while (Buttons && X>10);
  137. }
  138.  
  139. int FindEditable(GEMrealobject *Obj, int Object, int way)
  140. {
  141.     int c=Object+way;
  142.  
  143.     while (1) {
  144.         if (c<0) while (!(Obj[++c].ob_flags&LASTOB));
  145.         else if (Obj[c].ob_flags&EDITABLE || c==Object) return c;
  146.         else if (Obj[c].ob_flags&LASTOB && way>0) c=0;
  147.         else c+=way;
  148.     }
  149. }
  150.  
  151. void GEMformwindow::Edit(int Object, int Index)
  152. {
  153.     int X,Y,Buttons,Metas;
  154.  
  155.     objc_edit(Obj,Object,0,Index,EDSTART,&Index);
  156.     objc_edit(Obj,Object,0,Index,EDINIT,&Index);
  157.  
  158.     do graf_mkstate(&X,&Y,&Buttons,&Metas); while (Buttons);
  159.  
  160.     while (1) {
  161.         int Key;
  162.  
  163.         if (!GetKey(Key)) {
  164.             objc_edit(Obj,Object,0,Index,EDEND,&Index);
  165.             return;
  166.         }
  167.  
  168.         switch (Key>>8) {
  169.             case KEY_RETURN:
  170.                 objc_edit(Obj,Object,0,Index,EDEND,&Index);
  171.                 return;
  172.         break;    case KEY_UP:
  173.                 objc_edit(Obj,Object,0,Index,EDEND,&Index);
  174.                 Object=FindEditable(Obj,Object,-1);
  175.                 objc_edit(Obj,Object,0,Index,EDINIT,&Index);
  176.         break;    case KEY_DOWN:
  177.                 objc_edit(Obj,Object,0,Index,EDEND,&Index);
  178.                 Object=FindEditable(Obj,Object,+1);
  179.                 objc_edit(Obj,Object,0,Index,EDINIT,&Index);
  180.         break;    default:
  181.                 objc_edit(Obj,Object,Key,Index,EDCHAR,&Index);
  182.         }
  183.  
  184.     }
  185. }
  186.  
  187. bool inside(int x, int y, const GRECT& pt)
  188. {
  189.     return ( x>=pt.g_x && y>=pt.g_y && x<pt.g_x+pt.g_w && y<pt.g_y+pt.g_h );
  190. }
  191.  
  192. void GEMformwindow::top(int x, int y)
  193. {
  194.     GRECT R;
  195.     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);
  196.     if (inside(x,y,R)) click(x,y);
  197.     else GEMwindow::top(x,y);
  198. }
  199.  
  200. ClickResult GEMformwindow::click(int x, int y)
  201. {
  202.     int o=objc_find(Obj,ROOT,MAX_DEPTH,x,y);
  203.  
  204.     if (o<0) return ContinueInteraction;
  205.  
  206.     while (o>=0 && !Obj[o].Disabled() && !Obj[o].RadioButton()
  207.       && !Obj[o].TouchExit() && !Obj[o].Editable()
  208.       && !Obj[o].Exit() && !Obj[o].Selectable()) {
  209.         o=Parent(Obj,o);
  210.     }
  211.     if (o<0) o=0;
  212.  
  213.     GEMobject *O=Caller(o);
  214.     int Dummy=O==0;
  215.  
  216.     if (Dummy) O=new GEMobject(o,this);
  217.  
  218.     if (O->Disabled()) {
  219.         if (Dummy) delete O;
  220.         return ContinueInteraction;
  221.     }
  222.  
  223.     if (O->RadioButton()) {
  224.         if (!O->Selected()) {
  225.             int p=Parent(Obj,o);
  226.             int c=Obj[p].ob_head;
  227.             while (c!=p) {
  228.                 GEMobject P(c,this);
  229.                 if (P.Selected()) {
  230.                     P.Deselect();
  231.                     P.Redraw();
  232.                 }
  233.                 c=Obj[c].ob_next;
  234.             }
  235.             O->Select();
  236.             O->Redraw();
  237.         }
  238.     } else {
  239.         if (O->Selectable()) {
  240.             if (O->Selected()) O->Deselect();
  241.             else O->Select();
  242.             O->Redraw();
  243.         }
  244.     }
  245.  
  246.     if (O->TouchExit()) {
  247.         int X,Y;
  248.         objc_offset(Obj,o,&X,&Y);
  249.         O->touch(x-X,y-Y);
  250.     }
  251.  
  252.     if (O->Editable()) {
  253.         Edit(o,1/* Column */);
  254.     }
  255.  
  256.     if (O->Exit()) {
  257.         if (O->Selectable()) {
  258.             WatchBox(O);
  259.             if (O->Selected()) {
  260.                 O->Deselect();
  261.                 O->Redraw();
  262.             }
  263.         } else {
  264.             WaitForNoButton();
  265.         }
  266.     } else {
  267.         if (O->Selectable() && !O->RadioButton()) {
  268.             WaitForNoButton();
  269.         }
  270.     }
  271.  
  272.     if (Dummy) delete O;
  273.     return ContinueInteraction;
  274. }
  275.  
  276. void GEMformwindow::RedrawObject(int RSCindex)
  277. {
  278.     GRECT R;
  279.     objc_offset(Obj,RSCindex,&R.g_x,&R.g_y);
  280.     R.g_w=Obj[RSCindex].ob_width;
  281.     R.g_h=Obj[RSCindex].ob_height;
  282.     StartObject=RSCindex;
  283.     RedrawOverlaps(R);
  284.     StartObject=ROOT;
  285. }
  286.  
  287. void GEMformwindow::RedrawObject(int RSCindex,int Cx,int Cy,int Cw,int Ch) // Clipped
  288. {
  289.     GRECT R;
  290.     objc_offset(Obj,RSCindex,&R.g_x,&R.g_y);
  291.     R.g_x+=Cx;
  292.     R.g_y+=Cy;
  293.     R.g_w=Cw;
  294.     R.g_h=Ch;
  295.     StartObject=RSCindex;
  296.     RedrawOverlaps(R);
  297.     StartObject=ROOT;
  298. }
  299.