rutui 0.3.1 → 0.4

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.
data/lib/rutui.rb ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ #
4
+ # https://github.com/b1nary/rutui
5
+ #
6
+ # Author: Roman Pramberger (roman@pramberger.ch)
7
+ # License: MIT
8
+ #
9
+ require 'rutui/util'
10
+ require 'rutui/pixel'
11
+ require 'rutui/theme'
12
+ require 'rutui/objects'
13
+ require 'rutui/screen'
14
+ require 'rutui/screenmanager'
15
+ require 'rutui/figlet'
16
+ require 'rutui/axx'
17
+ require 'rutui/sprites'
18
+ require 'rutui/table'
19
+ require 'rutui/textfield'
20
+
21
+ module RuTui
22
+ Ansi = ::Ansi
23
+ Utils = ::Utils
24
+ Pixel = ::Pixel
25
+ Theme = ::Theme
26
+ BaseObject = ::BaseObject
27
+ Box = ::Box
28
+ Line = ::Line
29
+ Circle = ::Circle
30
+ Text = ::Text
31
+ Screen = ::Screen
32
+ ScreenManager = ::ScreenManager
33
+ Figlet = ::Figlet
34
+ Axx = ::Axx
35
+ Sprite = ::Sprite
36
+ Table = ::Table
37
+ Textfield = ::Textfield
38
+ end
data/lib/rutui/axx.rb ADDED
@@ -0,0 +1,86 @@
1
+ ## Basic Ascii Image format Axx
2
+ # First implemented: here :3
3
+ #
4
+ # Example:
5
+ # # Comments ...
6
+ # nil|A:1:0|A|A:2
7
+ #
8
+ # nil empty pixel
9
+ # A:1:0 Char is A, 1 is foreground, 0 is background
10
+ # A Char only (colors default)
11
+ # A:2 Char A, Foreground 2, Background default
12
+ #
13
+ class Axx < BaseObject
14
+ def initialize options
15
+ @file = options[:file]
16
+ @x = options[:x]
17
+ @y = options[:y]
18
+
19
+ return if @file.nil?
20
+ return if !File.exists? @file
21
+
22
+ @img = File.open(@file).read
23
+
24
+ parse
25
+ end
26
+
27
+ def parse
28
+ out = []
29
+ @img.split("\n").each_with_index do |line,li|
30
+ if !line.match(/^#/)
31
+ out[li] = []
32
+ line.split("|").each_with_index do |elem,ei|
33
+ ele = elem.split(":")
34
+ if ele.size == 3
35
+ out[li][ei] = Pixel.new(ele[1].to_i,ele[2].to_i,ele[0])
36
+ elsif ele.size == 2
37
+ out[li][ei] = Pixel.new(ele[1].to_i,nil,ele[0])
38
+ else
39
+ if ele[0] == "nil"
40
+ out[li][ei] = nil
41
+ else
42
+ out[li][ei] = Pixel.new(nil,nil,ele[0])
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ out.each do |o|
50
+ out.delete(o) if o.nil?
51
+ end
52
+ @obj = out
53
+ @height = out.size
54
+ @width = out.size
55
+ end
56
+
57
+ def self.parse data
58
+ out = []
59
+ data.split("\n").each_with_index do |line,li|
60
+ if !line.match(/^#/)
61
+ out[li] = []
62
+ line.split("|").each_with_index do |elem,ei|
63
+ ele = elem.split(":")
64
+ if ele.size == 3
65
+ out[li][ei] = Pixel.new(ele[1].to_i,ele[2].to_i,ele[0])
66
+ elsif ele.size == 2
67
+ out[li][ei] = Pixel.new(ele[1].to_i,nil,ele[0])
68
+ else
69
+ if ele[0] == "nil"
70
+ out[li][ei] = nil
71
+ else
72
+ out[li][ei] = Pixel.new(nil,nil,ele[0])
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ out.each do |o|
80
+ out.delete(o) if o.nil? or o == []
81
+ end
82
+ return out
83
+ end
84
+
85
+ end
86
+
@@ -0,0 +1,158 @@
1
+ # encoding: UTF-8
2
+ ## Figlet Class
3
+ # parse Figlet Font files
4
+ #
5
+ # Attributes (All accessable):
6
+ # :x MUST
7
+ # :y MUST
8
+ # :text Your text
9
+ # :font Use a loaded font file
10
+ # :rainbow true|any
11
+ # :colors Array of example pixels used for colors
12
+ #
13
+ #
14
+ # Example:
15
+ # Figlet.add :test, "path/to/font.flf"
16
+ # Figlet.new({ :text => "Meh", :font => :test, :rainbow => true })
17
+ #
18
+ # Config content (just to remember what the figlet slug means)
19
+ # 0 - name
20
+ # 1 - height of a character
21
+ # 2 - height of a character, not including descenders
22
+ # 3 - max line length (excluding comment lines) + a fudge factor
23
+ # 4 - default smushmode for this font (like "-m 0" on command line)
24
+ # 5 - number of comment lines
25
+ # 6 - rtol
26
+ #
27
+ class Figlet < BaseObject
28
+ attr_accessor :text, :rainbow, :font, :colors
29
+ # Figlet font: '!" #$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz[|]~ÄÖÜäöüß'
30
+ @@chars = '!!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz[|]~ÄÖÜäöüß'.split("")
31
+ @@rainbow = nil
32
+ @@fonts = {}
33
+
34
+ # Initialize (see above)
35
+ def initialize options
36
+ @x = options[:x]
37
+ @y = options[:y]
38
+
39
+ @@rainbow = Theme.get(:rainbow) if @@rainbow.nil?
40
+
41
+ return if @x.nil? or @y.nil?
42
+
43
+ @font = options[:font]
44
+ @text = options[:text]
45
+ @rainbow = options[:rainbow]
46
+ @space = options[:space]
47
+ @space = 0 if @space.nil?
48
+ @colors = options[:colors]
49
+ @colors = [Pixel.new(Theme.get(:textcolor), Theme.get(:background).bg, Theme.get(:background).symbol)] if @colors.nil?
50
+
51
+ create
52
+ end
53
+
54
+ # Create Figlet text object
55
+ # Recall it any time when attributes have changed
56
+ def create
57
+ obj = []
58
+ @@fonts[@font]['n'].size.times do
59
+ obj << []
60
+ end
61
+ current = 0
62
+
63
+ count = 0
64
+ @text.each_byte do |c|
65
+ if @@chars.include? c.chr
66
+ @@fonts[@font][c.chr].each_with_index do |fr,ri|
67
+ fr.each do |fc|
68
+ if @rainbow
69
+ obj[ri] << Pixel.new(@@rainbow[current], @colors[0].bg,fc)
70
+ else
71
+ obj[ri] << Pixel.new(@colors[current].fg,@colors[current].bg,fc)
72
+ end
73
+
74
+ if @rainbow != true
75
+ current += 1 if @colors.size > 1
76
+ current = 0 if current > @colors.size
77
+ end
78
+ end
79
+ end
80
+
81
+ if @rainbow
82
+ current += 1
83
+ current = 0 if current >= @@rainbow.size
84
+ end
85
+
86
+ if count < @text.size-1
87
+ @@fonts[@font]['n'].size.times do |ri|
88
+ @space.times do
89
+ if @rainbow
90
+ obj[ri] << Pixel.new(@@rainbow[current], @colors[0].bg,Theme.get(:background).symbol)
91
+ else
92
+ obj[ri] << Pixel.new(@colors[current].fg,@colors[current].bg,Theme.get(:background).symbol)
93
+ end
94
+ end
95
+ end
96
+ end
97
+ # SPace
98
+ else
99
+ @@fonts[@font]['n'].size.times do |ri|
100
+ 3.times do
101
+ if @rainbow
102
+ obj[ri] << Pixel.new(@@rainbow[current], @colors[0].bg, Theme.get(:background).symbol)
103
+ else
104
+ obj[ri] << Pixel.new(@colors[current].fg,@colors[current].bg, Theme.get(:background).symbol)
105
+ end
106
+ end
107
+ end
108
+ end
109
+ count += 1
110
+ end
111
+ @obj = obj
112
+ end
113
+
114
+ # Static methods to add/load new Fonts
115
+ def self.add name, file
116
+ if File.exists?(file)
117
+
118
+ data = File.new(file, "r").read.split("\n")
119
+ config = data[0].split(" ")
120
+
121
+ # Remove Comments (Size is in info line)
122
+ config[5].to_i.times do
123
+ data.delete_at(0)
124
+ end
125
+
126
+ # Remove empty line if exist
127
+ data.delete_at(0) if data[0].strip() == ""
128
+
129
+ height = config[2].to_i
130
+ rest = config[1].to_i - height
131
+
132
+ @@fonts[name] = {}
133
+
134
+ @@chars.each do |i|
135
+ out = []
136
+
137
+ (data.delete_at(0); rest -= 1) if data.size > 0 and data[0].gsub('$@','').gsub(' ','') == ''
138
+
139
+ height.times do |x|
140
+ break if data.size < 1
141
+ xdata = data[0].gsub("$"," ").gsub("@","").gsub("\r","").split("")
142
+ out << xdata if xdata.size > 0
143
+ data.delete_at(0)
144
+ end
145
+
146
+ rest.times do
147
+ data.delete_at(0)
148
+ end
149
+
150
+ @@fonts[name][i] = out
151
+ end
152
+ return true
153
+ else
154
+ return false
155
+ end
156
+ end
157
+ end
158
+
@@ -0,0 +1,285 @@
1
+ # This class contains different Objects
2
+
3
+ ## Base Object Class
4
+ # Dynamic Objects that get drawn on the Screen
5
+ # This class is used as basic class for other objects
6
+ #
7
+ class BaseObject
8
+ attr_accessor :x, :y, :width, :height, :obj
9
+ # Ex.: BaseObject.new({ :x => 1, :y => 20, :obj => [[Pixel.new(1),Pixel.new(2,4,"#")]] })
10
+ def initialize options
11
+ @obj = options[:obj]
12
+ @obj = Array.new(height){ Array.new(width) } if @obj.nil?
13
+
14
+ @x = options[:x]
15
+ @y = options[:y]
16
+ @x = 1 if @x.nil?
17
+ @y = 1 if @y.nil?
18
+
19
+ @height = @obj.size
20
+ @width = @obj[0].size
21
+ end
22
+
23
+ # Move object X and Y (modifiers like: -2, 2)
24
+ def move x, y; @x += x; @y += y; end
25
+ # Set object position X Y
26
+ def set_position x, y; @x = x; @y = y; end
27
+ # Set pixel on position on object
28
+ def set_pixel x, y, pixel
29
+ @obj[x][y] = pixel if !@obj[x].nil? and !@obj[x][y].nil?
30
+ end
31
+ # Get pixel by position
32
+ def get_pixel x, y
33
+ @obj[x][y] if !@obj[x].nil? and !@obj[x][y].nil?
34
+ end
35
+
36
+ # "special" each methods for objects
37
+ def each
38
+ @obj.each_with_index do |row,row_count|
39
+ row.each_with_index do |pixel,col_count|
40
+ yield row_count, col_count, pixel
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ ## Box Class
47
+ # draw a box with borders
48
+ #
49
+ # Attributes (all accessible):
50
+ # :width * Box width
51
+ # :height * Box height
52
+ # :x * Box X MUST
53
+ # :y * Box Y MUST
54
+ # :horizontal Horizontal Pixel
55
+ # :vertical Vertical Pixel
56
+ # :corner Corner Pixel
57
+ # :fill Between the border lines (Color)
58
+ #
59
+ # Example:
60
+ # Box.new({ :x => 1, :y => 42, :width => 10, :height => 5, :corner => Pixel.new(1,2,"#"), :fill => Pixel.new(4,6,":") })
61
+ #
62
+ class Box < BaseObject
63
+ attr_accessor :fill, :width, :height, :vertical, :horizontal, :corner
64
+
65
+ # initialize object (see above)
66
+ def initialize options
67
+ @x = options[:x]
68
+ @y = options[:y]
69
+ @width = options[:width]
70
+ @height = options[:height]
71
+
72
+ return if @x.nil? or @y.nil? or @width.nil? or @height.nil?
73
+
74
+ @fill = options[:fill]
75
+
76
+ @vertical = options[:vertical]
77
+ @horizontal = options[:horizontal]
78
+ @corner = options[:corner]
79
+ ref = Theme.get(:border)
80
+ @horizontal = Pixel.new(ref.fg,ref.bg,"-") if options[:horizontal].nil?
81
+ @vertical = Pixel.new(ref.fg,ref.bg,"|") if options[:vertical].nil?
82
+ @corner = Pixel.new(ref.fg,ref.bg,"*") if options[:corner].nil?
83
+
84
+ @width = 3 if @width < 3
85
+ @height = 3 if @height < 3
86
+
87
+ create
88
+ end
89
+
90
+ # Create Box
91
+ # can be recalled any time on attribute changes
92
+ def create
93
+ if !@fill.nil?
94
+ backpixel = Pixel.new(@fill.fg,@fill.bg,@fill.symbol)
95
+ obj = Array.new(@height){ Array.new(@width) { backpixel } }
96
+ else
97
+ obj = Array.new(@height){ Array.new(@width) }
98
+ end
99
+
100
+ (@width-2).times do |i|
101
+ obj[0][i+1] = @horizontal
102
+ obj[@height-1][i+1] = @horizontal
103
+ end
104
+
105
+ (@height-2).times do |i|
106
+ obj[i+1][0] = @vertical
107
+ obj[i+1][@width-1] = @vertical
108
+ end
109
+
110
+ obj[0][0] = @corner
111
+ obj[0][@width-1] = @corner
112
+ obj[@height-1][0] = @corner
113
+ obj[@height-1][@width-1] = @corner
114
+
115
+ @height = obj.size
116
+ @width = obj[0].size
117
+ @obj = obj
118
+ end
119
+ end
120
+
121
+
122
+ ## Line Class
123
+ # draw a straight line
124
+ #
125
+ # Attributes (all accessible)
126
+ # :x MUST
127
+ # :y MUST
128
+ # :direction :vertical|:horizontal (Default: :horizontal)
129
+ # :length
130
+ # :pixel
131
+ # :endpixel
132
+ #
133
+ class Line < BaseObject
134
+ attr_accessor :length, :pixel, :endpixel, :direction
135
+
136
+ def initialize options
137
+ @x = options[:x]
138
+ @y = options[:y]
139
+ @length = options[:length]
140
+ @direction = options[:direction]
141
+ @direction = :horizontal if @direction.nil?
142
+
143
+ return if @x.nil? or @y.nil? or @width.nil?
144
+ @pixel = options[:pixel]
145
+ @endpixel = options[:endpixel]
146
+
147
+ @pixel = Theme.get(:border) if @pixel.nil?
148
+
149
+ create
150
+ end
151
+
152
+ # Create Line
153
+ # can be recalled any time on attribute changes
154
+ def create
155
+ if @direction == :horizontal
156
+ @obj = [Array.new(@length){ @pixel }]
157
+ else
158
+ @obj = Array.new(@length){ [@pixel] }
159
+ end
160
+ if !@endpixel.nil?
161
+ @obj[0][0] = @endpixel
162
+ @obj[0][@length-1] = @endpixel
163
+ end
164
+ end
165
+ end
166
+
167
+ ## Circle Class
168
+ # draw a circle
169
+ #
170
+ # thx to: http://rubyquiz.strd6.com/quizzes/166-circle-drawing
171
+ #
172
+ # Attributes (all accessible):
173
+ # :x MUST
174
+ # :y MUST
175
+ # :radius - Circle radius
176
+ # :pixel - Circle Pixel
177
+ # :fill - Actually just fills the box not the circle...
178
+ #
179
+ class Circle < BaseObject
180
+ attr_accessor :radius, :pixel, :fill
181
+ # Initialize circle (see above)
182
+ def initialize options
183
+ @x = options[:x]
184
+ @y = options[:y]
185
+ @radius = options[:radius]
186
+ @pixel = options[:pixel]
187
+ @fill = options[:fill_pixel]
188
+
189
+ @pixel = Theme.get(:border) if @pixel.nil?
190
+
191
+ return if @x.nil? or @y.nil? or @radius.nil?
192
+
193
+ @width = options[:radius]*2 # needed?
194
+ @height = @width # needed?
195
+
196
+ create
197
+ end
198
+
199
+ # Create Circle
200
+ # can be recalled any time on attribute changes
201
+ def create
202
+ obj = []
203
+ (0..(@radius*2)).each do |x|
204
+ (0..(@radius*2)).each do |y|
205
+ obj[y] = [] if obj[y].nil?
206
+ obj[y][x] = distance_from_center(x,y).round == @radius ? @pixel : @fill
207
+ end
208
+ end
209
+ @obj = obj
210
+ end
211
+
212
+ private
213
+ def distance_from_center(x,y)
214
+ a = calc_side(x)
215
+ b = calc_side(y)
216
+ return Math.sqrt(a**2 + b**2)
217
+ end
218
+
219
+ def calc_side(z)
220
+ z < @radius ? (@radius - z) : (z - @radius)
221
+ end
222
+
223
+ end
224
+
225
+ ## Text Object Class
226
+ # Creates an Text element
227
+ #
228
+ # Attributes (all accessible):
229
+ # :x MUST
230
+ # :y MUST
231
+ # :text - the text to draw
232
+ # :background - Background color (0-255)
233
+ # :foreground - Foreground color (0-255)
234
+ # :rainbow - true|false|none Rainbow text
235
+ #
236
+ class Text < BaseObject
237
+ attr_accessor :bg, :fg, :text, :do_rainbow
238
+ @@rainbow = nil
239
+
240
+ def initialize options
241
+ @@rainbow = Theme.get(:rainbow) if @@rainbow.nil?
242
+ @do_rainbow = options[:rainbow]
243
+ @text = options[:text]
244
+ @x = options[:x]
245
+ @y = options[:y]
246
+ @bg = options[:background]
247
+ @fg = options[:foreground]
248
+ @bg = Theme.get(:background).bg if @bg.nil?
249
+ @fg = Theme.get(:textcolor) if @fg.nil?
250
+ return if @x.nil? or @y.nil?
251
+
252
+ @height = 1
253
+ create
254
+ end
255
+
256
+ # Create Text
257
+ # can be recalled any time on attribute changes
258
+ def create
259
+ if @do_rainbow
260
+ rainbow = 0
261
+ end
262
+ @width = @text.size
263
+ @obj = []
264
+ tmp = []
265
+ @text.split("").each do |t|
266
+ if @do_rainbow
267
+ tmp << Pixel.new(@@rainbow[rainbow],@bg,t)
268
+ rainbow += 1
269
+ rainbow = 0 if rainbow >= @@rainbow.size
270
+ else
271
+ tmp << Pixel.new(@fg,@bg,t)
272
+ end
273
+ end
274
+ @obj << tmp
275
+ end
276
+
277
+ def set_text text
278
+ @text = text
279
+ create
280
+ end
281
+
282
+ def get_text
283
+ @text
284
+ end
285
+ end