wpf主界面游戏引擎实现

2.GameEntityView.xaml

<UserControl x:Class="PrimalEditor.Editors.GameEntityView"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:local="clr-namespace:PrimalEditor.Editors"

xmlns:vm="clr-namespace:PrimalEditor.Components"

mc:Ignorable="d" Background="{StaticResource Editor.Window.GrayBrush3}"

d:DesignHeight="450" d:DesignWidth="800">

<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">

<ScrollViewer.Style>

<Style TargetType="ScrollViewer">

<Style.Triggers>

<Trigger Property="DataContext" Value="{x:Null}">

<Setter Property="Visibility" Value="Collapsed"/>

</Trigger>

</Style.Triggers>

</Style>

</ScrollViewer.Style>

<StackPanel>

<Border Height="32">

<ToggleButton x:Name="addComponent" VerticalAlignment="Center"

HorizontalAlignment="Left" Margin="5,0,0,0">

<ToggleButton.Content>

<DockPanel>

<TextBlock Text="Add Component" Margin="5,0"/>

<Path Margin="3,0,2,0"

Data="M0,0 L0,2 L4,6 L8,2 L8,0 L4,4 z"

HorizontalAlignment="Center" Fill="Black"

VerticalAlignment="Center"

/>

</DockPanel>

</ToggleButton.Content>

</ToggleButton>

</Border>

<Grid>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="78"/>

<ColumnDefinition/>

<ColumnDefinition Width="Auto"/>

</Grid.ColumnDefinitions>

<TextBlock Text="Name" Grid.Column="0" Margin="5,0,0,0"/>

<TextBox Text="{Binding Name}" Grid.Column="1" Tag="{Binding RenameCommand}"/>

<StackPanel Orientation="Horizontal" Grid.Column="2">

<TextBlock Text="Enabled" Margin="5,0,0,0"/>

<CheckBox IsChecked="{Binding IsEnabled}" Command="{Binding IsEnabledCommand}"

CommandParameter="{Binding IsChecked,RelativeSource={RelativeSource Self}}"

Margin="5,0" VerticalAlignment="Center"/>

</StackPanel>

</Grid>

<ItemsControl ItemsSource="{Binding Components}">

<ItemsControl.ItemsPanel>

<ItemsPanelTemplate>

<StackPanel/>

</ItemsPanelTemplate>

</ItemsControl.ItemsPanel>

</ItemsControl>

</StackPanel>

</ScrollViewer>

</UserControl>

2.GameEntityView.xaml.cs

using PrimalEditor.Components;

using PrimalEditor.GameProject;

using PrimalEditor.Utilities;

using System.Globalization;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Controls.Primitives;

using System.Windows.Data;

using System.Windows.Input;

namespace PrimalEditor.Editors

{

public class NullableBoolToBoolConverter : IValueConverter

{

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

{

return value is bool b && b == true;

}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

{

return value is bool b && b == true;

}

}

/// <summary>

/// GameEntityView.xaml 的交互逻辑

/// </summary>

public partial class GameEntityView : UserControl

{

private Action _undoAction;

private string _propertyName;

public static GameEntityView Instance { get; private set; }

public GameEntityView()

{

InitializeComponent();

DataContext = null;

Instance = this;

DataContextChanged += (_, __) =>

{

if (DataContext != null)

{

(DataContext as MSEntity).PropertyChanged += (s, e) => _propertyName = e.PropertyName;

}

};

}

private Action GetRenameAction()

{

var vm = DataContext as MSEntity;

var selection = vm.SelectedEntities.Select(entity => (entity, entity.Name)).ToList();

return new Action(() =>

{

selection.ForEach(item => item.entity.Name = item.Name);

(DataContext as MSEntity).Refresh();

});

}

private Action GetIsEnabledAction()

{

var vm = DataContext as MSEntity;

var selection = vm.SelectedEntities.Select(entity => (entity, entity.IsEnabled)).ToList();

return new Action(() =>

{

selection.ForEach(item => item.entity.IsEnabled = item.IsEnabled);

(DataContext as MSEntity).Refresh();

});

}

private void OnName_TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)

{

_propertyName = string.Empty;

_undoAction = GetRenameAction();

}

private void OnName_TextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)

{

if (_propertyName == nameof(MSEntity.Name) && _undoAction != null)

{

var vm = DataContext as MSEntity;

var selection = vm.SelectedEntities.Select(entity => (entity, entity.Name)).ToList();

var redoAction = new Action(() =>

{

selection.ForEach(item => item.entity.Name = item.Name);

});

Project.UndoRedo.Add(new UndoRedoAction(_undoAction, redoAction, "Rename game entity"));

_propertyName = null;

};

_undoAction = null;

}

private void OnIsEnabled_CheckBox_Click(object sender, RoutedEventArgs e)

{

var undoAction = GetIsEnabledAction();

var vm = DataContext as MSEntity;

vm.IsEnabled = (sender as CheckBox).IsChecked == true;

var redoAction = GetIsEnabledAction();

Project.UndoRedo.Add(new UndoRedoAction(undoAction, redoAction,

vm.IsEnabled == true ? "Enable game entity" : "Disable game entity"

));

}

private void OnAddComponent_Button_PreviewMouse_LBD(object sender, MouseButtonEventArgs e)

{

var menu = FindResource("addComponentMenu") as ContextMenu;

var btn = sender as ToggleButton;

btn.IsChecked = true;

menu.Placement = PlacementMode.Bottom;

menu.PlacementTarget = btn;

menu.MinWidth = btn.ActualWidth;

menu.IsOpen = true;

}

private void AddComponent(ComponentType componentType, object data)

{

var creationFunction = ComponentFactory.GetCreationFunction(componentType);

var changedEntities = new List<(GameEntity entity, Component component)>();

var vm = DataContext as MSEntity;

foreach (var entity in vm.SelectedEntities)

{

var component = creationFunction(entity, data);

if (entity.AddComponent(component))

{

changedEntities.Add((entity, component));

}

}

if (changedEntities.Any())

{

vm.Refresh();

Project.UndoRedo.Add(new UndoRedoAction(

() =>

{

changedEntities.ForEach(x => x.entity.RemoveComponent(x.component));

(DataContext as MSEntity).Refresh();

},

() =>

{

changedEntities.ForEach(x => x.entity.AddComponent(x.component));

(DataContext as MSEntity).Refresh();

},

$"Add {componentType} component"

));

}

}

private void AddScriptComponent(object sender, RoutedEventArgs e)

{

AddComponent(ComponentType.Script, (sender as MenuItem).Header.ToString());

}

}

}

相关推荐
相信神话20217 小时前
Godot Shader 中 mix 函数的用法
游戏引擎·godot
郝学胜-神的一滴7 小时前
Horse3D游戏引擎研发笔记(七):在QtOpenGL环境下,使用改进的Uniform变量管理方式绘制多彩四边形
c++·3d·unity·游戏引擎·图形渲染·虚幻·unreal engine
巨龙之路10 小时前
Unity的Cursor.lockState
unity·游戏引擎
枯萎穿心攻击18 小时前
从 Unity UGUI 到 Unreal UMG 的交互与高效实践:UI 事件、坐标系适配与性能优化
开发语言·ui·unity·性能优化·ue5·游戏引擎·虚幻引擎
诸葛务农18 小时前
人形机器人——电子皮肤技术路线:光学式电子皮肤及MIT基于光导纤维的分布式触觉传感电子皮肤
分布式·机器人·wpf
界面开发小八哥1 天前
界面控件DevExpress WPF中文教程:Data Grid - 绑定数据
ui·.net·wpf·界面控件·devexpress·ui开发
界面开发小八哥2 天前
图表组件SciChart WPF再升级:v8.9带来油气井图、新交互与可视化增强
信息可视化·wpf·数据可视化·scichart
Thomas_YXQ2 天前
Unity3D编辑器扩展-物体批量替换设置材质
游戏·unity·编辑器·游戏引擎·材质
雪下的新火3 天前
Unity-HDRP场景搭建-那山
经验分享·笔记·unity·游戏引擎·场景搭建
创可贴治愈心灵3 天前
WPF中UI线程频繁操作造成卡顿的处理
ui·c#·wpf