00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "falagard/CEGUIFalFrameComponent.h"
00025 #include "falagard/CEGUIFalXMLEnumHelper.h"
00026 #include "CEGUIImage.h"
00027 #include "CEGUIExceptions.h"
00028 #include "CEGUIImagesetManager.h"
00029 #include "CEGUIImageset.h"
00030 #include <iostream>
00031
00032
00033 namespace CEGUI
00034 {
00035 FrameComponent::FrameComponent() :
00036 d_vertFormatting(VF_STRETCHED),
00037 d_horzFormatting(HF_STRETCHED)
00038 {
00039 for (int i = 0; i < FIC_FRAME_IMAGE_COUNT; ++i)
00040 d_frameImages[i] = 0;
00041 }
00042
00043 VerticalFormatting FrameComponent::getBackgroundVerticalFormatting() const
00044 {
00045 return d_vertFormatting;
00046 }
00047
00048 void FrameComponent::setBackgroundVerticalFormatting(VerticalFormatting fmt)
00049 {
00050 d_vertFormatting = fmt;
00051 }
00052
00053 HorizontalFormatting FrameComponent::getBackgroundHorizontalFormatting() const
00054 {
00055 return d_horzFormatting;
00056 }
00057
00058 void FrameComponent::setBackgroundHorizontalFormatting(HorizontalFormatting fmt)
00059 {
00060 d_horzFormatting = fmt;
00061 }
00062
00063 const Image* FrameComponent::getImage(FrameImageComponent part) const
00064 {
00065 assert(part < FIC_FRAME_IMAGE_COUNT);
00066
00067 return d_frameImages[part];
00068 }
00069
00070 void FrameComponent::setImage(FrameImageComponent part, const Image* image)
00071 {
00072 assert(part < FIC_FRAME_IMAGE_COUNT);
00073
00074 d_frameImages[part] = image;
00075 }
00076
00077 void FrameComponent::setImage(FrameImageComponent part, const String& imageset, const String& image)
00078 {
00079 assert(part < FIC_FRAME_IMAGE_COUNT);
00080
00081 try
00082 {
00083 d_frameImages[part] = &ImagesetManager::getSingleton().getImageset(imageset)->getImage(image);
00084 }
00085 catch (UnknownObjectException)
00086 {
00087 d_frameImages[part] = 0;
00088 }
00089 }
00090
00091 void FrameComponent::render_impl(Window& srcWindow, Rect& destRect, float base_z, const CEGUI::ColourRect* modColours, const Rect* clipper, bool clipToDisplay) const
00092 {
00093 Rect backgroundRect(destRect);
00094 Rect finalRect;
00095 Size imageSize;
00096 ColourRect imageColours;
00097 float leftfactor, rightfactor, topfactor, bottomfactor;
00098 bool calcColoursPerImage;
00099
00100
00101 float topOffset = 0, bottomOffset = 0, leftOffset = 0, rightOffset = 0;
00102 float topWidth, bottomWidth, leftHeight, rightHeight;
00103 topWidth = bottomWidth = destRect.getWidth();
00104 leftHeight = rightHeight = destRect.getHeight();
00105
00106
00107 ColourRect finalColours;
00108 initColoursRect(srcWindow, modColours, finalColours);
00109
00110 if (finalColours.isMonochromatic())
00111 {
00112 calcColoursPerImage = false;
00113 imageColours = finalColours;
00114 }
00115 else
00116 {
00117 calcColoursPerImage = true;
00118 }
00119
00120
00121 if (d_frameImages[FIC_TOP_LEFT_CORNER])
00122 {
00123
00124 imageSize = d_frameImages[FIC_TOP_LEFT_CORNER]->getSize();
00125 finalRect.d_left = destRect.d_left;
00126 finalRect.d_top = destRect.d_top;
00127 finalRect.setSize(imageSize);
00128
00129
00130 topOffset += imageSize.d_width;
00131 leftOffset += imageSize.d_height;
00132 topWidth -= topOffset;
00133 leftHeight -= leftOffset;
00134
00135
00136 if (calcColoursPerImage)
00137 {
00138 leftfactor = (finalRect.d_left + d_frameImages[FIC_TOP_LEFT_CORNER]->getOffsetX()) / destRect.getWidth();
00139 rightfactor = leftfactor + finalRect.getWidth() / destRect.getWidth();
00140 topfactor = (finalRect.d_top + d_frameImages[FIC_TOP_LEFT_CORNER]->getOffsetY()) / destRect.getHeight();
00141 bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();
00142
00143 imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
00144 }
00145
00146
00147 srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_TOP_LEFT_CORNER], finalRect, base_z, imageColours, 0, clipToDisplay);
00148 }
00149
00150
00151 if (d_frameImages[FIC_TOP_RIGHT_CORNER])
00152 {
00153
00154 imageSize = d_frameImages[FIC_TOP_RIGHT_CORNER]->getSize();
00155 finalRect.d_left = destRect.d_right - imageSize.d_width;
00156 finalRect.d_top = destRect.d_top;
00157 finalRect.setSize(imageSize);
00158
00159
00160 rightOffset += imageSize.d_height;
00161 topWidth -= imageSize.d_width;
00162 rightHeight -= rightOffset;
00163
00164
00165 if (calcColoursPerImage)
00166 {
00167 leftfactor = (finalRect.d_left + d_frameImages[FIC_TOP_RIGHT_CORNER]->getOffsetX()) / destRect.getWidth();
00168 rightfactor = leftfactor + finalRect.getWidth() / destRect.getWidth();
00169 topfactor = (finalRect.d_top + d_frameImages[FIC_TOP_RIGHT_CORNER]->getOffsetY()) / destRect.getHeight();
00170 bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();
00171
00172 imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
00173 }
00174
00175
00176 srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_TOP_RIGHT_CORNER], finalRect, base_z, imageColours, 0, clipToDisplay);
00177 }
00178
00179
00180 if (d_frameImages[FIC_BOTTOM_LEFT_CORNER])
00181 {
00182
00183 imageSize = d_frameImages[FIC_BOTTOM_LEFT_CORNER]->getSize();
00184 finalRect.d_left = destRect.d_left;
00185 finalRect.d_top = destRect.d_bottom - imageSize.d_height;
00186 finalRect.setSize(imageSize);
00187
00188
00189 bottomOffset += imageSize.d_width;
00190 bottomWidth -= bottomOffset;
00191 leftHeight -= imageSize.d_height;
00192
00193
00194 if (calcColoursPerImage)
00195 {
00196 leftfactor = (finalRect.d_left + d_frameImages[FIC_BOTTOM_LEFT_CORNER]->getOffsetX()) / destRect.getWidth();
00197 rightfactor = leftfactor + finalRect.getWidth() / destRect.getWidth();
00198 topfactor = (finalRect.d_top + d_frameImages[FIC_BOTTOM_LEFT_CORNER]->getOffsetY()) / destRect.getHeight();
00199 bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();
00200
00201 imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
00202 }
00203
00204
00205 srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_BOTTOM_LEFT_CORNER], finalRect, base_z, imageColours, 0, clipToDisplay);
00206 }
00207
00208
00209 if (d_frameImages[FIC_BOTTOM_RIGHT_CORNER])
00210 {
00211
00212 imageSize = d_frameImages[FIC_BOTTOM_RIGHT_CORNER]->getSize();
00213 finalRect.d_left = destRect.d_right - imageSize.d_width;
00214 finalRect.d_top = destRect.d_bottom - imageSize.d_height;
00215 finalRect.setSize(imageSize);
00216
00217
00218 bottomWidth -= imageSize.d_width;
00219 rightHeight -= imageSize.d_height;
00220
00221
00222 if (calcColoursPerImage)
00223 {
00224 leftfactor = (finalRect.d_left + d_frameImages[FIC_BOTTOM_RIGHT_CORNER]->getOffsetX()) / destRect.getWidth();
00225 rightfactor = leftfactor + finalRect.getWidth() / destRect.getWidth();
00226 topfactor = (finalRect.d_top + d_frameImages[FIC_BOTTOM_RIGHT_CORNER]->getOffsetY()) / destRect.getHeight();
00227 bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();
00228
00229 imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
00230 }
00231
00232
00233 srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_BOTTOM_RIGHT_CORNER], finalRect, base_z, imageColours, 0, clipToDisplay);
00234 }
00235
00236
00237 if (d_frameImages[FIC_TOP_EDGE])
00238 {
00239
00240 imageSize = d_frameImages[FIC_TOP_EDGE]->getSize();
00241 finalRect.d_left = destRect.d_left + topOffset;
00242 finalRect.d_right = finalRect.d_left + topWidth;
00243 finalRect.d_top = destRect.d_top;
00244 finalRect.d_bottom = finalRect.d_top + imageSize.d_height;
00245
00246
00247 backgroundRect.d_top += imageSize.d_height + d_frameImages[FIC_TOP_EDGE]->getOffsetY();;
00248
00249
00250 if (calcColoursPerImage)
00251 {
00252 leftfactor = (finalRect.d_left + d_frameImages[FIC_TOP_EDGE]->getOffsetX()) / destRect.getWidth();
00253 rightfactor = leftfactor + finalRect.getWidth() / destRect.getWidth();
00254 topfactor = (finalRect.d_top + d_frameImages[FIC_TOP_EDGE]->getOffsetY()) / destRect.getHeight();
00255 bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();
00256
00257 imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
00258 }
00259
00260
00261 srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_TOP_EDGE], finalRect, base_z, imageColours, 0, clipToDisplay);
00262 }
00263
00264
00265 if (d_frameImages[FIC_BOTTOM_EDGE])
00266 {
00267
00268 imageSize = d_frameImages[FIC_BOTTOM_EDGE]->getSize();
00269 finalRect.d_left = destRect.d_left + bottomOffset;
00270 finalRect.d_right = finalRect.d_left + bottomWidth;
00271 finalRect.d_bottom = destRect.d_bottom;
00272 finalRect.d_top = finalRect.d_bottom - imageSize.d_height;
00273
00274
00275 backgroundRect.d_bottom -= imageSize.d_height - d_frameImages[FIC_BOTTOM_EDGE]->getOffsetY();;
00276
00277
00278 if (calcColoursPerImage)
00279 {
00280 leftfactor = (finalRect.d_left + d_frameImages[FIC_BOTTOM_EDGE]->getOffsetX()) / destRect.getWidth();
00281 rightfactor = leftfactor + finalRect.getWidth() / destRect.getWidth();
00282 topfactor = (finalRect.d_top + d_frameImages[FIC_BOTTOM_EDGE]->getOffsetY()) / destRect.getHeight();
00283 bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();
00284
00285 imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
00286 }
00287
00288
00289 srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_BOTTOM_EDGE], finalRect, base_z, imageColours, 0, clipToDisplay);
00290 }
00291
00292
00293 if (d_frameImages[FIC_LEFT_EDGE])
00294 {
00295
00296 imageSize = d_frameImages[FIC_LEFT_EDGE]->getSize();
00297 finalRect.d_left = destRect.d_left;
00298 finalRect.d_right = finalRect.d_left + imageSize.d_width;
00299 finalRect.d_top = destRect.d_top + leftOffset;
00300 finalRect.d_bottom = finalRect.d_top + leftHeight;
00301
00302
00303 backgroundRect.d_left += imageSize.d_width + d_frameImages[FIC_LEFT_EDGE]->getOffsetX();
00304
00305
00306 if (calcColoursPerImage)
00307 {
00308 leftfactor = (finalRect.d_left + d_frameImages[FIC_LEFT_EDGE]->getOffsetX()) / destRect.getWidth();
00309 rightfactor = leftfactor + finalRect.getWidth() / destRect.getWidth();
00310 topfactor = (finalRect.d_top + d_frameImages[FIC_LEFT_EDGE]->getOffsetY()) / destRect.getHeight();
00311 bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();
00312
00313 imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
00314 }
00315
00316
00317 srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_LEFT_EDGE], finalRect, base_z, imageColours, 0, clipToDisplay);
00318 }
00319
00320
00321 if (d_frameImages[FIC_RIGHT_EDGE])
00322 {
00323
00324 imageSize = d_frameImages[FIC_RIGHT_EDGE]->getSize();
00325 finalRect.d_top = destRect.d_top + rightOffset;
00326 finalRect.d_bottom = finalRect.d_top + rightHeight;
00327 finalRect.d_right = destRect.d_right;
00328 finalRect.d_left = finalRect.d_right - imageSize.d_width;
00329
00330
00331 backgroundRect.d_right -= imageSize.d_width - d_frameImages[FIC_RIGHT_EDGE]->getOffsetX();
00332
00333
00334 if (calcColoursPerImage)
00335 {
00336 leftfactor = (finalRect.d_left + d_frameImages[FIC_RIGHT_EDGE]->getOffsetX()) / destRect.getWidth();
00337 rightfactor = leftfactor + finalRect.getWidth() / destRect.getWidth();
00338 topfactor = (finalRect.d_top + d_frameImages[FIC_RIGHT_EDGE]->getOffsetY()) / destRect.getHeight();
00339 bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();
00340
00341 imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
00342 }
00343
00344
00345 srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_RIGHT_EDGE], finalRect, base_z, imageColours, 0, clipToDisplay);
00346 }
00347
00348 if (d_frameImages[FIC_BACKGROUND])
00349 {
00350
00351 if (calcColoursPerImage)
00352 {
00353 leftfactor = (backgroundRect.d_left + d_frameImages[FIC_BACKGROUND]->getOffsetX()) / destRect.getWidth();
00354 rightfactor = leftfactor + backgroundRect.getWidth() / destRect.getWidth();
00355 topfactor = (backgroundRect.d_top + d_frameImages[FIC_BACKGROUND]->getOffsetY()) / destRect.getHeight();
00356 bottomfactor = topfactor + backgroundRect.getHeight() / destRect.getHeight();
00357
00358 imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
00359 }
00360
00361
00362 doBackgroundRender(srcWindow, backgroundRect, base_z, imageColours, clipper, clipToDisplay);
00363 }
00364 }
00365
00366 void FrameComponent::doBackgroundRender(Window& srcWindow, Rect& destRect, float base_z, const ColourRect& colours, const Rect* clipper, bool clipToDisplay) const
00367 {
00368 HorizontalFormatting horzFormatting = d_horzFormatPropertyName.empty() ? d_horzFormatting :
00369 FalagardXMLHelper::stringToHorzFormat(srcWindow.getProperty(d_horzFormatPropertyName));
00370
00371 VerticalFormatting vertFormatting = d_vertFormatPropertyName.empty() ? d_vertFormatting :
00372 FalagardXMLHelper::stringToVertFormat(srcWindow.getProperty(d_vertFormatPropertyName));
00373
00374 uint horzTiles, vertTiles;
00375 float xpos, ypos;
00376
00377 Size imgSz(d_frameImages[FIC_BACKGROUND]->getSize());
00378
00379
00380 switch (horzFormatting)
00381 {
00382 case HF_STRETCHED:
00383 imgSz.d_width = destRect.getWidth();
00384 xpos = destRect.d_left;
00385 horzTiles = 1;
00386 break;
00387
00388 case HF_TILED:
00389 xpos = destRect.d_left;
00390 horzTiles = (uint)((destRect.getWidth() + (imgSz.d_width - 1)) / imgSz.d_width);
00391 break;
00392
00393 case HF_LEFT_ALIGNED:
00394 xpos = destRect.d_left;
00395 horzTiles = 1;
00396 break;
00397
00398 case HF_CENTRE_ALIGNED:
00399 xpos = destRect.d_left + PixelAligned((destRect.getWidth() - imgSz.d_width) * 0.5f);
00400 horzTiles = 1;
00401 break;
00402
00403 case HF_RIGHT_ALIGNED:
00404 xpos = destRect.d_right - imgSz.d_width;
00405 horzTiles = 1;
00406 break;
00407
00408 default:
00409 throw InvalidRequestException("FrameComponent::doBackgroundRender - An unknown HorizontalFormatting value was specified.");
00410 }
00411
00412
00413 switch (vertFormatting)
00414 {
00415 case VF_STRETCHED:
00416 imgSz.d_height = destRect.getHeight();
00417 ypos = destRect.d_top;
00418 vertTiles = 1;
00419 break;
00420
00421 case VF_TILED:
00422 ypos = destRect.d_top;
00423 vertTiles = (uint)((destRect.getHeight() + (imgSz.d_height - 1)) / imgSz.d_height);
00424 break;
00425
00426 case VF_TOP_ALIGNED:
00427 ypos = destRect.d_top;
00428 vertTiles = 1;
00429 break;
00430
00431 case VF_CENTRE_ALIGNED:
00432 ypos = destRect.d_top + PixelAligned((destRect.getHeight() - imgSz.d_height) * 0.5f);
00433 vertTiles = 1;
00434 break;
00435
00436 case VF_BOTTOM_ALIGNED:
00437 ypos = destRect.d_bottom - imgSz.d_height;
00438 vertTiles = 1;
00439 break;
00440
00441 default:
00442 throw InvalidRequestException("FrameComponent::doBackgroundRender - An unknown VerticalFormatting value was specified.");
00443 }
00444
00445
00446 Rect finalRect;
00447 Rect finalClipper;
00448 const Rect* clippingRect;
00449 finalRect.d_top = ypos;
00450 finalRect.d_bottom = ypos + imgSz.d_height;
00451
00452 for (uint row = 0; row < vertTiles; ++row)
00453 {
00454 finalRect.d_left = xpos;
00455 finalRect.d_right = xpos + imgSz.d_width;
00456
00457 for (uint col = 0; col < horzTiles; ++col)
00458 {
00459
00460 if (((vertFormatting == VF_TILED) && row == vertTiles - 1) ||
00461 ((horzFormatting == HF_TILED) && col == horzTiles - 1))
00462 {
00463 finalClipper = clipper ? clipper->getIntersection(destRect) : destRect;
00464 clippingRect = &finalClipper;
00465 }
00466
00467 else
00468 {
00469 clippingRect = clipper;
00470 }
00471
00472
00473 srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_BACKGROUND], finalRect, base_z, colours, clippingRect, clipToDisplay);
00474
00475 finalRect.d_left += imgSz.d_width;
00476 finalRect.d_right += imgSz.d_width;
00477 }
00478
00479 finalRect.d_top += imgSz.d_height;
00480 finalRect.d_bottom += imgSz.d_height;
00481 }
00482 }
00483
00484 void FrameComponent::writeXMLToStream(OutStream& out_stream) const
00485 {
00486
00487 out_stream << "<FrameComponent>" << std::endl;
00488
00489 d_area.writeXMLToStream(out_stream);
00490
00491
00492 for (int i = 0; i < FIC_FRAME_IMAGE_COUNT; ++i)
00493 {
00494 if (d_frameImages[i])
00495 {
00496 out_stream << "<Image imageset=\"" << d_frameImages[i]->getImagesetName();
00497 out_stream << "\" image=\"" << d_frameImages[i]->getName();
00498 out_stream << "\" type=\"" << FalagardXMLHelper::frameImageComponentToString(static_cast<FrameImageComponent>(i));
00499 out_stream << "\" />" << std::endl;
00500 }
00501 }
00502
00503
00504 writeColoursXML(out_stream);
00505
00506
00507 if (!writeVertFormatXML(out_stream))
00508 {
00509
00510 out_stream << "<VertFormat type=\"" << FalagardXMLHelper::vertFormatToString(d_vertFormatting) << "\" />" << std::endl;
00511 }
00512
00513
00514 if (!writeHorzFormatXML(out_stream))
00515 {
00516
00517 out_stream << "<HorzFormat type=\"" << FalagardXMLHelper::horzFormatToString(d_horzFormatting) << "\" />" << std::endl;
00518 }
00519
00520
00521 out_stream << "</FrameComponent>" << std::endl;
00522 }
00523
00524 }