mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 11:17:53 +01:00
[Projects] Re-implementing preview drawing - one common image
This commit is contained in:
@@ -210,7 +210,7 @@
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,0,8" >
|
||||
<Image
|
||||
Source="{Binding PreviewImage, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Source="{Binding PreviewIcons, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Height="20" />
|
||||
<TextBlock
|
||||
Text="{Binding AppsCountString}"
|
||||
|
||||
@@ -10,22 +10,6 @@ namespace ProjectsEditor.Models
|
||||
{
|
||||
public class MonitorSetup : Monitor, INotifyPropertyChanged
|
||||
{
|
||||
private BitmapImage _previewImage;
|
||||
|
||||
public BitmapImage PreviewImage
|
||||
{
|
||||
get
|
||||
{
|
||||
return _previewImage;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_previewImage = value;
|
||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(PreviewImage)));
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public void OnPropertyChanged(PropertyChangedEventArgs e)
|
||||
|
||||
@@ -184,11 +184,14 @@ namespace ProjectsEditor.Models
|
||||
|
||||
public List<MonitorSetup> Monitors { get; set; }
|
||||
|
||||
private BitmapImage _previewIcons;
|
||||
private BitmapImage _previewImage;
|
||||
private double _previewImageWidth;
|
||||
|
||||
public Project(Project selectedProject)
|
||||
{
|
||||
Name = selectedProject.Name;
|
||||
PreviewIcons = selectedProject.PreviewIcons;
|
||||
PreviewImage = selectedProject.PreviewImage;
|
||||
IsShortcutNeeded = selectedProject.IsShortcutNeeded;
|
||||
|
||||
@@ -197,7 +200,7 @@ namespace ProjectsEditor.Models
|
||||
Monitors = new List<MonitorSetup>();
|
||||
foreach (var item in selectedProject.Monitors.OrderBy(x => x.MonitorDpiAwareBounds.Left).ThenBy(x => x.MonitorDpiAwareBounds.Top))
|
||||
{
|
||||
Monitors.Add(new MonitorSetup($"Screen {screenIndex}", item.MonitorInstanceId, item.MonitorNumber, item.Dpi, item.MonitorDpiAwareBounds, item.MonitorDpiUnawareBounds) { PreviewImage = item.PreviewImage });
|
||||
Monitors.Add(new MonitorSetup($"Screen {screenIndex}", item.MonitorInstanceId, item.MonitorNumber, item.Dpi, item.MonitorDpiAwareBounds, item.MonitorDpiUnawareBounds));
|
||||
screenIndex++;
|
||||
}
|
||||
|
||||
@@ -226,6 +229,20 @@ namespace ProjectsEditor.Models
|
||||
{
|
||||
}
|
||||
|
||||
public BitmapImage PreviewIcons
|
||||
{
|
||||
get
|
||||
{
|
||||
return _previewIcons;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_previewIcons = value;
|
||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(PreviewIcons)));
|
||||
}
|
||||
}
|
||||
|
||||
public BitmapImage PreviewImage
|
||||
{
|
||||
get
|
||||
@@ -240,6 +257,20 @@ namespace ProjectsEditor.Models
|
||||
}
|
||||
}
|
||||
|
||||
public double PreviewImageWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
return _previewImageWidth;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_previewImageWidth = value;
|
||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(PreviewImageWidth)));
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public void OnPropertyChanged(PropertyChangedEventArgs e)
|
||||
@@ -249,12 +280,10 @@ namespace ProjectsEditor.Models
|
||||
|
||||
public async void Initialize()
|
||||
{
|
||||
PreviewImage = await Task.Run(() => DrawHelper.DrawPreviewIcons(this));
|
||||
foreach (MonitorSetup monitor in Monitors)
|
||||
{
|
||||
System.Windows.Rect rect = monitor.MonitorDpiAwareBounds;
|
||||
monitor.PreviewImage = await Task.Run(() => DrawHelper.DrawPreview(this, new Rectangle((int)rect.Left, (int)rect.Top, (int)(rect.Right - rect.Left), (int)(rect.Bottom - rect.Top))));
|
||||
}
|
||||
PreviewIcons = await Task.Run(() => DrawHelper.DrawPreviewIcons(this));
|
||||
Rectangle commonBounds = GetCommonBounds();
|
||||
PreviewImage = await Task.Run(() => DrawHelper.DrawPreview(this, commonBounds));
|
||||
PreviewImageWidth = commonBounds.Width / (commonBounds.Height * 1.2 / 200);
|
||||
}
|
||||
|
||||
private Rectangle GetCommonBounds()
|
||||
|
||||
@@ -171,45 +171,12 @@
|
||||
HorizontalAlignment="Stretch"
|
||||
Background="{DynamicResource MonitorViewBackgroundBrush}"
|
||||
CornerRadius="5">
|
||||
<ScrollViewer
|
||||
HorizontalAlignment="Center"
|
||||
HorizontalScrollBarVisibility="Auto">
|
||||
<ItemsControl
|
||||
ItemsSource="{Binding Monitors, Mode=OneWay}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel
|
||||
IsItemsHost="True"
|
||||
Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="models:MonitorSetup">
|
||||
<Grid
|
||||
Margin="20,20,20,20">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Text="{Binding MonitorInfoWithResolution}" Foreground="{DynamicResource PrimaryForegroundBrush}" FontSize="16" FontWeight="Normal" Margin="0,5,0,5"/>
|
||||
<Border
|
||||
Grid.Row="1"
|
||||
CornerRadius="5"
|
||||
BorderBrush="{DynamicResource TertiaryBackgroundBrush}"
|
||||
BorderThickness="2"
|
||||
Margin="0,0,0,10">
|
||||
<Image
|
||||
Width="200"
|
||||
Height="140"
|
||||
Source="{Binding PreviewImage, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Stretch="Fill"
|
||||
Margin="2"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
<Image
|
||||
Width="{Binding PreviewImageWidth, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Height="200"
|
||||
Source="{Binding PreviewImage, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Stretch="Fill"
|
||||
Margin="2"/>
|
||||
</Border>
|
||||
<ScrollViewer
|
||||
Margin="0,10,0,0"
|
||||
|
||||
@@ -23,12 +23,29 @@ namespace ProjectsEditor.Utils
|
||||
|
||||
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;
|
||||
|
||||
double scale = 0.1;
|
||||
int Scaled(double value)
|
||||
{
|
||||
return (int)(value * scale);
|
||||
}
|
||||
|
||||
int TransformX(double posX)
|
||||
{
|
||||
double gapTransform = verticalGaps.Where(x => x <= posX).Count() * gapWidth;
|
||||
return Scaled(posX - bounds.Left + gapTransform);
|
||||
}
|
||||
|
||||
int TransformY(double posY)
|
||||
{
|
||||
double gapTransform = horizontalGaps.Where(x => x <= posY).Count() * gapHeight;
|
||||
return Scaled(posY - bounds.Top + gapTransform);
|
||||
}
|
||||
|
||||
Dictionary<string, int> repeatCounter = new Dictionary<string, int>();
|
||||
|
||||
var selectedApps = project.Applications.Where(x => x.IsSelected);
|
||||
@@ -63,7 +80,22 @@ namespace ProjectsEditor.Utils
|
||||
app.OnPropertyChanged(new PropertyChangedEventArgs("RepeatIndexString"));
|
||||
}
|
||||
|
||||
Bitmap previewBitmap = new Bitmap(Scaled(bounds.Width), Scaled(bounds.Height * 1.2));
|
||||
foreach (MonitorSetup monitor in project.Monitors)
|
||||
{
|
||||
// check for vertical gap
|
||||
if (monitor.MonitorDpiAwareBounds.Left > bounds.Left && project.Monitors.Any(x => x.MonitorDpiAwareBounds.Right <= monitor.MonitorDpiAwareBounds.Left))
|
||||
{
|
||||
verticalGaps.Add(monitor.MonitorDpiAwareBounds.Left);
|
||||
}
|
||||
|
||||
// check for horizontal gap
|
||||
if (monitor.MonitorDpiAwareBounds.Top > bounds.Top && project.Monitors.Any(x => x.MonitorDpiAwareBounds.Bottom <= monitor.MonitorDpiAwareBounds.Top))
|
||||
{
|
||||
horizontalGaps.Add(monitor.MonitorDpiAwareBounds.Top);
|
||||
}
|
||||
}
|
||||
|
||||
Bitmap previewBitmap = new Bitmap(Scaled(bounds.Width + (verticalGaps.Count * gapWidth)), Scaled((bounds.Height * 1.2) + (horizontalGaps.Count * gapHeight)));
|
||||
double desiredIconSize = Scaled(Math.Min(bounds.Width, bounds.Height)) * 0.3;
|
||||
using (Graphics g = Graphics.FromImage(previewBitmap))
|
||||
{
|
||||
@@ -71,26 +103,32 @@ namespace ProjectsEditor.Utils
|
||||
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
|
||||
g.Clear(Color.FromArgb(0, 0, 0, 0));
|
||||
Brush brush = new SolidBrush(Common.ThemeManager.GetCurrentTheme() == Common.Theme.Dark ? Color.FromArgb(10, 255, 255, 255) : Color.FromArgb(10, 0, 0, 0));
|
||||
|
||||
// draw the monitors
|
||||
foreach (MonitorSetup monitor in project.Monitors)
|
||||
{
|
||||
Brush monitorBrush = new SolidBrush(Common.ThemeManager.GetCurrentTheme() == Common.Theme.Dark ? Color.FromArgb(32, 7, 91, 155) : Color.FromArgb(32, 7, 91, 155));
|
||||
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.IsSelected && !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(Scaled(app.ScaledPosition.X - bounds.Left), Scaled(app.ScaledPosition.Y - bounds.Top), Scaled(app.ScaledPosition.Width), Scaled(app.ScaledPosition.Height));
|
||||
Rectangle rect = new Rectangle(TransformX(app.ScaledPosition.X), TransformY(app.ScaledPosition.Y), Scaled(app.ScaledPosition.Width), Scaled(app.ScaledPosition.Height));
|
||||
DrawWindow(g, brush, rect, app, desiredIconSize);
|
||||
}
|
||||
|
||||
foreach (Application app in appsToDraw.Where(x => x.IsHighlighted))
|
||||
{
|
||||
Rectangle rect = new Rectangle(Scaled(app.ScaledPosition.X - bounds.Left), Scaled(app.ScaledPosition.Y - bounds.Top), Scaled(app.ScaledPosition.Width), Scaled(app.ScaledPosition.Height));
|
||||
Rectangle rect = new Rectangle(TransformX(app.ScaledPosition.X), TransformY(app.ScaledPosition.Y), Scaled(app.ScaledPosition.Width), Scaled(app.ScaledPosition.Height));
|
||||
DrawWindow(g, brush, rect, app, desiredIconSize);
|
||||
}
|
||||
|
||||
// draw the minimized windows
|
||||
Rectangle rectMinimized = new Rectangle(0, Scaled(bounds.Height), Scaled(bounds.Width), Scaled(bounds.Height * 0.2));
|
||||
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, rectMinimized, project.Applications.Where(x => x.IsSelected && x.Minimized));
|
||||
}
|
||||
|
||||
|
||||
@@ -157,6 +157,7 @@ namespace ProjectsEditor.ViewModels
|
||||
{
|
||||
editedProject.Name = projectToSave.Name;
|
||||
editedProject.IsShortcutNeeded = projectToSave.IsShortcutNeeded;
|
||||
editedProject.PreviewIcons = projectToSave.PreviewIcons;
|
||||
editedProject.PreviewImage = projectToSave.PreviewImage;
|
||||
for (int appIndex = editedProject.Applications.Count - 1; appIndex >= 0; appIndex--)
|
||||
{
|
||||
@@ -249,10 +250,7 @@ namespace ProjectsEditor.ViewModels
|
||||
var editPage = new ProjectEditor(this);
|
||||
SetEditedProject(selectedProject);
|
||||
Project projectEdited = new Project(selectedProject) { EditorWindowTitle = isNewlyCreated ? Properties.Resources.CreateProject : Properties.Resources.EditProject };
|
||||
if (isNewlyCreated)
|
||||
{
|
||||
projectEdited.Initialize();
|
||||
}
|
||||
projectEdited.Initialize();
|
||||
|
||||
editPage.DataContext = projectEdited;
|
||||
_mainWindow.ShowPage(editPage);
|
||||
|
||||
Reference in New Issue
Block a user