From 04d52d6062047ab54ffcbfb1b3c9a27d36ca11a8 Mon Sep 17 00:00:00 2001 From: Vincent Maas Date: Sun, 24 Jan 2021 15:35:00 +0100 Subject: [PATCH] add apply on startup, improve remote controller, fixed some bugs --- ColorControl/ColorControl.csproj | 3 +- ColorControl/Config.cs | 2 + ColorControl/LgService.cs | 48 +++--- ColorControl/MainForm.Designer.cs | 28 ++-- ColorControl/MainForm.cs | 117 ++++++++------ ColorControl/MessageForms.cs | 34 ++++ ColorControl/NvPreset.cs | 34 ++-- ColorControl/NvService.cs | 39 +++-- ColorControl/Properties/AssemblyInfo.cs | 4 +- ColorControl/RemoteControlForm.Designer.cs | 62 ++++++- ColorControl/RemoteControlForm.cs | 180 ++++++++++++++++++++- 11 files changed, 442 insertions(+), 109 deletions(-) create mode 100644 ColorControl/MessageForms.cs diff --git a/ColorControl/ColorControl.csproj b/ColorControl/ColorControl.csproj index 9693913..d14bb41 100644 --- a/ColorControl/ColorControl.csproj +++ b/ColorControl/ColorControl.csproj @@ -27,7 +27,7 @@ ColorControl Maassoft 0 - 1.4.0.0 + 1.5.0.0 false true true @@ -172,6 +172,7 @@ + diff --git a/ColorControl/Config.cs b/ColorControl/Config.cs index 828037b..951602f 100644 --- a/ColorControl/Config.cs +++ b/ColorControl/Config.cs @@ -13,6 +13,8 @@ public int FormWidth { get; set; } public int FormHeight { get; set; } + public int NvPresetId_ApplyOnStartup { get; set; } + public Config() { DisplaySettingsDelay = 1000; diff --git a/ColorControl/LgService.cs b/ColorControl/LgService.cs index cae96a6..2501075 100644 --- a/ColorControl/LgService.cs +++ b/ColorControl/LgService.cs @@ -89,16 +89,16 @@ namespace ColorControl var defaultButtons = GenerateDefaultRemoteControlButtons(); _rcButtonsFilename = Path.Combine(_dataDir, "LgRemoteControlButtons.json"); - if (File.Exists(_rcButtonsFilename)) - { - var json = File.ReadAllText(_rcButtonsFilename); + //if (File.Exists(_rcButtonsFilename)) + //{ + // var json = File.ReadAllText(_rcButtonsFilename); - _remoteControlButtons = _JsonDeserializer.Deserialize>(json); + // _remoteControlButtons = _JsonDeserializer.Deserialize>(json); - var missingButtons = defaultButtons.Where(b => !_remoteControlButtons.Any(x => x.name.Equals(b.name))); - _remoteControlButtons.AddRange(missingButtons); - } - else + // var missingButtons = defaultButtons.Where(b => !_remoteControlButtons.Any(x => x.name.Equals(b.name))); + // _remoteControlButtons.AddRange(missingButtons); + //} + //else { _remoteControlButtons = defaultButtons; } @@ -119,29 +119,34 @@ namespace ColorControl list.Add(GeneratePreset(button.ToString())); } - list.Add(GeneratePreset("Settings", appId: "com.palm.app.settings")); + list.Add(GeneratePreset("Settings", appId: "com.palm.app.settings", key: Keys.S)); - list.Add(GeneratePreset("Vol +", step: "VOLUMEUP")); - list.Add(GeneratePreset("Vol -", step: "VOLUMEDOWN")); - list.Add(GeneratePreset("Mute", step: "MUTE")); + 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("Up", step: "UP")); - list.Add(GeneratePreset("Down", step: "DOWN")); - list.Add(GeneratePreset("Left", step: "LEFT")); - list.Add(GeneratePreset("Right", step: "RIGHT")); + list.Add(GeneratePreset("Up", step: "UP", key: Keys.Up)); + list.Add(GeneratePreset("Down", step: "DOWN", key: Keys.Down)); + list.Add(GeneratePreset("Left", step: "LEFT", key: Keys.Left)); + list.Add(GeneratePreset("Right", step: "RIGHT", key: Keys.Right)); - list.Add(GeneratePreset("Enter", step: "ENTER")); - list.Add(GeneratePreset("Exit", step: "EXIT")); + list.Add(GeneratePreset("Enter", step: "ENTER", key: Keys.Enter)); + list.Add(GeneratePreset("Back", step: "BACK", key: Keys.Back)); + list.Add(GeneratePreset("Exit", step: "EXIT", key: Keys.Escape)); return list; } - private LgPreset GeneratePreset(string name, string step = null, string appId = null) + private LgPreset GeneratePreset(string name, string step = null, string appId = null, Keys key = Keys.None) { var preset = new LgPreset(); + var cvt = new KeysConverter(); + var shortcut = key != Keys.None ? (string)cvt.ConvertTo(key, typeof(string)) : null; + preset.name = name; preset.appId = appId; + preset.shortcut = shortcut; if (appId == null) { preset.steps.Add(step == null ? name : step); @@ -325,6 +330,11 @@ namespace ColorControl Thread.Sleep(delay); } + public async Task GetMouseAsync() + { + return await _lgTvApi.GetMouse(); + } + public async Task> RefreshApps(bool force = false) { if (SelectedDevice == null) diff --git a/ColorControl/MainForm.Designer.cs b/ColorControl/MainForm.Designer.cs index 707f398..44332bd 100644 --- a/ColorControl/MainForm.Designer.cs +++ b/ColorControl/MainForm.Designer.cs @@ -133,6 +133,7 @@ this.lbPlugins = new System.Windows.Forms.ListBox(); this.label7 = new System.Windows.Forms.Label(); this.lblInfo = new System.Windows.Forms.Label(); + this.miNvPresetApplyOnStartup = new System.Windows.Forms.ToolStripMenuItem(); this.tcMain.SuspendLayout(); this.tabNVIDIA.SuspendLayout(); this.mnuNvPresets.SuspendLayout(); @@ -289,6 +290,7 @@ this.mnuNvPresets.ImageScalingSize = new System.Drawing.Size(20, 20); this.mnuNvPresets.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.miNvApply, + this.miNvPresetApplyOnStartup, this.toolStripSeparator1, this.mnuNvDisplay, this.mnuNvPresetsColorSettings, @@ -296,27 +298,27 @@ this.miNvPresetDithering, this.miNvHDR}); this.mnuNvPresets.Name = "mnuNvPresets"; - this.mnuNvPresets.Size = new System.Drawing.Size(148, 142); + this.mnuNvPresets.Size = new System.Drawing.Size(181, 186); this.mnuNvPresets.Opening += new System.ComponentModel.CancelEventHandler(this.mnuNvPresets_Opening); // // miNvApply // this.miNvApply.Name = "miNvApply"; - this.miNvApply.Size = new System.Drawing.Size(147, 22); + this.miNvApply.Size = new System.Drawing.Size(180, 22); this.miNvApply.Text = "Apply"; this.miNvApply.Click += new System.EventHandler(this.miNvApply_Click); // // toolStripSeparator1 // this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(144, 6); + this.toolStripSeparator1.Size = new System.Drawing.Size(177, 6); // // mnuNvDisplay // this.mnuNvDisplay.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.miNvPrimaryDisplay}); this.mnuNvDisplay.Name = "mnuNvDisplay"; - this.mnuNvDisplay.Size = new System.Drawing.Size(147, 22); + this.mnuNvDisplay.Size = new System.Drawing.Size(180, 22); this.mnuNvDisplay.Text = "Display"; // // miNvPrimaryDisplay @@ -331,7 +333,7 @@ this.mnuNvPresetsColorSettings.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.miNvPresetColorSettings}); this.mnuNvPresetsColorSettings.Name = "mnuNvPresetsColorSettings"; - this.mnuNvPresetsColorSettings.Size = new System.Drawing.Size(147, 22); + this.mnuNvPresetsColorSettings.Size = new System.Drawing.Size(180, 22); this.mnuNvPresetsColorSettings.Text = "Color settings"; // // miNvPresetColorSettings @@ -346,7 +348,7 @@ this.mnuRefreshRate.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.miRefreshRateIncluded}); this.mnuRefreshRate.Name = "mnuRefreshRate"; - this.mnuRefreshRate.Size = new System.Drawing.Size(147, 22); + this.mnuRefreshRate.Size = new System.Drawing.Size(180, 22); this.mnuRefreshRate.Text = "Refresh Rate"; // // miRefreshRateIncluded @@ -364,7 +366,7 @@ this.mnuNvDitheringBitDepth, this.mnuNvDitheringMode}); this.miNvPresetDithering.Name = "miNvPresetDithering"; - this.miNvPresetDithering.Size = new System.Drawing.Size(147, 22); + this.miNvPresetDithering.Size = new System.Drawing.Size(180, 22); this.miNvPresetDithering.Text = "Dithering"; // // miNvPresetApplyDithering @@ -474,7 +476,7 @@ this.miToggleHDR, this.miHDREnabled}); this.miNvHDR.Name = "miNvHDR"; - this.miNvHDR.Size = new System.Drawing.Size(147, 22); + this.miNvHDR.Size = new System.Drawing.Size(180, 22); this.miNvHDR.Text = "HDR"; // // miHDRIncluded @@ -1285,6 +1287,14 @@ this.lblInfo.TabIndex = 1; this.lblInfo.Text = "Info"; // + // miNvPresetApplyOnStartup + // + this.miNvPresetApplyOnStartup.CheckOnClick = true; + this.miNvPresetApplyOnStartup.Name = "miNvPresetApplyOnStartup"; + this.miNvPresetApplyOnStartup.Size = new System.Drawing.Size(180, 22); + this.miNvPresetApplyOnStartup.Text = "Apply on startup"; + this.miNvPresetApplyOnStartup.Click += new System.EventHandler(this.miNvPresetApplyOnStartup_Click); + // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -1299,7 +1309,6 @@ this.Activated += new System.EventHandler(this.MainForm_Activated); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.MainForm_FormClosed); - this.Load += new System.EventHandler(this.MainForm_Load); this.Shown += new System.EventHandler(this.MainForm_Shown); this.Resize += new System.EventHandler(this.MainForm_Resize); this.tcMain.ResumeLayout(false); @@ -1439,6 +1448,7 @@ private System.Windows.Forms.ToolStripMenuItem spatialStatic2x2ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem temporalToolStripMenuItem; private System.Windows.Forms.Button btnLGRemoteControl; + private System.Windows.Forms.ToolStripMenuItem miNvPresetApplyOnStartup; } } diff --git a/ColorControl/MainForm.cs b/ColorControl/MainForm.cs index ae2873f..1be470c 100644 --- a/ColorControl/MainForm.cs +++ b/ColorControl/MainForm.cs @@ -72,6 +72,7 @@ namespace ColorControl private List _lgPresets; private string _lgPresetsFilename; private List _lgApps; + private RemoteControlForm _remoteControlForm; private MenuItem _nvTrayMenu; private MenuItem _lgTrayMenu; @@ -89,6 +90,8 @@ namespace ColorControl InitLogger(); + MessageForms.MainForm = this; + _nvTrayMenu = new MenuItem("NVIDIA presets"); _lgTrayMenu = new MenuItem("LG presets"); trayIcon = new NotifyIcon() @@ -122,6 +125,9 @@ namespace ColorControl var converter = new ColorDataConverter(); _JsonDeserializer.RegisterConverters(new[] { converter }); + _configFilename = Path.Combine(_dataDir, "Settings.json"); + LoadConfig(); + try { _nvService = new NvService(); @@ -159,9 +165,6 @@ namespace ColorControl } FillLgPresets(); - _configFilename = Path.Combine(_dataDir, "Settings.json"); - LoadConfig(); - try { _lgService = new LgService(_dataDir, StartUpParams.RunningFromScheduledTask); @@ -203,6 +206,8 @@ namespace ColorControl //Scale(new SizeF(1.25F, 1.25F)); _initialized = true; + + AfterInitialized(); } private void PowerModeChanged(object sender, PowerModeChangedEventArgs e) @@ -412,8 +417,16 @@ namespace ColorControl values.Add($"{refreshRate}Hz"); - //values.Add(_nvService.GetDithering() ? "Yes" : "No"); - values.Add(string.Empty); + var lastPreset = _nvService.GetLastAppliedPreset(); + if (lastPreset != null) + { + //values.Add(_nvService.GetDithering() ? "Yes" : "No"); + values.Add(lastPreset.GetDitheringDescription()); + } + else + { + values.Add(string.Empty); + } values.Add(_nvService.IsHDREnabled() ? "Yes" : "No"); @@ -459,7 +472,7 @@ namespace ColorControl preset = (NvPreset)item.Tag; } - var values = preset.GetDisplayValues(); + var values = preset.GetDisplayValues(_config); if (item == null) { @@ -648,7 +661,7 @@ namespace ColorControl if (!string.IsNullOrWhiteSpace(shortcut) && !shortcut.Contains("+")) { - WarningOk("Invalid shortcut. The shortcut should have modifiers and a normal key."); + MessageForms.WarningOk("Invalid shortcut. The shortcut should have modifiers and a normal key."); return; } @@ -720,7 +733,7 @@ namespace ColorControl } catch (Exception e) { - ErrorOk("Could not create/delete task: " + e.Message); + MessageForms.ErrorOk("Could not create/delete task: " + e.Message); } } @@ -943,6 +956,7 @@ namespace ColorControl var preset = GetSelectedNvPreset(); miNvApply.Enabled = preset != null; + miNvPresetApplyOnStartup.Enabled = preset != null; mnuNvDisplay.Enabled = preset != null; miNvPresetColorSettings.Enabled = preset != null; mnuNvPresetsColorSettings.Enabled = preset != null; @@ -952,6 +966,8 @@ namespace ColorControl if (preset != null) { + miNvPresetApplyOnStartup.Checked = _config.NvPresetId_ApplyOnStartup == preset.id; + if (mnuNvDisplay.DropDownItems.Count == 1) { var displays = _nvService.GetDisplays(); @@ -1327,7 +1343,7 @@ namespace ColorControl var shortcut = edtShortcutLg.Text.Trim(); if (!string.IsNullOrWhiteSpace(shortcut) && !shortcut.Contains("+")) { - WarningOk("Invalid shortcut. The shortcut should have modifiers and a normal key."); + MessageForms.WarningOk("Invalid shortcut. The shortcut should have modifiers and a normal key."); return; } @@ -1337,7 +1353,7 @@ namespace ColorControl if (name.Length == 0 || _lgPresets.Any(x => x.id != preset.id && x.name.Equals(name, StringComparison.OrdinalIgnoreCase))) { - WarningOk("The name can not be empty and must be unique."); + MessageForms.WarningOk("The name can not be empty and must be unique."); return; } @@ -1418,11 +1434,11 @@ namespace ColorControl if (added) { - InfoOk("Missing presets added."); + MessageForms.InfoOk("Missing presets added."); } else { - InfoOk("All presets for every color setting already exist."); + MessageForms.InfoOk("All presets for every color setting already exist."); } } @@ -1487,7 +1503,7 @@ namespace ColorControl if (!devices.Any()) { - WarningOk("It seems there's no LG TV available! Please make sure it's connected to the same network as this PC."); + 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) @@ -1501,7 +1517,7 @@ namespace ColorControl _lgApps = task.Result; if (_lgApps == null || !_lgApps.Any()) { - WarningOk("Could not refresh the apps. Check the log for details."); + MessageForms.WarningOk("Could not refresh the apps. Check the log for details."); return; } InitLgApps(); @@ -1660,7 +1676,7 @@ namespace ColorControl private void ApplyNvPreset(NvPreset preset) { - if (preset == null) + if (preset == null || _nvService == null) { return; } @@ -1669,14 +1685,14 @@ namespace ColorControl var result = _nvService.ApplyPreset(preset, _config); if (!result) { - throw new Exception("Error while applying NVIDIA preset"); + throw new Exception("Error while applying NVIDIA preset. At least one setting could not be applied. Check the log for details."); } UpdateDisplayInfoItems(); } catch (Exception e) { - ErrorOk($"Error applying NVIDIA-preset ({e.TargetSite.Name}): {e.Message}"); + MessageForms.ErrorOk($"Error applying NVIDIA-preset ({e.TargetSite.Name}): {e.Message}"); } } @@ -1699,7 +1715,7 @@ namespace ColorControl var result = task.Result; if (!result) { - WarningOk("Could not apply the preset (entirely). Check the log for details."); + MessageForms.WarningOk("Could not apply the preset (entirely). Check the log for details."); } } @@ -1738,26 +1754,6 @@ namespace ColorControl btnLGRemoteControl.Enabled = _lgService.SelectedDevice != null; } - private void WarningOk(string text) - { - MessageBox.Show(text, Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); - } - - private void ErrorOk(string text) - { - MessageBox.Show(text, Text, MessageBoxButtons.OK, MessageBoxIcon.Error); - } - - private void InfoOk(string text) - { - MessageBox.Show(text, Text, MessageBoxButtons.OK, MessageBoxIcon.Information); - } - - private DialogResult QuestionYesNo(string text) - { - return MessageBox.Show(text, Text, MessageBoxButtons.YesNo, MessageBoxIcon.Information); - } - private void lvLgPresets_DoubleClick(object sender, EventArgs e) { ApplySelectedLgPreset(); @@ -1828,7 +1824,7 @@ namespace ColorControl if (!(_lgService.Config.PowerOnAfterResume || _lgService.Config.PowerOnAfterStartup)) { - InfoOk( + MessageForms.InfoOk( @"Be sure to activate the following setting on the TV, or the app will not be able to wake the TV: Connection > Mobile TV On > Turn on via Wi-Fi @@ -1877,11 +1873,11 @@ Connection > Mobile TV On > Turn on via Wi-Fi It will also work over a wired connection. Do you want to continue?"; - if (QuestionYesNo(text) == DialogResult.Yes) + if (MessageForms.QuestionYesNo(text) == DialogResult.Yes) { _lgService.PowerOff(); - InfoOk("Press ENTER to wake the TV."); + MessageForms.InfoOk("Press ENTER to wake the TV."); _lgService.WakeSelectedDevice(); } @@ -1893,7 +1889,7 @@ Do you want to continue?"; if (!string.IsNullOrWhiteSpace(shortcut) && !shortcut.Contains("+")) { - WarningOk("Invalid shortcut. The shortcut should have modifiers and a normal key."); + MessageForms.WarningOk("Invalid shortcut. The shortcut should have modifiers and a normal key."); return; } @@ -2000,9 +1996,40 @@ Do you want to continue?"; private void btnLGRemoteControl_Click(object sender, EventArgs e) { - var buttons = _lgService.GetRemoteControlButtons(); - var remoteControlForm = new RemoteControlForm(_lgService, buttons); - remoteControlForm.Show(); + if (_remoteControlForm == null || _remoteControlForm.IsDisposed) + { + var buttons = _lgService.GetRemoteControlButtons(); + _remoteControlForm = new RemoteControlForm(_lgService, buttons); + _remoteControlForm.Show(); + } + else + { + _remoteControlForm.Show(); + } + } + + private void AfterInitialized() + { + if (_config.NvPresetId_ApplyOnStartup != 0) + { + var preset = _presets.FirstOrDefault(p => p.id == _config.NvPresetId_ApplyOnStartup); + if (preset == null) + { + _config.NvPresetId_ApplyOnStartup = 0; + } + else + { + ApplyNvPreset(preset); + } + } + } + + private void miNvPresetApplyOnStartup_Click(object sender, EventArgs e) + { + var preset = GetSelectedNvPreset(); + _config.NvPresetId_ApplyOnStartup = miNvPresetApplyOnStartup.Checked ? preset.id : 0; + + AddOrUpdateItem(); } } } \ No newline at end of file diff --git a/ColorControl/MessageForms.cs b/ColorControl/MessageForms.cs new file mode 100644 index 0000000..d784622 --- /dev/null +++ b/ColorControl/MessageForms.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace ColorControl +{ + class MessageForms + { + public static Form MainForm; + + public static void WarningOk(string text) + { + MessageBox.Show(text, MainForm?.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + + public static void ErrorOk(string text) + { + MessageBox.Show(text, MainForm?.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + public static void InfoOk(string text) + { + MessageBox.Show(text, MainForm?.Text, MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + public static DialogResult QuestionYesNo(string text) + { + return MessageBox.Show(text, MainForm?.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Information); + } + } +} diff --git a/ColorControl/NvPreset.cs b/ColorControl/NvPreset.cs index dd11a5a..cc9ff63 100644 --- a/ColorControl/NvPreset.cs +++ b/ColorControl/NvPreset.cs @@ -73,10 +73,10 @@ namespace ColorControl public static string[] GetColumnNames() { //return new[] { "BPC", "Format", "Dynamic range", "Toggle HDR", "Shortcut" }; - return new[] { "Display|140", "Color settings (BPC, format, dyn. range, color space)|260", "Refresh rate|100", "Dithering", "HDR", "Shortcut" }; + return new[] { "Display|140", "Color settings (BPC, format, dyn. range, color space)|260", "Refresh rate|100", "Dithering", "HDR", "Shortcut", "Apply on startup" }; } - public List GetDisplayValues() + public List GetDisplayValues(Config config) { var values = new List(); @@ -88,13 +88,7 @@ namespace ColorControl values.Add(colorSettings); values.Add(string.Format("{0}: {1}Hz", applyRefreshRate ? "Included" : "Excluded", refreshRate)); - var dithering = ditheringEnabled ? string.Empty : "Disabled"; - if (ditheringEnabled) - { - var ditherBitsDescription = ((NvDitherBits)ditheringBits).GetDescription(); - var ditherModeDescription = ((NvDitherMode)ditheringMode).GetDescription(); - dithering = string.Format("{0} {1}", ditherBitsDescription, ditherModeDescription); - } + var dithering = GetDitheringDescription(); values.Add(string.Format("{0}: {1}", applyDithering ? "Included" : "Excluded", dithering)); values.Add(string.Format("{0}: {1}", applyHDR ? "Included" : "Excluded", toggleHDR ? "Toggle" : HDREnabled ? "Enabled" : "Disabled")); @@ -105,9 +99,23 @@ namespace ColorControl //values.Add(toggleHDR.ToString()); values.Add(shortcut); + values.Add(string.Format("{0}", config.NvPresetId_ApplyOnStartup == id ? "Yes" : string.Empty)); + return values; } + public string GetDitheringDescription(string disabledText = "Disabled") + { + var dithering = ditheringEnabled ? string.Empty : disabledText; + if (ditheringEnabled) + { + var ditherBitsDescription = ((NvDitherBits)ditheringBits).GetDescription(); + var ditherModeDescription = ((NvDitherMode)ditheringMode).GetDescription(); + dithering = string.Format("{0} {1}", ditherBitsDescription, ditherModeDescription); + } + return dithering; + } + public static List GetDefaultPresets() { var presets = new List(); @@ -151,14 +159,8 @@ namespace ColorControl } if (applyDithering) { - var dithering = ditheringEnabled ? string.Empty : "No"; + var dithering = GetDitheringDescription("No"); sb.AppendFormat("Dithering: {0}", dithering); - if (ditheringEnabled) - { - var ditherBitsDescription = ((NvDitherBits)ditheringBits).GetDescription(); - var ditherModeDescription = ((NvDitherMode)ditheringMode).GetDescription(); - sb.AppendFormat("{0} {1}", ditherBitsDescription, ditherModeDescription); - } sb.Append(" / "); } if (applyHDR) diff --git a/ColorControl/NvService.cs b/ColorControl/NvService.cs index 4d1a11b..3b33fe0 100644 --- a/ColorControl/NvService.cs +++ b/ColorControl/NvService.cs @@ -97,6 +97,8 @@ namespace ColorControl public bool ApplyPreset(NvPreset preset, Config config) { + var result = true; + SetCurrentDisplay(preset); var hdrEnabled = IsHDREnabled(); @@ -121,6 +123,7 @@ namespace ColorControl catch (Exception ex) { Logger.Error($"SetColorData threw an exception: {ex.Message}"); + result = false; } if (hdrEnabled && newHdrEnabled) @@ -142,17 +145,23 @@ namespace ColorControl if (preset.applyRefreshRate) { - SetRefreshRate(preset.refreshRate); + if (!SetRefreshRate(preset.refreshRate)) + { + result = false; + } } if (preset.applyDithering) { - SetDithering(preset.ditheringEnabled, preset: preset); + if (!SetDithering(preset.ditheringEnabled, preset: preset)) + { + result = false; + } } _lastAppliedPreset = preset; - return true; + return result; } private bool ColorDataDiffers(ColorData colorData) @@ -163,7 +172,9 @@ namespace ColorControl var settingRange = colorData.DynamicRange == ColorDataDynamicRange.Auto ? colorData.ColorFormat == ColorDataFormat.RGB ? ColorDataDynamicRange.VESA : ColorDataDynamicRange.CEA : colorData.DynamicRange; - return colorData.ColorFormat != currentColorData.ColorFormat || colorData.ColorDepth != currentColorData.ColorDepth || settingRange != currentColorData.DynamicRange; + var settingSpace = colorData.Colorimetry; + + return colorData.ColorFormat != currentColorData.ColorFormat || colorData.ColorDepth != currentColorData.ColorDepth || settingRange != currentColorData.DynamicRange || settingSpace != currentColorData.Colorimetry; } private void SetHDRState(Display display, bool enabled, ColorData colorData = null) @@ -185,8 +196,10 @@ namespace ColorControl } } - public void SetDithering(bool enabled, uint bits = 1, uint mode = 4, NvPreset preset = null) + public bool SetDithering(bool enabled, uint bits = 1, uint mode = 4, NvPreset preset = null) { + var result = true; + var ptr = NvAPI64_QueryInterface(0xDF0DFCDD); if (ptr != IntPtr.Zero) { @@ -203,18 +216,26 @@ namespace ColorControl mode = preset.ditheringMode; } - var result = delegateValue(gpuHandle, displayId, (uint)(enabled ? 1 : 2), bits, mode); - if (result != 0) + var resultValue = delegateValue(gpuHandle, displayId, (uint)(enabled ? 1 : 2), bits, mode); + if (resultValue != 0) { - Logger.Error($"Could not set dithering because NvAPI_Disp_SetDitherControl returned a non-zero return code: {result}"); + Logger.Error($"Could not set dithering because NvAPI_Disp_SetDitherControl returned a non-zero return code: {resultValue}"); + result = false; } } + else + { + Logger.Error($"Could not set dithering because the function NvAPI_Disp_SetDitherControl could not be found"); + result = false; + } + + return result; } public bool GetDithering() { // Requires elevation, too bad :( - // Utils.GetRegistryKeyValue(@"SYSTEM\CurrentControlSet\Services\nvlddmkm\State\DisplayDatabase", "DitherRegistryKey"); + //Utils.GetRegistryKeyValue(@"SYSTEM\CurrentControlSet\Services\nvlddmkm\State\DisplayDatabase", "DitherRegistryKey"); /* var ptr = NvAPI64_QueryInterface(0x932AC8FB); diff --git a/ColorControl/Properties/AssemblyInfo.cs b/ColorControl/Properties/AssemblyInfo.cs index fa56faa..19c03da 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("1.4.0.0")] -[assembly: AssemblyFileVersion("1.4.0.0")] +[assembly: AssemblyVersion("1.5.0.0")] +[assembly: AssemblyFileVersion("1.5.0.0")] diff --git a/ColorControl/RemoteControlForm.Designer.cs b/ColorControl/RemoteControlForm.Designer.cs index d9428f7..df69698 100644 --- a/ColorControl/RemoteControlForm.Designer.cs +++ b/ColorControl/RemoteControlForm.Designer.cs @@ -32,18 +32,22 @@ namespace ColorControl 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.SuspendLayout(); // // flowPanel // - this.flowPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) + 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.Name = "flowPanel"; - this.flowPanel.Size = new System.Drawing.Size(326, 349); + this.flowPanel.Size = new System.Drawing.Size(787, 164); 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); + this.flowPanel.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.flowPanel_PreviewKeyDown); // // btnClose // @@ -52,7 +56,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(335, 0); + this.btnClose.Location = new System.Drawing.Point(796, 0); this.btnClose.Name = "btnClose"; this.btnClose.Size = new System.Drawing.Size(14, 23); this.btnClose.TabIndex = 1; @@ -70,23 +74,68 @@ namespace ColorControl this.lblUC.TabIndex = 0; this.lblUC.Text = "Under construction!"; // + // chkDirectMode + // + 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.Name = "chkDirectMode"; + this.chkDirectMode.Size = new System.Drawing.Size(105, 17); + this.chkDirectMode.TabIndex = 2; + this.chkDirectMode.Text = "Direct Mode (F1)"; + this.chkDirectMode.UseVisualStyleBackColor = true; + this.chkDirectMode.CheckedChanged += new System.EventHandler(this.chkDirectMode_CheckedChanged); + // + // pnlMouse + // + this.pnlMouse.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.pnlMouse.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.pnlMouse.Location = new System.Drawing.Point(12, 191); + this.pnlMouse.Name = "pnlMouse"; + this.pnlMouse.Size = new System.Drawing.Size(787, 446); + this.pnlMouse.TabIndex = 3; + this.pnlMouse.MouseEnter += new System.EventHandler(this.pnlMouse_MouseEnter); + this.pnlMouse.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pnlMouse_MouseMove); + this.pnlMouse.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pnlMouse_MouseUp); + // + // lblPos + // + 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.Name = "lblPos"; + this.lblPos.Size = new System.Drawing.Size(0, 13); + this.lblPos.TabIndex = 1; + // // 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(350, 377); + this.ClientSize = new System.Drawing.Size(811, 660); + this.Controls.Add(this.lblPos); + this.Controls.Add(this.pnlMouse); + this.Controls.Add(this.chkDirectMode); this.Controls.Add(this.lblUC); this.Controls.Add(this.btnClose); this.Controls.Add(this.flowPanel); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.KeyPreview = true; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "RemoteControlForm"; this.Opacity = 0.8D; this.Text = "RemoteControlForm"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.RemoteControlForm_FormClosed); this.Load += new System.EventHandler(this.RemoteControlForm_Load); + 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); + this.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.RemoteControlForm_PreviewKeyDown); this.ResumeLayout(false); this.PerformLayout(); @@ -97,5 +146,8 @@ namespace ColorControl private System.Windows.Forms.FlowLayoutPanel flowPanel; private System.Windows.Forms.Button btnClose; private System.Windows.Forms.Label lblUC; + private System.Windows.Forms.CheckBox chkDirectMode; + private System.Windows.Forms.Panel pnlMouse; + private System.Windows.Forms.Label lblPos; } } \ No newline at end of file diff --git a/ColorControl/RemoteControlForm.cs b/ColorControl/RemoteControlForm.cs index 5d97a2c..417264c 100644 --- a/ColorControl/RemoteControlForm.cs +++ b/ColorControl/RemoteControlForm.cs @@ -1,4 +1,5 @@ -using NWin32; +using LgTv; +using NWin32; using System; using System.Collections.Generic; using System.ComponentModel; @@ -15,6 +16,9 @@ namespace ColorControl { private LgService _lgService; private List _buttons; + private LgWebOsMouseService _mouseService; + private int _maxX, _maxY; + private int _posX, _posY; public RemoteControlForm(LgService lgService, List buttons) { @@ -22,6 +26,8 @@ namespace ColorControl _buttons = buttons; InitializeComponent(); + + pnlMouse.MouseWheel += new MouseEventHandler(pnlMouse_MouseWheel); } private void RemoteControlForm_Load(object sender, EventArgs e) @@ -43,9 +49,12 @@ namespace ColorControl private void ButtonClick(object sender, EventArgs e) { - var preset = (LgPreset)(sender as Button).Tag; + if (e is MouseEventArgs) + { + var preset = (LgPreset)(sender as Button).Tag; - _lgService.ApplyPreset(preset); + _lgService.ApplyPreset(preset); + } } private void btnClose_Click(object sender, EventArgs e) @@ -62,5 +71,170 @@ namespace ColorControl NativeMethods.SendMessageW(Handle, NativeConstants.WM_NCLBUTTONDOWN, intPtr, IntPtr.Zero); } } + + private void RemoteControlForm_KeyDown(object sender, KeyEventArgs e) + { + //var key = e.KeyCode; + //HandleKey(key); + } + + private void flowPanel_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + //HandleKey(e.KeyCode); + } + + private void HandleKey(Keys key) + { + if (!chkDirectMode.Checked) + { + return; + } + var cvt = new KeysConverter(); + var shortcut = (string)cvt.ConvertTo(key, typeof(string)); + + var preset = _buttons.FirstOrDefault(p => p.shortcut != null && p.shortcut.Equals(shortcut)); + if (preset != null) + { + _lgService.ApplyPreset(preset); + } + } + + private void RemoteControlForm_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + //HandleKey(e.KeyCode); + } + + private void RemoteControlForm_KeyUp(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.F1) + { + chkDirectMode.Checked = !chkDirectMode.Checked; + return; + } + + HandleKey(e.KeyCode); + } + + private void chkDirectMode_CheckedChanged(object sender, EventArgs e) + { + 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. + +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) + +Press F1 to stop Direct Mode." + ); + + if (_mouseService == null) + { + _lgService.GetMouseAsync().ContinueWith((task) => BeginInvoke(new Action>(SetMouseService), new[] { task })); + } + } + else + { + Cursor.Clip = Rectangle.Empty; + } + } + + private void SetMouseService(Task mouseServiceTask) + { + _mouseService = mouseServiceTask.Result; + + _maxX = 1920; + _maxY = 1080; + _posX = _maxX / 2; + _posY = _maxY / 2; + } + + private void flowPanel_MouseMove(object sender, MouseEventArgs e) + { + } + + private void pnlMouse_MouseEnter(object sender, EventArgs e) + { + if (chkDirectMode.Checked) + { + Cursor.Clip = RectangleToScreen(pnlMouse.Bounds); + } + } + + private void RemoteControlForm_FormClosed(object sender, FormClosedEventArgs e) + { + Cursor.Clip = Rectangle.Empty; + } + + private void pnlMouse_MouseUp(object sender, MouseEventArgs e) + { + if (chkDirectMode.Checked && _mouseService != null) + { + if (e.Button == MouseButtons.Left) + { + _mouseService.Click(); + } + else + { + HandleKey(Keys.Back); + } + } + } + + private void HandleMouse(MouseEventArgs e) + { + if (chkDirectMode.Checked && _mouseService != null) + { + var scaleX = (double)e.X / pnlMouse.Width; + var scaleY = (double)e.Y / pnlMouse.Height; + + var relX = scaleX * _maxX; + var relY = scaleY * _maxY; + + var dx = (int)relX - _posX; + var dy = (int)relY - _posY; + + _posX = Math.Min(_posX + dx, _maxX); + _posY = Math.Min(_posY + dy, _maxY); + + lblPos.Text = $"Pos: {_posX}, {_posY}"; + + //var cx = flowPanel.Width / 2; + //var cy = flowPanel.Height / 2; + + //var dx = (e.X - cx) / 10; + //var dy = (e.Y - cy) / 10; + + _mouseService.Move(dx, dy); + } + } + + private void pnlMouse_MouseMove(object sender, MouseEventArgs e) + { + HandleMouse(e); + } + + private void pnlMouse_MouseWheel(object sender, MouseEventArgs e) + { + if (chkDirectMode.Checked && _mouseService != null) + { + var dy = e.Delta * SystemInformation.MouseWheelScrollLines / 120; + + if (dy != 0) + { + _mouseService.Scroll(0, dy); + } + } + } } }