Pārlūkot izejas kodu

Added a (working) way to specify default size for editor windows

BearishSun 10 gadi atpakaļ
vecāks
revīzija
c9a85f77da

+ 16 - 3
BansheeEditor/Include/BsEditorWidget.h

@@ -50,6 +50,16 @@ namespace BansheeEngine
 		 */
 		UINT32 getHeight() const { return mHeight; }
 
+		/**
+		 * @brief	Returns the width of the widget when initially created, in pixels.
+		 */
+		UINT32 getDefaultWidth() const { return mDefaultWidth; }
+
+		/**
+		 * @brief	Returns the height of the widget when initially created, in pixels.
+		 */
+		UINT32 getDefaultHeight() const { return mDefaultHeight; }
+
 		/**
 		 * @brief	Returns the bounds of the widget in pixels, relative
 		 *			to its parent container.
@@ -151,7 +161,8 @@ namespace BansheeEngine
 	protected:
 		friend class EditorWidgetManager;
 
-		EditorWidgetBase(const HString& displayName, const String& name, EditorWidgetContainer& parentContainer);
+		EditorWidgetBase(const HString& displayName, const String& name, UINT32 defaultWidth,
+			UINT32 defaultHeight, EditorWidgetContainer& parentContainer);
 		virtual ~EditorWidgetBase();
 
 		/**
@@ -185,6 +196,7 @@ namespace BansheeEngine
 		EditorWidgetContainer* mParent;
 		INT32 mX, mY;
 		UINT32 mWidth, mHeight;
+		UINT32 mDefaultWidth, mDefaultHeight;
 		GUIPanel* mContent;
 		bool mHasFocus;
 	};
@@ -228,8 +240,9 @@ namespace BansheeEngine
 
 		struct ConstructPrivately {};
 
-		EditorWidget(const HString& displayName, EditorWidgetContainer& parentContainer)
-			:EditorWidgetBase(displayName, Type::getTypeName(), parentContainer)
+		EditorWidget(const HString& displayName, UINT32 defaultWidth, UINT32 defaultHeight, 
+			EditorWidgetContainer& parentContainer)
+			:EditorWidgetBase(displayName, Type::getTypeName(), defaultWidth, defaultHeight, parentContainer)
 		{ }
 
 	public:

+ 4 - 2
BansheeEditor/Source/BsEditorWidget.cpp

@@ -13,8 +13,10 @@
 
 namespace BansheeEngine
 {
-	EditorWidgetBase::EditorWidgetBase(const HString& displayName, const String& name, EditorWidgetContainer& parentContainer)
-		:mDisplayName(displayName), mName(name), mParent(nullptr), mContent(nullptr), mX(0), mY(0), mWidth(0), mHeight(0), mHasFocus(false)
+	EditorWidgetBase::EditorWidgetBase(const HString& displayName, const String& name, UINT32 defaultWidth,
+		UINT32 defaultHeight, EditorWidgetContainer& parentContainer)
+		:mDisplayName(displayName), mName(name), mParent(nullptr), mContent(nullptr), mX(0), mY(0), mWidth(0), 
+		mHeight(0), mHasFocus(false), mDefaultWidth(defaultWidth), mDefaultHeight(defaultHeight)
 	{
 		parentContainer.add(*this);
 	}

+ 4 - 0
BansheeEditor/Source/BsEditorWidgetManager.cpp

@@ -117,6 +117,10 @@ namespace BansheeEngine
 			return nullptr;
 		}
 
+		Vector2I widgetSize(newWidget->getDefaultWidth(), newWidget->getDefaultHeight());
+		Vector2I windowSize = EditorWidgetContainer::widgetToWindowSize(widgetSize);
+		window->setSize((UINT32)windowSize.x, (UINT32)windowSize.y);
+
 		return newWidget;
 	}
 

+ 1 - 4
MBansheeEditor/ConsoleWindow.cs

@@ -2,14 +2,13 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
-using System.Text;
-using System.Text.RegularExpressions;
 
 namespace BansheeEditor
 {
     /// <summary>
     /// Displays a list of log messages.
     /// </summary>
+    [DefaultSize(600, 300)]
     public class ConsoleWindow : EditorWindow
     {
         /// <summary>
@@ -60,8 +59,6 @@ namespace BansheeEditor
 
         private void OnInitialize()
         {
-            //Width = 300;
-
             GUILayoutY layout = GUI.AddLayoutY();
             GUILayoutX titleLayout = layout.AddLayoutX();
 

+ 20 - 0
MBansheeEditor/DefaultSize.cs

@@ -0,0 +1,20 @@
+using System;
+
+namespace BansheeEditor
+{
+    /// <summary>
+    /// Can be placed on <see cref="EditorWindow"/> class to provide a default size for the window when it is first opened.
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Class)]
+    public sealed class DefaultSize : Attribute
+    {
+        private int width = 400;
+        private int height = 400;
+
+        public DefaultSize(int width, int height)
+        {
+            this.width = width;
+            this.height = height;
+        }
+    }
+}

+ 0 - 8
MBansheeEditor/EditorWindow.cs

@@ -17,7 +17,6 @@ namespace BansheeEditor
         public int Width
         {
             get { return Internal_GetWidth(mCachedPtr); }
-            set { Internal_SetWidth(mCachedPtr, value); }
         }
 
         /// <summary>
@@ -26,7 +25,6 @@ namespace BansheeEditor
         public int Height
         {
             get { return Internal_GetHeight(mCachedPtr); }
-            set { Internal_SetHeight(mCachedPtr, value); }
         }
 
         /// <summary>
@@ -117,15 +115,9 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern int Internal_GetWidth(IntPtr nativeInstance);
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetWidth(IntPtr nativeInstance, int width);
-
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern int Internal_GetHeight(IntPtr nativeInstance);
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetHeight(IntPtr nativeInstance, int height);
-
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern bool Internal_HasFocus(IntPtr nativeInstance);
 

+ 1 - 0
MBansheeEditor/MBansheeEditor.csproj

@@ -45,6 +45,7 @@
     <Compile Include="CodeEditor.cs" />
     <Compile Include="ColorPicker.cs" />
     <Compile Include="ConsoleWindow.cs" />
+    <Compile Include="DefaultSize.cs" />
     <Compile Include="DialogBox.cs" />
     <Compile Include="DragDrop.cs" />
     <Compile Include="DropDownWindow.cs" />

+ 1 - 2
MBansheeEditor/SettingsWindow.cs

@@ -6,6 +6,7 @@ namespace BansheeEditor
     /// <summary>
     /// Displays project and editor settings
     /// </summary>
+    [DefaultSize(300, 200)]
     internal sealed class SettingsWindow : EditorWindow
     {
         internal const string ActiveCodeEditorKey = "__ActiveCodeEditor";
@@ -31,8 +32,6 @@ namespace BansheeEditor
 
         private void OnInitialize()
         {
-            Width = 300;
-
             GUIToggle projectFoldout = new GUIToggle(new LocEdString("Project"), EditorStyles.Foldout);
             GUIToggle editorFoldout = new GUIToggle(new LocEdString("Editor"), EditorStyles.Foldout);
 

+ 6 - 4
SBansheeEditor/Include/BsScriptEditorWindow.h

@@ -119,7 +119,8 @@ namespace BansheeEngine
 		/**
 		* @brief	Callback that is triggered when user requests a widget to be opened.
 		*/
-		static EditorWidgetBase* openEditorWidgetCallback(String ns, String type, EditorWidgetContainer& parentContainer);
+		static EditorWidgetBase* openEditorWidgetCallback(String ns, String type, UINT32 width, UINT32 height, 
+			EditorWidgetContainer& parentContainer);
 
 		static UnorderedMap<String, EditorWindowHandle> OpenScriptEditorWindows;
 		static Vector<String> AvailableWindowTypes;
@@ -134,9 +135,7 @@ namespace BansheeEngine
 		static void internal_screenToWindowPos(ScriptEditorWindow* thisPtr, Vector2I screenPos, Vector2I* windowPos);
 		static void internal_windowToScreenPos(ScriptEditorWindow* thisPtr, Vector2I windowPos, Vector2I* screenPos);
 		static UINT32 internal_getWidth(ScriptEditorWindow* thisPtr);
-		static void internal_setWidth(ScriptEditorWindow* thisPtr, UINT32 width);
 		static UINT32 internal_getHeight(ScriptEditorWindow* thisPtr);
-		static void internal_setHeight(ScriptEditorWindow* thisPtr, UINT32 height);
 	};
 
 	/**
@@ -152,9 +151,12 @@ namespace BansheeEngine
 		 *
 		 * @param	ns				Namespace of the widget type.
 		 * @param	type			Name of the widget type.
+		 * @param	defaultWidth	Default width of the widget when initially created.
+		 * @param	defaultHeight	Default height of the widget when initially created.
 		 * @param	parentContainer	Container to initially dock the widget in.
 		 */
-		ScriptEditorWidget(const String& ns, const String& type, EditorWidgetContainer& parentContainer);
+		ScriptEditorWidget(const String& ns, const String& type, UINT32 defaultWidth, 
+			UINT32 defaultHeight, EditorWidgetContainer& parentContainer);
 		~ScriptEditorWidget();
 
 		/**

+ 27 - 39
SBansheeEditor/Source/BsScriptEditorWindow.cpp

@@ -48,9 +48,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_CreateOrGetInstance", &ScriptEditorWindow::internal_createOrGetInstance);
 		metaData.scriptClass->addInternalCall("Internal_GetInstance", &ScriptEditorWindow::internal_getInstance);
 		metaData.scriptClass->addInternalCall("Internal_GetWidth", &ScriptEditorWindow::internal_getWidth);
-		metaData.scriptClass->addInternalCall("Internal_SetWidth", &ScriptEditorWindow::internal_setWidth);
 		metaData.scriptClass->addInternalCall("Internal_GetHeight", &ScriptEditorWindow::internal_getHeight);
-		metaData.scriptClass->addInternalCall("Internal_SetHeight", &ScriptEditorWindow::internal_setHeight);
 		metaData.scriptClass->addInternalCall("Internal_HasFocus", &ScriptEditorWindow::internal_hasFocus);
 		metaData.scriptClass->addInternalCall("Internal_ScreenToWindowPos", &ScriptEditorWindow::internal_screenToWindowPos);
 		metaData.scriptClass->addInternalCall("Internal_WindowToScreenPos", &ScriptEditorWindow::internal_windowToScreenPos);
@@ -200,21 +198,6 @@ namespace BansheeEngine
 			return 0;
 	}
 
-	void ScriptEditorWindow::internal_setWidth(ScriptEditorWindow* thisPtr, UINT32 width)
-	{
-		if (!thisPtr->isDestroyed())
-		{
-			EditorWindowBase* editorWindow = thisPtr->mEditorWidget->getParentWindow();
-			if (editorWindow != nullptr)
-			{
-				Vector2I widgetSize(width, thisPtr->mEditorWidget->getHeight());
-				Vector2I windowSize = EditorWidgetContainer::widgetToWindowSize(widgetSize);
-
-				editorWindow->setSize((UINT32)windowSize.x, (UINT32)windowSize.y);
-			}
-		}
-	}
-
 	UINT32 ScriptEditorWindow::internal_getHeight(ScriptEditorWindow* thisPtr)
 	{
 		if (!thisPtr->isDestroyed())
@@ -223,21 +206,6 @@ namespace BansheeEngine
 			return 0;
 	}
 
-	void ScriptEditorWindow::internal_setHeight(ScriptEditorWindow* thisPtr, UINT32 height)
-	{
-		if (!thisPtr->isDestroyed())
-		{
-			EditorWindowBase* editorWindow = thisPtr->mEditorWidget->getParentWindow();
-			if (editorWindow != nullptr)
-			{
-				Vector2I widgetSize(thisPtr->mEditorWidget->getWidth(), height);
-				Vector2I windowSize = EditorWidgetContainer::widgetToWindowSize(widgetSize);
-
-				editorWindow->setSize((UINT32)windowSize.x, (UINT32)windowSize.y);
-			}
-		}
-	}
-
 	void ScriptEditorWindow::onWidgetResized(UINT32 width, UINT32 height)
 	{
 		if (isDestroyed() || !mEditorWidget->isInitialized() || mManagedInstance == nullptr)
@@ -262,6 +230,13 @@ namespace BansheeEngine
 
 		if(assembly != nullptr)
 		{
+			MonoClass* defaultSizeAttrib = assembly->getClass("BansheeEditor", "DefaultSize");
+			if (defaultSizeAttrib == nullptr)
+				BS_EXCEPT(InternalErrorException, "Cannot find DefaultSize managed class.");
+
+			MonoField* defaultWidthField = defaultSizeAttrib->getField("width");
+			MonoField* defaultHeightField = defaultSizeAttrib->getField("height");
+
 			MonoClass* editorWindowClass = assembly->getClass("BansheeEditor", "EditorWindow");
 
 			const Vector<MonoClass*>& allClasses = assembly->getAllClasses();
@@ -269,9 +244,20 @@ namespace BansheeEngine
 			{
 				if(curClass->isSubClassOf(editorWindowClass) && curClass != editorWindowClass)
 				{
+					UINT32 width = 400;
+					UINT32 height = 400;
+
+					MonoObject* defaultSize = curClass->getAttribute(defaultSizeAttrib);
+					if (defaultSize != nullptr)
+					{
+						defaultWidthField->getValue(defaultSize, &width);
+						defaultHeightField->getValue(defaultSize, &height);
+					}
+
 					const String& className = curClass->getFullName();
 					EditorWidgetManager::instance().registerWidget(className, 
-						std::bind(&ScriptEditorWindow::openEditorWidgetCallback, curClass->getNamespace(), curClass->getTypeName(), std::placeholders::_1));
+						std::bind(&ScriptEditorWindow::openEditorWidgetCallback, curClass->getNamespace(), 
+						curClass->getTypeName(), width, height, _1));
 					AvailableWindowTypes.push_back(className);
 				}
 			}
@@ -288,9 +274,10 @@ namespace BansheeEngine
 		AvailableWindowTypes.clear();
 	}
 
-	EditorWidgetBase* ScriptEditorWindow::openEditorWidgetCallback(String ns, String type, EditorWidgetContainer& parentContainer)
+	EditorWidgetBase* ScriptEditorWindow::openEditorWidgetCallback(String ns, String type, UINT32 width, 
+		UINT32 height, EditorWidgetContainer& parentContainer)
 	{
-		ScriptEditorWidget* editorWidget = bs_new<ScriptEditorWidget>(ns, type, parentContainer);
+		ScriptEditorWidget* editorWidget = bs_new<ScriptEditorWidget>(ns, type, width, height, parentContainer);
 		ScriptEditorWindow* nativeInstance = new (bs_alloc<ScriptEditorWindow>()) ScriptEditorWindow(editorWidget);
 
 		ScriptEditorWindow::registerScriptEditorWindow(nativeInstance);
@@ -329,10 +316,11 @@ namespace BansheeEngine
 		}
 	}
 
-	ScriptEditorWidget::ScriptEditorWidget(const String& ns, const String& type, EditorWidgetContainer& parentContainer)
-		:EditorWidgetBase(HString(toWString(type)), ns + "." + type, parentContainer), mNamespace(ns), mTypename(type),
-		mUpdateThunk(nullptr), mManagedInstance(nullptr), mOnInitializeThunk(nullptr), mOnDestroyThunk(nullptr), 
-		mContentsPanel(nullptr), mScriptOwner(nullptr), mGetDisplayName(nullptr), mIsInitialized(false)
+	ScriptEditorWidget::ScriptEditorWidget(const String& ns, const String& type, UINT32 defaultWidth, 
+		UINT32 defaultHeight, EditorWidgetContainer& parentContainer)
+		:EditorWidgetBase(HString(toWString(type)), ns + "." + type, defaultWidth, defaultHeight, parentContainer), 
+		mNamespace(ns), mTypename(type), mUpdateThunk(nullptr), mManagedInstance(nullptr), mOnInitializeThunk(nullptr), 
+		mOnDestroyThunk(nullptr), mContentsPanel(nullptr), mScriptOwner(nullptr), mGetDisplayName(nullptr), mIsInitialized(false)
 	{
 		if(createManagedInstance())
 		{

+ 50 - 10
TODO.txt

@@ -14,15 +14,7 @@ Other polish:
  - Add menu items:
   - Edit: Cut/Copy/Paste/Duplicate/Delete(need to make sure it works in Hierarchy, with shortcuts), View/Move/rotate/scale
   - Game Object (also add to context): Create(Empty, Empty Child, Camera, Renderable, Point/Spot/Directional Light), Apply prefab, Break prefab, Revert prefab
- - When I expand inspector elements and them come back to that object it should remember the previous state
-   - In the Inspector base add a dictionary "Persistent<string, object>"
-   - InspectorWindow will keep a reference to this dictionary whenever it creates a new inspector for SO or resource
-    - Or if one already exists it will restore it
-	- This dictionary will not persist editor shutdown
-   - Generic inspector and inspectable fields can use the serialized property name for the key
-    - Will need a way to retrieve the full property name, up to the parent Component/Resource
-	- Will need to extend inspectable fields so they know their parent inspector so they have access to the dictionar
-   - Custom inspectors can get rid of manual "isExpanded" bools and use the dictionary instead
+ - Inspector persistance (See below for details)
 
 Stage 2 polish:
  - Game window
@@ -31,7 +23,6 @@ Stage 2 polish:
  - When managed exception happens log an error and continue execution
   - Doing a pass over all methods referencing Internal_ methods ensuring they do proper checking on C# side would be good
  - Game publishing (Build window, collect resources, output exe, default viewport) (described below)
- - Console window
 
 Optional:
  - When starting drag from hierarchy tree view it tends to select another object (can't repro)
@@ -63,6 +54,20 @@ Finalizing:
  - Add copyright notices in all files & change license to GPL
  - Need to generate a proper merge of dev and preview branches
    - Use "git revert --no-commit <COMMITID>..HEAD" to reverse anything on the preview branch that was done after the branch creation, then merge
+
+----------------------------------------------------------------------
+Inspector persistance
+
+ - When I expand inspector elements and them come back to that object it should remember the previous state
+   - In the Inspector base add a dictionary "Persistent<string, object>"
+   - InspectorWindow will keep a reference to this dictionary whenever it creates a new inspector for SO or resource
+    - Or if one already exists it will restore it
+	- This dictionary will not persist editor shutdown
+   - Generic inspector and inspectable fields can use the serialized property name for the key
+    - Will need a way to retrieve the full property name, up to the parent Component/Resource
+	- Will need to extend inspectable fields so they know their parent inspector so they have access to the dictionar
+   - Custom inspectors can get rid of manual "isExpanded" bools and use the dictionary instead
+
 ----------------------------------------------------------------------
 Build system
  - Test Resources (if loading works and if they're properly packaged in build)
@@ -74,11 +79,46 @@ Build system
    - Recompile script assemblies if needed and copy them from project Internal folder to output folder
    - Copy the Builtin resources for engine from Editor install folder to output folder
    - Copy all the resources marked with the flag mentioned above to \Data subfolder in the output folder, preserving the same asset structure
+     - Also all dependencies of those resources (add C# method FindDependantResources?)
    - Make sure to go over texture resources and ensure they are saved in the valid format
      as we don't want to do format conversion at runtime (Not cruical, but it should be done eventually)
      - This should something similar to Unity where when changing the platform all resources get reimported
    - Make sure to clear all prefab diffs (possibly store them elsewhere in the first place)
 	 - And all prefab instances should have updateFromPrefab called on them.
+  - Need to create an executable that creates a fullscreen window, loads main scene and renders the main camera to it
+   - Might need a way to load fullscreen & resolution state on start-up (so it can be modified internally and loaded immediately next time)
+    - Add GameSettings.asset that is generated on build
+	 - Has "firstStart" turned off
+	 - Contains wanted video mode and initial scene to load
+	 - This file is loaded by the application initially
+	 - Similar to project/editor settings this can contain user data as needed
+
+----------------------------------------------------------------------
+Game window
+ - Main camera
+  - Allow camera to be marked with "Main" toggle
+  - When Game window is created search the scene for such a camera
+   - Same needs to happen whenever a new scene is loaded
+  - Create a render target similar to scene window and render to it if the camera is found
+   - Otherwise output a message that main camera is missing
+ - Extend Time class (C++ and C#)
+  - Current time and frame idx should be renamed with Real prefix
+  - New time and frame idx should be added that do not tick when paused
+ - EditorApplication Play/Pause/Step
+  - When game is paused non-real time doesn't tick, and component OnInitialize/Update/OnDestroy methods aren't called
+   - Some components might rely on these being called when they're added/removed from the scene. Perhaps add
+     a separate set of initialize/destroy methods for internal only use that get called regardless?
+   - Internal (editor) components either ignore this rule, or use the internal-only versions exclusively
+   - When play is hit:
+     - Current scene data is serialized into a Prefab stored in memory
+	 - Time starts ticking and initialize/update/destroy methods start to get called normally
+   - When pause is hit:
+     - Time stops ticking and so do components method calls
+   - When stop is hit:
+     - Time stops ticking and so do components method calls
+	 - Current scene is unloaded and prefab from memory is loaded
+   - When frame-step is hit:
+     - Time and component updates are unpaused for a single frame and then paused again
 
 ----------------------------------------------------------------------
 Other