Implementing Launch and Edit feature

This commit is contained in:
donlaci
2024-07-16 09:37:40 +02:00
parent a7e5c0330b
commit dcc0634fb1
10 changed files with 163 additions and 32 deletions

View File

@@ -8,7 +8,7 @@ namespace ProjectsEditor.Data
{
public class TempProjectData : ProjectData
{
public string File
public static string File
{
get
{
@@ -16,7 +16,7 @@ namespace ProjectsEditor.Data
}
}
public void DeleteTempFile()
public static void DeleteTempFile()
{
if (System.IO.File.Exists(File))
{

View File

@@ -25,7 +25,7 @@ namespace ProjectsEditor
private /*async*/ void NewProjectButton_Click(object sender, RoutedEventArgs e)
{
_mainViewModel.EnterSnapshotMode();
_mainViewModel.EnterSnapshotMode(false);
}
private void EditButtonClicked(object sender, RoutedEventArgs e)

View File

@@ -124,6 +124,21 @@ namespace ProjectsEditor.Models
get => Name.Length > 0 && Applications.Count > 0;
}
private bool _isRevertEnabled;
public bool IsRevertEnabled
{
get => _isRevertEnabled;
set
{
if (_isRevertEnabled != value)
{
_isRevertEnabled = value;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsRevertEnabled)));
}
}
}
private bool _isPopupVisible;
[JsonIgnore]

View File

@@ -21,7 +21,15 @@
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="ButtonEnabledStyle" TargetType="Button">
<Setter Property="Foreground" Value="{DynamicResource PrimaryForegroundBrush}" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False" >
<Setter Property="Foreground" Value="{DynamicResource SecondaryForegroundBrush}" />
</Trigger>
</Style.Triggers>
</Style>
<DataTemplate x:Key="headerTemplate">
<Border
HorizontalAlignment="Stretch">
@@ -266,6 +274,7 @@
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
@@ -317,17 +326,43 @@
HorizontalAlignment="Stretch"
Background="{DynamicResource MonitorViewBackgroundBrush}"
CornerRadius="5">
<Image
Width="{Binding PreviewImageWidth, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Height="200"
Source="{Binding PreviewImage, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Stretch="Fill"
Margin="2"/>
<DockPanel>
<Image
DockPanel.Dock="Top"
Width="{Binding PreviewImageWidth, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Height="200"
Source="{Binding PreviewImage, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Stretch="Fill"
Margin="2"/>
<Button
DockPanel.Dock="Right"
x:Name="RevertButton"
Margin="0,0,20,10"
Height="36"
Padding="24,0,24,0"
IsEnabled="{Binding IsRevertEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Content="{x:Static props:Resources.Revert}"
Background="{DynamicResource SecondaryBackgroundBrush}"
AutomationProperties.Name="{x:Static props:Resources.Revert}"
HorizontalAlignment="Right"
Click="RevertButtonClicked"/>
<Button
DockPanel.Dock="Right"
x:Name="LaunchEditButton"
Margin="0,0,10,10"
Height="36"
Padding="24,0,24,0"
Content="{x:Static props:Resources.LaunchEdit}"
Background="{DynamicResource SecondaryBackgroundBrush}"
AutomationProperties.Name="{x:Static props:Resources.LaunchEdit}"
HorizontalAlignment="Right"
Click="LaunchEditButtonClicked"/>
</DockPanel>
</Border>
<ScrollViewer
Margin="0,10,0,0"
VerticalScrollBarVisibility="Auto"
Grid.Row="3">
Grid.Row="4">
<StackPanel Orientation="Vertical">
<Grid>
<Grid.RowDefinitions>
@@ -341,7 +376,7 @@
</Grid>
</StackPanel>
</ScrollViewer>
<DockPanel Grid.Row="4" Margin="0,20,0,20">
<DockPanel Grid.Row="5" Margin="0,20,0,20">
<CheckBox
DockPanel.Dock="Left"
Content="{x:Static props:Resources.CreateShortcut}"

View File

@@ -43,8 +43,7 @@ namespace ProjectsEditor
private void CancelButtonClicked(object sender, RoutedEventArgs e)
{
// delete the temp file created by the snapshot tool
TempProjectData parser = new TempProjectData();
parser.DeleteTempFile();
TempProjectData.DeleteTempFile();
_mainViewModel.SwitchToMainView();
}
@@ -91,6 +90,11 @@ namespace ProjectsEditor
{
Border border = sender as Border;
Models.Application app = border.DataContext as Models.Application;
if (app == null)
{
return;
}
app.IsHighlighted = false;
Project project = app.Parent;
project.Initialize();
@@ -184,5 +188,17 @@ namespace ProjectsEditor
Models.Application application = checkBox.DataContext as Models.Application;
application.MinimizedChecked();
}
private void LaunchEditButtonClicked(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
Project project = button.DataContext as Project;
_mainViewModel.LaunchAndEdit(project);
}
private void RevertButtonClicked(object sender, RoutedEventArgs e)
{
_mainViewModel.RevertLaunch();
}
}
}

View File

@@ -312,6 +312,15 @@ namespace ProjectsEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Launch &amp; Edit.
/// </summary>
public static string LaunchEdit {
get {
return ResourceManager.GetString("LaunchEdit", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Left.
/// </summary>
@@ -510,6 +519,15 @@ namespace ProjectsEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Revert.
/// </summary>
public static string Revert {
get {
return ResourceManager.GetString("Revert", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Save project.
/// </summary>

View File

@@ -199,6 +199,9 @@
<data name="LaunchAsAdmin" xml:space="preserve">
<value>Launch as Admin</value>
</data>
<data name="LaunchEdit" xml:space="preserve">
<value>Launch &amp; Edit</value>
</data>
<data name="Launch_args" xml:space="preserve">
<value>Launch args</value>
</data>
@@ -269,6 +272,9 @@
<data name="Recently" xml:space="preserve">
<value>recently</value>
</data>
<data name="Revert" xml:space="preserve">
<value>Revert</value>
</data>
<data name="Save_project" xml:space="preserve">
<value>Save project</value>
</data>

View File

@@ -142,7 +142,7 @@ namespace ProjectsEditor.Utils
// draw the minimized windows
Rectangle rectMinimized = new Rectangle(0, Scaled((bounds.Height * 1.02) + (horizontalGaps.Count * gapHeight)), Scaled(bounds.Width + (verticalGaps.Count * gapWidth)), Scaled(bounds.Height * 0.18));
DrawWindow(g, brush, brushForHighlight, rectMinimized, project.Applications.Where(x => x.Minimized));
DrawWindow(g, brush, brushForHighlight, rectMinimized, appsIncluded.Where(x => x.Minimized));
}
using (var memory = new MemoryStream())

View File

@@ -52,15 +52,15 @@ namespace ProjectsEditor.Utils
project = null;
try
{
TempProjectData parser = new TempProjectData();
if (!File.Exists(parser.File))
ProjectData parser = new ProjectData();
if (!File.Exists(TempProjectData.File))
{
Logger.LogWarning($"ParseProject method. Projects storage file not found: {parser.File}");
Logger.LogWarning($"ParseProject method. Projects storage file not found: {TempProjectData.File}");
return new ParsingResult(false);
}
project = GetProjectFromWrapper(parser.Read(parser.File));
parser.DeleteTempFile();
project = GetProjectFromWrapper(parser.Read(TempProjectData.File));
TempProjectData.DeleteTempFile();
return new ParsingResult(true);
}
@@ -121,7 +121,7 @@ namespace ProjectsEditor.Utils
return newProject;
}
public void SerializeProjects(List<Project> projects)
public void SerializeProjects(List<Project> projects, bool useTempFile = false)
{
ProjectsData serializer = new ProjectsData();
ProjectsData.ProjectsListWrapper projectsWrapper = new ProjectsData.ProjectsListWrapper { };
@@ -194,7 +194,7 @@ namespace ProjectsEditor.Utils
try
{
IOUtils ioUtils = new IOUtils();
ioUtils.WriteFile(serializer.File, serializer.Serialize(projectsWrapper));
ioUtils.WriteFile(useTempFile ? TempProjectData.File : serializer.File, serializer.Serialize(projectsWrapper));
}
catch (Exception e)
{
@@ -219,5 +219,10 @@ namespace ProjectsEditor.Utils
mainViewModel.Projects = new System.Collections.ObjectModel.ObservableCollection<Project> { };
return AddProjects(mainViewModel, projects);
}
internal void SerializeTempProject(Project project)
{
SerializeProjects(new List<Project>() { project }, true);
}
}
}

View File

@@ -14,6 +14,7 @@ using System.Linq;
using System.Threading.Tasks;
using System.Timers;
using ManagedCommon;
using ProjectsEditor.Data;
using ProjectsEditor.Models;
using ProjectsEditor.Utils;
using static ProjectsEditor.Data.ProjectsData;
@@ -23,8 +24,15 @@ namespace ProjectsEditor.ViewModels
public class MainViewModel : INotifyPropertyChanged, IDisposable
{
private ProjectsEditorIO _projectsEditorIO;
private ProjectEditor editPage;
private SnapshotWindow _snapshotWindow;
private List<OverlayWindow> _overlayWindows = new List<OverlayWindow>();
private bool _isExistingProjectLaunched;
private Project editedProject;
private Project projectBeforeLaunch;
private string projectNameBeingEdited;
private MainWindow _mainWindow;
private Timer lastUpdatedTimer;
public ObservableCollection<Project> Projects { get; set; } = new ObservableCollection<Project>();
@@ -126,11 +134,6 @@ namespace ProjectsEditor.ViewModels
PropertyChanged?.Invoke(this, e);
}
private Project editedProject;
private string projectNameBeingEdited;
private MainWindow _mainWindow;
private System.Timers.Timer lastUpdatedTimer;
public MainViewModel(ProjectsEditorIO projectsEditorIO)
{
_projectsEditorIO = projectsEditorIO;
@@ -226,13 +229,32 @@ namespace ProjectsEditor.ViewModels
Project project = new Project();
if (_projectsEditorIO.ParseTempProject(out project).Result)
{
EditProject(project, true);
if (_isExistingProjectLaunched)
{
UpdateProject(project);
}
else
{
EditProject(project, true);
}
}
}
private void UpdateProject(Project project)
{
project.Name = projectBeforeLaunch.Name;
project.IsRevertEnabled = true;
editPage.DataContext = project;
}
internal void RevertLaunch()
{
editPage.DataContext = projectBeforeLaunch;
}
public void EditProject(Project selectedProject, bool isNewlyCreated = false)
{
var editPage = new ProjectEditor(this);
editPage = new ProjectEditor(this);
SetEditedProject(selectedProject);
if (!isNewlyCreated)
@@ -353,10 +375,10 @@ namespace ProjectsEditor.ViewModels
p.WaitForExit();
}
private void RunLauncher(string projectId)
private void RunLauncher(string projectIdOrFilename)
{
Process p = new Process();
p.StartInfo = new ProcessStartInfo(@".\PowerToys.ProjectsLauncher.exe", projectId);
p.StartInfo = new ProcessStartInfo(@".\PowerToys.ProjectsLauncher.exe", projectIdOrFilename);
p.StartInfo.CreateNoWindow = true;
p.Start();
p.WaitForExit();
@@ -375,8 +397,9 @@ namespace ProjectsEditor.ViewModels
}
}
internal void EnterSnapshotMode()
internal void EnterSnapshotMode(bool isExistingProjectLaunched)
{
_isExistingProjectLaunched = isExistingProjectLaunched;
_mainWindow.WindowState = System.Windows.WindowState.Minimized;
_overlayWindows.Clear();
foreach (var screen in MonitorHelper.GetDpiUnawareScreens())
@@ -408,5 +431,18 @@ namespace ProjectsEditor.ViewModels
_mainWindow.WindowState = System.Windows.WindowState.Normal;
}
internal void LaunchAndEdit(Project project)
{
LaunchEditedProject(project);
projectBeforeLaunch = new Project(project);
EnterSnapshotMode(true);
}
private void LaunchEditedProject(Project project)
{
_projectsEditorIO.SerializeTempProject(project);
RunLauncher(TempProjectData.File);
}
}
}