mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
Automatic switch between Player <-> Editor Tabs
+ Allow Editor to inject into Settings
This commit is contained in:
@@ -711,6 +711,20 @@ namespace GlitchyEditor
|
||||
#endregion Project Management
|
||||
|
||||
#region Scene Management
|
||||
|
||||
/// Focuses the Play window, so that its tab will be shown.
|
||||
private void SwitchToPlayWindow()
|
||||
{
|
||||
let window = ImGui.FindWindowByName(GameViewportWindow.s_WindowTitle);
|
||||
ImGui.FocusWindow(window);
|
||||
}
|
||||
|
||||
/// Focuses the Editor window, so that its tab will be shown.
|
||||
private void SwitchToEditorWindow()
|
||||
{
|
||||
let window = ImGui.FindWindowByName(EditorViewportWindow.s_WindowTitle);
|
||||
ImGui.FocusWindow(window);
|
||||
}
|
||||
|
||||
/// Starts the play mode for the current scene
|
||||
private void OnScenePlay()
|
||||
@@ -728,6 +742,9 @@ namespace GlitchyEditor
|
||||
}
|
||||
|
||||
_editor.CurrentScene = _activeScene;
|
||||
|
||||
if (Application.Instance.Settings.EditorSettings.SwitchToPlayerOnPlay)
|
||||
SwitchToPlayWindow();
|
||||
}
|
||||
|
||||
/// Starts the physics simulation mode for the current scene
|
||||
@@ -746,18 +763,27 @@ namespace GlitchyEditor
|
||||
}
|
||||
|
||||
_editor.CurrentScene = _activeScene;
|
||||
|
||||
if (Application.Instance.Settings.EditorSettings.SwitchToPlayerOnSimulate)
|
||||
SwitchToPlayWindow();
|
||||
}
|
||||
|
||||
/// Pauses the scene
|
||||
private void OnScenePause()
|
||||
{
|
||||
_isPaused = true;
|
||||
|
||||
if (Application.Instance.Settings.EditorSettings.SwitchToEditorOnPause)
|
||||
SwitchToEditorWindow();
|
||||
}
|
||||
|
||||
/// Resumes the simulation / game
|
||||
private void OnSceneResume()
|
||||
{
|
||||
_isPaused = false;
|
||||
|
||||
if (Application.Instance.Settings.EditorSettings.SwitchToPlayerOnResume)
|
||||
SwitchToPlayWindow();
|
||||
}
|
||||
|
||||
/// Requests execution of a single simulation / game tick
|
||||
@@ -792,6 +818,9 @@ namespace GlitchyEditor
|
||||
*/
|
||||
GameViewportSizeChanged(null, _editor.GameViewportWindow.ViewportSize);
|
||||
}
|
||||
|
||||
if (Application.Instance.Settings.EditorSettings.SwitchToEditorOnStop)
|
||||
SwitchToEditorWindow();
|
||||
}
|
||||
|
||||
/// Stops the scene and cleans up the subsystems to allow loading another scene.
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using GlitchyEngine;
|
||||
using Bon;
|
||||
using GlitchyEditor;
|
||||
using System.Collections;
|
||||
|
||||
namespace GlitchyEngine
|
||||
{
|
||||
extension Settings
|
||||
{
|
||||
[SettingContainer, BonInclude]
|
||||
public readonly EditorSettings EditorSettings = new .() ~ delete _;
|
||||
|
||||
public this()
|
||||
{
|
||||
OnApplySettings.Add(new (s, e) => EditorSettings.Apply());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace GlitchyEditor;
|
||||
|
||||
[Reflect]
|
||||
class EditorSettings
|
||||
{
|
||||
[Setting("Editor", "Switch to Player on play", "If checked the editor will automatically switch to the \"Play\" window after starting the game."), BonInclude]
|
||||
public bool SwitchToPlayerOnPlay = true;
|
||||
|
||||
[Setting("Editor", "Switch to Player on simulate", "If checked the editor will automatically switch to the \"Play\" window after starting the simulation."), BonInclude]
|
||||
public bool SwitchToPlayerOnSimulate = true;
|
||||
|
||||
[Setting("Editor", "Switch to Player on continue", "If checked the editor will automatically switch to the \"Play\" window when the game is continued after pausing."), BonInclude]
|
||||
public bool SwitchToPlayerOnResume = false;
|
||||
|
||||
[Setting("Editor", "Switch to Editor on stop", "If checked the editor will automatically switch to the \"Editor\" window after stopping the game."), BonInclude]
|
||||
public bool SwitchToEditorOnStop = true;
|
||||
|
||||
[Setting("Editor", "Switch to Editor on pause", "If checked the editor will automatically switch to the \"Editor\" window when the game is being paused."), BonInclude]
|
||||
public bool SwitchToEditorOnPause = false;
|
||||
|
||||
//
|
||||
//public readonly List<String> RecentProjects = new .() ~ delete _;
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -14,12 +14,14 @@ namespace GlitchyEditor
|
||||
public Object SettingsObject;
|
||||
public String Name ~ delete _;
|
||||
public String FieldName ~ delete _;
|
||||
public StringView Tooltip;
|
||||
|
||||
public this(StringView name, StringView fieldName, Object settingsObject)
|
||||
public this(StringView name, StringView fieldName, Object settingsObject, StringView tooltip)
|
||||
{
|
||||
Name = new String(name);
|
||||
FieldName = new String(fieldName);
|
||||
SettingsObject = settingsObject;
|
||||
Tooltip = tooltip;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,9 +38,9 @@ namespace GlitchyEditor
|
||||
Header = new String(header);
|
||||
}
|
||||
|
||||
public void AddSetting(StringView name, StringView fieldName, Object settingsObject = null)
|
||||
public void AddSetting(StringView name, StringView fieldName, Object settingsObject = null, StringView tooltip = "")
|
||||
{
|
||||
Binding binding = new .(name, fieldName, settingsObject ?? SettingsObject);
|
||||
Binding binding = new .(name, fieldName, settingsObject ?? SettingsObject, tooltip);
|
||||
_bindings.Add(binding);
|
||||
}
|
||||
}
|
||||
@@ -89,7 +91,7 @@ namespace GlitchyEditor
|
||||
|
||||
if (settingResult case .Ok(let settingInfo))
|
||||
{
|
||||
AddSetting(settingInfo.Category, settingInfo.Name, field.Name, container);
|
||||
AddSetting(settingInfo.Category, settingInfo.Name, field.Name, container, settingInfo.Tooltip);
|
||||
}
|
||||
|
||||
Result<SettingContainerAttribute> containerResult = field.GetCustomAttribute<SettingContainerAttribute>();
|
||||
@@ -110,11 +112,11 @@ namespace GlitchyEditor
|
||||
}
|
||||
}
|
||||
|
||||
void AddSetting(String categoryName, String name, StringView fieldName, Object container)
|
||||
void AddSetting(String categoryName, String name, StringView fieldName, Object container, StringView tooltip)
|
||||
{
|
||||
Category category = AddCategory(categoryName);
|
||||
|
||||
category.AddSetting(name, fieldName, container);
|
||||
category.AddSetting(name, fieldName, container, tooltip);
|
||||
}
|
||||
|
||||
protected override void InternalShow()
|
||||
@@ -131,90 +133,7 @@ namespace GlitchyEditor
|
||||
{
|
||||
if (ImGui.BeginTabItem(category.Header))
|
||||
{
|
||||
ImGui.Columns(2);
|
||||
defer ImGui.Columns(1);
|
||||
ImGui.SetColumnWidth(0, 100);
|
||||
|
||||
for (Binding setting in category._bindings)
|
||||
{
|
||||
ImGui.TextUnformatted(setting.Name);
|
||||
|
||||
ImGui.NextColumn();
|
||||
|
||||
Type settingsObjectType = setting.SettingsObject.GetType();
|
||||
|
||||
Result<FieldInfo> result = settingsObjectType.GetField(setting.FieldName);
|
||||
|
||||
if (result case .Err)
|
||||
{
|
||||
ImGui.PushStyleColor(.Text, ImGui.Vec4(1f, 0f, 0f, 1f));
|
||||
ImGui.Text($"Field {setting.FieldName} not found.");
|
||||
ImGui.PopStyleColor();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
FieldInfo fieldInfo = result.Get();
|
||||
|
||||
Type fieldType = fieldInfo.FieldType;
|
||||
|
||||
mixin GetSettingValue<T>()
|
||||
{
|
||||
var error = fieldInfo.GetValue<T>(setting.SettingsObject, var value);
|
||||
|
||||
if (error case .Err(let err))
|
||||
{
|
||||
Log.EngineLogger.Error($"Could not get value of setting {setting.FieldName}. Error: {err}");
|
||||
|
||||
ImGui.PushStyleColor(.Text, ImGui.Vec4(1f, 0f, 0f, 1f));
|
||||
ImGui.Text($"Could not get value of setting {setting.FieldName}. Error: {err}");
|
||||
ImGui.PopStyleColor();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
value
|
||||
}
|
||||
|
||||
mixin SetSettingValue<T>(T value)
|
||||
{
|
||||
var error = fieldInfo.SetValue(setting.SettingsObject, value);
|
||||
|
||||
if (error case .Err(let err))
|
||||
{
|
||||
Log.EngineLogger.Error($"Could not set value of setting {setting.FieldName}. Error: {err}");
|
||||
}
|
||||
}
|
||||
|
||||
switch (fieldType)
|
||||
{
|
||||
case typeof(int32):
|
||||
int32 value = GetSettingValue!<int32>();
|
||||
|
||||
if (!ImGui.InputInt(scope $"##{setting.Name}", &value))
|
||||
break;
|
||||
|
||||
SetSettingValue!(value);
|
||||
|
||||
_settingsChanged = true;
|
||||
case typeof(String):
|
||||
String value = GetSettingValue!<String>();
|
||||
|
||||
char8[256] buffer = .();
|
||||
|
||||
value.CopyTo(buffer);
|
||||
|
||||
if (ImGui.InputText(scope $"##{setting.Name}", &buffer, buffer.Count))
|
||||
{
|
||||
value..Clear().Append(&buffer);
|
||||
|
||||
_settingsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.NextColumn();
|
||||
}
|
||||
|
||||
ShowCategory(category);
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
}
|
||||
@@ -249,5 +168,115 @@ namespace GlitchyEditor
|
||||
_open = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowCategory(Category category)
|
||||
{
|
||||
if (ImGui.BeginTable("SettingsTable", 2, .SizingFixedFit | .RowBg))
|
||||
{
|
||||
ImGui.TableSetupColumn("Settings");
|
||||
ImGui.TableSetupColumn("Values", .WidthStretch);
|
||||
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableSetColumnIndex(1);
|
||||
ImGui.PushItemWidth(ImGui.GetContentRegionAvail().x);
|
||||
|
||||
for (Binding setting in category._bindings)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
|
||||
// Name of setting
|
||||
ImGui.TextUnformatted(setting.Name);
|
||||
|
||||
if (!setting.Tooltip.IsWhiteSpace)
|
||||
ImGui.AttachTooltip(setting.Tooltip);
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
|
||||
Type settingsObjectType = setting.SettingsObject.GetType();
|
||||
|
||||
Result<FieldInfo> result = settingsObjectType.GetField(setting.FieldName);
|
||||
|
||||
if (result case .Err)
|
||||
{
|
||||
ImGui.PushStyleColor(.Text, ImGui.Vec4(1f, 0f, 0f, 1f));
|
||||
ImGui.Text($"Field {setting.FieldName} not found.");
|
||||
ImGui.PopStyleColor();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
FieldInfo fieldInfo = result.Get();
|
||||
|
||||
Type fieldType = fieldInfo.FieldType;
|
||||
|
||||
mixin GetSettingValue<T>()
|
||||
{
|
||||
var error = fieldInfo.GetValue<T>(setting.SettingsObject, var value);
|
||||
|
||||
if (error case .Err(let err))
|
||||
{
|
||||
Log.EngineLogger.Error($"Could not get value of setting {setting.FieldName}. Error: {err}");
|
||||
|
||||
ImGui.PushStyleColor(.Text, ImGui.Vec4(1f, 0f, 0f, 1f));
|
||||
ImGui.Text($"Could not get value of setting {setting.FieldName}. Error: {err}");
|
||||
ImGui.PopStyleColor();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
value
|
||||
}
|
||||
|
||||
mixin SetSettingValue<T>(T value)
|
||||
{
|
||||
var error = fieldInfo.SetValue(setting.SettingsObject, value);
|
||||
|
||||
if (error case .Err(let err))
|
||||
{
|
||||
Log.EngineLogger.Error($"Could not set value of setting {setting.FieldName}. Error: {err}");
|
||||
}
|
||||
}
|
||||
|
||||
switch (fieldType)
|
||||
{
|
||||
case typeof(bool):
|
||||
let value = GetSettingValue!<bool>();
|
||||
|
||||
if (!ImGui.Checkbox(scope $"##{setting.Name}", &value))
|
||||
break;
|
||||
|
||||
SetSettingValue!(value);
|
||||
|
||||
_settingsChanged = true;
|
||||
case typeof(int32):
|
||||
int32 value = GetSettingValue!<int32>();
|
||||
|
||||
if (!ImGui.InputInt(scope $"##{setting.Name}", &value))
|
||||
break;
|
||||
|
||||
SetSettingValue!(value);
|
||||
|
||||
_settingsChanged = true;
|
||||
case typeof(String):
|
||||
String value = GetSettingValue!<String>();
|
||||
|
||||
char8[256] buffer = .();
|
||||
|
||||
value.CopyTo(buffer);
|
||||
|
||||
if (ImGui.InputText(scope $"##{setting.Name}", &buffer, buffer.Count))
|
||||
{
|
||||
value..Clear().Append(&buffer);
|
||||
|
||||
_settingsChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user