diff --git a/ColorControl/ColorControl.csproj b/ColorControl/ColorControl.csproj index 2331356..fa24a7a 100644 --- a/ColorControl/ColorControl.csproj +++ b/ColorControl/ColorControl.csproj @@ -27,7 +27,7 @@ ColorControl Maassoft 0 - 2.2.0.0 + 3.0.0.0 false true true @@ -177,6 +177,18 @@ + + + True + True + Resources.resx + + + UserControl + + + RemoteControlPanel.cs + @@ -226,21 +238,22 @@ + + MainForm.cs ResXFileCodeGenerator - Resources.Designer.cs Designer + Resources.Designer.cs - - True - Resources.resx - RemoteControlForm.cs + + RemoteControlPanel.cs + PreserveNewest diff --git a/ColorControl/LgDevice.cs b/ColorControl/LgDevice.cs new file mode 100644 index 0000000..1dbbda0 --- /dev/null +++ b/ColorControl/LgDevice.cs @@ -0,0 +1,358 @@ +using LgTv; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace ColorControl +{ + class LgDevice + { + protected static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); + + public string Name { get; private set; } + public string IpAddress { get; private set; } + public string MacAddress { get; private set; } + public bool IsCustom { get; private set; } + [JsonIgnore] + public bool IsDummy { get; private set; } + + public bool PowerOnAfterStartup { get; set; } + public bool PowerOnAfterResume { get; set; } + public bool PowerOffOnShutdown { get; set; } + public bool PowerOffOnStandby { get; set; } + public bool PowerSwitchOnScreenSaver { get; set; } + + [JsonIgnore] + private LgTvApi _lgTvApi; + [JsonIgnore] + private bool _justWokeUp; + + [JsonIgnore] + private Dictionary> _invokableActions = new Dictionary>(); + + [JsonConstructor] + public LgDevice(string name, string ipAddress, string macAddress, bool isCustom = true, bool isDummy = false) + { + Name = name; + IpAddress = ipAddress; + MacAddress = macAddress; + IsCustom = isCustom; + IsDummy = isDummy; + + _invokableActions.Add("WOL", new Func(Wake)); + } + + public override string ToString() + { + return (IsDummy ? string.Empty : (IsCustom ? "Custom: " : "Auto detect: ")) + $"{Name}" + (!string.IsNullOrEmpty(IpAddress) ? $" ({IpAddress})" : string.Empty); + } + + public async Task Connect(int retries = 3) + { + try + { + DisposeConnection(); + _lgTvApi = await LgTvApi.CreateLgTvApi(IpAddress, retries); + + //Test(); + return _lgTvApi != null; + } + catch (Exception ex) + { + string logMessage = ex.ToLogString(Environment.StackTrace); + Logger.Error($"Error while connecting to {IpAddress}: {logMessage}"); + return false; + } + } + + public bool IsConnected() + { + return !_lgTvApi?.ConnectionClosed ?? false; + } + + internal void DisposeConnection() + { + if (_lgTvApi != null) + { + _lgTvApi.Dispose(); + _lgTvApi = null; + } + } + public async Task ExecutePreset(LgPreset preset, bool reconnect = false) + { + var hasApp = !string.IsNullOrEmpty(preset.appId); + + var hasWOL = preset.steps.Any(s => s.Equals("WOL", StringComparison.OrdinalIgnoreCase)); + + if (hasWOL) + { + var connected = await WakeAndConnect(0); + if (!connected) + { + return false; + } + } + + for (var tries = 0; tries <= 1; tries++) + { + if (!await Connected(reconnect || tries == 1)) + { + return false; + } + + if (hasApp) + { + try + { + await _lgTvApi.LaunchApp(preset.appId); + } + catch (Exception ex) + { + string logMessage = ex.ToLogString(Environment.StackTrace); + Logger.Error("Error while launching app: " + logMessage); + + if (tries == 0) + { + continue; + } + return false; + } + + if (_justWokeUp) + { + _justWokeUp = false; + await Task.Delay(1000); + } + } + + if (preset.steps.Any()) + { + if (hasApp) + { + await Task.Delay(1500); + } + try + { + await ExecuteSteps(_lgTvApi, preset); + } + catch (Exception ex) + { + string logMessage = ex.ToLogString(Environment.StackTrace); + Logger.Error("Error while executing steps: " + logMessage); + + if (tries == 0) + { + continue; + } + return false; + } + } + + return true; + } + + return true; + } + + private async Task ExecuteSteps(LgTvApi api, LgPreset preset) + { + var mouse = await api.GetMouse(); + foreach (var step in preset.steps) + { + var keySpec = step.Split(':'); + var key = keySpec[0].ToUpper(); + if (_invokableActions.ContainsKey(key)) + { + continue; + } + + if (keySpec.Length == 2) + { + SendKey(mouse, key, int.Parse(keySpec[1])); + } + else + { + SendKey(mouse, key); + } + } + } + + private void SendKey(LgWebOsMouseService mouse, string key, int delay = 180) + { + if (key.Length == 1 && int.TryParse(key, out _)) + { + key = "_" + key; + } + var button = (ButtonType)Enum.Parse(typeof(ButtonType), key); + mouse.SendButton(button); + Thread.Sleep(delay); + } + + public async Task GetMouseAsync() + { + return await _lgTvApi.GetMouse(); + } + + public async Task> GetApps(bool force = false) + { + if (!await Connected(force)) + { + Logger.Debug("Cannot refresh apps: no connection could be made"); + return new List(); + } + + return await _lgTvApi.GetApps(force); + } + + internal async Task PowerOff() + { + if (!await Connected(true)) + { + return false; + } + + await _lgTvApi.TurnOff(); + return true; + } + + internal async Task TestConnection(int retries = 1) + { + if (!await Connected(true, retries)) + { + return false; + } + + try + { + await _lgTvApi.IsMuted(); + return true; + } + catch (Exception ex) + { + Logger.Error("TestConnection: " + ex.ToLogString()); + return false; + } + } + + internal async Task WakeAndConnect(int wakeDelay = 5000, int connectDelay = 500) + { + try + { + //if (wakeDelay == 0) + //{ + // if (await ConnectToSelectedDevice()) + // { + // Logger.Debug("Already connected, no wake needed?"); + // return; + // }; + //} + + await Task.Delay(wakeDelay); + var result = Wake(); + if (!result) + { + Logger.Debug("WOL failed"); + return false; + } + Logger.Debug("WOL succeeded"); + await Task.Delay(connectDelay); + result = await Connect(); + Logger.Debug("Connect succeeded: " + result); + return result; + } + catch (Exception e) + { + Logger.Error("WakeAndConnectToSelectedDevice: " + e.ToLogString()); + return false; + } + } + + internal bool Wake() + { + var result = false; + + if (MacAddress != null) + { + result = WOL.WakeFunction(MacAddress); + _justWokeUp = true; + } + else + { + Logger.Debug("Cannot wake device: the device has no MAC-address"); + } + + return result; + } + + internal async Task WakeAndConnectWithRetries(int retries = 5) + { + var wakeDelay = 0; + var maxRetries = retries <= 1 ? 5 : retries; + + var result = false; + for (var retry = 0; retry < maxRetries && !result; retry++) + { + Logger.Debug($"WakeAndConnectWithRetries: attempt {retry + 1} of {maxRetries}..."); + + var ms = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + result = await WakeAndConnect(retry == 0 ? wakeDelay : 0); + ms = DateTimeOffset.Now.ToUnixTimeMilliseconds() - ms; + if (!result) + { + var delay = 2000 - ms; + if (delay > 0) + { + await Task.Delay((int)delay); + } + } + } + + return result; + } + + public Dictionary> GetInvokableActions() + { + return _invokableActions; + } + + public async Task PowerOn() + { + var mouse = await _lgTvApi.GetMouse(); + mouse.SendButton(ButtonType.POWER); + } + + public void Test() + { + try + { + //_lgTvApi.GetServiceList(); + //_lgTvApi?.Test(); + } + catch (Exception ex) + { + Logger.Error("TEST: " + ex.ToLogString()); + } + } + + private async Task Connected(bool reconnect = false, int retries = 3) + { + if (reconnect || !IsConnected() || !string.Equals(_lgTvApi.GetIpAddress(), IpAddress)) + { + if (!await Connect(retries)) + { + Logger.Debug("Cannot apply LG-preset: no connection could be made"); + return false; + } + } + return true; + } + + internal void ConvertToCustom() + { + IsCustom = true; + } + } +} diff --git a/ColorControl/LgPreset.cs b/ColorControl/LgPreset.cs index 7721999..fc113c7 100644 --- a/ColorControl/LgPreset.cs +++ b/ColorControl/LgPreset.cs @@ -1,4 +1,5 @@ using LgTv; +using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; @@ -6,10 +7,18 @@ namespace ColorControl { class LgPreset : PresetBase { + public static List LgApps { get; set; } + public static List LgDevices { get; set; } + + public string appId { get; set; } public List steps { get; set; } + public string DeviceMacAddress { get; set; } - public static List LgApps { get; set; } + [JsonIgnore] + public int X { get; set; } + [JsonIgnore] + public int Y { get; set; } public LgPreset() { @@ -37,7 +46,7 @@ namespace ColorControl public static List GetColumnNames() { - return new List() { "Name", "App|200", "Steps|400", "Shortcut" }; + return new List() { "Name", "Device|120", "App|200", "Steps|400", "Shortcut" }; } public override List GetDisplayValues(Config config = null) @@ -45,6 +54,29 @@ namespace ColorControl var values = new List(); values.Add(name); + + var deviceString = "Global"; + if (!string.IsNullOrEmpty(DeviceMacAddress)) + { + if (LgDevices != null) + { + var device = LgDevices.FirstOrDefault(d => !string.IsNullOrEmpty(d.MacAddress) && d.MacAddress.Equals(DeviceMacAddress)); + if (device != null) + { + deviceString = device.Name; + } + else + { + deviceString = "Unknown: device not found"; + } + } + else + { + deviceString = DeviceMacAddress; + } + } + values.Add(deviceString); + var app = appId; if (LgApps != null) { diff --git a/ColorControl/LgService.cs b/ColorControl/LgService.cs index fb1c452..dfb67a7 100644 --- a/ColorControl/LgService.cs +++ b/ColorControl/LgService.cs @@ -15,16 +15,21 @@ namespace ColorControl { class LgService : ServiceBase { + internal enum PowerOnOffState + { + StartUp = 1, + Resume = 2, + ScreenSaver = 3, + ShutDown = 4, + StandBy = 5 + } + protected static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); public static string LgListAppsJson = "listApps.json"; - //private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); - - //public string FriendlyScreenName { get; private set; } - - public List Devices { get; private set; } - public PnpDev SelectedDevice + public List Devices { get; private set; } + public LgDevice SelectedDevice { get { return _selectedDevice; } set @@ -36,17 +41,13 @@ namespace ColorControl public LgServiceConfig Config { get; private set; } - private LgTvApi _lgTvApi; private string _configFilename; private bool _allowPowerOn; - private bool _justWokeUp; - private PnpDev _selectedDevice; + private LgDevice _selectedDevice; private string _rcButtonsFilename; private List _remoteControlButtons; private List _lgApps = new List(); - private Dictionary> _invokableActions = new Dictionary>(); - private bool _poweredOffByScreenSaver; private int _poweredOffByScreenSaverProcessId; private Task _monitorTask; @@ -56,22 +57,11 @@ namespace ColorControl { _allowPowerOn = allowPowerOn; - _invokableActions.Add("WOL", new Func(WakeSelectedDevice)); - LgPreset.LgApps = _lgApps; LoadConfig(); LoadPresets(); LoadRemoteControlButtons(); - - //foreach (var screen in Screen.AllScreens) - //{ - // var name = screen.DeviceFriendlyName(); - // if (name.Contains("LG")) - // { - // FriendlyScreenName = name; - // } - //} } ~LgService() @@ -165,6 +155,8 @@ namespace ColorControl { Config = new LgServiceConfig(); } + + LgPreset.LgDevices = Config.Devices; } private void LoadRemoteControlButtons() @@ -192,11 +184,6 @@ namespace ColorControl return _remoteControlButtons; } - public Dictionary> GetInvokableActions() - { - return _invokableActions; - } - private List GenerateDefaultRemoteControlButtons() { var list = new List(); @@ -207,11 +194,18 @@ namespace ColorControl list.Add(GeneratePreset(button.ToString())); } + list.Add(GeneratePreset("Power", step: "POWER")); + list.Add(GeneratePreset("Home", appId: "com.webos.app.home", key: Keys.H)); list.Add(GeneratePreset("Settings", appId: "com.palm.app.settings", key: Keys.S)); + list.Add(GeneratePreset("TV Guide", appId: "com.webos.app.livemenu")); + list.Add(GeneratePreset("List", step: "LIST")); + list.Add(GeneratePreset("SAP", step: "SAP")); list.Add(GeneratePreset("Vol +", step: "VOLUMEUP", key: Keys.VolumeUp)); list.Add(GeneratePreset("Vol -", step: "VOLUMEDOWN", key: Keys.VolumeDown)); list.Add(GeneratePreset("Mute", step: "MUTE", key: Keys.VolumeMute)); + list.Add(GeneratePreset("Channel +", step: "CHANNELUP", key: Keys.MediaNextTrack)); + list.Add(GeneratePreset("Channel -", step: "CHANNELDOWN", key: Keys.MediaPreviousTrack)); list.Add(GeneratePreset("Up", step: "UP", key: Keys.Up)); list.Add(GeneratePreset("Down", step: "DOWN", key: Keys.Down)); @@ -222,6 +216,19 @@ namespace ColorControl list.Add(GeneratePreset("Back", step: "BACK", key: Keys.Back)); list.Add(GeneratePreset("Exit", step: "EXIT", key: Keys.Escape)); + list.Add(GeneratePreset("Netflix", appId: "netflix")); + list.Add(GeneratePreset("Inputs", appId: "com.webos.app.homeconnect")); + list.Add(GeneratePreset("Amazon Prime", appId: "amazon")); + + list.Add(GeneratePreset("Red", step: "RED")); + list.Add(GeneratePreset("Green", step: "GREEN")); + list.Add(GeneratePreset("Yellow", step: "YELLOW")); + list.Add(GeneratePreset("Blue", step: "BLUE")); + + list.Add(GeneratePreset("Rakuten TV", appId: "ui30")); + list.Add(GeneratePreset("Play", step: "PLAY")); + list.Add(GeneratePreset("Pause", step: "PAUSE")); + return list; } @@ -258,6 +265,8 @@ namespace ColorControl private void SaveConfig() { + Config.PowerOnAfterStartup = Devices.Any(d => d.PowerOnAfterStartup); + var json = JsonConvert.SerializeObject(Config); File.WriteAllText(_configFilename, json); } @@ -270,14 +279,36 @@ namespace ColorControl public async Task RefreshDevices(bool connect = true, bool afterStartUp = false) { - var devices = await Utils.GetPnpDevices(Config.DeviceSearchKey); - SetDevices(devices); + Devices = Config.Devices; + var customIpAddresses = Devices.Where(d => d.IsCustom).Select(d => d.IpAddress); + + var pnpDevices = await Utils.GetPnpDevices(Config.DeviceSearchKey); + + var autoDevices = pnpDevices.Where(p => !customIpAddresses.Contains(p.IpAddress)).Select(d => new LgDevice(d.Name, d.IpAddress, d.MacAddress, false)).ToList(); + var autoIpAddresses = pnpDevices.Select(d => d.IpAddress); + + Devices.RemoveAll(d => !d.IsCustom && !autoIpAddresses.Contains(d.IpAddress)); + + var newAutoDevices = autoDevices.Where(ad => !Devices.Any(d => d.IpAddress.Equals(ad.IpAddress))); + Devices.AddRange(newAutoDevices); + + if (Devices.Any()) + { + var preferredDevice = Devices.FirstOrDefault(x => x.MacAddress != null && x.MacAddress.Equals(Config.PreferredMacAddress)) ?? Devices[0]; + + SelectedDevice = preferredDevice; + } + else + { + SelectedDevice = null; + } if (afterStartUp && SelectedDevice == null && Config.PowerOnAfterStartup && !string.IsNullOrEmpty(Config.PreferredMacAddress)) { Logger.Debug("No device has been found, trying to wake it first..."); - WakeSelectedDevice(Config.PreferredMacAddress); + var tempDevice = new LgDevice("Test", string.Empty, Config.PreferredMacAddress); + tempDevice.Wake(); await Task.Delay(4000); await RefreshDevices(); @@ -287,70 +318,17 @@ namespace ColorControl if (connect && SelectedDevice != null) { - if (Config.PowerOnAfterStartup && _allowPowerOn) + if (_allowPowerOn) { - var _ = WakeAndConnectToSelectedDeviceWithRetries(); + WakeAfterStartupOrResume(); } else { - var _ = ConnectToSelectedDevice(); + var _ = SelectedDevice.Connect(); } } } - private void SetDevices(List devices) - { - Devices = devices; - if (Devices?.Count > 0) - { - var preferredDevice = Devices.FirstOrDefault(x => x.MacAddress != null && x.MacAddress.Equals(Config.PreferredMacAddress)) ?? Devices[0]; - - SelectedDevice = preferredDevice; - } - } - - public async Task ConnectToSelectedDevice(int retries = 3) - { - try - { - DisposeConnection(); - _lgTvApi = await LgTvApi.CreateLgTvApi(SelectedDevice.IpAddress, retries); - - //_lgTvApi.GetServiceList(); - return _lgTvApi != null; - } - catch (Exception ex) - { - string logMessage = ex.ToLogString(Environment.StackTrace); - Logger.Error($"Error while connecting to {SelectedDevice.IpAddress}: {logMessage}"); - return false; - } - } - - private async Task Connected(bool reconnect = false) - { - if (SelectedDevice == null) - { - Logger.Debug("Cannot apply LG-preset: no device has been selected"); - return false; - } - - if (reconnect || !IsConnected() || !string.Equals(_lgTvApi.GetIpAddress(), SelectedDevice.IpAddress)) - { - if (!await ConnectToSelectedDevice()) - { - Logger.Debug("Cannot apply LG-preset: no connection could be made"); - return false; - } - } - return true; - } - - private bool IsConnected() - { - return !_lgTvApi?.ConnectionClosed ?? false; - } - public async Task ApplyPreset(string presetName) { var preset = _presets.FirstOrDefault(p => p.name.Equals(presetName, StringComparison.OrdinalIgnoreCase)); @@ -366,123 +344,28 @@ namespace ColorControl public async Task ApplyPreset(LgPreset preset, bool reconnect = false) { - var hasApp = !string.IsNullOrEmpty(preset.appId); + var device = GetPresetDevice(preset); - var hasWOL = preset.steps.Any(s => s.Equals("WOL", StringComparison.OrdinalIgnoreCase)); - - if (hasWOL) + if (device == null) { - var connected = await WakeAndConnectToSelectedDevice(0); - if (!connected) - { - return false; - } + Logger.Debug("Cannot apply preset: no device has been selected"); + return false; } - for (var tries = 0; tries <= 1; tries++) - { - if (!await Connected(reconnect || tries == 1)) - { - return false; - } - - if (hasApp) - { - try - { - await _lgTvApi.LaunchApp(preset.appId); - } - catch (Exception ex) - { - string logMessage = ex.ToLogString(Environment.StackTrace); - Logger.Error("Error while launching app: " + logMessage); - - if (tries == 0) - { - continue; - } - return false; - } - - if (_justWokeUp) - { - _justWokeUp = false; - await Task.Delay(1000); - } - } - - if (preset.steps.Any()) - { - if (hasApp) - { - await Task.Delay(1500); - } - try - { - await ExecuteSteps(_lgTvApi, preset); - } - catch (Exception ex) - { - string logMessage = ex.ToLogString(Environment.StackTrace); - Logger.Error("Error while executing steps: " + logMessage); - - if (tries == 0) - { - continue; - } - return false; - } - } - - return true; - } - - return true; + return await device.ExecutePreset(preset, reconnect); } - public async Task PowerOn() + public LgDevice GetPresetDevice(LgPreset preset) { - var mouse = await _lgTvApi.GetMouse(); - mouse.SendButton(ButtonType.POWER); - } - - private async Task ExecuteSteps(LgTvApi api, LgPreset preset) - { - var mouse = await api.GetMouse(); - foreach (var step in preset.steps) - { - var keySpec = step.Split(':'); - var key = keySpec[0].ToUpper(); - if (_invokableActions.ContainsKey(key)) - { - continue; - } - - if (keySpec.Length == 2) - { - SendKey(mouse, key, int.Parse(keySpec[1])); - } - else - { - SendKey(mouse, key); - } - } - } - - private void SendKey(LgWebOsMouseService mouse, string key, int delay = 180) - { - if (key.Length == 1 && int.TryParse(key, out _)) - { - key = "_" + key; - } - var button = (ButtonType)Enum.Parse(typeof(ButtonType), key); - mouse.SendButton(button); - Thread.Sleep(delay); + var device = string.IsNullOrEmpty(preset.DeviceMacAddress) + ? SelectedDevice + : Devices.FirstOrDefault(d => d.MacAddress?.Equals(preset.DeviceMacAddress, StringComparison.OrdinalIgnoreCase) ?? false); + return device; } public async Task GetMouseAsync() { - return await _lgTvApi.GetMouse(); + return await SelectedDevice?.GetMouseAsync(); } public async Task RefreshApps(bool force = false) @@ -490,15 +373,16 @@ namespace ColorControl if (SelectedDevice == null) { Logger.Debug("Cannot refresh apps: no device has been selected"); + return; } - if (!await Connected(force)) + var apps = await SelectedDevice.GetApps(); + + if (apps.Any()) { - Logger.Debug("Cannot refresh apps: no connection could be made"); + _lgApps.Clear(); + _lgApps.AddRange(apps); } - - _lgApps.Clear(); - _lgApps.AddRange(await _lgTvApi.GetApps(force)); } public List GetApps() @@ -506,138 +390,47 @@ namespace ColorControl return _lgApps; } - internal void DisposeConnection() - { - if (_lgTvApi != null) - { - _lgTvApi.Dispose(); - _lgTvApi = null; - } - } - internal async Task PowerOff() { - if (!await Connected(true)) - { - return false; - } - - await _lgTvApi.TurnOff(); - return true; + return await SelectedDevice?.PowerOff(); } - internal async Task TestConnection() + internal Task PowerOffOnShutdownOrResume(PowerOnOffState state = PowerOnOffState.ShutDown) { - if (!await Connected(true)) + var devices = Devices.Where(d => state == PowerOnOffState.ShutDown && d.PowerOffOnShutdown || + state == PowerOnOffState.StandBy && d.PowerOffOnStandby); + + var tasks = new List(); + foreach (var device in devices) { - return false; + var task = device.PowerOff(); + + tasks.Add(task); } - try - { - await _lgTvApi.IsMuted(); - return true; - } - catch (Exception ex) - { - Logger.Error("TestConnection: " + ex.ToLogString()); - return false; - } + return Task.WhenAll(tasks.ToArray()); } internal bool WakeSelectedDevice() { - return WakeSelectedDevice(SelectedDevice?.MacAddress ?? Config.PreferredMacAddress); + return SelectedDevice?.Wake() ?? false; } - internal bool WakeSelectedDevice(string macAddress) - { - var result = false; - - macAddress = string.IsNullOrEmpty(macAddress) ? SelectedDevice?.MacAddress : macAddress; - if (macAddress != null) - { - result = WOL.WakeFunction(macAddress, Config.UseOldNpcapWol); - _justWokeUp = true; - } - else - { - Logger.Debug("Cannot wake device: no device has been selected or there is no preferred MAC-address stored in the configuration"); - } - - return result; - } - - internal void WakeAfterResume() - { - if (Config.PowerOnAfterResume) - { - var _ = WakeAndConnectToSelectedDeviceWithRetries(); - } - } - - private async Task WakeAndConnectToSelectedDeviceWithRetries(bool checkUserSession = true) + internal void WakeAfterStartupOrResume(PowerOnOffState state = PowerOnOffState.StartUp, bool checkUserSession = true) { if (checkUserSession && !UserSessionInfo.UserLocalSession) { - Logger.Debug($"WakeAndConnectToSelectedDeviceWithRetries: not waking because session info indicates no local session"); - return false; + Logger.Debug($"WakeAfterStartupOrResume: not waking because session info indicates no local session"); + return; } - var wakeDelay = 0; - var maxRetries = Config.PowerOnRetries <= 1 ? 5 : Config.PowerOnRetries; - - var result = false; - for (var retry = 0; retry < maxRetries && !result; retry++) + var wakeDevices = Devices.Where(d => state == PowerOnOffState.StartUp && d.PowerOnAfterStartup || + state == PowerOnOffState.Resume && d.PowerOnAfterResume || + state == PowerOnOffState.ScreenSaver && d.PowerSwitchOnScreenSaver); + foreach (var device in wakeDevices) { - Logger.Debug($"WakeAndConnectToSelectedDeviceWithRetries: attempt {retry + 1} of {maxRetries}..."); - - var ms = DateTimeOffset.Now.ToUnixTimeMilliseconds(); - result = await WakeAndConnectToSelectedDevice(retry == 0 ? wakeDelay : 0); - ms = DateTimeOffset.Now.ToUnixTimeMilliseconds() - ms; - if (!result) - { - var delay = 2000 - ms; - if (delay > 0) - { - await Task.Delay((int)delay); - } - } - } - - return result; - } - - private async Task WakeAndConnectToSelectedDevice(int wakeDelay = 5000, int connectDelay = 500) - { - try - { - //if (wakeDelay == 0) - //{ - // if (await ConnectToSelectedDevice()) - // { - // Logger.Debug("Already connected, no wake needed?"); - // return; - // }; - //} - - await Task.Delay(wakeDelay); - var result = WakeSelectedDevice(); - if (!result) - { - Logger.Debug("WOL failed"); - return false; - } - Logger.Debug("WOL succeeded"); - await Task.Delay(connectDelay); - result = await ConnectToSelectedDevice(); - Logger.Debug("Connect succeeded: " + result); - return result; - } - catch (Exception e) - { - Logger.Error("WakeAndConnectToSelectedDevice: " + e.ToLogString()); - return false; + device.DisposeConnection(); + var _ = device.WakeAndConnectWithRetries(Config.PowerOnRetries); } } @@ -663,7 +456,7 @@ namespace ColorControl Logger.Debug("User switched to local and screen was powered off due to screensaver: waking up"); _poweredOffByScreenSaver = false; _poweredOffByScreenSaverProcessId = 0; - var _ = WakeAndConnectToSelectedDeviceWithRetries(); + WakeAfterStartupOrResume(); } else { @@ -680,18 +473,17 @@ namespace ColorControl if (powerOn) { - DisposeConnection(); - WakeAfterResume(); + WakeAfterStartupOrResume(PowerOnOffState.Resume); return; } - if (Config.PowerOffOnStandby) + if (Devices.Any(d => d.PowerOffOnStandby)) { NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS | NativeConstants.ES_SYSTEM_REQUIRED | NativeConstants.ES_AWAYMODE_REQUIRED); try { Logger.Debug("Powering off tv..."); - var task = PowerOff(); + var task = PowerOffOnShutdownOrResume(PowerOnOffState.StandBy); Utils.WaitForTask(task); Logger.Debug("Done powering off tv"); } @@ -717,11 +509,12 @@ namespace ColorControl private void MonitorProcesses() { - if (Config.PowerSwitchOnScreenSaver && _monitorTask == null) + var enableMonitoring = Devices.Any(d => d.PowerSwitchOnScreenSaver); + if (enableMonitoring && _monitorTask == null) { _monitorTask = CheckProcesses(); } - else if (!Config.PowerSwitchOnScreenSaver && _monitorTask != null) + else if (!enableMonitoring && _monitorTask != null) { _monitorTask = null; } @@ -729,12 +522,12 @@ namespace ColorControl public async Task CheckProcesses() { - var wasConnected = IsConnected(); + var wasConnected = Devices.Any(d => d.PowerSwitchOnScreenSaver && d.IsConnected()); _monitorTaskCounter++; var validCounter = _monitorTaskCounter; var lastProcessId = 0; - while (Config.PowerSwitchOnScreenSaver && validCounter == _monitorTaskCounter) + while (Devices.Any(d => d.PowerSwitchOnScreenSaver) && validCounter == _monitorTaskCounter) { await Task.Delay(500); @@ -758,16 +551,18 @@ namespace ColorControl _poweredOffByScreenSaver = false; _poweredOffByScreenSaverProcessId = 0; lastProcessId = 0; - var _ = WakeAndConnectToSelectedDeviceWithRetries(); + WakeAfterStartupOrResume(PowerOnOffState.ScreenSaver); continue; } - if (!IsConnected()) + var devices = Devices.Where(d => d.PowerSwitchOnScreenSaver && d.IsConnected()).ToList(); + + if (!devices.Any()) { if (wasConnected) { - Logger.Debug("TV was connected, but not any longer"); + Logger.Debug("Screensaver check: TV(s) where connected, but not any longer"); wasConnected = false; } continue; @@ -775,49 +570,50 @@ namespace ColorControl if (!wasConnected) { - Logger.Debug("TV was not connected, but connection has now been established"); + Logger.Debug("Screensaver check: TV(s) where not connected, but connection has now been established"); wasConnected = true; } - foreach (var process in processes) - { - var name = process.ProcessName.ToLowerInvariant(); - if (name.EndsWith(".scr")) - { - var parent = process.Parent(); - if (parent?.ProcessName.Contains("winlogon") ?? false) - { - Logger.Debug($"Screensaver started: {process.ProcessName}, parent: {parent.ProcessName}"); - try - { - Logger.Debug("Test connection..."); - var test = await TestConnection(); - Logger.Debug("Test connection result: " + test); + var process = processes.FirstOrDefault(p => p.ProcessName.ToLowerInvariant().EndsWith(".scr")); - Logger.Debug("Powering off tv because of screensaver"); - _poweredOffByScreenSaver = await PowerOff(); - _poweredOffByScreenSaverProcessId = process.Id; - lastProcessId = 0; - } - catch (Exception e) - { - Logger.Error("CheckProcesses: can't power off: " + e.ToLogString()); - } - if (!IsConnected()) - { - _poweredOffByScreenSaver = false; - } - break; - } - else + if (process == null) + { + continue; + } + + var parent = process.Parent(); + + if (parent?.ProcessName.Contains("winlogon") ?? false) + { + Logger.Debug($"Screensaver started: {process.ProcessName}, parent: {parent.ProcessName}"); + try + { + foreach (var device in devices) { - if (process.Id != lastProcessId) + Logger.Debug($"Screensaver check: test connection with {device.Name}..."); + var test = await device.TestConnection(); + Logger.Debug("Screensaver check: test connection result: " + test); + if (!test) { - Logger.Debug($"Screensaver started: {process.ProcessName}, but invalid parent: {parent?.ProcessName ?? "no parent"}"); - lastProcessId = process.Id; + continue; } + + Logger.Debug($"Screensaver check: powering off tv {device.Name} because of screensaver"); + _poweredOffByScreenSaver = await device.PowerOff(); } + + _poweredOffByScreenSaverProcessId = process.Id; + lastProcessId = 0; } + catch (Exception e) + { + Logger.Error($"Screensaver check: can't power off: " + e.ToLogString()); + } + } + else if (process.Id != lastProcessId) + { + Logger.Debug($"Screensaver started: {process.ProcessName}, but invalid parent: {parent?.ProcessName ?? "no parent"}"); + lastProcessId = process.Id; } } catch (Exception ex) @@ -826,5 +622,29 @@ namespace ColorControl } } } + + internal void AddCustomDevice(LgDevice device) + { + Devices.Add(device); + } + + internal void RemoveCustomDevice(LgDevice device) + { + Devices.Remove(device); + + if (!string.IsNullOrEmpty(device.MacAddress)) + { + var presets = _presets.Where(p => !string.IsNullOrEmpty(p.DeviceMacAddress) && p.DeviceMacAddress.Equals(device.MacAddress)).ToList(); + presets.ForEach(preset => + { + preset.DeviceMacAddress = null; + }); + } + + if (SelectedDevice == device) + { + SelectedDevice = Devices.Any() ? Devices.First() : null; + } + } } } diff --git a/ColorControl/LgServiceConfig.cs b/ColorControl/LgServiceConfig.cs index 1a7ad36..9773eec 100644 --- a/ColorControl/LgServiceConfig.cs +++ b/ColorControl/LgServiceConfig.cs @@ -1,17 +1,11 @@ -namespace ColorControl +using System.Collections.Generic; + +namespace ColorControl { class LgServiceConfig { public bool PowerOnAfterStartup { get; set; } - public bool PowerOnAfterResume { get; set; } - - public bool PowerOffOnShutdown { get; set; } - - public bool PowerOffOnStandby { get; set; } - - public bool PowerSwitchOnScreenSaver { get; set; } - public int PowerOnDelayAfterResume { get; set; } public int PowerOnRetries { get; set; } @@ -22,11 +16,16 @@ public bool UseOldNpcapWol { get; set; } + public List Devices { get; set; } + + public bool ShowRemoteControl { get; set; } + public LgServiceConfig() { PowerOnDelayAfterResume = 5000; DeviceSearchKey = "[LG]"; PowerOnRetries = 10; + Devices = new List(); } } } diff --git a/ColorControl/MainForm.Designer.cs b/ColorControl/MainForm.Designer.cs index 21e165d..fa20d76 100644 --- a/ColorControl/MainForm.Designer.cs +++ b/ColorControl/MainForm.Designer.cs @@ -99,36 +99,43 @@ this.miAmdHDRIncluded = new System.Windows.Forms.ToolStripMenuItem(); this.miAmdHDRToggle = new System.Windows.Forms.ToolStripMenuItem(); this.miAmdHDREnabled = new System.Windows.Forms.ToolStripMenuItem(); + this.miAmdCopyId = new System.Windows.Forms.ToolStripMenuItem(); this.btnApplyAmd = new System.Windows.Forms.Button(); this.lvAmdPresets = new System.Windows.Forms.ListView(); this.tabLG = new System.Windows.Forms.TabPage(); - this.btnLGRemoteControl = new System.Windows.Forms.Button(); - this.btnLgDeviceFilterRefresh = new System.Windows.Forms.Button(); - this.clbLgPower = new System.Windows.Forms.CheckedListBox(); + this.scLgController = new System.Windows.Forms.SplitContainer(); + this.chkLgRemoteControlShow = new System.Windows.Forms.CheckBox(); + this.label3 = new System.Windows.Forms.Label(); + this.cbxLgDevices = new System.Windows.Forms.ComboBox(); + this.btnLgDeviceConvertToCustom = new System.Windows.Forms.Button(); + this.cbxLgApps = new System.Windows.Forms.ComboBox(); + this.lvLgPresets = new System.Windows.Forms.ListView(); + this.label5 = new System.Windows.Forms.Label(); + this.cbxLgPresetDevice = new System.Windows.Forms.ComboBox(); + this.btnDeleteLg = new System.Windows.Forms.Button(); + this.btnApplyLg = new System.Windows.Forms.Button(); + this.lblDeviceFilter = new System.Windows.Forms.Label(); + this.lblLgPresetDevice = new System.Windows.Forms.Label(); + this.btnAddLg = new System.Windows.Forms.Button(); + this.edtShortcutLg = new System.Windows.Forms.TextBox(); + this.edtLgDeviceFilter = new System.Windows.Forms.TextBox(); + this.btnLgRemoveDevice = new System.Windows.Forms.Button(); + this.btnLgRefreshApps = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.btnLgAddDevice = new System.Windows.Forms.Button(); + this.edtNameLg = new System.Windows.Forms.TextBox(); + this.btnSetShortcutLg = new System.Windows.Forms.Button(); + this.edtStepsLg = new System.Windows.Forms.TextBox(); this.btnLgAddButton = new System.Windows.Forms.Button(); this.mnuLgButtons = new System.Windows.Forms.ContextMenuStrip(this.components); this.mnuLgRcButtons = new System.Windows.Forms.ToolStripMenuItem(); this.mnuLgActions = new System.Windows.Forms.ToolStripMenuItem(); - this.label3 = new System.Windows.Forms.Label(); - this.cbxLgDevices = new System.Windows.Forms.ComboBox(); - this.btnLgRefreshApps = new System.Windows.Forms.Button(); - this.btnAddLg = new System.Windows.Forms.Button(); - this.btnDeleteLg = new System.Windows.Forms.Button(); - this.cbxLgApps = new System.Windows.Forms.ComboBox(); - this.label5 = new System.Windows.Forms.Label(); - this.lblDeviceFilter = new System.Windows.Forms.Label(); - this.edtLgDeviceFilter = new System.Windows.Forms.TextBox(); - this.label1 = new System.Windows.Forms.Label(); - this.edtNameLg = new System.Windows.Forms.TextBox(); - this.edtStepsLg = new System.Windows.Forms.TextBox(); - this.lblStepsLg = new System.Windows.Forms.Label(); - this.lblLgError = new System.Windows.Forms.Label(); this.btnCloneLg = new System.Windows.Forms.Button(); - this.btnSetShortcutLg = new System.Windows.Forms.Button(); - this.label2 = new System.Windows.Forms.Label(); - this.edtShortcutLg = new System.Windows.Forms.TextBox(); - this.btnApplyLg = new System.Windows.Forms.Button(); - this.lvLgPresets = new System.Windows.Forms.ListView(); + this.lblStepsLg = new System.Windows.Forms.Label(); + this.btnLgDeviceFilterRefresh = new System.Windows.Forms.Button(); + this.clbLgPower = new System.Windows.Forms.CheckedListBox(); + this.lblLgError = new System.Windows.Forms.Label(); this.tabOptions = new System.Windows.Forms.TabPage(); this.grpNvidiaOptions = new System.Windows.Forms.GroupBox(); this.lblDitheringMode = new System.Windows.Forms.Label(); @@ -168,13 +175,16 @@ this.lbPlugins = new System.Windows.Forms.ListBox(); this.label7 = new System.Windows.Forms.Label(); this.lblInfo = new System.Windows.Forms.Label(); - this.miAmdCopyId = new System.Windows.Forms.ToolStripMenuItem(); + this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); this.tcMain.SuspendLayout(); this.tabNVIDIA.SuspendLayout(); this.mnuNvPresets.SuspendLayout(); this.tabAMD.SuspendLayout(); this.mnuAmdPresets.SuspendLayout(); this.tabLG.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.scLgController)).BeginInit(); + this.scLgController.Panel1.SuspendLayout(); + this.scLgController.SuspendLayout(); this.mnuLgButtons.SuspendLayout(); this.tabOptions.SuspendLayout(); this.grpNvidiaOptions.SuspendLayout(); @@ -205,7 +215,7 @@ this.tcMain.Location = new System.Drawing.Point(12, 12); this.tcMain.Name = "tcMain"; this.tcMain.SelectedIndex = 0; - this.tcMain.Size = new System.Drawing.Size(849, 472); + this.tcMain.Size = new System.Drawing.Size(962, 479); this.tcMain.TabIndex = 1; this.tcMain.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged); // @@ -226,7 +236,7 @@ this.tabNVIDIA.Location = new System.Drawing.Point(4, 22); this.tabNVIDIA.Name = "tabNVIDIA"; this.tabNVIDIA.Padding = new System.Windows.Forms.Padding(3); - this.tabNVIDIA.Size = new System.Drawing.Size(841, 446); + this.tabNVIDIA.Size = new System.Drawing.Size(954, 453); this.tabNVIDIA.TabIndex = 0; this.tabNVIDIA.Text = "NVIDIA controller"; this.tabNVIDIA.UseVisualStyleBackColor = true; @@ -235,7 +245,7 @@ // this.lblNvPresetName.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.lblNvPresetName.AutoSize = true; - this.lblNvPresetName.Location = new System.Drawing.Point(6, 397); + this.lblNvPresetName.Location = new System.Drawing.Point(6, 404); this.lblNvPresetName.Name = "lblNvPresetName"; this.lblNvPresetName.Size = new System.Drawing.Size(38, 13); this.lblNvPresetName.TabIndex = 22; @@ -245,7 +255,7 @@ // this.edtNvPresetName.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.edtNvPresetName.Enabled = false; - this.edtNvPresetName.Location = new System.Drawing.Point(87, 394); + this.edtNvPresetName.Location = new System.Drawing.Point(87, 401); this.edtNvPresetName.Name = "edtNvPresetName"; this.edtNvPresetName.Size = new System.Drawing.Size(200, 20); this.edtNvPresetName.TabIndex = 21; @@ -253,7 +263,7 @@ // btnAddModesNv // this.btnAddModesNv.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnAddModesNv.Location = new System.Drawing.Point(330, 365); + this.btnAddModesNv.Location = new System.Drawing.Point(330, 372); this.btnAddModesNv.Name = "btnAddModesNv"; this.btnAddModesNv.Size = new System.Drawing.Size(75, 23); this.btnAddModesNv.TabIndex = 9; @@ -265,7 +275,7 @@ // this.btnNvPresetDelete.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnNvPresetDelete.Enabled = false; - this.btnNvPresetDelete.Location = new System.Drawing.Point(249, 365); + this.btnNvPresetDelete.Location = new System.Drawing.Point(249, 372); this.btnNvPresetDelete.Name = "btnNvPresetDelete"; this.btnNvPresetDelete.Size = new System.Drawing.Size(75, 23); this.btnNvPresetDelete.TabIndex = 8; @@ -287,7 +297,7 @@ // this.btnClone.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnClone.Enabled = false; - this.btnClone.Location = new System.Drawing.Point(168, 365); + this.btnClone.Location = new System.Drawing.Point(168, 372); this.btnClone.Name = "btnClone"; this.btnClone.Size = new System.Drawing.Size(75, 23); this.btnClone.TabIndex = 6; @@ -299,7 +309,7 @@ // this.btnNvPresetSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnNvPresetSave.Enabled = false; - this.btnNvPresetSave.Location = new System.Drawing.Point(411, 365); + this.btnNvPresetSave.Location = new System.Drawing.Point(411, 372); this.btnNvPresetSave.Name = "btnNvPresetSave"; this.btnNvPresetSave.Size = new System.Drawing.Size(75, 23); this.btnNvPresetSave.TabIndex = 5; @@ -311,7 +321,7 @@ // this.lblShortcut.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.lblShortcut.AutoSize = true; - this.lblShortcut.Location = new System.Drawing.Point(6, 423); + this.lblShortcut.Location = new System.Drawing.Point(6, 430); this.lblShortcut.Name = "lblShortcut"; this.lblShortcut.Size = new System.Drawing.Size(50, 13); this.lblShortcut.TabIndex = 4; @@ -321,7 +331,7 @@ // this.edtShortcut.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.edtShortcut.Enabled = false; - this.edtShortcut.Location = new System.Drawing.Point(87, 420); + this.edtShortcut.Location = new System.Drawing.Point(87, 427); this.edtShortcut.Name = "edtShortcut"; this.edtShortcut.ReadOnly = true; this.edtShortcut.Size = new System.Drawing.Size(200, 20); @@ -335,7 +345,7 @@ this.btnChange.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnChange.ContextMenuStrip = this.mnuNvPresets; this.btnChange.Enabled = false; - this.btnChange.Location = new System.Drawing.Point(87, 365); + this.btnChange.Location = new System.Drawing.Point(87, 372); this.btnChange.Name = "btnChange"; this.btnChange.Size = new System.Drawing.Size(75, 23); this.btnChange.TabIndex = 2; @@ -578,7 +588,7 @@ // this.btnApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnApply.Enabled = false; - this.btnApply.Location = new System.Drawing.Point(6, 365); + this.btnApply.Location = new System.Drawing.Point(6, 372); this.btnApply.Name = "btnApply"; this.btnApply.Size = new System.Drawing.Size(75, 23); this.btnApply.TabIndex = 1; @@ -597,7 +607,7 @@ this.lvNvPresets.Location = new System.Drawing.Point(6, 6); this.lvNvPresets.MultiSelect = false; this.lvNvPresets.Name = "lvNvPresets"; - this.lvNvPresets.Size = new System.Drawing.Size(829, 353); + this.lvNvPresets.Size = new System.Drawing.Size(942, 360); this.lvNvPresets.TabIndex = 0; this.lvNvPresets.UseCompatibleStateImageBehavior = false; this.lvNvPresets.View = System.Windows.Forms.View.Details; @@ -621,7 +631,7 @@ this.tabAMD.Location = new System.Drawing.Point(4, 22); this.tabAMD.Name = "tabAMD"; this.tabAMD.Padding = new System.Windows.Forms.Padding(3); - this.tabAMD.Size = new System.Drawing.Size(841, 446); + this.tabAMD.Size = new System.Drawing.Size(954, 453); this.tabAMD.TabIndex = 5; this.tabAMD.Text = "AMD controller"; this.tabAMD.UseVisualStyleBackColor = true; @@ -630,7 +640,7 @@ // this.lblAmdPresetName.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.lblAmdPresetName.AutoSize = true; - this.lblAmdPresetName.Location = new System.Drawing.Point(6, 397); + this.lblAmdPresetName.Location = new System.Drawing.Point(6, 404); this.lblAmdPresetName.Name = "lblAmdPresetName"; this.lblAmdPresetName.Size = new System.Drawing.Size(38, 13); this.lblAmdPresetName.TabIndex = 24; @@ -640,7 +650,7 @@ // this.edtAmdPresetName.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.edtAmdPresetName.Enabled = false; - this.edtAmdPresetName.Location = new System.Drawing.Point(87, 394); + this.edtAmdPresetName.Location = new System.Drawing.Point(87, 401); this.edtAmdPresetName.Name = "edtAmdPresetName"; this.edtAmdPresetName.Size = new System.Drawing.Size(200, 20); this.edtAmdPresetName.TabIndex = 23; @@ -648,7 +658,7 @@ // btnAddAmd // this.btnAddAmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnAddAmd.Location = new System.Drawing.Point(330, 365); + this.btnAddAmd.Location = new System.Drawing.Point(330, 372); this.btnAddAmd.Name = "btnAddAmd"; this.btnAddAmd.Size = new System.Drawing.Size(75, 23); this.btnAddAmd.TabIndex = 18; @@ -670,7 +680,7 @@ // this.btnDeleteAmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnDeleteAmd.Enabled = false; - this.btnDeleteAmd.Location = new System.Drawing.Point(249, 365); + this.btnDeleteAmd.Location = new System.Drawing.Point(249, 372); this.btnDeleteAmd.Name = "btnDeleteAmd"; this.btnDeleteAmd.Size = new System.Drawing.Size(75, 23); this.btnDeleteAmd.TabIndex = 17; @@ -682,7 +692,7 @@ // this.btnCloneAmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnCloneAmd.Enabled = false; - this.btnCloneAmd.Location = new System.Drawing.Point(168, 365); + this.btnCloneAmd.Location = new System.Drawing.Point(168, 372); this.btnCloneAmd.Name = "btnCloneAmd"; this.btnCloneAmd.Size = new System.Drawing.Size(75, 23); this.btnCloneAmd.TabIndex = 16; @@ -694,7 +704,7 @@ // this.btnAmdPresetSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnAmdPresetSave.Enabled = false; - this.btnAmdPresetSave.Location = new System.Drawing.Point(411, 365); + this.btnAmdPresetSave.Location = new System.Drawing.Point(411, 372); this.btnAmdPresetSave.Name = "btnAmdPresetSave"; this.btnAmdPresetSave.Size = new System.Drawing.Size(75, 23); this.btnAmdPresetSave.TabIndex = 15; @@ -706,7 +716,7 @@ // this.lblAmdShortcut.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.lblAmdShortcut.AutoSize = true; - this.lblAmdShortcut.Location = new System.Drawing.Point(6, 423); + this.lblAmdShortcut.Location = new System.Drawing.Point(6, 430); this.lblAmdShortcut.Name = "lblAmdShortcut"; this.lblAmdShortcut.Size = new System.Drawing.Size(50, 13); this.lblAmdShortcut.TabIndex = 14; @@ -716,7 +726,7 @@ // this.edtAmdShortcut.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.edtAmdShortcut.Enabled = false; - this.edtAmdShortcut.Location = new System.Drawing.Point(87, 420); + this.edtAmdShortcut.Location = new System.Drawing.Point(87, 427); this.edtAmdShortcut.Name = "edtAmdShortcut"; this.edtAmdShortcut.ReadOnly = true; this.edtAmdShortcut.Size = new System.Drawing.Size(200, 20); @@ -730,7 +740,7 @@ this.btnChangeAmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnChangeAmd.ContextMenuStrip = this.mnuAmdPresets; this.btnChangeAmd.Enabled = false; - this.btnChangeAmd.Location = new System.Drawing.Point(87, 365); + this.btnChangeAmd.Location = new System.Drawing.Point(87, 372); this.btnChangeAmd.Name = "btnChangeAmd"; this.btnChangeAmd.Size = new System.Drawing.Size(75, 23); this.btnChangeAmd.TabIndex = 12; @@ -752,7 +762,7 @@ this.mnuAmdHDR, this.miAmdCopyId}); this.mnuAmdPresets.Name = "mnuNvPresets"; - this.mnuAmdPresets.Size = new System.Drawing.Size(185, 208); + this.mnuAmdPresets.Size = new System.Drawing.Size(185, 186); this.mnuAmdPresets.Opening += new System.ComponentModel.CancelEventHandler(this.mnuAmdPresets_Opening); // // miAmdApply @@ -866,11 +876,18 @@ this.miAmdHDREnabled.Text = "Enabled"; this.miAmdHDREnabled.Click += new System.EventHandler(this.miAmdHDREnabled_Click); // + // miAmdCopyId + // + this.miAmdCopyId.Name = "miAmdCopyId"; + this.miAmdCopyId.Size = new System.Drawing.Size(184, 22); + this.miAmdCopyId.Text = "Copy Id to Clipboard"; + this.miAmdCopyId.Click += new System.EventHandler(this.miAmdCopyId_Click); + // // btnApplyAmd // this.btnApplyAmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnApplyAmd.Enabled = false; - this.btnApplyAmd.Location = new System.Drawing.Point(6, 365); + this.btnApplyAmd.Location = new System.Drawing.Point(6, 372); this.btnApplyAmd.Name = "btnApplyAmd"; this.btnApplyAmd.Size = new System.Drawing.Size(75, 23); this.btnApplyAmd.TabIndex = 11; @@ -889,7 +906,7 @@ this.lvAmdPresets.Location = new System.Drawing.Point(6, 6); this.lvAmdPresets.MultiSelect = false; this.lvAmdPresets.Name = "lvAmdPresets"; - this.lvAmdPresets.Size = new System.Drawing.Size(829, 353); + this.lvAmdPresets.Size = new System.Drawing.Size(942, 360); this.lvAmdPresets.TabIndex = 10; this.lvAmdPresets.UseCompatibleStateImageBehavior = false; this.lvAmdPresets.View = System.Windows.Forms.View.Details; @@ -898,51 +915,367 @@ // // tabLG // - this.tabLG.Controls.Add(this.btnLGRemoteControl); - this.tabLG.Controls.Add(this.btnLgDeviceFilterRefresh); - this.tabLG.Controls.Add(this.clbLgPower); - this.tabLG.Controls.Add(this.btnLgAddButton); - this.tabLG.Controls.Add(this.label3); - this.tabLG.Controls.Add(this.cbxLgDevices); - this.tabLG.Controls.Add(this.btnLgRefreshApps); - this.tabLG.Controls.Add(this.btnAddLg); - this.tabLG.Controls.Add(this.btnDeleteLg); - this.tabLG.Controls.Add(this.cbxLgApps); - this.tabLG.Controls.Add(this.label5); - this.tabLG.Controls.Add(this.lblDeviceFilter); - this.tabLG.Controls.Add(this.edtLgDeviceFilter); - this.tabLG.Controls.Add(this.label1); - this.tabLG.Controls.Add(this.edtNameLg); - this.tabLG.Controls.Add(this.edtStepsLg); - this.tabLG.Controls.Add(this.lblStepsLg); - this.tabLG.Controls.Add(this.lblLgError); - this.tabLG.Controls.Add(this.btnCloneLg); - this.tabLG.Controls.Add(this.btnSetShortcutLg); - this.tabLG.Controls.Add(this.label2); - this.tabLG.Controls.Add(this.edtShortcutLg); - this.tabLG.Controls.Add(this.btnApplyLg); - this.tabLG.Controls.Add(this.lvLgPresets); + this.tabLG.Controls.Add(this.scLgController); this.tabLG.Location = new System.Drawing.Point(4, 22); this.tabLG.Name = "tabLG"; this.tabLG.Padding = new System.Windows.Forms.Padding(3); - this.tabLG.Size = new System.Drawing.Size(841, 446); + this.tabLG.Size = new System.Drawing.Size(954, 453); this.tabLG.TabIndex = 1; this.tabLG.Text = "LG controller"; this.tabLG.UseVisualStyleBackColor = true; // - // btnLGRemoteControl + // scLgController // - this.btnLGRemoteControl.Location = new System.Drawing.Point(675, 5); - this.btnLGRemoteControl.Name = "btnLGRemoteControl"; - this.btnLGRemoteControl.Size = new System.Drawing.Size(95, 23); - this.btnLGRemoteControl.TabIndex = 36; - this.btnLGRemoteControl.Text = "Remote Control"; - this.btnLGRemoteControl.UseVisualStyleBackColor = true; - this.btnLGRemoteControl.Click += new System.EventHandler(this.btnLGRemoteControl_Click); + this.scLgController.Dock = System.Windows.Forms.DockStyle.Fill; + this.scLgController.Location = new System.Drawing.Point(3, 3); + this.scLgController.Name = "scLgController"; + // + // scLgController.Panel1 + // + this.scLgController.Panel1.Controls.Add(this.chkLgRemoteControlShow); + this.scLgController.Panel1.Controls.Add(this.label3); + this.scLgController.Panel1.Controls.Add(this.cbxLgDevices); + this.scLgController.Panel1.Controls.Add(this.btnLgDeviceConvertToCustom); + this.scLgController.Panel1.Controls.Add(this.cbxLgApps); + this.scLgController.Panel1.Controls.Add(this.lvLgPresets); + this.scLgController.Panel1.Controls.Add(this.label5); + this.scLgController.Panel1.Controls.Add(this.cbxLgPresetDevice); + this.scLgController.Panel1.Controls.Add(this.btnDeleteLg); + this.scLgController.Panel1.Controls.Add(this.btnApplyLg); + this.scLgController.Panel1.Controls.Add(this.lblDeviceFilter); + this.scLgController.Panel1.Controls.Add(this.lblLgPresetDevice); + this.scLgController.Panel1.Controls.Add(this.btnAddLg); + this.scLgController.Panel1.Controls.Add(this.edtShortcutLg); + this.scLgController.Panel1.Controls.Add(this.edtLgDeviceFilter); + this.scLgController.Panel1.Controls.Add(this.btnLgRemoveDevice); + this.scLgController.Panel1.Controls.Add(this.btnLgRefreshApps); + this.scLgController.Panel1.Controls.Add(this.label2); + this.scLgController.Panel1.Controls.Add(this.label1); + this.scLgController.Panel1.Controls.Add(this.btnLgAddDevice); + this.scLgController.Panel1.Controls.Add(this.edtNameLg); + this.scLgController.Panel1.Controls.Add(this.btnSetShortcutLg); + this.scLgController.Panel1.Controls.Add(this.edtStepsLg); + this.scLgController.Panel1.Controls.Add(this.btnLgAddButton); + this.scLgController.Panel1.Controls.Add(this.btnCloneLg); + this.scLgController.Panel1.Controls.Add(this.lblStepsLg); + this.scLgController.Panel1.Controls.Add(this.btnLgDeviceFilterRefresh); + this.scLgController.Panel1.Controls.Add(this.clbLgPower); + this.scLgController.Panel1.Controls.Add(this.lblLgError); + this.scLgController.Panel1MinSize = 750; + this.scLgController.Panel2MinSize = 150; + this.scLgController.Size = new System.Drawing.Size(948, 447); + this.scLgController.SplitterDistance = 767; + this.scLgController.TabIndex = 43; + // + // chkLgRemoteControlShow + // + this.chkLgRemoteControlShow.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.chkLgRemoteControlShow.Appearance = System.Windows.Forms.Appearance.Button; + this.chkLgRemoteControlShow.AutoSize = true; + this.chkLgRemoteControlShow.Location = new System.Drawing.Point(673, 7); + this.chkLgRemoteControlShow.Name = "chkLgRemoteControlShow"; + this.chkLgRemoteControlShow.Size = new System.Drawing.Size(90, 23); + this.chkLgRemoteControlShow.TabIndex = 43; + this.chkLgRemoteControlShow.Text = "Remote Control"; + this.chkLgRemoteControlShow.UseVisualStyleBackColor = true; + this.chkLgRemoteControlShow.CheckedChanged += new System.EventHandler(this.chkLgRemoteControlShow_CheckedChanged); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(5, 12); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(44, 13); + this.label3.TabIndex = 31; + this.label3.Text = "Device:"; + // + // cbxLgDevices + // + this.cbxLgDevices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbxLgDevices.FormattingEnabled = true; + this.cbxLgDevices.Location = new System.Drawing.Point(86, 8); + this.cbxLgDevices.Name = "cbxLgDevices"; + this.cbxLgDevices.Size = new System.Drawing.Size(318, 21); + this.cbxLgDevices.TabIndex = 30; + this.cbxLgDevices.SelectedIndexChanged += new System.EventHandler(this.cbxLgDevices_SelectedIndexChanged); + // + // btnLgDeviceConvertToCustom + // + this.btnLgDeviceConvertToCustom.Location = new System.Drawing.Point(572, 7); + this.btnLgDeviceConvertToCustom.Name = "btnLgDeviceConvertToCustom"; + this.btnLgDeviceConvertToCustom.Size = new System.Drawing.Size(75, 23); + this.btnLgDeviceConvertToCustom.TabIndex = 41; + this.btnLgDeviceConvertToCustom.Text = "To custom..."; + this.btnLgDeviceConvertToCustom.UseVisualStyleBackColor = true; + this.btnLgDeviceConvertToCustom.Click += new System.EventHandler(this.btnLgDeviceConvertToCustom_Click); + // + // cbxLgApps + // + this.cbxLgApps.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.cbxLgApps.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbxLgApps.Enabled = false; + this.cbxLgApps.FormattingEnabled = true; + this.cbxLgApps.Location = new System.Drawing.Point(86, 346); + this.cbxLgApps.Name = "cbxLgApps"; + this.cbxLgApps.Size = new System.Drawing.Size(200, 21); + this.cbxLgApps.TabIndex = 26; + // + // lvLgPresets + // + this.lvLgPresets.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lvLgPresets.FullRowSelect = true; + this.lvLgPresets.HideSelection = false; + this.lvLgPresets.Location = new System.Drawing.Point(5, 146); + this.lvLgPresets.MultiSelect = false; + this.lvLgPresets.Name = "lvLgPresets"; + this.lvLgPresets.Size = new System.Drawing.Size(758, 111); + this.lvLgPresets.TabIndex = 8; + this.lvLgPresets.UseCompatibleStateImageBehavior = false; + this.lvLgPresets.View = System.Windows.Forms.View.Details; + this.lvLgPresets.SelectedIndexChanged += new System.EventHandler(this.lvLgPresets_SelectedIndexChanged); + this.lvLgPresets.DoubleClick += new System.EventHandler(this.lvLgPresets_DoubleClick); + // + // label5 + // + this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(5, 349); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(29, 13); + this.label5.TabIndex = 25; + this.label5.Text = "App:"; + // + // cbxLgPresetDevice + // + this.cbxLgPresetDevice.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.cbxLgPresetDevice.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbxLgPresetDevice.Enabled = false; + this.cbxLgPresetDevice.FormattingEnabled = true; + this.cbxLgPresetDevice.Location = new System.Drawing.Point(86, 318); + this.cbxLgPresetDevice.Name = "cbxLgPresetDevice"; + this.cbxLgPresetDevice.Size = new System.Drawing.Size(318, 21); + this.cbxLgPresetDevice.TabIndex = 40; + // + // btnDeleteLg + // + this.btnDeleteLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnDeleteLg.Enabled = false; + this.btnDeleteLg.Location = new System.Drawing.Point(248, 263); + this.btnDeleteLg.Name = "btnDeleteLg"; + this.btnDeleteLg.Size = new System.Drawing.Size(75, 23); + this.btnDeleteLg.TabIndex = 27; + this.btnDeleteLg.Text = "Delete"; + this.btnDeleteLg.UseVisualStyleBackColor = true; + this.btnDeleteLg.Click += new System.EventHandler(this.btnDeleteLg_Click); + // + // btnApplyLg + // + this.btnApplyLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnApplyLg.Enabled = false; + this.btnApplyLg.Location = new System.Drawing.Point(5, 263); + this.btnApplyLg.Name = "btnApplyLg"; + this.btnApplyLg.Size = new System.Drawing.Size(75, 23); + this.btnApplyLg.TabIndex = 9; + this.btnApplyLg.Text = "Apply"; + this.btnApplyLg.UseVisualStyleBackColor = true; + this.btnApplyLg.Click += new System.EventHandler(this.btnApplyLg_Click); + // + // lblDeviceFilter + // + this.lblDeviceFilter.AutoSize = true; + this.lblDeviceFilter.Location = new System.Drawing.Point(5, 39); + this.lblDeviceFilter.Name = "lblDeviceFilter"; + this.lblDeviceFilter.Size = new System.Drawing.Size(66, 13); + this.lblDeviceFilter.TabIndex = 24; + this.lblDeviceFilter.Text = "Device filter:"; + // + // lblLgPresetDevice + // + this.lblLgPresetDevice.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.lblLgPresetDevice.AutoSize = true; + this.lblLgPresetDevice.Location = new System.Drawing.Point(5, 321); + this.lblLgPresetDevice.Name = "lblLgPresetDevice"; + this.lblLgPresetDevice.Size = new System.Drawing.Size(44, 13); + this.lblLgPresetDevice.TabIndex = 39; + this.lblLgPresetDevice.Text = "Device:"; + // + // btnAddLg + // + this.btnAddLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnAddLg.Location = new System.Drawing.Point(167, 263); + this.btnAddLg.Name = "btnAddLg"; + this.btnAddLg.Size = new System.Drawing.Size(75, 23); + this.btnAddLg.TabIndex = 28; + this.btnAddLg.Text = "Add"; + this.btnAddLg.UseVisualStyleBackColor = true; + this.btnAddLg.Click += new System.EventHandler(this.btnAddLg_Click); + // + // edtShortcutLg + // + this.edtShortcutLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.edtShortcutLg.Enabled = false; + this.edtShortcutLg.Location = new System.Drawing.Point(86, 373); + this.edtShortcutLg.Name = "edtShortcutLg"; + this.edtShortcutLg.ReadOnly = true; + this.edtShortcutLg.Size = new System.Drawing.Size(200, 20); + this.edtShortcutLg.TabIndex = 11; + this.edtShortcutLg.TextChanged += new System.EventHandler(this.edtShortcutLg_TextChanged); + this.edtShortcutLg.KeyDown += new System.Windows.Forms.KeyEventHandler(this.edtShortcut_KeyDown); + this.edtShortcutLg.KeyUp += new System.Windows.Forms.KeyEventHandler(this.edtShortcut_KeyUp); + // + // edtLgDeviceFilter + // + this.edtLgDeviceFilter.Location = new System.Drawing.Point(86, 35); + this.edtLgDeviceFilter.Name = "edtLgDeviceFilter"; + this.edtLgDeviceFilter.Size = new System.Drawing.Size(142, 20); + this.edtLgDeviceFilter.TabIndex = 23; + this.edtLgDeviceFilter.TextChanged += new System.EventHandler(this.edtLgDeviceFilter_TextChanged); + // + // btnLgRemoveDevice + // + this.btnLgRemoveDevice.Location = new System.Drawing.Point(491, 7); + this.btnLgRemoveDevice.Name = "btnLgRemoveDevice"; + this.btnLgRemoveDevice.Size = new System.Drawing.Size(75, 23); + this.btnLgRemoveDevice.TabIndex = 38; + this.btnLgRemoveDevice.Text = "Remove"; + this.btnLgRemoveDevice.UseVisualStyleBackColor = true; + this.btnLgRemoveDevice.Click += new System.EventHandler(this.btnLgRemoveDevice_Click); + // + // btnLgRefreshApps + // + this.btnLgRefreshApps.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnLgRefreshApps.Location = new System.Drawing.Point(292, 344); + this.btnLgRefreshApps.Name = "btnLgRefreshApps"; + this.btnLgRefreshApps.Size = new System.Drawing.Size(75, 23); + this.btnLgRefreshApps.TabIndex = 29; + this.btnLgRefreshApps.Text = "Refresh"; + this.btnLgRefreshApps.UseVisualStyleBackColor = true; + this.btnLgRefreshApps.Click += new System.EventHandler(this.btnLgRefreshApps_Click); + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(5, 376); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(50, 13); + this.label2.TabIndex = 12; + this.label2.Text = "Shortcut:"; + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(5, 295); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(38, 13); + this.label1.TabIndex = 20; + this.label1.Text = "Name:"; + // + // btnLgAddDevice + // + this.btnLgAddDevice.Location = new System.Drawing.Point(410, 7); + this.btnLgAddDevice.Name = "btnLgAddDevice"; + this.btnLgAddDevice.Size = new System.Drawing.Size(75, 23); + this.btnLgAddDevice.TabIndex = 37; + this.btnLgAddDevice.Text = "Add"; + this.btnLgAddDevice.UseVisualStyleBackColor = true; + this.btnLgAddDevice.Click += new System.EventHandler(this.btnLgAddDevice_Click); + // + // edtNameLg + // + this.edtNameLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.edtNameLg.Enabled = false; + this.edtNameLg.Location = new System.Drawing.Point(86, 292); + this.edtNameLg.Name = "edtNameLg"; + this.edtNameLg.Size = new System.Drawing.Size(200, 20); + this.edtNameLg.TabIndex = 19; + // + // btnSetShortcutLg + // + this.btnSetShortcutLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnSetShortcutLg.Enabled = false; + this.btnSetShortcutLg.Location = new System.Drawing.Point(329, 263); + this.btnSetShortcutLg.Name = "btnSetShortcutLg"; + this.btnSetShortcutLg.Size = new System.Drawing.Size(75, 23); + this.btnSetShortcutLg.TabIndex = 13; + this.btnSetShortcutLg.Text = "Save"; + this.btnSetShortcutLg.UseVisualStyleBackColor = true; + this.btnSetShortcutLg.Click += new System.EventHandler(this.btnSetShortcutLg_Click); + // + // edtStepsLg + // + this.edtStepsLg.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.edtStepsLg.Enabled = false; + this.edtStepsLg.Location = new System.Drawing.Point(86, 398); + this.edtStepsLg.Multiline = true; + this.edtStepsLg.Name = "edtStepsLg"; + this.edtStepsLg.Size = new System.Drawing.Size(596, 38); + this.edtStepsLg.TabIndex = 17; + // + // btnLgAddButton + // + this.btnLgAddButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnLgAddButton.ContextMenuStrip = this.mnuLgButtons; + this.btnLgAddButton.Enabled = false; + this.btnLgAddButton.Location = new System.Drawing.Point(688, 397); + this.btnLgAddButton.Name = "btnLgAddButton"; + this.btnLgAddButton.Size = new System.Drawing.Size(75, 23); + this.btnLgAddButton.TabIndex = 32; + this.btnLgAddButton.Text = "Add step"; + this.btnLgAddButton.UseVisualStyleBackColor = true; + this.btnLgAddButton.Click += new System.EventHandler(this.btnLgAddButton_Click); + // + // mnuLgButtons + // + this.mnuLgButtons.ImageScalingSize = new System.Drawing.Size(20, 20); + this.mnuLgButtons.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.mnuLgRcButtons, + this.mnuLgActions}); + this.mnuLgButtons.Name = "mnuLgButtons"; + this.mnuLgButtons.Size = new System.Drawing.Size(116, 48); + this.mnuLgButtons.Opening += new System.ComponentModel.CancelEventHandler(this.mnuLgButtons_Opening); + // + // mnuLgRcButtons + // + this.mnuLgRcButtons.Name = "mnuLgRcButtons"; + this.mnuLgRcButtons.Size = new System.Drawing.Size(115, 22); + this.mnuLgRcButtons.Text = "Buttons"; + // + // mnuLgActions + // + this.mnuLgActions.Name = "mnuLgActions"; + this.mnuLgActions.Size = new System.Drawing.Size(115, 22); + this.mnuLgActions.Text = "Actions"; + // + // btnCloneLg + // + this.btnCloneLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnCloneLg.Enabled = false; + this.btnCloneLg.Location = new System.Drawing.Point(86, 263); + this.btnCloneLg.Name = "btnCloneLg"; + this.btnCloneLg.Size = new System.Drawing.Size(75, 23); + this.btnCloneLg.TabIndex = 14; + this.btnCloneLg.Text = "Clone"; + this.btnCloneLg.UseVisualStyleBackColor = true; + this.btnCloneLg.Click += new System.EventHandler(this.btnCloneLg_Click); + // + // lblStepsLg + // + this.lblStepsLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.lblStepsLg.AutoSize = true; + this.lblStepsLg.Location = new System.Drawing.Point(5, 402); + this.lblStepsLg.Name = "lblStepsLg"; + this.lblStepsLg.Size = new System.Drawing.Size(37, 13); + this.lblStepsLg.TabIndex = 16; + this.lblStepsLg.Text = "Steps:"; // // btnLgDeviceFilterRefresh // - this.btnLgDeviceFilterRefresh.Location = new System.Drawing.Point(594, 5); + this.btnLgDeviceFilterRefresh.Location = new System.Drawing.Point(234, 34); this.btnLgDeviceFilterRefresh.Name = "btnLgDeviceFilterRefresh"; this.btnLgDeviceFilterRefresh.Size = new System.Drawing.Size(75, 23); this.btnLgDeviceFilterRefresh.TabIndex = 35; @@ -959,270 +1292,29 @@ this.clbLgPower.Items.AddRange(new object[] { "Automatically power on after startup. Requires \"Automatically start after login\" " + "- see Options.", - "Automatically power on after resume from standby. Needs a system dependent delay " + - "before waking TV, see Options.", + "Automatically power on after resume from standby. May need some retries for wakin" + + "g TV, see Options.", "Automatically power off on shutdown. Because this app cannot detect a restart, re" + "starting could also trigger this. Hold down Ctrl on restart to prevent power off" + ".", "Automatically power off on standby", "Automatically power off on screensaver and power on when screensaver deactivates"}); - this.clbLgPower.Location = new System.Drawing.Point(6, 33); + this.clbLgPower.Location = new System.Drawing.Point(5, 61); this.clbLgPower.Name = "clbLgPower"; - this.clbLgPower.Size = new System.Drawing.Size(829, 79); + this.clbLgPower.Size = new System.Drawing.Size(758, 79); this.clbLgPower.TabIndex = 34; this.clbLgPower.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.clbLgPower_ItemCheck); // - // btnLgAddButton - // - this.btnLgAddButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnLgAddButton.ContextMenuStrip = this.mnuLgButtons; - this.btnLgAddButton.Enabled = false; - this.btnLgAddButton.Location = new System.Drawing.Point(760, 400); - this.btnLgAddButton.Name = "btnLgAddButton"; - this.btnLgAddButton.Size = new System.Drawing.Size(75, 23); - this.btnLgAddButton.TabIndex = 32; - this.btnLgAddButton.Text = "Add step"; - this.btnLgAddButton.UseVisualStyleBackColor = true; - this.btnLgAddButton.Click += new System.EventHandler(this.btnLgAddButton_Click); - // - // mnuLgButtons - // - this.mnuLgButtons.ImageScalingSize = new System.Drawing.Size(20, 20); - this.mnuLgButtons.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.mnuLgRcButtons, - this.mnuLgActions}); - this.mnuLgButtons.Name = "mnuLgButtons"; - this.mnuLgButtons.Size = new System.Drawing.Size(116, 48); - // - // mnuLgRcButtons - // - this.mnuLgRcButtons.Name = "mnuLgRcButtons"; - this.mnuLgRcButtons.Size = new System.Drawing.Size(115, 22); - this.mnuLgRcButtons.Text = "Buttons"; - // - // mnuLgActions - // - this.mnuLgActions.Name = "mnuLgActions"; - this.mnuLgActions.Size = new System.Drawing.Size(115, 22); - this.mnuLgActions.Text = "Actions"; - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(6, 10); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(44, 13); - this.label3.TabIndex = 31; - this.label3.Text = "Device:"; - // - // cbxLgDevices - // - this.cbxLgDevices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cbxLgDevices.FormattingEnabled = true; - this.cbxLgDevices.Location = new System.Drawing.Point(87, 6); - this.cbxLgDevices.Name = "cbxLgDevices"; - this.cbxLgDevices.Size = new System.Drawing.Size(281, 21); - this.cbxLgDevices.TabIndex = 30; - this.cbxLgDevices.SelectedIndexChanged += new System.EventHandler(this.cbxLgDevices_SelectedIndexChanged); - // - // btnLgRefreshApps - // - this.btnLgRefreshApps.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnLgRefreshApps.Location = new System.Drawing.Point(293, 347); - this.btnLgRefreshApps.Name = "btnLgRefreshApps"; - this.btnLgRefreshApps.Size = new System.Drawing.Size(75, 23); - this.btnLgRefreshApps.TabIndex = 29; - this.btnLgRefreshApps.Text = "Refresh"; - this.btnLgRefreshApps.UseVisualStyleBackColor = true; - this.btnLgRefreshApps.Click += new System.EventHandler(this.btnLgRefreshApps_Click); - // - // btnAddLg - // - this.btnAddLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnAddLg.Location = new System.Drawing.Point(168, 294); - this.btnAddLg.Name = "btnAddLg"; - this.btnAddLg.Size = new System.Drawing.Size(75, 23); - this.btnAddLg.TabIndex = 28; - this.btnAddLg.Text = "Add"; - this.btnAddLg.UseVisualStyleBackColor = true; - this.btnAddLg.Click += new System.EventHandler(this.btnAddLg_Click); - // - // btnDeleteLg - // - this.btnDeleteLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnDeleteLg.Enabled = false; - this.btnDeleteLg.Location = new System.Drawing.Point(249, 294); - this.btnDeleteLg.Name = "btnDeleteLg"; - this.btnDeleteLg.Size = new System.Drawing.Size(75, 23); - this.btnDeleteLg.TabIndex = 27; - this.btnDeleteLg.Text = "Delete"; - this.btnDeleteLg.UseVisualStyleBackColor = true; - this.btnDeleteLg.Click += new System.EventHandler(this.btnDeleteLg_Click); - // - // cbxLgApps - // - this.cbxLgApps.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.cbxLgApps.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cbxLgApps.Enabled = false; - this.cbxLgApps.FormattingEnabled = true; - this.cbxLgApps.Location = new System.Drawing.Point(87, 349); - this.cbxLgApps.Name = "cbxLgApps"; - this.cbxLgApps.Size = new System.Drawing.Size(200, 21); - this.cbxLgApps.TabIndex = 26; - // - // label5 - // - this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(6, 352); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(29, 13); - this.label5.TabIndex = 25; - this.label5.Text = "App:"; - // - // lblDeviceFilter - // - this.lblDeviceFilter.AutoSize = true; - this.lblDeviceFilter.Location = new System.Drawing.Point(374, 10); - this.lblDeviceFilter.Name = "lblDeviceFilter"; - this.lblDeviceFilter.Size = new System.Drawing.Size(66, 13); - this.lblDeviceFilter.TabIndex = 24; - this.lblDeviceFilter.Text = "Device filter:"; - // - // edtLgDeviceFilter - // - this.edtLgDeviceFilter.Location = new System.Drawing.Point(446, 6); - this.edtLgDeviceFilter.Name = "edtLgDeviceFilter"; - this.edtLgDeviceFilter.Size = new System.Drawing.Size(142, 20); - this.edtLgDeviceFilter.TabIndex = 23; - this.edtLgDeviceFilter.TextChanged += new System.EventHandler(this.edtLgDeviceFilter_TextChanged); - // - // label1 - // - this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(6, 326); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(38, 13); - this.label1.TabIndex = 20; - this.label1.Text = "Name:"; - // - // edtNameLg - // - this.edtNameLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.edtNameLg.Enabled = false; - this.edtNameLg.Location = new System.Drawing.Point(87, 323); - this.edtNameLg.Name = "edtNameLg"; - this.edtNameLg.Size = new System.Drawing.Size(200, 20); - this.edtNameLg.TabIndex = 19; - // - // edtStepsLg - // - this.edtStepsLg.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.edtStepsLg.Enabled = false; - this.edtStepsLg.Location = new System.Drawing.Point(87, 402); - this.edtStepsLg.Multiline = true; - this.edtStepsLg.Name = "edtStepsLg"; - this.edtStepsLg.Size = new System.Drawing.Size(667, 37); - this.edtStepsLg.TabIndex = 17; - // - // lblStepsLg - // - this.lblStepsLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.lblStepsLg.AutoSize = true; - this.lblStepsLg.Location = new System.Drawing.Point(6, 405); - this.lblStepsLg.Name = "lblStepsLg"; - this.lblStepsLg.Size = new System.Drawing.Size(37, 13); - this.lblStepsLg.TabIndex = 16; - this.lblStepsLg.Text = "Steps:"; - // // lblLgError // this.lblLgError.AutoSize = true; - this.lblLgError.Location = new System.Drawing.Point(6, 6); + this.lblLgError.Location = new System.Drawing.Point(5, 8); this.lblLgError.Name = "lblLgError"; this.lblLgError.Size = new System.Drawing.Size(50, 13); this.lblLgError.TabIndex = 15; this.lblLgError.Text = "ErrorText"; this.lblLgError.Visible = false; // - // btnCloneLg - // - this.btnCloneLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnCloneLg.Enabled = false; - this.btnCloneLg.Location = new System.Drawing.Point(87, 294); - this.btnCloneLg.Name = "btnCloneLg"; - this.btnCloneLg.Size = new System.Drawing.Size(75, 23); - this.btnCloneLg.TabIndex = 14; - this.btnCloneLg.Text = "Clone"; - this.btnCloneLg.UseVisualStyleBackColor = true; - this.btnCloneLg.Click += new System.EventHandler(this.btnCloneLg_Click); - // - // btnSetShortcutLg - // - this.btnSetShortcutLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnSetShortcutLg.Enabled = false; - this.btnSetShortcutLg.Location = new System.Drawing.Point(330, 294); - this.btnSetShortcutLg.Name = "btnSetShortcutLg"; - this.btnSetShortcutLg.Size = new System.Drawing.Size(75, 23); - this.btnSetShortcutLg.TabIndex = 13; - this.btnSetShortcutLg.Text = "Save"; - this.btnSetShortcutLg.UseVisualStyleBackColor = true; - this.btnSetShortcutLg.Click += new System.EventHandler(this.btnSetShortcutLg_Click); - // - // label2 - // - this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(6, 379); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(50, 13); - this.label2.TabIndex = 12; - this.label2.Text = "Shortcut:"; - // - // edtShortcutLg - // - this.edtShortcutLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.edtShortcutLg.Enabled = false; - this.edtShortcutLg.Location = new System.Drawing.Point(87, 376); - this.edtShortcutLg.Name = "edtShortcutLg"; - this.edtShortcutLg.ReadOnly = true; - this.edtShortcutLg.Size = new System.Drawing.Size(200, 20); - this.edtShortcutLg.TabIndex = 11; - this.edtShortcutLg.TextChanged += new System.EventHandler(this.edtShortcutLg_TextChanged); - this.edtShortcutLg.KeyDown += new System.Windows.Forms.KeyEventHandler(this.edtShortcut_KeyDown); - this.edtShortcutLg.KeyUp += new System.Windows.Forms.KeyEventHandler(this.edtShortcut_KeyUp); - // - // btnApplyLg - // - this.btnApplyLg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnApplyLg.Enabled = false; - this.btnApplyLg.Location = new System.Drawing.Point(6, 294); - this.btnApplyLg.Name = "btnApplyLg"; - this.btnApplyLg.Size = new System.Drawing.Size(75, 23); - this.btnApplyLg.TabIndex = 9; - this.btnApplyLg.Text = "Apply"; - this.btnApplyLg.UseVisualStyleBackColor = true; - this.btnApplyLg.Click += new System.EventHandler(this.btnApplyLg_Click); - // - // lvLgPresets - // - this.lvLgPresets.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.lvLgPresets.FullRowSelect = true; - this.lvLgPresets.HideSelection = false; - this.lvLgPresets.Location = new System.Drawing.Point(6, 116); - this.lvLgPresets.MultiSelect = false; - this.lvLgPresets.Name = "lvLgPresets"; - this.lvLgPresets.Size = new System.Drawing.Size(829, 172); - this.lvLgPresets.TabIndex = 8; - this.lvLgPresets.UseCompatibleStateImageBehavior = false; - this.lvLgPresets.View = System.Windows.Forms.View.Details; - this.lvLgPresets.SelectedIndexChanged += new System.EventHandler(this.lvLgPresets_SelectedIndexChanged); - this.lvLgPresets.DoubleClick += new System.EventHandler(this.lvLgPresets_DoubleClick); - // // tabOptions // this.tabOptions.Controls.Add(this.grpNvidiaOptions); @@ -1233,7 +1325,7 @@ this.tabOptions.Location = new System.Drawing.Point(4, 22); this.tabOptions.Name = "tabOptions"; this.tabOptions.Padding = new System.Windows.Forms.Padding(3); - this.tabOptions.Size = new System.Drawing.Size(841, 446); + this.tabOptions.Size = new System.Drawing.Size(954, 453); this.tabOptions.TabIndex = 2; this.tabOptions.Text = "Options"; this.tabOptions.UseVisualStyleBackColor = true; @@ -1251,7 +1343,7 @@ this.grpNvidiaOptions.Controls.Add(this.pbGradient); this.grpNvidiaOptions.Location = new System.Drawing.Point(412, 6); this.grpNvidiaOptions.Name = "grpNvidiaOptions"; - this.grpNvidiaOptions.Size = new System.Drawing.Size(400, 297); + this.grpNvidiaOptions.Size = new System.Drawing.Size(514, 304); this.grpNvidiaOptions.TabIndex = 6; this.grpNvidiaOptions.TabStop = false; this.grpNvidiaOptions.Text = "NVIDIA options - test dithering"; @@ -1315,7 +1407,7 @@ this.pbGradient.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.pbGradient.Location = new System.Drawing.Point(6, 92); this.pbGradient.Name = "pbGradient"; - this.pbGradient.Size = new System.Drawing.Size(388, 198); + this.pbGradient.Size = new System.Drawing.Size(502, 205); this.pbGradient.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.pbGradient.TabIndex = 0; this.pbGradient.TabStop = false; @@ -1555,7 +1647,7 @@ this.tabLog.Location = new System.Drawing.Point(4, 22); this.tabLog.Name = "tabLog"; this.tabLog.Padding = new System.Windows.Forms.Padding(3); - this.tabLog.Size = new System.Drawing.Size(841, 446); + this.tabLog.Size = new System.Drawing.Size(954, 453); this.tabLog.TabIndex = 3; this.tabLog.Text = "Log"; this.tabLog.UseVisualStyleBackColor = true; @@ -1580,7 +1672,7 @@ this.edtLog.Name = "edtLog"; this.edtLog.ReadOnly = true; this.edtLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.edtLog.Size = new System.Drawing.Size(832, 408); + this.edtLog.Size = new System.Drawing.Size(920, 415); this.edtLog.TabIndex = 0; // // tabInfo @@ -1590,7 +1682,7 @@ this.tabInfo.Location = new System.Drawing.Point(4, 22); this.tabInfo.Name = "tabInfo"; this.tabInfo.Padding = new System.Windows.Forms.Padding(3); - this.tabInfo.Size = new System.Drawing.Size(841, 446); + this.tabInfo.Size = new System.Drawing.Size(954, 453); this.tabInfo.TabIndex = 4; this.tabInfo.Text = "Info"; this.tabInfo.UseVisualStyleBackColor = true; @@ -1604,7 +1696,7 @@ this.grpNVIDIAInfo.Controls.Add(this.tvNVIDIAInfo); this.grpNVIDIAInfo.Location = new System.Drawing.Point(397, 6); this.grpNVIDIAInfo.Name = "grpNVIDIAInfo"; - this.grpNVIDIAInfo.Size = new System.Drawing.Size(440, 436); + this.grpNVIDIAInfo.Size = new System.Drawing.Size(477, 443); this.grpNVIDIAInfo.TabIndex = 4; this.grpNVIDIAInfo.TabStop = false; this.grpNVIDIAInfo.Text = "NVIDIA info"; @@ -1612,7 +1704,7 @@ // btnRefreshNVIDIAInfo // this.btnRefreshNVIDIAInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnRefreshNVIDIAInfo.Location = new System.Drawing.Point(6, 407); + this.btnRefreshNVIDIAInfo.Location = new System.Drawing.Point(6, 414); this.btnRefreshNVIDIAInfo.Name = "btnRefreshNVIDIAInfo"; this.btnRefreshNVIDIAInfo.Size = new System.Drawing.Size(75, 23); this.btnRefreshNVIDIAInfo.TabIndex = 1; @@ -1627,7 +1719,7 @@ | System.Windows.Forms.AnchorStyles.Right))); this.tvNVIDIAInfo.Location = new System.Drawing.Point(6, 19); this.tvNVIDIAInfo.Name = "tvNVIDIAInfo"; - this.tvNVIDIAInfo.Size = new System.Drawing.Size(428, 382); + this.tvNVIDIAInfo.Size = new System.Drawing.Size(465, 389); this.tvNVIDIAInfo.TabIndex = 0; // // groupBox3 @@ -1669,19 +1761,12 @@ this.lblInfo.TabIndex = 1; this.lblInfo.Text = "Info"; // - // miAmdCopyId - // - this.miAmdCopyId.Name = "miAmdCopyId"; - this.miAmdCopyId.Size = new System.Drawing.Size(184, 22); - this.miAmdCopyId.Text = "Copy Id to Clipboard"; - this.miAmdCopyId.Click += new System.EventHandler(this.miAmdCopyId_Click); - // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.SystemColors.Control; - this.ClientSize = new System.Drawing.Size(873, 496); + this.ClientSize = new System.Drawing.Size(986, 503); this.Controls.Add(this.tcMain); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MinimumSize = new System.Drawing.Size(800, 535); @@ -1701,7 +1786,10 @@ this.tabAMD.PerformLayout(); this.mnuAmdPresets.ResumeLayout(false); this.tabLG.ResumeLayout(false); - this.tabLG.PerformLayout(); + this.scLgController.Panel1.ResumeLayout(false); + this.scLgController.Panel1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.scLgController)).EndInit(); + this.scLgController.ResumeLayout(false); this.mnuLgButtons.ResumeLayout(false); this.tabOptions.ResumeLayout(false); this.grpNvidiaOptions.ResumeLayout(false); @@ -1750,27 +1838,10 @@ private System.Windows.Forms.ToolStripMenuItem miToggleHDR; private System.Windows.Forms.ToolStripMenuItem miHDREnabled; private System.Windows.Forms.Label lblError; - private System.Windows.Forms.Label lblLgError; - private System.Windows.Forms.Button btnCloneLg; - private System.Windows.Forms.Button btnSetShortcutLg; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.TextBox edtShortcutLg; - private System.Windows.Forms.Button btnApplyLg; - private System.Windows.Forms.ListView lvLgPresets; - private System.Windows.Forms.TextBox edtStepsLg; - private System.Windows.Forms.Label lblStepsLg; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.TextBox edtNameLg; private System.Windows.Forms.Button btnNvPresetDelete; private System.Windows.Forms.Button btnAddModesNv; - private System.Windows.Forms.Label lblDeviceFilter; - private System.Windows.Forms.TextBox edtLgDeviceFilter; - private System.Windows.Forms.ComboBox cbxLgApps; - private System.Windows.Forms.Label label5; private System.Windows.Forms.ToolStripMenuItem miNvApply; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; - private System.Windows.Forms.Button btnDeleteLg; - private System.Windows.Forms.Button btnAddLg; private System.Windows.Forms.GroupBox grpGeneralOptions; private System.Windows.Forms.CheckBox chkStartMinimized; private System.Windows.Forms.CheckBox chkStartAfterLogin; @@ -1788,15 +1859,10 @@ private System.Windows.Forms.Label lblInfo; private System.Windows.Forms.GroupBox grpNVIDIAInfo; private System.Windows.Forms.TreeView tvNVIDIAInfo; - private System.Windows.Forms.Button btnLgRefreshApps; - private System.Windows.Forms.Label label3; - private System.Windows.Forms.ComboBox cbxLgDevices; private System.Windows.Forms.Button btnRefreshNVIDIAInfo; - private System.Windows.Forms.Button btnLgAddButton; private System.Windows.Forms.ContextMenuStrip mnuLgButtons; private System.Windows.Forms.ToolStripMenuItem mnuNvPresetsColorSettings; private System.Windows.Forms.ToolStripMenuItem miNvPresetColorSettings; - private System.Windows.Forms.CheckedListBox clbLgPower; private System.Windows.Forms.GroupBox grpLGOptions; private System.Windows.Forms.NumericUpDown edtLgMaxPowerOnRetries; private System.Windows.Forms.Label lblLgMaxPowerOnRetries; @@ -1813,7 +1879,6 @@ private System.Windows.Forms.TabPage tabAMD; private System.Windows.Forms.Label lblErrorAMD; private System.Windows.Forms.Button btnClearLog; - private System.Windows.Forms.Button btnLgDeviceFilterRefresh; private System.Windows.Forms.GroupBox grpNvidiaOptions; private System.Windows.Forms.PictureBox pbGradient; private System.Windows.Forms.Label lblDitheringMode; @@ -1831,7 +1896,6 @@ private System.Windows.Forms.ToolStripMenuItem spatialDynamic2x2ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem spatialStatic2x2ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem temporalToolStripMenuItem; - private System.Windows.Forms.Button btnLGRemoteControl; private System.Windows.Forms.ToolStripMenuItem miNvPresetApplyOnStartup; private System.Windows.Forms.CheckBox chkLgOldWolMechanism; private System.Windows.Forms.ToolStripMenuItem mnuLgRcButtons; @@ -1868,6 +1932,37 @@ private System.Windows.Forms.Label lblAmdPresetName; private System.Windows.Forms.TextBox edtAmdPresetName; private System.Windows.Forms.ToolStripMenuItem miAmdCopyId; + private System.Windows.Forms.SplitContainer scLgController; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.ComboBox cbxLgDevices; + private System.Windows.Forms.Button btnLgDeviceConvertToCustom; + private System.Windows.Forms.ComboBox cbxLgApps; + private System.Windows.Forms.ListView lvLgPresets; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.ComboBox cbxLgPresetDevice; + private System.Windows.Forms.Button btnDeleteLg; + private System.Windows.Forms.Button btnApplyLg; + private System.Windows.Forms.Label lblDeviceFilter; + private System.Windows.Forms.Label lblLgPresetDevice; + private System.Windows.Forms.Button btnAddLg; + private System.Windows.Forms.TextBox edtShortcutLg; + private System.Windows.Forms.TextBox edtLgDeviceFilter; + private System.Windows.Forms.Button btnLgRemoveDevice; + private System.Windows.Forms.Button btnLgRefreshApps; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button btnLgAddDevice; + private System.Windows.Forms.TextBox edtNameLg; + private System.Windows.Forms.Button btnSetShortcutLg; + private System.Windows.Forms.TextBox edtStepsLg; + private System.Windows.Forms.Button btnLgAddButton; + private System.Windows.Forms.Button btnCloneLg; + private System.Windows.Forms.Label lblStepsLg; + private System.Windows.Forms.Button btnLgDeviceFilterRefresh; + private System.Windows.Forms.CheckedListBox clbLgPower; + private System.Windows.Forms.Label lblLgError; + private System.Windows.Forms.CheckBox chkLgRemoteControlShow; + private System.ComponentModel.BackgroundWorker backgroundWorker1; } } diff --git a/ColorControl/MainForm.cs b/ColorControl/MainForm.cs index ae9a98e..4d2cfeb 100644 --- a/ColorControl/MainForm.cs +++ b/ColorControl/MainForm.cs @@ -37,12 +37,12 @@ namespace ColorControl private NotifyIcon _trayIcon; private bool _initialized = false; + private bool _disableEvents = false; private Config _config; private bool _setVisibleCalled = false; private RestartDetector _restartDetector; private LgService _lgService; - private RemoteControlForm _remoteControlForm; private MenuItem _nvTrayMenu; private MenuItem _amdTrayMenu; @@ -149,11 +149,6 @@ namespace ColorControl FillLgPresets(); - clbLgPower.SetItemChecked(0, _lgService.Config.PowerOnAfterStartup); - clbLgPower.SetItemChecked(1, _lgService.Config.PowerOnAfterResume); - clbLgPower.SetItemChecked(2, _lgService.Config.PowerOffOnShutdown); - clbLgPower.SetItemChecked(3, _lgService.Config.PowerOffOnStandby); - clbLgPower.SetItemChecked(4, _lgService.Config.PowerSwitchOnScreenSaver); edtLgMaxPowerOnRetries.Value = _lgService.Config.PowerOnRetries; edtLgDeviceFilter.Text = _lgService.Config.DeviceSearchKey; chkLgOldWolMechanism.Checked = _lgService.Config.UseOldNpcapWol; @@ -171,15 +166,6 @@ namespace ColorControl item.Click += miLgAddButton_Click; } - var actions = _lgService.GetInvokableActions(); - foreach (var keyValuePair in actions) - { - var text = keyValuePair.Key; - - var item = mnuLgActions.DropDownItems.Add(text); - item.Click += miLgAddAction_Click; - } - _lgService.InstallEventHandlers(); } catch (Exception e) @@ -403,7 +389,7 @@ namespace ColorControl GlobalSave(); - if (SystemShutdown && _lgService.Config.PowerOffOnShutdown) + if (SystemShutdown && _lgService.Devices.Any(d => d.PowerOffOnShutdown)) { Logger.Debug($"MainForm_FormClosing: SystemShutdown"); @@ -418,7 +404,7 @@ namespace ColorControl else { Logger.Debug("Powering off tv..."); - var task = _lgService.PowerOff(); + var task = _lgService.PowerOffOnShutdownOrResume(); Utils.WaitForTask(task); Logger.Debug("Done powering off tv"); //ExecPowerOffPreset(true); @@ -1049,6 +1035,7 @@ namespace ColorControl btnApplyLg.Enabled = enabled; btnCloneLg.Enabled = enabled; edtNameLg.Enabled = enabled; + cbxLgPresetDevice.Enabled = enabled; edtShortcutLg.Enabled = enabled; btnSetShortcutLg.Enabled = enabled; edtStepsLg.Enabled = enabled; @@ -1065,6 +1052,20 @@ namespace ColorControl cbxLgApps.SelectedIndex = lgApps == null ? -1 : lgApps.FindIndex(x => x.appId.Equals(preset.appId)); edtShortcutLg.Text = preset.shortcut; edtStepsLg.Text = preset.steps.Aggregate("", (a, b) => (string.IsNullOrEmpty(a) ? "" : a + ", ") + b); + + var index = -1; + + for (var i = 0; i < cbxLgPresetDevice.Items.Count; i++) + { + var pnpDev = (LgDevice)cbxLgPresetDevice.Items[i]; + if ((string.IsNullOrEmpty(preset.DeviceMacAddress) && string.IsNullOrEmpty(pnpDev.MacAddress)) || pnpDev.MacAddress.Equals(preset.DeviceMacAddress, StringComparison.OrdinalIgnoreCase)) + { + index = i; + break; + } + } + + cbxLgPresetDevice.SelectedIndex = index; } else { @@ -1072,6 +1073,7 @@ namespace ColorControl cbxLgApps.SelectedIndex = -1; edtShortcutLg.Text = string.Empty; edtStepsLg.Text = string.Empty; + cbxLgPresetDevice.SelectedIndex = -1; } } @@ -1105,6 +1107,16 @@ namespace ColorControl preset.name = name; + if (cbxLgPresetDevice.SelectedIndex == -1) + { + preset.DeviceMacAddress = string.Empty; + } + else + { + var device = (LgDevice)cbxLgPresetDevice.SelectedItem; + preset.DeviceMacAddress = device.MacAddress; + } + if (cbxLgApps.SelectedIndex == -1) { preset.appId = string.Empty; @@ -1199,6 +1211,15 @@ namespace ColorControl { FillLgDevices(); } + + if (scLgController.Panel2.Controls.Count == 0) + { + var rcPanel = new RemoteControlPanel(_lgService, _lgService.GetRemoteControlButtons()); + rcPanel.Parent = scLgController.Panel2; + rcPanel.Dock = DockStyle.Fill; + } + chkLgRemoteControlShow.Checked = _lgService.Config.ShowRemoteControl; + scLgController.Panel2Collapsed = !_lgService.Config.ShowRemoteControl; } } else if (tcMain.SelectedTab == tabLog) @@ -1236,15 +1257,21 @@ namespace ColorControl private void FillLgDevices() { - cbxLgDevices.Items.Clear(); var devices = _lgService.Devices; - foreach (var device in devices) + + cbxLgDevices.Items.Clear(); + cbxLgDevices.Items.AddRange(devices.ToArray()); + + cbxLgPresetDevice.Items.Clear(); + cbxLgPresetDevice.Items.AddRange(devices.ToArray()); + var globalDevice = new LgDevice("Globally selected device", string.Empty, string.Empty, true, true); + cbxLgPresetDevice.Items.Insert(0, globalDevice); + + var device = _lgService.SelectedDevice; + + if (device != null) { - cbxLgDevices.Items.Add(device); - } - if (_lgService.SelectedDevice != null) - { - cbxLgDevices.SelectedIndex = cbxLgDevices.Items.IndexOf(_lgService.SelectedDevice); + cbxLgDevices.SelectedIndex = cbxLgDevices.Items.IndexOf(device); } if (!devices.Any()) @@ -1252,10 +1279,32 @@ namespace ColorControl MessageForms.WarningOk("It seems there's no LG TV available! Please make sure it's connected to the same network as this PC."); } - if (cbxLgApps.Items.Count == 0 && _lgService.SelectedDevice != null) + if (cbxLgApps.Items.Count == 0 && device != null) { _lgService.RefreshApps().ContinueWith((task) => BeginInvoke(new Action(FillLgApps))); } + + SetLgDevicePowerOptions(); + } + + private void SetLgDevicePowerOptions() + { + var device = _lgService.SelectedDevice; + clbLgPower.Enabled = device != null; + + _disableEvents = true; + try + { + clbLgPower.SetItemChecked(0, device?.PowerOnAfterStartup ?? false); + clbLgPower.SetItemChecked(1, device?.PowerOnAfterResume ?? false); + clbLgPower.SetItemChecked(2, device?.PowerOffOnShutdown ?? false); + clbLgPower.SetItemChecked(3, device?.PowerOffOnStandby ?? false); + clbLgPower.SetItemChecked(4, device?.PowerSwitchOnScreenSaver ?? false); + } + finally + { + _disableEvents = false; + } } private void FillLgApps() @@ -1542,9 +1591,13 @@ namespace ColorControl } else { - _lgService.SelectedDevice = (PnpDev)cbxLgDevices.SelectedItem; + _lgService.SelectedDevice = (LgDevice)cbxLgDevices.SelectedItem; } - btnLGRemoteControl.Enabled = _lgService.SelectedDevice != null; + chkLgRemoteControlShow.Enabled = _lgService.SelectedDevice != null; + btnLgRemoveDevice.Enabled = _lgService.SelectedDevice != null && _lgService.SelectedDevice.IsCustom; + btnLgDeviceConvertToCustom.Enabled = _lgService.SelectedDevice != null && !_lgService.SelectedDevice.IsCustom; + + SetLgDevicePowerOptions(); } private void lvLgPresets_DoubleClick(object sender, EventArgs e) @@ -1620,12 +1673,18 @@ namespace ColorControl private void clbLgPower_ItemCheck(object sender, ItemCheckEventArgs e) { - if (!_initialized) + if (!_initialized || _disableEvents) { return; } - if (!(_lgService.Config.PowerOnAfterResume || _lgService.Config.PowerOnAfterStartup || _lgService.Config.PowerSwitchOnScreenSaver)) + var device = _lgService?.SelectedDevice; + if (device == null) + { + return; + } + + if (!(device.PowerOnAfterResume || device.PowerOnAfterStartup || device.PowerSwitchOnScreenSaver)) { MessageForms.InfoOk( @"Be sure to activate the following setting on the TV, or the app will not be able to wake the TV: @@ -1638,11 +1697,11 @@ See Options to test this functionality." BeginInvoke(new Action(() => { - _lgService.Config.PowerOnAfterStartup = clbLgPower.GetItemChecked(0); - _lgService.Config.PowerOnAfterResume = clbLgPower.GetItemChecked(1); - _lgService.Config.PowerOffOnShutdown = clbLgPower.GetItemChecked(2); - _lgService.Config.PowerOffOnStandby = clbLgPower.GetItemChecked(3); - _lgService.Config.PowerSwitchOnScreenSaver = clbLgPower.GetItemChecked(4); + device.PowerOnAfterStartup = clbLgPower.GetItemChecked(0); + device.PowerOnAfterResume = clbLgPower.GetItemChecked(1); + device.PowerOffOnShutdown = clbLgPower.GetItemChecked(2); + device.PowerOffOnStandby = clbLgPower.GetItemChecked(3); + device.PowerSwitchOnScreenSaver = clbLgPower.GetItemChecked(4); _lgService.InstallEventHandlers(); })); @@ -1810,16 +1869,6 @@ Do you want to continue?"; private void btnLGRemoteControl_Click(object sender, EventArgs e) { - if (_remoteControlForm == null || _remoteControlForm.IsDisposed) - { - var buttons = _lgService.GetRemoteControlButtons(); - _remoteControlForm = new RemoteControlForm(_lgService, buttons); - _remoteControlForm.Show(); - } - else - { - _remoteControlForm.Show(); - } } private void AfterInitialized() @@ -2273,5 +2322,116 @@ Do you want to continue?"; Clipboard.SetText(preset.id.ToString()); } } + + private void btnLgAddDevice_Click(object sender, EventArgs e) + { + var values = MessageForms.ShowDialog("Add tv", new[] { "Name", "Ip-address", "MAC-address" }, ValidateAddDevice); + if (values.Any()) + { + var device = new LgDevice(values[0], values[1], values[2]); + + var form = MessageForms.ShowProgress("Connecting to device..."); + + var result = false; + Enabled = false; + try + { + var task = device.TestConnection(); + + result = Utils.WaitForTask(task); + } + finally + { + form.Close(); + Enabled = true; + } + + if (!result && MessageForms.QuestionYesNo("Unable to connect to the device. Are you sure you want to add it?") != DialogResult.Yes) + { + return; + } + + _lgService.AddCustomDevice(device); + + FillLgDevices(); + } + } + + private string ValidateAddDevice(List values) + { + if (values.Any(v => string.IsNullOrEmpty(v))) + { + return "Please fill in all the fields"; + } + + return null; + } + + private void btnLgRemoveDevice_Click(object sender, EventArgs e) + { + if (MessageForms.QuestionYesNo("Are you sure you want to remove this device?") != DialogResult.Yes) + { + return; + } + + var device = _lgService.SelectedDevice; + + if (device != null) + { + _lgService.RemoveCustomDevice(device); + + FillLgDevices(); + } + } + + private void mnuLgButtons_Opening(object sender, CancelEventArgs e) + { + mnuLgActions.DropDownItems.Clear(); + + var preset = GetSelectedLgPreset(); + + if (preset == null) + { + return; + } + + var device = _lgService.GetPresetDevice(preset); + + var actions = device?.GetInvokableActions(); + foreach (var keyValuePair in actions) + { + var text = keyValuePair.Key; + + var item = mnuLgActions.DropDownItems.Add(text); + item.Click += miLgAddAction_Click; + } + + } + + private void btnLgDeviceConvertToCustom_Click(object sender, EventArgs e) + { + if (MessageForms.QuestionYesNo( +@"This will convert the automatically detected device to a custom variant. +This means that the device will remain here even if it is not detected anymore. +Do you want to continue?" + ) != DialogResult.Yes) + { + return; + } + + _lgService.SelectedDevice.ConvertToCustom(); + + FillLgDevices(); + } + + private void btnLgRemoteControlShow_Click(object sender, EventArgs e) + { + } + + private void chkLgRemoteControlShow_CheckedChanged(object sender, EventArgs e) + { + scLgController.Panel2Collapsed = !chkLgRemoteControlShow.Checked; + _lgService.Config.ShowRemoteControl = chkLgRemoteControlShow.Checked; + } } } \ No newline at end of file diff --git a/ColorControl/MainForm.resx b/ColorControl/MainForm.resx index 3c2e711..e2818cd 100644 --- a/ColorControl/MainForm.resx +++ b/ColorControl/MainForm.resx @@ -126,6 +126,9 @@ 147, 17 + + 419, 17 + diff --git a/ColorControl/MessageForms.cs b/ColorControl/MessageForms.cs index d784622..7f176fc 100644 --- a/ColorControl/MessageForms.cs +++ b/ColorControl/MessageForms.cs @@ -1,8 +1,7 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; namespace ColorControl @@ -30,5 +29,91 @@ namespace ColorControl { return MessageBox.Show(text, MainForm?.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Information); } + + public static List ShowDialog(string caption, IEnumerable labels, Func, string> validateFunc = null) + { + var values = new List(); + + var prompt = new Form() + { + Width = 500, + Height = 90 + (labels.Count() * 55), + FormBorderStyle = FormBorderStyle.FixedDialog, + Text = caption, + StartPosition = FormStartPosition.CenterScreen + }; + + var top = 10; + var boxes = new List(); + + foreach (var label in labels) + { + var textLabel = new Label() { Left = 40, Top = top, Text = label }; + top += 25; + prompt.Controls.Add(textLabel); + + var textBox = new MaskedTextBox() { Left = 40, Top = top, Width = 400 }; + + if (label.Contains("Ip-address")) + { + textBox.Mask = "###.###.###.###"; + textBox.ValidatingType = typeof(System.Net.IPAddress); + textBox.Culture = CultureInfo.InvariantCulture; + } + else if (label.Contains("MAC-address")) + { + textBox.Mask = "AA-AA-AA-AA-AA-AA"; + textBox.Culture = CultureInfo.InvariantCulture; + } + + top += 30; + prompt.Controls.Add(textBox); + boxes.Add(textBox); + } + + var confirmation = new Button() { Text = "Add", Left = 365, Width = 75, Top = prompt.ClientRectangle.Height - 30 }; + confirmation.Click += (sender, e) => + { + values.AddRange(boxes.Select(b => b.Text.Trim())); + + if (validateFunc != null) + { + var message = validateFunc(values); + + if (!string.IsNullOrEmpty(message)) + { + WarningOk(message); + values.Clear(); + return; + } + } + prompt.Close(); + }; + prompt.Controls.Add(confirmation); + prompt.AcceptButton = confirmation; + + prompt.ShowDialog(MainForm); + + return values; + } + + public static Form ShowProgress(string caption) + { + var prompt = new Form() + { + Width = 300, + Height = 100, + FormBorderStyle = FormBorderStyle.FixedToolWindow, + Text = caption, + StartPosition = FormStartPosition.CenterScreen, + ControlBox = false + }; + var textLabel = new Label() { Left = 20, Top = 25, Text = caption, AutoSize = true }; + prompt.Controls.Add(textLabel); + + prompt.Show(MainForm); + + return prompt; + } } -} +} \ No newline at end of file diff --git a/ColorControl/PnpDev.cs b/ColorControl/PnpDev.cs index 7133ed4..759f142 100644 --- a/ColorControl/PnpDev.cs +++ b/ColorControl/PnpDev.cs @@ -1,11 +1,14 @@ -using Windows.Devices.Enumeration; +using Newtonsoft.Json; +using Windows.Devices.Enumeration; using Windows.Devices.Enumeration.Pnp; namespace ColorControl { class PnpDev { + [JsonIgnore] public DeviceInformation DevInfo { get; private set; } + [JsonIgnore] public PnpObject PnpObject { get; private set; } public string Name { get; private set; } @@ -13,18 +16,27 @@ namespace ColorControl public string MacAddress { get; private set; } - public PnpDev(DeviceInformation devInfo, PnpObject pnpObject, string name, string ipAddress, string macAddress) + [JsonConstructor] + public PnpDev(string name, string ipAddress, string macAddress) { - DevInfo = devInfo; - PnpObject = pnpObject; Name = name; IpAddress = ipAddress; MacAddress = macAddress; } + public PnpDev(DeviceInformation devInfo, PnpObject pnpObject, string name, string ipAddress, string macAddress) : this(name, ipAddress, macAddress) + { + DevInfo = devInfo; + PnpObject = pnpObject; + } public override string ToString() { - return Name + " (" + IpAddress + ")"; + return (IsCustom() ? "Custom: " : "Auto detect: ") + $"{Name}" + (!string.IsNullOrEmpty(IpAddress) ? $"({IpAddress})" : string.Empty); + } + + public bool IsCustom() + { + return DevInfo == null; } } } diff --git a/ColorControl/PresetBase.cs b/ColorControl/PresetBase.cs index 6376ac3..cd9fc4f 100644 --- a/ColorControl/PresetBase.cs +++ b/ColorControl/PresetBase.cs @@ -1,12 +1,33 @@ using System; using System.Collections.Generic; +using System.ComponentModel; namespace ColorControl { + [Flags] + enum PresetTrigger + { + [Description("Startup")] + Startup = 1, + [Description("Resume")] + Resume = 2, + [Description("Shutdown")] + Shutdown = 4, + [Description("Standby")] + Standby = 8, + [Description("Screensaver")] + Screensaver = 16, + [Description("Process start")] + ProcessStart = 32, + [Description("Process exit")] + ProcessExit = 64 + } + internal abstract class PresetBase { public string name { get; set; } public string shortcut { get; set; } + public PresetTrigger Triggers { get; set; } private int _id; diff --git a/ColorControl/Program.cs b/ColorControl/Program.cs index 887f5fd..a490f08 100644 --- a/ColorControl/Program.cs +++ b/ColorControl/Program.cs @@ -150,7 +150,7 @@ namespace ColorControl Console.WriteLine("--amdpreset : execute AMD-preset"); Console.WriteLine("--lgpreset : execute LG-preset"); Console.WriteLine("--help : displays this help info"); - Console.WriteLine("Options :"); + Console.WriteLine("Options:"); Console.WriteLine("--nogui: starts command from the command line and will not open GUI (is forced when GUI is already running)"); result = true; diff --git a/ColorControl/Properties/AssemblyInfo.cs b/ColorControl/Properties/AssemblyInfo.cs index a217925..c969fec 100644 --- a/ColorControl/Properties/AssemblyInfo.cs +++ b/ColorControl/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // 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("2.2.0.0")] -[assembly: AssemblyFileVersion("2.2.0.0")] +[assembly: AssemblyVersion("3.0.0.0")] +[assembly: AssemblyFileVersion("3.0.0.0")] diff --git a/ColorControl/Properties/Resources.Designer.cs b/ColorControl/Properties/Resources.Designer.cs index e406eea..378073f 100644 --- a/ColorControl/Properties/Resources.Designer.cs +++ b/ColorControl/Properties/Resources.Designer.cs @@ -8,10 +8,10 @@ // //------------------------------------------------------------------------------ -namespace ColorControl.Properties -{ - - +namespace ColorControl.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -19,53 +19,82 @@ namespace ColorControl.Properties // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - + internal class Resources { + private static global::System.Resources.ResourceManager resourceMan; - + private static global::System.Globalization.CultureInfo resourceCulture; - + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { + internal Resources() { } - + /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ColorControl.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - + /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { + internal static global::System.Globalization.CultureInfo Culture { + get { return resourceCulture; } - set - { + set { resourceCulture = value; } } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap LG_remote { + get { + object obj = ResourceManager.GetObject("LG_remote", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Power;120;132 + ///1;106;228 + ///2;196;228 + ///3;286;228 + ///4;106;296 + ///5;196;296 + ///6;286;296 + ///7;106;362 + ///8;196;362 + ///9;286;362 + ///0;196;425 + ///Vol +;98;513 + ///Mute;198;513 + ///Channel +;298;513 + ///Vol -;98;622 + ///Speech;198;633 + ///Channel -;298;622 + ///Home;78;695 + ///Settings;318;695. + /// + internal static string RC_coords { + get { + return ResourceManager.GetString("RC_coords", resourceCulture); + } + } } } diff --git a/ColorControl/Properties/Resources.resx b/ColorControl/Properties/Resources.resx index af7dbeb..7bd5ff2 100644 --- a/ColorControl/Properties/Resources.resx +++ b/ColorControl/Properties/Resources.resx @@ -46,7 +46,7 @@ mimetype: application/x-microsoft.net.object.binary.base64 value : The object must be serialized with - : System.Serialization.Formatters.Binary.BinaryFormatter + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : and then encoded with base64 encoding. mimetype: application/x-microsoft.net.object.soap.base64 @@ -60,6 +60,7 @@ : and then encoded with base64 encoding. --> + @@ -68,9 +69,10 @@ - + + @@ -85,9 +87,10 @@ - + + @@ -109,9 +112,16 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\LG_remote.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\RC_coords.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + \ No newline at end of file diff --git a/ColorControl/RemoteControlForm.Designer.cs b/ColorControl/RemoteControlForm.Designer.cs index df69698..6718f69 100644 --- a/ColorControl/RemoteControlForm.Designer.cs +++ b/ColorControl/RemoteControlForm.Designer.cs @@ -29,21 +29,25 @@ namespace ColorControl /// private void InitializeComponent() { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RemoteControlForm)); this.flowPanel = new System.Windows.Forms.FlowLayoutPanel(); this.btnClose = new System.Windows.Forms.Button(); this.lblUC = new System.Windows.Forms.Label(); this.chkDirectMode = new System.Windows.Forms.CheckBox(); this.pnlMouse = new System.Windows.Forms.Panel(); this.lblPos = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); this.SuspendLayout(); // // flowPanel // this.flowPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.flowPanel.Location = new System.Drawing.Point(12, 16); + this.flowPanel.Location = new System.Drawing.Point(12, 185); this.flowPanel.Name = "flowPanel"; - this.flowPanel.Size = new System.Drawing.Size(787, 164); + this.flowPanel.Size = new System.Drawing.Size(817, 120); this.flowPanel.TabIndex = 0; this.flowPanel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.RemoteControlForm_MouseDown); this.flowPanel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.flowPanel_MouseMove); @@ -56,7 +60,7 @@ namespace ColorControl this.btnClose.FlatAppearance.BorderSize = 0; this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.btnClose.ForeColor = System.Drawing.Color.White; - this.btnClose.Location = new System.Drawing.Point(796, 0); + this.btnClose.Location = new System.Drawing.Point(826, 0); this.btnClose.Name = "btnClose"; this.btnClose.Size = new System.Drawing.Size(14, 23); this.btnClose.TabIndex = 1; @@ -68,7 +72,7 @@ namespace ColorControl // this.lblUC.AutoSize = true; this.lblUC.ForeColor = System.Drawing.Color.Maroon; - this.lblUC.Location = new System.Drawing.Point(130, 0); + this.lblUC.Location = new System.Drawing.Point(12, 0); this.lblUC.Name = "lblUC"; this.lblUC.Size = new System.Drawing.Size(100, 13); this.lblUC.TabIndex = 0; @@ -78,8 +82,8 @@ namespace ColorControl // this.chkDirectMode.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.chkDirectMode.AutoSize = true; - this.chkDirectMode.ForeColor = System.Drawing.Color.DarkGray; - this.chkDirectMode.Location = new System.Drawing.Point(12, 643); + this.chkDirectMode.ForeColor = System.Drawing.Color.White; + this.chkDirectMode.Location = new System.Drawing.Point(12, 718); this.chkDirectMode.Name = "chkDirectMode"; this.chkDirectMode.Size = new System.Drawing.Size(105, 17); this.chkDirectMode.TabIndex = 2; @@ -93,9 +97,9 @@ namespace ColorControl | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.pnlMouse.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.pnlMouse.Location = new System.Drawing.Point(12, 191); + this.pnlMouse.Location = new System.Drawing.Point(12, 311); this.pnlMouse.Name = "pnlMouse"; - this.pnlMouse.Size = new System.Drawing.Size(787, 446); + this.pnlMouse.Size = new System.Drawing.Size(817, 401); this.pnlMouse.TabIndex = 3; this.pnlMouse.MouseEnter += new System.EventHandler(this.pnlMouse_MouseEnter); this.pnlMouse.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pnlMouse_MouseMove); @@ -106,17 +110,53 @@ namespace ColorControl this.lblPos.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.lblPos.AutoSize = true; this.lblPos.ForeColor = System.Drawing.Color.Maroon; - this.lblPos.Location = new System.Drawing.Point(719, 643); + this.lblPos.Location = new System.Drawing.Point(749, 718); this.lblPos.Name = "lblPos"; this.lblPos.Size = new System.Drawing.Size(0, 13); this.lblPos.TabIndex = 1; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.ForeColor = System.Drawing.Color.White; + this.label1.Location = new System.Drawing.Point(12, 26); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(538, 52); + this.label1.TabIndex = 4; + this.label1.Text = resources.GetString("label1.Text"); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.ForeColor = System.Drawing.Color.White; + this.label2.Location = new System.Drawing.Point(231, 91); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(216, 52); + this.label2.TabIndex = 5; + this.label2.Text = "Mouse:\r\n- left button: activate/open item\r\n- right button: go back\r\n- wheel: scro" + + "ll through menus (only vertically)"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.ForeColor = System.Drawing.Color.White; + this.label3.Location = new System.Drawing.Point(12, 91); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(180, 91); + this.label3.TabIndex = 6; + this.label3.Text = "Keyboard keys:\r\n- arrow keys: navigate the menu\r\n- backspace: go back\r\n- escape: " + + "exit\r\n- S: open picture settings\r\n- H: open Home\r\n- media keys: volume up/down/m" + + "ute"; // // RemoteControlForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.Black; - this.ClientSize = new System.Drawing.Size(811, 660); + this.ClientSize = new System.Drawing.Size(841, 735); + this.Controls.Add(this.label3); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); this.Controls.Add(this.lblPos); this.Controls.Add(this.pnlMouse); this.Controls.Add(this.chkDirectMode); @@ -132,6 +172,7 @@ namespace ColorControl this.Text = "RemoteControlForm"; this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.RemoteControlForm_FormClosed); this.Load += new System.EventHandler(this.RemoteControlForm_Load); + this.Shown += new System.EventHandler(this.RemoteControlForm_Shown); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.RemoteControlForm_KeyDown); this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.RemoteControlForm_KeyUp); this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.RemoteControlForm_MouseDown); @@ -149,5 +190,8 @@ namespace ColorControl private System.Windows.Forms.CheckBox chkDirectMode; private System.Windows.Forms.Panel pnlMouse; private System.Windows.Forms.Label lblPos; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; } } \ No newline at end of file diff --git a/ColorControl/RemoteControlForm.cs b/ColorControl/RemoteControlForm.cs index 5c659bb..ef7dcfc 100644 --- a/ColorControl/RemoteControlForm.cs +++ b/ColorControl/RemoteControlForm.cs @@ -116,24 +116,24 @@ namespace ColorControl { if (chkDirectMode.Checked) { - MessageForms.InfoOk( -@"If you enable Direct Mode you will be able to control the TV directly via your keyboard and mouse. -Note that your mouse will be captured in a box and that due to pointer accelaration the control will not be perfect. +// MessageForms.InfoOk( +//@"If you enable Direct Mode you will be able to control the TV directly via your keyboard and mouse. +//Note that your mouse will be captured in a box and that due to pointer accelaration the control will not be perfect. -Keyboard keys: -- arrow keys: navigate the menu -- backspace: go back -- escape: exit -- S: open picture settings -- media keys: volume up/down/mute +//Keyboard keys: +//- arrow keys: navigate the menu +//- backspace: go back +//- escape: exit +//- S: open picture settings +//- media keys: volume up/down/mute -Mouse: -- left button: activate/open item -- right button: go back -- wheel: scroll through menus (only vertically) +//Mouse: +//- left button: activate/open item +//- right button: go back +//- wheel: scroll through menus (only vertically) -Press F1 to stop Direct Mode." - ); +//Press F1 to stop Direct Mode." +// ); if (_mouseService == null) { @@ -216,6 +216,11 @@ Press F1 to stop Direct Mode." } } + private void RemoteControlForm_Shown(object sender, EventArgs e) + { + chkDirectMode.Checked = true; + } + private void pnlMouse_MouseMove(object sender, MouseEventArgs e) { HandleMouse(e); diff --git a/ColorControl/RemoteControlForm.resx b/ColorControl/RemoteControlForm.resx index 1af7de1..dfefb6a 100644 --- a/ColorControl/RemoteControlForm.resx +++ b/ColorControl/RemoteControlForm.resx @@ -117,4 +117,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + This form allows you to control the TV directly via your keyboard and mouse. +Note that your mouse will be captured in a box and that due to pointer acceleration the control will not be perfect. + +Press F1 to stop Direct Mode. + \ No newline at end of file diff --git a/ColorControl/RemoteControlPanel.Designer.cs b/ColorControl/RemoteControlPanel.Designer.cs new file mode 100644 index 0000000..3c4cf30 --- /dev/null +++ b/ColorControl/RemoteControlPanel.Designer.cs @@ -0,0 +1,81 @@ + +namespace ColorControl +{ + partial class RemoteControlPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.pbRemote = new System.Windows.Forms.PictureBox(); + this.btnRcDirect = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.pbRemote)).BeginInit(); + this.SuspendLayout(); + // + // pbRemote + // + this.pbRemote.Dock = System.Windows.Forms.DockStyle.Fill; + this.pbRemote.Image = global::ColorControl.Properties.Resources.LG_remote; + this.pbRemote.Location = new System.Drawing.Point(0, 0); + this.pbRemote.Name = "pbRemote"; + this.pbRemote.Size = new System.Drawing.Size(129, 468); + this.pbRemote.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pbRemote.TabIndex = 0; + this.pbRemote.TabStop = false; + this.pbRemote.Click += new System.EventHandler(this.pbRemote_Click); + this.pbRemote.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pbRemote_MouseMove); + // + // btnRcDirect + // + this.btnRcDirect.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnRcDirect.Location = new System.Drawing.Point(71, 7); + this.btnRcDirect.Name = "btnRcDirect"; + this.btnRcDirect.Size = new System.Drawing.Size(55, 23); + this.btnRcDirect.TabIndex = 3; + this.btnRcDirect.Text = "Direct"; + this.btnRcDirect.UseVisualStyleBackColor = true; + this.btnRcDirect.Click += new System.EventHandler(this.button1_Click); + // + // RemoteControlPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.White; + this.Controls.Add(this.btnRcDirect); + this.Controls.Add(this.pbRemote); + this.Name = "RemoteControlPanel"; + this.Size = new System.Drawing.Size(129, 468); + this.Load += new System.EventHandler(this.RemoteControlPanel_Load); + ((System.ComponentModel.ISupportInitialize)(this.pbRemote)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.PictureBox pbRemote; + private System.Windows.Forms.Button btnRcDirect; + } +} diff --git a/ColorControl/RemoteControlPanel.cs b/ColorControl/RemoteControlPanel.cs new file mode 100644 index 0000000..5ef437d --- /dev/null +++ b/ColorControl/RemoteControlPanel.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Windows.Forms; + +namespace ColorControl +{ + partial class RemoteControlPanel : UserControl + { + private static int Range = 35; + + private LgService _lgService; + private List _buttons; + private RemoteControlForm _remoteControlForm; + private Bitmap _backupImage; + private LgPreset _lastHoveredPreset; + + public RemoteControlPanel(LgService lgService, List buttons) + { + _lgService = lgService; + _buttons = buttons; + + InitializeComponent(); + + _backupImage = new Bitmap(pbRemote.Image); + + var txtCoords = Utils.GetResourceFile("RC_coords.txt"); + + foreach (var line in txtCoords.Split('\n')) + { + var columns = line.Split(';'); + + var name = columns[0]; + var preset = _buttons.FirstOrDefault(p => p.name.Equals(name)); + if (preset != null) + { + preset.X = int.Parse(columns[1]); + preset.Y = int.Parse(columns[2]); + } + } + } + + private void RemoteControlPanel_Load(object sender, EventArgs e) + { + } + + private void ButtonClick(object sender, EventArgs e) + { + if (e is MouseEventArgs) + { + var preset = (LgPreset)(sender as Button).Tag; + + var _ = _lgService.ApplyPreset(preset); + } + } + + private void pbRemote_Click(object sender, EventArgs e) + { + if (e is MouseEventArgs mouseArgs) + { + var (posX, posY) = GetCoordsInImage(mouseArgs.X, mouseArgs.Y); + + var preset = _buttons.FirstOrDefault(p => posX >= (p.X - Range) && posX <= (p.X + Range) && posY >= (p.Y - Range) && posY <= (p.Y + Range)); + + if (preset != null) + { + var _ = _lgService.ApplyPreset(preset); + } + } + } + + private (int, int) GetCoordsInImage(int curX, int curY) + { + var width = pbRemote.Width; + var aspect = 0.27D; + var currentAspect = (double)pbRemote.Width / pbRemote.Height; + if (currentAspect > aspect) + { + width = (int)(aspect * pbRemote.Height); + curX = curX - ((pbRemote.Width - width) / 2); + } + else + { + var height = (int)(pbRemote.Width / aspect); + curY = curY - ((pbRemote.Height - height) / 2); + } + + var factor = 405D / width; + + var posX = (int)(curX * factor); + var posY = (int)(curY * factor); + + return (posX, posY); + } + + private void btnRcDirect_Click(object sender, EventArgs e) + { + } + + private void pbRemote_MouseMove(object sender, MouseEventArgs mouseArgs) + { + var (posX, posY) = GetCoordsInImage(mouseArgs.X, mouseArgs.Y); + + var preset = _buttons.FirstOrDefault(p => posX >= (p.X - Range) && posX <= (p.X + Range) && posY >= (p.Y - Range) && posY <= (p.Y + Range)); + + var refresh = false; + + if (_lastHoveredPreset != null && (preset == null || preset != _lastHoveredPreset)) + { + var image = (Bitmap)pbRemote.Image; + + for (var y = Math.Max(0, _lastHoveredPreset.Y - Range); y < _lastHoveredPreset.Y + Range; y++) + { + for (var x = Math.Max(0, _lastHoveredPreset.X - Range); x < _lastHoveredPreset.X + Range; x++) + { + image.SetPixel(x, y, _backupImage.GetPixel(x, y)); + + } + } + + refresh = true; + } + + if (preset != null && preset != _lastHoveredPreset) + { + var image = (Bitmap)pbRemote.Image; + var rec = new Rectangle(Math.Max(0, preset.X - Range), Math.Max(0, preset.Y - Range), Range * 2, Range * 2); + + using (var g = Graphics.FromImage(image)) + { + using (var cloud_brush = new SolidBrush(Color.FromArgb(128, Color.White))) + { + g.FillEllipse(cloud_brush, rec); + } + } + + //for (var y = preset.Y - 30; y < preset.Y + 30; y++) + //{ + // for (var x = preset.X - 30; x < preset.X + 30; x++) + // { + // var pixel = image.GetPixel(x, y); + + // image.SetPixel(x, y, Color.FromArgb(150, 0, 0)); + + // } + //} + + refresh = true; + } + + if (refresh) + { + pbRemote.Refresh(); + } + + _lastHoveredPreset = preset; + } + + private void button1_Click(object sender, EventArgs e) + { + if (_remoteControlForm == null || _remoteControlForm.IsDisposed) + { + var buttons = _lgService.GetRemoteControlButtons(); + _remoteControlForm = new RemoteControlForm(_lgService, buttons); + _remoteControlForm.Show(); + } + else + { + _remoteControlForm.Show(); + } + } + } +} diff --git a/ColorControl/RemoteControlPanel.resx b/ColorControl/RemoteControlPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ColorControl/RemoteControlPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ColorControl/Resources/LG_remote.jpg b/ColorControl/Resources/LG_remote.jpg new file mode 100644 index 0000000..58b9dda Binary files /dev/null and b/ColorControl/Resources/LG_remote.jpg differ diff --git a/ColorControl/Resources/RC_coords.txt b/ColorControl/Resources/RC_coords.txt new file mode 100644 index 0000000..727d1c6 --- /dev/null +++ b/ColorControl/Resources/RC_coords.txt @@ -0,0 +1,37 @@ +Power;120;136 +1;106;228 +2;196;228 +3;286;228 +4;106;296 +5;196;296 +6;286;296 +7;106;362 +8;196;362 +9;286;362 +List;106;425 +0;196;425 +SAP;286;425 +Vol +;98;513 +Mute;198;513 +Channel +;298;513 +Vol -;98;622 +Channel -;298;622 +Home;78;695 +Settings;318;695 +Up;200;748 +Left;98;852 +Enter;200;852 +Right;304;852 +Down;200;952 +Back;80;1000 +TV Guide;320;1000 +Netflix;92;1076 +Inputs;200;1066 +Amazon Prime;312;1076 +Red;90;1150 +Green;164;1150 +Yellow;240;1150 +Blue;316;1150 +Rakuten TV;116;1218 +Play;202;1218 +Pause;291;1218 \ No newline at end of file diff --git a/ColorControl/Utils.cs b/ColorControl/Utils.cs index 04164ac..ba0ff54 100644 --- a/ColorControl/Utils.cs +++ b/ColorControl/Utils.cs @@ -353,16 +353,25 @@ namespace ColorControl return devices; } - public static T WaitForTask(System.Threading.Tasks.Task task) + public static T WaitForTask(Task task) { while (task != null && (task.Status < TaskStatus.WaitingForChildrenToComplete)) { - Thread.Sleep(100); + Thread.Sleep(10); Application.DoEvents(); } return task.Result; } + public static void WaitForTask(System.Threading.Tasks.Task task) + { + while (task != null && (task.Status < TaskStatus.WaitingForChildrenToComplete)) + { + Thread.Sleep(10); + Application.DoEvents(); + } + } + public static void SetNotifyIconText(NotifyIcon ni, string text) { text = text.Substring(0, Math.Min(text.Length, 127)); @@ -686,6 +695,26 @@ namespace ColorControl return null; } + + public static void StartProcess(string fileName, string arguments) + { + var process = Process.Start(fileName, arguments); + } + + public static string GetResourceFile(string resourceName) + { + resourceName = "ColorControl.Resources." + resourceName; + + var assembly = Assembly.GetExecutingAssembly(); + + using (Stream stream = assembly.GetManifestResourceStream(resourceName)) + using (StreamReader reader = new StreamReader(stream)) + { + var result = reader.ReadToEnd(); + + return result; + } + } } public static class ProcessExtensions diff --git a/ColorControl/lgtv/LgTvApi.cs b/ColorControl/lgtv/LgTvApi.cs index 31d60b8..63515fc 100644 --- a/ColorControl/lgtv/LgTvApi.cs +++ b/ColorControl/lgtv/LgTvApi.cs @@ -91,7 +91,7 @@ namespace LgTv public async Task Connect() { - var ctx = _connection.Connect(new Uri(webSocketUri)); + var ctx = _connection.Connect(new Uri(webSocketUri)); return await ctx; } @@ -365,6 +365,12 @@ namespace LgTv return (string)response.sessionId; } + public async Task Test() + { + var msg = JObject.Parse(@"{ ""configs"": { ""tv.model.motionProMode"": ""OLED Motion Pro"" } }"); + var requestMessage = new RequestMessage("luna://com.webos.service.config/setConfigs", msg); + var response = await _connection.SendCommandAsync(requestMessage); + } public void Close() { diff --git a/ColorControl/lgtv/LgTvConnection.cs b/ColorControl/lgtv/LgTvConnection.cs index 63b9d01..5f7c192 100644 --- a/ColorControl/lgtv/LgTvConnection.cs +++ b/ColorControl/lgtv/LgTvConnection.cs @@ -44,12 +44,30 @@ namespace LgTv _connection.MessageReceived += Connection_MessageReceived; _connection.Closed += Connection_Closed; - await _connection.ConnectAsync(uri); + var cancellationTokenSource = new CancellationTokenSource(); + var connectTask = _connection.ConnectAsync(uri).AsTask(cancellationTokenSource.Token); - IsConnected?.Invoke(true); + cancellationTokenSource.CancelAfter(5000); - _messageWriter = new DataWriter(_connection.OutputStream); - return true; + var result = await connectTask.ContinueWith((antecedent) => + { + if (antecedent.Status == TaskStatus.RanToCompletion) + { + // connectTask ran to completion, so we know that the MessageWebSocket is connected. + // Add additional code here to use the MessageWebSocket. + IsConnected?.Invoke(true); + + _messageWriter = new DataWriter(_connection.OutputStream); + return true; + } + else + { + // connectTask timed out, or faulted. + return false; + } + }); + + return result; } catch (Exception e) { diff --git a/ColorControl/lgtv/LgWebOsMouseService.cs b/ColorControl/lgtv/LgWebOsMouseService.cs index 5d3d692..d64c8d2 100644 --- a/ColorControl/lgtv/LgWebOsMouseService.cs +++ b/ColorControl/lgtv/LgWebOsMouseService.cs @@ -33,7 +33,15 @@ namespace LgTv MUTE, MENU, CC, - DASH + DASH, + CHANNELUP, + CHANNELDOWN, + LIST, + AD, + SAP, + PROGRAM, + PLAY, + PAUSE } public class LgWebOsMouseService : IDisposable