Browse Source

Encapsulated all usages of mStyle in GUI and made sure GUI elements properly update sprites if style changes

Marko Pintera 11 years ago
parent
commit
16a796b5af

+ 1 - 1
BansheeEditor/Source/BsGUIColor.cpp

@@ -119,7 +119,7 @@ namespace BansheeEditor
 
 	Vector2I GUIColor::_getOptimalSize() const
 	{
-		return GUIHelper::calcOptimalContentsSize(Vector2I(80, 10), *mStyle, _getLayoutOptions()); // Arbitrary size
+		return GUIHelper::calcOptimalContentsSize(Vector2I(80, 10), *_getStyle(), _getLayoutOptions()); // Arbitrary size
 	}
 
 	void GUIColor::fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, UINT32 maxNumQuads, 

+ 2 - 2
BansheeEditor/Source/BsGUIWindowDropArea.cpp

@@ -38,9 +38,9 @@ namespace BansheeEditor
 	void GUIWindowDropArea::setFocused(bool focused)
 	{
 		if(focused)
-			mActiveTexture = mStyle->focused.texture;
+			mActiveTexture = _getStyle()->focused.texture;
 		else
-			mActiveTexture = mStyle->normal.texture;
+			mActiveTexture = _getStyle()->normal.texture;
 
 		markContentAsDirty();
 	}

+ 2 - 2
BansheeEditor/Source/BsGUIWindowFrame.cpp

@@ -43,9 +43,9 @@ namespace BansheeEditor
 	void GUIWindowFrame::setFocused(bool focused)
 	{
 		if(focused)
-			mActiveTexture = mStyle->focused.texture;
+			mActiveTexture = _getStyle()->focused.texture;
 		else
-			mActiveTexture = mStyle->normal.texture;
+			mActiveTexture = _getStyle()->normal.texture;
 
 		markContentAsDirty();
 	}

+ 3 - 1
BansheeEngine/Include/BsGUIButtonBase.h

@@ -77,13 +77,15 @@ namespace BansheeEngine
 
 		void setState(GUIButtonState state);
 		GUIButtonState getState() const { return mActiveState; }
+
+		const HSpriteTexture& getActiveTexture() const;
+		bool isActiveTextureLoaded() const;
 	private:
 		ImageSprite* mImageSprite;
 		ImageSprite* mContentImageSprite;
 		TextSprite* mTextSprite;
 		GUIButtonState mActiveState;
 
-		HSpriteTexture mActiveTexture;
 		IMAGE_SPRITE_DESC mImageDesc;
 		GUIContent mContent;
 

+ 6 - 1
BansheeEngine/Include/BsGUIElement.h

@@ -25,7 +25,7 @@ namespace BansheeEngine
 		};
 
 	public:
-		GUIElement(const GUIElementStyle* style, const GUILayoutOptions& layoutOptions);
+		GUIElement(const CM::String& styleName, const GUILayoutOptions& layoutOptions);
 		virtual ~GUIElement();
 
 		/**
@@ -125,6 +125,8 @@ namespace BansheeEngine
 		virtual CM::UINT32 _getRenderElementDepth(CM::UINT32 renderElementIdx) const { return _getDepth(); }
 		Type _getType() const { return GUIElementBase::Type::Element; }
 		bool _isDestroyed() const { return mIsDestroyed; }
+		void _refreshStyle();
+		const GUIElementStyle* _getStyle() const { return mStyle; }
 
 		const CM::RectI& _getClippedBounds() const { return mClippedBounds; }
 		const CM::RectI& _getClipRect() const { return mClipRect; }
@@ -167,6 +169,9 @@ namespace BansheeEngine
 		CM::Vector2I mOffset;
 		CM::UINT32 mWidth, mHeight;
 		CM::RectI mClipRect;
+
+	private:
 		const GUIElementStyle* mStyle;
+		CM::String mStyleName;
 	};
 }

+ 10 - 1
BansheeEngine/Include/BsGUIInputBox.h

@@ -10,6 +10,13 @@ namespace BansheeEngine
 {
 	class BS_EXPORT GUIInputBox : public GUIElement
 	{
+		enum class State
+		{
+			Normal,
+			Hover,
+			Focused
+		};
+
 	public:
 		static const CM::String& getGUITypeName();
 
@@ -85,8 +92,8 @@ namespace BansheeEngine
 		CM::Vector2I mTextOffset;
 		bool mHasFocus;
 		bool mIsMouseOver;
+		State mState;
 
-		HSpriteTexture mActiveTexture;
 		IMAGE_SPRITE_DESC mImageDesc;
 		CM::WString mText;
 		std::function<bool(const CM::WString&)> mFilter;
@@ -120,6 +127,8 @@ namespace BansheeEngine
 		CM::Vector2I getTextOffset() const;
 		CM::RectI getTextClipRect() const;
 		TEXT_SPRITE_DESC getTextDesc() const;
+		const HSpriteTexture& getActiveTexture() const;
+		bool isActiveTextureLoaded() const;
 		
 		void cutText();
 		void copyText();

+ 1 - 0
BansheeEngine/Include/BsGUITexture.h

@@ -45,6 +45,7 @@ namespace BansheeEngine
 		HSpriteTexture mActiveTexture;
 		IMAGE_SPRITE_DESC mDesc;
 		GUIImageScaleMode mScaleMode;
+		bool mUsingStyleTexture;
 
 		GUITexture(const GUIElementStyle* style, const HSpriteTexture& texture, GUIImageScaleMode scale, const GUILayoutOptions& layoutOptions);
 		virtual ~GUITexture();

+ 49 - 43
BansheeEngine/Source/BsGUIButtonBase.cpp

@@ -23,19 +23,6 @@ namespace BansheeEngine
 		if(contentTex != nullptr && contentTex.isLoaded())
 			mContentImageSprite = cm_new<ImageSprite, PoolAlloc>();
 
-		mActiveTexture = mStyle->normal.texture;
-		if(mActiveTexture != nullptr && mActiveTexture.isLoaded() &&
-			mActiveTexture->getTexture() != nullptr && mActiveTexture->getTexture().isLoaded())
-		{
-			mImageDesc.width = mActiveTexture->getTexture()->getWidth();
-			mImageDesc.height = mActiveTexture->getTexture()->getHeight();
-		}
-
-		mImageDesc.borderLeft = mStyle->border.left;
-		mImageDesc.borderRight = mStyle->border.right;
-		mImageDesc.borderTop = mStyle->border.top;
-		mImageDesc.borderBottom = mStyle->border.bottom;
-
 		mLocStringUpdatedConn = mContent.getText().addOnStringModifiedCallback(std::bind(&GUIButtonBase::markContentAsDirty, this));
 	}
 
@@ -118,8 +105,19 @@ namespace BansheeEngine
 		mImageDesc.width = mWidth;
 		mImageDesc.height = mHeight;
 
-		if(mActiveTexture != nullptr && mActiveTexture.isLoaded())
-			mImageDesc.texture = mActiveTexture.getInternalPtr();
+		if(isActiveTextureLoaded())
+		{
+			const HSpriteTexture& activeTex = getActiveTexture();
+
+			mImageDesc.width = activeTex->getTexture()->getWidth();
+			mImageDesc.height = activeTex->getTexture()->getHeight();
+			mImageDesc.texture = activeTex.getInternalPtr();
+		}
+
+		mImageDesc.borderLeft = _getStyle()->border.left;
+		mImageDesc.borderRight = _getStyle()->border.right;
+		mImageDesc.borderTop = _getStyle()->border.top;
+		mImageDesc.borderBottom = _getStyle()->border.bottom;
 
 		mImageSprite->update(mImageDesc);
 
@@ -147,13 +145,16 @@ namespace BansheeEngine
 	{
 		UINT32 imageWidth = 0;
 		UINT32 imageHeight = 0;
-		if(mActiveTexture != nullptr && mActiveTexture.isLoaded())
+
+		if(isActiveTextureLoaded())
 		{
-			imageWidth = mActiveTexture->getTexture()->getWidth();
-			imageHeight = mActiveTexture->getTexture()->getHeight();
+			const HSpriteTexture& activeTex = getActiveTexture();
+
+			imageWidth = activeTex->getTexture()->getWidth();
+			imageHeight = activeTex->getTexture()->getHeight();
 		}
 
-		Vector2I contentSize = GUIHelper::calcOptimalContentsSize(mContent, *mStyle, _getLayoutOptions());
+		Vector2I contentSize = GUIHelper::calcOptimalContentsSize(mContent, *_getStyle(), _getLayoutOptions());
 		UINT32 contentWidth = std::max(imageWidth, (UINT32)contentSize.x);
 		UINT32 contentHeight = std::max(imageHeight, (UINT32)contentSize.y);
 
@@ -202,7 +203,7 @@ namespace BansheeEngine
 			UINT32 freeWidth = (UINT32)std::max(0, contentBounds.width - textBounds.width - imageBounds.width);
 			INT32 imageXOffset = (INT32)(freeWidth / 2);
 
-			if(mStyle->imagePosition == GUIImagePosition::Right)
+			if(_getStyle()->imagePosition == GUIImagePosition::Right)
 			{
 				INT32 imageReservedWidth = std::max(0, contentBounds.width - textBounds.width);
 
@@ -293,50 +294,55 @@ namespace BansheeEngine
 	{
 		TEXT_SPRITE_DESC textDesc;
 		textDesc.text = mContent.getText();
-		textDesc.font = mStyle->font;
-		textDesc.fontSize = mStyle->fontSize;
+		textDesc.font = _getStyle()->font;
+		textDesc.fontSize = _getStyle()->fontSize;
 
 		RectI textBounds = getContentBounds();
 
 		textDesc.width = textBounds.width;
 		textDesc.height = textBounds.height;
-		textDesc.horzAlign = mStyle->textHorzAlign;
-		textDesc.vertAlign = mStyle->textVertAlign;
+		textDesc.horzAlign = _getStyle()->textHorzAlign;
+		textDesc.vertAlign = _getStyle()->textVertAlign;
 
 		return textDesc;
 	}
 
 	void GUIButtonBase::setState(GUIButtonState state)
 	{
-		switch(state)
+		mActiveState = state;
+
+		markContentAsDirty();
+	}
+
+	const HSpriteTexture& GUIButtonBase::getActiveTexture() const
+	{
+		switch(mActiveState)
 		{
 		case GUIButtonState::Normal:
-			mActiveTexture = mStyle->normal.texture;
-			break;
+			return _getStyle()->normal.texture;
 		case GUIButtonState::Hover:
-			mActiveTexture = mStyle->hover.texture;
-			break;
+			return _getStyle()->hover.texture;
 		case GUIButtonState::Active:
-			mActiveTexture = mStyle->active.texture;
-			break;
+			return _getStyle()->active.texture;
 		case GUIButtonState::Focused:
-			mActiveTexture = mStyle->focused.texture;
-			break;
+			return _getStyle()->focused.texture;
 		case GUIButtonState::NormalOn:
-			mActiveTexture = mStyle->normalOn.texture;
-			break;
+			return _getStyle()->normalOn.texture;
 		case GUIButtonState::HoverOn:
-			mActiveTexture = mStyle->hoverOn.texture;
-			break;
+			return _getStyle()->hoverOn.texture;
 		case GUIButtonState::ActiveOn:
-			mActiveTexture = mStyle->activeOn.texture;
-			break;
+			return _getStyle()->activeOn.texture;
 		case GUIButtonState::FocusedOn:
-			mActiveTexture = mStyle->focusedOn.texture;
-			break;
+			return _getStyle()->focusedOn.texture;
 		}
 
-		markContentAsDirty();
-		mActiveState = state;
+		return _getStyle()->normal.texture;
+	}
+
+	bool GUIButtonBase::isActiveTextureLoaded() const
+	{
+		const HSpriteTexture& activeTex = getActiveTexture();
+
+		return activeTex != nullptr && activeTex.isLoaded() && activeTex->getTexture() != nullptr && activeTex->getTexture().isLoaded();
 	}
 }

+ 21 - 4
BansheeEngine/Source/BsGUIElement.cpp

@@ -9,11 +9,11 @@ using namespace CamelotFramework;
 
 namespace BansheeEngine
 {
-	GUIElement::GUIElement(const GUIElementStyle* style, const GUILayoutOptions& layoutOptions)
-		:mLayoutOptions(layoutOptions), mWidth(0), mHeight(0), mDepth(0), mStyle(style),
-		mIsDestroyed(false)
+	GUIElement::GUIElement(const CM::String& styleName, const GUILayoutOptions& layoutOptions)
+		:mLayoutOptions(layoutOptions), mWidth(0), mHeight(0), mDepth(0), mStyle(nullptr),
+		mIsDestroyed(false), mStyleName(styleName)
 	{
-
+		_refreshStyle();
 	}
 
 	GUIElement::~GUIElement()
@@ -130,6 +130,8 @@ namespace BansheeEngine
 
 			if(widget != nullptr)
 				widget->registerElement(this);
+
+			_refreshStyle();
 		}
 
 		GUIElementBase::_changeParentWidget(widget);
@@ -206,6 +208,21 @@ namespace BansheeEngine
 		return contentBounds.contains(position);
 	}
 
+	void GUIElement::_refreshStyle()
+	{
+		const GUIElementStyle* newStyle = nullptr;
+		if(_getParentWidget() != nullptr)
+			newStyle = _getParentWidget()->getSkin().getStyle(mStyleName);
+		else
+			newStyle = &GUISkin::DefaultStyle;
+
+		if(newStyle != mStyle)
+		{
+			mStyle = newStyle;
+			markContentAsDirty();
+		}
+	}
+
 	void GUIElement::destroy(GUIElement* element)
 	{
 		if(element->mIsDestroyed)

+ 52 - 30
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -36,24 +36,11 @@ namespace BansheeEngine
 
 	GUIInputBox::GUIInputBox(const GUIElementStyle* style, const GUILayoutOptions& layoutOptions, bool multiline)
 		:GUIElement(style, layoutOptions), mDragInProgress(false),
-		mCaretShown(false), mSelectionShown(false), mIsMultiline(multiline), mHasFocus(false), mIsMouseOver(false)
+		mCaretShown(false), mSelectionShown(false), mIsMultiline(multiline), mHasFocus(false), mIsMouseOver(false),
+		mState(State::Normal)
 	{
 		mImageSprite = cm_new<ImageSprite, PoolAlloc>();
 		mTextSprite = cm_new<TextSprite, PoolAlloc>();
-
-		mActiveTexture = mStyle->normal.texture;
-
-		if(mActiveTexture != nullptr && mActiveTexture.isLoaded() &&
-			mActiveTexture->getTexture() != nullptr && mActiveTexture->getTexture().isLoaded())
-		{
-			mImageDesc.width = mActiveTexture->getTexture()->getWidth();
-			mImageDesc.height = mActiveTexture->getTexture()->getHeight();
-		}
-
-		mImageDesc.borderLeft = mStyle->border.left;
-		mImageDesc.borderRight = mStyle->border.right;
-		mImageDesc.borderTop = mStyle->border.top;
-		mImageDesc.borderBottom = mStyle->border.bottom;
 	}
 
 	GUIInputBox::~GUIInputBox()
@@ -144,11 +131,21 @@ namespace BansheeEngine
 
 	void GUIInputBox::updateRenderElementsInternal()
 	{		
-		if(mActiveTexture != nullptr && mActiveTexture.isLoaded())
-			mImageDesc.texture = mActiveTexture.getInternalPtr();
-
 		mImageDesc.width = mWidth;
 		mImageDesc.height = mHeight;
+		mImageDesc.borderLeft = _getStyle()->border.left;
+		mImageDesc.borderRight = _getStyle()->border.right;
+		mImageDesc.borderTop = _getStyle()->border.top;
+		mImageDesc.borderBottom = _getStyle()->border.bottom;
+
+		if(isActiveTextureLoaded())
+		{
+			const HSpriteTexture& activeTex = getActiveTexture();
+
+			mImageDesc.width = activeTex->getTexture()->getWidth();
+			mImageDesc.height = activeTex->getTexture()->getHeight();
+			mImageDesc.texture = activeTex.getInternalPtr();
+		}
 
 		mImageSprite->update(mImageDesc);
 
@@ -318,13 +315,15 @@ namespace BansheeEngine
 	{
 		UINT32 imageWidth = 0;
 		UINT32 imageHeight = 0;
-		if(mActiveTexture != nullptr && mActiveTexture.isLoaded())
+		if(isActiveTextureLoaded())
 		{
-			imageWidth = mActiveTexture->getTexture()->getWidth();
-			imageHeight = mActiveTexture->getTexture()->getHeight();
+			const HSpriteTexture& activeTex = getActiveTexture();
+
+			imageWidth = activeTex->getTexture()->getWidth();
+			imageHeight = activeTex->getTexture()->getHeight();
 		}
 
-		Vector2I contentSize = GUIHelper::calcOptimalContentsSize(mText, *mStyle, _getLayoutOptions());
+		Vector2I contentSize = GUIHelper::calcOptimalContentsSize(mText, *_getStyle(), _getLayoutOptions());
 		UINT32 contentWidth = std::max(imageWidth, (UINT32)contentSize.x);
 		UINT32 contentHeight = std::max(imageHeight, (UINT32)contentSize.y);
 
@@ -388,7 +387,7 @@ namespace BansheeEngine
 		{
 			if(!mHasFocus)
 			{
-				mActiveTexture = mStyle->hover.texture;
+				mState = State::Hover;
 				markContentAsDirty();
 			}
 
@@ -400,7 +399,7 @@ namespace BansheeEngine
 		{
 			if(!mHasFocus)
 			{
-				mActiveTexture = mStyle->normal.texture;
+				mState = State::Normal;
 				markContentAsDirty();
 			}
 
@@ -537,7 +536,7 @@ namespace BansheeEngine
 
 		if(ev.getType() == GUICommandEventType::FocusGained)
 		{
-			mActiveTexture = mStyle->focused.texture;
+			mState = State::Focused;
 
 			clearSelection();
 			showCaret();
@@ -550,7 +549,8 @@ namespace BansheeEngine
 		
 		if(ev.getType() == GUICommandEventType::FocusLost)
 		{
-			mActiveTexture = mStyle->normal.texture;
+			mState = State::Normal;
+
 			hideCaret();
 			clearSelection();
 			markContentAsDirty();
@@ -1027,19 +1027,41 @@ namespace BansheeEngine
 	{
 		TEXT_SPRITE_DESC textDesc;
 		textDesc.text = mText;
-		textDesc.font = mStyle->font;
-		textDesc.fontSize = mStyle->fontSize;
+		textDesc.font = _getStyle()->font;
+		textDesc.fontSize = _getStyle()->fontSize;
 
 		RectI textBounds = getContentBounds();
 		textDesc.width = textBounds.width;
 		textDesc.height = textBounds.height;
-		textDesc.horzAlign = mStyle->textHorzAlign;
-		textDesc.vertAlign = mStyle->textVertAlign;
+		textDesc.horzAlign = _getStyle()->textHorzAlign;
+		textDesc.vertAlign = _getStyle()->textVertAlign;
 		textDesc.wordWrap = mIsMultiline;
 
 		return textDesc;
 	}
 
+	const HSpriteTexture& GUIInputBox::getActiveTexture() const
+	{
+		switch(mState)
+		{
+		case State::Focused:
+			return _getStyle()->focused.texture;
+		case State::Hover:
+			return _getStyle()->hover.texture;
+		case State::Normal:
+			return _getStyle()->normal.texture;
+		}
+
+		return _getStyle()->normal.texture;
+	}
+
+	bool GUIInputBox::isActiveTextureLoaded() const
+	{
+		const HSpriteTexture& activeTex = getActiveTexture();
+
+		return activeTex != nullptr && activeTex.isLoaded() && activeTex->getTexture() != nullptr && activeTex->getTexture().isLoaded();
+	}
+
 	GUIContextMenu* GUIInputBox::getContextMenu() const
 	{
 		static bool initialized = false;

+ 6 - 7
BansheeEngine/Source/BsGUILabel.cpp

@@ -16,12 +16,6 @@ namespace BansheeEngine
 	{
 		mTextSprite = cm_new<TextSprite, PoolAlloc>();
 
-		mDesc.font = mStyle->font;
-		mDesc.fontSize = mStyle->fontSize;
-		mDesc.wordWrap = mStyle->wordWrap;
-		mDesc.horzAlign = mStyle->textHorzAlign;
-		mDesc.vertAlign = mStyle->textVertAlign;
-
 		mLocStringUpdatedConn = mContent.getText().addOnStringModifiedCallback(std::bind(&GUILabel::markContentAsDirty, this));
 	}
 
@@ -48,6 +42,11 @@ namespace BansheeEngine
 
 	void GUILabel::updateRenderElementsInternal()
 	{		
+		mDesc.font = _getStyle()->font;
+		mDesc.fontSize = _getStyle()->fontSize;
+		mDesc.wordWrap = _getStyle()->wordWrap;
+		mDesc.horzAlign = _getStyle()->textHorzAlign;
+		mDesc.vertAlign = _getStyle()->textVertAlign;
 		mDesc.width = mWidth;
 		mDesc.height = mHeight;
 		mDesc.text = mContent.getText();
@@ -64,7 +63,7 @@ namespace BansheeEngine
 
 	Vector2I GUILabel::_getOptimalSize() const
 	{
-		return GUIHelper::calcOptimalContentsSize(mContent, *mStyle, _getLayoutOptions());
+		return GUIHelper::calcOptimalContentsSize(mContent, *_getStyle(), _getLayoutOptions());
 	}
 
 	void GUILabel::fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, UINT32 maxNumQuads, 

+ 2 - 2
BansheeEngine/Source/BsGUIScrollBar.cpp

@@ -86,8 +86,8 @@ namespace BansheeEngine
 	{
 		IMAGE_SPRITE_DESC desc;
 
-		if(mStyle->normal.texture != nullptr && mStyle->normal.texture.isLoaded())
-			desc.texture = mStyle->normal.texture.getInternalPtr();
+		if(_getStyle()->normal.texture != nullptr && _getStyle()->normal.texture.isLoaded())
+			desc.texture = _getStyle()->normal.texture.getInternalPtr();
 
 		desc.width = mWidth;
 		desc.height = mHeight;

+ 8 - 8
BansheeEngine/Source/BsGUIScrollBarHandle.cpp

@@ -158,7 +158,7 @@ namespace BansheeEngine
 				{
 					mMouseOverHandle = false;
 
-					mCurTexture = mStyle->normal.texture;
+					mCurTexture = _getStyle()->normal.texture;
 					markContentAsDirty();
 
 					return true;
@@ -170,7 +170,7 @@ namespace BansheeEngine
 				{
 					mMouseOverHandle = true;
 
-					mCurTexture = mStyle->hover.texture;
+					mCurTexture = _getStyle()->hover.texture;
 					markContentAsDirty();
 
 					return true;
@@ -180,7 +180,7 @@ namespace BansheeEngine
 
 		if(ev.getType() == GUIMouseEventType::MouseDown && mMouseOverHandle)
 		{
-			mCurTexture = mStyle->active.texture;
+			mCurTexture = _getStyle()->active.texture;
 			markContentAsDirty();
 
 			if(mHorizontal)
@@ -227,7 +227,7 @@ namespace BansheeEngine
 
 		if(ev.getType() == GUIMouseEventType::MouseOut && !mHandleDragged)
 		{
-			mCurTexture = mStyle->normal.texture;
+			mCurTexture = _getStyle()->normal.texture;
 			mMouseOverHandle = false;
 			markContentAsDirty();
 
@@ -237,9 +237,9 @@ namespace BansheeEngine
 		if(ev.getType() == GUIMouseEventType::MouseUp)
 		{
 			if(mMouseOverHandle)
-				mCurTexture = mStyle->hover.texture;
+				mCurTexture = _getStyle()->hover.texture;
 			else
-				mCurTexture = mStyle->normal.texture;
+				mCurTexture = _getStyle()->normal.texture;
 
 			// If we clicked above or below the scroll handle, scroll by one page
 			INT32 handleOffset = 0;
@@ -287,9 +287,9 @@ namespace BansheeEngine
 			mHandleDragged = false;
 
 			if(mMouseOverHandle)
-				mCurTexture = mStyle->hover.texture;
+				mCurTexture = _getStyle()->hover.texture;
 			else
-				mCurTexture = mStyle->normal.texture;
+				mCurTexture = _getStyle()->normal.texture;
 
 			markContentAsDirty();
 			return true;

+ 15 - 7
BansheeEngine/Source/BsGUITexture.cpp

@@ -18,19 +18,17 @@ namespace BansheeEngine
 
 	GUITexture::GUITexture(const GUIElementStyle* style, const HSpriteTexture& texture, 
 		GUIImageScaleMode scale, const GUILayoutOptions& layoutOptions)
-		:GUIElement(style, layoutOptions), mScaleMode(scale)
+		:GUIElement(style, layoutOptions), mScaleMode(scale), mUsingStyleTexture(false)
 	{
 		mImageSprite = cm_new<ImageSprite, PoolAlloc>();
 
 		if(texture != nullptr)
+		{
 			mActiveTexture = texture;
+			mUsingStyleTexture = false;
+		}
 		else
-			mActiveTexture = style->normal.texture;
-	
-		mDesc.borderLeft = mStyle->border.left;
-		mDesc.borderRight = mStyle->border.right;
-		mDesc.borderTop = mStyle->border.top;
-		mDesc.borderBottom = mStyle->border.bottom;
+			mUsingStyleTexture = true;
 	}
 
 	GUITexture::~GUITexture()
@@ -84,6 +82,8 @@ namespace BansheeEngine
 	void GUITexture::setTexture(const HSpriteTexture& texture)
 	{
 		mActiveTexture = texture;
+		mUsingStyleTexture = false;
+
 		markContentAsDirty();
 	}
 
@@ -107,6 +107,14 @@ namespace BansheeEngine
 		mDesc.width = mWidth;
 		mDesc.height = mHeight;
 
+		mDesc.borderLeft = _getStyle()->border.left;
+		mDesc.borderRight = _getStyle()->border.right;
+		mDesc.borderTop = _getStyle()->border.top;
+		mDesc.borderBottom = _getStyle()->border.bottom;
+
+		if(mUsingStyleTexture)
+			mActiveTexture = _getStyle()->normal.texture;
+
 		float optimalWidth = 0.0f;
 		float optimalHeight = 0.0f;
 		if(mActiveTexture != nullptr && mActiveTexture.isLoaded())

+ 3 - 0
BansheeEngine/Source/BsGUIWidget.cpp

@@ -181,6 +181,9 @@ namespace BansheeEngine
 	void GUIWidget::setSkin(const GUISkin& skin)
 	{
 		mSkin = &skin;
+
+		for(auto& element : mElements)
+			element->_refreshStyle();
 	}
 
 	const GUISkin& GUIWidget::getSkin() const