Merge branch 'save-editor-window-docking' of https://github.com/MineBill/FlaxEngine into MineBill-save-editor-window-docking

This commit is contained in:
Wojtek Figat
2024-01-04 11:23:28 +01:00
15 changed files with 139 additions and 37 deletions

View File

@@ -133,6 +133,8 @@ void PS_Forward(
// Add lighting (apply ambient occlusion)
output.rgb += light.rgb * gBuffer.AO;
#endif
#if USE_FOG
// Calculate exponential height fog
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, 0);
@@ -148,7 +150,5 @@ void PS_Forward(
output = float4(lerp(float3(1, 1, 1), output.rgb, fog.aaa * fog.aaa), output.a);
#endif
#endif
#endif
}

View File

@@ -1,9 +1,9 @@
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using FlaxEditor.CustomEditors;
using FlaxEditor.GUI.Docking;
using FlaxEditor.Windows;
using FlaxEngine.GUI;
using DockState = FlaxEditor.GUI.Docking.DockState;
namespace FlaxEditor
{
@@ -97,9 +97,12 @@ namespace FlaxEditor
/// Shows the window.
/// </summary>
/// <param name="state">Initial window state.</param>
public void Show(DockState state = DockState.Float)
/// <param name="toDock">The panel to dock to, if any.</param>
/// <param name="autoSelect">Only used if <paramref name="toDock"/> is set. If true the window will be selected after docking it.</param>
/// <param name="splitterValue">The splitter value to use if toDock is not null. If not specified, a default value will be used.</param>
public void Show(DockState state = DockState.Float, DockPanel toDock = null, bool autoSelect = true, float? splitterValue = null)
{
_win.Show(state);
_win.Show(state, toDock, autoSelect, splitterValue);
}
}
}

View File

@@ -3,6 +3,7 @@
using System.Linq;
using FlaxEditor.CustomEditors.Elements;
using FlaxEditor.GUI.Dialogs;
using FlaxEditor.GUI.Input;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -17,6 +18,7 @@ namespace FlaxEditor.CustomEditors.Editors
private FloatValueElement _yElement;
private FloatValueElement _zElement;
private FloatValueElement _wElement;
private ColorValueBox _colorBox;
private CustomElement<ColorSelector> _trackball;
/// <inheritdoc />
@@ -53,7 +55,7 @@ namespace FlaxEditor.CustomEditors.Editors
gridControl.SlotPadding = new Margin(4, 2, 2, 2);
gridControl.ClipChildren = false;
gridControl.SlotsHorizontally = 1;
gridControl.SlotsVertically = 4;
gridControl.SlotsVertically = 5;
LimitAttribute limit = null;
var attributes = Values.GetAttributes();
@@ -61,7 +63,8 @@ namespace FlaxEditor.CustomEditors.Editors
{
limit = (LimitAttribute)attributes.FirstOrDefault(x => x is LimitAttribute);
}
_colorBox = grid.Custom<ColorValueBox>().CustomControl;
_colorBox.ValueChanged += OnColorBoxChanged;
_xElement = CreateFloatEditor(grid, limit, Color.Red);
_yElement = CreateFloatEditor(grid, limit, Color.Green);
_zElement = CreateFloatEditor(grid, limit, Color.Blue);
@@ -93,6 +96,13 @@ namespace FlaxEditor.CustomEditors.Editors
SetValue(value, token);
}
private void OnColorBoxChanged()
{
var token = _colorBox.IsSliding ? this : null;
var color = _colorBox.Value;
SetValue(new Float4(color.R, color.G, color.B, color.A), token);
}
private void OnValueChanged()
{
if (IsSetBlocked)
@@ -130,6 +140,7 @@ namespace FlaxEditor.CustomEditors.Editors
_yElement.Value = color.Y;
_zElement.Value = color.Z;
_wElement.Value = scale;
_colorBox.Value = new Color(color.X, color.Y, color.Z, scale);
_trackball.CustomControl.Color = Float3.Abs(color);
}
}

View File

@@ -518,9 +518,9 @@ namespace FlaxEditor.GUI.Docking
}
}
internal virtual void DockWindowInternal(DockState state, DockWindow window)
internal virtual void DockWindowInternal(DockState state, DockWindow window, bool autoSelect = true, float? splitterValue = null)
{
DockWindow(state, window);
DockWindow(state, window, autoSelect, splitterValue);
}
/// <summary>
@@ -528,7 +528,9 @@ namespace FlaxEditor.GUI.Docking
/// </summary>
/// <param name="state">The state.</param>
/// <param name="window">The window.</param>
protected virtual void DockWindow(DockState state, DockWindow window)
/// <param name="autoSelect">Whether or not to automatically select the window after docking it.</param>
/// <param name="splitterValue">The splitter value to use when docking to window.</param>
protected virtual void DockWindow(DockState state, DockWindow window, bool autoSelect = true, float? splitterValue = null)
{
CreateTabsProxy();
@@ -536,12 +538,12 @@ namespace FlaxEditor.GUI.Docking
if (state == DockState.DockFill)
{
// Add tab
AddTab(window);
AddTab(window, autoSelect);
}
else
{
// Create child panel
var dockPanel = CreateChildPanel(state, DefaultSplitterValue);
var dockPanel = CreateChildPanel(state, splitterValue ?? DefaultSplitterValue);
// Dock window as a tab in a child panel
dockPanel.DockWindow(DockState.DockFill, window);

View File

@@ -63,12 +63,9 @@ namespace FlaxEditor.GUI.Docking
public bool IsHidden => !Visible || _dockedTo == null;
/// <summary>
/// Gets the default window size.
/// Gets the default window size (in UI units, unscaled by DPI which is handled by windowing system).
/// </summary>
/// <remarks>
/// Scaled by the DPI, because the window should be large enough for its content on every monitor
/// </remarks>
public virtual Float2 DefaultSize => new Float2(900, 580) * DpiScale;
public virtual Float2 DefaultSize => new Float2(900, 580);
/// <summary>
/// Gets the serialization typename.
@@ -217,7 +214,9 @@ namespace FlaxEditor.GUI.Docking
/// </summary>
/// <param name="state">Initial window state.</param>
/// <param name="toDock">Panel to dock to it.</param>
public void Show(DockState state = DockState.Float, DockPanel toDock = null)
/// <param name="autoSelect">Only used if <paramref name="toDock"/> is set. If true the window will be selected after docking it.</param>
/// <param name="splitterValue">Only used if <paramref name="toDock"/> is set. The splitter value to use. If not specified, a default value will be used.</param>
public void Show(DockState state = DockState.Float, DockPanel toDock = null, bool autoSelect = true, float? splitterValue = null)
{
if (state == DockState.Hidden)
{
@@ -235,7 +234,7 @@ namespace FlaxEditor.GUI.Docking
Undock();
// Then dock
(toDock ?? _masterPanel).DockWindowInternal(state, this);
(toDock ?? _masterPanel).DockWindowInternal(state, this, autoSelect, splitterValue);
OnShow();
PerformLayout();
}

View File

@@ -24,6 +24,11 @@ namespace FlaxEditor.GUI
/// </summary>
public object[] Values { get; set; }
/// <summary>
/// Gets or sets the cell background colors. Null if unused, transparent values are ignored.
/// </summary>
public Color[] BackgroundColors { get; set; }
/// <summary>
/// Gets or sets the row depth level.
/// </summary>
@@ -58,6 +63,7 @@ namespace FlaxEditor.GUI
{
float x = 0;
int end = Mathf.Min(Values.Length, _table.Columns.Length);
var backgroundColors = BackgroundColors;
for (int i = 0; i < end; i++)
{
var column = _table.Columns[i];
@@ -98,6 +104,8 @@ namespace FlaxEditor.GUI
rect.Width -= leftDepthMargin;
Render2D.PushClip(rect);
if (backgroundColors != null && backgroundColors[i].A > 0)
Render2D.FillRectangle(rect, backgroundColors[i]);
Render2D.DrawText(style.FontMedium, text, rect, style.Foreground, column.CellAlignment, TextAlignment.Center);
Render2D.PopClip();

View File

@@ -36,6 +36,22 @@ namespace FlaxEditor.Modules
{
public string AssemblyName;
public string TypeName;
public DockState DockState;
public DockPanel DockedTo;
public float? SplitterValue = null;
public bool SelectOnShow = false;
public bool Maximize;
public bool Minimize;
public Float2 FloatSize;
public Float2 FloatPosition;
// Constructor, to allow for default values
public WindowRestoreData()
{
}
}
private readonly List<WindowRestoreData> _restoreWindows = new List<WindowRestoreData>();
@@ -676,7 +692,9 @@ namespace FlaxEditor.Modules
if (newLocation == DockState.Float)
{
// Check if there is a floating window that has the same size
var defaultSize = window.DefaultSize;
var dpi = (float)Platform.Dpi / 96.0f;
var dpiScale = Platform.CustomDpiScale;
var defaultSize = window.DefaultSize * dpi;
for (var i = 0; i < Editor.UI.MasterPanel.FloatingPanels.Count; i++)
{
var win = Editor.UI.MasterPanel.FloatingPanels[i];
@@ -688,7 +706,7 @@ namespace FlaxEditor.Modules
}
}
window.ShowFloating(defaultSize);
window.ShowFloating(defaultSize * dpiScale);
}
else
{
@@ -800,10 +818,38 @@ namespace FlaxEditor.Modules
if (constructor == null || type.IsGenericType)
return;
WindowRestoreData winData;
var winData = new WindowRestoreData();
var panel = win.Window.ParentDockPanel;
// Ensure that this window is only selected following recompilation
// if it was the active tab in its dock panel. Otherwise, there is a
// risk of interrupting the user's workflow by potentially selecting
// background tabs.
winData.SelectOnShow = panel.SelectedTab == win.Window;
if (panel is FloatWindowDockPanel)
{
winData.DockState = DockState.Float;
var window = win.Window.RootWindow.Window;
winData.FloatPosition = window.Position;
winData.FloatSize = window.ClientSize;
winData.Maximize = window.IsMaximized;
winData.Minimize = window.IsMinimized;
}
else
{
if (panel.TabsCount > 1)
{
winData.DockState = DockState.DockFill;
winData.DockedTo = panel;
}else
{
winData.DockState = panel.TryGetDockState(out var splitterValue);
winData.DockedTo = panel.ParentDockPanel;
winData.SplitterValue = splitterValue;
}
}
winData.AssemblyName = type.Assembly.GetName().Name;
winData.TypeName = type.FullName;
// TODO: cache and restore docking info
_restoreWindows.Add(winData);
}
@@ -822,7 +868,24 @@ namespace FlaxEditor.Modules
if (type != null)
{
var win = (CustomEditorWindow)Activator.CreateInstance(type);
win.Show();
win.Show(winData.DockState, winData.DockedTo, winData.SelectOnShow, winData.SplitterValue);
if (winData.DockState == DockState.Float)
{
var window = win.Window.RootWindow.Window;
window.Position = winData.FloatPosition;
if (winData.Maximize)
{
window.Maximize();
}
else if (winData.Minimize)
{
window.Minimize();
}
else
{
window.ClientSize = winData.FloatSize;
}
}
}
}
}

View File

@@ -386,6 +386,7 @@ namespace FlaxEditor.Windows.Assets
// Spawn it
Spawn(actor);
Rename();
}
/// <summary>
@@ -415,6 +416,7 @@ namespace FlaxEditor.Windows.Assets
// Create undo action
var action = new CustomDeleteActorsAction(new List<SceneGraphNode>(1) { actorNode }, true);
Undo.AddAction(action);
Select(actorNode);
}
private void OnTreeRightClick(TreeNode node, Float2 location)

View File

@@ -452,7 +452,6 @@ namespace FlaxEditor.Windows.Profiler
var data = _events.Get(_mainChart.SelectedSampleIndex);
if (data == null || data.Length == 0)
return;
float totalTimeMs = _mainChart.SelectedSample;
// Add rows
@@ -501,17 +500,24 @@ namespace FlaxEditor.Windows.Profiler
row = new Row
{
Values = new object[6],
BackgroundColors = new Color[6],
};
for (int k = 0; k < row.BackgroundColors.Length; k++)
row.BackgroundColors[k] = Color.Transparent;
}
{
// Event
row.Values[0] = name;
// Total (%)
row.Values[1] = (int)(time / totalTimeMs * 1000.0f) / 10.0f;
float rowTotalTimePerc = (float)(time / totalTimeMs);
row.Values[1] = (int)(rowTotalTimePerc * 1000.0f) / 10.0f;
row.BackgroundColors[1] = Color.Red.AlphaMultiplied(Mathf.Min(1, rowTotalTimePerc) * 0.5f);
// Self (%)
row.Values[2] = (int)((time - subEventsTimeTotal) / time * 1000.0f) / 10.0f;
float rowSelfTimePerc = (float)((time - subEventsTimeTotal) / totalTimeMs);
row.Values[2] = (int)(rowSelfTimePerc * 1000.0f) / 10.0f;
row.BackgroundColors[2] = Color.Red.AlphaMultiplied(Mathf.Min(1, rowSelfTimePerc) * 0.5f);
// Time ms
row.Values[3] = (float)((time * 10000.0f) / 10000.0f);

View File

@@ -150,9 +150,7 @@ void BinaryAsset::ClearDependencies()
{
auto asset = Cast<BinaryAsset>(Content::GetAsset(e.First));
if (asset)
{
asset->_dependantAssets.Remove(this);
}
}
Dependencies.Clear();
}
@@ -387,6 +385,16 @@ bool BinaryAsset::SaveToAsset(const StringView& path, AssetInitData& data, bool
if (binaryAsset)
binaryAsset->_isSaving = false;
if (binaryAsset)
{
// Inform dependant asset (use cloned version because it might be modified by assets when they got reloaded)
auto dependantAssets = binaryAsset->_dependantAssets;
for (auto& e : dependantAssets)
{
e->OnDependencyModified(binaryAsset);
}
}
return result;
}

View File

@@ -963,6 +963,7 @@ bool FlaxStorage::Create(WriteStream* stream, const AssetInitData* data, int32 d
// Asset Dependencies
stream->WriteInt32(header.Dependencies.Count());
stream->WriteBytes(header.Dependencies.Get(), header.Dependencies.Count() * sizeof(Pair<Guid, DateTime>));
static_assert(sizeof(Pair<Guid, DateTime>) == sizeof(Guid) + sizeof(DateTime), "Invalid data size.");
}
#if ASSETS_LOADING_EXTRA_VERIFICATION

View File

@@ -207,13 +207,12 @@ void PostFxMaterialsSettings::BlendWith(PostFxMaterialsSettings& other, float we
if (isHalf)
{
int32 indexSrc = 0;
const auto materialsSrc = other.Materials.Get();
const AssetReference<MaterialBase>* materialsSrc = other.Materials.Get();
while (Materials.Count() != POST_PROCESS_SETTINGS_MAX_MATERIALS && indexSrc < other.Materials.Count())
{
if (materialsSrc[indexSrc])
{
Materials.Add(materialsSrc[indexSrc]);
}
MaterialBase* mat = materialsSrc[indexSrc].Get();
if (mat && !Materials.Contains(mat))
Materials.Add(mat);
indexSrc++;
}
}

View File

@@ -244,7 +244,7 @@ bool AndroidFileSystem::FileExists(const StringView& path)
bool AndroidFileSystem::DeleteFile(const StringView& path)
{
const StringAsANSI<> pathANSI(*path, path.Length());
return unlink(pathANSI.Get()) == 0;
return unlink(pathANSI.Get()) != 0;
}
uint64 AndroidFileSystem::GetFileSize(const StringView& path)

View File

@@ -218,7 +218,7 @@ bool AppleFileSystem::FileExists(const StringView& path)
bool AppleFileSystem::DeleteFile(const StringView& path)
{
const StringAsANSI<> pathANSI(*path, path.Length());
return unlink(pathANSI.Get()) == 0;
return unlink(pathANSI.Get()) != 0;
}
uint64 AppleFileSystem::GetFileSize(const StringView& path)

View File

@@ -364,7 +364,7 @@ bool LinuxFileSystem::FileExists(const StringView& path)
bool LinuxFileSystem::DeleteFile(const StringView& path)
{
const StringAsANSI<> pathANSI(*path, path.Length());
return unlink(pathANSI.Get()) == 0;
return unlink(pathANSI.Get()) != 0;
}
uint64 LinuxFileSystem::GetFileSize(const StringView& path)