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/CEGUIFalDimensions.h"
00025 #include "falagard/CEGUIFalXMLEnumHelper.h"
00026 #include "CEGUIImagesetManager.h"
00027 #include "CEGUIImageset.h"
00028 #include "CEGUIImage.h"
00029 #include "CEGUIWindowManager.h"
00030 #include "CEGUIWindow.h"
00031 #include "CEGUIExceptions.h"
00032 #include "CEGUIFontManager.h"
00033 #include "CEGUIFont.h"
00034 #include "CEGUIPropertyHelper.h"
00035 #include <cassert>
00036
00037
00038 namespace CEGUI
00039 {
00040 BaseDim::BaseDim() :
00041 d_operator(DOP_NOOP),
00042 d_operand(0)
00043 {
00044 }
00045
00046 BaseDim::~BaseDim()
00047 {
00048 delete d_operand;
00049 }
00050
00051 float BaseDim::getValue(const Window& wnd) const
00052 {
00053
00054 float val = getValue_impl(wnd);
00055
00056
00057 if (d_operand)
00058 {
00059 switch (d_operator)
00060 {
00061 case DOP_ADD:
00062 val += d_operand->getValue(wnd);
00063 break;
00064 case DOP_SUBTRACT:
00065 val -= d_operand->getValue(wnd);
00066 break;
00067 case DOP_MULTIPLY:
00068 val *= d_operand->getValue(wnd);
00069 break;
00070 case DOP_DIVIDE:
00071 val /= d_operand->getValue(wnd);
00072 break;
00073 default:
00074
00075 break;
00076 }
00077 }
00078
00079 return val;
00080 }
00081
00082 float BaseDim::getValue(const Window& wnd, const Rect& container) const
00083 {
00084
00085 float val = getValue_impl(wnd, container);
00086
00087
00088 if (d_operand)
00089 {
00090 switch (d_operator)
00091 {
00092 case DOP_ADD:
00093 val += d_operand->getValue(wnd, container);
00094 break;
00095 case DOP_SUBTRACT:
00096 val -= d_operand->getValue(wnd, container);
00097 break;
00098 case DOP_MULTIPLY:
00099 val *= d_operand->getValue(wnd, container);
00100 break;
00101 case DOP_DIVIDE:
00102 val /= d_operand->getValue(wnd, container);
00103 break;
00104 default:
00105
00106 break;
00107 }
00108 }
00109
00110 return val;
00111 }
00112
00113 BaseDim* BaseDim::clone() const
00114 {
00115
00116 BaseDim* o = clone_impl();
00117
00118
00119 o->d_operator = d_operator;
00120
00121
00122 if (d_operand)
00123 o->d_operand = d_operand->clone();
00124
00125 return o;
00126 }
00127
00128 DimensionOperator BaseDim::getDimensionOperator() const
00129 {
00130 return d_operator;
00131 }
00132
00133 void BaseDim::setDimensionOperator(DimensionOperator op)
00134 {
00135 d_operator = op;
00136 }
00137
00138 const BaseDim* BaseDim::getOperand() const
00139 {
00140 return d_operand;
00141 }
00142
00143 void BaseDim::setOperand(const BaseDim& operand)
00144 {
00145
00146 if(d_operand) delete d_operand;
00147
00148 d_operand = operand.clone();
00149 }
00150
00151 void BaseDim::writeXMLToStream(OutStream& out_stream) const
00152 {
00153
00154 out_stream << "<";
00155
00156 writeXMLElementName_impl(out_stream);
00157 out_stream << " ";
00158 writeXMLElementAttributes_impl(out_stream);
00159
00160 if (d_operand)
00161 {
00162
00163 out_stream << ">" << std::endl;
00164
00165 out_stream << "<DimOperator op=\"" << FalagardXMLHelper::dimensionOperatorToString(d_operator) << "\">" << std::endl;
00166
00167 d_operand->writeXMLToStream(out_stream);
00168
00169 out_stream << "</DimOperator>" << std::endl;
00170
00171 out_stream << "</";
00172 writeXMLElementName_impl(out_stream);
00173 out_stream << ">" << std::endl;
00174 }
00175
00176 else
00177 {
00178 out_stream << " />" << std::endl;
00179 }
00180 }
00181
00183
00184 AbsoluteDim::AbsoluteDim(float val) :
00185 d_val(val)
00186 {}
00187
00188 void AbsoluteDim::setValue(float val)
00189 {
00190 d_val = val;
00191 }
00192
00193 float AbsoluteDim::getValue_impl(const Window& wnd) const
00194 {
00195 return d_val;
00196 }
00197
00198 float AbsoluteDim::getValue_impl(const Window& wnd, const Rect& container) const
00199 {
00200 return d_val;
00201 }
00202
00203 BaseDim* AbsoluteDim::clone_impl() const
00204 {
00205 AbsoluteDim* ndim = new AbsoluteDim(d_val);
00206 return ndim;
00207 }
00208
00209 void AbsoluteDim::writeXMLElementName_impl(OutStream& out_stream) const
00210 {
00211 out_stream << "AbsoluteDim";
00212 }
00213
00214 void AbsoluteDim::writeXMLElementAttributes_impl(OutStream& out_stream) const
00215 {
00216 out_stream << "value=\"" << d_val << "\"";
00217 }
00218
00219
00221
00222 ImageDim::ImageDim(const String& imageset, const String& image, DimensionType dim) :
00223 d_imageset(imageset),
00224 d_image(image),
00225 d_what(dim)
00226 {}
00227
00228 void ImageDim::setSourceImage(const String& imageset, const String& image)
00229 {
00230 d_imageset = imageset;
00231 d_image = image;
00232 }
00233
00234 void ImageDim::setSourceDimension(DimensionType dim)
00235 {
00236 d_what = dim;
00237 }
00238
00239 float ImageDim::getValue_impl(const Window& wnd) const
00240 {
00241 const Image* img = &ImagesetManager::getSingleton().getImageset(d_imageset)->getImage(d_image);
00242
00243 switch (d_what)
00244 {
00245 case DT_WIDTH:
00246 return img->getWidth();
00247 break;
00248
00249 case DT_HEIGHT:
00250 return img->getHeight();
00251 break;
00252
00253 case DT_X_OFFSET:
00254 return img->getOffsetX();
00255 break;
00256
00257 case DT_Y_OFFSET:
00258 return img->getOffsetY();
00259 break;
00260
00261
00262
00263 case DT_LEFT_EDGE:
00264 case DT_X_POSITION:
00265 return img->getSourceTextureArea().d_left;
00266 break;
00267
00268 case DT_TOP_EDGE:
00269 case DT_Y_POSITION:
00270 return img->getSourceTextureArea().d_top;
00271 break;
00272
00273 case DT_RIGHT_EDGE:
00274 return img->getSourceTextureArea().d_right;
00275 break;
00276
00277 case DT_BOTTOM_EDGE:
00278 return img->getSourceTextureArea().d_bottom;
00279 break;
00280
00281 default:
00282 throw InvalidRequestException("ImageDim::getValue - unknown or unsupported DimensionType encountered.");
00283 break;
00284 }
00285 }
00286
00287 float ImageDim::getValue_impl(const Window& wnd, const Rect& container) const
00288 {
00289
00290 return getValue(wnd);
00291 }
00292
00293
00294 BaseDim* ImageDim::clone_impl() const
00295 {
00296 ImageDim* ndim = new ImageDim(d_imageset, d_image, d_what);
00297 return ndim;
00298 }
00299
00300 void ImageDim::writeXMLElementName_impl(OutStream& out_stream) const
00301 {
00302 out_stream << "ImageDim";
00303 }
00304
00305 void ImageDim::writeXMLElementAttributes_impl(OutStream& out_stream) const
00306 {
00307 out_stream << "imageset=\"" << d_imageset << "\" image=\"" << d_image << "\" dimension=\"" << FalagardXMLHelper::dimensionTypeToString(d_what) << "\"";
00308 }
00309
00311
00312 WidgetDim::WidgetDim(const String& name, DimensionType dim) :
00313 d_widgetName(name),
00314 d_what(dim)
00315 {}
00316
00317 void WidgetDim::setWidgetName(const String& name)
00318 {
00319 d_widgetName = name;
00320 }
00321
00322 void WidgetDim::setSourceDimension(DimensionType dim)
00323 {
00324 d_what = dim;
00325 }
00326
00327 float WidgetDim::getValue_impl(const Window& wnd) const
00328 {
00329 const Window* widget;
00330
00331
00332 if (d_widgetName.empty())
00333 {
00334 widget = &wnd;
00335 }
00336
00337 else
00338 {
00339 widget = WindowManager::getSingleton().getWindow(wnd.getName() + d_widgetName);
00340 }
00341
00342 switch (d_what)
00343 {
00344 case DT_WIDTH:
00345 return widget->getAbsoluteWidth();
00346 break;
00347
00348 case DT_HEIGHT:
00349 return widget->getAbsoluteHeight();
00350 break;
00351
00352 case DT_X_OFFSET:
00353 Logger::getSingleton().logEvent("WigetDim::getValue - Nonsensical DimensionType of DT_X_OFFSET specified! returning 0.0f");
00354 return 0.0f;
00355 break;
00356
00357 case DT_Y_OFFSET:
00358 Logger::getSingleton().logEvent("WigetDim::getValue - Nonsensical DimensionType of DT_Y_OFFSET specified! returning 0.0f");
00359 return 0.0f;
00360 break;
00361
00362 case DT_LEFT_EDGE:
00363 case DT_X_POSITION:
00364 return widget->getAbsolutePosition().d_x;
00365 break;
00366
00367 case DT_TOP_EDGE:
00368 case DT_Y_POSITION:
00369 return widget->getAbsolutePosition().d_y;
00370 break;
00371
00372 case DT_RIGHT_EDGE:
00373 return widget->getAbsoluteRect().d_right;
00374 break;
00375
00376 case DT_BOTTOM_EDGE:
00377 return widget->getAbsoluteRect().d_bottom;
00378 break;
00379
00380 default:
00381 throw InvalidRequestException("WidgetDim::getValue - unknown or unsupported DimensionType encountered.");
00382 break;
00383 }
00384 }
00385
00386 float WidgetDim::getValue_impl(const Window& wnd, const Rect& container) const
00387 {
00388
00389 return getValue(wnd);
00390 }
00391
00392 BaseDim* WidgetDim::clone_impl() const
00393 {
00394 WidgetDim* ndim = new WidgetDim(d_widgetName, d_what);
00395 return ndim;
00396 }
00397
00398 void WidgetDim::writeXMLElementName_impl(OutStream& out_stream) const
00399 {
00400 out_stream << "WidgetDim";
00401 }
00402
00403 void WidgetDim::writeXMLElementAttributes_impl(OutStream& out_stream) const
00404 {
00405 if (!d_widgetName.empty())
00406 out_stream << "widget=\"" << d_widgetName << "\" ";
00407
00408 out_stream << "dimension=\"" << FalagardXMLHelper::dimensionTypeToString(d_what) << "\"";
00409 }
00410
00412
00413 FontDim::FontDim(const String& name, const String& font, const String& text, FontMetricType metric, float padding) :
00414 d_font(font),
00415 d_text(text),
00416 d_childSuffix(name),
00417 d_metric(metric),
00418 d_padding(padding)
00419 {
00420 }
00421
00422 float FontDim::getValue_impl(const Window& wnd) const
00423 {
00424
00425 const Window& sourceWindow = d_childSuffix.empty() ? wnd : *WindowManager::getSingleton().getWindow(wnd.getName() + d_childSuffix);
00426
00427 const Font* fontObj = d_font.empty() ? sourceWindow.getFont() : FontManager::getSingleton().getFont(d_font);
00428
00429 if (fontObj)
00430 {
00431 switch (d_metric)
00432 {
00433 case FMT_LINE_SPACING:
00434 return fontObj->getLineSpacing() + d_padding;
00435 break;
00436 case FMT_BASELINE:
00437 return fontObj->getBaseline() + d_padding;
00438 break;
00439 case FMT_HORZ_EXTENT:
00440 return fontObj->getTextExtent(d_text.empty() ? sourceWindow.getText() : d_text) + d_padding;
00441 break;
00442 default:
00443 throw InvalidRequestException("FontDim::getValue - unknown or unsupported FontMetricType encountered.");
00444 break;
00445 }
00446 }
00447
00448 else
00449 {
00450 return d_padding;
00451 }
00452 }
00453
00454 float FontDim::getValue_impl(const Window& wnd, const Rect& container) const
00455 {
00456 return getValue(wnd);
00457 }
00458
00459 BaseDim* FontDim::clone_impl() const
00460 {
00461 FontDim* ndim = new FontDim(d_childSuffix, d_font, d_text, d_metric, d_padding);
00462 return ndim;
00463 }
00464
00465 void FontDim::writeXMLElementName_impl(OutStream& out_stream) const
00466 {
00467 out_stream << "FontDim";
00468 }
00469
00470 void FontDim::writeXMLElementAttributes_impl(OutStream& out_stream) const
00471 {
00472 if (!d_childSuffix.empty())
00473 out_stream << "widget=\"" << d_childSuffix << "\" ";
00474
00475 if (!d_font.empty())
00476 out_stream << "font=\"" << d_font << "\" ";
00477
00478 if (!d_text.empty())
00479 out_stream << "string=\"" << d_text << "\" ";
00480
00481 if (d_padding != 0)
00482 out_stream << "padding=\"" << d_padding << "\" ";
00483
00484 out_stream << "type=\"" << FalagardXMLHelper::fontMetricTypeToString(d_metric) << "\"";
00485 }
00486
00488
00489 PropertyDim::PropertyDim(const String& name, const String& property) :
00490 d_property(property),
00491 d_childSuffix(name)
00492 {
00493 }
00494
00495 float PropertyDim::getValue_impl(const Window& wnd) const
00496 {
00497
00498 const Window& sourceWindow = d_childSuffix.empty() ? wnd : *WindowManager::getSingleton().getWindow(wnd.getName() + d_childSuffix);
00499
00500 return PropertyHelper::stringToFloat(sourceWindow.getProperty(d_property));
00501 }
00502
00503 float PropertyDim::getValue_impl(const Window& wnd, const Rect& container) const
00504 {
00505 return getValue(wnd);
00506 }
00507
00508 BaseDim* PropertyDim::clone_impl() const
00509 {
00510 PropertyDim* ndim = new PropertyDim(d_childSuffix, d_property);
00511 return ndim;
00512 }
00513
00514 void PropertyDim::writeXMLElementName_impl(OutStream& out_stream) const
00515 {
00516 if (!d_childSuffix.empty())
00517 out_stream << "widget=\"" << d_childSuffix << "\" ";
00518
00519 out_stream << "PropertyDim";
00520 }
00521
00522 void PropertyDim::writeXMLElementAttributes_impl(OutStream& out_stream) const
00523 {
00524 out_stream << "name=\"" << d_property << "\"";
00525 }
00526
00528
00529 Dimension::Dimension()
00530 {
00531 d_value = 0;
00532 d_type = DT_INVALID;
00533 }
00534
00535 Dimension::~Dimension()
00536 {
00537 if (d_value)
00538 delete d_value;
00539 }
00540
00541 Dimension::Dimension(const BaseDim& dim, DimensionType type)
00542 {
00543 d_value = dim.clone();
00544 d_type = type;
00545 }
00546
00547 Dimension::Dimension(const Dimension& other)
00548 {
00549 d_value = other.d_value ? other.d_value->clone() : 0;
00550 d_type = other.d_type;
00551 }
00552
00553 Dimension& Dimension::operator=(const Dimension& other)
00554 {
00555
00556 if (d_value) delete d_value;
00557
00558 d_value = other.d_value ? other.d_value->clone() : 0;
00559 d_type = other.d_type;
00560
00561 return *this;
00562 }
00563
00564 const BaseDim& Dimension::getBaseDimension() const
00565 {
00566 assert(d_value);
00567 return *d_value;
00568 }
00569
00570 void Dimension::setBaseDimension(const BaseDim& dim)
00571 {
00572
00573 if (d_value) delete d_value;
00574
00575 d_value = dim.clone();
00576 }
00577
00578 DimensionType Dimension::getDimensionType() const
00579 {
00580 return d_type;
00581 }
00582
00583 void Dimension::setDimensionType(DimensionType type)
00584 {
00585 d_type = type;
00586 }
00587
00588 void Dimension::writeXMLToStream(OutStream& out_stream) const
00589 {
00590 out_stream << "<Dim type=\"" << FalagardXMLHelper::dimensionTypeToString(d_type) << "\">" << std::endl;
00591
00592 if (d_value)
00593 d_value->writeXMLToStream(out_stream);
00594
00595 out_stream << "</Dim>" << std::endl;
00596 }
00597
00599
00600 UnifiedDim::UnifiedDim(const UDim& value, DimensionType dim) :
00601 d_value(value),
00602 d_what(dim)
00603 {
00604 }
00605
00606 float UnifiedDim::getValue_impl(const Window& wnd) const
00607 {
00608 switch (d_what)
00609 {
00610 case DT_LEFT_EDGE:
00611 case DT_RIGHT_EDGE:
00612 case DT_X_POSITION:
00613 case DT_X_OFFSET:
00614 case DT_WIDTH:
00615 return d_value.asAbsolute(wnd.getAbsoluteWidth());
00616 break;
00617
00618 case DT_TOP_EDGE:
00619 case DT_BOTTOM_EDGE:
00620 case DT_Y_POSITION:
00621 case DT_Y_OFFSET:
00622 case DT_HEIGHT:
00623 return d_value.asAbsolute(wnd.getAbsoluteHeight());
00624 break;
00625
00626 default:
00627 throw InvalidRequestException("UnifiedDim::getValue - unknown or unsupported DimensionType encountered.");
00628 break;
00629 }
00630 }
00631
00632 float UnifiedDim::getValue_impl(const Window& wnd, const Rect& container) const
00633 {
00634 switch (d_what)
00635 {
00636 case DT_LEFT_EDGE:
00637 case DT_RIGHT_EDGE:
00638 case DT_X_POSITION:
00639 case DT_X_OFFSET:
00640 case DT_WIDTH:
00641 return d_value.asAbsolute(container.getWidth());
00642 break;
00643
00644 case DT_TOP_EDGE:
00645 case DT_BOTTOM_EDGE:
00646 case DT_Y_POSITION:
00647 case DT_Y_OFFSET:
00648 case DT_HEIGHT:
00649 return d_value.asAbsolute(container.getHeight());
00650 break;
00651
00652 default:
00653 throw InvalidRequestException("UnifiedDim::getValue - unknown or unsupported DimensionType encountered.");
00654 break;
00655 }
00656 }
00657
00658 BaseDim* UnifiedDim::clone_impl() const
00659 {
00660 UnifiedDim* ndim = new UnifiedDim(d_value, d_what);
00661 return ndim;
00662 }
00663
00664 void UnifiedDim::writeXMLElementName_impl(OutStream& out_stream) const
00665 {
00666 out_stream << "UnifiedDim";
00667 }
00668
00669 void UnifiedDim::writeXMLElementAttributes_impl(OutStream& out_stream) const
00670 {
00671 if (d_value.d_scale != 0)
00672 out_stream << "scale=\"" << d_value.d_scale << "\" ";
00673
00674 if (d_value.d_offset != 0)
00675 out_stream << "offset=\"" << d_value.d_offset << "\" ";
00676
00677 out_stream << "type=\"" << FalagardXMLHelper::dimensionTypeToString(d_what) << "\"";
00678 }
00679
00681
00682 Rect ComponentArea::getPixelRect(const Window& wnd) const
00683 {
00684 Rect pixelRect;
00685
00686
00687 if (isAreaFetchedFromProperty())
00688 {
00689 pixelRect = PropertyHelper::stringToURect(wnd.getProperty(d_areaProperty)).asAbsolute(wnd.getAbsoluteSize());
00690 }
00691
00692 else
00693 {
00694
00695 assert(d_left.getDimensionType() == DT_LEFT_EDGE || d_left.getDimensionType() == DT_X_POSITION);
00696 assert(d_top.getDimensionType() == DT_TOP_EDGE || d_top.getDimensionType() == DT_Y_POSITION);
00697 assert(d_right_or_width.getDimensionType() == DT_RIGHT_EDGE || d_right_or_width.getDimensionType() == DT_WIDTH);
00698 assert(d_bottom_or_height.getDimensionType() == DT_BOTTOM_EDGE || d_bottom_or_height.getDimensionType() == DT_HEIGHT);
00699
00700 pixelRect.d_left = d_left.getBaseDimension().getValue(wnd);
00701 pixelRect.d_top = d_top.getBaseDimension().getValue(wnd);
00702
00703 if (d_right_or_width.getDimensionType() == DT_WIDTH)
00704 pixelRect.setWidth(d_right_or_width.getBaseDimension().getValue(wnd));
00705 else
00706 pixelRect.d_right = d_right_or_width.getBaseDimension().getValue(wnd);
00707
00708 if (d_bottom_or_height.getDimensionType() == DT_HEIGHT)
00709 pixelRect.setHeight(d_bottom_or_height.getBaseDimension().getValue(wnd));
00710 else
00711 pixelRect.d_bottom = d_bottom_or_height.getBaseDimension().getValue(wnd);
00712 }
00713
00714 return pixelRect;
00715 }
00716
00717 Rect ComponentArea::getPixelRect(const Window& wnd, const Rect& container) const
00718 {
00719 Rect pixelRect;
00720
00721
00722 if (isAreaFetchedFromProperty())
00723 {
00724 pixelRect = PropertyHelper::stringToURect(wnd.getProperty(d_areaProperty)).asAbsolute(wnd.getAbsoluteSize());
00725 }
00726
00727 else
00728 {
00729
00730 assert(d_left.getDimensionType() == DT_LEFT_EDGE || d_left.getDimensionType() == DT_X_POSITION);
00731 assert(d_top.getDimensionType() == DT_TOP_EDGE || d_top.getDimensionType() == DT_Y_POSITION);
00732 assert(d_right_or_width.getDimensionType() == DT_RIGHT_EDGE || d_right_or_width.getDimensionType() == DT_WIDTH);
00733 assert(d_bottom_or_height.getDimensionType() == DT_BOTTOM_EDGE || d_bottom_or_height.getDimensionType() == DT_HEIGHT);
00734
00735 pixelRect.d_left = d_left.getBaseDimension().getValue(wnd, container) + container.d_left;
00736 pixelRect.d_top = d_top.getBaseDimension().getValue(wnd, container) + container.d_top;
00737
00738 if (d_right_or_width.getDimensionType() == DT_WIDTH)
00739 pixelRect.setWidth(d_right_or_width.getBaseDimension().getValue(wnd, container));
00740 else
00741 pixelRect.d_right = d_right_or_width.getBaseDimension().getValue(wnd, container) + container.d_left;
00742
00743 if (d_bottom_or_height.getDimensionType() == DT_HEIGHT)
00744 pixelRect.setHeight(d_bottom_or_height.getBaseDimension().getValue(wnd, container));
00745 else
00746 pixelRect.d_bottom = d_bottom_or_height.getBaseDimension().getValue(wnd, container) + container.d_top;
00747 }
00748
00749 return pixelRect;
00750 }
00751
00752 void ComponentArea::writeXMLToStream(OutStream& out_stream) const
00753 {
00754 out_stream << "<Area>" << std::endl;
00755
00756
00757 if (isAreaFetchedFromProperty())
00758 {
00759 out_stream << "<AreaProperty name=\"" << d_areaProperty << "\" />" << std::endl;
00760 }
00761
00762 else
00763 {
00764 d_left.writeXMLToStream(out_stream);
00765 d_top.writeXMLToStream(out_stream);
00766 d_right_or_width.writeXMLToStream(out_stream);
00767 d_bottom_or_height.writeXMLToStream(out_stream);
00768 }
00769 out_stream << "</Area>" << std::endl;
00770 }
00771
00772 bool ComponentArea::isAreaFetchedFromProperty() const
00773 {
00774 return !d_areaProperty.empty();
00775 }
00776
00777 const String& ComponentArea::getAreaPropertySource() const
00778 {
00779 return d_areaProperty;
00780 }
00781
00782 void ComponentArea::setAreaPropertySource(const String& property)
00783 {
00784 d_areaProperty = property;
00785 }
00786
00787 }