فهرست منبع

Edit Support for GuiFrameSetCtrl

Added some edit time support for the Frame Set. More is probably needed, but at a minimum you can set up your frames and then add controls to it.
Peter Robinson 2 سال پیش
والد
کامیت
ac3481479d

+ 162 - 8
engine/source/gui/containers/guiFrameSetCtrl.cc

@@ -29,6 +29,8 @@
 #include "graphics/dgl.h"
 #include "gui/containers/guiTabBookCtrl.h"
 #include "gui/containers/guiTabPageCtrl.h"
+#include "gui/editor/guiEditCtrl.h"
+#include "collection/vector.h"
 
 #include "guiFrameSetCtrl_ScriptBinding.h"
 
@@ -60,6 +62,26 @@ void GuiFrameSetCtrl::Frame::resize(const Point2I& newPosition, const Point2I& n
 		}
 		control->resize(newPosition, newExtent);
 	}
+	if (!child1 && !child2 && owner->isEditMode())
+	{
+		if (extent.x > (3 * owner->minSize))
+		{
+			spliterRect1.set(localPosition.x + ((extent.x - owner->mDividerThickness) / 2), localPosition.y, owner->mDividerThickness, extent.y);
+		}
+		else
+		{
+			spliterRect1.set(0, 0, 0, 0);
+		}
+
+		if (extent.y > (3 * owner->minSize))
+		{
+			spliterRect2.set(localPosition.x, localPosition.y + ((extent.y - owner->mDividerThickness) / 2), extent.x, owner->mDividerThickness);
+		}
+		else
+		{
+			spliterRect2.set(0, 0, 0, 0);
+		}
+	}
 	else if (child1 && child2)
 	{
 		S32 spaceX = isVertical ? newExtent.x : newExtent.x - owner->mDividerThickness;
@@ -220,7 +242,7 @@ GuiFrameSetCtrl::Frame* GuiFrameSetCtrl::Frame::findFrameWithCtrl(GuiControl* ct
 GuiFrameSetCtrl::Frame* GuiFrameSetCtrl::Frame::findFrameWithPoint(const Point2I& point)
 {
 	//Point is local to the frame.
-	if (control)
+	if (!child1 && !child2)
 	{
 		return this;
 	}
@@ -231,20 +253,70 @@ GuiFrameSetCtrl::Frame* GuiFrameSetCtrl::Frame::findFrameWithPoint(const Point2I
 
 		Point2I pos2 = isVertical ? Point2I(x, child1->extent.y + owner->mDividerThickness) : Point2I(child1->extent.x + owner->mDividerThickness, y);
 
-
 		if ((isVertical && y < child1->extent.y) || (!isVertical && x < child1->extent.x))
 		{
 			return child1->findFrameWithPoint(point);
 		}
 		else if ((isVertical && y > pos2.y && y < (pos2.y + child2->extent.y)) || (!isVertical && x > pos2.x && x < (pos2.x + child2->extent.x)))
 		{
-			Point2I pt = Point2I(x - pos2.x, y - pos2.y);
+			Point2I pt = isVertical ? Point2I(x, y - pos2.y) : Point2I(x - pos2.x, y);
+
 			return child2->findFrameWithPoint(pt);
 		}
 	}
 	return nullptr;//This will happen if the mouse is over a divider.
 }
 
+void GuiFrameSetCtrl::Frame::editRender(const Point2I& cursorPt, const F32 fade)
+{
+	//cursorPt is local to owner
+	if (!child1 && !child2)
+	{
+		//Show the frame
+		RectI localRect = RectI(localPosition, extent);
+		Point2I pos = localPosition;
+		RectI rect = RectI(owner->localToGlobalCoord(pos), extent);
+		GuiEditCtrl* edit = GuiControl::smEditorHandle;
+		ColorI border = edit->getEditorColor();
+		if (!localRect.pointInRect(cursorPt))
+		{
+			border.alpha = (150 * fade);
+		}
+		dglDrawRect(rect, border);
+		ColorI fill = ColorI(border);
+		fill.alpha = (40 * fade);
+		dglDrawRectFill(rect, fill);
+
+		U8 divThickness = owner->mDividerThickness;
+
+		fill.alpha = (10 * fade);
+		if(spliterRect1.pointInRect(cursorPt))
+		{
+			fill.alpha = (200 * fade);
+		}
+		RectI globalSpliter1 = RectI(owner->localToGlobalCoord(spliterRect1.point), spliterRect1.extent);
+		dglDrawRectFill(globalSpliter1, fill);
+
+		fill.alpha = (10 * fade);
+		if (spliterRect2.pointInRect(cursorPt) && !spliterRect1.pointInRect(cursorPt))
+		{
+			fill.alpha = (200 * fade);
+		}
+		RectI globalSpliter2 = RectI(owner->localToGlobalCoord(spliterRect2.point), spliterRect2.extent);
+		dglDrawRectFill(globalSpliter2, fill);
+	}
+
+	if (child1)
+	{
+		child1->editRender(cursorPt, fade);
+	}
+
+	if (child2)
+	{
+		child2->editRender(cursorPt, fade);
+	}
+}
+
 
 //------------------------------------------------------------------------------
 
@@ -296,7 +368,7 @@ void GuiFrameSetCtrl::initPersistFields()
 {
 	Parent::initPersistFields();
 
-	addField("DividerThickness", TypeS32, Offset(mDividerThickness, GuiFrameSetCtrl));
+	addField("DividerThickness", TypeS8, Offset(mDividerThickness, GuiFrameSetCtrl));
 	addField("dropButtonProfile", TypeGuiProfile, Offset(mDropButtonProfile, GuiFrameSetCtrl));
 	addField("leftRightCursor", TypeGuiCursor, Offset(mLeftRightCursor, GuiFrameSetCtrl));
 	addField("upDownCursor", TypeGuiCursor, Offset(mUpDownCursor, GuiFrameSetCtrl));
@@ -416,7 +488,6 @@ void GuiFrameSetCtrl::onChildAdded(GuiControl* child)
 	{
 		child->setVertSizing(vertResizeTop);
 	}
-	resize(getPosition(), getExtent());
 
 	Parent::onChildAdded(child);
 
@@ -429,7 +500,7 @@ void GuiFrameSetCtrl::onChildAdded(GuiControl* child)
 			emptyFrame->control = child;
 		}
 	}
-	resize(getPosition(), getExtent());
+	//resize(getPosition(), getExtent());
 }
 
 void GuiFrameSetCtrl::onChildRemoved(GuiControl* child)
@@ -558,12 +629,26 @@ void GuiFrameSetCtrl::onPreRender()
 	SimSet::iterator i;
 	for(i = begin(); i < end(); i++)
 	{
-		GuiTabBookCtrl* book = static_cast<GuiTabBookCtrl*>(*i);
-		if (book->mIsFrameSetGenerated && book->size() == 0)
+		GuiTabBookCtrl* book = dynamic_cast<GuiTabBookCtrl*>(*i);
+		if (book && book->mIsFrameSetGenerated && book->size() == 0)
 		{
 			book->deleteObject();
 		}
 	}
+
+	if (isEditMode())
+	{
+		GuiCanvas* root = getRoot();
+		GuiEditCtrl* edit = GuiControl::smEditorHandle;
+		if (root && edit)
+		{
+			Point2I cursorPt = globalToLocalCoord(root->getCursorPos());
+			if (mBounds.pointInRect(cursorPt))
+			{
+				mHitDivider = mRootFrame.findHitDivider(cursorPt);
+			}
+		}
+	}
 }
 
 void GuiFrameSetCtrl::onRender(Point2I offset, const RectI& updateRect)
@@ -587,6 +672,25 @@ void GuiFrameSetCtrl::onRender(Point2I offset, const RectI& updateRect)
 	{
 		mOldHitDivider = nullptr;
 	}
+
+	if (isEditMode())
+	{
+		GuiCanvas* root = getRoot();
+		GuiEditCtrl* edit = GuiControl::smEditorHandle;
+		if(root && edit)
+		{
+			Point2I cursorPt = globalToLocalCoord(root->getCursorPos());
+			RectI visBounds = RectI(mBounds);
+			const S32 fadeDist = 140;
+			visBounds.inset(-fadeDist, -fadeDist);
+			if (visBounds.pointInRect(cursorPt) && isEditSelected())
+			{
+				visBounds.inset(fadeDist, fadeDist);
+				F32 fade = getMin(1.0, getMax(0.0, 1.0 - ((F32)visBounds.distanceToRect(cursorPt) / (F32)fadeDist)));
+				mRootFrame.editRender(cursorPt, fade);
+			}
+		}
+	}
 }
 
 void GuiFrameSetCtrl::onTouchMove(const GuiEvent& event)
@@ -698,6 +802,56 @@ void GuiFrameSetCtrl::getCursor(GuiCursor*& cursor, bool& showCursor, const GuiE
 	}
 }
 
+bool GuiFrameSetCtrl::onMouseDownEditor(const GuiEvent& event, const Point2I& offset)
+{
+	Point2I cursorPt = globalToLocalCoord(event.mousePoint);
+	Frame* frame = mRootFrame.findFrameWithPoint(cursorPt);
+
+	if(frame && isEditSelected())
+	{
+		if (frame->spliterRect1.pointInRect(cursorPt))
+		{
+			splitFrame(frame, GuiDirection::Left);
+			setFrameSize(frame->child1->id, (frame->extent.x - mDividerThickness) / 2);
+			return true;
+		}
+		else if (frame->spliterRect2.pointInRect(cursorPt))
+		{
+			splitFrame(frame, GuiDirection::Up);
+			setFrameSize(frame->child1->id, (frame->extent.y - mDividerThickness) / 2);
+			return true;
+		}
+	}
+	frame = mRootFrame.findHitDivider(cursorPt);
+	if (frame)
+	{
+		onTouchDown(event);
+		return true;
+	}
+
+	return Parent::onMouseDownEditor(event, offset);
+}
+
+bool GuiFrameSetCtrl::onMouseUpEditor(const GuiEvent& event, const Point2I& offset)
+{
+	if (mDepressed)
+	{
+		onTouchUp(event);
+		return true;
+	}
+	return false;
+}
+
+bool GuiFrameSetCtrl::onMouseDraggedEditor(const GuiEvent& event, const Point2I& offset)
+{
+	if (mDepressed)
+	{
+		onTouchDragged(event);
+		return true;
+	}
+	return false;
+}
+
 void GuiFrameSetCtrl::renderDropOptions(GuiWindowCtrl* window)
 {
 	Point2I cursorPt = Point2I(0, 0);

+ 9 - 1
engine/source/gui/containers/guiFrameSetCtrl.h

@@ -38,7 +38,8 @@ public:
 		Frame(GuiFrameSetCtrl* theOwner, Frame* theParent) : owner(theOwner), parent(theParent), child1(nullptr), child2(nullptr), 
 			control(nullptr), isVertical(true), id(1), extent(Point2I(100, 100)), dividerRect(RectI()),
 			localPosition(Point2I(0, 0)), mLeftButtonRect(RectI()), mRightButtonRect(RectI()), mCenterButtonRect(RectI()),
-			mTopButtonRect(RectI()), mBottomButtonRect(RectI()), isAnchored(true), hasLeftRightButtons(false), hasTopBottomButtons(false) { }
+			mTopButtonRect(RectI()), mBottomButtonRect(RectI()), isAnchored(true), hasLeftRightButtons(false), 
+			hasTopBottomButtons(false), spliterRect1(RectI()), spliterRect2(RectI()) { }
 		virtual ~Frame() { }
 		void deleteChildren();
 
@@ -48,6 +49,8 @@ public:
 		Point2I localPosition;
 		bool isAnchored;
 		RectI dividerRect;
+		RectI spliterRect1;//shown in edit mode
+		RectI spliterRect2;//shown in edit mode
 		RectI mLeftButtonRect;
 		RectI mRightButtonRect;
 		RectI mTopButtonRect;
@@ -71,6 +74,7 @@ public:
 		Frame* findHitDivider(const Point2I& position);
 		Frame* findFrameWithCtrl(GuiControl* ctrl);
 		Frame* findFrameWithPoint(const Point2I& point);
+		void editRender(const Point2I& cursorPt, const F32 fade);
 	};
 	Frame mRootFrame;
 	Frame* mHitDivider;
@@ -120,6 +124,10 @@ public:
 	void onTouchUp(const GuiEvent& event);
 	void getCursor(GuiCursor*& cursor, bool& showCursor, const GuiEvent& lastGuiEvent);
 
+	bool onMouseDownEditor(const GuiEvent& event, const Point2I& offset);
+	bool onMouseUpEditor(const GuiEvent& event, const Point2I& offset);
+	bool onMouseDraggedEditor(const GuiEvent& event, const Point2I& offset);
+
 	void setDropButtonProfile(GuiControlProfile* prof);
 	void setTabBookProfile(GuiControlProfile* prof);
 	void setTabProfile(GuiControlProfile* prof);

+ 3 - 3
engine/source/gui/containers/guiScrollCtrl.cc

@@ -820,7 +820,7 @@ void GuiScrollCtrl::onMouseWheelDown(const GuiEvent &event)
       parent->onMouseWheelDown(event);
 }
 
-bool GuiScrollCtrl::onMouseDownEditor(const GuiEvent& event, Point2I offset)
+bool GuiScrollCtrl::onMouseDownEditor(const GuiEvent& event, const Point2I& offset)
 {
 	Point2I curMousePos = globalToLocalCoord(event.mousePoint);
 	Region hitRegion = findHitRegion(curMousePos);
@@ -833,7 +833,7 @@ bool GuiScrollCtrl::onMouseDownEditor(const GuiEvent& event, Point2I offset)
 	return false;
 }
 
-bool GuiScrollCtrl::onMouseUpEditor(const GuiEvent& event, Point2I offset)
+bool GuiScrollCtrl::onMouseUpEditor(const GuiEvent& event, const Point2I& offset)
 {
 	Point2I curMousePos = globalToLocalCoord(event.mousePoint);
 	Region hitRegion = findHitRegion(curMousePos);
@@ -846,7 +846,7 @@ bool GuiScrollCtrl::onMouseUpEditor(const GuiEvent& event, Point2I offset)
 	return false;
 }
 
-bool GuiScrollCtrl::onMouseDraggedEditor(const GuiEvent& event, Point2I offset)
+bool GuiScrollCtrl::onMouseDraggedEditor(const GuiEvent& event, const Point2I& offset)
 {
 	Point2I curMousePos = globalToLocalCoord(event.mousePoint);
 	Region hitRegion = findHitRegion(curMousePos);

+ 3 - 3
engine/source/gui/containers/guiScrollCtrl.h

@@ -159,9 +159,9 @@ public:
    virtual void onTouchLeave(const GuiEvent &event);
    virtual void onMouseWheelUp(const GuiEvent &event);
    virtual void onMouseWheelDown(const GuiEvent &event);
-   virtual bool onMouseDownEditor(const GuiEvent& event, Point2I offset);
-   virtual bool onMouseUpEditor(const GuiEvent& event, Point2I offset);
-   virtual bool onMouseDraggedEditor(const GuiEvent& event, Point2I offset);
+   virtual bool onMouseDownEditor(const GuiEvent& event, const Point2I& offset);
+   virtual bool onMouseUpEditor(const GuiEvent& event, const Point2I& offset);
+   virtual bool onMouseDraggedEditor(const GuiEvent& event, const Point2I& offset);
 
    virtual bool onWake();
    virtual void onSleep();

+ 1 - 1
engine/source/gui/containers/guiTabBookCtrl.cc

@@ -336,7 +336,7 @@ void GuiTabBookCtrl::onTouchUp(const GuiEvent& event)
 	Parent::onTouchUp(event);
 }
 
-bool GuiTabBookCtrl::onMouseDownEditor(const GuiEvent &event, Point2I offset)
+bool GuiTabBookCtrl::onMouseDownEditor(const GuiEvent &event, const Point2I& offset)
 {
    bool handled = false;
    Point2I localMouse = globalToLocalCoord( event.mousePoint );

+ 1 - 1
engine/source/gui/containers/guiTabBookCtrl.h

@@ -247,7 +247,7 @@ private:
    void onTouchLeave(const GuiEvent &event);
    void onTouchDragged(const GuiEvent& event);
    void onTouchUp(const GuiEvent& event);
-   virtual bool onMouseDownEditor(const GuiEvent &event, Point2I offset);
+   bool onMouseDownEditor(const GuiEvent &event, const Point2I& offset);
    /// @}
 };
 

+ 1 - 1
engine/source/gui/containers/guiTabPageCtrl.cc

@@ -37,7 +37,7 @@ GuiTabPageCtrl::GuiTabPageCtrl(void)
    mIsContainer = true;
 }
 
-bool GuiTabPageCtrl::onMouseDownEditor(const GuiEvent &event, Point2I offset )
+bool GuiTabPageCtrl::onMouseDownEditor(const GuiEvent &event, const Point2I& offset )
 {
    // This shouldn't be called if it's not design time, but check just incase
    if ( GuiControl::smDesignTime )

+ 1 - 1
engine/source/gui/containers/guiTabPageCtrl.h

@@ -33,7 +33,7 @@ class GuiTabPageCtrl : public GuiControl
    public:
       GuiTabPageCtrl();
       DECLARE_CONOBJECT(GuiTabPageCtrl);
-      bool onMouseDownEditor(const GuiEvent &event, Point2I offset );   ///< Called when a mouseDown event occurs and the GUI editor is active
+      bool onMouseDownEditor(const GuiEvent &event, const Point2I& offset );   ///< Called when a mouseDown event occurs and the GUI editor is active
 
       S32 getTabIndex(void) { return mTabIndex; }  ///< Get the tab index of this control
 

+ 10 - 6
engine/source/gui/editor/guiEditCtrl.cc

@@ -615,7 +615,8 @@ void GuiEditCtrl::onRightMouseDown(const GuiEvent &event)
    //Design time mouse events
    GuiEvent designEvent = event;
    designEvent.mousePoint = mLastMousePos;
-   hitCtrl->onRightMouseDownEditor( designEvent, localToGlobalCoord( Point2I(0,0) ) );
+   Point2I localOffset = localToGlobalCoord( Point2I(0,0) );
+   hitCtrl->onRightMouseDownEditor( designEvent, localOffset );
 
 }
 void GuiEditCtrl::select(GuiControl *ctrl)
@@ -730,8 +731,9 @@ void GuiEditCtrl::onTouchDown(const GuiEvent &event)
    //find the control we clicked
    ctrl = mContentControl->findHitControl(mLastMousePos, mCurrentAddSet->mLayer);
 
-   bool handledEvent = ctrl->onMouseDownEditor( event, localToGlobalCoord( Point2I(0,0) ) );
-   if( handledEvent == true )
+   Point2I editorOffset = localToGlobalCoord(Point2I(0,0));
+   bool handledEvent = ctrl->onMouseDownEditor( event, editorOffset );
+   if( handledEvent )
    {
       // The Control handled the event and requested the edit ctrl
       // *NOT* act on it.  The dude abides.
@@ -857,7 +859,8 @@ void GuiEditCtrl::onTouchUp(const GuiEvent &event)
    //find the control we clicked
    GuiControl *ctrl = mContentControl->findHitControl(mLastMousePos, mCurrentAddSet->mLayer);
 
-   bool handledEvent = ctrl->onMouseUpEditor( event, localToGlobalCoord( Point2I(0,0) ) );
+   Point2I localOffset = localToGlobalCoord( Point2I(0,0) );
+   bool handledEvent = ctrl->onMouseUpEditor( event, localOffset );
    if( handledEvent == true )
    {
       // The Control handled the event and requested the edit ctrl
@@ -923,8 +926,9 @@ void GuiEditCtrl::onTouchDragged(const GuiEvent &event)
    //find the control we clicked
    GuiControl *ctrl = mContentControl->findHitControl(mousePoint, mCurrentAddSet->mLayer);
 
-   bool handledEvent = ctrl->onMouseDraggedEditor( event, localToGlobalCoord( Point2I(0,0) ) );
-   if( handledEvent == true )
+   Point2I dragOffset = localToGlobalCoord( Point2I(0,0) );
+   bool handledEvent = ctrl->onMouseDraggedEditor( event, dragOffset );
+   if( handledEvent )
    {
       // The Control handled the event and requested the edit ctrl
       // *NOT* act on it.  The dude abides.

+ 32 - 1
engine/source/gui/guiControl.cc

@@ -2327,8 +2327,39 @@ bool GuiControl::isEditMode()
 		{
 			return parent->isEditMode();
 		}
-		return false;
 	}
+	return false;
+}
+
+bool GuiControl::isEditSelected()
+{
+	if (smDesignTime && smEditorHandle)
+	{
+		GuiEditCtrl* edit = GuiControl::smEditorHandle;
+		
+		bool selected = false;
+		auto list = edit->getSelected();
+		for (auto i = list->begin(); i < list->end(); i++)
+		{
+			GuiControl* ctrl = dynamic_cast<GuiControl*>(*i);
+			if (ctrl && ctrl == this)
+			{
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+bool GuiControl::onMouseDownEditor(const GuiEvent& event, const Point2I& offset)
+{
+	GuiEditCtrl* edit = GuiControl::smEditorHandle;
+	GuiControl* parent = getParent();
+	if (this != edit->getRoot() && parent)
+	{
+		return parent->onMouseDownEditor(event, offset);
+	}
+	return false;
 }
 
 //--------------------------------------------------------------------

+ 5 - 4
engine/source/gui/guiControl.h

@@ -160,6 +160,7 @@ public:
     /// @}
 
 	virtual bool isEditMode();
+	virtual bool isEditSelected();
 
     /// @name Keyboard Input
     /// @{
@@ -619,22 +620,22 @@ public:
     /// Called when a mouseDown event occurs on a control and the GUI editor is active
     /// @param   event   the GuiEvent which caused the call to this function
     /// @param   offset   the offset which is representative of the units x and y that the editor takes up on screen
-    virtual bool onMouseDownEditor(const GuiEvent &event, Point2I offset) { return false; };
+    virtual bool onMouseDownEditor(const GuiEvent &event, const Point2I& offset);
 
     /// Called when a mouseUp event occurs on a control and the GUI editor is active
     /// @param   event   the GuiEvent which caused the call to this function
     /// @param   offset   the offset which is representative of the units x and y that the editor takes up on screen
-    virtual bool onMouseUpEditor(const GuiEvent &event, Point2I offset) { return false; };
+    virtual bool onMouseUpEditor(const GuiEvent &event, const Point2I& offset) { return false; };
 
     /// Called when a rightMouseDown event occurs on a control and the GUI editor is active
     /// @param   event   the GuiEvent which caused the call to this function
     /// @param   offset   the offset which is representative of the units x and y that the editor takes up on screen
-    virtual bool onRightMouseDownEditor(const GuiEvent &event, Point2I offset) { return false; };
+    virtual bool onRightMouseDownEditor(const GuiEvent &event, const Point2I& offset) { return false; };
 
     /// Called when a mouseDragged event occurs on a control and the GUI editor is active
     /// @param   event   the GuiEvent which caused the call to this function
     /// @param   offset   the offset which is representative of the units x and y that the editor takes up on screen
-    virtual bool onMouseDraggedEditor(const GuiEvent &event, Point2I offset) { return false; };
+    virtual bool onMouseDraggedEditor(const GuiEvent &event, const Point2I& offset) { return false; };
 
     /// @}
 

+ 13 - 0
engine/source/math/mRect.h

@@ -47,6 +47,7 @@ class RectI
 
    bool intersect(const RectI& clipRect);
    bool pointInRect(const Point2I& pt) const;
+   S32 distanceToRect(const Point2I& pt) const;
    bool contains(const RectI& R) const;
    bool overlaps(RectI R) const;
    void inset(S32 x, S32 y);
@@ -164,6 +165,18 @@ inline bool RectI::pointInRect(const Point2I &pt) const
    return (pt.x >= point.x && pt.x < point.x + extent.x && pt.y >= point.y && pt.y < point.y + extent.y);
 }
 
+inline S32 RectI::distanceToRect(const Point2I& pt) const
+{
+	if (pointInRect(pt))
+	{
+		return 0;
+	}
+	S32 x = pt.x < point.x ? point.x - pt.x : pt.x - (point.x + extent.x);
+	S32 y = pt.y < point.y ? point.y - pt.y : pt.y - (point.y + extent.y);
+
+	return getMax(x, y);
+}
+
 inline bool RectI::contains(const RectI& R) const
 {
    if (point.x <= R.point.x && point.y <= R.point.y)