Refactor thumbnail options to enum and ComboBox UI

Replaced multiple mutually-exclusive boolean properties for thumbnail text options with a single enum (`ThumbnailOption`) in the data model. Updated WinForms UI to use a ComboBox instead of radio buttons for selecting thumbnail mode. Adjusted designer, mapping profile, settings DTO, and settings service for enum support and backward compatibility. Simplified thumbnail generation logic and improved maintainability by ensuring only one mode can be selected at a time.
This commit is contained in:
MaddoScientisto 2026-02-16 19:55:37 +01:00
commit d13ec8abdf
7 changed files with 214 additions and 289 deletions

View file

@ -227,21 +227,23 @@ public class ImageCreatorSharp(PicSettings picSettings, ILogger<ImageCreatorShar
} }
} }
private void CreateThumbnails(Image sourceImage, ImageState imgState, Bitmap imgOutputBig, ImageFormat format) private void CreateThumbnails(Image sourceImage, ImageState imgState, Bitmap imgOutputBig, ImageFormat format)
{ {
if (!picSettings.CreaMiniature || picSettings.AggiungiScritteMiniature) // Only skip thumbnail generation when the global "create thumbnails" flag is false.
return; // Whether thumbnails include text is handled by ShouldRenderText/CreateThumbnailWithText
if (!picSettings.CreaMiniature)
return;
PrepareSignatureText(imgState); PrepareSignatureText(imgState);
if (IsSameDirectory(picSettings.DirectorySorgente, picSettings.DirectoryDestinazione)) if (IsSameDirectory(picSettings.DirectorySorgente, picSettings.DirectoryDestinazione))
UpdateFilenameWithCode(imgState); UpdateFilenameWithCode(imgState);
if (ShouldRenderText()) if (ShouldRenderText())
CreateThumbnailWithText(sourceImage, imgState, imgOutputBig, format); CreateThumbnailWithText(sourceImage, imgState, imgOutputBig, format);
else else
CreateSimpleThumbnail(sourceImage, imgState, format); CreateSimpleThumbnail(sourceImage, imgState, format);
} }
private void PrepareSignatureText(ImageState imgState) private void PrepareSignatureText(ImageState imgState)
{ {

View file

@ -960,22 +960,16 @@ namespace ImageCatalog_2
private bool _addTimeToThumbnails; private bool _addTimeToThumbnails;
public bool AddTimeToThumbnails public bool AddTimeToThumbnails
{ {
get => _addTimeToThumbnails; get => _thumbnailOption == ThumbnailOptionEnum.Time;
set set
{ {
if (_addTimeToThumbnails == value) return;
_addTimeToThumbnails = value;
if (value) if (value)
{ {
// ensure mutually exclusive choices ThumbnailOption = ThumbnailOptionEnum.Time;
_addTextToThumbnails = false; }
_showPhotoNumber = false; else if (_thumbnailOption == ThumbnailOptionEnum.Time)
_addNumberAndTimeToThumbnails = false; {
_addRaceTimeToThumbnails = false; ThumbnailOption = ThumbnailOptionEnum.None;
NotifyPropertyChanged(nameof(AddTextToThumbnails));
NotifyPropertyChanged(nameof(ShowPhotoNumber));
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails));
} }
NotifyPropertyChanged(); NotifyPropertyChanged();
} }
@ -984,10 +978,13 @@ namespace ImageCatalog_2
private bool _showFileNameOnThumbnails; private bool _showFileNameOnThumbnails;
public bool ShowFileNameOnThumbnails public bool ShowFileNameOnThumbnails
{ {
get => _showFileNameOnThumbnails; get => _thumbnailOption == ThumbnailOptionEnum.FileName;
set set
{ {
_showFileNameOnThumbnails = value; if (value)
ThumbnailOption = ThumbnailOptionEnum.FileName;
else if (_thumbnailOption == ThumbnailOptionEnum.FileName)
ThumbnailOption = ThumbnailOptionEnum.None;
NotifyPropertyChanged(); NotifyPropertyChanged();
} }
} }
@ -1028,23 +1025,13 @@ namespace ImageCatalog_2
private bool _addTextToThumbnails; private bool _addTextToThumbnails;
public bool AddTextToThumbnails public bool AddTextToThumbnails
{ {
get => _addTextToThumbnails; get => _thumbnailOption == ThumbnailOptionEnum.Text;
set set
{ {
if (_addTextToThumbnails == value) return;
_addTextToThumbnails = value;
if (value) if (value)
{ ThumbnailOption = ThumbnailOptionEnum.Text;
// ensure mutually exclusive choices else if (_thumbnailOption == ThumbnailOptionEnum.Text)
_addTimeToThumbnails = false; ThumbnailOption = ThumbnailOptionEnum.None;
_showPhotoNumber = false;
_addNumberAndTimeToThumbnails = false;
_addRaceTimeToThumbnails = false;
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
NotifyPropertyChanged(nameof(ShowPhotoNumber));
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails));
}
NotifyPropertyChanged(); NotifyPropertyChanged();
} }
} }
@ -1052,23 +1039,13 @@ namespace ImageCatalog_2
private bool _addRaceTimeToThumbnails; private bool _addRaceTimeToThumbnails;
public bool AddRaceTimeToThumbnails public bool AddRaceTimeToThumbnails
{ {
get => _addRaceTimeToThumbnails; get => _thumbnailOption == ThumbnailOptionEnum.RaceTime;
set set
{ {
if (_addRaceTimeToThumbnails == value) return;
_addRaceTimeToThumbnails = value;
if (value) if (value)
{ ThumbnailOption = ThumbnailOptionEnum.RaceTime;
// ensure mutually exclusive choices else if (_thumbnailOption == ThumbnailOptionEnum.RaceTime)
_addTimeToThumbnails = false; ThumbnailOption = ThumbnailOptionEnum.None;
_addTextToThumbnails = false;
_showPhotoNumber = false;
_addNumberAndTimeToThumbnails = false;
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
NotifyPropertyChanged(nameof(AddTextToThumbnails));
NotifyPropertyChanged(nameof(ShowPhotoNumber));
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
}
NotifyPropertyChanged(); NotifyPropertyChanged();
} }
} }
@ -1076,23 +1053,59 @@ namespace ImageCatalog_2
private bool _addNumberAndTimeToThumbnails; private bool _addNumberAndTimeToThumbnails;
public bool AddNumberAndTimeToThumbnails public bool AddNumberAndTimeToThumbnails
{ {
get => _addNumberAndTimeToThumbnails; get => _thumbnailOption == ThumbnailOptionEnum.FileNameAndTime;
set set
{ {
if (_addNumberAndTimeToThumbnails == value) return;
_addNumberAndTimeToThumbnails = value;
if (value) if (value)
{ ThumbnailOption = ThumbnailOptionEnum.FileNameAndTime;
// ensure mutually exclusive choices else if (_thumbnailOption == ThumbnailOptionEnum.FileNameAndTime)
_addTimeToThumbnails = false; ThumbnailOption = ThumbnailOptionEnum.None;
_addTextToThumbnails = false; NotifyPropertyChanged();
_showPhotoNumber = false; }
_addRaceTimeToThumbnails = false; }
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
NotifyPropertyChanged(nameof(AddTextToThumbnails)); // New enum and authoritative property for thumbnail selection
NotifyPropertyChanged(nameof(ShowPhotoNumber)); public enum ThumbnailOptionEnum
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails)); {
} None = 0,
Text = 1,
FileName = 2,
Time = 3,
FileNameAndTime = 4,
RaceTime = 5
}
private ThumbnailOptionEnum _thumbnailOption = ThumbnailOptionEnum.None;
// Name matches DTO property so SettingsService mapping works
public ThumbnailOptionEnum ThumbnailOption
{
get => _thumbnailOption;
set
{
if (_thumbnailOption == value) return;
_thumbnailOption = value;
// Notify all dependent properties so UI updates
NotifyPropertyChanged();
NotifyPropertyChanged(nameof(AddTextToThumbnails));
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
NotifyPropertyChanged(nameof(ShowPhotoNumber));
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails));
NotifyPropertyChanged(nameof(ShowFileNameOnThumbnails));
NotifyPropertyChanged(nameof(ThumbnailMode));
}
}
// Helper int property to bind ComboBox SelectedIndex in the WinForms designer
public int ThumbnailOptionIndex
{
get => (int)ThumbnailOption;
set
{
var opt = (ThumbnailOptionEnum)value;
if (opt == ThumbnailOption) return;
ThumbnailOption = opt;
NotifyPropertyChanged(); NotifyPropertyChanged();
} }
} }
@ -1103,52 +1116,40 @@ namespace ImageCatalog_2
{ {
get get
{ {
if (AddTextToThumbnails) return "Text"; return _thumbnailOption switch
if (AddTimeToThumbnails) return "Time"; {
if (ShowPhotoNumber) return "Number"; ThumbnailOptionEnum.Text => "Text",
if (AddNumberAndTimeToThumbnails) return "NumberAndTime"; ThumbnailOptionEnum.Time => "Time",
if (AddRaceTimeToThumbnails) return "RaceTime"; ThumbnailOptionEnum.FileName => "Number",
return "None"; ThumbnailOptionEnum.FileNameAndTime => "NumberAndTime",
ThumbnailOptionEnum.RaceTime => "RaceTime",
_ => "None",
};
} }
set set
{ {
var current = ThumbnailMode; // Map incoming string to enum and set the authoritative property
if (string.Equals(current, value, StringComparison.OrdinalIgnoreCase)) return;
// Set the boolean flags via their public setters so mutual-exclusion logic runs
switch ((value ?? string.Empty).ToLowerInvariant()) switch ((value ?? string.Empty).ToLowerInvariant())
{ {
case "text": case "text":
AddTextToThumbnails = true; ThumbnailOption = ThumbnailOptionEnum.Text;
break; break;
case "time": case "time":
AddTimeToThumbnails = true; ThumbnailOption = ThumbnailOptionEnum.Time;
break; break;
case "number": case "number":
ShowPhotoNumber = true; ThumbnailOption = ThumbnailOptionEnum.FileName;
break; break;
case "numberandtime": case "numberandtime":
AddNumberAndTimeToThumbnails = true; ThumbnailOption = ThumbnailOptionEnum.FileNameAndTime;
break; break;
case "racetime": case "racetime":
AddRaceTimeToThumbnails = true; ThumbnailOption = ThumbnailOptionEnum.RaceTime;
break; break;
default: default:
// clear all ThumbnailOption = ThumbnailOptionEnum.None;
_addTimeToThumbnails = false;
_addTextToThumbnails = false;
_showPhotoNumber = false;
_addRaceTimeToThumbnails = false;
_addNumberAndTimeToThumbnails = false;
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
NotifyPropertyChanged(nameof(AddTextToThumbnails));
NotifyPropertyChanged(nameof(ShowPhotoNumber));
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails));
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
break; break;
} }
NotifyPropertyChanged(nameof(ThumbnailMode));
} }
} }

View file

@ -14,7 +14,7 @@ namespace ImageCatalog
// Form overrides dispose to clean up the component list. // Form overrides dispose to clean up the component list.
[DebuggerNonUserCode()] [DebuggerNonUserCode()]
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
try try
{ {
if (disposing && components is object) if (disposing && components is object)
@ -138,12 +138,6 @@ namespace ImageCatalog
GroupBox1 = new GroupBox(); GroupBox1 = new GroupBox();
Label46 = new Label(); Label46 = new Label();
TextBox33 = new TextBox(); TextBox33 = new TextBox();
Panel2 = new Panel();
RadioButton3 = new RadioButton();
RadioButton7 = new RadioButton();
RadioButton4 = new RadioButton();
RadioButton6 = new RadioButton();
RadioButton5 = new RadioButton();
Label5 = new Label(); Label5 = new Label();
TextBox5 = new TextBox(); TextBox5 = new TextBox();
Label6 = new Label(); Label6 = new Label();
@ -151,8 +145,11 @@ namespace ImageCatalog
Label3 = new Label(); Label3 = new Label();
TextBox3 = new TextBox(); TextBox3 = new TextBox();
CheckBox1 = new CheckBox(); CheckBox1 = new CheckBox();
comboThumbnailOption = new ComboBox();
TabPage4 = new TabPage(); TabPage4 = new TabPage();
GroupBox6 = new GroupBox(); GroupBox6 = new GroupBox();
chkUseTransparentColor = new CheckBox();
btnSetTransparency = new Button();
_PictureBox1 = new PictureBox(); _PictureBox1 = new PictureBox();
ComboBox5 = new ComboBox(); ComboBox5 = new ComboBox();
ComboBox4 = new ComboBox(); ComboBox4 = new ComboBox();
@ -169,6 +166,7 @@ namespace ImageCatalog
_Button4 = new Button(); _Button4 = new Button();
TextBox10 = new TextBox(); TextBox10 = new TextBox();
Label29 = new Label(); Label29 = new Label();
PictureBox3 = new PictureBox();
versionLabel = new Label(); versionLabel = new Label();
_Button7 = new Button(); _Button7 = new Button();
_Button5 = new Button(); _Button5 = new Button();
@ -181,10 +179,8 @@ namespace ImageCatalog
_btnCreaCatalogoAsync = new Button(); _btnCreaCatalogoAsync = new Button();
timer1 = new System.Windows.Forms.Timer(components); timer1 = new System.Windows.Forms.Timer(components);
dataModelBindingSource1 = new BindingSource(components); dataModelBindingSource1 = new BindingSource(components);
PictureBox3 = new PictureBox();
colorDialog1 = new ColorDialog(); colorDialog1 = new ColorDialog();
btnSetTransparency = new Button(); label16 = new Label();
chkUseTransparentColor = new CheckBox();
((System.ComponentModel.ISupportInitialize)bindingSource1).BeginInit(); ((System.ComponentModel.ISupportInitialize)bindingSource1).BeginInit();
((System.ComponentModel.ISupportInitialize)dataModelBindingSource).BeginInit(); ((System.ComponentModel.ISupportInitialize)dataModelBindingSource).BeginInit();
TabControl1.SuspendLayout(); TabControl1.SuspendLayout();
@ -207,12 +203,11 @@ namespace ImageCatalog
TabPage1.SuspendLayout(); TabPage1.SuspendLayout();
Panel1.SuspendLayout(); Panel1.SuspendLayout();
GroupBox1.SuspendLayout(); GroupBox1.SuspendLayout();
Panel2.SuspendLayout();
TabPage4.SuspendLayout(); TabPage4.SuspendLayout();
GroupBox6.SuspendLayout(); GroupBox6.SuspendLayout();
((System.ComponentModel.ISupportInitialize)_PictureBox1).BeginInit(); ((System.ComponentModel.ISupportInitialize)_PictureBox1).BeginInit();
((System.ComponentModel.ISupportInitialize)dataModelBindingSource1).BeginInit();
((System.ComponentModel.ISupportInitialize)PictureBox3).BeginInit(); ((System.ComponentModel.ISupportInitialize)PictureBox3).BeginInit();
((System.ComponentModel.ISupportInitialize)dataModelBindingSource1).BeginInit();
SuspendLayout(); SuspendLayout();
// //
// ProgressBar1 // ProgressBar1
@ -1323,9 +1318,9 @@ namespace ImageCatalog
// //
// GroupBox1 // GroupBox1
// //
GroupBox1.Controls.Add(label16);
GroupBox1.Controls.Add(Label46); GroupBox1.Controls.Add(Label46);
GroupBox1.Controls.Add(TextBox33); GroupBox1.Controls.Add(TextBox33);
GroupBox1.Controls.Add(Panel2);
GroupBox1.Controls.Add(Label5); GroupBox1.Controls.Add(Label5);
GroupBox1.Controls.Add(TextBox5); GroupBox1.Controls.Add(TextBox5);
GroupBox1.Controls.Add(Label6); GroupBox1.Controls.Add(Label6);
@ -1333,6 +1328,7 @@ namespace ImageCatalog
GroupBox1.Controls.Add(Label3); GroupBox1.Controls.Add(Label3);
GroupBox1.Controls.Add(TextBox3); GroupBox1.Controls.Add(TextBox3);
GroupBox1.Controls.Add(CheckBox1); GroupBox1.Controls.Add(CheckBox1);
GroupBox1.Controls.Add(comboThumbnailOption);
GroupBox1.ForeColor = Color.FromArgb(0, 0, 192); GroupBox1.ForeColor = Color.FromArgb(0, 0, 192);
GroupBox1.Location = new Point(12, 12); GroupBox1.Location = new Point(12, 12);
GroupBox1.Margin = new Padding(6, 8, 6, 8); GroupBox1.Margin = new Padding(6, 8, 6, 8);
@ -1362,84 +1358,6 @@ namespace ImageCatalog
TextBox33.Size = new Size(196, 35); TextBox33.Size = new Size(196, 35);
TextBox33.TabIndex = 20; TextBox33.TabIndex = 20;
// //
// Panel2
//
Panel2.Controls.Add(RadioButton3);
Panel2.Controls.Add(RadioButton7);
Panel2.Controls.Add(RadioButton4);
Panel2.Controls.Add(RadioButton6);
Panel2.Controls.Add(RadioButton5);
Panel2.Location = new Point(113, 262);
Panel2.Margin = new Padding(6, 8, 6, 8);
Panel2.Name = "Panel2";
Panel2.Size = new Size(470, 207);
Panel2.TabIndex = 19;
//
// RadioButton3
//
RadioButton3.AutoSize = true;
RadioButton3.DataBindings.Add(new Binding("Checked", bindingSource1, "AddTextToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged));
RadioButton3.Location = new Point(30, 38);
RadioButton3.Margin = new Padding(6, 8, 6, 8);
RadioButton3.Name = "RadioButton3";
RadioButton3.Size = new Size(186, 34);
RadioButton3.TabIndex = 14;
RadioButton3.TabStop = true;
RadioButton3.Text = "Aggiungi Scritta";
RadioButton3.UseVisualStyleBackColor = true;
//
// RadioButton7
//
RadioButton7.AutoSize = true;
RadioButton7.DataBindings.Add(new Binding("Checked", bindingSource1, "AddNumberAndTimeToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged));
RadioButton7.Location = new Point(258, 93);
RadioButton7.Margin = new Padding(6, 8, 6, 8);
RadioButton7.Name = "RadioButton7";
RadioButton7.Size = new Size(184, 34);
RadioButton7.TabIndex = 18;
RadioButton7.TabStop = true;
RadioButton7.Text = "numero+tempo";
RadioButton7.UseVisualStyleBackColor = true;
//
// RadioButton4
//
RadioButton4.AutoSize = true;
RadioButton4.DataBindings.Add(new Binding("Checked", bindingSource1, "AddTimeToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged));
RadioButton4.Location = new Point(30, 93);
RadioButton4.Margin = new Padding(6, 8, 6, 8);
RadioButton4.Name = "RadioButton4";
RadioButton4.Size = new Size(182, 34);
RadioButton4.TabIndex = 15;
RadioButton4.TabStop = true;
RadioButton4.Text = "Aggiungi orario";
RadioButton4.UseVisualStyleBackColor = true;
//
// RadioButton6
//
RadioButton6.AutoSize = true;
RadioButton6.DataBindings.Add(new Binding("Checked", bindingSource1, "ShowPhotoNumber", true, DataSourceUpdateMode.OnPropertyChanged));
RadioButton6.Location = new Point(258, 38);
RadioButton6.Margin = new Padding(6, 8, 6, 8);
RadioButton6.Name = "RadioButton6";
RadioButton6.Size = new Size(158, 34);
RadioButton6.TabIndex = 17;
RadioButton6.TabStop = true;
RadioButton6.Text = "Numero foto";
RadioButton6.UseVisualStyleBackColor = true;
//
// RadioButton5
//
RadioButton5.AutoSize = true;
RadioButton5.DataBindings.Add(new Binding("Checked", bindingSource1, "AddRaceTimeToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged));
RadioButton5.Location = new Point(30, 150);
RadioButton5.Margin = new Padding(6, 8, 6, 8);
RadioButton5.Name = "RadioButton5";
RadioButton5.Size = new Size(149, 34);
RadioButton5.TabIndex = 16;
RadioButton5.TabStop = true;
RadioButton5.Text = "Tempo Gara";
RadioButton5.UseVisualStyleBackColor = true;
//
// Label5 // Label5
// //
Label5.AutoSize = true; Label5.AutoSize = true;
@ -1514,6 +1432,15 @@ namespace ImageCatalog
CheckBox1.TabIndex = 5; CheckBox1.TabIndex = 5;
CheckBox1.Text = "Crea miniature"; CheckBox1.Text = "Crea miniature";
// //
// comboThumbnailOption
//
comboThumbnailOption.DropDownStyle = ComboBoxStyle.DropDownList;
comboThumbnailOption.Location = new Point(204, 262);
comboThumbnailOption.Margin = new Padding(6, 8, 6, 8);
comboThumbnailOption.Name = "comboThumbnailOption";
comboThumbnailOption.Size = new Size(470, 38);
comboThumbnailOption.TabIndex = 18;
//
// TabPage4 // TabPage4
// //
TabPage4.Controls.Add(GroupBox6); TabPage4.Controls.Add(GroupBox6);
@ -1557,6 +1484,25 @@ namespace ImageCatalog
GroupBox6.TabStop = false; GroupBox6.TabStop = false;
GroupBox6.Text = "Logo"; GroupBox6.Text = "Logo";
// //
// chkUseTransparentColor
//
chkUseTransparentColor.AutoSize = true;
chkUseTransparentColor.Location = new Point(39, 461);
chkUseTransparentColor.Name = "chkUseTransparentColor";
chkUseTransparentColor.Size = new Size(210, 34);
chkUseTransparentColor.TabIndex = 46;
chkUseTransparentColor.Text = "Colore trasparente";
chkUseTransparentColor.UseVisualStyleBackColor = true;
//
// btnSetTransparency
//
btnSetTransparency.Location = new Point(288, 455);
btnSetTransparency.Name = "btnSetTransparency";
btnSetTransparency.Size = new Size(131, 40);
btnSetTransparency.TabIndex = 45;
btnSetTransparency.Text = "Imposta";
btnSetTransparency.UseVisualStyleBackColor = true;
//
// _PictureBox1 // _PictureBox1
// //
_PictureBox1.Cursor = Cursors.Cross; _PictureBox1.Cursor = Cursors.Cross;
@ -1729,6 +1675,17 @@ namespace ImageCatalog
Label29.Text = "Posizione orizzontale"; Label29.Text = "Posizione orizzontale";
Label29.TextAlign = ContentAlignment.MiddleLeft; Label29.TextAlign = ContentAlignment.MiddleLeft;
// //
// PictureBox3
//
PictureBox3.BorderStyle = BorderStyle.FixedSingle;
PictureBox3.Location = new Point(432, 442);
PictureBox3.Margin = new Padding(6, 8, 6, 8);
PictureBox3.Name = "PictureBox3";
PictureBox3.Size = new Size(45, 53);
PictureBox3.TabIndex = 44;
PictureBox3.TabStop = false;
PictureBox3.Visible = false;
//
// versionLabel // versionLabel
// //
versionLabel.DataBindings.Add(new Binding("Text", bindingSource1, "AppVersion", true)); versionLabel.DataBindings.Add(new Binding("Text", bindingSource1, "AppVersion", true));
@ -1844,35 +1801,14 @@ namespace ImageCatalog
// //
dataModelBindingSource1.DataSource = typeof(ImageCatalog_2.DataModel); dataModelBindingSource1.DataSource = typeof(ImageCatalog_2.DataModel);
// //
// PictureBox3 // label16
// //
PictureBox3.BorderStyle = BorderStyle.FixedSingle; label16.AutoSize = true;
PictureBox3.Location = new Point(432, 442); label16.Location = new Point(39, 262);
PictureBox3.Margin = new Padding(6, 8, 6, 8); label16.Name = "label16";
PictureBox3.Name = "PictureBox3"; label16.Size = new Size(156, 30);
PictureBox3.Size = new Size(45, 53); label16.TabIndex = 22;
PictureBox3.TabIndex = 44; label16.Text = "Testo Miniature";
PictureBox3.TabStop = false;
PictureBox3.Visible = false;
//
// btnSetTransparency
//
btnSetTransparency.Location = new Point(288, 455);
btnSetTransparency.Name = "btnSetTransparency";
btnSetTransparency.Size = new Size(131, 40);
btnSetTransparency.TabIndex = 45;
btnSetTransparency.Text = "Imposta";
btnSetTransparency.UseVisualStyleBackColor = true;
//
// chkUseTransparentColor
//
chkUseTransparentColor.AutoSize = true;
chkUseTransparentColor.Location = new Point(39, 461);
chkUseTransparentColor.Name = "chkUseTransparentColor";
chkUseTransparentColor.Size = new Size(210, 34);
chkUseTransparentColor.TabIndex = 46;
chkUseTransparentColor.Text = "Colore trasparente";
chkUseTransparentColor.UseVisualStyleBackColor = true;
// //
// MainForm // MainForm
// //
@ -1933,14 +1869,12 @@ namespace ImageCatalog
Panel1.PerformLayout(); Panel1.PerformLayout();
GroupBox1.ResumeLayout(false); GroupBox1.ResumeLayout(false);
GroupBox1.PerformLayout(); GroupBox1.PerformLayout();
Panel2.ResumeLayout(false);
Panel2.PerformLayout();
TabPage4.ResumeLayout(false); TabPage4.ResumeLayout(false);
GroupBox6.ResumeLayout(false); GroupBox6.ResumeLayout(false);
GroupBox6.PerformLayout(); GroupBox6.PerformLayout();
((System.ComponentModel.ISupportInitialize)_PictureBox1).EndInit(); ((System.ComponentModel.ISupportInitialize)_PictureBox1).EndInit();
((System.ComponentModel.ISupportInitialize)dataModelBindingSource1).EndInit();
((System.ComponentModel.ISupportInitialize)PictureBox3).EndInit(); ((System.ComponentModel.ISupportInitialize)PictureBox3).EndInit();
((System.ComponentModel.ISupportInitialize)dataModelBindingSource1).EndInit();
ResumeLayout(false); ResumeLayout(false);
PerformLayout(); PerformLayout();
} }
@ -2126,12 +2060,7 @@ namespace ImageCatalog
internal GroupBox GroupBox1; internal GroupBox GroupBox1;
internal Label Label46; internal Label Label46;
internal TextBox TextBox33; internal TextBox TextBox33;
internal Panel Panel2; private ComboBox comboThumbnailOption;
internal RadioButton RadioButton3;
internal RadioButton RadioButton7;
internal RadioButton RadioButton4;
internal RadioButton RadioButton6;
internal RadioButton RadioButton5;
internal Label Label5; internal Label Label5;
internal TextBox TextBox5; internal TextBox TextBox5;
internal Label Label6; internal Label Label6;
@ -2295,6 +2224,7 @@ namespace ImageCatalog
private ColorDialog colorDialog1; private ColorDialog colorDialog1;
private Button btnSetTransparency; private Button btnSetTransparency;
private CheckBox chkUseTransparentColor; private CheckBox chkUseTransparentColor;
private Label label16;
internal Button btnCreaCatalogoAsync internal Button btnCreaCatalogoAsync
{ {

View file

@ -83,54 +83,21 @@ public partial class MainForm
// Watch for model changes so we can reflect external updates // Watch for model changes so we can reflect external updates
Model.PropertyChanged += Model_PropertyChanged; Model.PropertyChanged += Model_PropertyChanged;
// Fix thumbnail radio buttons: clear designer bindings to avoid binding vs click conflicts // Thumbnail options moved to ComboBox to avoid conflicting bindings with multiple radio buttons
RadioButton3.DataBindings.Clear();
RadioButton4.DataBindings.Clear();
RadioButton5.DataBindings.Clear();
RadioButton6.DataBindings.Clear();
RadioButton7.DataBindings.Clear();
// Initialize radio state from model (thumbnail options) // Initialize ComboBox with Italian descriptions
try comboThumbnailOption.Items.Clear();
{ comboThumbnailOption.Items.AddRange(new object[] {
_suppressRadioUpdates = true; "Nessuna",
RadioButton3.Checked = Model.AddTextToThumbnails; "Aggiungi scritta",
RadioButton4.Checked = Model.AddTimeToThumbnails; "Nome file",
RadioButton6.Checked = Model.ShowPhotoNumber; "Aggiungi orario",
RadioButton7.Checked = Model.AddNumberAndTimeToThumbnails; "Nome+Orario",
RadioButton5.Checked = Model.AddRaceTimeToThumbnails; "Tempo gara"
} });
finally
{
_suppressRadioUpdates = false;
}
// Use CheckedChanged handlers to set the authoritative ThumbnailMode on the model // Bind to model via helper index property ThumbnailOptionIndex
RadioButton3.CheckedChanged += (s, ev) => comboThumbnailOption.DataBindings.Add(new Binding("SelectedIndex", bindingSource1, "ThumbnailOptionIndex", true, DataSourceUpdateMode.OnPropertyChanged));
{
if (_suppressRadioUpdates) return;
if (RadioButton3.Checked) Model.ThumbnailMode = "Text";
};
RadioButton4.CheckedChanged += (s, ev) =>
{
if (_suppressRadioUpdates) return;
if (RadioButton4.Checked) Model.ThumbnailMode = "Time";
};
RadioButton6.CheckedChanged += (s, ev) =>
{
if (_suppressRadioUpdates) return;
if (RadioButton6.Checked) Model.ThumbnailMode = "Number";
};
RadioButton7.CheckedChanged += (s, ev) =>
{
if (_suppressRadioUpdates) return;
if (RadioButton7.Checked) Model.ThumbnailMode = "NumberAndTime";
};
RadioButton5.CheckedChanged += (s, ev) =>
{
if (_suppressRadioUpdates) return;
if (RadioButton5.Checked) Model.ThumbnailMode = "RaceTime";
};
// Save user preferences on form close instead of immediately when dialogs are used // Save user preferences on form close instead of immediately when dialogs are used
this.FormClosing += MainForm_FormClosing; this.FormClosing += MainForm_FormClosing;
@ -185,22 +152,15 @@ public partial class MainForm
} }
} }
// Thumbnail mode changes - reflect back to radio buttons // Thumbnail mode changes - reflect back to combo box index
if (e.PropertyName == nameof(Model.ThumbnailMode) || if (e.PropertyName == nameof(Model.ThumbnailMode) ||
e.PropertyName == nameof(Model.AddTextToThumbnails) || e.PropertyName == nameof(Model.ThumbnailOption) ||
e.PropertyName == nameof(Model.AddTimeToThumbnails) || e.PropertyName == nameof(Model.ThumbnailOptionIndex))
e.PropertyName == nameof(Model.ShowPhotoNumber) ||
e.PropertyName == nameof(Model.AddNumberAndTimeToThumbnails) ||
e.PropertyName == nameof(Model.AddRaceTimeToThumbnails))
{ {
try try
{ {
_suppressRadioUpdates = true; _suppressRadioUpdates = true;
RadioButton3.Checked = Model.AddTextToThumbnails; comboThumbnailOption.SelectedIndex = Model.ThumbnailOptionIndex;
RadioButton4.Checked = Model.AddTimeToThumbnails;
RadioButton6.Checked = Model.ShowPhotoNumber;
RadioButton7.Checked = Model.AddNumberAndTimeToThumbnails;
RadioButton5.Checked = Model.AddRaceTimeToThumbnails;
} }
finally finally
{ {

View file

@ -70,15 +70,15 @@ public class DataModelMappingProfile : Profile
.ForMember(dest => dest.OverwriteFiles, opt => opt.MapFrom(src => src.OverwriteImages)) .ForMember(dest => dest.OverwriteFiles, opt => opt.MapFrom(src => src.OverwriteImages))
// Additional settings // Additional settings
.ForMember(dest => dest.UsaOrarioMiniatura, opt => opt.MapFrom(src => src.AddTimeToThumbnails)) .ForMember(dest => dest.UsaOrarioMiniatura, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.Time))
.ForMember(dest => dest.DataPartenza, opt => opt.MapFrom(src => src.RaceStartDate)) .ForMember(dest => dest.DataPartenza, opt => opt.MapFrom(src => src.RaceStartDate))
.ForMember(dest => dest.TestoOrario, opt => opt.MapFrom(src => src.TimeLabel)) .ForMember(dest => dest.TestoOrario, opt => opt.MapFrom(src => src.TimeLabel))
.ForMember(dest => dest.TestoMin, opt => opt.MapFrom(src => src.ShowFileNameOnThumbnails)) .ForMember(dest => dest.TestoMin, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.FileName))
// Thumbnail text options // Thumbnail text options
.ForMember(dest => dest.AggiungiScritteMiniature, opt => opt.MapFrom(src => src.AddTextToThumbnails)) .ForMember(dest => dest.AggiungiScritteMiniature, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.Text))
.ForMember(dest => dest.AggTempoGaraMin, opt => opt.MapFrom(src => src.AddRaceTimeToThumbnails)) .ForMember(dest => dest.AggTempoGaraMin, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.RaceTime))
.ForMember(dest => dest.AggNumTempMin, opt => opt.MapFrom(src => src.AddNumberAndTimeToThumbnails)) .ForMember(dest => dest.AggNumTempMin, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.FileNameAndTime))
// Ignore unmapped properties // Ignore unmapped properties
.ForMember(dest => dest.DestDir, opt => opt.Ignore()) .ForMember(dest => dest.DestDir, opt => opt.Ignore())

View file

@ -10,6 +10,21 @@ namespace ImageCatalog_2.Models
/// </summary> /// </summary>
public class SettingsDto public class SettingsDto
{ {
// New enum to represent thumbnail mode in a single property.
public enum ThumbnailOptionDto
{
None = 0,
Text = 1,
FileName = 2,
Time = 3,
FileNameAndTime = 4,
RaceTime = 5
}
[JsonPropertyName("ThumbnailOption")]
[XmlElement("MiniatureModalita")]
public ThumbnailOptionDto ThumbnailOption { get; set; } = ThumbnailOptionDto.None;
// Paths // Paths
[JsonPropertyName("SourcePath")] [JsonPropertyName("SourcePath")]
[XmlElement("DirSorgente")] [XmlElement("DirSorgente")]

View file

@ -75,7 +75,7 @@ namespace ImageCatalog_2.Services
try try
{ {
object value; object value;
if (prop.PropertyType == typeof(string)) if (prop.PropertyType == typeof(string))
{ {
value = fileParams.LeggiParametroString(xmlName); value = fileParams.LeggiParametroString(xmlName);
} }
@ -83,6 +83,22 @@ namespace ImageCatalog_2.Services
{ {
value = fileParams.LeggiParametroBoolean(xmlName); value = fileParams.LeggiParametroBoolean(xmlName);
} }
else if (prop.PropertyType.IsEnum)
{
// Read enum as string from XML and try to parse to the enum type. Fall back to default.
var str = fileParams.LeggiParametroString(xmlName);
try
{
var enumValue = Enum.Parse(prop.PropertyType, str ?? string.Empty, true);
value = enumValue;
}
catch
{
// try numeric
var intVal = fileParams.LeggiParametro<int>(xmlName, (int)(prop.GetValue(loadedDto) ?? 0));
value = Enum.ToObject(prop.PropertyType, intVal);
}
}
else if (prop.PropertyType == typeof(int)) else if (prop.PropertyType == typeof(int))
{ {
value = fileParams.LeggiParametro<int>(xmlName, (int)(prop.GetValue(loadedDto) ?? 0)); value = fileParams.LeggiParametro<int>(xmlName, (int)(prop.GetValue(loadedDto) ?? 0));
@ -117,6 +133,7 @@ namespace ImageCatalog_2.Services
} }
return loadedDto; return loadedDto;
// End of LoadSettingsAsync method
}); });
// Step 2: Apply DTO values to ViewModel on UI thread // Step 2: Apply DTO values to ViewModel on UI thread