diff -Nur stuntrally.orig/source/CMakeLists.txt stuntrally//source/CMakeLists.txt --- stuntrally.orig/source/CMakeLists.txt 2011-07-31 09:08:29.000000000 +0200 +++ stuntrally//source/CMakeLists.txt 2011-08-13 01:19:01.000000000 +0200 @@ -15,7 +15,7 @@ endif() # Search include files from all source sub directories -include_directories(btOgre bullet ogre paged-geom road tinyxml vdrift) +include_directories(btOgre bullet ogre paged-geom road tinyxml vdrift mygui) # Compile our libraries foreach(ourlib tinyxml bullet oisb paged-geom) diff -Nur stuntrally.orig/source/editor/Gui_Util.cpp stuntrally//source/editor/Gui_Util.cpp --- stuntrally.orig/source/editor/Gui_Util.cpp 2011-07-31 09:08:29.000000000 +0200 +++ stuntrally//source/editor/Gui_Util.cpp 2011-08-13 01:32:56.000000000 +0200 @@ -571,7 +571,7 @@ while (widgets.next()) { WidgetPtr wp = widgets.current(); - wp->setAlign(Align::Relative); + wp->setAlign(WidgetInfo::Relative); bool tip = wp->isUserString("tip"); if (tip) // if has tooltip string { diff -Nur stuntrally.orig/source/editor/OgreApp.h stuntrally//source/editor/OgreApp.h --- stuntrally.orig/source/editor/OgreApp.h 2011-07-31 09:08:29.000000000 +0200 +++ stuntrally//source/editor/OgreApp.h 2011-08-13 01:24:50.000000000 +0200 @@ -19,6 +19,7 @@ #include #include +#include "MessageBox/MessageBox.h" const int ciShadowNumSizes = 4; diff -Nur stuntrally.orig/source/mygui/BaseLayout/Attribute.h stuntrally//source/mygui/BaseLayout/Attribute.h --- stuntrally.orig/source/mygui/BaseLayout/Attribute.h 1970-01-01 01:00:00.000000000 +0100 +++ stuntrally//source/mygui/BaseLayout/Attribute.h 2011-08-13 01:27:05.000000000 +0200 @@ -0,0 +1,123 @@ +/*! + @file + @author Albert Semenov + @date 10/2009 + @module +*/ + +#ifndef __ATTRIBUTE_H__ +#define __ATTRIBUTE_H__ + +namespace attribute +{ + + // êëàññ îáåðòêà äëÿ óäàëåíèÿ äàííûõ èç ñòàòè÷åñêîãî âåêòîðà + template + struct DataHolder + { + ~DataHolder() + { + for (typename Type::iterator item = data.begin(); item != data.end(); ++item) + delete (*item).first; + } + + Type data; + }; + + // èíòåðôåéñ äëÿ îáåðòêè ïîëÿ + template + struct Field + { + virtual bool set(OwnerType* _target, typename SetterType::BaseValueType* _value) = 0; + virtual const std::string& getFieldTypeName() = 0; + }; + + // øàáëîí äëÿ îáåðòêè ïîëÿ + template + struct FieldHolder : public Field + { + FieldHolder(FieldType* OwnerType::* offset) : m_offset(offset) { } + FieldType* OwnerType::* const m_offset; + + virtual bool set(OwnerType* _target, typename SetterType::BaseValueType* _value) + { + _target->*m_offset = SetterType::template convert(_value); + return _target->*m_offset != 0; + } + virtual const std::string& getFieldTypeName() + { + return FieldType::getClassTypeName(); + } + }; + + // øàáëîí äëÿ àòðèáóòà ïîëÿ + template + struct AttributeField + { + typedef std::pair*, ValueType> BindPair; + typedef std::vector VectorBindPair; + + template + AttributeField(FieldType* OwnerType::* _offset, const ValueType& _value) + { + getData().push_back(BindPair(new FieldHolder(_offset), _value)); + } + static VectorBindPair& getData() + { + static DataHolder data; + return data.data; + } + }; + + // ìàêðîñ äëÿ èíñòàíñèðîâàíèÿ àòðèáóòà ïîëÿ +#define DECLARE_ATTRIBUTE_FIELD(_name, _type, _setter) \ + template \ + struct _name : public attribute::AttributeField \ + { \ + template \ + _name(FieldType* OwnerType::* _offset, const ValueType& _value) : \ + AttributeField(_offset, _value) { } \ + } + + // ìàêðîñ äëÿ èíñòàíñèðîâàíèÿ ýêçåìïëÿðà àòðèáóòà +#define ATTRIBUTE_FIELD(_attribute, _class, _field, _value) \ + struct _attribute##_##_field \ + { \ + _attribute##_##_field() \ + { \ + static attribute::_attribute<_class> bind(&_class::_field, _value); \ + } \ + } _attribute##_##_field + + + // øàáëîí äëÿ àòðèáóòà êëàññà + template + struct ClassAttribute + { + ClassAttribute(const ValueType& _value) + { + getData() = _value; + } + static ValueType& getData() + { + static ValueType data; + return data; + } + }; + + // ìàêðîñ äëÿ èíñòàíñèðîâàíèÿ àòðèáóòà êëàññà +#define DECLARE_ATTRIBUTE_CLASS(_name, _type) \ + template \ + struct _name : public attribute::ClassAttribute<_name, ValueType> \ + { \ + _name(const ValueType& _value) : \ + ClassAttribute<_name, ValueType>(_value) { } \ + } + + // ìàêðîñ äëÿ èíñòàíñèðîâàíèÿ ýêçåìïëÿðà êëàññà +#define ATTRIBUTE_CLASS(_attribute, _class, _value) \ + class _class; \ + static attribute::_attribute<_class> _attribute##_##_class(_value) +} + +#endif // __ATTRIBUTE_H__ diff -Nur stuntrally.orig/source/mygui/BaseLayout/BaseLayout.h stuntrally//source/mygui/BaseLayout/BaseLayout.h --- stuntrally.orig/source/mygui/BaseLayout/BaseLayout.h 1970-01-01 01:00:00.000000000 +0100 +++ stuntrally//source/mygui/BaseLayout/BaseLayout.h 2011-08-13 01:27:08.000000000 +0200 @@ -0,0 +1,241 @@ +/*! + @file + @author Albert Semenov + @date 07/2008 + @module +*/ + +#ifndef __BASE_LAYOUT_H__ +#define __BASE_LAYOUT_H__ + +#include +#include "WrapsAttribute.h" + +namespace wraps +{ + + class BaseLayout + { + protected: + BaseLayout() : mMainWidget(nullptr) + { + } + + BaseLayout(const std::string& _layout, MyGUI::Widget* _parent = nullptr) : mMainWidget(nullptr) + { + initialise(_layout, _parent); + } + + template + void assignWidget(T * & _widget, const std::string& _name, bool _throw = true, bool _createFakeWidgets = true) + { + _widget = nullptr; + for (MyGUI::VectorWidgetPtr::iterator iter = mListWindowRoot.begin(); iter != mListWindowRoot.end(); ++iter) + { + MyGUI::Widget* find = (*iter)->findWidget(mPrefix + _name); + if (nullptr != find) + { + T* cast = find->castType(false); + if (nullptr != cast) + { + _widget = cast; + } + else + { + MYGUI_LOG(Warning, "Widget with name '" << _name << "' have wrong type ('" << + find->getTypeName() << "instead of '" << T::getClassTypeName() << "'). [" << mLayoutName << "]"); + MYGUI_ASSERT( ! _throw, "Can't assign widget with name '" << _name << "'. [" << mLayoutName << "]"); + if (_createFakeWidgets) + _widget = _createFakeWidget(mMainWidget); + } + + return; + } + } + MYGUI_LOG(Warning, "Widget with name '" << _name << "' not found. [" << mLayoutName << "]"); + MYGUI_ASSERT( ! _throw, "Can't assign widget with name '" << _name << "'. [" << mLayoutName << "]"); + if (_createFakeWidgets) + _widget = _createFakeWidget(mMainWidget); + } + + template + void assignBase(T * & _widget, const std::string& _name, bool _throw = true, bool _createFakeWidgets = true) + { + _widget = nullptr; + for (MyGUI::VectorWidgetPtr::iterator iter = mListWindowRoot.begin(); iter != mListWindowRoot.end(); ++iter) + { + MyGUI::Widget* find = (*iter)->findWidget(mPrefix + _name); + if (nullptr != find) + { + _widget = new T(find); + mListBase.push_back(_widget); + return; + } + } + + MYGUI_LOG(Warning, "Widget with name '" << _name << "' not found. [" << mLayoutName << "]"); + MYGUI_ASSERT( ! _throw, "Can't assign base widget with name '" << _name << "'. [" << mLayoutName << "]"); + if (_createFakeWidgets) + { + _widget = new T(_createFakeWidget(mMainWidget)); + mListBase.push_back(_widget); + } + } + + void initialise(const std::string& _layout, MyGUI::Widget* _parent = nullptr, bool _throw = true, bool _createFakeWidgets = true) + { + const std::string MAIN_WINDOW1 = "_Main"; + const std::string MAIN_WINDOW2 = "Root"; + mLayoutName = _layout; + + // îáîðà÷èâàåì + if (mLayoutName.empty()) + { + mMainWidget = _parent; + } + // çàãðóæàåì ëåéàóò íà âèäæåò + else + { + mPrefix = MyGUI::utility::toString(this, "_"); + mListWindowRoot = MyGUI::LayoutManager::getInstance().loadLayout(mLayoutName, mPrefix, _parent); + + const std::string mainName1 = mPrefix + MAIN_WINDOW1; + const std::string mainName2 = mPrefix + MAIN_WINDOW2; + for (MyGUI::VectorWidgetPtr::iterator iter = mListWindowRoot.begin(); iter != mListWindowRoot.end(); ++iter) + { + if ((*iter)->getName() == mainName1 || (*iter)->getName() == mainName2) + { + mMainWidget = (*iter); + + snapToParent(mMainWidget); + + break; + } + } + + if (mMainWidget == nullptr) + { + MYGUI_LOG(Warning, "Root widget with name '" << MAIN_WINDOW1 << "' or '" << MAIN_WINDOW2 << "' not found. [" << mLayoutName << "]"); + MYGUI_ASSERT(!_throw, "No root widget. ['" << mLayoutName << "]"); + if (_createFakeWidgets) + mMainWidget = _createFakeWidget(_parent); + } + } + } + + void shutdown() + { + // óäàëÿåì âñå êëàññû + for (VectorBasePtr::reverse_iterator iter = mListBase.rbegin(); iter != mListBase.rend(); ++iter) + delete (*iter); + mListBase.clear(); + + // óäàëÿåì âñå ðóòîâûå âèäæåòû + MyGUI::LayoutManager::getInstance().unloadLayout(mListWindowRoot); + mListWindowRoot.clear(); + } + + template + void initialiseByAttributes(Type* _owner, MyGUI::Widget* _parent = nullptr, bool _throw = true, bool _createFakeWidgets = true) + { + initialise(attribute::AttributeLayout::getData(), _parent, _throw, _createFakeWidgets); + + typename attribute::AttributeFieldWidgetName::VectorBindPair& data = attribute::AttributeFieldWidgetName::getData(); + for (typename attribute::AttributeFieldWidgetName::VectorBindPair::iterator item = data.begin(); item != data.end(); ++item) + { + MyGUI::Widget* value = nullptr; + assignWidget(value, item->second, _throw, false); + + bool result = item->first->set(_owner, value); + + if (!result && _createFakeWidgets) + { + value = _createFakeWidgetT(item->first->getFieldTypeName(), mMainWidget); + item->first->set(_owner, value); + } + } + } + private: + void snapToParent(MyGUI::Widget* _child) + { + if (_child->isUserString("SnapTo")) + { + MyGUI::Align align = MyGUI::Align::parse(_child->getUserString("SnapTo")); + + MyGUI::IntCoord coord = _child->getCoord(); + MyGUI::IntSize size = _child->getParentSize(); + + if (align.isHStretch()) + { + coord.left = 0; + coord.width = size.width; + } + else if (align.isLeft()) + { + coord.left = 0; + } + else if (align.isRight()) + { + coord.left = size.width - coord.width; + } + else + { + coord.left = (size.width - coord.width) / 2; + } + + if (align.isVStretch()) + { + coord.top = 0; + coord.height = size.height; + } + else if (align.isTop()) + { + coord.top = 0; + } + else if (align.isBottom()) + { + coord.top = size.height - coord.height; + } + else + { + coord.top = (size.height - coord.height) / 2; + } + + _child->setCoord(coord); + } + } + + template + T* _createFakeWidget(MyGUI::Widget* _parent) + { + return static_cast(_createFakeWidgetT(T::getClassTypeName(), _parent)); + } + + MyGUI::Widget* _createFakeWidgetT(const std::string& _typeName, MyGUI::Widget* _parent) + { + if (_parent) + return _parent->createWidgetT(_typeName, MyGUI::SkinManager::getInstance().getDefaultSkin(), MyGUI::IntCoord(), MyGUI::Align::Default); + + return MyGUI::Gui::getInstance().createWidgetT(_typeName, MyGUI::SkinManager::getInstance().getDefaultSkin(), MyGUI::IntCoord(), MyGUI::Align::Default, ""); + } + + public: + virtual ~BaseLayout() + { + shutdown(); + } + + protected: + MyGUI::Widget* mMainWidget; + + private: + std::string mPrefix; + std::string mLayoutName; + MyGUI::VectorWidgetPtr mListWindowRoot; + typedef std::vector VectorBasePtr; + VectorBasePtr mListBase; + }; + +} // namespace wraps + +#endif // __BASE_LAYOUT_H__ diff -Nur stuntrally.orig/source/mygui/BaseLayout/WrapsAttribute.h stuntrally//source/mygui/BaseLayout/WrapsAttribute.h --- stuntrally.orig/source/mygui/BaseLayout/WrapsAttribute.h 1970-01-01 01:00:00.000000000 +0100 +++ stuntrally//source/mygui/BaseLayout/WrapsAttribute.h 2011-08-13 01:27:11.000000000 +0200 @@ -0,0 +1,47 @@ +/*! + @file + @author Albert Semenov + @date 10/2009 + @module +*/ + +#ifndef __WRAPS_ATTRIBUTE_H__ +#define __WRAPS_ATTRIBUTE_H__ + +#include +#include "Attribute.h" + +namespace attribute +{ + + struct FieldSetterWidget + { + typedef MyGUI::Widget BaseValueType; + + template + static Type* convert(BaseValueType* _value) + { + return _value == 0 ? 0 : _value->castType(false); + } + }; + + DECLARE_ATTRIBUTE_FIELD(AttributeFieldWidgetName, std::string, FieldSetterWidget); + +#define ATTRIBUTE_FIELD_WIDGET_NAME(_class, _field, _value) \ + ATTRIBUTE_FIELD(AttributeFieldWidgetName, _class, _field, _value) + + + DECLARE_ATTRIBUTE_CLASS(AttributeSize, MyGUI::IntSize); + +#define ATTRIBUTE_CLASS_SIZE(_class, _value) \ + ATTRIBUTE_CLASS(AttributeSize, _class, _value) + + + DECLARE_ATTRIBUTE_CLASS(AttributeLayout, std::string); + +#define ATTRIBUTE_CLASS_LAYOUT(_class, _value) \ + ATTRIBUTE_CLASS(AttributeLayout, _class, _value) + +} + +#endif // __WRAPS_ATTRIBUTE_H__ diff -Nur stuntrally.orig/source/mygui/MessageBox/MessageBox.h stuntrally//source/mygui/MessageBox/MessageBox.h --- stuntrally.orig/source/mygui/MessageBox/MessageBox.h 1970-01-01 01:00:00.000000000 +0100 +++ stuntrally//source/mygui/MessageBox/MessageBox.h 2011-08-13 01:16:08.000000000 +0200 @@ -0,0 +1,389 @@ +/*! + @file + @author Albert Semenov + @date 12/2010 +*/ +#ifndef __MESSAGE_BOX_H__ +#define __MESSAGE_BOX_H__ + +#include +#include "MessageBoxStyle.h" +#include "BaseLayout/BaseLayout.h" + +namespace MyGUI +{ + class Message; + + typedef delegates::CMultiDelegate2 EventHandle_MessageBoxPtrMessageStyle; + + class Message : + public wraps::BaseLayout + { + public: + Message() : + wraps::BaseLayout("MessageBox.layout"), + mWidgetText(nullptr), + mInfoOk(MessageBoxStyle::None), + mInfoCancel(MessageBoxStyle::None), + mSmoothShow(false), + mIcon(nullptr), + mLeftOffset1(0), + mLeftOffset2(0) + { + assignWidget(mWidgetText, "Text", false); + if (mWidgetText != nullptr) + { + mOffsetText.set(mMainWidget->getClientCoord().width - mWidgetText->getWidth(), mMainWidget->getClientCoord().height - mWidgetText->getHeight()); + mLeftOffset2 = mLeftOffset1 = mWidgetText->getLeft(); + } + + assignWidget(mIcon, "Icon", false); + if (mIcon != nullptr) + { + mLeftOffset2 = mIcon->getRight() + 3; + } + + mButtonType = Button::getClassTypeName(); + + if (mMainWidget->isUserString("ButtonSkin")) + mButtonSkin = mMainWidget->getUserString("ButtonSkin"); + + Widget* widget = nullptr; + assignWidget(widget, "ButtonPlace", false); + if (widget != nullptr) + { + mButtonOffset.set(widget->getLeft(), mMainWidget->getClientCoord().height - widget->getTop()); + widget->setVisible(false); + } + + assignWidget(widget, "ButtonTemplate", false); + if (widget != nullptr) + { + mButtonSize = widget->getSize(); + } + } + + virtual ~Message() + { + mWidgetText = nullptr; + mIcon = nullptr; + } + + /** Set caption text*/ + void setCaption(const UString& _value) + { + mMainWidget->castType()->setCaption(_value); + } + + /** Set message text*/ + void setMessageText(const UString& _value) + { + if (mWidgetText != nullptr) + mWidgetText->setCaption(_value); + updateSize(); + } + + /** Create button with specific name*/ + MessageBoxStyle addButtonName(const UString& _name) + { + if (mVectorButton.size() >= MessageBoxStyle::_CountUserButtons) + { + MYGUI_LOG(Warning, "Too many buttons in message box, ignored"); + return MessageBoxStyle::None; + } + // áèò, íîìåð êíîïêè + ñìåùåíèå äî Button1 + MessageBoxStyle info = MessageBoxStyle(MessageBoxStyle::Enum(MYGUI_FLAG(mVectorButton.size() + MessageBoxStyle::_IndexUserButton1))); + + // çàïîìèíàåì êíîïêè äëÿ îòìåíû è ïîäòâåðæäåíèÿ + if (mVectorButton.empty()) + mInfoOk = info; + mInfoCancel = info; + + Widget* widget = mMainWidget->createWidgetT(mButtonType, mButtonSkin, IntCoord(), Align::Left | Align::Bottom); + Button* button = widget->castType