home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / pascal / rehack / window / window.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-29  |  5.6 KB  |  238 lines

  1. #include "..\WINDOW\WINDOW.HPP"
  2.  
  3. // ------------------------------------------------------------------
  4. // File:        WINDOW.CPP
  5. // Path:        ...\REHACK\WINDOW\WINDOW.CPP
  6. // Version:        0.01
  7. // Author:        Pat Reilly
  8. // CIS Id:        71333,2764
  9. // Created On:    6/28/93
  10. // Modified On:
  11. // Description:    Window class for REHACK. See WINDOW.TXT for
  12. //                more details.
  13. // Tabs:        4
  14. // ------------------------------------------------------------------
  15.  
  16. Window::Window(const Rect& aBounds) :
  17.     Visible(aBounds), bottomObject(0), currentObject(0)
  18. {}
  19.  
  20. Window::~Window()
  21. {
  22.     // Since it 'owns' its objects, delete them.
  23.     while(bottomObject != 0)
  24.         delete bottomObject;
  25. }
  26.  
  27. // Static function used by handle().
  28. //    The point (void*) argument is assumed to be in *this' (obj's owner)
  29. //    coordinates.
  30. static bool containsThisPosition(Visible* obj, void* pt)
  31. {
  32.     if(!obj->getFlag(vfVisible))
  33.         return false;
  34.     else
  35.         return obj->getOwnerBounds().contains(*((Point*)pt));
  36. }
  37.  
  38. // Static function used by handle().
  39. static void handleEvent(Visible* obj, void* ev)
  40. {
  41.     // Only pass the event on if it hasn't been used (cleared) by a previous
  42.     //    object, and if its enabled in the eventMask mask.
  43.     if(!((Event*)ev)->isNull() && !obj->getFlag(vfDisabled) &&
  44.             (obj->eventMask & ((Event*)ev)->type) != 0)
  45.         obj->handle(*((Event*)ev));
  46. }
  47.  
  48. void Window::handle(Event& event)
  49. {
  50.     Visible* obj;
  51.  
  52.     if(!event.isNull())    // Ignore null events.
  53.         // Send positional events to the object which contains their position.
  54.         if(event.isPositional())
  55.             {
  56.             // Get the posDevice location in local coords.
  57.             Point point = makePointLocal(event.posDevice.location);
  58.             obj = lastObjectThat(containsThisPosition, &point);
  59.             if(obj != 0)
  60.                 obj->handle(event);
  61.             }
  62.  
  63.         // Send focused events to the focused object.
  64.         else if(event.isFocused() && currentObject != 0)
  65.             currentObject->handle(event);
  66.  
  67.         // Send all messages (including broadcasts) to all objects.
  68.         //     The difference between messages and broadcasts: whoever uses
  69.         //    a message should clear it; *no one* should clear a broadcast.
  70.         else if(event.isMessage())
  71.             forEachObject(handleEvent, &event);
  72. }
  73.  
  74. void Window::insert(Visible* obj)
  75. {
  76.     Visible* ptr;
  77.  
  78.     // Make sure its not already in the collection.
  79.     if(obj == 0 || obj->owner == this)
  80.         return;
  81.  
  82.     // If its in another collection, remove it.
  83.     if(obj->owner != 0)
  84.         obj->owner->remove(obj);
  85.  
  86.     obj->owner = this;
  87.     // Insert it into the collection.
  88.     if(bottomObject == 0)
  89.         {
  90.         bottomObject = obj;
  91.         obj->next = obj;
  92.         }
  93.     else
  94.         {
  95.         // Insert this as the top object.
  96.         ptr = bottomObject->prevObject();
  97.         ptr->next = obj;
  98.         obj->next = bottomObject;
  99.         }
  100.  
  101.     // If can't set this as the focused view, paint it.
  102.     if(!obj->grabFocus() && obj->getFlag(vfVisible))
  103.         {}
  104. }
  105.  
  106. void Window::remove(Visible* obj)
  107. {
  108.     Visible* prev;
  109.     Visible* newFocus;
  110.     Rect r;
  111.  
  112.     // If its not in the collection, ignore.
  113.     if(obj->owner != this)
  114.         return;
  115.  
  116.     // Find the object who's before obj.
  117.     prev = obj->prevObject();
  118.  
  119.     // If obj is focused, find the next focus.
  120.     for(newFocus = obj->next; newFocus != obj; newFocus = newFocus->next)
  121.         if(newFocus->getFlag(vfFocusable) && newFocus->getFlag(vfVisible) &&
  122.            !newFocus->getFlag(vfDisabled))
  123.             break;
  124.  
  125.     // Get obj's rectangle in *this' coords.
  126.     r = obj->getOwnerBounds();
  127.  
  128.     // remove obj.
  129.     if(prev == obj)     // obj is the only object in the collection.
  130.         currentObject = bottomObject = 0;
  131.     else
  132.         {
  133.         // adjust bottomObject if necessary.
  134.         if(bottomObject == obj)
  135.             bottomObject = obj->next;
  136.         // remove obj
  137.         prev->next = obj->next;
  138.         // move the focus
  139.         currentObject = 0;
  140.         newFocus->grabFocus();
  141.         }
  142.     obj->owner = 0;
  143.     // Paint 'under' obj if it was visible.
  144.     if(obj->getFlag(vfVisible))
  145.         {}
  146. }
  147.  
  148. bool Window::moveFocusTo(Visible* obj)
  149. {
  150.     // Make sure either current doesn't exist, or can lose focus.
  151.     if(currentObject != 0 && !currentObject->canLoseFocus())
  152.         return false;
  153.  
  154.     // Make sure obj is in the collection and can gain the focus.
  155.     if(obj == 0 || obj->owner != this || !obj->getFlag(vfVisible|vfFocusable) ||
  156.        obj->getFlag(vfDisabled))
  157.         return false;
  158.  
  159.     // Only move the focus if obj is not already focused.
  160.     if(currentObject != obj)
  161.         {
  162.         // release the focus from current.
  163.         if(currentObject != 0)
  164.             currentObject->setFlag(vfFocused, false);
  165.         // set the focus to obj.
  166.         currentObject = obj;
  167.         obj->setFlag(vfFocused, true);
  168.         }
  169.     return true;
  170. }
  171.  
  172. word Window::run()
  173. {
  174.     Event event;
  175.  
  176.     modalReturnValue = IdNull;
  177.     setFlag(vfModal, true);
  178.     do    {
  179.         get(event);
  180.         if(!event.isNull())
  181.             handle(event);
  182.         }
  183.     while(modalReturnValue == IdNull);
  184.     setFlag(vfModal, false);
  185.     return modalReturnValue;
  186. }
  187.  
  188. void Window::forEachObject(void (*fn)(Visible*, void*), void* args) const
  189. {
  190.     // Only do if there are objects in the list.
  191.     if(bottomObject != 0)
  192.         {
  193.         Visible* obj = bottomObject;
  194.         do    {
  195.             fn(obj, args);
  196.             obj = obj->next;
  197.             }
  198.         while(obj != bottomObject);
  199.         }
  200. }
  201.  
  202. Visible* Window::firstObjectThat(bool (*fn)(Visible*, void*), void* args) const
  203. {
  204.     // Return null if the list is empty.
  205.     if(bottomObject == 0)
  206.         return 0;
  207.     else
  208.         {
  209.         Visible* obj = bottomObject;
  210.         do    {
  211.             if(fn(obj,args))
  212.                 return obj;
  213.             obj = obj->next;
  214.             }
  215.         while(obj != bottomObject);
  216.         return 0;
  217.         }
  218. }
  219.  
  220. Visible* Window::lastObjectThat(bool (*fn)(Visible*, void*), void* args) const
  221. {
  222.     if(bottomObject == 0)
  223.         return 0;
  224.     else
  225.         {
  226.         Visible* ref = bottomObject->prevObject();
  227.         Visible* obj = ref;
  228.         do    {
  229.             if(fn(obj,args))
  230.                 return obj;
  231.             obj = obj->prevObject();
  232.             }
  233.         while(obj != ref);
  234.         return 0;
  235.         }
  236. }
  237.  
  238.