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

pgthemewidget.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:04 $
00024     Source File:      $Source: /home/cvspsrv/cvsroot/games/asc/source/libs/paragui/src/widgets/pgthemewidget.cpp,v $
00025     CVS/RCS Revision: $Revision: 1.2 $
00026     Status:           $State: Exp $
00027 */
00028 
00029 #include "pgthemewidget.h"
00030 #include "pgdraw.h"
00031 #include "pgapplication.h"
00032 #include "pglog.h"
00033 #include "pgtheme.h"
00034 
00035 #include "propstrings_priv.h"
00036 
00037 static PG_SurfaceCache my_SurfaceCache;
00038 
00039 class PG_ThemeWidgetDataInternal {
00040 public:
00041         PG_ThemeWidgetDataInternal() :
00042                         cachesurface(NULL),
00043                         backgroundcolor(128,128,128),
00044                         freeimage(false),
00045                         simplebackground(false),
00046         nocache(false) {}
00047         ;
00048 
00049         SDL_Surface* cachesurface;
00050         PG_Color backgroundcolor;
00051 
00052         bool freeimage;
00053         bool simplebackground;
00054         bool nocache;
00055 
00056 };
00057 
00058 PG_ThemeWidget::PG_ThemeWidget(PG_Widget* parent, const PG_Rect& r, const std::string& style) : PG_Widget(parent, r) {
00059         Init(style);
00060 }
00061 
00062 PG_ThemeWidget::PG_ThemeWidget(PG_Widget* parent, const PG_Rect& r, bool bCreateSurface, const std::string& style) : PG_Widget(parent, r, bCreateSurface) {
00063         Init(style);
00064 }
00065 
00066 void PG_ThemeWidget::Init(const std::string& style) {
00067         SetDirtyUpdate(true);
00068 
00069         _mid = new PG_ThemeWidgetDataInternal;
00070 
00071         my_backgroundFree = false;
00072         my_background = NULL;
00073         my_blendLevel = 0;
00074         my_backgroundMode = PG_Draw::TILE;
00075         my_bordersize = 0;
00076         my_has_gradient = false;
00077 
00078         my_image = NULL;
00079 
00080         LoadThemeStyle(style);
00081 }
00082 
00083 PG_ThemeWidget::~PG_ThemeWidget() {
00084 
00085         // free surfaces
00086         FreeSurface();
00087         FreeImage();
00088 
00089         // remove the cachesurface
00090         DeleteThemedSurface(_mid->cachesurface);
00091 
00092         // delete internal data
00093         delete _mid;
00094 }
00095 
00096 void PG_ThemeWidget::LoadThemeStyle(const std::string& widgettype) {
00097         if(widgettype != PG_PropStr::ThemeWidget) {
00098                 PG_ThemeWidget::LoadThemeStyle(PG_PropStr::ThemeWidget, PG_PropStr::ThemeWidget);
00099         }
00100         PG_ThemeWidget::LoadThemeStyle(widgettype, PG_PropStr::ThemeWidget);
00101 }
00102 
00103 void PG_ThemeWidget::LoadThemeStyle(const std::string& widgettype, const std::string& objectname) {
00104 
00105         PG_Theme* t = PG_Application::GetTheme();
00106 
00107         if(my_srfObject == NULL) {
00108                 if(objectname != PG_PropStr::ThemeWidget) {
00109                         PG_ThemeWidget::LoadThemeStyle(widgettype, PG_PropStr::ThemeWidget);
00110                 }
00111 
00112                 t->GetProperty(widgettype, objectname, PG_PropStr::simplebackground, _mid->simplebackground);
00113                 t->GetProperty(widgettype, objectname, PG_PropStr::nocache, _mid->nocache);
00114                 t->GetColor(widgettype, objectname, PG_PropStr::backgroundcolor, _mid->backgroundcolor);
00115         }
00116 
00117         const std::string& font = t->FindFontName(widgettype, objectname);
00118         int fontsize = t->FindFontSize(widgettype, objectname);
00119         PG_Font::Style fontstyle = t->FindFontStyle(widgettype, objectname);
00120 
00121         if(!font.empty()) {
00122                 SetFontName(font);
00123         }
00124 
00125         if(fontsize > 0) {
00126                 SetFontSize(fontsize);
00127         }
00128 
00129         if(fontstyle >= 0) {
00130                 SetFontStyle(fontstyle);
00131         }
00132 
00133         SetBackground(t->FindSurface(widgettype, objectname, PG_PropStr::background));
00134 
00135         t->GetProperty(widgettype, objectname, PG_PropStr::blend, my_blendLevel);
00136         t->GetProperty(widgettype, objectname, PG_PropStr::bordersize, my_bordersize);
00137         t->GetProperty(widgettype, objectname, PG_PropStr::backmode, my_backgroundMode);
00138 
00139         PG_Gradient* g = t->FindGradient(widgettype, objectname, PG_PropStr::gradient);
00140 
00141         if(g) {
00142                 SetGradient(*g);
00143         }
00144 
00145         Uint8 trans = GetTransparency();
00146         t->GetProperty(widgettype, objectname, PG_PropStr::transparency, trans);
00147         SetTransparency(trans);
00148 
00149         PG_Widget::LoadThemeStyle(widgettype, objectname);
00150 
00151         int w = Width();
00152         t->GetProperty(widgettype, objectname, PG_PropStr::width, w);
00153         int h = Height();
00154         t->GetProperty(widgettype, objectname, PG_PropStr::height, h);
00155 
00156         if((w != Width()) || (h != Height())) {
00157                 SizeWidget(w, h);
00158         }
00159 }
00160 
00161 void PG_ThemeWidget::eventDraw(SDL_Surface* surface, const PG_Rect& rect) {
00162         if(my_srfObject == NULL) {
00163                 return;
00164         }
00165 
00166         PG_Draw::DrawThemedSurface(
00167             surface,
00168             rect,
00169             my_has_gradient ? &my_gradient : 0,
00170             my_background,
00171             my_backgroundMode,
00172             my_blendLevel);
00173 
00174         if(my_bordersize > 0) {
00175                 DrawBorder(rect, my_bordersize);
00176         }
00177 }
00178 
00179 bool PG_ThemeWidget::SetBackground(const std::string& filename, PG_Draw::BkMode mode, const PG_Color &colorkey) {
00180         // try to load the file
00181         SDL_Surface* temp = PG_Application::LoadSurface(filename, true);
00182 
00183         // success ?
00184         if(!temp) {
00185                 return false;
00186         }
00187 
00188         // free previous surface
00189         FreeSurface();
00190 
00191         // mark my_background to be freed on destruction
00192         my_backgroundFree = true;
00193         my_backgroundMode = mode;
00194         my_background = temp;
00195 
00196         if(my_background == NULL) {
00197                 return false;
00198         }
00199 
00200         Uint32 c = colorkey.MapRGB(my_background->format);
00201         SDL_SetColorKey(my_background, SDL_SRCCOLORKEY, c);
00202 
00203         if(my_srfObject == NULL) {
00204                 CreateSurface();
00205         }
00206 
00207         return (my_background != NULL);
00208 }
00209 
00210 bool PG_ThemeWidget::SetBackground(const std::string& filename, PG_Draw::BkMode mode) {
00211 
00212         // try to load the file
00213         SDL_Surface* temp = PG_Application::LoadSurface(filename, true);
00214 
00215         // success ?
00216         if(!temp) {
00217                 return false;
00218         }
00219 
00220         // free previous surface
00221         FreeSurface();
00222 
00223         // mark my_background to be freed on destruction
00224         my_backgroundFree = true;
00225         my_backgroundMode = mode;
00226         my_background = temp;
00227 
00228         if(my_background == NULL) {
00229                 return false;
00230         }
00231 
00232         if(my_srfObject == NULL) {
00233                 CreateSurface();
00234         }
00235 
00236         return (my_background != NULL);
00237 }
00238 
00239 
00240 bool PG_ThemeWidget::SetBackground(SDL_Surface* surface, PG_Draw::BkMode mode) {
00241 
00242         if(!surface) {
00243                 return false;
00244         }
00245 
00246         FreeSurface();
00247 
00248         my_background = surface;
00249         my_backgroundFree = false;
00250         my_backgroundMode = mode;
00251 
00252         if(my_srfObject == NULL) {
00253                 CreateSurface();
00254         }
00255 
00256         return true;
00257 }
00258 
00259 void PG_ThemeWidget::SetBackgroundBlend(Uint8 backblend) {
00260         my_blendLevel = backblend;
00261 }
00262 
00263 void PG_ThemeWidget::FreeSurface() {
00264 
00265         // check if we have to free a previous surface
00266 
00267         if (my_backgroundFree && my_background != NULL) {
00268                 PG_Application::UnloadSurface(my_background);
00269                 my_background = NULL;
00270                 my_backgroundFree = false;
00271         }
00272 }
00273 
00274 void PG_ThemeWidget::SetGradient(const PG_Gradient& grad) {
00275         my_gradient = grad;
00276         my_has_gradient = true;
00277         DeleteThemedSurface(_mid->cachesurface);
00278         _mid->cachesurface = NULL;
00279         Redraw();
00280 }
00281 
00282 PG_Gradient PG_ThemeWidget::GetGradient() {
00283         return my_gradient;
00284 }
00285 
00286 void PG_ThemeWidget::FreeImage() {
00287 
00288         if(_mid->freeimage) {
00289                 PG_Application::UnloadSurface(my_image); // false
00290         }
00291 
00292         _mid->freeimage = false;
00293         my_image = NULL;
00294         return;
00295 }
00296 
00297 bool PG_ThemeWidget::SetImage(SDL_Surface* image, bool bFreeImage) {
00298         if(image == NULL) {
00299                 return false;
00300         }
00301 
00302         if(image == my_image) {
00303                 return true;
00304         }
00305 
00306         FreeImage();
00307         _mid->freeimage = bFreeImage;
00308         my_image = image;
00309 
00310         Update();
00311         return true;
00312 }
00313 
00314 bool PG_ThemeWidget::LoadImage(const std::string& filename, const PG_Color& key) {
00315         if(LoadImage(filename)) {
00316                 SDL_SetColorKey(my_image, SDL_SRCCOLORKEY, key);
00317                 return true;
00318         }
00319 
00320         return false;
00321 }
00322 
00323 bool PG_ThemeWidget::LoadImage(const std::string& filename) {
00324         SDL_Surface* image = PG_Application::LoadSurface(filename);
00325         return SetImage(image, true);
00326 }
00327 
00328 void PG_ThemeWidget::eventSizeWidget(Uint16 w, Uint16 h) {
00329         DeleteThemedSurface(_mid->cachesurface);
00330         _mid->cachesurface = NULL;
00331 }
00332 
00333 void PG_ThemeWidget::CreateSurface(Uint16 w, Uint16 h) {
00334         if(_mid->simplebackground) {
00335                 return;
00336         }
00337 
00338         DeleteThemedSurface(_mid->cachesurface);
00339 
00340         if(w == 0 || h == 0) {
00341                 _mid->cachesurface = NULL;
00342                 return;
00343         }
00344 
00345         PG_Rect r(my_xpos, my_ypos, w, h);
00346 
00347         _mid->cachesurface = CreateThemedSurface(
00348                                  r,
00349                                  my_has_gradient ? &my_gradient : 0,
00350                                  my_background,
00351                                  my_backgroundMode,
00352                                  my_blendLevel);
00353 }
00354 
00355 void PG_ThemeWidget::eventBlit(SDL_Surface* srf, const PG_Rect& src, const PG_Rect& dst) {
00356 
00357         if(my_srfObject != NULL) {
00358                 PG_Widget::eventBlit(srf, src, dst);
00359                 return;
00360         }
00361 
00362         if(!_mid->simplebackground && !_mid->nocache) {
00363                 if(_mid->cachesurface == NULL) {
00364                         CreateSurface(Width(), Height());
00365                 }
00366                 PG_Widget::eventBlit(_mid->cachesurface, src, dst);
00367         } else if (_mid->simplebackground) {
00368                 if(GetTransparency() < 255) {
00369                         Uint32 c = _mid->backgroundcolor.MapRGBA(
00370                                        PG_Application::GetScreen()->format,
00371                                        255-GetTransparency());
00372                         SDL_FillRect(PG_Application::GetScreen(), const_cast<PG_Rect*>(&dst), c);
00373                 }
00374         } else if (_mid->nocache) {
00375                 _mid->cachesurface = CreateThemedSurface(
00376                                          *this,
00377                                          my_has_gradient ? &my_gradient : 0,
00378                                          my_background,
00379                                          my_backgroundMode,
00380                                          my_blendLevel);
00381                 PG_Widget::eventBlit(_mid->cachesurface, src, dst);
00382                 DeleteThemedSurface(_mid->cachesurface);
00383                 _mid->cachesurface = NULL;
00384         }
00385 
00386         if(my_bordersize > 0) {
00387                 DrawBorder(PG_Rect(0, 0, Width(), Height()), my_bordersize, true);
00388         }
00389 
00390         if(my_image != NULL) {
00391                 PG_Rect my_src;
00392                 PG_Rect my_dst;
00393 
00394                 GetClipRects(my_src, my_dst, *this);
00395                 PG_Widget::eventBlit(my_image, my_src, my_dst);
00396         }
00397 }
00398 
00399 void PG_ThemeWidget::SetTransparency(Uint8 t, bool bRecursive) {
00400         if(_mid->simplebackground || _mid->nocache) {
00401                 PG_Widget::SetTransparency(t, bRecursive);
00402                 return;
00403         }
00404 
00405         if(t == 255) {
00406                 DeleteThemedSurface(_mid->cachesurface);
00407                 _mid->cachesurface = NULL;
00408         } else if(GetTransparency() == 255) {
00409                 CreateSurface();
00410         }
00411         PG_Widget::SetTransparency(t, bRecursive);
00412 }
00413 
00414 SDL_Surface* PG_ThemeWidget::CreateThemedSurface(const PG_Rect& r, PG_Gradient* gradient, SDL_Surface* background, PG_Draw::BkMode bkmode, Uint8 blend) {
00415         SDL_Surface* cache_surface = NULL;
00416         SDL_Surface* screen = PG_Application::GetScreen();
00417         std::string key;
00418 
00419         if(r.w == 0 || r.h == 0) {
00420                 return NULL;
00421         }
00422 
00423         // create a key for the surface
00424         my_SurfaceCache.CreateKey(key, r.my_width, r.my_height,  gradient, background, bkmode, blend);
00425 
00426         // lookup the surface in cache
00427         cache_surface = my_SurfaceCache.FindSurface(key);
00428 
00429         // draw the cached surface :)
00430         if(cache_surface != NULL) {
00431                 // increase the reference count
00432                 my_SurfaceCache.IncRef(key);
00433                 return cache_surface;
00434         }
00435 
00436         Uint8 bpp = screen->format->BitsPerPixel;
00437         Uint32 Rmask = screen->format->Rmask;
00438         Uint32 Gmask = screen->format->Gmask;
00439         Uint32 Bmask = screen->format->Bmask;
00440         Uint32 Amask = 0;
00441 
00442         if(background != NULL) {
00443                 if((background->format->Amask != 0) || ((bpp < background->format->BitsPerPixel) && (bpp <= 8))) {
00444                         bpp = background->format->BitsPerPixel;
00445                         Rmask = background->format->Rmask;
00446                         Gmask = background->format->Gmask;
00447                         Bmask = background->format->Bmask;
00448                         Amask = background->format->Amask;
00449                 }
00450         }
00451 
00452         SDL_Surface *surface = SDL_CreateRGBSurface(
00453                                    SDL_HWSURFACE,
00454                                    r.my_width,
00455                                    r.my_height,
00456                                    bpp,
00457                                    Rmask,
00458                                    Gmask,
00459                                    Bmask,
00460                                    Amask
00461                                );
00462 
00463 
00464         if(SDL_MUSTLOCK(surface)) {
00465                 SDL_LockSurface(surface);
00466         }
00467 
00468         if ( bpp == 8 )
00469                 SDL_SetPalette ( surface, SDL_LOGPAL, screen->format->palette->colors, 0, 256 );
00470 
00471         if(surface) {
00472                 if(background || gradient) {
00473                         PG_Draw::DrawThemedSurface(surface, PG_Rect(0, 0, r.my_width, r.my_height), gradient, background, bkmode, blend);
00474                 } else {
00475                         SDL_SetColorKey(surface, SDL_SRCCOLORKEY, 0);
00476                 }
00477         }
00478 
00479         if(SDL_MUSTLOCK(surface)) {
00480                 SDL_UnlockSurface(surface);
00481         }
00482 
00483         my_SurfaceCache.AddSurface(key, surface);
00484         return surface;
00485 }
00486 
00487 void PG_ThemeWidget::DeleteThemedSurface(SDL_Surface* surface) {
00488         if(surface == NULL) {
00489                 return;
00490         }
00491         my_SurfaceCache.DeleteSurface(surface);
00492 }
00493 
00494 void PG_ThemeWidget::SetSimpleBackground(bool simple) {
00495         _mid->simplebackground = simple;
00496         DeleteThemedSurface(_mid->cachesurface);
00497         _mid->cachesurface = NULL;
00498         Redraw();
00499 }
00500 
00501 void PG_ThemeWidget::SetBackgroundColor(const PG_Color& c) {
00502         _mid->backgroundcolor = c;
00503 }

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