Browse Source

Tree View Work

This code include more work on the Tree View so that it can better reflect what's actually happening in the editor.
Peter Robinson 2 years ago
parent
commit
b67b52f6e2

+ 2 - 2
editor/EditorCore/EditorCore.cs

@@ -249,13 +249,13 @@ function EditorCore::initGui(%this)
 
 			new GuiMenuItemCtrl() {
 				Text = "Select All";
-				Command = "GuiEditor.brain.SelectAll;";
+				Command = "GuiEditor.brain.SelectAll();";
 				Accelerator = "Ctrl A";
 			};
 			new GuiMenuItemCtrl() {
 				Text = "Deselect";
 				Command = "GuiEditor.brain.clearSelection();";
-				Accelerator = "Esc";
+				Accelerator = "Ctrl D";
 			};
 		};
 		new GuiMenuItemCtrl() {

+ 28 - 0
editor/EditorCore/Themes/BaseTheme/BaseTheme.cs

@@ -63,6 +63,7 @@ function BaseTheme::onAdd(%this)
 	%this.makeDropDownProfile();
 	%this.makeWindowProfile();
 	%this.makeListBoxProfile();
+	%this.makeTreeViewProfile();
 	%this.makeGraphProfile();
 	%this.makeTextDisplayProfile();
 	%this.makeSubListProfile();
@@ -1866,6 +1867,33 @@ function BaseTheme::makeListBoxProfile(%this)
 	};
 }
 
+function BaseTheme::makeTreeViewProfile(%this)
+{
+	%this.treeViewProfile = new GuiControlProfile ()
+	{
+	    // fill color
+	    fillColor = %this.adjustValue(%this.color1, 2);
+	    fillColorHL = %this.adjustValue(%this.color1, 4);
+	    fillColorSL = %this.color5;
+	    fillColorNA = %this.setAlpha(%this.color1, 150);
+		align = left;
+		vAlign = middle;
+
+		tab = false;
+		canKeyFocus = true;
+
+		fontType = %this.font[3];
+		fontDirectory = %this.fontDirectory;
+		fontSize = %this.fontSize - 2;
+		fontColor = %this.color4;
+		fontColorHL = %this.adjustValue(%this.color4, 20);
+		fontColorSL = %this.adjustValue(%this.color1, 2);
+		fontColorNA = %this.adjustValue(%this.color4, -30);
+
+		borderDefault = %this.emptyBorder;
+	};
+}
+
 function BaseTheme::makeGraphProfile(%this)
 {
 	%border = new GuiBorderProfile()

+ 9 - 0
editor/GuiEditor/scripts/GuiEditorExplorerTree.cs

@@ -49,4 +49,13 @@ function GuiEditorExplorerTree::onPostApply(%this, %obj)
     {
         %this.refreshItemText(%index);
     }
+}
+
+function GuiEditorExplorerTree::onGetObjectText(%this, %obj)
+{
+    if(%obj == GuiEditor.rootGui)
+    {
+        return "Canvas Simulation";
+    }
+    return "";
 }

+ 2 - 1
editor/GuiEditor/scripts/GuiEditorExplorerWindow.cs

@@ -26,8 +26,9 @@ function GuiEditorExplorerWindow::onAdd(%this)
 		VertSizing="height";
 		Position="0 0";
 		Extent="228 355";
+		BindToGuiEditor="1";
 	};
-	ThemeManager.setProfile(%this.tree, "listboxProfile");
+	ThemeManager.setProfile(%this.tree, "treeViewProfile");
 	%this.scroller.add(%this.tree);
 	%this.tree.startListening(GuiEditor.inspectorWindow.inspector);
 }

+ 33 - 22
engine/source/gui/editor/guiEditCtrl.cc

@@ -116,7 +116,7 @@ ConsoleMethod( GuiEditCtrl, select, void, 3, 3, "(GuiControl ctrl) Finds and sel
    if(!Sim::findObject(argv[2], ctrl))
       return;
 
-   object->setSelection(ctrl, false);
+   object->setSelection(ctrl);
 }
 
 ConsoleMethod( GuiEditCtrl, setCurrentAddSet, void, 3, 3, "(GuiControl ctrl) Set the current control set in which controls are added.\n"
@@ -195,13 +195,12 @@ ConsoleMethod( GuiEditCtrl, loadSelection, void, 3, 3, "(string fileName) Loads
    object->loadSelection(argv[2]);
 }
 
-ConsoleMethod( GuiEditCtrl, selectAll, void, 2, 2, "() Selects all controls in list\n"
-              "@return No return value.")
+ConsoleMethod(GuiEditCtrl, selectAll, void, 2, 2, "() Selects all controls\n"
+	"@return No return value.")
 {
-   object->selectAll();
+	object->selectAll();
 }
 
-
 ConsoleMethod( GuiEditCtrl, getSelected, S32, 2, 2, "() Gets the GUI control(s) the editor is currently selecting\n"
               "@return Returns the ID of the control.")
 {
@@ -291,7 +290,7 @@ void GuiEditCtrl::setEditMode(bool value)
    Con::executef(this, 1, "onClearSelected");
    mSelectedControls.clear();
    if (mActive && mAwake)
-      mCurrentAddSet = NULL;
+      mCurrentAddSet = mContentControl;
 }
 
 void GuiEditCtrl::setCurrentAddSet(GuiControl *ctrl, bool clearSelection)
@@ -315,11 +314,15 @@ const GuiControl* GuiEditCtrl::getCurrentAddSet() const
 void GuiEditCtrl::clearSelection(void)
 {
    mSelectedControls.clear();
+   if (isMethod("onClearSelected"))
+   {
+	   Con::executef(this, 1, "onClearSelected");
+   }
 }
-void GuiEditCtrl::setSelection(GuiControl *ctrl, bool inclusive)
+void GuiEditCtrl::setSelection(GuiControl *ctrl)
 {
    //sanity check
-   if (! ctrl)
+   if (!ctrl)
       return;
 
    if(mContentControl == ctrl)
@@ -334,7 +337,7 @@ void GuiEditCtrl::setSelection(GuiControl *ctrl, bool inclusive)
       GuiControl *newAddSet = ctrl->getParent();
 
       //see if we should clear the old selection set
-      if (newAddSet != mCurrentAddSet || (! inclusive)) {
+      if (newAddSet != mCurrentAddSet) {
          Con::executef(this, 1, "onClearSelected");
          mSelectedControls.clear();
       }
@@ -1339,19 +1342,27 @@ void GuiEditCtrl::saveSelection(const char* filename)
 
 void GuiEditCtrl::selectAll()
 {
-   GuiControl::iterator i;
-   if (!mCurrentAddSet)
-      return;
-   Con::executef(this, 1, "onClearSelected");
-   mSelectedControls.clear();
-   for(i = mCurrentAddSet->begin(); i != mCurrentAddSet->end(); i++)
-   {
-      GuiControl *ctrl = dynamic_cast<GuiControl *>(*i);
-      //if (!(ctrl->isLocked())) {
-         mSelectedControls.push_back(ctrl);
-         Con::executef(this, 2, "onAddSelected", Con::getIntArg(ctrl->getId()));
-      //}
-   }
+	if (!mCurrentAddSet)
+		return;
+
+	mSelectedControls.clear();
+	if (isMethod("onClearSelected"))
+	{
+		Con::executef(this, 1, "onClearSelected");
+	}
+
+	for (GuiControl::iterator i = mCurrentAddSet->begin(); i != mCurrentAddSet->end(); i++)
+	{
+		GuiControl* ctrl = dynamic_cast<GuiControl*>(*i);
+		if (ctrl)
+		{
+			mSelectedControls.push_back(ctrl);
+			if(isMethod("onAddSelected"))
+			{
+				Con::executef(this, 2, "onAddSelected", Con::getIntArg(ctrl->getId()));
+			}
+		}
+	}
 }
 
 void GuiEditCtrl::bringToFront()

+ 1 - 1
engine/source/gui/editor/guiEditCtrl.h

@@ -81,7 +81,7 @@ class GuiEditCtrl : public GuiControl
    bool selectionContains(GuiControl *ctrl);
    void setCurrentAddSet(GuiControl *ctrl, bool clearSelection = true);
    const GuiControl* getCurrentAddSet() const;
-   void setSelection(GuiControl *ctrl, bool inclusive = false);
+   void setSelection(GuiControl *ctrl);
 
    // Undo Access
    void undo();

+ 92 - 2
engine/source/gui/guiTreeViewCtrl.cc

@@ -24,6 +24,7 @@
 #include "graphics/dgl.h"
 #include "gui/guiDefaultControlRender.h"
 #include "gui/guiCanvas.h"
+#include "gui/editor/guiEditCtrl.h"
 
 #include "guiTreeViewCtrl_ScriptBinding.h"
 
@@ -39,6 +40,8 @@ GuiTreeViewCtrl::GuiTreeViewCtrl()
 	mDragActive = false;
 	mDragIndex = 0;
 	mIsDragLegal = false;
+	mIsBoundToGuiEditor = false;
+	mFocusControl = nullptr;
 }
 
 GuiTreeViewCtrl::~GuiTreeViewCtrl()
@@ -62,12 +65,30 @@ GuiTreeViewCtrl::TreeItem* GuiTreeViewCtrl::grabItemPtr(S32 index)
 void GuiTreeViewCtrl::initPersistFields()
 {
 	Parent::initPersistFields();
+	addField("BindToGuiEditor", TypeBool, Offset(mIsBoundToGuiEditor, GuiTreeViewCtrl));
 }
 
 void GuiTreeViewCtrl::onTouchDown(const GuiEvent& event)
 {
 	mTouchPoint == event.mousePoint;
-	Parent::onTouchDown(event);
+	S32 hitIndex = getHitIndex(event);
+	if (mIsBoundToGuiEditor && smDesignTime && hitIndex == 0)
+	{
+		if (!(event.modifier & SI_CTRL) && !(event.modifier & SI_SHIFT))
+		{
+			clearSelection();
+			GuiEditCtrl* edit = GuiControl::smEditorHandle;
+			if (edit)
+			{
+				GuiControl* root = static_cast<GuiControl*>(mItems[0]->itemData);
+				edit->setCurrentAddSet(root, true);
+			}
+		}
+	}
+	else 
+	{
+		Parent::onTouchDown(event);
+	}
 }
 
 void GuiTreeViewCtrl::onTouchDragged(const GuiEvent& event)
@@ -157,11 +178,38 @@ void GuiTreeViewCtrl::onTouchUp(const GuiEvent& event)
 
 void GuiTreeViewCtrl::onPreRender()
 {
-	
+	if (mIsBoundToGuiEditor && smDesignTime && smEditorHandle)
+	{
+		GuiEditCtrl* edit = GuiControl::smEditorHandle;
+		if (edit)
+		{
+			const GuiControl* oldFocus = mFocusControl;
+			mFocusControl = edit->getCurrentAddSet();
+			if(oldFocus != mFocusControl)
+			{
+				for (S32 i = 0; i < mItems.size(); i++)
+				{
+					LBItem* item = mItems[i];
+					TreeItem* treeItem = dynamic_cast<TreeItem*>(item);
+					SimObject* obj = static_cast<SimObject*>(item->itemData);
+					if (obj && obj->getId() == mFocusControl->getId())
+					{
+						treeItem->isSelected = false;
+						if(!treeItem->isOpen)
+						{
+							treeItem->isOpen = true;
+							refreshTree();
+						}
+					}
+				}
+			}
+		}
+	}
 }
 
 void GuiTreeViewCtrl::onRender(Point2I offset, const RectI& updateRect)
 {
+	mFocusLevel = -1;
 	RectI clip = dglGetClipRect();
 	if (mFitParentWidth && (mBounds.extent.x != clip.extent.x || mItemSize.x != clip.extent.x))
 	{
@@ -186,8 +234,19 @@ void GuiTreeViewCtrl::onRender(Point2I offset, const RectI& updateRect)
 
 		if(!treeItem || treeItem->isVisible)
 		{
+			if (mFocusLevel >= 0 && mFocusLevel >= treeItem->level)
+			{
+				mFocusLevel = -1;
+			}
+
 			// Render our item
 			onRenderItem(itemRect, mItems[i]);
+
+			if (mItems[i]->ID == mFocusControl->getId())
+			{
+				mFocusLevel = treeItem->level;
+			}
+
 			if (mDragActive && j == mDragIndex)
 			{
 				dragRect = RectI(itemRect);
@@ -217,6 +276,7 @@ void GuiTreeViewCtrl::onRenderItem(RectI& itemRect, LBItem* item)
 	{
 		cursorPt = root->getCursorPos();
 	}
+	bool isFocus = obj == mFocusControl;
 	GuiControlState currentState = GuiControlState::NormalState;
 	if (!mActive || !item->isActive)
 		currentState = GuiControlState::DisabledState;
@@ -238,6 +298,23 @@ void GuiTreeViewCtrl::onRenderItem(RectI& itemRect, LBItem* item)
 	RectI fillRect = applyBorders(ctrlRect.point, ctrlRect.extent, currentState, mProfile);
 	RectI contentRect = applyPadding(fillRect.point, fillRect.extent, currentState, mProfile);
 
+	//indent to the focus level
+	if(mFocusLevel >= 0)
+	{
+		contentRect.point.x += (mFocusLevel * contentRect.extent.y);
+		contentRect.extent.x -= (mFocusLevel * contentRect.extent.y);
+
+		//convert this space to a line by crushing down the sides
+		S32 crush = mRound((contentRect.extent.y - 2) / 2);
+		RectI line = RectI(contentRect.point.x + crush, contentRect.point.y, 2, contentRect.extent.y);
+		ColorI lineColor = currentState == SelectedState ? mProfile->getFillColor(NormalState) : mProfile->getFillColor(SelectedState);
+		dglDrawRectFill(line, lineColor);
+
+		//Remove indent
+		contentRect.point.x -= (mFocusLevel * contentRect.extent.y);
+		contentRect.extent.x += (mFocusLevel * contentRect.extent.y);
+	}
+
 	// Indent by level
 	contentRect.point.x += (treeItem->level * contentRect.extent.y);
 	contentRect.extent.x -= (treeItem->level * contentRect.extent.y);
@@ -253,6 +330,10 @@ void GuiTreeViewCtrl::onRenderItem(RectI& itemRect, LBItem* item)
 			RectI drawArea = RectI(contentRect.point.x, contentRect.point.y, contentRect.extent.y, contentRect.extent.y);
 			treeItem->triangleArea.set(drawArea.point, drawArea.extent);
 			ColorI color = mProfile->getFontColor(currentState);
+			if (isFocus)
+			{
+				color = mProfile->getFillColor(SelectedState);
+			}
 			renderTriangleIcon(drawArea, color, treeItem->isOpen ? GuiDirection::Down : GuiDirection::Right, 8);
 		}
 	}
@@ -490,6 +571,15 @@ StringTableEntry GuiTreeViewCtrl::getObjectText(SimObject* obj)
 	char buffer[1024];
 	if (obj)
 	{
+		if (isMethod("onGetObjectText"))
+		{
+			const char* text = Con::executef(this, 2, "onGetObjectText", Con::getIntArg(obj->getId()));
+			StringTableEntry name = StringTable->insert(text, true);
+			if (name != StringTable->EmptyString)
+			{
+				return name;
+			}
+		}
 		const char* pObjName = obj->getName();
 		const char* pInternalName = obj->getInternalName();
 		if (pObjName != NULL)

+ 3 - 0
engine/source/gui/guiTreeViewCtrl.h

@@ -35,6 +35,7 @@ private:
 	class TreeItem;
 
 	enum class ReorderMethod { Above, Below, Insert };
+	S32 mFocusLevel;
 
 protected:
 	SimObjectPtr<SimObject> mRootObject;
@@ -44,6 +45,8 @@ protected:
 	S32 mDragIndex;
 	bool mIsDragLegal;
 	ReorderMethod mReorderMethod;
+	bool mIsBoundToGuiEditor;
+	const GuiControl* mFocusControl;
 
 public:
 	GuiTreeViewCtrl();