wpf主界面游戏引擎实现

2.GameEntityView.xaml

             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">

  


   
       
           
       

       

       
                                      HorizontalAlignment="Left" Margin="5,0,0,0">
               
                   
                       
                                                  Data="M0,0 L0,2 L4,6 L8,2 L8,0 L4,4 z"
                          HorizontalAlignment="Center" Fill="Black"
                           VerticalAlignment="Center"                          
                          />
                   

               

           

       

       

           
               
               
               
           

            
           
           
               
               
                                  CommandParameter="{Binding IsChecked,RelativeSource={RelativeSource Self}}"
                      Margin="5,0" VerticalAlignment="Center"/>
           

       
        
       
           

               
                   

               


           
       


   

   

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;
        }
    }


    ///


    /// GameEntityView.xaml 的交互逻辑
    ///

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


        }


    }
}
 

你可能感兴趣的:(wpf,游戏引擎)