rutui 0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+