00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 PG_Widget* PG_RectList::IsInside(const PG_Point& p) {
00074
00075 for(PG_Widget* i = last(); i != NULL; i = i->prev()) {
00076
00077
00078 if(!i->IsVisible() || i->IsHidden()) {
00079 continue;
00080 }
00081
00082
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
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
00139 return false;
00140 }
00141
00142 if(my_count > 0) {
00143 my_count--;
00144 }
00145
00146
00147 if(rect->my_prev == NULL) {
00148 my_first = rect->next();
00149 if(my_first != NULL) {
00150 my_first->my_prev = NULL;
00151 }
00152
00153 else {
00154 my_last = NULL;
00155 }
00156 }
00157
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
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
00189 PG_Rect o;
00190 SDL_GetClipRect(screen, &o);
00191
00192
00193 for(PG_Widget* i = start; i != end; i = i->next()) {
00194
00195 if(!i->IsVisible() || i->IsHidden()) {
00196 continue;
00197 }
00198
00199
00200
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
00210 i->Blit(false, false);
00211
00212
00213 childs = i->GetChildList();
00214 if(childs) {
00215 childs->Blit(rect);
00216 }
00217 }
00218
00219
00220 SDL_SetClipRect(PG_Application::GetScreen(), &o);
00221 }
00222
00223 void PG_RectList::Blit() {
00224
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 }