View difference between Paste ID: ygebsjHs and Dfgc6z0T
SHOW: | | - or go back to the newest paste.
1
--To use the gui just download http://pastebin.com/Dfgc6z0T to a computer as /lib/gui.lua and try your best.
2
3
local versionMajor = "2"
4
local versionMinor = "5"
5
6
7
local component = require("component")
8
local gpu = component.gpu
9
local event = require("event")
10
local ser = require("serialization")
11
local computer = require("computer")
12
13
local screenWidth, screenHeight = gpu.getResolution()
14
15
local gui = {}
16
17
local colorScreenBackground = 0xC0C0C0
18
local colorScreenForeground = 0x000000
19
local colorTopLineBackground = 0x0000FF
20
local colorTopLineForeground = 0xFFFFFF
21
local colorBottomLineBackground = 0x0000FF
22
local colorBottomLineForeground = 0xFFFFFF
23
local colorFrameBackground = 0xC0C0C0
24
local colorFrameForeground = 0x000000
25
local colorButtonBackground = 0x0000FF
26
local colorButtonForeground = 0xFFFFFF
27
local colorButtonClickedBackground = 0x00FF00
28
local colorButtonClickedForeground = 0xFFFFFF
29
local colorButtonDisabledBackground = 0x000000
30
local colorButtonDisabledForeground = 0xFFFFFF
31
local colorTextBackground = 0x000000
32
local colorTextForeground = 0xFFFF00
33
local colorInputBackground = 0x0000FF
34
local colorInputForeground = 0xFFFFFF
35
local colorProgressBackground = 0x000000
36
local colorProgressForeground = 0x00FF00
37
local colorProgressNumberForeground = 0xFFFF00
38
local colorListBackground = 0x0000FF
39
local colorListForeground = 0xFFFFFF
40
local colorListActiveBackground = 0x00FF00
41
local colorListActiveForeground = 0xFFFF00
42
local colorListDisabledBackground = 0x000000
43
local colorListDisabledForeground = 0xFFFF00
44
local colorVProgressBackground = 0x000000
45
local colorVProgressForeground = 0x00FF00
46
local colorVSliderBackground = 0x000000
47
local colorVSliderForeground = 0x00FF00
48
local colorChartBackground = 0x000000
49
local colorChartForeground = 0x00FF00
50
51
local displayed = false
52
53
54
function gui.Version()
55
  return versionMajor .. "." .. versionMinor, versionMajor, versionMinor
56
end
57
58
function gui.checkVersion(major, minor)
59
  if major > tonumber(versionMajor) then
60
    compGui = gui.newGui("center", "center", 40, 9, true, nil, 0xFF0000, 0xFFFF00)
61
    gui.displayGui(compGui)
62
    gui.newLabel(compGui, "center", 1, "!Wrong Gui version!")
63
    gui.newLabel(compGui, "center", 3, string.format("Need version %d.%d",major, minor))
64
    gui.newLabel(compGui, "center", 5, string.format("Installed version is v %d.%d",versionMajor, versionMinor))
65
    gui.newHLine(compGui, 1, 6, 38)
66
    gui.newButton(compGui, "center", 7, "exit", gui.exit)
67
    while true do
68
      gui.runGui(compGui)
69
    end
70
  else
71
    if minor > tonumber(versionMinor) then
72
      compGui = gui.newGui("center", "center", 40, 9, true, nil, 0xFF0000, 0xFFFF00)
73
      gui.displayGui(compGui)
74
      gui.newLabel(compGui, "center", 1, "!Wrong Gui version!")
75
      gui.newLabel(compGui, "center", 3, string.format("Need version %d.%d",major, minor))
76
      gui.newLabel(compGui, "center", 5, string.format("Installed version is v %d.%d",versionMajor, versionMinor))
77
      gui.newHLine(compGui, 1, 6, 38)
78
      gui.newButton(compGui, "center", 7, "exit", gui.exit)
79
      while true do
80
	gui.runGui(compGui)
81
      end
82
    end
83
  end
84
end
85
86
function gui.clearScreen()
87
  gpu.setBackground(colorScreenBackground)
88
  gpu.setForeground(colorScreenForeground)
89
  gpu.fill(1, 1, screenWidth, screenHeight, " ")
90
91
  gpu.setBackground(colorTopLineBackground)
92
  gpu.setForeground(colorTopLineForeground)
93
  gpu.fill(1, 1, screenWidth, 1, " ")
94
  
95
  gpu.setBackground(colorBottomLineBackground)
96
  gpu.setForeground(colorBottomLineForeground)
97
  gpu.fill(1, screenHeight, screenWidth, 1, " ")
98
end
99
100
function gui.setTop(text)
101
  gpu.setBackground(colorTopLineBackground)
102
  gpu.setForeground(colorTopLineForeground)
103
  gpu.set( (screenWidth / 2) - (string.len(text) / 2), 1, text)
104
end
105
106
function gui.setBottom(text)
107
  gpu.setBackground(colorBottomLineBackground)
108
  gpu.setForeground(colorBottomLineForeground)
109
  gpu.set( (screenWidth / 2) - (string.len(text) / 2), screenHeight, text)
110
end
111
112
local function saveBackground(x,y,w,h)
113
  local buffer = {}
114
  for i = x,x + w do
115
    for j = y,y + h do
116
      local ch,fc,bc = gpu.get(i,j)
117
      local tmp = {i,j,ch,fc,bc}
118
      table.insert(buffer, tmp)
119
    end
120
  end
121
  return buffer
122
end
123
124
125
local function restoreBackground(buff)
126
  for k,v in pairs(buff) do
127
    gpu.setBackground(v[5])
128
    gpu.setForeground(v[4])
129
    gpu.set(v[1], v[2], v[3])
130
  end
131
end
132
133
function gui.closeGui(guiID)
134
--  print("restoring" .. guiID.num)
135
--  os.sleep(1)
136
  restoreBackground(guiID.buffer)
137
  guiID.new = true
138
end
139
140
141
-- displays the gui frame, if set or just clears the display area
142
local function _displayFrame(guiID)
143
  if guiID.new == true then
144
--    print("saving" .. guiID.num)
145
    guiID.buffer = saveBackground(guiID.x, guiID.y, guiID.width, guiID.height)
146
    guiID.new = false
147
--    os.sleep(1)
148
  end
149
  gpu.setBackground(guiID.bg)
150
  gpu.setForeground(guiID.fg)
151
  gpu.fill(guiID.x, guiID.y, guiID.width, guiID.height, " ")
152
  if guiID.frame == true then
153
    gpu.fill(guiID.x, guiID.y, 1, guiID.height, "║")
154
    gpu.fill(guiID.x + guiID.width - 1, guiID.y, 1, guiID.height, "║")
155
    gpu.fill(guiID.x, guiID.y, guiID.width, 1, "═")
156
    gpu.fill(guiID.x, guiID.y + guiID.height - 1, guiID.width, 1, "═")
157
    gpu.set(guiID.x, guiID.y, "╔")
158
    gpu.set(guiID.x + guiID.width - 1 , guiID.y, "╗")
159
    gpu.set(guiID.x, guiID.y + guiID.height - 1 , "╚")
160
    gpu.set(guiID.x + guiID.width - 1 , guiID.y + guiID.height - 1, "╝")
161
    if guiID.text then
162
      gpu.set(guiID.x + math.floor((guiID.width/2)) - math.floor((string.len(guiID.text)/2)), guiID.y, guiID.text)
163
    end
164
  end
165
end
166
167
-- displays a frame
168
local function _displayAFrame(guiID, frameID)
169
  if guiID[frameID].visible == true then
170
    gpu.setBackground(guiID.bg)
171
    gpu.setForeground(guiID.fg)
172
    gpu.fill(guiID[frameID].x, guiID[frameID].y, 1, guiID[frameID].height, "║")
173
    gpu.fill(guiID[frameID].x + guiID[frameID].width - 1, guiID[frameID].y, 1, guiID[frameID].height, "║")
174
    gpu.fill(guiID[frameID].x, guiID[frameID].y, guiID[frameID].width, 1, "═")
175
    gpu.fill(guiID[frameID].x, guiID[frameID].y + guiID[frameID].height - 1, guiID[frameID].width, 1, "═")
176
    gpu.set(guiID[frameID].x, guiID[frameID].y, "╔")
177
    gpu.set(guiID[frameID].x + guiID[frameID].width - 1 , guiID[frameID].y, "╗")
178
    gpu.set(guiID[frameID].x, guiID[frameID].y + guiID[frameID].height - 1 , "╚")
179
    gpu.set(guiID[frameID].x + guiID[frameID].width - 1 , guiID[frameID].y + guiID[frameID].height - 1, "╝")
180
    if guiID[frameID].text then
181
      gpu.set(guiID[frameID].x + math.floor((guiID[frameID].width/2)) - math.floor((string.len(guiID[frameID].text)/2)+1), guiID[frameID].y, "╡" .. guiID[frameID].text .. "┝")
182
    end
183
  end
184
end
185
186
--display a horizontal line
187
local function _displayHLine(guiID, lineID)
188
  gpu.setBackground(guiID.bg)
189
  gpu.setForeground(guiID.fg)
190
  gpu.fill(guiID[lineID].x, guiID[lineID].y, guiID[lineID].width, 1, "═")
191
end
192
193
-- displays a checkbox
194
local function _displayCheckbox(guiID, checkboxID)
195
  if guiID[checkboxID].visible == true then
196
    gpu.setBackground(guiID.bg)
197
    gpu.setForeground(guiID.fg)
198
    local x = 0
199
    x =guiID.x + guiID[checkboxID].x
200
    if guiID[checkboxID].status == true then
201
      gpu.set(x, guiID[checkboxID].y, "[√]")
202
    else
203
      gpu.set(x, guiID[checkboxID].y, "[ ]")
204
    end
205
  end
206
end
207
208
-- displays a radio button
209
local function _displayRadio(guiID, radioID)
210
  if guiID[radioID].visible == true then
211
    gpu.setBackground(guiID.bg)
212
    gpu.setForeground(guiID.fg)
213
    local x = 0
214
    x =guiID.x + guiID[radioID].x
215
    if guiID[radioID].status == true then
216
      gpu.set(x, guiID[radioID].y, "(x)")
217
    else
218
      gpu.set(x, guiID[radioID].y, "( )")
219
    end
220
  end
221
end
222
223
-- displays a label
224
local function _displayLabel(guiID, labelID)
225
  if guiID[labelID].visible == true then
226
    gpu.setBackground(guiID[labelID].bg)
227
    gpu.setForeground(guiID[labelID].fg)
228
    local x = 0
229
    if guiID[labelID].x == "center" then
230
      x = guiID.x + math.floor((guiID.width / 2)) - math.floor((string.len(guiID[labelID].text)) / 2)
231
    else
232
      x =guiID.x + guiID[labelID].x
233
    end
234
    gpu.fill(x, guiID[labelID].y, guiID[labelID].l , 1, " ")
235
    gpu.set(x, guiID[labelID].y, guiID[labelID].text)
236
  end
237
end
238
239
-- displays a time label
240
local function _displayTimeLabel(guiID, labelID)
241
  if guiID[labelID].visible == true then
242
    gpu.setBackground(guiID[labelID].bg)
243
    gpu.setForeground(guiID[labelID].fg)
244
    local x = guiID.x + guiID[labelID].x
245
    gpu.set(x, guiID[labelID].y, os.date("%H:%M", os.time()))
246
  end
247
end
248
249
-- displays a date label
250
local function _displayDateLabel(guiID, labelID)
251
  if guiID[labelID].visible == true then
252
    gpu.setBackground(guiID[labelID].bg)
253
    gpu.setForeground(guiID[labelID].fg)
254
    local x = guiID.x + guiID[labelID].x
255
    if guiID[labelID].frm == false then
256
      gpu.set(x, guiID[labelID].y, os.date("%d/%m/%Y"))
257
    elseif guiID[labelID].frm == true then
258
      gpu.set(x, guiID[labelID].y, os.date("%A %d. %B %Y"))
259
    end
260
  end
261
end
262
263
local function splitWords(Lines, limit)
264
    while #Lines[#Lines] > limit do
265
        Lines[#Lines+1] = Lines[#Lines]:sub(limit+1)
266
        Lines[#Lines-1] = Lines[#Lines-1]:sub(1,limit)
267
    end
268
end
269
270
local function wrap(str, limit)
271
    local Lines, here, limit, found = {}, 1, limit or 72, str:find("(%s+)()(%S+)()")
272
273
    if found then
274
        Lines[1] = string.sub(str,1,found-1)  -- Put the first word of the string in the first index of the table.
275
    else Lines[1] = str end
276
277
    str:gsub("(%s+)()(%S+)()",
278
        function(sp, st, word, fi)  -- Function gets called once for every space found.
279
            splitWords(Lines, limit)
280
281
            if fi-here > limit then
282
                here = st
283
                Lines[#Lines+1] = word                                             -- If at the end of a line, start a new table index...
284
            else Lines[#Lines] = Lines[#Lines].." "..word end  -- ... otherwise add to the current table index.
285
        end)
286
287
    splitWords(Lines, limit)
288
289
    return Lines
290
end
291
292
-- displays a multi line label
293
local function _displayMultiLineLabel(guiID, labelID)
294
  if guiID[labelID].visible == true then
295
    gpu.setBackground(guiID[labelID].bg)
296
    gpu.setForeground(guiID[labelID].fg)
297
    gpu.fill(guiID[labelID].x, guiID[labelID].y, guiID[labelID].w, guiID[labelID].h, " ")
298
    local text = wrap(guiID[labelID].text, guiID[labelID].w)
299
    for i = 1, #text do
300
      gpu.set(guiID[labelID].x, guiID[labelID].y + i, text[i])
301
    end
302
  end
303
end
304
305
-- displays a button
306
local function _displayButton(guiID, buttonID)
307
  if guiID[buttonID].visible == true then
308
    if guiID[buttonID].active == true then
309
      gpu.setBackground(colorButtonClickedBackground)
310
      gpu.setForeground(colorButtonClickedForeground)
311
    elseif guiID[buttonID].enabled == false then
312
      gpu.setBackground(colorButtonDisabledBackground)
313
      gpu.setForeground(colorButtonDisabledForeground)
314
    else
315
      gpu.setBackground(colorButtonBackground)
316
      gpu.setForeground(colorButtonForeground)
317
    end
318
    local x = 0
319
    if guiID[buttonID].x == "center" then
320
      x = guiID.x + math.floor((guiID.width / 2)) - math.floor((guiID[buttonID].lenght / 2))
321
    else
322
      x = guiID.x + guiID[buttonID].x
323
    end
324
    gpu.fill(x, guiID[buttonID].y, guiID[buttonID].lenght, 1, " ")
325
    gpu.set(x, guiID[buttonID].y, guiID[buttonID].text)
326
  end
327
end
328
329
-- displays a text
330
local function _displayText(guiID, textID)
331
  if guiID[textID].visible == true then
332
    gpu.setBackground(colorTextBackground)
333
    gpu.setForeground(colorTextForeground)
334
    local x = 0
335
    if guiID[textID].x == "center" then
336
      x = guiID.x + math.floor((guiID.width / 2)) - math.floor((guiID[textID].fieldLenght) / 2)
337
    else
338
      x = guiID.x + guiID[textID].x
339
    end
340
    gpu.fill(x, guiID[textID].y , guiID[textID].fieldLenght, 1, " ")
341
    tmpStr = guiID[textID].text
342
    if guiID[textID].hide == true then
343
      tmpStr = ""
344
      for i = 1, string.len(guiID[textID].text) do
345
	tmpStr = tmpStr .."*"
346
      end
347
    end
348
    gpu.set(x, guiID[textID].y, string.sub(tmpStr, 1, guiID[textID].fieldLenght))
349
  end
350
end
351
352
-- displays a vertical slider
353
local function _displayVslider(guiID, sliderID)
354
  if guiID[sliderID].visible == true then
355
    gpu.setBackground(colorVSliderBackground)
356
    gpu.setForeground(colorVSliderForeground)
357
    local x = 0
358
    x = guiID.x + guiID[sliderID].x
359
    gpu.fill(x, guiID[sliderID].y , guiID[sliderID].lenght + 2, 1, " ")
360
    gpu.setBackground(colorButtonBackground)
361
    gpu.setForeground(colorButtonForeground)
362
    gpu.set(x, guiID[sliderID].y, "-")
363
    gpu.set(x + guiID[sliderID].lenght + 1, guiID[sliderID].y, "+")
364
    x = x + 1
365
    local proz = math.floor(100 / guiID[sliderID].max * guiID[sliderID].value)
366
    if proz > 100 then
367
      proz = 100
368
      if guiID[sliderID].func then
369
	guiID[sliderID].func(guiID, sliderID)
370
      end
371
    end
372
    local pos = math.floor(guiID[sliderID].lenght / 100 * proz)
373
    gpu.setBackground(colorVSliderForeground)
374
    gpu.setForeground(colorVSliderBackground)
375
    gpu.fill(x, guiID[sliderID].y , pos, 1, " ")
376
    gpu.setBackground(colorVSliderBackground)
377
    gpu.setForeground(colorVSliderForeground)
378
    gpu.fill(x + pos, guiID[sliderID].y , guiID[sliderID].lenght - pos, 1, " ")
379
  end
380
end
381
382
-- displays a progress bar
383
local function _displayProgress(guiID, progressID)
384
  if guiID[progressID].visible == true then
385
    gpu.setBackground(colorProgressForeground)
386
    gpu.setForeground(colorProgressBackground)
387
    local x = 0
388
    if guiID[progressID].x == "center" then
389
      x = guiID.x + math.floor((guiID.width / 2)) - math.floor((guiID[progressID].lenght) / 2)
390
    else
391
      x = guiID.x + guiID[progressID].x
392
    end
393
    local proz = math.floor(100 / guiID[progressID].max * guiID[progressID].value)
394
    if proz > 100 then
395
      proz = 100
396
      if guiID[progressID].finished == false and guiID[progressID].func then
397
	guiID[progressID].func(guiID, progressID)
398
      end
399
      guiID[progressID].finished = true
400
    end
401
    local pos = math.floor(guiID[progressID].lenght / 100 * proz)
402
    gpu.fill(x, guiID[progressID].y , pos, 1, " ")
403
    gpu.setBackground(colorProgressBackground)
404
    gpu.setForeground(colorProgressForeground)
405
    gpu.fill(x + pos, guiID[progressID].y , guiID[progressID].lenght - pos, 1, " ")
406
    gpu.setBackground(guiID.bg)
407
    gpu.setForeground(guiID.fg)
408
    if guiID[progressID].displayNumber == true then
409
      gpu.fill(x, guiID[progressID].y - 1, guiID[progressID].lenght, 1, " ")
410
      gpu.set(x + (math.floor(guiID[progressID].lenght / 2)) - 1, guiID[progressID].y - 1, proz .. "%")
411
    end
412
  end
413
end
414
415
-- displays a vertical progress bar
416
local function _displayVProgress(guiID, progressID)
417
  if guiID[progressID].visible == true then
418
    local x = 0
419
    if guiID[progressID].x == "center" then
420
      x = guiID.x + math.floor((guiID.width / 2)) - math.floor((guiID[progressID].lenght) / 2)
421
    else
422
      x = guiID.x + guiID[progressID].x
423
    end
424
    local proz = math.floor(100 / guiID[progressID].max * guiID[progressID].value)
425
    if proz > 100 then
426
      proz = 100
427
      if guiID[progressID].finished == false and guiID[progressID].func then
428
	guiID[progressID].func(guiID, progressID)
429
      end
430
      guiID[progressID].finished = true
431
    end
432
    local pos = math.floor(guiID[progressID].lenght / 100 * proz)
433
    for i = 1, guiID[progressID].width do
434
      if guiID[progressID].direction == 0 then
435
	gpu.setBackground(colorProgressForeground)
436
	gpu.setForeground(colorProgressBackground)
437
	gpu.fill(x+i-1, guiID[progressID].y , 1, pos, " ")
438
	gpu.setBackground(colorProgressBackground)
439
	gpu.setForeground(colorProgressForeground)
440
	gpu.fill(x+i-1, guiID[progressID].y + pos, 1, guiID[progressID].lenght - pos, " ")
441
      end
442
      if guiID[progressID].direction == 1 then
443
	gpu.setBackground(colorProgressBackground)
444
	gpu.setForeground(colorProgressForeground)
445
	gpu.fill(x+i-1, guiID[progressID].y, 1, guiID[progressID].lenght, " ")
446
	gpu.setBackground(colorProgressForeground)
447
	gpu.setForeground(colorProgressBackground)
448
	gpu.fill(x+i-1, guiID[progressID].y + guiID[progressID].lenght - pos , 1, pos, " ")
449
      end
450
    end
451
  end
452
end
453
454
-- display list
455
local function _displayList(guiID, listID)
456
  if guiID[listID].visible == true then
457
    if guiID[listID].enabled == true then
458
      gpu.setBackground(colorListBackground)
459
      gpu.setForeground(colorListForeground)
460
    else
461
      gpu.setBackground(colorListDisabledBackground)
462
      gpu.setForeground(colorListDisabledForeground)
463
    end
464
    gpu.fill(guiID[listID].x, guiID[listID].y, guiID[listID].width, guiID[listID].height, " ")
465
    gpu.fill(guiID[listID].x, guiID[listID].y, guiID[listID].width, 1, "═")
466
    if guiID[listID].text then
467
      gpu.set( guiID[listID].x + (guiID[listID].width/2) - (string.len(guiID[listID].text)/2), guiID[listID].y, "╡" .. guiID[listID].text .. "┝")
468
    end
469
    if guiID[listID].active + guiID[listID].height - 3 > #guiID[listID].entries then
470
      l = #guiID[listID].entries
471
    else
472
      l = guiID[listID].active + guiID[listID].height - 3
473
    end
474
    gpu.fill(guiID[listID].x, guiID[listID].y +guiID[listID].height - 1, guiID[listID].width, 1, "═")
475
    gpu.set(guiID[listID].x, guiID[listID].y + guiID[listID].height - 1, "[<]")
476
    gpu.set(guiID[listID].x + guiID[listID].width - 3, guiID[listID].y + guiID[listID].height - 1, "[>]")
477
    for v = guiID[listID].active, l  do
478
      if v == guiID[listID].selected then
479
	gpu.setBackground(colorListActiveBackground)
480
	gpu.setForeground(colorListActiveForeground)
481
      else
482
	if guiID[listID].enabled == true then
483
	  gpu.setBackground(colorListBackground)
484
	  gpu.setForeground(colorListForeground)
485
	else
486
	  gpu.setBackground(colorListDisabledBackground)
487
	  gpu.setForeground(colorListDisabledForeground)
488
	end
489
      end
490
      gpu.fill(guiID[listID].x, guiID[listID].y + v - guiID[listID].active + 1, guiID[listID].width, 1 , " ")
491
      gpu.set(guiID[listID].x + 1, guiID[listID].y + v - guiID[listID].active + 1, guiID[listID].entries[v] )
492
    end
493
  end
494
end
495
496
-- displays a chart
497
local function _displayChart(guiID, chartID)
498
  if guiID[chartID].visible == true then
499
    gpu.setBackground(colorChartBackground)
500
    gpu.setForeground(colorChartForeground)
501
    for x = 1, #guiID[chartID].data do
502
	local proz = math.floor(100 / guiID[chartID].max * guiID[chartID].data[x])
503
	local dotPos = guiID[chartID].height - math.floor( guiID[chartID].height / guiID[chartID].max * guiID[chartID].data[x])
504
	for y = 1, guiID[chartID].height do
505
	  if dotPos == y then
506
	    gpu.setBackground(colorChartForeground)
507
	  else
508
	    gpu.setBackground(colorChartBackground)
509
	  end
510
	  gpu.set(x + guiID[chartID].x, y + guiID[chartID].y, " ")
511
	  
512
	end
513
    end
514
  end
515
end
516
517
-- display the gui and all widgets
518
function gui.displayGui(guiID)
519
520
  _displayFrame(guiID)
521
  
522
  for i = 1, #guiID do
523
    if guiID[i].type == "label" then
524
      _displayLabel(guiID, i)
525
    elseif guiID[i].type == "multiLineLabel" then
526
      _displayMultiLineLabel(guiID, i)
527
    elseif guiID[i].type == "button" then
528
      _displayButton(guiID, i)
529
    elseif guiID[i].type == "text" then
530
      _displayText(guiID, i)
531
    elseif guiID[i].type == "progress" then
532
      _displayProgress(guiID, i)
533
    elseif guiID[i].type == "vprogress" then
534
      _displayVProgress(guiID, i)
535
    elseif guiID[i].type == "list" then
536
      _displayList(guiID, i)
537
    elseif guiID[i].type == "frame" then
538
      _displayAFrame(guiID, i)
539
    elseif guiID[i].type == "hline" then
540
      _displayHLine(guiID, i)
541
    elseif guiID[i].type == "checkbox" then
542
      _displayCheckbox(guiID, i)
543
    elseif guiID[i].type == "radio" then
544
      _displayRadio(guiID, i)
545
    elseif guiID[i].type == "vslider" then
546
      _displayVslider(guiID, i)
547
    elseif guiID[i].type == "chart" then
548
      _displayChart(guiID, i)
549
    end
550
  end
551
end
552
553
function gui.displayWidget(guiID, widgetID)
554
555
    if guiID[widgetID].type == "label" then
556
      _displayLabel(guiID, widgetID)
557
    elseif guiID[widgetID].type == "multiLineLabel" then
558
      _displayMultiLineLabel(guiID, widgetID)
559
    elseif guiID[widgetID].type == "button" then
560
      _displayButton(guiID, widgetID)
561
    elseif guiID[widgetID].type == "text" then
562
      _displayText(guiID, widgetID)
563
    elseif guiID[widgetID].type == "progress" then
564
      _displayProgress(guiID, widgetID)
565
    elseif guiID[widgetID].type == "vprogress" then
566
      _displayVProgress(guiID, widgetID)
567
    elseif guiID[widgetID].type == "list" then
568
      _displayList(guiID, widgetID)
569
    elseif guiID[widgetID].type == "frame" then
570
      _displayAFrame(guiID, widgetID)
571
    elseif guiID[widgetID].type == "hline" then
572
      _displayHLine(guiID, widgetID)
573
    elseif guiID[widgetID].type == "checkbox" then
574
      _displayCheckbox(guiID, widgetID)
575
    elseif guiID[widgetID].type == "radio" then
576
      _displayRadio(guiID, widgetID)
577
    elseif guiID[widgetID].type == "vslider" then
578
      _displayVslider(guiID, widgetID)
579
    elseif guiID[widgetID].type == "chart" then
580
      _displayChart(guiID, widgetID)
581
    end
582
end
583
584
function gui.exit()
585
  gpu.setBackground(0x000000)
586
  gpu.setForeground(0xFFFFFF)
587
  gpu.fill(1, 1, screenWidth, screenHeight, " ")
588
  os.exit()
589
end
590
591
local guiCounter = 0
592
-- need to be called first to setup a new dialog
593
function gui.newGui(x, y, w, h, frame, text, bg, fg)
594
  local tmpTable = {}
595
  tmpTable["type"] = "gui"
596
  if x == "center" then
597
    tmpTable["x"] = math.floor((screenWidth / 2) - (w / 2))
598
  else
599
    tmpTable["x"] = x
600
  end
601
  if y == "center" then
602
    tmpTable["y"] = math.floor((screenHeight / 2) - (h / 2))
603
  else
604
    tmpTable["y"] = y
605
  end
606
  tmpTable["bg"] = bg or colorFrameBackground
607
  tmpTable["fg"] = fg or colorFrameForeground
608
  tmpTable["width"] = w
609
  tmpTable["height"] = h
610
  tmpTable["frame"] = frame
611
  if text then
612
    tmpTable["text"] = "╡" .. text .. "┝"
613
  end
614
  tmpTable["buffer"] = {}
615
  tmpTable["num"] = guiCounter
616
  guiCounter = guiCounter + 1
617
  tmpTable["new"] = true
618
  displayed = false
619
  return tmpTable
620
end
621
622
-- checkbox
623
function gui.newCheckbox(guiID, x, y, status, func)
624
  local tmpTable = {}
625
  tmpTable["type"] = "checkbox"
626
  tmpTable["status"] = status or false
627
  tmpTable["y"] = y + guiID.y
628
  tmpTable["visible"] = true
629
  tmpTable["enabled"] = true
630
  tmpTable["x"] = x
631
  tmpTable["func"] = func
632
  table.insert(guiID, tmpTable)
633
  return #guiID
634
end
635
636
-- radio button
637
function gui.newRadio(guiID, x, y, func)
638
  local tmpTable = {}
639
  tmpTable["type"] = "radio"
640
  tmpTable["status"] = false
641
  tmpTable["y"] = y + guiID.y
642
  tmpTable["visible"] = true
643
  tmpTable["enabled"] = true
644
  tmpTable["x"] = x
645
  tmpTable["func"] = func
646
  table.insert(guiID, tmpTable)
647
  return #guiID
648
end
649
650
-- label
651
function gui.newLabel(guiID, x, y, text, bg, fg, l)
652
  local tmpTable = {}
653
  tmpTable["type"] = "label"
654
  tmpTable["y"] = y + guiID.y
655
  tmpTable["text"] = text
656
  tmpTable["lenght"] = string.len(text)
657
  tmpTable["bg"] = bg or guiID.bg
658
  tmpTable["fg"] = fg or guiID.fg
659
  tmpTable["visible"] = true
660
  tmpTable["x"] = x
661
  tmpTable["l"] = l or string.len(text)
662
  table.insert(guiID, tmpTable)
663
  return #guiID
664
end
665
666
-- time label
667
function gui.newTimeLabel(guiID, x, y, bg, fg)
668
  local tmpTable = {}
669
  tmpTable["type"] = "timelabel"
670
  tmpTable["y"] = y + guiID.y
671
  tmpTable["bg"] = bg or guiID.bg
672
  tmpTable["fg"] = fg or guiID.fg
673
  tmpTable["visible"] = true
674
  tmpTable["x"] = x
675
  table.insert(guiID, tmpTable)
676
  return #guiID
677
end
678
679
-- date label
680
function gui.newDateLabel(guiID, x, y, bg, fg, frm)
681
  local tmpTable = {}
682
  tmpTable["type"] = "datelabel"
683
  tmpTable["y"] = y + guiID.y
684
  tmpTable["bg"] = bg or guiID.bg
685
  tmpTable["fg"] = fg or guiID.fg
686
  tmpTable["visible"] = true
687
  tmpTable["x"] = x
688
  tmpTable["frm"] = frm or false
689
  table.insert(guiID, tmpTable)
690
  return #guiID
691
end
692
693
-- multi line label
694
function gui.newMultiLineLabel(guiID, x, y, w, h, text, bg, fg)
695
  local tmpTable = {}
696
  tmpTable["type"] = "multiLineLabel"
697
  tmpTable["y"] = y + guiID.y
698
  tmpTable["text"] = text
699
  tmpTable["bg"] = bg or guiID.bg
700
  tmpTable["fg"] = fg or guiID.fg
701
  tmpTable["visible"] = true
702
  tmpTable["x"] = x + guiID.x
703
  tmpTable["w"] = w
704
  tmpTable["h"] = h
705
  table.insert(guiID, tmpTable)
706
  return #guiID
707
end
708
709
-- button
710
function gui.newButton(guiID, x, y, text, func)
711
  local tmpTable = {}
712
  tmpTable["type"] = "button"
713
  tmpTable["y"] = y + guiID.y
714
  tmpTable["text"] = "[" .. text .. "]"
715
  tmpTable["lenght"] = string.len(tmpTable.text)
716
  tmpTable["visible"] = true
717
  tmpTable["enabled"] = true
718
  tmpTable["active"] = false
719
  tmpTable["func"] = func
720
  tmpTable["x"] = x
721
  table.insert(guiID, tmpTable)
722
  return #guiID
723
end
724
725
-- text input field
726
function gui.newText(guiID, x, y, lenght, text, func, fieldLenght, hide)
727
  local tmpTable = {}
728
  tmpTable["type"] = "text"
729
  tmpTable["x"] = x
730
  tmpTable["y"] = y + guiID.y
731
  tmpTable["text"] = text
732
  tmpTable["lenght"] = lenght
733
  tmpTable["visible"] = true
734
  tmpTable["enabled"] = true
735
  tmpTable["func"] = func
736
  if fieldLenght then
737
    tmpTable["fieldLenght"] = fieldLenght
738
  else
739
    tmpTable["fieldLenght"] = lenght
740
  end
741
  table.insert(guiID, tmpTable)
742
  tmpTable["hide"] = hide or false
743
  return #guiID
744
end
745
746
-- progressbar
747
function gui.newProgress(guiID, x, y, lenght, maxValue, value, func, number)
748
  local tmpTable = {}
749
  tmpTable["type"] = "progress"
750
  tmpTable["x"] = x
751
  tmpTable["y"] = y + guiID.y
752
  tmpTable["lenght"] = lenght
753
  tmpTable["visible"] = true
754
  tmpTable["enabled"] = true
755
  tmpTable["max"] = maxValue
756
  tmpTable["value"] = value
757
  tmpTable["func"] = func
758
  tmpTable["finished"] = false
759
  tmpTable["displayNumber"] = number or false
760
  table.insert(guiID, tmpTable)
761
  return #guiID
762
end
763
764
-- vertical progress
765
function gui.newVProgress(guiID, x, y, lenght, width, maxValue, value, func, direction)
766
  local tmpTable = {}
767
  tmpTable["type"] = "vprogress"
768
  tmpTable["x"] = x
769
  tmpTable["y"] = y + guiID.y
770
  tmpTable["lenght"] = lenght
771
  tmpTable["width"] = width
772
  tmpTable["visible"] = true
773
  tmpTable["enabled"] = true
774
  tmpTable["max"] = maxValue
775
  tmpTable["value"] = value
776
  tmpTable["func"] = func
777
  tmpTable["direction"] = direction or 0
778
  tmpTable["finished"] = false
779
  table.insert(guiID, tmpTable)
780
  return #guiID
781
end
782
783
-- vertical slider
784
function gui.newVSlider(guiID, x, y, lenght, min, max, value, func)
785
  local tmpTable = {}
786
  tmpTable["type"] = "vslider"
787
  tmpTable["x"] = x
788
  tmpTable["y"] = y + guiID.y
789
  tmpTable["lenght"] = lenght
790
  tmpTable["visible"] = true
791
  tmpTable["enabled"] = true
792
  tmpTable["min"] = min
793
  tmpTable["max"] = max
794
  tmpTable["value"] = value
795
  tmpTable["func"] = func
796
  table.insert(guiID, tmpTable)
797
  return #guiID
798
end
799
800
-- list
801
function gui.newList(guiID, x, y, width, height, tab, func, text)
802
  local tmpTable = {}
803
  tmpTable["type"] = "list"
804
  tmpTable["x"] = x + guiID.x
805
  tmpTable["y"] = y + guiID.y
806
  tmpTable["width"] = width
807
  tmpTable["height"] = height
808
  tmpTable["visible"] = true
809
  tmpTable["enabled"] = true
810
  tmpTable["func"] = func
811
  tmpTable["selected"] = 1
812
  tmpTable["active"] = 1
813
  tmpTable["entries"] = tab
814
  tmpTable["text"] = text
815
  table.insert(guiID, tmpTable)
816
  return #guiID
817
end
818
819
--frame
820
function gui.newFrame(guiID, x, y, width, height, text)
821
  local tmpTable = {}
822
  tmpTable["type"] = "frame"
823
  tmpTable["x"] = x + guiID.x
824
  tmpTable["y"] = y + guiID.y
825
  tmpTable["width"] = width
826
  tmpTable["height"] = height
827
  tmpTable["visible"] = true
828
  tmpTable["enabled"] = true
829
  tmpTable["text"] = text
830
  table.insert(guiID, tmpTable)
831
  return #guiID
832
end
833
834
-- hline
835
function gui.newHLine(guiID, x, y, width)
836
  local tmpTable = {}
837
  tmpTable["type"] = "hline"
838
  tmpTable["x"] = x + guiID.x
839
  tmpTable["y"] = y + guiID.y
840
  tmpTable["width"] = width
841
  tmpTable["visible"] = true
842
  tmpTable["enabled"] = true
843
  table.insert(guiID, tmpTable)
844
  return #guiID
845
end
846
847
-- chart
848
function gui.newChart(guiID, x, y, minValue, maxValue, data, lenght, height, bg, fg)
849
  local tmpTable = {}
850
  tmpTable["type"] = "chart"
851
  tmpTable["y"] = y + guiID.y
852
  tmpTable["lenght"] = lenght
853
  tmpTable["height"] = height
854
  tmpTable["bg"] = bg or guiID.bg
855
  tmpTable["fg"] = fg or guiID.fg
856
  tmpTable["visible"] = true
857
  tmpTable["x"] = x + guiID.x
858
  tmpTable["data"] = data
859
  tmpTable["min"] = minValue
860
  tmpTable["max"] = maxValue
861
  table.insert(guiID, tmpTable)
862
  return #guiID
863
end
864
865
function gui.getSelected(guiID, listID)
866
  return guiID[listID].selected, guiID[listID].entries[guiID[listID].selected]
867
end
868
869
function gui.setSelected(guiID, listID, selection)
870
  if selection<= #guiID[listID].entries then
871
    guiID[listID].selected = selection
872
    _displayList(guiID, listID)
873
  end
874
end
875
876
function gui.setMax(guiID, widgetID, maxValue)
877
  guiID[widgetID].max = maxValue
878
  _displayProgress(guiID, widgetID)
879
end
880
881
function gui.setChartData(guiID, chartID, data)
882
  guiID[chartID].data = data
883
  _displayChart(guiID, chartID)
884
end
885
886
function gui.setValue(guiID, widgetID, value)
887
  guiID[widgetID].value = value
888
  if guiID[widgetID].type == "progress" then
889
    _displayProgress(guiID, widgetID)
890
  end
891
  if guiID[widgetID].type == "vprogress" then
892
    _displayVProgress(guiID, widgetID)
893
  end
894
  if guiID[widgetID].type == "vslider" then
895
    _displayVslider(guiID, widgetID)
896
  end
897
end
898
899
function gui.resetProgress(guiID, progressID)
900
  guiID[progressID].finished = false
901
  _displayProgress(guiID, progressID)
902
end
903
904
-- sets the text of a widget
905
function gui.setText(guiID, widgetID, text, refresh)
906
  guiID[widgetID].text = text
907
  if guiID[widgetID].type == "text" then
908
    if refresh == nil or refresh == true then
909
      _displayText(guiID, widgetID)
910
    end
911
  end
912
  if guiID[widgetID].type == "label" then
913
    if refresh == nil or refresh == true then
914
      _displayLabel(guiID, widgetID)
915
    end
916
  end
917
  if guiID[widgetID].type == "multiLineLabel" then
918
    if refresh == nil or refresh == true then
919
      _displayMultiLineLabel(guiID, widgetID)
920
    end
921
  end
922
--  gui.displayGui(guiID)
923
end
924
925
function gui.getText(guiID, widgetID)
926
  return guiID[widgetID].text
927
end
928
929
function gui.getCheckboxStatus(guiID, widgetID)
930
  return guiID[widgetID].status
931
end
932
933
function gui.setEnable(guiID, widgetID, state, refresh)
934
  guiID[widgetID].enabled = state
935
  if refresh == nil then
936
    gui.displayGui(guiID)
937
  end
938
  if refresh == true then
939
    gui.displayWidget(guiID, widgetID)
940
  end
941
end
942
943
function gui.setPosition(guiID, widgetID, x, y, refresh)
944
  guiID[widgetID].x = x
945
  guiID[widgetID].y = y
946
  if refresh == nil then
947
    gui.displayGui(guiID)
948
  end
949
  if refresh == true then
950
    gui.displayWidget(guiID, widgetID)
951
  end
952
end
953
954
function gui.setSize(guiID, widgetID, w, h, refresh)
955
  guiID[widgetID].width = w
956
  guiID[widgetID].height = h
957
  guiID[widgetID].w = w
958
  guiID[widgetID].h = h
959
  guiID[widgetID].lenght = w
960
  if refresh == nil then
961
    gui.displayGui(guiID)
962
  end
963
  if refresh == true then
964
    gui.displayWidget(guiID, widgetID)
965
  end
966
end
967
968
function gui.setVisible(guiID, widgetID, state, refresh)
969
  if state == false then
970
    guiID[widgetID].visible = state
971
    guiID[widgetID].enabled = state
972
  elseif state == true then
973
    guiID[widgetID].visible = state
974
  end
975
  if refresh == nil then
976
    gui.displayGui(guiID)
977
  end
978
  if refresh == true then
979
    gui.displayWidget(guiID, widgetID)
980
  end
981
end
982
983
function gui.setBackground(guiID, widgetID, color)
984
  guiID[widgetID].bg = color
985
  if guiID[widgetID].type == "label" then
986
    _displayLabel(guiID, widgetID)
987
  end
988
end
989
function gui.setForeground(guiID, widgetID, color)
990
  guiID[widgetID].fg = color
991
  if guiID[widgetID].type == "label" then
992
    _displayLabel(guiID, widgetID)
993
  end
994
end
995
996
function gui.clearList(guiID, listID)
997
  guiID[listID].entries = {}
998
end
999
1000
function gui.insertList(guiID, listID, value)
1001
  table.insert(guiID[listID].entries, value)
1002
  _displayList(guiID, listID)
1003
end
1004
1005
function gui.removeList(guiID, listID, entry)
1006
  table.remove(guiID[listID].entries, entry)
1007
  _displayList(guiID, listID)
1008
end
1009
1010
function gui.renameList(guiID, listID, entry, newName)
1011
  guiID[listID].entries[entry] = newName
1012
  _displayList(guiID, listID)
1013
end
1014
1015
function gui.getRadio(guiID)
1016
  for i = 1, #guiID do
1017
    if guiID[i].type == "radio" then
1018
      if guiID[i].status == true then
1019
	return i
1020
      end
1021
    end
1022
  end
1023
  return -1
1024
end
1025
1026
function gui.setRadio(guiID, radioID)
1027
  for i = 1, #guiID do
1028
    if guiID[i].type == "radio" then
1029
      guiID[i].status = false 
1030
    end
1031
  end
1032
  guiID[radioID].status = true
1033
  return -1
1034
end
1035
1036
function gui.setCheckbox(guiID, checkboxID, status)
1037
  guiID[checkboxID].status = status
1038
end
1039
1040
local function runInput(guiID, textID)
1041
  local inputText = guiID[textID].text
1042
  gpu.setBackground(colorInputBackground)
1043
  gpu.setForeground(colorInputForeground)
1044
  
1045
  local x = 0
1046
  if guiID[textID].x == "center" then
1047
    x = guiID.x + math.floor((guiID.width / 2)) - math.floor((guiID[textID].fieldLenght) / 2)
1048
  else
1049
    x =guiID.x + guiID[textID].x
1050
  end
1051
1052
  local loopRunning = true
1053
  while loopRunning == true do
1054
    gpu.fill(x, guiID[textID].y, guiID[textID].fieldLenght, 1, " ")
1055
    tmpStr = inputText
1056
    if guiID[textID].hide == true then
1057
      tmpStr = ""
1058
      for i = 1, string.len(inputText) do
1059
	tmpStr = tmpStr .."*"
1060
      end
1061
    end
1062
    if string.len(tmpStr) + 1 > guiID[textID].fieldLenght then
1063
      tmpStr = string.sub(tmpStr, string.len(tmpStr) - guiID[textID].fieldLenght + 2, string.len(tmpStr))
1064
    end
1065
    gpu.set(x, guiID[textID].y, tmpStr .. "_")
1066
    local e, _, character, code = event.pullMultiple(0.1, "key_down", "touch")
1067
    if e == "key_down" then
1068
      if character == 8 then	-- backspace
1069
	inputText = string.sub(inputText, 1, string.len(inputText) - 1)
1070
      elseif character == 13 then 	-- return
1071
	guiID[textID].text = inputText
1072
	if guiID[textID].func then
1073
	  guiID[textID].func(guiID, textID, inputText)
1074
	end
1075
	loopRunning = false
1076
      elseif character > 31 and character < 128 and string.len(inputText) < guiID[textID].lenght then
1077
	inputText = inputText .. string.char(character)
1078
      end
1079
    elseif e == "touch" then
1080
      if character < x or character > (x + guiID[textID].fieldLenght) or guiID[textID].y ~= code then
1081
	guiID[textID].text = inputText
1082
	_displayText(guiID, textID)
1083
	if guiID[textID].func then
1084
	  guiID[textID].func(guiID, textID, inputText)
1085
	end
1086
	loopRunning = false
1087
	computer.pushSignal("touch", _, character, code)
1088
      end
1089
    end
1090
  end
1091
end
1092
1093
1094
function gui.runGui(guiID)
1095
  if displayed == false then
1096
    displayed = true
1097
    gui.displayGui(guiID)
1098
  end
1099
1100
  -- events with out touch
1101
  for i = 1, #guiID do
1102
    if guiID[i].type == "timelabel" then
1103
      _displayTimeLabel(guiID, i)
1104
    elseif guiID[i].type == "datelabel" then
1105
      _displayDateLabel(guiID, i)
1106
    end
1107
  end
1108
  
1109
  local ix = 0
1110
  local e, _, x, y, button = event.pull(0.1, "touch")
1111
  if e == nil then
1112
    return false
1113
  end
1114
  for i = 1, #guiID do
1115
    if guiID[i].type == "button" then
1116
      if guiID[i].x == "center" then
1117
	ix = guiID.x + math.floor((guiID.width / 2)) - math.floor((guiID[i].lenght / 2))
1118
      else
1119
	ix = guiID.x + guiID[i].x
1120
      end
1121
      if x >= ix and x < (ix + guiID[i].lenght) and guiID[i].y == y then
1122
	if guiID[i].func and guiID[i].enabled == true then
1123
	  guiID[i].active = true
1124
	  gui.displayGui(guiID)
1125
	  os.sleep(0.05)
1126
	  guiID[i].active = false
1127
	  gui.displayGui(guiID)
1128
	  guiID[i].func(guiID, i)
1129
	end
1130
      end
1131
    elseif guiID[i].type == "timelabel" then
1132
      _displayTimeLabel(guiID, i)
1133
    elseif guiID[i].type == "checkbox" then
1134
      ix = guiID.x + guiID[i].x + 1
1135
      if x == ix and guiID[i].y == y then
1136
	if guiID[i].enabled == true then
1137
	  if guiID[i].status == true then
1138
	    guiID[i].status = false
1139
	  else
1140
	    guiID[i].status = true
1141
	  end
1142
	  if guiID[i].func then
1143
	    guiID[i].func(guiID, i, guiID[i].status)
1144
	  end
1145
	  _displayCheckbox(guiID, i)
1146
	end
1147
      end
1148
    elseif guiID[i].type == "radio" then
1149
      ix = guiID.x + guiID[i].x + 1
1150
      if x == ix and guiID[i].y == y then
1151
	if guiID[i].enabled == true then
1152
	  for c = 1, #guiID do
1153
	    if guiID[c].type == "radio" then
1154
	      guiID[c].status = false
1155
	      if guiID[i].func then
1156
		guiID[i].func(guiID, i, guiID[i].status)
1157
	      end
1158
	      _displayRadio(guiID, c)
1159
	    end
1160
	  end
1161
	  guiID[i].status = true
1162
	  if guiID[i].func then
1163
	    guiID[i].func(guiID, i, guiID[i].status)
1164
	  end
1165
	  _displayRadio(guiID, i)
1166
	end
1167
      end
1168
    elseif guiID[i].type == "text" then
1169
      if guiID[i].x == "center" then
1170
	ix = guiID.x + math.floor((guiID.width / 2)) - math.floor((guiID[i].lenght / 2))
1171
      else
1172
	ix = guiID.x + guiID[i].x
1173
      end
1174
      if x >= ix and x < (ix + guiID[i].fieldLenght) and guiID[i].y == y then
1175
	if guiID[i].enabled == true then
1176
	  runInput(guiID, i)
1177
	end
1178
      end
1179
    elseif guiID[i].type == "list" and guiID[i].enabled == true then
1180
      if x == guiID[i].x +1 and y == guiID[i].y + guiID[i].height - 1 then
1181
	guiID[i].active = guiID[i].active - guiID[i].height + 2
1182
	if guiID[i].active < 1 then
1183
	  guiID[i].active = 1
1184
	end
1185
	gpu.setBackground(colorListActiveBackground)
1186
	gpu.setForeground(colorListActiveForeground)
1187
	gpu.set(guiID[i].x, guiID[i].y + guiID[i].height - 1, "[<]")
1188
	guiID[i].selected = guiID[i].active
1189
--	_displayList(guiID, i)
1190
1191
	if guiID[i].func then
1192
	  gpu.setBackground(colorButtonClickedBackground)
1193
	  gpu.setForeground(colorButtonClickedForeground)
1194
	  gpu.set(guiID[i].x, guiID[i].y + guiID[i].height - 1, "[<]")
1195
	  os.sleep(0.05)
1196
	  gpu.setBackground(colorListBackground)
1197
	  gpu.setForeground(colorListForeground)
1198
	  gpu.set(guiID[i].x, guiID[i].y + guiID[i].height - 1, "[<]")
1199
	  guiID[i].func(guiID, i, guiID[i].selected, guiID[i].entries[guiID[i].selected])
1200
	end
1201
      end
1202
      if x == guiID[i].x + guiID[i].width - 2 and y == guiID[i].y + guiID[i].height - 1 then
1203
	if guiID[i].active + guiID[i].height - 2 < #guiID[i].entries + 1 then
1204
	  guiID[i].active = guiID[i].active + guiID[i].height - 2
1205
	  guiID[i].selected = guiID[i].active
1206
	end
1207
	gpu.setBackground(colorListActiveBackground)
1208
	gpu.setForeground(colorListActiveForeground)
1209
	gpu.set(guiID[i].x + guiID[i].width - 3, guiID[i].y + guiID[i].height - 1, "[>]")
1210
--	_displayList(guiID, i)
1211
	
1212
	if guiID[i].func then
1213
	  gpu.setBackground(colorButtonClickedBackground)
1214
	  gpu.setForeground(colorButtonClickedForeground)
1215
	  gpu.set(guiID[i].x + guiID[i].width - 3, guiID[i].y + guiID[i].height - 1, "[>]")
1216
	  os.sleep(0.05)
1217
	  gpu.setBackground(colorListBackground)
1218
	  gpu.setForeground(colorListForeground)
1219
	  gpu.set(guiID[i].x + guiID[i].width - 3, guiID[i].y + guiID[i].height - 1, "[>]")
1220
	  guiID[i].func(guiID, i, guiID[i].selected, guiID[i].entries[guiID[i].selected])
1221
	end
1222
      end
1223
      if x > guiID[i].x - 1 and x < guiID[i].x + guiID[i].width and y > guiID[i].y and y < guiID[i].y + guiID[i].height - 1 then
1224
	if guiID[i].active + y - guiID[i].y - 1 <= #guiID[i].entries then
1225
	  guiID[i].selected = guiID[i].active + y - guiID[i].y - 1
1226
--	  _displayList(guiID, i)
1227
	  
1228
	  if guiID[i].func then
1229
	    guiID[i].func(guiID, i, guiID[i].selected, guiID[i].entries[guiID[i].selected])
1230
	  end
1231
	end
1232
      end
1233
	  _displayList(guiID, i)
1234
    elseif guiID[i].type == "chart" and guiID[i].enabled == true then
1235
      _displayChart(guiID, i)
1236
    elseif guiID[i].type == "vslider" and guiID[i].enabled == true then
1237
      ix = guiID.x + guiID[i].x
1238
      if x == ix and y == guiID[i].y and guiID[i].value > guiID[i].min then
1239
	v = guiID[i].value - 1
1240
	gui.setValue(guiID, i, v)
1241
      elseif x == ix + guiID[i].lenght and y == guiID[i].y and guiID[i].value < guiID[i].max then
1242
	v = guiID[i].value + 1
1243
	gui.setValue(guiID, i, v)
1244
      end
1245
      if guiID[i].func then
1246
	guiID[i].func(guiID, i, guiID[i].value)
1247
      end
1248
      _displayVslider(guiID, i)
1249
    end
1250
  end
1251
  
1252
--  gui.displayGui(guiID)
1253
end
1254
1255
errorGui = gui.newGui("center", "center", 40, 10, true, "ERROR", 0xFF0000, 0xFFFF00)
1256
errorMsgLabel1 = gui.newLabel(errorGui, "center", 3, "")
1257
errorMsgLabel2 = gui.newLabel(errorGui, "center", 4, "")
1258
errorMsgLabel3 = gui.newLabel(errorGui, "center", 5, "")
1259
errorButton = gui.newButton(errorGui, "center", 8, "exit", gui.exit)
1260
1261
function gui.showError(msg1, msg2, msg3)
1262
  gui.displayGui(errorGui)
1263
  gui.setText(errorGui, errorMsgLabel1, msg1 or "")
1264
  gui.setText(errorGui, errorMsgLabel2, msg2 or "")
1265
  gui.setText(errorGui, errorMsgLabel3, msg3 or "")
1266
  while true do
1267
    gui.runGui(errorGui)
1268
  end
1269
  gui.closeGui(errorGui)
1270
end
1271
1272
1273
function gui.checkHardware(comp, msg)
1274
  if component.isAvailable(comp) == false then
1275
    compGui = gui.newGui("center", "center", 40, 8, true, nil, 0xFF0000, 0xFFFF00)
1276
    gui.displayGui(compGui)
1277
    gui.newLabel(compGui, "center", 1, "!Component missing!")
1278
    gui.newLabel(compGui, "center", 3, msg)
1279
    gui.newHLine(compGui, 1, 5, 38)
1280
    gui.newButton(compGui, "center", 6, "exit", gui.exit)
1281
    while true do
1282
      gui.runGui(compGui)
1283
    end
1284
  end
1285
end
1286
1287
1288
local msgRunning = true
1289
function msgCallback()
1290
  msgRunning = false
1291
end
1292
1293
msgGui = gui.newGui("center", "center", 40, 10, true, "Info")
1294
msgLabel1 = gui.newLabel(msgGui, "center", 3, "")
1295
msgLabel2 = gui.newLabel(msgGui, "center", 4, "")
1296
msgLabel3 = gui.newLabel(msgGui, "center", 5, "")
1297
msgButton = gui.newButton(msgGui, "center", 8, "ok", msgCallback)
1298
1299
function gui.showMsg(msg1, msg2, msg3)
1300
  gui.displayGui(msgGui)
1301
  gui.setText(msgGui, msgLabel1, msg1 or "")
1302
  gui.setText(msgGui, msgLabel2, msg2 or "")
1303
  gui.setText(msgGui, msgLabel3, msg3 or "")
1304
  msgRunning = true
1305
  while msgRunning == true do
1306
    gui.runGui(msgGui)
1307
  end
1308
  gui.closeGui(msgGui)
1309
end
1310
1311
1312
local yesNoRunning = true
1313
local yesNoValue = false
1314
1315
local function yesNoCallbackYes()
1316
  yesNoRunning = false
1317
  yesNoValue = true
1318
end
1319
local function yesNoCallbackNo()
1320
  yesNoRunning = false
1321
  yesNoValue = false
1322
end
1323
1324
yesNoGui = gui.newGui("center", "center", 40, 10, true, "Question")
1325
yesNoMsgLabel1 = gui.newLabel(yesNoGui, "center", 3, "")
1326
yesNoMsgLabel2 = gui.newLabel(yesNoGui, "center", 4, "")
1327
yesNoMsgLabel3 = gui.newLabel(yesNoGui, "center", 5, "")
1328
yesNoYesButton = gui.newButton(yesNoGui, 3, 8, "yes", yesNoCallbackYes)
1329
yesNoNoButton = gui.newButton(yesNoGui, 33, 8, "no", yesNoCallbackNo)
1330
1331
1332
function gui.getYesNo(msg1, msg2, msg3)
1333
  yesNoRunning = true
1334
  gui.displayGui(yesNoGui)
1335
  gui.setText(yesNoGui, yesNoMsgLabel1, msg1 or "")
1336
  gui.setText(yesNoGui, yesNoMsgLabel2, msg2 or "")
1337
  gui.setText(yesNoGui, yesNoMsgLabel3, msg3 or "")
1338
  while yesNoRunning == true do
1339
    gui.runGui(yesNoGui)
1340
  end
1341
  gui.closeGui(yesNoGui)
1342
  return yesNoValue
1343
end
1344
1345
1346
1347
1348
-- File handling
1349
1350
function gui.splitString(str, sep)
1351
        local sep, fields = sep or ":", {}
1352
        local pattern = string.format("([^%s]+)", sep)
1353
        str:gsub(pattern, function(c) fields[#fields+1] = c end)
1354
        return fields
1355
end
1356
1357
1358
1359
1360
local function convert( chars, dist, inv )
1361
  return string.char( ( string.byte( chars ) - 32 + ( inv and -dist or dist ) ) % 95 + 32 )
1362
end
1363
1364
function gui.string2key(str)
1365
  tmpTable = {}
1366
  for i = 1, string.len(str) do
1367
    tmpTable[i] = string.byte(str,i)
1368
  end
1369
  while #tmpTable < 5 do
1370
    table.insert(tmpTable,100)
1371
  end
1372
  return tmpTable
1373
end
1374
1375
1376
function gui.crypt(str, k, inv)
1377
  if not k then
1378
    k = {1,2,3,4,5}
1379
  end
1380
  while #k < 5 do
1381
    table.insert(k,100)
1382
  end
1383
  local enc= "";
1384
  for i=1,#str do
1385
    if(#str-k[#k] >= i or not inv)then
1386
      for inc=0,3 do
1387
	if(i%4 == inc)then
1388
	  enc = enc .. convert(string.sub(str,i,i),k[inc+1],inv);
1389
	  break;
1390
	end
1391
      end
1392
    end
1393
  end
1394
  if(not inv)then
1395
    for i=1,k[#k] do
1396
      enc = enc .. string.char(math.random(32,126));
1397
    end
1398
  end
1399
  return enc;
1400
end
1401
1402
--// exportstring( string )
1403
--// returns a "Lua" portable version of the string
1404
function exportstring( s )
1405
	s = string.format( "%q",s )
1406
	-- to replace
1407
	s = string.gsub( s,"\\\n","\\n" )
1408
	s = string.gsub( s,"\r","\\r" )
1409
	s = string.gsub( s,string.char(26),"\"..string.char(26)..\"" )
1410
	return s
1411
end
1412
--// The Save Function
1413
function gui.saveTable(tbl,filename )
1414
	local charS,charE = "   ","\n"
1415
	local file,err
1416
	-- create a pseudo file that writes to a string and return the string
1417
	if not filename then
1418
		file =  { write = function( self,newstr ) self.str = self.str..newstr end, str = "" }
1419
		charS,charE = "",""
1420
	-- write table to tmpfile
1421
	elseif filename == true or filename == 1 then
1422
		charS,charE,file = "","",io.tmpfile()
1423
	-- write table to file
1424
	-- use io.open here rather than io.output, since in windows when clicking on a file opened with io.output will create an error
1425
	else
1426
		file,err = io.open( filename, "w" )
1427
		if err then 
1428
		  print ("Gui-lib: Error saving table " .. filename .." -> " .. err)
1429
		  return _,err 
1430
		end
1431
	end
1432
	-- initiate variables for save procedure
1433
	local tables,lookup = { tbl },{ [tbl] = 1 }
1434
	file:write( "return {"..charE )
1435
	for idx,t in ipairs( tables ) do
1436
		if filename and filename ~= true and filename ~= 1 then
1437
			file:write( "-- Table: {"..idx.."}"..charE )
1438
		end
1439
		file:write( "{"..charE )
1440
		local thandled = {}
1441
		for i,v in ipairs( t ) do
1442
			thandled[i] = true
1443
			-- escape functions and userdata
1444
			if type( v ) ~= "userdata" then
1445
				-- only handle value
1446
				if type( v ) == "table" then
1447
					if not lookup[v] then
1448
						table.insert( tables, v )
1449
						lookup[v] = #tables
1450
					end
1451
					file:write( charS.."{"..lookup[v].."},"..charE )
1452
				elseif type( v ) == "function" then
1453
					file:write( charS.."loadstring("..exportstring(string.dump( v )).."),"..charE )
1454
				else
1455
					local value =  ( type( v ) == "string" and exportstring( v ) ) or tostring( v )
1456
					file:write(  charS..value..","..charE )
1457
				end
1458
			end
1459
		end
1460
		for i,v in pairs( t ) do
1461
			-- escape functions and userdata
1462
			if (not thandled[i]) and type( v ) ~= "userdata" then
1463
				-- handle index
1464
				if type( i ) == "table" then
1465
					if not lookup[i] then
1466
						table.insert( tables,i )
1467
						lookup[i] = #tables
1468
					end
1469
					file:write( charS.."[{"..lookup[i].."}]=" )
1470
				else
1471
					local index = ( type( i ) == "string" and "["..exportstring( i ).."]" ) or string.format( "[%d]",i )
1472
					file:write( charS..index.."=" )
1473
				end
1474
				-- handle value
1475
				if type( v ) == "table" then
1476
					if not lookup[v] then
1477
						table.insert( tables,v )
1478
						lookup[v] = #tables
1479
					end
1480
					file:write( "{"..lookup[v].."},"..charE )
1481
				elseif type( v ) == "function" then
1482
					file:write( "loadstring("..exportstring(string.dump( v )).."),"..charE )
1483
				else
1484
					local value =  ( type( v ) == "string" and exportstring( v ) ) or tostring( v )
1485
					file:write( value..","..charE )
1486
				end
1487
			end
1488
		end
1489
		file:write( "},"..charE )
1490
	end
1491
	file:write( "}" )
1492
	-- Return Values
1493
	-- return stringtable from string
1494
	if not filename then
1495
		-- set marker for stringtable
1496
		return file.str.."--|"
1497
	-- return stringttable from file
1498
	elseif filename == true or filename == 1 then
1499
		file:seek ( "set" )
1500
		-- no need to close file, it gets closed and removed automatically
1501
		-- set marker for stringtable
1502
		return file:read( "*a" ).."--|"
1503
	-- close file and return 1
1504
	else
1505
		file:close()
1506
		return 1
1507
	end
1508
end
1509
 
1510
--// The Load Function
1511
function gui.loadTable( sfile )
1512
	local tables, err, _
1513
1514
	-- catch marker for stringtable
1515
	if string.sub( sfile,-3,-1 ) == "--|" then
1516
		tables,err = loadstring( sfile )
1517
	else
1518
		tables,err = loadfile( sfile )
1519
	end
1520
	if err then 
1521
	  print("Gui-lib: Error loading table " ..sfile .. " -> " ..err)
1522
	  return _,err
1523
	end
1524
	tables = tables()
1525
	for idx = 1,#tables do
1526
		local tolinkv,tolinki = {},{}
1527
		for i,v in pairs( tables[idx] ) do
1528
			if type( v ) == "table" and tables[v[1]] then
1529
				table.insert( tolinkv,{ i,tables[v[1]] } )
1530
			end
1531
			if type( i ) == "table" and tables[i[1]] then
1532
				table.insert( tolinki,{ i,tables[i[1]] } )
1533
			end
1534
		end
1535
		-- link values, first due to possible changes of indices
1536
		for _,v in ipairs( tolinkv ) do
1537
			tables[idx][v[1]] = v[2]
1538
		end
1539
		-- link indices
1540
		for _,v in ipairs( tolinki ) do
1541
			tables[idx][v[2]],tables[idx][v[1]] =  tables[idx][v[1]],nil
1542
		end
1543
	end
1544
	return tables[1]
1545
end
1546
1547
function gui.sepString(str)
1548
  tmpTable = {}
1549
  for i = 1, string.len(str) do
1550
    tmpTable[i] = string.char(string.byte(str,i))
1551
  end
1552
  return tmpTable
1553
end
1554
1555
1556
1557
1558
1559
1560
return gui