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

CEGUIImageset.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002         filename:       CEGUIImageset.cpp
00003         created:        21/2/2004
00004         author:         Paul D Turner
00005         
00006         purpose:        Implements the Imageset class
00007 *************************************************************************/
00008 /*************************************************************************
00009     Crazy Eddie's GUI System (http://www.cegui.org.uk)
00010     Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
00011 
00012     This library is free software; you can redistribute it and/or
00013     modify it under the terms of the GNU Lesser General Public
00014     License as published by the Free Software Foundation; either
00015     version 2.1 of the License, or (at your option) any later version.
00016 
00017     This library is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020     Lesser General Public License for more details.
00021 
00022     You should have received a copy of the GNU Lesser General Public
00023     License along with this library; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 *************************************************************************/
00026 #include "CEGUIImageset.h"
00027 #include "CEGUIExceptions.h"
00028 #include "CEGUITexture.h"
00029 #include "CEGUIRenderer.h"
00030 #include "CEGUISystem.h"
00031 #include "CEGUIImageset_xmlHandler.h"
00032 #include "CEGUILogger.h"
00033 #include "CEGUIDataContainer.h"
00034 #include "CEGUIXMLParser.h"
00035 #include <iostream>
00036 #include <cmath>
00037 
00038 // Start of CEGUI namespace section
00039 namespace CEGUI
00040 {
00041 
00042 /*************************************************************************
00043         Definition of constant data for Imageset (and sub-classes)
00044 *************************************************************************/
00045 // Declared in Imageset
00046 const char      Imageset::ImagesetSchemaName[]                  = "Imageset.xsd";
00047 
00048 
00049 /*************************************************************************
00050         constructor
00051 *************************************************************************/
00052 Imageset::Imageset(const String& name, Texture* texture) :
00053         d_name(name),
00054         d_texture(texture)
00055 {
00056         if (d_texture == NULL)
00057         {
00058                 throw NullObjectException((utf8*)"Imageset::Imageset - Texture object supplied for Imageset creation must not be NULL");
00059         }
00060 
00061         // defaults for scaling options
00062         d_autoScale = false;
00063         setNativeResolution(Size(DefaultNativeHorzRes, DefaultNativeVertRes));
00064 }
00065 
00066 
00067 /*************************************************************************
00068         construct and initialise Imageset from the specified file.
00069 *************************************************************************/
00070 Imageset::Imageset(const String& filename, const String& resourceGroup)
00071 {
00072         // defaults for scaling options
00073         d_autoScale = false;
00074         setNativeResolution(Size(DefaultNativeHorzRes, DefaultNativeVertRes));
00075 
00076         d_texture = NULL;
00077         load(filename, resourceGroup);
00078 }
00079 
00080 
00081 Imageset::Imageset(const String& name, const String& filename, const String& resourceGroup) :
00082     d_name(name)
00083 {
00084     // try to load the image file using the renderer
00085     d_texture =
00086         System::getSingleton().getRenderer()->createTexture(filename, resourceGroup);
00087 
00088     // initialse the auto-scaling for this Imageset
00089     d_autoScale = true;
00090     setNativeResolution(
00091         Size(d_texture->getWidth(), d_texture->getHeight()));
00092 
00093     // define the default image for this Imageset
00094     defineImage(
00095         "full_image",
00096         Rect(0, 0, d_texture->getWidth(), d_texture->getHeight()),
00097         Point(0, 0)
00098     );
00099 }
00100 
00101 
00102 /*************************************************************************
00103         destructor
00104 *************************************************************************/
00105 Imageset::~Imageset(void)
00106 {
00107         unload();
00108 }
00109 
00110 
00111 /*************************************************************************
00112         Set texture for use by this imageset object
00113 *************************************************************************/
00114 void Imageset::setTexture(Texture* texture)
00115 {
00116         if (d_texture == NULL)
00117         {
00118                 throw NullObjectException((utf8*)"Imageset::setTexture - Texture object supplied for Imageset creation must not be NULL");
00119         }
00120 
00121         d_texture = texture;
00122 }
00123 
00124 
00125 /*************************************************************************
00126         load Imageset data from the specified file
00127 *************************************************************************/
00128 void Imageset::load(const String& filename, const String& resourceGroup)
00129 {
00130         // unload old data and texture.
00131         unload();
00132 
00133         if (filename.empty() || (filename == (utf8*)""))
00134         {
00135                 throw InvalidRequestException((utf8*)"Imageset::load - Filename supplied for Imageset loading must be valid");
00136         }
00137 
00138     // create handler object
00139     Imageset_xmlHandler handler(this);
00140 
00141         // do parse (which uses handler to create actual data)
00142         try
00143         {
00144         System::getSingleton().getXMLParser()->parseXMLFile(handler, filename, ImagesetSchemaName, resourceGroup);
00145         }
00146         catch(...)
00147         {
00148                 unload();
00149 
00150         Logger::getSingleton().logEvent("Imageset::load - loading of Imageset from file '" + filename +"' failed.", Errors);
00151         throw;
00152         }
00153 
00154 }
00155 
00156  
00157 /*************************************************************************
00158         return the Image object for the named image
00159 *************************************************************************/
00160 const Image& Imageset::getImage(const String& name) const
00161 {
00162         ImageRegistry::const_iterator   pos = d_images.find(name);
00163 
00164         if (pos == d_images.end())
00165         {
00166                 throw   UnknownObjectException("Imageset::getImage - The Image named '" + name + "' could not be found in Imageset '" + d_name + "'.");
00167         }
00168 
00169         return pos->second;
00170 }
00171 
00172 
00173 /*************************************************************************
00174         defines a new Image.
00175 *************************************************************************/
00176 void Imageset::defineImage(const String& name, const Rect& image_rect, const Point& render_offset)
00177 {
00178         if (isImageDefined(name))
00179         {
00180                 throw AlreadyExistsException("Imageset::defineImage - An image with the name '" + name + "' already exists in Imageset '" + d_name + "'.");
00181         }
00182 
00183         // get scaling factors
00184         float hscale = d_autoScale ? d_horzScaling : 1.0f;
00185         float vscale = d_autoScale ? d_vertScaling : 1.0f;
00186 
00187         // add the Image definition
00188         d_images[name] = Image(this, name, image_rect, render_offset, hscale, vscale);
00189 
00190         CEGUI_LOGINSANE("Image '" + name + "' has been defined for Imageset '" + d_name + "'.")
00191 }
00192 
00193 
00194 /*************************************************************************
00195         Queues an area of the associated Texture the be drawn on the screen.
00196         Low-level routine not normally used!
00197 *************************************************************************/
00198 void Imageset::draw(const Rect& source_rect, const Rect& dest_rect, float z, const Rect& clip_rect,const ColourRect& colours, QuadSplitMode quad_split_mode) const
00199 {
00200         // get the rect area that we will actually draw to (i.e. perform clipping)
00201         Rect final_rect(dest_rect.getIntersection(clip_rect));
00202 
00203         // check if rect was totally clipped
00204         if (final_rect.getWidth() != 0)
00205         {
00206                 float x_scale = 1.0f / (float)d_texture->getWidth();
00207                 float y_scale = 1.0f / (float)d_texture->getHeight();
00208 
00209                 float tex_per_pix_x = source_rect.getWidth() / dest_rect.getWidth();
00210                 float tex_per_pix_y = source_rect.getHeight() / dest_rect.getHeight();
00211 
00212                 // calculate final, clipped, texture co-ordinates
00213                 Rect  tex_rect((source_rect.d_left + ((final_rect.d_left - dest_rect.d_left) * tex_per_pix_x)) * x_scale,
00214                         (source_rect.d_top + ((final_rect.d_top - dest_rect.d_top) * tex_per_pix_y)) * y_scale,
00215                         (source_rect.d_right + ((final_rect.d_right - dest_rect.d_right) * tex_per_pix_x)) * x_scale,
00216                         (source_rect.d_bottom + ((final_rect.d_bottom - dest_rect.d_bottom) * tex_per_pix_y)) * y_scale);
00217 
00218                 final_rect.d_left       = PixelAligned(final_rect.d_left);
00219                 final_rect.d_right      = PixelAligned(final_rect.d_right);
00220                 final_rect.d_top        = PixelAligned(final_rect.d_top);
00221                 final_rect.d_bottom     = PixelAligned(final_rect.d_bottom);
00222 
00223                 // queue a quad to be rendered
00224                 d_texture->getRenderer()->addQuad(final_rect, z, d_texture, tex_rect, colours, quad_split_mode);
00225         }
00226 
00227 }
00228 
00229 /*************************************************************************
00230         Unload all data, leaving Imageset in a clean (but unusable) state
00231 *************************************************************************/
00232 void Imageset::unload(void)
00233 {
00234         undefineAllImages();
00235 
00236         // cleanup texture
00237         System::getSingleton().getRenderer()->destroyTexture(d_texture);
00238         d_texture = NULL;
00239 }
00240 
00241 
00242 /*************************************************************************
00243         Sets the scaling factor for all Images that are a part of this Imageset.
00244 *************************************************************************/
00245 void Imageset::updateImageScalingFactors(void)
00246 {
00247         float hscale, vscale;
00248 
00249         if (d_autoScale)
00250         {
00251                 hscale = d_horzScaling;
00252                 vscale = d_vertScaling;
00253         }
00254         else
00255         {
00256                 hscale = vscale = 1.0f;
00257         }
00258 
00259         ImageRegistry::iterator pos = d_images.begin(), end = d_images.end();
00260         for(; pos != end; ++pos)
00261         {
00262                 pos->second.setHorzScaling(hscale);
00263                 pos->second.setVertScaling(vscale);
00264         }
00265 
00266 }
00267 
00268 
00269 /*************************************************************************
00270         Enable or disable auto-scaling for this Imageset.
00271 *************************************************************************/
00272 void Imageset::setAutoScalingEnabled(bool setting)
00273 {
00274         if (setting != d_autoScale)
00275         {
00276                 d_autoScale = setting;
00277                 updateImageScalingFactors();
00278         }
00279 
00280 }
00281 
00282 
00283 /*************************************************************************
00284         Set the native resolution for this Imageset
00285 *************************************************************************/
00286 void Imageset::setNativeResolution(const Size& size)
00287 {
00288         d_nativeHorzRes = size.d_width;
00289         d_nativeVertRes = size.d_height;
00290 
00291         // re-calculate scaling factors & notify images as required
00292         notifyScreenResolution(System::getSingleton().getRenderer()->getSize());
00293 }
00294 
00295 
00296 /*************************************************************************
00297         Notify the Imageset of the current (usually new) display resolution.
00298 *************************************************************************/
00299 void Imageset::notifyScreenResolution(const Size& size)
00300 {
00301         d_horzScaling = size.d_width / d_nativeHorzRes;
00302         d_vertScaling = size.d_height / d_nativeVertRes;
00303 
00304         if (d_autoScale)
00305         {
00306                 updateImageScalingFactors();
00307         }
00308 
00309 }
00310 
00311 void Imageset::writeXMLToStream(OutStream& out_stream) const
00312 {
00313     // output opening tag
00314     out_stream << "<Imageset Name=\"" << d_name << "\" ";
00315     out_stream << "Filename=\"" << d_textureFilename << "\" ";
00316 
00317     if (d_nativeHorzRes != DefaultNativeHorzRes)
00318         out_stream << "NativeHorzRes=\"" << static_cast<uint>(d_nativeHorzRes) << "\" ";
00319 
00320     if (d_nativeVertRes != DefaultNativeVertRes)
00321         out_stream << "NativeVertRes=\"" << static_cast<uint>(d_nativeVertRes) << "\" ";
00322 
00323     if (d_autoScale)
00324         out_stream << "AutoScaled=\"True\" ";
00325 
00326     out_stream << ">" << std::endl;
00327 
00328     // output images
00329     ImageIterator image = getIterator();
00330 
00331     while (!image.isAtEnd())
00332     {
00333         image.getCurrentValue().writeXMLToStream(out_stream);
00334         ++image;
00335     }
00336 
00337     // output closing tag
00338     out_stream << "</Imageset>" << std::endl;
00339 }
00340 
00341 
00342 /*************************************************************************
00343         Return an iterator object that can be used to iterate over the Image
00344         objects in the Imageset.
00345 *************************************************************************/
00346 Imageset::ImageIterator Imageset::getIterator(void) const
00347 {
00348         return ImageIterator(d_images.begin(), d_images.end());
00349 }
00350 
00351 
00352 void Imageset::undefineImage(const String& name)
00353 {
00354         d_images.erase(name);
00355 
00356         CEGUI_LOGINSANE("Image '" + name + "' has been removed from Imageset '" + d_name + "'.")
00357 }
00358 
00359 
00360 void Imageset::undefineAllImages(void)
00361 {
00362         d_images.clear();
00363 
00364         CEGUI_LOGINSANE("All images have been removed from Imageset '" + d_name + "'.")
00365 }
00366 
00367 } // End of  CEGUI namespace section

Generated on Wed Sep 7 09:56:32 2005 for Crazy Eddies GUI System by  doxygen 1.4.3