From c168dabded83c9546259fe82786d8633778760e2 Mon Sep 17 00:00:00 2001 From: mika-n Date: Tue, 23 Apr 2019 03:39:44 +0300 Subject: [PATCH 1/3] ActionLoadProfile: Support for automatically untriggered (=unloaded) profiles when a regular action keys are released. LoadProfile special action has a new "automatically unload when a regular trigger released" option. This is sort of like "shift modifier for the whole profile" functionality. --- DS4Windows/DS4Control/Mapping.cs | 71 +++++++++++++++++++++++++----- DS4Windows/DS4Control/ScpUtil.cs | 7 ++- DS4Windows/DS4Forms/SpecActions.cs | 2 +- 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/DS4Windows/DS4Control/Mapping.cs b/DS4Windows/DS4Control/Mapping.cs index a0198a0..c6e8fc8 100644 --- a/DS4Windows/DS4Control/Mapping.cs +++ b/DS4Windows/DS4Control/Mapping.cs @@ -1899,11 +1899,14 @@ namespace DS4Windows if (!actionDone[index].dev[device] && (!useTempProfile[device] || untriggeraction[device] == null || untriggeraction[device].typeID != SpecialAction.ActionTypeId.Profile) ) { actionDone[index].dev[device] = true; - // If Loadprofile special action doesn't have unload trigger then don't set untrigger status. This way the new loaded profile allows yet another loadProfile action key events) - if (action.uTrigger.Count > 0) + // If Loadprofile special action doesn't have untrigger keys or automatic untrigger option is not set then don't set untrigger status. This way the new loaded profile allows yet another loadProfile action key event. + if (action.uTrigger.Count > 0 || action.automaticUntrigger) { untriggeraction[device] = action; untriggerindex[device] = index; + + // If the existing profile is a temp profile then store its name, because automaticUntrigger needs to know where to go back (empty name goes back to default regular profile) + untriggeraction[device].prevProfileName = (useTempProfile[device] ? tempprofilename[device] : string.Empty); } //foreach (DS4Controls dc in action.trigger) for (int i = 0, arlen = action.trigger.Count; i < arlen; i++) @@ -1926,6 +1929,22 @@ namespace DS4Windows string prolog = Properties.Resources.UsingProfile.Replace("*number*", (device + 1).ToString()).Replace("*Profile name*", action.details); AppLogger.LogToGui(prolog, false); LoadTempProfile(device, action.details, true, ctrl); + + if (action.uTrigger.Count == 0 && !action.automaticUntrigger) + { + // If the new profile has any actions with the same action key (controls) than this action (which doesn't have untrigger keys) then set status of those actions to wait for the release of the existing action key. + List profileActionsNext = getProfileActions(device); + for (int actionIndexNext = 0, profileListLenNext = profileActionsNext.Count; actionIndexNext < profileListLenNext; actionIndexNext++) + { + string actionnameNext = profileActionsNext[actionIndexNext]; + SpecialAction actionNext = GetProfileAction(device, actionnameNext); + int indexNext = GetProfileActionIndexOf(device, actionnameNext); + + if (actionNext.controls == action.controls) + actionDone[indexNext].dev[device] = true; + } + } + return; } } @@ -2273,15 +2292,37 @@ namespace DS4Windows { SpecialAction action = untriggeraction[device]; int index = untriggerindex[device]; - bool utriggeractivated = true; - //foreach (DS4Controls dc in action.uTrigger) - for (int i = 0, uTrigLen = action.uTrigger.Count; i < uTrigLen; i++) + bool utriggeractivated; + + if (!action.automaticUntrigger) { - DS4Controls dc = action.uTrigger[i]; - if (!getBoolSpecialActionMapping(device, dc, cState, eState, tp, fieldMapping)) + // Untrigger keys defined and auto-untrigger (=unload) profile option is NOT set. Unload a temporary profile only when specified untrigger keys have been triggered. + utriggeractivated = true; + + //foreach (DS4Controls dc in action.uTrigger) + for (int i = 0, uTrigLen = action.uTrigger.Count; i < uTrigLen; i++) { - utriggeractivated = false; - break; + DS4Controls dc = action.uTrigger[i]; + if (!getBoolSpecialActionMapping(device, dc, cState, eState, tp, fieldMapping)) + { + utriggeractivated = false; + break; + } + } + } + else + { + // Untrigger as soon any of the defined regular trigger keys have been released. + utriggeractivated = false; + + for (int i = 0, trigLen = action.trigger.Count; i < trigLen; i++) + { + DS4Controls dc = action.trigger[i]; + if (!getBoolSpecialActionMapping(device, dc, cState, eState, tp, fieldMapping)) + { + utriggeractivated = true; + break; + } } } @@ -2311,10 +2352,16 @@ namespace DS4Windows } } - untriggeraction[device] = null; - string prolog = Properties.Resources.UsingProfile.Replace("*number*", (device + 1).ToString()).Replace("*Profile name*", ProfilePath[device]); + string profileName = untriggeraction[device].prevProfileName; + string prolog = Properties.Resources.UsingProfile.Replace("*number*", (device + 1).ToString()).Replace("*Profile name*", (profileName == string.Empty ? ProfilePath[device] : profileName)); AppLogger.LogToGui(prolog, false); - LoadProfile(device, false, ctrl); + + untriggeraction[device] = null; + + if (profileName == string.Empty) + LoadProfile(device, false, ctrl); // Previous profile was a regular default profile of a controller + else + LoadTempProfile(device, profileName, true, ctrl); // Previous profile was a temporary profile, so re-load it as a temp profile } } } diff --git a/DS4Windows/DS4Control/ScpUtil.cs b/DS4Windows/DS4Control/ScpUtil.cs index f4b4176..4ff4663 100644 --- a/DS4Windows/DS4Control/ScpUtil.cs +++ b/DS4Windows/DS4Control/ScpUtil.cs @@ -4072,6 +4072,8 @@ namespace DS4Windows public DateTime pastTime; public DateTime firstTap; public DateTime TimeofEnd; + public bool automaticUntrigger = false; + public string prevProfileName; // Name of the previous profile where automaticUntrigger would jump back to (could be regular or temporary profile. Empty name is the same as regular profile) public SpecialAction(string name, string controls, string type, string details, double delay = 0, string extras = "") { @@ -4181,7 +4183,10 @@ namespace DS4Windows this.ucontrols = extras; string[] uctrls = extras.Split('/'); foreach (string s in uctrls) - uTrigger.Add(getDS4ControlsByName(s)); + { + if (s == "AutomaticUntrigger") this.automaticUntrigger = true; + else uTrigger.Add(getDS4ControlsByName(s)); + } } } diff --git a/DS4Windows/DS4Forms/SpecActions.cs b/DS4Windows/DS4Forms/SpecActions.cs index c9ce18d..cf6f338 100644 --- a/DS4Windows/DS4Forms/SpecActions.cs +++ b/DS4Windows/DS4Forms/SpecActions.cs @@ -270,7 +270,7 @@ namespace DS4Windows actRe = true; if (!string.IsNullOrEmpty(oldprofilename) && oldprofilename != tBName.Text) Global.RemoveAction(oldprofilename); - Global.SaveAction(tBName.Text, String.Join("/", controls), cBActions.SelectedIndex, cBProfiles.Text, edit, String.Join("/", ucontrols)); + Global.SaveAction(tBName.Text, String.Join("/", controls), cBActions.SelectedIndex, cBProfiles.Text, edit, String.Join("/", ucontrols) + (/* TODO: Is automaticUntrigger set */ true ? (ucontrols.Count > 0 ? "/" : "") + "AutomaticUntrigger" : "") ); } else btnSetUTriggerProfile.ForeColor = Color.Red; From 456145cf8eb8d77cdba143a6b48833fd99ecf3fa Mon Sep 17 00:00:00 2001 From: mika-n Date: Tue, 23 Apr 2019 12:32:12 +0300 Subject: [PATCH 2/3] Fixed a bug described in #664 issue where gyro mouse doesn't get correct properties (for example toggle option) right after Startup or Hotplug LoadProfile calls. The mouse object was created after LoadProfile function even when LoadProfile function tries to set few properties of that mouse object. --- DS4Windows/DS4Control/ControlService.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/DS4Windows/DS4Control/ControlService.cs b/DS4Windows/DS4Control/ControlService.cs index fd5f350..b541509 100644 --- a/DS4Windows/DS4Control/ControlService.cs +++ b/DS4Windows/DS4Control/ControlService.cs @@ -403,6 +403,9 @@ namespace DS4Windows device.SyncChange += this.On_SyncChange; device.SyncChange += DS4Devices.UpdateSerial; device.SerialChange += this.On_SerialChange; + + touchPad[i] = new Mouse(i, device); + if (!useTempProfile[i]) { if (device.isValidSerial() && containsLinkedProfile(device.getMacAddress())) @@ -417,7 +420,6 @@ namespace DS4Windows LoadProfile(i, false, this, false, false); } - touchPad[i] = new Mouse(i, device); device.LightBarColor = getMainColor(i); if (!getDInputOnly(i) && device.isSynced()) @@ -641,6 +643,9 @@ namespace DS4Windows device.SyncChange += this.On_SyncChange; device.SyncChange += DS4Devices.UpdateSerial; device.SerialChange += this.On_SerialChange; + + touchPad[Index] = new Mouse(Index, device); + if (!useTempProfile[Index]) { if (device.isValidSerial() && containsLinkedProfile(device.getMacAddress())) @@ -655,7 +660,6 @@ namespace DS4Windows LoadProfile(Index, false, this, false, false); } - touchPad[Index] = new Mouse(Index, device); device.LightBarColor = getMainColor(Index); int tempIdx = Index; From b09e5c277e63b84ee18b274941688b339e81fc54 Mon Sep 17 00:00:00 2001 From: mika-n Date: Tue, 23 Apr 2019 14:54:04 +0300 Subject: [PATCH 3/3] Added "Unload on regular trigger release" checkbox option to "SpecialAction.Profiles" edit panel. This option can be used to automatically unload a profile (ie. goes back to previous profile) when a regular trigger key is released. --- DS4Windows/DS4Forms/SpecActions.Designer.cs | 9 +++++ DS4Windows/DS4Forms/SpecActions.cs | 3 +- DS4Windows/DS4Forms/SpecActions.resx | 43 ++++++++++++++++++++- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/DS4Windows/DS4Forms/SpecActions.Designer.cs b/DS4Windows/DS4Forms/SpecActions.Designer.cs index 3283401..16d0036 100644 --- a/DS4Windows/DS4Forms/SpecActions.Designer.cs +++ b/DS4Windows/DS4Forms/SpecActions.Designer.cs @@ -86,6 +86,7 @@ this.lbDTapDVR = new System.Windows.Forms.Label(); this.lbHoldDVR = new System.Windows.Forms.Label(); this.lbTapDVR = new System.Windows.Forms.Label(); + this.cbProfileAutoUntrigger = new System.Windows.Forms.CheckBox(); ((System.ComponentModel.ISupportInitialize)(this.pBProgram)).BeginInit(); this.pnlProgram.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.nUDProg)).BeginInit(); @@ -383,6 +384,7 @@ // // pnlProfile // + this.pnlProfile.Controls.Add(this.cbProfileAutoUntrigger); this.pnlProfile.Controls.Add(this.lbUnloadTipProfile); this.pnlProfile.Controls.Add(this.cBProfiles); this.pnlProfile.Controls.Add(this.btnSetUTriggerProfile); @@ -596,6 +598,12 @@ resources.ApplyResources(this.lbTapDVR, "lbTapDVR"); this.lbTapDVR.Name = "lbTapDVR"; // + // cbProfileAutoUntrigger + // + resources.ApplyResources(this.cbProfileAutoUntrigger, "cbProfileAutoUntrigger"); + this.cbProfileAutoUntrigger.Name = "cbProfileAutoUntrigger"; + this.cbProfileAutoUntrigger.UseVisualStyleBackColor = true; + // // SpecActions // resources.ApplyResources(this, "$this"); @@ -698,5 +706,6 @@ public System.Windows.Forms.Button btnDTapT; public System.Windows.Forms.Button btnHoldT; public System.Windows.Forms.Button btnSTapT; + private System.Windows.Forms.CheckBox cbProfileAutoUntrigger; } } \ No newline at end of file diff --git a/DS4Windows/DS4Forms/SpecActions.cs b/DS4Windows/DS4Forms/SpecActions.cs index cf6f338..69c4b57 100644 --- a/DS4Windows/DS4Forms/SpecActions.cs +++ b/DS4Windows/DS4Forms/SpecActions.cs @@ -102,6 +102,7 @@ namespace DS4Windows break; } } + cbProfileAutoUntrigger.Checked = act.automaticUntrigger; break; case "Key": cBActions.SelectedIndex = 4; @@ -270,7 +271,7 @@ namespace DS4Windows actRe = true; if (!string.IsNullOrEmpty(oldprofilename) && oldprofilename != tBName.Text) Global.RemoveAction(oldprofilename); - Global.SaveAction(tBName.Text, String.Join("/", controls), cBActions.SelectedIndex, cBProfiles.Text, edit, String.Join("/", ucontrols) + (/* TODO: Is automaticUntrigger set */ true ? (ucontrols.Count > 0 ? "/" : "") + "AutomaticUntrigger" : "") ); + Global.SaveAction(tBName.Text, String.Join("/", controls), cBActions.SelectedIndex, cBProfiles.Text, edit, String.Join("/", ucontrols) + (cbProfileAutoUntrigger.Checked ? (ucontrols.Count > 0 ? "/" : "") + "AutomaticUntrigger" : "") ); } else btnSetUTriggerProfile.ForeColor = Color.Red; diff --git a/DS4Windows/DS4Forms/SpecActions.resx b/DS4Windows/DS4Forms/SpecActions.resx index 13b7a3a..66c2e08 100644 --- a/DS4Windows/DS4Forms/SpecActions.resx +++ b/DS4Windows/DS4Forms/SpecActions.resx @@ -2116,7 +2116,7 @@ NoControl - 0, 55 + 0, 95 100, 23 @@ -2140,7 +2140,7 @@ 206, 58 - 161, 94 + 161, 121 262 @@ -2160,6 +2160,45 @@ 11 + + cbProfileAutoUntrigger + + + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + pnlProfile + + + 0 + + + True + + + 0, 61 + + + 144, 17 + + + 260 + + + Unload on trigger release + + + cbProfileAutoUntrigger + + + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + pnlProfile + + + 0 + 56, 3