Przeglądaj źródła

Updated manuals
Organized managed code a bit better
Added documentation groups for managed code

BearishSun 9 lat temu
rodzic
commit
92321a6b19
100 zmienionych plików z 7623 dodań i 4479 usunięć
  1. 2 0
      .gitignore
  2. 2455 0
      Documentation/Doxygen/Managed.doxyconfig
  3. 20 20
      Documentation/Doxygen/Native.doxyconfig
  4. 0 0
      Documentation/Doxygen/doxystyle.css
  5. 0 0
      Documentation/Doxygen/footer.html
  6. 0 0
      Documentation/Doxygen/header.html
  7. 0 0
      Documentation/Doxygen/layout.xml
  8. 124 18
      Documentation/Manuals/Native/renderer.md
  9. 38 38
      Documentation/Manuals/Native/rtti.md
  10. 41 38
      Documentation/Manuals/Native/scripting.md
  11. 0 0
      Documentation/doxygen_objdb_9152.tmp
  12. 39 33
      Source/MBansheeEditor/GUI/EditorStyles.cs
  13. 6 0
      Source/MBansheeEditor/GUI/GUIColorField.cs
  14. 6 0
      Source/MBansheeEditor/GUI/GUIDictionaryField.cs
  15. 6 0
      Source/MBansheeEditor/GUI/GUIEnumField.cs
  16. 6 0
      Source/MBansheeEditor/GUI/GUIFloatField.cs
  17. 6 0
      Source/MBansheeEditor/GUI/GUIGameObjectField.cs
  18. 6 0
      Source/MBansheeEditor/GUI/GUIIntField.cs
  19. 6 0
      Source/MBansheeEditor/GUI/GUIListBoxField.cs
  20. 6 0
      Source/MBansheeEditor/GUI/GUIListField.cs
  21. 6 0
      Source/MBansheeEditor/GUI/GUIResourceField.cs
  22. 6 0
      Source/MBansheeEditor/GUI/GUISceneTreeView.cs
  23. 6 0
      Source/MBansheeEditor/GUI/GUISliderField.cs
  24. 6 0
      Source/MBansheeEditor/GUI/GUITextField.cs
  25. 6 0
      Source/MBansheeEditor/GUI/GUITextureField.cs
  26. 6 0
      Source/MBansheeEditor/GUI/GUIToggleField.cs
  27. 6 0
      Source/MBansheeEditor/GUI/GUIVector2Field.cs
  28. 6 0
      Source/MBansheeEditor/GUI/GUIVector3Field.cs
  29. 6 0
      Source/MBansheeEditor/GUI/GUIVector4Field.cs
  30. 6 5
      Source/MBansheeEditor/GUI/LocEdString.cs
  31. 989 983
      Source/MBansheeEditor/General/EditorApplication.cs
  32. 46 40
      Source/MBansheeEditor/General/IGlobalShortcuts.cs
  33. 78 1
      Source/MBansheeEditor/General/Program.cs
  34. 6 0
      Source/MBansheeEditor/General/Selection.cs
  35. 181 175
      Source/MBansheeEditor/Input/EditorInput.cs
  36. 6 0
      Source/MBansheeEditor/Input/EditorVirtualInput.cs
  37. 7 1
      Source/MBansheeEditor/Inspectors/BoxColliderInspector.cs
  38. 7 1
      Source/MBansheeEditor/Inspectors/CameraInspector.cs
  39. 7 1
      Source/MBansheeEditor/Inspectors/CapsuleColliderInspector.cs
  40. 6 0
      Source/MBansheeEditor/Inspectors/CharacterControllerInspector.cs
  41. 7 1
      Source/MBansheeEditor/Inspectors/ColliderInspector.cs
  42. 7 1
      Source/MBansheeEditor/Inspectors/D6JointInspector.cs
  43. 7 1
      Source/MBansheeEditor/Inspectors/DistanceJointInspector.cs
  44. 7 1
      Source/MBansheeEditor/Inspectors/FixedJointInspector.cs
  45. 8 2
      Source/MBansheeEditor/Inspectors/FontInspector.cs
  46. 8 2
      Source/MBansheeEditor/Inspectors/GUISkinInspector.cs
  47. 6 0
      Source/MBansheeEditor/Inspectors/GUIWidgetInspector.cs
  48. 7 1
      Source/MBansheeEditor/Inspectors/HingeJointInspector.cs
  49. 7 1
      Source/MBansheeEditor/Inspectors/JointInspector.cs
  50. 7 1
      Source/MBansheeEditor/Inspectors/LightInspector.cs
  51. 6 0
      Source/MBansheeEditor/Inspectors/LimitInspectors.cs
  52. 6 0
      Source/MBansheeEditor/Inspectors/MaterialInspector.cs
  53. 7 1
      Source/MBansheeEditor/Inspectors/MeshColliderInspector.cs
  54. 6 0
      Source/MBansheeEditor/Inspectors/MeshInspector.cs
  55. 6 0
      Source/MBansheeEditor/Inspectors/PhysicsMaterialInspector.cs
  56. 6 0
      Source/MBansheeEditor/Inspectors/PhysicsMeshInspector.cs
  57. 6 0
      Source/MBansheeEditor/Inspectors/PlainTextInspector.cs
  58. 7 1
      Source/MBansheeEditor/Inspectors/PlaneColliderInspector.cs
  59. 6 0
      Source/MBansheeEditor/Inspectors/PrefabInspector.cs
  60. 7 1
      Source/MBansheeEditor/Inspectors/RenderableInspector.cs
  61. 6 0
      Source/MBansheeEditor/Inspectors/RigidbodyInspector.cs
  62. 6 0
      Source/MBansheeEditor/Inspectors/ScriptCodeInspector.cs
  63. 6 0
      Source/MBansheeEditor/Inspectors/ShaderInspector.cs
  64. 7 1
      Source/MBansheeEditor/Inspectors/SliderJointInspector.cs
  65. 7 1
      Source/MBansheeEditor/Inspectors/SphereColliderInspector.cs
  66. 7 1
      Source/MBansheeEditor/Inspectors/SphericalJointInspector.cs
  67. 6 0
      Source/MBansheeEditor/Inspectors/SpriteTextureInspector.cs
  68. 7 1
      Source/MBansheeEditor/Inspectors/StringTableInspector.cs
  69. 6 0
      Source/MBansheeEditor/Inspectors/Texture2DInspector.cs
  70. 101 100
      Source/MBansheeEditor/MBansheeEditor.csproj
  71. 6 0
      Source/MBansheeEditor/Script/CodeEditor.cs
  72. 6 1
      Source/MBansheeEditor/Script/ScriptCodeManager.cs
  73. 6 2
      Source/MBansheeEditor/Script/ScriptCompiler.cs
  74. 12 6
      Source/MBansheeEditor/Tests/UnitTestTypes.cs
  75. 6 0
      Source/MBansheeEditor/Tests/UnitTests.cs
  76. 6 0
      Source/MBansheeEditor/Utility/DragDrop.cs
  77. 6 0
      Source/MBansheeEditor/Utility/EditorBuiltin.cs
  78. 6 0
      Source/MBansheeEditor/Utility/EditorUtility.cs
  79. 6 4
      Source/MBansheeEditor/Utility/FolderMonitor.cs
  80. 6 0
      Source/MBansheeEditor/Utility/OSDropTarget.cs
  81. 6 0
      Source/MBansheeEditor/Utility/PrefabUtility.cs
  82. 6 0
      Source/MBansheeEditor/Utility/UndoRedo.cs
  83. 6 0
      Source/MBansheeEditor/Window/DefaultSize.cs
  84. 6 0
      Source/MBansheeEditor/Window/DropDownWindow.cs
  85. 178 172
      Source/MBansheeEditor/Window/EditorWindow.cs
  86. 75 69
      Source/MBansheeEditor/Window/MenuItem.cs
  87. 666 660
      Source/MBansheeEditor/Window/MenuItems.cs
  88. 6 0
      Source/MBansheeEditor/Window/ModalWindow.cs
  89. 69 67
      Source/MBansheeEditor/Window/ToolbarItem.cs
  90. 182 176
      Source/MBansheeEditor/Windows/AboutBox.cs
  91. 65 65
      Source/MBansheeEditor/Windows/BrowseDialog.cs
  92. 521 515
      Source/MBansheeEditor/Windows/Build/BuildManager.cs
  93. 6 0
      Source/MBansheeEditor/Windows/Build/BuildWindow.cs
  94. 1162 1156
      Source/MBansheeEditor/Windows/ColorPicker.cs
  95. 6 0
      Source/MBansheeEditor/Windows/DialogBox.cs
  96. 6 0
      Source/MBansheeEditor/Windows/GameWindow.cs
  97. 120 114
      Source/MBansheeEditor/Windows/HierarchyWindow.cs
  98. 6 0
      Source/MBansheeEditor/Windows/Inspector/CustomInspector.cs
  99. 6 0
      Source/MBansheeEditor/Windows/Inspector/EditorPersistentData.cs
  100. 6 0
      Source/MBansheeEditor/Windows/Inspector/GenericInspector.cs

+ 2 - 0
.gitignore

@@ -14,3 +14,5 @@ Documentation/html
 *.opendb
 /Build/VS2015/BansheeEngine.VC.db
 /Build/Generated
+/Documentation/Generated/Managed/html
+/Documentation/Generated/Native/html

+ 2455 - 0
Documentation/Doxygen/Managed.doxyconfig

@@ -0,0 +1,2455 @@
+# Doxyfile 1.8.10
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = "Banshee 3D"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = 
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ../Generated/Managed
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = YES
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = YES
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = YES
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = NO
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = NO
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = YES
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = NO
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            = layout.xml
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = NO
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = ../../Source/MBansheeEngine \
+                         ../../Source/MBansheeEditor
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd,
+# *.vhdl, *.ucf, *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.idl \
+                         *.ddl \
+                         *.odl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.cs \
+                         *.d \
+                         *.php \
+                         *.php4 \
+                         *.php5 \
+                         *.phtml \
+                         *.inc \
+                         *.m \
+                         *.markdown \
+                         *.md \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.for \
+                         *.tcl \
+                         *.vhd \
+                         *.vhdl \
+                         *.ucf \
+                         *.qsf \
+                         *.as \
+                         *.js
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS = 
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# compiled with the --with-libclang option.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            = header.html
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            = footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  = doxystyle.css
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 37
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 212
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 100
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 50
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               = 
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           = 
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     = 
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     = 
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       = 
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     = 
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           = 
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET = 
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    = 
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             = 
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = YES
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = internal=private
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = NO
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            = 
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               = 
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           = 
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           = 
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH      = 
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH  = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES

+ 20 - 20
Doxyfile → Documentation/Doxygen/Native.doxyconfig

@@ -58,7 +58,7 @@ PROJECT_LOGO           =
 # entered, it will be relative to the location where doxygen was started. If
 # left blank the current directory will be used.
 
-OUTPUT_DIRECTORY       = C:\Projects\BansheeEngineDev\BansheeEngine\Documentation
+OUTPUT_DIRECTORY       = ../Generated/Native
 
 # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
 # directories (in 2 levels) under the output directory of each output format and
@@ -775,24 +775,24 @@ WARN_LOGFILE           =
 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = Source/BansheeUtility/Include \
-                         Source/BansheeCore/Include \
-                         Source/BansheeEngine/Include \
-                         Source/BansheeEditor/Include \
-                         Source/BansheeD3D9RenderAPI/Include \
-                         Source/BansheeD3D11RenderAPI/Include \
-                         Source/BansheeFBXImporter/Include \
-                         Source/BansheeFontImporter/Include \
-                         Source/BansheeFreeImgImporter/Include \
-                         Source/BansheeGLRenderAPI/Include \
-                         Source/BansheeMono/Include \
-                         Source/BansheeOISInput/Include \
-                         Source/BansheePhysX/Include \
-                         Source/BansheeSL/Include \
-                         Source/RenderBeast/Include \
-                         Source/SBansheeEngine/Include \
-                         Source/SBansheeEditor/Include \
-                         Documentation/Manuals/Native
+INPUT                  = ../../Source/BansheeUtility/Include \
+                         ../../Source/BansheeCore/Include \
+                         ../../Source/BansheeEngine/Include \
+                         ../../Source/BansheeEditor/Include \
+                         ../../Source/BansheeD3D9RenderAPI/Include \
+                         ../../Source/BansheeD3D11RenderAPI/Include \
+                         ../../Source/BansheeGLRenderAPI/Include \
+                         ../../Source/BansheeFBXImporter/Include \
+                         ../../Source/BansheeFontImporter/Include \
+                         ../../Source/BansheeFreeImgImporter/Include \
+                         ../../Source/BansheeOISInput/Include \
+                         ../../Source/BansheePhysX/Include \
+                         ../../Source/BansheeSL/Include \
+                         ../../Source/RenderBeast/Include \
+                         ../../Source/BansheeMono/Include \
+                         ../../Source/SBansheeEngine/Include \
+                         ../../Source/SBansheeEditor/Include \
+                         ../Manuals/Native
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -873,7 +873,7 @@ RECURSIVE              = YES
 # Note that relative paths are relative to the directory from which doxygen is
 # run.
 
-EXCLUDE                = Source/BansheeUtility/Include/ThirdParty
+EXCLUDE                = ../../Source/BansheeUtility/Include/ThirdParty
 
 # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
 # directories that are symbolic links (a Unix file system feature) are excluded

+ 0 - 0
doxystyle.css → Documentation/Doxygen/doxystyle.css


+ 0 - 0
footer.html → Documentation/Doxygen/footer.html


+ 0 - 0
header.html → Documentation/Doxygen/header.html


+ 0 - 0
layout.xml → Documentation/Doxygen/layout.xml


+ 124 - 18
Documentation/Manuals/Native/renderer.md

@@ -139,7 +139,7 @@ const Vector<RenderQueueElement>& sortedElements = queue->getSortedElements();
 ~~~~~~~~~~~~~
 
 ### Renderer material {#renderer_b_a_b}
-Often the renderer needs to use special shaders for various effects (e.g. post-processing effects like FXAA). Unlike shaders and materials used by users, these shaders are built-in into the engine. Since we know they'll always be there we make make it easier for the renderer to load and use them by implementing the @ref BansheeEngine::RendererMaterial "RendererMaterial" interface:
+Often the renderer needs to use special shaders for various effects (e.g. post-processing effects like FXAA). Unlike shaders and materials used by users, these shaders are built-in into the engine. Since we know they'll always be there we can make it easier for the renderer to load and use them by implementing the @ref BansheeEngine::RendererMaterial "RendererMaterial" interface:
 ~~~~~~~~~~~~~{.cpp}
 // Set up a post-processing material
 class DownsampleMat : public RendererMaterial<DownsampleMat>
@@ -152,7 +152,7 @@ public:
 	{
 		// Retrieve material parameters, and perform other set-up
 		mInputTexture = mMaterial->getParamTexture("gInputTex");
-		mInvTexSize = mMaterial->getParamTexture("gInvTexSize");
+		mInvTexSize = mMaterial->getParamVec2("gInvTexSize");
 	}
 
 	// Set up parameters and render a full screen quad using the material
@@ -185,31 +185,137 @@ void DirectionalLightMat::_initDefines(ShaderDefines& defines)
 
 Renderer material implementation starts by deriving from @ref BansheeEngine::RendererMaterial<T> "RendererMaterial<T>". This is followed by a declaration of the @ref RMAT_DEF macro, which contains a path to the shader file. The shader file should be located in "Data/Raw/Engine/Shaders/" folder.
 
-You must also implement `_initDefines` method, which allows you to modify the compilation environment. It can be empty if not required, but it is useful if your shader has different settings in the form of \#ifdef blocks, in which case different renderer materials can reference the same file, but different options depending on what is set on this method. Be aware that all built-in shaders are pre-processed by the @ref BansheeEngine::BuiltinResources "BuiltinResources" manager. If you are changing define options you should delete the "Data/Engine/Timestamp.asset" file, which will force the manager to rebuild all shaders (and actually apply the new defines).
+You must also implement `_initDefines` method, which allows you to modify the compilation environment. It can be empty if not required, but it is useful if your shader has different settings in the form of \#ifdef blocks, in which case different renderer materials can reference the same file, but yield different results depending on what is set in this method. Be aware that all built-in shaders are pre-processed by the @ref BansheeEngine::BuiltinResources "BuiltinResources" manager. If you are changing define options you should delete the "Data/Engine/Timestamp.asset" file, which will force the manager to rebuild all shaders (and actually apply the new defines).
 
 Once these methods/macros are implemented, you can then instantiate your renderer material and access the @ref BansheeEngine::Material "Material" using the `mMaterial` field. Normally your material will have some parameters, which you'll want to retrieve in the constructor, and then set before rendering. 
 
-@see materials
-@see renderTargets
-@see renderAPI
+@see @ref materials to learn how to work with materials in general.
+@see @ref renderTargets to learn how to create and render to a render target.
 
 ### Parameter blocks {#renderer_b_a_c}
+If you shader has data parameters (like float, int, bool) it is efficient to group them into blocks of parameters. These blocks are better known as uniform buffers in OpenGL, or constant buffers in DX11. An example of such a buffer in HLSL looks like this:
+~~~~~~~~~~~~~{.cpp}
+// Contains various parameters specific to the current camera
+cbuffer PerCamera
+{
+	float3	 gViewDir;
+	float3 	 gViewOrigin;
+	float4x4 gMatViewProj;
+	float4x4 gMatView;
+	float4x4 gMatProj;
+	float4x4 gMatInvProj;
+	float4x4 gMatInvViewProj;			
+}
+~~~~~~~~~~~~~
+
+While you could assign these parameters using the standard way as described in the [material](@ref materials) manual:
+~~~~~~~~~~~~~{.cpp}
+MaterialParamVec3Core viewDirParam = mMaterial->getParamVec3("gViewDir");
+viewDirParam.set(Vector3(0.707.0, 0.707f, 0.0f));
+// Or just simply:
+// mMaterial->setVec3("gViewDir", Vector3(0.707.0, 0.707f, 0.0f));
+
+... repeat for all other parameters
+~~~~~~~~~~~~~
+
+It is more efficient to assign them as a parameter block. Primarily because parameter blocks can be set once, and then shared between multiple materials. To set up a parameter block use the @ref BS_PARAM_BLOCK_BEGIN, @ref BS_PARAM_BLOCK_ENTRY and @ref BS_PARAM_BLOCK_END macros, like so:
+
+~~~~~~~~~~~~~{.cpp}
+BS_PARAM_BLOCK_BEGIN(PerCameraParamBlock)
+	BS_PARAM_BLOCK_ENTRY(Vector3, gViewDir)
+	BS_PARAM_BLOCK_ENTRY(Vector3, gViewOrigin)
+	BS_PARAM_BLOCK_ENTRY(Matrix4, gMatViewProj)
+	BS_PARAM_BLOCK_ENTRY(Matrix4, gMatView)
+	BS_PARAM_BLOCK_ENTRY(Matrix4, gMatProj)
+	BS_PARAM_BLOCK_ENTRY(Matrix4, gMatInvProj)
+	BS_PARAM_BLOCK_ENTRY(Matrix4, gMatInvViewProj)
+BS_PARAM_BLOCK_END
+~~~~~~~~~~~~~
+
+By using this approach you lose all the error checking normally performed by @ref BansheeEngine::Material "Material". You must make sure that the layout in C++ matches the layout in the GPU program. In case of GLSL you must also specify `layout(std140)` keyword to ensure its layout is compatible with C++ struct layout. You must also make sure that variable names match the names in the GPU program.
+
+Once your parameter block is created, you can instantiate it, assign values to it, and assign the blocks to materials, like so:
+~~~~~~~~~~~~~{.cpp}
+PerCameraParamBlock block; // Instantiate block, normally you'd want to store this
+block.gViewDir.set(Vector3(0.707.0, 0.707f, 0.0f));
+... set other parameters in block ...
+
+SPtr<MaterialCore> material = ...;
+material->setParamBlockBuffer("PerCamera", block.getBuffer());
+
+... render using the material ...
+~~~~~~~~~~~~~
+
+Blocks are often used with renderer materials we described in the previous section, although we didn't use one in that example.
 
 ### Renderer semantics {#renderer_b_a_d}
+Renderer semantics allow user created shaders to request that certain parameters in a GPU program are populated by the renderer. See the [materials](@ref materials) and [BSLFX](@ref bslfx) manuals on how to specify such semantics. 
+
+For example the user might request a "VP" semantic, which could be recognized by the renderer that the shader requests a view-projection matrix. Such a matrix is not something that the user should have to assign to the material himself. The renderer can choose to parse material parameters looking for supported semantics, and assign their values.
+
+For example:
+~~~~~~~~~~~~~{.cpp}
+StringID RPS_ViewProjTfrm = "VP"; // Define semantic identifier
 
-		auto& texParams = mMaterial->getShader()->getTextureParams();
-		for (auto& entry : texParams)
-		{
-			if (entry.second.rendererSemantic == RPS_GBufferA)
-				mGBufferA = mMaterial->getParamTexture(entry.second.name);
-			else if (entry.second.rendererSemantic == RPS_GBufferB)
-				mGBufferB = mMaterial->getParamTexture(entry.second.name);
-			else if (entry.second.rendererSemantic == RPS_GBufferDepth)
-				mGBufferDepth = mMaterial->getParamTexture(entry.second.name);
-		}
+SPtr<MaterialCore> material = ...;
+SPtr<ShaderCore> shader = material->getShader();
+auto& dataParams = shader->getDataParams();
+for (auto& entry : texParams)
+{
+	if (entry.second.rendererSemantic == RPS_ViewProjTfrm)
+	{
+		// Found it, assign some value to the parameter
+		mMaterial->setMat4(entry.second.name, Matrix4::IDENTITY);
+		break;
+	}
+}
+~~~~~~~~~~~~~
+
+You can choose to implement semantics in your renderer, but they aren't required. You can just as easily require the user to use specific parameter names, and then use those names directly (like we used in previous examples in this manual).
 
 ### RendererUtility {#renderer_b_a_e}
 
-### RenderTargetPool {#renderer_b_a_f}
+@ref BansheeEngine::RendererUtility "RendererUtility" provides some commonly required functionality for rendering. For the most part these are just wrappers around @ref BansheeEngine::RenderAPI "RenderAPI" methods, so you don't have to set things like vertex/index buffers manually, as described in [render API](@ref renderAPI) manual.
+ - @ref BansheeEngine::RendererUtility::setPass "RendererUtility::setPass" - Binds a pass from a specific @ref BansheeEngine::Material "Material" for rendering. Any further draw calls will be rendered using this pass.
+ - @ref BansheeEngine::RendererUtility::setPassParams "RendererUtility::setPassParams" - Binds parameters (textures, samplers, etc.) from a @ref BansheeEngine::Material "Material". Any further draw calls will be rendered using these parameters.
+ - @ref BansheeEngine::RendererUtility::draw "RendererUtility::draw" - Draws a specific sub-mesh of the provided @ref BansheeEngine::MeshCore "Mesh", using the currently bound pass.
+ - @ref BansheeEngine::RendererUtility::blit "RendererUtility::blit" - Copies the contents of the provided texture into the currently bound render target.
+ - @ref BansheeEngine::RendererUtility::drawScreenQuad "RendererUtility::drawScreenQuad" - Draws a quad using the currently bound pass.
+ 
+Use @ref BansheeEngine::gRendererUtility "gRendererUtility" to access the @ref BansheeEngine::RendererUtility "RendererUtility" more easily.
+ 
+Binding a material and rendering using @ref BansheeEngine::RendererUtility "RendererUtility":
+~~~~~~~~~~~~~{.cpp}
+SPtr<MaterialCore> material = ...;
+SPtr<MeshCore> mesh = ...;
+
+gRendererUtility().setPass(material);
+... set material parameters ...
+gRendererUtility().setPassParams(material);
+gRendererUtility().draw(mesh, mesh->getProperties().getSubMesh(0));
+~~~~~~~~~~~~~
+ 
+### RenderTexturePool {#renderer_b_a_f}
+Although you can create render textures manually as described in the [render target](@ref renderTargets) manual, @ref BansheeEngine::RenderTexturePool "RenderTexturePool" provides a simpler and more efficient way of doing it. It will keep alive any referenced render textures, so that other systems may re-use them if their size/formats match. This can improve performance when using many temporary/intermediary render textures (like in post-processing).
+
+To request a render texture, first populate the @ref BansheeEngine::POOLED_RENDER_TEXTURE_DESC "POOLED_RENDER_TEXTURE_DESC" descriptor, by calling either @ref BansheeEngine::POOLED_RENDER_TEXTURE_DESC::create2D "POOLED_RENDER_TEXTURE_DESC::create2D", @ref BansheeEngine::POOLED_RENDER_TEXTURE_DESC::create3D "POOLED_RENDER_TEXTURE_DESC::create3D" or @ref BansheeEngine::POOLED_RENDER_TEXTURE_DESC::createCube "POOLED_RENDER_TEXTURE_DESC::createCube".
+
+Then call @ref BansheeEngine::RenderTexturePool::get "RenderTexturePool::get" which will either create a new render texture, or return one from the pool. The returned object is @ref BansheeEngine::PooledRenderTexture "PooledRenderTexture" from which you can access the actual render texture.
+
+Once you are done using the texture, call @ref BansheeEngine::RenderTexturePool::release "RenderTexturePool::release" to return the texture to the pool, and make it available for other systems. If you plan on using this texture again, make sure to keep a reference to the @ref BansheeEngine::PooledRenderTexture "PooledRenderTexture". This will prevent the pool from fully destroying the texture so it may be reused.
+
+For example:
+~~~~~~~~~~~~~{.cpp}
+POOLED_RENDER_TEXTURE_DESC desc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8G8B8A8, 1024, 1024);
+SPtr<PooledRenderTexture> pooledRT = RenderTexturePool::instance().get(desc);
+
+RenderAPICore::instance().setRenderTarget(pooledRT->renderTexture);
+... render to target ...
+RenderTexturePool::instance().release(pooledRT);
+// Keep a reference to pooledRT if we plan on re-using it, then next time just call get() using the same descriptor
+~~~~~~~~~~~~~
+
+### Renderer options {#renderer_b_a_g}
+You can customize your rendering at runtime by implementing the @ref BansheeEngine::CoreRendererOptions "RendererOptions" class. Your @ref BansheeEngine::CoreRendererOptions "RendererOptions" implementation can then be assigned to the renderer by calling @ref BansheeEngine::CoreRenderer::setOptions "Renderer::setOptions", and accessed within the renderer via the `mOptions` field. No default options are provided and it's up to your renderer to decide what it requires.
 
-### Renderer options {#renderer_b_a_g}
+Be aware that options are set from the simulation thread, and if you want to use them on the core thread to either properly synchronize the access, or send a copy of the options to the core thread.

+ 38 - 38
Documentation/Manuals/Native/rtti.md

@@ -4,7 +4,7 @@ Run-time type information						{#rtti}
 
 This manual describes how is run-time type information (RTTI) used to provide meta-information about C++ classes during program execution. In Banshee specifically it allows you to:
  - Serialize/deserialize objects with no additional code 
- - Get name of a class, and exact polymorphic type of an object (including safe casting)
+ - Get the name of a class, and exact polymorphic type of an object (including safe casting)
  - Get the hierarchy of base/derived classes of a specific type
  - Iterate over all fields in an object, find their name and type, get/set their value
  - Create new instances of a type with only its type-name
@@ -13,8 +13,8 @@ This manual describes how is run-time type information (RTTI) used to provide me
 It is primarily used for saving/loading of objects (e.g. serialization/deserialization of a level), searching for objects (e.g. finding all resources used by a level) and generating "diffs" (Prefabs use diffs to persist/apply instance specific changes when the original changes).
 
 RTTI doesn't automatically work on all classes. You must manually specify the information required by the RTTI system. This involves two things:
- - Making sure your class derives from `IReflectable` and implements the required methods
- - Implement a `RTTIType` class
+ - Making sure your class derives from @ref BansheeEngine::IReflectable "IReflectable" and implements the required methods
+ - Implement the @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType> "RTTIType" interface
  
 # Adding RTTI to your own objects {#rtti_a}
 Assume you have a simple object you want to serialize:
@@ -25,7 +25,7 @@ class Texture
 };
 ~~~~~~~~~~~~~
 
-First off ensure it implements `IReflectable` and `getRTTIStatic` and `getRTTI` methods:
+First off ensure it implements @ref BansheeEngine::IReflectable "IReflectable" and `getRTTIStatic` and `getRTTI` methods:
 ~~~~~~~~~~~~~{.cpp}
 class Texture : public IReflectable
 {
@@ -39,9 +39,9 @@ class Texture : public IReflectable
 };
 ~~~~~~~~~~~~~
 	
-This interface and its methods only serve to return an instance of `TextureRTTI`, which derives from `RTTIType` and contains all the necessary RTTI information. You will also usually want to make the RTTI type a `friend` of the type so it can easily access its private and protected fields.
+This interface and its methods only serve to return an instance of `TextureRTTI`, which derives from @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType> "RTTIType" and contains all the necessary RTTI information. You will also usually want to make the RTTI type a `friend` of the type so it can easily access its private and protected fields.
 
-A basic implementation of `RTTIType` must provide information about the type name, unique ID of the type, its base class (`IReflectable` if it doesn't derive from anything else), a way to create a new instance of the type and a list of fields with their getter/setter methods. A simple one for our example `Texture` class might look like so:
+A basic implementation of @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType> "RTTIType" must provide information about the type name, unique ID of the type, its base class (@ref BansheeEngine::IReflectable "IReflectable" if it doesn't derive from anything else), a way to create a new instance of the type and a list of fields with their getter/setter methods. A simple one for our example `Texture` class might look like so:
 ~~~~~~~~~~~~~{.cpp}
 class TextureRTTI : public RTTIType<Texture, IReflectable, TextureRTTI> // Specify type the RTTI is for, its base type, and RTTI type itself
 {
@@ -56,8 +56,8 @@ class TextureRTTI : public RTTIType<Texture, IReflectable, TextureRTTI> // Speci
 	TextureRTTI ()
 	{
 		// Register the getter/setter methods above. You must specify a name and field id (both must be unique within the type).
-		addPlainField(“width”, 0, &TextureRTTI::getWidth, &TextureRTTI::setWidth);
-		addPlainField(“height”, 1, &TextureRTTI::getHeight, &TextureRTTI::setHeight);
+		addPlainField("width", 0, &TextureRTTI::getWidth, &TextureRTTI::setWidth);
+		addPlainField("height", 1, &TextureRTTI::getHeight, &TextureRTTI::setHeight);
 	}
 
 	const String& getRTTIName() override
@@ -78,21 +78,21 @@ class TextureRTTI : public RTTIType<Texture, IReflectable, TextureRTTI> // Speci
 };
 ~~~~~~~~~~~~~
 
-This is the minimum you need to do to add a RTTI type. However there are some advanced features that you might be interested in. You may specify different types of fields that can handle references to other complex objects, as well as provide arrays, or supply a pre- and post- processing steps for serialization. We'll cover this in the next chapters.
+This is the minimum you need to do to add a RTTI type. However there are some advanced features that you might be interested in. You may specify different types of fields that can handle references to other complex objects, as well as provide arrays, or supply a pre- and post- processing steps for serialization. We'll cover this in the next sections.
 
 Important thing to note about RTTI type fields is that they all require a unique ID. This ID ensures that serialized data isn't broken if the layout of the object changes during development. This means you can add new fields, or remove old ones and expect data saved using an older version to "just work". You do need to ensure never to assign an ID of a previously removed field to a new field. You also need to change the ID if the field's type changes (i.e. it used to be `int` but now it's `long`).
 
 # Advanced field types  {#rtti_b}
 
-When registering fields with the RTTI type, the systems supports a several sets of `add*Field` methods, each expecting a unique name/id, but different getter/setter methods and each field type has a special purpose.
+When registering fields with the RTTI type, the systems supports a several sets of `add*Field` methods, each expecting a unique name/id, but different getter/setter methods.
 
 ## Plain fields  {#rtti_b_a}
 In the example above we have shown how to provide getter/setter methods for fields of `int` type. These fields are considered "plain" fields by the engine, and fields for types like `float`, `bool` and any other built-in language type also falls into this category.
 
-You register plain fields by calling `addPlainField`. The getter/setter methods must return/accept a reference to the value of the field.
+You register plain fields by calling @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::addPlainField "RTTIType::addPlainField". The getter/setter methods must return/accept a reference to the value of the field.
 
 ## Reflectable fields  {#rtti_b_b}
-Reflectable fields contain types deriving from `IReflectable`, that is complex objects that contain their own RTTI types. For example if we were to add a `Material` class to our example, it might contain a texture. In such case we would provide getter/setter methods like so:
+Reflectable fields contain types deriving from @ref BansheeEngine::IReflectable "IReflectable", meaning they're complex objects that contain their own RTTI types. For example if we were to add a `Material` class to our example, it might contain a texture. In such case we would provide getter/setter methods like so:
 ~~~~~~~~~~~~~{.cpp}
 class Material : public IReflectable
 { 
@@ -115,14 +115,14 @@ class MaterialRTTI : public RTTIType<Material, IReflectable, MaterialRTTI>
 };
 ~~~~~~~~~~~~~
 
-As you can see the reflectable field is similar to a plain field, only the `addReflectableField` method is used. 
+As you can see the reflectable field is similar to a plain field, only the @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::addReflectableField "RTTIType::addReflectableField" method is used instead. 
 
 The problem with this approach is that during serialization whenever a material references a texture, that entire texture will end up being serialized with it. This is something you normally want to avoid since multiple materials will usually be referencing the same texture. For that purpose "Reflectable pointer" fields exist.
 
 ## Reflectable pointer fields  {#rtti_b_c}
-This fields are similar to reflectable fields, as they also contain types deriving from `IReflectable`. However they only return a pointer to the owned object, instead of copying the object by value. This is relevant for serialization as the system will be smart enough to detect multiple fields pointing to the same instance of an `IReflectable` object, and only serialize it once (instead of every time it is encountered). When deserializing the system will also properly restore the pointers, so that all fields keep pointing to the same instance.
+This type of field is similar to the reflectable field, as it also contains types deriving from @ref BansheeEngine::IReflectable "IReflectable". However they only return a pointer to the owned object, instead of copying the object by value. This is relevant for serialization as the system will be smart enough to detect multiple fields pointing to the same instance of an @ref BansheeEngine::IReflectable "IReflectable" object, and only serialize it once (instead of every time it is encountered). When deserializing the system will also properly restore the pointers, so that all fields keep pointing to the same instance.
 
-Reflectable pointer getter/setter methods must return shared pointers to the instance. For example if we modified our Material class like so:
+Reflectable pointer getter/setter methods must return shared pointers to the instance, and they're registered with @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::addReflectablePtrField "RTTIType::addReflectablePtrField". For example if we modified our `Material` class like so:
 ~~~~~~~~~~~~~{.cpp}
 class Material : public IReflectable
 { 
@@ -146,7 +146,7 @@ class MaterialRTTI : public RTTIType<Material, IReflectable, MaterialRTTI>
 ~~~~~~~~~~~~~
 
 ## Array fields  {#rtti_b_d}
-Each of the valid field types (plain/reflectable/reflectable pointer), also come in array form. The array form requires two additional getter/setter methods that return/set array size, and normal getter/setter require an extra index parameter. For example if we wanted to extend our material so it contains multiple textures:
+Each of the valid field types (plain/reflectable/reflectable pointer), also come in array form. The array form requires two additional getter/setter methods that get/set array size, and normal getter/setter methods require an additional index parameter. For example if we wanted to extend our material so it contains multiple textures:
 ~~~~~~~~~~~~~{.cpp}
 class Material : public IReflectable
 { 
@@ -174,24 +174,24 @@ class MaterialRTTI : public RTTIType<Material, IReflectable, MaterialRTTI>
 ~~~~~~~~~~~~~
 
 Methods for registering array fields are:
- - addPlainArrayField
- - addReflectableArrayField
- - addReflectablePtrArrayField
+ - @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::addPlainArrayField "RTTIType::addPlainArrayField"
+ - @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::addReflectableArrayField "RTTIType::addReflectableArrayField"
+ - @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::addReflectablePtrArrayField "RTTIType::addReflectablePtrArrayField"
 
 They all follow the same syntax as in the example above.
  
 ## Advanced plain fields  {#rtti_b_e}
-Although plain fields are primarily intended for simple built-in types, sometimes it also needs to be used on complex types. For example a `std::string` is often used as a field type, but it is not a simple built-in type, nor can we make it derive from `IReflectable`. For these purposes you can use `RTTIPlainType`. This is a templated class you can specialize for your specific type. 
+Although plain fields are primarily intended for simple built-in types, sometimes they also needs to be used on complex types. For example a `std::string` is often used as a field type, but it is not a simple built-in type, nor can we make it derive from @ref BansheeEngine::IReflectable "IReflectable" so we can't use reflectable fields either. For these purposes you can use @ref BansheeEngine::RTTIPlainType<T> "RTTIPlainType". This is a templated class you can specialize for your specific type. 
 
 It provides methods for serializing/deserializing and retrieving object size. It has no advanced functionality like versioning (so if the structure of the type changes, it will break any previously serialized data), or keeping references to other objects.
 
 For example if we wanted to serialize a string:
 ~~~~~~~~~~~~~{.cpp}
-template<> struct RTTIPlainType<String>
+template<> struct RTTIPlainType<std::string>
 {	
 	enum { id = 20 }; enum { hasDynamicSize = 1 }; // Provide unique ID, and a flag whether the size of the structure is dynamic.
 
-	static void toMemory(const String& data, char* memory)
+	static void toMemory(const std::string& data, char* memory)
 	{ 
 		UINT32 size = getDynamicSize(data);
 
@@ -201,44 +201,44 @@ template<> struct RTTIPlainType<String>
 		memcpy(memory, data.data(), size); 
 	}
 
-	static UINT32 fromMemory(String& data, char* memory)
+	static UINT32 fromMemory(std::string& data, char* memory)
 	{ 
 		UINT32 size;
 		memcpy(&size, memory, sizeof(UINT32)); 
 		memory += sizeof(UINT32);
 
 		UINT32 stringSize = size - sizeof(UINT32);
-		data = String(memory, stringSize);
+		data = std::string(memory, stringSize);
 
 		return size;
 	}
 
-	static UINT32 getDynamicSize(const String& data)	
+	static UINT32 getDynamicSize(const std::string& data)	
 	{ 
-		UINT64 dataSize = data.size() * sizeof(String::value_type) + sizeof(UINT32);
+		UINT64 dataSize = data.size() * sizeof(std::string::value_type) + sizeof(UINT32);
 		return (UINT32)dataSize;
 	}	
 }; 
 ~~~~~~~~~~~~~
 
-Each specialization must implement all three (toMemory/fromMemory/getDynamicSize) methods. It must also provide a flag whether or not it has dynamic size. Any structure whose size varies with each instance must set this flag to true. You must also set it to true if the size is static but larger than 255 bytes (This flag is just an optimization that can save a little space in serialized data when disabled).
+Each specialization must implement all three (`toMemory/fromMemory/getDynamicSize`) methods. It must also provide a flag `hasDynamicSize` which determines whether or not it has dynamic size. Any structure whose size varies with each instance must set this flag to true. You must also set it to true if the size is static but larger than 255 bytes.
 
-After you implement this class you will be able to use it in getters/setters for `addPlainField`. You can also use the BS_ALLOW_MEMCPY_SERIALIZATION macro for simple structures. It will create a basic `RTTIPlainType` specialization which uses memcpy()/sizeof() to implement the necessary methods.
+After you implement this class you will be able to use the type in getters/setters for plain fields as you would `int` or `float`. You can also use the @ref BS_ALLOW_MEMCPY_SERIALIZATION macro for simple structures. It will create a basic @ref BansheeEngine::RTTIPlainType<T> "RTTIPlainType" specialization which uses `memcpy()`/`sizeof()` to implement the necessary methods.
 
-If possible you should prefer implementing an `IReflectable` for complex objects instead of this approach. But it can be useful for types where no other option is available (like third party or standard library types) or types you are sure won't change or require other advanced functionality.
+If possible you should prefer implementing an @ref BansheeEngine::IReflectable "IReflectable" for complex objects instead of this approach. But it can be useful for types where no other option is available (like third party or standard library types) or types you are sure won't change or require other advanced functionality.
 
-`RTTIPlainType` specializations can also be used as a more traditional form of serialization in case you find the RTTI system an overkill. For example if you needed to transfer data over a network. The system provides helper methods that allow you to easily work with plain types in such case:
- - char* rttiReadElem(Type&, char*); // Deserializes the element from the provided buffer and returns offset into the buffer after the read data
- - char* rttiWriteElem(Type&, char*); // Serializes the element into the provided buffer and returns offset into the buffer after the written data
- - UINT32 rttiGetElemSize(Type&); // Returns a size of a specific plain type
+@ref BansheeEngine::RTTIPlainType<T> "RTTIPlainType" specializations can also be used as a more traditional form of serialization in case you find the RTTI system an overkill. For example if you needed to transfer data over a network. The system provides helper methods that allow you to easily work with plain types in such a case:
+ - @ref BansheeEngine::rttiReadElem "rttiReadElem" - Deserializes an object from the provided buffer and returns offset into the buffer after the read data
+ - @ref BansheeEngine::rttiWriteElem "rttiWriteElem" - Serializes an object into the provided buffer and returns offset into the buffer after the written data
+ - @ref BansheeEngine::rttiGetElemSize "rttiGetElemSize" - Returns a size an object
 
 # Advanced serialization  {#rtti_c}
-Implementations of `RTTIType` can optionally implement `onSerializationStarted´, `onSerializationEnded`, `onDeserializationStarted` and `onDeserializationEnded` methods. As their names imply they will get called during serialization/deserialization and allow you to do any pre- or post-processing of the data. Most other systems (other than serialization) that access field data will also call these functions before reading, and after writing field data.
+Implementations of @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType> "RTTIType" can optionally override @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::onSerializationStarted "RTTIType::onSerializationStarted", @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::onSerializationEnded "RTTIType::onSerializationEnded", @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::onDeserializationStarted "RTTIType::onDeserializationStarted" and @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::onDeserializationEnded "RTTIType::onDeserializationEnded" methods. As their names imply they will get called during serialization/deserialization and allow you to do any pre- or post-processing of the data. Most other systems (other than serialization) that access field data will also call these functions before reading, and after writing field data.
 
-Each of those methods accepts an `IReflectable` pointer to the object currently being processed. Each type that implements `IReflectable` also comes with a `mRTTIData` field which is of `Any` type, and can be used for storing temporary data during serialization/deserialization (primarily along the methods above).
+Each of those methods accepts an @ref BansheeEngine::IReflectable "IReflectable" pointer to the object currently being processed. Each type that implements @ref BansheeEngine::IReflectable "IReflectable" also comes with a `mRTTIData` field which is of @ref BansheeEngine::Any "Any" type, and can be used for storing temporary data during serialization/deserialization (primarily when using the methods above).
 
 # Using RTTI  {#rtti_d}
-Once you have an object with a RTTI type fully implement it you can use it for various purposes.
+Once you have an object with a RTTI type fully implemented you can use it for various purposes.
 
 ## Getting object information  {#rtti_d_a}
 
@@ -270,9 +270,9 @@ rttiField->isArray(); // Does the field contain an array
 ~~~~~~~~~~~~~
 
 ## Serialization  {#rtti_d_b}
-Serialization uses all the features shown in the chapter above in order to serialize an `IReflectable` object into a stream of bytes, and vice versa. By default binary serialization is used, but user can implement textual serialization (like XML or JSON) using the RTTI system, if needed.
+Serialization uses all the features shown in the chapter above in order to serialize an @ref BansheeEngine::IReflectable "IReflectable" object into a stream of bytes, and vice versa. By default binary serialization is used, but user can implement textual serialization (like XML or JSON) using the RTTI system, if needed.
 
-Binary serialized data can be output to memory, or to a file using: `MemorySerializer`, `FileEncoder`, `FileDecoder`. Their usage is simple:
+Binary serialized data can be output to memory, or to a file using: @ref BansheeEngine::MemorySerializer "MemorySerializer", @ref BansheeEngine::FileEncoder "FileEncoder", @ref BansheeEngine::FileDecoder "FileDecoder". Their usage is simple:
 ~~~~~~~~~~~~~{.cpp}
 IReflectable* myObject = ...;
 

+ 41 - 38
Documentation/Manuals/Native/scripting.md

@@ -10,12 +10,10 @@ Before we delve into the specifics of Banshee's scripting you should understand
 
 Because using Mono directly is complex (mostly due to its lack of documentation), Banshee provides a set of easy to use wrappers for almost all of Mono related functionality. 
 
-BansheeMono is a plugin that wraps the functionality of the Mono runtime. Here is where the Mono runtime is started and assemblies are loaded (and unloaded), while also giving you detailed information about all loaded classes and a way to communicate with managed code.
-
-The main entry point is the @ref BansheeEngine::MonoManager "MonoManager" class which allows you to start the runtime and load assemblies. The most important method here is @ref BansheeEngine::MonoManager::loadAssembly "MonoManager::loadAssembly". It takes as assembly path to load and returns a @ref BansheeEngine::MonoAssembly "MonoAssembly" object. 
+BansheeMono is a plugin that wraps the functionality of the Mono runtime. The main entry point of the scripting system is the @ref BansheeEngine::MonoManager "MonoManager" class which allows you to start the runtime and load managed (script) assemblies. The most important method here is @ref BansheeEngine::MonoManager::loadAssembly "MonoManager::loadAssembly". It loads all the script code from the managed assembly at the provided path, and provides meta-data for the entire assembly through the returned @ref BansheeEngine::MonoAssembly "MonoAssembly" object. 
 
 ## MonoAssembly 	{#scripting_a_a}
-@ref BansheeEngine::MonoAssembly "MonoAssembly" gives you access to all classes in the assembly. You can retrieve all clases using @ref BansheeEngine::MonoAssembly::getAllClasses "MonoAssembly::getAllClasses", or retrieve a specific one by calling @ref BansheeEngine::MonoAssembly::getClass(const String&, const String&) const "MonoAssembly::getClass(namespace, typename)". Both of these methods return a @ref BansheeEngine::MonoClass "MonoClass" object.
+@ref BansheeEngine::MonoAssembly "MonoAssembly" gives you access to all the script classes in an assembly. You can retrieve all clases using @ref BansheeEngine::MonoAssembly::getAllClasses "MonoAssembly::getAllClasses", or retrieve a specific one by calling @ref BansheeEngine::MonoAssembly::getClass(const String&, const String&) const "MonoAssembly::getClass(namespace, typename)". Both of these methods return a @ref BansheeEngine::MonoClass "MonoClass" object.
 
 ## MonoClass 	{#scripting_a_b}
 @ref BansheeEngine::MonoClass "MonoClass" gives you access to all methods, fields, properties and attributes of a specific class. It also allows you to register "internal" methods. These methods allow the managed code to call C++ code, and we'll go into them later.
@@ -27,25 +25,25 @@ To retrieve a method from a class call @ref BansheeEngine::MonoClass::getMethod(
 All the above methods return a @ref BansheeEngine::MonoMethod "MonoMethod" object.
 
 ## MonoMethod {#scripting_a_c}
-This class provides information about about a managed method, as well as giving you multiple ways of invoking it.
+This class provides information about about a managed method, as well as giving you multiple ways of invoking it (it allows you to call C# methods from C++).
 
 To invoke a method you may use multiple approaches:
- - @ref BansheeEngine::MonoMethod::invoke "MonoMethod::invoke" - Calls the exact method on a specific managed object, with the provided parameters. We'll take about how managed objects are referenced in native code later, as well as how passing data between C++ and managed code works.
+ - @ref BansheeEngine::MonoMethod::invoke "MonoMethod::invoke" - Calls the exact method on a specific managed object, with the provided parameters. We'll see how are managed objects referenced in native code later, as well as how passing data between C++ and managed code works.
  - @ref BansheeEngine::MonoMethod::invokeVirtual "MonoMethod::invokeVirtual" - Calls the method polymorphically. Determines the actual type of the provided managed object instance and calls an overriden method if available.
- - @ref BansheeEngine::MonoMethod::getThunk const "MonoMethod::getThunk" - Returns a C++ function pointer accepting a managed object, zero or more parameters and an exception object. You can then call the function pointer like you would a C++ function. This is equivalent to @ref BansheeEngine::MonoMethod::invoke "MonoMethod::invoke" but is significantly faster. A helper method @ref BansheeEngine::MonoUtil::invokeThunk<T, Args> "MonoUtil::invokeThunk" is provided - it is suggested you use it instead of calling thunks manually (it handles exceptions internally).
+ - @ref BansheeEngine::MonoMethod::getThunk "MonoMethod::getThunk" - Returns a C++ function pointer accepting a managed object, zero or more parameters and an exception object. You can then call the function pointer like you would a C++ function. This is equivalent to @ref BansheeEngine::MonoMethod::invoke "MonoMethod::invoke" but is significantly faster. A helper method @ref BansheeEngine::MonoUtil::invokeThunk<T, Args> "MonoUtil::invokeThunk" is provided - it is suggested you use it instead of calling thunks manually (it handles exceptions internally).
 
 When calling static methods you should provide a null value for the managed object instance.
 
 ## MonoField {#scripting_a_d}
-Similar to methods, field information can be retrieved from @ref BansheeEngine::MonoClass "MonoClass" by calling @ref BansheeEngine::MonoClass::getField "MonoClass::getField" or @ref BansheeEngine::MonoClass::getAllFields "MonoClass::getAllFields". The returned value is a @ref BansheeEngine::MonoField "MonoField" which provides information about the field and allows you to retrieve and set values in the field using @ref BansheeEngine::MonoField::getValue "MonoField::getValue" / @ref BansheeEngine::MonoField::setValue "MonoField::setValue". This works similar to how methods are invoked and is explained in more detail later.
+Similar to methods, field information can be retrieved from a @ref BansheeEngine::MonoClass "MonoClass" object by calling @ref BansheeEngine::MonoClass::getField "MonoClass::getField" or @ref BansheeEngine::MonoClass::getAllFields "MonoClass::getAllFields". The returned value is a @ref BansheeEngine::MonoField "MonoField" which provides information about the field and allows you to retrieve and set values in the field using @ref BansheeEngine::MonoField::getValue "MonoField::getValue" / @ref BansheeEngine::MonoField::setValue "MonoField::setValue". This works similar to how methods are invoked and is explained in more detail later.
 
 ## MonoProperty {#scripting_a_e}
-Properties are very similar to fields, retrieved from @ref BansheeEngine::MonoClass "MonoClass" by calling @ref BansheeEngine::MonoClass::getProperty "MonoClass::getProperty". The returned value is a @ref BansheeEngine::MonoProperty "MonoProperty" which provides information about the property and allows you to retrieve and set values in it. The main difference is that properties in C# can be indexed (like arrays) and therefore a two set of set/get methods are provided, one accepting an index and other one not. It's up to the user to know which one to call. The methods are @ref BansheeEngine::MonoProperty::get "MonoProperty::get" / @ref BansheeEngine::MonoProperty::set "MonoProperty::set" and @ref BansheeEngine::MonoProperty::getIndexed "MonoProperty::getIndexed" / @ref BansheeEngine::MonoProperty::setIndexed "MonoProperty::setIndexed".
+Properties are very similar to fields, retrieved from a @ref BansheeEngine::MonoClass "MonoClass" object by calling @ref BansheeEngine::MonoClass::getProperty "MonoClass::getProperty". The returned value is a @ref BansheeEngine::MonoProperty "MonoProperty" which provides information about the property and allows you to retrieve and set values on it. The main difference is that properties in C# can be indexed (like arrays) and therefore a two set of set/get methods are provided, one accepting an index and other one not. It's up to the user to know which one to call. The methods are @ref BansheeEngine::MonoProperty::get "MonoProperty::get" / @ref BansheeEngine::MonoProperty::set "MonoProperty::set" and @ref BansheeEngine::MonoProperty::getIndexed "MonoProperty::getIndexed" / @ref BansheeEngine::MonoProperty::setIndexed "MonoProperty::setIndexed".
 
 ## Attributes {#scripting_a_f}
 Attributes provide data about a class, method or field provided at runtime, which usually allows such objects to be specialized in some regard. Attributes don't have their own wrapper, because they are esentially normal managed objects and you can work with them as such.
 
-To retrieve a list of attributes from a class use @ref BansheeEngine::MonoClass::getAllAttributes() "MonoClass::getAllAttributes", which returns a list of @ref BansheeEngine::MonoClass "MonoClass" objects that identify the attribute types. To get the actual object instance of the attribute you may call @ref BansheeEngine::MonoClass::getAttribute "MonoClass::getAttribute" with the wanted attribute @ref BansheeEngine::MonoClass "MonoClass". After that you can call methods, work with field values and other, same as you would with a normal object.
+To retrieve a list of attributes from a class use @ref BansheeEngine::MonoClass::getAllAttributes() "MonoClass::getAllAttributes", which returns a list of @ref BansheeEngine::MonoClass "MonoClass" objects that identify the attribute types. To get the actual object instance of the attribute you may call @ref BansheeEngine::MonoClass::getAttribute "MonoClass::getAttribute" with the wanted attribute's @ref BansheeEngine::MonoClass "MonoClass". After that you can call methods, work with field values and other, same as you would with a normal managed object (described below).
 
 Attributes can also be retrieved from a @ref BansheeEngine::MonoMethod "MonoMethod" using @ref BansheeEngine::MonoMethod::getAttribute "MonoMethod::getAttribute", or from @ref BansheeEngine::MonoField "MonoField" using @ref BansheeEngine::MonoField::getAttribute "MonoField::getAttribute".
 
@@ -54,12 +52,12 @@ So far we have talked about invoking methods and retrieving field values, but we
 
 For example, when calling a non-static method the first parameter provided to @ref BansheeEngine::MonoMethod::invoke "MonoMethod::invoke" is a `MonoObject` pointer. Same goes for retrieving or setting values on fields, properties. Attributes are also a `MonoObject`.
 
-Mono also provides two more specialized types: `MonoArray` for managed arrays, and `MonoString` for managed strings, but they are both still a `MonoObject`.
+Mono also provides two more specialized types of managed objects: `MonoArray` for managed arrays, and `MonoString` for managed strings, but they are both still a `MonoObject`.
 
 Be aware that all managed objects are garbage collected. This means you should not keep a reference to them unless you are sure they are alive. Just having a pointer to a `MonoObject` will not keep the object alive and it may go out of scope as soon as the control returns to managed code. A good way to deal with this issue is:
  - Call a native method in the object's finalizer (`~MyObject()`) which will notify you when the object is no longer valid. Be aware that finalizer may be called after the object is unusable.
  - Require the user to manually destroy the object by calling a custom `Destroy` method or similar.
- - Force the garbage collector to keep the object alive by calling `mono_gchandle_new` which will return a handle to the object. The handle will keep the object alive until you release it by calling `mono_gchandle_free`. Be aware if an assembly the object belongs to is unloaded all objects will be destroyed regardless of the kept handles.
+ - Force the garbage collector to keep the object alive by calling `mono_gchandle_new` which will return a handle to the object. The handle will keep the object alive until you release it by calling `mono_gchandle_free`. Be aware if an assembly the object belongs to is unloaded all objects will be destroyed regardless of kept handles.
  
 ## Marshalling data {#scripting_a_h}
 Mono does not perform automatic marshalling of data when calling managed code from C++ (or vice versa). This is important when calling methods, retrieving/setting field/property values, and responding to calls from managed code, because you need to know in what format to expect the data.
@@ -67,21 +65,21 @@ Mono does not perform automatic marshalling of data when calling managed code fr
 The rules are:
  - All primitive types are passed as is. e.g. an `int` in C# will be a 4 byte integer in C++, a `float` will be a float, a `bool` will be a bool.
  - All reference types (`class` in C#) are passed as a `MonoObject*`. Strings and arrays are handled specially, where strings are passed as `MonoString*`, and arrays as `MonoArray*`.
-   - If a reference type parameter in a method is prefixed with an `out` modifier, then the received parameters are `MonoObject**`, `MonoString**`, `MonoArray**` and your method is expected to populate those values.
- - Structs (non-primitive value types) are provided as raw memory. Make sure that all structs in C# that require marshalling have a `[StructLayout(LayoutKind.Sequential)]` attribute, which ensures they have the same memory layout as C++ structs. This way you can just accept the raw C++ structure and read it with no additional conversion.
-  - It is suggested you never pass structures by value, it is known to cause problems in Mono. Instead pass all structures by prefixing them with `ref` which will give you a pointer to the structure in managed code (e.g. `MyStruct*`). If you need to output a struct use the `out` modifier which you will give you a double pointer (e.g. `MyStruct**`).
+   - If a reference type parameter in a method in managed code is prefixed with an `out` modifier, then the received parameters are `MonoObject**`, `MonoString**`, `MonoArray**` and your method is expected to populate those values.
+ - Structs (non-primitive value types, `struct` in C#) are provided as raw memory. Make sure that all structs in C# that require marshalling have a `[StructLayout(LayoutKind.Sequential)]` attribute, which ensures they have the same memory layout as C++ structs. This way you can just accept the raw C++ structure and read it with no additional conversion.
+  - It is suggested you never pass structures by value, it is known to cause problems in Mono. Instead pass all structures by prefixing them with `ref` which will give you a pointer to the structure (e.g. `MyStruct*`). If you need to output a struct use the `out` modifier which you will give you a double pointer (e.g. `MyStruct**`).
   - In cases where it is not possible to avoid passing structures by value (e.g. when retrieving them from a field, use the @ref BansheeEngine::MonoField::getValueBoxed "MonoField::getValueBoxed" method instead @ref BansheeEngine::MonoField::getValue "MonoField::getValue", which will return a struct in the form of a `MonoObject`. You can then retrieve the raw struct value by calling `mono_object_unbox`.
   - Everything above applies only when managed code is calling C++. When calling into managed code from C++, all structs need to be boxed (i.e. converted to `MonoObject`). Use `mono_value_box` to convert a C++ struct into a `MonoObject*`. See @ref BansheeEngine::ScriptVector3 "ScriptVector3" for an example implementation.
   
-Banshee provides a helper code to assist with marshalling string:
+Banshee provides a helper code to assist with marshalling strings:
  - @ref BansheeEngine::MonoUtil::monoToWString "MonoUtil::monoToWString" / @ref BansheeEngine::MonoUtil::monoToString "MonoUtil::monoToString" - Converts a `MonoString*` to a native string
  - @ref BansheeEngine::MonoUtil::wstringToMono "MonoUtil::wstringToMono" / @ref BansheeEngine::MonoUtil::stringToMono "MonoUtil::stringToMono" - Converts a native string into a `MonoString*`
 
-@ref BansheeEngine::ScriptArray "ScriptArray" allows you to construct new arrays and read managed arrays, easily. 
+@ref BansheeEngine::ScriptArray "ScriptArray" is a helper class that allows you to construct new arrays and read managed arrays, easily. 
 
 To create a new arrays call @ref BansheeEngine::ScriptArray::create "ScriptArray<Type>::create". Type can be a primitive type like `int`, `float`, a native string or a `Script*` object (more about `Script*` objects later). You can then fill the array by calling @ref BansheeEngine::ScriptArray::set "ScriptArray::set" and retrieve the managed `MonoArray*` by calling @ref BansheeEngine::ScriptArray::getInternal "ScriptArray::getInternal".
 
-To more easily read existing arrays create a new @ref BansheeEngine::ScriptArray "ScriptArray" by providing it with a `MonoArray*` as its parameters. Then you can easily retrieve the size of the array using @ref BansheeEngine::ScriptArray::size() "ScriptArray::size()", and the value of its elements by calling @ref BansheeEngine::ScriptArray::get "ScriptArray::get<Type>"". 
+To more easily read existing arrays create a new @ref BansheeEngine::ScriptArray "ScriptArray" by providing it with a `MonoArray*` in the constructor. Then you can easily retrieve the size of the array using @ref BansheeEngine::ScriptArray::size() "ScriptArray::size()", and the value of its elements by calling @ref BansheeEngine::ScriptArray::get "ScriptArray::get<Type>"". 
 
 ## Internal methods {#scripting_a_i}
 So far we have talked about calling managed code, and retrieving information about managed types, but we have yet to show how managed code calls C++ code. This is accomplished using native methods.
@@ -92,14 +90,19 @@ The first step is to define a stub method in managed code, like so:
 private static extern float Internal_GetSomeValue(MyObject obj);
 ~~~~~~~~~~~~~
 	
-You then hook up this method with managed code by calling @ref BansheeEngine::MonoClass::addInternalCall "MonoClass::addInternalCall". In this specific case it would be `myClass->addInternalCall("Internal_GetSomeValue", &myNativeFunction)`, assuming `myClass` is a @ref BansheeEngine::MonoClass "MonoClass" of the type that contains the stub method. After this call any call to the managed stub method will call the provided native function `myNativeFunction`. You should take care to properly handle parameter passing as described above.
+You then hook up this method with managed code by calling @ref BansheeEngine::MonoClass::addInternalCall "MonoClass::addInternalCall". In this specific case it would be:
+~~~~~~~~~~~~~{.cpp}
+myClass->addInternalCall("Internal_GetSomeValue", &myNativeFunction);
+~~~~~~~~~~~~~
+
+Assuming `myClass` is a @ref BansheeEngine::MonoClass "MonoClass" of the type that contains the stub method. After this call any call to the managed stub method will call the provided native function `myNativeFunction`. You should take care to properly handle parameter passing as described above.
 
 Take a look at @ref BansheeEngine::ScriptGUISkin "ScriptGUISkin" implementation for a simple example of how exactly does this work. 
 
 # Script objects {#scripting_b}
 As you can see interaction between the two languages can get a bit cumbersome. For that reason Banshee implements a higher level system built on the functionality shown so far. It provides an universal interface all script objects must implement. It primarily ensures that native and managed code is always linked by keeping a pointer to each other's objects, as well as gracefully handling managed object destruction and handling assembly refresh (due to script hot-swap).
 
-When creating a new class available for scripting you need to add two things:
+When exposing a class to the scripting interface you need to add two things:
  - A native interop object (C++)
  - Managed wrapper for the class (C#)
 
@@ -120,21 +123,21 @@ private:
 };
 ~~~~~~~~~~~~~	
 	
-All `ScriptObject`s must begin with a `SCRIPT_OBJ` macro. The macro accepts (in order): 
+All @ref BansheeEngine::ScriptObject "ScriptObjects" must begin with a @ref SCRIPT_OBJ macro. The macro accepts (in order): 
  - the name of the assembly (.dll) the manager script object is in, this is either `ENGINE_ASSEMBLY` or `EDITOR_ASSEMBLY`
  - the namespace the type is in
  - the name of the managed type
 
-`SCRIPT_OBJ` macro also defines a static `initRuntimeData()` method you need to implement (more on that later).
+@ref SCRIPT_OBJ macro also defines a static `initRuntimeData()` method you need to implement (more on that later).
 
-When constructing a `ScriptObject` you must also provide a pointer to the managed object that wraps it (note the constructor). If the `ScriptObject` is used for a class that is static then the constructor is of no consequence as the `ScriptObject` itself never needs to be instantiated (all of its methods will be static). 
+When constructing a @ref BansheeEngine::ScriptObject "ScriptObject" you must also provide a pointer to the managed object that wraps it (note the constructor). If the @ref BansheeEngine::ScriptObject "ScriptObject" is used for a class that is static then the constructor is of no consequence as the @ref BansheeEngine::ScriptObject "ScriptObject" itself never needs to be instantiated (all of its methods will be static). 
  
-The two last method definitions are called from C# (via an internal call, see the section about internal methods earlier).
+The two last method definitions in the example are called from C# (via an internal call, see the section about internal methods earlier).
 
 ### initRuntimeData ### {#scripting_b_a_a}
-`initRuntimeData` is a static method that every `ScriptObject` needs to implement. It takes care of hooking up managed internal methods to C++ functions. It gets called automatically whenever the assembly containing the related managed class is loaded. 
+`initRuntimeData` is a static method that every @ref BansheeEngine::ScriptObject "ScriptObject" needs to implement. It takes care of hooking up managed internal methods to C++ functions. It gets called automatically whenever the assembly containing the related managed class is loaded. 
 
-Every `ScriptObject` provides a static @ref BansheeEngine::ScriptObject<Type, Base>::getMetaData "metaData" structure you can use for retrieving the @ref BansheeEngine::MonoClass "MonoClass" of the related managed class. You can use that @ref BansheeEngine::MonoClass "MonoClass" to register internal methods to it (as described earlier). For example a basic `initRuntimeData()` might look like so:
+Every @ref BansheeEngine::ScriptObject "ScriptObject" provides a static @ref BansheeEngine::ScriptObject<Type, Base>::getMetaData "metaData" structure you can use for retrieving the @ref BansheeEngine::MonoClass "MonoClass" of the related managed class. You can use that @ref BansheeEngine::MonoClass "MonoClass" to register internal methods to it (as described earlier). For example a basic `initRuntimeData()` might look like so:
 ~~~~~~~~~~~~~{.cpp}
 void ScriptMyObject::initRuntimeData()
 {
@@ -143,10 +146,10 @@ void ScriptMyObject::initRuntimeData()
 }
 ~~~~~~~~~~~~~
 
-`initRuntimeData` is also a good spot to retrieve @ref BansheeEngine::MonoMethod "MonoMethod" (or thunks) for managed methods that needed to be called by the script interop object, if any.
+`initRuntimeData` is also a good spot to retrieve @ref BansheeEngine::MonoMethod "MonoMethods" (or thunks) for managed methods that needed to be called by the script interop object, if any.
 
 ### Creating script object instances ### {#scripting_b_a_b}	
-If your class is not static you will need to eventually create an instance of the script object. This can be done either from C# or C++, depending on what is needed. For example script interop objects for GUI will be created from managed code because user can add GUI elements himself, but a resource like @ref BansheeEngine::Font "Font" will have its script interop object (and managed instanced) created purely from C++ because such an object cannot be created directly in managed code.
+If your class is not static you will need to eventually create an instance of the script object. This can be done either from C# or C++, depending on what is needed. For example script interop objects for GUI will be created from managed code because user can add GUI elements himself, but a resource like @ref BansheeEngine::Font "Font" will have its script interop object (and managed instance) created purely from C++ because such an object cannot be created directly in managed code.
 
 For the first case you should set up an internal method that accepts the managed object instance, and is called in the managed constructor (`internal_CreateInstance` in the above example). This way the method gets called whenever the managed object gets created and you can create the related script interop object. A simple implementation would look like so:
 ~~~~~~~~~~~~~{.cpp}
@@ -156,7 +159,7 @@ void ScriptMyObject::internal_createInstance(MonoObject* obj)
 }
 ~~~~~~~~~~~~~
 	
-Note that you don't actually need to store the created object anywhere. The `ScriptObject` constructor ensures that the pointer to the script interop object is stored in the managed object.
+Note that you don't actually need to store the created object anywhere. The @ref BansheeEngine::ScriptObject "ScriptObject" constructor ensures that the pointer to the script interop object is stored in the managed object.
 
 For the second case where you want to create the interop object from C++ you can create a static `create()` method like so:
 ~~~~~~~~~~~~~{.cpp}
@@ -171,7 +174,7 @@ MonoObject* ScriptMyObject::create()
 	
 In this case the method calls a parameterless constructor but you may specify parameters as needed.
 
-If you have a `MonoObject*` but need to retrieve its `ScriptObject` use @ref BansheeEngine::ScriptObject::toNative(MonoObject*) "toNative(MonoObject*)" static method. Within the interop object instance you can use @ref BansheeEngine::ScriptObjectBase::getManagedInstance() "ScriptObject::getManagedInstance()" to retrieve the managed object.
+If you have a `MonoObject*` but need to retrieve its @ref BansheeEngine::ScriptObject "ScriptObject" use @ref BansheeEngine::ScriptObject::toNative(MonoObject*) "toNative(MonoObject*)" static method. Within the interop object instance you can use @ref BansheeEngine::ScriptObjectBase::getManagedInstance() "ScriptObject::getManagedInstance()" to retrieve the managed object.
 
 ### Destroying script object instances ### {#scripting_b_a_c}
 When the managed object is destroyed (e.g. goes out of scope and gets garbage collected) the system will automatically take care of freeing the related ScriptObject. If you need to add onto or replace that functionality you can override @ref BansheeEngine::ScriptObjectBase::_onManagedInstanceDeleted "ScriptObject::_onManagedInstanceDeleted" method.
@@ -211,23 +214,23 @@ What has been shown so far is enough to create a class exposed to script, howeve
 
 If you don't care about your object surviving the refresh, you do not need to implement what is described here. For example GUI elements don't persist refresh, because they're just rebuilt from the managed code every time the refresh happens. However objects like resources, scene objects and components are persistent - we don't wish to reload the entire scene and all resources every time assembly refresh happens.
 
-A persistent script object need to inherit a variation of `ScriptObject` like so:
+A persistent script object need to inherit a variation of @ref BansheeEngine::ScriptObject "ScriptObject" like so:
 ~~~~~~~~~~~~~{.cpp}
 class MyScriptObject : public ScriptObject<MyScriptObject, PersistentScriptObjectBase>
 ~~~~~~~~~~~~~	
 	
-This ensures that your object is treated properly during assembly refresh. Persistent object then needs to handle four different actions, represented by overrideable methods. These methods are called in order specified during assembly refresh.
+This ensures that your object is treated properly during assembly refresh. Persistent object then needs to handle four different actions, represented by overrideable methods. These methods are called in order specified, during assembly refresh.
  - @ref BansheeEngine::ScriptObjectBase::beginRefresh() "ScriptObject::beginRefresh()" - Called just before the refresh starts. The object is still alive here and you can perform needed actions (e.g. saving managed object's contents).
- - @ref BansheeEngine::ScriptObjectBase::_onManagedInstanceDeleted "ScriptObject::_onManagedInstanceDeleted()" - Called after assembly unload happened and the managed object was destroyed. You should override this to prevent the `ScriptObject` itself from being deleted if the assembly refresh is in progress (which is what the default implementation does). If assembly refresh is not in progress this method should delete the `ScriptObject` as normal because it likely got called due to standard reasons (managed object went out of scope).
+ - @ref BansheeEngine::ScriptObjectBase::_onManagedInstanceDeleted "ScriptObject::_onManagedInstanceDeleted()" - Called after assembly unload happened and the managed object was destroyed. You should override this to prevent the @ref BansheeEngine::ScriptObject "ScriptObject" itself from being deleted if the assembly refresh is in progress. If assembly refresh is not in progress this method should delete the @ref BansheeEngine::ScriptObject "ScriptObject" as normal because it likely got called due to standard reasons (managed object went out of scope).
  - @ref BansheeEngine::ScriptObject::_createManagedInstance "ScriptObject::_createManagedInstance()" - Creates the managed instance after new assemblies are loaded. You should override this if your managed class is constructed using a constructor with parameters. By default this will call @ref BansheeEngine::MonoClass::createInstance "MonoClass::createInstance()" using the parameterless constructor.
- - @ref BansheeEngine::ScriptObjectBase::endRefresh() "ScriptObject::endRefresh()" - Called after all assemblies are loaded, and after all script interop objects were either destroyed (non-persistent) or had their managed instances created (persistent). Allows you to restore data stored in `beginRefresh()`, but that is optional.
+ - @ref BansheeEngine::ScriptObjectBase::endRefresh() "ScriptObject::endRefresh()" - Called after all assemblies are loaded, and after all script interop objects were either destroyed (non-persistent) or had their managed instances created (persistent). If you stored any data during @ref BansheeEngine::ScriptObjectBase::beginRefresh() "ScriptObject::beginRefresh()", you should restore it here.
  
 See @ref BansheeEngine::ScriptSceneObject "ScriptSceneObject" and its base class @ref BansheeEngine::ScriptGameObjectBase "ScriptGameObjectBase" for example implementations of these methods.
 
 ## Deriving from ScriptObject ##
-Sometimes script objects are polymorphic. For example a `GUIElement` is derived from `ScriptObject` in managed code, and `GUIButton` from `GUIElement`, however they both have script interop objects of their own.
+Sometimes script objects are polymorphic. For example a `GUIElement` is derived from `ScriptObject` in managed code, and `GUIButton` is derived from `GUIElement`, however they both have script interop objects of their own.
 
-Due to the nature our script interop objects are defined we cannot follow the same simple chain of inheritance in C++ code. For example class definition script interop object for `GUIElement` would be:
+Due to the nature of how our script interop objects are defined we cannot follow the same simple chain of inheritance in C++ code. For example class definition script interop object for `GUIElement` would be:
 ~~~~~~~~~~~~~{.cpp}
 class ScriptGUIElement : public ScriptObject<ScriptGUIElement>
 {
@@ -237,9 +240,9 @@ public:
 }
 ~~~~~~~~~~~~~	
 	
-But what would it be for `GUIButton`? It also needs to implement `ScriptObject` with its own `SCRIPT_OBJ` macro so we cannot just inherit from `ScriptGUIElement` directly as it would clash.
+But what would it be for `GUIButton`? It also needs to implement @ref BansheeEngine::ScriptObject "ScriptObject" with its own @ref SCRIPT_OBJ macro so we cannot just inherit from `ScriptGUIElement` directly as it would clash.
 
-The solution is to create a third class that will serve as a base for both. This third class will be a base class for `ScriptObject` (its second template parameter allows us to override its default `ScriptObjectBase` base class). The third class will need to inherit @ref BansheeEngine::ScriptObjectBase "ScriptObjectBase" and can implement any functionality common to all GUI elements (e.g. it might store a pointer to a native `GUIElement*`).
+The solution is to create a third class that will serve as a base for both. This third class will be a base class for @ref BansheeEngine::ScriptObject "ScriptObject" (its second template parameter allows us to override its default `ScriptObjectBase` base class). The third class will need to inherit @ref BansheeEngine::ScriptObjectBase "ScriptObjectBase" and can implement any functionality common to all GUI elements (e.g. it might store a pointer to a native `GUIElement*`).
 
 Then we can define script interop object for GUI element as:
 ~~~~~~~~~~~~~{.cpp}

+ 0 - 0
Documentation/doxygen_objdb_9152.tmp


+ 39 - 33
Source/MBansheeEditor/EditorStyles.cs → Source/MBansheeEditor/GUI/EditorStyles.cs

@@ -1,33 +1,39 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Contains various editor specific GUI style names. You may use these to customize look and feel of various GUI 
-    /// elements.
-    /// </summary>
-    public static class EditorStyles
-    {
-        public const string Blank = "Blank";
-        public const string Label = "Label";
-        public const string LabelCentered = "LabelCentered";
-        public const string TitleLabel = "TitleLabel";
-        public const string MultiLineLabel = "MultiLineLabel";
-        public const string MultiLineLabelCentered = "MultiLineLabelCentered";
-        public const string Button = "Button";
-        public const string ButtonLeft = "ButtonLeft";
-        public const string ButtonRight = "ButtonRight";
-        public const string Toggle = "Toggle";
-        public const string InputBox = "InputBox";
-        public const string Foldout = "Foldout";
-        public const string ColorSliderHorz = "ColorSliderHorz";
-        public const string ColorSliderVert = "ColorSliderVert";
-        public const string ColorSlider2DHandle = "ColorSlider2DHandle";
-        public const string SelectionArea = "SelectionArea";
-        public const string SelectableLabel = "SelectableLabel";
-        public const string ScrollAreaBg = "ScrollAreaBg";
-        public const string InspectorTitleBg = "InspectorTitleBg";
-        public const string InspectorContentBg = "InspectorContentBg";
-        public const string InspectorContentBgAlternate = "InspectorContentBgAlternate";
-    }
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+namespace BansheeEditor
+{
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
+    /// <summary>
+    /// Contains various editor specific GUI style names. You may use these to customize look and feel of various GUI 
+    /// elements.
+    /// </summary>
+    public static class EditorStyles
+    {
+        public const string Blank = "Blank";
+        public const string Label = "Label";
+        public const string LabelCentered = "LabelCentered";
+        public const string TitleLabel = "TitleLabel";
+        public const string MultiLineLabel = "MultiLineLabel";
+        public const string MultiLineLabelCentered = "MultiLineLabelCentered";
+        public const string Button = "Button";
+        public const string ButtonLeft = "ButtonLeft";
+        public const string ButtonRight = "ButtonRight";
+        public const string Toggle = "Toggle";
+        public const string InputBox = "InputBox";
+        public const string Foldout = "Foldout";
+        public const string ColorSliderHorz = "ColorSliderHorz";
+        public const string ColorSliderVert = "ColorSliderVert";
+        public const string ColorSlider2DHandle = "ColorSlider2DHandle";
+        public const string SelectionArea = "SelectionArea";
+        public const string SelectableLabel = "SelectableLabel";
+        public const string ScrollAreaBg = "ScrollAreaBg";
+        public const string InspectorTitleBg = "InspectorTitleBg";
+        public const string InspectorContentBg = "InspectorContentBg";
+        public const string InspectorContentBgAlternate = "InspectorContentBgAlternate";
+    }
+
+    /** @} */
+}

+ 6 - 0
Source/MBansheeEditor/GUI/GUIColorField.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a color and an optional label. Allows the user to select a color using the color 
     /// picker.
@@ -111,4 +115,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetTint(IntPtr nativeInstance, ref Color color);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUIDictionaryField.cs

@@ -7,6 +7,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Base class for objects that display GUI for a modifyable dictionary of elements. Elements can be added, modified or
     /// removed.
@@ -1279,4 +1283,6 @@ namespace BansheeEditor
             localTitleLayout = false;
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUIEnumField.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a list box with elements of an enumeration and an optional label.
     /// </summary>
@@ -196,4 +200,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetTint(IntPtr nativeInstance, ref Color color);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUIFloatField.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a floating point input field and an optional label.
     /// </summary>
@@ -136,4 +140,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetRange(IntPtr nativeInstance, float min, float max);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUIGameObjectField.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a reference to a <see cref="GameObject"/> and an optional label. Game objects can
     /// be dragged and dropped onto the field to update the reference.
@@ -96,4 +100,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetTint(IntPtr nativeInstance, ref Color color);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUIIntField.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a integer input field and an optional label.
     /// </summary>
@@ -136,4 +140,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetTint(IntPtr nativeInstance, ref Color color);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUIListBoxField.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a list box with user-specified elements and an optional label. List box can be
     /// a standard list-box that allows a single element to be selected, or a multi-select list box where any number of
@@ -338,4 +342,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetTint(IntPtr nativeInstance, ref Color color);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUIListField.cs

@@ -7,6 +7,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Base class for objects that display GUI for a modifyable list of elements. Elements can be added, removed and moved.
     /// </summary>
@@ -1031,4 +1035,6 @@ namespace BansheeEditor
             localTitleLayout = false;
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUIResourceField.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a reference to a <see cref="Resource"/> and an optional label. Resources can
     /// be dragged and dropped onto the field to update the reference.
@@ -118,4 +122,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetTint(IntPtr nativeInstance, ref Color color);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUISceneTreeView.cs

@@ -8,6 +8,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// GUI element that displays all scene objects in the current scene as a tree view.
     /// </summary>
@@ -177,4 +181,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_RenameSelection(IntPtr thisPtr);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUISliderField.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a slider with floating point input field and an optional label.
     /// </summary>
@@ -118,4 +122,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetStep(IntPtr nativeInstance, float step);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUITextField.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a textual input field and an optional label.
     /// </summary>
@@ -124,4 +128,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetTint(IntPtr nativeInstance, ref Color color);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUITextureField.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a reference to a <see cref="Texture"/> and an optional label. Textures can
     /// be dragged and dropped onto the field to update the reference. This is similar to <see cref="GUIResourceField"/>
@@ -117,4 +121,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetTint(IntPtr nativeInstance, ref Color color);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUIToggleField.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a toggle button and an optional label.
     /// </summary>
@@ -93,4 +97,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetTint(IntPtr nativeInstance, ref Color color);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUIVector2Field.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a 2D vector input field and an optional label.
     /// </summary>
@@ -122,4 +126,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetTint(IntPtr nativeInstance, ref Color color);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUIVector3Field.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a 3D vector input field and an optional label.
     /// </summary>
@@ -122,4 +126,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetTint(IntPtr nativeInstance, ref Color color);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GUI/GUIVector4Field.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Editor GUI element that displays a 4D vector input field and an optional label.
     /// </summary>
@@ -122,4 +126,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetTint(IntPtr nativeInstance, ref Color color);
     }
+
+    /** @} */
 }

+ 6 - 5
Source/MBansheeEditor/LocEdString.cs → Source/MBansheeEditor/GUI/LocEdString.cs

@@ -1,14 +1,13 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup GUI-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Helper object that creates a localized string in the editor-specific string table. Allows easier separation between
     /// editor and game string tables.
@@ -61,4 +60,6 @@ namespace BansheeEditor
             return new GUIContent(edString.internalString);
         }
     }
+
+    /** @} */
 }

+ 989 - 983
Source/MBansheeEditor/EditorApplication.cs → Source/MBansheeEditor/General/EditorApplication.cs

@@ -1,983 +1,989 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using System;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-using System.IO;
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Available tools in the scene view.
-    /// </summary>
-    public enum SceneViewTool
-    {
-        View,
-        Move,
-        Rotate,
-        Scale
-    }
-
-    /// <summary>
-    /// Pivot mode used by the scene view tools.
-    /// </summary>
-    public enum HandlePivotMode
-    {
-        Center,
-        Pivot
-    }
-
-    /// <summary>
-    /// Coordinate mode used by the scene view tools.
-    /// </summary>
-    public enum HandleCoordinateMode
-    {
-        Local,
-        World
-    }
-
-    /// <summary>
-    /// Manages various generic and global settings relating to the editor.
-    /// </summary>
-    public class EditorApplication
-    {
-        internal const string CutBinding = "Cut";
-        internal const string CopyBinding = "Copy";
-        internal const string RenameBinding = "Rename";
-        internal const string DuplicateBinding = "Duplicate";
-        internal const string DeleteBinding = "Delete";
-        internal const string PasteBinding = "Paste";
-
-        /// <summary>
-        /// Determines the active tool shown in the scene view.
-        /// </summary>
-        public static SceneViewTool ActiveSceneTool
-        {
-            get { return EditorSettings.ActiveSceneTool; }
-            set { EditorSettings.ActiveSceneTool = value; }
-        }
-
-        /// <summary>
-        /// Determines the coordinate mode used by the tools in the scene view.
-        /// </summary>
-        public static HandleCoordinateMode ActiveCoordinateMode
-        {
-            get { return EditorSettings.ActiveCoordinateMode; }
-            set { EditorSettings.ActiveCoordinateMode = value; }
-        }
-
-        /// <summary>
-        /// Determines the pivot mode used by the tools in the scene view.
-        /// </summary>
-        public static HandlePivotMode ActivePivotMode
-        {
-            get { return EditorSettings.ActivePivotMode; }
-            set { EditorSettings.ActivePivotMode = value; }
-        }
-
-        /// <summary>
-        /// Camera used for rendering the scene view.
-        /// </summary>
-        public static Camera SceneViewCamera
-        {
-            get { return EditorWindow.GetWindow<SceneWindow>().Camera; }
-        }
-
-        /// <summary>
-        /// Absolute path to the folder containing the currently open project.
-        /// </summary>
-        public static string ProjectPath { get { return Internal_GetProjectPath(); } }
-
-        /// <summary>
-        /// Name of the currently open project.
-        /// </summary>
-        public static string ProjectName { get { return Internal_GetProjectName(); } }
-
-        /// <summary>
-        /// Checks is any project currently loaded.
-        /// </summary>
-        public static bool IsProjectLoaded { get { return Internal_GetProjectLoaded(); } }
-
-        /// <summary>
-        /// Determines is the game currently running in the editor, or is it stopped or paused. Setting this value to false
-        /// will stop the game, but if you just want to pause it use <see cref="IsPaused"/> property.
-        /// </summary>
-        public static bool IsPlaying
-        {
-            get { return Internal_GetIsPlaying(); }
-            set
-            {
-                ToggleToolbarItem("Play", value);
-                ToggleToolbarItem("Pause", false);
-
-                if (!value)
-                    Selection.SceneObject = null;
-                else
-                {
-                    if (EditorSettings.GetBool(LogWindow.CLEAR_ON_PLAY_KEY, true))
-                    {
-                        Debug.Clear();
-
-                        LogWindow log = EditorWindow.GetWindow<LogWindow>();
-                        if (log != null)
-                            log.Refresh();
-                    }
-                }
-
-                Internal_SetIsPlaying(value);
-            }
-        }
-
-        /// <summary>
-        /// Determines if the game is currently running in the editor, but paused. If the game is stopped and not running
-        /// this will return false. If the game is not running and this is enabled, the game will start running but be 
-        /// immediately paused.
-        /// </summary>
-        public static bool IsPaused
-        {
-            get { return Internal_GetIsPaused(); }
-            set
-            {
-                ToggleToolbarItem("Play", !value);
-                ToggleToolbarItem("Pause", value);
-                Internal_SetIsPaused(value);
-            }
-        }
-
-        /// <summary>
-        /// Returns true if the game is currently neither running nor paused. Use <see cref="IsPlaying"/> or 
-        /// <see cref="IsPaused"/> to actually change these states.
-        /// </summary>
-        public static bool IsStopped
-        {
-            get { return !IsPlaying && !IsPaused; }
-        }
-
-        /// <summary>
-        /// Checks whether the editor currently has focus.
-        /// </summary>
-        public static bool HasFocus
-        {
-            get { return Internal_HasFocus(); }
-        }
-
-        /// <summary>
-        /// Render target that the main camera in the scene (if any) will render its view to. This generally means the main 
-        /// game window when running standalone, or the Game viewport when running in editor.
-        /// </summary>
-        internal static RenderTarget MainRenderTarget
-        {
-            set
-            {
-                IntPtr rtPtr = IntPtr.Zero;
-                if (value != null)
-                    rtPtr = value.GetCachedPtr();
-
-                Internal_SetMainRenderTarget(rtPtr);
-            }
-        }
-
-        /// <summary>
-        /// Returns the path where the script compiler is located at.
-        /// </summary>
-        internal static string CompilerPath { get { return Internal_GetCompilerPath(); } }
-
-        /// <summary>
-        /// Returns the path to the folder where the custom script assemblies are located at.
-        /// </summary>
-        internal static string ScriptAssemblyPath { get { return Internal_GetScriptAssemblyPath(); } }
-
-        /// <summary>
-        /// Returns the path to the folder where the .NET framework assemblies are located at.
-        /// </summary>
-        internal static string FrameworkAssemblyPath { get { return Internal_GetFrameworkAssemblyPath(); } }
-
-        /// <summary>
-        /// Name of the builtin assembly containing engine specific types.
-        /// </summary>
-        internal static string EngineAssemblyName { get { return Internal_GetEngineAssemblyName(); } }
-
-        /// <summary>
-        /// Name of the builtin assembly containing editor specific types.
-        /// </summary>
-        internal static string EditorAssemblyName { get { return Internal_GetEditorAssemblyName(); } }
-
-        /// <summary>
-        /// Name of the custom assembly compiled from non-editor scripts within the project.
-        /// </summary>
-        internal static string ScriptGameAssemblyName { get { return Internal_GetScriptGameAssemblyName(); } }
-
-        /// <summary>
-        /// Name of the custom assembly compiled from editor scripts within the project.
-        /// </summary>
-        internal static string ScriptEditorAssemblyName { get { return Internal_GetScriptEditorAssemblyName(); } }
-
-        /// <summary>
-        /// Returns the path to the folder where the builtin release script assemblies are located at.
-        /// </summary>
-        internal static string BuiltinReleaseAssemblyPath { get { return Internal_GetBuiltinReleaseAssemblyPath(); } }
-
-        /// <summary>
-        /// Returns the path to the folder where the builtin debug script assemblies are located at.
-        /// </summary>
-        internal static string BuiltinDebugAssemblyPath { get { return Internal_GetBuiltinDebugAssemblyPath(); } }
-
-        internal static VirtualButton CutKey = new VirtualButton(CutBinding);
-        internal static VirtualButton CopyKey = new VirtualButton(CopyBinding);
-        internal static VirtualButton PasteKey = new VirtualButton(PasteBinding);
-        internal static VirtualButton RenameKey = new VirtualButton(RenameBinding);
-        internal static VirtualButton DuplicateKey = new VirtualButton(DuplicateBinding);
-        internal static VirtualButton DeleteKey = new VirtualButton(DeleteBinding);
-
-        private static EditorApplication instance;
-        private static FolderMonitor monitor;
-        private static ScriptCodeManager codeManager;
-        private static bool sceneDirty;
-        private static bool unitTestsExecuted;
-        private static EditorPersistentData persistentData;
-
-        /// <summary>
-        /// Constructs a new editor application. Called at editor start-up by the runtime, and any time assembly refresh
-        /// occurrs.
-        /// </summary>
-        internal EditorApplication()
-        {
-            instance = this;
-            codeManager = new ScriptCodeManager();
-
-            const string soName = "EditorPersistentData";
-            SceneObject so = Scene.Root.FindChild(soName);
-            if (so == null)
-                so = new SceneObject(soName, true);
-
-            persistentData = so.GetComponent<EditorPersistentData>();
-            if (persistentData == null)
-                persistentData = so.AddComponent<EditorPersistentData>();
-
-            // Register controls
-            InputConfiguration inputConfig = VirtualInput.KeyConfig;
-
-            inputConfig.RegisterButton(SceneCamera.MoveForwardBinding, ButtonCode.W);
-            inputConfig.RegisterButton(SceneCamera.MoveBackBinding, ButtonCode.S);
-            inputConfig.RegisterButton(SceneCamera.MoveLeftBinding, ButtonCode.A);
-            inputConfig.RegisterButton(SceneCamera.MoveRightBinding, ButtonCode.D);
-            inputConfig.RegisterButton(SceneCamera.MoveUpBinding, ButtonCode.E);
-            inputConfig.RegisterButton(SceneCamera.MoveDownBinding, ButtonCode.Q);
-            inputConfig.RegisterButton(SceneCamera.MoveForwardBinding, ButtonCode.Up);
-            inputConfig.RegisterButton(SceneCamera.MoveBackBinding, ButtonCode.Down);
-            inputConfig.RegisterButton(SceneCamera.MoveLeftBinding, ButtonCode.Left);
-            inputConfig.RegisterButton(SceneCamera.MoveRightBinding, ButtonCode.Right);
-            inputConfig.RegisterButton(SceneCamera.FastMoveBinding, ButtonCode.LeftShift);
-            inputConfig.RegisterButton(SceneCamera.RotateBinding, ButtonCode.MouseRight);
-            inputConfig.RegisterButton(SceneCamera.PanBinding, ButtonCode.MouseMiddle);
-            inputConfig.RegisterAxis(SceneCamera.HorizontalAxisBinding, InputAxis.MouseX);
-            inputConfig.RegisterAxis(SceneCamera.VerticalAxisBinding, InputAxis.MouseY);
-            inputConfig.RegisterAxis(SceneCamera.ScrollAxisBinding, InputAxis.MouseZ);
-
-            inputConfig.RegisterButton(SceneWindow.ToggleProfilerOverlayBinding, ButtonCode.P, ButtonModifier.CtrlAlt);
-            inputConfig.RegisterButton(SceneWindow.ViewToolBinding, ButtonCode.Q);
-            inputConfig.RegisterButton(SceneWindow.FrameBinding, ButtonCode.F);
-            inputConfig.RegisterButton(SceneWindow.MoveToolBinding, ButtonCode.W);
-            inputConfig.RegisterButton(SceneWindow.RotateToolBinding, ButtonCode.E);
-            inputConfig.RegisterButton(SceneWindow.ScaleToolBinding, ButtonCode.R);
-
-            inputConfig.RegisterButton(CutBinding, ButtonCode.X, ButtonModifier.Ctrl);
-            inputConfig.RegisterButton(CopyBinding, ButtonCode.C, ButtonModifier.Ctrl);
-            inputConfig.RegisterButton(PasteBinding, ButtonCode.V, ButtonModifier.Ctrl);
-            inputConfig.RegisterButton(DuplicateBinding, ButtonCode.D, ButtonModifier.Ctrl);
-            inputConfig.RegisterButton(DeleteBinding, ButtonCode.Delete);
-            inputConfig.RegisterButton(RenameBinding, ButtonCode.F2);
-
-            if (IsProjectLoaded)
-            {
-                monitor = new FolderMonitor(ProjectLibrary.ResourceFolder);
-                monitor.OnAdded += OnAssetModified;
-                monitor.OnRemoved += OnAssetModified;
-                monitor.OnModified += OnAssetModified;
-            }
-        }
-
-        /// <summary>
-        /// Triggered when the folder monitor detects an asset in the monitored folder was modified.
-        /// </summary>
-        /// <param name="path">Path to the modified file or folder.</param>
-        private static void OnAssetModified(string path)
-        {
-            ProjectLibrary.Refresh(path);
-        }
-
-        /// <summary>
-        /// Called every frame by the runtime.
-        /// </summary>
-        internal void OnEditorUpdate()
-        {
-            // Update managers
-            ProjectLibrary.Update();
-            codeManager.Update();
-        }
-
-        /// <summary>
-        /// Manually triggers a global shortcut.
-        /// </summary>
-        /// <param name="btn">Button for the shortcut. If this doesn't correspond to any shortcut, it is ignored.</param>
-        internal static void TriggerGlobalShortcut(VirtualButton btn)
-        {
-            IGlobalShortcuts window = null;
-
-            if (btn != PasteKey)
-            {
-                // The system ensures elsewhere that only either a resource or a scene object is selected, but not both
-                if (Selection.ResourcePaths.Length > 0)
-                {
-                    window = EditorWindow.GetWindow<LibraryWindow>();
-                }
-                else if (Selection.SceneObjects.Length > 0)
-                {
-                    window = EditorWindow.GetWindow<HierarchyWindow>();
-                    if (window == null)
-                        window = EditorWindow.GetWindow<SceneWindow>();
-                }
-
-                if (window != null)
-                {
-                    if (btn == CopyKey)
-                        window.OnCopyPressed();
-                    else if (btn == CutKey)
-                        window.OnCutPressed();
-                    else if (btn == PasteKey)
-                        window.OnPastePressed();
-                    else if (btn == DuplicateKey)
-                        window.OnDuplicatePressed();
-                    else if (btn == RenameKey)
-                        window.OnRenamePressed();
-                    else if (btn == DeleteKey)
-                        window.OnDeletePressed();
-                }
-            }
-            else
-            {
-
-                HierarchyWindow hierarchy = EditorWindow.GetWindow<HierarchyWindow>();
-                if (hierarchy != null && hierarchy.HasFocus)
-                    window = hierarchy;
-                else
-                {
-                    LibraryWindow library = EditorWindow.GetWindow<LibraryWindow>();
-                    if (library != null && library.HasFocus)
-                        window = library;
-                }
-
-                if (window != null)
-                    window.OnPastePressed();
-            }
-        }
-
-        /// <summary>
-        /// Creates a new empty scene.
-        /// </summary>
-        [MenuItem("File/New Scene", 10051, true)]
-        private static void NewScene()
-        {
-            LoadScene(null);
-        }
-
-        /// <summary>
-        /// Opens a dialog that allows the user to select a new prefab to load as the current scene. If current scene
-        /// is modified the user is offered a chance to save it.
-        /// </summary>
-        [MenuItem("File/Open Scene", ButtonModifier.Ctrl, ButtonCode.L, 10050)]
-        private static void LoadScene()
-        {
-            string[] scenePaths;
-            if (BrowseDialog.OpenFile(ProjectLibrary.ResourceFolder, "", false, out scenePaths))
-            {
-                if (scenePaths.Length > 0)
-                    LoadScene(scenePaths[0]);
-            }
-        }
-
-        /// <summary>
-        /// Opens a dialog to allows the user to select a location where to save the current scene. If scene was previously
-        /// saved it is instead automatically saved at the last location.
-        /// </summary>
-        public static void SaveScene(Action onSuccess = null, Action onFailure = null)
-        {
-            if (!string.IsNullOrEmpty(Scene.ActiveSceneUUID))
-            {
-                string scenePath = ProjectLibrary.GetPath(Scene.ActiveSceneUUID);
-                if (!string.IsNullOrEmpty(scenePath))
-                {
-                    SaveScene(scenePath);
-
-                    if (onSuccess != null)
-                        onSuccess();
-                }
-                else
-                    SaveSceneAs(onSuccess, onFailure);
-            }
-            else
-                SaveSceneAs(onSuccess, onFailure);
-        }
-
-        /// <summary>
-        /// Opens a dialog to allows the user to select a location where to save the current scene.
-        /// </summary>
-        public static void SaveSceneAs(Action onSuccess = null, Action onFailure = null)
-        {
-            string scenePath = "";
-            if (BrowseDialog.SaveFile(ProjectLibrary.ResourceFolder, "*.prefab", out scenePath))
-            {
-                if (!PathEx.IsPartOf(scenePath, ProjectLibrary.ResourceFolder))
-                {
-                    DialogBox.Open("Error", "The location must be inside the Resources folder of the project.",
-                        DialogBox.Type.OK,
-                        x =>
-                        {
-                            if (onFailure != null)
-                                onFailure();
-                        });
-                }
-                else
-                {
-                    // TODO - If path points to an existing non-scene asset or folder I should delete it otherwise
-                    //        Internal_SaveScene will silently fail.
-
-                    scenePath = Path.ChangeExtension(scenePath, ".prefab");
-                    SaveScene(scenePath);
-                }
-            }
-            else
-            {
-                // User canceled, so technically a success
-                if (onSuccess != null)
-                    onSuccess();
-            }
-        }
-
-        /// <summary>
-        /// Loads a prefab as the current scene at the specified path. If current scene is modified the user is offered a 
-        /// chance to save it.
-        /// </summary>
-        /// <param name="path">Path to a valid prefab relative to the resource folder. If path is empty a brand new
-        ///                    scene will be loaded.</param>
-        public static void LoadScene(string path)
-        {
-            Action<string> continueLoad =
-                (scenePath) =>
-                {
-                    if (string.IsNullOrEmpty(path))
-                        Scene.Clear();
-                    else
-                        Scene.Load(path);
-
-                    SetSceneDirty(false);
-
-                    ProjectSettings.LastOpenScene = scenePath;
-                    ProjectSettings.Save();
-                };
-
-            Action<DialogBox.ResultType> dialogCallback =
-            (result) =>
-            {
-                if (result == DialogBox.ResultType.Yes)
-                {
-                    SaveScene();
-                    continueLoad(path);
-                }
-                else if (result == DialogBox.ResultType.No)
-                    continueLoad(path);
-            };
-
-            if (IsSceneModified())
-            {
-                DialogBox.Open("Warning", "You current scene has modifications. Do you wish to save them first?",
-                    DialogBox.Type.YesNoCancel, dialogCallback);
-            }
-            else
-                continueLoad(path);
-        }
-
-        /// <summary>
-        /// Saves the currently loaded scene to the specified path.
-        /// </summary>
-        /// <param name="path">Path relative to the resource folder. This can be the path to the existing scene
-        ///                    prefab if it just needs updating. </param>
-        public static void SaveScene(string path)
-        {
-            Prefab scene = Internal_SaveScene(path);
-            Scene.SetActive(scene);
-
-            ProjectLibrary.Refresh(true);
-            SetSceneDirty(false);
-        }
-
-        /// <summary>
-        /// Checks does the folder at the provieded path contain a valid project.
-        /// </summary>
-        /// <param name="path">Absolute path to the root project folder.</param>
-        /// <returns>True if the folder contains a valid project.</returns>
-        public static bool IsValidProject(string path)
-        {
-            return Internal_IsValidProject(path);
-        }
-
-        /// <summary>
-        /// Contains a new project in the provided folder.
-        /// </summary>
-        /// <param name="path">Absolute path to the folder to create the project in. Name of this folder will be used as the
-        ///                    project's name.</param>
-        public static void CreateProject(string path)
-        {
-            Internal_CreateProject(path);
-        }
-
-        /// <summary>
-        /// Wrapper for menu items for <see cref="SaveScene(Action, Action)"/> method
-        /// </summary>
-        [MenuItem("File/Save Scene", ButtonModifier.Ctrl, ButtonCode.S, 10049)]
-        [ToolbarItem("Save Scene", ToolbarIcon.SaveScene, "Save scene (Ctrl + S)", 1998)]
-        private static void SaveSceneMenu()
-        {
-            SaveScene();
-        }
-
-        /// <summary>
-        /// Wrapper for menu items for <see cref="SaveSceneAs(Action, Action)"/> method
-        /// </summary>
-        [MenuItem("File/Save Scene As", 10048)]
-        private static void SaveSceneAsMenu()
-        {
-            SaveSceneAs();
-        }
-
-        /// <summary>
-        /// Opens a Project Window allowing you to browse for or create a project.
-        /// </summary>
-        [MenuItem("File/Open Project", 10100)]
-        [ToolbarItem("Open Project", ToolbarIcon.OpenProject, "Project manager", 2000)]
-        public static void BrowseForProject()
-        {
-            ProjectWindow.Open();
-        }
-
-        /// <summary>
-        /// Saves all data in the currently open project.
-        /// </summary>
-        [MenuItem("File/Save Project", 10099)]
-        [ToolbarItem("Save Project", ToolbarIcon.SaveProject, "Save project", 1999)]
-        public static void SaveProject()
-        {
-            foreach (var KVP in persistentData.dirtyResources)
-            {
-                string resourceUUID = KVP.Key;
-                string path = ProjectLibrary.GetPath(resourceUUID);
-                if (!IsNative(path))
-                    continue; // Native resources can't be changed
-
-                Resource resource = ProjectLibrary.Load<Resource>(path);
-
-                if(resource != null)
-                    ProjectLibrary.Save(resource);
-            }
-
-            persistentData.dirtyResources.Clear();
-            SetStatusProject(false);
-
-            Internal_SaveProject();
-        }
-
-        /// <summary>
-        /// Loads the project at the specified path. This method executes asynchronously.
-        /// </summary>
-        /// <param name="path">Absolute path to the project's root folder.</param>
-        public static void LoadProject(string path)
-        {
-            if (IsProjectLoaded && path == ProjectPath)
-                return;
-
-            if (!Internal_IsValidProject(path))
-            {
-                Debug.LogWarning("Provided path: \"" + path + "\" is not a valid project.");
-                return;
-            }
-
-            if (IsProjectLoaded)
-                UnloadProject();
-
-            Internal_LoadProject(path); // Triggers Internal_OnProjectLoaded when done
-        }
-
-        /// <summary>
-        /// Closes the editor.
-        /// </summary>
-        public static void Quit()
-        {
-            Internal_Quit();
-        }
-
-        /// <summary>
-        /// Toggles an existing toolbar button into an on or off state which changes the visuals of the button.
-        /// </summary>
-        /// <param name="name">Name of the existing button to toggle</param>
-        /// <param name="on">True to toggle on, false to toggle off (default)</param>
-        public static void ToggleToolbarItem(string name, bool on)
-        {
-            Internal_ToggleToolbarItem(name, on);
-        }
-
-        /// <summary>
-        /// Opens a file or a folder in the default external application.
-        /// </summary>
-        /// <param name="path">Absolute path to the file or folder to open.</param>
-        public static void OpenExternally(string path)
-        {
-            Internal_OpenExternally(path);
-        }
-
-        /// <summary>
-        /// Marks a resource as dirty so that it may be saved the next time the project is saved. Optionally you may also
-        /// call <see cref="ProjectLibrary.Save"/> to save it immediately.
-        /// </summary>
-        /// <param name="resource">Resource to mark as dirty</param>
-        public static void SetDirty(Resource resource)
-        {
-            if (resource == null)
-                return;
-
-            SetStatusProject(true);
-            persistentData.dirtyResources[resource.UUID] = true;
-        }
-
-        /// <summary>
-        /// Marks the current scene as dirty.
-        /// </summary>
-        public static void SetSceneDirty()
-        {
-            SetSceneDirty(true);
-        }
-
-        /// <summary>
-        /// Marks the current scene as clean or dirty.
-        /// </summary>
-        /// <param name="dirty">Should the scene be marked as clean or dirty.</param>
-        internal static void SetSceneDirty(bool dirty)
-        {
-            sceneDirty = dirty;
-            SetStatusScene(Scene.ActiveSceneName, dirty);
-
-            if (!dirty && Scene.ActiveSceneUUID != null)
-                persistentData.dirtyResources.Remove(Scene.ActiveSceneUUID);
-        }
-
-        /// <summary>
-        /// Checks is the specific resource dirty and needs saving.
-        /// </summary>
-        /// <param name="resource">Resource to check.</param>
-        /// <returns>True if the resource requires saving, false otherwise.</returns>
-        public static bool IsDirty(Resource resource)
-        {
-            return persistentData.dirtyResources.ContainsKey(resource.UUID);
-        }
-
-        /// <summary>
-        /// Checks does the path represent a native resource.
-        /// </summary>
-        /// <param name="path">Filename or path to check.</param>
-        /// <returns>True if the path represents a native resource.</returns>
-        public static bool IsNative(string path)
-        {
-            string extension = Path.GetExtension(path);
-
-            return extension == ".asset" || extension == ".prefab";
-        }
-
-        /// <summary>
-        /// Unloads the currently loaded project. Offers the user a chance to save the current scene if it is modified.
-        /// Automatically saves all project data before unloading.
-        /// </summary>
-        private static void UnloadProject()
-        {
-            Action continueUnload =
-                () =>
-                {
-                    Scene.Clear();
-
-                    if (monitor != null)
-                    {
-                        monitor.Destroy();
-                        monitor = null;
-                    }
-
-                    LibraryWindow window = EditorWindow.GetWindow<LibraryWindow>();
-                    if(window != null)
-                        window.Reset();
-
-                    SetSceneDirty(false);
-                    Internal_UnloadProject();
-                    SetStatusProject(false);
-                };
-
-            Action<DialogBox.ResultType> dialogCallback =
-            (result) =>
-            {
-                if (result == DialogBox.ResultType.Yes)
-                    SaveScene();
-
-                continueUnload();
-            };
-
-            if (IsSceneModified())
-            {
-                DialogBox.Open("Warning", "You current scene has modifications. Do you wish to save them first?",
-                    DialogBox.Type.YesNoCancel, dialogCallback);
-            }
-            else
-                continueUnload();
-        }
-
-        /// <summary>
-        /// Reloads all script assemblies in case they were modified. This action is delayed and will be executed
-        /// at the beginning of the next frame.
-        /// </summary>
-        public static void ReloadAssemblies()
-        {
-            Internal_ReloadAssemblies();
-        }
-
-        /// <summary>
-        /// Changes the scene displayed on the status bar.
-        /// </summary>
-        /// <param name="name">Name of the scene.</param>
-        /// <param name="modified">Whether to display the scene as modified or not.</param>
-        private static void SetStatusScene(string name, bool modified)
-        {
-            Internal_SetStatusScene(name, modified);
-        }
-
-        /// <summary>
-        /// Changes the project state displayed on the status bar.
-        /// </summary>
-        /// <param name="modified">Whether to display the project as modified or not.</param>
-        private static void SetStatusProject(bool modified)
-        {
-            Internal_SetStatusProject(modified);
-        }
-
-        /// <summary>
-        /// Displays or hides the "compilation in progress" visual on the status bar.
-        /// </summary>
-        /// <param name="compiling">True to display the visual, false otherwise.</param>
-        internal static void SetStatusCompiling(bool compiling)
-        {
-            Internal_SetStatusCompiling(compiling);
-        }
-
-        /// <summary>
-        /// Checks did we make any modifications to the scene since it was last saved.
-        /// </summary>
-        /// <returns>True if the scene was never saved, or was modified after last save.</returns>
-        public static bool IsSceneModified()
-        {
-            return sceneDirty;
-        }
-
-        /// <summary>
-        /// Runs a single frame of the game and pauses it. If the game is not currently running it will be started.
-        /// </summary>
-        public static void FrameStep()
-        {
-            if (IsStopped)
-            {
-                if (EditorSettings.GetBool(LogWindow.CLEAR_ON_PLAY_KEY, true))
-                {
-                    Debug.Clear();
-
-                    LogWindow log = EditorWindow.GetWindow<LogWindow>();
-                    if (log != null)
-                        log.Refresh();
-                }
-            }
-
-            ToggleToolbarItem("Play", false);
-            ToggleToolbarItem("Pause", true);
-            Internal_FrameStep();
-        }
-
-        /// <summary>
-        /// Executes any editor-specific unit tests. This should be called after a project is loaded if possible.
-        /// </summary>
-        private static void RunUnitTests()
-        {
-#if DEBUG
-            Internal_RunUnitTests();
-#endif
-        }
-
-        /// <summary>
-        /// Triggered by the runtime when <see cref="LoadProject"/> method completes.
-        /// </summary>
-        private static void Internal_OnProjectLoaded()
-        {
-            SetStatusProject(false);
-            if (!unitTestsExecuted)
-            {
-                RunUnitTests();
-                unitTestsExecuted = true;
-            }
-
-            if (!IsProjectLoaded)
-            {
-                ProjectWindow.Open();
-                return;
-            }
-
-            string projectPath = ProjectPath;
-
-            RecentProject[] recentProjects = EditorSettings.RecentProjects;
-            bool foundPath = false;
-            for (int i = 0; i < recentProjects.Length; i++)
-            {
-                if (PathEx.Compare(recentProjects[i].path, projectPath))
-                {
-                    recentProjects[i].accessTimestamp = (ulong)DateTime.Now.Ticks;
-                    EditorSettings.RecentProjects = recentProjects;
-                    foundPath = true;
-                    break;
-                }
-            }
-
-            if (!foundPath)
-            {
-                List<RecentProject> extendedRecentProjects = new List<RecentProject>();
-                extendedRecentProjects.AddRange(recentProjects);
-
-                RecentProject newProject = new RecentProject();
-                newProject.path = projectPath;
-                newProject.accessTimestamp = (ulong)DateTime.Now.Ticks;
-
-                extendedRecentProjects.Add(newProject);
-
-                EditorSettings.RecentProjects = extendedRecentProjects.ToArray();
-            }
-
-            EditorSettings.LastOpenProject = projectPath;
-            EditorSettings.Save();
-
-            ProjectLibrary.Refresh();
-            monitor = new FolderMonitor(ProjectLibrary.ResourceFolder);
-            monitor.OnAdded += OnAssetModified;
-            monitor.OnRemoved += OnAssetModified;
-            monitor.OnModified += OnAssetModified;
-
-            if (!string.IsNullOrWhiteSpace(ProjectSettings.LastOpenScene))
-            {
-                Scene.Load(ProjectSettings.LastOpenScene);
-                SetSceneDirty(false);
-            }
-        }
-
-        /// <summary>
-        /// Triggered by the runtime when the user clicks on the status bar.
-        /// </summary>
-        private static void Internal_OnStatusBarClicked()
-        {
-            EditorWindow.OpenWindow<LogWindow>();
-        }
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetStatusScene(string name, bool modified);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetStatusProject(bool modified);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetStatusCompiling(bool compiling);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetProjectPath();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetProjectName();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool Internal_GetProjectLoaded();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetCompilerPath();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetBuiltinReleaseAssemblyPath();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetBuiltinDebugAssemblyPath();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetScriptAssemblyPath();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetFrameworkAssemblyPath();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetEngineAssemblyName();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetEditorAssemblyName();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetScriptGameAssemblyName();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetScriptEditorAssemblyName();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern Prefab Internal_SaveScene(string path);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool Internal_IsValidProject(string path);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SaveProject();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_LoadProject(string path);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_UnloadProject();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateProject(string path);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_ReloadAssemblies();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_OpenExternally(string path);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_RunUnitTests();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_Quit();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_ToggleToolbarItem(string name, bool on);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool Internal_GetIsPlaying();
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetIsPlaying(bool value);
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool Internal_GetIsPaused();
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetIsPaused(bool value);
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_FrameStep();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetMainRenderTarget(IntPtr rendertarget);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool Internal_HasFocus();
-    }
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.IO;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /** @addtogroup General 
+     *  @{
+     */
+
+    /// <summary>
+    /// Available tools in the scene view.
+    /// </summary>
+    public enum SceneViewTool
+    {
+        View,
+        Move,
+        Rotate,
+        Scale
+    }
+
+    /// <summary>
+    /// Pivot mode used by the scene view tools.
+    /// </summary>
+    public enum HandlePivotMode
+    {
+        Center,
+        Pivot
+    }
+
+    /// <summary>
+    /// Coordinate mode used by the scene view tools.
+    /// </summary>
+    public enum HandleCoordinateMode
+    {
+        Local,
+        World
+    }
+
+    /// <summary>
+    /// Manages various generic and global settings relating to the editor.
+    /// </summary>
+    public class EditorApplication
+    {
+        internal const string CutBinding = "Cut";
+        internal const string CopyBinding = "Copy";
+        internal const string RenameBinding = "Rename";
+        internal const string DuplicateBinding = "Duplicate";
+        internal const string DeleteBinding = "Delete";
+        internal const string PasteBinding = "Paste";
+
+        /// <summary>
+        /// Determines the active tool shown in the scene view.
+        /// </summary>
+        public static SceneViewTool ActiveSceneTool
+        {
+            get { return EditorSettings.ActiveSceneTool; }
+            set { EditorSettings.ActiveSceneTool = value; }
+        }
+
+        /// <summary>
+        /// Determines the coordinate mode used by the tools in the scene view.
+        /// </summary>
+        public static HandleCoordinateMode ActiveCoordinateMode
+        {
+            get { return EditorSettings.ActiveCoordinateMode; }
+            set { EditorSettings.ActiveCoordinateMode = value; }
+        }
+
+        /// <summary>
+        /// Determines the pivot mode used by the tools in the scene view.
+        /// </summary>
+        public static HandlePivotMode ActivePivotMode
+        {
+            get { return EditorSettings.ActivePivotMode; }
+            set { EditorSettings.ActivePivotMode = value; }
+        }
+
+        /// <summary>
+        /// Camera used for rendering the scene view.
+        /// </summary>
+        public static Camera SceneViewCamera
+        {
+            get { return EditorWindow.GetWindow<SceneWindow>().Camera; }
+        }
+
+        /// <summary>
+        /// Absolute path to the folder containing the currently open project.
+        /// </summary>
+        public static string ProjectPath { get { return Internal_GetProjectPath(); } }
+
+        /// <summary>
+        /// Name of the currently open project.
+        /// </summary>
+        public static string ProjectName { get { return Internal_GetProjectName(); } }
+
+        /// <summary>
+        /// Checks is any project currently loaded.
+        /// </summary>
+        public static bool IsProjectLoaded { get { return Internal_GetProjectLoaded(); } }
+
+        /// <summary>
+        /// Determines is the game currently running in the editor, or is it stopped or paused. Setting this value to false
+        /// will stop the game, but if you just want to pause it use <see cref="IsPaused"/> property.
+        /// </summary>
+        public static bool IsPlaying
+        {
+            get { return Internal_GetIsPlaying(); }
+            set
+            {
+                ToggleToolbarItem("Play", value);
+                ToggleToolbarItem("Pause", false);
+
+                if (!value)
+                    Selection.SceneObject = null;
+                else
+                {
+                    if (EditorSettings.GetBool(LogWindow.CLEAR_ON_PLAY_KEY, true))
+                    {
+                        Debug.Clear();
+
+                        LogWindow log = EditorWindow.GetWindow<LogWindow>();
+                        if (log != null)
+                            log.Refresh();
+                    }
+                }
+
+                Internal_SetIsPlaying(value);
+            }
+        }
+
+        /// <summary>
+        /// Determines if the game is currently running in the editor, but paused. If the game is stopped and not running
+        /// this will return false. If the game is not running and this is enabled, the game will start running but be 
+        /// immediately paused.
+        /// </summary>
+        public static bool IsPaused
+        {
+            get { return Internal_GetIsPaused(); }
+            set
+            {
+                ToggleToolbarItem("Play", !value);
+                ToggleToolbarItem("Pause", value);
+                Internal_SetIsPaused(value);
+            }
+        }
+
+        /// <summary>
+        /// Returns true if the game is currently neither running nor paused. Use <see cref="IsPlaying"/> or 
+        /// <see cref="IsPaused"/> to actually change these states.
+        /// </summary>
+        public static bool IsStopped
+        {
+            get { return !IsPlaying && !IsPaused; }
+        }
+
+        /// <summary>
+        /// Checks whether the editor currently has focus.
+        /// </summary>
+        public static bool HasFocus
+        {
+            get { return Internal_HasFocus(); }
+        }
+
+        /// <summary>
+        /// Render target that the main camera in the scene (if any) will render its view to. This generally means the main 
+        /// game window when running standalone, or the Game viewport when running in editor.
+        /// </summary>
+        internal static RenderTarget MainRenderTarget
+        {
+            set
+            {
+                IntPtr rtPtr = IntPtr.Zero;
+                if (value != null)
+                    rtPtr = value.GetCachedPtr();
+
+                Internal_SetMainRenderTarget(rtPtr);
+            }
+        }
+
+        /// <summary>
+        /// Returns the path where the script compiler is located at.
+        /// </summary>
+        internal static string CompilerPath { get { return Internal_GetCompilerPath(); } }
+
+        /// <summary>
+        /// Returns the path to the folder where the custom script assemblies are located at.
+        /// </summary>
+        internal static string ScriptAssemblyPath { get { return Internal_GetScriptAssemblyPath(); } }
+
+        /// <summary>
+        /// Returns the path to the folder where the .NET framework assemblies are located at.
+        /// </summary>
+        internal static string FrameworkAssemblyPath { get { return Internal_GetFrameworkAssemblyPath(); } }
+
+        /// <summary>
+        /// Name of the builtin assembly containing engine specific types.
+        /// </summary>
+        internal static string EngineAssemblyName { get { return Internal_GetEngineAssemblyName(); } }
+
+        /// <summary>
+        /// Name of the builtin assembly containing editor specific types.
+        /// </summary>
+        internal static string EditorAssemblyName { get { return Internal_GetEditorAssemblyName(); } }
+
+        /// <summary>
+        /// Name of the custom assembly compiled from non-editor scripts within the project.
+        /// </summary>
+        internal static string ScriptGameAssemblyName { get { return Internal_GetScriptGameAssemblyName(); } }
+
+        /// <summary>
+        /// Name of the custom assembly compiled from editor scripts within the project.
+        /// </summary>
+        internal static string ScriptEditorAssemblyName { get { return Internal_GetScriptEditorAssemblyName(); } }
+
+        /// <summary>
+        /// Returns the path to the folder where the builtin release script assemblies are located at.
+        /// </summary>
+        internal static string BuiltinReleaseAssemblyPath { get { return Internal_GetBuiltinReleaseAssemblyPath(); } }
+
+        /// <summary>
+        /// Returns the path to the folder where the builtin debug script assemblies are located at.
+        /// </summary>
+        internal static string BuiltinDebugAssemblyPath { get { return Internal_GetBuiltinDebugAssemblyPath(); } }
+
+        internal static VirtualButton CutKey = new VirtualButton(CutBinding);
+        internal static VirtualButton CopyKey = new VirtualButton(CopyBinding);
+        internal static VirtualButton PasteKey = new VirtualButton(PasteBinding);
+        internal static VirtualButton RenameKey = new VirtualButton(RenameBinding);
+        internal static VirtualButton DuplicateKey = new VirtualButton(DuplicateBinding);
+        internal static VirtualButton DeleteKey = new VirtualButton(DeleteBinding);
+
+        private static EditorApplication instance;
+        private static FolderMonitor monitor;
+        private static ScriptCodeManager codeManager;
+        private static bool sceneDirty;
+        private static bool unitTestsExecuted;
+        private static EditorPersistentData persistentData;
+
+        /// <summary>
+        /// Constructs a new editor application. Called at editor start-up by the runtime, and any time assembly refresh
+        /// occurrs.
+        /// </summary>
+        internal EditorApplication()
+        {
+            instance = this;
+            codeManager = new ScriptCodeManager();
+
+            const string soName = "EditorPersistentData";
+            SceneObject so = Scene.Root.FindChild(soName);
+            if (so == null)
+                so = new SceneObject(soName, true);
+
+            persistentData = so.GetComponent<EditorPersistentData>();
+            if (persistentData == null)
+                persistentData = so.AddComponent<EditorPersistentData>();
+
+            // Register controls
+            InputConfiguration inputConfig = VirtualInput.KeyConfig;
+
+            inputConfig.RegisterButton(SceneCamera.MoveForwardBinding, ButtonCode.W);
+            inputConfig.RegisterButton(SceneCamera.MoveBackBinding, ButtonCode.S);
+            inputConfig.RegisterButton(SceneCamera.MoveLeftBinding, ButtonCode.A);
+            inputConfig.RegisterButton(SceneCamera.MoveRightBinding, ButtonCode.D);
+            inputConfig.RegisterButton(SceneCamera.MoveUpBinding, ButtonCode.E);
+            inputConfig.RegisterButton(SceneCamera.MoveDownBinding, ButtonCode.Q);
+            inputConfig.RegisterButton(SceneCamera.MoveForwardBinding, ButtonCode.Up);
+            inputConfig.RegisterButton(SceneCamera.MoveBackBinding, ButtonCode.Down);
+            inputConfig.RegisterButton(SceneCamera.MoveLeftBinding, ButtonCode.Left);
+            inputConfig.RegisterButton(SceneCamera.MoveRightBinding, ButtonCode.Right);
+            inputConfig.RegisterButton(SceneCamera.FastMoveBinding, ButtonCode.LeftShift);
+            inputConfig.RegisterButton(SceneCamera.RotateBinding, ButtonCode.MouseRight);
+            inputConfig.RegisterButton(SceneCamera.PanBinding, ButtonCode.MouseMiddle);
+            inputConfig.RegisterAxis(SceneCamera.HorizontalAxisBinding, InputAxis.MouseX);
+            inputConfig.RegisterAxis(SceneCamera.VerticalAxisBinding, InputAxis.MouseY);
+            inputConfig.RegisterAxis(SceneCamera.ScrollAxisBinding, InputAxis.MouseZ);
+
+            inputConfig.RegisterButton(SceneWindow.ToggleProfilerOverlayBinding, ButtonCode.P, ButtonModifier.CtrlAlt);
+            inputConfig.RegisterButton(SceneWindow.ViewToolBinding, ButtonCode.Q);
+            inputConfig.RegisterButton(SceneWindow.FrameBinding, ButtonCode.F);
+            inputConfig.RegisterButton(SceneWindow.MoveToolBinding, ButtonCode.W);
+            inputConfig.RegisterButton(SceneWindow.RotateToolBinding, ButtonCode.E);
+            inputConfig.RegisterButton(SceneWindow.ScaleToolBinding, ButtonCode.R);
+
+            inputConfig.RegisterButton(CutBinding, ButtonCode.X, ButtonModifier.Ctrl);
+            inputConfig.RegisterButton(CopyBinding, ButtonCode.C, ButtonModifier.Ctrl);
+            inputConfig.RegisterButton(PasteBinding, ButtonCode.V, ButtonModifier.Ctrl);
+            inputConfig.RegisterButton(DuplicateBinding, ButtonCode.D, ButtonModifier.Ctrl);
+            inputConfig.RegisterButton(DeleteBinding, ButtonCode.Delete);
+            inputConfig.RegisterButton(RenameBinding, ButtonCode.F2);
+
+            if (IsProjectLoaded)
+            {
+                monitor = new FolderMonitor(ProjectLibrary.ResourceFolder);
+                monitor.OnAdded += OnAssetModified;
+                monitor.OnRemoved += OnAssetModified;
+                monitor.OnModified += OnAssetModified;
+            }
+        }
+
+        /// <summary>
+        /// Triggered when the folder monitor detects an asset in the monitored folder was modified.
+        /// </summary>
+        /// <param name="path">Path to the modified file or folder.</param>
+        private static void OnAssetModified(string path)
+        {
+            ProjectLibrary.Refresh(path);
+        }
+
+        /// <summary>
+        /// Called every frame by the runtime.
+        /// </summary>
+        internal void OnEditorUpdate()
+        {
+            // Update managers
+            ProjectLibrary.Update();
+            codeManager.Update();
+        }
+
+        /// <summary>
+        /// Manually triggers a global shortcut.
+        /// </summary>
+        /// <param name="btn">Button for the shortcut. If this doesn't correspond to any shortcut, it is ignored.</param>
+        internal static void TriggerGlobalShortcut(VirtualButton btn)
+        {
+            IGlobalShortcuts window = null;
+
+            if (btn != PasteKey)
+            {
+                // The system ensures elsewhere that only either a resource or a scene object is selected, but not both
+                if (Selection.ResourcePaths.Length > 0)
+                {
+                    window = EditorWindow.GetWindow<LibraryWindow>();
+                }
+                else if (Selection.SceneObjects.Length > 0)
+                {
+                    window = EditorWindow.GetWindow<HierarchyWindow>();
+                    if (window == null)
+                        window = EditorWindow.GetWindow<SceneWindow>();
+                }
+
+                if (window != null)
+                {
+                    if (btn == CopyKey)
+                        window.OnCopyPressed();
+                    else if (btn == CutKey)
+                        window.OnCutPressed();
+                    else if (btn == PasteKey)
+                        window.OnPastePressed();
+                    else if (btn == DuplicateKey)
+                        window.OnDuplicatePressed();
+                    else if (btn == RenameKey)
+                        window.OnRenamePressed();
+                    else if (btn == DeleteKey)
+                        window.OnDeletePressed();
+                }
+            }
+            else
+            {
+
+                HierarchyWindow hierarchy = EditorWindow.GetWindow<HierarchyWindow>();
+                if (hierarchy != null && hierarchy.HasFocus)
+                    window = hierarchy;
+                else
+                {
+                    LibraryWindow library = EditorWindow.GetWindow<LibraryWindow>();
+                    if (library != null && library.HasFocus)
+                        window = library;
+                }
+
+                if (window != null)
+                    window.OnPastePressed();
+            }
+        }
+
+        /// <summary>
+        /// Creates a new empty scene.
+        /// </summary>
+        [MenuItem("File/New Scene", 10051, true)]
+        private static void NewScene()
+        {
+            LoadScene(null);
+        }
+
+        /// <summary>
+        /// Opens a dialog that allows the user to select a new prefab to load as the current scene. If current scene
+        /// is modified the user is offered a chance to save it.
+        /// </summary>
+        [MenuItem("File/Open Scene", ButtonModifier.Ctrl, ButtonCode.L, 10050)]
+        private static void LoadScene()
+        {
+            string[] scenePaths;
+            if (BrowseDialog.OpenFile(ProjectLibrary.ResourceFolder, "", false, out scenePaths))
+            {
+                if (scenePaths.Length > 0)
+                    LoadScene(scenePaths[0]);
+            }
+        }
+
+        /// <summary>
+        /// Opens a dialog to allows the user to select a location where to save the current scene. If scene was previously
+        /// saved it is instead automatically saved at the last location.
+        /// </summary>
+        public static void SaveScene(Action onSuccess = null, Action onFailure = null)
+        {
+            if (!string.IsNullOrEmpty(Scene.ActiveSceneUUID))
+            {
+                string scenePath = ProjectLibrary.GetPath(Scene.ActiveSceneUUID);
+                if (!string.IsNullOrEmpty(scenePath))
+                {
+                    SaveScene(scenePath);
+
+                    if (onSuccess != null)
+                        onSuccess();
+                }
+                else
+                    SaveSceneAs(onSuccess, onFailure);
+            }
+            else
+                SaveSceneAs(onSuccess, onFailure);
+        }
+
+        /// <summary>
+        /// Opens a dialog to allows the user to select a location where to save the current scene.
+        /// </summary>
+        public static void SaveSceneAs(Action onSuccess = null, Action onFailure = null)
+        {
+            string scenePath = "";
+            if (BrowseDialog.SaveFile(ProjectLibrary.ResourceFolder, "*.prefab", out scenePath))
+            {
+                if (!PathEx.IsPartOf(scenePath, ProjectLibrary.ResourceFolder))
+                {
+                    DialogBox.Open("Error", "The location must be inside the Resources folder of the project.",
+                        DialogBox.Type.OK,
+                        x =>
+                        {
+                            if (onFailure != null)
+                                onFailure();
+                        });
+                }
+                else
+                {
+                    // TODO - If path points to an existing non-scene asset or folder I should delete it otherwise
+                    //        Internal_SaveScene will silently fail.
+
+                    scenePath = Path.ChangeExtension(scenePath, ".prefab");
+                    SaveScene(scenePath);
+                }
+            }
+            else
+            {
+                // User canceled, so technically a success
+                if (onSuccess != null)
+                    onSuccess();
+            }
+        }
+
+        /// <summary>
+        /// Loads a prefab as the current scene at the specified path. If current scene is modified the user is offered a 
+        /// chance to save it.
+        /// </summary>
+        /// <param name="path">Path to a valid prefab relative to the resource folder. If path is empty a brand new
+        ///                    scene will be loaded.</param>
+        public static void LoadScene(string path)
+        {
+            Action<string> continueLoad =
+                (scenePath) =>
+                {
+                    if (string.IsNullOrEmpty(path))
+                        Scene.Clear();
+                    else
+                        Scene.Load(path);
+
+                    SetSceneDirty(false);
+
+                    ProjectSettings.LastOpenScene = scenePath;
+                    ProjectSettings.Save();
+                };
+
+            Action<DialogBox.ResultType> dialogCallback =
+            (result) =>
+            {
+                if (result == DialogBox.ResultType.Yes)
+                {
+                    SaveScene();
+                    continueLoad(path);
+                }
+                else if (result == DialogBox.ResultType.No)
+                    continueLoad(path);
+            };
+
+            if (IsSceneModified())
+            {
+                DialogBox.Open("Warning", "You current scene has modifications. Do you wish to save them first?",
+                    DialogBox.Type.YesNoCancel, dialogCallback);
+            }
+            else
+                continueLoad(path);
+        }
+
+        /// <summary>
+        /// Saves the currently loaded scene to the specified path.
+        /// </summary>
+        /// <param name="path">Path relative to the resource folder. This can be the path to the existing scene
+        ///                    prefab if it just needs updating. </param>
+        public static void SaveScene(string path)
+        {
+            Prefab scene = Internal_SaveScene(path);
+            Scene.SetActive(scene);
+
+            ProjectLibrary.Refresh(true);
+            SetSceneDirty(false);
+        }
+
+        /// <summary>
+        /// Checks does the folder at the provieded path contain a valid project.
+        /// </summary>
+        /// <param name="path">Absolute path to the root project folder.</param>
+        /// <returns>True if the folder contains a valid project.</returns>
+        public static bool IsValidProject(string path)
+        {
+            return Internal_IsValidProject(path);
+        }
+
+        /// <summary>
+        /// Contains a new project in the provided folder.
+        /// </summary>
+        /// <param name="path">Absolute path to the folder to create the project in. Name of this folder will be used as the
+        ///                    project's name.</param>
+        public static void CreateProject(string path)
+        {
+            Internal_CreateProject(path);
+        }
+
+        /// <summary>
+        /// Wrapper for menu items for <see cref="SaveScene(Action, Action)"/> method
+        /// </summary>
+        [MenuItem("File/Save Scene", ButtonModifier.Ctrl, ButtonCode.S, 10049)]
+        [ToolbarItem("Save Scene", ToolbarIcon.SaveScene, "Save scene (Ctrl + S)", 1998)]
+        private static void SaveSceneMenu()
+        {
+            SaveScene();
+        }
+
+        /// <summary>
+        /// Wrapper for menu items for <see cref="SaveSceneAs(Action, Action)"/> method
+        /// </summary>
+        [MenuItem("File/Save Scene As", 10048)]
+        private static void SaveSceneAsMenu()
+        {
+            SaveSceneAs();
+        }
+
+        /// <summary>
+        /// Opens a Project Window allowing you to browse for or create a project.
+        /// </summary>
+        [MenuItem("File/Open Project", 10100)]
+        [ToolbarItem("Open Project", ToolbarIcon.OpenProject, "Project manager", 2000)]
+        public static void BrowseForProject()
+        {
+            ProjectWindow.Open();
+        }
+
+        /// <summary>
+        /// Saves all data in the currently open project.
+        /// </summary>
+        [MenuItem("File/Save Project", 10099)]
+        [ToolbarItem("Save Project", ToolbarIcon.SaveProject, "Save project", 1999)]
+        public static void SaveProject()
+        {
+            foreach (var KVP in persistentData.dirtyResources)
+            {
+                string resourceUUID = KVP.Key;
+                string path = ProjectLibrary.GetPath(resourceUUID);
+                if (!IsNative(path))
+                    continue; // Native resources can't be changed
+
+                Resource resource = ProjectLibrary.Load<Resource>(path);
+
+                if(resource != null)
+                    ProjectLibrary.Save(resource);
+            }
+
+            persistentData.dirtyResources.Clear();
+            SetStatusProject(false);
+
+            Internal_SaveProject();
+        }
+
+        /// <summary>
+        /// Loads the project at the specified path. This method executes asynchronously.
+        /// </summary>
+        /// <param name="path">Absolute path to the project's root folder.</param>
+        public static void LoadProject(string path)
+        {
+            if (IsProjectLoaded && path == ProjectPath)
+                return;
+
+            if (!Internal_IsValidProject(path))
+            {
+                Debug.LogWarning("Provided path: \"" + path + "\" is not a valid project.");
+                return;
+            }
+
+            if (IsProjectLoaded)
+                UnloadProject();
+
+            Internal_LoadProject(path); // Triggers Internal_OnProjectLoaded when done
+        }
+
+        /// <summary>
+        /// Closes the editor.
+        /// </summary>
+        public static void Quit()
+        {
+            Internal_Quit();
+        }
+
+        /// <summary>
+        /// Toggles an existing toolbar button into an on or off state which changes the visuals of the button.
+        /// </summary>
+        /// <param name="name">Name of the existing button to toggle</param>
+        /// <param name="on">True to toggle on, false to toggle off (default)</param>
+        public static void ToggleToolbarItem(string name, bool on)
+        {
+            Internal_ToggleToolbarItem(name, on);
+        }
+
+        /// <summary>
+        /// Opens a file or a folder in the default external application.
+        /// </summary>
+        /// <param name="path">Absolute path to the file or folder to open.</param>
+        public static void OpenExternally(string path)
+        {
+            Internal_OpenExternally(path);
+        }
+
+        /// <summary>
+        /// Marks a resource as dirty so that it may be saved the next time the project is saved. Optionally you may also
+        /// call <see cref="ProjectLibrary.Save"/> to save it immediately.
+        /// </summary>
+        /// <param name="resource">Resource to mark as dirty</param>
+        public static void SetDirty(Resource resource)
+        {
+            if (resource == null)
+                return;
+
+            SetStatusProject(true);
+            persistentData.dirtyResources[resource.UUID] = true;
+        }
+
+        /// <summary>
+        /// Marks the current scene as dirty.
+        /// </summary>
+        public static void SetSceneDirty()
+        {
+            SetSceneDirty(true);
+        }
+
+        /// <summary>
+        /// Marks the current scene as clean or dirty.
+        /// </summary>
+        /// <param name="dirty">Should the scene be marked as clean or dirty.</param>
+        internal static void SetSceneDirty(bool dirty)
+        {
+            sceneDirty = dirty;
+            SetStatusScene(Scene.ActiveSceneName, dirty);
+
+            if (!dirty && Scene.ActiveSceneUUID != null)
+                persistentData.dirtyResources.Remove(Scene.ActiveSceneUUID);
+        }
+
+        /// <summary>
+        /// Checks is the specific resource dirty and needs saving.
+        /// </summary>
+        /// <param name="resource">Resource to check.</param>
+        /// <returns>True if the resource requires saving, false otherwise.</returns>
+        public static bool IsDirty(Resource resource)
+        {
+            return persistentData.dirtyResources.ContainsKey(resource.UUID);
+        }
+
+        /// <summary>
+        /// Checks does the path represent a native resource.
+        /// </summary>
+        /// <param name="path">Filename or path to check.</param>
+        /// <returns>True if the path represents a native resource.</returns>
+        public static bool IsNative(string path)
+        {
+            string extension = Path.GetExtension(path);
+
+            return extension == ".asset" || extension == ".prefab";
+        }
+
+        /// <summary>
+        /// Unloads the currently loaded project. Offers the user a chance to save the current scene if it is modified.
+        /// Automatically saves all project data before unloading.
+        /// </summary>
+        private static void UnloadProject()
+        {
+            Action continueUnload =
+                () =>
+                {
+                    Scene.Clear();
+
+                    if (monitor != null)
+                    {
+                        monitor.Destroy();
+                        monitor = null;
+                    }
+
+                    LibraryWindow window = EditorWindow.GetWindow<LibraryWindow>();
+                    if(window != null)
+                        window.Reset();
+
+                    SetSceneDirty(false);
+                    Internal_UnloadProject();
+                    SetStatusProject(false);
+                };
+
+            Action<DialogBox.ResultType> dialogCallback =
+            (result) =>
+            {
+                if (result == DialogBox.ResultType.Yes)
+                    SaveScene();
+
+                continueUnload();
+            };
+
+            if (IsSceneModified())
+            {
+                DialogBox.Open("Warning", "You current scene has modifications. Do you wish to save them first?",
+                    DialogBox.Type.YesNoCancel, dialogCallback);
+            }
+            else
+                continueUnload();
+        }
+
+        /// <summary>
+        /// Reloads all script assemblies in case they were modified. This action is delayed and will be executed
+        /// at the beginning of the next frame.
+        /// </summary>
+        public static void ReloadAssemblies()
+        {
+            Internal_ReloadAssemblies();
+        }
+
+        /// <summary>
+        /// Changes the scene displayed on the status bar.
+        /// </summary>
+        /// <param name="name">Name of the scene.</param>
+        /// <param name="modified">Whether to display the scene as modified or not.</param>
+        private static void SetStatusScene(string name, bool modified)
+        {
+            Internal_SetStatusScene(name, modified);
+        }
+
+        /// <summary>
+        /// Changes the project state displayed on the status bar.
+        /// </summary>
+        /// <param name="modified">Whether to display the project as modified or not.</param>
+        private static void SetStatusProject(bool modified)
+        {
+            Internal_SetStatusProject(modified);
+        }
+
+        /// <summary>
+        /// Displays or hides the "compilation in progress" visual on the status bar.
+        /// </summary>
+        /// <param name="compiling">True to display the visual, false otherwise.</param>
+        internal static void SetStatusCompiling(bool compiling)
+        {
+            Internal_SetStatusCompiling(compiling);
+        }
+
+        /// <summary>
+        /// Checks did we make any modifications to the scene since it was last saved.
+        /// </summary>
+        /// <returns>True if the scene was never saved, or was modified after last save.</returns>
+        public static bool IsSceneModified()
+        {
+            return sceneDirty;
+        }
+
+        /// <summary>
+        /// Runs a single frame of the game and pauses it. If the game is not currently running it will be started.
+        /// </summary>
+        public static void FrameStep()
+        {
+            if (IsStopped)
+            {
+                if (EditorSettings.GetBool(LogWindow.CLEAR_ON_PLAY_KEY, true))
+                {
+                    Debug.Clear();
+
+                    LogWindow log = EditorWindow.GetWindow<LogWindow>();
+                    if (log != null)
+                        log.Refresh();
+                }
+            }
+
+            ToggleToolbarItem("Play", false);
+            ToggleToolbarItem("Pause", true);
+            Internal_FrameStep();
+        }
+
+        /// <summary>
+        /// Executes any editor-specific unit tests. This should be called after a project is loaded if possible.
+        /// </summary>
+        private static void RunUnitTests()
+        {
+#if DEBUG
+            Internal_RunUnitTests();
+#endif
+        }
+
+        /// <summary>
+        /// Triggered by the runtime when <see cref="LoadProject"/> method completes.
+        /// </summary>
+        private static void Internal_OnProjectLoaded()
+        {
+            SetStatusProject(false);
+            if (!unitTestsExecuted)
+            {
+                RunUnitTests();
+                unitTestsExecuted = true;
+            }
+
+            if (!IsProjectLoaded)
+            {
+                ProjectWindow.Open();
+                return;
+            }
+
+            string projectPath = ProjectPath;
+
+            RecentProject[] recentProjects = EditorSettings.RecentProjects;
+            bool foundPath = false;
+            for (int i = 0; i < recentProjects.Length; i++)
+            {
+                if (PathEx.Compare(recentProjects[i].path, projectPath))
+                {
+                    recentProjects[i].accessTimestamp = (ulong)DateTime.Now.Ticks;
+                    EditorSettings.RecentProjects = recentProjects;
+                    foundPath = true;
+                    break;
+                }
+            }
+
+            if (!foundPath)
+            {
+                List<RecentProject> extendedRecentProjects = new List<RecentProject>();
+                extendedRecentProjects.AddRange(recentProjects);
+
+                RecentProject newProject = new RecentProject();
+                newProject.path = projectPath;
+                newProject.accessTimestamp = (ulong)DateTime.Now.Ticks;
+
+                extendedRecentProjects.Add(newProject);
+
+                EditorSettings.RecentProjects = extendedRecentProjects.ToArray();
+            }
+
+            EditorSettings.LastOpenProject = projectPath;
+            EditorSettings.Save();
+
+            ProjectLibrary.Refresh();
+            monitor = new FolderMonitor(ProjectLibrary.ResourceFolder);
+            monitor.OnAdded += OnAssetModified;
+            monitor.OnRemoved += OnAssetModified;
+            monitor.OnModified += OnAssetModified;
+
+            if (!string.IsNullOrWhiteSpace(ProjectSettings.LastOpenScene))
+            {
+                Scene.Load(ProjectSettings.LastOpenScene);
+                SetSceneDirty(false);
+            }
+        }
+
+        /// <summary>
+        /// Triggered by the runtime when the user clicks on the status bar.
+        /// </summary>
+        private static void Internal_OnStatusBarClicked()
+        {
+            EditorWindow.OpenWindow<LogWindow>();
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetStatusScene(string name, bool modified);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetStatusProject(bool modified);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetStatusCompiling(bool compiling);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetProjectPath();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetProjectName();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetProjectLoaded();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetCompilerPath();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetBuiltinReleaseAssemblyPath();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetBuiltinDebugAssemblyPath();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetScriptAssemblyPath();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetFrameworkAssemblyPath();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetEngineAssemblyName();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetEditorAssemblyName();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetScriptGameAssemblyName();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetScriptEditorAssemblyName();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern Prefab Internal_SaveScene(string path);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_IsValidProject(string path);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SaveProject();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_LoadProject(string path);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_UnloadProject();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_CreateProject(string path);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_ReloadAssemblies();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_OpenExternally(string path);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_RunUnitTests();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Quit();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_ToggleToolbarItem(string name, bool on);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetIsPlaying();
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetIsPlaying(bool value);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetIsPaused();
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetIsPaused(bool value);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_FrameStep();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetMainRenderTarget(IntPtr rendertarget);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_HasFocus();
+    }
+
+    /** @} */
+}

+ 46 - 40
Source/MBansheeEditor/IGlobalShortcuts.cs → Source/MBansheeEditor/General/IGlobalShortcuts.cs

@@ -1,40 +1,46 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Interface for editor windows that can respond to global shortcuts.
-    /// </summary>
-    internal interface IGlobalShortcuts
-    {
-        /// <summary>
-        /// Notifies the window that the delete shortcut was pressed.
-        /// </summary>
-        void OnDeletePressed();
-
-        /// <summary>
-        /// Notifies the window that the rename shortcut was pressed.
-        /// </summary>
-        void OnRenamePressed();
-
-        /// <summary>
-        /// Notifies the window that the duplicate shortcut was pressed.
-        /// </summary>
-        void OnDuplicatePressed();
-
-        /// <summary>
-        /// Notifies the window that the copy shortcut was pressed.
-        /// </summary>
-        void OnCopyPressed();
-
-        /// <summary>
-        /// Notifies the window that the cut shortcut was pressed.
-        /// </summary>
-        void OnCutPressed();
-
-        /// <summary>
-        /// Notifies the window that the paste shortcut was pressed.
-        /// </summary>
-        void OnPastePressed();
-    }
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+namespace BansheeEditor
+{
+    /** @addtogroup General 
+     *  @{
+     */
+
+    /// <summary>
+    /// Interface for editor windows that can respond to global shortcuts.
+    /// </summary>
+    internal interface IGlobalShortcuts
+    {
+        /// <summary>
+        /// Notifies the window that the delete shortcut was pressed.
+        /// </summary>
+        void OnDeletePressed();
+
+        /// <summary>
+        /// Notifies the window that the rename shortcut was pressed.
+        /// </summary>
+        void OnRenamePressed();
+
+        /// <summary>
+        /// Notifies the window that the duplicate shortcut was pressed.
+        /// </summary>
+        void OnDuplicatePressed();
+
+        /// <summary>
+        /// Notifies the window that the copy shortcut was pressed.
+        /// </summary>
+        void OnCopyPressed();
+
+        /// <summary>
+        /// Notifies the window that the cut shortcut was pressed.
+        /// </summary>
+        void OnCutPressed();
+
+        /// <summary>
+        /// Notifies the window that the paste shortcut was pressed.
+        /// </summary>
+        void OnPastePressed();
+    }
+
+    /** @} */
+}

+ 78 - 1
Source/MBansheeEditor/Program.cs → Source/MBansheeEditor/General/Program.cs

@@ -1,11 +1,86 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 using System;
-using System.Collections.Generic;
 using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup BansheeEditor
+     *  @{
+     */
+
+    /** @defgroup GUI-Editor GUI 
+     *
+     */
+
+    /** @defgroup Input-Editor Input 
+     *
+     */
+
+    /** @defgroup General General 
+     *
+     */
+
+    /** @defgroup Inspectors Inspectors 
+     *
+     */
+
+    /** @defgroup Script Script 
+     *
+     */
+
+    /** @defgroup Tests Tests 
+     *
+     */
+
+    /** @defgroup Utility-Editor Utility 
+     *
+     */
+
+    /** @defgroup Window Window 
+     *
+     */
+
+    /** @defgroup Windows Windows 
+     *  @{
+     */
+
+    /** @defgroup Build Build 
+     *
+     */
+
+    /** @defgroup Inspector Inspector 
+     *
+     */
+
+    /** @defgroup Library Library 
+     *
+     */
+
+    /** @defgroup Scene-Editor Scene 
+     *  @{
+     */
+
+    /** @defgroup Gizmos Gizmos 
+     *
+     */
+
+    /** @defgroup Handles Handles 
+     *
+     */
+
+    /** @} */
+
+    /** @defgroup Settings Settings 
+     *
+     */
+
+    /** @} */
+
+    /** @} */
+
+    /** @cond Interop */
+
     /// <summary>
     /// Entry point to the editor.
     /// </summary>
@@ -101,4 +176,6 @@ namespace BansheeEditor
             }
         }
     }
+
+    /** @endcond */
 }

+ 6 - 0
Source/MBansheeEditor/Selection.cs → Source/MBansheeEditor/General/Selection.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup General 
+     *  @{
+     */
+
     /// <summary>
     /// Handles scene object and resource selection. Triggeres events when selection changes and allows the user to query
     /// current selection state.
@@ -170,4 +174,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal static extern void Internal_PingSceneObject(SceneObject so);
     }
+
+    /** @} */
 }

+ 181 - 175
Source/MBansheeEditor/EditorInput.cs → Source/MBansheeEditor/Input/EditorInput.cs

@@ -1,175 +1,181 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Companion class to <see cref="Input"/> for use in editor only. Supplies events that trigger regardless whether
-    /// game is playing or not (unlike <see cref="Input"/>) which makes them usable for editor only scripts. Pollable
-    /// input should still be used from <see cref="Input"/>.
-    /// </summary>
-    public static class EditorInput
-    {
-        public delegate void ButtonEventDelegate(ButtonEvent ev);
-        public delegate void TextInputEventDelegate(TextInputEvent ev);
-        public delegate void PointerEventDelegate(PointerEvent ev);
-
-        /// <summary>
-        /// Triggered when a button on any device is pressed.
-        /// </summary>
-        public static event ButtonEventDelegate OnButtonDown;
-
-        /// <summary>
-        /// Triggered when a button on any device is released.
-        /// </summary>
-        public static event ButtonEventDelegate OnButtonUp;
-
-        /// <summary>
-        /// Triggered when a textual character is entered.
-        /// </summary>
-        public static event TextInputEventDelegate OnCharInput;
-
-        /// <summary>
-        /// Triggered when the pointing device (mouse, touch) is moved.
-        /// </summary>
-        public static event PointerEventDelegate OnPointerMoved;
-
-        /// <summary>
-        /// Triggered when a button on the pointing device (mouse, touch) is pressed.
-        /// </summary>
-        public static event PointerEventDelegate OnPointerPressed;
-
-        /// <summary>
-        /// Triggered when a button on the pointing device (mouse, touch) is released.
-        /// </summary>
-        public static event PointerEventDelegate OnPointerReleased;
-
-        /// <summary>
-        /// Triggered when a button on the pointing device (mouse, touch) is pressed twice in rappid succession.
-        /// </summary>
-        public static event PointerEventDelegate OnPointerDoubleClick;
-
-        /// <summary>
-        /// Triggered by runtime when a button is pressed.
-        /// </summary>
-        /// <param name="code">Code of the pressed button.</param>
-        /// <param name="deviceIdx">Device the event originated from.</param>
-        private static void Internal_TriggerButtonDown(ButtonCode code, int deviceIdx)
-        {
-            ButtonEvent ev = new ButtonEvent(code, deviceIdx);
-
-            if (OnButtonDown != null)
-                OnButtonDown(ev);
-        }
-
-        /// <summary>
-        /// Triggered by runtime when a button is released.
-        /// </summary>
-        /// <param name="code">Code of the released button.</param>
-        /// <param name="deviceIdx">Device the event originated from.</param>
-        private static void Internal_TriggerButtonUp(ButtonCode code, int deviceIdx)
-        {
-            ButtonEvent ev = new ButtonEvent(code, deviceIdx);
-
-            if (OnButtonUp != null)
-                OnButtonUp(ev);
-        }
-
-        /// <summary>
-        /// Triggered by runtime when character is input.
-        /// </summary>
-        /// <param name="textChar">Code of input character.</param>
-        private static void Internal_TriggerCharInput(int textChar)
-        {
-            TextInputEvent ev = new TextInputEvent(textChar);
-
-            if (OnCharInput != null)
-                OnCharInput(ev);
-        }
-
-        /// <summary>
-        /// Triggers when some pointing device (mouse cursor, touch) moves.
-        /// </summary>
-        /// <param name="screenPos">Screen position where the input event occurred.</param>
-        /// <param name="delta">Change in movement since last sent event.</param>
-        /// <param name="button">Button that triggered the pointer event. Might be irrelevant depending on event type. 
-        ///                      (for example move events don't correspond to a button.</param>
-        /// <param name="shift">Is shift button on the keyboard being held down.</param>
-        /// <param name="ctrl">Is control button on the keyboard being held down.</param>
-        /// <param name="alt">Is alt button on the keyboard being held down.</param>
-        /// <param name="scrollAmount">If mouse wheel is being scrolled, what is the amount. Only relevant for 
-        ///                            move events.</param>
-        private static void Internal_TriggerPointerMove(Vector2I screenPos, Vector2I delta, PointerButton button, bool shift,
-            bool ctrl, bool alt, float scrollAmount)
-        {
-            PointerEvent ev = new PointerEvent(screenPos, delta, button, shift, ctrl, alt, scrollAmount);
-
-            if (OnPointerMoved != null)
-                OnPointerMoved(ev);
-        }
-
-        /// <summary>
-        /// Triggers when some pointing device (mouse cursor, touch) button is pressed.
-        /// </summary>
-        /// <param name="screenPos">Screen position where the input event occurred.</param>
-        /// <param name="delta">Change in movement since last sent event.</param>
-        /// <param name="button">Button that triggered the pointer event. Might be irrelevant depending on event type. 
-        ///                      (for example move events don't correspond to a button.</param>
-        /// <param name="shift">Is shift button on the keyboard being held down.</param>
-        /// <param name="ctrl">Is control button on the keyboard being held down.</param>
-        /// <param name="alt">Is alt button on the keyboard being held down.</param>
-        /// <param name="scrollAmount">If mouse wheel is being scrolled, what is the amount. Only relevant for 
-        ///                            move events.</param>
-        private static void Internal_TriggerPointerPressed(Vector2I screenPos, Vector2I delta, PointerButton button, bool shift,
-            bool ctrl, bool alt, float scrollAmount)
-        {
-            PointerEvent ev = new PointerEvent(screenPos, delta, button, shift, ctrl, alt, scrollAmount);
-
-            if (OnPointerPressed != null)
-                OnPointerPressed(ev);
-        }
-
-        /// <summary>
-        /// Triggers when some pointing device (mouse cursor, touch) button is released.
-        /// </summary>
-        /// <param name="screenPos">Screen position where the input event occurred.</param>
-        /// <param name="delta">Change in movement since last sent event.</param>
-        /// <param name="button">Button that triggered the pointer event. Might be irrelevant depending on event type. 
-        ///                      (for example move events don't correspond to a button.</param>
-        /// <param name="shift">Is shift button on the keyboard being held down.</param>
-        /// <param name="ctrl">Is control button on the keyboard being held down.</param>
-        /// <param name="alt">Is alt button on the keyboard being held down.</param>
-        /// <param name="scrollAmount">If mouse wheel is being scrolled, what is the amount. Only relevant for 
-        ///                            move events.</param>
-        private static void Internal_TriggerPointerReleased(Vector2I screenPos, Vector2I delta, PointerButton button, bool shift,
-            bool ctrl, bool alt, float scrollAmount)
-        {
-            PointerEvent ev = new PointerEvent(screenPos, delta, button, shift, ctrl, alt, scrollAmount);
-
-            if (OnPointerReleased != null)
-                OnPointerReleased(ev);
-        }
-
-        /// <summary>
-        /// Triggers when some pointing device (mouse cursor, touch) button is double clicked.
-        /// </summary>
-        /// <param name="screenPos">Screen position where the input event occurred.</param>
-        /// <param name="delta">Change in movement since last sent event.</param>
-        /// <param name="button">Button that triggered the pointer event. Might be irrelevant depending on event type. 
-        ///                      (for example move events don't correspond to a button.</param>
-        /// <param name="shift">Is shift button on the keyboard being held down.</param>
-        /// <param name="ctrl">Is control button on the keyboard being held down.</param>
-        /// <param name="alt">Is alt button on the keyboard being held down.</param>
-        /// <param name="scrollAmount">If mouse wheel is being scrolled, what is the amount. Only relevant for 
-        ///                            move events.</param>
-        private static void Internal_TriggerPointerDoubleClick(Vector2I screenPos, Vector2I delta, PointerButton button, bool shift,
-            bool ctrl, bool alt, float scrollAmount)
-        {
-            PointerEvent ev = new PointerEvent(screenPos, delta, button, shift, ctrl, alt, scrollAmount);
-
-            if (OnPointerDoubleClick != null)
-                OnPointerDoubleClick(ev);
-        }
-    }
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /** @addtogroup Input-Editor 
+     *  @{
+     */
+
+    /// <summary>
+    /// Companion class to <see cref="Input"/> for use in editor only. Supplies events that trigger regardless whether
+    /// game is playing or not (unlike <see cref="Input"/>) which makes them usable for editor only scripts. Pollable
+    /// input should still be used from <see cref="Input"/>.
+    /// </summary>
+    public static class EditorInput
+    {
+        public delegate void ButtonEventDelegate(ButtonEvent ev);
+        public delegate void TextInputEventDelegate(TextInputEvent ev);
+        public delegate void PointerEventDelegate(PointerEvent ev);
+
+        /// <summary>
+        /// Triggered when a button on any device is pressed.
+        /// </summary>
+        public static event ButtonEventDelegate OnButtonDown;
+
+        /// <summary>
+        /// Triggered when a button on any device is released.
+        /// </summary>
+        public static event ButtonEventDelegate OnButtonUp;
+
+        /// <summary>
+        /// Triggered when a textual character is entered.
+        /// </summary>
+        public static event TextInputEventDelegate OnCharInput;
+
+        /// <summary>
+        /// Triggered when the pointing device (mouse, touch) is moved.
+        /// </summary>
+        public static event PointerEventDelegate OnPointerMoved;
+
+        /// <summary>
+        /// Triggered when a button on the pointing device (mouse, touch) is pressed.
+        /// </summary>
+        public static event PointerEventDelegate OnPointerPressed;
+
+        /// <summary>
+        /// Triggered when a button on the pointing device (mouse, touch) is released.
+        /// </summary>
+        public static event PointerEventDelegate OnPointerReleased;
+
+        /// <summary>
+        /// Triggered when a button on the pointing device (mouse, touch) is pressed twice in rappid succession.
+        /// </summary>
+        public static event PointerEventDelegate OnPointerDoubleClick;
+
+        /// <summary>
+        /// Triggered by runtime when a button is pressed.
+        /// </summary>
+        /// <param name="code">Code of the pressed button.</param>
+        /// <param name="deviceIdx">Device the event originated from.</param>
+        private static void Internal_TriggerButtonDown(ButtonCode code, int deviceIdx)
+        {
+            ButtonEvent ev = new ButtonEvent(code, deviceIdx);
+
+            if (OnButtonDown != null)
+                OnButtonDown(ev);
+        }
+
+        /// <summary>
+        /// Triggered by runtime when a button is released.
+        /// </summary>
+        /// <param name="code">Code of the released button.</param>
+        /// <param name="deviceIdx">Device the event originated from.</param>
+        private static void Internal_TriggerButtonUp(ButtonCode code, int deviceIdx)
+        {
+            ButtonEvent ev = new ButtonEvent(code, deviceIdx);
+
+            if (OnButtonUp != null)
+                OnButtonUp(ev);
+        }
+
+        /// <summary>
+        /// Triggered by runtime when character is input.
+        /// </summary>
+        /// <param name="textChar">Code of input character.</param>
+        private static void Internal_TriggerCharInput(int textChar)
+        {
+            TextInputEvent ev = new TextInputEvent(textChar);
+
+            if (OnCharInput != null)
+                OnCharInput(ev);
+        }
+
+        /// <summary>
+        /// Triggers when some pointing device (mouse cursor, touch) moves.
+        /// </summary>
+        /// <param name="screenPos">Screen position where the input event occurred.</param>
+        /// <param name="delta">Change in movement since last sent event.</param>
+        /// <param name="button">Button that triggered the pointer event. Might be irrelevant depending on event type. 
+        ///                      (for example move events don't correspond to a button.</param>
+        /// <param name="shift">Is shift button on the keyboard being held down.</param>
+        /// <param name="ctrl">Is control button on the keyboard being held down.</param>
+        /// <param name="alt">Is alt button on the keyboard being held down.</param>
+        /// <param name="scrollAmount">If mouse wheel is being scrolled, what is the amount. Only relevant for 
+        ///                            move events.</param>
+        private static void Internal_TriggerPointerMove(Vector2I screenPos, Vector2I delta, PointerButton button, bool shift,
+            bool ctrl, bool alt, float scrollAmount)
+        {
+            PointerEvent ev = new PointerEvent(screenPos, delta, button, shift, ctrl, alt, scrollAmount);
+
+            if (OnPointerMoved != null)
+                OnPointerMoved(ev);
+        }
+
+        /// <summary>
+        /// Triggers when some pointing device (mouse cursor, touch) button is pressed.
+        /// </summary>
+        /// <param name="screenPos">Screen position where the input event occurred.</param>
+        /// <param name="delta">Change in movement since last sent event.</param>
+        /// <param name="button">Button that triggered the pointer event. Might be irrelevant depending on event type. 
+        ///                      (for example move events don't correspond to a button.</param>
+        /// <param name="shift">Is shift button on the keyboard being held down.</param>
+        /// <param name="ctrl">Is control button on the keyboard being held down.</param>
+        /// <param name="alt">Is alt button on the keyboard being held down.</param>
+        /// <param name="scrollAmount">If mouse wheel is being scrolled, what is the amount. Only relevant for 
+        ///                            move events.</param>
+        private static void Internal_TriggerPointerPressed(Vector2I screenPos, Vector2I delta, PointerButton button, bool shift,
+            bool ctrl, bool alt, float scrollAmount)
+        {
+            PointerEvent ev = new PointerEvent(screenPos, delta, button, shift, ctrl, alt, scrollAmount);
+
+            if (OnPointerPressed != null)
+                OnPointerPressed(ev);
+        }
+
+        /// <summary>
+        /// Triggers when some pointing device (mouse cursor, touch) button is released.
+        /// </summary>
+        /// <param name="screenPos">Screen position where the input event occurred.</param>
+        /// <param name="delta">Change in movement since last sent event.</param>
+        /// <param name="button">Button that triggered the pointer event. Might be irrelevant depending on event type. 
+        ///                      (for example move events don't correspond to a button.</param>
+        /// <param name="shift">Is shift button on the keyboard being held down.</param>
+        /// <param name="ctrl">Is control button on the keyboard being held down.</param>
+        /// <param name="alt">Is alt button on the keyboard being held down.</param>
+        /// <param name="scrollAmount">If mouse wheel is being scrolled, what is the amount. Only relevant for 
+        ///                            move events.</param>
+        private static void Internal_TriggerPointerReleased(Vector2I screenPos, Vector2I delta, PointerButton button, bool shift,
+            bool ctrl, bool alt, float scrollAmount)
+        {
+            PointerEvent ev = new PointerEvent(screenPos, delta, button, shift, ctrl, alt, scrollAmount);
+
+            if (OnPointerReleased != null)
+                OnPointerReleased(ev);
+        }
+
+        /// <summary>
+        /// Triggers when some pointing device (mouse cursor, touch) button is double clicked.
+        /// </summary>
+        /// <param name="screenPos">Screen position where the input event occurred.</param>
+        /// <param name="delta">Change in movement since last sent event.</param>
+        /// <param name="button">Button that triggered the pointer event. Might be irrelevant depending on event type. 
+        ///                      (for example move events don't correspond to a button.</param>
+        /// <param name="shift">Is shift button on the keyboard being held down.</param>
+        /// <param name="ctrl">Is control button on the keyboard being held down.</param>
+        /// <param name="alt">Is alt button on the keyboard being held down.</param>
+        /// <param name="scrollAmount">If mouse wheel is being scrolled, what is the amount. Only relevant for 
+        ///                            move events.</param>
+        private static void Internal_TriggerPointerDoubleClick(Vector2I screenPos, Vector2I delta, PointerButton button, bool shift,
+            bool ctrl, bool alt, float scrollAmount)
+        {
+            PointerEvent ev = new PointerEvent(screenPos, delta, button, shift, ctrl, alt, scrollAmount);
+
+            if (OnPointerDoubleClick != null)
+                OnPointerDoubleClick(ev);
+        }
+    }
+
+    /** @} */
+}

+ 6 - 0
Source/MBansheeEditor/EditorVirtualInput.cs → Source/MBansheeEditor/Input/EditorVirtualInput.cs

@@ -4,6 +4,10 @@ using System.Runtime.CompilerServices;
 
 namespace BansheeEngine
 {
+    /** @addtogroup Input-Editor 
+     *  @{
+     */
+
     /// <summary>
     /// Handles virtual input that allows you to receive virtual input events that hide the actual physical input, allowing 
     /// you to easily change the input keys while being transparent to the external code.
@@ -65,4 +69,6 @@ namespace BansheeEngine
                 OnButtonHeld(button, deviceIdx);
         }
     };
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/BoxColliderInspector.cs

@@ -4,11 +4,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="BoxCollider"/> component.
     /// </summary>
     [CustomInspector(typeof(BoxCollider))]
-    public class BoxColliderInspector : ColliderInspector
+    internal class BoxColliderInspector : ColliderInspector
     {
         private GUIVector3Field centerField = new GUIVector3Field(new LocEdString("Center"));
         private GUIVector3Field extentsField = new GUIVector3Field(new LocEdString("Extents"));
@@ -72,4 +76,6 @@ namespace BansheeEditor
             base.Refresh(collider);
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/CameraInspector.cs

@@ -5,11 +5,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="Camera"/> component.
     /// </summary>
     [CustomInspector(typeof(Camera))]
-    public class CameraInspector : Inspector
+    internal class CameraInspector : Inspector
     {
         private GUIEnumField projectionTypeField = new GUIEnumField(typeof(ProjectionType), new LocEdString("Projection type"));
         private GUISliderField fieldOfView = new GUISliderField(1, 360, new LocEdString("Field of view"));
@@ -277,4 +281,6 @@ namespace BansheeEditor
                 modifyState |= InspectableState.Modified;
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/CapsuleColliderInspector.cs

@@ -4,11 +4,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="CapsuleCollider"/> component.
     /// </summary>
     [CustomInspector(typeof(CapsuleCollider))]
-    public class CapsuleColliderInspector : ColliderInspector
+    internal class CapsuleColliderInspector : ColliderInspector
     {
         private GUIVector3Field centerField = new GUIVector3Field(new LocEdString("Center"));
         private GUIVector3Field orientationField = new GUIVector3Field(new LocEdString("Orientation"));
@@ -101,4 +105,6 @@ namespace BansheeEditor
             base.Refresh(collider);
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/CharacterControllerInspector.cs

@@ -4,6 +4,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="CharacterController"/> component.
     /// </summary>
@@ -175,4 +179,6 @@ namespace BansheeEditor
                 modifyState |= InspectableState.Modified;
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/ColliderInspector.cs

@@ -4,10 +4,14 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders common inspector elements for all <see cref="Collider"/> components.
     /// </summary>
-    public abstract class ColliderInspector : Inspector
+    internal abstract class ColliderInspector : Inspector
     {
         private GUIToggleField isTriggerField = new GUIToggleField(new LocEdString("Is trigger"));
         private GUIFloatField massField = new GUIFloatField(new LocEdString("Mass"));
@@ -123,4 +127,6 @@ namespace BansheeEditor
                 modifyState |= InspectableState.Modified;
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/D6JointInspector.cs

@@ -5,11 +5,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="D6Joint"/> component.
     /// </summary>
     [CustomInspector(typeof(D6Joint))]
-    public class D6JointInspector : JointInspector
+    internal class D6JointInspector : JointInspector
     {
         private GUIEnumField[] motionFields = new GUIEnumField[(int) D6JointAxis.Count];
 
@@ -297,4 +301,6 @@ namespace BansheeEditor
                 OnConfirmed();
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/DistanceJointInspector.cs

@@ -4,11 +4,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="DistanceJoint"/> component.
     /// </summary>
     [CustomInspector(typeof(DistanceJoint))]
-    public class DistanceJointInspector : JointInspector
+    internal class DistanceJointInspector : JointInspector
     {
         private GUIToggleField enableMinLimitField = new GUIToggleField(new LocEdString("Enable minimum limit"));
         private GUIFloatField minLimitField = new GUIFloatField(new LocEdString("Minimum distance"));
@@ -154,4 +158,6 @@ namespace BansheeEditor
             base.Refresh(joint);
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/FixedJointInspector.cs

@@ -4,11 +4,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="FixedJoint"/> component.
     /// </summary>
     [CustomInspector(typeof(FixedJoint))]
-    public class FixedJointInspector : JointInspector
+    internal class FixedJointInspector : JointInspector
     {
         /// <inheritdoc/>
         protected internal override void Initialize()
@@ -35,4 +39,6 @@ namespace BansheeEditor
             return oldState;
         }
     }
+
+    /** @} */
 }

+ 8 - 2
Source/MBansheeEditor/Inspectors/FontInspector.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="Font"/> resource.
     /// </summary>
@@ -165,7 +169,7 @@ namespace BansheeEditor
         /// <summary>
         /// Row element used for displaying GUI for font size array elements.
         /// </summary>
-        public class FontSizeArrayRow : GUIListFieldRow
+        internal class FontSizeArrayRow : GUIListFieldRow
         {
             private GUIIntField sizeField;
 
@@ -195,7 +199,7 @@ namespace BansheeEditor
         /// <summary>
         /// Row element used for displaying GUI for character range array elements.
         /// </summary>
-        public class CharRangeArrayRow : GUIListFieldRow
+        internal class CharRangeArrayRow : GUIListFieldRow
         {
             private GUIIntField rangeStartField;
             private GUIIntField rangeEndField;
@@ -249,4 +253,6 @@ namespace BansheeEditor
             }
         }
     }
+
+    /** @} */
 }

+ 8 - 2
Source/MBansheeEditor/Inspectors/GUISkinInspector.cs

@@ -6,11 +6,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="GUISkin"/> resource.
     /// </summary>
     [CustomInspector(typeof(GUISkin))]
-    public class GUISkinInspector : Inspector
+    internal class GUISkinInspector : Inspector
     {
         private GUIDictionaryField<string, GUIElementStyle, GUIElementStyleEntry> valuesField;
 
@@ -105,7 +109,7 @@ namespace BansheeEditor
         /// <summary>
         /// Row element used for displaying GUI for GUI element style dictionary elements.
         /// </summary>
-        public class GUIElementStyleEntry : GUIDictionaryFieldRow
+        private class GUIElementStyleEntry : GUIDictionaryFieldRow
         {
             private GUITextField keyField;
             private GUIElementStyleGUI valueField;
@@ -627,4 +631,6 @@ namespace BansheeEditor
             }
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/GUIWidgetInspector.cs

@@ -4,6 +4,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="GUIWidget"/> component.
     /// </summary>
@@ -90,4 +94,6 @@ namespace BansheeEditor
                 modifyState |= InspectableState.Modified;
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/HingeJointInspector.cs

@@ -4,11 +4,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="HingeJoint"/> component.
     /// </summary>
     [CustomInspector(typeof(HingeJoint))]
-    public class HingeJointInspector : JointInspector
+    internal class HingeJointInspector : JointInspector
     {
         private GUIToggleField enableLimitField = new GUIToggleField(new LocEdString("Enable limit"));
         private LimitAngularRangeGUI limitGUI;
@@ -193,4 +197,6 @@ namespace BansheeEditor
             driveLayout.Active = enable;
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/JointInspector.cs

@@ -4,10 +4,14 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders common inspector elements for all <see cref="Joint"/> components.
     /// </summary>
-    public abstract class JointInspector : Inspector
+    internal abstract class JointInspector : Inspector
     {
         private GUIGameObjectField bodyAField = new GUIGameObjectField(typeof(Rigidbody), new LocEdString("Body A"));
         private GUIVector3Field bodyAOffsetField = new GUIVector3Field(new LocEdString("Body A offset"));
@@ -89,4 +93,6 @@ namespace BansheeEditor
                 modifyState |= InspectableState.Modified;
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/LightInspector.cs

@@ -5,11 +5,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="Light"/> component.
     /// </summary>
     [CustomInspector(typeof(Light))]
-    public class LightInspector : Inspector
+    internal class LightInspector : Inspector
     {
         private GUIEnumField lightTypeField = new GUIEnumField(typeof(LightType), new LocEdString("Light type"));
         private GUIColorField colorField = new GUIColorField(new LocEdString("Color"));
@@ -159,4 +163,6 @@ namespace BansheeEditor
                 modifyState |= InspectableState.Modified;
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/LimitInspectors.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Draws GUI elements for inspecting an <see cref="Spring"/> object.
     /// </summary>
@@ -489,4 +493,6 @@ namespace BansheeEditor
                 OnConfirmed();
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/MaterialInspector.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="Material"/> resource.
     /// </summary>
@@ -606,4 +610,6 @@ namespace BansheeEditor
             guiElem.Destroy();
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/MeshColliderInspector.cs

@@ -4,11 +4,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="MeshCollider"/> component.
     /// </summary>
     [CustomInspector(typeof(MeshCollider))]
-    public class MeshColliderInspector : ColliderInspector
+    internal class MeshColliderInspector : ColliderInspector
     {
         private GUIResourceField meshField = new GUIResourceField(typeof(PhysicsMesh), new LocEdString("Mesh"));
 
@@ -67,4 +71,6 @@ namespace BansheeEditor
             base.Refresh(collider);
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/MeshInspector.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="Mesh"/> resource.
     /// </summary>
@@ -118,4 +122,6 @@ namespace BansheeEditor
             ProjectLibrary.Reimport(resourcePath, importOptions, true);
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/PhysicsMaterialInspector.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="PhysicsMaterial"/> resource.
     /// </summary>
@@ -73,4 +77,6 @@ namespace BansheeEditor
             Layout.AddElement(restitutionField);
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/PhysicsMeshInspector.cs

@@ -4,6 +4,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="PhysicsMesh"/> resource.
     /// </summary>
@@ -22,4 +26,6 @@ namespace BansheeEditor
             return InspectableState.NotModified;
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/PlainTextInspector.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="PlainText"/> resource.
     /// </summary>
@@ -57,4 +61,6 @@ namespace BansheeEditor
             return InspectableState.NotModified;
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/PlaneColliderInspector.cs

@@ -4,11 +4,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="PlaneCollider"/> component.
     /// </summary>
     [CustomInspector(typeof(PlaneCollider))]
-    public class PlaneColliderInspector : ColliderInspector
+    internal class PlaneColliderInspector : ColliderInspector
     {
         private GUIVector3Field normalField = new GUIVector3Field(new LocEdString("Normal"));
         private GUIFloatField distanceField = new GUIFloatField(new LocEdString("Distance"));
@@ -82,4 +86,6 @@ namespace BansheeEditor
             base.Refresh(collider);
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/PrefabInspector.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="Prefab"/> resource.
     /// </summary>
@@ -23,4 +27,6 @@ namespace BansheeEditor
             return InspectableState.NotModified;
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/RenderableInspector.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="Renderable"/> component.
     /// </summary>
@@ -200,7 +204,7 @@ namespace BansheeEditor
         /// <summary>
         /// Row element used for displaying GUI for material array elements.
         /// </summary>
-        public class MaterialArrayRow : GUIListFieldRow
+        private class MaterialArrayRow : GUIListFieldRow
         {
             private GUIResourceField materialField;
 
@@ -232,4 +236,6 @@ namespace BansheeEditor
             }
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/RigidbodyInspector.cs

@@ -4,6 +4,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="Rigidbody"/> component.
     /// </summary>
@@ -149,4 +153,6 @@ namespace BansheeEditor
                 modifyState |= InspectableState.Modified;
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/ScriptCodeInspector.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="ScriptCode"/> resource.
     /// </summary>
@@ -118,4 +122,6 @@ namespace BansheeEditor
             ProjectLibrary.Reimport(resourcePath, importOptions, true);
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/ShaderInspector.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="Shader"/> resource.
     /// </summary>
@@ -23,4 +27,6 @@ namespace BansheeEditor
             return InspectableState.NotModified;
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/SliderJointInspector.cs

@@ -4,11 +4,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="SliderJoint"/> component.
     /// </summary>
     [CustomInspector(typeof(SliderJoint))]
-    public class SliderJointInspector : JointInspector
+    internal class SliderJointInspector : JointInspector
     {
         private GUIToggleField enableLimitField = new GUIToggleField(new LocEdString("Enable limit"));
         private LimitLinearRangeGUI limitGUI;
@@ -101,4 +105,6 @@ namespace BansheeEditor
             limitLayout.Active = enable;
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/SphereColliderInspector.cs

@@ -4,11 +4,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="SphereCollider"/> component.
     /// </summary>
     [CustomInspector(typeof(SphereCollider))]
-    public class SphereColliderInspector : ColliderInspector
+    internal class SphereColliderInspector : ColliderInspector
     {
         private GUIVector3Field centerField = new GUIVector3Field(new LocEdString("Center"));
         private GUIFloatField radiusField = new GUIFloatField(new LocEdString("Radius"));
@@ -72,4 +76,6 @@ namespace BansheeEditor
             base.Refresh(collider);
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/SphericalJointInspector.cs

@@ -4,11 +4,15 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="SphericalJoint"/> component.
     /// </summary>
     [CustomInspector(typeof(SphericalJoint))]
-    public class SphericalJointInspector : JointInspector
+    internal class SphericalJointInspector : JointInspector
     {
         private GUIToggleField enableLimitField = new GUIToggleField(new LocEdString("Enable limit"));
         private LimitConeRangeGUI limitGUI;
@@ -101,4 +105,6 @@ namespace BansheeEditor
             limitLayout.Active = enable;
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/SpriteTextureInspector.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="SpriteTexture"/> resource.
     /// </summary>
@@ -60,4 +64,6 @@ namespace BansheeEditor
             return InspectableState.NotModified;
         }
     }
+
+    /** @} */
 }

+ 7 - 1
Source/MBansheeEditor/Inspectors/StringTableInspector.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="StringTable"/> resource.
     /// </summary>
@@ -123,7 +127,7 @@ namespace BansheeEditor
         /// <summary>
         /// Row element used for displaying GUI for string table dictionary elements.
         /// </summary>
-        public class StringTableEntry : GUIDictionaryFieldRow
+        internal class StringTableEntry : GUIDictionaryFieldRow
         {
             private GUITextField keyField;
             private GUITextField valueField;
@@ -169,4 +173,6 @@ namespace BansheeEditor
             }
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspectors/Texture2DInspector.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspectors
+     *  @{
+     */
+
     /// <summary>
     /// Renders an inspector for the <see cref="Texture2D"/> resource.
     /// </summary>
@@ -105,4 +109,6 @@ namespace BansheeEditor
             ProjectLibrary.Reimport(resourcePath, importOptions, true);
         }
     }
+
+    /** @} */
 }

+ 101 - 100
Source/MBansheeEditor/MBansheeEditor.csproj

@@ -40,14 +40,14 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="AboutBox.cs" />
-    <Compile Include="BrowseDialog.cs" />
-    <Compile Include="BuildManager.cs" />
-    <Compile Include="BuildWindow.cs" />
-    <Compile Include="CodeEditor.cs" />
-    <Compile Include="ColorPicker.cs" />
-    <Compile Include="EditorPersistentData.cs" />
-    <Compile Include="IGlobalShortcuts.cs" />
+    <Compile Include="Windows\AboutBox.cs" />
+    <Compile Include="Windows\BrowseDialog.cs" />
+    <Compile Include="Windows\Build\BuildManager.cs" />
+    <Compile Include="Windows\Build\BuildWindow.cs" />
+    <Compile Include="Script\CodeEditor.cs" />
+    <Compile Include="Windows\ColorPicker.cs" />
+    <Compile Include="Windows\Inspector\EditorPersistentData.cs" />
+    <Compile Include="General\IGlobalShortcuts.cs" />
     <Compile Include="Inspectors\BoxColliderInspector.cs" />
     <Compile Include="Inspectors\CapsuleColliderInspector.cs" />
     <Compile Include="Inspectors\CharacterControllerInspector.cs" />
@@ -67,15 +67,15 @@
     <Compile Include="Inspectors\SliderJointInspector.cs" />
     <Compile Include="Inspectors\SphereColliderInspector.cs" />
     <Compile Include="Inspectors\SphericalJointInspector.cs" />
-    <Compile Include="LogWindow.cs" />
-    <Compile Include="DefaultSize.cs" />
-    <Compile Include="DialogBox.cs" />
-    <Compile Include="DragDrop.cs" />
-    <Compile Include="DropDownWindow.cs" />
-    <Compile Include="EditorInput.cs" />
-    <Compile Include="EditorVirtualInput.cs" />
-    <Compile Include="FolderMonitor.cs" />
-    <Compile Include="GameWindow.cs" />
+    <Compile Include="Windows\LogWindow.cs" />
+    <Compile Include="Window\DefaultSize.cs" />
+    <Compile Include="Windows\DialogBox.cs" />
+    <Compile Include="Utility\DragDrop.cs" />
+    <Compile Include="Window\DropDownWindow.cs" />
+    <Compile Include="Input\EditorInput.cs" />
+    <Compile Include="Input\EditorVirtualInput.cs" />
+    <Compile Include="Utility\FolderMonitor.cs" />
+    <Compile Include="Windows\GameWindow.cs" />
     <Compile Include="GUI\GUIDictionaryField.cs" />
     <Compile Include="GUI\GUIListField.cs" />
     <Compile Include="GUI\GUIEnumField.cs" />
@@ -83,7 +83,7 @@
     <Compile Include="GUI\GUISceneTreeView.cs" />
     <Compile Include="GUI\GUISliderField.cs" />
     <Compile Include="GUI\GUITextureField.cs" />
-    <Compile Include="HierarchyWindow.cs" />
+    <Compile Include="Windows\HierarchyWindow.cs" />
     <Compile Include="Inspectors\CameraInspector.cs" />
     <Compile Include="Inspectors\FontInspector.cs" />
     <Compile Include="Inspectors\GUISkinInspector.cs" />
@@ -98,25 +98,25 @@
     <Compile Include="Inspectors\SpriteTextureInspector.cs" />
     <Compile Include="Inspectors\StringTableInspector.cs" />
     <Compile Include="Inspectors\Texture2DInspector.cs" />
-    <Compile Include="Inspector\InspectableDictionary.cs" />
-    <Compile Include="Inspector\InspectorPersistentData.cs" />
-    <Compile Include="Inspector\InspectorUtility.cs" />
-    <Compile Include="Library\LibraryGUIContent.cs" />
-    <Compile Include="Library\LibraryDropDown.cs" />
-    <Compile Include="Library\LibraryGUIEntry.cs" />
-    <Compile Include="Library\LibraryMenu.cs" />
-    <Compile Include="Library\LibraryUtility.cs" />
-    <Compile Include="LocEdString.cs" />
-    <Compile Include="MenuItems.cs" />
-    <Compile Include="PrefabUtility.cs" />
-    <Compile Include="Library\LibraryDropTarget.cs" />
-    <Compile Include="OSDropTarget.cs" />
-    <Compile Include="EditorApplication.cs" />
-    <Compile Include="EditorBuiltin.cs" />
-    <Compile Include="EditorSettings.cs" />
-    <Compile Include="EditorStyles.cs" />
-    <Compile Include="EditorUtility.cs" />
-    <Compile Include="EditorWindow.cs" />
+    <Compile Include="Windows\Inspector\InspectableDictionary.cs" />
+    <Compile Include="Windows\Inspector\InspectorPersistentData.cs" />
+    <Compile Include="Windows\Inspector\InspectorUtility.cs" />
+    <Compile Include="Windows\Library\LibraryGUIContent.cs" />
+    <Compile Include="Windows\Library\LibraryDropDown.cs" />
+    <Compile Include="Windows\Library\LibraryGUIEntry.cs" />
+    <Compile Include="Windows\Library\LibraryMenu.cs" />
+    <Compile Include="Windows\Library\LibraryUtility.cs" />
+    <Compile Include="GUI\LocEdString.cs" />
+    <Compile Include="Window\MenuItems.cs" />
+    <Compile Include="Utility\PrefabUtility.cs" />
+    <Compile Include="Windows\Library\LibraryDropTarget.cs" />
+    <Compile Include="Utility\OSDropTarget.cs" />
+    <Compile Include="General\EditorApplication.cs" />
+    <Compile Include="Utility\EditorBuiltin.cs" />
+    <Compile Include="Windows\Settings\EditorSettings.cs" />
+    <Compile Include="GUI\EditorStyles.cs" />
+    <Compile Include="Utility\EditorUtility.cs" />
+    <Compile Include="Window\EditorWindow.cs" />
     <Compile Include="GUI\GUIGameObjectField.cs" />
     <Compile Include="GUI\GUIResourceField.cs" />
     <Compile Include="GUI\GUIVector3Field.cs" />
@@ -127,70 +127,70 @@
     <Compile Include="GUI\GUIToggleField.cs" />
     <Compile Include="GUI\GUIVector2Field.cs" />
     <Compile Include="GUI\GUIVector4Field.cs" />
-    <Compile Include="ImportOptions.cs" />
-    <Compile Include="Inspector\CustomInspector.cs" />
-    <Compile Include="Inspector\GenericInspector.cs" />
-    <Compile Include="Inspector\InspectableArray.cs" />
-    <Compile Include="Inspector\InspectableBool.cs" />
-    <Compile Include="Inspector\InspectableColor.cs" />
-    <Compile Include="Inspector\InspectableFieldLayout.cs" />
-    <Compile Include="Inspector\InspectableFloat.cs" />
-    <Compile Include="Inspector\InspectableGameObjectRef.cs" />
-    <Compile Include="Inspector\InspectableList.cs" />
-    <Compile Include="Inspector\InspectableObject.cs" />
-    <Compile Include="Inspector\InspectableField.cs" />
-    <Compile Include="Inspector\InspectableInt.cs" />
-    <Compile Include="Inspector\InspectableResourceRef.cs" />
-    <Compile Include="Inspector\InspectableString.cs" />
-    <Compile Include="Inspector\InspectableVector2.cs" />
-    <Compile Include="Inspector\InspectableVector3.cs" />
-    <Compile Include="Inspector\InspectableVector4.cs" />
-    <Compile Include="Inspector\Inspector.cs" />
-    <Compile Include="Inspector\InspectorWindow.cs" />
-    <Compile Include="MenuItem.cs" />
-    <Compile Include="ModalWindow.cs" />
-    <Compile Include="ProgressBar.cs" />
-    <Compile Include="ProjectSettings.cs" />
-    <Compile Include="Library\LibraryWindow.cs" />
-    <Compile Include="ProjectWindow.cs" />
-    <Compile Include="Scene\Gizmos\CharacterControllerGizmo.cs" />
-    <Compile Include="Scene\Gizmos\ColliderGizmos.cs" />
-    <Compile Include="Scene\Gizmos\JointGizmos.cs" />
-    <Compile Include="Scene\Gizmos\LightGizmos.cs" />
-    <Compile Include="Scene\SceneAxesGUI.cs" />
-    <Compile Include="Scene\SceneAxesHandle.cs" />
-    <Compile Include="Scene\SceneCamera.cs" />
-    <Compile Include="Scene\SceneGizmos.cs" />
-    <Compile Include="Scene\SceneGrid.cs" />
-    <Compile Include="Scene\SceneHandles.cs" />
-    <Compile Include="Scene\SceneSelection.cs" />
-    <Compile Include="Scene\SceneWindow.cs" />
-    <Compile Include="Scene\DefaultHandle.cs" />
-    <Compile Include="Scene\DefaultHandleManager.cs" />
-    <Compile Include="Scene\Handles.cs" />
-    <Compile Include="Scene\MoveHandle.cs" />
-    <Compile Include="Program.cs" />
-    <Compile Include="ProjectLibrary.cs" />
+    <Compile Include="Windows\Library\ImportOptions.cs" />
+    <Compile Include="Windows\Inspector\CustomInspector.cs" />
+    <Compile Include="Windows\Inspector\GenericInspector.cs" />
+    <Compile Include="Windows\Inspector\InspectableArray.cs" />
+    <Compile Include="Windows\Inspector\InspectableBool.cs" />
+    <Compile Include="Windows\Inspector\InspectableColor.cs" />
+    <Compile Include="Windows\Inspector\InspectableFieldLayout.cs" />
+    <Compile Include="Windows\Inspector\InspectableFloat.cs" />
+    <Compile Include="Windows\Inspector\InspectableGameObjectRef.cs" />
+    <Compile Include="Windows\Inspector\InspectableList.cs" />
+    <Compile Include="Windows\Inspector\InspectableObject.cs" />
+    <Compile Include="Windows\Inspector\InspectableField.cs" />
+    <Compile Include="Windows\Inspector\InspectableInt.cs" />
+    <Compile Include="Windows\Inspector\InspectableResourceRef.cs" />
+    <Compile Include="Windows\Inspector\InspectableString.cs" />
+    <Compile Include="Windows\Inspector\InspectableVector2.cs" />
+    <Compile Include="Windows\Inspector\InspectableVector3.cs" />
+    <Compile Include="Windows\Inspector\InspectableVector4.cs" />
+    <Compile Include="Windows\Inspector\Inspector.cs" />
+    <Compile Include="Windows\Inspector\InspectorWindow.cs" />
+    <Compile Include="Window\MenuItem.cs" />
+    <Compile Include="Window\ModalWindow.cs" />
+    <Compile Include="Windows\ProgressBar.cs" />
+    <Compile Include="Windows\Settings\ProjectSettings.cs" />
+    <Compile Include="Windows\Library\LibraryWindow.cs" />
+    <Compile Include="Windows\ProjectWindow.cs" />
+    <Compile Include="Windows\Scene\Gizmos\CharacterControllerGizmo.cs" />
+    <Compile Include="Windows\Scene\Gizmos\ColliderGizmos.cs" />
+    <Compile Include="Windows\Scene\Gizmos\JointGizmos.cs" />
+    <Compile Include="Windows\Scene\Gizmos\LightGizmos.cs" />
+    <Compile Include="Windows\Scene\SceneAxesGUI.cs" />
+    <Compile Include="Windows\Scene\SceneAxesHandle.cs" />
+    <Compile Include="Windows\Scene\SceneCamera.cs" />
+    <Compile Include="Windows\Scene\SceneGizmos.cs" />
+    <Compile Include="Windows\Scene\SceneGrid.cs" />
+    <Compile Include="Windows\Scene\SceneHandles.cs" />
+    <Compile Include="Windows\Scene\SceneSelection.cs" />
+    <Compile Include="Windows\Scene\SceneWindow.cs" />
+    <Compile Include="Windows\Scene\Handles\DefaultHandle.cs" />
+    <Compile Include="Windows\Scene\Handles\DefaultHandleManager.cs" />
+    <Compile Include="Windows\Scene\Handles\Handles.cs" />
+    <Compile Include="Windows\Scene\Handles\MoveHandle.cs" />
+    <Compile Include="General\Program.cs" />
+    <Compile Include="Windows\Library\ProjectLibrary.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Scene\CustomHandle.cs" />
-    <Compile Include="Scene\DrawGizmo.cs" />
-    <Compile Include="Scene\Gizmos.cs" />
-    <Compile Include="Scene\HandleDrawing.cs" />
-    <Compile Include="Scene\HandleSlider.cs" />
-    <Compile Include="Scene\HandleSliderDisc.cs" />
-    <Compile Include="Scene\HandleSliderLine.cs" />
-    <Compile Include="Scene\HandleSliderPlane.cs" />
-    <Compile Include="Scene\Handle.cs" />
-    <Compile Include="Scene\RotateHandle.cs" />
-    <Compile Include="Scene\ScaleHandle.cs" />
-    <Compile Include="ScriptCodeManager.cs" />
-    <Compile Include="ScriptCompiler.cs" />
-    <Compile Include="Selection.cs" />
-    <Compile Include="SettingsWindow.cs" />
-    <Compile Include="ToolbarItem.cs" />
-    <Compile Include="UndoRedo.cs" />
-    <Compile Include="UnitTests.cs" />
-    <Compile Include="UnitTestTypes.cs" />
+    <Compile Include="Windows\Scene\Handles\CustomHandle.cs" />
+    <Compile Include="Windows\Scene\Gizmos\DrawGizmo.cs" />
+    <Compile Include="Windows\Scene\Gizmos\Gizmos.cs" />
+    <Compile Include="Windows\Scene\Handles\HandleDrawing.cs" />
+    <Compile Include="Windows\Scene\Handles\HandleSlider.cs" />
+    <Compile Include="Windows\Scene\Handles\HandleSliderDisc.cs" />
+    <Compile Include="Windows\Scene\Handles\HandleSliderLine.cs" />
+    <Compile Include="Windows\Scene\Handles\HandleSliderPlane.cs" />
+    <Compile Include="Windows\Scene\Handles\Handle.cs" />
+    <Compile Include="Windows\Scene\Handles\RotateHandle.cs" />
+    <Compile Include="Windows\Scene\Handles\ScaleHandle.cs" />
+    <Compile Include="Script\ScriptCodeManager.cs" />
+    <Compile Include="Script\ScriptCompiler.cs" />
+    <Compile Include="General\Selection.cs" />
+    <Compile Include="Windows\Settings\SettingsWindow.cs" />
+    <Compile Include="Window\ToolbarItem.cs" />
+    <Compile Include="Utility\UndoRedo.cs" />
+    <Compile Include="Tests\UnitTests.cs" />
+    <Compile Include="Tests\UnitTestTypes.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\MBansheeEngine\MBansheeEngine.csproj">
@@ -198,6 +198,7 @@
       <Name>MBansheeEngine</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
     <PostBuildEvent>$(SolutionDir)..\..\Dependencies\tools\pdb2mdb.bat "$(TargetPath)" "$(ConfigurationName)"</PostBuildEvent>

+ 6 - 0
Source/MBansheeEditor/CodeEditor.cs → Source/MBansheeEditor/Script/CodeEditor.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Script
+     *  @{
+     */
+
     /// <summary>
     /// Contains all supported external code editors
     /// </summary>
@@ -107,4 +111,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal static extern void Internal_SyncSolution();
     }
+
+    /** @} */
 }

+ 6 - 1
Source/MBansheeEditor/ScriptCodeManager.cs → Source/MBansheeEditor/Script/ScriptCodeManager.cs

@@ -1,12 +1,15 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using System.IO;
 using System.Text;
 using System.Text.RegularExpressions;
 using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Script
+     *  @{
+     */
+
     /// <summary>
     /// Handles various operations related to script code in the active project, like compilation and code editor syncing.
     /// </summary>
@@ -230,4 +233,6 @@ namespace BansheeEditor
             return entry;
         }
     }
+
+    /** @} */
 }

+ 6 - 2
Source/MBansheeEditor/ScriptCompiler.cs → Source/MBansheeEditor/Script/ScriptCompiler.cs

@@ -4,15 +4,17 @@ using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
-using System.Linq;
 using System.Text;
 using System.Text.RegularExpressions;
 using System.Threading;
-using System.Threading.Tasks;
 using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Script
+     *  @{
+     */
+
     /// <summary>
     /// Type of assemblies that may be generated by the script compiler.
     /// </summary>
@@ -351,4 +353,6 @@ namespace BansheeEditor
         /// <summary>Column the message is referencing.</summary>
         public int column;
     }
+
+    /** @} */
 }

+ 12 - 6
Source/MBansheeEditor/UnitTestTypes.cs → Source/MBansheeEditor/Tests/UnitTestTypes.cs

@@ -5,10 +5,14 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Tests
+     *  @{
+     */
+
     /// <summary>
     /// Helper component used for unit tests.
     /// </summary>
-    public class UT1_Component1 : Component
+    internal class UT1_Component1 : Component
     {
         public int a;
         public string b;
@@ -36,7 +40,7 @@ namespace BansheeEditor
     /// <summary>
     /// Helper component used for unit tests.
     /// </summary>
-    public class UT1_Component2 : Component
+    internal class UT1_Component2 : Component
     {
         public int a2;
     }
@@ -45,7 +49,7 @@ namespace BansheeEditor
     /// Helper type used for unit tests.
     /// </summary>
     [SerializeObject]
-    public class UT1_SerzCls
+    internal class UT1_SerzCls
     {
         public int someValue2;
         public string anotherValue2;
@@ -57,7 +61,7 @@ namespace BansheeEditor
     /// Helper type used for unit tests.
     /// </summary>
     [SerializeObject]
-    public struct UT1_SerzObj
+    internal struct UT1_SerzObj
     {
         public UT1_SerzObj(int someValue, string anotherValue)
         {
@@ -73,7 +77,7 @@ namespace BansheeEditor
     /// Helper type used for unit tests.
     /// </summary>
     [SerializeObject]
-    public class UT_DiffChildObj
+    internal class UT_DiffChildObj
     {
         public int plain1 = 101;
         public string plain2 = "oneoone";
@@ -83,7 +87,7 @@ namespace BansheeEditor
     /// Helper type used for unit tests.
     /// </summary>
     [SerializeObject]
-    public class UT_DiffObj
+    internal class UT_DiffObj
     {
         public int plain1 = 5;
         public string plain2 = "six";
@@ -130,4 +134,6 @@ namespace BansheeEditor
             dictComplex2[32] = new UT_DiffChildObj();
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/UnitTests.cs → Source/MBansheeEditor/Tests/UnitTests.cs

@@ -11,6 +11,10 @@ using DebugUnit = System.Diagnostics.Debug;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Tests
+     *  @{
+     */
+
     /// <summary>
     /// Contains various managed unit tests.
     /// </summary>
@@ -793,4 +797,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_UT3_ApplyDiff(UT_DiffObj obj);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/DragDrop.cs → Source/MBansheeEditor/Utility/DragDrop.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Utility-Editor
+     *  @{
+     */
+
     /// <summary>
     /// Manages all drag and drop events within the engine. This doesn't include external OS drag and drop events.
     /// </summary>
@@ -145,4 +149,6 @@ namespace BansheeEditor
         SceneObject,
         None
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/EditorBuiltin.cs → Source/MBansheeEditor/Utility/EditorBuiltin.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Utility-Editor
+     *  @{
+     */
+
     /// <summary>
     /// Types of icons that may be displayed on the tool bar.
     /// </summary>
@@ -161,4 +165,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern SpriteTexture Internal_GetLogIcon(LogIcon icon, int size, bool dark);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/EditorUtility.cs → Source/MBansheeEditor/Utility/EditorUtility.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Utility-Editor
+     *  @{
+     */
+
     /// <summary>
     /// Contains various utility methods used throughout the editor.
     /// </summary>
@@ -83,4 +87,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern Resource[] Internal_FindDependencies(Resource resource, bool recursive);
     }
+
+    /** @} */
 }

+ 6 - 4
Source/MBansheeEditor/FolderMonitor.cs → Source/MBansheeEditor/Utility/FolderMonitor.cs

@@ -1,15 +1,15 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 using System;
-using System.Collections.Generic;
-using System.Linq;
 using System.Runtime.CompilerServices;
-using System.Text;
-using System.Threading.Tasks;
 using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Utility-Editor
+     *  @{
+     */
+
     /// <summary>
     /// Allows monitoring a file system folder for changes. Depending on the flags set this monitor can notify you when 
     /// file is changed/moved/renamed and similar.
@@ -101,4 +101,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_Destroy(IntPtr thisPtr);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/OSDropTarget.cs → Source/MBansheeEditor/Utility/OSDropTarget.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Utility-Editor
+     *  @{
+     */
+
     /// <summary>
     /// Drop targets allow you to register a certain portion of a window as a drop target that accepts file drops from the
     /// OS (platform) specific drag and drop system. You will receive events with the specified drop area as long as it is 
@@ -123,4 +127,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern string[] Internal_GetFilePaths(IntPtr nativeInstance);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/PrefabUtility.cs → Source/MBansheeEditor/Utility/PrefabUtility.cs

@@ -6,6 +6,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Utility-Editor
+     *  @{
+     */
+
     /// <summary>
     /// Performs various prefab specific operations.
     /// </summary>
@@ -97,4 +101,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern SceneObject Internal_GetPrefabParent(IntPtr nativeInstance);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/UndoRedo.cs → Source/MBansheeEditor/Utility/UndoRedo.cs

@@ -7,6 +7,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Utility-Editor
+     *  @{
+     */
+
     /// <summary>
     /// Provides functionality to undo or redo recently performed operations in the editor. All commands executed from this
     /// class are undoable/redoable.
@@ -258,4 +262,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal static extern void Internal_BreakPrefab(IntPtr soPtr, string description);
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/DefaultSize.cs → Source/MBansheeEditor/Window/DefaultSize.cs

@@ -4,6 +4,10 @@ using System;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Window
+     *  @{
+     */
+
     /// <summary>
     /// Can be placed on <see cref="EditorWindow"/> class to provide a default size for the window when it is first opened.
     /// </summary>
@@ -19,4 +23,6 @@ namespace BansheeEditor
             this.height = height;
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/DropDownWindow.cs → Source/MBansheeEditor/Window/DropDownWindow.cs

@@ -7,6 +7,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Window
+     *  @{
+     */
+
     /// <summary>
     /// Base class for all drop down window implementations. Drop down windows are temporary windows that open above all
     /// other GUI, and close as soon user clicks outside of them.
@@ -128,4 +132,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_WindowToScreenPos(IntPtr nativeInstance, ref Vector2I position, out Vector2I screenPos);
     }
+
+    /** @} */
 }

+ 178 - 172
Source/MBansheeEditor/EditorWindow.cs → Source/MBansheeEditor/Window/EditorWindow.cs

@@ -1,172 +1,178 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using System;
-using System.Runtime.CompilerServices;
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Base class for all editor windows. Editor window can be docked on the main editor window or float as a separate 
-    /// window. User is allowed to reposition and resize the window as he wishes. Editor window GUI is fully customizable.
-    /// </summary>
-    public class EditorWindow : ScriptObject
-    {
-        /// <summary>
-        /// Width of the window in pixels.
-        /// </summary>
-        public int Width
-        {
-            get { return Internal_GetWidth(mCachedPtr); }
-        }
-
-        /// <summary>
-        /// Height of the window in pixels.
-        /// </summary>
-        public int Height
-        {
-            get { return Internal_GetHeight(mCachedPtr); }
-        }
-
-        /// <summary>
-        /// Screen space bounds of the window.
-        /// </summary>
-        public Rect2I Bounds
-        {
-            get
-            {
-                Rect2I bounds;
-                Internal_GetBounds(mCachedPtr, out bounds);
-                return bounds;
-            }
-        }
-
-        /// <summary>
-        /// Determines whether the editor window currently has keyboard focus (has been clicked on most recently). Window
-        /// that isn't active (is not the active tab) cannot be put into focus without activating it first.
-        /// </summary>
-        public bool HasFocus
-        {
-            get { return Internal_HasFocus(mCachedPtr); }
-            set { Internal_SetFocus(mCachedPtr, value); }
-        }
-
-        /// <summary>
-        /// Determines is the mouse pointer currently hovering over the editor window.
-        /// </summary>
-        public bool IsPointerHovering { get { return Internal_IsPointerHovering(mCachedPtr); } }
-
-        /// <summary>
-        /// Checks if the window's tab is currently active. If the window is floating or not sharing space with any other
-        /// windows (just a single tab), it is always considered active.
-        /// </summary>
-        public bool Active { get { return Internal_IsActive(mCachedPtr); } }
-
-        protected GUIPanel GUI;
-
-        /// <summary>
-        /// Opens an editor window. If window is already open it returns the existing instance.
-        /// </summary>
-        /// <typeparam name="T">Type of window to open.</typeparam>
-        /// <returns>Instance of the open window.</returns>
-        public static T OpenWindow<T>() where T : EditorWindow
-        {
-            return (T)Internal_CreateOrGetInstance(typeof(T).Namespace, typeof(T).Name);
-        }
-
-        /// <summary>
-        /// Retrieves instance of an open window.
-        /// </summary>
-        /// <typeparam name="T">Type of window to retrieve the instance of.</typeparam>
-        /// <returns>Instance of the winodow if it is open, null otherwise.</returns>
-        public static T GetWindow<T>() where T : EditorWindow
-        {
-            return (T)Internal_GetInstance(typeof(T).Namespace, typeof(T).Name);
-        }
-
-        /// <summary>
-        /// Converts coordinates in screen space to coordinates relative to the window.
-        /// </summary>
-        /// <param name="screenPos">Coordinates in screen space.</param>
-        /// <returns>Coordinates relative to the window.</returns>
-        public Vector2I ScreenToWindowPos(Vector2I screenPos)
-        {
-            Vector2I windowPos;
-            Internal_ScreenToWindowPos(mCachedPtr, ref screenPos, out windowPos);
-            return windowPos;
-        }
-
-        /// <summary>
-        /// Converts coordinates relative to the window to screen space to coordinates.
-        /// </summary>
-        /// <param name="windowPos">Coordinates relative to the window.</param>
-        /// <returns>Coordinates in screen space.</returns>
-        public Vector2I WindowToScreenPos(Vector2I windowPos)
-        {
-            Vector2I screenPos;
-            Internal_WindowToScreenPos(mCachedPtr, ref windowPos, out screenPos);
-            return screenPos;
-        }
-
-        /// <summary>
-        /// Triggered whenever the window size ranges.
-        /// </summary>
-        /// <param name="width">New width of the window in pixels.</param>
-        /// <param name="height">New height of the window in pixels.</param>
-        protected virtual void WindowResized(int width, int height)
-        {
-
-        }
-
-        /// <summary>
-        /// Triggered whenever the window gains or loses focus.
-        /// </summary>
-        /// <param name="inFocus">True if focus was gained, false otherwise.</param>
-        protected virtual void FocusChanged(bool inFocus)
-        {
-            
-        }
-
-        /// <summary>
-        /// Name of the window to display in the title bar.
-        /// </summary>
-        /// <returns>Name of the window to display in the title bar.</returns>
-        protected virtual LocString GetDisplayName()
-        {
-            return GetType().Name;
-        }
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern EditorWindow Internal_CreateOrGetInstance(string ns, string typeName);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern EditorWindow Internal_GetInstance(string ns, string typeName);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern int Internal_GetWidth(IntPtr nativeInstance);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern int Internal_GetHeight(IntPtr nativeInstance);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool Internal_HasFocus(IntPtr nativeInstance);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetFocus(IntPtr nativeInstance, bool focus);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool Internal_IsActive(IntPtr nativeInstance);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool Internal_IsPointerHovering(IntPtr nativeInstance);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_GetBounds(IntPtr nativeInstance, out Rect2I bounds);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_ScreenToWindowPos(IntPtr nativeInstance, ref Vector2I position, out Vector2I windowPos);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_WindowToScreenPos(IntPtr nativeInstance, ref Vector2I position, out Vector2I screenPos);
-    }
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System;
+using System.Runtime.CompilerServices;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /** @addtogroup Window
+     *  @{
+     */
+
+    /// <summary>
+    /// Base class for all editor windows. Editor window can be docked on the main editor window or float as a separate 
+    /// window. User is allowed to reposition and resize the window as he wishes. Editor window GUI is fully customizable.
+    /// </summary>
+    public class EditorWindow : ScriptObject
+    {
+        /// <summary>
+        /// Width of the window in pixels.
+        /// </summary>
+        public int Width
+        {
+            get { return Internal_GetWidth(mCachedPtr); }
+        }
+
+        /// <summary>
+        /// Height of the window in pixels.
+        /// </summary>
+        public int Height
+        {
+            get { return Internal_GetHeight(mCachedPtr); }
+        }
+
+        /// <summary>
+        /// Screen space bounds of the window.
+        /// </summary>
+        public Rect2I Bounds
+        {
+            get
+            {
+                Rect2I bounds;
+                Internal_GetBounds(mCachedPtr, out bounds);
+                return bounds;
+            }
+        }
+
+        /// <summary>
+        /// Determines whether the editor window currently has keyboard focus (has been clicked on most recently). Window
+        /// that isn't active (is not the active tab) cannot be put into focus without activating it first.
+        /// </summary>
+        public bool HasFocus
+        {
+            get { return Internal_HasFocus(mCachedPtr); }
+            set { Internal_SetFocus(mCachedPtr, value); }
+        }
+
+        /// <summary>
+        /// Determines is the mouse pointer currently hovering over the editor window.
+        /// </summary>
+        public bool IsPointerHovering { get { return Internal_IsPointerHovering(mCachedPtr); } }
+
+        /// <summary>
+        /// Checks if the window's tab is currently active. If the window is floating or not sharing space with any other
+        /// windows (just a single tab), it is always considered active.
+        /// </summary>
+        public bool Active { get { return Internal_IsActive(mCachedPtr); } }
+
+        protected GUIPanel GUI;
+
+        /// <summary>
+        /// Opens an editor window. If window is already open it returns the existing instance.
+        /// </summary>
+        /// <typeparam name="T">Type of window to open.</typeparam>
+        /// <returns>Instance of the open window.</returns>
+        public static T OpenWindow<T>() where T : EditorWindow
+        {
+            return (T)Internal_CreateOrGetInstance(typeof(T).Namespace, typeof(T).Name);
+        }
+
+        /// <summary>
+        /// Retrieves instance of an open window.
+        /// </summary>
+        /// <typeparam name="T">Type of window to retrieve the instance of.</typeparam>
+        /// <returns>Instance of the winodow if it is open, null otherwise.</returns>
+        public static T GetWindow<T>() where T : EditorWindow
+        {
+            return (T)Internal_GetInstance(typeof(T).Namespace, typeof(T).Name);
+        }
+
+        /// <summary>
+        /// Converts coordinates in screen space to coordinates relative to the window.
+        /// </summary>
+        /// <param name="screenPos">Coordinates in screen space.</param>
+        /// <returns>Coordinates relative to the window.</returns>
+        public Vector2I ScreenToWindowPos(Vector2I screenPos)
+        {
+            Vector2I windowPos;
+            Internal_ScreenToWindowPos(mCachedPtr, ref screenPos, out windowPos);
+            return windowPos;
+        }
+
+        /// <summary>
+        /// Converts coordinates relative to the window to screen space to coordinates.
+        /// </summary>
+        /// <param name="windowPos">Coordinates relative to the window.</param>
+        /// <returns>Coordinates in screen space.</returns>
+        public Vector2I WindowToScreenPos(Vector2I windowPos)
+        {
+            Vector2I screenPos;
+            Internal_WindowToScreenPos(mCachedPtr, ref windowPos, out screenPos);
+            return screenPos;
+        }
+
+        /// <summary>
+        /// Triggered whenever the window size ranges.
+        /// </summary>
+        /// <param name="width">New width of the window in pixels.</param>
+        /// <param name="height">New height of the window in pixels.</param>
+        protected virtual void WindowResized(int width, int height)
+        {
+
+        }
+
+        /// <summary>
+        /// Triggered whenever the window gains or loses focus.
+        /// </summary>
+        /// <param name="inFocus">True if focus was gained, false otherwise.</param>
+        protected virtual void FocusChanged(bool inFocus)
+        {
+            
+        }
+
+        /// <summary>
+        /// Name of the window to display in the title bar.
+        /// </summary>
+        /// <returns>Name of the window to display in the title bar.</returns>
+        protected virtual LocString GetDisplayName()
+        {
+            return GetType().Name;
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern EditorWindow Internal_CreateOrGetInstance(string ns, string typeName);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern EditorWindow Internal_GetInstance(string ns, string typeName);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern int Internal_GetWidth(IntPtr nativeInstance);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern int Internal_GetHeight(IntPtr nativeInstance);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_HasFocus(IntPtr nativeInstance);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetFocus(IntPtr nativeInstance, bool focus);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_IsActive(IntPtr nativeInstance);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_IsPointerHovering(IntPtr nativeInstance);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetBounds(IntPtr nativeInstance, out Rect2I bounds);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_ScreenToWindowPos(IntPtr nativeInstance, ref Vector2I position, out Vector2I windowPos);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_WindowToScreenPos(IntPtr nativeInstance, ref Vector2I position, out Vector2I screenPos);
+    }
+
+    /** @} */
+}

+ 75 - 69
Source/MBansheeEditor/MenuItem.cs → Source/MBansheeEditor/Window/MenuItem.cs

@@ -1,69 +1,75 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using System;
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Adds an entry to the main menu bar. Clicking on that entry will trigger the method the attribute is attached to.
-    /// The method must be static, have no parameters or return values otherwise the attribute will be ignored.
-    /// </summary>
-    [AttributeUsage(AttributeTargets.Method)]
-    public sealed class MenuItem : Attribute
-    {
-        /// <summary>
-        /// Creates a new menu item attribute with a shortcut. Pressing the shortcut key or selecting the item in the menu
-        /// will trigger the menu item callback.
-        /// </summary>
-        /// <param name="path">Path that determines where in the menu to add the element. All path elements must be 
-        ///                    separated by /, for example "View/Toolbars/Find".</param>
-        /// <param name="shortcutModifier">Optional shortcut modifier that needs to be pressed along with the shortcut 
-        ///                                button in order to trigger the shortcut.</param>
-        /// <param name="shortcutKey">Shortcut key that will trigger the shortcut.</param>
-        /// <param name="priority">Priority determines the position of the menu item relative to its siblings.
-        ///                        Higher priority means it will be placed earlier in the menu.</param>
-        /// <param name="separator">Determines should a separator be inserted just before this element.</param>
-        /// <param name="contextCallback">Name of a method that returns a boolean determining whether the menu item callback
-        ///                               is allowed to trigger. This is useful if menu items are only valid in specific
-        ///                               situations (for example a scene object must be selected). The method must be
-        ///                               static, return a boolean value, accept no parameters and be in the same class as
-        ///                               the method this attribute is attached to.</param>
-        public MenuItem(string path, ButtonModifier shortcutModifier, ButtonCode shortcutKey, int priority = 0, 
-            bool separator = false, string contextCallback = null)
-        {
-            this.path = path;
-            this.shortcut = new ShortcutKey(shortcutModifier, shortcutKey);
-            this.priority = priority;
-            this.separator = separator;
-            this.contextCallback = contextCallback;
-        }
-
-        /// <summary>
-        /// Creates a new menu item attribute. Selecting the item in the menu will trigger the menu item callback.
-        /// </summary>
-        /// <param name="path">Path that determines where in the menu to add the element. All path elements must be 
-        ///                    separated by /, for example "View/Toolbars/Find".</param>
-        /// <param name="priority">Priority determines the position of the menu item relative to its siblings.
-        ///                        Higher priority means it will be placed earlier in the menu.</param>
-        /// <param name="separator">Determines should a separator be inserted just before this element.</param>
-        /// <param name="contextCallback">Name of a method that returns a boolean determining whether the menu item callback
-        ///                               is allowed to trigger. This is useful if menu items are only valid in specific
-        ///                               situations (for example a scene object must be selected). The method must be
-        ///                               static, return a boolean value, accept no parameters and be in the same class as
-        ///                               the method this attribute is attached to.</param>
-        public MenuItem(string path, int priority = 0, bool separator = false, string contextCallback = null)
-        {
-            this.path = path;
-            this.priority = priority;
-            this.separator = separator;
-            this.contextCallback = contextCallback;
-        }
-
-        private string path;
-        private ShortcutKey shortcut;
-        private int priority;
-        private bool separator;
-        private string contextCallback;
-    }
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /** @addtogroup Window
+     *  @{
+     */
+
+    /// <summary>
+    /// Adds an entry to the main menu bar. Clicking on that entry will trigger the method the attribute is attached to.
+    /// The method must be static, have no parameters or return values otherwise the attribute will be ignored.
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Method)]
+    public sealed class MenuItem : Attribute
+    {
+        /// <summary>
+        /// Creates a new menu item attribute with a shortcut. Pressing the shortcut key or selecting the item in the menu
+        /// will trigger the menu item callback.
+        /// </summary>
+        /// <param name="path">Path that determines where in the menu to add the element. All path elements must be 
+        ///                    separated by /, for example "View/Toolbars/Find".</param>
+        /// <param name="shortcutModifier">Optional shortcut modifier that needs to be pressed along with the shortcut 
+        ///                                button in order to trigger the shortcut.</param>
+        /// <param name="shortcutKey">Shortcut key that will trigger the shortcut.</param>
+        /// <param name="priority">Priority determines the position of the menu item relative to its siblings.
+        ///                        Higher priority means it will be placed earlier in the menu.</param>
+        /// <param name="separator">Determines should a separator be inserted just before this element.</param>
+        /// <param name="contextCallback">Name of a method that returns a boolean determining whether the menu item callback
+        ///                               is allowed to trigger. This is useful if menu items are only valid in specific
+        ///                               situations (for example a scene object must be selected). The method must be
+        ///                               static, return a boolean value, accept no parameters and be in the same class as
+        ///                               the method this attribute is attached to.</param>
+        public MenuItem(string path, ButtonModifier shortcutModifier, ButtonCode shortcutKey, int priority = 0, 
+            bool separator = false, string contextCallback = null)
+        {
+            this.path = path;
+            this.shortcut = new ShortcutKey(shortcutModifier, shortcutKey);
+            this.priority = priority;
+            this.separator = separator;
+            this.contextCallback = contextCallback;
+        }
+
+        /// <summary>
+        /// Creates a new menu item attribute. Selecting the item in the menu will trigger the menu item callback.
+        /// </summary>
+        /// <param name="path">Path that determines where in the menu to add the element. All path elements must be 
+        ///                    separated by /, for example "View/Toolbars/Find".</param>
+        /// <param name="priority">Priority determines the position of the menu item relative to its siblings.
+        ///                        Higher priority means it will be placed earlier in the menu.</param>
+        /// <param name="separator">Determines should a separator be inserted just before this element.</param>
+        /// <param name="contextCallback">Name of a method that returns a boolean determining whether the menu item callback
+        ///                               is allowed to trigger. This is useful if menu items are only valid in specific
+        ///                               situations (for example a scene object must be selected). The method must be
+        ///                               static, return a boolean value, accept no parameters and be in the same class as
+        ///                               the method this attribute is attached to.</param>
+        public MenuItem(string path, int priority = 0, bool separator = false, string contextCallback = null)
+        {
+            this.path = path;
+            this.priority = priority;
+            this.separator = separator;
+            this.contextCallback = contextCallback;
+        }
+
+        private string path;
+        private ShortcutKey shortcut;
+        private int priority;
+        private bool separator;
+        private string contextCallback;
+    }
+
+    /** @} */
+}

+ 666 - 660
Source/MBansheeEditor/MenuItems.cs → Source/MBansheeEditor/Window/MenuItems.cs

@@ -1,660 +1,666 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using System;
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Contains various menu item callbacks for the main editor menu bar.
-    /// </summary>
-    static class MenuItems
-    {
-        /// <summary>
-        /// Adds a camera component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Camera", 7050)]
-        private static void AddCamera()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-                return;
-
-            UndoRedo.RecordSO(so, false, "Added a Camera component");
-            Camera cam = so.AddComponent<Camera>();
-            cam.Main = true;
-
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a renderable component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Renderable", 7049)]
-        private static void AddRenderable()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-                return;
-
-            UndoRedo.RecordSO(so, false, "Added a Renderable component");
-            so.AddComponent<Renderable>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a point light component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Point light", 7048)]
-        private static void AddPointLight()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-                return;
-
-            UndoRedo.RecordSO(so, false, "Added a Light component");
-            Light light = so.AddComponent<Light>();
-            light.Type = LightType.Point;
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a spot light component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Spot light", 7047)]
-        private static void AddSpotLight()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-                return;
-
-            UndoRedo.RecordSO(so, false, "Added a Light component");
-            Light light = so.AddComponent<Light>();
-            light.Type = LightType.Spot;
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a directional light component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Directional light", 7046)]
-        private static void AddDirectionalLight()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-                return;
-
-            UndoRedo.RecordSO(so, false, "Added a Light component");
-            Light light = so.AddComponent<Light>();
-            light.Type = LightType.Directional;
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a GUI widget component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/GUI widget", 7045)]
-        private static void AddGUIWidget()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-                return;
-
-            UndoRedo.RecordSO(so, false, "Added a GUIWidget component");
-            so.AddComponent<GUIWidget>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a BoxCollider component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Physics/Box collider", 7044)]
-        private static void AddBoxCollider()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-            {
-                so = UndoRedo.CreateSO("BoxCollider", "New scene object");
-
-                Selection.SceneObject = so;
-                FocusOnHierarchyOrScene();
-            }
-
-            UndoRedo.RecordSO(so, false, "Added a BoxCollider component");
-            so.AddComponent<BoxCollider>();
-
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a SphereCollider component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Physics/Sphere collider", 7043)]
-        private static void AddSphereCollider()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-            { 
-                so = UndoRedo.CreateSO("SphereCollider", "New scene object");
-
-                Selection.SceneObject = so;
-                FocusOnHierarchyOrScene();
-            }
-
-            UndoRedo.RecordSO(so, false, "Added a SphereCollider component");
-            so.AddComponent<SphereCollider>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a CapsuleCollider component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Physics/Capsule collider", 7042)]
-        private static void AddCapsuleCollider()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-            { 
-                so = UndoRedo.CreateSO("CapsuleCollider", "New scene object");
-
-                Selection.SceneObject = so;
-                FocusOnHierarchyOrScene();
-            }
-
-            UndoRedo.RecordSO(so, false, "Added a CapsuleCollider component");
-            so.AddComponent<CapsuleCollider>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a MeshCollider component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Physics/Mesh collider", 7041)]
-        private static void AddMeshCollider()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-            { 
-                so = UndoRedo.CreateSO("MeshCollider", "New scene object");
-
-                Selection.SceneObject = so;
-                FocusOnHierarchyOrScene();
-            }
-
-            UndoRedo.RecordSO(so, false, "Added a MeshCollider component");
-            so.AddComponent<MeshCollider>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a PlaneCollider component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Physics/Plane collider", 7040)]
-        private static void AddPlaneCollider()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-            { 
-                so = UndoRedo.CreateSO("PlaneCollider", "New scene object");
-
-                Selection.SceneObject = so;
-                FocusOnHierarchyOrScene();
-            }
-
-            UndoRedo.RecordSO(so, false, "Added a PlaneCollider component");
-            so.AddComponent<PlaneCollider>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a Rigidbody component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Physics/Rigidbody", 7039, true)]
-        private static void AddRigidbody()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-            {
-                so = UndoRedo.CreateSO("Rigidbody", "New scene object");
-
-                Selection.SceneObject = so;
-                FocusOnHierarchyOrScene();
-            }
-
-            UndoRedo.RecordSO(so, false, "Added a Rigidbody component");
-            so.AddComponent<Rigidbody>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a CharacterController component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Physics/Character controller", 7038)]
-        private static void AddCharacterController()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-            { 
-                so = UndoRedo.CreateSO("CharacterController", "New scene object");
-
-                Selection.SceneObject = so;
-                FocusOnHierarchyOrScene();
-            }
-
-            UndoRedo.RecordSO(so, false, "Added a CharacterController component");
-            so.AddComponent<CharacterController>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a FixedJoint component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Physics/Fixed joint", 7037, true)]
-        private static void AddFixedJoint()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-            { 
-                so = UndoRedo.CreateSO("FixedJoint", "New scene object");
-
-                Selection.SceneObject = so;
-                FocusOnHierarchyOrScene();
-            }
-
-            UndoRedo.RecordSO(so, false, "Added a FixedJoint component");
-            so.AddComponent<FixedJoint>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a DistanceJoint component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Physics/Distance joint", 7036)]
-        private static void AddDistanceJoint()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-            { 
-                so = UndoRedo.CreateSO("DistanceJoint", "New scene object");
-
-                Selection.SceneObject = so;
-                FocusOnHierarchyOrScene();
-            }
-
-            UndoRedo.RecordSO(so, false, "Added a DistanceJoint component");
-            so.AddComponent<DistanceJoint>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a HingeJoint component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Physics/Hinge joint", 7035)]
-        private static void AddHingeJoint()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-            { 
-                so = UndoRedo.CreateSO("HingeJoint", "New scene object");
-
-                Selection.SceneObject = so;
-                FocusOnHierarchyOrScene();
-            }
-
-            UndoRedo.RecordSO(so, false, "Added a HingeJoint component");
-            so.AddComponent<HingeJoint>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a SphericalJoint component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Physics/Spherical joint", 7034)]
-        private static void AddSphericalJoint()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-            { 
-                so = UndoRedo.CreateSO("SphericalJoint", "New scene object");
-
-                Selection.SceneObject = so;
-                FocusOnHierarchyOrScene();
-            }
-
-            UndoRedo.RecordSO(so, false, "Added a SphericalJoint component");
-            so.AddComponent<SphericalJoint>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a SliderJoint component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Physics/Slider joint", 7032)]
-        private static void AddSliderJoint()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-            { 
-                so = UndoRedo.CreateSO("SliderJoint", "New scene object");
-
-                Selection.SceneObject = so;
-                FocusOnHierarchyOrScene();
-            }
-
-            UndoRedo.RecordSO(so, false, "Added a SliderJoint component");
-            so.AddComponent<SliderJoint>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Adds a D6Joint component to the currently selected scene object.
-        /// </summary>
-        [MenuItem("Components/Physics/D6 joint", 7032)]
-        private static void AddD6Joint()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-            { 
-                so = UndoRedo.CreateSO("D6Joint", "New scene object");
-
-                Selection.SceneObject = so;
-                FocusOnHierarchyOrScene();
-            }
-
-            UndoRedo.RecordSO(so, false, "Added a D6Joint component");
-            so.AddComponent<D6Joint>();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Creates a new empty scene object.
-        /// </summary>
-        [MenuItem("Scene Objects/Scene Object", 8051)]
-        [ToolbarItem("SceneObject", ToolbarIcon.NewSceneObject, "Creates a new empty scene object", 1601, true)]
-        private static void AddEmptySO()
-        {
-            SceneObject so = UndoRedo.CreateSO("SceneObject", "New scene object");
-
-            Selection.SceneObject = so;
-            FocusOnHierarchyOrScene();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Creates a new scene object with a camera component.
-        /// </summary>
-        [MenuItem("Scene Objects/Camera", 8050)]
-        [ToolbarItem("Camera", ToolbarIcon.NewCamera, "New camera", 1600, false)]
-        private static void AddCameraSO()
-        {
-            SceneObject so = UndoRedo.CreateSO("Camera", "Created a Camera");
-            Camera cam = so.AddComponent<Camera>();
-            cam.Main = true;
-
-            Selection.SceneObject = so;
-            FocusOnHierarchyOrScene();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Creates a new scene object with a renderable component.
-        /// </summary>
-        [MenuItem("Scene Objects/Renderable", 8049)]
-        [ToolbarItem("Renderable", ToolbarIcon.NewRenderable, "New renderable", 1599)]
-        private static void AddRenderableSO()
-        {
-            SceneObject so = UndoRedo.CreateSO("Renderable", "Created a Renderable");
-            so.AddComponent<Renderable>();
-
-            Selection.SceneObject = so;
-            FocusOnHierarchyOrScene();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Creates a new scene object with a point light component.
-        /// </summary>
-        [MenuItem("Scene Objects/Point light", 8048)]
-        [ToolbarItem("Point light", ToolbarIcon.NewPointLight, "New point light", 1598)]
-        private static void AddPointLightSO()
-        {
-            SceneObject so = UndoRedo.CreateSO("Point light", "Created a Light");
-            Light light = so.AddComponent<Light>();
-            light.Type = LightType.Point;
-
-            Selection.SceneObject = so;
-            FocusOnHierarchyOrScene();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Creates a new scene object with a spot light component.
-        /// </summary>
-        [MenuItem("Scene Objects/Spot light", 8047)]
-        [ToolbarItem("Spot light", ToolbarIcon.NewSpotLight, "New spot light", 1597)]
-        private static void AddSpotLightSO()
-        {
-            SceneObject so = UndoRedo.CreateSO("Spot light", "Created a Light");
-            Light light = so.AddComponent<Light>();
-            light.Type = LightType.Spot;
-
-            Selection.SceneObject = so;
-            FocusOnHierarchyOrScene();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Creates a new scene object with a directional light component.
-        /// </summary>
-        [MenuItem("Scene Objects/Directional light", 8046)]
-        [ToolbarItem("Directional light", ToolbarIcon.NewDirLight, "New directional light", 1596)]
-        private static void AddDirectionalLightSO()
-        {
-            SceneObject so = UndoRedo.CreateSO("Directional light", "Created a Light");
-            Light light = so.AddComponent<Light>();
-            light.Type = LightType.Directional;
-
-            Selection.SceneObject = so;
-            FocusOnHierarchyOrScene();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Creates a new scene object with a GUI widget component.
-        /// </summary>
-        [MenuItem("Scene Objects/GUI widget", 8045)]
-        private static void AddGUIWidgetSO()
-        {
-            SceneObject so = UndoRedo.CreateSO("GUIWidget", "Created a GUIWidget");
-            so.AddComponent<GUIWidget>();
-
-            Selection.SceneObject = so;
-            FocusOnHierarchyOrScene();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Creates a new scene object with a box primitive.
-        /// </summary>
-        [MenuItem("Scene Objects/3D primitives/Box", 8100)]
-        [ToolbarItem("Cube", ToolbarIcon.NewCube, "Creates a scene object with a box primitive", 1700, true)]
-        private static void Add3DBox()
-        {
-            SceneObject so = UndoRedo.CreateSO("Box", "Created a box");
-            Renderable renderable = so.AddComponent<Renderable>();
-            renderable.Mesh = Builtin.Box;
-
-            Selection.SceneObject = so;
-            FocusOnHierarchyOrScene();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Creates a new scene object with a sphere primitive.
-        /// </summary>
-        [MenuItem("Scene Objects/3D primitives/Sphere", 8099)]
-        [ToolbarItem("Sphere", ToolbarIcon.NewSphere, "Creates a scene object with a sphere primitive", 1699)]
-        private static void Add3DSphere()
-        {
-            SceneObject so = UndoRedo.CreateSO("Sphere", "Created a sphere");
-            Renderable renderable = so.AddComponent<Renderable>();
-            renderable.Mesh = Builtin.Sphere;
-
-            Selection.SceneObject = so;
-            FocusOnHierarchyOrScene();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Creates a new scene object with a cone primitive.
-        /// </summary>
-        [MenuItem("Scene Objects/3D primitives/Cone", 8098)]
-        [ToolbarItem("Cone", ToolbarIcon.NewCone, "Creates a scene object with a cone primitive", 1698)]
-        private static void Add3DCone()
-        {
-            SceneObject so = UndoRedo.CreateSO("Cone", "Created a cone");
-            Renderable renderable = so.AddComponent<Renderable>();
-            renderable.Mesh = Builtin.Cone;
-
-            Selection.SceneObject = so;
-            FocusOnHierarchyOrScene();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Creates a new scene object with a quad primitive.
-        /// </summary>
-        [MenuItem("Scene Objects/3D primitives/Quad", 8097)]
-        [ToolbarItem("Quad", ToolbarIcon.NewQuad, "Creates a scene object with a quad primitive", 1697)]
-        private static void Add3DQuad()
-        {
-            SceneObject so = UndoRedo.CreateSO("Quad", "Created a quad");
-            Renderable renderable = so.AddComponent<Renderable>();
-            renderable.Mesh = Builtin.Quad;
-
-            Selection.SceneObject = so;
-            FocusOnHierarchyOrScene();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Creates a new scene object with a disc primitive.
-        /// </summary>
-        [MenuItem("Scene Objects/3D primitives/Disc", 8096)]
-        private static void Add3DDisc()
-        {
-            SceneObject so = UndoRedo.CreateSO("Disc", "Created a disc");
-            Renderable renderable = so.AddComponent<Renderable>();
-            renderable.Mesh = Builtin.Disc;
-
-            Selection.SceneObject = so;
-            FocusOnHierarchyOrScene();
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Applies changes from the prefab instance to the prefab resource.
-        /// </summary>
-        [MenuItem("Scene Objects/Apply prefab", 8025, true)]
-        private static void ApplyPrefab()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-                return;
-
-            PrefabUtility.ApplyPrefab(so);
-        }
-
-        /// <summary>
-        /// Reverts a prefab instance to the original state of its prefab.
-        /// </summary>
-        [MenuItem("Scene Objects/Revert to prefab", 8024)]
-        private static void RevertToPrefab()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-                return;
-
-            UndoRedo.RecordSO(so, true, "Reverting \"" + so.Name + "\" to prefab.");
-
-            PrefabUtility.RevertPrefab(so);
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Breaks a link between a prefab and its instance.
-        /// </summary>
-        [MenuItem("Scene Objects/Break prefab link", 8023)]
-        private static void BreakPrefabLink()
-        {
-            SceneObject so = Selection.SceneObject;
-            if (so == null)
-                return;
-
-            UndoRedo.BreakPrefab(so, "Breaking prefab link for " + so.Name);
-            EditorApplication.SetSceneDirty();
-        }
-
-        /// <summary>
-        /// Cuts the currently selected scene object or resource.
-        /// </summary>
-        [MenuItem("Edit/Cut", 9450, true)]
-        public static void Cut()
-        {
-            EditorApplication.TriggerGlobalShortcut(EditorApplication.CutKey);
-        }
-
-        /// <summary>
-        /// Copies the currently selected scene object or resource.
-        /// </summary>
-        [MenuItem("Edit/Copy", 9449)]
-        public static void Copy()
-        {
-            EditorApplication.TriggerGlobalShortcut(EditorApplication.CopyKey);
-        }
-
-        /// <summary>
-        /// Pastes the scene objects or resources that were previously cut or copied.
-        /// </summary>
-        [MenuItem("Edit/Paste", 9448)]
-        public static void Paste()
-        {
-            EditorApplication.TriggerGlobalShortcut(EditorApplication.PasteKey);
-        }
-
-        /// <summary>
-        /// Deletes currently selected scene objects or resources.
-        /// </summary>
-        [MenuItem("Edit/Delete", 9447)]
-        public static void Delete()
-        {
-            EditorApplication.TriggerGlobalShortcut(EditorApplication.DeleteKey);
-        }
-
-        /// <summary>
-        /// Duplicates currently selected scene objects or resources.
-        /// </summary>
-        [MenuItem("Edit/Duplicate", 9446)]
-        public static void Duplicate()
-        {
-            EditorApplication.TriggerGlobalShortcut(EditorApplication.DuplicateKey);
-        }
-
-        /// <summary>
-        /// Sets keyboard focus to the Hierarchy or Scene windows if open.
-        /// </summary>
-        private static void FocusOnHierarchyOrScene()
-        {
-            HierarchyWindow hierarchyWindow = EditorWindow.GetWindow<HierarchyWindow>();
-            if (hierarchyWindow != null)
-            {
-                hierarchyWindow.HasFocus = true;
-                return;
-            }
-
-            SceneWindow sceneWindow = EditorWindow.GetWindow<SceneWindow>();
-            if (sceneWindow != null)
-                sceneWindow.HasFocus = true;
-        }
-    }
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /** @addtogroup Window
+     *  @{
+     */
+
+    /// <summary>
+    /// Contains various menu item callbacks for the main editor menu bar.
+    /// </summary>
+    static private class MenuItems
+    {
+        /// <summary>
+        /// Adds a camera component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Camera", 7050)]
+        private static void AddCamera()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+                return;
+
+            UndoRedo.RecordSO(so, false, "Added a Camera component");
+            Camera cam = so.AddComponent<Camera>();
+            cam.Main = true;
+
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a renderable component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Renderable", 7049)]
+        private static void AddRenderable()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+                return;
+
+            UndoRedo.RecordSO(so, false, "Added a Renderable component");
+            so.AddComponent<Renderable>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a point light component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Point light", 7048)]
+        private static void AddPointLight()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+                return;
+
+            UndoRedo.RecordSO(so, false, "Added a Light component");
+            Light light = so.AddComponent<Light>();
+            light.Type = LightType.Point;
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a spot light component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Spot light", 7047)]
+        private static void AddSpotLight()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+                return;
+
+            UndoRedo.RecordSO(so, false, "Added a Light component");
+            Light light = so.AddComponent<Light>();
+            light.Type = LightType.Spot;
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a directional light component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Directional light", 7046)]
+        private static void AddDirectionalLight()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+                return;
+
+            UndoRedo.RecordSO(so, false, "Added a Light component");
+            Light light = so.AddComponent<Light>();
+            light.Type = LightType.Directional;
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a GUI widget component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/GUI widget", 7045)]
+        private static void AddGUIWidget()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+                return;
+
+            UndoRedo.RecordSO(so, false, "Added a GUIWidget component");
+            so.AddComponent<GUIWidget>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a BoxCollider component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Physics/Box collider", 7044)]
+        private static void AddBoxCollider()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+            {
+                so = UndoRedo.CreateSO("BoxCollider", "New scene object");
+
+                Selection.SceneObject = so;
+                FocusOnHierarchyOrScene();
+            }
+
+            UndoRedo.RecordSO(so, false, "Added a BoxCollider component");
+            so.AddComponent<BoxCollider>();
+
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a SphereCollider component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Physics/Sphere collider", 7043)]
+        private static void AddSphereCollider()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+            { 
+                so = UndoRedo.CreateSO("SphereCollider", "New scene object");
+
+                Selection.SceneObject = so;
+                FocusOnHierarchyOrScene();
+            }
+
+            UndoRedo.RecordSO(so, false, "Added a SphereCollider component");
+            so.AddComponent<SphereCollider>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a CapsuleCollider component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Physics/Capsule collider", 7042)]
+        private static void AddCapsuleCollider()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+            { 
+                so = UndoRedo.CreateSO("CapsuleCollider", "New scene object");
+
+                Selection.SceneObject = so;
+                FocusOnHierarchyOrScene();
+            }
+
+            UndoRedo.RecordSO(so, false, "Added a CapsuleCollider component");
+            so.AddComponent<CapsuleCollider>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a MeshCollider component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Physics/Mesh collider", 7041)]
+        private static void AddMeshCollider()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+            { 
+                so = UndoRedo.CreateSO("MeshCollider", "New scene object");
+
+                Selection.SceneObject = so;
+                FocusOnHierarchyOrScene();
+            }
+
+            UndoRedo.RecordSO(so, false, "Added a MeshCollider component");
+            so.AddComponent<MeshCollider>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a PlaneCollider component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Physics/Plane collider", 7040)]
+        private static void AddPlaneCollider()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+            { 
+                so = UndoRedo.CreateSO("PlaneCollider", "New scene object");
+
+                Selection.SceneObject = so;
+                FocusOnHierarchyOrScene();
+            }
+
+            UndoRedo.RecordSO(so, false, "Added a PlaneCollider component");
+            so.AddComponent<PlaneCollider>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a Rigidbody component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Physics/Rigidbody", 7039, true)]
+        private static void AddRigidbody()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+            {
+                so = UndoRedo.CreateSO("Rigidbody", "New scene object");
+
+                Selection.SceneObject = so;
+                FocusOnHierarchyOrScene();
+            }
+
+            UndoRedo.RecordSO(so, false, "Added a Rigidbody component");
+            so.AddComponent<Rigidbody>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a CharacterController component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Physics/Character controller", 7038)]
+        private static void AddCharacterController()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+            { 
+                so = UndoRedo.CreateSO("CharacterController", "New scene object");
+
+                Selection.SceneObject = so;
+                FocusOnHierarchyOrScene();
+            }
+
+            UndoRedo.RecordSO(so, false, "Added a CharacterController component");
+            so.AddComponent<CharacterController>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a FixedJoint component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Physics/Fixed joint", 7037, true)]
+        private static void AddFixedJoint()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+            { 
+                so = UndoRedo.CreateSO("FixedJoint", "New scene object");
+
+                Selection.SceneObject = so;
+                FocusOnHierarchyOrScene();
+            }
+
+            UndoRedo.RecordSO(so, false, "Added a FixedJoint component");
+            so.AddComponent<FixedJoint>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a DistanceJoint component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Physics/Distance joint", 7036)]
+        private static void AddDistanceJoint()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+            { 
+                so = UndoRedo.CreateSO("DistanceJoint", "New scene object");
+
+                Selection.SceneObject = so;
+                FocusOnHierarchyOrScene();
+            }
+
+            UndoRedo.RecordSO(so, false, "Added a DistanceJoint component");
+            so.AddComponent<DistanceJoint>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a HingeJoint component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Physics/Hinge joint", 7035)]
+        private static void AddHingeJoint()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+            { 
+                so = UndoRedo.CreateSO("HingeJoint", "New scene object");
+
+                Selection.SceneObject = so;
+                FocusOnHierarchyOrScene();
+            }
+
+            UndoRedo.RecordSO(so, false, "Added a HingeJoint component");
+            so.AddComponent<HingeJoint>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a SphericalJoint component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Physics/Spherical joint", 7034)]
+        private static void AddSphericalJoint()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+            { 
+                so = UndoRedo.CreateSO("SphericalJoint", "New scene object");
+
+                Selection.SceneObject = so;
+                FocusOnHierarchyOrScene();
+            }
+
+            UndoRedo.RecordSO(so, false, "Added a SphericalJoint component");
+            so.AddComponent<SphericalJoint>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a SliderJoint component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Physics/Slider joint", 7032)]
+        private static void AddSliderJoint()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+            { 
+                so = UndoRedo.CreateSO("SliderJoint", "New scene object");
+
+                Selection.SceneObject = so;
+                FocusOnHierarchyOrScene();
+            }
+
+            UndoRedo.RecordSO(so, false, "Added a SliderJoint component");
+            so.AddComponent<SliderJoint>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Adds a D6Joint component to the currently selected scene object.
+        /// </summary>
+        [MenuItem("Components/Physics/D6 joint", 7032)]
+        private static void AddD6Joint()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+            { 
+                so = UndoRedo.CreateSO("D6Joint", "New scene object");
+
+                Selection.SceneObject = so;
+                FocusOnHierarchyOrScene();
+            }
+
+            UndoRedo.RecordSO(so, false, "Added a D6Joint component");
+            so.AddComponent<D6Joint>();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Creates a new empty scene object.
+        /// </summary>
+        [MenuItem("Scene Objects/Scene Object", 8051)]
+        [ToolbarItem("SceneObject", ToolbarIcon.NewSceneObject, "Creates a new empty scene object", 1601, true)]
+        private static void AddEmptySO()
+        {
+            SceneObject so = UndoRedo.CreateSO("SceneObject", "New scene object");
+
+            Selection.SceneObject = so;
+            FocusOnHierarchyOrScene();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Creates a new scene object with a camera component.
+        /// </summary>
+        [MenuItem("Scene Objects/Camera", 8050)]
+        [ToolbarItem("Camera", ToolbarIcon.NewCamera, "New camera", 1600, false)]
+        private static void AddCameraSO()
+        {
+            SceneObject so = UndoRedo.CreateSO("Camera", "Created a Camera");
+            Camera cam = so.AddComponent<Camera>();
+            cam.Main = true;
+
+            Selection.SceneObject = so;
+            FocusOnHierarchyOrScene();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Creates a new scene object with a renderable component.
+        /// </summary>
+        [MenuItem("Scene Objects/Renderable", 8049)]
+        [ToolbarItem("Renderable", ToolbarIcon.NewRenderable, "New renderable", 1599)]
+        private static void AddRenderableSO()
+        {
+            SceneObject so = UndoRedo.CreateSO("Renderable", "Created a Renderable");
+            so.AddComponent<Renderable>();
+
+            Selection.SceneObject = so;
+            FocusOnHierarchyOrScene();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Creates a new scene object with a point light component.
+        /// </summary>
+        [MenuItem("Scene Objects/Point light", 8048)]
+        [ToolbarItem("Point light", ToolbarIcon.NewPointLight, "New point light", 1598)]
+        private static void AddPointLightSO()
+        {
+            SceneObject so = UndoRedo.CreateSO("Point light", "Created a Light");
+            Light light = so.AddComponent<Light>();
+            light.Type = LightType.Point;
+
+            Selection.SceneObject = so;
+            FocusOnHierarchyOrScene();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Creates a new scene object with a spot light component.
+        /// </summary>
+        [MenuItem("Scene Objects/Spot light", 8047)]
+        [ToolbarItem("Spot light", ToolbarIcon.NewSpotLight, "New spot light", 1597)]
+        private static void AddSpotLightSO()
+        {
+            SceneObject so = UndoRedo.CreateSO("Spot light", "Created a Light");
+            Light light = so.AddComponent<Light>();
+            light.Type = LightType.Spot;
+
+            Selection.SceneObject = so;
+            FocusOnHierarchyOrScene();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Creates a new scene object with a directional light component.
+        /// </summary>
+        [MenuItem("Scene Objects/Directional light", 8046)]
+        [ToolbarItem("Directional light", ToolbarIcon.NewDirLight, "New directional light", 1596)]
+        private static void AddDirectionalLightSO()
+        {
+            SceneObject so = UndoRedo.CreateSO("Directional light", "Created a Light");
+            Light light = so.AddComponent<Light>();
+            light.Type = LightType.Directional;
+
+            Selection.SceneObject = so;
+            FocusOnHierarchyOrScene();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Creates a new scene object with a GUI widget component.
+        /// </summary>
+        [MenuItem("Scene Objects/GUI widget", 8045)]
+        private static void AddGUIWidgetSO()
+        {
+            SceneObject so = UndoRedo.CreateSO("GUIWidget", "Created a GUIWidget");
+            so.AddComponent<GUIWidget>();
+
+            Selection.SceneObject = so;
+            FocusOnHierarchyOrScene();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Creates a new scene object with a box primitive.
+        /// </summary>
+        [MenuItem("Scene Objects/3D primitives/Box", 8100)]
+        [ToolbarItem("Cube", ToolbarIcon.NewCube, "Creates a scene object with a box primitive", 1700, true)]
+        private static void Add3DBox()
+        {
+            SceneObject so = UndoRedo.CreateSO("Box", "Created a box");
+            Renderable renderable = so.AddComponent<Renderable>();
+            renderable.Mesh = Builtin.Box;
+
+            Selection.SceneObject = so;
+            FocusOnHierarchyOrScene();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Creates a new scene object with a sphere primitive.
+        /// </summary>
+        [MenuItem("Scene Objects/3D primitives/Sphere", 8099)]
+        [ToolbarItem("Sphere", ToolbarIcon.NewSphere, "Creates a scene object with a sphere primitive", 1699)]
+        private static void Add3DSphere()
+        {
+            SceneObject so = UndoRedo.CreateSO("Sphere", "Created a sphere");
+            Renderable renderable = so.AddComponent<Renderable>();
+            renderable.Mesh = Builtin.Sphere;
+
+            Selection.SceneObject = so;
+            FocusOnHierarchyOrScene();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Creates a new scene object with a cone primitive.
+        /// </summary>
+        [MenuItem("Scene Objects/3D primitives/Cone", 8098)]
+        [ToolbarItem("Cone", ToolbarIcon.NewCone, "Creates a scene object with a cone primitive", 1698)]
+        private static void Add3DCone()
+        {
+            SceneObject so = UndoRedo.CreateSO("Cone", "Created a cone");
+            Renderable renderable = so.AddComponent<Renderable>();
+            renderable.Mesh = Builtin.Cone;
+
+            Selection.SceneObject = so;
+            FocusOnHierarchyOrScene();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Creates a new scene object with a quad primitive.
+        /// </summary>
+        [MenuItem("Scene Objects/3D primitives/Quad", 8097)]
+        [ToolbarItem("Quad", ToolbarIcon.NewQuad, "Creates a scene object with a quad primitive", 1697)]
+        private static void Add3DQuad()
+        {
+            SceneObject so = UndoRedo.CreateSO("Quad", "Created a quad");
+            Renderable renderable = so.AddComponent<Renderable>();
+            renderable.Mesh = Builtin.Quad;
+
+            Selection.SceneObject = so;
+            FocusOnHierarchyOrScene();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Creates a new scene object with a disc primitive.
+        /// </summary>
+        [MenuItem("Scene Objects/3D primitives/Disc", 8096)]
+        private static void Add3DDisc()
+        {
+            SceneObject so = UndoRedo.CreateSO("Disc", "Created a disc");
+            Renderable renderable = so.AddComponent<Renderable>();
+            renderable.Mesh = Builtin.Disc;
+
+            Selection.SceneObject = so;
+            FocusOnHierarchyOrScene();
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Applies changes from the prefab instance to the prefab resource.
+        /// </summary>
+        [MenuItem("Scene Objects/Apply prefab", 8025, true)]
+        private static void ApplyPrefab()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+                return;
+
+            PrefabUtility.ApplyPrefab(so);
+        }
+
+        /// <summary>
+        /// Reverts a prefab instance to the original state of its prefab.
+        /// </summary>
+        [MenuItem("Scene Objects/Revert to prefab", 8024)]
+        private static void RevertToPrefab()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+                return;
+
+            UndoRedo.RecordSO(so, true, "Reverting \"" + so.Name + "\" to prefab.");
+
+            PrefabUtility.RevertPrefab(so);
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Breaks a link between a prefab and its instance.
+        /// </summary>
+        [MenuItem("Scene Objects/Break prefab link", 8023)]
+        private static void BreakPrefabLink()
+        {
+            SceneObject so = Selection.SceneObject;
+            if (so == null)
+                return;
+
+            UndoRedo.BreakPrefab(so, "Breaking prefab link for " + so.Name);
+            EditorApplication.SetSceneDirty();
+        }
+
+        /// <summary>
+        /// Cuts the currently selected scene object or resource.
+        /// </summary>
+        [MenuItem("Edit/Cut", 9450, true)]
+        public static void Cut()
+        {
+            EditorApplication.TriggerGlobalShortcut(EditorApplication.CutKey);
+        }
+
+        /// <summary>
+        /// Copies the currently selected scene object or resource.
+        /// </summary>
+        [MenuItem("Edit/Copy", 9449)]
+        public static void Copy()
+        {
+            EditorApplication.TriggerGlobalShortcut(EditorApplication.CopyKey);
+        }
+
+        /// <summary>
+        /// Pastes the scene objects or resources that were previously cut or copied.
+        /// </summary>
+        [MenuItem("Edit/Paste", 9448)]
+        public static void Paste()
+        {
+            EditorApplication.TriggerGlobalShortcut(EditorApplication.PasteKey);
+        }
+
+        /// <summary>
+        /// Deletes currently selected scene objects or resources.
+        /// </summary>
+        [MenuItem("Edit/Delete", 9447)]
+        public static void Delete()
+        {
+            EditorApplication.TriggerGlobalShortcut(EditorApplication.DeleteKey);
+        }
+
+        /// <summary>
+        /// Duplicates currently selected scene objects or resources.
+        /// </summary>
+        [MenuItem("Edit/Duplicate", 9446)]
+        public static void Duplicate()
+        {
+            EditorApplication.TriggerGlobalShortcut(EditorApplication.DuplicateKey);
+        }
+
+        /// <summary>
+        /// Sets keyboard focus to the Hierarchy or Scene windows if open.
+        /// </summary>
+        private static void FocusOnHierarchyOrScene()
+        {
+            HierarchyWindow hierarchyWindow = EditorWindow.GetWindow<HierarchyWindow>();
+            if (hierarchyWindow != null)
+            {
+                hierarchyWindow.HasFocus = true;
+                return;
+            }
+
+            SceneWindow sceneWindow = EditorWindow.GetWindow<SceneWindow>();
+            if (sceneWindow != null)
+                sceneWindow.HasFocus = true;
+        }
+    }
+
+    /** @} */
+}

+ 6 - 0
Source/MBansheeEditor/ModalWindow.cs → Source/MBansheeEditor/Window/ModalWindow.cs

@@ -7,6 +7,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Window
+     *  @{
+     */
+
     /// <summary>
     /// Base implementation of a window that when open doesn't allow you to interact with other windows. Modal windows 
     /// are similar to editor windows but cannot be docked, and are meant to be used for temporary operations like dialog 
@@ -128,4 +132,6 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_WindowToScreenPos(IntPtr nativeInstance, ref Vector2I position, out Vector2I screenPos);
     }
+
+    /** @} */
 }

+ 69 - 67
Source/MBansheeEditor/ToolbarItem.cs → Source/MBansheeEditor/Window/ToolbarItem.cs

@@ -1,67 +1,69 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Adds an entry to the main tool. Clicking on that entry will trigger the method the attribute is attached to.
-    /// The method must be static, have no parameters or return values otherwise the attribute will be ignored.
-    /// </summary>
-    [AttributeUsage(AttributeTargets.Method)]
-    class ToolbarItem : Attribute
-    {
-        /// <summary>
-        /// Creates a new toolbar item attribute. Selecting the item in the toolbar will trigger the callback.
-        /// </summary>
-        /// <param name="name">Path that determines where in the menu to add the element. All path elements must be 
-        ///                    separated by /, for example "View/Toolbars/Find".</param>
-        /// <param name="icon">Path to the sprite texture to display on the toolbar entry. Relative to project library 
-        ///                    resources folder.</param>
-        /// <param name="tooltip">Optional tooltip to display when the user hovers over the toolbar entry.</param>
-        /// <param name="priority">Priority determines the position of the toolbar item relative to its siblings.
-        ///                        Higher priority means it will be placed earlier.</param>
-        /// <param name="separator">Determines should a separator be inserted just before this element.</param>
-        public ToolbarItem(string name, string icon, string tooltip = "", int priority = 0, bool separator = false)
-        {
-            this.name = name;
-            this.icon = icon;
-            this.tooltip = tooltip;
-            this.priority = priority;
-            this.separator = separator;
-            this.builtinIcon = -1;
-        }
-
-        /// <summary>
-        /// Creates a new toolbar item attribute. Selecting the item in the toolbar will trigger the callback.
-        /// </summary>
-        /// <param name="name">Path that determines where in the menu to add the element. All path elements must be 
-        ///                    separated by /, for example "View/Toolbars/Find".</param>
-        /// <param name="icon">Type of builtin icon to display on the toolbar entry.</param>
-        /// <param name="tooltip">Optional tooltip to display when the user hovers over the toolbar entry.</param>
-        /// <param name="priority">Priority determines the position of the toolbar item relative to its siblings.
-        ///                        Higher priority means it will be placed earlier.</param>
-        /// <param name="separator">Determines should a separator be inserted just before this element.</param>
-        internal ToolbarItem(string name, ToolbarIcon icon, string tooltip = "", int priority = 0, bool separator = false)
-        {
-            this.name = name;
-            this.icon = null;
-            this.tooltip = tooltip;
-            this.priority = priority;
-            this.separator = separator;
-            this.builtinIcon = (int)icon;
-        }
-
-        private string name;
-        private string icon;
-        private int builtinIcon;
-        private string tooltip;
-        private int priority;
-        private bool separator;
-    }
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /** @addtogroup Window
+     *  @{
+     */
+
+    /// <summary>
+    /// Adds an entry to the main tool. Clicking on that entry will trigger the method the attribute is attached to.
+    /// The method must be static, have no parameters or return values otherwise the attribute will be ignored.
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Method)]
+    class ToolbarItem : Attribute
+    {
+        /// <summary>
+        /// Creates a new toolbar item attribute. Selecting the item in the toolbar will trigger the callback.
+        /// </summary>
+        /// <param name="name">Path that determines where in the menu to add the element. All path elements must be 
+        ///                    separated by /, for example "View/Toolbars/Find".</param>
+        /// <param name="icon">Path to the sprite texture to display on the toolbar entry. Relative to project library 
+        ///                    resources folder.</param>
+        /// <param name="tooltip">Optional tooltip to display when the user hovers over the toolbar entry.</param>
+        /// <param name="priority">Priority determines the position of the toolbar item relative to its siblings.
+        ///                        Higher priority means it will be placed earlier.</param>
+        /// <param name="separator">Determines should a separator be inserted just before this element.</param>
+        public ToolbarItem(string name, string icon, string tooltip = "", int priority = 0, bool separator = false)
+        {
+            this.name = name;
+            this.icon = icon;
+            this.tooltip = tooltip;
+            this.priority = priority;
+            this.separator = separator;
+            this.builtinIcon = -1;
+        }
+
+        /// <summary>
+        /// Creates a new toolbar item attribute. Selecting the item in the toolbar will trigger the callback.
+        /// </summary>
+        /// <param name="name">Path that determines where in the menu to add the element. All path elements must be 
+        ///                    separated by /, for example "View/Toolbars/Find".</param>
+        /// <param name="icon">Type of builtin icon to display on the toolbar entry.</param>
+        /// <param name="tooltip">Optional tooltip to display when the user hovers over the toolbar entry.</param>
+        /// <param name="priority">Priority determines the position of the toolbar item relative to its siblings.
+        ///                        Higher priority means it will be placed earlier.</param>
+        /// <param name="separator">Determines should a separator be inserted just before this element.</param>
+        internal ToolbarItem(string name, ToolbarIcon icon, string tooltip = "", int priority = 0, bool separator = false)
+        {
+            this.name = name;
+            this.icon = null;
+            this.tooltip = tooltip;
+            this.priority = priority;
+            this.separator = separator;
+            this.builtinIcon = (int)icon;
+        }
+
+        private string name;
+        private string icon;
+        private int builtinIcon;
+        private string tooltip;
+        private int priority;
+        private bool separator;
+    }
+
+    /** @} */
+}

+ 182 - 176
Source/MBansheeEditor/AboutBox.cs → Source/MBansheeEditor/Windows/AboutBox.cs

@@ -1,176 +1,182 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Displays information about the engine, its creator and licenses.
-    /// </summary>
-    public class AboutBox : ModalWindow
-    {
-        private GUITextBox emailLabel;
-
-        /// <summary>
-        /// Opens the about box.
-        /// </summary>
-        [MenuItem("Help/About", 5000)]
-        public static void Open()
-        {
-            new AboutBox();
-        }
-
-        /// <summary>
-        /// Constructs the about box.
-        /// </summary>
-        protected AboutBox()
-            : base(true)
-        {
-            Title = "About";
-            Width = 400;
-            Height = 400;
-        }
-
-        private void OnInitialize()
-        {
-            GUILabel title = new GUILabel(new LocEdString("Banshee Engine v0.3"), EditorStyles.TitleLabel);
-            GUILabel subTitle = new GUILabel(new LocEdString("A modern open-source game development toolkit"), 
-                EditorStyles.LabelCentered);
-            GUILabel license = new GUILabel(new LocEdString(
-                "This program is licensed under the GNU General Public License V3"), EditorStyles.LabelCentered);
-            GUILabel copyright = new GUILabel(new LocEdString("Copyright (C) 2015 Marko Pintera. All rights reserved."), 
-                EditorStyles.LabelCentered);
-            GUILabel emailTitle = new GUILabel(new LocEdString("E-mail"), GUIOption.FixedWidth(150));
-            emailLabel = new GUITextBox();
-            GUILabel linkedInTitle = new GUILabel(new LocEdString("LinkedIn"), GUIOption.FixedWidth(150));
-            GUIButton linkedInBtn = new GUIButton(new LocEdString("Profile"));
-
-            GUIToggleGroup foldoutGroup = new GUIToggleGroup(true);
-            GUIToggle contactFoldout = new GUIToggle(new LocEdString("Author contact"), foldoutGroup, EditorStyles.Foldout);
-            GUIToggle thirdPartyFoldout = new GUIToggle(new LocEdString("Used third party libraries"), foldoutGroup, EditorStyles.Foldout);
-            GUIToggle noticesFoldout = new GUIToggle(new LocEdString("Third party notices"), foldoutGroup, EditorStyles.Foldout);
-            GUIToggle collaboratorsFoldout = new GUIToggle(new LocEdString("Collaborators"), foldoutGroup, EditorStyles.Foldout);
-
-            GUILabel freeTypeNotice = new GUILabel(new LocEdString(
-                        "Portions of this software are copyright (C) 2015 The FreeType Project (www.freetype.org). " +
-                        "All rights reserved."), EditorStyles.MultiLineLabelCentered, 
-                        GUIOption.FlexibleHeight(), GUIOption.FixedWidth(380));
-
-            GUILabel fbxSdkNotice = new GUILabel(new LocEdString(
-                "This software contains Autodesk(R) FBX(R) code developed by Autodesk, Inc. Copyright 2013 Autodesk, Inc. " +
-                "All rights, reserved. Such code is provided \"as is\" and Autodesk, Inc. disclaims any and all warranties, " +
-                "whether express or implied, including without limitation the implied warranties of merchantability, " +
-                "fitness for a particular purpose or non-infringement of third party rights. In no event shall Autodesk, " +
-                "Inc. be liable for any direct, indirect, incidental, special, exemplary, or consequential damages " +
-                "(including, but not limited to, procurement of substitute goods or services; loss of use, data, or " +
-                "profits; or business interruption) however caused and on any theory of liability, whether in contract, " +
-                "strict liability, or tort (including negligence or otherwise) arising in any way out of such code."),
-                EditorStyles.MultiLineLabelCentered, GUIOption.FlexibleHeight(), GUIOption.FixedWidth(380));
-
-            GUILayoutY mainLayout = GUI.AddLayoutY();
-            mainLayout.AddSpace(10);
-            mainLayout.AddElement(title);
-            mainLayout.AddElement(subTitle);
-            mainLayout.AddSpace(10);
-            mainLayout.AddElement(license);
-            mainLayout.AddElement(copyright);
-            mainLayout.AddSpace(10);
-            mainLayout.AddElement(contactFoldout);
-
-            GUILayoutY contactLayout = mainLayout.AddLayoutY();
-            GUILayout emailLayout = contactLayout.AddLayoutX();
-            emailLayout.AddSpace(10);
-            emailLayout.AddElement(emailTitle);
-            emailLayout.AddElement(emailLabel);
-            emailLayout.AddSpace(10);
-            GUILayout linkedInLayout = contactLayout.AddLayoutX();
-            linkedInLayout.AddSpace(10);
-            linkedInLayout.AddElement(linkedInTitle);
-            linkedInLayout.AddElement(linkedInBtn);
-            linkedInLayout.AddSpace(10);
-
-            mainLayout.AddSpace(5);
-            mainLayout.AddElement(thirdPartyFoldout);
-            GUILayoutY thirdPartyLayout = mainLayout.AddLayoutY();
-
-            CreateThirdPartyGUI(thirdPartyLayout, "Autodesk FBX SDK",
-                "http://usa.autodesk.com/adsk/servlet/pc/item?siteID=123112&id=10775847", "FBX_SDK_License.rtf");
-            CreateThirdPartyGUI(thirdPartyLayout, "FreeImage", "http://freeimage.sourceforge.net/", "freeimage-license.txt");
-            CreateThirdPartyGUI(thirdPartyLayout, "FreeType", "http://www.freetype.org/", "FTL.TXT");
-            CreateThirdPartyGUI(thirdPartyLayout, "Mono", "http://www.mono-project.com/", "Mono.txt");
-            CreateThirdPartyGUI(thirdPartyLayout, "NVIDIA Texture Tools",
-                "https://github.com/castano/nvidia-texture-tools", "NVIDIATextureTools.txt");
-
-            mainLayout.AddSpace(5);
-            mainLayout.AddElement(noticesFoldout);
-            GUILayout noticesLayout = mainLayout.AddLayoutY();
-            noticesLayout.AddElement(freeTypeNotice);
-            noticesLayout.AddSpace(10);
-            noticesLayout.AddElement(fbxSdkNotice);
-
-            mainLayout.AddSpace(5);
-            mainLayout.AddElement(collaboratorsFoldout);
-            GUILayoutY collaboratorsLayout = mainLayout.AddLayoutY();
-            CreateCollaboratorGUI(collaboratorsLayout, "Danijel Ribic", "Logo, UI icons, 3D models & textures");
-
-            mainLayout.AddFlexibleSpace();
-
-            contactLayout.Active = false;
-            contactFoldout.OnToggled += x =>
-            {
-                contactLayout.Active = x;
-            };
-
-            thirdPartyLayout.Active = false;
-            thirdPartyFoldout.OnToggled += x => thirdPartyLayout.Active = x;
-
-            noticesLayout.Active = false;
-            noticesFoldout.OnToggled += x => noticesLayout.Active = x;
-
-            collaboratorsLayout.Active = false;
-            collaboratorsFoldout.OnToggled += x => collaboratorsLayout.Active = x;
-
-            emailLabel.Text = "[email protected]";
-            linkedInBtn.OnClick += () => { System.Diagnostics.Process.Start("http://hr.linkedin.com/in/markopintera"); };
-        }
-
-        private void CreateThirdPartyGUI(GUILayoutY layout, string name, string webURL, string licenseFile)
-        {
-            GUILabel label = new GUILabel(new LocEdString(name), GUIOption.FixedWidth(150));
-            GUIButton linkBtn = new GUIButton(new LocEdString("Website"), GUIOption.FixedWidth(50));
-            GUIButton licenseBtn = new GUIButton(new LocEdString("License"), GUIOption.FixedWidth(50));
-
-            string licensePath = "..\\..\\..\\License\\Third Party\\" + licenseFile;
-
-            GUILayoutX horzLayout = layout.AddLayoutX();
-            horzLayout.AddSpace(10);
-            horzLayout.AddElement(label);
-            horzLayout.AddSpace(10);
-            horzLayout.AddElement(linkBtn);
-            horzLayout.AddSpace(5);
-            horzLayout.AddElement(licenseBtn);
-            horzLayout.AddSpace(10);
-
-            linkBtn.OnClick += () => { System.Diagnostics.Process.Start(webURL); };
-            licenseBtn.OnClick += () => { System.Diagnostics.Process.Start(licensePath); };
-        }
-
-        private void CreateCollaboratorGUI(GUILayoutY layout, string name, string area)
-        {
-            GUILabel nameLabel = new GUILabel(new LocEdString(name), GUIOption.FixedWidth(150));
-            GUILabel areaLabel = new GUILabel(new LocEdString(area), GUIOption.FixedWidth(220));
-
-            GUILayoutX horzLayout = layout.AddLayoutX();
-            horzLayout.AddSpace(10);
-            horzLayout.AddElement(nameLabel);
-            horzLayout.AddSpace(10);
-            horzLayout.AddElement(areaLabel);
-            horzLayout.AddSpace(10);
-        }
-
-        private void OnEditorUpdate()
-        {
-            emailLabel.Text = "[email protected]";
-        }
-    }
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /** @addtogroup Windows
+     *  @{
+     */
+
+    /// <summary>
+    /// Displays information about the engine, its creator and licenses.
+    /// </summary>
+    public class AboutBox : ModalWindow
+    {
+        private GUITextBox emailLabel;
+
+        /// <summary>
+        /// Opens the about box.
+        /// </summary>
+        [MenuItem("Help/About", 5000)]
+        public static void Open()
+        {
+            new AboutBox();
+        }
+
+        /// <summary>
+        /// Constructs the about box.
+        /// </summary>
+        protected AboutBox()
+            : base(true)
+        {
+            Title = "About";
+            Width = 400;
+            Height = 400;
+        }
+
+        private void OnInitialize()
+        {
+            GUILabel title = new GUILabel(new LocEdString("Banshee Engine v0.3"), EditorStyles.TitleLabel);
+            GUILabel subTitle = new GUILabel(new LocEdString("A modern open-source game development toolkit"), 
+                EditorStyles.LabelCentered);
+            GUILabel license = new GUILabel(new LocEdString(
+                "This program is licensed under the GNU General Public License V3"), EditorStyles.LabelCentered);
+            GUILabel copyright = new GUILabel(new LocEdString("Copyright (C) 2015 Marko Pintera. All rights reserved."), 
+                EditorStyles.LabelCentered);
+            GUILabel emailTitle = new GUILabel(new LocEdString("E-mail"), GUIOption.FixedWidth(150));
+            emailLabel = new GUITextBox();
+            GUILabel linkedInTitle = new GUILabel(new LocEdString("LinkedIn"), GUIOption.FixedWidth(150));
+            GUIButton linkedInBtn = new GUIButton(new LocEdString("Profile"));
+
+            GUIToggleGroup foldoutGroup = new GUIToggleGroup(true);
+            GUIToggle contactFoldout = new GUIToggle(new LocEdString("Author contact"), foldoutGroup, EditorStyles.Foldout);
+            GUIToggle thirdPartyFoldout = new GUIToggle(new LocEdString("Used third party libraries"), foldoutGroup, EditorStyles.Foldout);
+            GUIToggle noticesFoldout = new GUIToggle(new LocEdString("Third party notices"), foldoutGroup, EditorStyles.Foldout);
+            GUIToggle collaboratorsFoldout = new GUIToggle(new LocEdString("Collaborators"), foldoutGroup, EditorStyles.Foldout);
+
+            GUILabel freeTypeNotice = new GUILabel(new LocEdString(
+                        "Portions of this software are copyright (C) 2015 The FreeType Project (www.freetype.org). " +
+                        "All rights reserved."), EditorStyles.MultiLineLabelCentered, 
+                        GUIOption.FlexibleHeight(), GUIOption.FixedWidth(380));
+
+            GUILabel fbxSdkNotice = new GUILabel(new LocEdString(
+                "This software contains Autodesk(R) FBX(R) code developed by Autodesk, Inc. Copyright 2013 Autodesk, Inc. " +
+                "All rights, reserved. Such code is provided \"as is\" and Autodesk, Inc. disclaims any and all warranties, " +
+                "whether express or implied, including without limitation the implied warranties of merchantability, " +
+                "fitness for a particular purpose or non-infringement of third party rights. In no event shall Autodesk, " +
+                "Inc. be liable for any direct, indirect, incidental, special, exemplary, or consequential damages " +
+                "(including, but not limited to, procurement of substitute goods or services; loss of use, data, or " +
+                "profits; or business interruption) however caused and on any theory of liability, whether in contract, " +
+                "strict liability, or tort (including negligence or otherwise) arising in any way out of such code."),
+                EditorStyles.MultiLineLabelCentered, GUIOption.FlexibleHeight(), GUIOption.FixedWidth(380));
+
+            GUILayoutY mainLayout = GUI.AddLayoutY();
+            mainLayout.AddSpace(10);
+            mainLayout.AddElement(title);
+            mainLayout.AddElement(subTitle);
+            mainLayout.AddSpace(10);
+            mainLayout.AddElement(license);
+            mainLayout.AddElement(copyright);
+            mainLayout.AddSpace(10);
+            mainLayout.AddElement(contactFoldout);
+
+            GUILayoutY contactLayout = mainLayout.AddLayoutY();
+            GUILayout emailLayout = contactLayout.AddLayoutX();
+            emailLayout.AddSpace(10);
+            emailLayout.AddElement(emailTitle);
+            emailLayout.AddElement(emailLabel);
+            emailLayout.AddSpace(10);
+            GUILayout linkedInLayout = contactLayout.AddLayoutX();
+            linkedInLayout.AddSpace(10);
+            linkedInLayout.AddElement(linkedInTitle);
+            linkedInLayout.AddElement(linkedInBtn);
+            linkedInLayout.AddSpace(10);
+
+            mainLayout.AddSpace(5);
+            mainLayout.AddElement(thirdPartyFoldout);
+            GUILayoutY thirdPartyLayout = mainLayout.AddLayoutY();
+
+            CreateThirdPartyGUI(thirdPartyLayout, "Autodesk FBX SDK",
+                "http://usa.autodesk.com/adsk/servlet/pc/item?siteID=123112&id=10775847", "FBX_SDK_License.rtf");
+            CreateThirdPartyGUI(thirdPartyLayout, "FreeImage", "http://freeimage.sourceforge.net/", "freeimage-license.txt");
+            CreateThirdPartyGUI(thirdPartyLayout, "FreeType", "http://www.freetype.org/", "FTL.TXT");
+            CreateThirdPartyGUI(thirdPartyLayout, "Mono", "http://www.mono-project.com/", "Mono.txt");
+            CreateThirdPartyGUI(thirdPartyLayout, "NVIDIA Texture Tools",
+                "https://github.com/castano/nvidia-texture-tools", "NVIDIATextureTools.txt");
+
+            mainLayout.AddSpace(5);
+            mainLayout.AddElement(noticesFoldout);
+            GUILayout noticesLayout = mainLayout.AddLayoutY();
+            noticesLayout.AddElement(freeTypeNotice);
+            noticesLayout.AddSpace(10);
+            noticesLayout.AddElement(fbxSdkNotice);
+
+            mainLayout.AddSpace(5);
+            mainLayout.AddElement(collaboratorsFoldout);
+            GUILayoutY collaboratorsLayout = mainLayout.AddLayoutY();
+            CreateCollaboratorGUI(collaboratorsLayout, "Danijel Ribic", "Logo, UI icons, 3D models & textures");
+
+            mainLayout.AddFlexibleSpace();
+
+            contactLayout.Active = false;
+            contactFoldout.OnToggled += x =>
+            {
+                contactLayout.Active = x;
+            };
+
+            thirdPartyLayout.Active = false;
+            thirdPartyFoldout.OnToggled += x => thirdPartyLayout.Active = x;
+
+            noticesLayout.Active = false;
+            noticesFoldout.OnToggled += x => noticesLayout.Active = x;
+
+            collaboratorsLayout.Active = false;
+            collaboratorsFoldout.OnToggled += x => collaboratorsLayout.Active = x;
+
+            emailLabel.Text = "[email protected]";
+            linkedInBtn.OnClick += () => { System.Diagnostics.Process.Start("http://hr.linkedin.com/in/markopintera"); };
+        }
+
+        private void CreateThirdPartyGUI(GUILayoutY layout, string name, string webURL, string licenseFile)
+        {
+            GUILabel label = new GUILabel(new LocEdString(name), GUIOption.FixedWidth(150));
+            GUIButton linkBtn = new GUIButton(new LocEdString("Website"), GUIOption.FixedWidth(50));
+            GUIButton licenseBtn = new GUIButton(new LocEdString("License"), GUIOption.FixedWidth(50));
+
+            string licensePath = "..\\..\\..\\License\\Third Party\\" + licenseFile;
+
+            GUILayoutX horzLayout = layout.AddLayoutX();
+            horzLayout.AddSpace(10);
+            horzLayout.AddElement(label);
+            horzLayout.AddSpace(10);
+            horzLayout.AddElement(linkBtn);
+            horzLayout.AddSpace(5);
+            horzLayout.AddElement(licenseBtn);
+            horzLayout.AddSpace(10);
+
+            linkBtn.OnClick += () => { System.Diagnostics.Process.Start(webURL); };
+            licenseBtn.OnClick += () => { System.Diagnostics.Process.Start(licensePath); };
+        }
+
+        private void CreateCollaboratorGUI(GUILayoutY layout, string name, string area)
+        {
+            GUILabel nameLabel = new GUILabel(new LocEdString(name), GUIOption.FixedWidth(150));
+            GUILabel areaLabel = new GUILabel(new LocEdString(area), GUIOption.FixedWidth(220));
+
+            GUILayoutX horzLayout = layout.AddLayoutX();
+            horzLayout.AddSpace(10);
+            horzLayout.AddElement(nameLabel);
+            horzLayout.AddSpace(10);
+            horzLayout.AddElement(areaLabel);
+            horzLayout.AddSpace(10);
+        }
+
+        private void OnEditorUpdate()
+        {
+            emailLabel.Text = "[email protected]";
+        }
+    }
+
+    /** @} */
+}

+ 65 - 65
Source/MBansheeEditor/BrowseDialog.cs → Source/MBansheeEditor/Windows/BrowseDialog.cs

@@ -1,65 +1,65 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Threading.Tasks;
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Contains methods for opening various OS-specific browse, open and save file/folder dialogs.
-    /// </summary>
-    public static class BrowseDialog
-    {
-        /// <summary>
-        /// Displays a platform specific dialog that allows the user to select file(s).
-        /// </summary>
-        /// <param name="defaultPath">Default path the dialog should point to.</param>
-        /// <param name="filterList">Semi-colon separated list of file names or types to display in the dialog, 
-        ///                          for example "exe;txt;png".</param>
-        /// <param name="allowMultiselect">True if user is allowed to select multiple files.</param>
-        /// <param name="outPaths">A list of file paths selected by the user.</param>
-        /// <returns>True if the user selected the file(s), false if the user canceled out of the dialog.</returns>
-        public static bool OpenFile(string defaultPath, string filterList, bool allowMultiselect, out string[] outPaths)
-        {
-            return Internal_OpenFile(defaultPath, filterList, allowMultiselect, out outPaths);
-        }
-
-        /// <summary>
-        /// Displays a platform specific dialog that allows the user to select a folder.
-        /// </summary>
-        /// <param name="defaultPath">Default path the dialog should point to.</param>
-        /// <param name="outPath">Path to the selected folder.</param>
-        /// <returns>True if the user selected the folder, false if the user canceled out of the dialog.</returns>
-        public static bool OpenFolder(string defaultPath, out string outPath)
-        {
-            return Internal_OpenFolder(defaultPath, out outPath);
-        }
-
-        /// <summary>
-        /// Displays a platform specific dialog that allows the user to select where to save a file.
-        /// </summary>
-        /// <param name="defaultPath">Default path the dialog should point to.</param>
-        /// <param name="filterList">Semi-colon separated list of file names or types to display in the dialog,
-        ///                          for example "exe;txt;png".</param>
-        /// <param name="outPath">File path selected by the user.</param>
-        /// <returns>True if the user selected the file, false if the user canceled out of the dialog.</returns>
-        public static bool SaveFile(string defaultPath, string filterList, out string outPath)
-        {
-            return Internal_SaveFile(defaultPath, filterList, out outPath);
-        }
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool Internal_OpenFile(string defaultPath, string filterList, bool allowMultiselect, out string[] outPaths);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool Internal_OpenFolder(string defaultPath, out string outPath);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool Internal_SaveFile(string defaultPath, string filterList, out string outPath);
-    }
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System.Runtime.CompilerServices;
+
+namespace BansheeEditor
+{
+    /** @addtogroup Windows
+     *  @{
+     */
+
+    /// <summary>
+    /// Contains methods for opening various OS-specific browse, open and save file/folder dialogs.
+    /// </summary>
+    public static class BrowseDialog
+    {
+        /// <summary>
+        /// Displays a platform specific dialog that allows the user to select file(s).
+        /// </summary>
+        /// <param name="defaultPath">Default path the dialog should point to.</param>
+        /// <param name="filterList">Semi-colon separated list of file names or types to display in the dialog, 
+        ///                          for example "exe;txt;png".</param>
+        /// <param name="allowMultiselect">True if user is allowed to select multiple files.</param>
+        /// <param name="outPaths">A list of file paths selected by the user.</param>
+        /// <returns>True if the user selected the file(s), false if the user canceled out of the dialog.</returns>
+        public static bool OpenFile(string defaultPath, string filterList, bool allowMultiselect, out string[] outPaths)
+        {
+            return Internal_OpenFile(defaultPath, filterList, allowMultiselect, out outPaths);
+        }
+
+        /// <summary>
+        /// Displays a platform specific dialog that allows the user to select a folder.
+        /// </summary>
+        /// <param name="defaultPath">Default path the dialog should point to.</param>
+        /// <param name="outPath">Path to the selected folder.</param>
+        /// <returns>True if the user selected the folder, false if the user canceled out of the dialog.</returns>
+        public static bool OpenFolder(string defaultPath, out string outPath)
+        {
+            return Internal_OpenFolder(defaultPath, out outPath);
+        }
+
+        /// <summary>
+        /// Displays a platform specific dialog that allows the user to select where to save a file.
+        /// </summary>
+        /// <param name="defaultPath">Default path the dialog should point to.</param>
+        /// <param name="filterList">Semi-colon separated list of file names or types to display in the dialog,
+        ///                          for example "exe;txt;png".</param>
+        /// <param name="outPath">File path selected by the user.</param>
+        /// <returns>True if the user selected the file, false if the user canceled out of the dialog.</returns>
+        public static bool SaveFile(string defaultPath, string filterList, out string outPath)
+        {
+            return Internal_SaveFile(defaultPath, filterList, out outPath);
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_OpenFile(string defaultPath, string filterList, bool allowMultiselect, out string[] outPaths);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_OpenFolder(string defaultPath, out string outPath);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_SaveFile(string defaultPath, string filterList, out string outPath);
+    }
+
+    /** @} */
+}

+ 521 - 515
Source/MBansheeEditor/BuildManager.cs → Source/MBansheeEditor/Windows/Build/BuildManager.cs

@@ -1,515 +1,521 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using System;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Threading;
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Contains a list of valid platforms that can be built for.
-    /// </summary>
-    public enum PlatformType // Note: Must match C++ enum PlatformType
-    {
-        Windows,
-        Count // Keep at end
-    }
-
-    /// <summary>
-    /// Contains build data for a specific platform.
-    /// </summary>
-    public abstract class PlatformInfo : ScriptObject
-    {
-        /// <summary>
-        /// Creates a new platform info. For internal runtime use only.
-        /// </summary>
-        protected PlatformInfo()
-        { }
-
-        /// <summary>
-        /// Returns the platform that this object contains data for.
-        /// </summary>
-        public PlatformType Type
-        {
-            get { return Internal_GetType(mCachedPtr); }
-        }
-
-        /// <summary>
-        /// Initial scene that is loaded when application is first started.
-        /// </summary>
-        public ResourceRef MainScene
-        {
-            get { return Internal_GetMainScene(mCachedPtr); }
-            set
-            {
-                IntPtr scenePtr = IntPtr.Zero;
-                if (value != null)
-                    scenePtr = value.GetCachedPtr();
-
-                Internal_SetMainScene(mCachedPtr, scenePtr);
-            }
-        }
-
-        /// <summary>
-        /// Determines should the application be started in fullscreen using the user's desktop resolution.
-        /// </summary>
-        public bool Fullscreen
-        {
-            get { return Internal_GetFullscreen(mCachedPtr); }
-            set { Internal_SetFullscreen(mCachedPtr, value); }
-        }
-
-        /// <summary>
-        /// Width of a window if the game is started in windowed mode. This is only relevant if <see cref="Fullscreen"/>
-        /// is off.
-        /// </summary>
-        public int WindowedWidth
-        {
-            get
-            {
-                int width, height;
-                Internal_GetResolution(mCachedPtr, out width, out height);
-
-                return width;
-            }
-
-            set { Internal_SetResolution(mCachedPtr, value, WindowedHeight); }
-        }
-
-        /// <summary>
-        /// Height of a window if the game is started in windowed mode. This is only relevant if <see cref="Fullscreen"/>
-        /// is off.
-        /// </summary>
-        public int WindowedHeight
-        {
-            get
-            {
-                int width, height;
-                Internal_GetResolution(mCachedPtr, out width, out height);
-
-                return height;
-            }
-
-            set { Internal_SetResolution(mCachedPtr, WindowedWidth, value); }
-        }
-
-        /// <summary>
-        /// Determines should the scripts be output in debug mode (worse performance but better error reporting).
-        /// </summary>
-        public bool Debug
-        {
-            get { return Internal_GetDebug(mCachedPtr); }
-            set { Internal_SetDebug(mCachedPtr, value); }
-        }
-
-        /// <summary>
-        /// A set of semicolon separated defines to use when compiling scripts for this platform.
-        /// </summary>
-        public string Defines
-        {
-            get { return Internal_GetDefines(mCachedPtr); }
-            set { Internal_SetDefines(mCachedPtr, value); }
-        }
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern PlatformType Internal_GetType(IntPtr thisPtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetDefines(IntPtr thisPtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetDefines(IntPtr thisPtr, string value);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern ResourceRef Internal_GetMainScene(IntPtr thisPtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        static extern void Internal_SetMainScene(IntPtr thisPtr, IntPtr prefabPtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        static extern bool Internal_GetFullscreen(IntPtr thisPtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        static extern void Internal_SetFullscreen(IntPtr thisPtr, bool fullscreen);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        static extern void Internal_GetResolution(IntPtr thisPtr, out int width, out int height);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        static extern void Internal_SetResolution(IntPtr thisPtr, int width, int height);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        static extern bool Internal_GetDebug(IntPtr thisPtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        static extern void Internal_SetDebug(IntPtr thisPtr, bool fullscreen);
-    }
-
-    /// <summary>
-    /// Supported icon sizes for Windows platform.
-    /// </summary>
-    public enum WinIconSizes
-    {
-        Icon16 = 16,
-        Icon32 = 32,
-        Icon48 = 48,
-        Icon64 = 64,
-        Icon96 = 96,
-        Icon128 = 128,
-        Icon196 = 196,
-        Icon256 = 256
-    }
-
-    /// <summary>
-    /// Platform data specific to Windows.
-    /// </summary>
-    public class WinPlatformInfo : PlatformInfo
-    {
-        /// <summary>
-        /// Texture that will be displayed on the application's executable.
-        /// </summary>
-        public ResourceRef Icon
-        {
-            get { return Internal_GetIcon(mCachedPtr); }
-            set
-            {
-                IntPtr texturePtr = IntPtr.Zero;
-                if (value != null)
-                    texturePtr = value.GetCachedPtr();
-
-                Internal_SetIcon(mCachedPtr, texturePtr);
-            }
-        }
-
-        /// <summary>
-        /// Text that will be displayed in the application's title bar.
-        /// </summary>
-        public string TitleText
-        {
-            get { return Internal_GetTitleText(mCachedPtr); }
-            set { Internal_SetTitleText(mCachedPtr, value); }
-        }
-        
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern ResourceRef Internal_GetIcon(IntPtr thisPtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetIcon(IntPtr thisPtr, IntPtr texturePtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetTitleText(IntPtr thisPtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetTitleText(IntPtr thisPtr, string value);
-    }
-
-    /// <summary>
-    /// Handles building of the game executable and packaging of all necessary resources, making the game be ready to ran
-    /// as a standalone product.
-    /// </summary>
-    public static class BuildManager
-    {
-        /// <summary>
-        /// Returns a list of all available platforms that can be built for.
-        /// </summary>
-        public static PlatformType[] AvailablePlatforms
-        {
-            get { return Internal_GetAvailablePlatforms(); }
-        }
-
-        /// <summary>
-        /// Returns the currently active platform.
-        /// </summary>
-        public static PlatformType ActivePlatform
-        {
-            get { return Internal_GetActivePlatform(); }
-            set { Internal_SetActivePlatform(value); }
-        }
-
-        /// <summary>
-        /// Returns the data about the currently active platform.
-        /// </summary>
-        public static PlatformInfo ActivePlatformInfo
-        {
-            get { return Internal_GetActivePlatformInfo(); }
-        }
-
-        /// <summary>
-        /// Returns absolute path to the folder where builds for the currently active platform are output.
-        /// </summary>
-        public static string OutputFolder
-        {
-            get { return GetBuildFolder(BuildFolder.DestinationRoot, ActivePlatform); }
-        }
-
-        /// <summary>
-        /// Returns a path to a specific folder used in the build process. See entries of BuildFolder enum for explanations 
-        /// of individual folder types.
-        /// </summary>
-        /// <param name="folder">Type of folder to retrieve the path for.</param>
-        /// <param name="platform">Platform to retrieve the path for.</param>
-        /// <returns>Path for the requested folder. This can be absolute or relative, see <see cref="BuildFolder"/> enum
-        ///          for details.</returns>
-        private static string GetBuildFolder(BuildFolder folder, PlatformType platform)
-        {
-            return Internal_GetBuildFolder(folder, platform);
-        }
-
-        /// <summary>
-        /// Returns a list of names of all native binaries required for a specific platform.
-        /// </summary>
-        /// <param name="platform">Platform type for which to get the binaries for.</param>
-        /// <returns>Array of names of native binary files.</returns>
-        private static string[] GetNativeBinaries(PlatformType platform)
-        {
-            return Internal_GetNativeBinaries(platform);
-        }
-
-        /// <summary>
-        /// Builds the executable and packages the game.
-        /// </summary>
-        public static void Build()
-        {
-            PlatformType activePlatform = ActivePlatform;
-            PlatformInfo platformInfo = ActivePlatformInfo;
-
-            string srcRoot = GetBuildFolder(BuildFolder.SourceRoot, activePlatform);
-            string destRoot = GetBuildFolder(BuildFolder.DestinationRoot, activePlatform);
-
-            // Prepare clean destination folder
-            if(Directory.Exists(destRoot))
-                Directory.Delete(destRoot, true);
-
-            Directory.CreateDirectory(destRoot);
-
-            // Compile game assembly
-            string bansheeAssemblyFolder;
-            if(platformInfo.Debug)
-                bansheeAssemblyFolder = GetBuildFolder(BuildFolder.BansheeDebugAssemblies, activePlatform);
-            else
-                bansheeAssemblyFolder = GetBuildFolder(BuildFolder.BansheeReleaseAssemblies, activePlatform);
-
-            string srcBansheeAssemblyFolder = Path.Combine(srcRoot, bansheeAssemblyFolder);
-            string destBansheeAssemblyFolder = Path.Combine(destRoot, bansheeAssemblyFolder);
-
-            Directory.CreateDirectory(destBansheeAssemblyFolder);
-            CompilerInstance ci = ScriptCompiler.CompileAsync(ScriptAssemblyType.Game, ActivePlatform, platformInfo.Debug, destBansheeAssemblyFolder);
-
-            // Copy engine assembly
-            {
-                string srcFile = Path.Combine(srcBansheeAssemblyFolder, EditorApplication.EngineAssemblyName);
-                string destFile = Path.Combine(destBansheeAssemblyFolder, EditorApplication.EngineAssemblyName);
-
-                File.Copy(srcFile, destFile);
-            }
-
-            // Copy builtin data
-            string dataFolder = GetBuildFolder(BuildFolder.Data, activePlatform);
-            string srcData = Path.Combine(srcRoot, dataFolder);
-            string destData = Path.Combine(destRoot, dataFolder);
-
-            DirectoryEx.Copy(srcData, destData);
-
-            // Copy native binaries
-            string binaryFolder = GetBuildFolder(BuildFolder.NativeBinaries, activePlatform);
-            string srcBin = Path.Combine(srcRoot, binaryFolder);
-            string destBin = destRoot;
-
-            string[] nativeBinaries = GetNativeBinaries(activePlatform);
-            foreach (var entry in nativeBinaries)
-            {
-                string srcFile = Path.Combine(srcBin, entry);
-                string destFile = Path.Combine(destBin, entry);
-
-                File.Copy(srcFile, destFile);
-            }
-
-            // Copy .NET framework assemblies
-            string frameworkAssemblyFolder = GetBuildFolder(BuildFolder.FrameworkAssemblies, activePlatform);
-            string srcFrameworkAssemblyFolder = Path.Combine(srcRoot, frameworkAssemblyFolder);
-            string destFrameworkAssemblyFolder = Path.Combine(destRoot, frameworkAssemblyFolder);
-
-            Directory.CreateDirectory(destFrameworkAssemblyFolder);
-
-            string[] frameworkAssemblies = GetFrameworkAssemblies(activePlatform);
-            foreach (var entry in frameworkAssemblies)
-            {
-                string srcFile = Path.Combine(srcFrameworkAssemblyFolder, entry + ".dll");
-                string destFile = Path.Combine(destFrameworkAssemblyFolder, entry + ".dll");
-
-                File.Copy(srcFile, destFile);
-            }
-
-            // Copy Mono
-            string monoFolder = GetBuildFolder(BuildFolder.Mono, activePlatform);
-            string srcMonoFolder = Path.Combine(srcRoot, monoFolder);
-            string destMonoFolder = Path.Combine(destRoot, monoFolder);
-
-            DirectoryEx.Copy(srcMonoFolder, destMonoFolder);
-
-            string srcExecFile = GetMainExecutable(activePlatform);
-            string destExecFile = Path.Combine(destBin, Path.GetFileName(srcExecFile));
-
-            File.Copy(srcExecFile, destExecFile);
-
-            InjectIcons(destExecFile, platformInfo);
-            PackageResources(destRoot, platformInfo);
-            CreateStartupSettings(destRoot, platformInfo);
-
-            // Wait until compile finishes
-            while (!ci.IsDone)
-                Thread.Sleep(200);
-
-            ci.Dispose();
-        }
-
-        /// <summary>
-        /// Injects icons specified in <see cref="PlatformInfo"/> into an executable at the specified path.
-        /// </summary>
-        /// <param name="filePath">Absolute path to the executable to inject icons in.</param>
-        /// <param name="info">Object containing references to icons to inject.</param>
-        private static void InjectIcons(string filePath, PlatformInfo info)
-        {
-            IntPtr infoPtr = IntPtr.Zero;
-            if (info != null)
-                infoPtr = info.GetCachedPtr();
-
-            Internal_InjectIcons(filePath, infoPtr);
-        }
-
-        /// <summary>
-        /// Finds all used resources by the build and packages them into an output folder.
-        /// </summary>
-        /// <param name="buildFolder">Absolute path to the root folder of the build. This is where the packaged resource
-        ///                           folder be placed.</param>
-        /// <param name="info">Platform information about the current build.</param>
-        private static void PackageResources(string buildFolder, PlatformInfo info)
-        {
-            IntPtr infoPtr = IntPtr.Zero;
-            if (info != null)
-                infoPtr = info.GetCachedPtr();
-
-            Internal_PackageResources(buildFolder, infoPtr);
-        }
-
-        /// <summary>
-        /// Creates a game settings asset that contains necessary data for starting up the game (for example initial scene).
-        /// </summary>
-        /// <param name="buildFolder">Absolute path to the root folder of the build. This is where the settings assets
-        ///                           will be output.</param>
-        /// <param name="info">Platform information about the current build.</param>
-        private static void CreateStartupSettings(string buildFolder, PlatformInfo info)
-        {
-            IntPtr infoPtr = IntPtr.Zero;
-            if (info != null)
-                infoPtr = info.GetCachedPtr();
-
-            Internal_CreateStartupSettings(buildFolder, infoPtr);
-        }
-
-        /// <summary>
-        /// Returns a list of .NET framework managed assemblies (without extension) to be included for the specified platform.
-        /// </summary>
-        /// <param name="type">Platform type to retrieve the list of assemblies for.</param>
-        /// <returns>A list of .NET framework managed assemblies (without extension) that will be included with the build.</returns>
-        internal static string[] GetFrameworkAssemblies(PlatformType type)
-        {
-            return Internal_GetFrameworkAssemblies(type);
-        }
-
-        /// <summary>
-        /// Returns the absolute path to the executable for the provided platform.
-        /// </summary>
-        /// <param name="type">Platform type to retrieve the executable location for.</param>
-        /// <returns>Absolute path to the executable.</returns>
-        internal static string GetMainExecutable(PlatformType type)
-        {
-            return Internal_GetMainExecutable(type);
-        }
-
-        /// <summary>
-        /// Returns a list of semicolon separated defines that will be used when compiling scripts for the specified 
-        /// platform.
-        /// </summary>
-        /// <param name="type">Platfrom type to retrieve the defines for.</param>
-        /// <returns>Semicolor separated defines that will be passed along to the script compiler.</returns>
-        internal static string GetDefines(PlatformType type)
-        {
-            return Internal_GetDefines(type);
-        }
-
-        /// <summary>
-        /// Returns an object containing all platform specific build data.
-        /// </summary>
-        /// <param name="type">Platform type to retrieve the data for.</param>
-        /// <returns>An object containing all platform specific build data</returns>
-        internal static PlatformInfo GetPlatformInfo(PlatformType type)
-        {
-            return Internal_GetPlatformInfo(type);
-        }
-
-        /// <summary>
-        /// Types of various folders used by the build manager.
-        /// </summary>
-        private enum BuildFolder // Note: Must match C++ enum ScriptBuildFolder
-        {
-            /// <summary>Absolute path to the root folder where all the prebuilt binaries and data exist.</summary>
-            SourceRoot,
-            /// <summary>Absolute path to the root folder for a build for a specific platform.</summary>
-            DestinationRoot,
-            /// <summary>Folder where native binaries are stored. Relative to root.</summary>
-            NativeBinaries,
-            /// <summary>Folder where Banshee specific debug assemblies are stored. Relative to root.</summary>
-            BansheeDebugAssemblies,
-            /// <summary>Folder where Banshee specific release assemblies are stored. Relative to root.</summary>
-            BansheeReleaseAssemblies,
-            /// <summary>Folder where .NET framework assemblies are stored. Relative to root.</summary>
-            FrameworkAssemblies,
-            /// <summary>Folder where miscelaneous Mono files are stored. Relative to root.</summary>
-            Mono,
-            /// <summary>Folder where builtin data is stored. Relative to root.</summary>
-            Data
-        }
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern PlatformType[] Internal_GetAvailablePlatforms();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern PlatformType Internal_GetActivePlatform();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetActivePlatform(PlatformType value);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern PlatformInfo Internal_GetActivePlatformInfo();
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern PlatformInfo Internal_GetPlatformInfo(PlatformType type);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string[] Internal_GetFrameworkAssemblies(PlatformType type);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetMainExecutable(PlatformType type);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetDefines(PlatformType type);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string[] Internal_GetNativeBinaries(PlatformType type);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetBuildFolder(BuildFolder folder, PlatformType platform);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_InjectIcons(string filePath, IntPtr info);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_PackageResources(string buildFolder, IntPtr info);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateStartupSettings(string buildFolder, IntPtr info);
-    }
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /** @addtogroup Build
+     *  @{
+     */
+
+    /// <summary>
+    /// Contains a list of valid platforms that can be built for.
+    /// </summary>
+    public enum PlatformType // Note: Must match C++ enum PlatformType
+    {
+        Windows,
+        Count // Keep at end
+    }
+
+    /// <summary>
+    /// Contains build data for a specific platform.
+    /// </summary>
+    public abstract class PlatformInfo : ScriptObject
+    {
+        /// <summary>
+        /// Creates a new platform info. For internal runtime use only.
+        /// </summary>
+        protected PlatformInfo()
+        { }
+
+        /// <summary>
+        /// Returns the platform that this object contains data for.
+        /// </summary>
+        public PlatformType Type
+        {
+            get { return Internal_GetType(mCachedPtr); }
+        }
+
+        /// <summary>
+        /// Initial scene that is loaded when application is first started.
+        /// </summary>
+        public ResourceRef MainScene
+        {
+            get { return Internal_GetMainScene(mCachedPtr); }
+            set
+            {
+                IntPtr scenePtr = IntPtr.Zero;
+                if (value != null)
+                    scenePtr = value.GetCachedPtr();
+
+                Internal_SetMainScene(mCachedPtr, scenePtr);
+            }
+        }
+
+        /// <summary>
+        /// Determines should the application be started in fullscreen using the user's desktop resolution.
+        /// </summary>
+        public bool Fullscreen
+        {
+            get { return Internal_GetFullscreen(mCachedPtr); }
+            set { Internal_SetFullscreen(mCachedPtr, value); }
+        }
+
+        /// <summary>
+        /// Width of a window if the game is started in windowed mode. This is only relevant if <see cref="Fullscreen"/>
+        /// is off.
+        /// </summary>
+        public int WindowedWidth
+        {
+            get
+            {
+                int width, height;
+                Internal_GetResolution(mCachedPtr, out width, out height);
+
+                return width;
+            }
+
+            set { Internal_SetResolution(mCachedPtr, value, WindowedHeight); }
+        }
+
+        /// <summary>
+        /// Height of a window if the game is started in windowed mode. This is only relevant if <see cref="Fullscreen"/>
+        /// is off.
+        /// </summary>
+        public int WindowedHeight
+        {
+            get
+            {
+                int width, height;
+                Internal_GetResolution(mCachedPtr, out width, out height);
+
+                return height;
+            }
+
+            set { Internal_SetResolution(mCachedPtr, WindowedWidth, value); }
+        }
+
+        /// <summary>
+        /// Determines should the scripts be output in debug mode (worse performance but better error reporting).
+        /// </summary>
+        public bool Debug
+        {
+            get { return Internal_GetDebug(mCachedPtr); }
+            set { Internal_SetDebug(mCachedPtr, value); }
+        }
+
+        /// <summary>
+        /// A set of semicolon separated defines to use when compiling scripts for this platform.
+        /// </summary>
+        public string Defines
+        {
+            get { return Internal_GetDefines(mCachedPtr); }
+            set { Internal_SetDefines(mCachedPtr, value); }
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern PlatformType Internal_GetType(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetDefines(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetDefines(IntPtr thisPtr, string value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern ResourceRef Internal_GetMainScene(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        static extern void Internal_SetMainScene(IntPtr thisPtr, IntPtr prefabPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        static extern bool Internal_GetFullscreen(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        static extern void Internal_SetFullscreen(IntPtr thisPtr, bool fullscreen);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        static extern void Internal_GetResolution(IntPtr thisPtr, out int width, out int height);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        static extern void Internal_SetResolution(IntPtr thisPtr, int width, int height);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        static extern bool Internal_GetDebug(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        static extern void Internal_SetDebug(IntPtr thisPtr, bool fullscreen);
+    }
+
+    /// <summary>
+    /// Supported icon sizes for Windows platform.
+    /// </summary>
+    public enum WinIconSizes
+    {
+        Icon16 = 16,
+        Icon32 = 32,
+        Icon48 = 48,
+        Icon64 = 64,
+        Icon96 = 96,
+        Icon128 = 128,
+        Icon196 = 196,
+        Icon256 = 256
+    }
+
+    /// <summary>
+    /// Platform data specific to Windows.
+    /// </summary>
+    public class WinPlatformInfo : PlatformInfo
+    {
+        /// <summary>
+        /// Texture that will be displayed on the application's executable.
+        /// </summary>
+        public ResourceRef Icon
+        {
+            get { return Internal_GetIcon(mCachedPtr); }
+            set
+            {
+                IntPtr texturePtr = IntPtr.Zero;
+                if (value != null)
+                    texturePtr = value.GetCachedPtr();
+
+                Internal_SetIcon(mCachedPtr, texturePtr);
+            }
+        }
+
+        /// <summary>
+        /// Text that will be displayed in the application's title bar.
+        /// </summary>
+        public string TitleText
+        {
+            get { return Internal_GetTitleText(mCachedPtr); }
+            set { Internal_SetTitleText(mCachedPtr, value); }
+        }
+        
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern ResourceRef Internal_GetIcon(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetIcon(IntPtr thisPtr, IntPtr texturePtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetTitleText(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetTitleText(IntPtr thisPtr, string value);
+    }
+
+    /// <summary>
+    /// Handles building of the game executable and packaging of all necessary resources, making the game be ready to ran
+    /// as a standalone product.
+    /// </summary>
+    public static class BuildManager
+    {
+        /// <summary>
+        /// Returns a list of all available platforms that can be built for.
+        /// </summary>
+        public static PlatformType[] AvailablePlatforms
+        {
+            get { return Internal_GetAvailablePlatforms(); }
+        }
+
+        /// <summary>
+        /// Returns the currently active platform.
+        /// </summary>
+        public static PlatformType ActivePlatform
+        {
+            get { return Internal_GetActivePlatform(); }
+            set { Internal_SetActivePlatform(value); }
+        }
+
+        /// <summary>
+        /// Returns the data about the currently active platform.
+        /// </summary>
+        public static PlatformInfo ActivePlatformInfo
+        {
+            get { return Internal_GetActivePlatformInfo(); }
+        }
+
+        /// <summary>
+        /// Returns absolute path to the folder where builds for the currently active platform are output.
+        /// </summary>
+        public static string OutputFolder
+        {
+            get { return GetBuildFolder(BuildFolder.DestinationRoot, ActivePlatform); }
+        }
+
+        /// <summary>
+        /// Returns a path to a specific folder used in the build process. See entries of BuildFolder enum for explanations 
+        /// of individual folder types.
+        /// </summary>
+        /// <param name="folder">Type of folder to retrieve the path for.</param>
+        /// <param name="platform">Platform to retrieve the path for.</param>
+        /// <returns>Path for the requested folder. This can be absolute or relative, see <see cref="BuildFolder"/> enum
+        ///          for details.</returns>
+        private static string GetBuildFolder(BuildFolder folder, PlatformType platform)
+        {
+            return Internal_GetBuildFolder(folder, platform);
+        }
+
+        /// <summary>
+        /// Returns a list of names of all native binaries required for a specific platform.
+        /// </summary>
+        /// <param name="platform">Platform type for which to get the binaries for.</param>
+        /// <returns>Array of names of native binary files.</returns>
+        private static string[] GetNativeBinaries(PlatformType platform)
+        {
+            return Internal_GetNativeBinaries(platform);
+        }
+
+        /// <summary>
+        /// Builds the executable and packages the game.
+        /// </summary>
+        public static void Build()
+        {
+            PlatformType activePlatform = ActivePlatform;
+            PlatformInfo platformInfo = ActivePlatformInfo;
+
+            string srcRoot = GetBuildFolder(BuildFolder.SourceRoot, activePlatform);
+            string destRoot = GetBuildFolder(BuildFolder.DestinationRoot, activePlatform);
+
+            // Prepare clean destination folder
+            if(Directory.Exists(destRoot))
+                Directory.Delete(destRoot, true);
+
+            Directory.CreateDirectory(destRoot);
+
+            // Compile game assembly
+            string bansheeAssemblyFolder;
+            if(platformInfo.Debug)
+                bansheeAssemblyFolder = GetBuildFolder(BuildFolder.BansheeDebugAssemblies, activePlatform);
+            else
+                bansheeAssemblyFolder = GetBuildFolder(BuildFolder.BansheeReleaseAssemblies, activePlatform);
+
+            string srcBansheeAssemblyFolder = Path.Combine(srcRoot, bansheeAssemblyFolder);
+            string destBansheeAssemblyFolder = Path.Combine(destRoot, bansheeAssemblyFolder);
+
+            Directory.CreateDirectory(destBansheeAssemblyFolder);
+            CompilerInstance ci = ScriptCompiler.CompileAsync(ScriptAssemblyType.Game, ActivePlatform, platformInfo.Debug, destBansheeAssemblyFolder);
+
+            // Copy engine assembly
+            {
+                string srcFile = Path.Combine(srcBansheeAssemblyFolder, EditorApplication.EngineAssemblyName);
+                string destFile = Path.Combine(destBansheeAssemblyFolder, EditorApplication.EngineAssemblyName);
+
+                File.Copy(srcFile, destFile);
+            }
+
+            // Copy builtin data
+            string dataFolder = GetBuildFolder(BuildFolder.Data, activePlatform);
+            string srcData = Path.Combine(srcRoot, dataFolder);
+            string destData = Path.Combine(destRoot, dataFolder);
+
+            DirectoryEx.Copy(srcData, destData);
+
+            // Copy native binaries
+            string binaryFolder = GetBuildFolder(BuildFolder.NativeBinaries, activePlatform);
+            string srcBin = Path.Combine(srcRoot, binaryFolder);
+            string destBin = destRoot;
+
+            string[] nativeBinaries = GetNativeBinaries(activePlatform);
+            foreach (var entry in nativeBinaries)
+            {
+                string srcFile = Path.Combine(srcBin, entry);
+                string destFile = Path.Combine(destBin, entry);
+
+                File.Copy(srcFile, destFile);
+            }
+
+            // Copy .NET framework assemblies
+            string frameworkAssemblyFolder = GetBuildFolder(BuildFolder.FrameworkAssemblies, activePlatform);
+            string srcFrameworkAssemblyFolder = Path.Combine(srcRoot, frameworkAssemblyFolder);
+            string destFrameworkAssemblyFolder = Path.Combine(destRoot, frameworkAssemblyFolder);
+
+            Directory.CreateDirectory(destFrameworkAssemblyFolder);
+
+            string[] frameworkAssemblies = GetFrameworkAssemblies(activePlatform);
+            foreach (var entry in frameworkAssemblies)
+            {
+                string srcFile = Path.Combine(srcFrameworkAssemblyFolder, entry + ".dll");
+                string destFile = Path.Combine(destFrameworkAssemblyFolder, entry + ".dll");
+
+                File.Copy(srcFile, destFile);
+            }
+
+            // Copy Mono
+            string monoFolder = GetBuildFolder(BuildFolder.Mono, activePlatform);
+            string srcMonoFolder = Path.Combine(srcRoot, monoFolder);
+            string destMonoFolder = Path.Combine(destRoot, monoFolder);
+
+            DirectoryEx.Copy(srcMonoFolder, destMonoFolder);
+
+            string srcExecFile = GetMainExecutable(activePlatform);
+            string destExecFile = Path.Combine(destBin, Path.GetFileName(srcExecFile));
+
+            File.Copy(srcExecFile, destExecFile);
+
+            InjectIcons(destExecFile, platformInfo);
+            PackageResources(destRoot, platformInfo);
+            CreateStartupSettings(destRoot, platformInfo);
+
+            // Wait until compile finishes
+            while (!ci.IsDone)
+                Thread.Sleep(200);
+
+            ci.Dispose();
+        }
+
+        /// <summary>
+        /// Injects icons specified in <see cref="PlatformInfo"/> into an executable at the specified path.
+        /// </summary>
+        /// <param name="filePath">Absolute path to the executable to inject icons in.</param>
+        /// <param name="info">Object containing references to icons to inject.</param>
+        private static void InjectIcons(string filePath, PlatformInfo info)
+        {
+            IntPtr infoPtr = IntPtr.Zero;
+            if (info != null)
+                infoPtr = info.GetCachedPtr();
+
+            Internal_InjectIcons(filePath, infoPtr);
+        }
+
+        /// <summary>
+        /// Finds all used resources by the build and packages them into an output folder.
+        /// </summary>
+        /// <param name="buildFolder">Absolute path to the root folder of the build. This is where the packaged resource
+        ///                           folder be placed.</param>
+        /// <param name="info">Platform information about the current build.</param>
+        private static void PackageResources(string buildFolder, PlatformInfo info)
+        {
+            IntPtr infoPtr = IntPtr.Zero;
+            if (info != null)
+                infoPtr = info.GetCachedPtr();
+
+            Internal_PackageResources(buildFolder, infoPtr);
+        }
+
+        /// <summary>
+        /// Creates a game settings asset that contains necessary data for starting up the game (for example initial scene).
+        /// </summary>
+        /// <param name="buildFolder">Absolute path to the root folder of the build. This is where the settings assets
+        ///                           will be output.</param>
+        /// <param name="info">Platform information about the current build.</param>
+        private static void CreateStartupSettings(string buildFolder, PlatformInfo info)
+        {
+            IntPtr infoPtr = IntPtr.Zero;
+            if (info != null)
+                infoPtr = info.GetCachedPtr();
+
+            Internal_CreateStartupSettings(buildFolder, infoPtr);
+        }
+
+        /// <summary>
+        /// Returns a list of .NET framework managed assemblies (without extension) to be included for the specified platform.
+        /// </summary>
+        /// <param name="type">Platform type to retrieve the list of assemblies for.</param>
+        /// <returns>A list of .NET framework managed assemblies (without extension) that will be included with the build.</returns>
+        internal static string[] GetFrameworkAssemblies(PlatformType type)
+        {
+            return Internal_GetFrameworkAssemblies(type);
+        }
+
+        /// <summary>
+        /// Returns the absolute path to the executable for the provided platform.
+        /// </summary>
+        /// <param name="type">Platform type to retrieve the executable location for.</param>
+        /// <returns>Absolute path to the executable.</returns>
+        internal static string GetMainExecutable(PlatformType type)
+        {
+            return Internal_GetMainExecutable(type);
+        }
+
+        /// <summary>
+        /// Returns a list of semicolon separated defines that will be used when compiling scripts for the specified 
+        /// platform.
+        /// </summary>
+        /// <param name="type">Platfrom type to retrieve the defines for.</param>
+        /// <returns>Semicolor separated defines that will be passed along to the script compiler.</returns>
+        internal static string GetDefines(PlatformType type)
+        {
+            return Internal_GetDefines(type);
+        }
+
+        /// <summary>
+        /// Returns an object containing all platform specific build data.
+        /// </summary>
+        /// <param name="type">Platform type to retrieve the data for.</param>
+        /// <returns>An object containing all platform specific build data</returns>
+        internal static PlatformInfo GetPlatformInfo(PlatformType type)
+        {
+            return Internal_GetPlatformInfo(type);
+        }
+
+        /// <summary>
+        /// Types of various folders used by the build manager.
+        /// </summary>
+        private enum BuildFolder // Note: Must match C++ enum ScriptBuildFolder
+        {
+            /// <summary>Absolute path to the root folder where all the prebuilt binaries and data exist.</summary>
+            SourceRoot,
+            /// <summary>Absolute path to the root folder for a build for a specific platform.</summary>
+            DestinationRoot,
+            /// <summary>Folder where native binaries are stored. Relative to root.</summary>
+            NativeBinaries,
+            /// <summary>Folder where Banshee specific debug assemblies are stored. Relative to root.</summary>
+            BansheeDebugAssemblies,
+            /// <summary>Folder where Banshee specific release assemblies are stored. Relative to root.</summary>
+            BansheeReleaseAssemblies,
+            /// <summary>Folder where .NET framework assemblies are stored. Relative to root.</summary>
+            FrameworkAssemblies,
+            /// <summary>Folder where miscelaneous Mono files are stored. Relative to root.</summary>
+            Mono,
+            /// <summary>Folder where builtin data is stored. Relative to root.</summary>
+            Data
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern PlatformType[] Internal_GetAvailablePlatforms();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern PlatformType Internal_GetActivePlatform();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetActivePlatform(PlatformType value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern PlatformInfo Internal_GetActivePlatformInfo();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern PlatformInfo Internal_GetPlatformInfo(PlatformType type);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string[] Internal_GetFrameworkAssemblies(PlatformType type);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetMainExecutable(PlatformType type);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetDefines(PlatformType type);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string[] Internal_GetNativeBinaries(PlatformType type);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetBuildFolder(BuildFolder folder, PlatformType platform);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_InjectIcons(string filePath, IntPtr info);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_PackageResources(string buildFolder, IntPtr info);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_CreateStartupSettings(string buildFolder, IntPtr info);
+    }
+
+    /** @} */
+}

+ 6 - 0
Source/MBansheeEditor/BuildWindow.cs → Source/MBansheeEditor/Windows/Build/BuildWindow.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Build
+     *  @{
+     */
+
     /// <summary>
     /// Provides options for customizing and activating the build process which will output an executable of the game for a 
     /// specific platform, as well as any required resources.
@@ -275,4 +279,6 @@ namespace BansheeEditor
             }
         }
     }
+
+    /** @} */
 }

+ 1162 - 1156
Source/MBansheeEditor/ColorPicker.cs → Source/MBansheeEditor/Windows/ColorPicker.cs

@@ -1,1156 +1,1162 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using System;
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// A color picker window that allows the user to select from a gamut of colors.
-    /// </summary>
-    public class ColorPicker : ModalWindow
-    {
-        private const int SliderIndividualWidth = 150;
-        private const int SliderIndividualHeight = 15;
-
-        private const int ColorBoxWidth = 200;
-        private const int ColorBoxHeight = 200;
-
-        private const int SliderSideWidth = 40;
-        private const int SliderSideHeight = 200;
-
-        private float colRed, colGreen, colBlue;
-        private float colHue, colSaturation, colValue;
-        private float colAlpha = 1.0f;
-
-        private ColorSlider1DHorz sliderR, sliderG, sliderB, sliderA;
-        private ColorSlider2D colorBox;
-        private ColorSlider1DVert sideSlider;
-
-        private ColorBoxMode colorBoxMode = ColorBoxMode.BG_R;
-        private SliderMode sliderMode = SliderMode.HSV;
-
-        private GUIColorField guiColor;
-        private GUITexture guiSlider2DTex;
-        private GUITexture guiSliderVertTex;
-        private GUITexture guiSliderRHorzTex;
-        private GUITexture guiSliderGHorzTex;
-        private GUITexture guiSliderBHorzTex;
-        private GUITexture guiSliderAHorzTex;
-
-        private GUIButton guiColorBoxBtn;
-        private GUIButton guiColorModeBtn;
-
-        private GUISliderV guiSliderVert;
-        private GUISliderH guiSliderRHorz;
-        private GUISliderH guiSliderGHorz;
-        private GUISliderH guiSliderBHorz;
-        private GUISliderH guiSliderAHorz;
-        private GUITexture guiSlider2DHandle;
-
-        private GUILabel guiLabelR;
-        private GUILabel guiLabelG;
-        private GUILabel guiLabelB;
-        private GUILabel guiLabelA;
-
-        private GUIIntField guiInputR;
-        private GUIIntField guiInputG;
-        private GUIIntField guiInputB;
-        private GUIIntField guiInputA;
-
-        private GUIButton guiOK;
-        private GUIButton guiCancel;
-
-        private Action<bool, Color> closedCallback;
-
-        /// <summary>
-        /// Determines color gamut shown in the color box.
-        /// </summary>
-        public enum ColorBoxMode
-        {
-            BG_R,
-            BR_G,
-            RG_B,
-            SV_H,
-            HV_S,
-            HS_V
-        }
-
-        /// <summary>
-        /// Determines color gamut shown in the horizontal sliders.
-        /// </summary>
-        public enum SliderMode
-        {
-            RGB,
-            HSV
-        }
-
-        /// <summary>
-        /// Returns currently selected color as RGBA values.
-        /// </summary>
-        public Color SelectedColor
-        {
-            get
-            {
-                return new Color(colRed, colGreen, colBlue, colAlpha);
-            }
-        }
-
-        /// <summary>
-        /// Shows the color picker window.
-        /// </summary>
-        /// <param name="closedCallback">Optional callback to trigger when the user selects a color or cancels out
-        ///                              of the dialog.</param>
-        /// <returns>A. instance of the color picker window.</returns>
-        public static ColorPicker Show(Action<bool, Color> closedCallback = null)
-        {
-            ColorPicker picker = new ColorPicker(Color.Black, closedCallback);
-            return picker;
-        }
-
-        /// <summary>
-        /// Shows the color picker window and sets the initial color to show.
-        /// </summary>
-        /// <param name="color">Initial color to display.</param>
-        /// <param name="closedCallback">Optional callback to trigger when the user selects a color or cancels out
-        ///                              of the dialog.</param>
-        /// <returns>A. instance of the color picker window.</returns>
-        public static ColorPicker Show(Color color, Action<bool, Color> closedCallback = null)
-        {
-            ColorPicker picker = new ColorPicker(color, closedCallback);
-            return picker;
-        }
-
-        /// <summary>
-        /// Constructs a new color picker window.
-        /// </summary>
-        /// <param name="color">Initial color to display.</param>
-        /// <param name="closedCallback">Optional callback to trigger when the user selects a color or cancels out
-        ///                              of the dialog.</param>
-        protected ColorPicker(Color color, Action<bool, Color> closedCallback = null)
-            : base(false)
-        {
-            Title = new LocEdString("Color Picker");
-            Width = 270;
-            Height = 400;
-
-            colRed = color.r;
-            colGreen = color.g;
-            colBlue = color.b;
-            colAlpha = color.a;
-
-            RGBToHSV();
-
-            this.closedCallback = closedCallback;
-        }
-
-        private void OnInitialize()
-        {
-            guiColor = new GUIColorField("", GUIOption.FixedWidth(100));
-            guiSlider2DTex = new GUITexture(null, GUIOption.FixedHeight(ColorBoxHeight), GUIOption.FixedWidth(ColorBoxWidth));
-            guiSliderVertTex = new GUITexture(null, GUIOption.FixedHeight(SliderSideHeight), GUIOption.FixedWidth(SliderSideWidth));
-            guiSliderRHorzTex = new GUITexture(null, GUIOption.FixedHeight(SliderIndividualHeight));
-            guiSliderGHorzTex = new GUITexture(null, GUIOption.FixedHeight(SliderIndividualHeight));
-            guiSliderBHorzTex = new GUITexture(null, GUIOption.FixedHeight(SliderIndividualHeight));
-            guiSliderAHorzTex = new GUITexture(null, GUIOption.FixedHeight(SliderIndividualHeight));
-
-            guiColorBoxBtn = new GUIButton(colorBoxMode.ToString());
-            guiColorModeBtn = new GUIButton(sliderMode.ToString());
-
-            guiSliderVert = new GUISliderV(EditorStyles.ColorSliderVert);
-            guiSliderRHorz = new GUISliderH(EditorStyles.ColorSliderHorz);
-            guiSliderGHorz = new GUISliderH(EditorStyles.ColorSliderHorz);
-            guiSliderBHorz = new GUISliderH(EditorStyles.ColorSliderHorz);
-            guiSliderAHorz = new GUISliderH(EditorStyles.ColorSliderHorz);
-            guiSlider2DHandle = new GUITexture(null, EditorStyles.ColorSlider2DHandle);
-
-            guiLabelR = new GUILabel(new LocEdString("R"));
-            guiLabelG = new GUILabel(new LocEdString("G"));
-            guiLabelB = new GUILabel(new LocEdString("B"));
-            guiLabelA = new GUILabel(new LocEdString("A"));
-
-            guiInputR = new GUIIntField();
-            guiInputG = new GUIIntField();
-            guiInputB = new GUIIntField();
-            guiInputA = new GUIIntField();
-
-            guiOK = new GUIButton(new LocEdString("OK"));
-            guiCancel = new GUIButton(new LocEdString("Cancel"));
-
-            guiColorBoxBtn.OnClick += OnColorBoxModeChanged;
-            guiColorModeBtn.OnClick += OnSliderModeChanged;
-
-            guiSliderVert.OnChanged += OnSliderVertChanged;
-            guiSliderRHorz.OnChanged += OnSliderRHorzChanged;
-            guiSliderGHorz.OnChanged += OnSliderGHorzChanged;
-            guiSliderBHorz.OnChanged += OnSliderBHorzChanged;
-            guiSliderAHorz.OnChanged += OnSliderAHorzChanged;
-
-            guiInputR.OnChanged += OnInputRChanged;
-            guiInputG.OnChanged += OnInputGChanged;
-            guiInputB.OnChanged += OnInputBChanged;
-            guiInputA.OnChanged += OnInputAChanged;
-
-            guiOK.OnClick += OnOK;
-            guiCancel.OnClick += OnCancel;
-
-            GUIPanel mainPanel = GUI.AddPanel(0);
-            GUILayout v0 = mainPanel.AddLayoutY();
-
-            v0.AddSpace(5);
-
-            GUILayout h0 = v0.AddLayoutX();
-            h0.AddSpace(10);
-            h0.AddElement(guiColor);
-            h0.AddFlexibleSpace();
-            h0.AddElement(guiColorBoxBtn);
-            h0.AddElement(guiColorModeBtn);
-            h0.AddSpace(10);
-
-            v0.AddSpace(10);
-
-            GUILayout h1 = v0.AddLayoutX();
-            h1.AddSpace(10);
-            h1.AddElement(guiSlider2DTex);
-            h1.AddFlexibleSpace();
-            h1.AddElement(guiSliderVertTex);
-            h1.AddSpace(10);
-
-            v0.AddSpace(10);
-
-            GUILayout h2 = v0.AddLayoutX();
-            h2.AddSpace(10);
-            h2.AddElement(guiLabelR);
-            h2.AddFlexibleSpace();
-            h2.AddElement(guiSliderRHorzTex);
-            h2.AddFlexibleSpace();
-            h2.AddElement(guiInputR);
-            h2.AddSpace(10);
-
-            v0.AddSpace(5);
-
-            GUILayout h3 = v0.AddLayoutX();
-            h3.AddSpace(10);
-            h3.AddElement(guiLabelG);
-            h3.AddFlexibleSpace();
-            h3.AddElement(guiSliderGHorzTex);
-            h3.AddFlexibleSpace();
-            h3.AddElement(guiInputG);
-            h3.AddSpace(10);
-
-            v0.AddSpace(5);
-
-            GUILayout h4 = v0.AddLayoutX();
-            h4.AddSpace(10);
-            h4.AddElement(guiLabelB);
-            h4.AddFlexibleSpace();
-            h4.AddElement(guiSliderBHorzTex);
-            h4.AddFlexibleSpace();
-            h4.AddElement(guiInputB);
-            h4.AddSpace(10);
-
-            v0.AddSpace(5);
-
-            GUILayout h5 = v0.AddLayoutX();
-            h5.AddSpace(10);
-            h5.AddElement(guiLabelA);
-            h5.AddFlexibleSpace();
-            h5.AddElement(guiSliderAHorzTex);
-            h5.AddFlexibleSpace();
-            h5.AddElement(guiInputA);
-            h5.AddSpace(10);
-
-            v0.AddSpace(10);
-
-            GUILayout h6 = v0.AddLayoutX();
-            h6.AddFlexibleSpace();
-            h6.AddElement(guiOK);
-            h6.AddSpace(10);
-            h6.AddElement(guiCancel);
-            h6.AddFlexibleSpace();
-
-            v0.AddSpace(5);
-
-            GUIPanel overlay = GUI.AddPanel(-1);
-            overlay.SetWidth(Width);
-            overlay.SetHeight(Height);
-
-            overlay.AddElement(guiSliderVert);
-            overlay.AddElement(guiSliderRHorz);
-            overlay.AddElement(guiSliderGHorz);
-            overlay.AddElement(guiSliderBHorz);
-            overlay.AddElement(guiSliderAHorz);
-            overlay.AddElement(guiSlider2DHandle);
-
-            colorBox = new ColorSlider2D(guiSlider2DTex, guiSlider2DHandle, ColorBoxWidth, ColorBoxHeight);
-            sideSlider = new ColorSlider1DVert(guiSliderVertTex, guiSliderVert, SliderSideWidth, SliderSideHeight);
-
-            sliderR = new ColorSlider1DHorz(guiSliderRHorzTex, guiSliderRHorz, SliderIndividualWidth, SliderIndividualHeight);
-            sliderG = new ColorSlider1DHorz(guiSliderGHorzTex, guiSliderGHorz, SliderIndividualWidth, SliderIndividualHeight);
-            sliderB = new ColorSlider1DHorz(guiSliderBHorzTex, guiSliderBHorz, SliderIndividualWidth, SliderIndividualHeight);
-            sliderA = new ColorSlider1DHorz(guiSliderAHorzTex, guiSliderAHorz, SliderIndividualWidth, SliderIndividualHeight);
-
-            colorBox.OnValueChanged += OnColorBoxValueChanged;
-
-            Color startA = new Color(0, 0, 0, 1);
-            Color stepA = new Color(1, 1, 1, 0);
-            sliderA.UpdateTexture(startA, stepA, false);
-            guiInputA.SetRange(0, 255);
-            guiInputA.Value = 255;
-            guiSliderAHorz.Percent = 1.0f;
-
-            guiColor.Value = SelectedColor;
-            UpdateInputBoxValues();
-            Update2DSliderValues();
-            Update1DSliderValues();
-            UpdateSliderMode();
-            Update2DSliderTextures();
-            Update1DSliderTextures();
-        }
-
-        private void OnEditorUpdate()
-        {
-            Vector2I windowPos = ScreenToWindowPos(Input.PointerPosition);
-
-            colorBox.UpdateInput(windowPos);
-        }
-
-        /// <summary>
-        /// Fills a 2D area with colors using the provided starting point and gradients.
-        /// </summary>
-        /// <param name="width">Width of the area to fill.</param>
-        /// <param name="height">Height of the area to fill.</param>
-        /// <param name="colors">Array to contain the output. Must be of 
-        ///                      <paramref name="width"/>*<paramref name="height"/> size.</param>
-        /// <param name="start">Initial color in the top-left corner of the area.</param>
-        /// <param name="rightGradient">Gradient towards which the colors increase to the right of the area.</param>
-        /// <param name="downGradient">Gradient towards which the colors increase to the bottom of the area.</param>
-        private static void FillArea(int width, int height, Color[] colors, Color start, Color rightGradient, Color downGradient)
-        {
-            Color rightDelta = new Color(0, 0, 0, 0);
-            if (width > 1)
-                rightDelta = rightGradient / (width - 1);
-
-            Color downDelta = new Color(0, 0, 0, 0);
-            if (height > 1)
-                downDelta = downGradient / (height - 1);
-
-            Color verticalColor = start;
-            for (int y = 0; y < height; y++)
-            {
-                int rowIdx = (height - y - 1) * width;
-
-                Color currentColor = verticalColor;
-                for (int x = 0; x < width; x++)
-                {
-                    colors[rowIdx + x] = currentColor;
-                    currentColor += rightDelta;
-                }
-                verticalColor += downDelta;
-            }
-        }
-
-        /// <summary>
-        /// Converts the currently selected color from HSV to RGB color space.
-        /// </summary>
-        void HSVToRGB()
-        {
-            Color hsv = new Color(colHue, colSaturation, colValue);
-            Color rgb = Color.HSV2RGB(hsv);
-
-            colRed = rgb.r;
-            colGreen = rgb.g;
-            colBlue = rgb.b;
-        }
-
-        /// <summary>
-        /// Converts the currently selected color from RGB to HSV color space.
-        /// </summary>
-        void RGBToHSV()
-        {
-            Color rgb = new Color(colRed, colGreen, colBlue);
-            Color hsv = Color.RGB2HSV(rgb);
-
-            colHue = hsv.r;
-            colSaturation = hsv.g;
-            colValue = hsv.b;
-        }
-
-        /// <summary>
-        /// Triggered when the user selects a new mode for the color box, changing the gamut of colors displayed in the box.
-        /// </summary>
-        void OnColorBoxModeChanged()
-        {
-            int maxModes = Enum.GetNames(colorBoxMode.GetType()).Length;
-            colorBoxMode = (ColorBoxMode)(((int)colorBoxMode + 1) % maxModes);
-
-            guiColorBoxBtn.SetContent(colorBoxMode.ToString());
-            Update2DSliderTextures();
-            Update2DSliderValues();
-        }
-
-        /// <summary>
-        /// Triggered when the user selects a new mode for the side slider, changing the gamut of colors displayed in the 
-        /// slider.
-        /// </summary>
-        void OnSliderModeChanged()
-        {
-            int maxModes = Enum.GetNames(sliderMode.GetType()).Length;
-            sliderMode = (SliderMode)(((int)sliderMode + 1) % maxModes);
-
-            UpdateSliderMode();
-
-            guiColorModeBtn.SetContent(sliderMode.ToString());
-            UpdateInputBoxValues();
-            Update1DSliderTextures();
-            Update1DSliderValues();
-        }
-
-        /// <summary>
-        /// Triggered when the user selects a color in the color box.
-        /// </summary>
-        /// <param name="value">Location on the color box that was selected.</param>
-        void OnColorBoxValueChanged(Vector2 value)
-        {
-            switch (colorBoxMode)
-            {
-                case ColorBoxMode.BG_R:
-                    colBlue = value.x;
-                    colGreen = value.y;
-                    RGBToHSV();
-                    break;
-                case ColorBoxMode.BR_G:
-                    colBlue = value.x;
-                    colRed = value.y;
-                    RGBToHSV();
-                    break;
-                case ColorBoxMode.RG_B:
-                    colRed = value.x;
-                    colGreen = value.y;
-                    RGBToHSV();
-                    break;
-                case ColorBoxMode.SV_H:
-                    colSaturation = value.x;
-                    colValue = value.y;
-                    HSVToRGB();
-                    break;
-                case ColorBoxMode.HV_S:
-                    colHue = value.x;
-                    colValue = value.y;
-                    HSVToRGB();
-                    break;
-                case ColorBoxMode.HS_V:
-                    colHue = value.x;
-                    colSaturation = value.y;
-                    HSVToRGB();
-                    break;
-            }
-
-            guiColor.Value = SelectedColor;
-            UpdateInputBoxValues();
-            Update1DSliderTextures();
-            Update1DSliderValues();
-            UpdateSideSliderTexture();
-
-            Vector2 xy;
-            float z;
-
-            GetColorBoxValues(out xy, out z);
-            guiSliderVert.Percent = 1.0f - z;
-        }
-
-        /// <summary>
-        /// Triggered when the user moves the side slider.
-        /// </summary>
-        /// <param name="percent">New value of the slider.</param>
-        void OnSliderVertChanged(float percent)
-        {
-            percent = 1.0f - percent;
-
-            switch (colorBoxMode)
-            {
-                case ColorBoxMode.BG_R:
-                    colRed = percent;
-                    RGBToHSV();
-                    break;
-                case ColorBoxMode.BR_G:
-                    colGreen = percent;
-                    RGBToHSV();
-                    break;
-                case ColorBoxMode.RG_B:
-                    colBlue = percent;
-                    RGBToHSV();
-                    break;
-                case ColorBoxMode.SV_H:
-                    colHue = percent;
-                    HSVToRGB();
-                    break;
-                case ColorBoxMode.HV_S:
-                    colSaturation = percent;
-                    HSVToRGB();
-                    break;
-                case ColorBoxMode.HS_V:
-                    colValue = percent;
-                    HSVToRGB();
-                    break;
-            }
-
-            guiColor.Value = SelectedColor;
-            UpdateInputBoxValues();
-            Update1DSliderTextures();
-            Update1DSliderValues();
-        }
-
-        /// <summary>
-        /// Triggered when the user moves the horizontal Red/Hue slider.
-        /// </summary>
-        /// <param name="percent">New value of the slider.</param>
-        void OnSliderRHorzChanged(float percent)
-        {
-            bool isHSV = sliderMode == SliderMode.HSV;
-            if (isHSV)
-            {
-                colHue = percent;
-                HSVToRGB();
-            }
-            else
-            {
-                colRed = percent;
-                RGBToHSV();
-            }
-
-            guiColor.Value = SelectedColor;
-            UpdateInputBoxValues();
-            Update2DSliderTextures();
-            Update2DSliderValues();
-        }
-
-        /// <summary>
-        /// Triggered when the user moves the horizontal Green/Saturation slider.
-        /// </summary>
-        /// <param name="percent">New value of the slider.</param>
-        void OnSliderGHorzChanged(float percent)
-        {
-            bool isHSV = sliderMode == SliderMode.HSV;
-            if (isHSV)
-            {
-                colSaturation = percent;
-                HSVToRGB();
-            }
-            else
-            {
-                colGreen = percent;
-                RGBToHSV();
-            }
-
-            guiColor.Value = SelectedColor;
-            UpdateInputBoxValues();
-            Update2DSliderTextures();
-            Update2DSliderValues();
-        }
-
-        /// <summary>
-        /// Triggered when the user moves the horizontal Blue/Value slider.
-        /// </summary>
-        /// <param name="percent">New value of the slider.</param>
-        void OnSliderBHorzChanged(float percent)
-        {
-            bool isHSV = sliderMode == SliderMode.HSV;
-            if (isHSV)
-            {
-                colValue = percent;
-                HSVToRGB();
-            }
-            else
-            {
-                colBlue = percent;
-                RGBToHSV();
-            }
-
-            guiColor.Value = SelectedColor;
-            UpdateInputBoxValues();
-            Update2DSliderTextures();
-            Update2DSliderValues();
-        }
-
-        /// <summary>
-        /// Triggered when the user moves the horizontal alpha slider.
-        /// </summary>
-        /// <param name="percent">New value of the slider.</param>
-        void OnSliderAHorzChanged(float percent)
-        {
-            colAlpha = percent;
-
-            guiColor.Value = SelectedColor;
-            guiInputA.Value = MathEx.RoundToInt(colAlpha * 255.0f);
-        }
-
-        /// <summary>
-        /// Triggered when the user inputs new value in the Red/Hue input box.
-        /// </summary>
-        /// <param name="value">New value in the input box.</param>
-        void OnInputRChanged(int value)
-        {
-            bool isHSV = sliderMode == SliderMode.HSV;
-            if (isHSV)
-            {
-                colHue = value/359.0f;
-                HSVToRGB();
-            }
-            else
-            {
-                colRed = value/255.0f;
-                RGBToHSV();
-            }
-
-            guiColor.Value = SelectedColor;
-            Update1DSliderValues();
-            Update2DSliderTextures();
-            Update2DSliderValues();
-        }
-
-        /// <summary>
-        /// Triggered when the user inputs new value in the Green/Saturation input box.
-        /// </summary>
-        /// <param name="value">New value in the input box.</param>
-        void OnInputGChanged(int value)
-        {
-            bool isHSV = sliderMode == SliderMode.HSV;
-            if (isHSV)
-            {
-                colSaturation = value / 255.0f;
-                HSVToRGB();
-            }
-            else
-            {
-                colGreen = value / 255.0f;
-                RGBToHSV();
-            }
-
-            guiColor.Value = SelectedColor;
-            Update1DSliderValues();
-            Update2DSliderTextures();
-            Update2DSliderValues();
-        }
-
-        /// <summary>
-        /// Triggered when the user inputs new value in the Blue/Value input box.
-        /// </summary>
-        /// <param name="value">New value in the input box.</param>
-        void OnInputBChanged(int value)
-        {
-            bool isHSV = sliderMode == SliderMode.HSV;
-            if (isHSV)
-            {
-                colValue = value / 255.0f;
-                HSVToRGB();
-            }
-            else
-            {
-                colBlue = value / 255.0f;
-                RGBToHSV();
-            }
-
-            guiColor.Value = SelectedColor;
-            Update1DSliderValues();
-            Update2DSliderTextures();
-            Update2DSliderValues();
-        }
-
-        /// <summary>
-        /// Triggered when the user inputs new value in the alpha input box.
-        /// </summary>
-        /// <param name="value">New value in the input box.</param>
-        void OnInputAChanged(int value)
-        {
-            colAlpha = value/255.0f;
-
-            guiColor.Value = SelectedColor;
-            guiSliderAHorz.Percent = colAlpha;
-        }
-
-        /// <summary>
-        /// Triggered when the user selects a color and closes the dialog.
-        /// </summary>
-        void OnOK()
-        {
-            if (closedCallback != null)
-                closedCallback(true, SelectedColor);
-
-            Close();
-        }
-
-        /// <summary>
-        /// Triggered when the user cancels color selection and closes the dialog.
-        /// </summary>
-        void OnCancel()
-        {
-            if (closedCallback != null)
-                closedCallback(false, SelectedColor);
-
-            Close();
-        }
-
-        /// <summary>
-        /// Updates Red/Green/Blue or Hue/Saturation/Value labels and input box ranges depending on currently active mode.
-        /// </summary>
-        void UpdateSliderMode()
-        {
-            if (sliderMode == SliderMode.RGB)
-            {
-                guiLabelR.SetContent(new LocEdString("R"));
-                guiLabelG.SetContent(new LocEdString("G"));
-                guiLabelB.SetContent(new LocEdString("B"));
-
-                guiInputR.SetRange(0, 255);
-                guiInputG.SetRange(0, 255);
-                guiInputB.SetRange(0, 255);
-            }
-            else
-            {
-                guiLabelR.SetContent(new LocEdString("H"));
-                guiLabelG.SetContent(new LocEdString("S"));
-                guiLabelB.SetContent(new LocEdString("V"));
-
-                guiInputR.SetRange(0, 359);
-                guiInputG.SetRange(0, 255);
-                guiInputB.SetRange(0, 255);
-            }
-        }
-
-        /// <summary>
-        /// Updates Red/Green/Blue or Hue/Saturation/Value input boxes with currently selected color.
-        /// </summary>
-        void UpdateInputBoxValues()
-        {
-            bool isHSV = sliderMode == SliderMode.HSV;
-            if (isHSV)
-            {
-                guiInputR.Value = MathEx.RoundToInt(colHue * 359.0f);
-                guiInputG.Value = MathEx.RoundToInt(colSaturation * 255.0f);
-                guiInputB.Value = MathEx.RoundToInt(colValue * 255.0f);
-            }
-            else
-            {
-                guiInputR.Value = MathEx.RoundToInt(colRed * 255.0f);
-                guiInputG.Value = MathEx.RoundToInt(colGreen * 255.0f);
-                guiInputB.Value = MathEx.RoundToInt(colBlue * 255.0f);
-            }
-        }
-
-        /// <summary>
-        /// Updates Red/Green/Blue or Hue/Saturation/Value sliders with currently selected color.
-        /// </summary>
-        void Update1DSliderValues()
-        {
-            bool isHSV = sliderMode == SliderMode.HSV;
-            if (isHSV)
-            {
-                guiSliderRHorz.Percent = colHue;
-                guiSliderGHorz.Percent = colSaturation;
-                guiSliderBHorz.Percent = colValue;
-            }
-            else
-            {
-                guiSliderRHorz.Percent = colRed;
-                guiSliderGHorz.Percent = colGreen;
-                guiSliderBHorz.Percent = colBlue;
-            }
-        }
-
-        /// <summary>
-        /// Returns the current color in the form of color box and side slider coordinates.
-        /// </summary>
-        /// <param name="xy">Coordinates on the color box the current color is located on.</param>
-        /// <param name="z">Coordinates on the side slider the current color is located on.</param>
-        void GetColorBoxValues(out Vector2 xy, out float z)
-        {
-            xy = Vector2.Zero;
-            z = 0.0f;
-
-            switch (colorBoxMode)
-            {
-                case ColorBoxMode.BG_R:
-                    xy.x = colBlue;
-                    xy.y = colGreen;
-                    z = colRed;
-                    break;
-                case ColorBoxMode.BR_G:
-                    xy.x = colBlue;
-                    xy.y = colRed;
-                    z = colGreen;
-                    break;
-                case ColorBoxMode.RG_B:
-                    xy.x = colRed;
-                    xy.y = colGreen;
-                    z = colBlue;
-                    break;
-                case ColorBoxMode.SV_H:
-                    xy.x = colSaturation;
-                    xy.y = colValue;
-                    z = colHue;
-                    break;
-                case ColorBoxMode.HV_S:
-                    xy.x = colHue;
-                    xy.y = colValue;
-                    z = colSaturation;
-                    break;
-                case ColorBoxMode.HS_V:
-                    xy.x = colHue;
-                    xy.y = colSaturation;
-                    z = colValue;
-                    break;
-            }
-        }
-
-        /// <summary>
-        /// Updates values of the color box and side slider according to the current color.
-        /// </summary>
-        void Update2DSliderValues()
-        {
-            Vector2 xy = Vector2.Zero;
-            float z = 0.0f;
-
-            GetColorBoxValues(out xy, out z);
-
-            colorBox.SetValue(xy);
-            guiSliderVert.Percent = z;
-        }
-
-        /// <summary>
-        /// Generates textures to display for all horizontal (RGB/HSV) sliders depending on active slider mode.
-        /// </summary>
-        void Update1DSliderTextures()
-        {
-            bool isHSV = sliderMode == SliderMode.HSV;
-
-            if (isHSV)
-            {
-                Color startH = new Color(0, 1, 1);
-                Color stepH = new Color(1, 0, 0, 0);
-
-                sliderR.UpdateTexture(startH, stepH, true);
-
-                Color startS = new Color(colHue, 0, MathEx.Max(colValue, 0.2f));
-                Color stepS = new Color(0, 1, 0, 0);
-
-                sliderG.UpdateTexture(startS, stepS, true);
-
-                Color startV = new Color(colHue, colSaturation, 0);
-                Color stepV = new Color(0, 0, 1, 0);
-
-                sliderB.UpdateTexture(startV, stepV, true);
-            }
-            else
-            {
-                Color startR = new Color(0, colGreen, colBlue);
-                Color stepR = new Color(1, 0, 0, 0);
-
-                sliderR.UpdateTexture(startR, stepR, false);
-
-                Color startG = new Color(colRed, 0, colBlue);
-                Color stepG = new Color(0, 1, 0, 0);
-
-                sliderG.UpdateTexture(startG, stepG, false);
-
-                Color startB = new Color(colRed, colGreen, 0);
-                Color stepB = new Color(0, 0, 1, 0);
-
-                sliderB.UpdateTexture(startB, stepB, false);
-            }
-        }
-
-        /// <summary>
-        /// Generates a texture for the side slider depending on active color box mode.
-        /// </summary>
-        void UpdateSideSliderTexture()
-        {
-            switch (colorBoxMode)
-            {
-                case ColorBoxMode.BG_R:
-                    sideSlider.UpdateTexture(new Color(0, colGreen, colBlue, 1), new Color(1, 0, 0, 0), false);
-                    break;
-                case ColorBoxMode.BR_G:
-                    sideSlider.UpdateTexture(new Color(colRed, 0, colBlue, 1), new Color(0, 1, 0, 0), false);
-                    break;
-                case ColorBoxMode.RG_B:
-                    sideSlider.UpdateTexture(new Color(colRed, colGreen, 0, 1), new Color(0, 0, 1, 0), false);
-                    break;
-                case ColorBoxMode.SV_H:
-                    sideSlider.UpdateTexture(new Color(0, 1, 1, 1), new Color(1, 0, 0, 0), true);
-                    break;
-                case ColorBoxMode.HV_S:
-                    sideSlider.UpdateTexture(new Color(colHue, 0, MathEx.Max(colValue, 0.2f), 1), new Color(0, 1, 0, 0), true);
-                    break;
-                case ColorBoxMode.HS_V:
-                    sideSlider.UpdateTexture(new Color(colHue, colSaturation, 0, 1), new Color(0, 0, 1, 0), true);
-                    break;
-            }
-        }
-
-        /// <summary>
-        /// Generates textures for the color box and the side slider depending on active color box mode.
-        /// </summary>
-        void Update2DSliderTextures()
-        {
-            UpdateSideSliderTexture();
-
-            float[] valueLookup = new float[] { colRed, colGreen, colBlue, colHue, colSaturation, colValue };
-            colorBox.UpdateTexture(colorBoxMode, valueLookup[(int)colorBoxMode]);
-        }
-
-        /// <summary>
-        /// Manages GUI for a 1D horizontal slider (used RGB/HSV display).
-        /// </summary>
-        public class ColorSlider1DHorz
-        {
-            private const int SLIDER_X_OFFSET = 3;
-            private const int SLIDER_Y_OFFSET = 5;
-
-            private int width, height;
-            private Texture2D texture;
-            private SpriteTexture spriteTexture;
-
-            private GUITexture guiTexture;
-            private GUISliderH guiSlider;
-
-            /// <summary>
-            /// Creates a new horizontal slider.
-            /// </summary>
-            /// <param name="guiTexture">GUI element to display the slider color range on.</param>
-            /// <param name="guiSlider">Slider rendered on top of the texture that may be moved by the user to select a 
-            ///                         color.</param>
-            /// <param name="width">Width of the slider in pixels.</param>
-            /// <param name="height">Height of the slider in pixels.</param>
-            public ColorSlider1DHorz(GUITexture guiTexture, GUISliderH guiSlider, int width, int height)
-            {
-                this.width = width;
-                this.height = height;
-                this.guiTexture = guiTexture;
-                this.guiSlider = guiSlider;
-
-                texture = new Texture2D(width, height);
-                spriteTexture = new SpriteTexture(texture);
-            }
-
-            /// <summary>
-            /// Updates the displayed texture with specified color information.
-            /// </summary>
-            /// <param name="start">Initial color on the left of the slider.</param>
-            /// <param name="step">Final color to the right of the slider.</param>
-            /// <param name="isHSV">Determines are the provided colors in RGB or HSV space.</param>
-            public void UpdateTexture(Color start, Color step, bool isHSV)
-            {
-                Color[] colors = new Color[width * height];
-                FillArea(width, height, colors, start, step, new Color(0, 0, 0, 0));
-
-                if (isHSV)
-                {
-                    for (int i = 0; i < colors.Length; i++)
-                        colors[i] = Color.HSV2RGB(colors[i]);
-                }
-
-                texture.SetPixels(colors);
-                guiTexture.SetTexture(spriteTexture);
-
-                Rect2I sliderBounds = guiTexture.Bounds;
-                sliderBounds.x -= SLIDER_X_OFFSET;
-                sliderBounds.width += SLIDER_X_OFFSET * 2;
-                sliderBounds.y -= SLIDER_Y_OFFSET;
-                sliderBounds.height += SLIDER_Y_OFFSET;
-
-                guiSlider.Bounds = sliderBounds;
-            }
-        }
-
-        /// <summary>
-        /// Manages GUI for a 1D vertical slider (side slider along with the color box).
-        /// </summary>
-        public class ColorSlider1DVert
-        {
-            private const int SLIDER_X_OFFSET = 5;
-            private const int SLIDER_Y_OFFSET = 3;
-
-            private int width, height;
-            private Texture2D texture;
-            private SpriteTexture spriteTexture;
-
-            private GUITexture guiTexture;
-            private GUISliderV guiSlider;
-
-            /// <summary>
-            /// Creates a new vertical slider.
-            /// </summary>
-            /// <param name="guiTexture">GUI element to display the slider color range on.</param>
-            /// <param name="guiSlider">Slider rendered on top of the texture that may be moved by the user to select a 
-            ///                         color.</param>
-            /// <param name="width">Width of the slider in pixels.</param>
-            /// <param name="height">Height of the slider in pixels.</param>
-            public ColorSlider1DVert(GUITexture guiTexture, GUISliderV guiSlider, int width, int height)
-            {
-                this.width = width;
-                this.height = height;
-                this.guiTexture = guiTexture;
-                this.guiSlider = guiSlider;
-
-                texture = new Texture2D(width, height);
-                spriteTexture = new SpriteTexture(texture);
-            }
-
-            /// <summary>
-            /// Updates the displayed texture with specified color information.
-            /// </summary>
-            /// <param name="start">Initial color on the top of the slider.</param>
-            /// <param name="step">Final color to the bottom of the slider.</param>
-            /// <param name="isHSV">Determines are the provided colors in RGB or HSV space.</param>
-            public void UpdateTexture(Color start, Color step, bool isHSV)
-            {
-                Color[] colors = new Color[width * height];
-                FillArea(width, height, colors, start, new Color(0, 0, 0, 0), step);
-
-                if (isHSV)
-                {
-                    for (int i = 0; i < colors.Length; i++)
-                        colors[i] = Color.HSV2RGB(colors[i]);
-                }
-
-                texture.SetPixels(colors);
-                guiTexture.SetTexture(spriteTexture);
-
-                Rect2I sliderBounds = guiTexture.Bounds;
-                sliderBounds.x -= SLIDER_X_OFFSET;
-                sliderBounds.width += SLIDER_X_OFFSET;
-                sliderBounds.y -= SLIDER_Y_OFFSET;
-                sliderBounds.height += SLIDER_Y_OFFSET * 2;
-
-                guiSlider.Bounds = sliderBounds;
-            }
-        }
-
-        /// <summary>
-        /// Manages GUI for a 2D color box, as well as manually handling color box input. Color box serves as a 2D sliders 
-        /// as you can portion of it to select a color.
-        /// </summary>
-        public class ColorSlider2D
-        {
-            private int width, height;
-            private Texture2D texture;
-            private SpriteTexture spriteTexture;
-
-            private GUITexture guiTexture;
-            private GUITexture guiSliderHandle;
-
-            private Vector2 oldValue = new Vector2(-1, -1);
-
-            public delegate void OnValueChangedDelegate(Vector2 value);
-            public event OnValueChangedDelegate OnValueChanged;
-
-            /// <summary>
-            /// Creates a new color box.
-            /// </summary>
-            /// <param name="guiTexture">GUI element to display the 2D color range on.</param>
-            /// <param name="guiSliderHandle">Texture to be used for displaying the position of the currently selected 
-            ///                               color.</param>
-            /// <param name="width">Width of the slider in pixels.</param>
-            /// <param name="height">Height of the slider in pixels.</param>
-            public ColorSlider2D(GUITexture guiTexture, GUITexture guiSliderHandle, int width, int height)
-            {
-                this.width = width;
-                this.height = height;
-
-                this.guiTexture = guiTexture;
-                this.guiSliderHandle = guiSliderHandle;
-
-                texture = new Texture2D(width, height);
-                spriteTexture = new SpriteTexture(texture);
-            }
-
-            /// <summary>
-            /// Updates the texture displayed on the color box.
-            /// </summary>
-            /// <param name="mode">Mode determining the color gamut shown in the color box.</param>
-            /// <param name="value">Value of the third component (normally retrieved from the separate side slider).</param>
-            public void UpdateTexture(ColorBoxMode mode, float value)
-            {
-                Color[] colors = new Color[width * height];
-
-                switch (mode)
-                {
-                    case ColorBoxMode.BG_R:
-                        FillArea(width, height, colors, new Color(value, 0, 0, 1), new Color(0, 0, 1, 0), new Color(0, 1, 0, 0));
-                        break;
-                    case ColorBoxMode.BR_G:
-                        FillArea(width, height, colors, new Color(0, value, 0, 1), new Color(0, 0, 1, 0), new Color(1, 0, 0, 0));
-                        break;
-                    case ColorBoxMode.RG_B:
-                        FillArea(width, height, colors, new Color(0, 0, value, 1), new Color(1, 0, 0, 0), new Color(0, 1, 0, 0));
-                        break;
-                    case ColorBoxMode.SV_H:
-                        FillArea(width, height, colors, new Color(value, 0, 0, 1), new Color(0, 1, 0, 0), new Color(0, 0, 1, 0));
-                        for (int i = 0; i < colors.Length; i++)
-                            colors[i] = Color.HSV2RGB(colors[i]);
-                        break;
-                    case ColorBoxMode.HV_S:
-                        FillArea(width, height, colors, new Color(0, value, 0, 1), new Color(1, 0, 0, 0), new Color(0, 0, 1, 0));
-                        for (int i = 0; i < colors.Length; i++)
-                            colors[i] = Color.HSV2RGB(colors[i]);
-                        break;
-                    case ColorBoxMode.HS_V:
-                        FillArea(width, height, colors, new Color(0, 0, value, 1), new Color(1, 0, 0, 0), new Color(0, 1, 0, 0));
-                        for (int i = 0; i < colors.Length; i++)
-                            colors[i] = Color.HSV2RGB(colors[i]);
-                        break;
-                }
-
-                texture.SetPixels(colors);
-                guiTexture.SetTexture(spriteTexture);
-            }
-
-            /// <summary>
-            /// Handles input over the color box, moving the handle as needed.
-            /// </summary>
-            /// <param name="windowPos">Position of the pointer relative to the color picker window.</param>
-            public void UpdateInput(Vector2I windowPos)
-            {
-                if (Input.IsPointerButtonHeld(PointerButton.Left))
-                {
-                    Rect2I bounds = guiTexture.Bounds;
-
-                    if (bounds.Contains(windowPos))
-                    {
-                        Vector2 newValue = Vector2.Zero;
-                        newValue.x = (windowPos.x - bounds.x) / (float)bounds.width;
-                        newValue.y = 1.0f - (windowPos.y - bounds.y) / (float)bounds.height;
-
-                        SetValue(newValue);
-                    }
-                }
-            }
-
-            /// <summary>
-            /// Moves the handle to a specific location on the color box and selects that color.
-            /// </summary>
-            /// <param name="value">Coordinates relative to the color box.</param>
-            public void SetValue(Vector2 value)
-            {
-                Vector2 pos = value;
-                pos.y = 1.0f - pos.y;
-
-                if (oldValue == value)
-                    return;
-
-                Rect2I handleBounds = guiSliderHandle.Bounds;
-                Rect2I boxBounds = guiTexture.Bounds;
-
-                handleBounds.x = boxBounds.x + MathEx.RoundToInt(pos.x * boxBounds.width) - handleBounds.width / 2;
-                handleBounds.y = boxBounds.y + MathEx.RoundToInt(pos.y * boxBounds.height) - handleBounds.height / 2;
-
-                guiSliderHandle.Bounds = handleBounds;
-                oldValue = value;
-
-                if (OnValueChanged != null)
-                    OnValueChanged(value);
-            }
-        }
-    }
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /** @addtogroup Windows
+     *  @{
+     */
+
+    /// <summary>
+    /// A color picker window that allows the user to select from a gamut of colors.
+    /// </summary>
+    public class ColorPicker : ModalWindow
+    {
+        private const int SliderIndividualWidth = 150;
+        private const int SliderIndividualHeight = 15;
+
+        private const int ColorBoxWidth = 200;
+        private const int ColorBoxHeight = 200;
+
+        private const int SliderSideWidth = 40;
+        private const int SliderSideHeight = 200;
+
+        private float colRed, colGreen, colBlue;
+        private float colHue, colSaturation, colValue;
+        private float colAlpha = 1.0f;
+
+        private ColorSlider1DHorz sliderR, sliderG, sliderB, sliderA;
+        private ColorSlider2D colorBox;
+        private ColorSlider1DVert sideSlider;
+
+        private ColorBoxMode colorBoxMode = ColorBoxMode.BG_R;
+        private SliderMode sliderMode = SliderMode.HSV;
+
+        private GUIColorField guiColor;
+        private GUITexture guiSlider2DTex;
+        private GUITexture guiSliderVertTex;
+        private GUITexture guiSliderRHorzTex;
+        private GUITexture guiSliderGHorzTex;
+        private GUITexture guiSliderBHorzTex;
+        private GUITexture guiSliderAHorzTex;
+
+        private GUIButton guiColorBoxBtn;
+        private GUIButton guiColorModeBtn;
+
+        private GUISliderV guiSliderVert;
+        private GUISliderH guiSliderRHorz;
+        private GUISliderH guiSliderGHorz;
+        private GUISliderH guiSliderBHorz;
+        private GUISliderH guiSliderAHorz;
+        private GUITexture guiSlider2DHandle;
+
+        private GUILabel guiLabelR;
+        private GUILabel guiLabelG;
+        private GUILabel guiLabelB;
+        private GUILabel guiLabelA;
+
+        private GUIIntField guiInputR;
+        private GUIIntField guiInputG;
+        private GUIIntField guiInputB;
+        private GUIIntField guiInputA;
+
+        private GUIButton guiOK;
+        private GUIButton guiCancel;
+
+        private Action<bool, Color> closedCallback;
+
+        /// <summary>
+        /// Determines color gamut shown in the color box.
+        /// </summary>
+        public enum ColorBoxMode
+        {
+            BG_R,
+            BR_G,
+            RG_B,
+            SV_H,
+            HV_S,
+            HS_V
+        }
+
+        /// <summary>
+        /// Determines color gamut shown in the horizontal sliders.
+        /// </summary>
+        public enum SliderMode
+        {
+            RGB,
+            HSV
+        }
+
+        /// <summary>
+        /// Returns currently selected color as RGBA values.
+        /// </summary>
+        public Color SelectedColor
+        {
+            get
+            {
+                return new Color(colRed, colGreen, colBlue, colAlpha);
+            }
+        }
+
+        /// <summary>
+        /// Shows the color picker window.
+        /// </summary>
+        /// <param name="closedCallback">Optional callback to trigger when the user selects a color or cancels out
+        ///                              of the dialog.</param>
+        /// <returns>A. instance of the color picker window.</returns>
+        public static ColorPicker Show(Action<bool, Color> closedCallback = null)
+        {
+            ColorPicker picker = new ColorPicker(Color.Black, closedCallback);
+            return picker;
+        }
+
+        /// <summary>
+        /// Shows the color picker window and sets the initial color to show.
+        /// </summary>
+        /// <param name="color">Initial color to display.</param>
+        /// <param name="closedCallback">Optional callback to trigger when the user selects a color or cancels out
+        ///                              of the dialog.</param>
+        /// <returns>A. instance of the color picker window.</returns>
+        public static ColorPicker Show(Color color, Action<bool, Color> closedCallback = null)
+        {
+            ColorPicker picker = new ColorPicker(color, closedCallback);
+            return picker;
+        }
+
+        /// <summary>
+        /// Constructs a new color picker window.
+        /// </summary>
+        /// <param name="color">Initial color to display.</param>
+        /// <param name="closedCallback">Optional callback to trigger when the user selects a color or cancels out
+        ///                              of the dialog.</param>
+        protected ColorPicker(Color color, Action<bool, Color> closedCallback = null)
+            : base(false)
+        {
+            Title = new LocEdString("Color Picker");
+            Width = 270;
+            Height = 400;
+
+            colRed = color.r;
+            colGreen = color.g;
+            colBlue = color.b;
+            colAlpha = color.a;
+
+            RGBToHSV();
+
+            this.closedCallback = closedCallback;
+        }
+
+        private void OnInitialize()
+        {
+            guiColor = new GUIColorField("", GUIOption.FixedWidth(100));
+            guiSlider2DTex = new GUITexture(null, GUIOption.FixedHeight(ColorBoxHeight), GUIOption.FixedWidth(ColorBoxWidth));
+            guiSliderVertTex = new GUITexture(null, GUIOption.FixedHeight(SliderSideHeight), GUIOption.FixedWidth(SliderSideWidth));
+            guiSliderRHorzTex = new GUITexture(null, GUIOption.FixedHeight(SliderIndividualHeight));
+            guiSliderGHorzTex = new GUITexture(null, GUIOption.FixedHeight(SliderIndividualHeight));
+            guiSliderBHorzTex = new GUITexture(null, GUIOption.FixedHeight(SliderIndividualHeight));
+            guiSliderAHorzTex = new GUITexture(null, GUIOption.FixedHeight(SliderIndividualHeight));
+
+            guiColorBoxBtn = new GUIButton(colorBoxMode.ToString());
+            guiColorModeBtn = new GUIButton(sliderMode.ToString());
+
+            guiSliderVert = new GUISliderV(EditorStyles.ColorSliderVert);
+            guiSliderRHorz = new GUISliderH(EditorStyles.ColorSliderHorz);
+            guiSliderGHorz = new GUISliderH(EditorStyles.ColorSliderHorz);
+            guiSliderBHorz = new GUISliderH(EditorStyles.ColorSliderHorz);
+            guiSliderAHorz = new GUISliderH(EditorStyles.ColorSliderHorz);
+            guiSlider2DHandle = new GUITexture(null, EditorStyles.ColorSlider2DHandle);
+
+            guiLabelR = new GUILabel(new LocEdString("R"));
+            guiLabelG = new GUILabel(new LocEdString("G"));
+            guiLabelB = new GUILabel(new LocEdString("B"));
+            guiLabelA = new GUILabel(new LocEdString("A"));
+
+            guiInputR = new GUIIntField();
+            guiInputG = new GUIIntField();
+            guiInputB = new GUIIntField();
+            guiInputA = new GUIIntField();
+
+            guiOK = new GUIButton(new LocEdString("OK"));
+            guiCancel = new GUIButton(new LocEdString("Cancel"));
+
+            guiColorBoxBtn.OnClick += OnColorBoxModeChanged;
+            guiColorModeBtn.OnClick += OnSliderModeChanged;
+
+            guiSliderVert.OnChanged += OnSliderVertChanged;
+            guiSliderRHorz.OnChanged += OnSliderRHorzChanged;
+            guiSliderGHorz.OnChanged += OnSliderGHorzChanged;
+            guiSliderBHorz.OnChanged += OnSliderBHorzChanged;
+            guiSliderAHorz.OnChanged += OnSliderAHorzChanged;
+
+            guiInputR.OnChanged += OnInputRChanged;
+            guiInputG.OnChanged += OnInputGChanged;
+            guiInputB.OnChanged += OnInputBChanged;
+            guiInputA.OnChanged += OnInputAChanged;
+
+            guiOK.OnClick += OnOK;
+            guiCancel.OnClick += OnCancel;
+
+            GUIPanel mainPanel = GUI.AddPanel(0);
+            GUILayout v0 = mainPanel.AddLayoutY();
+
+            v0.AddSpace(5);
+
+            GUILayout h0 = v0.AddLayoutX();
+            h0.AddSpace(10);
+            h0.AddElement(guiColor);
+            h0.AddFlexibleSpace();
+            h0.AddElement(guiColorBoxBtn);
+            h0.AddElement(guiColorModeBtn);
+            h0.AddSpace(10);
+
+            v0.AddSpace(10);
+
+            GUILayout h1 = v0.AddLayoutX();
+            h1.AddSpace(10);
+            h1.AddElement(guiSlider2DTex);
+            h1.AddFlexibleSpace();
+            h1.AddElement(guiSliderVertTex);
+            h1.AddSpace(10);
+
+            v0.AddSpace(10);
+
+            GUILayout h2 = v0.AddLayoutX();
+            h2.AddSpace(10);
+            h2.AddElement(guiLabelR);
+            h2.AddFlexibleSpace();
+            h2.AddElement(guiSliderRHorzTex);
+            h2.AddFlexibleSpace();
+            h2.AddElement(guiInputR);
+            h2.AddSpace(10);
+
+            v0.AddSpace(5);
+
+            GUILayout h3 = v0.AddLayoutX();
+            h3.AddSpace(10);
+            h3.AddElement(guiLabelG);
+            h3.AddFlexibleSpace();
+            h3.AddElement(guiSliderGHorzTex);
+            h3.AddFlexibleSpace();
+            h3.AddElement(guiInputG);
+            h3.AddSpace(10);
+
+            v0.AddSpace(5);
+
+            GUILayout h4 = v0.AddLayoutX();
+            h4.AddSpace(10);
+            h4.AddElement(guiLabelB);
+            h4.AddFlexibleSpace();
+            h4.AddElement(guiSliderBHorzTex);
+            h4.AddFlexibleSpace();
+            h4.AddElement(guiInputB);
+            h4.AddSpace(10);
+
+            v0.AddSpace(5);
+
+            GUILayout h5 = v0.AddLayoutX();
+            h5.AddSpace(10);
+            h5.AddElement(guiLabelA);
+            h5.AddFlexibleSpace();
+            h5.AddElement(guiSliderAHorzTex);
+            h5.AddFlexibleSpace();
+            h5.AddElement(guiInputA);
+            h5.AddSpace(10);
+
+            v0.AddSpace(10);
+
+            GUILayout h6 = v0.AddLayoutX();
+            h6.AddFlexibleSpace();
+            h6.AddElement(guiOK);
+            h6.AddSpace(10);
+            h6.AddElement(guiCancel);
+            h6.AddFlexibleSpace();
+
+            v0.AddSpace(5);
+
+            GUIPanel overlay = GUI.AddPanel(-1);
+            overlay.SetWidth(Width);
+            overlay.SetHeight(Height);
+
+            overlay.AddElement(guiSliderVert);
+            overlay.AddElement(guiSliderRHorz);
+            overlay.AddElement(guiSliderGHorz);
+            overlay.AddElement(guiSliderBHorz);
+            overlay.AddElement(guiSliderAHorz);
+            overlay.AddElement(guiSlider2DHandle);
+
+            colorBox = new ColorSlider2D(guiSlider2DTex, guiSlider2DHandle, ColorBoxWidth, ColorBoxHeight);
+            sideSlider = new ColorSlider1DVert(guiSliderVertTex, guiSliderVert, SliderSideWidth, SliderSideHeight);
+
+            sliderR = new ColorSlider1DHorz(guiSliderRHorzTex, guiSliderRHorz, SliderIndividualWidth, SliderIndividualHeight);
+            sliderG = new ColorSlider1DHorz(guiSliderGHorzTex, guiSliderGHorz, SliderIndividualWidth, SliderIndividualHeight);
+            sliderB = new ColorSlider1DHorz(guiSliderBHorzTex, guiSliderBHorz, SliderIndividualWidth, SliderIndividualHeight);
+            sliderA = new ColorSlider1DHorz(guiSliderAHorzTex, guiSliderAHorz, SliderIndividualWidth, SliderIndividualHeight);
+
+            colorBox.OnValueChanged += OnColorBoxValueChanged;
+
+            Color startA = new Color(0, 0, 0, 1);
+            Color stepA = new Color(1, 1, 1, 0);
+            sliderA.UpdateTexture(startA, stepA, false);
+            guiInputA.SetRange(0, 255);
+            guiInputA.Value = 255;
+            guiSliderAHorz.Percent = 1.0f;
+
+            guiColor.Value = SelectedColor;
+            UpdateInputBoxValues();
+            Update2DSliderValues();
+            Update1DSliderValues();
+            UpdateSliderMode();
+            Update2DSliderTextures();
+            Update1DSliderTextures();
+        }
+
+        private void OnEditorUpdate()
+        {
+            Vector2I windowPos = ScreenToWindowPos(Input.PointerPosition);
+
+            colorBox.UpdateInput(windowPos);
+        }
+
+        /// <summary>
+        /// Fills a 2D area with colors using the provided starting point and gradients.
+        /// </summary>
+        /// <param name="width">Width of the area to fill.</param>
+        /// <param name="height">Height of the area to fill.</param>
+        /// <param name="colors">Array to contain the output. Must be of 
+        ///                      <paramref name="width"/>*<paramref name="height"/> size.</param>
+        /// <param name="start">Initial color in the top-left corner of the area.</param>
+        /// <param name="rightGradient">Gradient towards which the colors increase to the right of the area.</param>
+        /// <param name="downGradient">Gradient towards which the colors increase to the bottom of the area.</param>
+        private static void FillArea(int width, int height, Color[] colors, Color start, Color rightGradient, Color downGradient)
+        {
+            Color rightDelta = new Color(0, 0, 0, 0);
+            if (width > 1)
+                rightDelta = rightGradient / (width - 1);
+
+            Color downDelta = new Color(0, 0, 0, 0);
+            if (height > 1)
+                downDelta = downGradient / (height - 1);
+
+            Color verticalColor = start;
+            for (int y = 0; y < height; y++)
+            {
+                int rowIdx = (height - y - 1) * width;
+
+                Color currentColor = verticalColor;
+                for (int x = 0; x < width; x++)
+                {
+                    colors[rowIdx + x] = currentColor;
+                    currentColor += rightDelta;
+                }
+                verticalColor += downDelta;
+            }
+        }
+
+        /// <summary>
+        /// Converts the currently selected color from HSV to RGB color space.
+        /// </summary>
+        void HSVToRGB()
+        {
+            Color hsv = new Color(colHue, colSaturation, colValue);
+            Color rgb = Color.HSV2RGB(hsv);
+
+            colRed = rgb.r;
+            colGreen = rgb.g;
+            colBlue = rgb.b;
+        }
+
+        /// <summary>
+        /// Converts the currently selected color from RGB to HSV color space.
+        /// </summary>
+        void RGBToHSV()
+        {
+            Color rgb = new Color(colRed, colGreen, colBlue);
+            Color hsv = Color.RGB2HSV(rgb);
+
+            colHue = hsv.r;
+            colSaturation = hsv.g;
+            colValue = hsv.b;
+        }
+
+        /// <summary>
+        /// Triggered when the user selects a new mode for the color box, changing the gamut of colors displayed in the box.
+        /// </summary>
+        void OnColorBoxModeChanged()
+        {
+            int maxModes = Enum.GetNames(colorBoxMode.GetType()).Length;
+            colorBoxMode = (ColorBoxMode)(((int)colorBoxMode + 1) % maxModes);
+
+            guiColorBoxBtn.SetContent(colorBoxMode.ToString());
+            Update2DSliderTextures();
+            Update2DSliderValues();
+        }
+
+        /// <summary>
+        /// Triggered when the user selects a new mode for the side slider, changing the gamut of colors displayed in the 
+        /// slider.
+        /// </summary>
+        void OnSliderModeChanged()
+        {
+            int maxModes = Enum.GetNames(sliderMode.GetType()).Length;
+            sliderMode = (SliderMode)(((int)sliderMode + 1) % maxModes);
+
+            UpdateSliderMode();
+
+            guiColorModeBtn.SetContent(sliderMode.ToString());
+            UpdateInputBoxValues();
+            Update1DSliderTextures();
+            Update1DSliderValues();
+        }
+
+        /// <summary>
+        /// Triggered when the user selects a color in the color box.
+        /// </summary>
+        /// <param name="value">Location on the color box that was selected.</param>
+        void OnColorBoxValueChanged(Vector2 value)
+        {
+            switch (colorBoxMode)
+            {
+                case ColorBoxMode.BG_R:
+                    colBlue = value.x;
+                    colGreen = value.y;
+                    RGBToHSV();
+                    break;
+                case ColorBoxMode.BR_G:
+                    colBlue = value.x;
+                    colRed = value.y;
+                    RGBToHSV();
+                    break;
+                case ColorBoxMode.RG_B:
+                    colRed = value.x;
+                    colGreen = value.y;
+                    RGBToHSV();
+                    break;
+                case ColorBoxMode.SV_H:
+                    colSaturation = value.x;
+                    colValue = value.y;
+                    HSVToRGB();
+                    break;
+                case ColorBoxMode.HV_S:
+                    colHue = value.x;
+                    colValue = value.y;
+                    HSVToRGB();
+                    break;
+                case ColorBoxMode.HS_V:
+                    colHue = value.x;
+                    colSaturation = value.y;
+                    HSVToRGB();
+                    break;
+            }
+
+            guiColor.Value = SelectedColor;
+            UpdateInputBoxValues();
+            Update1DSliderTextures();
+            Update1DSliderValues();
+            UpdateSideSliderTexture();
+
+            Vector2 xy;
+            float z;
+
+            GetColorBoxValues(out xy, out z);
+            guiSliderVert.Percent = 1.0f - z;
+        }
+
+        /// <summary>
+        /// Triggered when the user moves the side slider.
+        /// </summary>
+        /// <param name="percent">New value of the slider.</param>
+        void OnSliderVertChanged(float percent)
+        {
+            percent = 1.0f - percent;
+
+            switch (colorBoxMode)
+            {
+                case ColorBoxMode.BG_R:
+                    colRed = percent;
+                    RGBToHSV();
+                    break;
+                case ColorBoxMode.BR_G:
+                    colGreen = percent;
+                    RGBToHSV();
+                    break;
+                case ColorBoxMode.RG_B:
+                    colBlue = percent;
+                    RGBToHSV();
+                    break;
+                case ColorBoxMode.SV_H:
+                    colHue = percent;
+                    HSVToRGB();
+                    break;
+                case ColorBoxMode.HV_S:
+                    colSaturation = percent;
+                    HSVToRGB();
+                    break;
+                case ColorBoxMode.HS_V:
+                    colValue = percent;
+                    HSVToRGB();
+                    break;
+            }
+
+            guiColor.Value = SelectedColor;
+            UpdateInputBoxValues();
+            Update1DSliderTextures();
+            Update1DSliderValues();
+        }
+
+        /// <summary>
+        /// Triggered when the user moves the horizontal Red/Hue slider.
+        /// </summary>
+        /// <param name="percent">New value of the slider.</param>
+        void OnSliderRHorzChanged(float percent)
+        {
+            bool isHSV = sliderMode == SliderMode.HSV;
+            if (isHSV)
+            {
+                colHue = percent;
+                HSVToRGB();
+            }
+            else
+            {
+                colRed = percent;
+                RGBToHSV();
+            }
+
+            guiColor.Value = SelectedColor;
+            UpdateInputBoxValues();
+            Update2DSliderTextures();
+            Update2DSliderValues();
+        }
+
+        /// <summary>
+        /// Triggered when the user moves the horizontal Green/Saturation slider.
+        /// </summary>
+        /// <param name="percent">New value of the slider.</param>
+        void OnSliderGHorzChanged(float percent)
+        {
+            bool isHSV = sliderMode == SliderMode.HSV;
+            if (isHSV)
+            {
+                colSaturation = percent;
+                HSVToRGB();
+            }
+            else
+            {
+                colGreen = percent;
+                RGBToHSV();
+            }
+
+            guiColor.Value = SelectedColor;
+            UpdateInputBoxValues();
+            Update2DSliderTextures();
+            Update2DSliderValues();
+        }
+
+        /// <summary>
+        /// Triggered when the user moves the horizontal Blue/Value slider.
+        /// </summary>
+        /// <param name="percent">New value of the slider.</param>
+        void OnSliderBHorzChanged(float percent)
+        {
+            bool isHSV = sliderMode == SliderMode.HSV;
+            if (isHSV)
+            {
+                colValue = percent;
+                HSVToRGB();
+            }
+            else
+            {
+                colBlue = percent;
+                RGBToHSV();
+            }
+
+            guiColor.Value = SelectedColor;
+            UpdateInputBoxValues();
+            Update2DSliderTextures();
+            Update2DSliderValues();
+        }
+
+        /// <summary>
+        /// Triggered when the user moves the horizontal alpha slider.
+        /// </summary>
+        /// <param name="percent">New value of the slider.</param>
+        void OnSliderAHorzChanged(float percent)
+        {
+            colAlpha = percent;
+
+            guiColor.Value = SelectedColor;
+            guiInputA.Value = MathEx.RoundToInt(colAlpha * 255.0f);
+        }
+
+        /// <summary>
+        /// Triggered when the user inputs new value in the Red/Hue input box.
+        /// </summary>
+        /// <param name="value">New value in the input box.</param>
+        void OnInputRChanged(int value)
+        {
+            bool isHSV = sliderMode == SliderMode.HSV;
+            if (isHSV)
+            {
+                colHue = value/359.0f;
+                HSVToRGB();
+            }
+            else
+            {
+                colRed = value/255.0f;
+                RGBToHSV();
+            }
+
+            guiColor.Value = SelectedColor;
+            Update1DSliderValues();
+            Update2DSliderTextures();
+            Update2DSliderValues();
+        }
+
+        /// <summary>
+        /// Triggered when the user inputs new value in the Green/Saturation input box.
+        /// </summary>
+        /// <param name="value">New value in the input box.</param>
+        void OnInputGChanged(int value)
+        {
+            bool isHSV = sliderMode == SliderMode.HSV;
+            if (isHSV)
+            {
+                colSaturation = value / 255.0f;
+                HSVToRGB();
+            }
+            else
+            {
+                colGreen = value / 255.0f;
+                RGBToHSV();
+            }
+
+            guiColor.Value = SelectedColor;
+            Update1DSliderValues();
+            Update2DSliderTextures();
+            Update2DSliderValues();
+        }
+
+        /// <summary>
+        /// Triggered when the user inputs new value in the Blue/Value input box.
+        /// </summary>
+        /// <param name="value">New value in the input box.</param>
+        void OnInputBChanged(int value)
+        {
+            bool isHSV = sliderMode == SliderMode.HSV;
+            if (isHSV)
+            {
+                colValue = value / 255.0f;
+                HSVToRGB();
+            }
+            else
+            {
+                colBlue = value / 255.0f;
+                RGBToHSV();
+            }
+
+            guiColor.Value = SelectedColor;
+            Update1DSliderValues();
+            Update2DSliderTextures();
+            Update2DSliderValues();
+        }
+
+        /// <summary>
+        /// Triggered when the user inputs new value in the alpha input box.
+        /// </summary>
+        /// <param name="value">New value in the input box.</param>
+        void OnInputAChanged(int value)
+        {
+            colAlpha = value/255.0f;
+
+            guiColor.Value = SelectedColor;
+            guiSliderAHorz.Percent = colAlpha;
+        }
+
+        /// <summary>
+        /// Triggered when the user selects a color and closes the dialog.
+        /// </summary>
+        void OnOK()
+        {
+            if (closedCallback != null)
+                closedCallback(true, SelectedColor);
+
+            Close();
+        }
+
+        /// <summary>
+        /// Triggered when the user cancels color selection and closes the dialog.
+        /// </summary>
+        void OnCancel()
+        {
+            if (closedCallback != null)
+                closedCallback(false, SelectedColor);
+
+            Close();
+        }
+
+        /// <summary>
+        /// Updates Red/Green/Blue or Hue/Saturation/Value labels and input box ranges depending on currently active mode.
+        /// </summary>
+        void UpdateSliderMode()
+        {
+            if (sliderMode == SliderMode.RGB)
+            {
+                guiLabelR.SetContent(new LocEdString("R"));
+                guiLabelG.SetContent(new LocEdString("G"));
+                guiLabelB.SetContent(new LocEdString("B"));
+
+                guiInputR.SetRange(0, 255);
+                guiInputG.SetRange(0, 255);
+                guiInputB.SetRange(0, 255);
+            }
+            else
+            {
+                guiLabelR.SetContent(new LocEdString("H"));
+                guiLabelG.SetContent(new LocEdString("S"));
+                guiLabelB.SetContent(new LocEdString("V"));
+
+                guiInputR.SetRange(0, 359);
+                guiInputG.SetRange(0, 255);
+                guiInputB.SetRange(0, 255);
+            }
+        }
+
+        /// <summary>
+        /// Updates Red/Green/Blue or Hue/Saturation/Value input boxes with currently selected color.
+        /// </summary>
+        void UpdateInputBoxValues()
+        {
+            bool isHSV = sliderMode == SliderMode.HSV;
+            if (isHSV)
+            {
+                guiInputR.Value = MathEx.RoundToInt(colHue * 359.0f);
+                guiInputG.Value = MathEx.RoundToInt(colSaturation * 255.0f);
+                guiInputB.Value = MathEx.RoundToInt(colValue * 255.0f);
+            }
+            else
+            {
+                guiInputR.Value = MathEx.RoundToInt(colRed * 255.0f);
+                guiInputG.Value = MathEx.RoundToInt(colGreen * 255.0f);
+                guiInputB.Value = MathEx.RoundToInt(colBlue * 255.0f);
+            }
+        }
+
+        /// <summary>
+        /// Updates Red/Green/Blue or Hue/Saturation/Value sliders with currently selected color.
+        /// </summary>
+        void Update1DSliderValues()
+        {
+            bool isHSV = sliderMode == SliderMode.HSV;
+            if (isHSV)
+            {
+                guiSliderRHorz.Percent = colHue;
+                guiSliderGHorz.Percent = colSaturation;
+                guiSliderBHorz.Percent = colValue;
+            }
+            else
+            {
+                guiSliderRHorz.Percent = colRed;
+                guiSliderGHorz.Percent = colGreen;
+                guiSliderBHorz.Percent = colBlue;
+            }
+        }
+
+        /// <summary>
+        /// Returns the current color in the form of color box and side slider coordinates.
+        /// </summary>
+        /// <param name="xy">Coordinates on the color box the current color is located on.</param>
+        /// <param name="z">Coordinates on the side slider the current color is located on.</param>
+        void GetColorBoxValues(out Vector2 xy, out float z)
+        {
+            xy = Vector2.Zero;
+            z = 0.0f;
+
+            switch (colorBoxMode)
+            {
+                case ColorBoxMode.BG_R:
+                    xy.x = colBlue;
+                    xy.y = colGreen;
+                    z = colRed;
+                    break;
+                case ColorBoxMode.BR_G:
+                    xy.x = colBlue;
+                    xy.y = colRed;
+                    z = colGreen;
+                    break;
+                case ColorBoxMode.RG_B:
+                    xy.x = colRed;
+                    xy.y = colGreen;
+                    z = colBlue;
+                    break;
+                case ColorBoxMode.SV_H:
+                    xy.x = colSaturation;
+                    xy.y = colValue;
+                    z = colHue;
+                    break;
+                case ColorBoxMode.HV_S:
+                    xy.x = colHue;
+                    xy.y = colValue;
+                    z = colSaturation;
+                    break;
+                case ColorBoxMode.HS_V:
+                    xy.x = colHue;
+                    xy.y = colSaturation;
+                    z = colValue;
+                    break;
+            }
+        }
+
+        /// <summary>
+        /// Updates values of the color box and side slider according to the current color.
+        /// </summary>
+        void Update2DSliderValues()
+        {
+            Vector2 xy = Vector2.Zero;
+            float z = 0.0f;
+
+            GetColorBoxValues(out xy, out z);
+
+            colorBox.SetValue(xy);
+            guiSliderVert.Percent = z;
+        }
+
+        /// <summary>
+        /// Generates textures to display for all horizontal (RGB/HSV) sliders depending on active slider mode.
+        /// </summary>
+        void Update1DSliderTextures()
+        {
+            bool isHSV = sliderMode == SliderMode.HSV;
+
+            if (isHSV)
+            {
+                Color startH = new Color(0, 1, 1);
+                Color stepH = new Color(1, 0, 0, 0);
+
+                sliderR.UpdateTexture(startH, stepH, true);
+
+                Color startS = new Color(colHue, 0, MathEx.Max(colValue, 0.2f));
+                Color stepS = new Color(0, 1, 0, 0);
+
+                sliderG.UpdateTexture(startS, stepS, true);
+
+                Color startV = new Color(colHue, colSaturation, 0);
+                Color stepV = new Color(0, 0, 1, 0);
+
+                sliderB.UpdateTexture(startV, stepV, true);
+            }
+            else
+            {
+                Color startR = new Color(0, colGreen, colBlue);
+                Color stepR = new Color(1, 0, 0, 0);
+
+                sliderR.UpdateTexture(startR, stepR, false);
+
+                Color startG = new Color(colRed, 0, colBlue);
+                Color stepG = new Color(0, 1, 0, 0);
+
+                sliderG.UpdateTexture(startG, stepG, false);
+
+                Color startB = new Color(colRed, colGreen, 0);
+                Color stepB = new Color(0, 0, 1, 0);
+
+                sliderB.UpdateTexture(startB, stepB, false);
+            }
+        }
+
+        /// <summary>
+        /// Generates a texture for the side slider depending on active color box mode.
+        /// </summary>
+        void UpdateSideSliderTexture()
+        {
+            switch (colorBoxMode)
+            {
+                case ColorBoxMode.BG_R:
+                    sideSlider.UpdateTexture(new Color(0, colGreen, colBlue, 1), new Color(1, 0, 0, 0), false);
+                    break;
+                case ColorBoxMode.BR_G:
+                    sideSlider.UpdateTexture(new Color(colRed, 0, colBlue, 1), new Color(0, 1, 0, 0), false);
+                    break;
+                case ColorBoxMode.RG_B:
+                    sideSlider.UpdateTexture(new Color(colRed, colGreen, 0, 1), new Color(0, 0, 1, 0), false);
+                    break;
+                case ColorBoxMode.SV_H:
+                    sideSlider.UpdateTexture(new Color(0, 1, 1, 1), new Color(1, 0, 0, 0), true);
+                    break;
+                case ColorBoxMode.HV_S:
+                    sideSlider.UpdateTexture(new Color(colHue, 0, MathEx.Max(colValue, 0.2f), 1), new Color(0, 1, 0, 0), true);
+                    break;
+                case ColorBoxMode.HS_V:
+                    sideSlider.UpdateTexture(new Color(colHue, colSaturation, 0, 1), new Color(0, 0, 1, 0), true);
+                    break;
+            }
+        }
+
+        /// <summary>
+        /// Generates textures for the color box and the side slider depending on active color box mode.
+        /// </summary>
+        void Update2DSliderTextures()
+        {
+            UpdateSideSliderTexture();
+
+            float[] valueLookup = new float[] { colRed, colGreen, colBlue, colHue, colSaturation, colValue };
+            colorBox.UpdateTexture(colorBoxMode, valueLookup[(int)colorBoxMode]);
+        }
+
+        /// <summary>
+        /// Manages GUI for a 1D horizontal slider (used RGB/HSV display).
+        /// </summary>
+        public class ColorSlider1DHorz
+        {
+            private const int SLIDER_X_OFFSET = 3;
+            private const int SLIDER_Y_OFFSET = 5;
+
+            private int width, height;
+            private Texture2D texture;
+            private SpriteTexture spriteTexture;
+
+            private GUITexture guiTexture;
+            private GUISliderH guiSlider;
+
+            /// <summary>
+            /// Creates a new horizontal slider.
+            /// </summary>
+            /// <param name="guiTexture">GUI element to display the slider color range on.</param>
+            /// <param name="guiSlider">Slider rendered on top of the texture that may be moved by the user to select a 
+            ///                         color.</param>
+            /// <param name="width">Width of the slider in pixels.</param>
+            /// <param name="height">Height of the slider in pixels.</param>
+            public ColorSlider1DHorz(GUITexture guiTexture, GUISliderH guiSlider, int width, int height)
+            {
+                this.width = width;
+                this.height = height;
+                this.guiTexture = guiTexture;
+                this.guiSlider = guiSlider;
+
+                texture = new Texture2D(width, height);
+                spriteTexture = new SpriteTexture(texture);
+            }
+
+            /// <summary>
+            /// Updates the displayed texture with specified color information.
+            /// </summary>
+            /// <param name="start">Initial color on the left of the slider.</param>
+            /// <param name="step">Final color to the right of the slider.</param>
+            /// <param name="isHSV">Determines are the provided colors in RGB or HSV space.</param>
+            public void UpdateTexture(Color start, Color step, bool isHSV)
+            {
+                Color[] colors = new Color[width * height];
+                FillArea(width, height, colors, start, step, new Color(0, 0, 0, 0));
+
+                if (isHSV)
+                {
+                    for (int i = 0; i < colors.Length; i++)
+                        colors[i] = Color.HSV2RGB(colors[i]);
+                }
+
+                texture.SetPixels(colors);
+                guiTexture.SetTexture(spriteTexture);
+
+                Rect2I sliderBounds = guiTexture.Bounds;
+                sliderBounds.x -= SLIDER_X_OFFSET;
+                sliderBounds.width += SLIDER_X_OFFSET * 2;
+                sliderBounds.y -= SLIDER_Y_OFFSET;
+                sliderBounds.height += SLIDER_Y_OFFSET;
+
+                guiSlider.Bounds = sliderBounds;
+            }
+        }
+
+        /// <summary>
+        /// Manages GUI for a 1D vertical slider (side slider along with the color box).
+        /// </summary>
+        public class ColorSlider1DVert
+        {
+            private const int SLIDER_X_OFFSET = 5;
+            private const int SLIDER_Y_OFFSET = 3;
+
+            private int width, height;
+            private Texture2D texture;
+            private SpriteTexture spriteTexture;
+
+            private GUITexture guiTexture;
+            private GUISliderV guiSlider;
+
+            /// <summary>
+            /// Creates a new vertical slider.
+            /// </summary>
+            /// <param name="guiTexture">GUI element to display the slider color range on.</param>
+            /// <param name="guiSlider">Slider rendered on top of the texture that may be moved by the user to select a 
+            ///                         color.</param>
+            /// <param name="width">Width of the slider in pixels.</param>
+            /// <param name="height">Height of the slider in pixels.</param>
+            public ColorSlider1DVert(GUITexture guiTexture, GUISliderV guiSlider, int width, int height)
+            {
+                this.width = width;
+                this.height = height;
+                this.guiTexture = guiTexture;
+                this.guiSlider = guiSlider;
+
+                texture = new Texture2D(width, height);
+                spriteTexture = new SpriteTexture(texture);
+            }
+
+            /// <summary>
+            /// Updates the displayed texture with specified color information.
+            /// </summary>
+            /// <param name="start">Initial color on the top of the slider.</param>
+            /// <param name="step">Final color to the bottom of the slider.</param>
+            /// <param name="isHSV">Determines are the provided colors in RGB or HSV space.</param>
+            public void UpdateTexture(Color start, Color step, bool isHSV)
+            {
+                Color[] colors = new Color[width * height];
+                FillArea(width, height, colors, start, new Color(0, 0, 0, 0), step);
+
+                if (isHSV)
+                {
+                    for (int i = 0; i < colors.Length; i++)
+                        colors[i] = Color.HSV2RGB(colors[i]);
+                }
+
+                texture.SetPixels(colors);
+                guiTexture.SetTexture(spriteTexture);
+
+                Rect2I sliderBounds = guiTexture.Bounds;
+                sliderBounds.x -= SLIDER_X_OFFSET;
+                sliderBounds.width += SLIDER_X_OFFSET;
+                sliderBounds.y -= SLIDER_Y_OFFSET;
+                sliderBounds.height += SLIDER_Y_OFFSET * 2;
+
+                guiSlider.Bounds = sliderBounds;
+            }
+        }
+
+        /// <summary>
+        /// Manages GUI for a 2D color box, as well as manually handling color box input. Color box serves as a 2D sliders 
+        /// as you can portion of it to select a color.
+        /// </summary>
+        public class ColorSlider2D
+        {
+            private int width, height;
+            private Texture2D texture;
+            private SpriteTexture spriteTexture;
+
+            private GUITexture guiTexture;
+            private GUITexture guiSliderHandle;
+
+            private Vector2 oldValue = new Vector2(-1, -1);
+
+            public delegate void OnValueChangedDelegate(Vector2 value);
+            public event OnValueChangedDelegate OnValueChanged;
+
+            /// <summary>
+            /// Creates a new color box.
+            /// </summary>
+            /// <param name="guiTexture">GUI element to display the 2D color range on.</param>
+            /// <param name="guiSliderHandle">Texture to be used for displaying the position of the currently selected 
+            ///                               color.</param>
+            /// <param name="width">Width of the slider in pixels.</param>
+            /// <param name="height">Height of the slider in pixels.</param>
+            public ColorSlider2D(GUITexture guiTexture, GUITexture guiSliderHandle, int width, int height)
+            {
+                this.width = width;
+                this.height = height;
+
+                this.guiTexture = guiTexture;
+                this.guiSliderHandle = guiSliderHandle;
+
+                texture = new Texture2D(width, height);
+                spriteTexture = new SpriteTexture(texture);
+            }
+
+            /// <summary>
+            /// Updates the texture displayed on the color box.
+            /// </summary>
+            /// <param name="mode">Mode determining the color gamut shown in the color box.</param>
+            /// <param name="value">Value of the third component (normally retrieved from the separate side slider).</param>
+            public void UpdateTexture(ColorBoxMode mode, float value)
+            {
+                Color[] colors = new Color[width * height];
+
+                switch (mode)
+                {
+                    case ColorBoxMode.BG_R:
+                        FillArea(width, height, colors, new Color(value, 0, 0, 1), new Color(0, 0, 1, 0), new Color(0, 1, 0, 0));
+                        break;
+                    case ColorBoxMode.BR_G:
+                        FillArea(width, height, colors, new Color(0, value, 0, 1), new Color(0, 0, 1, 0), new Color(1, 0, 0, 0));
+                        break;
+                    case ColorBoxMode.RG_B:
+                        FillArea(width, height, colors, new Color(0, 0, value, 1), new Color(1, 0, 0, 0), new Color(0, 1, 0, 0));
+                        break;
+                    case ColorBoxMode.SV_H:
+                        FillArea(width, height, colors, new Color(value, 0, 0, 1), new Color(0, 1, 0, 0), new Color(0, 0, 1, 0));
+                        for (int i = 0; i < colors.Length; i++)
+                            colors[i] = Color.HSV2RGB(colors[i]);
+                        break;
+                    case ColorBoxMode.HV_S:
+                        FillArea(width, height, colors, new Color(0, value, 0, 1), new Color(1, 0, 0, 0), new Color(0, 0, 1, 0));
+                        for (int i = 0; i < colors.Length; i++)
+                            colors[i] = Color.HSV2RGB(colors[i]);
+                        break;
+                    case ColorBoxMode.HS_V:
+                        FillArea(width, height, colors, new Color(0, 0, value, 1), new Color(1, 0, 0, 0), new Color(0, 1, 0, 0));
+                        for (int i = 0; i < colors.Length; i++)
+                            colors[i] = Color.HSV2RGB(colors[i]);
+                        break;
+                }
+
+                texture.SetPixels(colors);
+                guiTexture.SetTexture(spriteTexture);
+            }
+
+            /// <summary>
+            /// Handles input over the color box, moving the handle as needed.
+            /// </summary>
+            /// <param name="windowPos">Position of the pointer relative to the color picker window.</param>
+            public void UpdateInput(Vector2I windowPos)
+            {
+                if (Input.IsPointerButtonHeld(PointerButton.Left))
+                {
+                    Rect2I bounds = guiTexture.Bounds;
+
+                    if (bounds.Contains(windowPos))
+                    {
+                        Vector2 newValue = Vector2.Zero;
+                        newValue.x = (windowPos.x - bounds.x) / (float)bounds.width;
+                        newValue.y = 1.0f - (windowPos.y - bounds.y) / (float)bounds.height;
+
+                        SetValue(newValue);
+                    }
+                }
+            }
+
+            /// <summary>
+            /// Moves the handle to a specific location on the color box and selects that color.
+            /// </summary>
+            /// <param name="value">Coordinates relative to the color box.</param>
+            public void SetValue(Vector2 value)
+            {
+                Vector2 pos = value;
+                pos.y = 1.0f - pos.y;
+
+                if (oldValue == value)
+                    return;
+
+                Rect2I handleBounds = guiSliderHandle.Bounds;
+                Rect2I boxBounds = guiTexture.Bounds;
+
+                handleBounds.x = boxBounds.x + MathEx.RoundToInt(pos.x * boxBounds.width) - handleBounds.width / 2;
+                handleBounds.y = boxBounds.y + MathEx.RoundToInt(pos.y * boxBounds.height) - handleBounds.height / 2;
+
+                guiSliderHandle.Bounds = handleBounds;
+                oldValue = value;
+
+                if (OnValueChanged != null)
+                    OnValueChanged(value);
+            }
+        }
+    }
+
+    /** @} */
+}

+ 6 - 0
Source/MBansheeEditor/DialogBox.cs → Source/MBansheeEditor/Windows/DialogBox.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Windows
+     *  @{
+     */
+
     /// <summary>
     /// Displays a modal window containing a title, a message and a set of buttons. Allows an easy way to query and inform
     /// the user.
@@ -282,4 +286,6 @@ namespace BansheeEditor
             Close();
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/GameWindow.cs → Source/MBansheeEditor/Windows/GameWindow.cs

@@ -4,6 +4,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Windows
+     *  @{
+     */
+
     /// <summary>
     /// Displays in-game viewport in the editor.
     /// </summary>
@@ -216,4 +220,6 @@ namespace BansheeEditor
             public int height;
         }
     }
+
+    /** @} */
 }

+ 120 - 114
Source/MBansheeEditor/HierarchyWindow.cs → Source/MBansheeEditor/Windows/HierarchyWindow.cs

@@ -1,114 +1,120 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Editor window that displays the scene hierarchy tree view, displaying all scene objects in the current scene.
-    /// </summary>
-    public class HierarchyWindow : EditorWindow, IGlobalShortcuts
-    {
-        private GUISceneTreeView treeView;
-
-        /// <summary>
-        /// Opens the hierarchy window.
-        /// </summary>
-        [MenuItem("Windows/Hierarchy", ButtonModifier.CtrlAlt, ButtonCode.H, 6000)]
-        private static void OpenHierarchyWindow()
-        {
-            OpenWindow<HierarchyWindow>();
-        }
-
-        /// <inheritdoc/>
-        protected override LocString GetDisplayName()
-        {
-            return new LocEdString("Hierarchy");
-        }
-
-        /// <inheritdoc/>
-        void IGlobalShortcuts.OnDeletePressed()
-        {
-            treeView.DeleteSelection();
-        }
-
-        /// <inheritdoc/>
-        void IGlobalShortcuts.OnRenamePressed()
-        {
-            treeView.RenameSelection();
-        }
-
-        /// <inheritdoc/>
-        void IGlobalShortcuts.OnDuplicatePressed()
-        {
-            treeView.DuplicateSelection();
-        }
-
-        /// <inheritdoc/>
-        void IGlobalShortcuts.OnCopyPressed()
-        {
-            treeView.CopySelection();
-        }
-
-        /// <inheritdoc/>
-        void IGlobalShortcuts.OnCutPressed()
-        {
-            treeView.CutSelection();
-        }
-
-        /// <inheritdoc/>
-        void IGlobalShortcuts.OnPastePressed()
-        {
-            treeView.PasteToSelection();
-        }
-
-        private void OnInitialize()
-        {
-            GUIScrollArea scrollArea = new GUIScrollArea();
-            GUI.AddElement(scrollArea);
-
-            treeView = new GUISceneTreeView(GUIOption.FlexibleHeight(20), GUIOption.FlexibleWidth(20));
-            scrollArea.Layout.AddElement(treeView);
-
-            EditorVirtualInput.OnButtonUp += OnButtonUp;
-        }
-
-        private void OnEditorUpdate()
-        {
-            treeView.Update();
-        }
-
-        private void OnDestroy()
-        {
-            EditorVirtualInput.OnButtonUp -= OnButtonUp;
-        }
-
-        /// <summary>
-        /// Triggered when the user presses a virtual button.
-        /// </summary>
-        /// <param name="btn">Button that was pressed.</param>
-        /// <param name="deviceIdx">Index of the device it was pressed on. </param>
-        private void OnButtonUp(VirtualButton btn, int deviceIdx)
-        {
-            if (!HasFocus)
-                return;
-
-            IGlobalShortcuts shortcuts = this;
-
-            if (btn == EditorApplication.CopyKey)
-                shortcuts.OnCopyPressed();
-            else if (btn == EditorApplication.CutKey)
-                shortcuts.OnCutPressed();
-            else if (btn == EditorApplication.PasteKey)
-                shortcuts.OnPastePressed();
-            else if (btn == EditorApplication.DuplicateKey)
-                shortcuts.OnDuplicatePressed();
-            else if (btn == EditorApplication.RenameKey)
-                shortcuts.OnRenamePressed();
-            else if (btn == EditorApplication.DeleteKey)
-                shortcuts.OnDeletePressed();
-            else if(btn == EditorApplication.PasteKey)
-                shortcuts.OnPastePressed();
-        }
-    }
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /** @addtogroup Windows
+     *  @{
+     */
+
+    /// <summary>
+    /// Editor window that displays the scene hierarchy tree view, displaying all scene objects in the current scene.
+    /// </summary>
+    public class HierarchyWindow : EditorWindow, IGlobalShortcuts
+    {
+        private GUISceneTreeView treeView;
+
+        /// <summary>
+        /// Opens the hierarchy window.
+        /// </summary>
+        [MenuItem("Windows/Hierarchy", ButtonModifier.CtrlAlt, ButtonCode.H, 6000)]
+        private static void OpenHierarchyWindow()
+        {
+            OpenWindow<HierarchyWindow>();
+        }
+
+        /// <inheritdoc/>
+        protected override LocString GetDisplayName()
+        {
+            return new LocEdString("Hierarchy");
+        }
+
+        /// <inheritdoc/>
+        void IGlobalShortcuts.OnDeletePressed()
+        {
+            treeView.DeleteSelection();
+        }
+
+        /// <inheritdoc/>
+        void IGlobalShortcuts.OnRenamePressed()
+        {
+            treeView.RenameSelection();
+        }
+
+        /// <inheritdoc/>
+        void IGlobalShortcuts.OnDuplicatePressed()
+        {
+            treeView.DuplicateSelection();
+        }
+
+        /// <inheritdoc/>
+        void IGlobalShortcuts.OnCopyPressed()
+        {
+            treeView.CopySelection();
+        }
+
+        /// <inheritdoc/>
+        void IGlobalShortcuts.OnCutPressed()
+        {
+            treeView.CutSelection();
+        }
+
+        /// <inheritdoc/>
+        void IGlobalShortcuts.OnPastePressed()
+        {
+            treeView.PasteToSelection();
+        }
+
+        private void OnInitialize()
+        {
+            GUIScrollArea scrollArea = new GUIScrollArea();
+            GUI.AddElement(scrollArea);
+
+            treeView = new GUISceneTreeView(GUIOption.FlexibleHeight(20), GUIOption.FlexibleWidth(20));
+            scrollArea.Layout.AddElement(treeView);
+
+            EditorVirtualInput.OnButtonUp += OnButtonUp;
+        }
+
+        private void OnEditorUpdate()
+        {
+            treeView.Update();
+        }
+
+        private void OnDestroy()
+        {
+            EditorVirtualInput.OnButtonUp -= OnButtonUp;
+        }
+
+        /// <summary>
+        /// Triggered when the user presses a virtual button.
+        /// </summary>
+        /// <param name="btn">Button that was pressed.</param>
+        /// <param name="deviceIdx">Index of the device it was pressed on. </param>
+        private void OnButtonUp(VirtualButton btn, int deviceIdx)
+        {
+            if (!HasFocus)
+                return;
+
+            IGlobalShortcuts shortcuts = this;
+
+            if (btn == EditorApplication.CopyKey)
+                shortcuts.OnCopyPressed();
+            else if (btn == EditorApplication.CutKey)
+                shortcuts.OnCutPressed();
+            else if (btn == EditorApplication.PasteKey)
+                shortcuts.OnPastePressed();
+            else if (btn == EditorApplication.DuplicateKey)
+                shortcuts.OnDuplicatePressed();
+            else if (btn == EditorApplication.RenameKey)
+                shortcuts.OnRenamePressed();
+            else if (btn == EditorApplication.DeleteKey)
+                shortcuts.OnDeletePressed();
+            else if(btn == EditorApplication.PasteKey)
+                shortcuts.OnPastePressed();
+        }
+    }
+
+    /** @} */
+}

+ 6 - 0
Source/MBansheeEditor/Inspector/CustomInspector.cs → Source/MBansheeEditor/Windows/Inspector/CustomInspector.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspector
+     *  @{
+     */
+
     /// <summary>
     /// Specifies that a class or a struct uses a custom inspector for GUI display. This attribute can be placed on an 
     /// implementation of <see cref="Inspector"/> in which case the type must reference a <see cref="Component"/> or a
@@ -26,4 +30,6 @@ namespace BansheeEditor
             this.type = type;
         }
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/EditorPersistentData.cs → Source/MBansheeEditor/Windows/Inspector/EditorPersistentData.cs

@@ -5,6 +5,10 @@ using System.Collections.Generic;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspector
+     *  @{
+     */
+
     /// <summary>
     /// Contains editor data that should persist assembly refresh.
     /// </summary>
@@ -13,4 +17,6 @@ namespace BansheeEditor
         [SerializeField]
         internal Dictionary<string, bool> dirtyResources = new Dictionary<string, bool>();
     }
+
+    /** @} */
 }

+ 6 - 0
Source/MBansheeEditor/Inspector/GenericInspector.cs → Source/MBansheeEditor/Windows/Inspector/GenericInspector.cs

@@ -5,6 +5,10 @@ using BansheeEngine;
 
 namespace BansheeEditor
 {
+    /** @addtogroup Inspector
+     *  @{
+     */
+
     /// <summary>
     /// Default implementation of the inspector used when no specified inspector is provided for the type. Inspector 
     /// displays GUI for all the inspectable fields in the object.
@@ -61,4 +65,6 @@ namespace BansheeEditor
             base.SetVisible(!isEmpty && visible);
         }
     }
+
+    /** @} */
 }

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików