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());

}

}

}

相关推荐
应用市场11 小时前
无人机姿态控制系统详解与实现
游戏引擎·cocos2d
陈言必行15 小时前
Unity 性能优化 之 编辑器创建资源优化( 工作流 | 场景 | 预制体)
unity·编辑器·游戏引擎
1uther21 小时前
Unity核心概念⑨:Screen
开发语言·游戏·unity·c#·游戏引擎
玉面小君1 天前
从 WPF 到 Avalonia 的迁移系列实战篇6:Trigger、MultiTrigger、DataTrigger 的迁移
wpf·avalonia
死也不注释1 天前
【Unity UGUI 交互组件——Slider(7)】
unity·游戏引擎·交互
挂科是不可能出现的1 天前
unity导入blender动画
unity·游戏引擎·blender
派葛穆1 天前
Unity-按钮实现场景跳转
java·unity·游戏引擎
招风的黑耳2 天前
Java生态圈核心组件深度解析:Spring技术栈与分布式系统实战
java·spring·wpf
绀目澄清2 天前
unity UGUI 鼠标画线
unity·计算机外设·游戏引擎
lfw20192 天前
WPF 数据绑定模式详解(TwoWay、OneWay、OneTime、OneWayToSource、Default)
wpf