Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 60 additions & 6 deletions FoliCon/Modules/Media/ProIcon.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,74 @@
ο»Ώnamespace FoliCon.Modules.Media;

public class ProIcon(string filePath)
public class ProIcon
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly string _filePath;
private readonly IconOverlay _iconOverlay;
private readonly string _rating;
private readonly string _ratingVisibility;
private readonly string _mockupVisibility;
private readonly string _mediaTitle;

public ProIcon(string filePath)
{
_filePath = filePath;
_iconOverlay = IconOverlay.Legacy;
_rating = string.Empty;
_ratingVisibility = "hidden";
_mockupVisibility = "hidden";
_mediaTitle = string.Empty;
}

public ProIcon(string filePath, IconOverlay iconOverlay, string rating = "", string ratingVisibility = "hidden", string mockupVisibility = "hidden", string mediaTitle = "")
{
_filePath = filePath;
_iconOverlay = iconOverlay;
_rating = rating;
_ratingVisibility = ratingVisibility;
_mockupVisibility = mockupVisibility;
_mediaTitle = mediaTitle;
}

public Bitmap RenderToBitmap()
{
Logger.Debug("Rendering icon to bitmap");
return PosterIconBase.RenderTargetBitmapTo32BppArgb(AsRenderTargetBitmap());
Logger.Debug("Rendering icon to bitmap with overlay: {Overlay}", _iconOverlay);

if (_iconOverlay == IconOverlay.Legacy)
{
// Use the original simple resize for Legacy mode
return PosterIconBase.RenderTargetBitmapTo32BppArgb(AsRenderTargetBitmap());
}

// For other overlay types, use the appropriate PosterIcon implementation
using var task = _iconOverlay switch
{
IconOverlay.Alternate => StaTask.Start(() =>
new PosterIconAlt(new PosterIcon(_filePath, _rating, _ratingVisibility, _mockupVisibility))
.RenderToBitmap()),
IconOverlay.Liaher => StaTask.Start(() =>
new PosterIconLiaher(new PosterIcon(_filePath, _rating, _ratingVisibility, _mockupVisibility))
.RenderToBitmap()),
IconOverlay.Faelpessoal => StaTask.Start(() => new PosterIconFaelpessoal(new PosterIcon(
_filePath, _rating,
_ratingVisibility, _mockupVisibility, _mediaTitle)).RenderToBitmap()),
IconOverlay.FaelpessoalHorizontal => StaTask.Start(() => new PosterIconFaelpessoalHorizontal(
new PosterIcon(
_filePath, _rating,
_ratingVisibility, _mockupVisibility, _mediaTitle)).RenderToBitmap()),
_ => StaTask.Start(() =>
new Views.PosterIcon(new PosterIcon(_filePath, _rating, _ratingVisibility, _mockupVisibility))
.RenderToBitmap())
};

return task.Result;
}

private BitmapSource AsRenderTargetBitmap()
{
using var img = new Bitmap(filePath);
using var img = new Bitmap(_filePath);
using var icon = new Bitmap(img, 256, 256);
Logger.Debug("Icon resized to 256x256, filePath: {FilePath}", filePath);
Logger.Debug("Icon resized to 256x256, filePath: {FilePath}", _filePath);
return ImageUtils.LoadBitmap(icon);
}
}
}
20 changes: 20 additions & 0 deletions FoliCon/Modules/Media/ProIcon.cs.orig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
ο»Ώnamespace FoliCon.Modules.Media;

public class ProIcon(string filePath)
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

public Bitmap RenderToBitmap()
{
Logger.Debug("Rendering icon to bitmap");
return PosterIconBase.RenderTargetBitmapTo32BppArgb(AsRenderTargetBitmap());
}

private BitmapSource AsRenderTargetBitmap()
{
using var img = new Bitmap(filePath);
using var icon = new Bitmap(img, 256, 256);
Logger.Debug("Icon resized to 256x256, filePath: {FilePath}", filePath);
return ImageUtils.LoadBitmap(icon);
}
}
49 changes: 42 additions & 7 deletions FoliCon/ViewModels/CustomIconControlViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace FoliCon.ViewModels;
public class CustomIconControlViewModel : BindableBase, IDialogAware, IFileDragDropTarget
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

public IDropTarget ReOrderDropHandler { get; } = new ReOrderDropHandler();
private string _selectedDirectory;
private string _selectedIconsDirectory;
Expand All @@ -26,6 +26,9 @@ public class CustomIconControlViewModel : BindableBase, IDialogAware, IFileDragD
private string _busyContent = Lang.CreatingIcons;
private int _index;
private int _totalIcons;
private string _iconOverlay = IconOverlay.Liaher.ToString();
private bool _isRatingVisible;
private bool _isMockupVisible;
public bool KeepExactOnly
{
get => _keepExactOnly;
Expand Down Expand Up @@ -55,6 +58,24 @@ public bool IsUndoEnable
set => SetProperty(ref _isUndoEnable, value);
}

public string IconOverlay
{
get => _iconOverlay;
set => SetProperty(ref _iconOverlay, value);
}

public bool IsRatingVisible
{
get => _isRatingVisible;
set => SetProperty(ref _isRatingVisible, value);
}

public bool IsMockupVisible
{
get => _isMockupVisible;
set => SetProperty(ref _isMockupVisible, value);
}

private string SelectedDirectory
{
get => _selectedDirectory;
Expand Down Expand Up @@ -109,6 +130,7 @@ public ObservableCollection<string> Icons
public DelegateCommand<dynamic> KeyPressFolderList { get; set; }
public DelegateCommand<dynamic> KeyPressIconsList { get; set; }
public DelegateCommand StopSearchCommand { get; set; }
public DelegateCommand<string> IconOverlayChangedCommand { get; set; }
public string BusyContent
{
get => _busyContent;
Expand All @@ -129,6 +151,7 @@ public CustomIconControlViewModel()
UndoIcons = new DelegateCommand(UndoCreatedIcons);
KeyPressFolderList = new DelegateCommand<dynamic>(FolderListKeyPress);
KeyPressIconsList = new DelegateCommand<dynamic>(IconsListKeyPress);
IconOverlayChangedCommand = new DelegateCommand<string>(param => IconOverlay = param);
}

private async void UndoCreatedIcons()
Expand Down Expand Up @@ -270,14 +293,26 @@ private int MakeIcons()
var iconPath = Path.Combine(SelectedIconsDirectory, Icons[i]);
var folderPath = Path.Combine(SelectedDirectory, Directories[i]);
var newIconPath = Path.Combine(folderPath, $"{Directories[i]}.ico");

Logger.Debug("Creating icon for {Folder} from {Icon}, new Path is: {NewIconPath}",
folderPath, iconPath, newIconPath);

if (Path.GetExtension(Icons[i].ToLower(CultureInfo.InvariantCulture)) != ".ico")
{
Logger.Info("Converting {Icon} to .ico", iconPath);
var icon = new ProIcon(iconPath).RenderToBitmap();
Logger.Info("Converting {Icon} to .ico with overlay {Overlay}", iconPath, IconOverlay);

// Parse the IconOverlay string to the enum value
if (!Enum.TryParse<IconOverlay>(IconOverlay, out var iconOverlay))
{
iconOverlay = IconOverlay.Legacy;
}

// Convert visibility booleans to strings
var ratingVisibility = IsRatingVisible ? "visible" : "hidden";
var mockupVisibility = IsMockupVisible ? "visible" : "hidden";

// Use the new ProIcon constructor with overlay settings
var icon = new ProIcon(iconPath, iconOverlay, "", ratingVisibility, mockupVisibility).RenderToBitmap();
iconPath = iconPath.Replace(Path.GetExtension(Icons[i])!, ".ico");
PngToIcoService.Convert(icon, iconPath);
icon.Dispose();
Expand Down Expand Up @@ -328,7 +363,7 @@ private void RestoreCollections()
{
Logger.Debug("Restoring collections from backup icon count: {Count}, backup directory count: {DirectoryCount}",
_backupIcons.Count, _backupDirectories.Count);

if (_backupIcons.Count == 0 || _backupDirectories.Count == 0)
{
return;
Expand Down Expand Up @@ -383,4 +418,4 @@ public void OnFileDrop(string[] filePaths, string senderName)
break;
}
}
}
}
101 changes: 92 additions & 9 deletions FoliCon/Views/CustomIconControl.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,21 @@
xmlns:langs="clr-namespace:FoliCon.Properties.Langs"
xmlns:extension="clr-namespace:FoliCon.Modules.Extension"
xmlns:ui="clr-namespace:FoliCon.Modules.UI"
xmlns:convertor="clr-namespace:FoliCon.Modules.Convertor"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance viewModels:CustomIconControlViewModel}"
Background="{DynamicResource RegionBrush}"
prism:ViewModelLocator.AutoWireViewModel="True" AllowDrop="True" >
<UserControl.Resources>
<ResourceDictionary>
<convertor:String2BooleanConvertor x:Key="StringToBooleanConvertor" />
</ResourceDictionary>
</UserControl.Resources>
<prism:Dialog.WindowStyle>
<Style TargetType="Window">
<Setter Property="Icon" Value="/Resources/icons/folicon Icon.ico"/>
<Setter Property="Height" Value="500" />
<Setter Property="Width" Value="636" />
<Setter Property="Height" Value="700" />
<Setter Property="Width" Value="800" />
<Setter Property="prism:Dialog.WindowStartupLocation" Value="CenterOwner" />
</Style>
</prism:Dialog.WindowStyle>
Expand Down Expand Up @@ -84,13 +90,90 @@
</i:KeyTrigger>
</i:Interaction.Triggers>
</ListBox>
<VirtualizingStackPanel Grid.Row="3" Grid.Column="0">
<CheckBox Content="{extension:Lang Key={x:Static langs:LangKeys.OnlyKeepExactMatches}}" HorizontalAlignment="Center" Margin="5" IsChecked="{Binding KeepExactOnly}"/>
<Button Style="{StaticResource ButtonInfo}" Content="{extension:Lang Key={x:Static langs:LangKeys.Undo}}" HorizontalAlignment="Stretch" Margin="5" IsEnabled="{Binding IsUndoEnable}" Command="{Binding UndoIcons}"/>
</VirtualizingStackPanel>
<Grid Grid.Row="3" Grid.ColumnSpan="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<Button Style="{StaticResource ButtonPrimary}" Grid.Column="1" Grid.Row="3" Margin="10,10,10,10" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Content="{extension:Lang Key={x:Static langs:LangKeys.Apply}}"
Command="{Binding Apply}" />
<!-- Overlay Selection -->
<GroupBox Grid.Row="0" Header="Icon Overlay Style" Margin="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<RadioButton x:Name="RPoster" Grid.Column="0" GroupName="PosterOverlay"
Command="{Binding IconOverlayChangedCommand}"
CommandParameter="Legacy" hc:Poptip.Content="Legacy" hc:Poptip.Placement="LeftTop"
Margin="0,4,0,4" FontSize="16" VerticalAlignment="Stretch"
HorizontalAlignment="Left"
IsChecked="{Binding IconOverlay, ConverterParameter=Legacy, Converter={StaticResource StringToBooleanConvertor}}">
<RadioButton.Content>
<Image Source="/Resources/mockup_demos/simple/PosterIcon.ico" />
</RadioButton.Content>
</RadioButton>
<RadioButton x:Name="RPosterAlt" Grid.Column="1" GroupName="PosterOverlay"
Command="{Binding IconOverlayChangedCommand}"
CommandParameter="Alternate" FontSize="16" hc:Poptip.Content="Alternate" hc:Poptip.Placement="LeftTop"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
IsChecked="{Binding IconOverlay, ConverterParameter=Alternate, Converter={StaticResource StringToBooleanConvertor}}">
<RadioButton.Content>
<Image Source="/Resources/mockup_demos/dvd/PosterIconAlt.ico" />
</RadioButton.Content>
</RadioButton>
<RadioButton x:Name="RPosterFaelpessoal" Grid.Column="2" GroupName="PosterOverlay"
Command="{Binding IconOverlayChangedCommand}"
CommandParameter="Faelpessoal" FontSize="16" hc:Poptip.Content="Faelpessoal" hc:Poptip.Placement="LeftTop"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
IsChecked="{Binding IconOverlay, ConverterParameter=Faelpessoal, Converter={StaticResource StringToBooleanConvertor}}">
<RadioButton.Content>
<Image Source="/Resources/mockup_demos/faelpessoal/PosterIconFaelpessoal.ico" />
</RadioButton.Content>
</RadioButton>
<RadioButton x:Name="RPosterLiaher" Grid.Column="3" GroupName="PosterOverlay"
Command="{Binding IconOverlayChangedCommand}"
CommandParameter="Liaher" FontSize="16" hc:Poptip.Content="Liaher" hc:Poptip.Placement="LeftTop"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
IsChecked="{Binding IconOverlay, ConverterParameter=Liaher, Converter={StaticResource StringToBooleanConvertor}}">
<RadioButton.Content>
<Image Source="/Resources/mockup_demos/liaher/PosterIconLiaher.ico" />
</RadioButton.Content>
</RadioButton>
<RadioButton x:Name="RPosterFaelpessoalHorizontal" Grid.Column="4" GroupName="PosterOverlay"
ToolTip="{extension:Lang Key={x:Static langs:LangKeys.BestSuitedForHorizontal}}"
Command="{Binding IconOverlayChangedCommand}"
CommandParameter="FaelpessoalHorizontal" FontSize="16" hc:Poptip.Content="Faelpessoal Horizontal" hc:Poptip.Placement="LeftTop"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
IsChecked="{Binding IconOverlay, ConverterParameter=FaelpessoalHorizontal, Converter={StaticResource StringToBooleanConvertor}}">
<RadioButton.Content>
<Image Source="/Resources/mockup_demos/faelpessoal/PosterIconFaelpessoalHorizontal.ico" />
</RadioButton.Content>
</RadioButton>
</Grid>
</GroupBox>

<!-- Settings and Buttons -->
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<VirtualizingStackPanel Grid.Column="0">
<CheckBox Content="{extension:Lang Key={x:Static langs:LangKeys.OnlyKeepExactMatches}}" HorizontalAlignment="Center" Margin="5" IsChecked="{Binding KeepExactOnly}"/>
<CheckBox Content="Show Rating" HorizontalAlignment="Center" Margin="5" IsChecked="{Binding IsRatingVisible}"/>
<CheckBox Content="Show Mockup" HorizontalAlignment="Center" Margin="5" IsChecked="{Binding IsMockupVisible}"/>
<Button Style="{StaticResource ButtonInfo}" Content="{extension:Lang Key={x:Static langs:LangKeys.Undo}}" HorizontalAlignment="Stretch" Margin="5" IsEnabled="{Binding IsUndoEnable}" Command="{Binding UndoIcons}"/>
</VirtualizingStackPanel>

<Button Style="{StaticResource ButtonPrimary}" Grid.Column="1" Margin="10,10,10,10" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Content="{extension:Lang Key={x:Static langs:LangKeys.Apply}}"
Command="{Binding Apply}" />
</Grid>
</Grid>
</Grid>
</hc:BusyIndicator>
</UserControl>
</UserControl>
Loading