Implementing major new features: remove button, position manipulation, arguments, admin, minimized, maximized

This commit is contained in:
donlaci
2024-07-11 12:45:19 +02:00
parent d7467e24ae
commit dae91d2874
11 changed files with 675 additions and 104 deletions

View File

@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Windows;
using System.Windows.Controls;
namespace ProjectsEditor.Controls
{
public class ResetIsEnabled : ContentControl
{
static ResetIsEnabled()
{
IsEnabledProperty.OverrideMetadata(
typeof(ResetIsEnabled),
new UIPropertyMetadata(
defaultValue: true,
propertyChangedCallback: (_, __) => { },
coerceValueCallback: (_, x) => x));
}
}
}

View File

@@ -33,6 +33,8 @@ namespace ProjectsEditor.Data
public string CommandLineArguments { get; set; }
public bool LaunchesAsAdmin { get; set; }
public bool Minimized { get; set; }
public bool Maximized { get; set; }

View File

@@ -22,6 +22,8 @@ namespace ProjectsEditor.Models
{
public class Application : INotifyPropertyChanged, IDisposable
{
private bool _isInitialized;
public event PropertyChangedEventHandler PropertyChanged;
public Project Parent { get; set; }
@@ -47,9 +49,80 @@ namespace ProjectsEditor.Models
public string CommandLineArguments { get; set; }
public bool Minimized { get; set; }
private bool _launchesAsAdmin;
public bool Maximized { get; set; }
public bool LaunchesAsAdmin
{
get => _launchesAsAdmin;
set
{
_launchesAsAdmin = value;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(AppMainParams)));
}
}
internal void SwitchDeletion()
{
IsIncluded = !IsIncluded;
RedrawPreviewImage();
}
private void RedrawPreviewImage()
{
if (_isInitialized)
{
Parent.Initialize();
}
}
private bool _minimized;
public bool Minimized
{
get => _minimized;
set
{
_minimized = value;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(Minimized)));
OnPropertyChanged(new PropertyChangedEventArgs(nameof(EditPositionEnabled)));
RedrawPreviewImage();
}
}
private bool _maximized;
public bool Maximized
{
get => _maximized;
set
{
_maximized = value;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(Maximized)));
OnPropertyChanged(new PropertyChangedEventArgs(nameof(EditPositionEnabled)));
RedrawPreviewImage();
}
}
public bool EditPositionEnabled { get => !Minimized && !Maximized; }
private string _appMainParams;
public string AppMainParams
{
get
{
_appMainParams = _launchesAsAdmin ? Properties.Resources.Admin : string.Empty;
if (!string.IsNullOrWhiteSpace(CommandLineArguments))
{
_appMainParams += (_appMainParams == string.Empty ? string.Empty : " | ") + Properties.Resources.Args + ": " + CommandLineArguments;
}
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsAppMainParamVisible)));
return _appMainParams;
}
}
public bool IsAppMainParamVisible { get => !string.IsNullOrWhiteSpace(_appMainParams); }
private bool _isNotFound;
@@ -82,7 +155,7 @@ namespace ProjectsEditor.Models
{
get
{
return RepeatIndex == 0 ? string.Empty : RepeatIndex.ToString(CultureInfo.InvariantCulture);
return RepeatIndex <= 1 ? string.Empty : RepeatIndex.ToString(CultureInfo.InvariantCulture);
}
}
@@ -201,7 +274,17 @@ namespace ProjectsEditor.Models
}
}
public WindowPosition Position { get; set; }
private WindowPosition _position;
public WindowPosition Position
{
get => _position;
set
{
_position = value;
_scaledPosition = null;
}
}
private WindowPosition? _scaledPosition;
@@ -247,6 +330,11 @@ namespace ProjectsEditor.Models
PropertyChanged?.Invoke(this, e);
}
public void InitializationFinished()
{
_isInitialized = true;
}
private bool? _isPackagedApp;
public string PackagedId { get; set; }
@@ -287,9 +375,62 @@ namespace ProjectsEditor.Models
}
}
private bool _isExpanded;
public bool IsExpanded
{
get => _isExpanded;
set
{
if (_isExpanded != value)
{
_isExpanded = value;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsExpanded)));
}
}
}
public string DeleteButtonContent { get => _isIncluded ? Properties.Resources.Delete : Properties.Resources.AddBack; }
private bool _isIncluded = true;
public bool IsIncluded
{
get => _isIncluded;
set
{
if (_isIncluded != value)
{
_isIncluded = value;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsIncluded)));
OnPropertyChanged(new PropertyChangedEventArgs(nameof(DeleteButtonContent)));
if (!_isIncluded)
{
IsExpanded = false;
}
}
}
}
public void Dispose()
{
GC.SuppressFinalize(this);
}
internal void CommandLineTextChanged(string newCommandLineValue)
{
CommandLineArguments = newCommandLineValue;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(AppMainParams)));
}
internal void MaximizedChecked()
{
Minimized = false;
}
internal void MinimizedChecked()
{
Maximized = false;
}
}
}

View File

@@ -209,20 +209,23 @@ namespace ProjectsEditor.Models
Applications = new List<Application>();
foreach (var item in selectedProject.Applications)
{
Applications.Add(new Application()
Application newApp = new Application()
{
AppName = item.AppName,
AppPath = item.AppPath,
AppTitle = item.AppTitle,
CommandLineArguments = item.CommandLineArguments,
PackageFullName = item.PackageFullName,
LaunchesAsAdmin = item.LaunchesAsAdmin,
Minimized = item.Minimized,
Maximized = item.Maximized,
MonitorNumber = item.MonitorNumber,
IsNotFound = item.IsNotFound,
Position = new Application.WindowPosition() { X = item.Position.X, Y = item.Position.Y, Height = item.Position.Height, Width = item.Position.Width },
Parent = this,
});
};
newApp.InitializationFinished();
Applications.Add(newApp);
}
}
@@ -304,5 +307,13 @@ namespace ProjectsEditor.Models
return new Rectangle((int)minX, (int)minY, (int)(maxX - minX), (int)(maxY - minY));
}
internal void CloseExpanders()
{
foreach (Application app in Applications)
{
app.IsExpanded = false;
}
}
}
}

View File

@@ -6,12 +6,22 @@
xmlns:props="clr-namespace:ProjectsEditor.Properties"
xmlns:local="clr-namespace:ProjectsEditor"
xmlns:models="clr-namespace:ProjectsEditor.Models"
xmlns:controls="clr-namespace:ProjectsEditor.Controls"
mc:Ignorable="d"
Title="Project Editor"
Background="{DynamicResource PrimaryBackgroundBrush}">
<Page.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis" />
<Style x:Key="TextBlockEnabledStyle" TargetType="TextBlock">
<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">
@@ -29,81 +39,218 @@
<Border
Background="{DynamicResource SecondaryBackgroundBrush}"
MouseEnter="AppBorder_MouseEnter"
MouseLeave="AppBorder_MouseLeave">
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Text="&#xE7BA;"
Foreground="#EED202"
FontSize="14"
FontFamily="{DynamicResource SymbolThemeFontFamily}"
FontWeight="Normal"
Margin="5 0 0 0"
ToolTip="{x:Static props:Resources.NotFoundTooltip}"
Visibility="{Binding IsNotFound, Converter={StaticResource BoolToVis}, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center"/>
<Image
Grid.Column="1"
Width="20"
Height="20"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="10"
Source="{Binding IconBitmapImage}"/>
<TextBlock
Grid.Column="2"
Text="{Binding RepeatIndexString, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Foreground="{DynamicResource PrimaryForegroundBrush}"
FontSize="14"
FontWeight="Normal"
Width="20"
VerticalAlignment="Center"/>
<TextBlock
Grid.Column="3"
Text="{Binding AppName}"
Foreground="{DynamicResource PrimaryForegroundBrush}"
FontSize="14"
FontWeight="Normal"
VerticalAlignment="Center"/>
<TextBox
x:Name="CommandLineTextBox"
Grid.Column="4"
Text="{Binding CommandLineArguments, Mode=TwoWay}"
Foreground="{DynamicResource PrimaryForegroundBrush}"
Background="{DynamicResource TertiaryBackgroundBrush}"
BorderThickness="0"
FontSize="14"
FontWeight="Normal"
VerticalContentAlignment="Center" />
<TextBlock
Grid.Column="4"
IsHitTestVisible="False"
Text="{x:Static props:Resources.WriteArgs}"
Foreground="{DynamicResource SecondaryForegroundBrush}"
Background="{DynamicResource TertiaryBackgroundBrush}"
FontSize="14"
FontWeight="Normal"
VerticalAlignment="Center"
Margin="12,0,12,0">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Text, ElementName=CommandLineTextBox}" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
MouseLeave="AppBorder_MouseLeave"
Margin="1">
<Expander
Margin="5,5,25,5"
FlowDirection="RightToLeft"
IsExpanded="{Binding IsExpanded, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding IsIncluded, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
<Expander.Header>
<Grid
FlowDirection="LeftToRight"
HorizontalAlignment="{Binding HorizontalAlignment, RelativeSource={RelativeSource AncestorType=ContentPresenter}, Mode=OneWayToSource}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Text="&#xE7BA;"
Foreground="#EED202"
FontSize="14"
FontFamily="{DynamicResource SymbolThemeFontFamily}"
FontWeight="Normal"
Margin="5 0 0 0"
ToolTip="{x:Static props:Resources.NotFoundTooltip}"
Visibility="{Binding IsNotFound, Converter={StaticResource BoolToVis}, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center"/>
<Image
Grid.Column="1"
Width="20"
Height="20"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="10"
Source="{Binding IconBitmapImage}"/>
<TextBlock
Grid.Column="2"
Text="{Binding RepeatIndexString, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Foreground="{DynamicResource PrimaryForegroundBrush}"
FontSize="14"
FontWeight="Normal"
Width="20"
VerticalAlignment="Center"/>
<StackPanel
Grid.Column="3"
VerticalAlignment="Center">
<TextBlock
Text="{Binding AppName}"
Foreground="{DynamicResource PrimaryForegroundBrush}"
FontSize="14"
FontWeight="Normal"
/>
<TextBlock
Text="{Binding AppMainParams, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Foreground="{DynamicResource SecondaryForegroundBrush}"
Visibility="{Binding IsAppMainParamVisible, Converter={StaticResource BoolToVis}, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
FontSize="12"
FontWeight="Normal"
/>
</StackPanel>
<controls:ResetIsEnabled
Grid.Column="4">
<Button
Padding="24 6"
Margin="10 5"
Width="120"
Content="{Binding DeleteButtonContent, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Background="{DynamicResource TertiaryBackgroundBrush}"
AutomationProperties.Name="{x:Static props:Resources.Delete}"
IsEnabled="True"
Click="DeleteButtonClicked">
</Button>
</controls:ResetIsEnabled>
</Grid>
</Expander.Header>
<Grid
FlowDirection="LeftToRight"
HorizontalAlignment="{Binding HorizontalAlignment, RelativeSource={RelativeSource AncestorType=ContentPresenter}, Mode=OneWayToSource}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DockPanel
Margin="100 5 0 0">
<TextBlock
Text="{x:Static props:Resources.CliArguments}"
Foreground="{DynamicResource PrimaryForegroundBrush}"
FontSize="14"
FontWeight="Normal"
VerticalAlignment="Center" />
<TextBox
Margin="15 0 0 0"
x:Name="CommandLineTextBox"
Text="{Binding CommandLineArguments, Mode=TwoWay}"
Foreground="{DynamicResource PrimaryForegroundBrush}"
Background="{DynamicResource TertiaryBackgroundBrush}"
BorderThickness="0"
FontSize="14"
FontWeight="Normal"
VerticalContentAlignment="Center"
HorizontalAlignment="Stretch"
TextChanged="CommandLineTextBox_TextChanged"/>
</DockPanel>
<StackPanel
Orientation="Horizontal"
Grid.Row="1"
Margin="100 5 0 0">
<CheckBox
Content="{x:Static props:Resources.LaunchAsAdmin}"
IsChecked="{Binding LaunchesAsAdmin, Mode=TwoWay}"
MinWidth="10"/>
<CheckBox
Margin="15 0 0 0"
Content="{x:Static props:Resources.Maximized}"
IsChecked="{Binding Maximized, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
MinWidth="10"
Checked="MaximizedChecked"/>
<CheckBox
Margin="15 0 0 0"
Content="{x:Static props:Resources.Minimized}"
IsChecked="{Binding Minimized, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
MinWidth="10"
Checked="MinimizedChecked"/>
</StackPanel>
<StackPanel
Orientation="Horizontal"
Grid.Row="2"
Margin="100 5 0 0">
<TextBlock
Style="{StaticResource TextBlockEnabledStyle}"
Text="{x:Static props:Resources.Left}"
IsEnabled="{Binding EditPositionEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
FontSize="14"
FontWeight="Normal"
VerticalAlignment="Center" />
<TextBox
Margin="15 0 0 0"
x:Name="LeftTextBox"
Text="{Binding Position.X, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding EditPositionEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Background="{DynamicResource TertiaryBackgroundBrush}"
BorderThickness="0"
FontSize="14"
FontWeight="Normal"
VerticalContentAlignment="Center"
HorizontalAlignment="Stretch"
TextChanged="LeftTextBox_TextChanged"/>
<TextBlock
Text="{x:Static props:Resources.Top}"
Margin="15 0 0 0"
Style="{StaticResource TextBlockEnabledStyle}"
IsEnabled="{Binding EditPositionEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
FontSize="14"
FontWeight="Normal"
VerticalAlignment="Center" />
<TextBox
Margin="15 0 0 0"
x:Name="TopTextBox"
Text="{Binding Position.Y, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding EditPositionEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Background="{DynamicResource TertiaryBackgroundBrush}"
BorderThickness="0"
FontSize="14"
FontWeight="Normal"
VerticalContentAlignment="Center"
HorizontalAlignment="Stretch"
TextChanged="TopTextBox_TextChanged"/>
<TextBlock
Text="{x:Static props:Resources.Width}"
Margin="15 0 0 0"
Style="{StaticResource TextBlockEnabledStyle}"
IsEnabled="{Binding EditPositionEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
FontSize="14"
FontWeight="Normal"
VerticalAlignment="Center" />
<TextBox
Margin="15 0 0 0"
x:Name="WidthTextBox"
Text="{Binding Position.Width, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding EditPositionEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Background="{DynamicResource TertiaryBackgroundBrush}"
BorderThickness="0"
FontSize="14"
FontWeight="Normal"
VerticalContentAlignment="Center"
HorizontalAlignment="Stretch"
TextChanged="WidthTextBox_TextChanged"/>
<TextBlock
Text="{x:Static props:Resources.Height}"
Margin="15 0 0 0"
Style="{StaticResource TextBlockEnabledStyle}"
IsEnabled="{Binding EditPositionEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
FontSize="14"
FontWeight="Normal"
VerticalAlignment="Center" />
<TextBox
Margin="15 0 0 0"
x:Name="HeightTextBox"
Text="{Binding Position.Height, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding EditPositionEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Background="{DynamicResource TertiaryBackgroundBrush}"
BorderThickness="0"
FontSize="14"
FontWeight="Normal"
VerticalContentAlignment="Center"
HorizontalAlignment="Stretch"
TextChanged="HeightTextBox_TextChanged"/>
</StackPanel>
</Grid>
</Expander>
</Border>
</DataTemplate>
<models:AppListDataTemplateSelector

View File

@@ -27,7 +27,9 @@ namespace ProjectsEditor
private void SaveButtonClicked(object sender, RoutedEventArgs e)
{
_mainViewModel.SwitchToMainView();
Project projectToSave = this.DataContext as Project;
projectToSave.CloseExpanders();
if (projectToSave.EditorWindowTitle == Properties.Resources.CreateProject)
{
_mainViewModel.AddNewProject(projectToSave);
@@ -36,8 +38,6 @@ namespace ProjectsEditor
{
_mainViewModel.SaveProject(projectToSave);
}
_mainViewModel.SwitchToMainView();
}
private void CancelButtonClicked(object sender, RoutedEventArgs e)
@@ -49,13 +49,21 @@ namespace ProjectsEditor
_mainViewModel.SwitchToMainView();
}
private void DeleteButtonClicked(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
Models.Application app = button.DataContext as Models.Application;
app.SwitchDeletion();
}
private void EditNameTextBoxKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
e.Handled = true;
Project project = this.DataContext as Project;
project.Name = EditNameTextBox.Text;
TextBox textBox = sender as TextBox;
project.Name = textBox.Text;
}
else if (e.Key == Key.Escape)
{
@@ -91,8 +99,90 @@ namespace ProjectsEditor
private void EditNameTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
Project project = this.DataContext as Project;
project.Name = EditNameTextBox.Text;
TextBox textBox = sender as TextBox;
project.Name = textBox.Text;
project.OnPropertyChanged(new PropertyChangedEventArgs(nameof(Project.CanBeSaved)));
}
private void LeftTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
Models.Application application = textBox.DataContext as Models.Application;
int newPos;
if (!int.TryParse(textBox.Text, out newPos))
{
newPos = 0;
}
application.Position = new Models.Application.WindowPosition() { X = newPos, Y = application.Position.Y, Width = application.Position.Width, Height = application.Position.Height };
Project project = application.Parent;
project.Initialize();
}
private void TopTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
Models.Application application = textBox.DataContext as Models.Application;
int newPos;
if (!int.TryParse(textBox.Text, out newPos))
{
newPos = 0;
}
application.Position = new Models.Application.WindowPosition() { X = application.Position.X, Y = newPos, Width = application.Position.Width, Height = application.Position.Height };
Project project = application.Parent;
project.Initialize();
}
private void WidthTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
Models.Application application = textBox.DataContext as Models.Application;
int newPos;
if (!int.TryParse(textBox.Text, out newPos))
{
newPos = 0;
}
application.Position = new Models.Application.WindowPosition() { X = application.Position.X, Y = application.Position.Y, Width = newPos, Height = application.Position.Height };
Project project = application.Parent;
project.Initialize();
}
private void HeightTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
Models.Application application = textBox.DataContext as Models.Application;
int newPos;
if (!int.TryParse(textBox.Text, out newPos))
{
newPos = 0;
}
application.Position = new Models.Application.WindowPosition() { X = application.Position.X, Y = application.Position.Y, Width = application.Position.Width, Height = newPos };
Project project = application.Parent;
project.Initialize();
}
private void CommandLineTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
Models.Application application = textBox.DataContext as Models.Application;
application.CommandLineTextChanged(textBox.Text);
}
private void MaximizedChecked(object sender, RoutedEventArgs e)
{
CheckBox checkBox = sender as CheckBox;
Models.Application application = checkBox.DataContext as Models.Application;
application.MaximizedChecked();
}
private void MinimizedChecked(object sender, RoutedEventArgs e)
{
CheckBox checkBox = sender as CheckBox;
Models.Application application = checkBox.DataContext as Models.Application;
application.MinimizedChecked();
}
}
}

View File

@@ -60,6 +60,24 @@ namespace ProjectsEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Add Back.
/// </summary>
public static string AddBack {
get {
return ResourceManager.GetString("AddBack", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Admin.
/// </summary>
public static string Admin {
get {
return ResourceManager.GetString("Admin", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to app.
/// </summary>
@@ -105,6 +123,15 @@ namespace ProjectsEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Args.
/// </summary>
public static string Args {
get {
return ResourceManager.GetString("Args", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cancel.
/// </summary>
@@ -114,6 +141,15 @@ namespace ProjectsEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to CLI arguments.
/// </summary>
public static string CliArguments {
get {
return ResourceManager.GetString("CliArguments", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Created.
/// </summary>
@@ -222,6 +258,15 @@ namespace ProjectsEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Height.
/// </summary>
public static string Height {
get {
return ResourceManager.GetString("Height", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to hours ago.
/// </summary>
@@ -258,6 +303,24 @@ namespace ProjectsEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Launch as Admin.
/// </summary>
public static string LaunchAsAdmin {
get {
return ResourceManager.GetString("LaunchAsAdmin", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Left.
/// </summary>
public static string Left {
get {
return ResourceManager.GetString("Left", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Projects demo app.
/// </summary>
@@ -267,6 +330,24 @@ namespace ProjectsEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Maximized.
/// </summary>
public static string Maximized {
get {
return ResourceManager.GetString("Maximized", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Minimized.
/// </summary>
public static string Minimized {
get {
return ResourceManager.GetString("Minimized", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Minimized Apps.
/// </summary>
@@ -528,6 +609,24 @@ namespace ProjectsEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Top.
/// </summary>
public static string Top {
get {
return ResourceManager.GetString("Top", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Width.
/// </summary>
public static string Width {
get {
return ResourceManager.GetString("Width", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Write arguments here.
/// </summary>

View File

@@ -117,6 +117,12 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AddBack" xml:space="preserve">
<value>Add Back</value>
</data>
<data name="Admin" xml:space="preserve">
<value>Admin</value>
</data>
<data name="App" xml:space="preserve">
<value>app</value>
</data>
@@ -132,9 +138,16 @@
<data name="Are_You_Sure_Description" xml:space="preserve">
<value>Are you sure you want to delete this project?</value>
</data>
<data name="Args" xml:space="preserve">
<value>Args</value>
<comment>Arguments</comment>
</data>
<data name="Cancel" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="CliArguments" xml:space="preserve">
<value>CLI arguments</value>
</data>
<data name="Created" xml:space="preserve">
<value>Created</value>
</data>
@@ -171,6 +184,9 @@
<data name="Error_Parsing_Message" xml:space="preserve">
<value>Error parsing projects data.</value>
</data>
<data name="Height" xml:space="preserve">
<value>Height</value>
</data>
<data name="HoursAgo" xml:space="preserve">
<value>hours ago</value>
</data>
@@ -180,12 +196,25 @@
<data name="Launch" xml:space="preserve">
<value>Launch</value>
</data>
<data name="LaunchAsAdmin" xml:space="preserve">
<value>Launch as Admin</value>
</data>
<data name="Launch_args" xml:space="preserve">
<value>Launch args</value>
</data>
<data name="Left" xml:space="preserve">
<value>Left</value>
<comment>the left x coordinate</comment>
</data>
<data name="MainTitle" xml:space="preserve">
<value>Projects demo app</value>
</data>
<data name="Maximized" xml:space="preserve">
<value>Maximized</value>
</data>
<data name="Minimized" xml:space="preserve">
<value>Minimized</value>
</data>
<data name="Minimized_Apps" xml:space="preserve">
<value>Minimized Apps</value>
</data>
@@ -273,6 +302,13 @@
<data name="Take_Snapshot" xml:space="preserve">
<value>Capture</value>
</data>
<data name="Top" xml:space="preserve">
<value>Top</value>
<comment>the top y coordinate</comment>
</data>
<data name="Width" xml:space="preserve">
<value>Width</value>
</data>
<data name="WriteArgs" xml:space="preserve">
<value>Write arguments here</value>
</data>

View File

@@ -14,21 +14,24 @@ using System.Linq;
using System.Windows.Media.Imaging;
using ManagedCommon;
using ProjectsEditor.Models;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TextBox;
namespace ProjectsEditor.Utils
{
public class DrawHelper
{
private static Font font = new("Tahoma", 24);
private static double scale = 0.1;
private static double gapWidth;
private static double gapHeight;
public static BitmapImage DrawPreview(Project project, Rectangle bounds)
{
List<double> horizontalGaps = new List<double>();
List<double> verticalGaps = new List<double>();
double gapWidth = bounds.Width * 0.01;
double gapHeight = bounds.Height * 0.01;
gapWidth = bounds.Width * 0.01;
gapHeight = bounds.Height * 0.01;
double scale = 0.1;
int Scaled(double value)
{
return (int)(value * scale);
@@ -46,9 +49,25 @@ namespace ProjectsEditor.Utils
return Scaled(posY - bounds.Top + gapTransform);
}
Rectangle GetAppRect(Application app)
{
if (app.Maximized)
{
Project project = app.Parent;
var monitor = project.Monitors.Where(x => x.MonitorNumber == app.MonitorNumber).FirstOrDefault();
return new Rectangle(TransformX(monitor.MonitorDpiAwareBounds.Left), TransformY(monitor.MonitorDpiAwareBounds.Top), Scaled(monitor.MonitorDpiAwareBounds.Width), Scaled(monitor.MonitorDpiAwareBounds.Height));
}
else
{
return new Rectangle(TransformX(app.ScaledPosition.X), TransformY(app.ScaledPosition.Y), Scaled(app.ScaledPosition.Width), Scaled(app.ScaledPosition.Height));
}
}
Dictionary<string, int> repeatCounter = new Dictionary<string, int>();
foreach (Application app in project.Applications)
var appsIncluded = project.Applications.Where(x => x.IsIncluded);
foreach (Application app in appsIncluded)
{
if (repeatCounter.TryGetValue(app.AppPath, out int value))
{
@@ -62,13 +81,7 @@ namespace ProjectsEditor.Utils
app.RepeatIndex = repeatCounter[app.AppPath];
}
// remove those repeatIndexes, which are single 1-es (no repetitions) by setting them to 0
foreach (Application app in project.Applications.Where(x => repeatCounter[x.AppPath] == 1))
{
app.RepeatIndex = 0;
}
foreach (Application app in project.Applications)
foreach (Application app in project.Applications.Where(x => !x.IsIncluded))
{
app.RepeatIndex = 0;
}
@@ -112,18 +125,18 @@ namespace ProjectsEditor.Utils
g.FillRectangle(monitorBrush, new Rectangle(TransformX(monitor.MonitorDpiAwareBounds.Left), TransformY(monitor.MonitorDpiAwareBounds.Top), Scaled(monitor.MonitorDpiAwareBounds.Width), Scaled(monitor.MonitorDpiAwareBounds.Height)));
}
var appsToDraw = project.Applications.Where(x => !x.Minimized);
var appsToDraw = appsIncluded.Where(x => !x.Minimized);
// draw the highlighted app at the end to have its icon in the foreground for the case there are overlapping icons
foreach (Application app in appsToDraw.Where(x => !x.IsHighlighted))
{
Rectangle rect = new Rectangle(TransformX(app.ScaledPosition.X), TransformY(app.ScaledPosition.Y), Scaled(app.ScaledPosition.Width), Scaled(app.ScaledPosition.Height));
Rectangle rect = GetAppRect(app);
DrawWindow(g, brush, rect, app, desiredIconSize);
}
foreach (Application app in appsToDraw.Where(x => x.IsHighlighted))
{
Rectangle rect = new Rectangle(TransformX(app.ScaledPosition.X), TransformY(app.ScaledPosition.Y), Scaled(app.ScaledPosition.Width), Scaled(app.ScaledPosition.Height));
Rectangle rect = GetAppRect(app);
DrawWindow(g, brushForHighlight, rect, app, desiredIconSize);
}
@@ -180,7 +193,7 @@ namespace ProjectsEditor.Utils
try
{
graphics.DrawIcon(app.Icon, iconBounds);
if (app.RepeatIndex > 0)
if (app.RepeatIndex > 1)
{
string indexString = app.RepeatIndex.ToString(CultureInfo.InvariantCulture);
int indexSize = (int)(iconBounds.Width * 0.5);

View File

@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using ManagedCommon;
using ProjectsEditor.Data;
@@ -85,7 +86,7 @@ namespace ProjectsEditor.Utils
foreach (var app in project.Applications)
{
newProject.Applications.Add(new Models.Application()
Models.Application newApp = new Models.Application()
{
AppName = app.Application,
AppPath = app.ApplicationPath,
@@ -93,6 +94,7 @@ namespace ProjectsEditor.Utils
PackageFullName = app.PackageFullName,
Parent = newProject,
CommandLineArguments = app.CommandLineArguments,
LaunchesAsAdmin = app.LaunchesAsAdmin,
Maximized = app.Maximized,
Minimized = app.Minimized,
IsNotFound = false,
@@ -104,7 +106,9 @@ namespace ProjectsEditor.Utils
Y = app.Position.Y,
},
MonitorNumber = app.Monitor,
});
};
newApp.InitializationFinished();
newProject.Applications.Add(newApp);
}
foreach (var monitor in project.MonitorConfiguration)
@@ -136,7 +140,7 @@ namespace ProjectsEditor.Utils
MonitorConfiguration = new List<ProjectData.MonitorConfigurationWrapper> { },
};
foreach (var app in project.Applications)
foreach (var app in project.Applications.Where(x => x.IsIncluded))
{
wrapper.Applications.Add(new ProjectData.ApplicationWrapper
{
@@ -145,6 +149,7 @@ namespace ProjectsEditor.Utils
Title = app.AppTitle,
PackageFullName = app.PackageFullName,
CommandLineArguments = app.CommandLineArguments,
LaunchesAsAdmin = app.LaunchesAsAdmin,
Maximized = app.Maximized,
Minimized = app.Minimized,
Position = new ProjectData.ApplicationWrapper.WindowPositionWrapper

View File

@@ -161,7 +161,7 @@ namespace ProjectsEditor.ViewModels
editedProject.IsShortcutNeeded = projectToSave.IsShortcutNeeded;
editedProject.PreviewIcons = projectToSave.PreviewIcons;
editedProject.PreviewImage = projectToSave.PreviewImage;
editedProject.Applications = projectToSave.Applications;
editedProject.Applications = projectToSave.Applications.Where(x => x.IsIncluded).ToList();
editedProject.OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("AppsCountString"));
editedProject.Initialize();
@@ -233,7 +233,12 @@ namespace ProjectsEditor.ViewModels
public void EditProject(Project selectedProject, bool isNewlyCreated = false)
{
var editPage = new ProjectEditor(this);
SetEditedProject(selectedProject);
if (!isNewlyCreated)
{
selectedProject = new Project(selectedProject);
}
if (isNewlyCreated)
{