ソースを参照

Added ability to update offset/clip rect without recreating entire GUIElement mesh

Marko Pintera 12 年 前
コミット
269c01c4e7

+ 14 - 4
BansheeEngine/Include/BsGUIElement.h

@@ -92,6 +92,7 @@ namespace BansheeEngine
 		void _setWidth(CM::UINT32 width);
 		void _setWidth(CM::UINT32 width);
 		void _setHeight(CM::UINT32 height);
 		void _setHeight(CM::UINT32 height);
 		void _setClipRect(const CM::Rect& clipRect);
 		void _setClipRect(const CM::Rect& clipRect);
+		void _markAsClean() { mIsDirty = 0; }
 		virtual void _setFocus(bool focus) {}
 		virtual void _setFocus(bool focus) {}
 
 
 		CM::UINT32 _getWidth() const { return mWidth; }
 		CM::UINT32 _getWidth() const { return mWidth; }
@@ -104,7 +105,8 @@ namespace BansheeEngine
 		const CM::Rect& _getBounds() const { return mBounds; }
 		const CM::Rect& _getBounds() const { return mBounds; }
 		CM::UINT32 _getDepth() const { return mDepth; }
 		CM::UINT32 _getDepth() const { return mDepth; }
 		GUIWidget& _getParentWidget() const { return mParent; }
 		GUIWidget& _getParentWidget() const { return mParent; }
-		bool _isDirty() const { return mIsDirty; }
+		bool _isContentDirty() const;
+		bool _isMeshDirty() const; 
 		virtual bool _isInBounds(const CM::Int2 position) const;
 		virtual bool _isInBounds(const CM::Int2 position) const;
 		bool _acceptsKeyboardFocus() const { return mAcceptsKeyboardFocus; }
 		bool _acceptsKeyboardFocus() const { return mAcceptsKeyboardFocus; }
 
 
@@ -117,8 +119,16 @@ namespace BansheeEngine
 
 
 		void setLayoutOptions(const GUILayoutOptions& layoutOptions);
 		void setLayoutOptions(const GUILayoutOptions& layoutOptions);
 		
 		
-		void markAsClean() { mIsDirty = false; }
-		void markAsDirty();
+		/**
+		 * @brief	Marks the elements contents as dirty, which causes the sprite meshes to be recreated from scratch.
+		 */
+		void markContentAsDirty();
+
+		/**
+		 * @brief	Mark only the elements that operate directly on the sprite mesh without requiring the mesh
+		 * 			to be recreated as dirty. This includes position, depth and clip rectangle.
+		 */
+		void markMeshAsDirty();
 
 
 		CM::Rect getContentBounds() const;
 		CM::Rect getContentBounds() const;
 
 
@@ -129,7 +139,7 @@ namespace BansheeEngine
 		GUILayoutOptions mLayoutOptions;
 		GUILayoutOptions mLayoutOptions;
 		CM::Rect mBounds;
 		CM::Rect mBounds;
 
 
-		bool mIsDirty;
+		CM::UINT8 mIsDirty;
 		bool mAcceptsKeyboardFocus;
 		bool mAcceptsKeyboardFocus;
 		CM::UINT32 mDepth;
 		CM::UINT32 mDepth;
 		CM::Int2 mOffset;
 		CM::Int2 mOffset;

+ 4 - 4
BansheeEngine/Source/BsGUIButton.cpp

@@ -169,28 +169,28 @@ namespace BansheeEngine
 		if(ev.getType() == GUIMouseEventType::MouseOver)
 		if(ev.getType() == GUIMouseEventType::MouseOver)
 		{
 		{
 			mImageDesc.texture = mStyle->hover.texture;
 			mImageDesc.texture = mStyle->hover.texture;
-			markAsDirty();
+			markContentAsDirty();
 
 
 			return true;
 			return true;
 		}
 		}
 		else if(ev.getType() == GUIMouseEventType::MouseOut)
 		else if(ev.getType() == GUIMouseEventType::MouseOut)
 		{
 		{
 			mImageDesc.texture = mStyle->normal.texture;
 			mImageDesc.texture = mStyle->normal.texture;
-			markAsDirty();
+			markContentAsDirty();
 
 
 			return true;
 			return true;
 		}
 		}
 		else if(ev.getType() == GUIMouseEventType::MouseDown)
 		else if(ev.getType() == GUIMouseEventType::MouseDown)
 		{
 		{
 			mImageDesc.texture = mStyle->active.texture;
 			mImageDesc.texture = mStyle->active.texture;
-			markAsDirty();
+			markContentAsDirty();
 
 
 			return true;
 			return true;
 		}
 		}
 		else if(ev.getType() == GUIMouseEventType::MouseUp)
 		else if(ev.getType() == GUIMouseEventType::MouseUp)
 		{
 		{
 			mImageDesc.texture = mStyle->hover.texture;
 			mImageDesc.texture = mStyle->hover.texture;
-			markAsDirty();
+			markContentAsDirty();
 
 
 			return true;
 			return true;
 		}
 		}

+ 35 - 12
BansheeEngine/Source/BsGUIElement.cpp

@@ -24,7 +24,7 @@ namespace BansheeEngine
 	void GUIElement::updateRenderElements()
 	void GUIElement::updateRenderElements()
 	{
 	{
 		updateRenderElementsInternal();
 		updateRenderElementsInternal();
-		markAsClean();
+		_markAsClean();
 	}
 	}
 
 
 	void GUIElement::setLayoutOptions(const GUILayoutOptions& layoutOptions) 
 	void GUIElement::setLayoutOptions(const GUILayoutOptions& layoutOptions) 
@@ -63,37 +63,45 @@ namespace BansheeEngine
 	void GUIElement::_setWidgetDepth(UINT8 depth) 
 	void GUIElement::_setWidgetDepth(UINT8 depth) 
 	{ 
 	{ 
 		mDepth |= depth << 24; 
 		mDepth |= depth << 24; 
-		markAsDirty();
+		markMeshAsDirty();
 	}
 	}
 
 
 	void GUIElement::_setAreaDepth(UINT16 depth) 
 	void GUIElement::_setAreaDepth(UINT16 depth) 
 	{ 
 	{ 
 		mDepth |= depth << 8; 
 		mDepth |= depth << 8; 
-		markAsDirty();
+		markMeshAsDirty();
 	}
 	}
 
 
 	void GUIElement::_setOffset(const CM::Int2& offset) 
 	void GUIElement::_setOffset(const CM::Int2& offset) 
 	{ 
 	{ 
-		mOffset = offset; 
-		markAsDirty();
+		if(mOffset != offset)
+			markMeshAsDirty();
+
+		mOffset = offset;
 	}
 	}
 
 
 	void GUIElement::_setWidth(UINT32 width) 
 	void GUIElement::_setWidth(UINT32 width) 
 	{ 
 	{ 
+		if(mWidth != width)
+			markContentAsDirty();
+
 		mWidth = width; 
 		mWidth = width; 
-		markAsDirty();
 	}
 	}
 
 
 	void GUIElement::_setHeight(UINT32 height) 
 	void GUIElement::_setHeight(UINT32 height) 
 	{ 
 	{ 
-		mHeight = height; 
-		markAsDirty();
+		if(mHeight != height)
+			markContentAsDirty();
+
+		mHeight = height;
 	}
 	}
 
 
 	void GUIElement::_setClipRect(const CM::Rect& clipRect) 
 	void GUIElement::_setClipRect(const CM::Rect& clipRect) 
 	{ 
 	{ 
+		if(mClipRect != clipRect)
+			markMeshAsDirty();
+
 		mClipRect = clipRect; 
 		mClipRect = clipRect; 
-		markAsDirty();
 	}
 	}
 
 
 	Rect GUIElement::getContentBounds() const
 	Rect GUIElement::getContentBounds() const
@@ -115,17 +123,32 @@ namespace BansheeEngine
 		return contentBounds.contains(position);
 		return contentBounds.contains(position);
 	}
 	}
 
 
-	void GUIElement::markAsDirty() 
+	bool GUIElement::_isContentDirty() const
+	{
+		return (mIsDirty & 0x01) != 0;
+	}
+
+	bool GUIElement::_isMeshDirty() const
+	{
+		return (mIsDirty & 0x02) != 0;
+	}
+
+	void GUIElement::markContentAsDirty() 
 	{ 
 	{ 
-		if(!mIsDirty)
+		if(!_isContentDirty())
 		{
 		{
 			if(mParentLayout != nullptr)
 			if(mParentLayout != nullptr)
 				mParentLayout->_markAsDirty();
 				mParentLayout->_markAsDirty();
 
 
-			mIsDirty = true; 
+			mIsDirty |= 0x01; 
 		}
 		}
 	}
 	}
 
 
+	void GUIElement::markMeshAsDirty()
+	{
+		mIsDirty |= 0x02;
+	}
+
 	GUILayoutOptions GUIElement::getDefaultLayoutOptions(const GUIElementStyle* style)
 	GUILayoutOptions GUIElement::getDefaultLayoutOptions(const GUIElementStyle* style)
 	{
 	{
 		GUILayoutOptions layoutOptions;
 		GUILayoutOptions layoutOptions;

+ 27 - 27
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -319,7 +319,7 @@ namespace BansheeEngine
 		if(ev.getType() == GUIMouseEventType::MouseOver)
 		if(ev.getType() == GUIMouseEventType::MouseOver)
 		{
 		{
 			mImageDesc.texture = mStyle->hover.texture;
 			mImageDesc.texture = mStyle->hover.texture;
-			markAsDirty();
+			markContentAsDirty();
 
 
 			if(!mInputCursorSet)
 			if(!mInputCursorSet)
 			{
 			{
@@ -332,7 +332,7 @@ namespace BansheeEngine
 		else if(ev.getType() == GUIMouseEventType::MouseOut)
 		else if(ev.getType() == GUIMouseEventType::MouseOut)
 		{
 		{
 			mImageDesc.texture = mStyle->normal.texture;
 			mImageDesc.texture = mStyle->normal.texture;
-			markAsDirty();
+			markContentAsDirty();
 
 
 			if(!mDragInProgress && mInputCursorSet)
 			if(!mDragInProgress && mInputCursorSet)
 			{
 			{
@@ -356,7 +356,7 @@ namespace BansheeEngine
 			scrollTextToCaret();
 			scrollTextToCaret();
 
 
 			clearSelection();
 			clearSelection();
-			markAsDirty();
+			markContentAsDirty();
 
 
 			return true;
 			return true;
 		}
 		}
@@ -364,7 +364,7 @@ namespace BansheeEngine
 		{
 		{
 			mImageDesc.texture = mStyle->hover.texture;
 			mImageDesc.texture = mStyle->hover.texture;
 
 
-			markAsDirty();
+			markContentAsDirty();
 
 
 			return true;
 			return true;
 		}
 		}
@@ -404,7 +404,7 @@ namespace BansheeEngine
 
 
 			scrollTextToCaret();
 			scrollTextToCaret();
 
 
-			markAsDirty();
+			markContentAsDirty();
 			return true;
 			return true;
 		}
 		}
 
 
@@ -440,7 +440,7 @@ namespace BansheeEngine
 						}
 						}
 					}
 					}
 
 
-					markAsDirty();
+					markContentAsDirty();
 				}
 				}
 
 
 				return true;
 				return true;
@@ -470,7 +470,7 @@ namespace BansheeEngine
 						}
 						}
 					}
 					}
 
 
-					markAsDirty();
+					markContentAsDirty();
 				}
 				}
 
 
 				return true;
 				return true;
@@ -492,7 +492,7 @@ namespace BansheeEngine
 					gGUIManager().getInputSelectionTool()->moveSelectionToCaret(gGUIManager().getInputCaretTool()->getCaretPos());
 					gGUIManager().getInputSelectionTool()->moveSelectionToCaret(gGUIManager().getInputCaretTool()->getCaretPos());
 
 
 				scrollTextToCaret();
 				scrollTextToCaret();
-				markAsDirty();
+				markContentAsDirty();
 				return true;
 				return true;
 			}
 			}
 
 
@@ -512,7 +512,7 @@ namespace BansheeEngine
 					gGUIManager().getInputSelectionTool()->moveSelectionToCaret(gGUIManager().getInputCaretTool()->getCaretPos());
 					gGUIManager().getInputSelectionTool()->moveSelectionToCaret(gGUIManager().getInputCaretTool()->getCaretPos());
 
 
 				scrollTextToCaret();
 				scrollTextToCaret();
-				markAsDirty();
+				markContentAsDirty();
 				return true;
 				return true;
 			}
 			}
 
 
@@ -532,7 +532,7 @@ namespace BansheeEngine
 					gGUIManager().getInputSelectionTool()->moveSelectionToCaret(gGUIManager().getInputCaretTool()->getCaretPos());
 					gGUIManager().getInputSelectionTool()->moveSelectionToCaret(gGUIManager().getInputCaretTool()->getCaretPos());
 
 
 				scrollTextToCaret();
 				scrollTextToCaret();
-				markAsDirty();
+				markContentAsDirty();
 				return true;
 				return true;
 			}
 			}
 
 
@@ -552,7 +552,7 @@ namespace BansheeEngine
 					gGUIManager().getInputSelectionTool()->moveSelectionToCaret(gGUIManager().getInputCaretTool()->getCaretPos());
 					gGUIManager().getInputSelectionTool()->moveSelectionToCaret(gGUIManager().getInputCaretTool()->getCaretPos());
 
 
 				scrollTextToCaret();
 				scrollTextToCaret();
-				markAsDirty();
+				markContentAsDirty();
 				return true;
 				return true;
 			}
 			}
 
 
@@ -568,7 +568,7 @@ namespace BansheeEngine
 					gGUIManager().getInputCaretTool()->moveCaretRight();
 					gGUIManager().getInputCaretTool()->moveCaretRight();
 					scrollTextToCaret();
 					scrollTextToCaret();
 
 
-					markAsDirty();
+					markContentAsDirty();
 					return true;
 					return true;
 				}
 				}
 				
 				
@@ -579,7 +579,7 @@ namespace BansheeEngine
 				showSelection(0);
 				showSelection(0);
 				gGUIManager().getInputSelectionTool()->selectAll();
 				gGUIManager().getInputSelectionTool()->selectAll();
 
 
-				markAsDirty();
+				markContentAsDirty();
 				return true;
 				return true;
 			}
 			}
 		}
 		}
@@ -595,7 +595,7 @@ namespace BansheeEngine
 
 
 			scrollTextToCaret();
 			scrollTextToCaret();
 
 
-			markAsDirty();
+			markContentAsDirty();
 			return true;
 			return true;
 		}
 		}
 
 
@@ -606,7 +606,7 @@ namespace BansheeEngine
 	{
 	{
 		if(ev.getType() == GUICommandEventType::Redraw)
 		if(ev.getType() == GUICommandEventType::Redraw)
 		{
 		{
-			markAsDirty();
+			markMeshAsDirty();
 			return true;
 			return true;
 		}
 		}
 
 
@@ -616,28 +616,28 @@ namespace BansheeEngine
 	void GUIInputBox::showCaret()
 	void GUIInputBox::showCaret()
 	{
 	{
 		mCaretShown = true;
 		mCaretShown = true;
-		markAsDirty();
+		markContentAsDirty();
 	}
 	}
 
 
 
 
 	void GUIInputBox::hideCaret()
 	void GUIInputBox::hideCaret()
 	{
 	{
 		mCaretShown = false;
 		mCaretShown = false;
-		markAsDirty();
+		markContentAsDirty();
 	}
 	}
 
 
 	void GUIInputBox::showSelection(CM::UINT32 anchorCaretPos)
 	void GUIInputBox::showSelection(CM::UINT32 anchorCaretPos)
 	{
 	{
 		gGUIManager().getInputSelectionTool()->showSelection(anchorCaretPos);
 		gGUIManager().getInputSelectionTool()->showSelection(anchorCaretPos);
 		mSelectionShown = true;
 		mSelectionShown = true;
-		markAsDirty();
+		markContentAsDirty();
 	}
 	}
 
 
 	void GUIInputBox::clearSelection()
 	void GUIInputBox::clearSelection()
 	{
 	{
 		gGUIManager().getInputSelectionTool()->clearSelection();
 		gGUIManager().getInputSelectionTool()->clearSelection();
 		mSelectionShown = false;
 		mSelectionShown = false;
-		markAsDirty();
+		markContentAsDirty();
 	}
 	}
 
 
 	void GUIInputBox::scrollTextToCaret()
 	void GUIInputBox::scrollTextToCaret()
@@ -683,7 +683,7 @@ namespace BansheeEngine
 		gGUIManager().getInputCaretTool()->updateText(textDesc, newOffset, mTextOffset);
 		gGUIManager().getInputCaretTool()->updateText(textDesc, newOffset, mTextOffset);
 		gGUIManager().getInputSelectionTool()->updateText(textDesc, newOffset, mTextOffset);
 		gGUIManager().getInputSelectionTool()->updateText(textDesc, newOffset, mTextOffset);
 
 
-		markAsDirty();
+		markContentAsDirty();
 	}
 	}
 
 
 	void GUIInputBox::insertChar(CM::UINT32 charIdx, CM::UINT32 charCode)
 	void GUIInputBox::insertChar(CM::UINT32 charIdx, CM::UINT32 charCode)
@@ -746,13 +746,13 @@ namespace BansheeEngine
 
 
 	CM::Rect GUIInputBox::getTextBounds() const
 	CM::Rect GUIInputBox::getTextBounds() const
 	{
 	{
-		Rect textBounds = mBounds;
+		Rect textBounds;
 
 
-		textBounds.x += mStyle->margins.left + mStyle->contentOffset.left;
-		textBounds.y += mStyle->margins.top + mStyle->contentOffset.top;
-		textBounds.width = (UINT32)std::max(0, (INT32)textBounds.width - 
+		textBounds.x = mOffset.x + mStyle->margins.left + mStyle->contentOffset.left;
+		textBounds.y = mOffset.y + mStyle->margins.top + mStyle->contentOffset.top;
+		textBounds.width = (UINT32)std::max(0, (INT32)mWidth - 
 			(INT32)(mStyle->margins.left + mStyle->margins.right + mStyle->contentOffset.left + mStyle->contentOffset.right));
 			(INT32)(mStyle->margins.left + mStyle->margins.right + mStyle->contentOffset.left + mStyle->contentOffset.right));
-		textBounds.height = (UINT32)std::max(0, (INT32)textBounds.height - 
+		textBounds.height = (UINT32)std::max(0, (INT32)mHeight - 
 			(INT32)(mStyle->margins.top + mStyle->margins.bottom + mStyle->contentOffset.top + mStyle->contentOffset.bottom));
 			(INT32)(mStyle->margins.top + mStyle->margins.bottom + mStyle->contentOffset.top + mStyle->contentOffset.bottom));
 
 
 		return textBounds;
 		return textBounds;
@@ -780,14 +780,14 @@ namespace BansheeEngine
 		if(focus)
 		if(focus)
 		{
 		{
 			mImageDesc.texture = mStyle->focused.texture;
 			mImageDesc.texture = mStyle->focused.texture;
-			markAsDirty();
+			markContentAsDirty();
 		}
 		}
 		else
 		else
 		{
 		{
 			mImageDesc.texture = mStyle->normal.texture;
 			mImageDesc.texture = mStyle->normal.texture;
 			hideCaret();
 			hideCaret();
 			clearSelection();
 			clearSelection();
-			markAsDirty();
+			markContentAsDirty();
 		}
 		}
 	}
 	}
 }
 }

+ 1 - 1
BansheeEngine/Source/BsGUILabel.cpp

@@ -100,7 +100,7 @@ namespace BansheeEngine
 	{
 	{
 		mDesc.text = text;
 		mDesc.text = text;
 
 
-		markAsDirty();
+		markContentAsDirty();
 	}
 	}
 
 
 	GUILabel* GUILabel::create(GUIWidget& parent, const WString& text, const GUIElementStyle* style)
 	GUILabel* GUILabel::create(GUIWidget& parent, const WString& text, const GUIElementStyle* style)

+ 4 - 4
BansheeEngine/Source/BsGUIToggle.cpp

@@ -173,7 +173,7 @@ namespace BansheeEngine
 			else
 			else
 				mImageDesc.texture = mStyle->hover.texture;
 				mImageDesc.texture = mStyle->hover.texture;
 
 
-			markAsDirty();
+			markContentAsDirty();
 			return true;
 			return true;
 		}
 		}
 		else if(ev.getType() == GUIMouseEventType::MouseOut)
 		else if(ev.getType() == GUIMouseEventType::MouseOut)
@@ -183,7 +183,7 @@ namespace BansheeEngine
 			else
 			else
 				mImageDesc.texture = mStyle->normal.texture;
 				mImageDesc.texture = mStyle->normal.texture;
 
 
-			markAsDirty();
+			markContentAsDirty();
 			return true;
 			return true;
 		}
 		}
 		else if(ev.getType() == GUIMouseEventType::MouseDown)
 		else if(ev.getType() == GUIMouseEventType::MouseDown)
@@ -193,7 +193,7 @@ namespace BansheeEngine
 			else
 			else
 				mImageDesc.texture = mStyle->active.texture;
 				mImageDesc.texture = mStyle->active.texture;
 
 
-			markAsDirty();
+			markContentAsDirty();
 			return true;
 			return true;
 		}
 		}
 		else if(ev.getType() == GUIMouseEventType::MouseUp)
 		else if(ev.getType() == GUIMouseEventType::MouseUp)
@@ -205,7 +205,7 @@ namespace BansheeEngine
 			else
 			else
 				mImageDesc.texture = mStyle->normal.texture;
 				mImageDesc.texture = mStyle->normal.texture;
 
 
-			markAsDirty();
+			markContentAsDirty();
 			return true;
 			return true;
 		}
 		}
 
 

+ 11 - 3
BansheeEngine/Source/BsGUIWidget.cpp

@@ -187,14 +187,22 @@ namespace BansheeEngine
 
 
 			for(auto& elem : mElements)
 			for(auto& elem : mElements)
 			{
 			{
-				if(elem->_isDirty())
+				if(elem->_isContentDirty())
 				{
 				{
 					dirty = true;
 					dirty = true;
 					elem->updateRenderElements();
 					elem->updateRenderElements();
 				}
 				}
+
+				if(elem->_isMeshDirty())
+				{
+					dirty = true;
+					elem->_markAsClean();
+				}
 			}
 			}
 
 
-			updateBounds();
+			if(dirty)
+				updateBounds();
+
 			return dirty;
 			return dirty;
 		}
 		}
 		else
 		else
@@ -204,7 +212,7 @@ namespace BansheeEngine
 
 
 			for(auto& elem : mElements)
 			for(auto& elem : mElements)
 			{
 			{
-				if(elem->_isDirty())
+				if(elem->_isContentDirty() || elem->_isMeshDirty())
 				{
 				{
 					return true;
 					return true;
 				}
 				}

+ 1 - 1
BansheeEngine/Source/BsGUIWindowFrame.cpp

@@ -214,7 +214,7 @@ namespace BansheeEngine
 		else
 		else
 			mDesc.texture = mStyle->normal.texture;
 			mDesc.texture = mStyle->normal.texture;
 
 
-		markAsDirty();
+		markContentAsDirty();
 	}
 	}
 
 
 	bool GUIWindowFrame::mouseEvent(const GUIMouseEvent& ev)
 	bool GUIWindowFrame::mouseEvent(const GUIMouseEvent& ev)

+ 1 - 1
BansheeEngine/Source/BsGUIWindowMover.cpp

@@ -120,7 +120,7 @@ namespace BansheeEngine
 		else
 		else
 			mDesc.texture = mStyle->normal.texture;
 			mDesc.texture = mStyle->normal.texture;
 
 
-		markAsDirty();
+		markContentAsDirty();
 	}
 	}
 
 
 	bool GUIWindowMover::mouseEvent(const GUIMouseEvent& ev)
 	bool GUIWindowMover::mouseEvent(const GUIMouseEvent& ev)

+ 11 - 1
CamelotUtility/Include/CmRect.h

@@ -10,6 +10,8 @@ namespace CamelotFramework
 		Rect();
 		Rect();
 		Rect(int _x, int _y, int _width, int _height);
 		Rect(int _x, int _y, int _width, int _height);
 
 
+		int x, y, width, height;
+
 		bool contains(const Int2& point) const;
 		bool contains(const Int2& point) const;
 		bool overlaps(const Rect& other) const;
 		bool overlaps(const Rect& other) const;
 		void encapsulate(const Rect& other);
 		void encapsulate(const Rect& other);
@@ -24,6 +26,14 @@ namespace CamelotFramework
 		 */
 		 */
 		void transform(const Matrix4& matrix);
 		void transform(const Matrix4& matrix);
 
 
-		int x, y, width, height;
+		inline bool operator== (const Rect& rhs) const
+		{
+			return x == rhs.x && y == rhs.y && width == rhs.width && height == rhs.height;
+		}
+
+		inline bool operator!= (const Rect& rhs) const
+		{
+			return !(*this == rhs);
+		}
 	};
 	};
 }
 }