rutui 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. data/rutui.rb +550 -0
  2. metadata +66 -0
data/rutui.rb ADDED
@@ -0,0 +1,550 @@
1
+ #
2
+ # Generated one file script of rutui
3
+ # This file is commandless and stripped down
4
+ # For full source please visit:
5
+ # https://github.com/b1nary/rutui
6
+ #
7
+ # Author: Roman Pramberger (roman.pramberger@gmail.com)
8
+ # License: MIT
9
+ #
10
+ # Son Jul 22 16:26:42 CEST 2012
11
+ #
12
+ class RuTui
13
+ class Color
14
+ # Calculate color from RGB values
15
+ def self.rgb(red, green, blue); 16 + (red * 36) + (green * 6) + blue; end
16
+ # Set background color
17
+ def self.bg color; "\x1b[48;5;#{color}m"; end
18
+ # Set text color
19
+ def self.fg color; "\x1b[38;5;#{color}m"; end
20
+ # "Shortcut" to background color
21
+ def self.background color; self.bg color; end
22
+ # "Shortcut" to foreground/text color
23
+ def self.foreground color; self.fg color; end
24
+ # Clear all color
25
+ def self.clear_color; "\x1b[0m"; end
26
+ # Clear Screen/Terminal
27
+ def self.clear; "\e[2J\e[1;1H"; end
28
+ end
29
+ class Utils
30
+ # Get Windows size
31
+ def self.winsize
32
+ # > Ruby 1.9.3
33
+ #require 'io/console'
34
+ #IO.console.winsize
35
+ #rescue LoadError
36
+ # unix only but each ruby
37
+ [Integer(`tput lines`), Integer(`tput cols`)]
38
+ #if !ENV["LINES"].nil?
39
+ # [ENV["LINES"], ENV["COLUMNS"]]
40
+ #else
41
+ # [Integer(`tput lines`), Integer(`tput cols`)]
42
+ #end
43
+ end
44
+ # Get input char without enter
45
+ # UNIX only!
46
+ def self.gets
47
+ # Win32API.new("crtdll", "_getch", [], "L").Call).chr
48
+ begin
49
+ system("stty raw -echo")
50
+ str = STDIN.getc
51
+ ensure
52
+ system("stty -raw echo")
53
+ end
54
+ return str
55
+ end
56
+ # Hides the cursor
57
+ def self.init
58
+ system("tput civis")
59
+ end
60
+ # Brings the cursor back
61
+ def self.clear
62
+ system("tput cnorm")
63
+ end
64
+ end
65
+ class BaseObject
66
+ attr_accessor :x, :y, :width, :height, :obj
67
+ # Ex.: BaseObject.new({ :x => 1, :y => 20, :obj => [[Pixel.new(1),Pixel.new(2,4,"#")]] })
68
+ def initialize options
69
+ @obj = options[:obj]
70
+ @obj = Array.new(height){ Array.new(width) } if @obj.nil?
71
+ @x = options[:x]
72
+ @y = options[:y]
73
+ @height = @obj.size
74
+ @width = @obj[0].size
75
+ end
76
+ # Move object X and Y (modifiers like: -2, 2)
77
+ def move x, y; @x += x; @y += y; end
78
+ # Set object position X Y
79
+ def set_position x, y; @x = x; @y = y; end
80
+ # Set pixel on position on object
81
+ def set_pixel x, y, pixel
82
+ @obj[x][y] = pixel if !@obj[x].nil? and !@obj[x][y].nil?
83
+ end
84
+ # "special" each methods for objects
85
+ def each
86
+ @obj.each_with_index do |row,row_count|
87
+ row.each_with_index do |pixel,col_count|
88
+ yield row_count, col_count, pixel
89
+ end
90
+ end
91
+ end
92
+ end
93
+ class Box < RuTui::BaseObject
94
+ attr_accessor :fill, :width, :height, :vertical, :horizontal, :corner
95
+ # initialize object (see above)
96
+ def initialize options
97
+ @x = options[:x]
98
+ @y = options[:y]
99
+ @width = options[:width]
100
+ @height = options[:height]
101
+ return if @x.nil? or @y.nil? or @width.nil? or @height.nil?
102
+ @fill = options[:fill]
103
+ @vertical = options[:vertical]
104
+ @horizontal = options[:horizontal]
105
+ @corner = options[:corner]
106
+ @horizontal = Pixel.new(3,0,"-") if options[:horizontal].nil?
107
+ @vertical = Pixel.new(3,0,"|") if options[:vertical].nil?
108
+ @corner = Pixel.new(3,0,"*") if options[:corner].nil?
109
+ @width = 3 if @width < 3
110
+ @height = 3 if @height < 3
111
+ create
112
+ end
113
+ # Create Box
114
+ # can be recalled any time on attribute changes
115
+ def create
116
+ if !@fill.nil?
117
+ backpixel = Pixel.new(@fill.fg,@fill.bg,@fill.symbol)
118
+ obj = Array.new(@height){ Array.new(@width) { backpixel } }
119
+ else
120
+ obj = Array.new(@height){ Array.new(@width) }
121
+ end
122
+ (@width-2).times do |i|
123
+ obj[0][i+1] = @horizontal
124
+ obj[@height-1][i+1] = @horizontal
125
+ end
126
+ (@height-2).times do |i|
127
+ obj[i+1][0] = @vertical
128
+ obj[i+1][@width-1] = @vertical
129
+ end
130
+ obj[0][0] = @corner
131
+ obj[0][@width-1] = @corner
132
+ obj[@height-1][0] = @corner
133
+ obj[@height-1][@width-1] = @corner
134
+ @height = obj.size
135
+ @width = obj[0].size
136
+ @obj = obj
137
+ end
138
+ end
139
+ class Line < BaseObject
140
+ attr_accessor :length, :pixel, :endpixel, :direction
141
+ def initialize options
142
+ @x = options[:x]
143
+ @y = options[:y]
144
+ @length = options[:length]
145
+ @direction = options[:direction]
146
+ @direction = :horizontal if @direction.nil?
147
+ return if @x.nil? or @y.nil? or @width.nil?
148
+ @pixel = options[:pixel]
149
+ @endpixel = options[:endpixel]
150
+ @pixel = Pixel.new(2) if @pixel.nil?
151
+ create
152
+ end
153
+ # Create Line
154
+ # can be recalled any time on attribute changes
155
+ def create
156
+ if @direction == :horizontal
157
+ @obj = [Array.new(@length){ @pixel }]
158
+ else
159
+ @obj = Array.new(@length){ [@pixel] }
160
+ end
161
+ if !@endpixel.nil?
162
+ @obj[0][0] = @endpixel
163
+ @obj[0][@length-1] = @endpixel
164
+ end
165
+ end
166
+ end
167
+ class Circle < BaseObject
168
+ attr_accessor :radius, :pixel, :fill
169
+ # Initialize circle (see above)
170
+ def initialize options
171
+ @x = options[:x]
172
+ @y = options[:y]
173
+ @radius = options[:radius]
174
+ @pixel = options[:pixel]
175
+ @fill = options[:fill_pixel]
176
+ return if @x.nil? or @y.nil? or @radius.nil?
177
+ @width = options[:radius]*2 # needed?
178
+ @height = @width # needed?
179
+ create
180
+ end
181
+ # Create Circle
182
+ # can be recalled any time on attribute changes
183
+ def create
184
+ obj = []
185
+ (0..(@radius*2)).each do |x|
186
+ (0..(@radius*2)).each do |y|
187
+ obj[y] = [] if obj[y].nil?
188
+ obj[y][x] = distance_from_center(x,y).round == @radius ? @pixel : @fill
189
+ end
190
+ end
191
+ @obj = obj
192
+ end
193
+ private
194
+ def distance_from_center(x,y)
195
+ a = calc_side(x)
196
+ b = calc_side(y)
197
+ return Math.sqrt(a**2 + b**2)
198
+ end
199
+ def calc_side(z)
200
+ z < @radius ? (@radius - z) : (z - @radius)
201
+ end
202
+ end
203
+ class Text < BaseObject
204
+ attr_accessor :bg, :fg, :text, :do_rainbow
205
+ @@rainbow = [1,3,11,2,4,5]
206
+ def initialize options
207
+ @do_rainbow = options[:rainbow]
208
+ @text = options[:text]
209
+ @x = options[:x]
210
+ @y = options[:y]
211
+ @bg = options[:background]
212
+ @fg = options[:foreground]
213
+ @bg = 236 if @bg.nil?
214
+ @fg = 245 if @fg.nil?
215
+ return if @x.nil? or @y.nil?
216
+ @height = 1
217
+ create
218
+ end
219
+ # Create Text
220
+ # can be recalled any time on attribute changes
221
+ def create
222
+ if @do_rainbow
223
+ rainbow = 0
224
+ end
225
+ @width = @text.size
226
+ @obj = []
227
+ tmp = []
228
+ @text.split("").each do |t|
229
+ if @do_rainbow
230
+ tmp << Pixel.new(@@rainbow[rainbow],@bg,t)
231
+ rainbow += 1
232
+ rainbow = 0 if rainbow >= @@rainbow.size
233
+ else
234
+ tmp << Pixel.new(@fg,@bg,t)
235
+ end
236
+ end
237
+ @obj << tmp
238
+ end
239
+ def set_text text
240
+ @text = text
241
+ create
242
+ end
243
+ end
244
+ class Pixel
245
+ attr_accessor :fg, :bg, :symbol
246
+ def initialize foreground = 15, background = nil, symbol = " "
247
+ @fg = foreground
248
+ @bg = background
249
+ @symbol = symbol
250
+ end
251
+ def self.random sym = "#"
252
+ Pixel.new(rand(255),rand(255),sym)
253
+ end
254
+ end
255
+ class Screen
256
+ # Initialize me with a default pixel, if you want
257
+ def initialize default_pixel = Pixel.new(238,236,":")
258
+ size = Utils.winsize
259
+ @smap = Array.new(size[0]){ Array.new(size[1]) }
260
+ @map = @smap.dup
261
+ @default = default_pixel
262
+ @objects = []
263
+ @statics = []
264
+ # Set as default if first screen
265
+ ScreenManager.add :default, self if ScreenManager.size == 0
266
+ end
267
+ # regen screen (size change?)
268
+ def rescreen
269
+ size = Utils.winsize
270
+ @smap = Array.new(size[0]){ Array.new(size[1]) }
271
+ @statics.each do |s|
272
+ self.add_static s
273
+ end
274
+ @map = @smap.dup
275
+ end
276
+ # Set default/background pixel
277
+ # Ex.: screen.set_default Pixel.new(244,1,";")
278
+ def set_default pixel
279
+ @default = pixel
280
+ end
281
+ # Get default/background pixel
282
+ def get_default
283
+ @default
284
+ end
285
+ # add object that doesnt change over time
286
+ def add_static object
287
+ @statics << object if !@statics.include? object
288
+ object.each do |ri,ci,pixel|
289
+ @smap[object.y+ri][object.x+ci] = pixel if !pixel.nil? and object.y+ri > 0 and object.y+ci > 0
290
+ end
291
+ end
292
+ # add dynamic object
293
+ def add object
294
+ @objects << object
295
+ end
296
+ # draw the pixel-screen map
297
+ def draw
298
+ lastpixel = Pixel.new(rand(255), rand(255), ".")
299
+ @map = Marshal.load( Marshal.dump( @smap )) # Deep copy
300
+ # get all the objects
301
+ @objects.each do |o|
302
+ next if o.x.nil? or o.y.nil?
303
+ o.each do |ri,ci,pixel|
304
+ @map[o.y + ri][o.x + ci] = pixel if !pixel.nil? and o.y+ri > 0 and o.x+ci > 0 and o.y+ri < @map.size and o.x+ci < @map[0].size
305
+ end
306
+ end
307
+ # an DRAW!
308
+ @map.each do |line|
309
+ line.each do |pixel|
310
+ if pixel != lastpixel
311
+ print Color.clear_color if lastpixel != 0
312
+ if pixel.nil?
313
+ lastpixel = pixel
314
+ print "#{Color.bg(@default.bg)}#{Color.fg(@default.fg)}#{@default.symbol}"
315
+ else
316
+ lastpixel = pixel
317
+ print "#{Color.bg(pixel.bg)}#{Color.fg(pixel.fg)}#{pixel.symbol}"
318
+ end
319
+ else
320
+ if pixel.nil?
321
+ print @default.symbol
322
+ else
323
+ print pixel.symbol
324
+ end
325
+ end
326
+ end
327
+ end
328
+ end
329
+ end
330
+ class ScreenManager
331
+ @@screens = {}
332
+ @@current = :default
333
+ # Set a screen
334
+ # Ex.: ScreenManager.set :default, Screen.new
335
+ def self.add name, screen
336
+ @@screens[name] = screen
337
+ end
338
+ # Get count of existing screens
339
+ def self.size
340
+ @@screens.size
341
+ end
342
+ # Delete screen by name
343
+ def self.delete name
344
+ @@screens.delete(name) if !@@screens[name].nil?
345
+ end
346
+ # Set current screen
347
+ def self.set_current name
348
+ @@current = name
349
+ end
350
+ # Get current screen
351
+ def self.get_current
352
+ # Fix size and others of screen here
353
+ @@current
354
+ end
355
+ # Get the complete screen by name
356
+ def self.get_screen name
357
+ @@screens[name]
358
+ end
359
+ # Refit screen size
360
+ def refit
361
+ size = Utils.winsize
362
+ if @autofit or size != @lastsize
363
+ File.open("log.log", 'w') {|f| f.write("#{size[0]}-#{size[1]}\n") }
364
+ @@screens[@@current].rescreen
365
+ @lastsize = size
366
+ end
367
+ end
368
+ # draw current screen
369
+ def self.draw
370
+ print Color.clear
371
+ @@screens[@@current].draw
372
+ end
373
+ # Raw Game Loop
374
+ # Ex.: ScreenManager.loop({ :autodraw => true, :autofit => true }){ |key| p key }
375
+ def self.loop options
376
+ autodraw = options[:autodraw]
377
+ @autofit = options[:autofit]
378
+ @lastsize = nil
379
+ Utils.init
380
+ ScreenManager.draw
381
+ while true
382
+ key = Utils.gets
383
+ yield key
384
+ ScreenManager.refit if @autofit
385
+ ScreenManager.draw if autodraw
386
+ end
387
+ end
388
+ end
389
+ class Figlet < BaseObject
390
+ attr_accessor :text, :rainbow, :font, :colors
391
+ # Figlet font: '!" #$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz[|]~ÄÖÜäöüß'
392
+ @@chars = '!!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz[|]~ÄÖÜäöüß'.split("")
393
+ @@rainbow = [1,3,11,2,4,5]
394
+ @@fonts = {}
395
+ # Initialize (see above)
396
+ def initialize options
397
+ @x = options[:x]
398
+ @y = options[:y]
399
+ return if @x.nil? or @y.nil?
400
+ @font = options[:font]
401
+ @text = options[:text]
402
+ @rainbow = options[:rainbow]
403
+ @space = options[:space]
404
+ @space = 0 if @space.nil?
405
+ @colors = options[:colors]
406
+ @colors = [Pixel.new(15)] if @colors.nil?
407
+ create
408
+ end
409
+
410
+ # Create Figlet text object
411
+ # Recall it any time when attributes have changed
412
+ def create
413
+ obj = []
414
+ @@fonts[@font]['n'].size.times do
415
+ obj << []
416
+ end
417
+ p obj
418
+ current = 0
419
+ p @@fonts[@font]['F']
420
+ p @@fonts[@font]['L']
421
+ count = 0
422
+ @text.each_byte do |c|
423
+ if @@chars.include? c.chr
424
+ @@fonts[@font][c.chr].each_with_index do |fr,ri|
425
+ fr.each do |fc|
426
+ if @rainbow
427
+ obj[ri] << Pixel.new(@@rainbow[current], @colors[0].bg,fc)
428
+ else
429
+ obj[ri] << Pixel.new(@colors[current].fg,@colors[current].bg,fc)
430
+ end
431
+ if @rainbow != true
432
+ current += 1 if @colors.size > 1
433
+ current = 0 if current > @colors.size
434
+ end
435
+ end
436
+ end
437
+ if @rainbow
438
+ current += 1
439
+ current = 0 if current >= @@rainbow.size
440
+ end
441
+ if count < @text.size-1
442
+ @@fonts[@font]['n'].size.times do |ri|
443
+ @space.times do
444
+ if @rainbow
445
+ obj[ri] << Pixel.new(@@rainbow[current], @colors[0].bg," ")
446
+ else
447
+ obj[ri] << Pixel.new(@colors[current].fg,@colors[current].bg," ")
448
+ end
449
+ end
450
+ end
451
+ end
452
+ # SPace
453
+ elsif c.chr == " "
454
+ @@fonts[@font]['n'].size.times do |ri|
455
+ 3.times do
456
+ if @rainbow
457
+ obj[ri] << Pixel.new(@@rainbow[current], @colors[0].bg," ")
458
+ else
459
+ obj[ri] << Pixel.new(@colors[current].fg,@colors[current].bg," ")
460
+ end
461
+ end
462
+ end
463
+ end
464
+ count += 1
465
+ end
466
+ @obj = obj
467
+ end
468
+ # Static methods to add/load new Fonts
469
+ def self.add name, file
470
+ if File.exists?(file)
471
+ data = File.new(file, "r").read.split("\n")
472
+ config = data[0].split(" ")
473
+ # Remove Comments (Size is in info line)
474
+ config[5].to_i.times do
475
+ data.delete_at(0)
476
+ end
477
+ # Remove empty line if exist
478
+ data.delete_at(0) if data[0].strip() == ""
479
+ height = config[2].to_i
480
+ rest = config[1].to_i - height
481
+ @@fonts[name] = {}
482
+
483
+ @@chars.each do |i|
484
+ out = []
485
+ (data.delete_at(0); rest -= 1) if data.size > 0 and data[0].gsub('$@','').gsub(' ','') == ''
486
+ height.times do |x|
487
+ break if data.size < 1
488
+ xdata = data[0].gsub("$"," ").gsub("@","").gsub("\r","").split("")
489
+ out << xdata if xdata.size > 0
490
+ data.delete_at(0)
491
+ end
492
+ rest.times do
493
+ data.delete_at(0)
494
+ end
495
+ @@fonts[name][i] = out
496
+ end
497
+ return true
498
+ else
499
+ return false
500
+ end
501
+ end
502
+ end
503
+ class Axx < BaseObject
504
+ def initialize options
505
+ @x = options[:x]
506
+ @y = options[:y]
507
+ @file = options[:file]
508
+ @attr, @xx, @yy, @save_x, @save_y, @attr = 0,0,0,0,0,0
509
+ return if @x.nil? or @y.nil? or @file.nil?
510
+ return if !File.exists? @file
511
+ @img = File.open(@file).read
512
+ self.parse
513
+ end
514
+ def parse
515
+
516
+ end
517
+ end
518
+ class Axx < BaseObject
519
+ def initialize options
520
+ @x = options[:x]
521
+ @y = options[:y]
522
+ @file = options[:file]
523
+ @attr, @xx, @yy, @save_x, @save_y, @attr = 0,0,0,0,0,0
524
+ return if @x.nil? or @y.nil? or @file.nil?
525
+ return if !File.exists? @file
526
+ @img = File.open(@file).read
527
+ p @img
528
+ parse
529
+ end
530
+ def parse
531
+ out = []
532
+ @img.split("\n").each_with_index do |line,li|
533
+ out[li] << []
534
+ line.split("|").each_with_index do |elem,ei|
535
+ ele = elem.split(";")
536
+ if ele.size == 3
537
+ out[li][ei] = Pixel.new(elem[1].to_i,elem[2].to_i,elem[0])
538
+ elsif ele.size == 2
539
+ out[li][ei] = Pixel.new(elem[1].to_i,nil,elem[0])
540
+ else
541
+ out[li][ei] = Pixel.new(nil,nil,elem[0])
542
+ end
543
+ end
544
+ end
545
+ @obj = out
546
+ @height = out.size
547
+ @width = out[0].size
548
+ end
549
+ end
550
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rutui
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ version: "0.1"
10
+ platform: ruby
11
+ authors:
12
+ - Roman Pramberger
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-07-22 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Create Pure Ruby textbased interfaces of all kinds (Unix only)
22
+ email: roman.pramberger@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - rutui.rb
31
+ has_rdoc: true
32
+ homepage: http://rubygems.org/gems/rutui
33
+ licenses: []
34
+
35
+ post_install_message:
36
+ rdoc_options: []
37
+
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ hash: 3
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.7
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: RUby Textbased User Interface
65
+ test_files: []
66
+