forked from MidnightCommander/mc
-
Notifications
You must be signed in to change notification settings - Fork 2
/
scrollbar.lua
112 lines (87 loc) · 2.83 KB
/
scrollbar.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
--[[
Draws a scrollbar in the editor.
Installation:
require('samples.editbox.scrollbar').install()
Or, if you want to customize its appearance:
local sb = require('samples.editbox.scrollbar')
sb.style.color.thumb = 'core.header'
sb.style.char.thumb.unicode = '┃'
-- You might find a west-aligned scrollbar (a la emacs) to be
-- more convenient because it's closer to the text:
sb.region = 'west'
sb.install()
]]
local scrollbar_utils = require('samples.libs.scrollbar')
local docker = require('samples.libs.docker-editor')
local M = {
style = {
color = {
thumb = 'editor.editframeactive',
trough = 'editor._default_',
disabled = 'editor._default_',
},
char = {
thumb = {
unicode = '█',
eightbit = nil,
fallback = 'widget-scollbar.current-char',
},
trough = {
unicode = '│',
eightbit = nil,
fallback = 'widget-scollbar.background-char',
},
disabled = {
unicode = '░', -- darker version: '▒'
eightbit = ':',
},
}
},
region = 'east',
}
--
-- Note: We have to use rawset/get in several places because, by default, the
-- "properties" mechanism of widgets protects againt typos by raising exceptions
-- when setting/getting unknown properties.
--
local function scrollbar_constructor(dlg)
local style = scrollbar_utils.compile_style(M.style)
local sb = ui.Custom{cols=1}
-- Store it in the dialog so we can refer to it later.
rawset(dlg, 'scrollbar', sb)
rawset(sb, 'update', function(self, edt)
local c = self:get_canvas()
-- Some might argue that we could do some optimizations here.
--
-- E.g., 'edt:get_max_line()' etc. would be faster than 'edt.max_line'.
-- And we might want to compare 'top'/'ht' to their previous values to
-- see if there's any change.
--
-- HOWEVER, we must first do some benchmarking, to see if there's any
-- justification for this "optimization". There probably isn't any: Lua
-- is fast enough as it is.
-- Note: 'self.rows' differs from 'edt.rows' when the editbox isn't "fullscreen".
local top, ht = scrollbar_utils.calculate(edt.max_line, edt.rows, edt.top_line, self.rows)
if top then
c:set_style(style.color.trough)
c:erase(style.char.trough)
c:set_style(style.color.thumb)
c:fill_rect(0,top,1, ht, style.char.thumb)
else
c:set_style(style.color.disabled)
c:erase(style.char.disabled)
end
end)
return sb
end
function M.install()
docker.register_widget(M.region, scrollbar_constructor)
ui.Editbox.bind('<<draw>>', function(edt)
local dlg = edt.dialog
local sb = rawget(dlg, 'scrollbar')
if sb and sb:is_alive() then -- The :is_alive() is needed when restarting Lua (@todo: explain why).
sb:update(edt)
end
end)
end
return M