1 | bgColor = -1 -- white |
2 | fontW, fontH = 16, 16 |
3 | displayCols, displayRows = 40, 10 |
4 | displayW, displayH = fontW*displayCols, fontH*displayRows |
5 | width, height = displayW, displayH |
6 | cursorBlinkRate = 500 |
7 | --eventRate = 50 |
8 | eventRate = 20 -- high speed! |
9 | eventsPerCursorBlink = cursorBlinkRate/eventRate |
10 | needsRepaint = false |
11 | repaintTriggeringVars = {"curX", "curY", "cursorVisible", "scrollX", "scrollY"} |
12 | fatCursor = true |
13 | |
14 | autoScroll = loadSnippet("#192") |
15 | |
16 | -- volatile data |
17 | if not inited then |
18 | scrollX, scrollY = 0, 0 |
19 | curX, curY = 0, 0 |
20 | if lines == nil then lines = {"hello", "world"} end |
21 | needsRepaint = true |
22 | inited = true |
23 | end |
24 | |
25 | local min, max = math.min, math.max |
26 | |
27 | get("#109") -- copyRect |
28 | |
29 | fontRendererEnv = newCleanEnv() |
30 | --fontRenderer = get("#178", fontRendererEnv) |
31 | fontRenderer = get("#186", fontRendererEnv) |
32 | |
33 | grab("#175") -- tableToString |
34 | |
35 | function renderText(x, y, s) |
36 | --print("renderText", x, y, s) |
37 | fontRendererEnv.render(s) |
38 | --print("fontWidth="..tostring(fontRendererEnv.fontWidth)) |
39 | copyRect(fontRendererEnv, _G, 0, 0, fontRendererEnv.width, fontRendererEnv.height, x, y) |
40 | --[[for y=0, 1 do |
41 | for x=0, 15 do |
42 | print(fontRendererEnv.pixels[x+y*fontRendererEnv.width+1]) |
43 | end |
44 | end]] |
45 | end |
46 | |
47 | -- "hook" is an identifier for the place to extend. |
48 | -- example: "processEvents" for extending the processEvents |
49 | -- function. |
50 | function extensions(hook) |
51 | -- put your extensions here :) |
52 | end |
53 | |
54 | function setPixel(x, y, col) |
55 | if x >= 0 and y >= 0 and x < displayW and y < displayH then |
56 | pixels[x+y*width+1] = col |
57 | end |
58 | end |
59 | |
60 | function invertPixel(x, y) |
61 | if x >= 0 and y >= 0 and x < displayW and y < displayH then |
62 | local ofs = x+y*width+1 |
63 | pixels[ofs] = pixels[ofs] and -1-pixels[ofs] or -1 |
64 | end |
65 | end |
66 | |
67 | function stepCursor() |
68 | if lastCurX ~= curX or lastCurY ~= curY then |
69 | cursorCount = -1 |
70 | end |
71 | lastCurX = curX |
72 | lastCurY = curY |
73 | cursorCount = (cursorCount+1) % (eventsPerCursorBlink*2) |
74 | cursorVisible = cursorCount < eventsPerCursorBlink |
75 | end |
76 | |
77 | function renderCursor() |
78 | if cursorVisible then |
79 | for x=0, fatCursor and fontW-1 or 0 do |
80 | for y=0, fontH-1 do |
81 | invertPixel((curX-scrollX)*fontW+x, (curY-scrollY)*fontH+y) |
82 | end |
83 | end |
84 | end |
85 | end |
86 | |
87 | function cursorLeft() |
88 | if curX > 0 then |
89 | curX=curX-1 |
90 | elseif curY > 0 then |
91 | curY=curY-1 |
92 | end |
93 | end |
94 | |
95 | function cursorRight() |
96 | curX=curX+1 |
97 | end |
98 | |
99 | function cursorUp() |
100 | if curY > 0 then |
101 | curY=curY-1 |
102 | end |
103 | end |
104 | |
105 | function cursorDown() |
106 | if curY < #lines-1 then |
107 | curY=curY+1 |
108 | end |
109 | end |
110 | |
111 | function saveVars() |
112 | savedVars = {} |
113 | for _, var in ipairs(repaintTriggeringVars) do |
114 | savedVars[var] = _G[var] |
115 | end |
116 | end |
117 | |
118 | function compareVars() |
119 | for _, var in ipairs(repaintTriggeringVars) do |
120 | if savedVars[var] ~= _G[var] then |
121 | needsRepaint = true |
122 | return |
123 | end |
124 | end |
125 | end |
126 | |
127 | function moveCursorToSpot(x, y) |
128 | local col = math.floor((x+scrollX)/fontW) |
129 | local row = math.floor((y+scrollY)/fontH) |
130 | row = max(0, min(row, #lines-1)) |
131 | col = max(0, col) |
132 | curX, curY = col, row |
133 | end |
134 | |
135 | function insertText2(s) |
136 | if s == '' then return end |
137 | local l = lines[curY+1] |
138 | local left, right = l:sub(1, curX), l:sub(curX+1) |
139 | if s == '\n' then |
140 | table.insert(lines, curY+1, left) |
141 | lines[curY+2] = right |
142 | curY = curY+1 |
143 | curX = 0 |
144 | else |
145 | lines[curY+1] = left..s..right |
146 | curX = curX+#s |
147 | needsRepaint = true |
148 | end |
149 | end |
150 | |
151 | function insertText(s) |
152 | local i = s:find("\n", 1, plain) |
153 | if not i then |
154 | insertText2(s) |
155 | else |
156 | insertText2(s:sub(1, i-1)) |
157 | insertText2("\n") |
158 | insertText(s:sub(i+1)) -- gotta love recursion! |
159 | end |
160 | end |
161 | |
162 | function backspace() |
163 | local l = lines[curY+1] |
164 | if curX > 0 then |
165 | lines[curY+1] = l:sub(1, curX-1)..l:sub(curX+1) |
166 | curX=curX-1 |
167 | elseif curY > 0 then |
168 | local p = lines[curY] |
169 | lines[curY] = p..l |
170 | table.remove(lines, curY+1) |
171 | curY=curY-1 |
172 | curX=#p |
173 | end |
174 | end |
175 | |
176 | function home() |
177 | curX = 0 |
178 | end |
179 | |
180 | function endPos() |
181 | curX = #lines[curY+1] |
182 | end |
183 | |
184 | function processEvents() |
185 | saveVars() |
186 | |
187 | if inputEvents then |
188 | for _, e in ipairs(inputEvents) do |
189 | --print("event:", tableToString(e)) |
190 | if e[1] == 'keyPressed' then |
191 | if e.keyCode == 39 then |
192 | cursorRight() |
193 | elseif e.keyCode == 37 then |
194 | cursorLeft() |
195 | elseif e.keyCode == 40 then |
196 | cursorDown() |
197 | elseif e.keyCode == 38 then |
198 | cursorUp() |
199 | elseif e.keyCode == 0x24 then |
200 | home() |
201 | elseif e.keyCode == 0x23 then |
202 | endPos() |
203 | end |
204 | elseif e[1] == 'keyTyped' then |
205 | if e.keyChar == '\8' then |
206 | backspace() |
207 | else |
208 | insertText(e.keyChar) |
209 | end |
210 | elseif e[1] == 'mousePressed' then |
211 | moveCursorToSpot(e.x, e.y) |
212 | end |
213 | end |
214 | end |
215 | extensions('processEvents1') |
216 | |
217 | stepCursor() |
218 | autoScroll() |
219 | extensions('processEvents') |
220 | compareVars() |
221 | end |
222 | |
223 | function render() |
224 | if needsRepaint then |
225 | pixels = {} |
226 | for i = 1, width*height do pixels[i] = bgColor end |
227 | |
228 | for l = 1, min(#lines-scrollY, displayRows) do |
229 | renderText(0, (l-1)*fontH, lines[l+scrollY]:sub(scrollX+1, scrollX+1+displayCols)) |
230 | end |
231 | |
232 | renderCursor() |
233 | needsRepaint = false |
234 | end |
235 | end |
236 | |
237 | function step() |
238 | pixels = nil |
239 | processEvents() |
240 | render() |
241 | if exit then |
242 | animateAgainIn = nil |
243 | else |
244 | animateAgainIn = {eventRate, step} |
245 | end |
246 | end |
247 | |
248 | step() |
Began life as a copy of #172
show applet test run test run with input download show line numbers
Travelled to 12 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Recognizer | Recognition Result | Visualize | Recalc |
---|---|---|---|
#308 | 5501 | [visualize] |
Snippet ID: | #185 |
Snippet name: | Editor 2.1 |
Eternal ID of this version: | #185/1 |
Text MD5: | f841a51ae3f6fbf7fcfb21ef939e5556 |
Author: | stefan |
Category: | editors |
Type: | Lua code - GUI |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2014-01-23 02:05:36 |
Source code size: | 5501 bytes / 248 lines |
Pitched / IR pitched: | No / Yes |
Views / Downloads: | 1066 / 674 |
Referenced in: | [show references] |