mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 03:37:59 +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; }
|
||||
|
||||
private bool _isNotFound;
|
||||
|
||||
[JsonIgnore]
|
||||
public bool IsNotFound
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isNotFound;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_isNotFound != value)
|
||||
{
|
||||
_isNotFound = value;
|
||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsNotFound)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public bool IsSelected { get; set; }
|
||||
|
||||
@@ -85,9 +105,17 @@ namespace ProjectsEditor.Models
|
||||
{
|
||||
Task<AppListEntry> task = Task.Run<AppListEntry>(async () => await GetAppByPackageFamilyNameAsync());
|
||||
AppListEntry packApp = task.Result;
|
||||
string filename = Path.GetFileName(AppPath);
|
||||
string newExeLocation = Path.Combine(packApp.AppInfo.Package.InstalledPath, filename);
|
||||
_icon = Icon.ExtractAssociatedIcon(newExeLocation);
|
||||
if (packApp == null)
|
||||
{
|
||||
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
|
||||
{
|
||||
@@ -97,6 +125,7 @@ namespace ProjectsEditor.Models
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError($"Exception while extracting icon from app path: {AppPath}. Exception message: {e.Message}");
|
||||
IsNotFound = true;
|
||||
_icon = new Icon(@"images\DefaultIcon.ico");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,6 +213,7 @@ namespace ProjectsEditor.Models
|
||||
Maximized = item.Maximized,
|
||||
IsSelected = item.IsSelected,
|
||||
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,
|
||||
});
|
||||
@@ -246,7 +247,7 @@ namespace ProjectsEditor.Models
|
||||
|
||||
public async void Initialize()
|
||||
{
|
||||
PreviewImage = await Task.Run(() => DrawPreviewIcons());
|
||||
PreviewImage = await Task.Run(() => DrawHelper.DrawPreviewIcons(this));
|
||||
foreach (MonitorSetup monitor in Monitors)
|
||||
{
|
||||
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()
|
||||
{
|
||||
double minX = Monitors.First().MonitorDpiUnawareBounds.Left;
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
Title="Project Editor"
|
||||
Background="{DynamicResource PrimaryBackgroundBrush}">
|
||||
<Page.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis" />
|
||||
|
||||
<DataTemplate x:Key="headerTemplate">
|
||||
<Border>
|
||||
<TextBlock
|
||||
@@ -28,13 +30,25 @@
|
||||
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=""
|
||||
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
|
||||
Grid.Column="1"
|
||||
Width="20"
|
||||
Height="20"
|
||||
HorizontalAlignment="Center"
|
||||
@@ -42,7 +56,7 @@
|
||||
Margin="10"
|
||||
Source="{Binding IconBitmapImage}"/>
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
Grid.Column="2"
|
||||
Text="{Binding RepeatIndexString, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Foreground="{DynamicResource PrimaryForegroundBrush}"
|
||||
FontSize="14"
|
||||
@@ -50,7 +64,7 @@
|
||||
Width="20"
|
||||
VerticalAlignment="Center"/>
|
||||
<TextBlock
|
||||
Grid.Column="2"
|
||||
Grid.Column="3"
|
||||
Text="{Binding AppName}"
|
||||
Foreground="{DynamicResource PrimaryForegroundBrush}"
|
||||
FontSize="14"
|
||||
@@ -58,7 +72,7 @@
|
||||
VerticalAlignment="Center"/>
|
||||
<TextBox
|
||||
x:Name="CommandLineTextBox"
|
||||
Grid.Column="3"
|
||||
Grid.Column="4"
|
||||
Text="{Binding CommandLineArguments, Mode=TwoWay}"
|
||||
Foreground="{DynamicResource PrimaryForegroundBrush}"
|
||||
Background="{DynamicResource TertiaryBackgroundBrush}"
|
||||
@@ -67,7 +81,7 @@
|
||||
FontWeight="Normal"
|
||||
VerticalContentAlignment="Center" />
|
||||
<TextBlock
|
||||
Grid.Column="3"
|
||||
Grid.Column="4"
|
||||
IsHitTestVisible="False"
|
||||
Text="{x:Static props:Resources.WriteArgs}"
|
||||
Foreground="{DynamicResource SecondaryForegroundBrush}"
|
||||
@@ -88,7 +102,7 @@
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
<CheckBox
|
||||
Grid.Column="4"
|
||||
Grid.Column="5"
|
||||
IsChecked="{Binding IsSelected, Mode=TwoWay}"
|
||||
Checked="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>
|
||||
/// Looks up a localized string similar to an hour ago.
|
||||
/// </summary>
|
||||
|
||||
@@ -189,6 +189,9 @@
|
||||
<data name="New_project" xml:space="preserve">
|
||||
<value>New project</value>
|
||||
</data>
|
||||
<data name="NotFoundTooltip" xml:space="preserve">
|
||||
<value>The application cannot be found</value>
|
||||
</data>
|
||||
<data name="No_Projects_Message" xml:space="preserve">
|
||||
<value>There are no saved projects.</value>
|
||||
</data>
|
||||
|
||||
@@ -12,6 +12,7 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Media.Imaging;
|
||||
using ManagedCommon;
|
||||
using ProjectsEditor.Models;
|
||||
|
||||
namespace ProjectsEditor.Utils
|
||||
@@ -140,11 +141,11 @@ namespace ProjectsEditor.Utils
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
@@ -198,11 +199,11 @@ namespace ProjectsEditor.Utils
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
@@ -395,6 +396,53 @@ namespace ProjectsEditor.Utils
|
||||
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)
|
||||
{
|
||||
Bitmap bitmap = new Bitmap(IconSize + 1000, IconSize * iconBrushes.Count);
|
||||
|
||||
@@ -118,6 +118,7 @@ namespace ProjectsEditor.Utils
|
||||
Maximized = app.Maximized,
|
||||
Minimized = app.Minimized,
|
||||
IsSelected = true,
|
||||
IsNotFound = false,
|
||||
Position = new Models.Application.WindowPosition()
|
||||
{
|
||||
Height = app.Position.Height,
|
||||
|
||||
Reference in New Issue
Block a user