home *** CD-ROM | disk | FTP | other *** search
- #include "..\WINDOW\WINDOW.HPP"
-
- // ------------------------------------------------------------------
- // File: WINDOW.CPP
- // Path: ...\REHACK\WINDOW\WINDOW.CPP
- // Version: 0.01
- // Author: Pat Reilly
- // CIS Id: 71333,2764
- // Created On: 6/28/93
- // Modified On:
- // Description: Window class for REHACK. See WINDOW.TXT for
- // more details.
- // Tabs: 4
- // ------------------------------------------------------------------
-
- Window::Window(const Rect& aBounds) :
- Visible(aBounds), bottomObject(0), currentObject(0)
- {}
-
- Window::~Window()
- {
- // Since it 'owns' its objects, delete them.
- while(bottomObject != 0)
- delete bottomObject;
- }
-
- // Static function used by handle().
- // The point (void*) argument is assumed to be in *this' (obj's owner)
- // coordinates.
- static bool containsThisPosition(Visible* obj, void* pt)
- {
- if(!obj->getFlag(vfVisible))
- return false;
- else
- return obj->getOwnerBounds().contains(*((Point*)pt));
- }
-
- // Static function used by handle().
- static void handleEvent(Visible* obj, void* ev)
- {
- // Only pass the event on if it hasn't been used (cleared) by a previous
- // object, and if its enabled in the eventMask mask.
- if(!((Event*)ev)->isNull() && !obj->getFlag(vfDisabled) &&
- (obj->eventMask & ((Event*)ev)->type) != 0)
- obj->handle(*((Event*)ev));
- }
-
- void Window::handle(Event& event)
- {
- Visible* obj;
-
- if(!event.isNull()) // Ignore null events.
- // Send positional events to the object which contains their position.
- if(event.isPositional())
- {
- // Get the posDevice location in local coords.
- Point point = makePointLocal(event.posDevice.location);
- obj = lastObjectThat(containsThisPosition, &point);
- if(obj != 0)
- obj->handle(event);
- }
-
- // Send focused events to the focused object.
- else if(event.isFocused() && currentObject != 0)
- currentObject->handle(event);
-
- // Send all messages (including broadcasts) to all objects.
- // The difference between messages and broadcasts: whoever uses
- // a message should clear it; *no one* should clear a broadcast.
- else if(event.isMessage())
- forEachObject(handleEvent, &event);
- }
-
- void Window::insert(Visible* obj)
- {
- Visible* ptr;
-
- // Make sure its not already in the collection.
- if(obj == 0 || obj->owner == this)
- return;
-
- // If its in another collection, remove it.
- if(obj->owner != 0)
- obj->owner->remove(obj);
-
- obj->owner = this;
- // Insert it into the collection.
- if(bottomObject == 0)
- {
- bottomObject = obj;
- obj->next = obj;
- }
- else
- {
- // Insert this as the top object.
- ptr = bottomObject->prevObject();
- ptr->next = obj;
- obj->next = bottomObject;
- }
-
- // If can't set this as the focused view, paint it.
- if(!obj->grabFocus() && obj->getFlag(vfVisible))
- {}
- }
-
- void Window::remove(Visible* obj)
- {
- Visible* prev;
- Visible* newFocus;
- Rect r;
-
- // If its not in the collection, ignore.
- if(obj->owner != this)
- return;
-
- // Find the object who's before obj.
- prev = obj->prevObject();
-
- // If obj is focused, find the next focus.
- for(newFocus = obj->next; newFocus != obj; newFocus = newFocus->next)
- if(newFocus->getFlag(vfFocusable) && newFocus->getFlag(vfVisible) &&
- !newFocus->getFlag(vfDisabled))
- break;
-
- // Get obj's rectangle in *this' coords.
- r = obj->getOwnerBounds();
-
- // remove obj.
- if(prev == obj) // obj is the only object in the collection.
- currentObject = bottomObject = 0;
- else
- {
- // adjust bottomObject if necessary.
- if(bottomObject == obj)
- bottomObject = obj->next;
- // remove obj
- prev->next = obj->next;
- // move the focus
- currentObject = 0;
- newFocus->grabFocus();
- }
- obj->owner = 0;
- // Paint 'under' obj if it was visible.
- if(obj->getFlag(vfVisible))
- {}
- }
-
- bool Window::moveFocusTo(Visible* obj)
- {
- // Make sure either current doesn't exist, or can lose focus.
- if(currentObject != 0 && !currentObject->canLoseFocus())
- return false;
-
- // Make sure obj is in the collection and can gain the focus.
- if(obj == 0 || obj->owner != this || !obj->getFlag(vfVisible|vfFocusable) ||
- obj->getFlag(vfDisabled))
- return false;
-
- // Only move the focus if obj is not already focused.
- if(currentObject != obj)
- {
- // release the focus from current.
- if(currentObject != 0)
- currentObject->setFlag(vfFocused, false);
- // set the focus to obj.
- currentObject = obj;
- obj->setFlag(vfFocused, true);
- }
- return true;
- }
-
- word Window::run()
- {
- Event event;
-
- modalReturnValue = IdNull;
- setFlag(vfModal, true);
- do {
- get(event);
- if(!event.isNull())
- handle(event);
- }
- while(modalReturnValue == IdNull);
- setFlag(vfModal, false);
- return modalReturnValue;
- }
-
- void Window::forEachObject(void (*fn)(Visible*, void*), void* args) const
- {
- // Only do if there are objects in the list.
- if(bottomObject != 0)
- {
- Visible* obj = bottomObject;
- do {
- fn(obj, args);
- obj = obj->next;
- }
- while(obj != bottomObject);
- }
- }
-
- Visible* Window::firstObjectThat(bool (*fn)(Visible*, void*), void* args) const
- {
- // Return null if the list is empty.
- if(bottomObject == 0)
- return 0;
- else
- {
- Visible* obj = bottomObject;
- do {
- if(fn(obj,args))
- return obj;
- obj = obj->next;
- }
- while(obj != bottomObject);
- return 0;
- }
- }
-
- Visible* Window::lastObjectThat(bool (*fn)(Visible*, void*), void* args) const
- {
- if(bottomObject == 0)
- return 0;
- else
- {
- Visible* ref = bottomObject->prevObject();
- Visible* obj = ref;
- do {
- if(fn(obj,args))
- return obj;
- obj = obj->prevObject();
- }
- while(obj != ref);
- return 0;
- }
- }
-
-