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