savio 0.1.0

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,211 @@
1
+ module Savio
2
+ class ColorSlider
3
+ include IORenderable
4
+
5
+ attr_reader :value, :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
+ @value = args[:value] || rand(0..360)
18
+ @baseColor = args[:baseColor] || 'white'
19
+ @knobColor = args[:baseColor] || 'gray'
20
+ @textColor = args[:textColor] || 'black'
21
+ @sectors = args[:sectors] || 64
22
+
23
+ @optionsShown = false
24
+ @steps = 0
25
+ @animating = false
26
+
27
+ @radiusStep = 0
28
+ @yStep = 0
29
+
30
+ build()
31
+ end
32
+
33
+ def baseColor=(c)
34
+ @baseColor = c
35
+ rebuild()
36
+ end
37
+ def knobColor=(c)
38
+ @knob.color = c
39
+ end
40
+ def textColor=(c)
41
+ @textColor = c
42
+ rebuild()
43
+ end
44
+
45
+ def remove()
46
+ super()
47
+ @innerCircle.remove
48
+ @outerCircle.remove
49
+ @knob.remove
50
+ @mySaturation.remove
51
+ @myValue.remove
52
+ end
53
+
54
+ def add()
55
+ super()
56
+ @innerCircle.add
57
+ @outerCircle.add
58
+ @knob.add
59
+ @mySaturation.add
60
+ @myValue.add
61
+ end
62
+
63
+ def animate()
64
+ animatorThread = Thread.new do
65
+ 12.times do
66
+ sleep(1 / 60)
67
+ @steps += 1
68
+ @innerCircle.radius += @radiusStep
69
+ @innerCircle.y += @yStep
70
+ if @steps >= 12
71
+ @steps = 0
72
+ @radiusStep = 0
73
+ @yStep = 0
74
+ @animating = false
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ def calculateStep(desire, start, steps)
81
+ delta = desire.to_f - start.to_f
82
+ step = delta/steps
83
+ return step
84
+ end
85
+
86
+ def showOptions()
87
+ if @optionsShown == false
88
+ @optionsShown = true
89
+
90
+ @steps = 0
91
+ @radiusStep = 0
92
+ @yStep = 0
93
+ @animating = false
94
+
95
+ @radiusStep = calculateStep(0.25 * @size, @innerCircle.radius, 12)
96
+ @yStep = calculateStep(@y - @size + 0.35 * @size, @innerCircle.y, 12)
97
+ @animating = true
98
+ animate()
99
+ end
100
+ end
101
+
102
+ def hideOptions()
103
+ if @optionsShown == true
104
+ @optionsShown = false
105
+
106
+ @steps = 0
107
+ @radiusStep = 0
108
+ @yStep = 0
109
+ @animating = false
110
+
111
+ @radiusStep = calculateStep(@size * 0.95, @innerCircle.radius, 12)
112
+ @yStep = calculateStep(@y, @innerCircle.y, 12)
113
+ @animating = true
114
+ animate()
115
+ end
116
+ end
117
+
118
+ def setValue(angle)
119
+ @knob.x = (@size).to_f * Math.cos((angle.to_f % 360.0) * Math::PI/180.0) + @x.to_f
120
+ @knob.y = (@size).to_f * Math.sin((angle.to_f % 360.0) * Math::PI/180.0) + @y.to_f
121
+ @value = angle
122
+
123
+ hue = Savio.hsv2rgb(@value % 360,@mySaturation.value,@myValue.value)
124
+ @innerCircle.color.r = hue[0]
125
+ @innerCircle.color.g = hue[1]
126
+ @innerCircle.color.b = hue[2]
127
+ end
128
+
129
+ def rgb()
130
+ return Savio.hsv2rgb(@value % 360,@mySaturation.value,@myValue.value)
131
+ end
132
+
133
+ def hsv()
134
+ return [@value % 360, @mySaturation.value, @myValue.value]
135
+ end
136
+
137
+ def hex()
138
+ return ("#%02x%02x%02x" % [rgb()[0]*255,rgb()[1]*255,rgb()[2]*255])
139
+ end
140
+
141
+ def chord(placement)
142
+ margin = 20
143
+ height = @size * placement
144
+ angle = 2 * Math.acos( 1.0 - height / @size.to_f)
145
+ angle = angle * 180/Math::PI
146
+ chord = 2 * Math.sqrt(2 * @size * height - height**2)
147
+ adjust = (@size * 2 - chord) / 2
148
+ return Struct.new(:margin, :height, :angle, :chord, :adjust).new(margin,height,angle,chord,adjust)
149
+ end
150
+
151
+ def build()
152
+ @shown = true
153
+
154
+ @innerCircle = Circle.new(
155
+ x: @x, y: @y,
156
+ radius: @size * 0.95,
157
+ color: 'black',
158
+ z: @z + 4,
159
+ sectors: @sectors
160
+ )
161
+
162
+ @outerCircle = Circle.new(
163
+ x: @x, y: @y,
164
+ radius: @size,
165
+ color: @baseColor,
166
+ z: @z,
167
+ sectors: @sectors
168
+ )
169
+
170
+ @knob = Circle.new(
171
+ x: @x + @size, y: @y,
172
+ radius: @size * 0.15,
173
+ color: @knobColor,
174
+ z: @z + 5,
175
+ sectors: @sectors
176
+ )
177
+
178
+ placement = chord(1.0)
179
+ @mySaturation = Slider.new(
180
+ displayName: "Saturation",
181
+ labelColor: @textColor,
182
+ x:@x - @size + placement.adjust + placement.margin,
183
+ y:@y - @size + placement.height,
184
+ z:@z + 1,
185
+ min:0.0,
186
+ max:1.0,
187
+ length:(placement.chord - placement.margin * 2),
188
+ size: @size * 0.06,
189
+ showValue: false
190
+ )
191
+
192
+ placement = chord(1.3)
193
+ @myValue = Slider.new(
194
+ displayName: "Value",
195
+ labelColor: @textColor,
196
+ x:@x - @size + placement.adjust + placement.margin,
197
+ y:@y - @size + placement.height,
198
+ z: @z + 1,
199
+ min:0.0,
200
+ max:1.0,
201
+ length:(placement.chord - placement.margin * 2),
202
+ size: @size * 0.06,
203
+ showValue: false
204
+ )
205
+ @myValue.showValue=false
206
+ @mySaturation.showValue=false
207
+
208
+ setValue(@value)
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,127 @@
1
+ module Savio
2
+ module IORenderable
3
+ attr_accessor :enabled, :allowDrag, :draggingEnabled, :duplicate
4
+ attr_reader :x, :y, :z, :size, :shown, :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
+ @size = args[:size] || 10
13
+ @enabled = args[:enabled] || true
14
+
15
+ @displayName = args[:displayName] || "Default"
16
+
17
+ @draggingEnabled = args[:draggingEnabled] || false
18
+ @dragType = args[:dragType] || "move"
19
+ @isDragging = false
20
+ @allowDrag = false
21
+ end
22
+
23
+ def remove()
24
+ if @shown == false
25
+ return
26
+ end
27
+ @shown = false
28
+ end
29
+
30
+ def add()
31
+ if @shown == true
32
+ return
33
+ end
34
+ @shown = true
35
+ end
36
+
37
+ def kill()
38
+ remove()
39
+ end
40
+
41
+ def rebuild()
42
+ remove()
43
+ build()
44
+ end
45
+
46
+ def x=(x)
47
+ @x = x
48
+ rebuild()
49
+ end
50
+ def y=(y)
51
+ @y = y
52
+ rebuild()
53
+ end
54
+ def z=(z)
55
+ @z = z
56
+ rebuild()
57
+ end
58
+ def size=(size)
59
+ @size = size.abs
60
+ rebuild()
61
+ end
62
+ def displayName=(displayName)
63
+ @displayName = displayName
64
+ rebuild()
65
+ end
66
+ def dragType=(type)
67
+ if type == "move" || type == "duplicate"
68
+ @dragType = type
69
+ end
70
+ end
71
+
72
+ def drag(x, y)
73
+ case @dragType
74
+ when "move"
75
+ if @isDragging == false
76
+ @grabFixX = (x - @x).abs
77
+ @grabFixY = (y - @y).abs
78
+ @isDragging = true
79
+ end
80
+ if @isDragging == true
81
+ @x = x - @grabFixX
82
+ @y = y - @grabFixY
83
+ rebuild()
84
+ end
85
+ when "duplicate"
86
+ if @isDragging == false
87
+ @grabFixX = (x - @x).abs
88
+ @grabFixY = (y - @y).abs
89
+
90
+ classType = Object.const_get(self.class.name)
91
+
92
+ @duplicate = classType.new(self.context)
93
+ @duplicate.enabled = false
94
+ @duplicate.draggingEnabled = false
95
+ @duplicate.dragType = "move"
96
+ @isDragging = true
97
+ end
98
+ if @isDragging == true
99
+ @duplicate.enabled = false
100
+ @duplicate.draggingEnabled = false
101
+ @duplicate.x = x - @grabFixX
102
+ @duplicate.y = y - @grabFixY
103
+ end
104
+ end
105
+ end
106
+
107
+ def context()
108
+ self.instance_variables.map do |attribute|
109
+ key = attribute.to_s.gsub('@','').intern
110
+ [key, self.instance_variable_get(attribute)]
111
+ end.to_h
112
+ end
113
+
114
+ def endDrag()
115
+ if @isDragging
116
+ if @dragType == "duplicate"
117
+ @duplicate.draggingEnabled = true
118
+ @duplicate.enabled = true
119
+ @duplicate.allowDrag = false
120
+ @duplicate = nil
121
+ end
122
+ @isDragging = false
123
+ @allowDrag = false
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,136 @@
1
+ module Savio
2
+ class InputBox
3
+ include IORenderable
4
+
5
+ attr_accessor :shift
6
+ attr_reader :selected, :value, :length, :height
7
+
8
+ @@inputBoxs = []
9
+ def self.inputBoxs
10
+ @@inputBoxs
11
+ end
12
+
13
+ def initialize(args = {})
14
+ @@inputBoxs.push(self)
15
+ super(args)
16
+
17
+ @selected = args[:selected] || false
18
+
19
+ @shift = false
20
+
21
+ @value = args[:value] || @displayName
22
+ @displayName = @value
23
+
24
+ @length = args[:length] || @size * 10
25
+ @height = args[:height] || @size * 1.2
26
+
27
+ @color = args[:color] || 'gray'
28
+ @activeColor = args[:activeColor] || 'green'
29
+
30
+ build()
31
+ end
32
+
33
+ def remove()
34
+ super()
35
+ @display.remove
36
+ @container.remove
37
+ end
38
+
39
+ def add()
40
+ super()
41
+ @display.add
42
+ @container.add
43
+ end
44
+
45
+ def color=(color)
46
+ @color = color
47
+ rebuild()
48
+ end
49
+ def activeColor=(color)
50
+ @activeColor = color
51
+ rebuild()
52
+ end
53
+ def length=(length)
54
+ @length = length
55
+ rebuild()
56
+ end
57
+ def height=(height)
58
+ @height = height
59
+ rebuild()
60
+ end
61
+
62
+ def value=(value)
63
+ @value = value
64
+ @displayName = @value
65
+ @display.text = @value
66
+ end
67
+
68
+ def size=(size)
69
+ @length = size * 10
70
+ @height = size * 1.2
71
+ super(size)
72
+ end
73
+
74
+ def addKey(key)
75
+ if key == "space"
76
+ @value += + " "
77
+ updateDisplay()
78
+ elsif key == "return"
79
+ deselect()
80
+ elsif key == "backspace"
81
+ @value = @value[0...-1]
82
+ updateDisplay()
83
+ elsif key.chars.count == 1
84
+ if @shift == true
85
+ key = key.upcase
86
+ end
87
+ @value += key
88
+ updateDisplay()
89
+ else
90
+ puts "SAVIO : I am a work in progress, and the key you pressed couldnt be handled"
91
+ puts "SAVIO : Unknown key : " + key.to_s
92
+ end
93
+ end
94
+
95
+ def updateDisplay()
96
+ @display.text = @value + "|"
97
+ end
98
+
99
+ def select()
100
+ @selected = true
101
+
102
+ if @value == @displayName
103
+ @value = ""
104
+ end
105
+
106
+ @display.text = @value + "|"
107
+ @container.color = @activeColor
108
+ end
109
+
110
+ def deselect()
111
+ @selected = false
112
+
113
+ if @value == ""
114
+ @value = @displayName
115
+ end
116
+
117
+ @display.text = @value
118
+ @container.color = @color
119
+ end
120
+
121
+ def toggle()
122
+ if @selected
123
+ deselect()
124
+ else
125
+ select()
126
+ end
127
+ end
128
+
129
+ def build()
130
+ @shown = true
131
+
132
+ @display = Text.new(@value,x: @x,y: @y,z: @z + 1, size: @size)
133
+ @container = Rectangle.new(x: @x, y: @y, z: @z, height: @height, width: @length, color: @color)
134
+ end
135
+ end
136
+ end