public ShaderEditorPageViewModel(ShaderStorageLinker shaderStorage, Workspace workspace, EventAggregator eventAggregator)
        {
            int index = workspace.SelectedIndex;

            _shaderStorage = shaderStorage;
            Workspace      = workspace;

            ShadersFlattened.AddRange(_shaderStorage.ShaderGroups.SelectMany((s) => s.Shaders));
            ShaderGroupsView        = CollectionViewSource.GetDefaultView(ShadersFlattened);
            ShaderGroupsView.Filter = (s) => ((Shader)s).Group.IsOpen;
            ShaderGroupsView.GroupDescriptions.Add(new PropertyGroupDescription("Group"));
            RaiseLoadedCommand = new DelegateCommand(RaiseLoaded);

            SelectErrorCommand         = new DelegateCommand <SelectionChangedEventArgs>(SelectError);
            RaiseCompileShaderCommand  = new DelegateCommand(RaiseCompileShader, CanExecuteCompileShader);
            RaiseNewShaderGroupCommand = new DelegateCommand(RaiseNewShaderGroup);

            RaiseShaderNameChangedCommand = new DelegateCommand <ShaderNameChangedEventArgs>(RaiseShaderNameChanged);

            InitializeExplorerButtons();
            InitializeSaveButtonCommands();

            RaiseBuildShaderGroupCommand = new DelegateCommand(RaiseBuildShaderGroup, CanExecuteCompileShader);

            _includeHeaderCallback = new CallbackDelegate(SaveIncludeHeaderCallback);

            Workspace.SelectedIndex = index;

            eventAggregator.GetEvent <RefreshExplorer>().Subscribe(RefreshExplorerEvent);
        }
 private void RefreshExplorerEvent(ShaderGroup shaderGroup)
 {
     if (shaderGroup != null)
     {
         foreach (Shader shader in shaderGroup.Shaders)
         {
             ShadersFlattened.Remove(shader);
         }
     }
     ShaderGroupsView.Refresh();
 }
        private void RaiseEditShaderGroup(ShaderGroup group)
        {
            ShaderGroupNotification notification = new ShaderGroupNotification();

            notification.ShaderGroup = group.Copy();
            notification.Title       = "Edit Shader";
            notification.Content     = true;

            bool          selectionNeedsUpdate = false;
            int           selectedIndex        = ShaderGroupsView.CurrentPosition;
            List <Shader> openItems            = ShaderGroupsView.Cast <Shader>().ToList();
            int           originalCount        = group.Shaders.Count;
            int           startIndex           = 0;

            if (openItems[selectedIndex].Group == group)
            {
                selectionNeedsUpdate = true;
                startIndex           = openItems.IndexOf(group.Shaders[0]);
            }

            ShaderGroupRequest.Raise(notification, (returned) =>
            {
                if (returned.Confirmed)
                {
                    int flattenedIndex = ShadersFlattened.IndexOf(group.Shaders[0]);

                    int index = _shaderStorage.ShaderGroups.IndexOf(group);
                    _shaderStorage.ShaderGroups.Remove(group);
                    _shaderStorage.ShaderGroups.Insert(index, notification.ShaderGroup);

                    group.AnnotationShaderGroups.Clear();
                    group.IsBuilded = false;

                    group.Shaders.ToList().ForEach((s) => ShadersFlattened.Remove(s));
                    for (int i = 0; i < notification.ShaderGroup.Shaders.Count; ++i)
                    {
                        ShadersFlattened.Insert(flattenedIndex + i, notification.ShaderGroup.Shaders[i]);
                    }

                    if (selectionNeedsUpdate)
                    {
                        selectedIndex = Math.Min(openItems.Count - 1, selectedIndex);
                        if (startIndex + notification.ShaderGroup.Shaders.Count <= selectedIndex)
                        {
                            selectedIndex = startIndex + notification.ShaderGroup.Shaders.Count - 1;
                        }
                        ShaderGroupsView.MoveCurrentToPosition(selectedIndex);
                    }
                }
            });
        }
        private void RaiseRemoveHeader(Shader shader)
        {
            if (MessageBox.Show("Are you sure you want to permanently delete this shader: \n\"" + shader.Name + "\"\nThis action is irreversible." +
                                (shader.Group.ShaderGroupType == ShaderGroupType.SharedHeaders ? "\n\nThis is a SHARED shader and can result in breaking multiple groups" : ""),
                                "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
            {
                shader.Group.Shaders.Remove(shader);
                shader.Group.Save(Workspace);

                ShadersFlattened.Remove(shader);

                shader.Delete();
            }
        }
        private void RaiseNewShaderGroup()
        {
            ShaderGroupNotification notification = new ShaderGroupNotification();

            notification.Title   = "New Shader";
            notification.Content = null;
            ShaderGroupRequest.Raise(notification, (returned) =>
            {
                if (returned.Confirmed)
                {
                    notification.ShaderGroup.IsOpen = true;
                    _shaderStorage.ShaderGroups.Add(notification.ShaderGroup);
                    ShadersFlattened.AddRange(notification.ShaderGroup.Shaders);

                    notification.ShaderGroup.Save(Workspace);
                    Workspace.Save();
                }
            });
        }
        private void RaiseAddHeader(ShaderGroup group)
        {
            string name = "Header";
            IEnumerable <string> headers = group.Shaders.Where((s) => s.ShaderType == ShaderType.Header).Select((s) => s.Name);

            int counter = 0;

            while (headers.Contains(name + ".hlsli"))
            {
                ++counter;
                name = "Header_" + counter.ToString("D3");
            }

            Shader shader = new Shader(name + ".hlsli", ShaderType.Header);

            group.AddShader(shader);
            group.Save(Workspace);

            ShadersFlattened.Add(shader);
        }