Mutually exclusive thumbnail mode selection in UI
Implement mutually exclusive logic for thumbnail display modes in DataModel and MainForm. Add ThumbnailMode property for authoritative state. Replace radio button bindings with event handlers. Synchronize UI with model changes. Explicitly map thumbnail flags to PicSettings. Force WinForms startup, disabling WPF branch.
This commit is contained in:
parent
6a5173a20d
commit
214e540170
4 changed files with 229 additions and 16 deletions
|
|
@ -836,8 +836,22 @@ namespace ImageCatalog_2
|
|||
get => _showPhotoNumber;
|
||||
set
|
||||
{
|
||||
if (_showPhotoNumber == value) return;
|
||||
_showPhotoNumber = value;
|
||||
if (value)
|
||||
{
|
||||
// ensure mutually exclusive choices
|
||||
_addTimeToThumbnails = false;
|
||||
_addTextToThumbnails = false;
|
||||
_addNumberAndTimeToThumbnails = false;
|
||||
_addRaceTimeToThumbnails = false;
|
||||
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
|
||||
NotifyPropertyChanged(nameof(AddTextToThumbnails));
|
||||
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
|
||||
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails));
|
||||
}
|
||||
NotifyPropertyChanged();
|
||||
NotifyPropertyChanged(nameof(ThumbnailMode));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -949,7 +963,20 @@ namespace ImageCatalog_2
|
|||
get => _addTimeToThumbnails;
|
||||
set
|
||||
{
|
||||
if (_addTimeToThumbnails == value) return;
|
||||
_addTimeToThumbnails = value;
|
||||
if (value)
|
||||
{
|
||||
// ensure mutually exclusive choices
|
||||
_addTextToThumbnails = false;
|
||||
_showPhotoNumber = false;
|
||||
_addNumberAndTimeToThumbnails = false;
|
||||
_addRaceTimeToThumbnails = false;
|
||||
NotifyPropertyChanged(nameof(AddTextToThumbnails));
|
||||
NotifyPropertyChanged(nameof(ShowPhotoNumber));
|
||||
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
|
||||
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails));
|
||||
}
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
|
@ -1004,7 +1031,20 @@ namespace ImageCatalog_2
|
|||
get => _addTextToThumbnails;
|
||||
set
|
||||
{
|
||||
if (_addTextToThumbnails == value) return;
|
||||
_addTextToThumbnails = value;
|
||||
if (value)
|
||||
{
|
||||
// ensure mutually exclusive choices
|
||||
_addTimeToThumbnails = false;
|
||||
_showPhotoNumber = false;
|
||||
_addNumberAndTimeToThumbnails = false;
|
||||
_addRaceTimeToThumbnails = false;
|
||||
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
|
||||
NotifyPropertyChanged(nameof(ShowPhotoNumber));
|
||||
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
|
||||
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails));
|
||||
}
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
|
@ -1015,7 +1055,20 @@ namespace ImageCatalog_2
|
|||
get => _addRaceTimeToThumbnails;
|
||||
set
|
||||
{
|
||||
if (_addRaceTimeToThumbnails == value) return;
|
||||
_addRaceTimeToThumbnails = value;
|
||||
if (value)
|
||||
{
|
||||
// ensure mutually exclusive choices
|
||||
_addTimeToThumbnails = false;
|
||||
_addTextToThumbnails = false;
|
||||
_showPhotoNumber = false;
|
||||
_addNumberAndTimeToThumbnails = false;
|
||||
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
|
||||
NotifyPropertyChanged(nameof(AddTextToThumbnails));
|
||||
NotifyPropertyChanged(nameof(ShowPhotoNumber));
|
||||
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
|
||||
}
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
|
@ -1026,11 +1079,79 @@ namespace ImageCatalog_2
|
|||
get => _addNumberAndTimeToThumbnails;
|
||||
set
|
||||
{
|
||||
if (_addNumberAndTimeToThumbnails == value) return;
|
||||
_addNumberAndTimeToThumbnails = value;
|
||||
if (value)
|
||||
{
|
||||
// ensure mutually exclusive choices
|
||||
_addTimeToThumbnails = false;
|
||||
_addTextToThumbnails = false;
|
||||
_showPhotoNumber = false;
|
||||
_addRaceTimeToThumbnails = false;
|
||||
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
|
||||
NotifyPropertyChanged(nameof(AddTextToThumbnails));
|
||||
NotifyPropertyChanged(nameof(ShowPhotoNumber));
|
||||
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails));
|
||||
}
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// Single authoritative thumbnail mode string to avoid conflicting bindings
|
||||
// Possible values: "None", "Text", "Time", "Number", "NumberAndTime", "RaceTime"
|
||||
public string ThumbnailMode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (AddTextToThumbnails) return "Text";
|
||||
if (AddTimeToThumbnails) return "Time";
|
||||
if (ShowPhotoNumber) return "Number";
|
||||
if (AddNumberAndTimeToThumbnails) return "NumberAndTime";
|
||||
if (AddRaceTimeToThumbnails) return "RaceTime";
|
||||
return "None";
|
||||
}
|
||||
set
|
||||
{
|
||||
var current = ThumbnailMode;
|
||||
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())
|
||||
{
|
||||
case "text":
|
||||
AddTextToThumbnails = true;
|
||||
break;
|
||||
case "time":
|
||||
AddTimeToThumbnails = true;
|
||||
break;
|
||||
case "number":
|
||||
ShowPhotoNumber = true;
|
||||
break;
|
||||
case "numberandtime":
|
||||
AddNumberAndTimeToThumbnails = true;
|
||||
break;
|
||||
case "racetime":
|
||||
AddRaceTimeToThumbnails = true;
|
||||
break;
|
||||
default:
|
||||
// clear all
|
||||
_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;
|
||||
}
|
||||
|
||||
NotifyPropertyChanged(nameof(ThumbnailMode));
|
||||
}
|
||||
}
|
||||
|
||||
// Image processing progress and status
|
||||
private string _processingStatus = "";
|
||||
public string ProcessingStatus
|
||||
|
|
@ -1132,6 +1253,24 @@ namespace ImageCatalog_2
|
|||
|
||||
// Update PicSettings from DataModel using AutoMapper
|
||||
_mapper.Map(this, _picSettings);
|
||||
// Explicitly ensure thumbnail-related flags are applied to PicSettings
|
||||
// because AutoMapper may not map differently-named properties.
|
||||
try
|
||||
{
|
||||
_picSettings.AggiungiScritteMiniature = this.AddTextToThumbnails;
|
||||
_picSettings.UsaOrarioMiniatura = this.AddTimeToThumbnails;
|
||||
_picSettings.AggNumTempMin = this.AddNumberAndTimeToThumbnails;
|
||||
_picSettings.AggTempoGaraMin = this.AddRaceTimeToThumbnails;
|
||||
_picSettings.CreaMiniature = this.CreateThumbnails;
|
||||
_picSettings.LarghezzaSmall = this.ThumbnailWidth;
|
||||
_picSettings.AltezzaSmall = this.ThumbnailHeight;
|
||||
_picSettings.DimMin = this.FontSizeThumbnail;
|
||||
_picSettings.JpegQualityMin = this.JpegQualityThumbnail;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Best-effort; do not fail processing on mapping issues
|
||||
}
|
||||
|
||||
var imageCreationOptions = new ImageCreationStuff.Options
|
||||
{
|
||||
|
|
|
|||
2
imagecatalog/MainForm.Designer.cs
generated
2
imagecatalog/MainForm.Designer.cs
generated
|
|
@ -1404,6 +1404,7 @@ namespace ImageCatalog
|
|||
// 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";
|
||||
|
|
@ -1416,6 +1417,7 @@ namespace ImageCatalog
|
|||
// 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";
|
||||
|
|
|
|||
|
|
@ -83,6 +83,55 @@ public partial class MainForm
|
|||
// Watch for model changes so we can reflect external updates
|
||||
Model.PropertyChanged += Model_PropertyChanged;
|
||||
|
||||
// Fix thumbnail radio buttons: clear designer bindings to avoid binding vs click conflicts
|
||||
RadioButton3.DataBindings.Clear();
|
||||
RadioButton4.DataBindings.Clear();
|
||||
RadioButton5.DataBindings.Clear();
|
||||
RadioButton6.DataBindings.Clear();
|
||||
RadioButton7.DataBindings.Clear();
|
||||
|
||||
// Initialize radio state from model (thumbnail options)
|
||||
try
|
||||
{
|
||||
_suppressRadioUpdates = true;
|
||||
RadioButton3.Checked = Model.AddTextToThumbnails;
|
||||
RadioButton4.Checked = Model.AddTimeToThumbnails;
|
||||
RadioButton6.Checked = Model.ShowPhotoNumber;
|
||||
RadioButton7.Checked = Model.AddNumberAndTimeToThumbnails;
|
||||
RadioButton5.Checked = Model.AddRaceTimeToThumbnails;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_suppressRadioUpdates = false;
|
||||
}
|
||||
|
||||
// Use CheckedChanged handlers to set the authoritative ThumbnailMode on the model
|
||||
RadioButton3.CheckedChanged += (s, ev) =>
|
||||
{
|
||||
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
|
||||
this.FormClosing += MainForm_FormClosing;
|
||||
|
||||
|
|
@ -135,6 +184,29 @@ public partial class MainForm
|
|||
_suppressRadioUpdates = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Thumbnail mode changes - reflect back to radio buttons
|
||||
if (e.PropertyName == nameof(Model.ThumbnailMode) ||
|
||||
e.PropertyName == nameof(Model.AddTextToThumbnails) ||
|
||||
e.PropertyName == nameof(Model.AddTimeToThumbnails) ||
|
||||
e.PropertyName == nameof(Model.ShowPhotoNumber) ||
|
||||
e.PropertyName == nameof(Model.AddNumberAndTimeToThumbnails) ||
|
||||
e.PropertyName == nameof(Model.AddRaceTimeToThumbnails))
|
||||
{
|
||||
try
|
||||
{
|
||||
_suppressRadioUpdates = true;
|
||||
RadioButton3.Checked = Model.AddTextToThumbnails;
|
||||
RadioButton4.Checked = Model.AddTimeToThumbnails;
|
||||
RadioButton6.Checked = Model.ShowPhotoNumber;
|
||||
RadioButton7.Checked = Model.AddNumberAndTimeToThumbnails;
|
||||
RadioButton5.Checked = Model.AddRaceTimeToThumbnails;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_suppressRadioUpdates = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void BindControls()
|
||||
|
|
|
|||
|
|
@ -79,24 +79,24 @@ static class Program
|
|||
// the block below and comment out the WPF branch.
|
||||
// -----------------------------------------------------------------------------
|
||||
// // Force WinForms UI (uncomment to enable)
|
||||
// var mainForm = serviceProvider.GetRequiredService<MainForm>();
|
||||
// // If you want to set the DataModel explicitly on the WinForms form use the lines below
|
||||
// // var mainViewModel = serviceProvider.GetRequiredService<DataModel>();
|
||||
// // mainForm.Model = mainViewModel;
|
||||
// Application.Run(mainForm);
|
||||
var mainForm = serviceProvider.GetRequiredService<MainForm>();
|
||||
// If you want to set the DataModel explicitly on the WinForms form use the lines below
|
||||
// var mainViewModel = serviceProvider.GetRequiredService<DataModel>();
|
||||
// mainForm.Model = mainViewModel;
|
||||
Application.Run(mainForm);
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
if (serviceProvider.GetService(typeof(ImageCatalog_2.MainWindow)) is ImageCatalog_2.MainWindow wpfMain)
|
||||
{
|
||||
// Start WPF app
|
||||
var app = new System.Windows.Application();
|
||||
app.Run(wpfMain);
|
||||
}
|
||||
else
|
||||
{
|
||||
var mainForm = serviceProvider.GetRequiredService<MainForm>();
|
||||
Application.Run(mainForm);
|
||||
}
|
||||
//if (serviceProvider.GetService(typeof(ImageCatalog_2.MainWindow)) is ImageCatalog_2.MainWindow wpfMain)
|
||||
//{
|
||||
// // Start WPF app
|
||||
// var app = new System.Windows.Application();
|
||||
// app.Run(wpfMain);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// var mainForm = serviceProvider.GetRequiredService<MainForm>();
|
||||
// Application.Run(mainForm);
|
||||
//}
|
||||
}
|
||||
|
||||
private static void ConfigureServices(ServiceCollection services)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue