savio 0.1.5 → 0.1.6

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.
@@ -0,0 +1,106 @@
1
+ module Savio
2
+ class ButtonManager
3
+ attr_reader :selected, :buttons
4
+
5
+ @@buttonManagers = []
6
+ def self.buttonManagers
7
+ @@buttonManagers
8
+ end
9
+
10
+ def initialize(args = {})
11
+ @@buttonManagers.push(self)
12
+
13
+ @buttons = []
14
+ @selected = []
15
+
16
+ @type = args[:type] || 'radio'
17
+
18
+ if @type != 'checkbox' && @type != 'radio'
19
+ raise ArgumentError, 'ButtonManager type ' + @type.to_s + ' is invalid. Must be radio or checkbox'
20
+ end
21
+
22
+ end
23
+
24
+ def type=(type)
25
+ if type == 'radio' || type == "checkbox"
26
+ @type = type
27
+ else
28
+ raise ArgumentError, 'ButtonManager type ' + type.to_s + ' is invalid. Must be radio or checkbox'
29
+ end
30
+ end
31
+
32
+ def addButton(button)
33
+ if button.class.name != 'Savio::Button'
34
+ raise ArgumentError, 'Given object ' + button.to_s + ' is not a Button. Must be of type Button'
35
+ end
36
+ button.deselect(false)
37
+ @buttons.push(button)
38
+ if button.buttonManager != self
39
+ button.buttonManager = self
40
+ end
41
+ end
42
+
43
+ def removeButton(button, overwrite = true)
44
+ if @buttons.include?(button)
45
+ @buttons.delete(button)
46
+ if @selected.include?(button)
47
+ @selected.delete(button)
48
+ end
49
+ if overwrite == true
50
+ button.buttonManager = nil
51
+ end
52
+ else
53
+ raise ArgumentError, ('Could not find button ' + button.to_s + ' in buttonManager')
54
+ end
55
+ end
56
+
57
+ def toggle(button)
58
+ if @buttons.include?(button)
59
+ if @type == 'checkbox'
60
+ if button.selected
61
+ deselect(button)
62
+ else
63
+ select(button)
64
+ end
65
+ elsif @type == 'radio'
66
+ select(button)
67
+ end
68
+ else
69
+ raise ArgumentError, ('Could not find button ' + button.to_s + ' in buttonManager')
70
+ end
71
+ end
72
+
73
+ def select(button)
74
+ if @buttons.include?(button)
75
+ if @type == 'checkbox'
76
+ @selected.push(button)
77
+ button.select(false)
78
+ elsif @type == 'radio'
79
+ @buttons.each do |i|
80
+ i.deselect(false)
81
+ end
82
+ @selected.clear
83
+ @selected.push(button)
84
+ button.select(false)
85
+ end
86
+ else
87
+ raise ArgumentError, ('Could not find button ' + button.to_s + ' in buttonManager')
88
+ end
89
+ end
90
+
91
+ def deselect(button)
92
+ if @buttons.include?(button)
93
+ if @type == 'checkbox'
94
+ @selected.delete(button)
95
+ button.deselect(false)
96
+ elsif @type == 'radio'
97
+ @selected.delete(button)
98
+ button.deselect(false)
99
+ end
100
+ else
101
+ raise ArgumentError, ('Could not find button ' + button.to_s + ' in buttonManager')
102
+ end
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,224 @@
1
+ module Savio
2
+ class ColorSlider
3
+ include IORenderable
4
+
5
+ attr_reader :baseColor, :knobColor, :textColor, :sectors, :optionsShown, :animating
6
+
7
+ @@colorSliders = []
8
+ def self.colorSliders
9
+ @@colorSliders
10
+ end
11
+
12
+ def initialize(args = {})
13
+ args[:size] = args[:size] || 80
14
+ super(args)
15
+ @@colorSliders.push(self)
16
+
17
+ @color = args[:color] || HsvColor.new(rand(0..360), rand(0.0..1.0),rand(0.0..1.0))
18
+ @hue = @color[0]
19
+
20
+ @baseColor = args[:baseColor] || Savio::Colors::White
21
+ @knobColor = args[:baseColor] || Savio::Colors::Gray
22
+ @textColor = args[:textColor] || Savio::Colors::Black
23
+ @sectors = args[:sectors] || 64
24
+
25
+ @optionsShown = false
26
+ @steps = 0
27
+ @animating = false
28
+
29
+ @radiusStep = 0
30
+ @yStep = 0
31
+
32
+ build()
33
+ end
34
+
35
+ def baseColor=(c)
36
+ @baseColor = c
37
+ rebuild()
38
+ end
39
+ def knobColor=(c)
40
+ @knob.color = c
41
+ end
42
+ def textColor=(c)
43
+ @textColor = c
44
+ rebuild()
45
+ end
46
+
47
+ def remove()
48
+ super()
49
+ @innerCircle.remove
50
+ @outerCircle.remove
51
+ @knob.remove
52
+ @saturationSlider.remove
53
+ @valueSlider.remove
54
+ end
55
+
56
+ def add()
57
+ super()
58
+ @innerCircle.add
59
+ @outerCircle.add
60
+ @knob.add
61
+ @saturationSlider.add
62
+ @valueSlider.add
63
+ end
64
+
65
+ def animate()
66
+ animatorThread = Thread.new do
67
+ 12.times do
68
+ sleep(1 / 60)
69
+ @steps += 1
70
+ @innerCircle.radius += @radiusStep
71
+ @innerCircle.y += @yStep
72
+ if @steps >= 12
73
+ @steps = 0
74
+ @radiusStep = 0
75
+ @yStep = 0
76
+ @animating = false
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ def calculateStep(desire, start, steps)
83
+ delta = desire.to_f - start.to_f
84
+ step = delta/steps
85
+ return step
86
+ end
87
+
88
+ def showOptions()
89
+ if @optionsShown == false
90
+ @optionsShown = true
91
+
92
+ @steps = 0
93
+ @radiusStep = 0
94
+ @yStep = 0
95
+ @animating = false
96
+
97
+ @radiusStep = calculateStep(0.25 * @size, @innerCircle.radius, 12)
98
+ @yStep = calculateStep(@y - @size + 0.35 * @size, @innerCircle.y, 12)
99
+ @animating = true
100
+ animate()
101
+ end
102
+ end
103
+
104
+ def hideOptions()
105
+ if @optionsShown == true
106
+ @optionsShown = false
107
+
108
+ @steps = 0
109
+ @radiusStep = 0
110
+ @yStep = 0
111
+ @animating = false
112
+
113
+ @radiusStep = calculateStep(@size * 0.95, @innerCircle.radius, 12)
114
+ @yStep = calculateStep(@y, @innerCircle.y, 12)
115
+ @animating = true
116
+ animate()
117
+ end
118
+ end
119
+
120
+ def setValue(angle)
121
+ @knob.x = (@size).to_f * Math.cos((angle.to_f % 360.0) * Math::PI/180.0) + @x.to_f
122
+ @knob.y = (@size).to_f * Math.sin((angle.to_f % 360.0) * Math::PI/180.0) + @y.to_f
123
+
124
+ @color = HsvColor.new(angle % 360, @saturationSlider.value, @valueSlider.value)
125
+ @hue = @color[0]
126
+
127
+ rgb = RgbColor.newFromHSV(@color)
128
+ @innerCircle.color.r = rgb[0]
129
+ @innerCircle.color.g = rgb[1]
130
+ @innerCircle.color.b = rgb[2]
131
+ end
132
+
133
+ def rgb()
134
+ return RgbColor.newFromHSV(@color)
135
+ end
136
+
137
+ def hsv()
138
+ return HsvColor.new(@color[0],@color[1],@color[2])
139
+ end
140
+
141
+ def hex()
142
+ rgb = RgbColor.newFromHSV(@color)
143
+ return ("#%02x%02x%02x" % [rgb[0]*255,rgb[1]*255,rgb[2]*255])
144
+ end
145
+
146
+ def chord(placement)
147
+ margin = 20
148
+ height = @size * placement
149
+ angle = 2 * Math.acos( 1.0 - height / @size.to_f)
150
+ angle = angle * 180/Math::PI
151
+ chord = 2 * Math.sqrt(2 * @size * height - height**2)
152
+ adjust = (@size * 2 - chord) / 2
153
+ return Struct.new(:margin, :height, :angle, :chord, :adjust).new(margin,height,angle,chord,adjust)
154
+ end
155
+
156
+ def build()
157
+ @shown = true
158
+
159
+ @innerCircle = Circle.new(
160
+ x: @x, y: @y,
161
+ radius: @size * 0.95,
162
+ color: 'black',
163
+ z: @z + 4,
164
+ sectors: @sectors
165
+ )
166
+
167
+ @outerCircle = Circle.new(
168
+ x: @x, y: @y,
169
+ radius: @size,
170
+ color: @baseColor,
171
+ z: @z,
172
+ sectors: @sectors
173
+ )
174
+
175
+ @knob = Circle.new(
176
+ x: @x + @size, y: @y,
177
+ radius: @size * 0.15,
178
+ color: @knobColor,
179
+ z: @z + 5,
180
+ sectors: @sectors
181
+ )
182
+
183
+ placement = chord(1.0)
184
+ @saturationSlider = Slider.new(
185
+ displayName: "Saturation",
186
+ labelColor: @textColor,
187
+ x:@x - @size + placement.adjust + placement.margin,
188
+ y:@y - @size + placement.height,
189
+ z:@z + 1,
190
+ min:0.0,
191
+ max:1.0,
192
+ length:(placement.chord - placement.margin * 2),
193
+ size: @size * 0.06,
194
+ showValue: false
195
+ )
196
+
197
+ placement = chord(1.3)
198
+ @valueSlider = Slider.new(
199
+ displayName: "Value",
200
+ labelColor: @textColor,
201
+ x:@x - @size + placement.adjust + placement.margin,
202
+ y:@y - @size + placement.height,
203
+ z: @z + 1,
204
+ min:0.0,
205
+ max:1.0,
206
+ length:(placement.chord - placement.margin * 2),
207
+ size: @size * 0.06,
208
+ showValue: false
209
+ )
210
+ @valueSlider.showValue=false
211
+ @saturationSlider.showValue=false
212
+
213
+ @valueSlider.onChange do
214
+ setValue(@hue)
215
+ end
216
+
217
+ @saturationSlider.onChange do
218
+ setValue(@hue)
219
+ end
220
+
221
+ setValue(@hue)
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,13 @@
1
+ module Savio
2
+ module Colors
3
+ White = '#FDFDFD'
4
+ Gray = '#858585'
5
+ Black = '#1A1A1A'
6
+
7
+ Red = '#FF728B'
8
+ Green = '#28E457'
9
+ Blue = '#28B2E4'
10
+ Yellow = '#FFED61'
11
+ Purple = '#FF90FF'
12
+ end
13
+ end
@@ -0,0 +1,126 @@
1
+ module Savio
2
+ module IORenderable
3
+ attr_accessor :enabled, :shown, :allowDrag, :draggingEnabled, :duplicate
4
+ attr_reader :x, :y, :z, :size, :displayName
5
+
6
+ def initialize(args = {})
7
+ Savio.addElement(self)
8
+
9
+ @x = args[:x] || 0
10
+ @y = args[:y] || 0
11
+ @z = args[:z] || 1
12
+
13
+ @size = args[:size] || 10
14
+
15
+ @enabled = args[:enabled] || true
16
+ @shown = args[:shown] || true
17
+
18
+ @displayName = args[:displayName] || ""
19
+
20
+ @draggingEnabled = args[:draggingEnabled] || false
21
+ @dragType = args[:dragType] || "move"
22
+ @isDragging = false
23
+ @allowDrag = false
24
+
25
+ end
26
+
27
+ def remove()
28
+ @shown = false
29
+ end
30
+
31
+ def add()
32
+ @shown = true
33
+ end
34
+
35
+ def kill()
36
+ remove()
37
+ end
38
+
39
+ def rebuild()
40
+ remove()
41
+ build()
42
+ end
43
+
44
+ def x=(x)
45
+ @x = x
46
+ rebuild()
47
+ end
48
+ def y=(y)
49
+ @y = y
50
+ rebuild()
51
+ end
52
+ def z=(z)
53
+ @z = z
54
+ rebuild()
55
+ end
56
+ def size=(size)
57
+ @size = size.abs
58
+ rebuild()
59
+ end
60
+ def displayName=(displayName)
61
+ @displayName = displayName
62
+ rebuild()
63
+ end
64
+
65
+ def dragType=(type)
66
+ if type == "move" || type == "duplicate"
67
+ @dragType = type
68
+ end
69
+ end
70
+
71
+ def drag(x, y)
72
+ case @dragType
73
+ when "move"
74
+ if @isDragging == false
75
+ @grabFixX = (x - @x).abs
76
+ @grabFixY = (y - @y).abs
77
+ @isDragging = true
78
+ end
79
+ if @isDragging == true
80
+ @x = x - @grabFixX
81
+ @y = y - @grabFixY
82
+ rebuild()
83
+ end
84
+ when "duplicate"
85
+ if @isDragging == false
86
+ @grabFixX = (x - @x).abs
87
+ @grabFixY = (y - @y).abs
88
+
89
+ classType = Object.const_get(self.class.name)
90
+
91
+ @duplicate = classType.new(self.context)
92
+ @duplicate.enabled = false
93
+ @duplicate.draggingEnabled = false
94
+ @duplicate.dragType = "move"
95
+ @isDragging = true
96
+ end
97
+ if @isDragging == true
98
+ @duplicate.enabled = false
99
+ @duplicate.draggingEnabled = false
100
+ @duplicate.x = x - @grabFixX
101
+ @duplicate.y = y - @grabFixY
102
+ end
103
+ end
104
+ end
105
+
106
+ def context()
107
+ self.instance_variables.map do |attribute|
108
+ key = attribute.to_s.gsub('@','').intern
109
+ [key, self.instance_variable_get(attribute)]
110
+ end.to_h
111
+ end
112
+
113
+ def endDrag()
114
+ if @isDragging
115
+ if @dragType == "duplicate"
116
+ @duplicate.draggingEnabled = true
117
+ @duplicate.enabled = true
118
+ @duplicate.allowDrag = false
119
+ @duplicate = nil
120
+ end
121
+ @isDragging = false
122
+ @allowDrag = false
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,196 @@
1
+ module Savio
2
+ class InputBox
3
+ include IORenderable
4
+
5
+ attr_accessor :shift
6
+ attr_reader :selected, :value, :length, :height, :displayName
7
+
8
+ @@inputBoxs = []
9
+ def self.inputBoxs
10
+ @@inputBoxs
11
+ end
12
+
13
+ @@tabIndex = 0
14
+
15
+ def initialize(args = {})
16
+ super(args)
17
+
18
+ @@inputBoxs.push(self)
19
+
20
+ @selected = args[:selected] || false
21
+
22
+ @size = args[:size] || 20
23
+
24
+ @shift = false
25
+
26
+ @value = args[:value] || ""
27
+
28
+ @length = args[:length] || @size * 10
29
+ @height = args[:height] || @size * 1.2
30
+
31
+ @color = args[:color] || Savio::Colors::White
32
+ @activeColor = args[:activeColor] || Savio::Colors::Green
33
+
34
+ @activeTextColor = args[:activeTextColor] || Savio::Colors::White
35
+ @inactiveTextColor = args[:inactiveTextColor] || Savio::Colors::Gray
36
+
37
+ build()
38
+
39
+ if @shown == false
40
+ remove()
41
+ end
42
+
43
+ end
44
+
45
+ def remove()
46
+ super()
47
+ @display.remove
48
+ @container.remove
49
+ end
50
+
51
+ def add()
52
+ super()
53
+ @display.add
54
+ @container.add
55
+ end
56
+
57
+ def color=(color)
58
+ @color = color
59
+ rebuild()
60
+ end
61
+ def activeColor=(color)
62
+ @activeColor = color
63
+ rebuild()
64
+ end
65
+ def activeTextcolor=(color)
66
+ @activeTextcolor = color
67
+ rebuild()
68
+ end
69
+ def inactiveTextColor=(color)
70
+ @inactiveTextColor = color
71
+ rebuild()
72
+ end
73
+ def length=(length)
74
+ @length = length
75
+ rebuild()
76
+ end
77
+ def height=(height)
78
+ @height = height
79
+ rebuild()
80
+ end
81
+
82
+ def value=(value)
83
+ @value = value
84
+ if @value == ""
85
+ @display.text = @displayName
86
+ else
87
+ @display.text = @value
88
+ end
89
+ end
90
+
91
+ def clear()
92
+ @value = ""
93
+ @display.text = @displayName
94
+ end
95
+
96
+ def size=(size)
97
+ @length = size * 10
98
+ @height = size * 1.2
99
+ super(size)
100
+ end
101
+
102
+ def tabMover()
103
+ if @@tabIndex >= @@inputBoxs.count
104
+ @@tabIndex = 0
105
+ end
106
+
107
+ for i in @@tabIndex..@@inputBoxs.count do
108
+ if @@inputBoxs[i].enabled && @@inputBoxs[i].shown
109
+ @@tabIndex = i
110
+ deselect()
111
+ @@inputBoxs[i].select()
112
+ end
113
+ if @selected
114
+ @@tabIndex = 0
115
+ end
116
+ end
117
+ end
118
+
119
+ def addKey(key)
120
+ if key == "space"
121
+ @value += + " "
122
+ updateDisplay()
123
+ elsif key == "return"
124
+ deselect()
125
+ elsif key == "backspace"
126
+ @value = @value[0...-1]
127
+ updateDisplay()
128
+ elsif key.chars.count == 1
129
+ if @shift == true
130
+ key = key.upcase
131
+ end
132
+ @value += key
133
+ updateDisplay()
134
+ elsif key == "tab"
135
+ tabMover()
136
+ else
137
+ puts "SAVIO : I am a work in progress, and the key you pressed couldnt be handled"
138
+ puts "SAVIO : Unknown key : " + key.to_s
139
+ end
140
+ end
141
+
142
+ def updateDisplay()
143
+ @display.text = @value + "|"
144
+ end
145
+
146
+ def selected=(bool)
147
+ if bool == true
148
+ select()
149
+ elsif bool == false
150
+ deselect()
151
+ end
152
+ end
153
+
154
+ def select()
155
+ @selected = true
156
+
157
+ @display.text = @value + "|"
158
+ @display.color = @activeTextColor
159
+ @container.color = @activeColor
160
+ end
161
+
162
+ def deselect()
163
+ @selected = false
164
+
165
+ if @value == ""
166
+ @display.text = @displayName
167
+ else
168
+ @display.text = @value
169
+ end
170
+
171
+ @display.color = @inactiveTextColor
172
+ @container.color = @color
173
+ end
174
+
175
+ def toggle()
176
+ if @selected
177
+ deselect()
178
+ else
179
+ select()
180
+ end
181
+ end
182
+
183
+ def build()
184
+ if @value == ""
185
+ @display = Text.new(@displayName,x: @x + 0.02 * @length,y: @y,z: @z + 1, size: @size, color: @inactiveTextColor)
186
+ else
187
+ @display = Text.new(@value,x: @x + 0.02 * @length,y: @y,z: @z + 1, size: @size, color: @inactiveTextColor)
188
+ end
189
+ @height = @display.height * 1.1
190
+
191
+ @container = Rectangle.new(x: @x, y: @y, z: @z, height: @height, width: @length, color: @color)
192
+
193
+ @display.y = @container.y + @container.height / 2 - @display.height / 2
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,55 @@
1
+ module Savio
2
+ class Scene
3
+ attr_accessor :elements
4
+ def initialize(file, color = 'black')
5
+ @file = file
6
+ @color = color
7
+ show()
8
+ end
9
+
10
+ def show()
11
+ @bg = Square.new(x: 0, y: 0, z: 999, size: Window.width+1, color: @color)
12
+ @elements = []
13
+ content = File.read(@file)
14
+ content = content.gsub('[', "").gsub(']', "").gsub('"',"").chomp.split(",")
15
+
16
+ (content.count-1).times do |i|
17
+ if (i % 2) == 0
18
+ classType = Object.const_get(content[i].gsub(" ",""))
19
+ hash = content[i+1].gsub(';', ',').gsub('"',"").chomp
20
+ pairs = hash.split(",").to_s.gsub('"',"").chomp
21
+ keypair = pairs.split("=>").to_s.gsub('"',"").chomp
22
+ new = keypair.gsub('{', "").gsub('}', "").gsub('[', "").gsub(']', "").gsub('"',"").gsub(" ","").chomp.split(",")
23
+ build = {}
24
+ (new.count-1).times do |j|
25
+ if (j % 2) == 0
26
+ case Savio.guessType(new[j+1].chomp)
27
+ when "int"
28
+ value = new[j+1].chomp.to_i
29
+ when "float"
30
+ value = new[j+1].chomp.to_f
31
+ when "str"
32
+ value = new[j+1].chomp.to_s
33
+ when "bool"
34
+ value = Savio.makeBool(new[j+1].chomp)
35
+ end
36
+ build[new[j].intern] = value
37
+ end
38
+ end
39
+ puts "SCENE: " + @file.to_s + build.to_s
40
+ @elements.push(classType.new(build))
41
+ end
42
+ end
43
+ @elements.each do |e|
44
+ e.z = 1000
45
+ end
46
+ end
47
+
48
+ def remove()
49
+ @bg.remove
50
+ @elements.each do |e|
51
+ e.kill()
52
+ end
53
+ end
54
+ end
55
+ end