Skip to content

Commit

Permalink
Allow to set default image duration in SIQuester
Browse files Browse the repository at this point in the history
  • Loading branch information
VladimirKhil committed Feb 1, 2024
1 parent 1deb5e2 commit 66362f4
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 59 deletions.
102 changes: 50 additions & 52 deletions src/SIQuester/SIQuester.ViewModel/ContentItemsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ public ContentItemsViewModel(QuestionViewModel question, List<ContentItem> conte

CollectionChanged += ContentItemsViewModel_CollectionChanged;

AddText = new SimpleCommand(AddText_Executed);
AddVoice = new SimpleCommand(AddVoice_Executed);
AddText = new SimpleCommand(AddScreenText_Executed);
AddVoice = new SimpleCommand(AddReplicText_Executed);

ChangePlacement = new SimpleCommand(ChangePlacement_Executed);

Expand All @@ -79,9 +79,9 @@ public ContentItemsViewModel(QuestionViewModel question, List<ContentItem> conte
IsTopLevel = isTopLevel;
}

internal void AddText_Executed(object? arg) => QDocument.ActivatedObject = Add(AtomTypes.Text, "", ContentPlacements.Screen);
internal void AddScreenText_Executed(object? arg) => QDocument.ActivatedObject = Add(ContentTypes.Text, "", ContentPlacements.Screen);

private void AddVoice_Executed(object? arg)
private void AddReplicText_Executed(object? arg)
{
var index = CurrentPosition;

Expand All @@ -90,7 +90,7 @@ private void AddVoice_Executed(object? arg)
RemoveAt(index);
}

QDocument.ActivatedObject = Add(AtomTypes.Text, "", ContentPlacements.Replic);
QDocument.ActivatedObject = Add(ContentTypes.Text, "", ContentPlacements.Replic);
}

private void ChangePlacement_Executed(object? arg)
Expand All @@ -101,7 +101,7 @@ private void ChangePlacement_Executed(object? arg)
{
var contentItem = this[index];

if (contentItem.Type != AtomTypes.Text)
if (contentItem.Type != ContentTypes.Text)
{
return;
}
Expand Down Expand Up @@ -214,13 +214,13 @@ private void ContentItemsViewModel_CollectionChanged(object? sender, NotifyColle
private void UpdateContentItemCommands()
{
var contentItem = CurrentItem;
var atomType = contentItem?.Model.Type;
var contentType = contentItem?.Model.Type;

var isMedia = atomType == AtomTypes.Image
|| atomType == AtomTypes.Audio
|| atomType == AtomTypes.AudioNew
|| atomType == AtomTypes.Video
|| atomType == AtomTypes.Html;
var isMedia = contentType == ContentTypes.Image
|| contentType == AtomTypes.Audio
|| contentType == ContentTypes.Audio
|| contentType == ContentTypes.Video
|| contentType == ContentTypes.Html;

SetTime.CanBeExecuted = contentItem != null && contentItem.Model.Duration == TimeSpan.Zero;

Expand Down Expand Up @@ -259,13 +259,7 @@ private void ExportMedia_Executed(object? arg)
{
try
{
var document = Owner.OwnerTheme.OwnerRound?.OwnerPackage?.Document;

if (document == null)
{
throw new InvalidOperationException("document is undefined");
}

var document = OwnerDocument ?? throw new InvalidOperationException("document is undefined");
var media = document.Document.GetLink(CurrentItem.Model);

if (media.GetStream != null && media.Uri != null)
Expand All @@ -291,7 +285,7 @@ private void NavigateToFile_Executed(object? arg)
{
try
{
var document = (Owner.OwnerTheme.OwnerRound?.OwnerPackage?.Document) ?? throw new InvalidOperationException("document is undefined");
var document = OwnerDocument ?? throw new InvalidOperationException("document is undefined");
var collection = document.TryGetCollectionByMediaType(CurrentItem.Model.Type);

if (collection == null)
Expand All @@ -318,18 +312,18 @@ private void NavigateToFile_Executed(object? arg)

public bool SelectAtomObjectCore(object? arg)
{
var data = (Tuple<object, object>)arg;
var data = (Tuple<object, object>?)arg;
var media = data.Item1;
var mediaType = data.Item2.ToString() ?? "";
var contentType = data.Item2.ToString() ?? "";

if (mediaType == AtomTypes.Audio)
if (contentType == AtomTypes.Audio)
{
mediaType = ContentTypes.Audio;
contentType = ContentTypes.Audio;
}

if (media is MediaItemViewModel file)
{
SelectAtomObject_Do(mediaType, file);
LinkExistingContentFile(contentType, file);
return false;
}

Expand All @@ -340,15 +334,15 @@ public bool SelectAtomObjectCore(object? arg)

if (text == Resources.File) // TODO: do not rely business logic on resource strings
{
return AddAtomObject(mediaType);
return AddContentFile(contentType);
}
else
{
return LinkAtomObject(mediaType);
return LinkContentUri(contentType);
}
}

private bool LinkAtomObject(string mediaType)
private bool LinkContentUri(string contentType)
{
var document = OwnerDocument ?? throw new InvalidOperationException("document is undefined");
var index = CurrentPosition;
Expand All @@ -374,15 +368,16 @@ private bool LinkAtomObject(string mediaType)
RemoveAt(index--);
}

var atom = new ContentItemViewModel(new ContentItem
var contentItemViewModel = new ContentItemViewModel(new ContentItem
{
Type = mediaType,
Type = contentType,
Value = uri,
Placement = mediaType == ContentTypes.Audio ? ContentPlacements.Background : ContentPlacements.Screen
Placement = contentType == ContentTypes.Audio ? ContentPlacements.Background : ContentPlacements.Screen,
Duration = document.GetDurationByContentType(contentType),
});

QDocument.ActivatedObject = atom;
Insert(index + 1, atom);
QDocument.ActivatedObject = contentItemViewModel;
Insert(index + 1, contentItemViewModel);
document.ActiveItem = null;

change.Commit();
Expand All @@ -395,8 +390,9 @@ private bool LinkAtomObject(string mediaType)
}
}

private void SelectAtomObject_Do(string mediaType, MediaItemViewModel file)
private void LinkExistingContentFile(string contentType, MediaItemViewModel file)
{
var document = OwnerDocument ?? throw new InvalidOperationException("document is undefined");
var index = CurrentPosition;

if (index == -1)
Expand All @@ -406,37 +402,38 @@ private void SelectAtomObject_Do(string mediaType, MediaItemViewModel file)

try
{
using var change = OwnerDocument.OperationsManager.BeginComplexChange();
using var change = document.OperationsManager.BeginComplexChange();

if (string.IsNullOrWhiteSpace(this[index].Model.Value))
{
RemoveAt(index--);
}

var atom = new ContentItemViewModel(new ContentItem
var contentItemViewModel = new ContentItemViewModel(new ContentItem
{
Type = mediaType,
Type = contentType,
Value = "",
Placement = mediaType == ContentTypes.Audio ? ContentPlacements.Background : ContentPlacements.Screen
Placement = contentType == ContentTypes.Audio ? ContentPlacements.Background : ContentPlacements.Screen,
Duration = document.GetDurationByContentType(contentType),
});

Insert(index + 1, atom);
Insert(index + 1, contentItemViewModel);

atom.Model.IsRef = true;
atom.Model.Value = file.Model.Name;
OwnerDocument.ActiveItem = null;
contentItemViewModel.Model.IsRef = true;
contentItemViewModel.Model.Value = file.Model.Name;
document.ActiveItem = null;

change.Commit();
}
catch (Exception exc)
{
OwnerDocument.OnError(exc);
document.OnError(exc);
}
}

private bool AddAtomObject(string mediaType)
private bool AddContentFile(string contentType)
{
QDocument document;
QDocument? document;

try
{
Expand All @@ -453,7 +450,7 @@ private bool AddAtomObject(string mediaType)
return false;
}

var collection = document.GetCollectionByMediaType(mediaType);
var collection = document.GetCollectionByMediaType(contentType);
var initialItemCount = collection.Files.Count;

try
Expand Down Expand Up @@ -498,19 +495,20 @@ private bool AddAtomObject(string mediaType)

for (var i = initialItemCount; i < collection.Files.Count; i++)
{
var contentItem = new ContentItemViewModel(new ContentItem
var contentItemViewModel = new ContentItemViewModel(new ContentItem
{
Type = mediaType,
Type = contentType,
Value = "",
Placement = mediaType == ContentTypes.Audio ? ContentPlacements.Background : ContentPlacements.Screen
Placement = contentType == ContentTypes.Audio ? ContentPlacements.Background : ContentPlacements.Screen,
Duration = document.GetDurationByContentType(contentType),
});

Insert(index + 1, contentItem);
Insert(index + 1, contentItemViewModel);

var file = collection.Files[i];

contentItem.Model.IsRef = true;
contentItem.Model.Value = file.Model.Name;
contentItemViewModel.Model.IsRef = true;
contentItemViewModel.Model.Value = file.Model.Name;

if (AppSettings.Default.SetRightAnswerFromFileName)
{
Expand Down
8 changes: 4 additions & 4 deletions src/SIQuester/SIQuester.ViewModel/ItemsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ public int CurrentPosition
}
}

private T _currentItem;
private T? _currentItem;

public T CurrentItem
public T? CurrentItem
{
get => _currentItem;
set
Expand All @@ -51,15 +51,15 @@ public T CurrentItem
{
var oldValue = _currentItem;
_currentItem = value;
CurrentPosition = IndexOf(_currentItem);
CurrentPosition = _currentItem == null ? -1 : IndexOf(_currentItem);
OnCurrentItemChanged(oldValue, value);

OnPropertyChanged(new PropertyChangedEventArgs(nameof(CurrentItem)));
}
}
}

protected virtual void OnCurrentItemChanged(T oldValue, T newValue) { }
protected virtual void OnCurrentItemChanged(T? oldValue, T? newValue) { }

public void SetCurrentItem(object item)
{
Expand Down
41 changes: 41 additions & 0 deletions src/SIQuester/SIQuester.ViewModel/Model/AppSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public sealed class AppSettings : INotifyPropertyChanged
private const string DefaultFontFamily = "Calibri";

private const int DefaultSelectOptionCount = 4;
private const bool DefaultUseImageDuration = false;
private const int DefaultImageDurationSeconds = 5;

/// <summary>
/// Auto-save interval.
Expand Down Expand Up @@ -493,6 +495,43 @@ public int SelectOptionCount
}
}

private bool _useImageDuration = DefaultUseImageDuration;

/// <summary>
/// Use custom image duration.
/// </summary>
[DefaultValue(DefaultUseImageDuration)]
public bool UseImageDuration
{
get => _useImageDuration;
set
{
if (_useImageDuration != value)
{
_useImageDuration = value;
OnPropertyChanged();
}
}
}

private int _imageDurationSeconds = DefaultImageDurationSeconds;

/// <summary>
/// Image duration in seconds.
/// </summary>
[DefaultValue(DefaultImageDurationSeconds)]
public int ImageDurationSeconds
{
get => _imageDurationSeconds;
set
{
if (_imageDurationSeconds != value && value > 0 && value <= 120)
{
_imageDurationSeconds = value;
OnPropertyChanged();
}
}
}

/// <summary>
/// Maximum recommended image size.
Expand Down Expand Up @@ -585,5 +624,7 @@ internal void Reset()
SelectOptionCount = DefaultSelectOptionCount;
CheckFileSize = defaultSettings.CheckFileSize;
SetRightAnswerFromFileName = defaultSettings.SetRightAnswerFromFileName;
UseImageDuration = defaultSettings.UseImageDuration;
ImageDurationSeconds = defaultSettings.ImageDurationSeconds;
}
}
17 changes: 17 additions & 0 deletions src/SIQuester/SIQuester.ViewModel/Workspaces/QDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ public sealed class QDocument : WorkspaceViewModel

public MediaStorageViewModel Html { get; private set; }

public AppSettings Settings => AppSettings.Default;

public MediaStorageViewModel? TryGetCollectionByMediaType(string mediaType) => mediaType switch
{
AtomTypes.Image => Images,
Expand Down Expand Up @@ -487,6 +489,11 @@ public object? ActiveItem
{
if (_activeItem != value)
{
if (_activeItem is ContentItemsViewModel contentItems)
{
contentItems.CurrentItem = null;
}

_activeItem = value;
OnPropertyChanged();
}
Expand Down Expand Up @@ -3899,4 +3906,14 @@ internal void RemoveUnusedFiles()
RemoveFileByName(Html, item);
}
}

internal TimeSpan GetDurationByContentType(string contentType)
{
if (contentType == ContentTypes.Image && Settings.UseImageDuration)
{
return TimeSpan.FromSeconds(Settings.ImageDurationSeconds);
}

return TimeSpan.Zero;
}
}
Loading

0 comments on commit 66362f4

Please sign in to comment.