462 Commits
goake ... sdl3

Author SHA1 Message Date
8ba7351206 asd
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
2024-07-25 23:18:05 +03:00
7c901a56e5 _inp 2024-07-25 23:17:24 +03:00
8ba44e75a4 _header 2024-07-25 22:59:34 +03:00
7cadc8d331 _bin 2024-07-25 22:59:08 +03:00
7debd885b9 _windowtype 2024-07-25 22:59:01 +03:00
44a9c52c44 _mouse 2024-07-25 22:58:55 +03:00
dcc444173d _cleanup 2024-07-25 22:52:22 +03:00
d3c4b5b8c1 Enable warning sound in question dialogs
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
2024-07-25 22:33:15 +03:00
56236b0579 Enable modern Windows dialog boxes 2024-07-25 22:33:15 +03:00
c2a588f738 Implement relative mouse mode (raw input) for SDL platform 2024-07-25 22:33:15 +03:00
09331b601b Add flag for Window types 2024-07-25 22:33:14 +03:00
17d7716e41 Enable native windowing system settings with SDL platform 2024-07-25 22:33:14 +03:00
0344cde98f Add command-line switches to force X11 and Wayland SDL drivers 2024-07-25 22:33:14 +03:00
9f35f175ab Implement SDL platform, windowing and input handling 2024-07-25 22:33:13 +03:00
cabf8736c7 Refactor application window class name 2024-07-25 22:32:54 +03:00
93344a33d3 Move Window related enums to separate header file 2024-07-25 22:32:27 +03:00
3898df1b68 Refactor Windows drag and drop implementation 2024-07-25 22:32:26 +03:00
33909cf931 Refactor ScreenUtilities 2024-07-25 22:32:26 +03:00
3bc70c147b Add more helper methods for managing Git repos 2024-07-25 22:32:26 +03:00
70dea56d44 Fix centered window location on X11 2024-07-25 22:32:25 +03:00
348e15475f Fix rebuilding dependencies using Git with existing local folders 2024-07-25 22:32:25 +03:00
fe568cf16a Fix initial position of Tooltips 2024-07-25 22:32:25 +03:00
1066a38130 _bin 2024-07-25 22:32:24 +03:00
2494c3cb23 _deps build sdl only 2024-07-25 22:08:10 +03:00
ecc34320d1 Disable LFS override 2024-07-25 20:18:26 +03:00
Wojtek Figat
9f078a6e3c Fix crash when using and saving scene with Visual Script object instance which asset was deleted 2024-07-25 17:17:28 +02:00
Wojtek Figat
b4d1e6197c Fix crash when removing Visual Script asset that's instance is selected in Properties window 2024-07-25 17:16:50 +02:00
Wojtek Figat
d14a4f1f66 Minor codestyle fixes 2024-07-25 16:50:16 +02:00
Wojtek Figat
1e43b031ba Fix unpacking marshaled field value
#2790
2024-07-25 16:50:01 +02:00
Wojtek Figat
41fd7b724e Fix test build regression 2024-07-25 15:32:05 +02:00
Wojtek Figat
2a1706decb Fix vehicles simulation instability when physics substepping is enabled
#2796
2024-07-25 14:19:01 +02:00
Wojtek Figat
ab7de52531 Fix compilation regression 2024-07-25 13:51:41 +02:00
Wojtek Figat
1891b9e367 Refactor PhysX vehicles and cloth simulation code to be more readable
#2796
2024-07-25 13:51:32 +02:00
Wojtek Figat
3ac7dfbd3a Merge branch 'RomanZhu-IndustryStandardTransformHotkeysSupport' 2024-07-25 10:54:45 +02:00
Wojtek Figat
2853273205 Merge branch 'IndustryStandardTransformHotkeysSupport' of https://github.com/RomanZhu/FlaxPublic into RomanZhu-IndustryStandardTransformHotkeysSupport 2024-07-25 10:54:08 +02:00
Wojtek Figat
2201dd681e Merge branch 'mtszkarbowiak-fix/move-semantics' 2024-07-25 10:53:50 +02:00
Wojtek Figat
013dab4ba7 Fix codestyle and apply pr feedback
#2730
2024-07-25 10:52:54 +02:00
Wojtek Figat
cf501945a3 Merge branch 'fix/move-semantics' of https://github.com/mtszkarbowiak/FlaxEngine into mtszkarbowiak-fix/move-semantics 2024-07-25 10:47:31 +02:00
Wojtek Figat
ab4703c3dd Merge branch 'Arcnor-colorPickerAlwaysChangesColor' 2024-07-25 10:06:32 +02:00
Wojtek Figat
4ce853d892 Merge branch 'RuanLucasGD-RenameActors' 2024-07-25 10:06:23 +02:00
Wojtek Figat
6cdd56ad11 Merge branch 'colorPickerAlwaysChangesColor' of https://github.com/Arcnor/FlaxEngine into Arcnor-colorPickerAlwaysChangesColor
# Conflicts:
#	Source/Editor/Options/InterfaceOptions.cs
2024-07-25 10:06:05 +02:00
Wojtek Figat
66122e6e3b Merge branch 'RenameActors' of https://github.com/RuanLucasGD/FlaxEngine into RuanLucasGD-RenameActors 2024-07-25 09:28:14 +02:00
Wojtek Figat
c444661884 Merge branch 'Swiggies-lightmap-material-nodes' 2024-07-25 09:25:48 +02:00
Wojtek Figat
91a8a670d5 Merge branch 'lightmap-material-nodes' of https://github.com/Swiggies/FlaxEngine into Swiggies-lightmap-material-nodes 2024-07-25 09:25:15 +02:00
Wojtek Figat
dbd5566ee0 Merge branch 'Tryibion-inject-scene-load-children' 2024-07-25 09:24:16 +02:00
Wojtek Figat
ad2d4a2626 Merge branch 'inject-scene-load-children' of https://github.com/Tryibion/FlaxEngine into Tryibion-inject-scene-load-children 2024-07-25 09:24:12 +02:00
Wojtek Figat
148f03205f Merge branch 'Tryibion-table-improve' 2024-07-25 09:23:54 +02:00
Wojtek Figat
2c1f835528 Merge branch 'table-improve' of https://github.com/Tryibion/FlaxEngine into Tryibion-table-improve 2024-07-25 09:17:01 +02:00
Wojtek Figat
8038e045b0 Merge branch 'GoaLitiuM-assert_directions' 2024-07-25 09:16:23 +02:00
Wojtek Figat
7a635e2896 Merge branch 'assert_directions' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-assert_directions 2024-07-25 09:16:16 +02:00
Wojtek Figat
a40a5721f3 Merge branch 'Tryibion-jsontype-thumbnail' 2024-07-25 08:41:29 +02:00
Wojtek Figat
e4cf4c9f17 Merge branch 'jsontype-thumbnail' of https://github.com/Tryibion/FlaxEngine into Tryibion-jsontype-thumbnail 2024-07-25 08:41:21 +02:00
Wojtek Figat
5299afa276 Merge branch 'GoaLitiuM-module_compilation_fix' 2024-07-25 08:41:07 +02:00
Wojtek Figat
8e8e41d5e1 Merge branch 'module_compilation_fix' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-module_compilation_fix 2024-07-25 08:40:56 +02:00
Wojtek Figat
153e45c345 Merge branch 'GoaLitiuM-csharp_warning_fix' 2024-07-25 08:40:29 +02:00
Wojtek Figat
7bb365c57b Merge branch 'csharp_warning_fix' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-csharp_warning_fix 2024-07-25 08:40:22 +02:00
Wojtek Figat
8397a81428 Merge branch 'Tryibion-empty-ref-text' 2024-07-25 08:40:05 +02:00
Wojtek Figat
17c484b97b Merge branch 'empty-ref-text' of https://github.com/Tryibion/FlaxEngine into Tryibion-empty-ref-text 2024-07-25 08:39:42 +02:00
Wojtek Figat
3b740659f5 Merge branch 'GoaLitiuM-customeditor_fixes' 2024-07-25 08:38:41 +02:00
Wojtek Figat
2913bb39e8 Merge branch 'customeditor_fixes' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-customeditor_fixes 2024-07-25 08:38:32 +02:00
Chandler Cox
8209639261 Add being able to add a thumbnail to a SpawnableJsonProxy 2024-07-23 22:08:01 -05:00
Roman Zhuravlev
a580d6785f Ignore Translate/Rotate/Scale/TransformSpace hotkeys while holding RMB.
Allows to use industry standard WER hotkeys for transformations and not change modes while navigating through level.
2024-07-21 22:25:25 +02:00
8b22ffe007 Fix warnings about upcoming C# reserved keywords 2024-07-20 20:46:32 +03:00
24f7ec4a54 Fix statically linked binary modules not getting compiled 2024-07-20 15:41:26 +03:00
55d55212c3 Add assertions for checking against un-normalized direction vectors 2024-07-20 15:34:11 +03:00
Chandler Cox
1142fa68ea Small table improvements. 2024-07-19 20:49:58 -05:00
Chandler Cox
305f725394 Ensure to add all scene objects of injected actors. 2024-07-19 08:19:34 -05:00
Chandler Cox
8a297a6fd4 Clean up code more. 2024-07-19 07:59:57 -05:00
Chandler Cox
d717430256 Clean up code 2024-07-19 07:48:01 -05:00
Chandler Cox
8804738193 Allow for Initializing children injected via scene loading. 2024-07-19 07:42:57 -05:00
Chandler Cox
9b11461eaf Add type display to empty object ref in editor 2024-07-19 06:48:35 -05:00
Wojtek Figat
d879b8e064 Add utility GetInstance method to Json Asset refs in csharp
#2774
2024-07-18 15:14:26 +02:00
Wojtek Figat
f132198ead Add more functionality and thumbnail to content items in finder for scripts 2024-07-18 14:19:27 +02:00
Wojtek Figat
5e0d90af2e Add displaying file extension for scripts in content finder to distinguish C++ files 2024-07-18 14:18:52 +02:00
Wojtek Figat
736119fdc6 Merge branch 'Zode-quaternion-fix-down' 2024-07-18 12:40:06 +02:00
Wojtek Figat
5259c41b40 Merge branch 'quaternion-fix-down' of https://github.com/Zode/FlaxEngine into Zode-quaternion-fix-down 2024-07-18 12:40:00 +02:00
Wojtek Figat
4a6f2f8821 Merge branch 'Swiggies-ccd-fix' 2024-07-18 12:39:24 +02:00
Wojtek Figat
529de24da4 Cache DisableCCD locally in physics backend
#2768
2024-07-18 12:39:15 +02:00
Wojtek Figat
fc3d15c544 Merge branch 'ccd-fix' of https://github.com/Swiggies/FlaxEngine into Swiggies-ccd-fix 2024-07-18 12:27:33 +02:00
Wojtek Figat
261c4a7e88 Merge branch 'GoaLitiuM-simplemove_gravity' 2024-07-18 12:26:11 +02:00
Wojtek Figat
ccd619f659 Merge branch 'simplemove_gravity' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-simplemove_gravity 2024-07-18 12:26:06 +02:00
Wojtek Figat
35bbd52f89 Merge branch 'GoaLitiuM-charcontroller_terrain_fix' 2024-07-18 11:54:54 +02:00
Wojtek Figat
ea45aa9b19 Merge branch 'charcontroller_terrain_fix' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-charcontroller_terrain_fix 2024-07-18 11:54:46 +02:00
Wojtek Figat
655c377da8 Merge branch 'Tryibion-phyx-ed' 2024-07-18 11:50:56 +02:00
Wojtek Figat
5498cbf3bf Merge branch 'phyx-ed' of https://github.com/Tryibion/FlaxEngine into Tryibion-phyx-ed 2024-07-18 11:50:46 +02:00
Wojtek Figat
10a343a490 Merge branch 'Tryibion-mesh-collider-neg-scale-fix' 2024-07-18 11:47:46 +02:00
Wojtek Figat
b2faad9634 Merge branch 'mesh-collider-neg-scale-fix' of https://github.com/Tryibion/FlaxEngine into Tryibion-mesh-collider-neg-scale-fix 2024-07-18 11:47:39 +02:00
Wojtek Figat
786ab54f84 Merge branch 'Tryibion-pref-layout-splitter' 2024-07-18 11:46:03 +02:00
Wojtek Figat
d41d153cff Merge branch 'pref-layout-splitter' of https://github.com/Tryibion/FlaxEngine into Tryibion-pref-layout-splitter 2024-07-18 11:45:53 +02:00
Wojtek Figat
89bd733142 Merge branch 'Tryibion-picker-type' 2024-07-18 11:11:58 +02:00
Wojtek Figat
5d2a1e0507 Merge branch 'picker-type' of https://github.com/Tryibion/FlaxEngine into Tryibion-picker-type 2024-07-18 11:09:51 +02:00
Wojtek Figat
22ff68b89f Merge branch 'Tryibion-remove-redundant-tab' 2024-07-18 10:48:05 +02:00
Wojtek Figat
fe41ef619b Improve floating dock window hidden header to handle inputs properly
#2770
2024-07-18 10:47:46 +02:00
Wojtek Figat
3870a013fa Merge branch 'remove-redundant-tab' of https://github.com/Tryibion/FlaxEngine into Tryibion-remove-redundant-tab 2024-07-18 10:36:53 +02:00
Wojtek Figat
ebd890a0da Merge branch 'Tryibion-fix-last-tab-drag' 2024-07-18 10:35:29 +02:00
Wojtek Figat
964a1940c4 Merge branch 'fix-last-tab-drag' of https://github.com/Tryibion/FlaxEngine into Tryibion-fix-last-tab-drag 2024-07-18 10:34:32 +02:00
Wojtek Figat
b11af95ec7 Merge branch 'Tryibion-texture-window-tabs' 2024-07-18 10:31:16 +02:00
Wojtek Figat
e8de6c37fc Merge branch 'texture-window-tabs' of https://github.com/Tryibion/FlaxEngine into Tryibion-texture-window-tabs 2024-07-18 08:46:38 +02:00
Wojtek Figat
af41cefaac Merge branch 'Tryibion-layer-resize-fix' 2024-07-18 08:44:51 +02:00
Wojtek Figat
900a96938b Merge branch 'layer-resize-fix' of https://github.com/Tryibion/FlaxEngine into Tryibion-layer-resize-fix 2024-07-18 08:44:45 +02:00
Wojtek Figat
c58d43ac1e Merge branch 'Tryibion-editor-update' 2024-07-18 08:43:52 +02:00
Wojtek Figat
0122ee94a5 Merge branch 'editor-update' of https://github.com/Tryibion/FlaxEngine into Tryibion-editor-update 2024-07-18 08:43:48 +02:00
Wojtek Figat
dfb541011d Merge branch 'Tryibion-audio-play-rename' 2024-07-18 08:42:43 +02:00
Chandler Cox
85a04f8e81 Perform layout of splitter panel once splitter is done being dragged. 2024-07-16 20:36:27 -05:00
Chandler Cox
531c75bff9 Display asset picker type. 2024-07-16 20:32:47 -05:00
Chandler Cox
12f70572b0 Remove redundant first tab on floating window. 2024-07-16 20:05:27 -05:00
Chandler Cox
7090e85224 Fix not being able to drag a window tab all of the way to the right. 2024-07-16 19:25:05 -05:00
Olly Rybak
e5e1f945ea Added eDETECT_CCD_CONTACT to PairFlags, hopefully properly enabling CCD 2024-07-17 10:04:14 +10:00
Zode
e1cf41b94b Fix Quaternion.FromDirection giving bogus output when fed a perfect down vector 2024-07-17 01:12:17 +03:00
Chandler Cox
d4bf8368b1 Separate import settings as new tab in texture window. 2024-07-16 11:43:04 -05:00
Chandler Cox
6588a71879 Dont allow resize of layers array. 2024-07-15 18:19:14 -05:00
Chandler Cox
d700df6afb Add PhysX option for enabling enhanced determinism 2024-07-15 16:23:49 -05:00
35d46e23a8 Fix CharacterController::SimpleMove gravity displacement handling 2024-07-13 16:39:22 +03:00
f1fc086612 Fix CharacterController to not process hits against removed actors 2024-07-13 16:39:06 +03:00
Chandler Cox
7b4e509140 Fix mesh collider not rotating correctly due to negative scale. 2024-07-11 18:44:55 -05:00
Chandler Cox
c168ce3a7e Deprecate IsActuallyPlayingSth and add IsActuallyPlaying to AudioSource 2024-07-11 17:39:11 -05:00
Chandler Cox
e1dcd290b1 Add Editor update event. 2024-07-11 15:48:50 -05:00
Wojtek Figat
009e1aaebb Merge branch 'Tryibion-content-cut' 2024-07-04 18:07:10 +02:00
Wojtek Figat
fe9996dd4f Merge branch 'content-cut' of https://github.com/Tryibion/FlaxEngine into Tryibion-content-cut 2024-07-04 18:07:03 +02:00
Wojtek Figat
d1e54b821b Fix asset to be soft when transformation is nan or inf
#2742
2024-07-04 18:05:47 +02:00
Chandler Cox
8877aac8cb Small code cleanup 2024-07-03 13:07:02 -05:00
Chandler Cox
a61096ffa5 Add cutting of content items. 2024-07-03 12:53:50 -05:00
Olly Rybak
751c1f20dc Returns lightmap UV correctly with no errors 2024-07-03 18:35:32 +10:00
Wojtek Figat
f40cf6539a Update Assimp for Mac 2024-07-02 11:29:56 +02:00
Wojtek Figat
8e4f7babf3 Merge branch 'GoaLitiuM-unsafeaccessor_init' 2024-07-02 10:04:05 +02:00
Wojtek Figat
e18b059234 Merge branch 'unsafeaccessor_init' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-unsafeaccessor_init 2024-07-02 10:04:00 +02:00
Wojtek Figat
e3114c29af Merge branch 'envision3d-feature/add-default-audio-listener' 2024-07-02 10:02:31 +02:00
Wojtek Figat
3539f84c9a Merge branch 'feature/add-default-audio-listener' of https://github.com/envision3d/FlaxEngine into envision3d-feature/add-default-audio-listener 2024-07-02 10:02:24 +02:00
Wojtek Figat
5b0c6d1aff Merge branch 'xxSeys1-AudioListenerWarning' 2024-07-02 10:01:54 +02:00
Wojtek Figat
1b72b14376 Merge branch 'AudioListenerWarning' of https://github.com/xxSeys1/FlaxEngine into xxSeys1-AudioListenerWarning 2024-07-02 10:01:39 +02:00
Wojtek Figat
32af6ede73 Merge branch 'GoaLitiuM-update_assimp' 2024-07-02 10:00:08 +02:00
Wojtek Figat
a79fb237e5 Update Assimp to v5.4.1
#2727
2024-07-02 09:59:30 +02:00
Wojtek Figat
ec510425a1 Merge branch 'update_assimp' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-update_assimp 2024-07-02 09:12:27 +02:00
Wojtek Figat
bf772a5eb9 Merge branch 'Tryibion-prefab-buttons' 2024-07-02 09:11:44 +02:00
Wojtek Figat
fe3a9fbd67 Merge branch 'prefab-buttons' of https://github.com/Tryibion/FlaxEngine into Tryibion-prefab-buttons 2024-07-02 09:11:38 +02:00
Wojtek Figat
090b9ea0c1 Merge branch 'Tryibion-wrap-on-underscore' 2024-07-02 09:11:12 +02:00
Wojtek Figat
ddfaeddb5f Merge branch 'wrap-on-underscore' of https://github.com/Tryibion/FlaxEngine into Tryibion-wrap-on-underscore 2024-07-02 09:10:37 +02:00
Wojtek Figat
abe938c30a Merge branch 'Tryibion-fix-profiler-timeline' 2024-07-02 09:10:10 +02:00
Wojtek Figat
cf02fecadc Merge branch 'fix-profiler-timeline' of https://github.com/Tryibion/FlaxEngine into Tryibion-fix-profiler-timeline 2024-07-02 09:06:21 +02:00
Wojtek Figat
54c24f8434 Merge branch 'Tryibion-inv-culture-unknown' 2024-07-02 09:05:53 +02:00
Wojtek Figat
35ab0f4261 Merge branch 'inv-culture-unknown' of https://github.com/Tryibion/FlaxEngine into Tryibion-inv-culture-unknown 2024-07-02 09:05:37 +02:00
Wojtek Figat
73342615d1 Merge branch 'GoaLitiuM-winsdk_24h2' 2024-07-02 09:05:15 +02:00
Wojtek Figat
d64108a5c1 Merge branch 'winsdk_24h2' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-winsdk_24h2 2024-07-02 09:05:08 +02:00
Wojtek Figat
1dfa92b0c3 Merge branch 'Tryibion-select-multi-drop' 2024-07-02 09:04:26 +02:00
d56493da54 Use UnsafeAccessor to initialize scripting object interop fields 2024-06-30 15:52:14 +03:00
16b0228394 Add support for Windows SDK build 26100 (24H2) 2024-06-28 23:02:25 +03:00
Mateusz Karbowiak
cb3e8e4112 Ambiguous name fix 2024-06-22 16:41:29 +02:00
Mateusz Karbowiak
5f4aee71b8 Actor naming without string copy fix 2024-06-22 15:14:02 +02:00
Mateusz Karbowiak
02403377cd Array move semantics fix 2024-06-22 15:13:53 +02:00
6436fb3bde Update AssImp to latest version 2024-06-21 21:55:30 +03:00
Chandler Cox
a1adab1156 Change variable name to dropping. 2024-06-19 09:24:33 -05:00
Chandler Cox
919e118a2f Select all assets and scripts that are dropped in the tree panel. 2024-06-18 21:46:22 -05:00
Chandler Cox
f38df259a7 Dont show Select prefab, Edit prefab, and view changes buttons when editing actor in the prefab. 2024-06-18 21:10:42 -05:00
Chandler Cox
ec10e3bb30 Fix changing to invariant culture for unknown LCID. 2024-06-18 19:59:27 -05:00
Chandler Cox
224c2c049e Fix the profiler charts in place and only scroll profiler info. 2024-06-18 19:25:12 -05:00
Chandler Cox
8509761d67 Only wrap text on underscores and not other special characters 2024-06-18 17:37:54 -05:00
Wojtek Figat
0d8691045b Merge branch 'GoaLitiuM-vulkan_amd_fixes' 2024-06-17 21:49:04 +02:00
Wojtek Figat
bd727ae189 Merge branch 'vulkan_amd_fixes' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-vulkan_amd_fixes 2024-06-17 21:49:00 +02:00
Wojtek Figat
4bfda76666 Merge branch 'MrCapy0-Fix-Vehicle-Crash' 2024-06-17 21:47:39 +02:00
Wojtek Figat
a030978558 Merge branch 'Fix-Vehicle-Crash' of https://github.com/MrCapy0/FlaxEngine into MrCapy0-Fix-Vehicle-Crash 2024-06-17 21:47:34 +02:00
Wojtek Figat
2aff3d76ca Merge branch 'Chikinsupu-Visject-FixGroupFilterBreakingSmartFloats' 2024-06-17 21:46:29 +02:00
Wojtek Figat
8312659275 Merge branch 'Visject-FixGroupFilterBreakingSmartFloats' of https://github.com/Chikinsupu/FlaxEngine into Chikinsupu-Visject-FixGroupFilterBreakingSmartFloats 2024-06-17 21:46:11 +02:00
Wojtek Figat
55ce33bc1c Merge branch 'Tryibion-fix-tint-border' 2024-06-17 21:45:31 +02:00
Wojtek Figat
1613bdcd06 Merge branch 'fix-tint-border' of https://github.com/Tryibion/FlaxEngine into Tryibion-fix-tint-border 2024-06-17 21:45:11 +02:00
Wojtek Figat
a67dc00fa3 Fix tree nodes culling when using search in scene tree
#2462
2024-06-17 21:44:31 +02:00
1c82c73bc0 Fix graphical glitches in Vulkan backend 2024-06-17 20:55:04 +03:00
xxSeys1
a05fe5ce9b add a warning when there is more than one audio listener enabled
checks every time a listener gets enabled
2024-06-15 19:40:23 +02:00
MrCapy0
8899e3ebb7 clean code 2024-06-15 12:11:08 -03:00
MrCapy0
727ff8be95 Fix crash on add new drive steer vs speed 2024-06-15 12:09:19 -03:00
Nils Hausfeld
a8d97f1daa - Skip group filtering if the string in front of the dot is empty or doesn't start with a letter, to make spawning float nodes work again 2024-06-15 11:32:47 +02:00
Chandler Cox
488485e23e Fix borders not tinting. 2024-06-14 14:06:49 -05:00
envision3d
79138dfaf0 add default audio listener to newly created scenes 2024-06-14 02:14:20 -05:00
Wojtek Figat
f52059522b Merge branch 'GoaLitiuM-logcontext_fix' 2024-06-11 19:22:53 +02:00
691ac6d439 Fix missing LogContext data 2024-06-11 19:54:51 +03:00
Wojtek Figat
6fc056cba2 Add default material for Radial Menu control
#2678
2024-06-11 15:57:54 +02:00
Wojtek Figat
54cb82cbda Merge branch 'Menotdan-load-source-log' 2024-06-11 12:54:00 +02:00
Wojtek Figat
b8c9130ae4 Simplify and cleanup code
#2368
2024-06-11 12:53:47 +02:00
Wojtek Figat
c2e1b92cce Move LogContext
#2368
2024-06-11 11:55:56 +02:00
Wojtek Figat
6113325e07 Merge branch 'load-source-log' of https://github.com/Menotdan/FlaxEngine into Menotdan-load-source-log 2024-06-11 11:54:45 +02:00
Wojtek Figat
bea7e1526d Merge branch 'z1dev-master' 2024-06-11 11:40:35 +02:00
Wojtek Figat
abc75e6c3d Merge branch 'master' of https://github.com/z1dev/FlaxEngine into z1dev-master 2024-06-11 11:40:26 +02:00
Wojtek Figat
dfc1db672d Add minor Y offset to grid to prevent artifacts with floor in sample scenes 2024-06-11 11:40:13 +02:00
Wojtek Figat
5b71591998 Add option to disable particles preview in scene view and play only looping effects
#1767
2024-06-11 11:37:49 +02:00
Wojtek Figat
4dabf4bf01 Merge branch 'cNori-RadialMenu-and-material-nodes' 2024-06-11 09:49:00 +02:00
Wojtek Figat
210c443b30 Cleanup code 2024-06-11 09:48:53 +02:00
Wojtek Figat
f95e7e96bf Codestyle fixes and some nodes docs 2024-06-11 08:43:31 +02:00
Wojtek Figat
735aa70b53 Merge branch 'RadialMenu-and-material-nodes' of https://github.com/cNori/FlaxEngineFork into cNori-RadialMenu-and-material-nodes 2024-06-11 08:21:40 +02:00
Wojtek Figat
b1fd178341 Fix compilation error
#2697
2024-06-11 08:10:28 +02:00
Wojtek Figat
0bb21ef4a0 Update shader 2024-06-10 23:19:32 +02:00
Olly Rybak
2a4a5d2519 Merge branch 'grid-update' of https://github.com/Swiggies/FlaxEngine into Swiggies-grid-update
#2663
2024-06-10 23:17:39 +02:00
Menotdan
892ab47b7a Merge branch 'reordering' of https://github.com/Menotdan/FlaxEngine into Menotdan-reordering
#2670
2024-06-10 23:13:50 +02:00
Wojtek Figat
7f6805aac6 Merge branch 'Tryibion-grid-slot-spacing' 2024-06-10 18:16:24 +02:00
Wojtek Figat
d56d624f0f Merge branch 'grid-slot-spacing' of https://github.com/Tryibion/FlaxEngine into Tryibion-grid-slot-spacing 2024-06-10 18:12:35 +02:00
Wojtek Figat
fd91e912fe Merge branch 'GoaLitiuM-array_object_free_fix' 2024-06-10 18:09:06 +02:00
Wojtek Figat
7106791186 Merge branch 'array_object_free_fix' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-array_object_free_fix 2024-06-10 18:08:55 +02:00
Wojtek Figat
a0f379f613 Merge branch 'GoaLitiuM-animation_timeline_fix' 2024-06-10 18:07:43 +02:00
Wojtek Figat
c0847f6789 Merge branch 'animation_timeline_fix' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-animation_timeline_fix 2024-06-10 18:07:36 +02:00
Wojtek Figat
831289afc3 Merge branch 'GoaLitiuM-physicsmaterial_reload_fix' 2024-06-10 17:47:01 +02:00
7ba97f3c32 Fix freeing managed Object references in marshalled arrays 2024-06-08 21:16:57 +03:00
992436b47c Fix error when previewing animation timeline values after reimport 2024-06-08 19:25:13 +03:00
7614481d78 Fix PhysicsMaterial not updating in Colliders after asset reload 2024-06-08 19:24:13 +03:00
07371ddfdf Fix crash when PhysicsMaterial asset is reloaded in editor 2024-06-08 19:24:10 +03:00
Wojtek Figat
50c29f6a9b Fix #2388 namespaces overlap in some plugins 2024-06-08 12:47:15 +02:00
Wojtek Figat
a4877c6294 Merge branch 'GoaLitiuM-marshaller_namespace' 2024-06-08 12:06:21 +02:00
Wojtek Figat
c9bebc0700 Merge branch 'marshaller_namespace' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-marshaller_namespace 2024-06-08 12:06:17 +02:00
Wojtek Figat
26867bfd8f Merge branch 'Swiggies-progress-bar-fix' 2024-06-08 12:02:31 +02:00
Wojtek Figat
dfd6df7f42 Merge branch 'progress-bar-fix' of https://github.com/Swiggies/FlaxEngine into Swiggies-progress-bar-fix 2024-06-08 12:02:26 +02:00
Wojtek Figat
092681aea7 Merge branch 'Chikinsupu-ItemSearchContextMenuSearchImprovements' 2024-06-08 11:59:17 +02:00
Wojtek Figat
3a2f4843ba Merge branch 'ItemSearchContextMenuSearchImprovements' of https://github.com/Chikinsupu/FlaxEngine into Chikinsupu-ItemSearchContextMenuSearchImprovements 2024-06-08 11:59:10 +02:00
Wojtek Figat
db6cdc3ce0 Merge branch 'Chikinsupu-Visject-DragDropParamAltSetter' 2024-06-08 11:57:40 +02:00
Wojtek Figat
b23aa6cebd Merge branch 'Visject-DragDropParamAltSetter' of https://github.com/Chikinsupu/FlaxEngine into Chikinsupu-Visject-DragDropParamAltSetter 2024-06-08 11:57:35 +02:00
Wojtek Figat
2676daabf1 Merge branch 'xxSeys1-IncreasedExecutionLineThickness' 2024-06-05 18:01:05 +02:00
Wojtek Figat
c82e67083f Merge branch 'IncreasedExecutionLineThickness' of https://github.com/xxSeys1/FlaxEngine into xxSeys1-IncreasedExecutionLineThickness 2024-06-05 18:00:59 +02:00
Wojtek Figat
175fd31431 Fix Delegate invoke to copy arguments values to each call instead of passing as reference 2024-06-05 18:00:00 +02:00
Wojtek Figat
3b1a96582a Fix crash in gpu memory profiler if resource name is missing
#2688
2024-06-05 17:14:44 +02:00
xxSeys1
2b46f04baf Changed how thickness is calculated
Now works with the stuff done in #2671.
2024-06-03 23:25:54 +02:00
xxSeys1
106b48f4d5 Code style fixes
Changed two if statements to be single line.
2024-06-03 23:03:21 +02:00
xxSeys1
732b34d28b Draw impulse/ execution lines thicker than data ones
Slightly increases the thickness of impulse/ execution lines for node editors to make it easier for the user to follow execution flow (and indirectly also data flow)
2024-06-03 23:00:25 +02:00
Wojtek Figat
116539ce34 Merge branch 'Tryibion-fix-cursor-show-edge-cases' 2024-06-03 19:17:58 +02:00
Wojtek Figat
e8421d4274 Merge branch 'fix-cursor-show-edge-cases' of https://github.com/Tryibion/FlaxEngine into Tryibion-fix-cursor-show-edge-cases 2024-06-03 19:17:50 +02:00
Wojtek Figat
0b9ee23a5c Merge branch 'Chikinsupu-Visject-ConnectionImprovements' 2024-06-03 14:22:04 +02:00
Wojtek Figat
2d2841d59e Merge branch 'Visject-ConnectionImprovements' of https://github.com/Chikinsupu/FlaxEngine into Chikinsupu-Visject-ConnectionImprovements 2024-06-03 14:17:11 +02:00
Wojtek Figat
a0c2f6a51e Merge branch 'HydrogenC-scroll-fix' 2024-06-03 11:09:59 +02:00
Wojtek Figat
1d946afe82 Merge branch 'scroll-fix' of https://github.com/HydrogenC/FlaxEngine into HydrogenC-scroll-fix 2024-06-03 11:09:52 +02:00
Wojtek Figat
6ea519b55a Merge branch 'GoaLitiuM-variant_fixes' 2024-06-03 11:04:18 +02:00
Wojtek Figat
2d6c49ee20 Merge branch 'variant_fixes' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-variant_fixes 2024-06-03 11:04:06 +02:00
Wojtek Figat
59b250f091 Merge branch 'GoaLitiuM-exr_crash_fix' 2024-06-03 11:01:24 +02:00
Wojtek Figat
6c347f08b6 Merge branch 'exr_crash_fix' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-exr_crash_fix 2024-06-03 11:01:11 +02:00
Wojtek Figat
304f24764b Merge branch 'GoaLitiuM-debuglog_options' 2024-06-03 10:58:57 +02:00
Wojtek Figat
3dac26ffda Merge branch 'debuglog_options' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-debuglog_options 2024-06-03 10:58:49 +02:00
Wojtek Figat
f51a442357 Fix crash when using content search in Visject surface 2024-06-03 10:54:22 +02:00
Norite SC
d4145179a9 RadialMenu and material nodes 2024-06-02 02:23:48 +02:00
bf5e5d1254 Refactor native interop internal type lookup 2024-06-01 23:20:33 +03:00
adbe43c2c2 Move generated marshallers into separate namespace
Avoid polluting the `FlaxEngine` namespace with interop related
marshallers, move those to nested namespace called `Interop` where most
of the common marshallers are placed already.
2024-06-01 23:20:32 +03:00
974e3e192b Include original type of the fields in blittable struct in comments 2024-06-01 23:17:07 +03:00
2283a15172 Refactor struct custom marshalling generation 2024-06-01 23:17:07 +03:00
c4d5e50f22 Update Editor options when window is shown 2024-06-01 23:13:34 +03:00
86d90605fc Fix Editor options data applying in realtime after first save
Reclone the data in order to not modify the currently applied options
data after save.
2024-06-01 23:13:34 +03:00
db71bf2868 Store Debug Log view options in Editor options 2024-06-01 23:13:34 +03:00
fef124a01d Fix crash when trying to import unsupported EXR-file 2024-06-01 21:36:22 +03:00
272977a521 Defer Editor EndInit after loading scripting assemblies
Assets containing deserialized data of scripting assembly structures
needs to be loaded after the scripting assemblies have been loaded.
2024-06-01 20:24:57 +03:00
dedb3d57fd Fix Variant getters returning already freed managed handles 2024-06-01 20:22:16 +03:00
Nils Hausfeld
0fc507e238 - Visject Drag and Drop now tries to get a parameter setter node while holding the alt key
- Visual Script surface now returns a setter node
2024-06-01 14:23:36 +02:00
ExMatics HydrogenC
9e9013ec43 Add missing recalculations of the thumb 2024-06-01 18:23:37 +08:00
Nils Hausfeld
0c50fa9816 - Implemented a connection line offset that increases the less curvature the line has
- Made connection lines a tiny bit thicker and added constants at the top of OutputBox to easily change the default style
2024-05-31 20:16:33 +02:00
Nils Hausfeld
83ccb79fa3 Merge branch 'master' into ItemSearchContextMenuSearchImprovements 2024-05-31 17:29:42 +02:00
Olly Rybak
8b72c063a8 Quick fix 2024-05-31 21:18:00 +10:00
Wojtek Figat
e0791eacad Fix game crashes due to scene objects C# instances removal on EndPlay before all game logic ends 2024-05-31 10:29:23 +02:00
Nils Hausfeld
11ec018933 - Improved Items list context menu item search (based on visject search improvements) 2024-05-30 19:53:54 +02:00
Nils Hausfeld
8ef1cad6fb Revert "- Improved item search for item list context menu (based on visject CM item search improvements)"
This reverts commit 6885e561db.
2024-05-30 19:48:43 +02:00
Nils Hausfeld
6885e561db - Improved item search for item list context menu (based on visject CM item search improvements) 2024-05-30 19:48:34 +02:00
Wojtek Figat
806bff19f4 Fix editor play state exceptions into errors to prevent locking editor state 2024-05-30 17:26:43 +02:00
Wojtek Figat
949057b1c3 Fix some html tags parsing to be safer 2024-05-30 17:22:43 +02:00
Wojtek Figat
5c23f4ac09 Fix project cache in editor to use invariant culture when converting numbers 2024-05-30 17:22:30 +02:00
Chandler Cox
cdd53f09b9 Add extra spacing for transform properties. 2024-05-30 10:01:32 -05:00
Chandler Cox
f3210608ae make color value box the same spacing as the others in the editor. 2024-05-30 09:07:42 -05:00
Chandler Cox
f01784108d Add check to cursor hidden/showing loops. 2024-05-30 08:47:41 -05:00
Chandler Cox
30c1068a13 Fix wrong spacing calculation. 2024-05-30 08:38:42 -05:00
Wojtek Figat
3f3df090f4 Format code in Visject 2024-05-30 12:20:40 +02:00
Wojtek Figat
390f574662 Merge branch 'Chikinsupu-Visject-ImprovedSearchAndFiltering' 2024-05-30 12:15:41 +02:00
Wojtek Figat
48a09c9783 Merge branch 'Visject-ImprovedSearchAndFiltering' of https://github.com/Chikinsupu/FlaxEngine into Chikinsupu-Visject-ImprovedSearchAndFiltering 2024-05-30 12:15:35 +02:00
Wojtek Figat
981109a6f1 Merge branch 'Chikinsupu-Visject-ConnectionCurvatureOption' 2024-05-30 12:11:45 +02:00
Wojtek Figat
2f8428db1a Merge branch 'Visject-ConnectionCurvatureOption' of https://github.com/Chikinsupu/FlaxEngine into Chikinsupu-Visject-ConnectionCurvatureOption 2024-05-30 12:11:40 +02:00
Wojtek Figat
d0ec3fa2e2 Merge branch 'Tryibion-slider-focus' 2024-05-30 12:07:25 +02:00
Wojtek Figat
9533289e57 Merge branch 'slider-focus' of https://github.com/Tryibion/FlaxEngine into Tryibion-slider-focus 2024-05-30 12:05:10 +02:00
Wojtek Figat
0f485cf77c Merge branch 'Tryibion-cwidget-size' 2024-05-30 12:01:03 +02:00
Wojtek Figat
8c8b4613d2 Merge branch 'cwidget-size' of https://github.com/Tryibion/FlaxEngine into Tryibion-cwidget-size 2024-05-30 12:00:56 +02:00
Wojtek Figat
3b872f08a8 Merge branch 'Chikinsupu-Visject-CommentRenameImprovements' 2024-05-30 11:54:36 +02:00
Wojtek Figat
e89e0159bf Merge branch 'Visject-CommentRenameImprovements' of https://github.com/Chikinsupu/FlaxEngine into Chikinsupu-Visject-CommentRenameImprovements 2024-05-30 11:46:53 +02:00
Wojtek Figat
857d2c26f4 Merge branch 'MrCapy0-Fix-Game-Compilation' 2024-05-30 11:44:40 +02:00
Wojtek Figat
49e70637db Merge branch 'Fix-Game-Compilation' of https://github.com/MrCapy0/FlaxEngine into MrCapy0-Fix-Game-Compilation 2024-05-30 11:36:16 +02:00
Wojtek Figat
72a151816a Merge branch 'Tryibion-control-update-fix' 2024-05-30 11:24:15 +02:00
Wojtek Figat
528b20dc00 Merge branch 'control-update-fix' of https://github.com/Tryibion/FlaxEngine into Tryibion-control-update-fix 2024-05-30 11:23:46 +02:00
Wojtek Figat
ce2d2b78c4 Merge branch 'Chikinsupu-Visject-ImprovedInactiveBoxes' 2024-05-30 10:37:10 +02:00
Wojtek Figat
b22c42b9e3 Merge branch 'Visject-ImprovedInactiveBoxes' of https://github.com/Chikinsupu/FlaxEngine into Chikinsupu-Visject-ImprovedInactiveBoxes 2024-05-30 10:37:04 +02:00
Wojtek Figat
377d25a1fd Merge branch 'Chikinsupu-Visject-RerouteMovingQoL' 2024-05-30 10:35:04 +02:00
Wojtek Figat
32a60c3b5c Merge branch 'Visject-RerouteMovingQoL' of https://github.com/Chikinsupu/FlaxEngine into Chikinsupu-Visject-RerouteMovingQoL 2024-05-30 10:26:29 +02:00
Wojtek Figat
3f40aff01f Merge branch 'Tryibion-header-height' 2024-05-30 10:24:31 +02:00
Chandler Cox
09563caf37 Fix header height when using HeaderAttribute with multiline label. 2024-05-29 15:48:31 -05:00
Nils Hausfeld
130fc5b54d - Cleanup 2024-05-27 23:41:01 +02:00
Nils Hausfeld
e15a848ac6 - Implemented filtering by group by using a dot as a seperator
- Added type sort priority to context sensitive search
- Now updating filters when populating groups for the first time in order to make sort priority actually work when opening context menu for the first time
- Fixed some cases where context sensitivity was applied even when context sensitive search was disabled
2024-05-27 23:19:00 +02:00
Nils Hausfeld
1729fe6993 - Added connection curvature to editor options 2024-05-26 21:41:59 +02:00
MrCapy0
cc01e88ce8 fix compilation when calling debug draw on scripts 2024-05-26 11:09:17 -04:00
Nils Hausfeld
f18715a497 - Replaced renamepopup with textbox in surface comment 2024-05-25 13:25:52 +02:00
Nils Hausfeld
d47a191d5c - Added IsActive state to boxes
- Replaced box.enabled with box.isActive on some nodes
- Made connection lines draw with alpha when connected box is inactive
2024-05-24 22:26:20 +02:00
Chandler Cox
afdae7f670 Only size ui widgets based on viewscale and not control size. 2024-05-23 16:51:31 -05:00
Chandler Cox
7c4b8758ea Fix a few edge cases for cursor showing/not showing 2024-05-22 21:10:01 -05:00
Chandler Cox
f22e559e83 Add slot spacing to uniform grid panel. 2024-05-22 20:45:37 -05:00
Wojtek Figat
9731437717 Merge branch 'abrasivetroop-edit-prefab-button' 2024-05-22 23:19:02 +02:00
Wojtek Figat
6f7bb8dbf2 Merge branch 'edit-prefab-button' of https://github.com/abrasivetroop/FlaxEngine into abrasivetroop-edit-prefab-button 2024-05-22 23:17:23 +02:00
Wojtek Figat
3dd83c52bf Merge branch 'Tryibion-outputlog-collase-save' 2024-05-22 23:16:37 +02:00
Wojtek Figat
949ac08643 Merge branch 'outputlog-collase-save' of https://github.com/Tryibion/FlaxEngine into Tryibion-outputlog-collase-save 2024-05-22 23:16:18 +02:00
Wojtek Figat
4948b1b86a Merge branch 'Tryibion-script-group' 2024-05-22 23:12:24 +02:00
Wojtek Figat
e5bf0e1b9f Merge branch 'script-group' of https://github.com/Tryibion/FlaxEngine into Tryibion-script-group 2024-05-22 23:12:18 +02:00
Wojtek Figat
b776465919 Merge branch 'Tryibion-play-game-fix' 2024-05-22 23:11:29 +02:00
Wojtek Figat
82181b28b0 Merge branch 'play-game-fix' of https://github.com/Tryibion/FlaxEngine into Tryibion-play-game-fix 2024-05-22 23:11:25 +02:00
Wojtek Figat
eb07fd7b9a Fix xml tooltips processing to ignore excessive whitespaces 2024-05-22 23:10:05 +02:00
Chandler Cox
79dbad6547 Ensure slider max and min are snapped to if the value is close to them. 2024-05-22 15:56:39 -05:00
Chandler Cox
94884fc39a Run control update even when UiCanvas skips events. 2024-05-22 14:52:30 -05:00
Chandler Cox
aec5ef8332 Add message for no first scene. 2024-05-22 14:42:20 -05:00
Chandler Cox
8e4783a0c6 Play scene if invalid first scene data in editor while selected to play game from first scene. 2024-05-22 14:38:17 -05:00
Wojtek Figat
c23f2b61cc Fix editor error when underlying int value provider returns other scalar type 2024-05-22 18:38:08 +02:00
Chandler Cox
6481897ffa Fix SliderControl not being unfocused on value change. 2024-05-22 07:52:25 -05:00
Chandler Cox
499a7c6129 change to debug log collapse 2024-05-21 07:18:56 -05:00
Chandler Cox
84fdf9cc80 Save output log collapse state. 2024-05-20 21:46:57 -05:00
Chandler Cox
f8d023ed5c Remove drop down image on scripts if no objects are in the group. 2024-05-20 21:36:44 -05:00
Wojtek Figat
5ca61d8568 Fix Convert to Parameter to check if can perform action 2024-05-20 22:39:46 +02:00
Nils Hausfeld
58998f4576 - Reroute node now always checks if the mouse is inside the "connecting bounds" and changes the cursor accordingly
- Slightly increased "connecting bounds" padding
2024-05-20 21:18:12 +02:00
Wojtek Figat
c486577b07 Fix TAA in editor's debug view modes 2024-05-20 19:03:28 +02:00
Wojtek Figat
a69c8ce6a2 Revert 73f68c102d and reopen #2610 2024-05-20 18:37:15 +02:00
Wojtek Figat
e527783e55 Fix missing curve initialization when loading from json 2024-05-20 18:36:41 +02:00
Wojtek Figat
4d9c92dd49 Fix editor hang when scene deserialization fails 2024-05-20 18:24:20 +02:00
Wojtek Figat
9b01229e58 Fix regression in GPU Particle collisions in editor 2024-05-20 18:12:35 +02:00
Wojtek Figat
e3a030fad8 Update version 2024-05-20 17:10:23 +02:00
Wojtek Figat
cb878294ea Minor fixes 2024-05-20 17:09:59 +02:00
Abra
b2fc5e8fd3 increase horizontal slot amount 2024-05-20 17:01:07 +03:00
Abra
4fb42319ef add edit prefab button 2024-05-20 16:59:32 +03:00
Wojtek Figat
1bd1aca0f0 Merge branch 'GoaLitiuM-richtextbox_fix' 2024-05-20 14:43:26 +02:00
Wojtek Figat
b433312042 Merge branch 'richtextbox_fix' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-richtextbox_fix 2024-05-20 14:43:09 +02:00
Wojtek Figat
1041b1b86d Merge branch 'tecnessino-patch-2' 2024-05-20 14:23:20 +02:00
Wojtek Figat
1ace5fd10d Merge branch 'patch-2' of https://github.com/tecnessino/FlaxEngine into tecnessino-patch-2 2024-05-20 14:23:03 +02:00
Wojtek Figat
cfc9f73744 Fix deadlock between content storage and asset that is being updated during load
#2621
2024-05-20 14:22:03 +02:00
Wojtek Figat
2418167182 Merge branch 'Tryibion-update-cursor-unlock-text' 2024-05-20 11:47:07 +02:00
Wojtek Figat
52090d3a6b Merge branch 'update-cursor-unlock-text' of https://github.com/Tryibion/FlaxEngine into Tryibion-update-cursor-unlock-text 2024-05-20 11:47:01 +02:00
Wojtek Figat
73f68c102d Revert #2421 two bone ik to solve #2610 regression 2024-05-20 11:19:03 +02:00
tecnessino
862dd1e5f1 Change comment 2024-05-18 20:37:43 +02:00
58351d1989 Fix RichTextBox not drawing the last character 2024-05-18 00:00:27 +03:00
Chandler Cox
6705205e2f Update cursor unlock text with correct input key bind. 2024-05-17 09:41:02 -05:00
Wojtek Figat
2cdd0ff644 Fix test compilation 2024-05-17 15:47:50 +02:00
Wojtek Figat
69ae841f64 Merge branch 'Tryibion-sel-prefab-clear-search' 2024-05-17 15:31:04 +02:00
Wojtek Figat
7f8700288f Merge branch 'sel-prefab-clear-search' of https://github.com/Tryibion/FlaxEngine into Tryibion-sel-prefab-clear-search 2024-05-17 15:30:59 +02:00
Wojtek Figat
f87dec6ca6 Merge branch 'Tryibion-edit-options-move' 2024-05-17 15:30:50 +02:00
Wojtek Figat
65a6c0aed5 Merge branch 'edit-options-move' of https://github.com/Tryibion/FlaxEngine into Tryibion-edit-options-move 2024-05-17 15:30:44 +02:00
Wojtek Figat
f6dd0decfb Merge branch 'Tryibion-prefab-camera' 2024-05-17 15:30:26 +02:00
Wojtek Figat
816984542a Merge branch 'prefab-camera' of https://github.com/Tryibion/FlaxEngine into Tryibion-prefab-camera 2024-05-17 15:30:18 +02:00
Chandler Cox
3837e8b263 Rename "Options" to "Editor Options" and move under the "Edit" menu. 2024-05-16 23:20:44 -05:00
Chandler Cox
47b3141f18 Clear item search on select prefab 2024-05-16 23:00:32 -05:00
Chandler Cox
e10ee3e55a Force camera model to load in prefabs. 2024-05-16 16:49:56 -05:00
Wojtek Figat
0a4e89e29b Fix UI navigation when using multiple canvases
#2574
2024-05-16 16:12:53 +02:00
Wojtek Figat
0765fa92b5 Add option to move all selected UI Controls while holding Shift key 2024-05-16 14:11:11 +02:00
Wojtek Figat
2529312152 Refactor Color.FromRGBA and add matching old logic Color.FromARGB
2592
2024-05-16 13:45:29 +02:00
Wojtek Figat
3404643636 Add better error messages to NetworkReplicator::SetObjectOwnership for incorrect usage 2024-05-16 10:49:51 +02:00
Wojtek Figat
6b9f6ac82e Fix incorrect async methods used as RPCs (not supported now) 2024-05-16 10:35:17 +02:00
Wojtek Figat
ab5bb79754 Fix regression in collections editing after improving ReadOnly option 2024-05-16 10:34:57 +02:00
Wojtek Figat
58f95d6ce3 Simplify 6f2bd0e932 2024-05-15 23:49:46 +02:00
Wojtek Figat
1cd2f6a070 Fix compilation when using non-strongly typed enum as default value 2024-05-15 13:23:30 +02:00
Wojtek Figat
35ddfc2455 Add test case of nested types in scripting
#2582 #2591
2024-05-15 13:09:51 +02:00
Wojtek Figat
17d1d87268 Merge branch 'GoaLitiuM-nested_type_fixes' 2024-05-15 12:51:57 +02:00
Wojtek Figat
fd871ce830 Merge branch 'nested_type_fixes' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-nested_type_fixes 2024-05-15 12:50:44 +02:00
Wojtek Figat
b4a4a8a591 Minor code cleanup 2024-05-15 12:40:08 +02:00
Wojtek Figat
24e4015425 Merge branch 'Tryibion-font-case' 2024-05-15 12:30:43 +02:00
Wojtek Figat
c670887b1a Merge branch 'font-case' of https://github.com/Tryibion/FlaxEngine into Tryibion-font-case 2024-05-15 12:30:39 +02:00
Wojtek Figat
d3cd6a461b Merge branch 'Tryibion-ui-edit-handles' 2024-05-15 12:26:25 +02:00
Wojtek Figat
2625a9d762 Merge branch 'ui-edit-handles' of https://github.com/Tryibion/FlaxEngine into Tryibion-ui-edit-handles 2024-05-15 12:26:20 +02:00
Wojtek Figat
4fdd9a242b Merge branch 'Tryibion-add-script' 2024-05-15 12:26:06 +02:00
Wojtek Figat
a6e8e6f749 Merge branch 'add-script' of https://github.com/Tryibion/FlaxEngine into Tryibion-add-script 2024-05-15 12:25:59 +02:00
Wojtek Figat
03eabbcf63 Merge branch 'Tryibion-control-trans-dup' 2024-05-15 12:25:34 +02:00
Wojtek Figat
13f94dcf11 Merge branch 'control-trans-dup' of https://github.com/Tryibion/FlaxEngine into Tryibion-control-trans-dup 2024-05-15 12:25:28 +02:00
Wojtek Figat
3b44062eb0 Merge branch 'Tryibion-checkerboard-colorpicker' 2024-05-15 12:25:13 +02:00
Wojtek Figat
1457637707 Merge branch 'checkerboard-colorpicker' of https://github.com/Tryibion/FlaxEngine into Tryibion-checkerboard-colorpicker 2024-05-15 12:25:08 +02:00
Wojtek Figat
d28567111f Merge branch 'Tryibion-treenode-guidelines' 2024-05-15 12:24:17 +02:00
Wojtek Figat
1c7f06e570 Merge branch 'treenode-guidelines' of https://github.com/Tryibion/FlaxEngine into Tryibion-treenode-guidelines 2024-05-15 12:24:12 +02:00
Wojtek Figat
63cc0fef2e Merge branch 'Tryibion-tooltip-text-padding' 2024-05-15 12:23:52 +02:00
Wojtek Figat
57084b3d6c Merge branch 'tooltip-text-padding' of https://github.com/Tryibion/FlaxEngine into Tryibion-tooltip-text-padding 2024-05-15 12:23:47 +02:00
Wojtek Figat
fa23619f08 Merge branch 'Tryibion-scroll-colors' 2024-05-15 12:23:12 +02:00
Wojtek Figat
1f2456fc67 Merge branch 'scroll-colors' of https://github.com/Tryibion/FlaxEngine into Tryibion-scroll-colors 2024-05-15 12:23:08 +02:00
Wojtek Figat
0b71e906a6 Merge branch 'Tryibion-textbox-add' 2024-05-15 12:22:47 +02:00
Wojtek Figat
2e59c35a44 Merge branch 'textbox-add' of https://github.com/Tryibion/FlaxEngine into Tryibion-textbox-add 2024-05-15 12:22:40 +02:00
Wojtek Figat
6f2bd0e932 Another attempt on 6a883bc7c6 2024-05-15 11:22:07 +02:00
Wojtek Figat
6a883bc7c6 Revert file handles bug 2024-05-14 09:03:52 +02:00
Chandler Cox
17de6388ca Code fix 2024-05-13 17:42:37 -05:00
Chandler Cox
e028d263f1 Remove unused include. 2024-05-13 16:38:38 -05:00
Chandler Cox
6962ed6730 Fix case spelling 2024-05-13 16:38:10 -05:00
Chandler Cox
b66d50ae1b Add font and case options to Label and Textbox 2024-05-13 16:34:23 -05:00
Chandler Cox
675ce71935 Draw hover before selection so that way ui selection is drawn on top. 2024-05-13 12:45:59 -05:00
Chandler Cox
833f844d59 Minor improvements to ui editor widget drawing. 2024-05-13 12:38:11 -05:00
Wojtek Figat
af08dc1c69 Fix ReadOnly attribute handling in collection editors 2024-05-13 16:08:50 +02:00
Chandler Cox
07628d2ec7 Clean up code 2024-05-11 21:31:00 -05:00
Chandler Cox
aac3dbfe09 Fix control transform duplicating when changing anchor. 2024-05-11 21:29:45 -05:00
Chandler Cox
185f24ce49 Fix value alpha transparency being applied twice to preview color. 2024-05-11 20:19:51 -05:00
77e29109ee Fix native internal type name for deeply nested types 2024-05-11 15:48:49 +03:00
8d89b9efb0 Fix internal type name for nested blittable element types 2024-05-11 15:48:43 +03:00
Chandler Cox
b2fee31a13 Add checkerboard background to color picker dialog color. 2024-05-10 20:30:14 -05:00
Chandler Cox
fc7628e2ee Add tree node guidlines 2024-05-10 19:22:23 -05:00
Chandler Cox
2e3e4959d6 Add width padding for tooltip 2024-05-10 17:18:10 -05:00
Chandler Cox
f22105c2c3 Allow adding script via drag drop 2024-05-10 16:58:40 -05:00
Chandler Cox
533902d185 Change panel scroll bar style editor order. 2024-05-10 15:04:27 -05:00
Wojtek Figat
68653fa91f Add small code optimizations 2024-05-10 12:27:28 +02:00
Chandler Cox
dc0aa61a14 Add scrollbar colors to Panel 2024-05-09 22:14:08 -05:00
Chandler Cox
ee790ff3a9 Change colors for tabs to be seen better. 2024-05-09 21:53:22 -05:00
Chandler Cox
a2a3926aee Expose colors in scrollbar 2024-05-09 21:53:04 -05:00
Chandler Cox
9a70344c1f Fix carrot location on text box with no text. Add vertical and horizontal alignment options to textbox. 2024-05-09 21:31:54 -05:00
Wojtek Figat
44006dd533 Various code improvements 2024-05-09 18:59:09 +02:00
Wojtek Figat
f6aabf2d14 Optimize navmesh building and reduce scene lock time 2024-05-09 18:58:47 +02:00
Wojtek Figat
dc1f15f18d Add OnStaticFlagsChanged to Actor 2024-05-09 16:55:05 +02:00
Wojtek Figat
7d7808af8f Remove default value tooltips from post process docs to prevent errors 2024-05-09 10:56:42 +02:00
Wojtek Figat
5029584a9f Fix crash when Visual Script event binding instance is invalid
#2548
2024-05-09 10:17:23 +02:00
Wojtek Figat
f353d3f114 Fix looping root motion 2024-05-09 10:16:45 +02:00
Wojtek Figat
667e8bc293 Minor cleanup in anim code 2024-05-09 10:16:34 +02:00
Wojtek Figat
2edb9cc4d8 Fix compilation warnings when using 64-bit coords 2024-05-08 23:24:23 +02:00
Wojtek Figat
7018666a8c Add layer masking for PostFxVolume against Camera's RenderLayersMask
#2573
2024-05-08 22:42:35 +02:00
Wojtek Figat
f04926ad94 Merge branch 'GoaLitiuM-treenode_expanded_fix' 2024-05-08 19:30:55 +02:00
50f5f0acd9 Fix TreeNode rendering issues with expanded nodes 2024-05-08 20:15:55 +03:00
Wojtek Figat
3745979b81 Add attributes for game into AndroidManifest 2024-05-08 18:49:16 +02:00
Wojtek Figat
db15f6f08a Add For Distribution to be enabled by default in Release builds
#2571
2024-05-08 18:48:55 +02:00
Wojtek Figat
e1a2f51d5a Merge branch 'GoaLitiuM-editor_font_validation' 2024-05-08 18:17:53 +02:00
Wojtek Figat
a8e1fd7a4a Merge branch 'editor_font_validation' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-editor_font_validation 2024-05-08 18:17:46 +02:00
Wojtek Figat
d46ef6ac92 Merge branch 'Tryibion-add-shift-scroll' 2024-05-08 18:17:20 +02:00
Wojtek Figat
36d21b27c7 Merge branch 'add-shift-scroll' of https://github.com/Tryibion/FlaxEngine into Tryibion-add-shift-scroll 2024-05-08 18:17:13 +02:00
Wojtek Figat
b1636c27e7 Merge branch 'Tryibion-Move-control-transform' 2024-05-08 17:39:48 +02:00
Wojtek Figat
5d32fc6c5e Merge branch 'Move-control-transform' of https://github.com/Tryibion/FlaxEngine into Tryibion-Move-control-transform 2024-05-08 17:31:47 +02:00
Wojtek Figat
065dc474c0 Merge branch 'Tryibion-game-window-focus-issue' 2024-05-08 17:31:16 +02:00
Wojtek Figat
1fb7b24aad Merge branch 'game-window-focus-issue' of https://github.com/Tryibion/FlaxEngine into Tryibion-game-window-focus-issue 2024-05-08 17:31:08 +02:00
Wojtek Figat
f0b72aa025 Merge branch 'Tryibion-color-picker' 2024-05-08 17:30:50 +02:00
Wojtek Figat
058077736b Merge branch 'color-picker' of https://github.com/Tryibion/FlaxEngine into Tryibion-color-picker 2024-05-08 17:30:45 +02:00
Wojtek Figat
b02f011627 Merge branch 'GoaLitiuM-drawtext_fix' 2024-05-08 10:34:33 +02:00
ea04c746fd Fix Editor not launching if custom interface fonts are missing 2024-05-07 21:18:09 +03:00
97454fc82e Fix drawing an extra character with Render2D.DrawText 2024-05-07 20:10:05 +03:00
Chandler Cox
4a6afdb108 Small fixes for color picker. 2024-05-07 08:41:23 -05:00
Wojtek Figat
65e852600a Merge branch 'Tryibion-skip-empty-layers' 2024-05-05 22:56:47 +02:00
Wojtek Figat
fedd990c13 Merge branch 'skip-empty-layers' of https://github.com/Tryibion/FlaxEngine into Tryibion-skip-empty-layers 2024-05-05 22:56:41 +02:00
Wojtek Figat
c0329abe40 Merge branch 'Tryibion-fix-properties-1st-offset' 2024-05-05 22:55:30 +02:00
Wojtek Figat
d8850a56a8 Merge branch 'fix-properties-1st-offset' of https://github.com/Tryibion/FlaxEngine into Tryibion-fix-properties-1st-offset 2024-05-05 22:55:26 +02:00
Wojtek Figat
e171bb06ec Merge branch 'GoaLitiuM-unbox_array_fix' 2024-05-05 22:54:18 +02:00
Wojtek Figat
3825e07adc Merge branch 'unbox_array_fix' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-unbox_array_fix 2024-05-05 22:54:12 +02:00
Wojtek Figat
db8adf7d96 Fix creating virtual terrain collision of actor that is not in a game 2024-05-05 22:50:12 +02:00
e77ae12b9b Fix unboxing of array type Variants 2024-05-05 13:15:54 +03:00
Chandler Cox
bf4e4aeaf6 Fix bottom offset for last property label and property 2024-05-04 22:32:00 -05:00
Chandler Cox
2107b069db Fix odd offset between 1st property and property label. 2024-05-04 19:25:56 -05:00
Chandler Cox
ea2005dacb Add layer number to LayerMask UI 2024-05-04 18:08:53 -05:00
Chandler Cox
d5cded8aaa Skip empty layers for LayerMask Editor 2024-05-04 17:51:27 -05:00
Chandler Cox
430b22d5d7 Dont unfocus game window while cursor is not visible unless the lock mode is none. 2024-05-04 17:37:32 -05:00
Wojtek Figat
9d830eb1e2 Fix crash when using scripting object as interface implementation in object property displayed in Editor
#2493
2024-05-02 18:31:30 +02:00
Wojtek Figat
7e3f84f95e Merge branch 'Tryibion-gg-keep-last-type' 2024-05-02 15:57:50 +02:00
Wojtek Figat
cddee38d71 Merge branch 'gg-keep-last-type' of https://github.com/Tryibion/FlaxEngine into Tryibion-gg-keep-last-type 2024-05-02 15:57:45 +02:00
Wojtek Figat
e030d0461b Merge branch 'Tryibion-smoothstep-node-width' 2024-05-02 15:57:31 +02:00
Wojtek Figat
4978c8e0d9 Merge branch 'smoothstep-node-width' of https://github.com/Tryibion/FlaxEngine into Tryibion-smoothstep-node-width 2024-05-02 15:57:20 +02:00
Wojtek Figat
dc7b7e6e10 Merge branch 'Tryibion-rename-trim' 2024-05-02 15:56:33 +02:00
Wojtek Figat
1e3eb11b94 Merge branch 'rename-trim' of https://github.com/Tryibion/FlaxEngine into Tryibion-rename-trim 2024-05-02 15:56:25 +02:00
Wojtek Figat
b15b231b85 Merge branch 'Tryibion-windows-hide-cursor' 2024-05-02 15:55:56 +02:00
Wojtek Figat
262992571a Merge branch 'windows-hide-cursor' of https://github.com/Tryibion/FlaxEngine into Tryibion-windows-hide-cursor 2024-05-02 15:55:50 +02:00
Wojtek Figat
352bf3f9a7 Merge branch 'Tryibion-fix-toolbox-panel-size' 2024-05-02 15:55:29 +02:00
Chandler Cox
9683868767 Add shift scroll for panels and textbox 2024-05-01 16:12:53 -05:00
Chandler Cox
40284fbbf8 Fix smooth step visject node width 2024-05-01 14:05:10 -05:00
Chandler Cox
0c86a900da Default gameplay global type selection to last selected type. 2024-05-01 13:54:41 -05:00
Chandler Cox
c1e3eaeab1 Force windows cursor to show or hide based on cursor hidden value 2024-05-01 13:23:56 -05:00
Chandler Cox
3c487dff47 Trim actor name on rename. 2024-05-01 12:01:01 -05:00
Chandler Cox
2260d79e26 Trim content item name on rename 2024-05-01 11:54:07 -05:00
Chandler Cox
3209320547 Add margin to item tree in toolbox 2024-04-30 15:05:58 -05:00
Chandler Cox
d1db06a9bb Change text alignment to far on some control transform properties 2024-04-29 19:44:49 -05:00
Chandler Cox
1c1d2fd96f Fix still showing some control transform properties in wrong spot. 2024-04-29 19:38:36 -05:00
Chandler Cox
2e5ad8c48a Always set control transform under general tab 2024-04-29 18:28:04 -05:00
Chandler Cox
9a6f866956 Move control transform to be under general group in layout. 2024-04-29 18:24:01 -05:00
Menotdan
d8ca8f5985 Attempt to fix compilation error. 2024-03-26 21:26:29 -04:00
Menotdan
ac36297e27 Add basic support for log contexts. 2024-03-26 21:09:18 -04:00
z1dev
7fef21218e Alternative Rectangle function names for naming consistency. 2024-03-21 14:13:24 +01:00
7aa4ae1782 Fix assigning null values into value types in Custom Editor
Resets back to previous value instead of setting the editor value to
empty.
2024-03-16 14:11:49 +02:00
dd7739f95e Avoid deserializing clipboard content in Custom Editor paste checks 2024-03-16 14:11:46 +02:00
ruan
203f5d06d1 Fix typo 2024-02-10 20:46:05 -04:00
ruan
c6515da8c9 Improve rename window style and refactor 2024-02-10 20:36:42 -04:00
ruan
5d61e45ecd Add rename multiple actors 2024-02-04 10:42:29 -04:00
Edu Garcia
2bec653b81 Add color picker option to accept changes on dismissal 2023-10-07 10:15:17 +01:00
533 changed files with 83763 additions and 7405 deletions

View File

@@ -1,4 +1,4 @@
# Redirect to our own Git LFS server # Redirect to our own Git LFS server
[lfs] [lfs]
url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs" #url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
locksverify = false locksverify = false

BIN
Content/Engine/DefaultRadialMenu.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Shaders/Editor/Grid.flax (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -3,8 +3,8 @@
"Version": { "Version": {
"Major": 1, "Major": 1,
"Minor": 8, "Minor": 8,
"Revision": 1, "Revision": 2,
"Build": 6511 "Build": 6512
}, },
"Company": "Flax", "Company": "Flax",
"Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.", "Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.",
@@ -13,6 +13,7 @@
"Configuration": { "Configuration": {
"UseCSharp": true, "UseCSharp": true,
"UseLargeWorlds": false, "UseLargeWorlds": false,
"UseDotNet": true "UseDotNet": true,
"UseSDL": true
} }
} }

View File

@@ -74,6 +74,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION_005FMEMBER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION_005FMEMBER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AI/@EntryIndexedValue">AI</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AI/@EntryIndexedValue">AI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ARGB/@EntryIndexedValue">ARGB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LO/@EntryIndexedValue">LO</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LO/@EntryIndexedValue">LO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RPC/@EntryIndexedValue">RPC</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RPC/@EntryIndexedValue">RPC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SDK/@EntryIndexedValue">SDK</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SDK/@EntryIndexedValue">SDK</s:String>

View File

@@ -61,6 +61,8 @@ namespace FlaxEditor.Content.GUI
private bool _isRubberBandSpanning; private bool _isRubberBandSpanning;
private Float2 _mousePressLocation; private Float2 _mousePressLocation;
private Rectangle _rubberBandRectangle; private Rectangle _rubberBandRectangle;
private bool _isCutting;
private List<ContentItem> _cutItems = new List<ContentItem>();
private bool _validDragOver; private bool _validDragOver;
private DragActors _dragActors; private DragActors _dragActors;
@@ -83,9 +85,9 @@ namespace FlaxEditor.Content.GUI
public event Action<List<ContentItem>> OnDelete; public event Action<List<ContentItem>> OnDelete;
/// <summary> /// <summary>
/// Called when user wants to paste the files/folders. /// Called when user wants to paste the files/folders. Bool is for cutting.
/// </summary> /// </summary>
public event Action<string[]> OnPaste; public event Action<string[], bool> OnPaste;
/// <summary> /// <summary>
/// Called when user wants to duplicate the item(s). /// Called when user wants to duplicate the item(s).
@@ -210,6 +212,12 @@ namespace FlaxEditor.Content.GUI
}), }),
new InputActionsContainer.Binding(options => options.Copy, Copy), new InputActionsContainer.Binding(options => options.Copy, Copy),
new InputActionsContainer.Binding(options => options.Paste, Paste), new InputActionsContainer.Binding(options => options.Paste, Paste),
new InputActionsContainer.Binding(options => options.Cut, Cut),
new InputActionsContainer.Binding(options => options.Undo, () =>
{
if (_isCutting)
UpdateContentItemCut(false);
}),
new InputActionsContainer.Binding(options => options.Duplicate, Duplicate), new InputActionsContainer.Binding(options => options.Duplicate, Duplicate),
}); });
} }
@@ -462,6 +470,7 @@ namespace FlaxEditor.Content.GUI
/// </summary> /// </summary>
public void Duplicate() public void Duplicate()
{ {
UpdateContentItemCut(false);
OnDuplicate?.Invoke(_selection); OnDuplicate?.Invoke(_selection);
} }
@@ -475,6 +484,7 @@ namespace FlaxEditor.Content.GUI
var files = _selection.ConvertAll(x => x.Path).ToArray(); var files = _selection.ConvertAll(x => x.Path).ToArray();
Clipboard.Files = files; Clipboard.Files = files;
UpdateContentItemCut(false);
} }
/// <summary> /// <summary>
@@ -496,7 +506,36 @@ namespace FlaxEditor.Content.GUI
if (files == null || files.Length == 0) if (files == null || files.Length == 0)
return; return;
OnPaste?.Invoke(files); OnPaste?.Invoke(files, _isCutting);
UpdateContentItemCut(false);
}
/// <summary>
/// Cuts the items.
/// </summary>
public void Cut()
{
Copy();
UpdateContentItemCut(true);
}
private void UpdateContentItemCut(bool cut)
{
_isCutting = cut;
// Add selection to cut list
if (cut)
_cutItems.AddRange(_selection);
// Update item with if it is being cut.
foreach (var item in _cutItems)
{
item.IsBeingCut = cut;
}
// Clean up cut items
if (!cut)
_cutItems.Clear();
} }
/// <summary> /// <summary>

View File

@@ -58,10 +58,10 @@ namespace FlaxEngine.Tools
FieldInfo[] fields = typeof(CustomMaxSizes).GetFields(); FieldInfo[] fields = typeof(CustomMaxSizes).GetFields();
for (int i = 0; i < fields.Length; i++) for (int i = 0; i < fields.Length; i++)
{ {
var field = fields[i]; var @field = fields[i];
if (field.Name.Equals("value__")) if (@field.Name.Equals("value__"))
continue; continue;
if (value == (int)field.GetRawConstantValue()) if (value == (int)@field.GetRawConstantValue())
return (CustomMaxSizes)value; return (CustomMaxSizes)value;
} }
return CustomMaxSizes._8192; return CustomMaxSizes._8192;

View File

@@ -182,6 +182,11 @@ namespace FlaxEditor.Content
/// </summary> /// </summary>
public const int DefaultHeight = (DefaultThumbnailSize + 2 * DefaultMarginSize + DefaultTextHeight); public const int DefaultHeight = (DefaultThumbnailSize + 2 * DefaultMarginSize + DefaultTextHeight);
/// <summary>
/// Whether the item is being but.
/// </summary>
public bool IsBeingCut;
private ContentFolder _parentFolder; private ContentFolder _parentFolder;
private bool _isMouseDown; private bool _isMouseDown;
@@ -747,6 +752,12 @@ namespace FlaxEditor.Content
Render2D.PushClip(ref textRect); Render2D.PushClip(ref textRect);
Render2D.DrawText(style.FontMedium, ShowFileExtension || view.ShowFileExtensions ? FileName : ShortName, textRect, style.Foreground, nameAlignment, TextAlignment.Center, TextWrapping.WrapWords, 1f, 0.95f); Render2D.DrawText(style.FontMedium, ShowFileExtension || view.ShowFileExtensions ? FileName : ShortName, textRect, style.Foreground, nameAlignment, TextAlignment.Center, TextWrapping.WrapWords, 1f, 0.95f);
Render2D.PopClip(); Render2D.PopClip();
if (IsBeingCut)
{
var color = style.LightBackground.AlphaMultiplied(0.5f);
Render2D.FillRectangle(clientRect, color);
}
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -100,12 +100,16 @@ namespace FlaxEditor.Content
/// <inheritdoc /> /// <inheritdoc />
public object GetValue(object obj) public object GetValue(object obj)
{ {
if (!_type.Asset)
throw new TargetException("Missing Visual Script asset.");
return _type.Asset.GetScriptInstanceParameterValue(_parameter.Name, (Object)obj); return _type.Asset.GetScriptInstanceParameterValue(_parameter.Name, (Object)obj);
} }
/// <inheritdoc /> /// <inheritdoc />
public void SetValue(object obj, object value) public void SetValue(object obj, object value)
{ {
if (!_type.Asset)
throw new TargetException("Missing Visual Script asset.");
_type.Asset.SetScriptInstanceParameterValue(_parameter.Name, (Object)obj, value); _type.Asset.SetScriptInstanceParameterValue(_parameter.Name, (Object)obj, value);
} }
} }

View File

@@ -166,6 +166,18 @@ namespace FlaxEditor.Content
/// <inheritdoc /> /// <inheritdoc />
public override string Name { get; } = Utilities.Utils.GetPropertyNameUI(typeof(T).Name); public override string Name { get; } = Utilities.Utils.GetPropertyNameUI(typeof(T).Name);
private SpriteHandle _thumbnail;
public SpawnableJsonAssetProxy()
{
_thumbnail = SpriteHandle.Invalid;
}
public SpawnableJsonAssetProxy(SpriteHandle thumbnail)
{
_thumbnail = thumbnail;
}
/// <inheritdoc /> /// <inheritdoc />
public override bool CanCreate(ContentFolder targetLocation) public override bool CanCreate(ContentFolder targetLocation)
{ {
@@ -178,6 +190,12 @@ namespace FlaxEditor.Content
Editor.SaveJsonAsset(outputPath, new T()); Editor.SaveJsonAsset(outputPath, new T());
} }
/// <inheritdoc />
public override AssetItem ConstructItem(string path, string typeName, ref Guid id)
{
return _thumbnail.IsValid ? new JsonAssetItem(path, id, typeName, _thumbnail) : base.ConstructItem(path, typeName, ref id);
}
/// <inheritdoc /> /// <inheritdoc />
public override string TypeName { get; } = typeof(T).FullName; public override string TypeName { get; } = typeof(T).FullName;
} }

View File

@@ -365,7 +365,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
Platform::CreateProcess(procSettings); Platform::CreateProcess(procSettings);
} }
#endif #endif
const bool distributionPackage = buildSettings->ForDistribution; const bool distributionPackage = buildSettings->ForDistribution || data.Configuration == BuildConfiguration::Release;
{ {
CreateProcessSettings procSettings; CreateProcessSettings procSettings;
procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug")); procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug"));

View File

@@ -111,6 +111,11 @@ namespace FlaxEditor.CustomEditors
/// </summary> /// </summary>
public PropertyNameLabel LinkedLabel; public PropertyNameLabel LinkedLabel;
/// <summary>
/// Gets the layout for this editor. Used to calculate bounds.
/// </summary>
public LayoutElementsContainer Layout => _layout;
internal virtual void Initialize(CustomEditorPresenter presenter, LayoutElementsContainer layout, ValueContainer values) internal virtual void Initialize(CustomEditorPresenter presenter, LayoutElementsContainer layout, ValueContainer values)
{ {
_layout = layout; _layout = layout;
@@ -659,7 +664,7 @@ namespace FlaxEditor.CustomEditors
} }
} }
if (obj == null || Values.Type.IsInstanceOfType(obj)) if ((obj == null && !Values.Type.IsValueType) || Values.Type.IsInstanceOfType(obj))
{ {
result = obj; result = obj;
return true; return true;
@@ -671,20 +676,7 @@ namespace FlaxEditor.CustomEditors
/// <summary> /// <summary>
/// Gets a value indicating whether can paste value from the system clipboard to the property value container. /// Gets a value indicating whether can paste value from the system clipboard to the property value container.
/// </summary> /// </summary>
public bool CanPaste public bool CanPaste => !string.IsNullOrEmpty(Clipboard.Text);
{
get
{
try
{
return GetClipboardObject(out _, false);
}
catch
{
return false;
}
}
}
/// <summary> /// <summary>
/// Sets the value from the system clipboard. /// Sets the value from the system clipboard.

View File

@@ -52,13 +52,18 @@ namespace FlaxEditor.CustomEditors
// Check if use provided editor // Check if use provided editor
if (overrideEditor != null) if (overrideEditor != null)
return overrideEditor; return overrideEditor;
ScriptType targetType = values.Type;
// Special case if property is a pure object type and all values are the same type // Special case if property is a pure object type and all values are the same type
if (values.Type.Type == typeof(object) && values.Count > 0 && values[0] != null && !values.HasDifferentTypes) if (targetType.Type == typeof(object) && values.Count > 0 && values[0] != null && !values.HasDifferentTypes)
return CreateEditor(TypeUtils.GetObjectType(values[0]), canUseRefPicker); return CreateEditor(TypeUtils.GetObjectType(values[0]), canUseRefPicker);
// Special case if property is interface but the value is implemented as Scripting Object that should use reference picker
if (targetType.IsInterface && canUseRefPicker && values.Count > 0 && values[0] is FlaxEngine.Object)
return new DummyEditor();
// Use editor for the property type // Use editor for the property type
return CreateEditor(values.Type, canUseRefPicker); return CreateEditor(targetType, canUseRefPicker);
} }
internal static CustomEditor CreateEditor(ScriptType targetType, bool canUseRefPicker = true) internal static CustomEditor CreateEditor(ScriptType targetType, bool canUseRefPicker = true)

View File

@@ -67,19 +67,35 @@ namespace FlaxEditor.CustomEditors.Dedicated
// Use default prefab instance as a reference for the editor // Use default prefab instance as a reference for the editor
Values.SetReferenceValue(prefabInstance); Values.SetReferenceValue(prefabInstance);
// Add some UI if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter)
var panel = layout.CustomContainer<UniformGridPanel>(); {
panel.CustomControl.Height = 20.0f; // Add some UI
panel.CustomControl.SlotsVertically = 1; var panel = layout.CustomContainer<UniformGridPanel>();
panel.CustomControl.SlotsHorizontally = 2; panel.CustomControl.Height = 20.0f;
panel.CustomControl.SlotsVertically = 1;
panel.CustomControl.SlotsHorizontally = 3;
// Selecting actor prefab asset // Selecting actor prefab asset
var selectPrefab = panel.Button("Select Prefab"); var selectPrefab = panel.Button("Select Prefab");
selectPrefab.Button.Clicked += () => Editor.Instance.Windows.ContentWin.Select(prefab); selectPrefab.Button.Clicked += () =>
{
Editor.Instance.Windows.ContentWin.ClearItemsSearch();
Editor.Instance.Windows.ContentWin.Select(prefab);
};
// Viewing changes applied to this actor // Edit selected prefab asset
var viewChanges = panel.Button("View Changes"); var editPrefab = panel.Button("Edit Prefab");
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f)); editPrefab.Button.Clicked += () =>
{
Editor.Instance.Windows.ContentWin.ClearItemsSearch();
Editor.Instance.Windows.ContentWin.Select(prefab);
Editor.Instance.Windows.ContentWin.Open(Editor.Instance.Windows.ContentWin.View.Selection[0]);
};
// Viewing changes applied to this actor
var viewChanges = panel.Button("View Changes");
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
}
// Link event to update editor on prefab apply // Link event to update editor on prefab apply
_linkedPrefabId = prefab.ID; _linkedPrefabId = prefab.ID;

View File

@@ -38,15 +38,15 @@ namespace FlaxEditor.CustomEditors.Dedicated
_gizmoMode = new ClothPaintingGizmoMode(); _gizmoMode = new ClothPaintingGizmoMode();
var projectCache = Editor.Instance.ProjectCache; var projectCache = Editor.Instance.ProjectCache;
if (projectCache.TryGetCustomData("ClothGizmoPaintValue", out var cachedPaintValue)) if (projectCache.TryGetCustomData("ClothGizmoPaintValue", out string cachedPaintValue))
_gizmoMode.PaintValue = JsonSerializer.Deserialize<float>(cachedPaintValue); _gizmoMode.PaintValue = JsonSerializer.Deserialize<float>(cachedPaintValue);
if (projectCache.TryGetCustomData("ClothGizmoContinuousPaint", out var cachedContinuousPaint)) if (projectCache.TryGetCustomData("ClothGizmoContinuousPaint", out string cachedContinuousPaint))
_gizmoMode.ContinuousPaint = JsonSerializer.Deserialize<bool>(cachedContinuousPaint); _gizmoMode.ContinuousPaint = JsonSerializer.Deserialize<bool>(cachedContinuousPaint);
if (projectCache.TryGetCustomData("ClothGizmoBrushFalloff", out var cachedBrushFalloff)) if (projectCache.TryGetCustomData("ClothGizmoBrushFalloff", out string cachedBrushFalloff))
_gizmoMode.BrushFalloff = JsonSerializer.Deserialize<float>(cachedBrushFalloff); _gizmoMode.BrushFalloff = JsonSerializer.Deserialize<float>(cachedBrushFalloff);
if (projectCache.TryGetCustomData("ClothGizmoBrushSize", out var cachedBrushSize)) if (projectCache.TryGetCustomData("ClothGizmoBrushSize", out string cachedBrushSize))
_gizmoMode.BrushSize = JsonSerializer.Deserialize<float>(cachedBrushSize); _gizmoMode.BrushSize = JsonSerializer.Deserialize<float>(cachedBrushSize);
if (projectCache.TryGetCustomData("ClothGizmoBrushStrength", out var cachedBrushStrength)) if (projectCache.TryGetCustomData("ClothGizmoBrushStrength", out string cachedBrushStrength))
_gizmoMode.BrushStrength = JsonSerializer.Deserialize<float>(cachedBrushStrength); _gizmoMode.BrushStrength = JsonSerializer.Deserialize<float>(cachedBrushStrength);
gizmos.AddMode(_gizmoMode); gizmos.AddMode(_gizmoMode);

View File

@@ -1,5 +1,6 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System.Collections.Generic;
using FlaxEditor.Content.Settings; using FlaxEditor.Content.Settings;
using FlaxEngine; using FlaxEngine;
using FlaxEngine.GUI; using FlaxEngine.GUI;
@@ -12,7 +13,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
[CustomEditor(typeof(LayersMask)), DefaultEditor] [CustomEditor(typeof(LayersMask)), DefaultEditor]
internal class LayersMaskEditor : CustomEditor internal class LayersMaskEditor : CustomEditor
{ {
private CheckBox[] _checkBoxes; private List<CheckBox> _checkBoxes;
/// <inheritdoc /> /// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout) public override void Initialize(LayoutElementsContainer layout)
@@ -24,16 +25,18 @@ namespace FlaxEditor.CustomEditors.Dedicated
return; return;
} }
_checkBoxes = new CheckBox[layers.Length]; _checkBoxes = new List<CheckBox>();
for (int i = 0; i < layers.Length; i++) for (int i = 0; i < layers.Length; i++)
{ {
var layer = layers[i]; var layer = layers[i];
var property = layout.AddPropertyItem(layer); if (string.IsNullOrEmpty(layer))
continue;
var property = layout.AddPropertyItem($"{i}: {layer}");
var checkbox = property.Checkbox().CheckBox; var checkbox = property.Checkbox().CheckBox;
UpdateCheckbox(checkbox, i); UpdateCheckbox(checkbox, i);
checkbox.Tag = i; checkbox.Tag = i;
checkbox.StateChanged += OnCheckboxStateChanged; checkbox.StateChanged += OnCheckboxStateChanged;
_checkBoxes[i] = checkbox; _checkBoxes.Add(checkbox);
} }
} }
@@ -50,9 +53,9 @@ namespace FlaxEditor.CustomEditors.Dedicated
{ {
if (_checkBoxes != null) if (_checkBoxes != null)
{ {
for (int i = 0; i < _checkBoxes.Length; i++) for (int i = 0; i < _checkBoxes.Count; i++)
{ {
UpdateCheckbox(_checkBoxes[i], i); UpdateCheckbox(_checkBoxes[i], (int)_checkBoxes[i].Tag);
} }
} }

View File

@@ -880,6 +880,13 @@ namespace FlaxEditor.CustomEditors.Dedicated
group.Panel.HeaderTextMargin = new Margin(scriptDrag.Right - 12, 15, 2, 2); group.Panel.HeaderTextMargin = new Margin(scriptDrag.Right - 12, 15, 2, 2);
group.Object(values, editor); group.Object(values, editor);
// Remove drop down arrows and containment lines if no objects in the group
if (group.Children.Count == 0)
{
group.Panel.ArrowImageOpened = null;
group.Panel.ArrowImageClosed = null;
group.Panel.EnableContainmentLines = false;
}
// Scripts arrange bar // Scripts arrange bar
dragBar = layout.Custom<ScriptArrangeBar>(); dragBar = layout.Custom<ScriptArrangeBar>();

View File

@@ -456,14 +456,57 @@ namespace FlaxEditor.CustomEditors.Dedicated
for (int i = 0; i < layout.Children.Count; i++) for (int i = 0; i < layout.Children.Count; i++)
{ {
if (layout.Children[i] is GroupElement group && group.Panel.HeaderText == "Transform") if (layout.Children[i] is GroupElement group && group.Panel.HeaderText.Equals("Transform", StringComparison.Ordinal))
{ {
VerticalPanelElement mainHor = VerticalPanelWithoutMargin(group); layout.Children.Remove(group);
CreateTransformElements(mainHor, ValuesTypes); layout.ContainerControl.Children.Remove(group.Panel);
group.ContainerControl.ChangeChildIndex(mainHor.Control, 0);
break; break;
} }
} }
// Setup transform
if (Presenter is LayoutElementsContainer l)
{
for (int i = 0; i < l.Children.Count; i++)
{
if (l.Children[i] is GroupElement g && g.Panel.HeaderText.Equals("Transform", StringComparison.Ordinal))
{
l.Children.Remove(g);
l.ContainerControl.Children.Remove(g.Panel);
break;
}
}
var transformGroup = l.Group("Transform");
VerticalPanelElement mainHor = VerticalPanelWithoutMargin(transformGroup);
CreateTransformElements(mainHor, ValuesTypes);
ScriptMemberInfo scaleInfo = ValuesTypes[0].GetProperty("Scale");
ItemInfo scaleItem = new ItemInfo(scaleInfo);
transformGroup.Property("Scale", scaleItem.GetValues(Values));
ScriptMemberInfo pivotInfo = ValuesTypes[0].GetProperty("Pivot");
ItemInfo pivotItem = new ItemInfo(pivotInfo);
transformGroup.Property("Pivot", pivotItem.GetValues(Values));
ScriptMemberInfo shearInfo = ValuesTypes[0].GetProperty("Shear");
ItemInfo shearItem = new ItemInfo(shearInfo);
transformGroup.Property("Shear", shearItem.GetValues(Values));
ScriptMemberInfo rotationInfo = ValuesTypes[0].GetProperty("Rotation");
ItemInfo rotationItem = new ItemInfo(rotationInfo);
transformGroup.Property("Rotation", rotationItem.GetValues(Values));
// Get position of general tab
for (int i = 0; i < l.Children.Count; i++)
{
if (l.Children[i] is GroupElement g && g.Panel.HeaderText.Equals("General", StringComparison.Ordinal) && i + 1 <= l.Children.Count)
{
Presenter.ContainerControl.ChangeChildIndex(transformGroup.Control, i + 1);
break;
}
}
}
} }
private void CreateTransformElements(LayoutElementsContainer main, ScriptType[] valueTypes) private void CreateTransformElements(LayoutElementsContainer main, ScriptType[] valueTypes)
@@ -645,7 +688,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
{ {
var grid = UniformGridTwoByOne(el); var grid = UniformGridTwoByOne(el);
grid.CustomControl.SlotPadding = new Margin(5, 5, 1, 1); grid.CustomControl.SlotPadding = new Margin(5, 5, 1, 1);
var label = grid.Label(text); var label = grid.Label(text, TextAlignment.Far);
var editor = grid.Object(values); var editor = grid.Object(values);
if (editor is FloatEditor floatEditor && floatEditor.Element is FloatValueElement floatEditorElement) if (editor is FloatEditor floatEditor && floatEditor.Element is FloatValueElement floatEditorElement)
{ {

View File

@@ -42,6 +42,13 @@ namespace FlaxEditor.CustomEditors.Editors
{ {
base.Initialize(layout); base.Initialize(layout);
if (XElement.ValueBox.Parent is UniformGridPanel ug)
{
ug.Height += 2;
ug.SlotSpacing = new Float2(4);
ug.SlotPadding = new Margin(0, 0, 1, 1);
}
// Override colors // Override colors
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground; var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
XElement.ValueBox.BorderColor = Color.Lerp(AxisColorX, back, AxisGreyOutFactor); XElement.ValueBox.BorderColor = Color.Lerp(AxisColorX, back, AxisGreyOutFactor);
@@ -67,6 +74,13 @@ namespace FlaxEditor.CustomEditors.Editors
{ {
base.Initialize(layout); base.Initialize(layout);
if (XElement.ValueBox.Parent is UniformGridPanel ug)
{
ug.Height += 2;
ug.SlotSpacing = new Float2(4);
ug.SlotPadding = new Margin(0, 0, 1, 1);
}
// Override colors // Override colors
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground; var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
XElement.ValueBox.BorderColor = Color.Lerp(AxisColorX, back, AxisGreyOutFactor); XElement.ValueBox.BorderColor = Color.Lerp(AxisColorX, back, AxisGreyOutFactor);
@@ -123,6 +137,13 @@ namespace FlaxEditor.CustomEditors.Editors
}; };
} }
if (XElement.ValueBox.Parent is UniformGridPanel ug)
{
ug.Height += 2;
ug.SlotSpacing = new Float2(4);
ug.SlotPadding = new Margin(0, 0, 1, 1);
}
// Override colors // Override colors
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground; var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
var grayOutFactor = 0.6f; var grayOutFactor = 0.6f;

View File

@@ -38,6 +38,9 @@ namespace FlaxEditor.CustomEditors.Editors
/// </summary> /// </summary>
public readonly int Index; public readonly int Index;
private Rectangle _arrangeButtonRect;
private bool _arrangeButtonInUse;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="CollectionItemLabel"/> class. /// Initializes a new instance of the <see cref="CollectionItemLabel"/> class.
/// </summary> /// </summary>
@@ -50,6 +53,12 @@ namespace FlaxEditor.CustomEditors.Editors
Index = index; Index = index;
SetupContextMenu += OnSetupContextMenu; SetupContextMenu += OnSetupContextMenu;
_arrangeButtonRect = new Rectangle(2, 3, 12, 12);
// Extend margin of the label to support a dragging handle.
Margin m = Margin;
m.Left += 16;
Margin = m;
} }
private void OnSetupContextMenu(PropertyNameLabel label, ContextMenu menu, CustomEditor linkedEditor) private void OnSetupContextMenu(PropertyNameLabel label, ContextMenu menu, CustomEditor linkedEditor)
@@ -57,17 +66,119 @@ namespace FlaxEditor.CustomEditors.Editors
menu.ItemsContainer.RemoveChildren(); menu.ItemsContainer.RemoveChildren();
menu.AddButton("Copy", linkedEditor.Copy); menu.AddButton("Copy", linkedEditor.Copy);
var paste = menu.AddButton("Paste", linkedEditor.Paste); var b = menu.AddButton("Paste", linkedEditor.Paste);
paste.Enabled = linkedEditor.CanPaste; b.Enabled = linkedEditor.CanPaste && !Editor._readOnly;
menu.AddSeparator(); menu.AddSeparator();
var moveUpButton = menu.AddButton("Move up", OnMoveUpClicked); b = menu.AddButton("Move up", OnMoveUpClicked);
moveUpButton.Enabled = Index > 0; b.Enabled = Index > 0 && !Editor._readOnly;
var moveDownButton = menu.AddButton("Move down", OnMoveDownClicked); b = menu.AddButton("Move down", OnMoveDownClicked);
moveDownButton.Enabled = Index + 1 < Editor.Count; b.Enabled = Index + 1 < Editor.Count && !Editor._readOnly;
menu.AddButton("Remove", OnRemoveClicked); b = menu.AddButton("Remove", OnRemoveClicked);
b.Enabled = !Editor._readOnly;
}
/// <inheritdoc />
public override void OnEndMouseCapture()
{
base.OnEndMouseCapture();
_arrangeButtonInUse = false;
}
/// <inheritdoc />
public override void Draw()
{
base.Draw();
var style = FlaxEngine.GUI.Style.Current;
var mousePosition = PointFromScreen(Input.MouseScreenPosition);
var dragBarColor = _arrangeButtonRect.Contains(mousePosition) ? style.Foreground : style.ForegroundGrey;
Render2D.DrawSprite(FlaxEditor.Editor.Instance.Icons.DragBar12, _arrangeButtonRect, _arrangeButtonInUse ? Color.Orange : dragBarColor);
if (_arrangeButtonInUse && ArrangeAreaCheck(out _, out var arrangeTargetRect))
{
Render2D.FillRectangle(arrangeTargetRect, style.Selection);
}
}
private bool ArrangeAreaCheck(out int index, out Rectangle rect)
{
var child = Editor.ChildrenEditors[0];
var container = child.Layout.ContainerControl;
var mousePosition = container.PointFromScreen(Input.MouseScreenPosition);
var barSidesExtend = 20.0f;
var barHeight = 5.0f;
var barCheckAreaHeight = 40.0f;
var pos = mousePosition.Y + barCheckAreaHeight * 0.5f;
for (int i = 0; i < container.Children.Count / 2; i++)
{
var containerChild = container.Children[i * 2]; // times 2 to skip the value editor
if (Mathf.IsInRange(pos, containerChild.Top, containerChild.Top + barCheckAreaHeight) || (i == 0 && pos < containerChild.Top))
{
index = i;
var p1 = containerChild.UpperLeft;
rect = new Rectangle(PointFromParent(p1) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
return true;
}
}
var p2 = container.Children[((container.Children.Count / 2) - 1) * 2].BottomLeft;
if (pos > p2.Y)
{
index = (container.Children.Count / 2) - 1;
rect = new Rectangle(PointFromParent(p2) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
return true;
}
index = -1;
rect = Rectangle.Empty;
return false;
}
/// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button)
{
if (button == MouseButton.Left && _arrangeButtonRect.Contains(ref location))
{
_arrangeButtonInUse = true;
Focus();
StartMouseCapture();
return true;
}
return base.OnMouseDown(location, button);
}
/// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button)
{
if (button == MouseButton.Left && _arrangeButtonInUse)
{
_arrangeButtonInUse = false;
EndMouseCapture();
if (ArrangeAreaCheck(out var index, out _))
{
Editor.Shift(Index, index);
}
}
return base.OnMouseUp(location, button);
}
/// <inheritdoc />
public override void OnLostFocus()
{
if (_arrangeButtonInUse)
{
_arrangeButtonInUse = false;
EndMouseCapture();
}
base.OnLostFocus();
} }
private void OnMoveUpClicked() private void OnMoveUpClicked()
@@ -105,6 +216,9 @@ namespace FlaxEditor.CustomEditors.Editors
private bool _canReorder = true; private bool _canReorder = true;
private Rectangle _arrangeButtonRect;
private bool _arrangeButtonInUse;
public void Setup(CollectionEditor editor, int index, bool canReorder = true) public void Setup(CollectionEditor editor, int index, bool canReorder = true)
{ {
HeaderHeight = 18; HeaderHeight = 18;
@@ -122,10 +236,92 @@ namespace FlaxEditor.CustomEditors.Editors
MouseButtonRightClicked += OnMouseButtonRightClicked; MouseButtonRightClicked += OnMouseButtonRightClicked;
if (_canReorder) if (_canReorder)
{ {
// TODO: Drag drop HeaderTextMargin = new Margin(18, 0, 0, 0);
_arrangeButtonRect = new Rectangle(16, 3, 12, 12);
} }
} }
private bool ArrangeAreaCheck(out int index, out Rectangle rect)
{
var container = Parent;
var mousePosition = container.PointFromScreen(Input.MouseScreenPosition);
var barSidesExtend = 20.0f;
var barHeight = 5.0f;
var barCheckAreaHeight = 40.0f;
var pos = mousePosition.Y + barCheckAreaHeight * 0.5f;
for (int i = 0; i < (container.Children.Count + 1) / 2; i++) // Add 1 to pretend there is a spacer at the end.
{
var containerChild = container.Children[i * 2]; // times 2 to skip the value editor
if (Mathf.IsInRange(pos, containerChild.Top, containerChild.Top + barCheckAreaHeight) || (i == 0 && pos < containerChild.Top))
{
index = i;
var p1 = containerChild.UpperLeft;
rect = new Rectangle(PointFromParent(p1) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
return true;
}
}
var p2 = container.Children[container.Children.Count - 1].BottomLeft;
if (pos > p2.Y)
{
index = ((container.Children.Count + 1) / 2) - 1;
rect = new Rectangle(PointFromParent(p2) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
return true;
}
index = -1;
rect = Rectangle.Empty;
return false;
}
public override void Draw()
{
base.Draw();
if (_canReorder)
{
var style = FlaxEngine.GUI.Style.Current;
var mousePosition = PointFromScreen(Input.MouseScreenPosition);
var dragBarColor = _arrangeButtonRect.Contains(mousePosition) ? style.Foreground : style.ForegroundGrey;
Render2D.DrawSprite(FlaxEditor.Editor.Instance.Icons.DragBar12, _arrangeButtonRect, _arrangeButtonInUse ? Color.Orange : dragBarColor);
if (_arrangeButtonInUse && ArrangeAreaCheck(out _, out var arrangeTargetRect))
{
Render2D.FillRectangle(arrangeTargetRect, style.Selection);
}
}
}
/// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button)
{
if (button == MouseButton.Left && _arrangeButtonRect.Contains(ref location))
{
_arrangeButtonInUse = true;
Focus();
StartMouseCapture();
return true;
}
return base.OnMouseDown(location, button);
}
/// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button)
{
if (button == MouseButton.Left && _arrangeButtonInUse)
{
_arrangeButtonInUse = false;
EndMouseCapture();
if (ArrangeAreaCheck(out var index, out _))
{
Editor.Shift(Index, index);
}
}
return base.OnMouseUp(location, button);
}
private void OnMouseButtonRightClicked(DropPanel panel, Float2 location) private void OnMouseButtonRightClicked(DropPanel panel, Float2 location)
{ {
if (LinkedEditor == null) if (LinkedEditor == null)
@@ -177,6 +373,7 @@ namespace FlaxEditor.CustomEditors.Editors
private IntValueBox _sizeBox; private IntValueBox _sizeBox;
private Color _background; private Color _background;
private int _elementsCount, _minCount, _maxCount; private int _elementsCount, _minCount, _maxCount;
private bool _readOnly;
private bool _canResize; private bool _canResize;
private bool _canReorderItems; private bool _canReorderItems;
private CollectionAttribute.DisplayType _displayType; private CollectionAttribute.DisplayType _displayType;
@@ -209,6 +406,7 @@ namespace FlaxEditor.CustomEditors.Editors
return; return;
var size = Count; var size = Count;
_readOnly = false;
_canResize = true; _canResize = true;
_canReorderItems = true; _canReorderItems = true;
_minCount = 0; _minCount = 0;
@@ -224,7 +422,8 @@ namespace FlaxEditor.CustomEditors.Editors
var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute); var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);
if (collection != null) if (collection != null)
{ {
_canResize = !collection.ReadOnly; _canResize = collection.CanResize;
_readOnly = collection.ReadOnly;
_minCount = collection.MinCount; _minCount = collection.MinCount;
_maxCount = collection.MaxCount; _maxCount = collection.MaxCount;
_canReorderItems = collection.CanReorderItems; _canReorderItems = collection.CanReorderItems;
@@ -235,6 +434,12 @@ namespace FlaxEditor.CustomEditors.Editors
spacing = collection.Spacing; spacing = collection.Spacing;
_displayType = collection.Display; _displayType = collection.Display;
} }
if (attributes != null && attributes.Any(x => x is ReadOnlyAttribute))
{
_readOnly = true;
_canResize = false;
_canReorderItems = false;
}
if (_maxCount == 0) if (_maxCount == 0)
_maxCount = ushort.MaxValue; _maxCount = ushort.MaxValue;
_canResize &= _minCount < _maxCount; _canResize &= _minCount < _maxCount;
@@ -243,8 +448,7 @@ namespace FlaxEditor.CustomEditors.Editors
dragArea.CustomControl.Editor = this; dragArea.CustomControl.Editor = this;
dragArea.CustomControl.ElementType = ElementType; dragArea.CustomControl.ElementType = ElementType;
// Check for the AssetReferenceAttribute. In JSON assets, it can be used to filter // Check for the AssetReferenceAttribute. In JSON assets, it can be used to filter which scripts can be dragged over and dropped on this collection editor
// which scripts can be dragged over and dropped on this collection editor.
var assetReference = (AssetReferenceAttribute)attributes?.FirstOrDefault(x => x is AssetReferenceAttribute); var assetReference = (AssetReferenceAttribute)attributes?.FirstOrDefault(x => x is AssetReferenceAttribute);
if (assetReference != null) if (assetReference != null)
{ {
@@ -315,7 +519,6 @@ namespace FlaxEditor.CustomEditors.Editors
(elementType.GetProperties().Length == 1 && elementType.GetFields().Length == 0) || (elementType.GetProperties().Length == 1 && elementType.GetFields().Length == 0) ||
elementType.Equals(new ScriptType(typeof(JsonAsset))) || elementType.Equals(new ScriptType(typeof(JsonAsset))) ||
elementType.Equals(new ScriptType(typeof(SettingsBase))); elementType.Equals(new ScriptType(typeof(SettingsBase)));
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
// Apply spacing // Apply spacing
@@ -333,6 +536,8 @@ namespace FlaxEditor.CustomEditors.Editors
var property = panel.AddPropertyItem(itemLabel); var property = panel.AddPropertyItem(itemLabel);
var itemLayout = (LayoutElementsContainer)property; var itemLayout = (LayoutElementsContainer)property;
itemLabel.LinkedEditor = itemLayout.Object(new ListValueContainer(elementType, i, Values, attributes), overrideEditor); itemLabel.LinkedEditor = itemLayout.Object(new ListValueContainer(elementType, i, Values, attributes), overrideEditor);
if (_readOnly && itemLayout.Children.Count > 0)
GenericEditor.OnReadOnlyProperty(itemLayout);
} }
else if (_displayType == CollectionAttribute.DisplayType.Header || (_displayType == CollectionAttribute.DisplayType.Default && !single)) else if (_displayType == CollectionAttribute.DisplayType.Header || (_displayType == CollectionAttribute.DisplayType.Default && !single))
{ {
@@ -340,13 +545,15 @@ namespace FlaxEditor.CustomEditors.Editors
cdp.CustomControl.Setup(this, i, _canReorderItems); cdp.CustomControl.Setup(this, i, _canReorderItems);
var itemLayout = cdp.VerticalPanel(); var itemLayout = cdp.VerticalPanel();
cdp.CustomControl.LinkedEditor = itemLayout.Object(new ListValueContainer(elementType, i, Values, attributes), overrideEditor); cdp.CustomControl.LinkedEditor = itemLayout.Object(new ListValueContainer(elementType, i, Values, attributes), overrideEditor);
if (_readOnly && itemLayout.Children.Count > 0)
GenericEditor.OnReadOnlyProperty(itemLayout);
} }
} }
} }
_elementsCount = size; _elementsCount = size;
// Add/Remove buttons // Add/Remove buttons
if (_canResize) if (_canResize && !_readOnly)
{ {
var panel = dragArea.HorizontalPanel(); var panel = dragArea.HorizontalPanel();
panel.Panel.Size = new Float2(0, 20); panel.Panel.Size = new Float2(0, 20);
@@ -427,6 +634,39 @@ namespace FlaxEditor.CustomEditors.Editors
SetValue(cloned); SetValue(cloned);
} }
/// <summary>
/// Shifts the specified item at the given index and moves it through the list to the other item. It supports undo.
/// </summary>
/// <param name="srcIndex">Index of the source item.</param>
/// <param name="dstIndex">Index of the destination to move to.</param>
private void Shift(int srcIndex, int dstIndex)
{
if (IsSetBlocked)
return;
var cloned = CloneValues();
if (dstIndex > srcIndex)
{
for (int i = srcIndex; i < dstIndex; i++)
{
var tmp = cloned[i + 1];
cloned[i + 1] = cloned[i];
cloned[i] = tmp;
}
}
else
{
for (int i = srcIndex; i > dstIndex; i--)
{
var tmp = cloned[i - 1];
cloned[i - 1] = cloned[i];
cloned[i] = tmp;
}
}
SetValue(cloned);
}
/// <summary> /// <summary>
/// Removes the item at the specified index. It supports undo. /// Removes the item at the specified index. It supports undo.
/// </summary> /// </summary>

View File

@@ -131,7 +131,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseDoubleClick(Float2 location, MouseButton button) public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
{ {
if (button == MouseButton.Left) if (button == MouseButton.Left && _editor._canEditKeys)
{ {
OnEditClicked(null); OnEditClicked(null);
return true; return true;
@@ -189,6 +189,7 @@ namespace FlaxEditor.CustomEditors.Editors
var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute); var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);
if (collection != null) if (collection != null)
{ {
_canEditKeys &= collection.CanReorderItems;
_readOnly = collection.ReadOnly; _readOnly = collection.ReadOnly;
_notNullItems = collection.NotNullItems; _notNullItems = collection.NotNullItems;
if (collection.BackgroundColor.HasValue) if (collection.BackgroundColor.HasValue)
@@ -197,6 +198,11 @@ namespace FlaxEditor.CustomEditors.Editors
spacing = collection.Spacing; spacing = collection.Spacing;
_displayType = collection.Display; _displayType = collection.Display;
} }
if (attributes != null && attributes.Any(x => x is ReadOnlyAttribute))
{
_readOnly = true;
_canEditKeys = false;
}
// Size // Size
if (layout.ContainerControl is DropPanel dropPanel) if (layout.ContainerControl is DropPanel dropPanel)
@@ -240,14 +246,6 @@ namespace FlaxEditor.CustomEditors.Editors
var keys = keysEnumerable as object[] ?? keysEnumerable.ToArray(); var keys = keysEnumerable as object[] ?? keysEnumerable.ToArray();
var valuesType = new ScriptType(valueType); var valuesType = new ScriptType(valueType);
bool single = valuesType.IsPrimitive ||
valuesType.Equals(new ScriptType(typeof(string))) ||
valuesType.IsEnum ||
(valuesType.GetFields().Length == 1 && valuesType.GetProperties().Length == 0) ||
(valuesType.GetProperties().Length == 1 && valuesType.GetFields().Length == 0) ||
valuesType.Equals(new ScriptType(typeof(JsonAsset))) ||
valuesType.Equals(new ScriptType(typeof(SettingsBase)));
// Use separate layout cells for each collection items to improve layout updates for them in separation // Use separate layout cells for each collection items to improve layout updates for them in separation
var useSharedLayout = valueType.IsPrimitive || valueType.IsEnum; var useSharedLayout = valueType.IsPrimitive || valueType.IsEnum;
@@ -263,6 +261,8 @@ namespace FlaxEditor.CustomEditors.Editors
var property = panel.AddPropertyItem(new DictionaryItemLabel(this, key)); var property = panel.AddPropertyItem(new DictionaryItemLabel(this, key));
var itemLayout = useSharedLayout ? (LayoutElementsContainer)property : property.VerticalPanel(); var itemLayout = useSharedLayout ? (LayoutElementsContainer)property : property.VerticalPanel();
itemLayout.Object(new DictionaryValueContainer(valuesType, key, Values), overrideEditor); itemLayout.Object(new DictionaryValueContainer(valuesType, key, Values), overrideEditor);
if (_readOnly && itemLayout.Children.Count > 0)
GenericEditor.OnReadOnlyProperty(itemLayout);
} }
} }
_elementsCount = size; _elementsCount = size;

View File

@@ -0,0 +1,17 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
namespace FlaxEditor.CustomEditors.Editors
{
internal sealed class DummyEditor : CustomEditor
{
public override void Initialize(LayoutElementsContainer layout)
{
string valueName;
if (Values.Count != 0 && Values[0] != null)
valueName = Values[0].ToString();
else
valueName = "null";
layout.Label($"{valueName} ({Values.Type})");
}
}
}

View File

@@ -208,7 +208,7 @@ namespace FlaxEditor.CustomEditors.Editors
else else
{ {
// Draw info // Draw info
Render2D.DrawText(style.FontMedium, "-", nameRect, isEnabled ? Color.OrangeRed : Color.DarkOrange, TextAlignment.Near, TextAlignment.Center); Render2D.DrawText(style.FontMedium, Type != null ? $"None ({Utilities.Utils.GetPropertyNameUI(Type.ToString())})" : "-", nameRect, isEnabled ? Color.OrangeRed : Color.DarkOrange, TextAlignment.Near, TextAlignment.Center);
} }
// Draw picker button // Draw picker button

View File

@@ -474,32 +474,7 @@ namespace FlaxEditor.CustomEditors.Editors
} }
if (layout.Editors.Count != 0) if (layout.Editors.Count != 0)
{ {
var sb = Clipboard.Text; return !string.IsNullOrEmpty(Clipboard.Text);
if (!string.IsNullOrEmpty(sb))
{
try
{
var data = JsonSerializer.Deserialize<string[]>(sb);
if (data == null || data.Length != layout.Editors.Count)
return false;
for (var i = 0; i < layout.Editors.Count; i++)
{
Clipboard.Text = data[i];
if (!layout.Editors[i].CanPaste)
return false;
}
return true;
}
catch
{
return false;
}
finally
{
Clipboard.Text = sb;
}
}
return false;
} }
if (layout.Children.Any(x => x is LayoutElementsContainer)) if (layout.Children.Any(x => x is LayoutElementsContainer))
{ {
@@ -581,6 +556,43 @@ namespace FlaxEditor.CustomEditors.Editors
return layout; return layout;
} }
internal static void OnReadOnlyProperty(LayoutElementsContainer itemLayout, int labelIndex = -1)
{
PropertiesListElement list = null;
int firstChildControlIndex = 0;
bool disableSingle = true;
var control = itemLayout.Children[itemLayout.Children.Count - 1];
if (control is GroupElement group && group.Children.Count > 0)
{
list = group.Children[0] as PropertiesListElement;
disableSingle = false; // Disable all nested editors
}
else if (control is PropertiesListElement list1 && labelIndex != -1)
{
list = list1;
firstChildControlIndex = list.Labels[labelIndex].FirstChildControlIndex;
}
else if (control?.Control != null)
{
control.Control.Enabled = false;
}
if (list != null)
{
// Disable controls added to the editor
var count = list.Properties.Children.Count;
for (int j = firstChildControlIndex; j < count; j++)
{
var child = list.Properties.Children[j];
if (disableSingle && child is PropertyNameLabel)
break;
if (child != null)
child.Enabled = false;
}
}
}
/// <summary> /// <summary>
/// Evaluate the <see cref="VisibleIfAttribute"/> cache for a given property item. /// Evaluate the <see cref="VisibleIfAttribute"/> cache for a given property item.
/// </summary> /// </summary>
@@ -660,35 +672,7 @@ namespace FlaxEditor.CustomEditors.Editors
if (item.IsReadOnly && itemLayout.Children.Count > 0) if (item.IsReadOnly && itemLayout.Children.Count > 0)
{ {
PropertiesListElement list = null; OnReadOnlyProperty(itemLayout, labelIndex);
int firstChildControlIndex = 0;
bool disableSingle = true;
var control = itemLayout.Children[itemLayout.Children.Count - 1];
if (control is GroupElement group && group.Children.Count > 0)
{
list = group.Children[0] as PropertiesListElement;
disableSingle = false; // Disable all nested editors
}
else if (control is PropertiesListElement list1)
{
list = list1;
firstChildControlIndex = list.Labels[labelIndex].FirstChildControlIndex;
}
if (list != null)
{
// Disable controls added to the editor
var count = list.Properties.Children.Count;
for (int j = firstChildControlIndex; j < count; j++)
{
var child = list.Properties.Children[j];
if (disableSingle && child is PropertyNameLabel)
break;
if (child != null)
child.Enabled = false;
}
}
} }
EvaluateVisibleIf(itemLayout, item, labelIndex); EvaluateVisibleIf(itemLayout, item, labelIndex);

View File

@@ -83,6 +83,22 @@ namespace FlaxEditor.CustomEditors.Editors
_element.Value = asInt; _element.Value = asInt;
else if (value is float asFloat) else if (value is float asFloat)
_element.Value = (int)asFloat; _element.Value = (int)asFloat;
else if (value is double asDouble)
_element.Value = (int)asDouble;
else if (value is uint asUint)
_element.Value = (int)asUint;
else if (value is long asLong)
_element.Value = (int)asLong;
else if (value is ulong asULong)
_element.Value = (int)asULong;
else if (value is short asShort)
_element.Value = asShort;
else if (value is ushort asUshort)
_element.Value = asUshort;
else if (value is byte asByte)
_element.Value = asByte;
else if (value is sbyte asSbyte)
_element.Value = asSbyte;
else else
throw new Exception(string.Format("Invalid value type {0}.", value?.GetType().ToString() ?? "<null>")); throw new Exception(string.Format("Invalid value type {0}.", value?.GetType().ToString() ?? "<null>"));
} }
@@ -338,7 +354,7 @@ namespace FlaxEditor.CustomEditors.Editors
protected abstract ulong GetValue(object value); protected abstract ulong GetValue(object value);
/// <summary> /// <summary>
/// Gets the value from long. /// Sets the value from long.
/// </summary> /// </summary>
/// <param name="value">The value from editor.</param> /// <param name="value">The value from editor.</param>
/// <returns>The value to object.</returns> /// <returns>The value to object.</returns>

View File

@@ -39,7 +39,7 @@ namespace FlaxEditor.CustomEditors.Editors
if (watermarkAttribute is WatermarkAttribute watermark) if (watermarkAttribute is WatermarkAttribute watermark)
{ {
_watermarkText = watermark.WatermarkText; _watermarkText = watermark.WatermarkText;
var watermarkColor = watermark.WatermarkColor > 0 ? Color.FromRGBA(watermark.WatermarkColor) : FlaxEngine.GUI.Style.Current.ForegroundDisabled; var watermarkColor = watermark.WatermarkColor > 0 ? Color.FromRGB(watermark.WatermarkColor) : FlaxEngine.GUI.Style.Current.ForegroundDisabled;
_watermarkColor = watermarkColor; _watermarkColor = watermarkColor;
_element.TextBox.WatermarkText = watermark.WatermarkText; _element.TextBox.WatermarkText = watermark.WatermarkText;
_element.TextBox.WatermarkTextColor = watermarkColor; _element.TextBox.WatermarkTextColor = watermarkColor;

View File

@@ -242,7 +242,7 @@ namespace FlaxEditor.CustomEditors.GUI
float namesWidth = _splitterValue * Width; float namesWidth = _splitterValue * Width;
int count = _element.Labels.Count; int count = _element.Labels.Count;
float[] yStarts = new float[count + 1]; float[] yStarts = new float[count + 1];
for (int i = 1; i < count; i++) for (int i = 0; i < count; i++)
{ {
var label = _element.Labels[i]; var label = _element.Labels[i];
@@ -251,9 +251,13 @@ namespace FlaxEditor.CustomEditors.GUI
else if (_children.Count <= label.FirstChildControlIndex) else if (_children.Count <= label.FirstChildControlIndex)
yStarts[i] = y; yStarts[i] = y;
else else
{
yStarts[i] = _children[label.FirstChildControlIndex].Top; yStarts[i] = _children[label.FirstChildControlIndex].Top;
if (i == count - 1)
yStarts[i + 1] = _children[label.FirstChildControlIndex].Bottom;
}
} }
yStarts[count] = y;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
var label = _element.Labels[i]; var label = _element.Labels[i];

View File

@@ -318,7 +318,9 @@ namespace FlaxEditor.CustomEditors
if (header.FontSize > 0) if (header.FontSize > 0)
element.Label.Font = new FontReference(element.Label.Font.Font, header.FontSize); element.Label.Font = new FontReference(element.Label.Font.Font, header.FontSize);
if (header.Color > 0) if (header.Color > 0)
element.Label.TextColor = Color.FromRGBA(header.Color); element.Label.TextColor = Color.FromRGB(header.Color);
var size = element.Label.Font.GetFont().MeasureText(header.Text);
element.Label.Height = size.Y;
return element; return element;
} }

View File

@@ -247,6 +247,11 @@ namespace FlaxEditor
/// </summary> /// </summary>
public event Action PlayModeEnd; public event Action PlayModeEnd;
/// <summary>
/// Fired on Editor update
/// </summary>
public event Action EditorUpdate;
internal Editor() internal Editor()
{ {
Instance = this; Instance = this;
@@ -330,7 +335,7 @@ namespace FlaxEditor
} }
case GeneralOptions.StartupSceneModes.LastOpened: case GeneralOptions.StartupSceneModes.LastOpened:
{ {
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out var lastSceneIdName)) if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out string lastSceneIdName))
{ {
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName); var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
foreach (var scene in lastScenes) foreach (var scene in lastScenes)
@@ -442,7 +447,7 @@ namespace FlaxEditor
} }
case GeneralOptions.StartupSceneModes.LastOpened: case GeneralOptions.StartupSceneModes.LastOpened:
{ {
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out var lastSceneIdName)) if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out string lastSceneIdName))
{ {
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName); var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
foreach (var sceneId in lastScenes) foreach (var sceneId in lastScenes)
@@ -459,7 +464,7 @@ namespace FlaxEditor
} }
// Restore view // Restore view
if (ProjectCache.TryGetCustomData(ProjectDataLastSceneSpawn, out var lastSceneSpawnName)) if (ProjectCache.TryGetCustomData(ProjectDataLastSceneSpawn, out string lastSceneSpawnName))
Windows.EditWin.Viewport.ViewRay = JsonSerializer.Deserialize<Ray>(lastSceneSpawnName); Windows.EditWin.Viewport.ViewRay = JsonSerializer.Deserialize<Ray>(lastSceneSpawnName);
} }
break; break;
@@ -486,6 +491,8 @@ namespace FlaxEditor
StateMachine.CurrentState.UpdateFPS(); StateMachine.CurrentState.UpdateFPS();
} }
EditorUpdate?.Invoke();
// Update modules // Update modules
for (int i = 0; i < _modules.Count; i++) for (int i = 0; i < _modules.Count; i++)
{ {
@@ -1364,6 +1371,7 @@ namespace FlaxEditor
public byte AutoReloadScriptsOnMainWindowFocus; public byte AutoReloadScriptsOnMainWindowFocus;
public byte ForceScriptCompilationOnStartup; public byte ForceScriptCompilationOnStartup;
public byte UseAssetImportPathRelative; public byte UseAssetImportPathRelative;
public byte EnableParticlesPreview;
public byte AutoRebuildCSG; public byte AutoRebuildCSG;
public float AutoRebuildCSGTimeoutMs; public float AutoRebuildCSGTimeoutMs;
public byte AutoRebuildNavMesh; public byte AutoRebuildNavMesh;

View File

@@ -105,9 +105,9 @@ namespace FlaxEditor.GUI
private Rectangle Button1Rect => new Rectangle(Height + ButtonsOffset, 0, ButtonsSize, ButtonsSize); private Rectangle Button1Rect => new Rectangle(Height + ButtonsOffset, 0, ButtonsSize, ButtonsSize);
private Rectangle Button2Rect => new Rectangle(Height + ButtonsOffset, ButtonsSize, ButtonsSize, ButtonsSize); private Rectangle Button2Rect => new Rectangle(Height + ButtonsOffset, ButtonsSize + 2, ButtonsSize, ButtonsSize);
private Rectangle Button3Rect => new Rectangle(Height + ButtonsOffset, ButtonsSize * 2, ButtonsSize, ButtonsSize); private Rectangle Button3Rect => new Rectangle(Height + ButtonsOffset, (ButtonsSize + 2) * 2, ButtonsSize, ButtonsSize);
/// <inheritdoc /> /// <inheritdoc />
public override void Draw() public override void Draw()
@@ -149,6 +149,13 @@ namespace FlaxEditor.GUI
style.Foreground, style.Foreground,
TextAlignment.Near, TextAlignment.Near,
TextAlignment.Center); TextAlignment.Center);
Render2D.DrawText(
style.FontSmall,
$"{TypeUtils.GetTypeDisplayName(Validator.AssetType.Type)}",
new Rectangle(button1Rect.Right + 2, ButtonsSize + 2, sizeForTextLeft, ButtonsSize),
style.ForegroundGrey,
TextAlignment.Near,
TextAlignment.Center);
} }
} }
// Check if has no item but has an asset (eg. virtual asset) // Check if has no item but has an asset (eg. virtual asset)
@@ -171,6 +178,13 @@ namespace FlaxEditor.GUI
style.Foreground, style.Foreground,
TextAlignment.Near, TextAlignment.Near,
TextAlignment.Center); TextAlignment.Center);
Render2D.DrawText(
style.FontSmall,
$"{TypeUtils.GetTypeDisplayName(Validator.AssetType.Type)}",
new Rectangle(button1Rect.Right + 2, ButtonsSize + 2, sizeForTextLeft, ButtonsSize),
style.ForegroundGrey,
TextAlignment.Near,
TextAlignment.Center);
} }
} }
else else
@@ -178,6 +192,24 @@ namespace FlaxEditor.GUI
// No element selected // No element selected
Render2D.FillRectangle(iconRect, style.BackgroundNormal); Render2D.FillRectangle(iconRect, style.BackgroundNormal);
Render2D.DrawText(style.FontMedium, "No asset\nselected", iconRect, Color.Orange, TextAlignment.Center, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, Height / DefaultIconSize); Render2D.DrawText(style.FontMedium, "No asset\nselected", iconRect, Color.Orange, TextAlignment.Center, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, Height / DefaultIconSize);
float sizeForTextLeft = Width - button1Rect.Right;
if (sizeForTextLeft > 30)
{
Render2D.DrawText(
style.FontSmall,
$"None",
new Rectangle(button1Rect.Right + 2, 0, sizeForTextLeft, ButtonsSize),
style.Foreground,
TextAlignment.Near,
TextAlignment.Center);
Render2D.DrawText(
style.FontSmall,
$"{TypeUtils.GetTypeDisplayName(Validator.AssetType.Type)}",
new Rectangle(button1Rect.Right + 2, ButtonsSize + 2, sizeForTextLeft, ButtonsSize),
style.ForegroundGrey,
TextAlignment.Near,
TextAlignment.Center);
}
} }
// Check if drag is over // Check if drag is over

View File

@@ -1,6 +1,7 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using FlaxEngine; using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.GUI namespace FlaxEditor.GUI
{ {
@@ -43,10 +44,20 @@ namespace FlaxEditor.GUI
public Color TitleColor = Color.White; public Color TitleColor = Color.White;
/// <summary> /// <summary>
/// The column title background background. /// The column title background color.
/// </summary> /// </summary>
public Color TitleBackgroundColor = Color.Brown; public Color TitleBackgroundColor = Color.Brown;
/// <summary>
/// The column title horizontal text alignment
/// </summary>
public TextAlignment TitleAlignment = TextAlignment.Near;
/// <summary>
/// The column title margin.
/// </summary>
public Margin TitleMargin = new Margin(4, 4, 0, 0);
/// <summary> /// <summary>
/// The minimum size (in pixels) of the column. /// The minimum size (in pixels) of the column.
/// </summary> /// </summary>

View File

@@ -1,7 +1,10 @@
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS || PLATFORM_SDL
#define USE_IS_FOREGROUND #define USE_IS_FOREGROUND
#else #else
#endif #endif
#if PLATFORM_SDL
#define USE_SDL_WORKAROUNDS
#endif
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System.Collections.Generic; using System.Collections.Generic;
@@ -111,7 +114,7 @@ namespace FlaxEditor.GUI.ContextMenu
} }
/// <summary> /// <summary>
/// Shows the empty menu popup o na screen. /// Shows the empty menu popup on a screen.
/// </summary> /// </summary>
/// <param name="control">The target control.</param> /// <param name="control">The target control.</param>
/// <param name="area">The target control area to cover.</param> /// <param name="area">The target control area to cover.</param>
@@ -215,7 +218,7 @@ namespace FlaxEditor.GUI.ContextMenu
desc.AllowMaximize = false; desc.AllowMaximize = false;
desc.AllowDragAndDrop = false; desc.AllowDragAndDrop = false;
desc.IsTopmost = true; desc.IsTopmost = true;
desc.IsRegularWindow = false; desc.Type = WindowType.Utility;
desc.HasSizingFrame = false; desc.HasSizingFrame = false;
OnWindowCreating(ref desc); OnWindowCreating(ref desc);
_window = Platform.CreateWindow(ref desc); _window = Platform.CreateWindow(ref desc);
@@ -228,8 +231,6 @@ namespace FlaxEditor.GUI.ContextMenu
// Show // Show
Visible = true; Visible = true;
if (_window == null)
return;
_window.Show(); _window.Show();
PerformLayout(); PerformLayout();
_previouslyFocused = parentWin.FocusedControl; _previouslyFocused = parentWin.FocusedControl;
@@ -378,6 +379,11 @@ namespace FlaxEditor.GUI.ContextMenu
} }
} }
#if USE_SDL_WORKAROUNDS
private void OnWindowGotFocus()
{
}
#else
private void OnWindowGotFocus() private void OnWindowGotFocus()
{ {
var child = _childCM; var child = _childCM;
@@ -391,6 +397,7 @@ namespace FlaxEditor.GUI.ContextMenu
}); });
} }
} }
#endif
private void OnWindowLostFocus() private void OnWindowLostFocus()
{ {
@@ -489,7 +496,12 @@ namespace FlaxEditor.GUI.ContextMenu
// Let root context menu to check if none of the popup windows // Let root context menu to check if none of the popup windows
if (_parentCM == null && !IsForeground) if (_parentCM == null && !IsForeground)
{ {
#if USE_SDL_WORKAROUNDS
if (!IsMouseOver)
Hide();
#else
Hide(); Hide();
#endif
} }
} }
#endif #endif

View File

@@ -40,6 +40,7 @@ namespace FlaxEditor.GUI.Dialogs
private bool _disableEvents; private bool _disableEvents;
private bool _useDynamicEditing; private bool _useDynamicEditing;
private bool _activeEyedropper; private bool _activeEyedropper;
private bool _canPassLastChangeEvent = true;
private ColorValueBox.ColorPickerEvent _onChanged; private ColorValueBox.ColorPickerEvent _onChanged;
private ColorValueBox.ColorPickerClosedEvent _onClosed; private ColorValueBox.ColorPickerClosedEvent _onClosed;
@@ -119,10 +120,8 @@ namespace FlaxEditor.GUI.Dialogs
_onClosed = pickerClosed; _onClosed = pickerClosed;
// Get saved colors if they exist // Get saved colors if they exist
if (Editor.Instance.ProjectCache.TryGetCustomData("ColorPickerSavedColors", out var savedColors)) if (Editor.Instance.ProjectCache.TryGetCustomData("ColorPickerSavedColors", out string savedColors))
{
_savedColors = JsonSerializer.Deserialize<List<Color>>(savedColors); _savedColors = JsonSerializer.Deserialize<List<Color>>(savedColors);
}
// Selector // Selector
_cSelector = new ColorSelectorWithSliders(180, 18) _cSelector = new ColorSelectorWithSliders(180, 18)
@@ -264,6 +263,7 @@ namespace FlaxEditor.GUI.Dialogs
{ {
Text = "+", Text = "+",
Parent = this, Parent = this,
TooltipText = "Save Color.",
Tag = null, Tag = null,
}; };
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b); savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b);
@@ -370,9 +370,25 @@ namespace FlaxEditor.GUI.Dialogs
Render2D.DrawText(style.FontMedium, "Hex", hex, textColor, TextAlignment.Near, TextAlignment.Center); Render2D.DrawText(style.FontMedium, "Hex", hex, textColor, TextAlignment.Near, TextAlignment.Center);
// Color difference // Color difference
var newRect = new Rectangle(_cOK.X, _cHex.Bottom + PickerMargin, _cCancel.Right - _cOK.Left, 0); var newRect = new Rectangle(_cOK.X - 3, _cHex.Bottom + PickerMargin, 130, 0);
newRect.Size.Y = _cValue.Bottom - newRect.Y; newRect.Size.Y = 50;
Render2D.FillRectangle(newRect, _value * _value.A); Render2D.FillRectangle(newRect, Color.White);
var smallRectSize = 10;
var numHor = Mathf.FloorToInt(newRect.Width / smallRectSize);
var numVer = Mathf.FloorToInt(newRect.Height / smallRectSize);
// Draw checkerboard for background of color to help with transparency
for (int i = 0; i < numHor; i++)
{
for (int j = 0; j < numVer; j++)
{
if ((i + j) % 2 == 0)
{
var rect = new Rectangle(newRect.X + smallRectSize * i, newRect.Y + smallRectSize * j, new Float2(smallRectSize));
Render2D.FillRectangle(rect, Color.Gray);
}
}
}
Render2D.FillRectangle(newRect, _value);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -380,7 +396,7 @@ namespace FlaxEditor.GUI.Dialogs
{ {
// Auto cancel on lost focus // Auto cancel on lost focus
#if !PLATFORM_LINUX #if !PLATFORM_LINUX
((WindowRootControl)Root).Window.LostFocus += OnCancel; ((WindowRootControl)Root).Window.LostFocus += OnWindowLostFocus;
#endif #endif
base.OnShow(); base.OnShow();
@@ -489,7 +505,7 @@ namespace FlaxEditor.GUI.Dialogs
BackgroundColorHighlighted = savedColor, BackgroundColorHighlighted = savedColor,
BackgroundColorSelected = savedColor.RGBMultiplied(0.8f), BackgroundColorSelected = savedColor.RGBMultiplied(0.8f),
}; };
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b); savedColorButton.ButtonClicked += OnSavedColorButtonClicked;
_savedColorButtons.Add(savedColorButton); _savedColorButtons.Add(savedColorButton);
} }
if (_savedColors.Count < 8) if (_savedColors.Count < 8)
@@ -498,13 +514,27 @@ namespace FlaxEditor.GUI.Dialogs
{ {
Text = "+", Text = "+",
Parent = this, Parent = this,
TooltipText = "Save Color.",
Tag = null, Tag = null,
}; };
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b); savedColorButton.ButtonClicked += OnSavedColorButtonClicked;
_savedColorButtons.Add(savedColorButton); _savedColorButtons.Add(savedColorButton);
} }
} }
private void OnWindowLostFocus()
{
// Auto apply color on defocus
var autoAcceptColorPickerChange = Editor.Instance.Options.Options.Interface.AutoAcceptColorPickerChange;
if (_useDynamicEditing && _initialValue != _value && _canPassLastChangeEvent && autoAcceptColorPickerChange)
{
_canPassLastChangeEvent = false;
_onChanged?.Invoke(_value, false);
}
OnCancel();
}
/// <inheritdoc /> /// <inheritdoc />
public override void OnSubmit() public override void OnSubmit()
{ {
@@ -529,8 +559,9 @@ namespace FlaxEditor.GUI.Dialogs
_disableEvents = true; _disableEvents = true;
// Restore color if modified // Restore color if modified
if (_useDynamicEditing && _initialValue != _value) if (_useDynamicEditing && _initialValue != _value && _canPassLastChangeEvent)
{ {
_canPassLastChangeEvent = false;
_onChanged?.Invoke(_initialValue, false); _onChanged?.Invoke(_initialValue, false);
} }

View File

@@ -311,7 +311,9 @@ namespace FlaxEditor.GUI.Dialogs
// Alpha // Alpha
float alphaY = _slider2Rect.Height * (1 - _color.A); float alphaY = _slider2Rect.Height * (1 - _color.A);
var alphaR = new Rectangle(_slider2Rect.X - slidersOffset, _slider2Rect.Y + alphaY - slidersThickness / 2, _slider2Rect.Width + slidersOffset * 2, slidersThickness); var alphaR = new Rectangle(_slider2Rect.X - slidersOffset, _slider2Rect.Y + alphaY - slidersThickness / 2, _slider2Rect.Width + slidersOffset * 2, slidersThickness);
Render2D.FillRectangle(_slider2Rect, _color, _color, Color.Transparent, Color.Transparent); var color = _color;
color.A = 1; // Keep slider 2 fill rect from changing color alpha while selecting.
Render2D.FillRectangle(_slider2Rect, color, color, Color.Transparent, Color.Transparent);
Render2D.DrawRectangle(_slider2Rect, _isMouseDownSlider2 ? style.BackgroundSelected : Color.Black); Render2D.DrawRectangle(_slider2Rect, _isMouseDownSlider2 ? style.BackgroundSelected : Color.Black);
Render2D.DrawRectangle(alphaR, _isMouseDownSlider2 ? Color.White : Color.Gray); Render2D.DrawRectangle(alphaR, _isMouseDownSlider2 ? Color.White : Color.Gray);
} }

View File

@@ -67,9 +67,7 @@ namespace FlaxEditor.GUI.Docking
Proxy.Window.MouseUp += OnMouseUp; Proxy.Window.MouseUp += OnMouseUp;
Proxy.Window.MouseMove += OnMouseMove; Proxy.Window.MouseMove += OnMouseMove;
Proxy.Window.LostFocus += OnLostFocus; Proxy.Window.LostFocus += OnLostFocus;
_toMove.Window.Window.MouseUp += OnMouseUp; // Intercept the drag release mouse event from source window
// Start tracking mouse
Proxy.Window.StartTrackingMouse(false);
// Update window GUI // Update window GUI
Proxy.Window.GUI.PerformLayout(); Proxy.Window.GUI.PerformLayout();
@@ -77,13 +75,16 @@ namespace FlaxEditor.GUI.Docking
// Update rectangles // Update rectangles
UpdateRects(); UpdateRects();
// Hide base window
window.Hide();
// Enable hit window presentation // Enable hit window presentation
Proxy.Window.RenderingEnabled = true; Proxy.Window.RenderingEnabled = true;
Proxy.Window.Show(); Proxy.Window.Show();
Proxy.Window.Focus(); Proxy.Window.Focus();
// Hide base window
window.Hide();
// Start tracking mouse
Proxy.Window.StartTrackingMouse(false);
} }
/// <summary> /// <summary>
@@ -101,6 +102,8 @@ namespace FlaxEditor.GUI.Docking
Proxy.Window.MouseUp -= OnMouseUp; Proxy.Window.MouseUp -= OnMouseUp;
Proxy.Window.MouseMove -= OnMouseMove; Proxy.Window.MouseMove -= OnMouseMove;
Proxy.Window.LostFocus -= OnLostFocus; Proxy.Window.LostFocus -= OnLostFocus;
if (_toMove?.Window?.Window)
_toMove.Window.Window.MouseUp -= OnMouseUp;
// Hide the proxy // Hide the proxy
Proxy.Hide(); Proxy.Hide();
@@ -438,7 +441,7 @@ namespace FlaxEditor.GUI.Docking
settings.AllowMinimize = false; settings.AllowMinimize = false;
settings.HasBorder = false; settings.HasBorder = false;
settings.HasSizingFrame = false; settings.HasSizingFrame = false;
settings.IsRegularWindow = false; settings.Type = WindowType.Utility;
settings.SupportsTransparency = true; settings.SupportsTransparency = true;
settings.ShowInTaskbar = false; settings.ShowInTaskbar = false;
settings.ShowAfterFirstPaint = false; settings.ShowAfterFirstPaint = false;
@@ -470,7 +473,7 @@ namespace FlaxEditor.GUI.Docking
settings.AllowMinimize = false; settings.AllowMinimize = false;
settings.HasBorder = false; settings.HasBorder = false;
settings.HasSizingFrame = false; settings.HasSizingFrame = false;
settings.IsRegularWindow = false; settings.Type = WindowType.Utility;
settings.SupportsTransparency = true; settings.SupportsTransparency = true;
settings.ShowInTaskbar = false; settings.ShowInTaskbar = false;
settings.ActivateWhenFirstShown = false; settings.ActivateWhenFirstShown = false;

View File

@@ -629,7 +629,7 @@ namespace FlaxEditor.GUI.Docking
internal void MoveTabRight(int index) internal void MoveTabRight(int index)
{ {
if (index < _tabs.Count - 2) if (index < _tabs.Count - 1)
{ {
var tab = _tabs[index]; var tab = _tabs[index];
_tabs.RemoveAt(index); _tabs.RemoveAt(index);

View File

@@ -51,6 +51,7 @@ namespace FlaxEditor.GUI.Docking
public DockWindow StartDragAsyncWindow; public DockWindow StartDragAsyncWindow;
private Rectangle HeaderRectangle => new Rectangle(0, 0, Width, DockPanel.DefaultHeaderHeight); private Rectangle HeaderRectangle => new Rectangle(0, 0, Width, DockPanel.DefaultHeaderHeight);
private bool IsSingleFloatingWindow => _panel.TabsCount == 1 && _panel.IsFloating && _panel.ChildPanelsCount == 0;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DockPanelProxy"/> class. /// Initializes a new instance of the <see cref="DockPanelProxy"/> class.
@@ -187,6 +188,10 @@ namespace FlaxEditor.GUI.Docking
var headerRect = HeaderRectangle; var headerRect = HeaderRectangle;
var tabsCount = _panel.TabsCount; var tabsCount = _panel.TabsCount;
// Return and don't draw tab if only 1 window and it is floating
if (IsSingleFloatingWindow)
return;
// Check if has only one window docked // Check if has only one window docked
if (tabsCount == 1) if (tabsCount == 1)
{ {
@@ -321,6 +326,9 @@ namespace FlaxEditor.GUI.Docking
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseDoubleClick(Float2 location, MouseButton button) public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
{ {
if (IsSingleFloatingWindow)
return base.OnMouseDoubleClick(location, button);
// Maximize/restore on double click // Maximize/restore on double click
var tab = GetTabAtPos(location, out _); var tab = GetTabAtPos(location, out _);
var rootWindow = tab?.RootWindow; var rootWindow = tab?.RootWindow;
@@ -339,6 +347,8 @@ namespace FlaxEditor.GUI.Docking
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button) public override bool OnMouseDown(Float2 location, MouseButton button)
{ {
if (IsSingleFloatingWindow)
return base.OnMouseDown(location, button);
MouseDownWindow = GetTabAtPos(location, out IsMouseDownOverCross); MouseDownWindow = GetTabAtPos(location, out IsMouseDownOverCross);
// Check buttons // Check buttons
@@ -368,6 +378,9 @@ namespace FlaxEditor.GUI.Docking
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button) public override bool OnMouseUp(Float2 location, MouseButton button)
{ {
if (IsSingleFloatingWindow)
return base.OnMouseUp(location, button);
// Check tabs under mouse position at the beginning and at the end // Check tabs under mouse position at the beginning and at the end
var tab = GetTabAtPos(location, out var overCross); var tab = GetTabAtPos(location, out var overCross);
@@ -410,7 +423,7 @@ namespace FlaxEditor.GUI.Docking
public override void OnMouseMove(Float2 location) public override void OnMouseMove(Float2 location)
{ {
MousePosition = location; MousePosition = location;
if (IsMouseLeftButtonDown) if (IsMouseLeftButtonDown && !IsSingleFloatingWindow)
{ {
// Check if mouse is outside the header // Check if mouse is outside the header
if (!HeaderRectangle.Contains(location)) if (!HeaderRectangle.Contains(location))
@@ -501,7 +514,10 @@ namespace FlaxEditor.GUI.Docking
/// <inheritdoc /> /// <inheritdoc />
public override void GetDesireClientArea(out Rectangle rect) public override void GetDesireClientArea(out Rectangle rect)
{ {
rect = new Rectangle(0, DockPanel.DefaultHeaderHeight, Width, Height - DockPanel.DefaultHeaderHeight); if (IsSingleFloatingWindow)
rect = new Rectangle(0, 0, Width, Height);
else
rect = new Rectangle(0, DockPanel.DefaultHeaderHeight, Width, Height - DockPanel.DefaultHeaderHeight);
} }
private DragDropEffect TrySelectTabUnderLocation(ref Float2 location) private DragDropEffect TrySelectTabUnderLocation(ref Float2 location)

View File

@@ -82,7 +82,7 @@ namespace FlaxEditor.GUI.Docking
settings.AllowMaximize = true; settings.AllowMaximize = true;
settings.AllowDragAndDrop = true; settings.AllowDragAndDrop = true;
settings.IsTopmost = false; settings.IsTopmost = false;
settings.IsRegularWindow = true; settings.Type = WindowType.Regular;
settings.HasSizingFrame = true; settings.HasSizingFrame = true;
settings.ShowAfterFirstPaint = false; settings.ShowAfterFirstPaint = false;
settings.ShowInTaskbar = true; settings.ShowInTaskbar = true;

View File

@@ -130,7 +130,7 @@ namespace FlaxEditor.GUI.Input
base.Draw(); base.Draw();
var style = Style.Current; var style = Style.Current;
var r = new Rectangle(2, 2, Width - 4, Height - 4); var r = new Rectangle(0, 0, Width, Height);
Render2D.FillRectangle(r, _value); Render2D.FillRectangle(r, _value);
Render2D.DrawRectangle(r, IsMouseOver || IsNavFocused ? style.BackgroundSelected : Color.Black); Render2D.DrawRectangle(r, IsMouseOver || IsNavFocused ? style.BackgroundSelected : Color.Black);

View File

@@ -132,6 +132,8 @@ namespace FlaxEditor.GUI.Input
_isSliding = false; _isSliding = false;
EndMouseCapture(); EndMouseCapture();
SlidingEnd?.Invoke(); SlidingEnd?.Invoke();
Defocus();
Parent?.Focus();
} }
/// <summary> /// <summary>
@@ -183,6 +185,8 @@ namespace FlaxEditor.GUI.Input
{ {
// Click change // Click change
Value += (mousePosition < _thumbCenter ? -1 : 1) * 10; Value += (mousePosition < _thumbCenter ? -1 : 1) * 10;
Defocus();
Parent?.Focus();
} }
} }
@@ -197,6 +201,10 @@ namespace FlaxEditor.GUI.Input
// Update sliding // Update sliding
var slidePosition = location + Root.TrackingMouseOffset; var slidePosition = location + Root.TrackingMouseOffset;
Value = Mathf.Remap(slidePosition.X, 4, TrackSize - 4, Minimum, Maximum); Value = Mathf.Remap(slidePosition.X, 4, TrackSize - 4, Minimum, Maximum);
if (Mathf.NearEqual(Value, Maximum))
Value = Maximum;
else if (Mathf.NearEqual(Value, Minimum))
Value = Minimum;
} }
else else
{ {
@@ -364,7 +372,7 @@ namespace FlaxEditor.GUI.Input
}; };
_slider.ValueChanged += SliderOnValueChanged; _slider.ValueChanged += SliderOnValueChanged;
_slider.SlidingStart += SlidingStart; _slider.SlidingStart += SlidingStart;
_slider.SlidingEnd += SlidingEnd; _slider.SlidingEnd += SliderOnSliderEnd;
_textBox = new TextBox(false, split, 0) _textBox = new TextBox(false, split, 0)
{ {
Text = _value.ToString(CultureInfo.InvariantCulture), Text = _value.ToString(CultureInfo.InvariantCulture),
@@ -375,6 +383,13 @@ namespace FlaxEditor.GUI.Input
_textBox.EditEnd += OnTextBoxEditEnd; _textBox.EditEnd += OnTextBoxEditEnd;
} }
private void SliderOnSliderEnd()
{
SlidingEnd?.Invoke();
Defocus();
Parent?.Focus();
}
private void SliderOnValueChanged() private void SliderOnValueChanged()
{ {
if (_valueIsChanging) if (_valueIsChanging)
@@ -397,6 +412,8 @@ namespace FlaxEditor.GUI.Input
{ {
UpdateText(); UpdateText();
} }
Defocus();
Parent?.Focus();
} }
/// <summary> /// <summary>

View File

@@ -266,6 +266,7 @@ namespace FlaxEditor.GUI.Input
return base.OnMouseDown(location, button); return base.OnMouseDown(location, button);
} }
#if !PLATFORM_SDL
/// <inheritdoc /> /// <inheritdoc />
public override void OnMouseMove(Float2 location) public override void OnMouseMove(Float2 location)
{ {
@@ -292,6 +293,36 @@ namespace FlaxEditor.GUI.Input
base.OnMouseMove(location); base.OnMouseMove(location);
} }
#else
/// <inheritdoc />
public override void OnMouseMoveRelative(Float2 mouseMotion)
{
var location = Root.TrackingMouseOffset;
if (_isSliding)
{
// Update sliding
ApplySliding(Root.TrackingMouseOffset.X * _slideSpeed);
return;
}
// Update cursor type so user knows they can slide value
if (CanUseSliding && SlideRect.Contains(location) && !_isSliding)
{
Cursor = CursorType.SizeWE;
_cursorChanged = true;
}
else if (_cursorChanged && !_isSliding)
{
Cursor = CursorType.Default;
_cursorChanged = false;
}
base.OnMouseMoveRelative(mouseMotion);
}
#endif
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button) public override bool OnMouseUp(Float2 location, MouseButton button)
{ {

View File

@@ -23,6 +23,9 @@ namespace FlaxEditor.GUI
[HideInEditor] [HideInEditor]
public class Item : Control public class Item : Control
{ {
private bool _isStartsWithMatch;
private bool _isFullMatch;
/// <summary> /// <summary>
/// The is mouse down flag. /// The is mouse down flag.
/// </summary> /// </summary>
@@ -43,6 +46,11 @@ namespace FlaxEditor.GUI
/// </summary> /// </summary>
public string Category; public string Category;
/// <summary>
/// A computed score for the context menu order
/// </summary>
public float SortScore;
/// <summary> /// <summary>
/// Occurs when items gets clicked by the user. /// Occurs when items gets clicked by the user.
/// </summary> /// </summary>
@@ -61,44 +69,69 @@ namespace FlaxEditor.GUI
{ {
} }
/// <summary>
/// Updates the <see cref="SortScore"/>
/// </summary>
public void UpdateScore()
{
SortScore = 0;
if (!Visible)
return;
if (_highlights is { Count: > 0 })
SortScore += 1;
if (_isStartsWithMatch)
SortScore += 2;
if (_isFullMatch)
SortScore += 5;
}
/// <summary> /// <summary>
/// Updates the filter. /// Updates the filter.
/// </summary> /// </summary>
/// <param name="filterText">The filter text.</param> /// <param name="filterText">The filter text.</param>
public void UpdateFilter(string filterText) public void UpdateFilter(string filterText)
{ {
_isStartsWithMatch = _isFullMatch = false;
if (string.IsNullOrWhiteSpace(filterText)) if (string.IsNullOrWhiteSpace(filterText))
{ {
// Clear filter // Clear filter
_highlights?.Clear(); _highlights?.Clear();
Visible = true; Visible = true;
return;
} }
else
if (QueryFilterHelper.Match(filterText, Name, out var ranges))
{ {
if (QueryFilterHelper.Match(filterText, Name, out var ranges)) // Update highlights
{ if (_highlights == null)
// Update highlights _highlights = new List<Rectangle>(ranges.Length);
if (_highlights == null)
_highlights = new List<Rectangle>(ranges.Length);
else
_highlights.Clear();
var style = Style.Current;
var font = style.FontSmall;
for (int i = 0; i < ranges.Length; i++)
{
var start = font.GetCharPosition(Name, ranges[i].StartIndex);
var end = font.GetCharPosition(Name, ranges[i].EndIndex);
_highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height));
}
Visible = true;
}
else else
_highlights.Clear();
var style = Style.Current;
var font = style.FontSmall;
for (int i = 0; i < ranges.Length; i++)
{ {
// Hide var start = font.GetCharPosition(Name, ranges[i].StartIndex);
_highlights?.Clear(); var end = font.GetCharPosition(Name, ranges[i].EndIndex);
Visible = false; _highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height));
if (ranges[i].StartIndex <= 0)
{
_isStartsWithMatch = true;
if (ranges[i].Length == Name.Length)
_isFullMatch = true;
}
} }
Visible = true;
return;
} }
// Hide
_highlights?.Clear();
Visible = false;
} }
/// <summary> /// <summary>
@@ -178,7 +211,14 @@ namespace FlaxEditor.GUI
public override int Compare(Control other) public override int Compare(Control other)
{ {
if (other is Item otherItem) if (other is Item otherItem)
return string.Compare(Name, otherItem.Name, StringComparison.Ordinal); {
int order = -1 * SortScore.CompareTo(otherItem.SortScore);
if (order == 0)
{
order = string.Compare(Name, otherItem.Name, StringComparison.Ordinal);
}
return order;
}
return base.Compare(other); return base.Compare(other);
} }
} }
@@ -249,7 +289,10 @@ namespace FlaxEditor.GUI
for (int i = 0; i < items.Count; i++) for (int i = 0; i < items.Count; i++)
{ {
if (items[i] is Item item) if (items[i] is Item item)
{
item.UpdateFilter(_searchBox.Text); item.UpdateFilter(_searchBox.Text);
item.UpdateScore();
}
} }
if (_categoryPanels != null) if (_categoryPanels != null)
{ {
@@ -262,6 +305,7 @@ namespace FlaxEditor.GUI
if (category.Children[j] is Item item2) if (category.Children[j] is Item item2)
{ {
item2.UpdateFilter(_searchBox.Text); item2.UpdateFilter(_searchBox.Text);
item2.UpdateScore();
anyVisible |= item2.Visible; anyVisible |= item2.Visible;
} }
} }
@@ -273,6 +317,8 @@ namespace FlaxEditor.GUI
} }
} }
SortItems();
UnlockChildrenRecursive(); UnlockChildrenRecursive();
PerformLayout(true); PerformLayout(true);
_searchBox.Focus(); _searchBox.Focus();

View File

@@ -12,7 +12,7 @@ namespace FlaxEditor.GUI
/// <seealso cref="FlaxEngine.GUI.ContainerControl" /> /// <seealso cref="FlaxEngine.GUI.ContainerControl" />
public sealed class MainMenu : ContainerControl public sealed class MainMenu : ContainerControl
{ {
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS || PLATFORM_SDL
private bool _useCustomWindowSystem; private bool _useCustomWindowSystem;
private Image _icon; private Image _icon;
private Label _title; private Label _title;
@@ -67,7 +67,7 @@ namespace FlaxEditor.GUI
AutoFocus = false; AutoFocus = false;
AnchorPreset = AnchorPresets.HorizontalStretchTop; AnchorPreset = AnchorPresets.HorizontalStretchTop;
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS || PLATFORM_SDL
_useCustomWindowSystem = !Editor.Instance.Options.Options.Interface.UseNativeWindowSystem; _useCustomWindowSystem = !Editor.Instance.Options.Options.Interface.UseNativeWindowSystem;
if (_useCustomWindowSystem) if (_useCustomWindowSystem)
{ {
@@ -166,7 +166,7 @@ namespace FlaxEditor.GUI
} }
} }
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS || PLATFORM_SDL
/// <inheritdoc /> /// <inheritdoc />
public override void Update(float deltaTime) public override void Update(float deltaTime)
{ {
@@ -291,7 +291,7 @@ namespace FlaxEditor.GUI
if (base.OnMouseDoubleClick(location, button)) if (base.OnMouseDoubleClick(location, button))
return true; return true;
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS || PLATFORM_SDL
var child = GetChildAtRecursive(location); var child = GetChildAtRecursive(location);
if (_useCustomWindowSystem && child is not Button && child is not MainMenuButton) if (_useCustomWindowSystem && child is not Button && child is not MainMenuButton)
{ {
@@ -321,7 +321,7 @@ namespace FlaxEditor.GUI
{ {
float x = 0; float x = 0;
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS || PLATFORM_SDL
if (_useCustomWindowSystem) if (_useCustomWindowSystem)
{ {
// Icon // Icon
@@ -349,7 +349,7 @@ namespace FlaxEditor.GUI
} }
} }
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS || PLATFORM_SDL
if (_useCustomWindowSystem) if (_useCustomWindowSystem)
{ {
// Buttons // Buttons
@@ -367,7 +367,7 @@ namespace FlaxEditor.GUI
#endif #endif
} }
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS || PLATFORM_SDL
/// <inheritdoc /> /// <inheritdoc />
public override void OnDestroy() public override void OnDestroy()
{ {

View File

@@ -42,7 +42,7 @@ namespace FlaxEditor.GUI
Text = text; Text = text;
var style = Style.Current; var style = Style.Current;
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS || PLATFORM_SDL
if (Editor.Instance.Options.Options.Interface.UseNativeWindowSystem) if (Editor.Instance.Options.Options.Interface.UseNativeWindowSystem)
{ {
BackgroundColorMouseOver = style.BackgroundHighlighted; BackgroundColorMouseOver = style.BackgroundHighlighted;

View File

@@ -38,7 +38,7 @@ namespace FlaxEditor.GUI
ContentItem = item; ContentItem = item;
ContentItem.AddReference(this); ContentItem.AddReference(this);
Name = item.ShortName; OnItemRenamed(item);
TooltipText = item.Path; TooltipText = item.Path;
Height = IconSize + 4; Height = IconSize + 4;
@@ -82,7 +82,9 @@ namespace FlaxEditor.GUI
/// <inheritdoc /> /// <inheritdoc />
public void OnItemRenamed(ContentItem item) public void OnItemRenamed(ContentItem item)
{ {
Name = ContentItem.ShortName; Name = item.ShortName;
if (item is ScriptItem)
Name = item.FileName; // Show extension for scripts (esp. for .h and .cpp files of the same name)
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -130,12 +130,14 @@ namespace FlaxEditor.GUI
var style = Style.Current; var style = Style.Current;
var font = column.TitleFont ?? style.FontMedium; var font = column.TitleFont ?? style.FontMedium;
Render2D.DrawText(font, column.Title, rect, column.TitleColor, TextAlignment.Center, TextAlignment.Center); var textRect = rect;
column.TitleMargin.ShrinkRectangle(ref textRect);
Render2D.DrawText(font, column.Title, textRect, column.TitleColor, column.TitleAlignment, TextAlignment.Center);
if (columnIndex < _columns.Length - 1) if (columnIndex < _columns.Length - 1)
{ {
var splitRect = new Rectangle(rect.Right - 1, 2, 2, rect.Height - 4); var splitRect = new Rectangle(rect.Right - 2, 2, 4, rect.Height - 4);
Render2D.FillRectangle(splitRect, _movingSplit == columnIndex || splitRect.Contains(_mousePos) ? style.BorderNormal : column.TitleBackgroundColor * 0.9f); Render2D.FillRectangle(splitRect, _movingSplit == columnIndex || splitRect.Contains(_mousePos) ? style.BorderNormal : style.Background * 0.9f);
} }
} }
@@ -151,7 +153,7 @@ namespace FlaxEditor.GUI
{ {
rect.Width = GetColumnWidth(i); rect.Width = GetColumnWidth(i);
var splitRect = new Rectangle(rect.Right - 1, 2, 2, rect.Height - 4); var splitRect = new Rectangle(rect.Right - 2, 2, 4, rect.Height - 4);
if (splitRect.Contains(location)) if (splitRect.Contains(location))
{ {
// Start moving splitter // Start moving splitter
@@ -193,6 +195,31 @@ namespace FlaxEditor.GUI
PerformLayout(); PerformLayout();
} }
else
{
if (_columns != null && _splits != null)
{
Rectangle rect = new Rectangle(0, 0, 0, _headerHeight);
for (int i = 0; i < _columns.Length - 1; i++)
{
rect.Width = GetColumnWidth(i);
var splitRect = new Rectangle(rect.Right - 2, 2, 4, rect.Height - 4);
if (splitRect.Contains(location))
{
// Start moving splitter
Cursor = CursorType.SizeWE;
break;
}
else
{
Cursor = CursorType.Default;
}
rect.X += rect.Width;
}
}
}
base.OnMouseMove(location); base.OnMouseMove(location);
} }

View File

@@ -418,9 +418,19 @@ namespace FlaxEditor.GUI.Tabs
{ {
// If scroll bar is visible it covers part of the tab header so include this in tab size to improve usability // If scroll bar is visible it covers part of the tab header so include this in tab size to improve usability
if (_orientation == Orientation.Horizontal && TabsPanel.HScrollBar.Visible) if (_orientation == Orientation.Horizontal && TabsPanel.HScrollBar.Visible)
{
tabsSize.Y += TabsPanel.HScrollBar.Height; tabsSize.Y += TabsPanel.HScrollBar.Height;
var style = Style.Current;
TabsPanel.HScrollBar.TrackColor = style.Background;
TabsPanel.HScrollBar.ThumbColor = style.ForegroundGrey;
}
else if (_orientation == Orientation.Vertical && TabsPanel.VScrollBar.Visible) else if (_orientation == Orientation.Vertical && TabsPanel.VScrollBar.Visible)
{
tabsSize.X += TabsPanel.VScrollBar.Width; tabsSize.X += TabsPanel.VScrollBar.Width;
var style = Style.Current;
TabsPanel.VScrollBar.TrackColor = style.Background;
TabsPanel.VScrollBar.ThumbColor = style.ForegroundGrey;
}
} }
// Fit the tabs panel // Fit the tabs panel

View File

@@ -130,7 +130,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
/// The keyframes. /// The keyframes.
/// </summary> /// </summary>
[EditorDisplay("Keyframes", EditorDisplayAttribute.InlineStyle), ExpandGroups] [EditorDisplay("Keyframes", EditorDisplayAttribute.InlineStyle), ExpandGroups]
[Collection(CanReorderItems = false, ReadOnly = true)] [Collection(CanReorderItems = false, CanResize = true)]
public List<KeyValuePair<string, object>> Keyframes; public List<KeyValuePair<string, object>> Keyframes;
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -159,7 +159,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
/// The parameters values. /// The parameters values.
/// </summary> /// </summary>
[EditorDisplay("Parameters", EditorDisplayAttribute.InlineStyle), ExpandGroups] [EditorDisplay("Parameters", EditorDisplayAttribute.InlineStyle), ExpandGroups]
[Collection(CanReorderItems = false, ReadOnly = true)] [Collection(CanReorderItems = false, CanResize = true)]
public object[] Parameters; public object[] Parameters;
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -363,6 +363,8 @@ namespace FlaxEditor.GUI.Timeline.Tracks
/// <inheritdoc /> /// <inheritdoc />
public override void OnDestroy() public override void OnDestroy()
{ {
if (_previewValue != null)
Timeline.ShowPreviewValuesChanged -= OnTimelineShowPreviewValuesChanged;
_previewValue = null; _previewValue = null;
_rightKey = null; _rightKey = null;
_addKey = null; _addKey = null;

View File

@@ -698,6 +698,38 @@ namespace FlaxEditor.GUI.Tree
} }
} }
// Show tree guidelines
if (Editor.Instance.Options.Options.Interface.ShowTreeLines)
{
TreeNode parentNode = Parent as TreeNode;
bool thisNodeIsLast = false;
while (parentNode != null && parentNode != ParentTree.Children[0])
{
float bottomOffset = 0;
float topOffset = 0;
if (Parent == parentNode && this == Parent.Children[0])
topOffset = 2;
if (thisNodeIsLast && parentNode.Children.Count == 1)
bottomOffset = topOffset != 0 ? 4 : 2;
if (Parent == parentNode && this == Parent.Children[Parent.Children.Count - 1] && !_opened)
{
thisNodeIsLast = true;
bottomOffset = topOffset != 0 ? 4 : 2;
}
float leftOffset = 9;
// Adjust offset for icon image
if (_iconCollaped.IsValid)
leftOffset += 18;
var lineRect1 = new Rectangle(parentNode.TextRect.Left - leftOffset, parentNode.HeaderRect.Top + topOffset, 1, parentNode.HeaderRect.Height - bottomOffset);
Render2D.FillRectangle(lineRect1, isSelected ? style.ForegroundGrey : style.LightBackground);
parentNode = parentNode.Parent as TreeNode;
}
}
// Base // Base
if (_opened) if (_opened)
{ {
@@ -721,15 +753,16 @@ namespace FlaxEditor.GUI.Tree
var children = _children; var children = _children;
if (children.Count == 0) if (children.Count == 0)
return; return;
var last = children.Count - 1;
if (CullChildren) if (CullChildren)
{ {
Render2D.PeekClip(out var globalClipping); Render2D.PeekClip(out var globalClipping);
Render2D.PeekTransform(out var globalTransform); Render2D.PeekTransform(out var globalTransform);
// Try to estimate the rough location of the first node, assuming the node height is constant // Try to estimate the rough location of the first and the last nodes, assuming the node height is constant
var firstChildGlobalRect = GetChildGlobalRectangle(children[0], ref globalTransform); var firstChildGlobalRect = GetChildGlobalRectangle(children[0], ref globalTransform);
var firstVisibleChild = Math.Clamp((int)Math.Floor((globalClipping.Y - firstChildGlobalRect.Top) / firstChildGlobalRect.Height) + 1, 0, children.Count - 1); var firstVisibleChild = Math.Clamp((int)Math.Floor((globalClipping.Top - firstChildGlobalRect.Top) / _headerHeight) + 1, 0, last);
if (GetChildGlobalRectangle(children[firstVisibleChild], ref globalTransform).Top > globalClipping.Top || !children[firstVisibleChild].Visible) if (GetChildGlobalRectangle(children[firstVisibleChild], ref globalTransform).Top > globalClipping.Top || !children[firstVisibleChild].Visible)
{ {
// Estimate overshoot, either it's partially visible or hidden in the tree // Estimate overshoot, either it's partially visible or hidden in the tree
@@ -738,22 +771,29 @@ namespace FlaxEditor.GUI.Tree
var child = children[firstVisibleChild]; var child = children[firstVisibleChild];
if (!child.Visible) if (!child.Visible)
continue; continue;
if (GetChildGlobalRectangle(child, ref globalTransform).Top < globalClipping.Top) if (GetChildGlobalRectangle(child, ref globalTransform).Top < globalClipping.Top)
break; break;
} }
} }
var lastVisibleChild = Math.Clamp((int)Math.Ceiling((globalClipping.Bottom - firstChildGlobalRect.Top) / _headerHeight) + 1, firstVisibleChild, last);
if (GetChildGlobalRectangle(children[lastVisibleChild], ref globalTransform).Top < globalClipping.Bottom || !children[lastVisibleChild].Visible)
{
// Estimate overshoot, either it's partially visible or hidden in the tree
for (; lastVisibleChild < last; lastVisibleChild++)
{
var child = children[lastVisibleChild];
if (!child.Visible)
continue;
if (GetChildGlobalRectangle(child, ref globalTransform).Top > globalClipping.Bottom)
break;
}
}
for (int i = firstVisibleChild; i < children.Count; i++) for (int i = firstVisibleChild; i <= lastVisibleChild; i++)
{ {
var child = children[i]; var child = children[i];
if (!child.Visible) if (!child.Visible)
continue; continue;
var childGlobalRect = GetChildGlobalRectangle(child, ref globalTransform);
if (!globalClipping.Intersects(ref childGlobalRect))
break;
Render2D.PushTransform(ref child._cachedTransform); Render2D.PushTransform(ref child._cachedTransform);
child.Draw(); child.Draw();
Render2D.PopTransform(); Render2D.PopTransform();
@@ -767,7 +807,7 @@ namespace FlaxEditor.GUI.Tree
} }
else else
{ {
for (int i = 0; i < children.Count; i++) for (int i = 0; i <= last; i++)
{ {
var child = children[i]; var child = children[i];
if (child.Visible) if (child.Visible)

View File

@@ -2,6 +2,7 @@
using System; using System;
using FlaxEngine; using FlaxEngine;
using System.Runtime.InteropServices;
namespace FlaxEditor.Gizmo namespace FlaxEditor.Gizmo
{ {
@@ -15,91 +16,120 @@ namespace FlaxEditor.Gizmo
[HideInEditor] [HideInEditor]
private sealed class Renderer : PostProcessEffect private sealed class Renderer : PostProcessEffect
{ {
private IntPtr _debugDrawContext; [StructLayout(LayoutKind.Sequential)]
private struct Data
{
public Matrix WorldMatrix;
public Matrix ViewProjectionMatrix;
public Float4 GridColor;
public Float3 ViewPos;
public float Far;
public Float3 Padding;
public float GridSize;
}
private static readonly uint[] _triangles =
{
0, 2, 1, // Face front
1, 3, 0,
};
private GPUBuffer[] _vbs = new GPUBuffer[1];
private GPUBuffer _vertexBuffer;
private GPUBuffer _indexBuffer;
private GPUPipelineState _psGrid;
private Shader _shader;
public Renderer() public Renderer()
{ {
Order = -100;
UseSingleTarget = true; UseSingleTarget = true;
Location = PostProcessEffectLocation.BeforeForwardPass; Location = PostProcessEffectLocation.Default;
_shader = FlaxEngine.Content.LoadAsyncInternal<Shader>("Shaders/Editor/Grid");
} }
~Renderer() ~Renderer()
{ {
if (_debugDrawContext != IntPtr.Zero) Destroy(ref _psGrid);
{ Destroy(ref _vertexBuffer);
DebugDraw.FreeContext(_debugDrawContext); Destroy(ref _indexBuffer);
_debugDrawContext = IntPtr.Zero; _shader = null;
}
} }
public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output) public override unsafe void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
{ {
if (_shader == null)
return;
Profiler.BeginEventGPU("Editor Grid"); Profiler.BeginEventGPU("Editor Grid");
if (_debugDrawContext == IntPtr.Zero)
_debugDrawContext = DebugDraw.AllocateContext();
DebugDraw.SetContext(_debugDrawContext);
DebugDraw.UpdateContext(_debugDrawContext, 1.0f / Mathf.Max(Engine.FramesPerSecond, 1));
var viewPos = (Vector3)renderContext.View.Position;
var plane = new Plane(Vector3.Zero, Vector3.UnitY);
var dst = CollisionsHelper.DistancePlanePoint(ref plane, ref viewPos);
var options = Editor.Instance.Options.Options; var options = Editor.Instance.Options.Options;
float space = options.Viewport.ViewportGridScale, size; Float3 camPos = renderContext.View.WorldPosition;
if (dst <= 500.0f) float gridSize = renderContext.View.Far + 20000;
// Lazy-init resources
if (_vertexBuffer == null)
{ {
size = 8000; _vertexBuffer = new GPUBuffer();
var desc = GPUBufferDescription.Vertex(sizeof(Float3), 4);
_vertexBuffer.Init(ref desc);
} }
else if (dst <= 2000.0f) if (_indexBuffer == null)
{ {
space *= 2; _indexBuffer = new GPUBuffer();
size = 8000; fixed (uint* ptr = _triangles)
{
var desc = GPUBufferDescription.Index(sizeof(uint), _triangles.Length, new IntPtr(ptr));
_indexBuffer.Init(ref desc);
}
} }
else if (_psGrid == null)
{ {
space *= 20; _psGrid = new GPUPipelineState();
size = 100000; var desc = GPUPipelineState.Description.Default;
desc.BlendMode = BlendingMode.AlphaBlend;
desc.CullMode = CullMode.TwoSided;
desc.VS = _shader.GPU.GetVS("VS_Grid");
desc.PS = _shader.GPU.GetPS("PS_Grid");
_psGrid.Init(ref desc);
} }
float bigLineIntensity = 0.8f; // Update vertices of the plane
Color bigColor = Color.Gray * bigLineIntensity; // TODO: perf this operation in a Vertex Shader
Color color = bigColor * 0.8f; float y = 1.5f; // Add small bias to reduce Z-fighting with geometry at scene origin
int count = (int)(size / space); var vertices = new Float3[]
int midLine = count / 2;
int bigLinesMod = count / 8;
Vector3 start = new Vector3(0, 0, size * -0.5f);
Vector3 end = new Vector3(0, 0, size * 0.5f);
for (int i = 0; i <= count; i++)
{ {
start.X = end.X = i * space + start.Z; new Float3(-gridSize + camPos.X, y, -gridSize + camPos.Z),
Color lineColor = color; new Float3(gridSize + camPos.X, y, gridSize + camPos.Z),
if (i == midLine) new Float3(-gridSize + camPos.X, y, gridSize + camPos.Z),
lineColor = Color.Blue * bigLineIntensity; new Float3(gridSize + camPos.X, y, -gridSize + camPos.Z),
else if (i % bigLinesMod == 0) };
lineColor = bigColor; fixed (Float3* ptr = vertices)
DebugDraw.DrawLine(start, end, lineColor); {
context.UpdateBuffer(_vertexBuffer, new IntPtr(ptr), (uint)(sizeof(Float3) * vertices.Length));
} }
start = new Vector3(size * -0.5f, 0, 0); // Update constant buffer data
end = new Vector3(size * 0.5f, 0, 0); var cb = _shader.GPU.GetCB(0);
if (cb != IntPtr.Zero)
for (int i = 0; i <= count; i++)
{ {
start.Z = end.Z = i * space + start.X; var data = new Data();
Color lineColor = color; Matrix.Multiply(ref renderContext.View.View, ref renderContext.View.Projection, out var viewProjection);
if (i == midLine) data.WorldMatrix = Matrix.Identity;
lineColor = Color.Red * bigLineIntensity; Matrix.Transpose(ref viewProjection, out data.ViewProjectionMatrix);
else if (i % bigLinesMod == 0) data.ViewPos = renderContext.View.WorldPosition;
lineColor = bigColor; data.GridColor = options.Viewport.ViewportGridColor;
DebugDraw.DrawLine(start, end, lineColor); data.Far = renderContext.View.Far;
data.GridSize = options.Viewport.ViewportGridViewDistance;
context.UpdateCB(cb, new IntPtr(&data));
} }
DebugDraw.Draw(ref renderContext, input.View(), null, true); // Draw geometry using custom Pixel Shader and Vertex Shader
DebugDraw.SetContext(IntPtr.Zero); context.BindCB(0, cb);
context.BindIB(_indexBuffer);
_vbs[0] = _vertexBuffer;
context.BindVB(_vbs);
context.SetState(_psGrid);
context.SetRenderTarget(renderContext.Buffers.DepthBuffer.View(), input.View());
context.DrawIndexed((uint)_triangles.Length);
Profiler.EndEventGPU(); Profiler.EndEventGPU();
} }

View File

@@ -253,7 +253,11 @@ namespace FlaxEditor
{ {
// Select node (with additive mode) // Select node (with additive mode)
var selection = new List<SceneGraphNode>(); var selection = new List<SceneGraphNode>();
if (Root.GetKey(KeyboardKeys.Control)) if (Root.GetKey(KeyboardKeys.Shift) && transformGizmo.Selection.Contains(uiControlNode))
{
// Move whole selection
}
else if (Root.GetKey(KeyboardKeys.Control))
{ {
// Add/remove from selection // Add/remove from selection
selection.AddRange(transformGizmo.Selection); selection.AddRange(transformGizmo.Selection);
@@ -261,13 +265,14 @@ namespace FlaxEditor
selection.Remove(uiControlNode); selection.Remove(uiControlNode);
else else
selection.Add(uiControlNode); selection.Add(uiControlNode);
owner.Select(selection);
} }
else else
{ {
// Select // Select
selection.Add(uiControlNode); selection.Add(uiControlNode);
owner.Select(selection);
} }
owner.Select(selection);
// Initialize control movement // Initialize control movement
_mouseMovesControl = true; _mouseMovesControl = true;
@@ -499,6 +504,15 @@ namespace FlaxEditor
bool drawAnySelectedControl = false; bool drawAnySelectedControl = false;
var transformGizmo = TransformGizmo; var transformGizmo = TransformGizmo;
var mousePos = PointFromWindow(RootWindow.MousePosition); var mousePos = PointFromWindow(RootWindow.MousePosition);
if (EnableSelecting && !_mouseMovesControl && !_mouseMovesWidget && IsMouseOver)
{
// Highlight control under mouse for easier selecting (except if already selected)
if (RayCastControl(ref mousePos, out var hitControl) &&
(transformGizmo == null || !transformGizmo.Selection.Any(x => x.EditableObject is UIControl controlActor && controlActor.Control == hitControl)))
{
DrawControl(null, hitControl, false, ref mousePos, ref drawAnySelectedControl);
}
}
if (transformGizmo != null) if (transformGizmo != null)
{ {
// Selected UI controls outline // Selected UI controls outline
@@ -511,15 +525,6 @@ namespace FlaxEditor
} }
} }
} }
if (EnableSelecting && !_mouseMovesControl && !_mouseMovesWidget && IsMouseOver)
{
// Highlight control under mouse for easier selecting (except if already selected)
if (RayCastControl(ref mousePos, out var hitControl) &&
(transformGizmo == null || !transformGizmo.Selection.Any(x => x.EditableObject is UIControl controlActor && controlActor.Control == hitControl)))
{
DrawControl(null, hitControl, false, ref mousePos, ref drawAnySelectedControl);
}
}
if (drawAnySelectedControl) if (drawAnySelectedControl)
Render2D.PopTransform(); Render2D.PopTransform();
@@ -617,40 +622,36 @@ namespace FlaxEditor
// Draw sizing widgets // Draw sizing widgets
if (_widgets == null) if (_widgets == null)
_widgets = new List<Widget>(); _widgets = new List<Widget>();
var widgetSize = 8.0f; var widgetSize = 10.0f;
var viewScale = ViewScale; var viewScale = ViewScale;
if (viewScale < 0.7f) if (viewScale < 0.7f)
widgetSize *= viewScale; widgetSize *= viewScale;
var controlSize = control.Size.Absolute.MinValue / 50.0f; var widgetHandleSize = new Float2(widgetSize);
if (controlSize < 1.0f) DrawControlWidget(uiControl, ref ul, ref mousePos, ref widgetHandleSize, viewScale, new Float2(-1, -1), CursorType.SizeNWSE);
widgetSize *= Mathf.Clamp(controlSize + 0.1f, 0.1f, 1.0f); DrawControlWidget(uiControl, ref ur, ref mousePos, ref widgetHandleSize, viewScale, new Float2(1, -1), CursorType.SizeNESW);
var cornerSize = new Float2(widgetSize); DrawControlWidget(uiControl, ref bl, ref mousePos, ref widgetHandleSize, viewScale, new Float2(-1, 1), CursorType.SizeNESW);
DrawControlWidget(uiControl, ref ul, ref mousePos, ref cornerSize, new Float2(-1, -1), CursorType.SizeNWSE); DrawControlWidget(uiControl, ref br, ref mousePos, ref widgetHandleSize, viewScale, new Float2(1, 1), CursorType.SizeNWSE);
DrawControlWidget(uiControl, ref ur, ref mousePos, ref cornerSize, new Float2(1, -1), CursorType.SizeNESW);
DrawControlWidget(uiControl, ref bl, ref mousePos, ref cornerSize, new Float2(-1, 1), CursorType.SizeNESW);
DrawControlWidget(uiControl, ref br, ref mousePos, ref cornerSize, new Float2(1, 1), CursorType.SizeNWSE);
var edgeSizeV = new Float2(widgetSize * 2, widgetSize);
var edgeSizeH = new Float2(edgeSizeV.Y, edgeSizeV.X);
Float2.Lerp(ref ul, ref bl, 0.5f, out var el); Float2.Lerp(ref ul, ref bl, 0.5f, out var el);
Float2.Lerp(ref ur, ref br, 0.5f, out var er); Float2.Lerp(ref ur, ref br, 0.5f, out var er);
Float2.Lerp(ref ul, ref ur, 0.5f, out var eu); Float2.Lerp(ref ul, ref ur, 0.5f, out var eu);
Float2.Lerp(ref bl, ref br, 0.5f, out var eb); Float2.Lerp(ref bl, ref br, 0.5f, out var eb);
DrawControlWidget(uiControl, ref el, ref mousePos, ref edgeSizeH, new Float2(-1, 0), CursorType.SizeWE); DrawControlWidget(uiControl, ref el, ref mousePos, ref widgetHandleSize, viewScale, new Float2(-1, 0), CursorType.SizeWE);
DrawControlWidget(uiControl, ref er, ref mousePos, ref edgeSizeH, new Float2(1, 0), CursorType.SizeWE); DrawControlWidget(uiControl, ref er, ref mousePos, ref widgetHandleSize, viewScale, new Float2(1, 0), CursorType.SizeWE);
DrawControlWidget(uiControl, ref eu, ref mousePos, ref edgeSizeV, new Float2(0, -1), CursorType.SizeNS); DrawControlWidget(uiControl, ref eu, ref mousePos, ref widgetHandleSize, viewScale, new Float2(0, -1), CursorType.SizeNS);
DrawControlWidget(uiControl, ref eb, ref mousePos, ref edgeSizeV, new Float2(0, 1), CursorType.SizeNS); DrawControlWidget(uiControl, ref eb, ref mousePos, ref widgetHandleSize, viewScale, new Float2(0, 1), CursorType.SizeNS);
// TODO: draw anchors // TODO: draw anchors
} }
} }
private void DrawControlWidget(UIControl uiControl, ref Float2 pos, ref Float2 mousePos, ref Float2 size, Float2 resizeAxis, CursorType cursor) private void DrawControlWidget(UIControl uiControl, ref Float2 pos, ref Float2 mousePos, ref Float2 size, float scale, Float2 resizeAxis, CursorType cursor)
{ {
var style = Style.Current; var style = Style.Current;
var rect = new Rectangle(pos - size * 0.5f, size); var rect = new Rectangle((pos + resizeAxis * 10 * scale) - size * 0.5f, size);
if (rect.Contains(ref mousePos)) if (rect.Contains(ref mousePos))
{ {
Render2D.FillRectangle(rect, style.Foreground); Render2D.FillRectangle(rect, style.Foreground);
Render2D.DrawRectangle(rect, style.SelectionBorder);
} }
else else
{ {

View File

@@ -433,6 +433,9 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_RunVisualScriptBreakpointLoopTick(floa
case InputDevice::EventType::MouseMove: case InputDevice::EventType::MouseMove:
window->OnMouseMove(window->ScreenToClient(e.MouseData.Position)); window->OnMouseMove(window->ScreenToClient(e.MouseData.Position));
break; break;
case InputDevice::EventType::MouseMoveRelative:
window->OnMouseMoveRelative(e.MouseMovementData.PositionRelative);
break;
case InputDevice::EventType::MouseLeave: case InputDevice::EventType::MouseLeave:
window->OnMouseLeave(); window->OnMouseLeave();
break; break;

View File

@@ -223,6 +223,19 @@ void ManagedEditor::Init()
{ {
LOG(Info, "Loading managed assemblies (due to disabled compilation on startup)"); LOG(Info, "Loading managed assemblies (due to disabled compilation on startup)");
Scripting::Load(); Scripting::Load();
const auto endInitMethod = mclass->GetMethod("EndInit");
if (endInitMethod == nullptr)
{
LOG(Fatal, "Invalid Editor assembly! Missing EndInit method.");
}
endInitMethod->Invoke(instance, nullptr, &exception);
if (exception)
{
MException ex(exception);
ex.Log(LogType::Warning, TEXT("ManagedEditor::EndInit"));
LOG_STR(Fatal, TEXT("Failed to initialize editor during EndInit! ") + ex.Message);
}
} }
// Call building if need to (based on CL) // Call building if need to (based on CL)

View File

@@ -27,6 +27,7 @@ API_CLASS(Namespace="FlaxEditor", Name="Editor", NoSpawn, NoConstructor) class M
byte AutoReloadScriptsOnMainWindowFocus = 1; byte AutoReloadScriptsOnMainWindowFocus = 1;
byte ForceScriptCompilationOnStartup = 1; byte ForceScriptCompilationOnStartup = 1;
byte UseAssetImportPathRelative = 1; byte UseAssetImportPathRelative = 1;
byte EnableParticlesPreview = 1;
byte AutoRebuildCSG = 1; byte AutoRebuildCSG = 1;
float AutoRebuildCSGTimeoutMs = 50; float AutoRebuildCSGTimeoutMs = 50;
byte AutoRebuildNavMesh = 1; byte AutoRebuildNavMesh = 1;

View File

@@ -228,7 +228,7 @@ namespace FlaxEditor.Modules
new SearchResult { Name = item.ShortName, Type = assetItem.TypeName, Item = item } new SearchResult { Name = item.ShortName, Type = assetItem.TypeName, Item = item }
}; };
} }
var actor = FlaxEngine.Object.Find<Actor>(ref id); var actor = FlaxEngine.Object.Find<Actor>(ref id, true);
if (actor != null) if (actor != null)
{ {
return new List<SearchResult> return new List<SearchResult>
@@ -236,6 +236,16 @@ namespace FlaxEditor.Modules
new SearchResult { Name = actor.Name, Type = actor.TypeName, Item = actor } new SearchResult { Name = actor.Name, Type = actor.TypeName, Item = actor }
}; };
} }
var script = FlaxEngine.Object.Find<Script>(ref id, true);
if (script != null && script.Actor != null)
{
string actorPathStart = $"{script.Actor.Name}/";
return new List<SearchResult>
{
new SearchResult { Name = $"{actorPathStart}{script.TypeName}", Type = script.TypeName, Item = script }
};
}
} }
Profiler.BeginEvent("ContentFinding.Search"); Profiler.BeginEvent("ContentFinding.Search");
@@ -332,9 +342,10 @@ namespace FlaxEditor.Modules
{ {
foreach (var contentItem in items) foreach (var contentItem in items)
{ {
var name = contentItem.ShortName;
if (contentItem.IsAsset) if (contentItem.IsAsset)
{ {
if (nameRegex.Match(contentItem.ShortName).Success) if (nameRegex.Match(name).Success)
{ {
var asset = contentItem as AssetItem; var asset = contentItem as AssetItem;
if (asset == null || !typeRegex.Match(asset.TypeName).Success) if (asset == null || !typeRegex.Match(asset.TypeName).Success)
@@ -348,7 +359,7 @@ namespace FlaxEditor.Modules
var splits = asset.TypeName.Split('.'); var splits = asset.TypeName.Split('.');
finalName = splits[splits.Length - 1]; finalName = splits[splits.Length - 1];
} }
matches.Add(new SearchResult { Name = asset.ShortName, Type = finalName, Item = asset }); matches.Add(new SearchResult { Name = name, Type = finalName, Item = asset });
} }
} }
else if (contentItem.IsFolder) else if (contentItem.IsFolder)
@@ -360,11 +371,12 @@ namespace FlaxEditor.Modules
} }
else else
{ {
if (nameRegex.Match(contentItem.ShortName).Success && typeRegex.Match(contentItem.GetType().Name).Success) if (nameRegex.Match(name).Success && typeRegex.Match(contentItem.GetType().Name).Success)
{ {
string finalName = contentItem.GetType().Name.Replace("Item", ""); string finalName = contentItem.GetType().Name.Replace("Item", "");
if (contentItem is ScriptItem)
matches.Add(new SearchResult { Name = contentItem.ShortName, Type = finalName, Item = contentItem }); name = contentItem.FileName; // Show extension for scripts (esp. for .h and .cpp files of the same name)
matches.Add(new SearchResult { Name = name, Type = finalName, Item = contentItem });
} }
} }
} }
@@ -388,6 +400,13 @@ namespace FlaxEditor.Modules
Editor.Instance.SceneEditing.Select(actor); Editor.Instance.SceneEditing.Select(actor);
Editor.Instance.Windows.EditWin.Viewport.FocusSelection(); Editor.Instance.Windows.EditWin.Viewport.FocusSelection();
break; break;
case Script script:
if (script.Actor != null)
{
Editor.Instance.SceneEditing.Select(script.Actor);
Editor.Instance.Windows.EditWin.Viewport.FocusSelection();
}
break;
} }
} }

View File

@@ -202,6 +202,7 @@ namespace FlaxEditor.Modules
var prefabId = ((ActorNode)selection[0]).Actor.PrefabID; var prefabId = ((ActorNode)selection[0]).Actor.PrefabID;
var prefab = FlaxEngine.Content.LoadAsync<Prefab>(prefabId); var prefab = FlaxEngine.Content.LoadAsync<Prefab>(prefabId);
Editor.Windows.ContentWin.ClearItemsSearch();
Editor.Windows.ContentWin.Select(prefab); Editor.Windows.ContentWin.Select(prefab);
} }

View File

@@ -2,7 +2,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.IO; using System.IO;
using System.Runtime.CompilerServices;
using FlaxEngine; using FlaxEngine;
namespace FlaxEditor.Modules namespace FlaxEditor.Modules
@@ -119,6 +121,30 @@ namespace FlaxEditor.Modules
return _customData.TryGetValue(key, out value); return _customData.TryGetValue(key, out value);
} }
/// <summary>
/// Tries to get the custom data by the key.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">When this method returns, contains the value associated with the specified key, if the key is found; otherwise, the default value for the type of the <paramref name="value" /> parameter. This parameter is passed uninitialized.</param>
/// <returns>The custom data.</returns>
public bool TryGetCustomData(string key, out bool value)
{
value = false;
return _customData.TryGetValue(key, out var valueStr) && bool.TryParse(valueStr, out value);
}
/// <summary>
/// Tries to get the custom data by the key.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">When this method returns, contains the value associated with the specified key, if the key is found; otherwise, the default value for the type of the <paramref name="value" /> parameter. This parameter is passed uninitialized.</param>
/// <returns>The custom data.</returns>
public bool TryGetCustomData(string key, out float value)
{
value = 0.0f;
return _customData.TryGetValue(key, out var valueStr) && float.TryParse(valueStr, out value);
}
/// <summary> /// <summary>
/// Sets the custom data. /// Sets the custom data.
/// </summary> /// </summary>
@@ -130,6 +156,28 @@ namespace FlaxEditor.Modules
_isDirty = true; _isDirty = true;
} }
/// <summary>
/// Sets the custom data.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The value.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetCustomData(string key, bool value)
{
SetCustomData(key, value.ToString());
}
/// <summary>
/// Sets the custom data.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The value.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetCustomData(string key, float value)
{
SetCustomData(key, value.ToString(CultureInfo.InvariantCulture));
}
/// <summary> /// <summary>
/// Removes the custom data. /// Removes the custom data.
/// </summary> /// </summary>

View File

@@ -182,6 +182,9 @@ namespace FlaxEditor.Modules
var cam = scene.AddChild<Camera>(); var cam = scene.AddChild<Camera>();
cam.Name = "Camera"; cam.Name = "Camera";
cam.Position = new Vector3(0, 150, -300); cam.Position = new Vector3(0, 150, -300);
//
var audioListener = cam.AddChild<AudioListener>();
audioListener.Name = "Audio Listener";
// Serialize // Serialize
var bytes = Level.SaveSceneToBytes(scene); var bytes = Level.SaveSceneToBytes(scene);

View File

@@ -127,13 +127,12 @@ namespace FlaxEditor.Modules
public void RequestStartPlayGame() public void RequestStartPlayGame()
{ {
if (!Editor.StateMachine.IsEditMode) if (!Editor.StateMachine.IsEditMode)
{
return; return;
}
var firstScene = Content.Settings.GameSettings.Load().FirstScene; var firstScene = Content.Settings.GameSettings.Load().FirstScene;
if (firstScene == Guid.Empty) if (firstScene == Guid.Empty)
{ {
Editor.LogWarning("No First Scene assigned in Game Settings.");
if (Level.IsAnySceneLoaded) if (Level.IsAnySceneLoaded)
Editor.Simulation.RequestStartPlayScenes(); Editor.Simulation.RequestStartPlayScenes();
return; return;
@@ -141,6 +140,9 @@ namespace FlaxEditor.Modules
if (!FlaxEngine.Content.GetAssetInfo(firstScene.ID, out var info)) if (!FlaxEngine.Content.GetAssetInfo(firstScene.ID, out var info))
{ {
Editor.LogWarning("Invalid First Scene in Game Settings."); Editor.LogWarning("Invalid First Scene in Game Settings.");
if (Level.IsAnySceneLoaded)
Editor.Simulation.RequestStartPlayScenes();
return;
} }
// Load scenes after entering the play mode // Load scenes after entering the play mode

View File

@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Xml; using System.Xml;
using FlaxEditor.Scripting; using FlaxEditor.Scripting;
@@ -65,7 +66,7 @@ namespace FlaxEditor.Modules.SourceCodeEditing
{ {
var key = "T:" + GetXmlKey(type.Type.FullName); var key = "T:" + GetXmlKey(type.Type.FullName);
if (xml.TryGetValue(key, out var xmlDoc)) if (xml.TryGetValue(key, out var xmlDoc))
text += '\n' + xmlDoc; text += '\n' + FilterWhitespaces(xmlDoc);
} }
} }
@@ -262,6 +263,27 @@ namespace FlaxEditor.Modules.SourceCodeEditing
return Regex.Replace(typeFullNameString, @"\[.*\]", string.Empty).Replace('+', '.'); return Regex.Replace(typeFullNameString, @"\[.*\]", string.Empty).Replace('+', '.');
} }
private static string FilterWhitespaces(string str)
{
if (str.Contains(" ", StringComparison.Ordinal))
{
var sb = new StringBuilder();
var prev = str[0];
sb.Append(prev);
for (int i = 1; i < str.Length; i++)
{
var c = str[i];
if (prev != ' ' || c != ' ')
{
sb.Append(c);
}
prev = c;
}
str = sb.ToString();
}
return str;
}
private Dictionary<string, string> GetXmlDocs(Assembly assembly) private Dictionary<string, string> GetXmlDocs(Assembly assembly)
{ {
if (!_xmlCache.TryGetValue(assembly, out var result)) if (!_xmlCache.TryGetValue(assembly, out var result))

View File

@@ -381,7 +381,7 @@ namespace FlaxEditor.Modules
Editor.Options.OptionsChanged += OnOptionsChanged; Editor.Options.OptionsChanged += OnOptionsChanged;
// Add dummy control for drawing the main window borders if using a custom style // Add dummy control for drawing the main window borders if using a custom style
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS || PLATFORM_SDL
if (!Editor.Options.Options.Interface.UseNativeWindowSystem) if (!Editor.Options.Options.Interface.UseNativeWindowSystem)
#endif #endif
{ {
@@ -565,6 +565,7 @@ namespace FlaxEditor.Modules
if (item != null) if (item != null)
Editor.ContentEditing.Open(item); Editor.ContentEditing.Open(item);
}); });
cm.AddButton("Editor Options", () => Editor.Windows.EditorOptionsWin.Show());
// Scene // Scene
MenuScene = MainMenu.AddButton("Scene"); MenuScene = MainMenu.AddButton("Scene");
@@ -619,7 +620,6 @@ namespace FlaxEditor.Modules
_menuToolsTakeScreenshot = cm.AddButton("Take screenshot", inputOptions.TakeScreenshot, Editor.Windows.TakeScreenshot); _menuToolsTakeScreenshot = cm.AddButton("Take screenshot", inputOptions.TakeScreenshot, Editor.Windows.TakeScreenshot);
cm.AddSeparator(); cm.AddSeparator();
cm.AddButton("Plugins", () => Editor.Windows.PluginsWin.Show()); cm.AddButton("Plugins", () => Editor.Windows.PluginsWin.Show());
cm.AddButton("Options", () => Editor.Windows.EditorOptionsWin.Show());
// Window // Window
MenuWindow = MainMenu.AddButton("Window"); MenuWindow = MainMenu.AddButton("Window");

View File

@@ -511,11 +511,11 @@ namespace FlaxEditor.Modules
{ {
var bounds = node["Bounds"]; var bounds = node["Bounds"];
var isMaximizedText = bounds.GetAttribute("IsMaximized"); var isMaximizedText = bounds.GetAttribute("IsMaximized");
if (!string.IsNullOrEmpty(isMaximizedText)) if (!string.IsNullOrEmpty(isMaximizedText) && bool.TryParse(isMaximizedText, out var tmpBool))
isMaximized = bool.Parse(isMaximizedText); isMaximized = tmpBool;
var isMinimizedText = bounds.GetAttribute("IsMinimized"); var isMinimizedText = bounds.GetAttribute("IsMinimized");
if (!string.IsNullOrEmpty(isMinimizedText)) if (!string.IsNullOrEmpty(isMinimizedText) && bool.TryParse(isMinimizedText, out tmpBool))
isMinimized = bool.Parse(isMinimizedText); isMinimized = tmpBool;
float x = float.Parse(bounds.GetAttribute("X"), CultureInfo.InvariantCulture); float x = float.Parse(bounds.GetAttribute("X"), CultureInfo.InvariantCulture);
float y = float.Parse(bounds.GetAttribute("Y"), CultureInfo.InvariantCulture); float y = float.Parse(bounds.GetAttribute("Y"), CultureInfo.InvariantCulture);
float width = float.Parse(bounds.GetAttribute("Width"), CultureInfo.InvariantCulture); float width = float.Parse(bounds.GetAttribute("Width"), CultureInfo.InvariantCulture);
@@ -760,8 +760,10 @@ namespace FlaxEditor.Modules
{ {
settings.HasBorder = false; settings.HasBorder = false;
#if !PLATFORM_SDL
// Skip OS sizing frame and implement it using LeftButtonHit // Skip OS sizing frame and implement it using LeftButtonHit
settings.HasSizingFrame = false; settings.HasSizingFrame = false;
#endif
} }
#elif PLATFORM_LINUX #elif PLATFORM_LINUX
settings.HasBorder = false; settings.HasBorder = false;

View File

@@ -145,7 +145,7 @@ namespace FlaxEditor.Options
[EditorDisplay("Interface"), EditorOrder(10), Tooltip("Editor User Interface scale. Applied to all UI elements, windows and text. Can be used to scale the interface up on a bigger display. Editor restart required.")] [EditorDisplay("Interface"), EditorOrder(10), Tooltip("Editor User Interface scale. Applied to all UI elements, windows and text. Can be used to scale the interface up on a bigger display. Editor restart required.")]
public float InterfaceScale { get; set; } = 1.0f; public float InterfaceScale { get; set; } = 1.0f;
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS || PLATFORM_SDL
/// <summary> /// <summary>
/// Gets or sets a value indicating whether use native window title bar. Editor restart required. /// Gets or sets a value indicating whether use native window title bar. Editor restart required.
/// </summary> /// </summary>
@@ -175,13 +175,6 @@ namespace FlaxEditor.Options
[EditorDisplay("Interface", "New Window Location"), EditorOrder(150), Tooltip("Define the opening method for new windows, open in a new tab by default.")] [EditorDisplay("Interface", "New Window Location"), EditorOrder(150), Tooltip("Define the opening method for new windows, open in a new tab by default.")]
public DockStateProxy NewWindowLocation { get; set; } = DockStateProxy.Float; public DockStateProxy NewWindowLocation { get; set; } = DockStateProxy.Float;
/// <summary>
/// Gets or sets the timestamps prefix mode for debug log messages.
/// </summary>
[DefaultValue(TimestampsFormats.None)]
[EditorDisplay("Interface"), EditorOrder(210), Tooltip("The timestamps prefix mode for debug log messages.")]
public TimestampsFormats DebugLogTimestampsFormat { get; set; } = TimestampsFormats.None;
/// <summary> /// <summary>
/// Gets or sets the editor icons scale. Editor restart required. /// Gets or sets the editor icons scale. Editor restart required.
/// </summary> /// </summary>
@@ -196,6 +189,13 @@ namespace FlaxEditor.Options
[EditorDisplay("Interface"), EditorOrder(280), Tooltip("Editor content window orientation.")] [EditorDisplay("Interface"), EditorOrder(280), Tooltip("Editor content window orientation.")]
public FlaxEngine.GUI.Orientation ContentWindowOrientation { get; set; } = FlaxEngine.GUI.Orientation.Horizontal; public FlaxEngine.GUI.Orientation ContentWindowOrientation { get; set; } = FlaxEngine.GUI.Orientation.Horizontal;
/// <summary>
/// If checked, color pickers will always modify the color unless 'Cancel' if pressed, otherwise color won't change unless 'Ok' is pressed.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Interface"), EditorOrder(290)]
public bool AutoAcceptColorPickerChange { get; set; } = true;
/// <summary> /// <summary>
/// Gets or sets the formatting option for numeric values in the editor. /// Gets or sets the formatting option for numeric values in the editor.
/// </summary> /// </summary>
@@ -211,23 +211,79 @@ namespace FlaxEditor.Options
public bool SeparateValueAndUnit { get; set; } public bool SeparateValueAndUnit { get; set; }
/// <summary> /// <summary>
/// Gets or sets the timestamps prefix mode for output log messages. /// Gets or sets the option to put a space between numbers and units for unit formatting.
/// </summary> /// </summary>
[DefaultValue(TimestampsFormats.TimeSinceStartup)] [DefaultValue(true)]
[EditorDisplay("Output Log", "Timestamps Format"), EditorOrder(300), Tooltip("The timestamps prefix mode for output log messages.")] [EditorDisplay("Interface"), EditorOrder(320)]
public TimestampsFormats OutputLogTimestampsFormat { get; set; } = TimestampsFormats.TimeSinceStartup; public bool ShowTreeLines { get; set; } = true;
/// <summary> /// <summary>
/// Gets or sets the timestamps prefix mode for output log messages. /// Gets or sets the timestamps prefix mode for output log messages.
/// </summary> /// </summary>
[DefaultValue(TimestampsFormats.None)]
[EditorDisplay("Debug Log"), EditorOrder(350), Tooltip("The timestamps prefix mode for debug log messages.")]
public TimestampsFormats DebugLogTimestampsFormat { get; set; } = TimestampsFormats.None;
/// <summary>
/// Gets or sets the clear on play for debug log messages.
/// </summary>
[DefaultValue(true)] [DefaultValue(true)]
[EditorDisplay("Output Log", "Show Log Type"), EditorOrder(310), Tooltip("Determines whether show log type prefix in output log messages.")] [EditorDisplay("Debug Log", "Clear on Play"), EditorOrder(360), Tooltip("Clears all log entries on enter playmode.")]
public bool DebugLogClearOnPlay { get; set; } = true;
/// <summary>
/// Gets or sets the collapse mode for debug log messages.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Debug Log"), EditorOrder(361), Tooltip("Collapses similar or repeating log entries.")]
public bool DebugLogCollapse { get; set; } = true;
/// <summary>
/// Gets or sets the automatic pause on error for debug log messages.
/// </summary>
[DefaultValue(false)]
[EditorDisplay("Debug Log", "Pause on Error"), EditorOrder(362), Tooltip("Performs auto pause on error.")]
public bool DebugLogPauseOnError { get; set; } = false;
/// <summary>
/// Gets or sets the automatic pause on error for debug log messages.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Debug Log", "Show error messages"), EditorOrder(370), Tooltip("Shows/hides error messages.")]
public bool DebugLogShowErrorMessages { get; set; } = true;
/// <summary>
/// Gets or sets the automatic pause on error for debug log messages.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Debug Log", "Show warning messages"), EditorOrder(371), Tooltip("Shows/hides warning messages.")]
public bool DebugLogShowWarningMessages { get; set; } = true;
/// <summary>
/// Gets or sets the automatic pause on error for debug log messages.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Debug Log", "Show info messages"), EditorOrder(372), Tooltip("Shows/hides info messages.")]
public bool DebugLogShowInfoMessages { get; set; } = true;
/// <summary>
/// Gets or sets the timestamps prefix mode for output log messages.
/// </summary>
[DefaultValue(TimestampsFormats.TimeSinceStartup)]
[EditorDisplay("Output Log", "Timestamps Format"), EditorOrder(400), Tooltip("The timestamps prefix mode for output log messages.")]
public TimestampsFormats OutputLogTimestampsFormat { get; set; } = TimestampsFormats.TimeSinceStartup;
/// <summary>
/// Gets or sets the log type prefix mode for output log messages.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Output Log", "Show Log Type"), EditorOrder(410), Tooltip("Determines whether show log type prefix in output log messages.")]
public bool OutputLogShowLogType { get; set; } = true; public bool OutputLogShowLogType { get; set; } = true;
/// <summary> /// <summary>
/// Gets or sets the output log text font. /// Gets or sets the output log text font.
/// </summary> /// </summary>
[EditorDisplay("Output Log", "Text Font"), EditorOrder(320), Tooltip("The output log text font.")] [EditorDisplay("Output Log", "Text Font"), EditorOrder(420), Tooltip("The output log text font.")]
public FontReference OutputLogTextFont public FontReference OutputLogTextFont
{ {
get => _outputLogFont; get => _outputLogFont;
@@ -246,65 +302,79 @@ namespace FlaxEditor.Options
/// Gets or sets the output log text color. /// Gets or sets the output log text color.
/// </summary> /// </summary>
[DefaultValue(typeof(Color), "1,1,1,1")] [DefaultValue(typeof(Color), "1,1,1,1")]
[EditorDisplay("Output Log", "Text Color"), EditorOrder(330), Tooltip("The output log text color.")] [EditorDisplay("Output Log", "Text Color"), EditorOrder(430), Tooltip("The output log text color.")]
public Color OutputLogTextColor { get; set; } = Color.White; public Color OutputLogTextColor { get; set; } = Color.White;
/// <summary> /// <summary>
/// Gets or sets the output log text shadow color. /// Gets or sets the output log text shadow color.
/// </summary> /// </summary>
[DefaultValue(typeof(Color), "0,0,0,0.5")] [DefaultValue(typeof(Color), "0,0,0,0.5")]
[EditorDisplay("Output Log", "Text Shadow Color"), EditorOrder(340), Tooltip("The output log text shadow color.")] [EditorDisplay("Output Log", "Text Shadow Color"), EditorOrder(440), Tooltip("The output log text shadow color.")]
public Color OutputLogTextShadowColor { get; set; } = new Color(0, 0, 0, 0.5f); public Color OutputLogTextShadowColor { get; set; } = new Color(0, 0, 0, 0.5f);
/// <summary> /// <summary>
/// Gets or sets the output log text shadow offset. Set to 0 to disable this feature. /// Gets or sets the output log text shadow offset. Set to 0 to disable this feature.
/// </summary> /// </summary>
[DefaultValue(typeof(Float2), "1,1")] [DefaultValue(typeof(Float2), "1,1")]
[EditorDisplay("Output Log", "Text Shadow Offset"), EditorOrder(340), Tooltip("The output log text shadow offset. Set to 0 to disable this feature.")] [EditorDisplay("Output Log", "Text Shadow Offset"), EditorOrder(445), Tooltip("The output log text shadow offset. Set to 0 to disable this feature.")]
public Float2 OutputLogTextShadowOffset { get; set; } = new Float2(1); public Float2 OutputLogTextShadowOffset { get; set; } = new Float2(1);
/// <summary> /// <summary>
/// Gets or sets a value indicating whether auto-focus output log window on code compilation error. /// Gets or sets a value indicating whether auto-focus output log window on code compilation error.
/// </summary> /// </summary>
[DefaultValue(true)] [DefaultValue(true)]
[EditorDisplay("Output Log", "Focus Output Log On Compilation Error"), EditorOrder(350), Tooltip("Determines whether auto-focus output log window on code compilation error.")] [EditorDisplay("Output Log", "Focus Output Log On Compilation Error"), EditorOrder(450), Tooltip("Determines whether auto-focus output log window on code compilation error.")]
public bool FocusOutputLogOnCompilationError { get; set; } = true; public bool FocusOutputLogOnCompilationError { get; set; } = true;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether auto-focus output log window on game build error. /// Gets or sets a value indicating whether auto-focus output log window on game build error.
/// </summary> /// </summary>
[DefaultValue(true)] [DefaultValue(true)]
[EditorDisplay("Output Log", "Focus Output Log On Game Build Error"), EditorOrder(360), Tooltip("Determines whether auto-focus output log window on game build error.")] [EditorDisplay("Output Log", "Focus Output Log On Game Build Error"), EditorOrder(460), Tooltip("Determines whether auto-focus output log window on game build error.")]
public bool FocusOutputLogOnGameBuildError { get; set; } = true; public bool FocusOutputLogOnGameBuildError { get; set; } = true;
/// <summary>
/// Gets or sets the value for automatic scroll to bottom in output log.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Output Log", "Scroll to bottom"), EditorOrder(470), Tooltip("Scroll the output log view to bottom automatically after new lines are added.")]
public bool OutputLogScrollToBottom { get; set; } = true;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether auto-focus game window on play mode start. /// Gets or sets a value indicating whether auto-focus game window on play mode start.
/// </summary> /// </summary>
[DefaultValue(true)] [DefaultValue(true)]
[EditorDisplay("Play In-Editor", "Focus Game Window On Play"), EditorOrder(400), Tooltip("Determines whether auto-focus game window on play mode start.")] [EditorDisplay("Play In-Editor", "Focus Game Window On Play"), EditorOrder(500), Tooltip("Determines whether auto-focus game window on play mode start.")]
public bool FocusGameWinOnPlay { get; set; } = true; public bool FocusGameWinOnPlay { get; set; } = true;
/// <summary> /// <summary>
/// Gets or sets a value indicating what action should be taken upon pressing the play button. /// Gets or sets a value indicating what action should be taken upon pressing the play button.
/// </summary> /// </summary>
[DefaultValue(PlayAction.PlayScenes)] [DefaultValue(PlayAction.PlayScenes)]
[EditorDisplay("Play In-Editor", "Play Button Action"), EditorOrder(410)] [EditorDisplay("Play In-Editor", "Play Button Action"), EditorOrder(510)]
public PlayAction PlayButtonAction { get; set; } = PlayAction.PlayScenes; public PlayAction PlayButtonAction { get; set; } = PlayAction.PlayScenes;
/// <summary> /// <summary>
/// Gets or sets a value indicating how the game window should be displayed when the game is launched. /// Gets or sets a value indicating how the game window should be displayed when the game is launched.
/// </summary> /// </summary>
[DefaultValue(GameWindowMode.Docked)] [DefaultValue(GameWindowMode.Docked)]
[EditorDisplay("Play In-Editor", "Game Window Mode"), EditorOrder(420), Tooltip("Determines how the game window is displayed when the game is launched.")] [EditorDisplay("Play In-Editor", "Game Window Mode"), EditorOrder(520), Tooltip("Determines how the game window is displayed when the game is launched.")]
public GameWindowMode DefaultGameWindowMode { get; set; } = GameWindowMode.Docked; public GameWindowMode DefaultGameWindowMode { get; set; } = GameWindowMode.Docked;
/// <summary> /// <summary>
/// Gets or sets a value indicating the number of game clients to launch when building and/or running cooked game. /// Gets or sets a value indicating the number of game clients to launch when building and/or running cooked game.
/// </summary> /// </summary>
[DefaultValue(1), Range(1, 4)] [DefaultValue(1), Range(1, 4)]
[EditorDisplay("Cook & Run"), EditorOrder(500)] [EditorDisplay("Cook & Run"), EditorOrder(600)]
public int NumberOfGameClientsToLaunch = 1; public int NumberOfGameClientsToLaunch = 1;
/// <summary>
/// Gets or sets the visject connection curvature.
/// </summary>
[DefaultValue(1.0f), Range(0.0f, 2.0f)]
[EditorDisplay("Visject"), EditorOrder(550)]
public float ConnectionCurvature { get; set; } = 1.0f;
private static FontAsset DefaultFont => FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.PrimaryFont); private static FontAsset DefaultFont => FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.PrimaryFont);
private static FontAsset ConsoleFont => FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.InconsolataRegularFont); private static FontAsset ConsoleFont => FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.InconsolataRegularFont);
@@ -317,13 +387,13 @@ namespace FlaxEditor.Options
/// <summary> /// <summary>
/// The list of fallback fonts to use when main text font is missing certain characters. Empty to use fonts from GraphicsSettings. /// The list of fallback fonts to use when main text font is missing certain characters. Empty to use fonts from GraphicsSettings.
/// </summary> /// </summary>
[EditorDisplay("Fonts"), EditorOrder(650)] [EditorDisplay("Fonts"), EditorOrder(750)]
public FontAsset[] FallbackFonts = new FontAsset[1] { FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.FallbackFont) }; public FontAsset[] FallbackFonts = new FontAsset[1] { FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.FallbackFont) };
/// <summary> /// <summary>
/// Gets or sets the title font for editor UI. /// Gets or sets the title font for editor UI.
/// </summary> /// </summary>
[EditorDisplay("Fonts"), EditorOrder(600), Tooltip("The title font for editor UI.")] [EditorDisplay("Fonts"), EditorOrder(700), Tooltip("The title font for editor UI.")]
public FontReference TitleFont public FontReference TitleFont
{ {
get => _titleFont; get => _titleFont;
@@ -341,7 +411,7 @@ namespace FlaxEditor.Options
/// <summary> /// <summary>
/// Gets or sets the large font for editor UI. /// Gets or sets the large font for editor UI.
/// </summary> /// </summary>
[EditorDisplay("Fonts"), EditorOrder(610), Tooltip("The large font for editor UI.")] [EditorDisplay("Fonts"), EditorOrder(710), Tooltip("The large font for editor UI.")]
public FontReference LargeFont public FontReference LargeFont
{ {
get => _largeFont; get => _largeFont;
@@ -359,7 +429,7 @@ namespace FlaxEditor.Options
/// <summary> /// <summary>
/// Gets or sets the medium font for editor UI. /// Gets or sets the medium font for editor UI.
/// </summary> /// </summary>
[EditorDisplay("Fonts"), EditorOrder(620), Tooltip("The medium font for editor UI.")] [EditorDisplay("Fonts"), EditorOrder(720), Tooltip("The medium font for editor UI.")]
public FontReference MediumFont public FontReference MediumFont
{ {
get => _mediumFont; get => _mediumFont;
@@ -377,7 +447,7 @@ namespace FlaxEditor.Options
/// <summary> /// <summary>
/// Gets or sets the small font for editor UI. /// Gets or sets the small font for editor UI.
/// </summary> /// </summary>
[EditorDisplay("Fonts"), EditorOrder(630), Tooltip("The small font for editor UI.")] [EditorDisplay("Fonts"), EditorOrder(730), Tooltip("The small font for editor UI.")]
public FontReference SmallFont public FontReference SmallFont
{ {
get => _smallFont; get => _smallFont;

View File

@@ -192,6 +192,7 @@ namespace FlaxEditor.Options
internalOptions.AutoReloadScriptsOnMainWindowFocus = (byte)(Options.General.AutoReloadScriptsOnMainWindowFocus ? 1 : 0); internalOptions.AutoReloadScriptsOnMainWindowFocus = (byte)(Options.General.AutoReloadScriptsOnMainWindowFocus ? 1 : 0);
internalOptions.ForceScriptCompilationOnStartup = (byte)(Options.General.ForceScriptCompilationOnStartup ? 1 : 0); internalOptions.ForceScriptCompilationOnStartup = (byte)(Options.General.ForceScriptCompilationOnStartup ? 1 : 0);
internalOptions.UseAssetImportPathRelative = (byte)(Options.General.UseAssetImportPathRelative ? 1 : 0); internalOptions.UseAssetImportPathRelative = (byte)(Options.General.UseAssetImportPathRelative ? 1 : 0);
internalOptions.EnableParticlesPreview = (byte)(Options.Visual.EnableParticlesPreview ? 1 : 0);
internalOptions.AutoRebuildCSG = (byte)(Options.General.AutoRebuildCSG ? 1 : 0); internalOptions.AutoRebuildCSG = (byte)(Options.General.AutoRebuildCSG ? 1 : 0);
internalOptions.AutoRebuildCSGTimeoutMs = Options.General.AutoRebuildCSGTimeoutMs; internalOptions.AutoRebuildCSGTimeoutMs = Options.General.AutoRebuildCSGTimeoutMs;
internalOptions.AutoRebuildNavMesh = (byte)(Options.General.AutoRebuildNavMesh ? 1 : 0); internalOptions.AutoRebuildNavMesh = (byte)(Options.General.AutoRebuildNavMesh ? 1 : 0);
@@ -255,6 +256,17 @@ namespace FlaxEditor.Options
} }
} }
// Ensure custom fonts are valid, reset if not
var defaultInterfaceOptions = new InterfaceOptions();
if (Style.Current.FontTitle == null)
Style.Current.FontTitle = defaultInterfaceOptions.TitleFont.GetFont();
if (Style.Current.FontSmall == null)
Style.Current.FontSmall = defaultInterfaceOptions.SmallFont.GetFont();
if (Style.Current.FontMedium == null)
Style.Current.FontMedium = defaultInterfaceOptions.MediumFont.GetFont();
if (Style.Current.FontLarge == null)
Style.Current.FontLarge = defaultInterfaceOptions.LargeFont.GetFont();
// Set fallback fonts // Set fallback fonts
var fallbackFonts = Options.Interface.FallbackFonts; var fallbackFonts = Options.Interface.FallbackFonts;
if (fallbackFonts == null || fallbackFonts.Length == 0 || fallbackFonts.All(x => x == null)) if (fallbackFonts == null || fallbackFonts.Length == 0 || fallbackFonts.All(x => x == null))

View File

@@ -129,5 +129,19 @@ namespace FlaxEditor.Options
[DefaultValue(50.0f), Limit(25.0f, 500.0f, 5.0f)] [DefaultValue(50.0f), Limit(25.0f, 500.0f, 5.0f)]
[EditorDisplay("Defaults"), EditorOrder(220), Tooltip("The default editor viewport grid scale.")] [EditorDisplay("Defaults"), EditorOrder(220), Tooltip("The default editor viewport grid scale.")]
public float ViewportGridScale { get; set; } = 50.0f; public float ViewportGridScale { get; set; } = 50.0f;
/// <summary>
/// Gets or sets the view distance you can see the grid.
/// </summary>
[DefaultValue(2500.0f)]
[EditorDisplay("Grid"), EditorOrder(300), Tooltip("The maximum distance you will be able to see the grid.")]
public float ViewportGridViewDistance { get; set; } = 2500.0f;
/// <summary>
/// Gets or sets the grid color.
/// </summary>
[DefaultValue(typeof(Color), "0.5,0.5,0.5,1.0")]
[EditorDisplay("Grid"), EditorOrder(310), Tooltip("The color for the viewport grid.")]
public Color ViewportGridColor { get; set; } = new Color(0.5f, 0.5f, 0.5f, 1.0f);
} }
} }

View File

@@ -59,5 +59,12 @@ namespace FlaxEditor.Options
[DefaultValue(true)] [DefaultValue(true)]
[EditorDisplay("Quality", "Enable MSAA For Debug Draw"), EditorOrder(500), Tooltip("Determines whether enable MSAA for DebugDraw primitives rendering. Helps with pixel aliasing but reduces performance.")] [EditorDisplay("Quality", "Enable MSAA For Debug Draw"), EditorOrder(500), Tooltip("Determines whether enable MSAA for DebugDraw primitives rendering. Helps with pixel aliasing but reduces performance.")]
public bool EnableMSAAForDebugDraw { get; set; } = true; public bool EnableMSAAForDebugDraw { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating whether show looping particle effects in Editor viewport to simulate in-game look.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Preview"), EditorOrder(1000)]
public bool EnableParticlesPreview { get; set; } = true;
} }
} }

View File

@@ -15,6 +15,7 @@ using FlaxEditor.Windows.Assets;
using FlaxEngine; using FlaxEngine;
using FlaxEngine.GUI; using FlaxEngine.GUI;
using FlaxEngine.Utilities; using FlaxEngine.Utilities;
using Object = FlaxEngine.Object;
namespace FlaxEditor.SceneGraph.GUI namespace FlaxEditor.SceneGraph.GUI
{ {
@@ -355,7 +356,7 @@ namespace FlaxEditor.SceneGraph.GUI
private void OnRenamed(RenamePopup renamePopup) private void OnRenamed(RenamePopup renamePopup)
{ {
using (new UndoBlock(ActorNode.Root.Undo, Actor, "Rename")) using (new UndoBlock(ActorNode.Root.Undo, Actor, "Rename"))
Actor.Name = renamePopup.Text; Actor.Name = renamePopup.Text.Trim();
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -625,6 +626,7 @@ namespace FlaxEditor.SceneGraph.GUI
{ {
var item = _dragScriptItems.Objects[i]; var item = _dragScriptItems.Objects[i];
var actorType = Editor.Instance.CodeEditing.Actors.Get(item); var actorType = Editor.Instance.CodeEditing.Actors.Get(item);
var scriptType = Editor.Instance.CodeEditing.Scripts.Get(item);
if (actorType != ScriptType.Null) if (actorType != ScriptType.Null)
{ {
var actor = actorType.CreateInstance() as Actor; var actor = actorType.CreateInstance() as Actor;
@@ -639,6 +641,18 @@ namespace FlaxEditor.SceneGraph.GUI
ActorNode.Root.Spawn(actor, spawnParent); ActorNode.Root.Spawn(actor, spawnParent);
actor.OrderInParent = newOrder; actor.OrderInParent = newOrder;
} }
else if (scriptType != ScriptType.Null)
{
if (DragOverMode == DragItemPositioning.Above || DragOverMode == DragItemPositioning.Below)
{
Editor.LogWarning("Failed to spawn script of type " + actorType.TypeName);
continue;
}
IUndoAction action = new AddRemoveScript(true, newParent, scriptType);
Select();
ActorNode.Root.Undo?.AddAction(action);
action.Do();
}
} }
result = DragDropEffect.Move; result = DragDropEffect.Move;
} }
@@ -699,9 +713,9 @@ namespace FlaxEditor.SceneGraph.GUI
return Editor.Instance.CodeEditing.Controls.Get().Contains(controlType); return Editor.Instance.CodeEditing.Controls.Get().Contains(controlType);
} }
private static bool ValidateDragScriptItem(ScriptItem script) private bool ValidateDragScriptItem(ScriptItem script)
{ {
return Editor.Instance.CodeEditing.Actors.Get(script) != ScriptType.Null; return Editor.Instance.CodeEditing.Actors.Get(script) != ScriptType.Null || Editor.Instance.CodeEditing.Scripts.Get(script) != ScriptType.Null;
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -51,12 +51,12 @@ namespace FlaxEditor.Scripting
int standardToken = _managed?.MetadataToken ?? _custom?.MetadataToken ?? 0; int standardToken = _managed?.MetadataToken ?? _custom?.MetadataToken ?? 0;
if (_managed is PropertyInfo && _managed.DeclaringType != null) if (_managed is PropertyInfo && _managed.DeclaringType != null)
{ {
var field = _managed.DeclaringType.GetField(string.Format("<{0}>k__BackingField", Name), BindingFlags.Instance | BindingFlags.NonPublic); var backingField = _managed.DeclaringType.GetField(string.Format("<{0}>k__BackingField", Name), BindingFlags.Instance | BindingFlags.NonPublic);
if (field == null || field.MetadataToken == 0) if (backingField == null || backingField.MetadataToken == 0)
{ {
return standardToken; return standardToken;
} }
return field.MetadataToken; return backingField.MetadataToken;
} }
return standardToken; return standardToken;
} }

View File

@@ -71,7 +71,6 @@ namespace FlaxEditor.States
{ {
// Skip compilation on startup // Skip compilation on startup
OnCompilationEnd(true); OnCompilationEnd(true);
Editor.EndInit();
} }
} }

View File

@@ -77,7 +77,6 @@ namespace FlaxEditor.States
{ {
if (!IsActive) if (!IsActive)
throw new InvalidOperationException(); throw new InvalidOperationException();
Time.GamePaused = value; Time.GamePaused = value;
} }
} }

View File

@@ -60,7 +60,7 @@ namespace FlaxEditor.Surface.Archetypes
Op1(1, "Boolean NOT", "Negates the boolean value", new[] { "!", "~" }), Op1(1, "Boolean NOT", "Negates the boolean value", new[] { "!", "~" }),
Op2(2, "Boolean AND", "Performs a logical conjunction on two values", new[] { "&&" }), Op2(2, "Boolean AND", "Performs a logical conjunction on two values", new[] { "&&" }),
Op2(3, "Boolean OR", "Returns true if either (or both) of its operands is true", new[] { "||" }), Op2(3, "Boolean OR", "Returns true if either (or both) of its operands is true", new[] { "||" }),
Op2(4, "Boolean XOR", "", new [] { "^" } ), Op2(4, "Boolean XOR", "", new[] { "^" }),
Op2(5, "Boolean NOR", ""), Op2(5, "Boolean NOR", ""),
Op2(6, "Boolean NAND", ""), Op2(6, "Boolean NAND", ""),
}; };

View File

@@ -47,7 +47,8 @@ namespace FlaxEditor.Surface.Archetypes
base.OnShowSecondaryContextMenu(menu, location); base.OnShowSecondaryContextMenu(menu, location);
menu.AddSeparator(); menu.AddSeparator();
menu.AddButton("Convert to Parameter", OnConvertToParameter); var b = menu.AddButton("Convert to Parameter", OnConvertToParameter);
b.Enabled = Surface.Owner is IVisjectSurfaceWindow window && Surface.Owner.SurfaceAsset && window.NewParameterTypes.Contains(_type);
} }
private void OnConvertToParameter() private void OnConvertToParameter()
@@ -122,8 +123,7 @@ namespace FlaxEditor.Surface.Archetypes
private bool OnParameterRenameValidate(string value) private bool OnParameterRenameValidate(string value)
{ {
if (Surface.Owner is not IVisjectSurfaceWindow window) var window = (IVisjectSurfaceWindow)Surface.Owner;
throw new Exception("Surface owner is not a Visject Surface Window");
return !string.IsNullOrWhiteSpace(value) && window.VisjectSurface.Parameters.All(x => x.Name != value); return !string.IsNullOrWhiteSpace(value) && window.VisjectSurface.Parameters.All(x => x.Name != value);
} }
} }

View File

@@ -2198,21 +2198,23 @@ namespace FlaxEditor.Surface.Archetypes
_combobox.ClearItems(); _combobox.ClearItems();
_tooltips.Clear(); _tooltips.Clear();
_functionNodesIds.Clear(); _functionNodesIds.Clear();
var nodes = Surface.Nodes; if (Surface != null && _signature != null)
var count = _signature != null ? nodes.Count : 0;
for (int i = 0; i < count; i++)
{ {
if (nodes[i] is VisualScriptFunctionNode functionNode) var nodes = Surface.Nodes;
for (int i = 0; i < nodes.Count; i++)
{ {
// Get if function signature matches the event signature if (nodes[i] is VisualScriptFunctionNode functionNode)
functionNode.GetSignature(out var functionSig);
if (IsValidFunctionSignature(ref functionSig))
{ {
if (functionNode.ID == handlerFunctionNodeId) // Get if function signature matches the event signature
toSelect = _functionNodesIds.Count; functionNode.GetSignature(out var functionSig);
_functionNodesIds.Add(functionNode.ID); if (IsValidFunctionSignature(ref functionSig))
_tooltips.Add(functionNode.TooltipText); {
_combobox.AddItem(functionSig.ToString()); if (functionNode.ID == handlerFunctionNodeId)
toSelect = _functionNodesIds.Count;
_functionNodesIds.Add(functionNode.ID);
_tooltips.Add(functionNode.TooltipText);
_combobox.AddItem(functionSig.ToString());
}
} }
} }
} }

View File

@@ -71,20 +71,20 @@ namespace FlaxEditor.Surface.Archetypes
// Layered material // Layered material
if (GetBox(MaterialNodeBoxes.Layer).HasAnyConnection) if (GetBox(MaterialNodeBoxes.Layer).HasAnyConnection)
{ {
GetBox(MaterialNodeBoxes.Color).Enabled = false; GetBox(MaterialNodeBoxes.Color).IsActive = false;
GetBox(MaterialNodeBoxes.Mask).Enabled = false; GetBox(MaterialNodeBoxes.Mask).IsActive = false;
GetBox(MaterialNodeBoxes.Emissive).Enabled = false; GetBox(MaterialNodeBoxes.Emissive).IsActive = false;
GetBox(MaterialNodeBoxes.Metalness).Enabled = false; GetBox(MaterialNodeBoxes.Metalness).IsActive = false;
GetBox(MaterialNodeBoxes.Specular).Enabled = false; GetBox(MaterialNodeBoxes.Specular).IsActive = false;
GetBox(MaterialNodeBoxes.Roughness).Enabled = false; GetBox(MaterialNodeBoxes.Roughness).IsActive = false;
GetBox(MaterialNodeBoxes.AmbientOcclusion).Enabled = false; GetBox(MaterialNodeBoxes.AmbientOcclusion).IsActive = false;
GetBox(MaterialNodeBoxes.Normal).Enabled = false; GetBox(MaterialNodeBoxes.Normal).IsActive = false;
GetBox(MaterialNodeBoxes.Opacity).Enabled = false; GetBox(MaterialNodeBoxes.Opacity).IsActive = false;
GetBox(MaterialNodeBoxes.Refraction).Enabled = false; GetBox(MaterialNodeBoxes.Refraction).IsActive = false;
GetBox(MaterialNodeBoxes.PositionOffset).Enabled = false; GetBox(MaterialNodeBoxes.PositionOffset).IsActive = false;
GetBox(MaterialNodeBoxes.TessellationMultiplier).Enabled = false; GetBox(MaterialNodeBoxes.TessellationMultiplier).IsActive = false;
GetBox(MaterialNodeBoxes.WorldDisplacement).Enabled = false; GetBox(MaterialNodeBoxes.WorldDisplacement).IsActive = false;
GetBox(MaterialNodeBoxes.SubsurfaceColor).Enabled = false; GetBox(MaterialNodeBoxes.SubsurfaceColor).IsActive = false;
return; return;
} }
@@ -102,94 +102,94 @@ namespace FlaxEditor.Surface.Archetypes
bool isNotUnlit = info.ShadingModel != MaterialShadingModel.Unlit; bool isNotUnlit = info.ShadingModel != MaterialShadingModel.Unlit;
bool withTess = info.TessellationMode != TessellationMethod.None; bool withTess = info.TessellationMode != TessellationMethod.None;
GetBox(MaterialNodeBoxes.Color).Enabled = isNotUnlit; GetBox(MaterialNodeBoxes.Color).IsActive = isNotUnlit;
GetBox(MaterialNodeBoxes.Mask).Enabled = true; GetBox(MaterialNodeBoxes.Mask).IsActive = true;
GetBox(MaterialNodeBoxes.Emissive).Enabled = true; GetBox(MaterialNodeBoxes.Emissive).IsActive = true;
GetBox(MaterialNodeBoxes.Metalness).Enabled = isNotUnlit; GetBox(MaterialNodeBoxes.Metalness).IsActive = isNotUnlit;
GetBox(MaterialNodeBoxes.Specular).Enabled = isNotUnlit; GetBox(MaterialNodeBoxes.Specular).IsActive = isNotUnlit;
GetBox(MaterialNodeBoxes.Roughness).Enabled = isNotUnlit; GetBox(MaterialNodeBoxes.Roughness).IsActive = isNotUnlit;
GetBox(MaterialNodeBoxes.AmbientOcclusion).Enabled = isNotUnlit; GetBox(MaterialNodeBoxes.AmbientOcclusion).IsActive = isNotUnlit;
GetBox(MaterialNodeBoxes.Normal).Enabled = isNotUnlit; GetBox(MaterialNodeBoxes.Normal).IsActive = isNotUnlit;
GetBox(MaterialNodeBoxes.Opacity).Enabled = info.ShadingModel == MaterialShadingModel.Subsurface || info.ShadingModel == MaterialShadingModel.Foliage || info.BlendMode != MaterialBlendMode.Opaque; GetBox(MaterialNodeBoxes.Opacity).IsActive = info.ShadingModel == MaterialShadingModel.Subsurface || info.ShadingModel == MaterialShadingModel.Foliage || info.BlendMode != MaterialBlendMode.Opaque;
GetBox(MaterialNodeBoxes.Refraction).Enabled = info.BlendMode != MaterialBlendMode.Opaque; GetBox(MaterialNodeBoxes.Refraction).IsActive = info.BlendMode != MaterialBlendMode.Opaque;
GetBox(MaterialNodeBoxes.PositionOffset).Enabled = true; GetBox(MaterialNodeBoxes.PositionOffset).IsActive = true;
GetBox(MaterialNodeBoxes.TessellationMultiplier).Enabled = withTess; GetBox(MaterialNodeBoxes.TessellationMultiplier).IsActive = withTess;
GetBox(MaterialNodeBoxes.WorldDisplacement).Enabled = withTess; GetBox(MaterialNodeBoxes.WorldDisplacement).IsActive = withTess;
GetBox(MaterialNodeBoxes.SubsurfaceColor).Enabled = info.ShadingModel == MaterialShadingModel.Subsurface || info.ShadingModel == MaterialShadingModel.Foliage; GetBox(MaterialNodeBoxes.SubsurfaceColor).IsActive = info.ShadingModel == MaterialShadingModel.Subsurface || info.ShadingModel == MaterialShadingModel.Foliage;
break; break;
} }
case MaterialDomain.PostProcess: case MaterialDomain.PostProcess:
{ {
GetBox(MaterialNodeBoxes.Color).Enabled = false; GetBox(MaterialNodeBoxes.Color).IsActive = false;
GetBox(MaterialNodeBoxes.Mask).Enabled = false; GetBox(MaterialNodeBoxes.Mask).IsActive = false;
GetBox(MaterialNodeBoxes.Emissive).Enabled = true; GetBox(MaterialNodeBoxes.Emissive).IsActive = true;
GetBox(MaterialNodeBoxes.Metalness).Enabled = false; GetBox(MaterialNodeBoxes.Metalness).IsActive = false;
GetBox(MaterialNodeBoxes.Specular).Enabled = false; GetBox(MaterialNodeBoxes.Specular).IsActive = false;
GetBox(MaterialNodeBoxes.Roughness).Enabled = false; GetBox(MaterialNodeBoxes.Roughness).IsActive = false;
GetBox(MaterialNodeBoxes.AmbientOcclusion).Enabled = false; GetBox(MaterialNodeBoxes.AmbientOcclusion).IsActive = false;
GetBox(MaterialNodeBoxes.Normal).Enabled = false; GetBox(MaterialNodeBoxes.Normal).IsActive = false;
GetBox(MaterialNodeBoxes.Opacity).Enabled = true; GetBox(MaterialNodeBoxes.Opacity).IsActive = true;
GetBox(MaterialNodeBoxes.Refraction).Enabled = false; GetBox(MaterialNodeBoxes.Refraction).IsActive = false;
GetBox(MaterialNodeBoxes.PositionOffset).Enabled = false; GetBox(MaterialNodeBoxes.PositionOffset).IsActive = false;
GetBox(MaterialNodeBoxes.TessellationMultiplier).Enabled = false; GetBox(MaterialNodeBoxes.TessellationMultiplier).IsActive = false;
GetBox(MaterialNodeBoxes.WorldDisplacement).Enabled = false; GetBox(MaterialNodeBoxes.WorldDisplacement).IsActive = false;
GetBox(MaterialNodeBoxes.SubsurfaceColor).Enabled = false; GetBox(MaterialNodeBoxes.SubsurfaceColor).IsActive = false;
break; break;
} }
case MaterialDomain.Decal: case MaterialDomain.Decal:
{ {
var mode = info.DecalBlendingMode; var mode = info.DecalBlendingMode;
GetBox(MaterialNodeBoxes.Color).Enabled = mode == MaterialDecalBlendingMode.Translucent || mode == MaterialDecalBlendingMode.Stain; GetBox(MaterialNodeBoxes.Color).IsActive = mode == MaterialDecalBlendingMode.Translucent || mode == MaterialDecalBlendingMode.Stain;
GetBox(MaterialNodeBoxes.Mask).Enabled = true; GetBox(MaterialNodeBoxes.Mask).IsActive = true;
GetBox(MaterialNodeBoxes.Emissive).Enabled = mode == MaterialDecalBlendingMode.Translucent || mode == MaterialDecalBlendingMode.Emissive; GetBox(MaterialNodeBoxes.Emissive).IsActive = mode == MaterialDecalBlendingMode.Translucent || mode == MaterialDecalBlendingMode.Emissive;
GetBox(MaterialNodeBoxes.Metalness).Enabled = mode == MaterialDecalBlendingMode.Translucent; GetBox(MaterialNodeBoxes.Metalness).IsActive = mode == MaterialDecalBlendingMode.Translucent;
GetBox(MaterialNodeBoxes.Specular).Enabled = mode == MaterialDecalBlendingMode.Translucent; GetBox(MaterialNodeBoxes.Specular).IsActive = mode == MaterialDecalBlendingMode.Translucent;
GetBox(MaterialNodeBoxes.Roughness).Enabled = mode == MaterialDecalBlendingMode.Translucent; GetBox(MaterialNodeBoxes.Roughness).IsActive = mode == MaterialDecalBlendingMode.Translucent;
GetBox(MaterialNodeBoxes.AmbientOcclusion).Enabled = false; GetBox(MaterialNodeBoxes.AmbientOcclusion).IsActive = false;
GetBox(MaterialNodeBoxes.Normal).Enabled = mode == MaterialDecalBlendingMode.Translucent || mode == MaterialDecalBlendingMode.Normal; GetBox(MaterialNodeBoxes.Normal).IsActive = mode == MaterialDecalBlendingMode.Translucent || mode == MaterialDecalBlendingMode.Normal;
GetBox(MaterialNodeBoxes.Opacity).Enabled = true; GetBox(MaterialNodeBoxes.Opacity).IsActive = true;
GetBox(MaterialNodeBoxes.Refraction).Enabled = false; GetBox(MaterialNodeBoxes.Refraction).IsActive = false;
GetBox(MaterialNodeBoxes.PositionOffset).Enabled = false; GetBox(MaterialNodeBoxes.PositionOffset).IsActive = false;
GetBox(MaterialNodeBoxes.TessellationMultiplier).Enabled = false; GetBox(MaterialNodeBoxes.TessellationMultiplier).IsActive = false;
GetBox(MaterialNodeBoxes.WorldDisplacement).Enabled = false; GetBox(MaterialNodeBoxes.WorldDisplacement).IsActive = false;
GetBox(MaterialNodeBoxes.SubsurfaceColor).Enabled = false; GetBox(MaterialNodeBoxes.SubsurfaceColor).IsActive = false;
break; break;
} }
case MaterialDomain.GUI: case MaterialDomain.GUI:
{ {
GetBox(MaterialNodeBoxes.Color).Enabled = false; GetBox(MaterialNodeBoxes.Color).IsActive = false;
GetBox(MaterialNodeBoxes.Mask).Enabled = true; GetBox(MaterialNodeBoxes.Mask).IsActive = true;
GetBox(MaterialNodeBoxes.Emissive).Enabled = true; GetBox(MaterialNodeBoxes.Emissive).IsActive = true;
GetBox(MaterialNodeBoxes.Metalness).Enabled = false; GetBox(MaterialNodeBoxes.Metalness).IsActive = false;
GetBox(MaterialNodeBoxes.Specular).Enabled = false; GetBox(MaterialNodeBoxes.Specular).IsActive = false;
GetBox(MaterialNodeBoxes.Roughness).Enabled = false; GetBox(MaterialNodeBoxes.Roughness).IsActive = false;
GetBox(MaterialNodeBoxes.AmbientOcclusion).Enabled = false; GetBox(MaterialNodeBoxes.AmbientOcclusion).IsActive = false;
GetBox(MaterialNodeBoxes.Normal).Enabled = false; GetBox(MaterialNodeBoxes.Normal).IsActive = false;
GetBox(MaterialNodeBoxes.Opacity).Enabled = true; GetBox(MaterialNodeBoxes.Opacity).IsActive = true;
GetBox(MaterialNodeBoxes.Refraction).Enabled = false; GetBox(MaterialNodeBoxes.Refraction).IsActive = false;
GetBox(MaterialNodeBoxes.PositionOffset).Enabled = false; GetBox(MaterialNodeBoxes.PositionOffset).IsActive = false;
GetBox(MaterialNodeBoxes.TessellationMultiplier).Enabled = false; GetBox(MaterialNodeBoxes.TessellationMultiplier).IsActive = false;
GetBox(MaterialNodeBoxes.WorldDisplacement).Enabled = false; GetBox(MaterialNodeBoxes.WorldDisplacement).IsActive = false;
GetBox(MaterialNodeBoxes.SubsurfaceColor).Enabled = false; GetBox(MaterialNodeBoxes.SubsurfaceColor).IsActive = false;
break; break;
} }
case MaterialDomain.VolumeParticle: case MaterialDomain.VolumeParticle:
{ {
GetBox(MaterialNodeBoxes.Color).Enabled = true; GetBox(MaterialNodeBoxes.Color).IsActive = true;
GetBox(MaterialNodeBoxes.Mask).Enabled = true; GetBox(MaterialNodeBoxes.Mask).IsActive = true;
GetBox(MaterialNodeBoxes.Emissive).Enabled = true; GetBox(MaterialNodeBoxes.Emissive).IsActive = true;
GetBox(MaterialNodeBoxes.Metalness).Enabled = false; GetBox(MaterialNodeBoxes.Metalness).IsActive = false;
GetBox(MaterialNodeBoxes.Specular).Enabled = false; GetBox(MaterialNodeBoxes.Specular).IsActive = false;
GetBox(MaterialNodeBoxes.Roughness).Enabled = false; GetBox(MaterialNodeBoxes.Roughness).IsActive = false;
GetBox(MaterialNodeBoxes.AmbientOcclusion).Enabled = false; GetBox(MaterialNodeBoxes.AmbientOcclusion).IsActive = false;
GetBox(MaterialNodeBoxes.Normal).Enabled = false; GetBox(MaterialNodeBoxes.Normal).IsActive = false;
GetBox(MaterialNodeBoxes.Opacity).Enabled = true; GetBox(MaterialNodeBoxes.Opacity).IsActive = true;
GetBox(MaterialNodeBoxes.Refraction).Enabled = false; GetBox(MaterialNodeBoxes.Refraction).IsActive = false;
GetBox(MaterialNodeBoxes.PositionOffset).Enabled = false; GetBox(MaterialNodeBoxes.PositionOffset).IsActive = false;
GetBox(MaterialNodeBoxes.TessellationMultiplier).Enabled = false; GetBox(MaterialNodeBoxes.TessellationMultiplier).IsActive = false;
GetBox(MaterialNodeBoxes.WorldDisplacement).Enabled = false; GetBox(MaterialNodeBoxes.WorldDisplacement).IsActive = false;
GetBox(MaterialNodeBoxes.SubsurfaceColor).Enabled = false; GetBox(MaterialNodeBoxes.SubsurfaceColor).IsActive = false;
break; break;
} }
default: throw new ArgumentOutOfRangeException(); default: throw new ArgumentOutOfRangeException();
@@ -936,6 +936,142 @@ namespace FlaxEditor.Surface.Archetypes
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(float), 2), NodeElementArchetype.Factory.Output(0, string.Empty, typeof(float), 2),
} }
}, },
new NodeArchetype
{
TypeID = 43,
Title = "Rotate UV",
Description = "Rotates 2D vector by given angle around (0,0) origin",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(250, 40),
ConnectionsHints = ConnectionsHint.Vector,
DefaultValues =
[
0.0f,
],
Elements =
[
NodeElementArchetype.Factory.Input(0, "UV", true, typeof(Float2), 0),
NodeElementArchetype.Factory.Input(1, "Angle", true, typeof(float), 1, 0),
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(Float2), 2),
]
},
new NodeArchetype
{
TypeID = 44,
Title = "Cone Gradient",
Description = "Creates cone gradient around normalized UVs (range [-1; 1]), angle is in radians (range [0; TwoPi])",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(175, 40),
ConnectionsHints = ConnectionsHint.Vector,
DefaultValues =
[
0.0f,
],
Elements =
[
NodeElementArchetype.Factory.Input(0, "UV", true, typeof(Float2), 0),
NodeElementArchetype.Factory.Input(1, "Angle", true, typeof(float), 1, 0),
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(float), 2),
]
},
new NodeArchetype
{
TypeID = 45,
Title = "Cycle Gradient",
Description = "Creates 2D sphere mask gradient around normalized UVs (range [-1; 1])",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(175, 20),
ConnectionsHints = ConnectionsHint.Vector,
Elements =
[
NodeElementArchetype.Factory.Input(0, "UV", true, typeof(Float2), 0),
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(float), 1),
]
},
new NodeArchetype
{
TypeID = 46,
Title = "Falloff and Offset",
Description = "",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(175, 60),
ConnectionsHints = ConnectionsHint.Numeric,
DefaultValues =
[
0.0f,
0.9f
],
Elements =
[
NodeElementArchetype.Factory.Input(0, "Value", true, typeof(float), 0),
NodeElementArchetype.Factory.Input(1, "Offset", true, typeof(float), 1, 0),
NodeElementArchetype.Factory.Input(2, "Falloff", true, typeof(float), 2, 1),
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(float), 3),
]
},
new NodeArchetype
{
TypeID = 47,
Title = "Linear Gradient",
Description = "x = Gradient along X axis, y = Gradient along Y axis",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(175, 60),
ConnectionsHints = ConnectionsHint.Vector,
DefaultValues =
[
0.0f,
false
],
Elements =
[
NodeElementArchetype.Factory.Input(0, "UV", true, typeof(Float2), 0),
NodeElementArchetype.Factory.Input(1, "Angle", true, typeof(float), 1, 0),
NodeElementArchetype.Factory.Input(2, "Mirror", true, typeof(bool), 2, 1),
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(Float2), 3),
]
},
new NodeArchetype
{
TypeID = 48,
Title = "Radial Gradient",
Description = "",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(175, 40),
ConnectionsHints = ConnectionsHint.Vector,
DefaultValues =
[
0.0f,
],
Elements =
[
NodeElementArchetype.Factory.Input(0, "UV", true, typeof(Float2), 0),
NodeElementArchetype.Factory.Input(1, "Angle", true, typeof(float), 1, 0),
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(float), 2),
]
},
new NodeArchetype
{
TypeID = 49,
Title = "Ring Gradient",
Description = "x = InnerMask,y = OuterMask,z = Mask",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(175, 80),
ConnectionsHints = ConnectionsHint.Vector,
DefaultValues =
[
1.0f,
0.8f,
0.05f,
],
Elements =
[
NodeElementArchetype.Factory.Input(0, "UV", true, typeof(Float2), 0),
NodeElementArchetype.Factory.Input(1, "OuterBounds", true, typeof(float), 1, 0),
NodeElementArchetype.Factory.Input(2, "InnerBounds", true, typeof(float), 2, 1),
NodeElementArchetype.Factory.Input(3, "Falloff", true, typeof(float), 3, 2),
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(Float3), 4),
]
},
}; };
} }
} }

View File

@@ -114,10 +114,10 @@ namespace FlaxEditor.Surface.Archetypes
Op1(13, "Round", "Rounds A to the nearest integer"), Op1(13, "Round", "Rounds A to the nearest integer"),
Op1(14, "Saturate", "Clamps A to the range [0, 1]"), Op1(14, "Saturate", "Clamps A to the range [0, 1]"),
Op1(15, "Sine", "Returns sine of A"), Op1(15, "Sine", "Returns sine of A"),
Op1(16, "Sqrt", "Returns square root of A", new [] { "Square Root", "Square", "Root" }), Op1(16, "Sqrt", "Returns square root of A", new[] { "Square Root", "Square", "Root" }),
Op1(17, "Tangent", "Returns tangent of A"), Op1(17, "Tangent", "Returns tangent of A"),
Op2(18, "Cross", "Returns the cross product of A and B", ConnectionsHint.None, typeof(Float3)), Op2(18, "Cross", "Returns the cross product of A and B", ConnectionsHint.None, typeof(Float3)),
Op2(19, "Distance", "Returns a distance scalar between A and B", new [] { "Magnitude", "Mag", "Length" }, ConnectionsHint.Vector, null, typeof(float), false), Op2(19, "Distance", "Returns a distance scalar between A and B", new[] { "Magnitude", "Mag", "Length" }, ConnectionsHint.Vector, null, typeof(float), false),
Op2(20, "Dot", "Returns the dot product of A and B", ConnectionsHint.Vector, null, typeof(float), false), Op2(20, "Dot", "Returns the dot product of A and B", ConnectionsHint.Vector, null, typeof(float), false),
Op2(21, "Max", "Selects the greater of A and B"), Op2(21, "Max", "Selects the greater of A and B"),
Op2(22, "Min", "Selects the lesser of A and B"), Op2(22, "Min", "Selects the lesser of A and B"),
@@ -192,7 +192,7 @@ namespace FlaxEditor.Surface.Archetypes
} }
}, },
// //
Op1(27, "Negate", "Returns opposite value", new [] { "Invert" }), Op1(27, "Negate", "Returns opposite value", new[] { "Invert" }),
Op1(28, "One Minus", "Returns 1 - value"), Op1(28, "One Minus", "Returns 1 - value"),
// //
new NodeArchetype new NodeArchetype
@@ -232,7 +232,7 @@ namespace FlaxEditor.Surface.Archetypes
{ {
TypeID = 31, TypeID = 31,
Title = "Mad", Title = "Mad",
AlternativeTitles = new [] { "Multiply", "Add", "*+" }, AlternativeTitles = new[] { "Multiply", "Add", "*+" },
Description = "Performs value multiplication and addition at once", Description = "Performs value multiplication and addition at once",
Flags = NodeFlags.AllGraphs, Flags = NodeFlags.AllGraphs,
Size = new Float2(160, 60), Size = new Float2(160, 60),
@@ -430,7 +430,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Smoothstep", Title = "Smoothstep",
Description = "Returns a smooth Hermite interpolation between 0 and 1, if value is in the range [min, max].", Description = "Returns a smooth Hermite interpolation between 0 and 1, if value is in the range [min, max].",
Flags = NodeFlags.MaterialGraph, Flags = NodeFlags.MaterialGraph,
Size = new Float2(120, 60), Size = new Float2(200, 60),
ConnectionsHints = ConnectionsHint.Numeric, ConnectionsHints = ConnectionsHint.Numeric,
IndependentBoxes = new[] { 0, 1, 2 }, IndependentBoxes = new[] { 0, 1, 2 },
DependentBoxes = new[] { 3 }, DependentBoxes = new[] { 3 },

View File

@@ -399,7 +399,7 @@ namespace FlaxEditor.Surface.Archetypes
private void UpdateInputBox() private void UpdateInputBox()
{ {
var facingMode = (ParticleSpriteFacingMode)Values[2]; var facingMode = (ParticleSpriteFacingMode)Values[2];
GetBox(0).Enabled = facingMode == ParticleSpriteFacingMode.CustomFacingVector || facingMode == ParticleSpriteFacingMode.FixedAxis; GetBox(0).IsActive = facingMode == ParticleSpriteFacingMode.CustomFacingVector || facingMode == ParticleSpriteFacingMode.FixedAxis;
} }
} }

View File

@@ -434,6 +434,19 @@ namespace FlaxEditor.Surface.Archetypes
NodeElementArchetype.Factory.ComboBox(50, Surface.Constants.LayoutOffsetY * 4, 100, 0, typeof(CommonSamplerType)) NodeElementArchetype.Factory.ComboBox(50, Surface.Constants.LayoutOffsetY * 4, 100, 0, typeof(CommonSamplerType))
} }
}, },
new NodeArchetype
{
TypeID = 18,
Title = "Lightmap UV",
AlternativeTitles = new string[] { "Lightmap TexCoord" },
Description = "Lightmap UVs",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(110, 30),
Elements = new []
{
NodeElementArchetype.Factory.Output(0, "UVs", typeof(Float2), 0)
}
}
}; };
} }
} }

View File

@@ -1032,7 +1032,8 @@ namespace FlaxEditor.Surface.Archetypes
private Rectangle _localBounds; private Rectangle _localBounds;
private InputBox _input; private InputBox _input;
private OutputBox _output; private OutputBox _output;
private bool _isMouseDown, _isConnecting; private bool _isMouseDown, _isConnecting, _isMouseInConnectingBounds;
private const float ConnectingBounds = -12.0f;
/// <inheritdoc /> /// <inheritdoc />
public RerouteNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch) public RerouteNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
@@ -1170,7 +1171,7 @@ namespace FlaxEditor.Surface.Archetypes
if (button == MouseButton.Left) if (button == MouseButton.Left)
{ {
_isMouseDown = true; _isMouseDown = true;
_isConnecting = _localBounds.MakeExpanded(-10.0f).Contains(ref location); // Inner area for connecting, outer area for moving _isConnecting = _isMouseInConnectingBounds;
if (_isConnecting) if (_isConnecting)
{ {
Focus(); Focus();
@@ -1189,12 +1190,22 @@ namespace FlaxEditor.Surface.Archetypes
if (Surface.CanEdit && _isConnecting) if (Surface.CanEdit && _isConnecting)
Surface.ConnectingStart(this); Surface.ConnectingStart(this);
} }
_isMouseInConnectingBounds = false;
Cursor = CursorType.Default;
base.OnMouseLeave(); base.OnMouseLeave();
} }
/// <inheritdoc /> /// <inheritdoc />
public override void OnMouseMove(Float2 location) public override void OnMouseMove(Float2 location)
{ {
_isMouseInConnectingBounds = IsMouseOver && _localBounds.MakeExpanded(ConnectingBounds).Contains(ref location); // Inner area for connecting, outer area for moving
if (!_isMouseInConnectingBounds && !_isMouseDown)
Cursor = CursorType.SizeAll;
else
Cursor = CursorType.Default;
Surface.ConnectingOver(this); Surface.ConnectingOver(this);
base.OnMouseMove(location); base.OnMouseMove(location);
} }
@@ -1255,7 +1266,7 @@ namespace FlaxEditor.Surface.Archetypes
/// <inheritdoc /> /// <inheritdoc />
public void DrawConnectingLine(ref Float2 startPos, ref Float2 endPos, ref Color color) public void DrawConnectingLine(ref Float2 startPos, ref Float2 endPos, ref Color color)
{ {
OutputBox.DrawConnection(Surface.Style, ref startPos, ref endPos, ref color, 2); OutputBox.DrawConnection(Surface.Style, ref startPos, ref endPos, ref color, OutputBox.ConnectingConnectionThickness);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -1483,7 +1494,7 @@ namespace FlaxEditor.Surface.Archetypes
{ {
TypeID = 11, TypeID = 11,
Title = "Comment", Title = "Comment",
AlternativeTitles = new[] { "//" , "Group" }, AlternativeTitles = new[] { "//", "Group" },
TryParseText = (string filterText, out object[] data) => TryParseText = (string filterText, out object[] data) =>
{ {
data = null; data = null;
@@ -1639,7 +1650,7 @@ namespace FlaxEditor.Surface.Archetypes
{ {
TypeID = 22, TypeID = 22,
Title = "As", Title = "As",
AlternativeTitles = new [] { "Cast" }, AlternativeTitles = new[] { "Cast" },
Create = (id, context, arch, groupArch) => new AsNode(id, context, arch, groupArch), Create = (id, context, arch, groupArch) => new AsNode(id, context, arch, groupArch),
Description = "Casts the object to a different type. Returns null if cast fails.", Description = "Casts the object to a different type. Returns null if cast fails.",
Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph, Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph,

View File

@@ -307,7 +307,10 @@ namespace FlaxEditor.Surface.ContextMenu
if (!IsLayoutLocked) if (!IsLayoutLocked)
{ {
group.UnlockChildrenRecursive(); group.UnlockChildrenRecursive();
SortGroups(); if (_contextSensitiveSearchEnabled && _selectedBox != null)
UpdateFilters();
else
SortGroups();
if (ShowExpanded) if (ShowExpanded)
group.Open(false); group.Open(false);
group.PerformLayout(); group.PerformLayout();
@@ -367,7 +370,10 @@ namespace FlaxEditor.Surface.ContextMenu
if (!isLayoutLocked) if (!isLayoutLocked)
{ {
SortGroups(); if (_contextSensitiveSearchEnabled && _selectedBox != null)
UpdateFilters();
else
SortGroups();
Profiler.BeginEvent("Perform Layout"); Profiler.BeginEvent("Perform Layout");
UnlockChildrenRecursive(); UnlockChildrenRecursive();
foreach (var group in groups) foreach (var group in groups)
@@ -482,10 +488,11 @@ namespace FlaxEditor.Surface.ContextMenu
// Update groups // Update groups
LockChildrenRecursive(); LockChildrenRecursive();
var contextSensitiveSelectedBox = _contextSensitiveSearchEnabled ? _selectedBox : null;
for (int i = 0; i < _groups.Count; i++) for (int i = 0; i < _groups.Count; i++)
{ {
_groups[i].UpdateFilter(_searchBox.Text, _contextSensitiveSearchEnabled ? _selectedBox : null); _groups[i].UpdateFilter(_searchBox.Text, contextSensitiveSelectedBox);
_groups[i].UpdateItemSort(_selectedBox); _groups[i].UpdateItemSort(contextSensitiveSelectedBox);
} }
SortGroups(); SortGroups();
UnlockChildrenRecursive(); UnlockChildrenRecursive();
@@ -560,7 +567,10 @@ namespace FlaxEditor.Surface.ContextMenu
} }
UnlockChildrenRecursive(); UnlockChildrenRecursive();
SortGroups(); if (_contextSensitiveSearchEnabled && _selectedBox != null)
UpdateFilters();
else
SortGroups();
PerformLayout(); PerformLayout();
Profiler.EndEvent(); Profiler.EndEvent();

View File

@@ -89,6 +89,30 @@ namespace FlaxEditor.Surface.ContextMenu
{ {
Profiler.BeginEvent("VisjectCMGroup.UpdateFilter"); Profiler.BeginEvent("VisjectCMGroup.UpdateFilter");
// Check if a dot is inside the filter text and split the string accordingly.
// Everything in front of the dot is for specifying a class/group name. And everything afterward is the actual item filter text
if (!string.IsNullOrEmpty(filterText))
{
int dotIndex = filterText.IndexOf('.');
if (dotIndex != -1)
{
string filterGroupName = filterText.Substring(0, dotIndex);
// If the string in front of the dot has the length of 0 or doesn't start with a letter we skip the filtering to make spawning floats work
if (filterGroupName.Length > 0 && char.IsLetter(filterGroupName[0]))
{
// Early out and make the group invisible if it doesn't start with the specified string
if (!Name.StartsWith(filterGroupName, StringComparison.InvariantCultureIgnoreCase))
{
Visible = false;
Profiler.EndEvent();
return;
}
filterText = filterText.Substring(dotIndex + 1);
}
}
}
// Update items // Update items
bool isAnyVisible = false; bool isAnyVisible = false;
bool groupHeaderMatches = QueryFilterHelper.Match(filterText, HeaderText); bool groupHeaderMatches = QueryFilterHelper.Match(filterText, HeaderText);
@@ -177,6 +201,13 @@ namespace FlaxEditor.Surface.ContextMenu
SortScore = item.SortScore; SortScore = item.SortScore;
} }
} }
if (selectedBox != null)
{
if (string.Equals(Name, selectedBox.CurrentType.Name, StringComparison.InvariantCultureIgnoreCase))
SortScore += 10;
}
SortChildren(); SortChildren();
Profiler.EndEvent(); Profiler.EndEvent();

View File

@@ -219,7 +219,7 @@ namespace FlaxEditor.Surface.ContextMenu
} }
// Check archetype synonyms // Check archetype synonyms
if (_archetype.AlternativeTitles!= null && _archetype.AlternativeTitles.Any(altTitle => QueryFilterHelper.Match(filterText, altTitle, out ranges))) if (_archetype.AlternativeTitles != null && _archetype.AlternativeTitles.Any(altTitle => QueryFilterHelper.Match(filterText, altTitle, out ranges)))
{ {
// Update highlights // Update highlights
if (_highlights == null) if (_highlights == null)

View File

@@ -41,6 +41,11 @@ namespace FlaxEditor.Surface.Elements
/// </summary> /// </summary>
protected bool _isSelected; protected bool _isSelected;
/// <summary>
/// The is active flag for the box. Unlike <see cref="FlaxEngine.GUI.Control.Enabled"/>, inactive boxes can still be interacted with, they just will be drawn like disabled boxes
/// </summary>
protected bool _isActive = true;
/// <summary> /// <summary>
/// Unique box ID within single node. /// Unique box ID within single node.
/// </summary> /// </summary>
@@ -180,6 +185,15 @@ namespace FlaxEditor.Surface.Elements
} }
} }
/// <summary>
/// Gets or sets the active state of the box. Unlike <see cref="FlaxEngine.GUI.Control.Enabled"/>, inactive boxes can still be interacted with, they just will be drawn like disabled boxes
/// </summary>
public bool IsActive
{
get => _isActive;
set => _isActive = value;
}
/// <inheritdoc /> /// <inheritdoc />
protected Box(SurfaceNode parentNode, NodeElementArchetype archetype, Float2 location) protected Box(SurfaceNode parentNode, NodeElementArchetype archetype, Float2 location)
: base(parentNode, archetype, location, new Float2(Constants.BoxSize), false) : base(parentNode, archetype, location, new Float2(Constants.BoxSize), false)
@@ -724,7 +738,7 @@ namespace FlaxEditor.Surface.Elements
/// <inheritdoc /> /// <inheritdoc />
public void DrawConnectingLine(ref Float2 startPos, ref Float2 endPos, ref Color color) public void DrawConnectingLine(ref Float2 startPos, ref Float2 endPos, ref Color color)
{ {
OutputBox.DrawConnection(Surface.Style, ref startPos, ref endPos, ref color, 2); OutputBox.DrawConnection(Surface.Style, ref startPos, ref endPos, ref color, OutputBox.ConnectingConnectionThickness);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -35,7 +35,7 @@ namespace FlaxEditor.Surface.Elements
ParentNode.ValuesChanged += OnNodeValuesChanged; ParentNode.ValuesChanged += OnNodeValuesChanged;
// Disable slider if surface doesn't allow it // Disable slider if surface doesn't allow it
if (!ParentNode.Surface.CanLivePreviewValueChanges) if (ParentNode.Surface != null && !ParentNode.Surface.CanLivePreviewValueChanges)
_slideSpeed = 0.0f; _slideSpeed = 0.0f;
} }

View File

@@ -3,6 +3,7 @@
using FlaxEngine; using FlaxEngine;
using FlaxEngine.GUI; using FlaxEngine.GUI;
using System; using System;
using FlaxEditor.Options;
namespace FlaxEditor.Surface.Elements namespace FlaxEditor.Surface.Elements
{ {
@@ -13,6 +14,26 @@ namespace FlaxEditor.Surface.Elements
[HideInEditor] [HideInEditor]
public class OutputBox : Box public class OutputBox : Box
{ {
/// <summary>
/// The default thickness of the connection line
/// </summary>
public const float DefaultConnectionThickness = 1.5f;
/// <summary>
/// The thickness of a highlighted connection line
/// </summary>
public const float ConnectingConnectionThickness = 2.5f;
/// <summary>
/// The thickness of the selected connection line
/// </summary>
public const float SelectedConnectionThickness = 3f;
/// <summary>
/// The offset between the connection line and the box
/// </summary>
public const float DefaultConnectionOffset = 24f;
/// <summary> /// <summary>
/// Distance for the mouse to be considered above the connection /// Distance for the mouse to be considered above the connection
/// </summary> /// </summary>
@@ -32,7 +53,7 @@ namespace FlaxEditor.Surface.Elements
/// <param name="end">The end location.</param> /// <param name="end">The end location.</param>
/// <param name="color">The connection color.</param> /// <param name="color">The connection color.</param>
/// <param name="thickness">The connection thickness.</param> /// <param name="thickness">The connection thickness.</param>
public static void DrawConnection(SurfaceStyle style, ref Float2 start, ref Float2 end, ref Color color, float thickness = 1) public static void DrawConnection(SurfaceStyle style, ref Float2 start, ref Float2 end, ref Color color, float thickness = DefaultConnectionThickness)
{ {
if (style.DrawConnection != null) if (style.DrawConnection != null)
{ {
@@ -40,11 +61,22 @@ namespace FlaxEditor.Surface.Elements
return; return;
} }
float connectionOffset = Mathf.Max(0f, DefaultConnectionOffset * (1 - Editor.Instance.Options.Options.Interface.ConnectionCurvature));
Float2 offsetStart = new Float2(start.X + connectionOffset, start.Y);
Float2 offsetEnd = new Float2(end.X - connectionOffset, end.Y);
// Calculate control points // Calculate control points
CalculateBezierControlPoints(start, end, out var control1, out var control2); CalculateBezierControlPoints(offsetStart, offsetEnd, out var control1, out var control2);
// Draw offset lines only if necessary
if (connectionOffset >= float.Epsilon)
{
Render2D.DrawLine(start, offsetStart, color, thickness);
Render2D.DrawLine(offsetEnd, end, color, thickness);
}
// Draw line // Draw line
Render2D.DrawBezier(start, control1, control2, end, color, thickness); Render2D.DrawBezier(offsetStart, control1, control2, offsetEnd, color, thickness);
/* /*
// Debug drawing control points // Debug drawing control points
@@ -57,8 +89,8 @@ namespace FlaxEditor.Surface.Elements
private static void CalculateBezierControlPoints(Float2 start, Float2 end, out Float2 control1, out Float2 control2) private static void CalculateBezierControlPoints(Float2 start, Float2 end, out Float2 control1, out Float2 control2)
{ {
// Control points parameters // Control points parameters
const float minControlLength = 100f; const float minControlLength = 50f;
const float maxControlLength = 150f; const float maxControlLength = 120f;
var dst = (end - start).Length; var dst = (end - start).Length;
var yDst = Mathf.Abs(start.Y - end.Y); var yDst = Mathf.Abs(start.Y - end.Y);
@@ -66,6 +98,7 @@ namespace FlaxEditor.Surface.Elements
var minControlDst = dst * 0.5f; var minControlDst = dst * 0.5f;
var maxControlDst = Mathf.Max(Mathf.Min(maxControlLength, dst), minControlLength); var maxControlDst = Mathf.Max(Mathf.Min(maxControlLength, dst), minControlLength);
var controlDst = Mathf.Lerp(minControlDst, maxControlDst, Mathf.Clamp(yDst / minControlLength, 0f, 1f)); var controlDst = Mathf.Lerp(minControlDst, maxControlDst, Mathf.Clamp(yDst / minControlLength, 0f, 1f));
controlDst *= Editor.Instance.Options.Options.Interface.ConnectionCurvature;
control1 = new Float2(start.X + controlDst, start.Y); control1 = new Float2(start.X + controlDst, start.Y);
control2 = new Float2(end.X - controlDst, end.Y); control2 = new Float2(end.X - controlDst, end.Y);
@@ -78,9 +111,10 @@ namespace FlaxEditor.Surface.Elements
/// <param name="mousePosition">The mouse position</param> /// <param name="mousePosition">The mouse position</param>
public bool IntersectsConnection(Box targetBox, ref Float2 mousePosition) public bool IntersectsConnection(Box targetBox, ref Float2 mousePosition)
{ {
var startPos = ConnectionOrigin; float connectionOffset = Mathf.Max(0f, DefaultConnectionOffset * (1 - Editor.Instance.Options.Options.Interface.ConnectionCurvature));
var endPos = targetBox.ConnectionOrigin; Float2 start = new Float2(ConnectionOrigin.X + connectionOffset, ConnectionOrigin.Y);
return IntersectsConnection(ref startPos, ref endPos, ref mousePosition, MouseOverConnectionDistance); Float2 end = new Float2(targetBox.ConnectionOrigin.X - connectionOffset, targetBox.ConnectionOrigin.Y);
return IntersectsConnection(ref start, ref end, ref mousePosition, MouseOverConnectionDistance);
} }
/// <summary> /// <summary>
@@ -100,22 +134,26 @@ namespace FlaxEditor.Surface.Elements
if ((point.Y - (start.Y - offset)) * ((end.Y + offset) - point.Y) < 0) if ((point.Y - (start.Y - offset)) * ((end.Y + offset) - point.Y) < 0)
return false; return false;
float squaredDistance = distance; float connectionOffset = Mathf.Max(0f, DefaultConnectionOffset * (1 - Editor.Instance.Options.Options.Interface.ConnectionCurvature));
CalculateBezierControlPoints(start, end, out var control1, out var control2); Float2 offsetStart = new Float2(start.X + connectionOffset, start.Y);
Float2 offsetEnd = new Float2(end.X - connectionOffset, end.Y);
var d1 = control1 - start; float squaredDistance = distance;
CalculateBezierControlPoints(offsetStart, offsetEnd, out var control1, out var control2);
var d1 = control1 - offsetStart;
var d2 = control2 - control1; var d2 = control2 - control1;
var d3 = end - control2; var d3 = offsetEnd - control2;
float len = d1.Length + d2.Length + d3.Length; float len = d1.Length + d2.Length + d3.Length;
int segmentCount = Math.Min(Math.Max(Mathf.CeilToInt(len * 0.05f), 1), 100); int segmentCount = Math.Min(Math.Max(Mathf.CeilToInt(len * 0.05f), 1), 100);
float segmentCountInv = 1.0f / segmentCount; float segmentCountInv = 1.0f / segmentCount;
Bezier(ref start, ref control1, ref control2, ref end, 0, out var p); Bezier(ref offsetStart, ref control1, ref control2, ref offsetEnd, 0, out var p);
for (int i = 1; i <= segmentCount; i++) for (int i = 1; i <= segmentCount; i++)
{ {
var oldp = p; var oldp = p;
float t = i * segmentCountInv; float t = i * segmentCountInv;
Bezier(ref start, ref control1, ref control2, ref end, t, out p); Bezier(ref offsetStart, ref control1, ref control2, ref offsetEnd, t, out p);
// Maybe it would be reasonable to return the point? // Maybe it would be reasonable to return the point?
CollisionsHelper.ClosestPointPointLine(ref point, ref oldp, ref p, out var result); CollisionsHelper.ClosestPointPointLine(ref point, ref oldp, ref p, out var result);
@@ -151,14 +189,20 @@ namespace FlaxEditor.Surface.Elements
{ {
Box targetBox = Connections[i]; Box targetBox = Connections[i];
var endPos = targetBox.ConnectionOrigin; var endPos = targetBox.ConnectionOrigin;
var highlight = 1 + Mathf.Max(startHighlight, targetBox.ConnectionsHighlightIntensity); var highlight = DefaultConnectionThickness + Mathf.Max(startHighlight, targetBox.ConnectionsHighlightIntensity);
var color = _currentTypeColor * highlight; var alpha = targetBox.Enabled && targetBox.IsActive ? 1.0f : 0.6f;
// We have to calculate an offset here to preserve the original color for when the default connection thickness is larger than 1
var highlightOffset = (highlight - (DefaultConnectionThickness - 1));
var color = _currentTypeColor * highlightOffset * alpha;
// TODO: Figure out how to only draw the topmost connection // TODO: Figure out how to only draw the topmost connection
if (IntersectsConnection(ref startPos, ref endPos, ref mousePosition, mouseOverDistance)) if (IntersectsConnection(ref startPos, ref endPos, ref mousePosition, mouseOverDistance))
{ highlight += DefaultConnectionThickness * 0.5f;
highlight += 0.5f;
} // Increase thickness on impulse/ execution lines
if (targetBox.CurrentType.IsVoid)
highlight *= 2;
DrawConnection(style, ref startPos, ref endPos, ref color, highlight); DrawConnection(style, ref startPos, ref endPos, ref color, highlight);
} }
@@ -172,7 +216,9 @@ namespace FlaxEditor.Surface.Elements
// Draw all the connections // Draw all the connections
var startPos = ConnectionOrigin; var startPos = ConnectionOrigin;
var endPos = targetBox.ConnectionOrigin; var endPos = targetBox.ConnectionOrigin;
DrawConnection(Surface.Style, ref startPos, ref endPos, ref _currentTypeColor, 2.5f); var alpha = targetBox.Enabled && targetBox.IsActive ? 1.0f : 0.6f;
var color = _currentTypeColor * alpha;
DrawConnection(Surface.Style, ref startPos, ref endPos, ref color, SelectedConnectionThickness);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -20,12 +20,18 @@ namespace FlaxEditor.Surface
private Rectangle _colorButtonRect; private Rectangle _colorButtonRect;
private Rectangle _resizeButtonRect; private Rectangle _resizeButtonRect;
private Float2 _startResizingSize; private Float2 _startResizingSize;
private readonly TextBox _renameTextBox;
/// <summary> /// <summary>
/// True if sizing tool is in use. /// True if sizing tool is in use.
/// </summary> /// </summary>
protected bool _isResizing; protected bool _isResizing;
/// <summary>
/// True if rename textbox is active in order to rename comment
/// </summary>
protected bool _isRenaming;
/// <summary> /// <summary>
/// Gets or sets the color of the comment. /// Gets or sets the color of the comment.
/// </summary> /// </summary>
@@ -63,6 +69,13 @@ namespace FlaxEditor.Surface
public SurfaceComment(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch) public SurfaceComment(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
: base(id, context, nodeArch, groupArch) : base(id, context, nodeArch, groupArch)
{ {
_renameTextBox = new TextBox(false, 0, 0, Width)
{
Height = Constants.NodeHeaderSize,
Visible = false,
Parent = this,
EndEditOnClick = false, // We have to handle this ourselves, otherwise the textbox instantly loses focus when double-clicking the header
};
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -83,7 +96,7 @@ namespace FlaxEditor.Surface
IndexInParent = 0; IndexInParent = 0;
OrderValue = IndexInParent; OrderValue = IndexInParent;
} }
else if(OrderValue != -1) else if (OrderValue != -1)
{ {
IndexInParent = OrderValue; IndexInParent = OrderValue;
} }
@@ -97,7 +110,7 @@ namespace FlaxEditor.Surface
// Randomize color // Randomize color
Color = ColorValue = Color.FromHSV(new Random().NextFloat(0, 360), 0.7f, 0.25f, 0.8f); Color = ColorValue = Color.FromHSV(new Random().NextFloat(0, 360), 0.7f, 0.25f, 0.8f);
if(OrderValue == -1) if (OrderValue == -1)
OrderValue = Context.CommentCount - 1; OrderValue = Context.CommentCount - 1;
IndexInParent = OrderValue; IndexInParent = OrderValue;
} }
@@ -149,6 +162,20 @@ namespace FlaxEditor.Surface
_closeButtonRect = new Rectangle(Width - buttonSize - buttonMargin, buttonMargin, buttonSize, buttonSize); _closeButtonRect = new Rectangle(Width - buttonSize - buttonMargin, buttonMargin, buttonSize, buttonSize);
_colorButtonRect = new Rectangle(_closeButtonRect.Left - buttonSize - buttonMargin, buttonMargin, buttonSize, buttonSize); _colorButtonRect = new Rectangle(_closeButtonRect.Left - buttonSize - buttonMargin, buttonMargin, buttonSize, buttonSize);
_resizeButtonRect = new Rectangle(_closeButtonRect.Left, Height - buttonSize - buttonMargin, buttonSize, buttonSize); _resizeButtonRect = new Rectangle(_closeButtonRect.Left, Height - buttonSize - buttonMargin, buttonSize, buttonSize);
_renameTextBox.Width = Width;
_renameTextBox.Height = headerSize;
}
/// <inheritdoc />
public override void Update(float deltaTime)
{
if (_isRenaming && (!_renameTextBox.IsFocused || !RootWindow.IsFocused))
{
Rename(_renameTextBox.Text);
StopRenaming();
}
base.Update(deltaTime);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -158,7 +185,7 @@ namespace FlaxEditor.Surface
var color = Color; var color = Color;
var backgroundRect = new Rectangle(Float2.Zero, Size); var backgroundRect = new Rectangle(Float2.Zero, Size);
var headerColor = new Color(Mathf.Clamp(color.R, 0.1f, 0.3f), Mathf.Clamp(color.G, 0.1f, 0.3f), Mathf.Clamp(color.B, 0.1f, 0.3f), 0.4f); var headerColor = new Color(Mathf.Clamp(color.R, 0.1f, 0.3f), Mathf.Clamp(color.G, 0.1f, 0.3f), Mathf.Clamp(color.B, 0.1f, 0.3f), 0.4f);
if (IsSelected) if (IsSelected && !_isRenaming)
headerColor *= 2.0f; headerColor *= 2.0f;
// Paint background // Paint background
@@ -169,7 +196,8 @@ namespace FlaxEditor.Surface
// Header // Header
Render2D.FillRectangle(_headerRect, headerColor); Render2D.FillRectangle(_headerRect, headerColor);
Render2D.DrawText(style.FontLarge, Title, _headerRect, style.Foreground, TextAlignment.Center, TextAlignment.Center); if (!_isRenaming)
Render2D.DrawText(style.FontLarge, Title, _headerRect, style.Foreground, TextAlignment.Center, TextAlignment.Center);
// Close button // Close button
Render2D.DrawSprite(style.Cross, _closeButtonRect, _closeButtonRect.Contains(_mousePosition) && Surface.CanEdit ? style.Foreground : style.ForegroundGrey); Render2D.DrawSprite(style.Cross, _closeButtonRect, _closeButtonRect.Contains(_mousePosition) && Surface.CanEdit ? style.Foreground : style.ForegroundGrey);
@@ -213,6 +241,13 @@ namespace FlaxEditor.Surface
EndResizing(); EndResizing();
} }
// Check if was renaming
if (_isRenaming)
{
Rename(_renameTextBox.Text);
StopRenaming();
}
// Base // Base
base.OnLostFocus(); base.OnLostFocus();
} }
@@ -294,17 +329,47 @@ namespace FlaxEditor.Surface
/// </summary> /// </summary>
public void StartRenaming() public void StartRenaming()
{ {
Surface.Select(this); _isRenaming = true;
var dialog = RenamePopup.Show(this, _headerRect, Title, false); _renameTextBox.Visible = true;
dialog.Renamed += OnRenamed; _renameTextBox.SetText(Title);
_renameTextBox.Focus();
_renameTextBox.SelectAll();
} }
private void OnRenamed(RenamePopup renamePopup) private void StopRenaming()
{ {
Title = TitleValue = renamePopup.Text; _isRenaming = false;
_renameTextBox.Visible = false;
}
private void Rename(string newTitle)
{
if (string.Equals(Title, newTitle, StringComparison.Ordinal))
return;
Title = TitleValue = newTitle;
Surface.MarkAsEdited(false); Surface.MarkAsEdited(false);
} }
/// <inheritdoc />
public override bool OnKeyDown(KeyboardKeys key)
{
if (key == KeyboardKeys.Return)
{
Rename(_renameTextBox.Text);
StopRenaming();
return true;
}
if (key == KeyboardKeys.Escape)
{
StopRenaming();
return true;
}
return base.OnKeyDown(key);
}
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button) public override bool OnMouseUp(Float2 location, MouseButton button)
{ {
@@ -350,18 +415,18 @@ namespace FlaxEditor.Surface
{ {
cmOrder.ContextMenu.AddButton("Bring Forward", () => cmOrder.ContextMenu.AddButton("Bring Forward", () =>
{ {
if(IndexInParent < Context.CommentCount-1) if (IndexInParent < Context.CommentCount - 1)
IndexInParent++; IndexInParent++;
OrderValue = IndexInParent; OrderValue = IndexInParent;
}); });
cmOrder.ContextMenu.AddButton("Bring to Front", () => cmOrder.ContextMenu.AddButton("Bring to Front", () =>
{ {
IndexInParent = Context.CommentCount-1; IndexInParent = Context.CommentCount - 1;
OrderValue = IndexInParent; OrderValue = IndexInParent;
}); });
cmOrder.ContextMenu.AddButton("Send Backward", () => cmOrder.ContextMenu.AddButton("Send Backward", () =>
{ {
if(IndexInParent > 0) if (IndexInParent > 0)
IndexInParent--; IndexInParent--;
OrderValue = IndexInParent; OrderValue = IndexInParent;
}); });

View File

@@ -228,7 +228,7 @@ namespace FlaxEditor.Surface
// Draw icon // Draw icon
bool hasConnections = box.HasAnyConnection; bool hasConnections = box.HasAnyConnection;
float alpha = box.Enabled ? 1.0f : 0.6f; float alpha = box.Enabled && box.IsActive ? 1.0f : 0.6f;
Color color = box.CurrentTypeColor * alpha; Color color = box.CurrentTypeColor * alpha;
var style = box.Surface.Style; var style = box.Surface.Style;
SpriteHandle icon; SpriteHandle icon;

View File

@@ -190,15 +190,7 @@ namespace FlaxEditor.Surface
if (data == null || data.Length < 2) if (data == null || data.Length < 2)
return false; return false;
try return true;
{
var model = JsonConvert.DeserializeObject<DataModel>(data);
return model?.Nodes != null && model.Nodes.Length != 0;
}
catch (Exception)
{
return false;
}
} }
/// <summary> /// <summary>
@@ -215,7 +207,15 @@ namespace FlaxEditor.Surface
try try
{ {
// Load Mr Json // Load Mr Json
var model = FlaxEngine.Json.JsonSerializer.Deserialize<DataModel>(data); DataModel model;
try
{
model = FlaxEngine.Json.JsonSerializer.Deserialize<DataModel>(data);
}
catch
{
return;
}
if (model.Nodes == null) if (model.Nodes == null)
model.Nodes = new DataModelNode[0]; model.Nodes = new DataModelNode[0];

View File

@@ -129,7 +129,12 @@ namespace FlaxEditor.Surface
/// <param name="args">The drag drop arguments data.</param> /// <param name="args">The drag drop arguments data.</param>
protected virtual void HandleDragDropParameters(List<string> objects, DragDropEventArgs args) protected virtual void HandleDragDropParameters(List<string> objects, DragDropEventArgs args)
{ {
var arch = GetParameterGetterNodeArchetype(out var groupId); // Try to get the setter node when holding the ALT key, otherwise get the getter node
if (!Input.GetKey(KeyboardKeys.Alt) || !TryGetParameterSetterNodeArchetype(out var groupId, out var arch))
{
arch = GetParameterGetterNodeArchetype(out groupId);
}
for (int i = 0; i < objects.Count; i++) for (int i = 0; i < objects.Count; i++)
{ {
var parameter = GetParameter(objects[i]); var parameter = GetParameter(objects[i]);
@@ -156,5 +161,18 @@ namespace FlaxEditor.Surface
groupId = 6; groupId = 6;
return Archetypes.Parameters.Nodes[0]; return Archetypes.Parameters.Nodes[0];
} }
/// <summary>
/// Tries to get the parameter setter node archetype to use.
/// </summary>
/// <param name="groupId">The group ID.</param>
/// <param name="archetype">The node archetype.</param>
/// <returns>True if a setter node exists.</returns>
protected virtual bool TryGetParameterSetterNodeArchetype(out ushort groupId, out NodeArchetype archetype)
{
groupId = 0;
archetype = null;
return false;
}
} }
} }

View File

@@ -35,6 +35,12 @@ namespace FlaxEditor.Surface
return RootContext.GetParameter(name); return RootContext.GetParameter(name);
} }
/// <inheritdoc />
public void OnParamReordered()
{
MarkAsEdited();
}
/// <inheritdoc /> /// <inheritdoc />
public void OnParamCreated(SurfaceParameter param) public void OnParamCreated(SurfaceParameter param)
{ {

View File

@@ -350,6 +350,213 @@ namespace FlaxEditor.Surface
} }
} }
sealed class ReorderParamAction : IUndoAction
{
/// <summary>
/// The window reference.
/// </summary>
public IVisjectSurfaceWindow Window;
/// <summary>
/// The parameters editor for this action.
/// </summary>
public ParametersEditor Editor;
/// <summary>
/// The old index the parameter was at.
/// </summary>
public int OldIndex;
/// <summary>
/// The new index the parameter will be at.
/// </summary>
public int NewIndex;
/// <inheritdoc />
public string ActionString => "Reorder Parameter";
/// <inheritdoc />
public void Dispose()
{
Window = null;
Editor = null;
}
public void Swap(int oldIdx, int newIdx)
{
if (oldIdx == newIdx)
return; // ?
var parameters = Window.VisjectSurface.Parameters;
if (newIdx > oldIdx)
{
for (int i = oldIdx; i < newIdx; i++)
{
SurfaceParameter old = parameters[i + 1];
parameters[i + 1] = parameters[i];
parameters[i] = old;
}
}
else
{
for (int i = oldIdx; i > newIdx; i--)
{
SurfaceParameter old = parameters[i - 1];
parameters[i - 1] = parameters[i];
parameters[i] = old;
}
}
}
/// <inheritdoc />
public void Do()
{
Swap(OldIndex, NewIndex);
Window.VisjectSurface.OnParamReordered();
}
/// <inheritdoc />
public void Undo()
{
Swap(NewIndex, OldIndex);
Window.VisjectSurface.OnParamReordered();
}
}
/// <summary>
/// Custom draggable property name label that handles reordering visject parameters.
/// </summary>
/// <seealso cref="FlaxEditor.CustomEditors.GUI.DraggablePropertyNameLabel" />
[HideInEditor]
public class ParameterPropertyNameLabel : DraggablePropertyNameLabel
{
private ParametersEditor _editor;
private IVisjectSurfaceWindow _window;
private Rectangle _arrangeButtonRect;
private bool _arrangeButtonInUse;
/// <inheritdoc />
public ParameterPropertyNameLabel(string name, ParametersEditor editor)
: base(name)
{
_editor = editor;
_window = _editor.Values[0] as IVisjectSurfaceWindow;
_arrangeButtonRect = new Rectangle(2, 3, 12, 12);
// Extend margin of the label to support a dragging handle
Margin m = Margin;
m.Left += 16;
Margin = m;
}
private bool ArrangeAreaCheck(out int index, out Rectangle rect)
{
var child = _editor.ChildrenEditors[0];
var container = child.Layout.ContainerControl;
var mousePosition = container.PointFromScreen(Input.MouseScreenPosition);
var barSidesExtend = 20.0f;
var barHeight = 5.0f;
var barCheckAreaHeight = 40.0f;
var pos = mousePosition.Y + barCheckAreaHeight * 0.5f;
for (int i = 0; i < container.Children.Count / 2; i++)
{
var containerChild = container.Children[i * 2]; // times 2 to skip the value editor
if (Mathf.IsInRange(pos, containerChild.Top, containerChild.Top + barCheckAreaHeight) || (i == 0 && pos < containerChild.Top))
{
index = i;
var p1 = containerChild.UpperLeft;
rect = new Rectangle(PointFromParent(p1) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
return true;
}
}
var p2 = container.Children[((container.Children.Count / 2) - 1) * 2].BottomLeft;
if (pos > p2.Y)
{
index = (container.Children.Count / 2) - 1;
rect = new Rectangle(PointFromParent(p2) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
return true;
}
index = -1;
rect = Rectangle.Empty;
return false;
}
/// <inheritdoc />
public override void Draw()
{
base.Draw();
var style = Style.Current;
var mousePosition = PointFromScreen(Input.MouseScreenPosition);
var dragBarColor = _arrangeButtonRect.Contains(mousePosition) ? style.Foreground : style.ForegroundGrey;
Render2D.DrawSprite(Editor.Instance.Icons.DragBar12, _arrangeButtonRect, _arrangeButtonInUse ? Color.Orange : dragBarColor);
if (_arrangeButtonInUse && ArrangeAreaCheck(out _, out var arrangeTargetRect))
{
Render2D.FillRectangle(arrangeTargetRect, style.Selection);
}
}
/// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button)
{
if (button == MouseButton.Left && _arrangeButtonRect.Contains(ref location))
{
_arrangeButtonInUse = true;
Focus();
StartMouseCapture();
return true;
}
return base.OnMouseDown(location, button);
}
/// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button)
{
if (button == MouseButton.Left && _arrangeButtonInUse)
{
_arrangeButtonInUse = false;
EndMouseCapture();
ArrangeAreaCheck(out var index, out _);
var action = new ReorderParamAction
{
OldIndex = (int)Tag,
NewIndex = index,
Window = _window,
Editor = _editor
};
action.Do();
_window.Undo.AddAction(action);
}
return base.OnMouseUp(location, button);
}
/// <inheritdoc />
public override void OnLostFocus()
{
if (_arrangeButtonInUse)
{
_arrangeButtonInUse = false;
EndMouseCapture();
}
base.OnLostFocus();
}
/// <inheritdoc />
protected override void OnSizeChanged()
{
base.OnSizeChanged();
// Center the drag button vertically
_arrangeButtonRect = new Rectangle(2, Mathf.Ceil((Height - 12) * 0.5f) + 1, 12, 12);
}
}
/// <summary> /// <summary>
/// Custom editor for editing Visject Surface parameters collection. /// Custom editor for editing Visject Surface parameters collection.
/// </summary> /// </summary>
@@ -431,10 +638,10 @@ namespace FlaxEditor.Surface
attributes attributes
); );
var propertyLabel = new DraggablePropertyNameLabel(name) var propertyLabel = new ParameterPropertyNameLabel(name, this)
{ {
Tag = pIndex, Tag = pIndex,
Drag = OnDragParameter Drag = OnDragParameter,
}; };
if (!p.IsPublic) if (!p.IsPublic)
propertyLabel.TextColor = propertyLabel.TextColor.RGBMultiplied(0.7f); propertyLabel.TextColor = propertyLabel.TextColor.RGBMultiplied(0.7f);

View File

@@ -187,6 +187,14 @@ namespace FlaxEditor.Surface
return Archetypes.Parameters.Nodes[2]; return Archetypes.Parameters.Nodes[2];
} }
/// <inheritdoc />
protected override bool TryGetParameterSetterNodeArchetype(out ushort groupId, out NodeArchetype archetype)
{
groupId = 6;
archetype = Archetypes.Parameters.Nodes[3];
return true;
}
/// <inheritdoc /> /// <inheritdoc />
protected override void OnShowPrimaryMenu(VisjectCM activeCM, Float2 location, Box startBox) protected override void OnShowPrimaryMenu(VisjectCM activeCM, Float2 location, Box startBox)
{ {

View File

@@ -82,7 +82,7 @@ namespace FlaxEditor.Tools.Foliage
} }
} }
[EditorOrder(20), EditorDisplay("Model"), Collection(ReadOnly = true), Tooltip("Model materials override collection. Can be used to change a specific material of the mesh to the custom one without editing the asset.")] [EditorOrder(20), EditorDisplay("Model"), Collection(CanResize = true), Tooltip("Model materials override collection. Can be used to change a specific material of the mesh to the custom one without editing the asset.")]
public MaterialBase[] Materials public MaterialBase[] Materials
{ {
get get

View File

@@ -36,7 +36,10 @@ namespace FlaxEditor.Utilities
public void GatherSceneData() public void GatherSceneData()
{ {
if (HasData) if (HasData)
throw new InvalidOperationException("DuplicateScenes has already gathered scene data."); {
Editor.LogError("DuplicateScenes has already gathered scene data.");
return;
}
Profiler.BeginEvent("DuplicateScenes.GatherSceneData"); Profiler.BeginEvent("DuplicateScenes.GatherSceneData");
Editor.Log("Collecting scene data"); Editor.Log("Collecting scene data");
@@ -47,7 +50,8 @@ namespace FlaxEditor.Utilities
if (scenesCount == 0) if (scenesCount == 0)
{ {
Profiler.EndEvent(); Profiler.EndEvent();
throw new InvalidOperationException("Cannot gather scene data. No scene loaded."); Editor.LogWarning("Cannot gather scene data. No scene loaded.");
return;
} }
var sceneIds = new Guid[scenesCount]; var sceneIds = new Guid[scenesCount];
for (int i = 0; i < scenesCount; i++) for (int i = 0; i < scenesCount; i++)
@@ -72,7 +76,8 @@ namespace FlaxEditor.Utilities
if (Level.UnloadAllScenes()) if (Level.UnloadAllScenes())
{ {
Profiler.EndEvent(); Profiler.EndEvent();
throw new Exception("Failed to unload scenes."); Editor.LogError("Failed to unload scenes.");
return;
} }
FlaxEngine.Scripting.FlushRemovedObjects(); FlaxEngine.Scripting.FlushRemovedObjects();
@@ -82,7 +87,8 @@ namespace FlaxEditor.Utilities
if (noScenes != null && noScenes.Length != 0) if (noScenes != null && noScenes.Length != 0)
{ {
Profiler.EndEvent(); Profiler.EndEvent();
throw new Exception("Failed to unload scenes."); Editor.LogError("Failed to unload scenes.");
return;
} }
} }
@@ -96,7 +102,10 @@ namespace FlaxEditor.Utilities
public void CreateScenes() public void CreateScenes()
{ {
if (!HasData) if (!HasData)
throw new InvalidOperationException("DuplicateScenes has not gathered scene data yet."); {
Editor.LogError("DuplicateScenes has not gathered scene data yet.");
return;
}
Profiler.BeginEvent("DuplicateScenes.CreateScenes"); Profiler.BeginEvent("DuplicateScenes.CreateScenes");
Editor.Log("Creating scenes"); Editor.Log("Creating scenes");
@@ -110,7 +119,8 @@ namespace FlaxEditor.Utilities
if (scene == null) if (scene == null)
{ {
Profiler.EndEvent(); Profiler.EndEvent();
throw new Exception("Failed to deserialize scene"); Editor.LogError("Failed to deserialize scene.");
return;
} }
} }
@@ -131,7 +141,8 @@ namespace FlaxEditor.Utilities
if (Level.UnloadAllScenes()) if (Level.UnloadAllScenes())
{ {
Profiler.EndEvent(); Profiler.EndEvent();
throw new Exception("Failed to unload scenes."); Editor.LogError("Failed to unload scenes.");
return;
} }
FlaxEngine.Scripting.FlushRemovedObjects(); FlaxEngine.Scripting.FlushRemovedObjects();
Editor.WipeOutLeftoverSceneObjects(); Editor.WipeOutLeftoverSceneObjects();
@@ -145,7 +156,10 @@ namespace FlaxEditor.Utilities
public void RestoreSceneData() public void RestoreSceneData()
{ {
if (!HasData) if (!HasData)
throw new InvalidOperationException("DuplicateScenes has not gathered scene data yet."); {
Editor.LogError("DuplicateScenes has not gathered scene data yet.");
return;
}
Profiler.BeginEvent("DuplicateScenes.RestoreSceneData"); Profiler.BeginEvent("DuplicateScenes.RestoreSceneData");
// Deserialize old scenes // Deserialize old scenes
@@ -155,8 +169,8 @@ namespace FlaxEditor.Utilities
var scene = Level.LoadSceneFromBytes(data.Bytes); var scene = Level.LoadSceneFromBytes(data.Bytes);
if (scene == null) if (scene == null)
{ {
Profiler.EndEvent(); Editor.LogError("Failed to restore scene");
throw new Exception("Failed to deserialize scene"); continue;
} }
// Restore `dirty` state // Restore `dirty` state

View File

@@ -1,131 +0,0 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#include "ScreenUtilities.h"
#include "Engine/Core/Math/Vector2.h"
#include "Engine/Core/Delegate.h"
#include "Engine/Core/Log.h"
#include "Engine/Profiler/ProfilerCPU.h"
Delegate<Color32> ScreenUtilities::PickColorDone;
#if PLATFORM_WINDOWS
#include <Windows.h>
#pragma comment(lib, "Gdi32.lib")
static HHOOK MouseCallbackHook;
LRESULT CALLBACK OnScreenUtilsMouseCallback(_In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
if (nCode >= 0 && wParam == WM_LBUTTONDOWN)
{
UnhookWindowsHookEx(MouseCallbackHook);
// Push event with the picked color
const Float2 cursorPos = Platform::GetMousePosition();
const Color32 colorPicked = ScreenUtilities::GetColorAt(cursorPos);
ScreenUtilities::PickColorDone(colorPicked);
return 1;
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
Color32 ScreenUtilities::GetColorAt(const Float2& pos)
{
PROFILE_CPU();
HDC deviceContext = GetDC(NULL);
COLORREF color = GetPixel(deviceContext, (int)pos.X, (int)pos.Y);
ReleaseDC(NULL, deviceContext);
return Color32(GetRValue(color), GetGValue(color), GetBValue(color), 255);
}
void ScreenUtilities::PickColor()
{
MouseCallbackHook = SetWindowsHookEx(WH_MOUSE_LL, OnScreenUtilsMouseCallback, NULL, NULL);
if (MouseCallbackHook == NULL)
{
LOG(Warning, "Failed to set mouse hook.");
LOG(Warning, "Error: {0}", GetLastError());
}
}
#elif PLATFORM_LINUX
#include "Engine/Platform/Linux/LinuxPlatform.h"
#include "Engine/Platform/Linux/IncludeX11.h"
Color32 ScreenUtilities::GetColorAt(const Float2& pos)
{
X11::XColor color;
X11::Display* display = (X11::Display*) LinuxPlatform::GetXDisplay();
int defaultScreen = X11::XDefaultScreen(display);
X11::XImage* image;
image = X11::XGetImage(display, X11::XRootWindow(display, defaultScreen), (int)pos.X, (int)pos.Y, 1, 1, AllPlanes, XYPixmap);
color.pixel = XGetPixel(image, 0, 0);
X11::XFree(image);
X11::XQueryColor(display, X11::XDefaultColormap(display, defaultScreen), &color);
Color32 outputColor;
outputColor.R = color.red / 256;
outputColor.G = color.green / 256;
outputColor.B = color.blue / 256;
outputColor.A = 255;
return outputColor;
}
void OnScreenUtilsXEventCallback(void* eventPtr)
{
X11::XEvent* event = (X11::XEvent*) eventPtr;
X11::Display* display = (X11::Display*)LinuxPlatform::GetXDisplay();
if (event->type == ButtonPress)
{
const Float2 cursorPos = Platform::GetMousePosition();
const Color32 colorPicked = ScreenUtilities::GetColorAt(cursorPos);
X11::XUngrabPointer(display, CurrentTime);
ScreenUtilities::PickColorDone(colorPicked);
LinuxPlatform::xEventRecieved.Unbind(OnScreenUtilsXEventCallback);
}
}
void ScreenUtilities::PickColor()
{
PROFILE_CPU();
X11::Display* display = (X11::Display*) LinuxPlatform::GetXDisplay();
X11::Window rootWindow = X11::XRootWindow(display, X11::XDefaultScreen(display));
X11::Cursor cursor = XCreateFontCursor(display, 130);
int grabbedPointer = X11::XGrabPointer(display, rootWindow, 0, ButtonPressMask, GrabModeAsync, GrabModeAsync, rootWindow, cursor, CurrentTime);
if (grabbedPointer != GrabSuccess)
{
LOG(Error, "Failed to grab cursor for events.");
X11::XFreeCursor(display, cursor);
return;
}
X11::XFreeCursor(display, cursor);
LinuxPlatform::xEventRecieved.Bind(OnScreenUtilsXEventCallback);
}
#elif PLATFORM_MAC
#include <Cocoa/Cocoa.h>
#include <AppKit/AppKit.h>
Color32 ScreenUtilities::GetColorAt(const Float2& pos)
{
// TODO: implement ScreenUtilities for macOS
return { 0, 0, 0, 255 };
}
void ScreenUtilities::PickColor()
{
// This is what C# calls to start the color picking sequence
// This should stop mouse clicks from working for one click, and that click is on the selected color
// There is a class called NSColorSample that might implement that for you, but maybe not.
}
#endif

View File

@@ -2,32 +2,4 @@
#pragma once #pragma once
#include "Engine/Core/Types/BaseTypes.h" #include "Engine/Platform/ScreenUtilities.h"
#include "Engine/Core/Math/Color32.h"
#include "Engine/Core/Math/Vector2.h"
#include "Engine/Core/Delegate.h"
/// <summary>
/// Platform-dependent screen utilities.
/// </summary>
API_CLASS(Static) class FLAXENGINE_API ScreenUtilities
{
DECLARE_SCRIPTING_TYPE_MINIMAL(ScreenUtilities);
/// <summary>
/// Gets the pixel color at the specified coordinates.
/// </summary>
/// <param name="pos">Screen-space coordinate to read.</param>
/// <returns>Pixel color at the specified coordinates.</returns>
API_FUNCTION() static Color32 GetColorAt(const Float2& pos);
/// <summary>
/// Starts async color picking. Color will be returned through PickColorDone event when the actions ends (user selected the final color with a mouse). When action is active, GetColorAt can be used to read the current value.
/// </summary>
API_FUNCTION() static void PickColor();
/// <summary>
/// Called when PickColor action is finished.
/// </summary>
API_EVENT() static Delegate<Color32> PickColorDone;
};

View File

@@ -137,19 +137,19 @@ namespace FlaxEditor.Viewport
if (useProjectCache) if (useProjectCache)
{ {
// Initialize snapping enabled from cached values // Initialize snapping enabled from cached values
if (editor.ProjectCache.TryGetCustomData("TranslateSnapState", out var cachedState)) if (editor.ProjectCache.TryGetCustomData("TranslateSnapState", out bool cachedBool))
transformGizmo.TranslationSnapEnable = bool.Parse(cachedState); transformGizmo.TranslationSnapEnable = cachedBool;
if (editor.ProjectCache.TryGetCustomData("RotationSnapState", out cachedState)) if (editor.ProjectCache.TryGetCustomData("RotationSnapState", out cachedBool))
transformGizmo.RotationSnapEnabled = bool.Parse(cachedState); transformGizmo.RotationSnapEnabled = cachedBool;
if (editor.ProjectCache.TryGetCustomData("ScaleSnapState", out cachedState)) if (editor.ProjectCache.TryGetCustomData("ScaleSnapState", out cachedBool))
transformGizmo.ScaleSnapEnabled = bool.Parse(cachedState); transformGizmo.ScaleSnapEnabled = cachedBool;
if (editor.ProjectCache.TryGetCustomData("TranslateSnapValue", out cachedState)) if (editor.ProjectCache.TryGetCustomData("TranslateSnapValue", out float cachedFloat))
transformGizmo.TranslationSnapValue = float.Parse(cachedState); transformGizmo.TranslationSnapValue = cachedFloat;
if (editor.ProjectCache.TryGetCustomData("RotationSnapValue", out cachedState)) if (editor.ProjectCache.TryGetCustomData("RotationSnapValue", out cachedFloat))
transformGizmo.RotationSnapValue = float.Parse(cachedState); transformGizmo.RotationSnapValue = cachedFloat;
if (editor.ProjectCache.TryGetCustomData("ScaleSnapValue", out cachedState)) if (editor.ProjectCache.TryGetCustomData("ScaleSnapValue", out cachedFloat))
transformGizmo.ScaleSnapValue = float.Parse(cachedState); transformGizmo.ScaleSnapValue = cachedFloat;
if (editor.ProjectCache.TryGetCustomData("TransformSpaceState", out cachedState) && Enum.TryParse(cachedState, out TransformGizmoBase.TransformSpace space)) if (editor.ProjectCache.TryGetCustomData("TransformSpaceState", out string cachedText) && Enum.TryParse(cachedText, out TransformGizmoBase.TransformSpace space))
transformGizmo.ActiveTransformSpace = space; transformGizmo.ActiveTransformSpace = space;
} }
@@ -181,7 +181,7 @@ namespace FlaxEditor.Viewport
{ {
transformGizmo.ScaleSnapEnabled = !transformGizmo.ScaleSnapEnabled; transformGizmo.ScaleSnapEnabled = !transformGizmo.ScaleSnapEnabled;
if (useProjectCache) if (useProjectCache)
editor.ProjectCache.SetCustomData("ScaleSnapState", transformGizmo.ScaleSnapEnabled.ToString()); editor.ProjectCache.SetCustomData("ScaleSnapState", transformGizmo.ScaleSnapEnabled);
}; };
var scaleSnappingCM = new ContextMenu(); var scaleSnappingCM = new ContextMenu();
var scaleSnapping = new ViewportWidgetButton(transformGizmo.ScaleSnapValue.ToString(), SpriteHandle.Invalid, scaleSnappingCM) var scaleSnapping = new ViewportWidgetButton(transformGizmo.ScaleSnapValue.ToString(), SpriteHandle.Invalid, scaleSnappingCM)
@@ -200,7 +200,7 @@ namespace FlaxEditor.Viewport
transformGizmo.ScaleSnapValue = v; transformGizmo.ScaleSnapValue = v;
scaleSnapping.Text = v.ToString(); scaleSnapping.Text = v.ToString();
if (useProjectCache) if (useProjectCache)
editor.ProjectCache.SetCustomData("ScaleSnapValue", transformGizmo.ScaleSnapValue.ToString("N")); editor.ProjectCache.SetCustomData("ScaleSnapValue", transformGizmo.ScaleSnapValue);
}; };
scaleSnappingCM.VisibleChanged += control => scaleSnappingCM.VisibleChanged += control =>
{ {
@@ -231,7 +231,7 @@ namespace FlaxEditor.Viewport
{ {
transformGizmo.RotationSnapEnabled = !transformGizmo.RotationSnapEnabled; transformGizmo.RotationSnapEnabled = !transformGizmo.RotationSnapEnabled;
if (useProjectCache) if (useProjectCache)
editor.ProjectCache.SetCustomData("RotationSnapState", transformGizmo.RotationSnapEnabled.ToString()); editor.ProjectCache.SetCustomData("RotationSnapState", transformGizmo.RotationSnapEnabled);
}; };
var rotateSnappingCM = new ContextMenu(); var rotateSnappingCM = new ContextMenu();
var rotateSnapping = new ViewportWidgetButton(transformGizmo.RotationSnapValue.ToString(), SpriteHandle.Invalid, rotateSnappingCM) var rotateSnapping = new ViewportWidgetButton(transformGizmo.RotationSnapValue.ToString(), SpriteHandle.Invalid, rotateSnappingCM)
@@ -250,7 +250,7 @@ namespace FlaxEditor.Viewport
transformGizmo.RotationSnapValue = v; transformGizmo.RotationSnapValue = v;
rotateSnapping.Text = v.ToString(); rotateSnapping.Text = v.ToString();
if (useProjectCache) if (useProjectCache)
editor.ProjectCache.SetCustomData("RotationSnapValue", transformGizmo.RotationSnapValue.ToString("N")); editor.ProjectCache.SetCustomData("RotationSnapValue", transformGizmo.RotationSnapValue);
}; };
rotateSnappingCM.VisibleChanged += control => rotateSnappingCM.VisibleChanged += control =>
{ {
@@ -281,7 +281,7 @@ namespace FlaxEditor.Viewport
{ {
transformGizmo.TranslationSnapEnable = !transformGizmo.TranslationSnapEnable; transformGizmo.TranslationSnapEnable = !transformGizmo.TranslationSnapEnable;
if (useProjectCache) if (useProjectCache)
editor.ProjectCache.SetCustomData("TranslateSnapState", transformGizmo.TranslationSnapEnable.ToString()); editor.ProjectCache.SetCustomData("TranslateSnapState", transformGizmo.TranslationSnapEnable);
}; };
var translateSnappingCM = new ContextMenu(); var translateSnappingCM = new ContextMenu();
var translateSnapping = new ViewportWidgetButton(transformGizmo.TranslationSnapValue.ToString(), SpriteHandle.Invalid, translateSnappingCM) var translateSnapping = new ViewportWidgetButton(transformGizmo.TranslationSnapValue.ToString(), SpriteHandle.Invalid, translateSnappingCM)
@@ -307,7 +307,7 @@ namespace FlaxEditor.Viewport
else else
translateSnapping.Text = v.ToString(); translateSnapping.Text = v.ToString();
if (useProjectCache) if (useProjectCache)
editor.ProjectCache.SetCustomData("TranslateSnapValue", transformGizmo.TranslationSnapValue.ToString("N")); editor.ProjectCache.SetCustomData("TranslateSnapValue", transformGizmo.TranslationSnapValue);
}; };
translateSnappingCM.VisibleChanged += control => translateSnappingCM.VisibleChanged += control =>
{ {
@@ -360,11 +360,36 @@ namespace FlaxEditor.Viewport
}; };
// Setup input actions // Setup input actions
viewport.InputActions.Add(options => options.TranslateMode, () => transformGizmo.ActiveMode = TransformGizmoBase.Mode.Translate); viewport.InputActions.Add(options => options.TranslateMode, () =>
viewport.InputActions.Add(options => options.RotateMode, () => transformGizmo.ActiveMode = TransformGizmoBase.Mode.Rotate); {
viewport.InputActions.Add(options => options.ScaleMode, () => transformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale); viewport.GetInput(out var input);
if (input.IsMouseRightDown)
return;
transformGizmo.ActiveMode = TransformGizmoBase.Mode.Translate;
});
viewport.InputActions.Add(options => options.RotateMode, () =>
{
viewport.GetInput(out var input);
if (input.IsMouseRightDown)
return;
transformGizmo.ActiveMode = TransformGizmoBase.Mode.Rotate;
});
viewport.InputActions.Add(options => options.ScaleMode, () =>
{
viewport.GetInput(out var input);
if (input.IsMouseRightDown)
return;
transformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale;
});
viewport.InputActions.Add(options => options.ToggleTransformSpace, () => viewport.InputActions.Add(options => options.ToggleTransformSpace, () =>
{ {
viewport.GetInput(out var input);
if (input.IsMouseRightDown)
return;
transformGizmo.ToggleTransformSpace(); transformGizmo.ToggleTransformSpace();
if (useProjectCache) if (useProjectCache)
editor.ProjectCache.SetCustomData("TransformSpaceState", transformGizmo.ActiveTransformSpace.ToString()); editor.ProjectCache.SetCustomData("TransformSpaceState", transformGizmo.ActiveTransformSpace.ToString());

View File

@@ -155,18 +155,22 @@ namespace FlaxEditor.Viewport
private float _movementSpeed; private float _movementSpeed;
private float _minMovementSpeed; private float _minMovementSpeed;
private float _maxMovementSpeed; private float _maxMovementSpeed;
#if !PLATFORM_SDL
private float _mouseAccelerationScale; private float _mouseAccelerationScale;
private bool _useMouseFiltering; private bool _useMouseFiltering;
private bool _useMouseAcceleration; private bool _useMouseAcceleration;
#endif
// Input // Input
internal bool _disableInputUpdate; internal bool _disableInputUpdate;
private bool _isControllingMouse, _isViewportControllingMouse, _wasVirtualMouseRightDown, _isVirtualMouseRightDown; private bool _isControllingMouse, _isViewportControllingMouse, _wasVirtualMouseRightDown, _isVirtualMouseRightDown;
private int _deltaFilteringStep;
private Float2 _startPos; private Float2 _startPos;
#if !PLATFORM_SDL
private Float2 _mouseDeltaLast; private Float2 _mouseDeltaLast;
private int _deltaFilteringStep;
private Float2[] _deltaFilteringBuffer = new Float2[FpsCameraFilteringFrames]; private Float2[] _deltaFilteringBuffer = new Float2[FpsCameraFilteringFrames];
#endif
/// <summary> /// <summary>
/// The previous input (from the previous update). /// The previous input (from the previous update).
@@ -522,10 +526,11 @@ namespace FlaxEditor.Viewport
: base(task) : base(task)
{ {
_editor = Editor.Instance; _editor = Editor.Instance;
#if !PLATFORM_SDL
_mouseAccelerationScale = 0.1f; _mouseAccelerationScale = 0.1f;
_useMouseFiltering = false; _useMouseFiltering = false;
_useMouseAcceleration = false; _useMouseAcceleration = false;
#endif
_camera = camera; _camera = camera;
if (_camera != null) if (_camera != null)
_camera.Viewport = this; _camera.Viewport = this;
@@ -540,30 +545,30 @@ namespace FlaxEditor.Viewport
} }
// Initialize camera values from cache // Initialize camera values from cache
if (_editor.ProjectCache.TryGetCustomData("CameraMovementSpeedValue", out var cachedState)) if (_editor.ProjectCache.TryGetCustomData("CameraMovementSpeedValue", out float cachedFloat))
MovementSpeed = float.Parse(cachedState); MovementSpeed = cachedFloat;
if (_editor.ProjectCache.TryGetCustomData("CameraMinMovementSpeedValue", out cachedState)) if (_editor.ProjectCache.TryGetCustomData("CameraMinMovementSpeedValue", out cachedFloat))
_minMovementSpeed = float.Parse(cachedState); _minMovementSpeed = cachedFloat;
if (_editor.ProjectCache.TryGetCustomData("CameraMaxMovementSpeedValue", out cachedState)) if (_editor.ProjectCache.TryGetCustomData("CameraMaxMovementSpeedValue", out cachedFloat))
_maxMovementSpeed = float.Parse(cachedState); _maxMovementSpeed = cachedFloat;
if (_editor.ProjectCache.TryGetCustomData("UseCameraEasingState", out cachedState)) if (_editor.ProjectCache.TryGetCustomData("UseCameraEasingState", out bool cachedBool))
_useCameraEasing = bool.Parse(cachedState); _useCameraEasing = cachedBool;
if (_editor.ProjectCache.TryGetCustomData("CameraPanningSpeedValue", out cachedState)) if (_editor.ProjectCache.TryGetCustomData("CameraPanningSpeedValue", out cachedFloat))
_panningSpeed = float.Parse(cachedState); _panningSpeed = cachedFloat;
if (_editor.ProjectCache.TryGetCustomData("CameraInvertPanningState", out cachedState)) if (_editor.ProjectCache.TryGetCustomData("CameraInvertPanningState", out cachedBool))
_invertPanning = bool.Parse(cachedState); _invertPanning = cachedBool;
if (_editor.ProjectCache.TryGetCustomData("CameraRelativePanningState", out cachedState)) if (_editor.ProjectCache.TryGetCustomData("CameraRelativePanningState", out cachedBool))
_relativePanning = bool.Parse(cachedState); _relativePanning = cachedBool;
if (_editor.ProjectCache.TryGetCustomData("CameraOrthographicState", out cachedState)) if (_editor.ProjectCache.TryGetCustomData("CameraOrthographicState", out cachedBool))
_isOrtho = bool.Parse(cachedState); _isOrtho = cachedBool;
if (_editor.ProjectCache.TryGetCustomData("CameraOrthographicSizeValue", out cachedState)) if (_editor.ProjectCache.TryGetCustomData("CameraOrthographicSizeValue", out cachedFloat))
_orthoSize = float.Parse(cachedState); _orthoSize = cachedFloat;
if (_editor.ProjectCache.TryGetCustomData("CameraFieldOfViewValue", out cachedState)) if (_editor.ProjectCache.TryGetCustomData("CameraFieldOfViewValue", out cachedFloat))
_fieldOfView = float.Parse(cachedState); _fieldOfView = cachedFloat;
if (_editor.ProjectCache.TryGetCustomData("CameraNearPlaneValue", out cachedState)) if (_editor.ProjectCache.TryGetCustomData("CameraNearPlaneValue", out cachedFloat))
_nearPlane = float.Parse(cachedState); _nearPlane = cachedFloat;
if (_editor.ProjectCache.TryGetCustomData("CameraFarPlaneValue", out cachedState)) if (_editor.ProjectCache.TryGetCustomData("CameraFarPlaneValue", out cachedFloat))
_farPlane = float.Parse(cachedState); _farPlane = cachedFloat;
OnCameraMovementProgressChanged(); OnCameraMovementProgressChanged();
@@ -1041,7 +1046,7 @@ namespace FlaxEditor.Viewport
MovementSpeed = value; MovementSpeed = value;
OnCameraMovementProgressChanged(); OnCameraMovementProgressChanged();
_editor.ProjectCache.SetCustomData("CameraMovementSpeedValue", _movementSpeed.ToString()); _editor.ProjectCache.SetCustomData("CameraMovementSpeedValue", _movementSpeed);
} }
private void OnMinMovementSpeedChanged(FloatValueBox control) private void OnMinMovementSpeedChanged(FloatValueBox control)
@@ -1053,7 +1058,7 @@ namespace FlaxEditor.Viewport
MovementSpeed = value; MovementSpeed = value;
OnCameraMovementProgressChanged(); OnCameraMovementProgressChanged();
_editor.ProjectCache.SetCustomData("CameraMinMovementSpeedValue", _minMovementSpeed.ToString()); _editor.ProjectCache.SetCustomData("CameraMinMovementSpeedValue", _minMovementSpeed);
} }
private void OnMaxMovementSpeedChanged(FloatValueBox control) private void OnMaxMovementSpeedChanged(FloatValueBox control)
@@ -1065,7 +1070,7 @@ namespace FlaxEditor.Viewport
MovementSpeed = value; MovementSpeed = value;
OnCameraMovementProgressChanged(); OnCameraMovementProgressChanged();
_editor.ProjectCache.SetCustomData("CameraMaxMovementSpeedValue", _maxMovementSpeed.ToString()); _editor.ProjectCache.SetCustomData("CameraMaxMovementSpeedValue", _maxMovementSpeed);
} }
private void OnCameraEasingToggled(Control control) private void OnCameraEasingToggled(Control control)
@@ -1073,25 +1078,25 @@ namespace FlaxEditor.Viewport
_useCameraEasing = !_useCameraEasing; _useCameraEasing = !_useCameraEasing;
OnCameraMovementProgressChanged(); OnCameraMovementProgressChanged();
_editor.ProjectCache.SetCustomData("UseCameraEasingState", _useCameraEasing.ToString()); _editor.ProjectCache.SetCustomData("UseCameraEasingState", _useCameraEasing);
} }
private void OnPanningSpeedChanged(FloatValueBox control) private void OnPanningSpeedChanged(FloatValueBox control)
{ {
_panningSpeed = control.Value; _panningSpeed = control.Value;
_editor.ProjectCache.SetCustomData("CameraPanningSpeedValue", _panningSpeed.ToString()); _editor.ProjectCache.SetCustomData("CameraPanningSpeedValue", _panningSpeed);
} }
private void OnRelativePanningToggled(Control control) private void OnRelativePanningToggled(Control control)
{ {
_relativePanning = !_relativePanning; _relativePanning = !_relativePanning;
_editor.ProjectCache.SetCustomData("CameraRelativePanningState", _relativePanning.ToString()); _editor.ProjectCache.SetCustomData("CameraRelativePanningState", _relativePanning);
} }
private void OnInvertPanningToggled(Control control) private void OnInvertPanningToggled(Control control)
{ {
_invertPanning = !_invertPanning; _invertPanning = !_invertPanning;
_editor.ProjectCache.SetCustomData("CameraInvertPanningState", _invertPanning.ToString()); _editor.ProjectCache.SetCustomData("CameraInvertPanningState", _invertPanning);
} }
@@ -1104,7 +1109,7 @@ namespace FlaxEditor.Viewport
private void OnFieldOfViewChanged(FloatValueBox control) private void OnFieldOfViewChanged(FloatValueBox control)
{ {
_fieldOfView = control.Value; _fieldOfView = control.Value;
_editor.ProjectCache.SetCustomData("CameraFieldOfViewValue", _fieldOfView.ToString()); _editor.ProjectCache.SetCustomData("CameraFieldOfViewValue", _fieldOfView);
} }
private void OnOrthographicModeToggled(Control control) private void OnOrthographicModeToggled(Control control)
@@ -1120,25 +1125,25 @@ namespace FlaxEditor.Viewport
OrientViewport(ref orient); OrientViewport(ref orient);
} }
_editor.ProjectCache.SetCustomData("CameraOrthographicState", _isOrtho.ToString()); _editor.ProjectCache.SetCustomData("CameraOrthographicState", _isOrtho);
} }
private void OnOrthographicSizeChanged(FloatValueBox control) private void OnOrthographicSizeChanged(FloatValueBox control)
{ {
_orthoSize = control.Value; _orthoSize = control.Value;
_editor.ProjectCache.SetCustomData("CameraOrthographicSizeValue", _orthoSize.ToString()); _editor.ProjectCache.SetCustomData("CameraOrthographicSizeValue", _orthoSize);
} }
private void OnNearPlaneChanged(FloatValueBox control) private void OnNearPlaneChanged(FloatValueBox control)
{ {
_nearPlane = control.Value; _nearPlane = control.Value;
_editor.ProjectCache.SetCustomData("CameraNearPlaneValue", _nearPlane.ToString()); _editor.ProjectCache.SetCustomData("CameraNearPlaneValue", _nearPlane);
} }
private void OnFarPlaneChanged(FloatValueBox control) private void OnFarPlaneChanged(FloatValueBox control)
{ {
_farPlane = control.Value; _farPlane = control.Value;
_editor.ProjectCache.SetCustomData("CameraFarPlaneValue", _farPlane.ToString()); _editor.ProjectCache.SetCustomData("CameraFarPlaneValue", _farPlane);
} }
/// <summary> /// <summary>
@@ -1217,7 +1222,7 @@ namespace FlaxEditor.Viewport
var speed = Mathf.Lerp(_minMovementSpeed, _maxMovementSpeed, progress); var speed = Mathf.Lerp(_minMovementSpeed, _maxMovementSpeed, progress);
MovementSpeed = (float)Math.Round(speed, 3); MovementSpeed = (float)Math.Round(speed, 3);
_editor.ProjectCache.SetCustomData("CameraMovementSpeedValue", _movementSpeed.ToString()); _editor.ProjectCache.SetCustomData("CameraMovementSpeedValue", _movementSpeed);
} }
private void OnEditorOptionsChanged(EditorOptions options) private void OnEditorOptionsChanged(EditorOptions options)
@@ -1420,7 +1425,9 @@ namespace FlaxEditor.Viewport
// Hide cursor and start tracking mouse movement // Hide cursor and start tracking mouse movement
win.StartTrackingMouse(false); win.StartTrackingMouse(false);
win.Cursor = CursorType.Hidden; win.Cursor = CursorType.Hidden;
win.MouseMoveRelative += OnMouseMoveRelative;
#if !PLATFORM_SDL
// Center mouse position if it's too close to the edge // Center mouse position if it's too close to the edge
var size = Size; var size = Size;
var center = Float2.Round(size * 0.5f); var center = Float2.Round(size * 0.5f);
@@ -1429,6 +1436,7 @@ namespace FlaxEditor.Viewport
_viewMousePos = center; _viewMousePos = center;
win.MousePosition = PointToWindow(_viewMousePos); win.MousePosition = PointToWindow(_viewMousePos);
} }
#endif
} }
/// <summary> /// <summary>
@@ -1440,6 +1448,7 @@ namespace FlaxEditor.Viewport
// Restore cursor and stop tracking mouse movement // Restore cursor and stop tracking mouse movement
win.Cursor = CursorType.Default; win.Cursor = CursorType.Default;
win.EndTrackingMouse(); win.EndTrackingMouse();
win.MouseMoveRelative -= OnMouseMoveRelative;
} }
/// <summary> /// <summary>
@@ -1544,6 +1553,14 @@ namespace FlaxEditor.Viewport
else else
EndMouseCapture(); EndMouseCapture();
} }
#if PLATFORM_SDL
bool useMouse = IsControllingMouse || true;
_prevInput = _input;
if (canUseInput && ContainsFocus)
_input.Gather(win.Window, useMouse, ref _prevInput);
else
_input.Clear();
#else
bool useMouse = IsControllingMouse || (Mathf.IsInRange(_viewMousePos.X, 0, Width) && Mathf.IsInRange(_viewMousePos.Y, 0, Height)); bool useMouse = IsControllingMouse || (Mathf.IsInRange(_viewMousePos.X, 0, Width) && Mathf.IsInRange(_viewMousePos.Y, 0, Height));
_prevInput = _input; _prevInput = _input;
var hit = GetChildAt(_viewMousePos, c => c.Visible && !(c is CanvasRootControl) && !(c is UIEditorRoot)); var hit = GetChildAt(_viewMousePos, c => c.Visible && !(c is CanvasRootControl) && !(c is UIEditorRoot));
@@ -1551,6 +1568,7 @@ namespace FlaxEditor.Viewport
_input.Gather(win.Window, useMouse, ref _prevInput); _input.Gather(win.Window, useMouse, ref _prevInput);
else else
_input.Clear(); _input.Clear();
#endif
// Track controlling mouse state change // Track controlling mouse state change
bool wasControllingMouse = _prevInput.IsControllingMouse; bool wasControllingMouse = _prevInput.IsControllingMouse;
@@ -1659,6 +1677,10 @@ namespace FlaxEditor.Viewport
if (_input.IsControlDown) if (_input.IsControlDown)
moveDelta *= 0.3f; moveDelta *= 0.3f;
#if PLATFORM_SDL
var mouseDelta = _mouseDelta;
_mouseDelta = Float2.Zero;
#else
// Calculate smooth mouse delta not dependant on viewport size // Calculate smooth mouse delta not dependant on viewport size
var offset = _viewMousePos - _startPos; var offset = _viewMousePos - _startPos;
if (_input.IsZooming && !_input.IsMouseRightDown && !_input.IsMouseLeftDown && !_input.IsMouseMiddleDown && !_isOrtho && !rmbWheel && !_isVirtualMouseRightDown) if (_input.IsZooming && !_input.IsMouseRightDown && !_input.IsMouseLeftDown && !_input.IsMouseMiddleDown && !_isOrtho && !rmbWheel && !_isVirtualMouseRightDown)
@@ -1700,18 +1722,21 @@ namespace FlaxEditor.Viewport
mouseDelta += _mouseDeltaLast * _mouseAccelerationScale; mouseDelta += _mouseDeltaLast * _mouseAccelerationScale;
_mouseDeltaLast = currentDelta; _mouseDeltaLast = currentDelta;
} }
#endif
// Update // Update
moveDelta *= dt * (60.0f * 4.0f); moveDelta *= dt * (60.0f * 4.0f);
mouseDelta *= 0.1833f * MouseSpeed * _mouseSensitivity; mouseDelta *= 0.1833f * MouseSpeed * _mouseSensitivity;
UpdateView(dt, ref moveDelta, ref mouseDelta, out var centerMouse); UpdateView(dt, ref moveDelta, ref mouseDelta, out var centerMouse);
#if !PLATFORM_SDL
// Move mouse back to the root position // Move mouse back to the root position
if (centerMouse && (_input.IsMouseRightDown || _input.IsMouseLeftDown || _input.IsMouseMiddleDown || _isVirtualMouseRightDown)) if (centerMouse && (_input.IsMouseRightDown || _input.IsMouseLeftDown || _input.IsMouseMiddleDown || _isVirtualMouseRightDown))
{ {
var center = PointToWindow(_startPos); var center = PointToWindow(_startPos);
win.MousePosition = center; win.MousePosition = center;
} }
#endif
// Change Ortho size on mouse scroll // Change Ortho size on mouse scroll
if (_isOrtho && !rmbWheel) if (_isOrtho && !rmbWheel)
@@ -1723,6 +1748,8 @@ namespace FlaxEditor.Viewport
} }
else else
{ {
#if PLATFORM_SDL
#else
if (_input.IsMouseLeftDown || _input.IsMouseRightDown || _isVirtualMouseRightDown) if (_input.IsMouseLeftDown || _input.IsMouseRightDown || _isVirtualMouseRightDown)
{ {
// Calculate smooth mouse delta not dependant on viewport size // Calculate smooth mouse delta not dependant on viewport size
@@ -1737,6 +1764,7 @@ namespace FlaxEditor.Viewport
_mouseDelta = Float2.Zero; _mouseDelta = Float2.Zero;
} }
_mouseDeltaLast = Float2.Zero; _mouseDeltaLast = Float2.Zero;
#endif
if (ContainsFocus) if (ContainsFocus)
{ {
@@ -1786,6 +1814,12 @@ namespace FlaxEditor.Viewport
_input.MouseWheelDelta = 0; _input.MouseWheelDelta = 0;
} }
/// <inheritdoc />
public void OnMouseMoveRelative(ref Float2 mouseMotion)
{
_mouseDelta += mouseMotion;
}
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button) public override bool OnMouseDown(Float2 location, MouseButton button)
{ {

View File

@@ -351,6 +351,8 @@ namespace FlaxEditor.Viewport
private void OnCollectDrawCalls(ref RenderContext renderContext) private void OnCollectDrawCalls(ref RenderContext renderContext)
{ {
if (renderContext.View.Pass == DrawPass.Depth)
return;
DragHandlers.CollectDrawCalls(_debugDrawData, ref renderContext); DragHandlers.CollectDrawCalls(_debugDrawData, ref renderContext);
if (ShowNavigation) if (ShowNavigation)
Editor.Internal_DrawNavMesh(); Editor.Internal_DrawNavMesh();
@@ -620,12 +622,12 @@ namespace FlaxEditor.Viewport
private static bool ValidateDragActorType(ScriptType actorType) private static bool ValidateDragActorType(ScriptType actorType)
{ {
return Level.IsAnySceneLoaded; return Level.IsAnySceneLoaded && Editor.Instance.CodeEditing.Actors.Get().Contains(actorType);
} }
private static bool ValidateDragScriptItem(ScriptItem script) private static bool ValidateDragScriptItem(ScriptItem script)
{ {
return Editor.Instance.CodeEditing.Actors.Get(script) != ScriptType.Null; return Level.IsAnySceneLoaded && Editor.Instance.CodeEditing.Actors.Get(script) != ScriptType.Null;
} }
/// <inheritdoc /> /// <inheritdoc />

Some files were not shown because too many files have changed in this diff Show More