Ver Fonte

Ability to move the editor window

Marko Pintera há 12 anos atrás
pai
commit
dba0b8bb86

+ 2 - 0
BansheeEngine/BansheeEngine.vcxproj

@@ -161,6 +161,7 @@
     <ClInclude Include="Include\BsGUITexture.h" />
     <ClInclude Include="Include\BsGUIToggle.h" />
     <ClInclude Include="Include\BsGUIWindowFrame.h" />
+    <ClInclude Include="Include\BsGUIWindowMover.h" />
     <ClInclude Include="Include\BsPrerequisites.h" />
     <ClInclude Include="Include\BsGUIElement.h" />
     <ClInclude Include="Include\BsGUIElementStyle.h" />
@@ -207,6 +208,7 @@
     <ClCompile Include="Source\BsGUIToggle.cpp" />
     <ClCompile Include="Source\BsGUIWidget.cpp" />
     <ClCompile Include="Source\BsGUIWindowFrame.cpp" />
+    <ClCompile Include="Source\BsGUIWindowMover.cpp" />
     <ClCompile Include="Source\BsImageSprite.cpp" />
     <ClCompile Include="Source\BsSceneManager.cpp" />
     <ClCompile Include="Source\BsSprite.cpp" />

+ 6 - 0
BansheeEngine/BansheeEngine.vcxproj.filters

@@ -156,6 +156,9 @@
     <ClInclude Include="Include\BsGUIKeyEvent.h">
       <Filter>Header Files\GUI</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsGUIWindowMover.h">
+      <Filter>Header Files\GUI</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsGUIElement.cpp">
@@ -260,5 +263,8 @@
     <ClCompile Include="Source\BsGUIKeyEvent.cpp">
       <Filter>Source Files\GUI</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsGUIWindowMover.cpp">
+      <Filter>Source Files\GUI</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 57 - 0
BansheeEngine/Include/BsGUIWindowMover.h

@@ -0,0 +1,57 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "BsGUIElement.h"
+#include "BsImageSprite.h"
+
+namespace BansheeEngine
+{
+	class BS_EXPORT GUIWindowMover : public GUIElement
+	{
+	public:
+		static const CM::String& getGUITypeName();
+
+		static GUIWindowMover* create(GUIWidget& parent, const GUIElementStyle* style = nullptr);
+		static GUIWindowMover* create(GUIWidget& parent, const GUILayoutOptions& layoutOptions, const GUIElementStyle* style = nullptr);
+
+		void setFocused(bool focused);
+	protected:
+		~GUIWindowMover();
+
+		/**
+		 * @copydoc GUIElement::getNumRenderElements()
+		 */
+		virtual CM::UINT32 getNumRenderElements() const;
+
+		/**
+		 * @copydoc GUIElement::getMaterial()
+		 */
+		virtual const CM::HMaterial& getMaterial(CM::UINT32 renderElementIdx) const;
+
+		/**
+		 * @copydoc GUIElement::getNumQuads()
+		 */
+		virtual CM::UINT32 getNumQuads(CM::UINT32 renderElementIdx) const;
+
+		/**
+		 * @copydoc GUIElement::fillBuffer()
+		 */
+		virtual void fillBuffer(CM::UINT8* vertices, CM::UINT8* uv, CM::UINT32* indices, CM::UINT32 startingQuad, 
+			CM::UINT32 maxNumQuads, CM::UINT32 vertexStride, CM::UINT32 indexStride, CM::UINT32 renderElementIdx) const;
+
+		/**
+		 * @copydoc GUIElement::updateRenderElementsInternal()
+		 */
+		virtual void updateRenderElementsInternal();
+
+		virtual CM::UINT32 _getOptimalWidth() const;
+		virtual CM::UINT32 _getOptimalHeight() const;
+	private:
+		ImageSprite* mImageSprite;
+		IMAGE_SPRITE_DESC mDesc;
+
+		GUIWindowMover(GUIWidget& parent, const GUIElementStyle* style, const GUILayoutOptions& layoutOptions);
+
+		virtual bool mouseEvent(const GUIMouseEvent& ev);
+	};
+}

+ 1 - 0
BansheeEngine/Include/BsPrerequisites.h

@@ -34,6 +34,7 @@ namespace BansheeEngine
 	class GUITexture;
 	class GUIToggle;
 	class GUIWindowFrame;
+	class GUIWindowMover;
 	class GUIInputBox;
 	class GUISkin;
 	struct GUIElementStyle;

+ 142 - 0
BansheeEngine/Source/BsGUIWindowMover.cpp

@@ -0,0 +1,142 @@
+#include "BsGUIWindowMover.h"
+#include "CmApplication.h"
+#include "CmTexture.h"
+#include "BsGUIWidget.h"
+#include "BsGUISkin.h"
+#include "BsSpriteTexture.h"
+#include "BsGUILayoutOptions.h"
+#include "BsGUIMouseEvent.h"
+
+using namespace CamelotFramework;
+
+namespace BansheeEngine
+{
+	const String& GUIWindowMover::getGUITypeName()
+	{
+		static String name = "WindowMover";
+		return name;
+	}
+
+	GUIWindowMover::GUIWindowMover(GUIWidget& parent, const GUIElementStyle* style, const GUILayoutOptions& layoutOptions)
+		:GUIElement(parent, style, layoutOptions)
+	{
+		mImageSprite = cm_new<ImageSprite, PoolAlloc>();
+
+		mDesc.texture = mStyle->normal.texture;
+
+		if(mDesc.texture != nullptr)
+		{
+			mDesc.width = mDesc.texture->getTexture()->getWidth();
+			mDesc.height = mDesc.texture->getTexture()->getHeight();
+		}
+
+		mDesc.borderLeft = mStyle->border.left;
+		mDesc.borderRight = mStyle->border.right;
+		mDesc.borderTop = mStyle->border.top;
+		mDesc.borderBottom = mStyle->border.bottom;
+	}
+
+	GUIWindowMover::~GUIWindowMover()
+	{
+		cm_delete<PoolAlloc>(mImageSprite);
+	}
+
+	GUIWindowMover* GUIWindowMover::create(GUIWidget& parent, const GUIElementStyle* style)
+	{
+		if(style == nullptr)
+		{
+			const GUISkin* skin = parent.getSkin();
+			style = skin->getStyle(getGUITypeName());
+		}
+
+		return new (cm_alloc<GUIWindowMover, PoolAlloc>()) GUIWindowMover(parent, style, getDefaultLayoutOptions(style));
+	}
+
+	GUIWindowMover* GUIWindowMover::create(GUIWidget& parent, const GUILayoutOptions& layoutOptions, const GUIElementStyle* style)
+	{
+		if(style == nullptr)
+		{
+			const GUISkin* skin = parent.getSkin();
+			style = skin->getStyle(getGUITypeName());
+		}
+
+		return new (cm_alloc<GUIWindowMover, PoolAlloc>()) GUIWindowMover(parent, style, layoutOptions);
+	}
+
+	UINT32 GUIWindowMover::getNumRenderElements() const
+	{
+		return mImageSprite->getNumRenderElements();
+	}
+
+	const HMaterial& GUIWindowMover::getMaterial(UINT32 renderElementIdx) const
+	{
+		return mImageSprite->getMaterial(renderElementIdx);
+	}
+
+	UINT32 GUIWindowMover::getNumQuads(UINT32 renderElementIdx) const
+	{
+		return mImageSprite->getNumQuads(renderElementIdx);
+	}
+
+	void GUIWindowMover::updateRenderElementsInternal()
+	{		
+		mDesc.offset = mOffset;
+		mDesc.width = mWidth;
+		mDesc.height = mHeight;
+		mDesc.clipRect = mClipRect;
+
+		mImageSprite->update(mDesc);
+		mBounds = mImageSprite->getBounds();
+	}
+
+	UINT32 GUIWindowMover::_getOptimalWidth() const
+	{
+		if(mDesc.texture != nullptr)
+		{
+			return mDesc.texture->getTexture()->getWidth();
+		}
+
+		return 0;
+	}
+
+	UINT32 GUIWindowMover::_getOptimalHeight() const
+	{
+		if(mDesc.texture != nullptr)
+		{
+			return mDesc.texture->getTexture()->getHeight();
+		}
+
+		return 0;
+	}
+
+	void GUIWindowMover::fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, UINT32 maxNumQuads, 
+		UINT32 vertexStride, UINT32 indexStride, UINT32 renderElementIdx) const
+	{
+		mImageSprite->fillBuffer(vertices, uv, indices, startingQuad, maxNumQuads, vertexStride, indexStride, renderElementIdx);
+	}
+
+	void GUIWindowMover::setFocused(bool focused)
+	{
+		if(focused)
+			mDesc.texture = mStyle->focused.texture;
+		else
+			mDesc.texture = mStyle->normal.texture;
+
+		markAsDirty();
+	}
+
+	bool GUIWindowMover::mouseEvent(const GUIMouseEvent& ev)
+	{
+		if(ev.getType() == GUIMouseEventType::MouseDown)
+		{
+			RenderWindow* window = _getParentWidget().getOwnerWindow();
+			RenderWindowPtr windowPtr = std::static_pointer_cast<RenderWindow>(window->getThisPtr());
+
+			gMainCA().startMove(windowPtr);
+
+			return true;
+		}
+
+		return false;
+	}
+}

+ 4 - 3
CamelotClient/BsGUITabbedTitleBar.cpp

@@ -4,6 +4,7 @@
 #include "BsGUITexture.h"
 #include "BsGUIButton.h"
 #include "BsGUIToggle.h"
+#include "BsGUIWindowMover.h"
 #include "BsEngineGUI.h"
 #include "CmMath.h"
 
@@ -31,7 +32,7 @@ namespace BansheeEditor
 	void TabbedTitleBar::insertTab(UINT32 idx, const CM::String& name)
 	{
 		GUIToggle* newTabToggle = GUIToggle::create(*this, toWString(name), EngineGUI::instance().getSkin().getStyle("TabbedBarBtn"));
-		GUITexture* newDragDropElement = GUITexture::create(*this, GUIImageScaleMode::StretchToFit, EngineGUI::instance().getSkin().getStyle("TabbedBarDropArea"));
+		GUIWindowMover* newDragDropElement = GUIWindowMover::create(*this, EngineGUI::instance().getSkin().getStyle("TabbedBarDropArea"));
 
 		idx = Math::Clamp(idx, 0U, (UINT32)mTabButtons.size());
 
@@ -61,14 +62,14 @@ namespace BansheeEditor
 		GUIWidget::initialize(target, ownerWindow);
 
 		GUIArea* backgroundArea = GUIArea::create(*this, 0, 1, 0, 13, 500);
-		GUITexture* titleBarBg = GUITexture::create(*this, GUIImageScaleMode::StretchToFit, getSkin()->getStyle("TitleBarBackground"));
+		GUIWindowMover* titleBarBg = GUIWindowMover::create(*this, getSkin()->getStyle("TitleBarBackground"));
 		GUIFixedSpace& space1 = backgroundArea->getLayout().addSpace(1);
 		backgroundArea->getLayout().addElement(titleBarBg);
 		GUIFixedSpace& space2 = backgroundArea->getLayout().addSpace(1);
 
 		mMainArea = GUIArea::create(*this, 0, 1, 0, 13, 499);
 
-		GUITexture* dragDropElement = GUITexture::create(*this, GUILayoutOptions::expandableX(13, 20), GUIImageScaleMode::StretchToFit, getSkin()->getStyle("TabbedBarDropArea"));
+		GUIWindowMover* dragDropElement = GUIWindowMover::create(*this, GUILayoutOptions::expandableX(13, 20), getSkin()->getStyle("TabbedBarDropArea"));
 		mLastDropElement = dragDropElement;
 
 		mMinBtn = GUIButton::create(*this, L"", getSkin()->getStyle("WinMinimizeBtn"));

+ 2 - 2
CamelotClient/BsGUITabbedTitleBar.h

@@ -22,14 +22,14 @@ namespace BansheeEditor
 		boost::signal<void(CM::UINT32)> onTabAdded;
 		boost::signal<void(CM::UINT32)> onTabRemoved;
 	protected:
-		CM::Vector<BS::GUITexture*>::type mDragDropElements;
+		CM::Vector<BS::GUIWindowMover*>::type mDragDropElements;
 		CM::Vector<BS::GUIToggle*>::type mTabButtons;
 
 		BS::GUIArea* mMainArea;
 		BS::GUILayout* mMainLayout;
 		BS::GUIButton* mMinBtn;
 		BS::GUIButton* mCloseBtn;
-		BS::GUITexture* mLastDropElement;
+		BS::GUIWindowMover* mLastDropElement;
 
 		virtual void update();
 

+ 10 - 0
CamelotCore/Include/CmCoreThreadAccessor.h

@@ -252,6 +252,16 @@ namespace CamelotFramework
 			mCommandQueue->queue(boost::bind(&RenderWindow::endResize, renderWindow.get()));
 		}
 
+		void startMove(RenderWindowPtr& renderWindow)
+		{
+			mCommandQueue->queue(boost::bind(&RenderWindow::startMove, renderWindow.get()));
+		}
+
+		void endMove(RenderWindowPtr& renderWindow)
+		{
+			mCommandQueue->queue(boost::bind(&RenderWindow::endMove, renderWindow.get()));
+		}
+
 		/**
 		 * @brief	Makes all the currently queued commands available to the core thread. They will be executed
 		 * 			as soon as the core thread is ready.

+ 3 - 0
CamelotCore/Include/CmRenderWindow.h

@@ -195,6 +195,9 @@ namespace CamelotFramework
 		virtual void startResize(WindowResizeDirection direction) = 0;
 		virtual void endResize() = 0;
 
+		virtual void startMove() = 0;
+		virtual void endMove() = 0;
+
 		virtual void destroy();
 
 		static RenderWindowPtr create(RENDER_WINDOW_DESC& desc, RenderWindowPtr parentWindow = nullptr);

+ 3 - 0
CamelotD3D11RenderSystem/Include/CmD3D11RenderWindow.h

@@ -78,6 +78,9 @@ namespace CamelotFramework
 		void startResize(WindowResizeDirection direction);
 		void endResize();
 
+		void startMove();
+		void endMove();
+
 		/**
 		 * @copydoc RenderWindow::reposition
 		 */

+ 10 - 0
CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp

@@ -589,6 +589,16 @@ namespace CamelotFramework
 
 	}
 
+	void D3D11RenderWindow::startMove()
+	{
+		SendMessage(mHWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
+	}
+
+	void D3D11RenderWindow::endMove()
+	{
+
+	}
+
 	void D3D11RenderWindow::_windowMovedOrResized()
 	{
 		THROW_IF_NOT_CORE_THREAD;

+ 3 - 0
CamelotD3D9Renderer/Include/CmD3D9RenderWindow.h

@@ -106,6 +106,9 @@ namespace CamelotFramework
 		void startResize(WindowResizeDirection direction);
 		void endResize();
 
+		void startMove();
+		void endMove();
+
 		/**
 		 * @copydoc RenderWindow::_windowMovedOrResized
 		 */

+ 10 - 0
CamelotD3D9Renderer/Source/CmD3D9RenderWindow.cpp

@@ -514,6 +514,16 @@ namespace CamelotFramework
 
 	}
 
+	void D3D9RenderWindow::startMove()
+	{
+		SendMessage(mHWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
+	}
+
+	void D3D9RenderWindow::endMove()
+	{
+
+	}
+
 	void D3D9RenderWindow::_windowMovedOrResized()
 	{
 		THROW_IF_NOT_CORE_THREAD;

+ 3 - 0
CamelotGLRenderer/Include/CmWin32Window.h

@@ -111,6 +111,9 @@ namespace CamelotFramework
 		void startResize(WindowResizeDirection direction);
 		void endResize();
 
+		void startMove();
+		void endMove();
+
 		HWND _getWindowHandle() const { return mHWnd; }
 		HDC _getHDC() const { return mHDC; }
 		

+ 10 - 0
CamelotGLRenderer/Source/CmWin32Window.cpp

@@ -763,6 +763,16 @@ namespace CamelotFramework {
 
 	}
 
+	void Win32Window::startMove()
+	{
+		SendMessage(mHWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
+	}
+
+	void Win32Window::endMove()
+	{
+
+	}
+
 	void Win32Window::_windowMovedOrResized()
 	{
 		if (!mHWnd || IsIconic(mHWnd))

+ 0 - 4
TODO.txt

@@ -12,10 +12,6 @@ I call waitUntilLoaded too many times. Sometimes 5-6 times in a single function.
 GUIWidget::updateMeshes leaks. If I leave the game running I can see memory continously going up
 
 IMMEDIATE:
- - Resizing twice in a row doesn't work because ButtonUp event apparently doesn't register
- - Add startMove/endMove
- - It's possible to resize smaller than 0 and cause an exception
- - Cursor doesn't stay inside the window we're resizing, window seems to resize slower than the cursor moves
  - Update debug camera so it uses callbacks
  - Add support for diacritical marks
  - onMovedOrResized is still used by Viewport