Skip to content

Commit bbf75a7

Browse files
authored
Merge pull request #1365 from TymurGubayev/gui/tooltips/1
Create gui/spectate
2 parents 1e288db + 46689c2 commit bbf75a7

File tree

2 files changed

+228
-3
lines changed

2 files changed

+228
-3
lines changed

docs/gui/spectate.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ gui/spectate
88
This is an in-game configuration interface for `spectate`, which automatically
99
sets the camera to follow interesting units.
1010

11+
You can configure the overlay tooltip settings as well as the follow mode
12+
settings.
13+
1114
Usage
1215
-----
1316

gui/spectate.lua

Lines changed: 225 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,242 @@
11
local gui = require('gui')
2+
local overlay = require('plugins.overlay')
23
local spectate = require('plugins.spectate')
4+
local textures = require('gui.textures')
5+
local utils = require('utils')
36
local widgets = require('gui.widgets')
47

8+
local OVERLAY_NAME = 'spectate.tooltip'
9+
10+
--------------------------------------------------------------------------------
11+
--- ToggleLabel
12+
13+
-- pens are the same as gui/control-panel.lua
14+
local function get_icon_pens()
15+
local enabled_pen_left = dfhack.pen.parse{fg=COLOR_CYAN,
16+
tile=curry(textures.tp_control_panel, 1), ch=string.byte('[')}
17+
local enabled_pen_center = dfhack.pen.parse{fg=COLOR_LIGHTGREEN,
18+
tile=curry(textures.tp_control_panel, 2) or nil, ch=251} -- check
19+
local enabled_pen_right = dfhack.pen.parse{fg=COLOR_CYAN,
20+
tile=curry(textures.tp_control_panel, 3) or nil, ch=string.byte(']')}
21+
local disabled_pen_left = dfhack.pen.parse{fg=COLOR_CYAN,
22+
tile=curry(textures.tp_control_panel, 4) or nil, ch=string.byte('[')}
23+
local disabled_pen_center = dfhack.pen.parse{fg=COLOR_RED,
24+
tile=curry(textures.tp_control_panel, 5) or nil, ch=string.byte('x')}
25+
local disabled_pen_right = dfhack.pen.parse{fg=COLOR_CYAN,
26+
tile=curry(textures.tp_control_panel, 6) or nil, ch=string.byte(']')}
27+
return enabled_pen_left, enabled_pen_center, enabled_pen_right,
28+
disabled_pen_left, disabled_pen_center, disabled_pen_right
29+
end
30+
local ENABLED_PEN_LEFT, ENABLED_PEN_CENTER, ENABLED_PEN_RIGHT,
31+
DISABLED_PEN_LEFT, DISABLED_PEN_CENTER, DISABLED_PEN_RIGHT = get_icon_pens()
32+
33+
ToggleLabel = defclass(ToggleLabel, widgets.ToggleHotkeyLabel)
34+
35+
function ToggleLabel:init()
36+
local text = self.text
37+
-- the very last token is the On/Off text -- we'll repurpose it as an indicator
38+
text[#text] = { tile = function() return self:getOptionValue() and ENABLED_PEN_LEFT or DISABLED_PEN_LEFT end }
39+
text[#text + 1] = { tile = function() return self:getOptionValue() and ENABLED_PEN_CENTER or DISABLED_PEN_CENTER end }
40+
text[#text + 1] = { tile = function() return self:getOptionValue() and ENABLED_PEN_RIGHT or DISABLED_PEN_RIGHT end }
41+
self:setText(text)
42+
end
43+
44+
--------------------------------------------------------------------------------
45+
--- Spectate config window
546
Spectate = defclass(Spectate, widgets.Window)
647
Spectate.ATTRS {
748
frame_title='Spectate',
8-
frame={w=50, h=45},
9-
resizable=true,
10-
resize_min={w=50, h=20},
49+
frame={l=5, t=5, w=36, h=39},
1150
}
1251

52+
local function create_toggle_button(frame, cfg_elem, hotkey, label, cfg_elem_key)
53+
return ToggleLabel{
54+
frame=frame,
55+
initial_option=spectate.get_config_elem(cfg_elem, cfg_elem_key),
56+
on_change=function(val) dfhack.run_command('spectate', 'set', cfg_elem, tostring(val)) end,
57+
key=hotkey,
58+
label=label,
59+
}
60+
end
61+
62+
local function create_numeric_edit_field(frame, cfg_elem, hotkey, label)
63+
local editOnSubmit
64+
local ef = widgets.EditField{
65+
frame=frame,
66+
label_text = label,
67+
text = tostring(spectate.get_config_elem(cfg_elem)),
68+
modal = true,
69+
key = hotkey,
70+
on_char = function(ch) return ch:match('%d') end,
71+
on_submit = function(text) editOnSubmit(text) end,
72+
}
73+
editOnSubmit = function(text)
74+
if text == '' then
75+
ef:setText(tostring(spectate.get_config_elem(cfg_elem)))
76+
else
77+
dfhack.run_command('spectate', 'set', cfg_elem, text)
78+
end
79+
end
80+
81+
return ef
82+
end
83+
84+
local function create_row_toggle_buttons(keyFollow, keyHover, colFollow, colHover, cfg_elem_key)
85+
local tlFollow = create_toggle_button({l=colFollow+2}, keyFollow, nil, nil, cfg_elem_key)
86+
local tlHover = create_toggle_button({l=colHover+1}, keyHover, nil, nil, cfg_elem_key)
87+
return tlFollow, tlHover
88+
end
89+
90+
local function create_row(frame, label, hotkey, suffix, colFollow, colHover)
91+
suffix = suffix or ''
92+
if suffix ~= '' then suffix = '-'..suffix end
93+
94+
local keyFollow = 'tooltip-follow'..suffix
95+
local keyHover = 'tooltip-hover'..suffix
96+
97+
local tlFollow, tlHover = create_row_toggle_buttons(keyFollow, keyHover, colFollow, colHover)
98+
99+
return widgets.Panel{
100+
frame=utils.assign({h=1}, frame),
101+
subviews={
102+
widgets.HotkeyLabel{
103+
frame={l=0,w=1},
104+
key='CUSTOM_' .. hotkey,
105+
key_sep='',
106+
on_activate=function() tlFollow:cycle() end,
107+
},
108+
widgets.HotkeyLabel{
109+
frame={l=1,w=1},
110+
key='CUSTOM_SHIFT_' .. hotkey,
111+
key_sep='',
112+
on_activate=function() tlHover:cycle() end,
113+
},
114+
widgets.Label{
115+
frame={l=2},
116+
text = ': ' .. label,
117+
},
118+
tlFollow,
119+
tlHover,
120+
},
121+
}
122+
end
123+
124+
local function make_choice(text, tlFollow, tlHover)
125+
return {
126+
text=text,
127+
data={tlFollow=tlFollow, tlHover=tlHover},
128+
}
129+
end
130+
131+
-- individual stress levels
132+
-- a list on the left to select one, individual buttons in two columns to be able to click on them
133+
local function create_stress_list(frame, colFollow, colHover)
134+
local levelsKey = 'tooltip-stress-levels'
135+
local stressFollowKey = 'tooltip-follow-stress-levels'
136+
local stressHoverKey = 'tooltip-hover-stress-levels'
137+
138+
local choices, subviews = {}, {}
139+
for idx=0,6 do
140+
local cfgElemKey = tostring(idx)
141+
local tlFollow, tlHover = create_row_toggle_buttons(stressFollowKey, stressHoverKey, colFollow, colHover, cfgElemKey)
142+
table.insert(subviews, widgets.Panel{
143+
frame={t=idx, h=1},
144+
subviews={
145+
tlFollow,
146+
tlHover,
147+
}
148+
})
149+
150+
local elem = spectate.get_config_elem(levelsKey, cfgElemKey)
151+
table.insert(choices, make_choice({{text=elem.text, pen=elem.pen}, ' ', elem.name}, tlFollow, tlHover))
152+
end
153+
154+
table.insert(subviews, widgets.List{
155+
frame={l=2},
156+
on_submit=function(_, choice) choice.data.tlFollow:cycle() end,
157+
on_submit2=function(_, choice) choice.data.tlHover:cycle() end,
158+
choices=choices,
159+
})
160+
161+
return widgets.Panel{
162+
frame=frame,
163+
subviews=subviews,
164+
}
165+
end
166+
167+
local function rpad(s, i)
168+
return string.format("%-"..i.."s", s)
169+
end
170+
13171
function Spectate:init()
172+
local lWidth = 21
173+
local colFollow, colHover = 15, 25
174+
14175
self:addviews{
176+
widgets.Label{
177+
frame={t=0, l=0},
178+
text='See help for option details:',
179+
},
180+
widgets.HelpButton{
181+
frame={t=0, r=0},
182+
command = 'spectate',
183+
},
184+
ToggleLabel{
185+
frame={t=2},
186+
view_id='spectate_mode',
187+
initial_option=spectate.isEnabled(),
188+
on_change=function(val) dfhack.run_command(val and 'enable' or 'disable', 'spectate') end,
189+
key='CUSTOM_ALT_E',
190+
label='Spectate mode ',
191+
},
192+
create_numeric_edit_field({t=4}, 'follow-seconds', 'CUSTOM_ALT_F', 'Switch target (sec): '),
193+
create_toggle_button({t=6}, 'auto-unpause', 'CUSTOM_ALT_U', rpad('Auto unpause', lWidth)),
194+
create_toggle_button({t=7}, 'cinematic-action', 'CUSTOM_ALT_C', rpad('Cinematic action', lWidth)),
195+
create_toggle_button({t=8}, 'include-animals', 'CUSTOM_ALT_A', rpad('Include animals', lWidth)),
196+
create_toggle_button({t=9}, 'include-hostiles', 'CUSTOM_ALT_H', rpad('Include hostiles', lWidth)),
197+
create_toggle_button({t=10}, 'include-visitors', 'CUSTOM_ALT_V', rpad('Include visitors', lWidth)),
198+
create_toggle_button({t=11}, 'include-wildlife', 'CUSTOM_ALT_W', rpad('Include wildlife', lWidth)),
199+
create_toggle_button({t=12}, 'prefer-conflict', 'CUSTOM_ALT_B', rpad('Prefer conflict', lWidth)),
200+
create_toggle_button({t=13}, 'prefer-new-arrivals', 'CUSTOM_ALT_N', rpad('Prefer new arrivals', lWidth)),
201+
widgets.Divider{
202+
frame={t=15, h=1},
203+
frame_style=gui.FRAME_THIN,
204+
frame_style_l=false,
205+
frame_style_r=false,
206+
},
207+
widgets.Label{
208+
frame={t=17, l=0},
209+
text="Tooltips:"
210+
},
211+
ToggleLabel{
212+
frame={t=17, l=12},
213+
initial_option=overlay.isOverlayEnabled(OVERLAY_NAME),
214+
on_change=function(val) dfhack.run_command('overlay', val and 'enable' or 'disable', OVERLAY_NAME) end,
215+
key='CUSTOM_ALT_O',
216+
label="Overlay ",
217+
},
218+
widgets.Label{
219+
frame={t=19, l=colFollow},
220+
text='Follow',
221+
},
222+
widgets.Label{
223+
frame={t=19, l=colHover},
224+
text='Hover',
225+
},
226+
create_row({t=21}, 'Enabled', 'E', '', colFollow, colHover),
227+
create_numeric_edit_field({t=23}, 'tooltip-follow-blink-milliseconds', 'CUSTOM_B', 'Blink period (ms): '),
228+
create_row({t=25}, 'Job', 'J', 'job', colFollow, colHover),
229+
create_row({t=26}, 'Name', 'N', 'name', colFollow, colHover),
230+
create_row({t=27}, 'Stress', 'S', 'stress', colFollow, colHover),
231+
create_stress_list({t=28}, colFollow, colHover),
15232
}
16233
end
17234

235+
function Spectate:render(dc)
236+
self.subviews.spectate_mode:setOption(spectate.isEnabled())
237+
Spectate.super.render(self, dc)
238+
end
239+
18240
SpectateScreen = defclass(SpectateScreen, gui.ZScreen)
19241
SpectateScreen.ATTRS {
20242
focus_path='spectate',

0 commit comments

Comments
 (0)