From 8e412c3eb32990418baf990bd963328d08035017 Mon Sep 17 00:00:00 2001 From: dterrahe Date: Sat, 25 Mar 2023 10:59:19 -0400 Subject: [PATCH 1/5] example slider mimic script for x-touch mini --- examples/x-touch.lua | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 examples/x-touch.lua diff --git a/examples/x-touch.lua b/examples/x-touch.lua new file mode 100644 index 0000000..6adfa4c --- /dev/null +++ b/examples/x-touch.lua @@ -0,0 +1,40 @@ +local dt = require "darktable" +local du = require "lib/dtutils" + +du.check_min_api_version("9.1.0", "x-touch") + +function knob(action, element, effect, size) + k = tonumber(action:sub(-1)) + + if dt.gui.action("iop/blend/tools/show and edit mask elements") ~= 0 then + local s = { "opacity", "size", "feather", "hardness","rotation","curvature","compression" } + which = "lib/masks/properties/" .. s[k] + + elseif dt.gui.action("iop/colorzones", "focus") ~= 0 then + local e = { "red", "orange", "yellow", "green", "aqua", "blue", "purple", "magenta" } + element = e[k] + which = "iop/colorzones/graph" + + elseif dt.gui.action("iop/toneequal", "focus") ~= 0 then + which ="iop/toneequal/simple/"..(k-9).." EV" + + elseif k == 4 and dt.gui.action("iop/colorbalancergb", "focus") ~= 0 then + which = "iop/colorbalancergb/contrast" + + else + local s = { "iop/exposure/exposure", + "iop/filmicrgb/white relative exposure", + "iop/filmicrgb/black relative exposure", + "iop/filmicrgb/contrast", + "iop/crop/left", + "iop/crop/right", + "iop/crop/top", + "iop/crop/bottom" } + which = s[k] + end + return dt.gui.action(which, element, effect, size) +end + +for k = 1,8 do + dt.gui.mimic("slider", "knob ".. k, knob) +end From 6bf3706455ba1104fbc3136b34804124491f3764 Mon Sep 17 00:00:00 2001 From: dterrahe Date: Sat, 25 Mar 2023 18:14:19 +0000 Subject: [PATCH 2/5] add x-touch color calibration customisation --- examples/x-touch.lua | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/examples/x-touch.lua b/examples/x-touch.lua index 6adfa4c..0aa2e6f 100644 --- a/examples/x-touch.lua +++ b/examples/x-touch.lua @@ -1,7 +1,7 @@ local dt = require "darktable" local du = require "lib/dtutils" -du.check_min_api_version("9.1.0", "x-touch") +du.check_min_api_version("9.1.0", "x-touch") function knob(action, element, effect, size) k = tonumber(action:sub(-1)) @@ -11,16 +11,30 @@ function knob(action, element, effect, size) which = "lib/masks/properties/" .. s[k] elseif dt.gui.action("iop/colorzones", "focus") ~= 0 then + which = "iop/colorzones/graph" local e = { "red", "orange", "yellow", "green", "aqua", "blue", "purple", "magenta" } element = e[k] - which = "iop/colorzones/graph" elseif dt.gui.action("iop/toneequal", "focus") ~= 0 then which ="iop/toneequal/simple/"..(k-9).." EV" - elseif k == 4 and dt.gui.action("iop/colorbalancergb", "focus") ~= 0 then + elseif dt.gui.action("iop/colorbalancergb", "focus") ~= 0 and k == 4 then which = "iop/colorbalancergb/contrast" + elseif dt.gui.action("iop/channelmixerrgb", "focus") ~= 0 and k >= 5 then + if k == 5 then + which = "iop/channelmixerrgb/page" + element = "CAT" + if effect == "up" then effect = "next" + elseif effect == "down" then effect = "previous" + else effect = "activate" + end + else + which = "iop/focus/sliders" + local e = { "1st", "2nd", "3rd" } + element = e[k - 5] + end + else local s = { "iop/exposure/exposure", "iop/filmicrgb/white relative exposure", @@ -32,6 +46,7 @@ function knob(action, element, effect, size) "iop/crop/bottom" } which = s[k] end + return dt.gui.action(which, element, effect, size) end From 3889742e0647fa6d5f550ac53c6f94521f0492e1 Mon Sep 17 00:00:00 2001 From: dterrahe Date: Sat, 25 Mar 2023 18:49:55 +0000 Subject: [PATCH 3/5] add x-touch mini script documentation --- examples/x-touch.lua | 52 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/examples/x-touch.lua b/examples/x-touch.lua index 0aa2e6f..0cb31c1 100644 --- a/examples/x-touch.lua +++ b/examples/x-touch.lua @@ -1,3 +1,55 @@ +--[[ + This file is part of darktable, + copyright (c) 2023 Diederik ter Rahe + + darktable is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + darktable is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with darktable. If not, see . +]] +--[[ +X-Touch Mini flexible encoder shortcuts + +This script will create virtual sliders that are mapped dynamically to +the most relevant sliders for the currently focused processing module. +Tailored modules are color zones, tone equalizer, color calibration and +mask manager properties. The script can easily be amended for other +devices or personal preferences. Virtual "toggle" buttons can be created +as well, that dynamically change meaning depending on current status. + +USAGE +* require this script from your main lua file +* restart darktable +* create shortcuts for each of the encoders on the x-touch mini + to a virtual slider under lua/x-touch + or import the following shortcutsrc file in the shortcuts dialog/preferences tab: + +None;midi:CC1=lua/x-touch/knob 1 +None;midi:CC2=lua/x-touch/knob 2 +None;midi:CC3=lua/x-touch/knob 3 +None;midi:CC4=lua/x-touch/knob 4 +None;midi:CC5=lua/x-touch/knob 5 +None;midi:CC6=lua/x-touch/knob 6 +None;midi:CC7=lua/x-touch/knob 7 +None;midi:CC8=lua/x-touch/knob 8 +midi:E0=global/modifiers +midi:F0=global/modifiers;ctrl +midi:F#0=global/modifiers;alt +midi:G#-1=iop/blend/tools/show and edit mask elements +midi:A-1=iop/colorzones;focus +midi:A#-1=iop/toneequal;focus +midi:B-1=iop/colorbalancergb;focus +midi:C0=iop/channelmixerrgb;focus +]] + local dt = require "darktable" local du = require "lib/dtutils" From 7ac37ddc1a2abfc94c9c6d7091e8e5c61b32f76f Mon Sep 17 00:00:00 2001 From: dterrahe Date: Wed, 3 May 2023 23:43:01 +0100 Subject: [PATCH 4/5] Probe individual mask sliders --- examples/x-touch.lua | 142 +++++++++++++++++++++++++++---------------- 1 file changed, 91 insertions(+), 51 deletions(-) diff --git a/examples/x-touch.lua b/examples/x-touch.lua index 0cb31c1..c1020fa 100644 --- a/examples/x-touch.lua +++ b/examples/x-touch.lua @@ -18,7 +18,7 @@ --[[ X-Touch Mini flexible encoder shortcuts -This script will create virtual sliders that are mapped dynamically to +This script will create virtual sliders that are mapped dynamically to the most relevant sliders for the currently focused processing module. Tailored modules are color zones, tone equalizer, color calibration and mask manager properties. The script can easily be amended for other @@ -28,8 +28,8 @@ as well, that dynamically change meaning depending on current status. USAGE * require this script from your main lua file * restart darktable -* create shortcuts for each of the encoders on the x-touch mini - to a virtual slider under lua/x-touch +* create shortcuts for each of the encoders on the x-touch mini + to a virtual slider under lua/x-touch or import the following shortcutsrc file in the shortcuts dialog/preferences tab: None;midi:CC1=lua/x-touch/knob 1 @@ -55,53 +55,93 @@ local du = require "lib/dtutils" du.check_min_api_version("9.1.0", "x-touch") -function knob(action, element, effect, size) - k = tonumber(action:sub(-1)) - - if dt.gui.action("iop/blend/tools/show and edit mask elements") ~= 0 then - local s = { "opacity", "size", "feather", "hardness","rotation","curvature","compression" } - which = "lib/masks/properties/" .. s[k] - - elseif dt.gui.action("iop/colorzones", "focus") ~= 0 then - which = "iop/colorzones/graph" - local e = { "red", "orange", "yellow", "green", "aqua", "blue", "purple", "magenta" } - element = e[k] - - elseif dt.gui.action("iop/toneequal", "focus") ~= 0 then - which ="iop/toneequal/simple/"..(k-9).." EV" - - elseif dt.gui.action("iop/colorbalancergb", "focus") ~= 0 and k == 4 then - which = "iop/colorbalancergb/contrast" - - elseif dt.gui.action("iop/channelmixerrgb", "focus") ~= 0 and k >= 5 then - if k == 5 then - which = "iop/channelmixerrgb/page" - element = "CAT" - if effect == "up" then effect = "next" - elseif effect == "down" then effect = "previous" - else effect = "activate" - end - else - which = "iop/focus/sliders" - local e = { "1st", "2nd", "3rd" } - element = e[k - 5] - end - - else - local s = { "iop/exposure/exposure", - "iop/filmicrgb/white relative exposure", - "iop/filmicrgb/black relative exposure", - "iop/filmicrgb/contrast", - "iop/crop/left", - "iop/crop/right", - "iop/crop/top", - "iop/crop/bottom" } - which = s[k] - end - - return dt.gui.action(which, element, effect, size) -end - +-- set up 8 mimic sliders with the same function for k = 1,8 do - dt.gui.mimic("slider", "knob ".. k, knob) + dt.gui.mimic("slider", "knob ".. k, + function(action, element, effect, size) + -- take the number from the mimic name + local k = tonumber(action:sub(-1)) + + -- only operate in darkroom; return NAN otherwise + if dt.gui.current_view() ~= dt.gui.views.darkroom then + return 0/0 + end + + -- first try if the mask slider at that position is active + local s = { "opacity", + "size", + "feather", + "hardness", + "rotation", + "curvature", + "compression" } + local maskval = dt.gui.action("lib/masks/properties/" .. s[k], + element, effect, size) + -- if a value different from NAN is returned, the slider was active + if maskval == maskval then + return maskval + + -- try if colorzones module is focused; if so select element of graph + elseif dt.gui.action("iop/colorzones", "focus") ~= 0 then + which = "iop/colorzones/graph" + local e = { "red", + "orange", + "yellow", + "green", + "aqua", + "blue", + "purple", + "magenta" } + element = e[k] + + -- if the tone equalizer is focused, + -- select one of the sliders in the "simple" tab + elseif dt.gui.action("iop/toneequal", "focus") ~= 0 then + which ="iop/toneequal/simple/"..(k-9).." EV" + + -- if color calibration is focused, + -- the last 4 knobs are sent there + elseif dt.gui.action("iop/channelmixerrgb", "focus") ~= 0 + and k >= 5 then + -- knob 5 selects the active tab; pressing it resets to CAT + if k == 5 then + which = "iop/channelmixerrgb/page" + element = "CAT" + -- since the tab action is not a slider, + -- the effects need to be translated + if effect == "up" then effect = "next" + elseif effect == "down" then effect = "previous" + else effect = "activate" + end + else + -- knobs 6, 7 and 8 are for the three color sliders on each tab + which = "iop/focus/sliders" + local e = { "1st", + "2nd", + "3rd" } + element = e[k - 5] + end + + -- the 4th knob is contrast; + -- either colorbalance if it is focused, or filmic + elseif dt.gui.action("iop/colorbalancergb", "focus") ~= 0 + and k == 4 then + which = "iop/colorbalancergb/contrast" + + -- in all other cases use a default selection + else + local s = { "iop/exposure/exposure", + "iop/filmicrgb/white relative exposure", + "iop/filmicrgb/black relative exposure", + "iop/filmicrgb/contrast", + "iop/crop/left", + "iop/crop/right", + "iop/crop/top", + "iop/crop/bottom" } + which = s[k] + end + + -- now pass the element/effect/size to the selected slider + return dt.gui.action(which, element, effect, size) + end) end From 4726821e7def774c398579b73c85fe0f02f66c3f Mon Sep 17 00:00:00 2001 From: dterrahe Date: Fri, 5 May 2023 23:19:00 +0100 Subject: [PATCH 5/5] Fix 8th knob --- examples/x-touch.lua | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/x-touch.lua b/examples/x-touch.lua index c1020fa..7c5b998 100644 --- a/examples/x-touch.lua +++ b/examples/x-touch.lua @@ -67,16 +67,19 @@ for k = 1,8 do return 0/0 end - -- first try if the mask slider at that position is active - local s = { "opacity", - "size", - "feather", - "hardness", - "rotation", - "curvature", - "compression" } - local maskval = dt.gui.action("lib/masks/properties/" .. s[k], - element, effect, size) + local maskval = 0/0 + if k < 8 then + -- first try if the mask slider at that position is active + local s = { "opacity", + "size", + "feather", + "hardness", + "rotation", + "curvature", + "compression" } + maskval = dt.gui.action("lib/masks/properties/" .. s[k], + element, effect, size) + end -- if a value different from NAN is returned, the slider was active if maskval == maskval then return maskval