Skip to content

Commit

Permalink
Merge pull request #473 from emoacht/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
emoacht authored Jun 4, 2023
2 parents 827c48e + 966c0cd commit 1f22575
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 64 deletions.
2 changes: 1 addition & 1 deletion Source/Installer/Product.wxs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="Monitorian" Manufacturer="emoacht" Version="4.3.4"
<Product Id="*" Name="Monitorian" Manufacturer="emoacht" Version="4.3.5"
Language="1033" Codepage="1252" UpgradeCode="{81A4D148-75D3-462E-938D-8C208FB48E3C}">
<Package Id="*" InstallerVersion="500" Compressed="yes"
InstallScope="perMachine" InstallPrivileges="elevated"
Expand Down
24 changes: 19 additions & 5 deletions Source/Monitorian.Core/Models/Monitor/DdcMonitorItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,21 +123,35 @@ public override AccessResult ChangeValue(byte code, int value = -1)
var (result, _, current, _) = MonitorConfiguration.GetValue(_handle, code);
if (result.Status == AccessStatus.Succeeded)
{
var next = ((value >= 0) && values.Contains((byte)value)) ? (byte)value : GetNext(values, (byte)current);
var (next, index) = GetNext(values, value, current);
result = MonitorConfiguration.SetValue(_handle, code, next);

Debug.WriteLine($"Change {code:X2}: {(byte)current} -> {next}");

if (result.Status == AccessStatus.Succeeded)
result = new AccessResult(AccessStatus.Succeeded, $"{index + 1}/{values.Count}");
}
return result;

static byte GetNext(IReadOnlyList<byte> source, byte current)
static (byte next, int index) GetNext(IReadOnlyList<byte> source, int specified, uint current)
{
var isSpecified = specified is >= byte.MinValue and <= byte.MaxValue;
int index = 0;
for (int i = 0; i < source.Count; i++)
{
if (source[i] == current)
return (i < source.Count - 1) ? source[i + 1] : source[0];
if (isSpecified && (source[i] == (byte)specified))
{
index = i;
break;
}
if ((i < source.Count - 1) && (source[i] == (byte)current))
{
index = i + 1;
if (!isSpecified)
break;
}
}
return source.First(); // Fallback
return (source[index], index);
}
}

Expand Down
4 changes: 2 additions & 2 deletions Source/Monitorian.Core/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("4.3.4.0")]
[assembly: AssemblyFileVersion("4.3.4.0")]
[assembly: AssemblyVersion("4.3.5.0")]
[assembly: AssemblyFileVersion("4.3.5.0")]
[assembly: NeutralResourcesLanguage("en-US")]

// For unit test
Expand Down
66 changes: 48 additions & 18 deletions Source/Monitorian.Core/ViewModels/MonitorViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ private bool SetContrast(int contrast)

#region Non-Continuous

public void ChangeValue(byte code, int value = -1)
public (bool? success, string message) ChangeValue(byte code, int value = -1)
{
AccessResult result;
lock (_lock)
Expand All @@ -405,8 +405,10 @@ public void ChangeValue(byte code, int value = -1)
switch (result.Status)
{
case AccessStatus.NotSupported:
return (null, null);

case AccessStatus.Succeeded:
break;
return (true, result.Message);

default:
_controller.OnMonitorAccessFailed(result);
Expand All @@ -419,7 +421,7 @@ public void ChangeValue(byte code, int value = -1)
_controller.OnMonitorsChangeFound();
break;
}
break;
return (false, result.Message);
}
}

Expand Down Expand Up @@ -473,7 +475,7 @@ private void OnSucceeded()
if (formerCount <= InitialCount)
{
OnPropertyChanged(nameof(IsControllable));
OnPropertyChanged(nameof(Message));
WarningMessage = CreateWarningMessage();
}

_isConfirmed = true;
Expand All @@ -485,29 +487,57 @@ private void OnFailed()
if (--_controllableCount == 0)
{
OnPropertyChanged(nameof(IsControllable));
OnPropertyChanged(nameof(Message));
WarningMessage = CreateWarningMessage();
}
}

public string Message
private string CreateWarningMessage()
{
get
if (IsReachable && (0 < _controllableCount))
return null;

LanguageService.Switch();

var reason = _monitor switch
{
if (IsReachable && (0 < _controllableCount))
return null;
DdcMonitorItem => Resources.StatusReasonDdcFailing,
UnreachableMonitorItem { IsInternal: false } => Resources.StatusReasonDdcNotEnabled,
_ => null,
};

return Resources.StatusNotControllable + (reason is null ? string.Empty : Environment.NewLine + reason);
}

LanguageService.Switch();
#endregion

var reason = _monitor switch
{
DdcMonitorItem => Resources.StatusReasonDdcFailing,
UnreachableMonitorItem { IsInternal: false } => Resources.StatusReasonDdcNotEnabled,
_ => null,
};
#region Message

return Resources.StatusNotControllable + (reason is null ? string.Empty : Environment.NewLine + reason);
}
private Throttle _show;

public async Task ShowNormalMessageAsync(string message, TimeSpan duration)
{
_show ??= new Throttle(
duration,
() => NormalMessage = null);

NormalMessage = message;

await _show.PushAsync();
}

public string NormalMessage
{
get => _normalMessage;
private set => SetProperty(ref _normalMessage, value);
}
private string _normalMessage;

public string WarningMessage
{
get => _warningMessage;
private set => SetProperty(ref _warningMessage, value);
}
private string _warningMessage;

#endregion

Expand Down
102 changes: 75 additions & 27 deletions Source/Monitorian.Core/Views/Behaviors/ItemSliderBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using Microsoft.Xaml.Behaviors;

Expand All @@ -18,43 +19,53 @@ public class ItemSliderBehavior : ItemBehavior<Slider>
/// </summary>
private Window _window;

/// <summary>
/// Item container which hosts first and second Sliders
/// </summary>
private ListBoxItem _container;

protected override void OnAttached()
{
base.OnAttached();

_window = Window.GetWindow(this.AssociatedObject);
_container = this.AssociatedObject.GetSelfAndAncestors().OfType<ListBoxItem>().FirstOrDefault();

this.AssociatedObject.Initialized += OnInitialized;
this.AssociatedObject.Loaded += OnLoaded;
this.AssociatedObject.Unloaded += OnUnloaded;
this.AssociatedObject.GotFocus += OnGotFocus;
this.AssociatedObject.PreviewKeyDown += OnPreviewKeyDown;

_window = Window.GetWindow(this.AssociatedObject);

_container = this.AssociatedObject.GetSelfAndAncestors().OfType<ListBoxItem>().FirstOrDefault();
if (_container is not null)
{
_container.Selected += OnSelected;
_container.Unselected += OnUnselected;
_container.GotFocus += OnSelected;
this.AssociatedObject.GotFocus += OnGotFocus;

var expression = BindingOperations.GetBindingExpression(this, IsSelectedProperty);
if (expression is not null) // IsSelectedProperty is bound.
{
this.AssociatedObject.Loaded += OnLoaded;

_container.Selected += OnContainerSelected;
_container.Unselected += OnContainerUnselected;
_container.GotFocus += OnContainerSelected;
}
}
}

protected override void OnDetaching()
{
base.OnDetaching();

this.AssociatedObject.Loaded -= OnLoaded;
this.AssociatedObject.Unloaded -= OnUnloaded;
this.AssociatedObject.GotFocus -= OnGotFocus;
this.AssociatedObject.PreviewKeyDown -= OnPreviewKeyDown;

if (_container is not null)
{
_container.Selected -= OnSelected;
_container.Unselected -= OnUnselected;
_container.GotFocus -= OnSelected;
this.AssociatedObject.Loaded -= OnLoaded;
this.AssociatedObject.GotFocus -= OnGotFocus;

_container.Selected -= OnContainerSelected;
_container.Unselected -= OnContainerUnselected;
_container.GotFocus -= OnContainerSelected;
}
}

Expand All @@ -67,19 +78,23 @@ private void OnInitialized(object sender, EventArgs e)

private void OnLoaded(object sender, RoutedEventArgs e)
{
if (IsSelected && (_container is not null))
OnSelected(null, null);
this.AssociatedObject.Loaded -= OnLoaded;

if (IsSelected)
OnContainerSelected(null, new RoutedEventArgs());
}

private void OnUnloaded(object sender, RoutedEventArgs e)
{
this.AssociatedObject.Unloaded -= OnUnloaded;

Unsubscribe();
this.Detach();
}

private void OnGotFocus(object sender, RoutedEventArgs e)
{
if ((_container is not null) && !_container.IsSelected)
if (!_container.IsSelected)
Selector.SetIsSelected(_container, true);
}

Expand Down Expand Up @@ -122,14 +137,30 @@ private void OnPreviewKeyDown(object sender, KeyEventArgs e)

case Key.Tab:
e.Handled = true;
if (!this.AssociatedObject.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down)))
{
UIElement element = this.AssociatedObject;
while (element.PredictFocus(FocusNavigationDirection.Up) is UIElement buffer)
element = buffer;

if (!ReferenceEquals(element, this.AssociatedObject))
element.Focus();
if (SecondObject is { Visibility: Visibility.Visible })
{
try
{
this.AssociatedObject.Focusable = false;
SecondObject.Focus();
}
finally
{
this.AssociatedObject.Focusable = true;
}
}
else
{
if (!this.AssociatedObject.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down)))
{
UIElement element = this.AssociatedObject;
while (element.PredictFocus(FocusNavigationDirection.Up) is UIElement buffer)
element = buffer;

if (!ReferenceEquals(element, this.AssociatedObject))
element.Focus();
}
}
break;
}
Expand All @@ -148,20 +179,37 @@ public bool IsSelected
"IsSelected",
typeof(bool),
typeof(ItemSliderBehavior),
new PropertyMetadata(false));
new PropertyMetadata(defaultValue: false));

private void OnSelected(object sender, RoutedEventArgs e)
private void OnContainerSelected(object sender, RoutedEventArgs e)
{
if (!this.AssociatedObject.IsFocused)
if ((SecondObject is not null) && ReferenceEquals(e.OriginalSource, SecondObject))
{
_container.Focusable = false;
SecondObject.Focus();
}
else if (!this.AssociatedObject.IsFocused)
{
_container.Focusable = false;
this.AssociatedObject.Focus();
}
}

private void OnUnselected(object sender, RoutedEventArgs e)
private void OnContainerUnselected(object sender, RoutedEventArgs e)
{
_container.Focusable = true;
}

public Slider SecondObject
{
get { return (Slider)GetValue(SecondObjectProperty); }
set { SetValue(SecondObjectProperty, value); }
}
public static readonly DependencyProperty SecondObjectProperty =
DependencyProperty.Register(
"SecondObject",
typeof(Slider),
typeof(ItemSliderBehavior),
new PropertyMetadata(defaultValue: null));
}
}
Loading

0 comments on commit 1f22575

Please sign in to comment.