From 8abf5bfc8f263a84f1f664be08aa90b9f559aa1b Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Mon, 24 Aug 2026 12:35:06 -0700 Subject: [PATCH 01/17] [Chores] Changed the license --- LICENSE | 526 ++++++++++++------ README.md | 2 +- .../Build/CreateProjectView.swift | 8 +- .../Config/EditorFeatureFlags.swift | 8 +- .../Editor/AssetBrowserView.swift | 8 +- .../Editor/AssetNodeEditingPolicy.swift | 8 +- .../Editor/AssetWindowDelegate.swift | 6 + .../Editor/ComponentEditorForm.swift | 8 +- .../UntoldEditor/Editor/DemoGalleryView.swift | 8 +- .../Editor/DemoSceneCatalog.swift | 8 +- .../Editor/EditorController.swift | 8 +- .../UntoldEditor/Editor/EditorSceneView.swift | 8 +- .../UntoldEditor/Editor/EditorScheme.swift | 8 +- .../Editor/EditorUndoManager.swift | 8 +- Sources/UntoldEditor/Editor/EditorView.swift | 6 + .../UntoldEditor/Editor/EngineStatsView.swift | 8 +- .../UntoldEditor/Editor/EnvironmentView.swift | 8 +- .../Editor/ExplicitClickTextField.swift | 8 +- .../UntoldEditor/Editor/InspectorView.swift | 8 +- .../Editor/LODComponentEditorView.swift | 8 +- .../Editor/LoadingIndicatorView.swift | 8 +- .../UntoldEditor/Editor/LogConsoleView.swift | 8 +- .../Editor/NumericInputView.swift | 8 +- .../Editor/QuickPreviewComponent.swift | 8 +- .../Editor/SceneHierarchyView.swift | 8 +- .../Editor/ScriptComponentInspector.swift | 8 +- .../Editor/SelectionManager.swift | 8 +- .../Editor/StarterStreamModels.swift | 8 +- .../Editor/StaticBatchingView.swift | 8 +- .../Editor/TransformManipulationView.swift | 8 +- .../Renderer/EditorRenderPasses.swift | 8 +- .../Renderer/EditorRenderPipeLines.swift | 8 +- .../Renderer/EditorRendererInitializer.swift | 8 +- .../Renderer/EditorUntoldRenderer.swift | 8 +- .../Renderer/EditorUntoldRendererConfig.swift | 8 +- .../Systems/EditorCameraSystem.swift | 8 +- .../Systems/EditorInputSystemAppKit.swift | 8 +- .../Systems/EditorInputSystemUIKit.swift | 8 +- .../Systems/EditorLightingSystem.swift | 8 +- .../Systems/EditorRenderingSystem.swift | 8 +- .../UntoldEditor/Systems/GizmoSystem.swift | 8 +- .../Systems/HotReloadingSystem.swift | 8 +- .../Systems/ScriptProjectManager.swift | 22 +- .../UntoldEditor/Systems/VisualDebugger.swift | 8 +- .../UntoldEditor/Utils/EditorFuncUtils.swift | 8 +- .../UntoldEditor/Utils/EditorGlobals.swift | 8 +- .../Utils/UntoldMaterialPersistence.swift | 6 + Sources/UntoldEditor/main.swift | 8 +- .../AssetBrowserViewTests.swift | 8 +- .../AssetNodeEditingPolicyTests.swift | 8 +- .../ComponentEditorFormTests.swift | 8 +- .../CreateProjectViewTests.swift | 8 +- .../DemoGalleryViewTests.swift | 8 +- .../EditorCameraSystemTests.swift | 8 +- .../EditorControllerTests.swift | 8 +- .../EditorFuncUtilsTests.swift | 8 +- .../EditorRenderPassesTests.swift | 8 +- .../EditorRenderPipeLinesTests.swift | 8 +- .../EditorRendererInitializerTests.swift | 8 +- .../EditorRenderingSystemTests.swift | 8 +- .../EditorUndoManagerTests.swift | 8 +- .../EditorUntoldRendererTests.swift | 8 +- .../EnvironmentViewTests.swift | 8 +- .../FindSceneCameraTest.swift | 8 +- Tests/UntoldEditorTests/GizmoSystemTest.swift | 8 +- .../InputSystemCoreTests.swift | 8 +- .../InspectorViewTests.swift | 8 +- .../LightDebugMeshTest.swift | 8 +- .../LogConsoleViewTests.swift | 8 +- .../UntoldEditorTests/NumericInputTest.swift | 8 +- .../ParentingSerializationTests.swift | 8 +- .../SceneHierarchyViewTests.swift | 8 +- .../ScriptProjectManagerTests.swift | 8 +- .../SelectionManagerTests.swift | 8 +- .../UntoldEditorTests/ToolbarViewTests.swift | 8 +- .../TransformManipulationViewTests.swift | 8 +- scripts/changecopyright.sh | 5 +- 77 files changed, 753 insertions(+), 380 deletions(-) diff --git a/LICENSE b/LICENSE index 0a04128..d7e38a8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,165 +1,373 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 +Mozilla Public License Version 2.0 +================================== - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. +1. Definitions +-------------- +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. - 0. Additional Definitions. +1.3. "Contribution" + means Covered Software of a particular Contributor. - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. + For purposes of this definition, "control" means (a) the power, + direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (b) ownership of more + than fifty percent (50%) of the outstanding shares or membership + interests of such entity. + +2. License Grants and Conditions +--------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been advised of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/README.md b/README.md index 87f3e25..3270c32 100644 --- a/README.md +++ b/README.md @@ -179,5 +179,5 @@ See **CONTRIBUTING.md** and **CODE_OF_CONDUCT.md** (coming soon). ## 📜 License -Licensed under **GNU LGPL v3.0**. +Licensed under **Mozilla Public License 2.0**. See [LICENSE](LICENSE) for details. diff --git a/Sources/UntoldEditor/Build/CreateProjectView.swift b/Sources/UntoldEditor/Build/CreateProjectView.swift index 4ac978e..8922aa4 100644 --- a/Sources/UntoldEditor/Build/CreateProjectView.swift +++ b/Sources/UntoldEditor/Build/CreateProjectView.swift @@ -2,9 +2,11 @@ // CreateProjectView.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import SwiftUI diff --git a/Sources/UntoldEditor/Config/EditorFeatureFlags.swift b/Sources/UntoldEditor/Config/EditorFeatureFlags.swift index fb795b1..7b366dd 100644 --- a/Sources/UntoldEditor/Config/EditorFeatureFlags.swift +++ b/Sources/UntoldEditor/Config/EditorFeatureFlags.swift @@ -2,9 +2,11 @@ // EditorFeatureFlags.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation diff --git a/Sources/UntoldEditor/Editor/AssetBrowserView.swift b/Sources/UntoldEditor/Editor/AssetBrowserView.swift index 87b5239..c376527 100644 --- a/Sources/UntoldEditor/Editor/AssetBrowserView.swift +++ b/Sources/UntoldEditor/Editor/AssetBrowserView.swift @@ -2,9 +2,11 @@ // AssetBrowserView.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import SwiftUI import UniformTypeIdentifiers diff --git a/Sources/UntoldEditor/Editor/AssetNodeEditingPolicy.swift b/Sources/UntoldEditor/Editor/AssetNodeEditingPolicy.swift index 635e6c6..6609318 100644 --- a/Sources/UntoldEditor/Editor/AssetNodeEditingPolicy.swift +++ b/Sources/UntoldEditor/Editor/AssetNodeEditingPolicy.swift @@ -2,9 +2,11 @@ // AssetNodeEditingPolicy.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import UntoldEngine diff --git a/Sources/UntoldEditor/Editor/AssetWindowDelegate.swift b/Sources/UntoldEditor/Editor/AssetWindowDelegate.swift index ff81547..499cc33 100644 --- a/Sources/UntoldEditor/Editor/AssetWindowDelegate.swift +++ b/Sources/UntoldEditor/Editor/AssetWindowDelegate.swift @@ -1,3 +1,9 @@ +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + import AppKit final class AssetWindowDelegate: NSObject, NSWindowDelegate { diff --git a/Sources/UntoldEditor/Editor/ComponentEditorForm.swift b/Sources/UntoldEditor/Editor/ComponentEditorForm.swift index c19e231..50ce69d 100644 --- a/Sources/UntoldEditor/Editor/ComponentEditorForm.swift +++ b/Sources/UntoldEditor/Editor/ComponentEditorForm.swift @@ -2,9 +2,11 @@ // ComponentEditorForm.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation import SwiftUI diff --git a/Sources/UntoldEditor/Editor/DemoGalleryView.swift b/Sources/UntoldEditor/Editor/DemoGalleryView.swift index c711f26..b32fc70 100644 --- a/Sources/UntoldEditor/Editor/DemoGalleryView.swift +++ b/Sources/UntoldEditor/Editor/DemoGalleryView.swift @@ -2,9 +2,11 @@ // DemoGalleryView.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import SwiftUI diff --git a/Sources/UntoldEditor/Editor/DemoSceneCatalog.swift b/Sources/UntoldEditor/Editor/DemoSceneCatalog.swift index 6bdab82..ca6aa61 100644 --- a/Sources/UntoldEditor/Editor/DemoSceneCatalog.swift +++ b/Sources/UntoldEditor/Editor/DemoSceneCatalog.swift @@ -2,9 +2,11 @@ // DemoSceneCatalog.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation diff --git a/Sources/UntoldEditor/Editor/EditorController.swift b/Sources/UntoldEditor/Editor/EditorController.swift index b2ba6c5..5e611a9 100644 --- a/Sources/UntoldEditor/Editor/EditorController.swift +++ b/Sources/UntoldEditor/Editor/EditorController.swift @@ -2,9 +2,11 @@ // EditorController.swift // UntoldEngine // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import AppKit import Foundation diff --git a/Sources/UntoldEditor/Editor/EditorSceneView.swift b/Sources/UntoldEditor/Editor/EditorSceneView.swift index 9ce3f49..6af9a40 100644 --- a/Sources/UntoldEditor/Editor/EditorSceneView.swift +++ b/Sources/UntoldEditor/Editor/EditorSceneView.swift @@ -2,9 +2,11 @@ // EditorSceneView.swift // UntoldEngine // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import MetalKit import SwiftUI diff --git a/Sources/UntoldEditor/Editor/EditorScheme.swift b/Sources/UntoldEditor/Editor/EditorScheme.swift index 6fc1c8b..406ac81 100644 --- a/Sources/UntoldEditor/Editor/EditorScheme.swift +++ b/Sources/UntoldEditor/Editor/EditorScheme.swift @@ -2,9 +2,11 @@ // EditorScheme.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import SwiftUI diff --git a/Sources/UntoldEditor/Editor/EditorUndoManager.swift b/Sources/UntoldEditor/Editor/EditorUndoManager.swift index d49e219..aba8654 100644 --- a/Sources/UntoldEditor/Editor/EditorUndoManager.swift +++ b/Sources/UntoldEditor/Editor/EditorUndoManager.swift @@ -2,9 +2,11 @@ // EditorUndoManager.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation diff --git a/Sources/UntoldEditor/Editor/EditorView.swift b/Sources/UntoldEditor/Editor/EditorView.swift index 656888e..0a3b927 100644 --- a/Sources/UntoldEditor/Editor/EditorView.swift +++ b/Sources/UntoldEditor/Editor/EditorView.swift @@ -1,3 +1,9 @@ +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + import Combine import MetalKit import SwiftUI diff --git a/Sources/UntoldEditor/Editor/EngineStatsView.swift b/Sources/UntoldEditor/Editor/EngineStatsView.swift index 4adca03..53bbb97 100644 --- a/Sources/UntoldEditor/Editor/EngineStatsView.swift +++ b/Sources/UntoldEditor/Editor/EngineStatsView.swift @@ -2,9 +2,11 @@ // EngineStatsView.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Combine diff --git a/Sources/UntoldEditor/Editor/EnvironmentView.swift b/Sources/UntoldEditor/Editor/EnvironmentView.swift index f7df0a1..24c90b1 100644 --- a/Sources/UntoldEditor/Editor/EnvironmentView.swift +++ b/Sources/UntoldEditor/Editor/EnvironmentView.swift @@ -2,9 +2,11 @@ // EnvironmentView.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import CShaderTypes import simd diff --git a/Sources/UntoldEditor/Editor/ExplicitClickTextField.swift b/Sources/UntoldEditor/Editor/ExplicitClickTextField.swift index ce07ebc..547c9a8 100644 --- a/Sources/UntoldEditor/Editor/ExplicitClickTextField.swift +++ b/Sources/UntoldEditor/Editor/ExplicitClickTextField.swift @@ -2,9 +2,11 @@ // ExplicitClickTextField.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // #if canImport(AppKit) import AppKit diff --git a/Sources/UntoldEditor/Editor/InspectorView.swift b/Sources/UntoldEditor/Editor/InspectorView.swift index 02a732f..bfcdf71 100644 --- a/Sources/UntoldEditor/Editor/InspectorView.swift +++ b/Sources/UntoldEditor/Editor/InspectorView.swift @@ -2,9 +2,11 @@ // InspectorView.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import simd import SwiftUI diff --git a/Sources/UntoldEditor/Editor/LODComponentEditorView.swift b/Sources/UntoldEditor/Editor/LODComponentEditorView.swift index 8951806..d612b20 100644 --- a/Sources/UntoldEditor/Editor/LODComponentEditorView.swift +++ b/Sources/UntoldEditor/Editor/LODComponentEditorView.swift @@ -2,9 +2,11 @@ // LODComponentEditorView.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import SwiftUI import UntoldEngine diff --git a/Sources/UntoldEditor/Editor/LoadingIndicatorView.swift b/Sources/UntoldEditor/Editor/LoadingIndicatorView.swift index 05fc829..274ffe9 100644 --- a/Sources/UntoldEditor/Editor/LoadingIndicatorView.swift +++ b/Sources/UntoldEditor/Editor/LoadingIndicatorView.swift @@ -2,9 +2,11 @@ // LoadingIndicatorView.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import SwiftUI diff --git a/Sources/UntoldEditor/Editor/LogConsoleView.swift b/Sources/UntoldEditor/Editor/LogConsoleView.swift index 5d69245..1bd40d0 100644 --- a/Sources/UntoldEditor/Editor/LogConsoleView.swift +++ b/Sources/UntoldEditor/Editor/LogConsoleView.swift @@ -2,9 +2,11 @@ // LogConsoleView.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Combine import Foundation diff --git a/Sources/UntoldEditor/Editor/NumericInputView.swift b/Sources/UntoldEditor/Editor/NumericInputView.swift index 5c05f1f..b2e163f 100644 --- a/Sources/UntoldEditor/Editor/NumericInputView.swift +++ b/Sources/UntoldEditor/Editor/NumericInputView.swift @@ -2,9 +2,11 @@ // NumericInputView.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // #if canImport(AppKit) import AppKit diff --git a/Sources/UntoldEditor/Editor/QuickPreviewComponent.swift b/Sources/UntoldEditor/Editor/QuickPreviewComponent.swift index b06f27e..1d7173f 100644 --- a/Sources/UntoldEditor/Editor/QuickPreviewComponent.swift +++ b/Sources/UntoldEditor/Editor/QuickPreviewComponent.swift @@ -2,9 +2,11 @@ // QuickPreviewComponent.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation diff --git a/Sources/UntoldEditor/Editor/SceneHierarchyView.swift b/Sources/UntoldEditor/Editor/SceneHierarchyView.swift index 5a20c9e..77bb2f0 100644 --- a/Sources/UntoldEditor/Editor/SceneHierarchyView.swift +++ b/Sources/UntoldEditor/Editor/SceneHierarchyView.swift @@ -2,9 +2,11 @@ // SceneHierarchyView.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import SwiftUI import UntoldEngine diff --git a/Sources/UntoldEditor/Editor/ScriptComponentInspector.swift b/Sources/UntoldEditor/Editor/ScriptComponentInspector.swift index 49ea031..e2dde8b 100644 --- a/Sources/UntoldEditor/Editor/ScriptComponentInspector.swift +++ b/Sources/UntoldEditor/Editor/ScriptComponentInspector.swift @@ -2,9 +2,11 @@ // ScriptComponentInspector.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // // This file were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Sources/UntoldEditor/Editor/SelectionManager.swift b/Sources/UntoldEditor/Editor/SelectionManager.swift index aacceb9..369954c 100644 --- a/Sources/UntoldEditor/Editor/SelectionManager.swift +++ b/Sources/UntoldEditor/Editor/SelectionManager.swift @@ -2,9 +2,11 @@ // SelectionManager.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation import simd diff --git a/Sources/UntoldEditor/Editor/StarterStreamModels.swift b/Sources/UntoldEditor/Editor/StarterStreamModels.swift index d0a0628..3560e41 100644 --- a/Sources/UntoldEditor/Editor/StarterStreamModels.swift +++ b/Sources/UntoldEditor/Editor/StarterStreamModels.swift @@ -2,9 +2,11 @@ // StarterStreamModels.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation import simd diff --git a/Sources/UntoldEditor/Editor/StaticBatchingView.swift b/Sources/UntoldEditor/Editor/StaticBatchingView.swift index ffb8e6f..8927d8c 100644 --- a/Sources/UntoldEditor/Editor/StaticBatchingView.swift +++ b/Sources/UntoldEditor/Editor/StaticBatchingView.swift @@ -2,9 +2,11 @@ // StaticBatchingView.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import SwiftUI import UntoldEngine diff --git a/Sources/UntoldEditor/Editor/TransformManipulationView.swift b/Sources/UntoldEditor/Editor/TransformManipulationView.swift index 2f9a0a1..0b3a454 100644 --- a/Sources/UntoldEditor/Editor/TransformManipulationView.swift +++ b/Sources/UntoldEditor/Editor/TransformManipulationView.swift @@ -2,9 +2,11 @@ // TransformManipulationView.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation import SwiftUI diff --git a/Sources/UntoldEditor/Renderer/EditorRenderPasses.swift b/Sources/UntoldEditor/Renderer/EditorRenderPasses.swift index beb1906..a5184f1 100644 --- a/Sources/UntoldEditor/Renderer/EditorRenderPasses.swift +++ b/Sources/UntoldEditor/Renderer/EditorRenderPasses.swift @@ -2,9 +2,11 @@ // EditorRenderPasses.swift // UntoldEngine // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import CShaderTypes diff --git a/Sources/UntoldEditor/Renderer/EditorRenderPipeLines.swift b/Sources/UntoldEditor/Renderer/EditorRenderPipeLines.swift index 28475fd..4057561 100644 --- a/Sources/UntoldEditor/Renderer/EditorRenderPipeLines.swift +++ b/Sources/UntoldEditor/Renderer/EditorRenderPipeLines.swift @@ -2,9 +2,11 @@ // EditorRenderPipeLines.swift // UntoldEngine // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import UntoldEngine diff --git a/Sources/UntoldEditor/Renderer/EditorRendererInitializer.swift b/Sources/UntoldEditor/Renderer/EditorRendererInitializer.swift index 9318c53..b248c80 100644 --- a/Sources/UntoldEditor/Renderer/EditorRendererInitializer.swift +++ b/Sources/UntoldEditor/Renderer/EditorRendererInitializer.swift @@ -2,9 +2,11 @@ // EditorRendererInitializer.swift // UntoldEngine // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import CShaderTypes diff --git a/Sources/UntoldEditor/Renderer/EditorUntoldRenderer.swift b/Sources/UntoldEditor/Renderer/EditorUntoldRenderer.swift index 2d62d9a..e7e4c02 100644 --- a/Sources/UntoldEditor/Renderer/EditorUntoldRenderer.swift +++ b/Sources/UntoldEditor/Renderer/EditorUntoldRenderer.swift @@ -2,9 +2,11 @@ // EditorUntoldRenderer.swift // UntoldEngine // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import simd diff --git a/Sources/UntoldEditor/Renderer/EditorUntoldRendererConfig.swift b/Sources/UntoldEditor/Renderer/EditorUntoldRendererConfig.swift index 573cf00..8338f6f 100644 --- a/Sources/UntoldEditor/Renderer/EditorUntoldRendererConfig.swift +++ b/Sources/UntoldEditor/Renderer/EditorUntoldRendererConfig.swift @@ -2,9 +2,11 @@ // EditorUntoldRendererConfig.swift // UntoldEngine // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import UntoldEngine diff --git a/Sources/UntoldEditor/Systems/EditorCameraSystem.swift b/Sources/UntoldEditor/Systems/EditorCameraSystem.swift index b93ec77..2c59bc7 100644 --- a/Sources/UntoldEditor/Systems/EditorCameraSystem.swift +++ b/Sources/UntoldEditor/Systems/EditorCameraSystem.swift @@ -2,9 +2,11 @@ // EditorCameraSystem.swift // UntoldEngine // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import UntoldEngine diff --git a/Sources/UntoldEditor/Systems/EditorInputSystemAppKit.swift b/Sources/UntoldEditor/Systems/EditorInputSystemAppKit.swift index ac4d20d..53af0c9 100644 --- a/Sources/UntoldEditor/Systems/EditorInputSystemAppKit.swift +++ b/Sources/UntoldEditor/Systems/EditorInputSystemAppKit.swift @@ -1,9 +1,11 @@ // // EditorInputSystemAppKit.swift // Untold Engine -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // Copyright © 2024 Untold Engine Studios. All rights reserved. // diff --git a/Sources/UntoldEditor/Systems/EditorInputSystemUIKit.swift b/Sources/UntoldEditor/Systems/EditorInputSystemUIKit.swift index c347682..1433165 100644 --- a/Sources/UntoldEditor/Systems/EditorInputSystemUIKit.swift +++ b/Sources/UntoldEditor/Systems/EditorInputSystemUIKit.swift @@ -1,9 +1,11 @@ // // EditorInputSystemUIKit.swift // Untold Engine -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // Copyright © 2024 Untold Engine Studios. All rights reserved. // diff --git a/Sources/UntoldEditor/Systems/EditorLightingSystem.swift b/Sources/UntoldEditor/Systems/EditorLightingSystem.swift index c8462a4..f045f0f 100644 --- a/Sources/UntoldEditor/Systems/EditorLightingSystem.swift +++ b/Sources/UntoldEditor/Systems/EditorLightingSystem.swift @@ -2,9 +2,11 @@ // EditorLightingSystem.swift // UntoldEngine // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import UntoldEngine diff --git a/Sources/UntoldEditor/Systems/EditorRenderingSystem.swift b/Sources/UntoldEditor/Systems/EditorRenderingSystem.swift index 5b40619..09b6801 100644 --- a/Sources/UntoldEditor/Systems/EditorRenderingSystem.swift +++ b/Sources/UntoldEditor/Systems/EditorRenderingSystem.swift @@ -2,9 +2,11 @@ // EditorRenderingSystem.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import UntoldEngine diff --git a/Sources/UntoldEditor/Systems/GizmoSystem.swift b/Sources/UntoldEditor/Systems/GizmoSystem.swift index 148eae3..3291233 100644 --- a/Sources/UntoldEditor/Systems/GizmoSystem.swift +++ b/Sources/UntoldEditor/Systems/GizmoSystem.swift @@ -2,9 +2,11 @@ // GizmoSystem.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation diff --git a/Sources/UntoldEditor/Systems/HotReloadingSystem.swift b/Sources/UntoldEditor/Systems/HotReloadingSystem.swift index 469c66c..58eeff4 100644 --- a/Sources/UntoldEditor/Systems/HotReloadingSystem.swift +++ b/Sources/UntoldEditor/Systems/HotReloadingSystem.swift @@ -1,9 +1,11 @@ // HotReloadingSystem.swift // UntoldEngine // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // Copyright © 2024 Untold Engine Studios. All rights reserved. // diff --git a/Sources/UntoldEditor/Systems/ScriptProjectManager.swift b/Sources/UntoldEditor/Systems/ScriptProjectManager.swift index aeead25..c03a3a9 100644 --- a/Sources/UntoldEditor/Systems/ScriptProjectManager.swift +++ b/Sources/UntoldEditor/Systems/ScriptProjectManager.swift @@ -2,9 +2,11 @@ // ScriptProjectManager.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation @@ -259,8 +261,11 @@ class ScriptProjectManager { // GenerateScripts.swift // USC Script Generator // - // Copyright (C) Untold Engine Studios - // Licensed under the GNU LGPL v3.0 or later. + // Copyright (C) Untold Engine Studios + // + // This Source Code Form is subject to the terms of the Mozilla Public + // License, v. 2.0. If a copy of the MPL was not distributed with this + // file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation @@ -300,8 +305,11 @@ class ScriptProjectManager { // \(name).swift // USC Script // - // Copyright (C) Untold Engine Studios - // Licensed under the GNU LGPL v3.0 or later. + // Copyright (C) Untold Engine Studios + // + // This Source Code Form is subject to the terms of the Mozilla Public + // License, v. 2.0. If a copy of the MPL was not distributed with this + // file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation diff --git a/Sources/UntoldEditor/Systems/VisualDebugger.swift b/Sources/UntoldEditor/Systems/VisualDebugger.swift index 0af95cf..bbe2c2c 100644 --- a/Sources/UntoldEditor/Systems/VisualDebugger.swift +++ b/Sources/UntoldEditor/Systems/VisualDebugger.swift @@ -2,9 +2,11 @@ // VisualDebugger.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation diff --git a/Sources/UntoldEditor/Utils/EditorFuncUtils.swift b/Sources/UntoldEditor/Utils/EditorFuncUtils.swift index 15ef820..49cdcd6 100644 --- a/Sources/UntoldEditor/Utils/EditorFuncUtils.swift +++ b/Sources/UntoldEditor/Utils/EditorFuncUtils.swift @@ -2,9 +2,11 @@ // EditorFuncUtils.swift // // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation diff --git a/Sources/UntoldEditor/Utils/EditorGlobals.swift b/Sources/UntoldEditor/Utils/EditorGlobals.swift index 476ef00..93a8ca6 100644 --- a/Sources/UntoldEditor/Utils/EditorGlobals.swift +++ b/Sources/UntoldEditor/Utils/EditorGlobals.swift @@ -2,9 +2,11 @@ // Globals.swift // UntoldEngine // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import Foundation import UntoldEngine diff --git a/Sources/UntoldEditor/Utils/UntoldMaterialPersistence.swift b/Sources/UntoldEditor/Utils/UntoldMaterialPersistence.swift index 618a2b9..cd520f5 100644 --- a/Sources/UntoldEditor/Utils/UntoldMaterialPersistence.swift +++ b/Sources/UntoldEditor/Utils/UntoldMaterialPersistence.swift @@ -1,3 +1,9 @@ +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + import CryptoKit import Foundation import UntoldEngine diff --git a/Sources/UntoldEditor/main.swift b/Sources/UntoldEditor/main.swift index bdedf4e..ee030af 100644 --- a/Sources/UntoldEditor/main.swift +++ b/Sources/UntoldEditor/main.swift @@ -2,9 +2,11 @@ // main.swift // UntoldEngine // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import AppKit diff --git a/Tests/UntoldEditorTests/AssetBrowserViewTests.swift b/Tests/UntoldEditorTests/AssetBrowserViewTests.swift index d0127df..e401ffb 100644 --- a/Tests/UntoldEditorTests/AssetBrowserViewTests.swift +++ b/Tests/UntoldEditorTests/AssetBrowserViewTests.swift @@ -2,9 +2,11 @@ // AssetBrowserViewTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/AssetNodeEditingPolicyTests.swift b/Tests/UntoldEditorTests/AssetNodeEditingPolicyTests.swift index 5e52268..15aa84a 100644 --- a/Tests/UntoldEditorTests/AssetNodeEditingPolicyTests.swift +++ b/Tests/UntoldEditorTests/AssetNodeEditingPolicyTests.swift @@ -2,9 +2,11 @@ // AssetNodeEditingPolicyTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import simd diff --git a/Tests/UntoldEditorTests/ComponentEditorFormTests.swift b/Tests/UntoldEditorTests/ComponentEditorFormTests.swift index e421902..f0fc7c6 100644 --- a/Tests/UntoldEditorTests/ComponentEditorFormTests.swift +++ b/Tests/UntoldEditorTests/ComponentEditorFormTests.swift @@ -2,9 +2,11 @@ // ComponentEditorFormTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/CreateProjectViewTests.swift b/Tests/UntoldEditorTests/CreateProjectViewTests.swift index 4b811c8..28f39cf 100644 --- a/Tests/UntoldEditorTests/CreateProjectViewTests.swift +++ b/Tests/UntoldEditorTests/CreateProjectViewTests.swift @@ -2,9 +2,11 @@ // CreateProjectViewTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/DemoGalleryViewTests.swift b/Tests/UntoldEditorTests/DemoGalleryViewTests.swift index f98beb8..eebf89d 100644 --- a/Tests/UntoldEditorTests/DemoGalleryViewTests.swift +++ b/Tests/UntoldEditorTests/DemoGalleryViewTests.swift @@ -2,9 +2,11 @@ // DemoGalleryViewTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import SwiftUI diff --git a/Tests/UntoldEditorTests/EditorCameraSystemTests.swift b/Tests/UntoldEditorTests/EditorCameraSystemTests.swift index 9a625cc..df44afb 100644 --- a/Tests/UntoldEditorTests/EditorCameraSystemTests.swift +++ b/Tests/UntoldEditorTests/EditorCameraSystemTests.swift @@ -2,9 +2,11 @@ // EditorCameraSystemTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/EditorControllerTests.swift b/Tests/UntoldEditorTests/EditorControllerTests.swift index 96dc83a..983e3ac 100644 --- a/Tests/UntoldEditorTests/EditorControllerTests.swift +++ b/Tests/UntoldEditorTests/EditorControllerTests.swift @@ -2,9 +2,11 @@ // EditorControllerTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/EditorFuncUtilsTests.swift b/Tests/UntoldEditorTests/EditorFuncUtilsTests.swift index 26fb99e..a4b7ba8 100644 --- a/Tests/UntoldEditorTests/EditorFuncUtilsTests.swift +++ b/Tests/UntoldEditorTests/EditorFuncUtilsTests.swift @@ -2,9 +2,11 @@ // EditorFuncUtilsTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/EditorRenderPassesTests.swift b/Tests/UntoldEditorTests/EditorRenderPassesTests.swift index 7231ffe..e62d60c 100644 --- a/Tests/UntoldEditorTests/EditorRenderPassesTests.swift +++ b/Tests/UntoldEditorTests/EditorRenderPassesTests.swift @@ -2,9 +2,11 @@ // EditorRenderPassesTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/EditorRenderPipeLinesTests.swift b/Tests/UntoldEditorTests/EditorRenderPipeLinesTests.swift index 9d005b2..dff1343 100644 --- a/Tests/UntoldEditorTests/EditorRenderPipeLinesTests.swift +++ b/Tests/UntoldEditorTests/EditorRenderPipeLinesTests.swift @@ -2,9 +2,11 @@ // EditorRenderPipeLinesTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/EditorRendererInitializerTests.swift b/Tests/UntoldEditorTests/EditorRendererInitializerTests.swift index bc3217e..5ae8143 100644 --- a/Tests/UntoldEditorTests/EditorRendererInitializerTests.swift +++ b/Tests/UntoldEditorTests/EditorRendererInitializerTests.swift @@ -2,9 +2,11 @@ // EditorRendererInitializerTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/EditorRenderingSystemTests.swift b/Tests/UntoldEditorTests/EditorRenderingSystemTests.swift index 6efda4f..c2f44f1 100644 --- a/Tests/UntoldEditorTests/EditorRenderingSystemTests.swift +++ b/Tests/UntoldEditorTests/EditorRenderingSystemTests.swift @@ -2,9 +2,11 @@ // EditorRenderingSystemTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // @testable import UntoldEditor diff --git a/Tests/UntoldEditorTests/EditorUndoManagerTests.swift b/Tests/UntoldEditorTests/EditorUndoManagerTests.swift index a657401..c57da62 100644 --- a/Tests/UntoldEditorTests/EditorUndoManagerTests.swift +++ b/Tests/UntoldEditorTests/EditorUndoManagerTests.swift @@ -2,9 +2,11 @@ // EditorUndoManagerTests.swift // UntoldEditorTests // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // import simd diff --git a/Tests/UntoldEditorTests/EditorUntoldRendererTests.swift b/Tests/UntoldEditorTests/EditorUntoldRendererTests.swift index b2bfb91..bec8135 100644 --- a/Tests/UntoldEditorTests/EditorUntoldRendererTests.swift +++ b/Tests/UntoldEditorTests/EditorUntoldRendererTests.swift @@ -2,9 +2,11 @@ // EditorUntoldRendererTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/EnvironmentViewTests.swift b/Tests/UntoldEditorTests/EnvironmentViewTests.swift index 342d5f5..c0de821 100644 --- a/Tests/UntoldEditorTests/EnvironmentViewTests.swift +++ b/Tests/UntoldEditorTests/EnvironmentViewTests.swift @@ -2,9 +2,11 @@ // EnvironmentViewTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/FindSceneCameraTest.swift b/Tests/UntoldEditorTests/FindSceneCameraTest.swift index 4e9b8bb..d7af686 100644 --- a/Tests/UntoldEditorTests/FindSceneCameraTest.swift +++ b/Tests/UntoldEditorTests/FindSceneCameraTest.swift @@ -2,9 +2,11 @@ // FindSceneCameraTest.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/GizmoSystemTest.swift b/Tests/UntoldEditorTests/GizmoSystemTest.swift index 8bc71cf..b2e0b4e 100644 --- a/Tests/UntoldEditorTests/GizmoSystemTest.swift +++ b/Tests/UntoldEditorTests/GizmoSystemTest.swift @@ -2,9 +2,11 @@ // GizmoSystemTest.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/InputSystemCoreTests.swift b/Tests/UntoldEditorTests/InputSystemCoreTests.swift index 93db31d..52a1484 100644 --- a/Tests/UntoldEditorTests/InputSystemCoreTests.swift +++ b/Tests/UntoldEditorTests/InputSystemCoreTests.swift @@ -2,9 +2,11 @@ // InputSystemCoreTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/InspectorViewTests.swift b/Tests/UntoldEditorTests/InspectorViewTests.swift index a185e69..561f3c0 100644 --- a/Tests/UntoldEditorTests/InspectorViewTests.swift +++ b/Tests/UntoldEditorTests/InspectorViewTests.swift @@ -2,9 +2,11 @@ // InspectorViewTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/LightDebugMeshTest.swift b/Tests/UntoldEditorTests/LightDebugMeshTest.swift index 32a200d..fa29e28 100644 --- a/Tests/UntoldEditorTests/LightDebugMeshTest.swift +++ b/Tests/UntoldEditorTests/LightDebugMeshTest.swift @@ -2,9 +2,11 @@ // LightDebugMeshTest.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/LogConsoleViewTests.swift b/Tests/UntoldEditorTests/LogConsoleViewTests.swift index d6aeff9..b555f0a 100644 --- a/Tests/UntoldEditorTests/LogConsoleViewTests.swift +++ b/Tests/UntoldEditorTests/LogConsoleViewTests.swift @@ -2,9 +2,11 @@ // LogConsoleViewTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/NumericInputTest.swift b/Tests/UntoldEditorTests/NumericInputTest.swift index 428c747..3f89f52 100644 --- a/Tests/UntoldEditorTests/NumericInputTest.swift +++ b/Tests/UntoldEditorTests/NumericInputTest.swift @@ -2,9 +2,11 @@ // NumericInputTest.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/ParentingSerializationTests.swift b/Tests/UntoldEditorTests/ParentingSerializationTests.swift index 366d3fa..9429fca 100644 --- a/Tests/UntoldEditorTests/ParentingSerializationTests.swift +++ b/Tests/UntoldEditorTests/ParentingSerializationTests.swift @@ -2,9 +2,11 @@ // ParentingSerializationTests.swift // UntoldEditor Tests // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/SceneHierarchyViewTests.swift b/Tests/UntoldEditorTests/SceneHierarchyViewTests.swift index 9a8ae73..28b0e68 100644 --- a/Tests/UntoldEditorTests/SceneHierarchyViewTests.swift +++ b/Tests/UntoldEditorTests/SceneHierarchyViewTests.swift @@ -2,9 +2,11 @@ // SceneHierarchyViewTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/ScriptProjectManagerTests.swift b/Tests/UntoldEditorTests/ScriptProjectManagerTests.swift index 87076e1..6de3735 100644 --- a/Tests/UntoldEditorTests/ScriptProjectManagerTests.swift +++ b/Tests/UntoldEditorTests/ScriptProjectManagerTests.swift @@ -2,9 +2,11 @@ // ScriptProjectManagerTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/SelectionManagerTests.swift b/Tests/UntoldEditorTests/SelectionManagerTests.swift index c96bd41..3a2f441 100644 --- a/Tests/UntoldEditorTests/SelectionManagerTests.swift +++ b/Tests/UntoldEditorTests/SelectionManagerTests.swift @@ -2,9 +2,11 @@ // SelectionManagerTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/ToolbarViewTests.swift b/Tests/UntoldEditorTests/ToolbarViewTests.swift index d309a75..bf8d583 100644 --- a/Tests/UntoldEditorTests/ToolbarViewTests.swift +++ b/Tests/UntoldEditorTests/ToolbarViewTests.swift @@ -2,9 +2,11 @@ // ToolbarViewTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/Tests/UntoldEditorTests/TransformManipulationViewTests.swift b/Tests/UntoldEditorTests/TransformManipulationViewTests.swift index 302983b..8dc02eb 100644 --- a/Tests/UntoldEditorTests/TransformManipulationViewTests.swift +++ b/Tests/UntoldEditorTests/TransformManipulationViewTests.swift @@ -2,9 +2,11 @@ // TransformManipulationViewTests.swift // UntoldEditor // -// Copyright (C) Untold Engine Studios -// Licensed under the GNU LGPL v3.0 or later. -// See the LICENSE file or for details. +// Copyright (C) Untold Engine Studios +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. // These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. diff --git a/scripts/changecopyright.sh b/scripts/changecopyright.sh index 7b293c8..4df15a0 100755 --- a/scripts/changecopyright.sh +++ b/scripts/changecopyright.sh @@ -11,7 +11,7 @@ # replaces any line containing “Created by” with the standard # copyright and license notice. This helps ensure all source # files remain consistent with the Untold Engine’s licensing -# policy (GNU LGPL v3.0 or later). +# policy (Mozilla Public License 2.0). # # How it works: # - Uses `find` to locate all `.swift` files. @@ -34,5 +34,4 @@ YEAR=$(date +"%Y") -find . -name "*.swift" -type f -exec sed -i '' "1,/Created by/s#//.*Created by.*#// Copyright (C) Untold Engine Studios\n// Licensed under the GNU LGPL v3.0 or later.\n// See the LICENSE file or for details.#" {} + - +find . -name "*.swift" -type f -exec sed -i '' "1,/Created by/s#//.*Created by.*#// Copyright (C) Untold Engine Studios\n//\n// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at https://mozilla.org/MPL/2.0/.#" {} + From 81b1a0d47c584e3eae796fbc1a56314940277fb6 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Mon, 24 Aug 2026 14:55:46 -0700 Subject: [PATCH 02/17] [Patch] Fixed directional light rotation - gizmo --- .../UntoldEditor/Editor/InspectorView.swift | 1 + .../Renderer/EditorUntoldRenderer.swift | 4 +++ .../UntoldEditor/Systems/GizmoSystem.swift | 26 +++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/Sources/UntoldEditor/Editor/InspectorView.swift b/Sources/UntoldEditor/Editor/InspectorView.swift index bfcdf71..6ba9848 100644 --- a/Sources/UntoldEditor/Editor/InspectorView.swift +++ b/Sources/UntoldEditor/Editor/InspectorView.swift @@ -1202,6 +1202,7 @@ struct TransformationEditorView: View { let before = EditorTransformSnapshot(entityId: entityId) handleTransformChange() applyAxisRotations(entityId: entityId, axis: newOrientation) + syncLightDirectionHandleToActiveLight(entityId: entityId) EditorUndoManager.shared.registerTransformChange( entityId: entityId, before: before, diff --git a/Sources/UntoldEditor/Renderer/EditorUntoldRenderer.swift b/Sources/UntoldEditor/Renderer/EditorUntoldRenderer.swift index e7e4c02..5aec48e 100644 --- a/Sources/UntoldEditor/Renderer/EditorUntoldRenderer.swift +++ b/Sources/UntoldEditor/Renderer/EditorUntoldRenderer.swift @@ -142,6 +142,7 @@ extension UntoldRenderer { sensitivity: 100.0 ) applyGizmoRotationDelta(entityId: activeEntity, axis: axis, degrees: -angle * 10) + syncLightDirectionHandleToActiveLight(entityId: activeEntity) refreshInspector() case (.rotate, .y) where InputSystem.shared.mouseActive: @@ -158,6 +159,7 @@ extension UntoldRenderer { sensitivity: 100.0 ) applyGizmoRotationDelta(entityId: activeEntity, axis: axis, degrees: angle * 10) + syncLightDirectionHandleToActiveLight(entityId: activeEntity) refreshInspector() case (.rotate, .z) where InputSystem.shared.mouseActive: @@ -174,6 +176,7 @@ extension UntoldRenderer { sensitivity: 100.0 ) applyGizmoRotationDelta(entityId: activeEntity, axis: axis, degrees: angle * 10) + syncLightDirectionHandleToActiveLight(entityId: activeEntity) refreshInspector() // MARK: - Scale @@ -291,6 +294,7 @@ extension UntoldRenderer { localTransformComponent.rotationY = euler.yaw localTransformComponent.rotationZ = euler.roll translateTo(entityId: activeEntity, position: localTransformComponent.position) + refreshInspector() default: break diff --git a/Sources/UntoldEditor/Systems/GizmoSystem.swift b/Sources/UntoldEditor/Systems/GizmoSystem.swift index 3291233..30078bc 100644 --- a/Sources/UntoldEditor/Systems/GizmoSystem.swift +++ b/Sources/UntoldEditor/Systems/GizmoSystem.swift @@ -407,6 +407,32 @@ private func initialLightDirectionHandleOffset() -> simd_float3 { return handleDirection * abs(GizmoDimensions.directionHandleOffsetY) } +/// Repositions the light direction handle (and its hit proxy) to match the given light +/// entity's current orientation. Call this after changing a light's rotation through any +/// path other than dragging the handle itself (e.g. editing the Orientation fields in the +/// Inspector), so the gizmo doesn't go stale relative to the light it represents. +func syncLightDirectionHandleToActiveLight(entityId: EntityID) { + guard entityId != .invalid, + entityId == activeEntity, + gizmoActive, + parentEntityIdGizmo != .invalid, + hasComponent(entityId: entityId, componentType: LightComponent.self) + else { + return + } + + let localPosition = initialLightDirectionHandleOffset() + + for handle in getEntityChildren(parentId: parentEntityIdGizmo) { + guard let handleComponent = scene.get(component: GizmoHandleComponent.self, for: handle), + handleComponent.mode == .lightRotate, handleComponent.axis == .none + else { + continue + } + translateTo(entityId: handle, position: localPosition) + } +} + private func rotationFromYAxis(to direction: simd_float3) -> (angle: Float, axis: simd_float3)? { let up = simd_float3(0.0, 1.0, 0.0) let dirLength = simd_length(direction) From 41df956e33d7818a3ad3b182339259093eb8dad6 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Mon, 24 Aug 2026 15:25:54 -0700 Subject: [PATCH 03/17] [Patch] Fixed parent-child selection in viewport --- .../Systems/EditorInputSystemAppKit.swift | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/Sources/UntoldEditor/Systems/EditorInputSystemAppKit.swift b/Sources/UntoldEditor/Systems/EditorInputSystemAppKit.swift index 53af0c9..e790052 100644 --- a/Sources/UntoldEditor/Systems/EditorInputSystemAppKit.swift +++ b/Sources/UntoldEditor/Systems/EditorInputSystemAppKit.swift @@ -258,19 +258,24 @@ if hasComponent(entityId: entityId, componentType: GizmoComponent.self) { activeEntity = selectableTransformEntity(for: entityId) selectionDelegate?.didSelectEntity(entityId) - } else if keyState.shiftPressed, - let rayContext, + } else if keyState.commandPressed { + // Cmd+click selects the top-level asset root, for moving/rotating + // the whole imported group at once. + let transformEntityId = editableAssetRootEntity(for: entityId) + activeEntity = selectableTransformEntity(for: transformEntityId) + selectionDelegate?.didSelectEntity(entityId) + } else if let rayContext, let meshIndex = pickMeshIndexForEntity( entityId: entityId, rayOrigin: rayContext.rayOrigin, rayDirection: rayContext.rayDirection ) { + // Default: click selects the specific child mesh under the cursor. activeEntity = selectableTransformEntity(for: entityId) selectionDelegate?.didInspectMesh(entityId, meshIndex: meshIndex) } else { - let transformEntityId = editableAssetRootEntity(for: entityId) - activeEntity = selectableTransformEntity(for: transformEntityId) + activeEntity = selectableTransformEntity(for: entityId) selectionDelegate?.didSelectEntity(entityId) } selectionDelegate?.resetActiveAxis() @@ -551,6 +556,13 @@ } else { keyState.ctrlPressed = false } + + // Command key + if event.modifierFlags.contains(.command) { + keyState.commandPressed = true + } else { + keyState.commandPressed = false + } } private func raycastContext(currentLocation: NSPoint, view: NSView) -> (rayOrigin: simd_float3, rayDirection: simd_float3)? { From 1c17fdd37fe45f18df9a79736cb15fee26a3e974 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Mon, 24 Aug 2026 15:33:30 -0700 Subject: [PATCH 04/17] [Patch] Fixed the active directional light --- Sources/UntoldEditor/Editor/EditorView.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Sources/UntoldEditor/Editor/EditorView.swift b/Sources/UntoldEditor/Editor/EditorView.swift index 0a3b927..c2c2be8 100644 --- a/Sources/UntoldEditor/Editor/EditorView.swift +++ b/Sources/UntoldEditor/Editor/EditorView.swift @@ -1156,6 +1156,13 @@ public struct EditorView: View { let light = createEntity() setEntityName(entityId: light, name: "Directional Light") createDirLight(entityId: light) + // destroyAllEntities() above only marks the previous scene's entities for deferred + // destruction; the actual cleanup (which nulls activeDirectionalLight if it pointed + // at the old light) doesn't run until finalizePendingDestroys() later this frame. + // createDirLight()'s "activate only if nil" check can therefore see a stale non-nil + // pointer here and skip activating this new light. Force it active explicitly so a + // freshly cleared scene never ends up with an inactive (shadow-less) default sun. + setDirectionalLight(.active(light)) let sceneCamera = findSceneCamera() From ea5ed67e2562ad876399f578398beb6d2bbf6927 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Tue, 25 Aug 2026 05:21:23 -0700 Subject: [PATCH 05/17] [Patch] Re-added Import textures features --- .../UntoldEditor/Editor/InspectorView.swift | 62 ++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/Sources/UntoldEditor/Editor/InspectorView.swift b/Sources/UntoldEditor/Editor/InspectorView.swift index 6ba9848..979a8ed 100644 --- a/Sources/UntoldEditor/Editor/InspectorView.swift +++ b/Sources/UntoldEditor/Editor/InspectorView.swift @@ -10,6 +10,7 @@ // import simd import SwiftUI +import UniformTypeIdentifiers import UntoldEngine public struct ComponentOption_Editor: Identifiable { @@ -37,6 +38,45 @@ func openFilePicker() -> URL? { return panel.runModal() == .OK ? panel.urls.first : nil } +private func pickTextureImageFile() -> URL? { + let panel = NSOpenPanel() + panel.allowsMultipleSelection = false + panel.canChooseDirectories = false + panel.canChooseFiles = true + panel.allowedContentTypes = [.png, .jpeg, .tiff] + + return panel.runModal() == .OK ? panel.urls.first : nil +} + +/// Copies an externally-picked texture image into the project's Materials asset folder, +/// mirroring the single-file fallback of the Asset Browser's own Materials import (a +/// subfolder named after the file, matching what updateMaterialTexture(path:) expects to +/// resolve via LoadingSystem's resource search paths). +private func importTextureAsset(from sourceURL: URL) -> URL? { + guard let basePath = assetBasePath else { + Logger.logWarning(message: "[InspectorView] assetBasePath is not set; cannot import texture \(sourceURL.lastPathComponent).") + return nil + } + + let fm = FileManager.default + let materialsRoot = basePath.appendingPathComponent("Materials", isDirectory: true) + let baseName = sourceURL.deletingPathExtension().lastPathComponent + let materialFolder = materialsRoot.appendingPathComponent(baseName, isDirectory: true) + let destFile = materialFolder.appendingPathComponent(sourceURL.lastPathComponent) + + do { + try fm.createDirectory(at: materialFolder, withIntermediateDirectories: true) + if fm.fileExists(atPath: destFile.path) { + try fm.removeItem(at: destFile) + } + try fm.copyItem(at: sourceURL, to: destFile) + return destFile + } catch { + Logger.logWarning(message: "[InspectorView] Failed to import texture \(sourceURL.lastPathComponent): \(error.localizedDescription)") + return nil + } +} + private func onAddMesh_Editor(entityId: EntityID, url: URL) { let filename = url.deletingPathExtension().lastPathComponent let withExtension = url.pathExtension @@ -318,12 +358,16 @@ struct InspectorView: View { if let inspectedMesh = selectionManager.inspectedMesh, inspectedMesh.entityId == entityId { + // inspectMesh() (see SelectionManager) only ever sets inspectedMesh + // alongside selectedEntity on the same entity, so reaching this + // block means entityId genuinely is the active selection, not just + // a passive peek — safe (and expected) to be fully editable here. RenderingEditorView( entityId: entityId, asset: selectedAsset, refreshView: refreshView, meshIndex: inspectedMesh.meshIndex, - inspectionOnly: true + inspectionOnly: false ) Divider() } @@ -334,7 +378,16 @@ struct InspectorView: View { editor_availableComponents: availableComponents_Editor ) - let sortedComponents = sortEntityComponents(componentOption_Editor: mergedComponents) + // The inspectedMesh banner above already renders this entity's + // Render Component (with the correct submesh index) when it targets + // this same entity. Skip the generic entry here so Material + // Properties / Wrap Mode don't render twice. + let isInspectedMeshEntity = selectionManager.inspectedMesh?.entityId == entityId + let visibleComponents = isInspectedMeshEntity + ? mergedComponents.filter { $0.key != ObjectIdentifier(RenderComponent.self) } + : mergedComponents + + let sortedComponents = sortEntityComponents(componentOption_Editor: visibleComponents) // Static Batching Section - Show for any entity with renderable hierarchy if EditorAuthoringMode.sceneCompositionOnly == false, isDerivedAssetNode(entityId) == false { @@ -698,6 +751,11 @@ struct RenderingEditorView: View { if asset?.category == "Materials", let path = asset?.path { updateMaterialTexture(entityId: entityId, textureType: type, path: path, meshIndex: meshIndex) refreshView() + } else if let pickedURL = pickTextureImageFile(), + let importedURL = importTextureAsset(from: pickedURL) + { + updateMaterialTexture(entityId: entityId, textureType: type, path: importedURL, meshIndex: meshIndex) + refreshView() } }) { if let image { From bd0308e3af463b9c94f53e96598abad3460277ad Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Wed, 26 Aug 2026 21:44:38 -0700 Subject: [PATCH 06/17] [Patch] Allow exporting blender files --- .../Editor/AssetBrowserView.swift | 6 ++--- .../Editor/EditorController.swift | 27 +++++++++++++++++++ Sources/UntoldEditor/Editor/EditorView.swift | 8 +++--- .../Editor/QuickPreviewComponent.swift | 8 +++--- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/Sources/UntoldEditor/Editor/AssetBrowserView.swift b/Sources/UntoldEditor/Editor/AssetBrowserView.swift index c376527..6beb166 100644 --- a/Sources/UntoldEditor/Editor/AssetBrowserView.swift +++ b/Sources/UntoldEditor/Editor/AssetBrowserView.swift @@ -14,7 +14,7 @@ import UntoldEngine private let runtimeAssetExtension = "untold" private let runtimeTextureFolderNames = ["Textures", "textures"] -private let sourceAssetExtensions: Set = ["usd", "usda", "usdc", "usdz"] +private let sourceAssetExtensions: Set = ["usd", "usda", "usdc", "usdz", "blend"] private let streamModelResourceFolderNames = ["tile_exports", "tile_export", "Textures", "textures"] struct RuntimeExportRequest: Identifiable, Equatable { @@ -1027,7 +1027,7 @@ struct AssetBrowserView: View { .font(.title2) .bold() - Text("This USD file needs to be converted to Untold Engine's .untold runtime format before it can be added to your project.") + Text("This USD or .blend file needs to be converted to Untold Engine's .untold runtime format before it can be added to your project.") .fixedSize(horizontal: false, vertical: true) VStack(alignment: .leading, spacing: 6) { @@ -1277,7 +1277,7 @@ struct AssetBrowserView: View { .font(.title2) .bold() - Text("This USD file will be partitioned into tile payloads and a manifest JSON using export-untold-tiles.") + Text("This USD or .blend file will be partitioned into tile payloads and a manifest JSON using export-untold-tiles.") .fixedSize(horizontal: false, vertical: true) VStack(alignment: .leading, spacing: 6) { diff --git a/Sources/UntoldEditor/Editor/EditorController.swift b/Sources/UntoldEditor/Editor/EditorController.swift index 5e611a9..bf797f4 100644 --- a/Sources/UntoldEditor/Editor/EditorController.swift +++ b/Sources/UntoldEditor/Editor/EditorController.swift @@ -79,6 +79,15 @@ class EditorController: SelectionDelegate, ObservableObject { @Published var activeAxis: TransformAxis = .none @Published var currentSceneURL: URL? + /// refreshInspector() can be called once per rendered frame while a gizmo is being + /// dragged (see EditorUntoldRenderer.handleSceneInput). Each call forces SwiftUI to + /// re-diff the whole Inspector, which is far too expensive to do 60 times a second, + /// so calls are throttled to minInspectorRefreshInterval with a trailing edge to + /// guarantee the final value is always reflected once dragging settles. + private var lastInspectorRefreshTime: TimeInterval = 0 + private var pendingInspectorRefresh: DispatchWorkItem? + private let minInspectorRefreshInterval: TimeInterval = 1.0 / 15.0 + init(selectionManager: SelectionManager) { self.selectionManager = selectionManager selectionDelegate = self @@ -108,6 +117,24 @@ class EditorController: SelectionDelegate, ObservableObject { } func refreshInspector() { + pendingInspectorRefresh?.cancel() + + let now = Date().timeIntervalSinceReferenceDate + let elapsed = now - lastInspectorRefreshTime + guard elapsed >= minInspectorRefreshInterval else { + // Too soon since the last refresh — schedule a trailing-edge refresh so the + // Inspector still catches up to the latest value once the burst quiets down. + let workItem = DispatchWorkItem { [weak self] in + guard let self else { return } + lastInspectorRefreshTime = Date().timeIntervalSinceReferenceDate + selectionManager.objectWillChange.send() + } + pendingInspectorRefresh = workItem + DispatchQueue.main.asyncAfter(deadline: .now() + (minInspectorRefreshInterval - elapsed), execute: workItem) + return + } + + lastInspectorRefreshTime = now DispatchQueue.main.async { self.selectionManager.objectWillChange.send() } diff --git a/Sources/UntoldEditor/Editor/EditorView.swift b/Sources/UntoldEditor/Editor/EditorView.swift index c2c2be8..d422a65 100644 --- a/Sources/UntoldEditor/Editor/EditorView.swift +++ b/Sources/UntoldEditor/Editor/EditorView.swift @@ -1904,7 +1904,7 @@ public struct EditorView: View { let fileName = fileURL.deletingPathExtension().lastPathComponent pendingQuickPreviewLoadsInExplore = fromExploreMode - if isUSDSourceAsset(fileURL) { + if isConvertibleSourceAsset(fileURL) { queueQuickPreviewRuntimeExport(sourceURL: fileURL) return } @@ -2070,8 +2070,8 @@ public struct EditorView: View { } } - private func isUSDSourceAsset(_ url: URL) -> Bool { - ["usd", "usda", "usdc", "usdz"].contains(url.pathExtension.lowercased()) + private func isConvertibleSourceAsset(_ url: URL) -> Bool { + ["usd", "usda", "usdc", "usdz", "blend"].contains(url.pathExtension.lowercased()) } private func queueQuickPreviewRuntimeExport(sourceURL: URL) { @@ -2092,7 +2092,7 @@ public struct EditorView: View { .font(.title2) .bold() - Text("This USD file needs to be converted to Untold Engine's .untold runtime format before it can be previewed.") + Text("This USD or .blend file needs to be converted to Untold Engine's .untold runtime format before it can be previewed.") .fixedSize(horizontal: false, vertical: true) VStack(alignment: .leading, spacing: 6) { diff --git a/Sources/UntoldEditor/Editor/QuickPreviewComponent.swift b/Sources/UntoldEditor/Editor/QuickPreviewComponent.swift index 1d7173f..ec24341 100644 --- a/Sources/UntoldEditor/Editor/QuickPreviewComponent.swift +++ b/Sources/UntoldEditor/Editor/QuickPreviewComponent.swift @@ -21,7 +21,7 @@ enum QuickPreviewImportMode: String, CaseIterable { var menuTitle: String { switch self { case .untoldAsset: - return "Load Untold Asset (.untold, USD)" + return "Load Untold Asset (.untold, USD, .blend)" case .tiledScene: return "Load Tiled Stream (.json)" case .gaussian: @@ -43,7 +43,7 @@ enum QuickPreviewImportMode: String, CaseIterable { var filePickerTitle: String { switch self { case .untoldAsset: - return "Load Preview - Select Untold or USD Asset" + return "Load Preview - Select Untold, USD, or Blend Asset" case .tiledScene: return "Load Preview - Select Tiled Stream Manifest" case .gaussian: @@ -54,7 +54,7 @@ enum QuickPreviewImportMode: String, CaseIterable { var filePickerMessage: String { switch self { case .untoldAsset: - return "Select an Untold runtime asset or USD source asset to preview without creating a project" + return "Select an Untold runtime asset, USD source asset, or .blend file to preview without creating a project" case .tiledScene: return "Select a tiled stream manifest to preview without creating a project" case .gaussian: @@ -65,7 +65,7 @@ enum QuickPreviewImportMode: String, CaseIterable { var allowedContentTypes: [UTType] { switch self { case .untoldAsset: - return ["untold", "usd", "usda", "usdc", "usdz"].compactMap { UTType(filenameExtension: $0) } + return ["untold", "usd", "usda", "usdc", "usdz", "blend"].compactMap { UTType(filenameExtension: $0) } case .tiledScene: return [.json] case .gaussian: From d460c63e43582fdd60a0da185316e5ab772bb2b1 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Sat, 29 Aug 2026 06:29:04 -0700 Subject: [PATCH 07/17] [Feature] Add Height/POM material channel to Inspector --- .../UntoldEditor/Editor/InspectorView.swift | 126 ++++++++++++++++++ .../UntoldEditor/Utils/EditorFuncUtils.swift | 2 + 2 files changed, 128 insertions(+) diff --git a/Sources/UntoldEditor/Editor/InspectorView.swift b/Sources/UntoldEditor/Editor/InspectorView.swift index 979a8ed..6cd0981 100644 --- a/Sources/UntoldEditor/Editor/InspectorView.swift +++ b/Sources/UntoldEditor/Editor/InspectorView.swift @@ -908,6 +908,132 @@ struct RenderingEditorView: View { } } + HStack { + // Height Scale Input — total Parallax Occlusion Mapping ray-march depth, + // in UV-normalized units. Only has a visible effect once a Height texture + // is assigned above. + VStack { + TextInputNumberView( + label: "", + value: Binding( + get: { getMaterialHeightScale(entityId: entityId, meshIndex: meshIndex) }, + set: { newValue in + updateMaterialHeightScale(entityId: entityId, heightScale: newValue, meshIndex: meshIndex) + if inspectionOnly, isUntoldBackedMesh { + hasPendingUntoldWrite = true + untoldUpdateStatus = nil + } + refreshView() + } + ) + ) + .frame(width: 60) + + Text("Height Scale") + .font(.caption) + .foregroundColor(.secondary) + } + + // Midlevel Input — matches Blender's Displacement node "Midlevel" + // (default 0.5 = no shift). + VStack { + TextInputNumberView( + label: "", + value: Binding( + get: { getMaterialHeightMidlevel(entityId: entityId, meshIndex: meshIndex) }, + set: { newValue in + updateMaterialHeightMidlevel(entityId: entityId, heightMidlevel: newValue, meshIndex: meshIndex) + if inspectionOnly, isUntoldBackedMesh { + hasPendingUntoldWrite = true + untoldUpdateStatus = nil + } + refreshView() + } + ) + ) + .frame(width: 60) + + Text("Midlevel") + .font(.caption) + .foregroundColor(.secondary) + } + + // POM Enabled Toggle — lets testers A/B compare normal-mapping-only vs. + // normal+POM without discarding the height texture assignment. + VStack { + Toggle(isOn: Binding( + get: { getMaterialHeightEnabled(entityId: entityId, meshIndex: meshIndex) }, + set: { newValue in + updateMaterialHeightEnabled(entityId: entityId, heightEnabled: newValue, meshIndex: meshIndex) + if inspectionOnly, isUntoldBackedMesh { + hasPendingUntoldWrite = true + untoldUpdateStatus = nil + } + refreshView() + } + )) { + EmptyView() + } + .toggleStyle(.checkbox) + .frame(width: 60) + + Text("POM Enabled") + .font(.caption) + .foregroundColor(.secondary) + } + } + + HStack { + // Height Remap Min/Max — contrast-stretch the raw height sample before + // Midlevel is applied. Many real-world displacement maps (Substance/ + // Poliigon exports especially) only use a narrow slice of the full [0,1] + // range, leaving POM almost no local contrast to work with even at a + // reasonable Height Scale. Identity is (0.0, 1.0). + VStack { + TextInputNumberView( + label: "", + value: Binding( + get: { getMaterialHeightRemapMin(entityId: entityId, meshIndex: meshIndex) }, + set: { newValue in + updateMaterialHeightRemapMin(entityId: entityId, heightRemapMin: newValue, meshIndex: meshIndex) + if inspectionOnly, isUntoldBackedMesh { + hasPendingUntoldWrite = true + untoldUpdateStatus = nil + } + refreshView() + } + ) + ) + .frame(width: 60) + + Text("Height Remap Min") + .font(.caption) + .foregroundColor(.secondary) + } + + VStack { + TextInputNumberView( + label: "", + value: Binding( + get: { getMaterialHeightRemapMax(entityId: entityId, meshIndex: meshIndex) }, + set: { newValue in + updateMaterialHeightRemapMax(entityId: entityId, heightRemapMax: newValue, meshIndex: meshIndex) + if inspectionOnly, isUntoldBackedMesh { + hasPendingUntoldWrite = true + untoldUpdateStatus = nil + } + refreshView() + } + ) + ) + .frame(width: 60) + + Text("Height Remap Max") + .font(.caption) + .foregroundColor(.secondary) + } + } + HStack { VStack { TextInputNumberView( diff --git a/Sources/UntoldEditor/Utils/EditorFuncUtils.swift b/Sources/UntoldEditor/Utils/EditorFuncUtils.swift index 49cdcd6..e9c02fc 100644 --- a/Sources/UntoldEditor/Utils/EditorFuncUtils.swift +++ b/Sources/UntoldEditor/Utils/EditorFuncUtils.swift @@ -40,6 +40,8 @@ func bindingForWrapMode( return material.roughness.wrapMode case .metallic: return material.metallic.wrapMode + case .height: + return material.height.wrapMode } }, set: { newValue in From 9eb898aaf489cda733c27cafa2829939af245d23 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Sun, 30 Aug 2026 05:43:58 -0700 Subject: [PATCH 08/17] Auto-assign material textures from asset browser folders --- .../Editor/AssetBrowserView.swift | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/Sources/UntoldEditor/Editor/AssetBrowserView.swift b/Sources/UntoldEditor/Editor/AssetBrowserView.swift index 6beb166..3ab923c 100644 --- a/Sources/UntoldEditor/Editor/AssetBrowserView.swift +++ b/Sources/UntoldEditor/Editor/AssetBrowserView.swift @@ -16,6 +16,7 @@ private let runtimeAssetExtension = "untold" private let runtimeTextureFolderNames = ["Textures", "textures"] private let sourceAssetExtensions: Set = ["usd", "usda", "usdc", "usdz", "blend"] private let streamModelResourceFolderNames = ["tile_exports", "tile_export", "Textures", "textures"] +private let materialTextureExtensions: Set = ["png", "jpg", "jpeg", "tif", "tiff"] struct RuntimeExportRequest: Identifiable, Equatable { let id = UUID() @@ -320,6 +321,66 @@ enum AssetCategory: String, CaseIterable { } } +func editorTextureType(from filename: String) -> TextureType? { + let lowercasedName = filename.lowercased() + + if lowercasedName.contains("basecolor") + || lowercasedName.contains("base_color") + || lowercasedName.contains("albedo") + || lowercasedName.contains("diffuse") + || lowercasedName.contains("color") + { + return .baseColor + } else if lowercasedName.contains("roughness") || lowercasedName.contains("rough") { + return .roughness + } else if lowercasedName.contains("metallic") || lowercasedName.contains("metalness") || lowercasedName.contains("metal") { + return .metallic + } else if lowercasedName.contains("normalgx") + || lowercasedName.contains("normaldx") + || lowercasedName.contains("normalgl") + || lowercasedName.contains("normal") + || lowercasedName.contains("nrm") + { + return .normal + } else if lowercasedName.contains("height") + || lowercasedName.contains("displacement") + || lowercasedName.contains("displace") + || lowercasedName.contains("bump") + { + return .height + } + + return nil +} + +func editorMaterialTextureAssignments(in folder: URL, fileManager: FileManager = .default) -> [TextureType: URL] { + guard let enumerator = fileManager.enumerator( + at: folder, + includingPropertiesForKeys: [.isRegularFileKey], + options: [.skipsHiddenFiles] + ) else { + return [:] + } + + let textureURLs = enumerator.compactMap { item -> URL? in + guard let url = item as? URL else { return nil } + guard materialTextureExtensions.contains(url.pathExtension.lowercased()) else { return nil } + return url + } + + var assignments: [TextureType: URL] = [:] + for url in textureURLs.sorted(by: { $0.lastPathComponent.localizedCaseInsensitiveCompare($1.lastPathComponent) == .orderedAscending }) { + guard let textureType = editorTextureType(from: url.deletingPathExtension().lastPathComponent), + assignments[textureType] == nil + else { + continue + } + assignments[textureType] = url + } + + return assignments +} + private struct RemoteStreamImportSheet: View { @Binding var urlString: String var onImport: () -> Void @@ -1836,6 +1897,54 @@ struct AssetBrowserView: View { // MARK: - Add Model with Double Click + private func selectedMaterialTarget() -> (entityId: EntityID, meshIndex: Int)? { + if let inspectedMesh = selectionManager.inspectedMesh, + inspectedMesh.entityId != .invalid, + hasComponent(entityId: inspectedMesh.entityId, componentType: RenderComponent.self) + { + return (inspectedMesh.entityId, inspectedMesh.meshIndex) + } + + guard let entityId = selectionManager.selectedEntity, + entityId != .invalid, + hasComponent(entityId: entityId, componentType: RenderComponent.self) + else { + return nil + } + + return (entityId, 0) + } + + private func assignMaterialFolder(_ asset: Asset) { + guard asset.category == AssetCategory.materials.rawValue, asset.isFolder else { + return + } + + guard let target = selectedMaterialTarget() else { + showStatus("Select a mesh before assigning materials", isError: true) + return + } + + let assignments = editorMaterialTextureAssignments(in: asset.path) + guard assignments.isEmpty == false else { + showStatus("No recognized material textures in \(asset.name)", isError: true) + return + } + + for textureType in TextureType.allCases { + guard let textureURL = assignments[textureType] else { continue } + updateMaterialTexture( + entityId: target.entityId, + textureType: textureType, + path: textureURL, + meshIndex: target.meshIndex + ) + } + + selectionManager.objectWillChange.send() + showStatus("Assigned \(assignments.count) material textures from \(asset.name)") + } + private func resolvedRuntimeAsset(for asset: Asset) -> Asset? { guard asset.isFolder else { return asset } guard asset.category == AssetCategory.models.rawValue || asset.category == AssetCategory.animations.rawValue else { @@ -2008,6 +2117,11 @@ struct AssetBrowserView: View { } private func handle_add_model_double_click(asset: Asset) { + if asset.category == AssetCategory.materials.rawValue, asset.isFolder { + assignMaterialFolder(asset) + return + } + if asset.category == AssetCategory.streamModels.rawValue { if asset.path.pathExtension.lowercased() == "remotestream" { loadRemoteStreamModel(from: asset) From 37c4b133aaa0b5d1d06c8437f89ec98f6c19e07e Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Sun, 30 Aug 2026 05:49:11 -0700 Subject: [PATCH 09/17] [Patch] Show material texture details on inspector hover --- .../UntoldEditor/Editor/InspectorView.swift | 23 ++++++++++++++++++ .../InspectorViewTests.swift | 24 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/Sources/UntoldEditor/Editor/InspectorView.swift b/Sources/UntoldEditor/Editor/InspectorView.swift index 6cd0981..102ce1f 100644 --- a/Sources/UntoldEditor/Editor/InspectorView.swift +++ b/Sources/UntoldEditor/Editor/InspectorView.swift @@ -77,6 +77,26 @@ private func importTextureAsset(from sourceURL: URL) -> URL? { } } +func editorMaterialSlotHoverText(textureType: TextureType, textureURL: URL?) -> String { + guard let textureURL else { + return "No \(textureType.displayName) texture assigned" + } + + let materialName: String + if let host = textureURL.host, textureURL.scheme == "usdz-embedded", host.isEmpty == false { + materialName = host + } else { + let folderName = textureURL.deletingLastPathComponent().lastPathComponent + materialName = folderName.isEmpty ? "Unknown" : folderName + } + + return """ + \(textureType.displayName) + Material: \(materialName) + Texture: \(textureURL.lastPathComponent) + """ +} + private func onAddMesh_Editor(entityId: EntityID, url: URL) { let filename = url.deletingPathExtension().lastPathComponent let withExtension = url.pathExtension @@ -738,6 +758,8 @@ struct RenderingEditorView: View { ScrollView(.horizontal, showsIndicators: false) { HStack(alignment: .top, spacing: 24) { ForEach(TextureType.allCases) { type in + let textureURL = getMaterialTextureURL(entityId: entityId, type: type, meshIndex: meshIndex) + let hoverText = editorMaterialSlotHoverText(textureType: type, textureURL: textureURL) let image: NSImage? = { if let img = getMaterialTextureImage(entityId: entityId, type: type, meshIndex: meshIndex) { return img @@ -771,6 +793,7 @@ struct RenderingEditorView: View { } } .buttonStyle(PlainButtonStyle()) + .help(hoverText) HStack(spacing: 8) { Button(action: { diff --git a/Tests/UntoldEditorTests/InspectorViewTests.swift b/Tests/UntoldEditorTests/InspectorViewTests.swift index 561f3c0..9a7ec16 100644 --- a/Tests/UntoldEditorTests/InspectorViewTests.swift +++ b/Tests/UntoldEditorTests/InspectorViewTests.swift @@ -84,6 +84,30 @@ final class InspectorViewTests: XCTestCase { // MARK: - Tests + func test_editorMaterialSlotHoverText_showsEmptySlotFallback() { + let text = editorMaterialSlotHoverText(textureType: .roughness, textureURL: nil) + + XCTAssertEqual(text, "No Roughness texture assigned") + } + + func test_editorMaterialSlotHoverText_showsMaterialFolderAndTextureName() { + let url = URL(fileURLWithPath: "/Project/Materials/RustedIron/RustedIron_Roughness.png") + let text = editorMaterialSlotHoverText(textureType: .roughness, textureURL: url) + + XCTAssertTrue(text.contains("Roughness")) + XCTAssertTrue(text.contains("Material: RustedIron")) + XCTAssertTrue(text.contains("Texture: RustedIron_Roughness.png")) + } + + func test_editorMaterialSlotHoverText_showsEmbeddedTextureHostAsMaterialName() { + let url = URL(string: "usdz-embedded://Robot/normal")! + let text = editorMaterialSlotHoverText(textureType: .normal, textureURL: url) + + XCTAssertTrue(text.contains("Normal")) + XCTAssertTrue(text.contains("Material: Robot")) + XCTAssertTrue(text.contains("Texture: normal")) + } + func test_nameEditing_updatesEntityName_andRefreshesHierarchy() { // Arrange let e = createEntityWithName("Old Name") From 6ea624cd8a366dee82cb37d8d897594f25a67b30 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Sun, 30 Aug 2026 05:59:18 -0700 Subject: [PATCH 10/17] [Patch] Coalesce gizmo drag updates during viewport transforms --- .../Renderer/EditorUntoldRenderer.swift | 23 +++++++++++++++++-- .../Systems/EditorInputSystemAppKit.swift | 2 +- .../UntoldEditor/Systems/GizmoSystem.swift | 17 ++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/Sources/UntoldEditor/Renderer/EditorUntoldRenderer.swift b/Sources/UntoldEditor/Renderer/EditorUntoldRenderer.swift index 5aec48e..1616980 100644 --- a/Sources/UntoldEditor/Renderer/EditorUntoldRenderer.swift +++ b/Sources/UntoldEditor/Renderer/EditorUntoldRenderer.swift @@ -62,6 +62,13 @@ extension UntoldRenderer { editorController.refreshInspector() } + @inline(__always) + func consumeMouseDragDelta() { + InputSystem.shared.mouseDeltaX = 0.0 + InputSystem.shared.mouseDeltaY = 0.0 + InputSystem.shared.mouseActive = false + } + /// Remove static batching when entity is transformed via gizmo @inline(__always) func handleStaticBatchOnTransform(entityId: EntityID) { @@ -74,8 +81,10 @@ extension UntoldRenderer { } if hasActiveAxisGizmoDrag() { - handleStaticBatchOnTransform(entityId: activeEntity) - refreshInspector() + if applyPendingGizmoDragUpdate() { + handleStaticBatchOnTransform(entityId: activeEntity) + refreshInspector() + } return } @@ -97,6 +106,7 @@ extension UntoldRenderer { translateBy(entityId: activeEntity, position: t) translateBy(entityId: parentEntityIdGizmo, position: t) refreshInspector() + consumeMouseDragDelta() case (.translate, .y) where InputSystem.shared.mouseActive: handleStaticBatchOnTransform(entityId: activeEntity) @@ -111,6 +121,7 @@ extension UntoldRenderer { translateBy(entityId: activeEntity, position: t) translateBy(entityId: parentEntityIdGizmo, position: t) refreshInspector() + consumeMouseDragDelta() case (.translate, .z) where InputSystem.shared.mouseActive: handleStaticBatchOnTransform(entityId: activeEntity) @@ -125,6 +136,7 @@ extension UntoldRenderer { translateBy(entityId: activeEntity, position: t) translateBy(entityId: parentEntityIdGizmo, position: t) refreshInspector() + consumeMouseDragDelta() // MARK: - Rotate @@ -144,6 +156,7 @@ extension UntoldRenderer { applyGizmoRotationDelta(entityId: activeEntity, axis: axis, degrees: -angle * 10) syncLightDirectionHandleToActiveLight(entityId: activeEntity) refreshInspector() + consumeMouseDragDelta() case (.rotate, .y) where InputSystem.shared.mouseActive: handleStaticBatchOnTransform(entityId: activeEntity) @@ -161,6 +174,7 @@ extension UntoldRenderer { applyGizmoRotationDelta(entityId: activeEntity, axis: axis, degrees: angle * 10) syncLightDirectionHandleToActiveLight(entityId: activeEntity) refreshInspector() + consumeMouseDragDelta() case (.rotate, .z) where InputSystem.shared.mouseActive: handleStaticBatchOnTransform(entityId: activeEntity) @@ -178,6 +192,7 @@ extension UntoldRenderer { applyGizmoRotationDelta(entityId: activeEntity, axis: axis, degrees: angle * 10) syncLightDirectionHandleToActiveLight(entityId: activeEntity) refreshInspector() + consumeMouseDragDelta() // MARK: - Scale @@ -196,6 +211,7 @@ extension UntoldRenderer { applyWorldSpaceScaleDelta(entityId: activeEntity, worldAxis: axis, projectedAmount: amt) } refreshInspector() + consumeMouseDragDelta() case (.scale, .y) where InputSystem.shared.mouseActive: handleStaticBatchOnTransform(entityId: activeEntity) @@ -212,6 +228,7 @@ extension UntoldRenderer { applyWorldSpaceScaleDelta(entityId: activeEntity, worldAxis: axis, projectedAmount: amt) } refreshInspector() + consumeMouseDragDelta() case (.scale, .z) where InputSystem.shared.mouseActive: handleStaticBatchOnTransform(entityId: activeEntity) @@ -228,6 +245,7 @@ extension UntoldRenderer { applyWorldSpaceScaleDelta(entityId: activeEntity, worldAxis: axis, projectedAmount: amt) } refreshInspector() + consumeMouseDragDelta() // MARK: - Light direction (view-plane drag) @@ -295,6 +313,7 @@ extension UntoldRenderer { localTransformComponent.rotationZ = euler.roll translateTo(entityId: activeEntity, position: localTransformComponent.position) refreshInspector() + consumeMouseDragDelta() default: break diff --git a/Sources/UntoldEditor/Systems/EditorInputSystemAppKit.swift b/Sources/UntoldEditor/Systems/EditorInputSystemAppKit.swift index e790052..e71fd45 100644 --- a/Sources/UntoldEditor/Systems/EditorInputSystemAppKit.swift +++ b/Sources/UntoldEditor/Systems/EditorInputSystemAppKit.swift @@ -350,7 +350,7 @@ if activeHitGizmoEntity != .invalid, let rayContext = raycastContext(currentLocation: currentLocation, view: view) { - updateGizmoDrag( + queueGizmoDragUpdate( ray: GizmoDragRay( origin: rayContext.rayOrigin, direction: rayContext.rayDirection diff --git a/Sources/UntoldEditor/Systems/GizmoSystem.swift b/Sources/UntoldEditor/Systems/GizmoSystem.swift index 30078bc..e9eccfa 100644 --- a/Sources/UntoldEditor/Systems/GizmoSystem.swift +++ b/Sources/UntoldEditor/Systems/GizmoSystem.swift @@ -82,6 +82,7 @@ private struct GizmoDragState { } private var gizmoDragState: GizmoDragState? +private var pendingGizmoDragRay: GizmoDragRay? func gizmoRootWorldPosition() -> simd_float3 { guard parentEntityIdGizmo != .invalid else { @@ -177,8 +178,24 @@ func updateGizmoDrag(ray: GizmoDragRay) { gizmoDragState = state } +func queueGizmoDragUpdate(ray: GizmoDragRay) { + pendingGizmoDragRay = ray +} + +@discardableResult +func applyPendingGizmoDragUpdate() -> Bool { + guard let ray = pendingGizmoDragRay else { + return false + } + + pendingGizmoDragRay = nil + updateGizmoDrag(ray: ray) + return true +} + func endGizmoDrag() { gizmoDragState = nil + pendingGizmoDragRay = nil } func hasActiveAxisGizmoDrag() -> Bool { From f47a293ef847fd072990d81ec83b2ea30b7ecd30 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Sun, 30 Aug 2026 06:22:06 -0700 Subject: [PATCH 11/17] [Chores] Fixed lint ci test failures --- .github/workflows/swiftformat-lint.yml | 21 ++++++++++++++++++--- Makefile | 16 ++++++++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/.github/workflows/swiftformat-lint.yml b/.github/workflows/swiftformat-lint.yml index e93a257..63c431d 100644 --- a/.github/workflows/swiftformat-lint.yml +++ b/.github/workflows/swiftformat-lint.yml @@ -13,13 +13,28 @@ jobs: - name: Install SwiftFormat run: | - brew update - brew install swiftformat + SWIFTFORMAT_VERSION="$(awk -F':=' '/^SWIFTFORMAT_VERSION/ { gsub(/[[:space:]]/, "", $2); print $2 }' Makefile)" + if [ -z "$SWIFTFORMAT_VERSION" ]; then + echo "Unable to determine SWIFTFORMAT_VERSION from Makefile" + exit 1 + fi + curl -fsSL -o /tmp/swiftformat.zip \ + "https://github.com/nicklockwood/SwiftFormat/releases/download/${SWIFTFORMAT_VERSION}/swiftformat.zip" + unzip -o /tmp/swiftformat.zip -d /tmp/swiftformat + CURRENT_SWIFTFORMAT="$(command -v swiftformat || true)" + if [ -n "$CURRENT_SWIFTFORMAT" ]; then + INSTALL_PATH="$CURRENT_SWIFTFORMAT" + else + INSTALL_PATH="/usr/local/bin/swiftformat" + fi + sudo install -m 755 /tmp/swiftformat/swiftformat "$INSTALL_PATH" + echo "$(dirname "$INSTALL_PATH")" >> "$GITHUB_PATH" - name: Show versions run: | + which swiftformat swiftformat --version swift --version - name: Run SwiftFormat (lint mode) - run: swiftformat --lint . --swiftversion 5.8 --reporter github-actions-log + run: make lint diff --git a/Makefile b/Makefile index 5c39494..58cd39f 100644 --- a/Makefile +++ b/Makefile @@ -14,10 +14,22 @@ clean: test: swift test +# Required SwiftFormat version +SWIFTFORMAT_VERSION := 0.60.1 + +# Verify installed SwiftFormat matches the required version +check-swiftformat-version: + @INSTALLED=$$(swiftformat --version 2>&1 | awk '{print $$NF}'); \ + if [ "$$INSTALLED" != "$(SWIFTFORMAT_VERSION)" ]; then \ + echo "Error: swiftformat $(SWIFTFORMAT_VERSION) required, but found $$INSTALLED"; \ + echo "Install from: https://github.com/nicklockwood/SwiftFormat/releases/tag/$(SWIFTFORMAT_VERSION)"; \ + exit 1; \ + fi + # Lint Swift files using SwiftFormat -lint: +lint: check-swiftformat-version swiftformat --lint . --swiftversion 5.8 --reporter github-actions-log # Auto-format Swift files (for convenience) -format: +format: check-swiftformat-version swiftformat . --swiftversion 5.8 --quiet From ce88e5e7be80c89f196ed5446e0ab82c6b2f5f23 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Sun, 30 Aug 2026 06:22:49 -0700 Subject: [PATCH 12/17] [Chores] Formatted files --- .../Editor/AssetBrowserView.swift | 16 +++---- .../Editor/EditorMenuCommands.swift | 2 +- .../UntoldEditor/Editor/EditorScheme.swift | 15 +++++-- Sources/UntoldEditor/Editor/EditorView.swift | 42 +++++++++---------- .../Editor/ProjectSceneCatalog.swift | 4 +- .../Editor/SceneHierarchyView.swift | 10 +++-- .../Editor/SelectionManager.swift | 4 +- Sources/UntoldEditor/main.swift | 42 ++++++++++++++----- .../InspectorViewTests.swift | 4 +- 9 files changed, 85 insertions(+), 54 deletions(-) diff --git a/Sources/UntoldEditor/Editor/AssetBrowserView.swift b/Sources/UntoldEditor/Editor/AssetBrowserView.swift index 3ab923c..e8f1745 100644 --- a/Sources/UntoldEditor/Editor/AssetBrowserView.swift +++ b/Sources/UntoldEditor/Editor/AssetBrowserView.swift @@ -586,10 +586,10 @@ struct AssetBrowserView: View { importAssetForCategory(category, into: currentDirectoryURL) } - // Returns AnyView (not `some View`) so the recursive child call is allowed. - // `category == nil` marks a generic (non-category) folder such as the root - // or a custom directory created at root level. `url` may be nil for a - // category root when no project folder is set yet. + /// Returns AnyView (not `some View`) so the recursive child call is allowed. + /// `category == nil` marks a generic (non-category) folder such as the root + /// or a custom directory created at root level. `url` may be nil for a + /// category root when no project folder is set yet. private func directoryNode(url: URL?, name: String, category: String?, depth: Int) -> AnyView { let isGeneric = (category == nil) let subfolders: [URL] = { @@ -671,8 +671,8 @@ struct AssetBrowserView: View { ) } - // Root node of the directory tree (the project's asset folder). Right-click - // to create a directory at root level. + /// Root node of the directory tree (the project's asset folder). Right-click + /// to create a directory at root level. private var rootDirectoryRow: some View { let root = assetBasePath let isSelected = root.map { r in selectedDirURL?.standardizedFileURL == r.standardizedFileURL } ?? false @@ -1758,8 +1758,8 @@ struct AssetBrowserView: View { .cornerRadius(6) } - // Shared row list used by both the flat-category listing and - // folderContentsView. Only the folder-tap navigation differs per call site. + /// Shared row list used by both the flat-category listing and + /// folderContentsView. Only the folder-tap navigation differs per call site. private func assetRowList(_ assets: [Asset], spacing: CGFloat, onFolderTap: @escaping (Asset) -> Void) -> some View { VStack(alignment: .leading, spacing: spacing) { ForEach(assets) { asset in diff --git a/Sources/UntoldEditor/Editor/EditorMenuCommands.swift b/Sources/UntoldEditor/Editor/EditorMenuCommands.swift index 50050ae..a2bc49a 100644 --- a/Sources/UntoldEditor/Editor/EditorMenuCommands.swift +++ b/Sources/UntoldEditor/Editor/EditorMenuCommands.swift @@ -46,7 +46,7 @@ final class EditorPanelVisibility: ObservableObject { @Published var showBottomPanel: Bool = true @Published var showRightPanel: Bool = true - // Saved layout used by the "focus viewport" toggle (⌘F). + /// Saved layout used by the "focus viewport" toggle (⌘F). private var savedLayout: (left: Bool, bottom: Bool, right: Bool)? private init() {} diff --git a/Sources/UntoldEditor/Editor/EditorScheme.swift b/Sources/UntoldEditor/Editor/EditorScheme.swift index 406ac81..dd5729c 100644 --- a/Sources/UntoldEditor/Editor/EditorScheme.swift +++ b/Sources/UntoldEditor/Editor/EditorScheme.swift @@ -11,40 +11,47 @@ import SwiftUI // MARK: - Editor color scheme (Dracula-inspired) -// -// Single source of truth for the editor UI palette. All views should reference -// these semantic tokens instead of hardcoding `Color.white`, `.secondary`, -// `.red`, opacities, etc. Grouped by role so a re-theme only touches this file. + +/// +/// Single source of truth for the editor UI palette. All views should reference +/// these semantic tokens instead of hardcoding `Color.white`, `.secondary`, +/// `.red`, opacities, etc. Grouped by role so a re-theme only touches this file. extension Color { // MARK: Base surfaces + static let editorBackground = Color(red: 0.15, green: 0.16, blue: 0.21) // dracula background static let editorPanelBackground = Color(red: 0.19, green: 0.20, blue: 0.26) // dracula current line static let editorSurface = Color(red: 0.24, green: 0.25, blue: 0.32) // dracula selection // MARK: Accents + static let editorAccent = Color(red: 0.91, green: 0.64, blue: 0.35) // muted dracula orange static let editorAccentSoft = Color(red: 0.91, green: 0.64, blue: 0.35, opacity: 0.16) static let editorSecondaryAccent = Color(red: 0.74, green: 0.58, blue: 0.98) // dracula purple // MARK: Text hierarchy + static let editorTextPrimary = Color.white // titles, primary labels, text on accent buttons static let editorTextSecondary = Color.white.opacity(0.70) // supporting / secondary labels static let editorTextTertiary = Color.white.opacity(0.45) // muted / disabled-looking labels static let editorTextInverse = Color.black.opacity(0.90) // dark text on light/accent fills // MARK: Semantic status + static let editorError = Color(red: 0.94, green: 0.38, blue: 0.42) // dracula red static let editorSuccess = Color(red: 0.31, green: 0.82, blue: 0.55) // dracula green static let editorWarning = Color(red: 0.95, green: 0.78, blue: 0.42) // dracula yellow/orange static let editorInfo = Color(red: 0.55, green: 0.73, blue: 0.98) // dracula blue/cyan // MARK: Fills & separators + static let editorFillSubtle = Color.white.opacity(0.05) // faint row / zebra backgrounds static let editorFill = Color.white.opacity(0.10) // subtle panel / hover fills static let editorDivider = Color.white.opacity(0.10) // borders, strokes, separators static let editorDisabled = Color.white.opacity(0.15) // disabled control backgrounds // MARK: Overlays & shadows + static let editorShadow = Color.black.opacity(0.20) // default drop shadows static let editorShadowStrong = Color.black.opacity(0.34) // elevated cards / popovers static let editorScrim = Color.black.opacity(0.40) // floating stat cards over the scene diff --git a/Sources/UntoldEditor/Editor/EditorView.swift b/Sources/UntoldEditor/Editor/EditorView.swift index d422a65..cd67d0a 100644 --- a/Sources/UntoldEditor/Editor/EditorView.swift +++ b/Sources/UntoldEditor/Editor/EditorView.swift @@ -452,8 +452,8 @@ public struct EditorView: View { case effects } - // Right panel is contextual: the project shows Environment/Effects (with a - // themed segmented switch); a selected object shows the Inspector. + /// Right panel is contextual: the project shows Environment/Effects (with a + /// themed segmented switch); a selected object shows the Inspector. private var editorRightPanel: some View { Group { if selectionManager.projectSelected { @@ -498,7 +498,7 @@ public struct EditorView: View { } } - // Inspector shown when the active scene is selected in the Scene Graph. + /// Inspector shown when the active scene is selected in the Scene Graph. private var sceneInspector: some View { let sceneName = editorController?.currentSceneURL?.deletingPathExtension().lastPathComponent ?? "Untitled Scene" return VStack(alignment: .leading, spacing: 10) { @@ -573,8 +573,8 @@ public struct EditorView: View { .focusable(false) } - // Themed segmented selector matching the editor style (accent-filled active - // segment inside a rounded surface container). + /// Themed segmented selector matching the editor style (accent-filled active + /// segment inside a rounded surface container). private var editorPanelTabs: some View { HStack(spacing: 2) { panelTabButton(.assets, title: "Assets", icon: "shippingbox") @@ -609,13 +609,13 @@ public struct EditorView: View { .focusable(false) } - // Bottom dock: a segmented Assets/Console selector (replacing the old - // native TabView tab strip) plus the selected panel below it. - // Pause the Metal render loop for the duration of a panel show/hide - // animation so the viewport doesn't compete with the layout change (which - // caused stutter). Called from onChange, so it covers every trigger: edge - // tabs, the View menu (⌘1/2/3) and Focus Viewport (⌘F). The viewport freezes - // on its last frame, then resumes. + /// Bottom dock: a segmented Assets/Console selector (replacing the old + /// native TabView tab strip) plus the selected panel below it. + /// Pause the Metal render loop for the duration of a panel show/hide + /// animation so the viewport doesn't compete with the layout change (which + /// caused stutter). Called from onChange, so it covers every trigger: edge + /// tabs, the View menu (⌘1/2/3) and Focus Viewport (⌘F). The viewport freezes + /// on its last frame, then resumes. private func pauseRenderForPanelAnimation() { renderer?.metalView.isPaused = true renderPauseGeneration += 1 @@ -627,8 +627,8 @@ public struct EditorView: View { } } - // Small always-visible tab that protrudes from a panel's inner edge (placed - // as an overlay above the viewport) to collapse/expand the panel. + /// Small always-visible tab that protrudes from a panel's inner edge (placed + /// as an overlay above the viewport) to collapse/expand the panel. private func panelEdgeTabVertical( isOpen: Bool, openIcon: String, @@ -1091,8 +1091,8 @@ public struct EditorView: View { } } - // Load a scene file from the project into the (single) ECS world, replacing - // whatever is currently loaded. Used by the Scene Graph panel. + /// Load a scene file from the project into the (single) ECS world, replacing + /// whatever is currently loaded. Used by the Scene Graph panel. private func editor_loadScene(from url: URL) { guard let sceneData = loadGameScene(from: url) else { print("❌ Failed to load scene from \(url.lastPathComponent)") @@ -1120,7 +1120,7 @@ public struct EditorView: View { print("✅ Scene loaded: \(url.lastPathComponent)") } - // Ask before switching scenes: loading discards the current world. + /// Ask before switching scenes: loading discards the current world. private func editor_requestLoadScene(_ url: URL) { if url == editorController?.currentSceneURL { return } pendingSceneToLoad = url @@ -1133,13 +1133,13 @@ public struct EditorView: View { editor_loadScene(from: url) } - // Save the project. Projects persist as folders (scenes + imported assets on - // disk), so for now this writes the active scene's work into the project. + /// Save the project. Projects persist as folders (scenes + imported assets on + /// disk), so for now this writes the active scene's work into the project. private func editor_saveProject() { editor_handleSave() } - // Start a fresh, unsaved scene (File → Add New Scene). + /// Start a fresh, unsaved scene (File → Add New Scene). private func editor_newScene() { editor_clearScene() editorController?.currentSceneURL = nil @@ -1252,7 +1252,7 @@ public struct EditorView: View { sceneGraphModel.refreshHierarchy() } - // Delete a specific entity (used by the Scene Graph right-click menu). + /// Delete a specific entity (used by the Scene Graph right-click menu). private func editor_removeEntity(_ entityId: EntityID) { guard isDerivedAssetNode(entityId) == false else { print("⚠️ Asset nodes cannot be removed directly") diff --git a/Sources/UntoldEditor/Editor/ProjectSceneCatalog.swift b/Sources/UntoldEditor/Editor/ProjectSceneCatalog.swift index 11fdbb2..70c998d 100644 --- a/Sources/UntoldEditor/Editor/ProjectSceneCatalog.swift +++ b/Sources/UntoldEditor/Editor/ProjectSceneCatalog.swift @@ -19,7 +19,9 @@ struct ProjectSceneFile: Identifiable, Hashable { let url: URL let name: String - var id: URL { url } + var id: URL { + url + } } final class ProjectSceneCatalog: ObservableObject { diff --git a/Sources/UntoldEditor/Editor/SceneHierarchyView.swift b/Sources/UntoldEditor/Editor/SceneHierarchyView.swift index 77bb2f0..c0953c1 100644 --- a/Sources/UntoldEditor/Editor/SceneHierarchyView.swift +++ b/Sources/UntoldEditor/Editor/SceneHierarchyView.swift @@ -98,13 +98,15 @@ struct SceneHierarchyView: View { ) } - // A scene node in the tree. `url == nil` represents the current, not-yet-saved - // ("Untitled") scene, which is always the active one. + /// A scene node in the tree. `url == nil` represents the current, not-yet-saved + /// ("Untitled") scene, which is always the active one. private struct SceneItem: Identifiable { let url: URL? let name: String let isActive: Bool - var id: String { url?.absoluteString ?? "__untitled__" } + var id: String { + url?.absoluteString ?? "__untitled__" + } } private var sceneItems: [SceneItem] { @@ -353,7 +355,7 @@ struct HierarchyNode: View { var onParentEntity: (EntityID, EntityID) -> Void = { _, _ in } var onUnparentEntity: (EntityID) -> Void = { _ in } var onDeleteEntity: (EntityID) -> Void = { _ in } - var addActions: AddEntityActions = AddEntityActions() + var addActions: AddEntityActions = .init() @State private var isDragOver = false var body: some View { diff --git a/Sources/UntoldEditor/Editor/SelectionManager.swift b/Sources/UntoldEditor/Editor/SelectionManager.swift index 369954c..1953714 100644 --- a/Sources/UntoldEditor/Editor/SelectionManager.swift +++ b/Sources/UntoldEditor/Editor/SelectionManager.swift @@ -55,8 +55,8 @@ struct MeshInspectionSelection: Equatable { class SceneGraphModel: ObservableObject { @Published var childrenMap: [EntityID: [EntityID]] = [:] - // Every node is collapsed by default; we track only the ones the user - // expanded. Opening a project therefore shows a tidy, collapsed tree. + /// Every node is collapsed by default; we track only the ones the user + /// expanded. Opening a project therefore shows a tidy, collapsed tree. @Published private(set) var expandedEntityIds: Set = [] func refreshHierarchy() { diff --git a/Sources/UntoldEditor/main.swift b/Sources/UntoldEditor/main.swift index ee030af..de8193b 100644 --- a/Sources/UntoldEditor/main.swift +++ b/Sources/UntoldEditor/main.swift @@ -139,8 +139,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { return item } - // Keep the View-menu checkmarks in sync with the current overlay / camera state. - func menuNeedsUpdate(_ menu: NSMenu) { + /// Keep the View-menu checkmarks in sync with the current overlay / camera state. + func menuNeedsUpdate(_: NSMenu) { let store = EditorEngineStatsStore.shared showFPSItem?.state = store.overlayMode != .off ? .on : .off showFPSAdvancedItem?.state = store.overlayMode == .advanced ? .on : .off @@ -155,13 +155,33 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { // MARK: - File actions (bridged to SwiftUI via notifications) - @objc private func menuNew() { NotificationCenter.default.post(name: .editorMenuNew, object: nil) } - @objc private func menuOpen() { NotificationCenter.default.post(name: .editorMenuOpen, object: nil) } - @objc private func menuNewScene() { NotificationCenter.default.post(name: .editorMenuNewScene, object: nil) } - @objc private func menuSaveProject() { NotificationCenter.default.post(name: .editorMenuSaveProject, object: nil) } - @objc private func menuSave() { NotificationCenter.default.post(name: .editorMenuSave, object: nil) } - @objc private func menuSaveAs() { NotificationCenter.default.post(name: .editorMenuSaveAs, object: nil) } - @objc private func menuReset() { NotificationCenter.default.post(name: .editorMenuReset, object: nil) } + @objc private func menuNew() { + NotificationCenter.default.post(name: .editorMenuNew, object: nil) + } + + @objc private func menuOpen() { + NotificationCenter.default.post(name: .editorMenuOpen, object: nil) + } + + @objc private func menuNewScene() { + NotificationCenter.default.post(name: .editorMenuNewScene, object: nil) + } + + @objc private func menuSaveProject() { + NotificationCenter.default.post(name: .editorMenuSaveProject, object: nil) + } + + @objc private func menuSave() { + NotificationCenter.default.post(name: .editorMenuSave, object: nil) + } + + @objc private func menuSaveAs() { + NotificationCenter.default.post(name: .editorMenuSaveAs, object: nil) + } + + @objc private func menuReset() { + NotificationCenter.default.post(name: .editorMenuReset, object: nil) + } // MARK: - View actions (mutate shared stores directly) @@ -188,8 +208,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { EditorPlaybackSettings.shared.useSceneCameraDuringPlay.toggle() } - // Animation + render-pause are driven by EditorView (which observes these - // values), so the menu just flips the state. + /// Animation + render-pause are driven by EditorView (which observes these + /// values), so the menu just flips the state. @objc private func menuToggleLeftPanel() { EditorPanelVisibility.shared.showLeftPanel.toggle() } diff --git a/Tests/UntoldEditorTests/InspectorViewTests.swift b/Tests/UntoldEditorTests/InspectorViewTests.swift index 9a7ec16..368e674 100644 --- a/Tests/UntoldEditorTests/InspectorViewTests.swift +++ b/Tests/UntoldEditorTests/InspectorViewTests.swift @@ -99,8 +99,8 @@ final class InspectorViewTests: XCTestCase { XCTAssertTrue(text.contains("Texture: RustedIron_Roughness.png")) } - func test_editorMaterialSlotHoverText_showsEmbeddedTextureHostAsMaterialName() { - let url = URL(string: "usdz-embedded://Robot/normal")! + func test_editorMaterialSlotHoverText_showsEmbeddedTextureHostAsMaterialName() throws { + let url = try XCTUnwrap(URL(string: "usdz-embedded://Robot/normal")) let text = editorMaterialSlotHoverText(textureType: .normal, textureURL: url) XCTAssertTrue(text.contains("Normal")) From 75afd7e5cf9b8f1c8cbdab74653dcf94f9cfabf6 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Sun, 30 Aug 2026 06:24:12 -0700 Subject: [PATCH 13/17] [Patch] Removed TaskBar View test --- .../UntoldEditorTests/ToolbarViewTests.swift | 263 ------------------ 1 file changed, 263 deletions(-) delete mode 100644 Tests/UntoldEditorTests/ToolbarViewTests.swift diff --git a/Tests/UntoldEditorTests/ToolbarViewTests.swift b/Tests/UntoldEditorTests/ToolbarViewTests.swift deleted file mode 100644 index bf8d583..0000000 --- a/Tests/UntoldEditorTests/ToolbarViewTests.swift +++ /dev/null @@ -1,263 +0,0 @@ -// -// ToolbarViewTests.swift -// UntoldEditor -// -// Copyright (C) Untold Engine Studios -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// These unit tests were jump-started with AI assistance — then refined by humans. If you spot an issue, please submit an issue. - -import SwiftUI -@testable import UntoldEditor -@testable import UntoldEngine -import XCTest - -#if canImport(AppKit) - final class ToolbarViewTests: XCTestCase { - /// Build a ToolbarView with closures that flip flags so we can assert wiring. - private func makeSUT( - selectionManager: SelectionManager = SelectionManager(), - onSaveCalled: UnsafeMutablePointer, - onSaveAsCalled: UnsafeMutablePointer, - onClearCalled: UnsafeMutablePointer, - onCameraSaveCalled _: UnsafeMutablePointer, - onPlayToggledValues: UnsafeMutablePointer<[Bool]>, - onDirLightCalled: UnsafeMutablePointer, - onPointLightCalled: UnsafeMutablePointer, - onSpotLightCalled: UnsafeMutablePointer, - onAreaLightCalled: UnsafeMutablePointer, - onCreateCubeCalled: UnsafeMutablePointer, - onCreateSphereCalled: UnsafeMutablePointer, - onCreatePlaneCalled: UnsafeMutablePointer, - onCreateCylinderCalled: UnsafeMutablePointer, - onCreateConeCalled: UnsafeMutablePointer - ) -> ToolbarView { - ToolbarView( - selectionManager: selectionManager, - onSave: { onSaveCalled.pointee = true }, - onSaveAs: { onSaveAsCalled.pointee = true }, - onClear: { onClearCalled.pointee = true }, - onPlayToggled: { value in onPlayToggledValues.pointee.append(value) }, - useSceneCameraDuringPlay: .constant(false), - dirLightCreate: { onDirLightCalled.pointee = true }, - pointLightCreate: { onPointLightCalled.pointee = true }, - spotLightCreate: { onSpotLightCalled.pointee = true }, - areaLightCreate: { onAreaLightCalled.pointee = true }, - onCreateCube: { onCreateCubeCalled.pointee = true }, - onCreateSphere: { onCreateSphereCalled.pointee = true }, - onCreatePlane: { onCreatePlaneCalled.pointee = true }, - onCreateCylinder: { onCreateCylinderCalled.pointee = true }, - onCreateCone: { onCreateConeCalled.pointee = true } - ) - } - - func test_actionsAreWired_up() { - var onSave = false - var onSaveAs = false - var onClear = false - var onCameraSave = false - var playValues: [Bool] = [] - var onDir = false - var onPoint = false - var onSpot = false - var onArea = false - var onCube = false - var onSphere = false - var onPlane = false - var onCylinder = false - var onCone = false - - let sut = makeSUT( - onSaveCalled: &onSave, - onSaveAsCalled: &onSaveAs, - onClearCalled: &onClear, - onCameraSaveCalled: &onCameraSave, - onPlayToggledValues: &playValues, - onDirLightCalled: &onDir, - onPointLightCalled: &onPoint, - onSpotLightCalled: &onSpot, - onAreaLightCalled: &onArea, - onCreateCubeCalled: &onCube, - onCreateSphereCalled: &onSphere, - onCreatePlaneCalled: &onPlane, - onCreateCylinderCalled: &onCylinder, - onCreateConeCalled: &onCone - ) - - // We cannot programmatically tap SwiftUI Buttons without a host and introspection. - // Instead, assert that injected closures can be called and flip their flags. - sut.onSave() - sut.onSaveAs() - sut.onClear() - sut.dirLightCreate() - sut.pointLightCreate() - sut.spotLightCreate() - sut.areaLightCreate() - sut.onCreateCube() - sut.onCreateSphere() - sut.onCreatePlane() - sut.onCreateCylinder() - sut.onCreateCone() - - XCTAssertTrue(onSave, "onSave should be wired.") - XCTAssertTrue(onSaveAs, "onSaveAs should be wired.") - XCTAssertTrue(onClear, "onClear should be wired.") - XCTAssertTrue(onDir, "dirLightCreate should be wired.") - XCTAssertTrue(onPoint, "pointLightCreate should be wired.") - XCTAssertTrue(onSpot, "spotLightCreate should be wired.") - XCTAssertTrue(onArea, "areaLightCreate should be wired.") - XCTAssertTrue(onCube, "onCreateCube should be wired.") - XCTAssertTrue(onSphere, "onCreateSphere should be wired.") - XCTAssertTrue(onPlane, "onCreatePlane should be wired.") - XCTAssertTrue(onCylinder, "onCreateCylinder should be wired.") - XCTAssertTrue(onCone, "onCreateCone should be wired.") - - // For play toggle, verify the closure records values we pass. - // Since @State is internal, we mimic the button behavior by calling the closure directly. - sut.onPlayToggled(true) - sut.onPlayToggled(false) - XCTAssertEqual(playValues, [true, false], "onPlayToggled should receive toggled values in order.") - } - - func test_viewComposesWithoutCrash() { - // Smoke test: ensure the view can be created and rendered to a hosting controller without crashing. - let selection = SelectionManager() - var playValues: [Bool] = [] - - let sut = ToolbarView( - selectionManager: selection, - onSave: {}, - onSaveAs: {}, - onClear: {}, - onPlayToggled: { playValues.append($0) }, - useSceneCameraDuringPlay: .constant(false), - dirLightCreate: {}, - pointLightCreate: {}, - spotLightCreate: {}, - areaLightCreate: {}, - onCreateCube: {}, - onCreateSphere: {}, - onCreatePlane: {}, - onCreateCylinder: {}, - onCreateCone: {} - ) - - // Wrap in a hosting controller to ensure SwiftUI can build the body. - let host = NSHostingController(rootView: sut) - XCTAssertNotNil(host.view, "Hosting controller should create a view.") - _ = host // keep alive - _ = playValues // keep referenced to avoid 'never read' warning - } - - // MARK: - Primitive Creation Tests - - func test_primitiveButtons_callCorrectClosures() { - // Given: A ToolbarView with tracked primitive creation callbacks - var cubeCreated = false - var sphereCreated = false - var planeCreated = false - var cylinderCreated = false - var coneCreated = false - - let sut = ToolbarView( - selectionManager: SelectionManager(), - onSave: {}, - onSaveAs: {}, - onClear: {}, - onPlayToggled: { _ in }, - useSceneCameraDuringPlay: .constant(false), - dirLightCreate: {}, - pointLightCreate: {}, - spotLightCreate: {}, - areaLightCreate: {}, - onCreateCube: { cubeCreated = true }, - onCreateSphere: { sphereCreated = true }, - onCreatePlane: { planeCreated = true }, - onCreateCylinder: { cylinderCreated = true }, - onCreateCone: { coneCreated = true } - ) - - // When: Invoking the primitive creation closures - sut.onCreateCube() - sut.onCreateSphere() - sut.onCreatePlane() - sut.onCreateCylinder() - sut.onCreateCone() - - // Then: Each closure should be called - XCTAssertTrue(cubeCreated, "Cube creation callback should be invoked") - XCTAssertTrue(sphereCreated, "Sphere creation callback should be invoked") - XCTAssertTrue(planeCreated, "Plane creation callback should be invoked") - XCTAssertTrue(cylinderCreated, "Cylinder creation callback should be invoked") - XCTAssertTrue(coneCreated, "Cone creation callback should be invoked") - } - - func test_primitivesSection_existsInView() { - // Given: A ToolbarView instance - var callCount = 0 - let sut = ToolbarView( - selectionManager: SelectionManager(), - onSave: {}, - onSaveAs: {}, - onClear: {}, - onPlayToggled: { _ in }, - useSceneCameraDuringPlay: .constant(false), - dirLightCreate: {}, - pointLightCreate: {}, - spotLightCreate: {}, - areaLightCreate: {}, - onCreateCube: { callCount += 1 }, - onCreateSphere: { callCount += 1 }, - onCreatePlane: { callCount += 1 }, - onCreateCylinder: {}, - onCreateCone: {} - ) - - // When: Calling the primitive closures - sut.onCreateCube() - sut.onCreateSphere() - sut.onCreatePlane() - - // Then: All three active primitives should have been called - XCTAssertEqual(callCount, 3, "All three active primitive buttons (cube, sphere, plane) should be functional") - } - - func test_primitiveCallbacks_areIndependent() { - // Given: Separate tracking for each primitive - var cubeCount = 0 - var sphereCount = 0 - var planeCount = 0 - - let sut = ToolbarView( - selectionManager: SelectionManager(), - onSave: {}, - onSaveAs: {}, - onClear: {}, - onPlayToggled: { _ in }, - useSceneCameraDuringPlay: .constant(false), - dirLightCreate: {}, - pointLightCreate: {}, - spotLightCreate: {}, - areaLightCreate: {}, - onCreateCube: { cubeCount += 1 }, - onCreateSphere: { sphereCount += 1 }, - onCreatePlane: { planeCount += 1 }, - onCreateCylinder: {}, - onCreateCone: {} - ) - - // When: Calling specific primitive closures multiple times - sut.onCreateCube() - sut.onCreateCube() - sut.onCreateSphere() - - // Then: Each closure should track independently - XCTAssertEqual(cubeCount, 2, "Cube should be created twice") - XCTAssertEqual(sphereCount, 1, "Sphere should be created once") - XCTAssertEqual(planeCount, 0, "Plane should not be created") - } - } -#endif From bb1b9e11b2532380092b49d897724986f58b1fa7 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Sun, 30 Aug 2026 06:37:25 -0700 Subject: [PATCH 14/17] [Test] fixed tests --- .../AssetBrowserViewTests.swift | 2 ++ .../EditorUntoldRendererTests.swift | 4 +-- .../LogConsoleViewTests.swift | 2 +- .../SceneHierarchyViewTests.swift | 31 ++++++++++++++----- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Tests/UntoldEditorTests/AssetBrowserViewTests.swift b/Tests/UntoldEditorTests/AssetBrowserViewTests.swift index e401ffb..c778a3a 100644 --- a/Tests/UntoldEditorTests/AssetBrowserViewTests.swift +++ b/Tests/UntoldEditorTests/AssetBrowserViewTests.swift @@ -32,6 +32,7 @@ final class AssetBrowserViewTests: XCTestCase { selectedAsset: Binding, selectionManager: SelectionManager = SelectionManager(), sceneGraphModel: SceneGraphModel = SceneGraphModel(), + searchQuery: Binding = .constant(""), editor_addEntityWithAsset: @escaping () -> Void = {}, editor_loadSceneAuthoredFromAsset: @escaping (Asset) -> Void = { _ in }) -> AssetBrowserView { @@ -40,6 +41,7 @@ final class AssetBrowserViewTests: XCTestCase { selectedAsset: selectedAsset, selectionManager: selectionManager, sceneGraphModel: sceneGraphModel, + searchQuery: searchQuery, editor_addEntityWithAsset: editor_addEntityWithAsset, editor_loadSceneAuthoredFromAsset: editor_loadSceneAuthoredFromAsset ) diff --git a/Tests/UntoldEditorTests/EditorUntoldRendererTests.swift b/Tests/UntoldEditorTests/EditorUntoldRendererTests.swift index bec8135..50b5cad 100644 --- a/Tests/UntoldEditorTests/EditorUntoldRendererTests.swift +++ b/Tests/UntoldEditorTests/EditorUntoldRendererTests.swift @@ -466,8 +466,8 @@ final class EditorUntoldRendererTests: XCTestCase { // Act renderer.handleSceneInput() - // Assert - Should process transformation (may fail due to other missing setup) - XCTAssertTrue(InputSystem.shared.mouseActive, "Mouse should be active") + // Assert - Should process and consume the mouse drag + XCTAssertFalse(InputSystem.shared.mouseActive, "Mouse drag should be consumed after transformation") removeGizmo() } diff --git a/Tests/UntoldEditorTests/LogConsoleViewTests.swift b/Tests/UntoldEditorTests/LogConsoleViewTests.swift index b555f0a..a8e737a 100644 --- a/Tests/UntoldEditorTests/LogConsoleViewTests.swift +++ b/Tests/UntoldEditorTests/LogConsoleViewTests.swift @@ -17,7 +17,7 @@ import XCTest /// A minimal harness exposing the private helpers of LogConsoleView for testing. private struct LogConsoleViewHarness { - let view = LogConsoleView() + let view = LogConsoleView(searchQuery: .constant(""), autoScroll: .constant(true)) func tag(for level: LogLevel) -> String { // Mirror the production logic diff --git a/Tests/UntoldEditorTests/SceneHierarchyViewTests.swift b/Tests/UntoldEditorTests/SceneHierarchyViewTests.swift index 28b0e68..ec31beb 100644 --- a/Tests/UntoldEditorTests/SceneHierarchyViewTests.swift +++ b/Tests/UntoldEditorTests/SceneHierarchyViewTests.swift @@ -248,7 +248,7 @@ final class SceneHierarchyViewTests: XCTestCase { XCTAssertFalse(sceneGraphModel.hasChildren(entityId: child), "Leaf child should not report children") } - func test_sceneGraphModel_nodesAreExpandedByDefault() { + func test_sceneGraphModel_nodesAreCollapsedByDefault() { // Arrange let entity = createEntity() @@ -256,35 +256,35 @@ final class SceneHierarchyViewTests: XCTestCase { sceneGraphModel.refreshHierarchy() // Assert - XCTAssertTrue(sceneGraphModel.isExpanded(entityId: entity), "Nodes should be expanded by default") + XCTAssertFalse(sceneGraphModel.isExpanded(entityId: entity), "Nodes should be collapsed by default") } - func test_sceneGraphModel_toggleExpandedCollapsesAndExpandsNode() { + func test_sceneGraphModel_toggleExpandedExpandsAndCollapsesNode() { // Arrange let entity = createEntity() sceneGraphModel.refreshHierarchy() // Act / Assert sceneGraphModel.toggleExpanded(entityId: entity) - XCTAssertFalse(sceneGraphModel.isExpanded(entityId: entity), "Toggle should collapse expanded nodes") + XCTAssertTrue(sceneGraphModel.isExpanded(entityId: entity), "Toggle should expand collapsed nodes") sceneGraphModel.toggleExpanded(entityId: entity) - XCTAssertTrue(sceneGraphModel.isExpanded(entityId: entity), "Toggle should expand collapsed nodes") + XCTAssertFalse(sceneGraphModel.isExpanded(entityId: entity), "Toggle should collapse expanded nodes") } - func test_sceneGraphModel_refreshPrunesCollapsedDestroyedEntities() { + func test_sceneGraphModel_refreshPrunesExpandedDestroyedEntities() { // Arrange let entity = createEntity() sceneGraphModel.refreshHierarchy() sceneGraphModel.toggleExpanded(entityId: entity) - XCTAssertFalse(sceneGraphModel.isExpanded(entityId: entity)) + XCTAssertTrue(sceneGraphModel.isExpanded(entityId: entity)) // Act destroyEntity(entityId: entity) sceneGraphModel.refreshHierarchy() // Assert - XCTAssertTrue(sceneGraphModel.isExpanded(entityId: entity), "Destroyed entities should be pruned from collapsed state") + XCTAssertFalse(sceneGraphModel.isExpanded(entityId: entity), "Destroyed entities should be pruned from expanded state") } // MARK: - SelectionManager Integration Tests @@ -333,6 +333,11 @@ final class SceneHierarchyViewTests: XCTestCase { let view = SceneHierarchyView( selectionManager: selectionManager, sceneGraphModel: sceneGraphModel, + sceneCatalog: ProjectSceneCatalog(), + projectName: "TestProject", + onSelectScene: { _ in }, + isPlaying: false, + onTogglePlay: {}, entityList: [], onAddEntity_Editor: { addEntityCalled = true }, onRemoveEntity_Editor: { removeEntityCalled = true }, @@ -405,6 +410,11 @@ final class SceneHierarchyViewTests: XCTestCase { let view = SceneHierarchyView( selectionManager: selectionManager, sceneGraphModel: sceneGraphModel, + sceneCatalog: ProjectSceneCatalog(), + projectName: "TestProject", + onSelectScene: { _ in }, + isPlaying: false, + onTogglePlay: {}, entityList: entityList, onAddEntity_Editor: {}, onRemoveEntity_Editor: {}, @@ -430,6 +440,11 @@ final class SceneHierarchyViewTests: XCTestCase { let view = SceneHierarchyView( selectionManager: selectionManager, sceneGraphModel: sceneGraphModel, + sceneCatalog: ProjectSceneCatalog(), + projectName: "TestProject", + onSelectScene: { _ in }, + isPlaying: false, + onTogglePlay: {}, entityList: [], onAddEntity_Editor: {}, onRemoveEntity_Editor: {}, From c458924a34d4df2213e261a4bea14c7cf7f4a094 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Sun, 30 Aug 2026 06:38:00 -0700 Subject: [PATCH 15/17] [Chores] Added option in make file --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 58cd39f..d69732c 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,10 @@ clean: test: swift test +# Test against the local UntoldEngine package using a stable build path +localtest: + swift test --build-path /tmp/untoldeditor-local-build + # Required SwiftFormat version SWIFTFORMAT_VERSION := 0.60.1 From ce97cfe39679cde9fdfa079de693b9f1fe47e1e4 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Sun, 30 Aug 2026 06:53:55 -0700 Subject: [PATCH 16/17] [Chores] Updated editor to use v0.18.0 of engine --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index e2987a9..e0613c1 100644 --- a/Package.swift +++ b/Package.swift @@ -13,7 +13,7 @@ let package = Package( // Use a branch during active development: // .package(url: "https://github.com/untoldengine/UntoldEngine.git", branch: "develop"), // Or pin to a release: - .package(url: "https://github.com/untoldengine/UntoldEngine.git", exact: "0.16.0"), + .package(url: "https://github.com/untoldengine/UntoldEngine.git", exact: "0.18.0"), ], targets: [ .executableTarget( From a60eb097b821ddb5b239f0534ad2fe13b3bb49b2 Mon Sep 17 00:00:00 2001 From: Untold Engine Date: Sun, 30 Aug 2026 07:00:49 -0700 Subject: [PATCH 17/17] [Release] Preparing release 0.18.0 --- CHANGELOG.md | 13 +++++++++++++ Sources/UntoldEditor/main.swift | 4 ++-- scripts/next-version.sh | 6 +----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6133f5..23890bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,17 @@ # Changelog +## v0.18.0 - 2026-08-30 +### 🐞 Fixes +- [Patch]Restore scene-authored loading in Environment panel (bac0530…) +- [Patch] Fixed directional light rotation - gizmo (81b1a0d…) +- [Patch] Fixed parent-child selection in viewport (41df956…) +- [Patch] Fixed the active directional light (1c17fdd…) +- [Patch] Re-added Import textures features (ea5ed67…) +- [Patch] Allow exporting blender files (bd0308e…) +- [Patch] Show material texture details on inspector hover (37c4b13…) +- [Patch] Coalesce gizmo drag updates during viewport transforms (6ea624c…) +- [Patch] Removed TaskBar View test (75afd7e…) +### 🚀 Features +- [Feature] Add Height/POM material channel to Inspector (d460c63…) ## v0.16.0 - 2026-08-12 ### 🐞 Fixes - [Patch] fix area light mesh culling (9122f78…) diff --git a/Sources/UntoldEditor/main.swift b/Sources/UntoldEditor/main.swift index de8193b..b9f8746 100644 --- a/Sources/UntoldEditor/main.swift +++ b/Sources/UntoldEditor/main.swift @@ -29,7 +29,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { private var rightPanelItem: NSMenuItem? func applicationDidFinishLaunching(_: Notification) { - Logger.log(message: "Launching Untold Engine Editor v0.16.0") + Logger.log(message: "Launching Untold Engine Editor v0.18.0") setupMainMenu() @@ -41,7 +41,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { defer: false ) - window.title = "Untold Engine Editor v0.16.0" + window.title = "Untold Engine Editor v0.18.0" // Force dark appearance so AppKit-drawn chrome (title bar, native tab // strips, segmented controls) matches the dark editor theme. window.appearance = NSAppearance(named: .darkAqua) diff --git a/scripts/next-version.sh b/scripts/next-version.sh index 042bd1a..79da3d8 100755 --- a/scripts/next-version.sh +++ b/scripts/next-version.sh @@ -13,7 +13,7 @@ # Optional Flags: # --with-v : Print version with 'v' prefix (e.g. v0.12.7) # --cliff : Run git-cliff to prepend a changelog section, -# then update version strings in main.swift and ToolbarView.swift +# then update version strings in main.swift # --docs : Run Docusaurus docs:version command to # snapshot documentation for the new release # @@ -79,10 +79,6 @@ if [[ "${DO_CLIFF}" == "true" ]]; then Sources/UntoldEditor/main.swift echo "Updated version to ${NEXT} in UntoldEditor/main.swift." - # Update editorVersionLabel in ToolbarView.swift - sed -i '' 's/private let editorVersionLabel = "v[^"]*"/private let editorVersionLabel = "v'"${NEXT}"'"/' \ - Sources/UntoldEditor/Editor/ToolbarView.swift - echo "Updated editorVersionLabel to v${NEXT} in ToolbarView.swift." fi # Optionally run Docusaurus docs:version