Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

pgrectlist.cpp

Go to the documentation of this file.
00001 /*
00002     ParaGUI - crossplatform widgetset
00003     Copyright (C) 2000,2001,2002  Alexander Pipelka
00004  
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009  
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014  
00015     You should have received a copy of the GNU Library General Public
00016     License along with this library; if not, write to the Free
00017     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  
00019     Alexander Pipelka
00020     pipelka@teleweb.at
00021  
00022     Last Update:      $Author: mbickel $
00023     Update Date:      $Date: 2007-04-13 16:16:00 $
00024     Source File:      $Source: /home/cvspsrv/cvsroot/games/asc/source/libs/paragui/src/core/pgrectlist.cpp,v $
00025     CVS/RCS Revision: $Revision: 1.2 $
00026     Status:           $State: Exp $
00027 */
00028 
00029 #include "pgrectlist.h"
00030 #include "pgwidget.h"
00031 #include "pgapplication.h"
00032 #include "pglog.h"
00033 
00034 #include <algorithm>
00035 
00036 PG_RectList::PG_RectList() :
00037                 my_first(NULL),
00038                 my_last(NULL),
00039 my_count(0) {}
00040 
00041 PG_RectList::~PG_RectList() {}
00042 
00043 /*PG_RectList PG_RectList::Intersect(PG_Rect* rect, PG_Rect* first, PG_Rect* last) {
00044         PG_RectList result;
00045  
00046         if(first == NULL) {
00047                 return result;
00048         }
00049  
00050         //PG_Widget* testwidget;
00051         PG_Rect* testrect;
00052  
00053         // loop through all rects
00054         for(PG_Widget* i = static_cast<PG_Widget*>(first); i != last; i = static_cast<PG_Widget*>(i->next)) {
00055  
00056                 // get the next rectangle to test
00057                 //testwidget = (*i).second;
00058  
00059                 if(!i->IsVisible() || i->IsHidden()) {
00060                         continue;
00061                 }
00062  
00063                 testrect = i->GetClipRect();
00064                 if(rect->OverlapRect(*testrect)) {
00065                         // append the matching rectangle
00066                         result.Add(new PG_Rect(*i));
00067                 }
00068         }
00069  
00070         return result;
00071 }*/
00072 
00073 PG_Widget* PG_RectList::IsInside(const PG_Point& p) {
00074         // loop down all rects till we find a match
00075         for(PG_Widget* i = last(); i != NULL; i = i->prev()) {
00076 
00077                 // check if the tested rect is visible
00078                 if(!i->IsVisible() || i->IsHidden()) {
00079                         continue;
00080                 }
00081 
00082                 // check for a match
00083                 if(i->GetClipRect()->IsInside(p)) {
00084                         return i;
00085                 }
00086         }
00087 
00088         return NULL;
00089 }
00090 
00091 void PG_RectList::Add(PG_Widget* rect, bool front) {
00092         if(rect->next() != NULL || rect->prev() != NULL) {
00093                 PG_LogWRN("PG_RectList::Add(...) Trying to add a linked PG_Rect object");
00094                 return;
00095         }
00096 
00097         Uint32 index = 2^31;
00098         my_count++;
00099 
00100         // get highest index
00101         if(my_last != NULL) {
00102                 index = my_last->index;
00103         }
00104         index++;
00105 
00106         if(front) {
00107                 if(my_first != NULL) {
00108                         my_first->my_prev = rect;
00109                         rect->index = my_first->index-1;
00110                 } else {
00111                         rect->index = index;
00112                 }
00113                 rect->my_next = my_first;
00114                 rect->my_prev = NULL;
00115                 my_first = rect;
00116                 return;
00117         }
00118 
00119         if(my_first == NULL) {
00120                 my_first = rect;
00121                 rect->my_prev = NULL;
00122                 rect->my_next = NULL;
00123         } else {
00124                 my_last->my_next = rect;
00125                 rect->my_next = NULL;
00126                 rect->my_prev = my_last;
00127         }
00128         my_last = rect;
00129         rect->index = index;
00130 }
00131 
00132 bool PG_RectList::Remove(PG_Rect* rect) {
00133         if(rect == NULL) {
00134                 return false;
00135         }
00136 
00137         if((rect->next() == NULL) && (rect->prev() == NULL) && (my_first != rect)) {
00138                 //PG_LogWRN("PG_RectList::Remove(...) Trying to remove an unlinked PG_Rect object");
00139                 return false;
00140         }
00141 
00142         if(my_count > 0) {
00143                 my_count--;
00144         }
00145 
00146         // first in list
00147         if(rect->my_prev == NULL) {
00148                 my_first = rect->next();
00149                 if(my_first != NULL) {
00150                         my_first->my_prev = NULL;
00151                 }
00152                 // first and last
00153                 else {
00154                         my_last = NULL;
00155                 }
00156         }
00157         // last
00158         else if(rect->my_next == NULL) {
00159                 my_last = rect->my_prev;
00160                 if(my_last != NULL) {
00161                         my_last->my_next = NULL;
00162                 }
00163         }
00164         // in between
00165         else {
00166                 rect->my_prev->my_next = rect->my_next;
00167                 rect->my_next->my_prev = rect->my_prev;
00168         }
00169 
00170         rect->my_next = NULL;
00171         rect->my_prev = NULL;
00172 
00173         return true;
00174 }
00175 
00176 void PG_RectList::Blit(const PG_Rect& rect) {
00177         Blit(rect, first());
00178 }
00179 
00180 void PG_RectList::Blit(const PG_Rect& rect, PG_Widget* start, PG_Widget* end) {
00181         if(start == NULL) {
00182                 return;
00183         }
00184 
00185         PG_RectList* childs;
00186         SDL_Surface* screen = PG_Application::GetScreen();
00187 
00188         // store old clipping rectangle
00189         PG_Rect o;
00190         SDL_GetClipRect(screen, &o);
00191 
00192         // blit all objects in the list
00193         for(PG_Widget* i = start; i != end; i = i->next()) {
00194 
00195                 if(!i->IsVisible() || i->IsHidden()) {
00196                         continue;
00197                 }
00198 
00199                 // calculate the clipping rectangle
00200                 // cliprect = blittingregion / widgetcliprect
00201                 PG_Rect* cr = i->GetClipRect();
00202                 if(!rect.OverlapRect(*cr)) {
00203                         continue;
00204                 }
00205 
00206                 PG_Rect c = cr->IntersectRect(rect);
00207                 SDL_SetClipRect(screen, &c);
00208 
00209                 // blit it
00210                 i->Blit(false, false);
00211 
00212                 // blit all children of the widget
00213                 childs = i->GetChildList();
00214                 if(childs) {
00215                         childs->Blit(rect);
00216                 }
00217         }
00218 
00219         // reset clipping rectangle
00220         SDL_SetClipRect(PG_Application::GetScreen(), &o);
00221 }
00222 
00223 void PG_RectList::Blit() {
00224         // blit all objects in the list
00225         for(PG_Widget* i = first(); i != NULL; i = i->next()) {
00226                 if(!i->IsVisible() || i->IsHidden()) {
00227                         continue;
00228                 }
00229 
00230                 i->Blit(true, false);
00231         }
00232 }
00233 
00234 bool PG_RectList::BringToFront(PG_Widget* rect) {
00235         if(!Remove(rect)) {
00236                 return false;
00237         }
00238         Add(rect);
00239 
00240         return true;
00241 }
00242 
00243 bool PG_RectList::SendToBack(PG_Widget* rect) {
00244         if(!Remove(rect)) {
00245                 return false;
00246         }
00247         Add(rect, true);
00248 
00249         return true;
00250 }
00251 
00252 PG_Widget* PG_RectList::Find(int id, bool recursive ) {
00253         for(PG_Widget* i = first(); i != NULL; i = i->next()) {
00254                 if(i->GetID() == id) {
00255                         return i;
00256                 }
00257         }
00258         if ( recursive )
00259                 for(PG_Widget* i = first(); i != NULL; i = i->next()) {
00260                         PG_Widget* w = i->FindChild(id, recursive );
00261                         if( w ) {
00262                                 return w;
00263                         }
00264                 }
00265         return NULL;
00266 }
00267 
00268 PG_Widget* PG_RectList::Find(const std::string& name, bool recursive ) {
00269         for(PG_Widget* i = first(); i != NULL; i = i->next()) {
00270                 if(i->GetName() == name) {
00271                         return i;
00272                 }
00273         }
00274         if ( recursive )
00275                 for(PG_Widget* i = first(); i != NULL; i = i->next()) {
00276                         PG_Widget* w = i->FindChild(name, recursive );
00277                         if( w ) {
00278                                 return w;
00279                         }
00280                 }
00281         return NULL;
00282 }
00283 
00284 void PG_RectList::clear() {
00285         my_first = NULL;
00286         my_last = NULL;
00287         my_count = 0;
00288 }

Generated on Tue Jun 24 01:27:49 2008 for Advanced Strategic Command by  doxygen 1.4.2