mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
Merge branch 'dev/feature/projects' of https://github.com/microsoft/PowerToys into dev/feature/projects
This commit is contained in:
@@ -51,6 +51,26 @@ namespace ProjectsEditor.Models
|
|||||||
|
|
||||||
public bool Maximized { get; set; }
|
public bool Maximized { get; set; }
|
||||||
|
|
||||||
|
private bool _isNotFound;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public bool IsNotFound
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _isNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_isNotFound != value)
|
||||||
|
{
|
||||||
|
_isNotFound = value;
|
||||||
|
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsNotFound)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool IsSelected { get; set; }
|
public bool IsSelected { get; set; }
|
||||||
|
|
||||||
@@ -85,9 +105,17 @@ namespace ProjectsEditor.Models
|
|||||||
{
|
{
|
||||||
Task<AppListEntry> task = Task.Run<AppListEntry>(async () => await GetAppByPackageFamilyNameAsync());
|
Task<AppListEntry> task = Task.Run<AppListEntry>(async () => await GetAppByPackageFamilyNameAsync());
|
||||||
AppListEntry packApp = task.Result;
|
AppListEntry packApp = task.Result;
|
||||||
string filename = Path.GetFileName(AppPath);
|
if (packApp == null)
|
||||||
string newExeLocation = Path.Combine(packApp.AppInfo.Package.InstalledPath, filename);
|
{
|
||||||
_icon = Icon.ExtractAssociatedIcon(newExeLocation);
|
IsNotFound = true;
|
||||||
|
_icon = new Icon(@"images\DefaultIcon.ico");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string filename = Path.GetFileName(AppPath);
|
||||||
|
string newExeLocation = Path.Combine(packApp.AppInfo.Package.InstalledPath, filename);
|
||||||
|
_icon = Icon.ExtractAssociatedIcon(newExeLocation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -97,6 +125,7 @@ namespace ProjectsEditor.Models
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.LogError($"Exception while extracting icon from app path: {AppPath}. Exception message: {e.Message}");
|
Logger.LogError($"Exception while extracting icon from app path: {AppPath}. Exception message: {e.Message}");
|
||||||
|
IsNotFound = true;
|
||||||
_icon = new Icon(@"images\DefaultIcon.ico");
|
_icon = new Icon(@"images\DefaultIcon.ico");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,6 +213,7 @@ namespace ProjectsEditor.Models
|
|||||||
Maximized = item.Maximized,
|
Maximized = item.Maximized,
|
||||||
IsSelected = item.IsSelected,
|
IsSelected = item.IsSelected,
|
||||||
MonitorNumber = item.MonitorNumber,
|
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 },
|
Position = new Application.WindowPosition() { X = item.Position.X, Y = item.Position.Y, Height = item.Position.Height, Width = item.Position.Width },
|
||||||
Parent = this,
|
Parent = this,
|
||||||
});
|
});
|
||||||
@@ -246,7 +247,7 @@ namespace ProjectsEditor.Models
|
|||||||
|
|
||||||
public async void Initialize()
|
public async void Initialize()
|
||||||
{
|
{
|
||||||
PreviewImage = await Task.Run(() => DrawPreviewIcons());
|
PreviewImage = await Task.Run(() => DrawHelper.DrawPreviewIcons(this));
|
||||||
foreach (MonitorSetup monitor in Monitors)
|
foreach (MonitorSetup monitor in Monitors)
|
||||||
{
|
{
|
||||||
System.Windows.Rect rect = monitor.MonitorDpiAwareBounds;
|
System.Windows.Rect rect = monitor.MonitorDpiAwareBounds;
|
||||||
@@ -254,53 +255,6 @@ namespace ProjectsEditor.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private BitmapImage DrawPreviewIcons()
|
|
||||||
{
|
|
||||||
var selectedApps = Applications.Where(x => x.IsSelected);
|
|
||||||
int appsCount = selectedApps.Count();
|
|
||||||
if (appsCount == 0)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bitmap previewBitmap = new Bitmap(32 * appsCount, 24);
|
|
||||||
using (Graphics graphics = Graphics.FromImage(previewBitmap))
|
|
||||||
{
|
|
||||||
graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
|
||||||
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
||||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
|
||||||
int appIndex = 0;
|
|
||||||
foreach (var app in selectedApps)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
graphics.DrawIcon(app.Icon, new Rectangle(32 * appIndex, 0, 24, 24));
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Logger.LogError($"Exception while drawing the icon for app {Name}. Exception message: {e.Message}");
|
|
||||||
}
|
|
||||||
|
|
||||||
appIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var memory = new MemoryStream())
|
|
||||||
{
|
|
||||||
previewBitmap.Save(memory, ImageFormat.Png);
|
|
||||||
memory.Position = 0;
|
|
||||||
|
|
||||||
var bitmapImage = new BitmapImage();
|
|
||||||
bitmapImage.BeginInit();
|
|
||||||
bitmapImage.StreamSource = memory;
|
|
||||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
|
||||||
bitmapImage.EndInit();
|
|
||||||
bitmapImage.Freeze();
|
|
||||||
|
|
||||||
return bitmapImage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Rectangle GetCommonBounds()
|
private Rectangle GetCommonBounds()
|
||||||
{
|
{
|
||||||
double minX = Monitors.First().MonitorDpiUnawareBounds.Left;
|
double minX = Monitors.First().MonitorDpiUnawareBounds.Left;
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
Title="Project Editor"
|
Title="Project Editor"
|
||||||
Background="{DynamicResource PrimaryBackgroundBrush}">
|
Background="{DynamicResource PrimaryBackgroundBrush}">
|
||||||
<Page.Resources>
|
<Page.Resources>
|
||||||
|
<BooleanToVisibilityConverter x:Key="BoolToVis" />
|
||||||
|
|
||||||
<DataTemplate x:Key="headerTemplate">
|
<DataTemplate x:Key="headerTemplate">
|
||||||
<Border>
|
<Border>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
@@ -28,13 +30,25 @@
|
|||||||
MouseLeave="AppBorder_MouseLeave">
|
MouseLeave="AppBorder_MouseLeave">
|
||||||
<Grid Margin="5">
|
<Grid Margin="5">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="20"/>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
<ColumnDefinition Width="3*"/>
|
<ColumnDefinition Width="3*"/>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock
|
||||||
|
Text=""
|
||||||
|
Foreground="Red"
|
||||||
|
FontSize="14"
|
||||||
|
FontFamily="{DynamicResource SymbolThemeFontFamily}"
|
||||||
|
FontWeight="Normal"
|
||||||
|
Margin="2 0"
|
||||||
|
ToolTip="{x:Static props:Resources.NotFoundTooltip}"
|
||||||
|
Visibility="{Binding IsNotFound, Converter={StaticResource BoolToVis}, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
<Image
|
<Image
|
||||||
|
Grid.Column="1"
|
||||||
Width="20"
|
Width="20"
|
||||||
Height="20"
|
Height="20"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
@@ -42,7 +56,7 @@
|
|||||||
Margin="10"
|
Margin="10"
|
||||||
Source="{Binding IconBitmapImage}"/>
|
Source="{Binding IconBitmapImage}"/>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Column="1"
|
Grid.Column="2"
|
||||||
Text="{Binding RepeatIndexString, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
|
Text="{Binding RepeatIndexString, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
Foreground="{DynamicResource PrimaryForegroundBrush}"
|
Foreground="{DynamicResource PrimaryForegroundBrush}"
|
||||||
FontSize="14"
|
FontSize="14"
|
||||||
@@ -50,7 +64,7 @@
|
|||||||
Width="20"
|
Width="20"
|
||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center"/>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Column="2"
|
Grid.Column="3"
|
||||||
Text="{Binding AppName}"
|
Text="{Binding AppName}"
|
||||||
Foreground="{DynamicResource PrimaryForegroundBrush}"
|
Foreground="{DynamicResource PrimaryForegroundBrush}"
|
||||||
FontSize="14"
|
FontSize="14"
|
||||||
@@ -58,7 +72,7 @@
|
|||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center"/>
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="CommandLineTextBox"
|
x:Name="CommandLineTextBox"
|
||||||
Grid.Column="3"
|
Grid.Column="4"
|
||||||
Text="{Binding CommandLineArguments, Mode=TwoWay}"
|
Text="{Binding CommandLineArguments, Mode=TwoWay}"
|
||||||
Foreground="{DynamicResource PrimaryForegroundBrush}"
|
Foreground="{DynamicResource PrimaryForegroundBrush}"
|
||||||
Background="{DynamicResource TertiaryBackgroundBrush}"
|
Background="{DynamicResource TertiaryBackgroundBrush}"
|
||||||
@@ -67,7 +81,7 @@
|
|||||||
FontWeight="Normal"
|
FontWeight="Normal"
|
||||||
VerticalContentAlignment="Center" />
|
VerticalContentAlignment="Center" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Column="3"
|
Grid.Column="4"
|
||||||
IsHitTestVisible="False"
|
IsHitTestVisible="False"
|
||||||
Text="{x:Static props:Resources.WriteArgs}"
|
Text="{x:Static props:Resources.WriteArgs}"
|
||||||
Foreground="{DynamicResource SecondaryForegroundBrush}"
|
Foreground="{DynamicResource SecondaryForegroundBrush}"
|
||||||
@@ -88,7 +102,7 @@
|
|||||||
</TextBlock.Style>
|
</TextBlock.Style>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<CheckBox
|
<CheckBox
|
||||||
Grid.Column="4"
|
Grid.Column="5"
|
||||||
IsChecked="{Binding IsSelected, Mode=TwoWay}"
|
IsChecked="{Binding IsSelected, Mode=TwoWay}"
|
||||||
Checked="CheckBox_Checked"
|
Checked="CheckBox_Checked"
|
||||||
Unchecked="CheckBox_Checked"
|
Unchecked="CheckBox_Checked"
|
||||||
|
|||||||
@@ -285,6 +285,15 @@ namespace ProjectsEditor.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to The application cannot be found.
|
||||||
|
/// </summary>
|
||||||
|
public static string NotFoundTooltip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("NotFoundTooltip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to an hour ago.
|
/// Looks up a localized string similar to an hour ago.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -189,6 +189,9 @@
|
|||||||
<data name="New_project" xml:space="preserve">
|
<data name="New_project" xml:space="preserve">
|
||||||
<value>New project</value>
|
<value>New project</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="NotFoundTooltip" xml:space="preserve">
|
||||||
|
<value>The application cannot be found</value>
|
||||||
|
</data>
|
||||||
<data name="No_Projects_Message" xml:space="preserve">
|
<data name="No_Projects_Message" xml:space="preserve">
|
||||||
<value>There are no saved projects.</value>
|
<value>There are no saved projects.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using System.Globalization;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
using ManagedCommon;
|
||||||
using ProjectsEditor.Models;
|
using ProjectsEditor.Models;
|
||||||
|
|
||||||
namespace ProjectsEditor.Utils
|
namespace ProjectsEditor.Utils
|
||||||
@@ -140,11 +141,11 @@ namespace ProjectsEditor.Utils
|
|||||||
{
|
{
|
||||||
if (app.IsHighlighted)
|
if (app.IsHighlighted)
|
||||||
{
|
{
|
||||||
graphics.DrawPath(new Pen(Common.ThemeManager.GetCurrentTheme() == Common.Theme.Dark ? Color.White : Color.DarkGray, graphics.VisibleClipBounds.Height / 25), path);
|
graphics.DrawPath(new Pen(Common.ThemeManager.GetCurrentTheme() == Common.Theme.Dark ? Color.White : Color.DarkGray, graphics.VisibleClipBounds.Height / 50), path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
graphics.DrawPath(new Pen(Common.ThemeManager.GetCurrentTheme() == Common.Theme.Dark ? Color.FromArgb(128, 82, 82, 82) : Color.FromArgb(128, 160, 160, 160), graphics.VisibleClipBounds.Height / 100), path);
|
graphics.DrawPath(new Pen(Common.ThemeManager.GetCurrentTheme() == Common.Theme.Dark ? Color.FromArgb(128, 82, 82, 82) : Color.FromArgb(128, 160, 160, 160), graphics.VisibleClipBounds.Height / 200), path);
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics.FillPath(brush, path);
|
graphics.FillPath(brush, path);
|
||||||
@@ -198,11 +199,11 @@ namespace ProjectsEditor.Utils
|
|||||||
{
|
{
|
||||||
if (apps.Where(x => x.IsHighlighted).Any())
|
if (apps.Where(x => x.IsHighlighted).Any())
|
||||||
{
|
{
|
||||||
graphics.DrawPath(new Pen(Common.ThemeManager.GetCurrentTheme() == Common.Theme.Dark ? Color.White : Color.DarkGray, graphics.VisibleClipBounds.Height / 25), path);
|
graphics.DrawPath(new Pen(Common.ThemeManager.GetCurrentTheme() == Common.Theme.Dark ? Color.White : Color.DarkGray, graphics.VisibleClipBounds.Height / 50), path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
graphics.DrawPath(new Pen(Common.ThemeManager.GetCurrentTheme() == Common.Theme.Dark ? Color.FromArgb(128, 82, 82, 82) : Color.FromArgb(128, 160, 160, 160), graphics.VisibleClipBounds.Height / 100), path);
|
graphics.DrawPath(new Pen(Common.ThemeManager.GetCurrentTheme() == Common.Theme.Dark ? Color.FromArgb(128, 82, 82, 82) : Color.FromArgb(128, 160, 160, 160), graphics.VisibleClipBounds.Height / 200), path);
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics.FillPath(brush, path);
|
graphics.FillPath(brush, path);
|
||||||
@@ -395,6 +396,53 @@ namespace ProjectsEditor.Utils
|
|||||||
return shortcutIconFilename;
|
return shortcutIconFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static BitmapImage DrawPreviewIcons(Project project)
|
||||||
|
{
|
||||||
|
var selectedApps = project.Applications.Where(x => x.IsSelected);
|
||||||
|
int appsCount = selectedApps.Count();
|
||||||
|
if (appsCount == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap previewBitmap = new Bitmap(32 * appsCount, 24);
|
||||||
|
using (Graphics graphics = Graphics.FromImage(previewBitmap))
|
||||||
|
{
|
||||||
|
graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
int appIndex = 0;
|
||||||
|
foreach (var app in selectedApps)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
graphics.DrawIcon(app.Icon, new Rectangle(32 * appIndex, 0, 24, 24));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.LogError($"Exception while drawing the icon for app {app.AppName}. Exception message: {e.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
appIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var memory = new MemoryStream())
|
||||||
|
{
|
||||||
|
previewBitmap.Save(memory, ImageFormat.Png);
|
||||||
|
memory.Position = 0;
|
||||||
|
|
||||||
|
var bitmapImage = new BitmapImage();
|
||||||
|
bitmapImage.BeginInit();
|
||||||
|
bitmapImage.StreamSource = memory;
|
||||||
|
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||||
|
bitmapImage.EndInit();
|
||||||
|
bitmapImage.Freeze();
|
||||||
|
|
||||||
|
return bitmapImage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void CreateExamples(Project project)
|
private static void CreateExamples(Project project)
|
||||||
{
|
{
|
||||||
Bitmap bitmap = new Bitmap(IconSize + 1000, IconSize * iconBrushes.Count);
|
Bitmap bitmap = new Bitmap(IconSize + 1000, IconSize * iconBrushes.Count);
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ namespace ProjectsEditor.Utils
|
|||||||
Maximized = app.Maximized,
|
Maximized = app.Maximized,
|
||||||
Minimized = app.Minimized,
|
Minimized = app.Minimized,
|
||||||
IsSelected = true,
|
IsSelected = true,
|
||||||
|
IsNotFound = false,
|
||||||
Position = new Models.Application.WindowPosition()
|
Position = new Models.Application.WindowPosition()
|
||||||
{
|
{
|
||||||
Height = app.Position.Height,
|
Height = app.Position.Height,
|
||||||
|
|||||||
Reference in New Issue
Block a user