Add settings for fallback behavior
update action icon with padding
This commit is contained in:
@@ -1,113 +1,101 @@
|
||||
using BarRaider.SdTools;
|
||||
using BarRaider.SdTools.Payloads;
|
||||
using CoreAudio;
|
||||
using FocusVolumeControl.AudioSessions;
|
||||
using FocusVolumeControl.UI;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ServiceModel.Description;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace FocusVolumeControl
|
||||
namespace FocusVolumeControl;
|
||||
|
||||
[PluginActionId("com.dlprows.focusvolumecontrol.dialaction")]
|
||||
public class DialAction : EncoderBase
|
||||
{
|
||||
|
||||
/*
|
||||
todo:
|
||||
link both discord processes
|
||||
steam not detecting
|
||||
|
||||
long press reset
|
||||
|
||||
option for what to do when on app without sound
|
||||
|
||||
*/
|
||||
|
||||
|
||||
[PluginActionId("com.dlprows.focusvolumecontrol.dialaction")]
|
||||
public class DialAction : EncoderBase
|
||||
private class PluginSettings
|
||||
{
|
||||
private class PluginSettings
|
||||
|
||||
[JsonProperty("onVolumeNotFound")]
|
||||
public FallbackBehavior FallbackBehavior { get; set; }
|
||||
|
||||
public static PluginSettings CreateDefaultSettings()
|
||||
{
|
||||
public static PluginSettings CreateDefaultSettings()
|
||||
{
|
||||
PluginSettings instance = new PluginSettings();
|
||||
return instance;
|
||||
}
|
||||
PluginSettings instance = new PluginSettings();
|
||||
instance.FallbackBehavior = FallbackBehavior.PreviousApp;
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
private PluginSettings settings;
|
||||
|
||||
IntPtr _foregroundWindowChangedEvent;
|
||||
Native.WinEventDelegate _delegate;
|
||||
|
||||
IAudioSession _currentAudioSession;
|
||||
AudioHelper _audioHelper = new AudioHelper();
|
||||
|
||||
Thread _thread;
|
||||
Dispatcher _dispatcher;
|
||||
|
||||
UIState _previousState;
|
||||
|
||||
public DialAction(ISDConnection connection, InitialPayload payload) : base(connection, payload)
|
||||
{
|
||||
if (payload.Settings == null || payload.Settings.Count == 0)
|
||||
{
|
||||
settings = PluginSettings.CreateDefaultSettings();
|
||||
SaveSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
settings = payload.Settings.ToObject<PluginSettings>();
|
||||
}
|
||||
|
||||
private PluginSettings settings;
|
||||
|
||||
IntPtr _foregroundWindowChangedEvent;
|
||||
Native.WinEventDelegate _delegate;
|
||||
|
||||
ActiveAudioSessionWrapper _currentAudioSession;
|
||||
AudioHelper _audioHelper = new AudioHelper();
|
||||
|
||||
Thread _thread;
|
||||
Dispatcher _dispatcher;
|
||||
|
||||
UIState _previousState;
|
||||
|
||||
public DialAction(ISDConnection connection, InitialPayload payload) : base(connection, payload)
|
||||
_thread = new Thread(() =>
|
||||
{
|
||||
if (payload.Settings == null || payload.Settings.Count == 0)
|
||||
{
|
||||
settings = PluginSettings.CreateDefaultSettings();
|
||||
SaveSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
settings = payload.Settings.ToObject<PluginSettings>();
|
||||
}
|
||||
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Registering for events");
|
||||
_delegate = new Native.WinEventDelegate(WinEventProc);
|
||||
_foregroundWindowChangedEvent = Native.RegisterForForegroundWindowChangedEvent(_delegate);
|
||||
|
||||
_thread = new Thread(() =>
|
||||
{
|
||||
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Registering for events");
|
||||
_delegate = new Native.WinEventDelegate(WinEventProc);
|
||||
_foregroundWindowChangedEvent = Native.RegisterForForegroundWindowChangedEvent(_delegate);
|
||||
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Starting Dispatcher");
|
||||
_dispatcher = Dispatcher.CurrentDispatcher;
|
||||
Dispatcher.Run();
|
||||
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Dispatcher Stopped");
|
||||
});
|
||||
_thread.SetApartmentState(ApartmentState.STA);
|
||||
_thread.Start();
|
||||
|
||||
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Starting Dispatcher");
|
||||
_dispatcher = Dispatcher.CurrentDispatcher;
|
||||
Dispatcher.Run();
|
||||
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Dispatcher Stopped");
|
||||
});
|
||||
_thread.SetApartmentState(ApartmentState.STA);
|
||||
_thread.Start();
|
||||
|
||||
_currentAudioSession = settings.FallbackBehavior == FallbackBehavior.SystemSounds ? _audioHelper.GetSystemSounds() : _audioHelper.GetSystemVolume();
|
||||
}
|
||||
|
||||
public override async void DialDown(DialPayload payload)
|
||||
{
|
||||
//dial pressed down
|
||||
Logger.Instance.LogMessage(TracingLevel.INFO, "Dial Down");
|
||||
await ToggleMuteAsync();
|
||||
}
|
||||
|
||||
public override async void TouchPress(TouchpadPressPayload payload)
|
||||
{
|
||||
Logger.Instance.LogMessage(TracingLevel.INFO, "Touch Press");
|
||||
if (payload.IsLongPress)
|
||||
{
|
||||
_audioHelper.ResetAll();
|
||||
}
|
||||
|
||||
public override async void DialDown(DialPayload payload)
|
||||
else
|
||||
{
|
||||
//dial pressed down
|
||||
Logger.Instance.LogMessage(TracingLevel.INFO, "Dial Down");
|
||||
await ToggleMuteAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public override async void TouchPress(TouchpadPressPayload payload)
|
||||
async Task ToggleMuteAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.Instance.LogMessage(TracingLevel.INFO, "Touch Press");
|
||||
if (payload.IsLongPress)
|
||||
{
|
||||
//todo: iterate through all sessions setting them back to 100 except the master volume
|
||||
}
|
||||
else
|
||||
{
|
||||
await ToggleMuteAsync();
|
||||
}
|
||||
}
|
||||
|
||||
async Task ToggleMuteAsync()
|
||||
{
|
||||
if (_currentAudioSession != null)
|
||||
{
|
||||
_currentAudioSession.ToggleMute();
|
||||
@@ -118,11 +106,19 @@ namespace FocusVolumeControl
|
||||
await Connection.ShowAlert();
|
||||
}
|
||||
}
|
||||
|
||||
public override async void DialRotate(DialRotatePayload payload)
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Connection.ShowAlert();
|
||||
Logger.Instance.LogMessage(TracingLevel.ERROR, $"Unable to toggle mute: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public override async void DialRotate(DialRotatePayload payload)
|
||||
{
|
||||
Logger.Instance.LogMessage(TracingLevel.INFO, "Dial Rotate");
|
||||
//dial rotated. ticks positive for right, negative for left
|
||||
try
|
||||
{
|
||||
Logger.Instance.LogMessage(TracingLevel.INFO, "Dial Rotate");
|
||||
//dial rotated. ticks positive for right, negative for left
|
||||
if (_currentAudioSession != null)
|
||||
{
|
||||
_currentAudioSession.IncrementVolumeLevel(1, payload.Ticks);
|
||||
@@ -133,89 +129,89 @@ namespace FocusVolumeControl
|
||||
await Connection.ShowAlert();
|
||||
}
|
||||
}
|
||||
|
||||
public override void DialUp(DialPayload payload)
|
||||
catch (Exception ex)
|
||||
{
|
||||
//dial unpressed
|
||||
Logger.Instance.LogMessage(TracingLevel.INFO, "Dial Up");
|
||||
await Connection.ShowAlert();
|
||||
Logger.Instance.LogMessage(TracingLevel.ERROR, $"Unable to toggle mute: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Disposing");
|
||||
public override void DialUp(DialPayload payload)
|
||||
{
|
||||
//dial unpressed
|
||||
Logger.Instance.LogMessage(TracingLevel.INFO, "Dial Up");
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Disposing");
|
||||
if(_foregroundWindowChangedEvent != IntPtr.Zero)
|
||||
{
|
||||
Native.UnhookWinEvent(_foregroundWindowChangedEvent);
|
||||
}
|
||||
_dispatcher.InvokeShutdown();
|
||||
_dispatcher.InvokeShutdown();
|
||||
}
|
||||
|
||||
public override async void OnTick()
|
||||
{
|
||||
//called once every 1000ms and can be used for updating the title/image of the key
|
||||
var activeSession = _audioHelper.GetActiveSession(settings.FallbackBehavior);
|
||||
|
||||
if(activeSession != null)
|
||||
{
|
||||
_currentAudioSession = activeSession;
|
||||
}
|
||||
|
||||
public override async void OnTick()
|
||||
{
|
||||
//called once every 1000ms and can be used for updating the title/image fo the key
|
||||
var activeSession = _audioHelper.GetActiveSession();
|
||||
await UpdateStateIfNeeded();
|
||||
}
|
||||
|
||||
if (activeSession == null)
|
||||
private async Task UpdateStateIfNeeded()
|
||||
{
|
||||
if (_currentAudioSession != null)
|
||||
{
|
||||
|
||||
var uiState = new UIState(_currentAudioSession);
|
||||
|
||||
if ( _previousState != null && uiState != null &&
|
||||
uiState.Title == _previousState.Title &&
|
||||
uiState.Value.Value == _previousState.Value.Value &&
|
||||
uiState.Value.Opacity == _previousState.Value.Opacity &&
|
||||
uiState.Indicator.Value == _previousState.Indicator.Value &&
|
||||
uiState.Indicator.Opacity == _previousState.Indicator.Opacity &&
|
||||
uiState.icon.Value == _previousState.icon.Value &&
|
||||
uiState.icon.Opacity == _previousState.icon.Opacity
|
||||
)
|
||||
{
|
||||
//todo: something?
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentAudioSession = activeSession;
|
||||
return;
|
||||
}
|
||||
|
||||
await UpdateStateIfNeeded();
|
||||
}
|
||||
|
||||
private async Task UpdateStateIfNeeded()
|
||||
{
|
||||
if (_currentAudioSession != null)
|
||||
{
|
||||
|
||||
var uiState = UIState.Build(_currentAudioSession);
|
||||
|
||||
if ( _previousState != null && uiState != null &&
|
||||
uiState.Title == _previousState.Title &&
|
||||
uiState.Value.Value == _previousState.Value.Value &&
|
||||
uiState.Value.Opacity == _previousState.Value.Opacity &&
|
||||
uiState.Indicator.Value == _previousState.Indicator.Value &&
|
||||
uiState.Indicator.Opacity == _previousState.Indicator.Opacity &&
|
||||
uiState.icon.Value == _previousState.icon.Value &&
|
||||
uiState.icon.Opacity == _previousState.icon.Opacity
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await Connection.SetFeedbackAsync(uiState);
|
||||
_previousState = uiState;
|
||||
}
|
||||
await Connection.SetFeedbackAsync(uiState);
|
||||
_previousState = uiState;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload)
|
||||
{
|
||||
}
|
||||
public override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override void ReceivedSettings(ReceivedSettingsPayload payload)
|
||||
{
|
||||
Tools.AutoPopulateSettings(settings, payload.Settings);
|
||||
SaveSettings();
|
||||
}
|
||||
public override void ReceivedSettings(ReceivedSettingsPayload payload)
|
||||
{
|
||||
Tools.AutoPopulateSettings(settings, payload.Settings);
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
private Task SaveSettings()
|
||||
{
|
||||
return Connection.SetSettingsAsync(JObject.FromObject(settings));
|
||||
}
|
||||
private Task SaveSettings()
|
||||
{
|
||||
return Connection.SetSettingsAsync(JObject.FromObject(settings));
|
||||
}
|
||||
|
||||
|
||||
public void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
|
||||
{
|
||||
OnTick();
|
||||
OnTick();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user