home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / program / gempp15b / gemfw.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-23  |  7.2 KB  |  328 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  This file is Copyright 1992,1993 by Warwick W. Allison.
  4. //  This file is part of the gem++ library.
  5. //  You are free to copy and modify these sources, provided you acknowledge
  6. //  the origin by retaining this notice, and adhere to the conditions
  7. //  described in the file COPYING.LIB.
  8. //
  9. /////////////////////////////////////////////////////////////////////////////
  10.  
  11. #include <aesbind.h>
  12. #include <osbind.h>
  13. #include "gemfw.h"
  14. #include "gemo.h"
  15. #include "geme.h"
  16. #include "scancode.h"
  17.  
  18. // The global int "StartObject" links the call to RedrawOverlaps
  19. // with RedrawOverlaps' calls to Redraw.  An alternative solution
  20. // would be to have RedrawOverlaps accept a parameter which it
  21. // just blindly passed to Redraw, however this would involve a
  22. // void* pointer, and would delocalize the issue.  When setting
  23. // the StartObject, be sure to reset it to ROOT, since redraw
  24. // events, etc. will also call RedrawOverlaps.
  25. static int StartObject=ROOT;
  26.  
  27.  
  28. static
  29. bool GetKey(int& Key)
  30. // Modal.  Menu bar is not active while getting keys.
  31. // Returns FALSE if non-key event arrives.
  32. {
  33.     int Pipe[32];
  34.     int mx,my,button,meta,count;
  35.  
  36.     wind_update(BEG_MCTRL);
  37.  
  38.     int got=evnt_multi(MU_KEYBD|MU_BUTTON,
  39.                 1,1,1,0,0,0,0,0,0,0,0,0,0,
  40.                 Pipe,0,&mx,&my,&button,&meta,&Key,&count
  41.             );
  42.  
  43.     wind_update(END_MCTRL);
  44.  
  45.     if (got&MU_KEYBD) {
  46.         return TRUE;
  47.     }
  48.  
  49.     return FALSE;
  50. }
  51.  
  52. void GEMformwindow::Redraw(const GRect& area)
  53. {
  54.     if (IsOpen()) {
  55.         objc_draw(Obj, StartObject, MAX_DEPTH, area.g_x, area.g_y, area.g_w, area.g_h);
  56.     }
  57. }
  58.  
  59. void GEMformwindow::SetWorkRect(const GRect& r)
  60. // Do the normal SetWorkRect, then adjust object tree position.
  61. {
  62.     GEMwindow::SetWorkRect(r);
  63.  
  64.     Obj[ROOT].MoveTo(Pos.g_x-LeftColumn()*ColumnWidth(),
  65.         Pos.g_y-TopLine()*LineHeight());
  66. }
  67.  
  68. bool GEMformwindow::HAlignSlider()
  69. // Adjust object tree position.
  70. {
  71.     Obj[ROOT].MoveTo(Pos.g_x-LeftColumn()*ColumnWidth(),
  72.         Pos.g_y-TopLine()*LineHeight());
  73.     return FALSE;
  74. }
  75.  
  76. bool GEMformwindow::VAlignSlider()
  77. // Adjust object tree position.
  78. {
  79.     Obj[ROOT].MoveTo(Pos.g_x-LeftColumn()*ColumnWidth(),
  80.         Pos.g_y-TopLine()*LineHeight());
  81.     return FALSE;
  82. }
  83.  
  84. GEMformwindow::GEMformwindow(GEMactivity& act, const GEMrsc& in, int RSCindex) :
  85.     GEMwindow(act,CLOSER|MOVER|NAME), GEMform(in, RSCindex)
  86. {
  87.     GRect workArea(Obj[ROOT].X(), Obj[ROOT].Y(),
  88.         Obj[ROOT].Width(), Obj[ROOT].Height());
  89.     Max = Pos = workArea;
  90.     initialized = TRUE;
  91.     Align(0,0,2,2); // For simple shade patterns (complex ones require 4x4)
  92. }
  93.  
  94. GEMformwindow::GEMformwindow(GEMactivity& act, const GEMrsc& in, int RSCindex, int Parts) :
  95.     GEMwindow(act,Parts), GEMform(in, RSCindex)
  96. {
  97.     GRect workArea(Obj[ROOT].X(), Obj[ROOT].Y(),
  98.         Obj[ROOT].Width(), Obj[ROOT].Height());
  99.     Max = Pos = workArea;
  100.     initialized = TRUE;
  101.     Align(0,0,2,2); // For simple shade patterns (complex ones require 4x4)
  102.  
  103.     // Assumes ColumnWidth() and LineHeight() are 1.
  104.     SetTotalColumns(Obj[ROOT].Width());
  105.     SetTotalLines(Obj[ROOT].Height());
  106.     SetVisibleColumns(Obj[ROOT].Width());
  107.     SetVisibleLines(Obj[ROOT].Height());
  108. }
  109.  
  110. GEMformwindow::GEMformwindow(const GEMformwindow& copy) :
  111.     GEMwindow(copy), GEMform(copy)
  112. {
  113.     // GEMwindow is exactly the same, except position changes slightly.
  114.     Obj[ROOT].MoveTo(Pos.g_x,Pos.g_y);
  115. }
  116.  
  117. static
  118. void WaitForNoButton()
  119. {
  120.     int X,Y,Buttons,Metas;
  121.  
  122.     do graf_mkstate(&X,&Y,&Buttons,&Metas); while (Buttons);
  123. }
  124.  
  125.  
  126. // Any point in making this a method of GEMobjects?
  127. static
  128. void WatchBox(GEMobject *O)
  129. {
  130.     int X,Y,Buttons,Metas;
  131.     bool OldOn=O->Selected();
  132.     bool On=FALSE;
  133.  
  134.     do {
  135.         graf_mkstate(&X,&Y,&Buttons,&Metas);
  136.         On=O->ContainsPoint(X,Y);
  137.         if (On!=OldOn) {
  138.             OldOn=On;
  139.             O->Selected(On);
  140.             O->Redraw();
  141.         }
  142.     } while (Buttons);
  143. }
  144.  
  145. static
  146. int FindEditable(GEMrawobject *Obj, int Object, int way)
  147. {
  148.     int c=Object+way;
  149.  
  150.     while (1) {
  151.         if (c<0) while (!(Obj[++c].LastObject()));
  152.         else if (Obj[c].Editable() || c==Object) return c;
  153.         else if (Obj[c].LastObject() && way>0) c=0;
  154.         else c+=way;
  155.     }
  156. }
  157.  
  158. void GEMformwindow::Edit(int Object, int Index)
  159. {
  160.     objc_edit(Obj,Object,0,Index,EDSTART,&Index);
  161.     objc_edit(Obj,Object,0,Index,EDINIT,&Index);
  162.  
  163.     WaitForNoButton();
  164.  
  165.     while (1) {
  166.         int Key;
  167.  
  168.         if (!GetKey(Key)) {
  169.             objc_edit(Obj,Object,0,Index,EDEND,&Index);
  170.             return;
  171.         }
  172.  
  173.         switch (Key>>8) {
  174.             case KEY_RETURN:
  175.                 objc_edit(Obj,Object,0,Index,EDEND,&Index);
  176.                 return;
  177.         break;    case KEY_UP:
  178.                 objc_edit(Obj,Object,0,Index,EDEND,&Index);
  179.                 Object=FindEditable(Obj,Object,-1);
  180.                 objc_edit(Obj,Object,0,Index,EDINIT,&Index);
  181.         break;    case KEY_DOWN:
  182.                 objc_edit(Obj,Object,0,Index,EDEND,&Index);
  183.                 Object=FindEditable(Obj,Object,+1);
  184.                 objc_edit(Obj,Object,0,Index,EDINIT,&Index);
  185.         break;    default:
  186.                 objc_edit(Obj,Object,Key,Index,EDCHAR,&Index);
  187.         }
  188.  
  189.     }
  190. }
  191.  
  192. static
  193. bool inside(int x, int y, const GRECT& pt)
  194. {
  195.     return ( x>=pt.g_x && y>=pt.g_y && x<pt.g_x+pt.g_w && y<pt.g_y+pt.g_h );
  196. }
  197.  
  198. void GEMformwindow::Top(const GEMevent& e)
  199. {
  200.     GRECT R;
  201.     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);
  202.     if (!inside(e.X(),e.Y(),R) || Click(e)==IgnoredClick) GEMwindow::Top(e);
  203. }
  204.  
  205. GEMfeedback GEMformwindow::Click(const GEMevent& e)
  206. {
  207.     int o=objc_find(Obj,ROOT,MAX_DEPTH,e.X(),e.Y());
  208.  
  209.     if (o<0) return IgnoredClick;
  210.  
  211.     while (o>=0 && !Obj[o].Disabled() && !Obj[o].RadioButton()
  212.       && !Obj[o].TouchExit() && !Obj[o].Editable()
  213.       && !Obj[o].Exit() && !Obj[o].Selectable()) {
  214.         o=Parent(o);
  215.     }
  216.     if (o<0) o=0;
  217.  
  218.     GEMobject *O=operator[](o).Cook();
  219.     int Dummy=O==0;
  220.  
  221.     if (Dummy) O=new GEMobject(*this,o);
  222.  
  223.     if (O->Disabled()) {
  224.         if (Dummy) delete O;
  225.         return IgnoredClick;
  226.     }
  227.  
  228.     GEMfeedback result=IgnoredClick;
  229.  
  230.     int X,Y;
  231.     objc_offset(Obj,o,&X,&Y);
  232.  
  233.     if (O->TouchExit())
  234.         result=DoItem(o,e);
  235.  
  236.     if (O->RadioButton()) {
  237.         if (!O->Selected()) {
  238.             int p=Parent(o);
  239.             int c=Obj[p].Head();
  240.             while (c!=p) {
  241.                 GEMobject P(*this,c);
  242.                 if (P.Selected() && P.RadioButton()) {
  243.                     P.Deselect();
  244.                     P.Redraw();
  245.                 }
  246.                 c=Obj[c].Next();
  247.             }
  248.             O->Select();
  249.             O->Redraw();
  250.  
  251.             result=DoItem(o,e);
  252.         } else 
  253.             result=ContinueInteraction;
  254.     } else {
  255.         if (O->Selectable() && !O->Exit()) {
  256.             if (O->Selected()) O->Deselect();
  257.             else O->Select();
  258.             O->Redraw();
  259.  
  260.             result=DoItem(o,e);
  261.             WaitForNoButton();
  262.         }
  263.     }
  264.  
  265.     if (O->Editable()) {
  266.         Edit(o,1/* Column */);
  267.         result=DoItem(o,e);
  268.     }
  269.  
  270.     if (O->Exit()) {
  271.         result=ContinueInteraction;
  272.         if (O->Selectable()) {
  273.             WatchBox(O);
  274.             if (O->Selected()) {
  275.                 result=DoItem(o,e);
  276.                 O->Deselect();
  277.                 O->Redraw();
  278.             }
  279.         } else {
  280.             WaitForNoButton();
  281.         }
  282.     }
  283.  
  284.     if (Dummy) delete O;
  285.  
  286.     return result;
  287. }
  288.  
  289. void GEMformwindow::RedrawObject(int RSCindex)
  290. {
  291.     if (IsOpen()) {
  292.         int x,y;
  293.         objc_offset(Obj,RSCindex,&x,&y);
  294.         GRect R(x,y,Obj[RSCindex].Width(),Obj[RSCindex].Height());
  295.         StartObject=RSCindex;
  296.         RedrawOverlaps(R);
  297.         StartObject=ROOT;
  298.     }
  299. }
  300.  
  301. void GEMformwindow::RedrawObject(int RSCindex,int Cx,int Cy,int Cw,int Ch) // Clipped
  302. {
  303.     if (IsOpen()) {
  304.         int x,y;
  305.         objc_offset(Obj,RSCindex,&x,&y);
  306.         GRect R(x+Cx,y+Cy,Cw,Ch);
  307.         StartObject=RSCindex;
  308.         RedrawOverlaps(R);
  309.         StartObject=ROOT;
  310.     }
  311. }
  312.  
  313. void GEMformwindow::AlignObject(int RSCindex, int xmlt=8, int ymlt=1)
  314. {
  315.     GEMform::AlignObject(RSCindex,xmlt,ymlt);
  316.  
  317.     int j;
  318.     int x,y;
  319.     wind_calc(1,parts,xoffset,yoffset,50,50,&x,&y,&j,&j);
  320.  
  321.     Align(x,y,xmult,ymult);
  322. }
  323.  
  324. bool GEMformwindow::IsOpen() const
  325. {
  326.     return GEMwindow::IsOpen();
  327. }
  328.