Skip to content

Commit cd1d623

Browse files
authored
Merge pull request darktable-org#409 from dterrahe/x_touch_mimic
example slider mimic script for x-touch mini
2 parents 612ecaf + 4726821 commit cd1d623

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed

examples/x-touch.lua

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
--[[
2+
This file is part of darktable,
3+
copyright (c) 2023 Diederik ter Rahe
4+
5+
darktable is free software: you can redistribute it and/or modify
6+
it under the terms of the GNU General Public License as published by
7+
the Free Software Foundation, either version 3 of the License, or
8+
(at your option) any later version.
9+
10+
darktable is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
GNU General Public License for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with darktable. If not, see <http://www.gnu.org/licenses/>.
17+
]]
18+
--[[
19+
X-Touch Mini flexible encoder shortcuts
20+
21+
This script will create virtual sliders that are mapped dynamically to
22+
the most relevant sliders for the currently focused processing module.
23+
Tailored modules are color zones, tone equalizer, color calibration and
24+
mask manager properties. The script can easily be amended for other
25+
devices or personal preferences. Virtual "toggle" buttons can be created
26+
as well, that dynamically change meaning depending on current status.
27+
28+
USAGE
29+
* require this script from your main lua file
30+
* restart darktable
31+
* create shortcuts for each of the encoders on the x-touch mini
32+
to a virtual slider under lua/x-touch
33+
or import the following shortcutsrc file in the shortcuts dialog/preferences tab:
34+
35+
None;midi:CC1=lua/x-touch/knob 1
36+
None;midi:CC2=lua/x-touch/knob 2
37+
None;midi:CC3=lua/x-touch/knob 3
38+
None;midi:CC4=lua/x-touch/knob 4
39+
None;midi:CC5=lua/x-touch/knob 5
40+
None;midi:CC6=lua/x-touch/knob 6
41+
None;midi:CC7=lua/x-touch/knob 7
42+
None;midi:CC8=lua/x-touch/knob 8
43+
midi:E0=global/modifiers
44+
midi:F0=global/modifiers;ctrl
45+
midi:F#0=global/modifiers;alt
46+
midi:G#-1=iop/blend/tools/show and edit mask elements
47+
midi:A-1=iop/colorzones;focus
48+
midi:A#-1=iop/toneequal;focus
49+
midi:B-1=iop/colorbalancergb;focus
50+
midi:C0=iop/channelmixerrgb;focus
51+
]]
52+
53+
local dt = require "darktable"
54+
local du = require "lib/dtutils"
55+
56+
du.check_min_api_version("9.1.0", "x-touch")
57+
58+
-- set up 8 mimic sliders with the same function
59+
for k = 1,8 do
60+
dt.gui.mimic("slider", "knob ".. k,
61+
function(action, element, effect, size)
62+
-- take the number from the mimic name
63+
local k = tonumber(action:sub(-1))
64+
65+
-- only operate in darkroom; return NAN otherwise
66+
if dt.gui.current_view() ~= dt.gui.views.darkroom then
67+
return 0/0
68+
end
69+
70+
local maskval = 0/0
71+
if k < 8 then
72+
-- first try if the mask slider at that position is active
73+
local s = { "opacity",
74+
"size",
75+
"feather",
76+
"hardness",
77+
"rotation",
78+
"curvature",
79+
"compression" }
80+
maskval = dt.gui.action("lib/masks/properties/" .. s[k],
81+
element, effect, size)
82+
end
83+
-- if a value different from NAN is returned, the slider was active
84+
if maskval == maskval then
85+
return maskval
86+
87+
-- try if colorzones module is focused; if so select element of graph
88+
elseif dt.gui.action("iop/colorzones", "focus") ~= 0 then
89+
which = "iop/colorzones/graph"
90+
local e = { "red",
91+
"orange",
92+
"yellow",
93+
"green",
94+
"aqua",
95+
"blue",
96+
"purple",
97+
"magenta" }
98+
element = e[k]
99+
100+
-- if the tone equalizer is focused,
101+
-- select one of the sliders in the "simple" tab
102+
elseif dt.gui.action("iop/toneequal", "focus") ~= 0 then
103+
which ="iop/toneequal/simple/"..(k-9).." EV"
104+
105+
-- if color calibration is focused,
106+
-- the last 4 knobs are sent there
107+
elseif dt.gui.action("iop/channelmixerrgb", "focus") ~= 0
108+
and k >= 5 then
109+
-- knob 5 selects the active tab; pressing it resets to CAT
110+
if k == 5 then
111+
which = "iop/channelmixerrgb/page"
112+
element = "CAT"
113+
-- since the tab action is not a slider,
114+
-- the effects need to be translated
115+
if effect == "up" then effect = "next"
116+
elseif effect == "down" then effect = "previous"
117+
else effect = "activate"
118+
end
119+
else
120+
-- knobs 6, 7 and 8 are for the three color sliders on each tab
121+
which = "iop/focus/sliders"
122+
local e = { "1st",
123+
"2nd",
124+
"3rd" }
125+
element = e[k - 5]
126+
end
127+
128+
-- the 4th knob is contrast;
129+
-- either colorbalance if it is focused, or filmic
130+
elseif dt.gui.action("iop/colorbalancergb", "focus") ~= 0
131+
and k == 4 then
132+
which = "iop/colorbalancergb/contrast"
133+
134+
-- in all other cases use a default selection
135+
else
136+
local s = { "iop/exposure/exposure",
137+
"iop/filmicrgb/white relative exposure",
138+
"iop/filmicrgb/black relative exposure",
139+
"iop/filmicrgb/contrast",
140+
"iop/crop/left",
141+
"iop/crop/right",
142+
"iop/crop/top",
143+
"iop/crop/bottom" }
144+
which = s[k]
145+
end
146+
147+
-- now pass the element/effect/size to the selected slider
148+
return dt.gui.action(which, element, effect, size)
149+
end)
150+
end

0 commit comments

Comments
 (0)