glimmer-dsl-libui 0.1.11 → 0.2.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -0
- data/README.md +573 -23
- data/VERSION +1 -1
- data/examples/area_gallery.rb +7 -1
- data/examples/area_gallery2.rb +14 -4
- data/examples/area_gallery3.rb +8 -2
- data/examples/area_gallery4.rb +15 -5
- data/examples/basic_draw_text.rb +67 -0
- data/examples/color_the_circles.rb +220 -0
- data/examples/midi_player.rb +2 -2
- data/examples/timer.rb +135 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/dsl/libui/control_expression.rb +0 -1
- data/lib/glimmer/dsl/libui/property_expression.rb +3 -1
- data/lib/glimmer/dsl/libui/string_expression.rb +48 -0
- data/lib/glimmer/libui/attributed_string.rb +90 -0
- data/lib/glimmer/libui/control_proxy/area_proxy.rb +14 -3
- data/lib/glimmer/libui/control_proxy/font_button_proxy.rb +3 -3
- data/lib/glimmer/libui/control_proxy/menu_item_proxy/radio_menu_item_proxy.rb +69 -0
- data/lib/glimmer/libui/control_proxy/menu_proxy.rb +3 -0
- data/lib/glimmer/libui/control_proxy/path_proxy.rb +0 -2
- data/lib/glimmer/libui/control_proxy/text_proxy.rb +158 -0
- data/lib/glimmer/libui/control_proxy/window_proxy.rb +0 -6
- data/lib/glimmer/libui/control_proxy.rb +7 -1
- data/lib/glimmer/libui/shape/arc.rb +6 -3
- data/lib/glimmer/libui/shape/circle.rb +50 -0
- data/lib/glimmer/libui/shape/rectangle.rb +4 -0
- data/lib/glimmer/libui/shape/square.rb +4 -0
- data/lib/glimmer/libui.rb +73 -6
- data/sounds/AlanWalker-Faded.mid +0 -0
- data/sounds/AlanWalker-SingMeToSleep.mid +0 -0
- data/sounds/CalvinHarris-Blame.mid +0 -0
- data/sounds/CalvinHarris-MyWay.mid +0 -0
- data/sounds/deadmau5-2448.mid +0 -0
- data/sounds/deadmau5-SoThereIWas.mid +0 -0
- metadata +16 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.3
|
data/examples/area_gallery.rb
CHANGED
@@ -41,11 +41,17 @@ window('Area Gallery', 400, 400) {
|
|
41
41
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
42
42
|
}
|
43
43
|
path { # declarative stable path
|
44
|
-
|
44
|
+
circle(200, 200, 90)
|
45
45
|
|
46
46
|
fill r: 202, g: 102, b: 204, a: 0.5
|
47
47
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
48
48
|
}
|
49
|
+
path { # declarative stable path
|
50
|
+
arc(400, 220, 180, 90, 90, false)
|
51
|
+
|
52
|
+
fill r: 204, g: 102, b: 204, a: 0.5
|
53
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
54
|
+
}
|
49
55
|
|
50
56
|
on_mouse_event do |area_mouse_event|
|
51
57
|
p area_mouse_event
|
data/examples/area_gallery2.rb
CHANGED
@@ -95,18 +95,28 @@ window('Area Gallery', 400, 400) {
|
|
95
95
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
96
96
|
}
|
97
97
|
path { # declarative stable path
|
98
|
-
|
98
|
+
circle {
|
99
99
|
x_center 200
|
100
100
|
y_center 200
|
101
101
|
radius 90
|
102
|
-
start_angle 0
|
103
|
-
sweep 360
|
104
|
-
is_negative false
|
105
102
|
}
|
106
103
|
|
107
104
|
fill r: 202, g: 102, b: 204, a: 0.5
|
108
105
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
109
106
|
}
|
107
|
+
path { # declarative stable path
|
108
|
+
arc {
|
109
|
+
x_center 400
|
110
|
+
y_center 220
|
111
|
+
radius 180
|
112
|
+
start_angle 90
|
113
|
+
sweep 90
|
114
|
+
is_negative false
|
115
|
+
}
|
116
|
+
|
117
|
+
fill r: 204, g: 102, b: 204, a: 0.5
|
118
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
119
|
+
}
|
110
120
|
|
111
121
|
on_mouse_event do |area_mouse_event|
|
112
122
|
p area_mouse_event
|
data/examples/area_gallery3.rb
CHANGED
@@ -42,11 +42,17 @@ window('Area Gallery', 400, 400) {
|
|
42
42
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
43
43
|
}
|
44
44
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
45
|
-
|
46
|
-
|
45
|
+
circle(200, 200, 90)
|
46
|
+
|
47
47
|
fill r: 202, g: 102, b: 204, a: 0.5
|
48
48
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
49
49
|
}
|
50
|
+
path { # a dynamic path is added semi-declaratively inside on_draw block
|
51
|
+
arc(400, 220, 180, 90, 90, false)
|
52
|
+
|
53
|
+
fill r: 204, g: 102, b: 204, a: 0.5
|
54
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
55
|
+
}
|
50
56
|
end
|
51
57
|
|
52
58
|
on_mouse_event do |area_mouse_event|
|
data/examples/area_gallery4.rb
CHANGED
@@ -96,18 +96,28 @@ window('Area Gallery', 400, 400) {
|
|
96
96
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
97
97
|
}
|
98
98
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
99
|
-
|
99
|
+
circle {
|
100
100
|
x_center 200
|
101
101
|
y_center 200
|
102
102
|
radius 90
|
103
|
-
start_angle 0
|
104
|
-
sweep 360
|
105
|
-
is_negative false
|
106
103
|
}
|
107
|
-
|
104
|
+
|
108
105
|
fill r: 202, g: 102, b: 204, a: 0.5
|
109
106
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
110
107
|
}
|
108
|
+
path { # a dynamic path is added semi-declaratively inside on_draw block
|
109
|
+
arc {
|
110
|
+
x_center 400
|
111
|
+
y_center 220
|
112
|
+
radius 180
|
113
|
+
start_angle 90
|
114
|
+
sweep 90
|
115
|
+
is_negative false
|
116
|
+
}
|
117
|
+
|
118
|
+
fill r: 204, g: 102, b: 204, a: 0.5
|
119
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
120
|
+
}
|
111
121
|
end
|
112
122
|
|
113
123
|
on_mouse_event do |area_mouse_event|
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
|
3
|
+
# Michael Ende (1929-1995)
|
4
|
+
# The Neverending Story is a fantasy novel by German writer Michael Ende,
|
5
|
+
# The English version, translated by Ralph Manheim, was published in 1983.
|
6
|
+
class BasicDrawText
|
7
|
+
include Glimmer
|
8
|
+
|
9
|
+
def alternating_color_string(&block)
|
10
|
+
@index ||= 0
|
11
|
+
@index += 1
|
12
|
+
string {
|
13
|
+
if @index.odd?
|
14
|
+
color r: 0.5, g: 0, b: 0.25, a: 0.7
|
15
|
+
else
|
16
|
+
color r: 0, g: 0.5, b: 0, a: 0.7
|
17
|
+
end
|
18
|
+
|
19
|
+
block.call + "\n\n"
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def launch
|
24
|
+
window('Michael Ende (1929-1995) The Neverending Story', 600, 400) {
|
25
|
+
margined true
|
26
|
+
|
27
|
+
area {
|
28
|
+
on_draw do |area_draw_params|
|
29
|
+
text(0, 0, area_draw_params[:area_width]) {
|
30
|
+
align 0
|
31
|
+
default_font family: 'Georgia', size: 13, weight: 500, italic: 0, stretch: 4
|
32
|
+
|
33
|
+
alternating_color_string {
|
34
|
+
' At last Ygramul sensed that something was coming toward ' \
|
35
|
+
'her. With the speed of lightning, she turned about, confronting ' \
|
36
|
+
'Atreyu with an enormous steel-blue face. Her single eye had a ' \
|
37
|
+
'vertical pupil, which stared at Atreyu with inconceivable malignancy. '
|
38
|
+
}
|
39
|
+
alternating_color_string {
|
40
|
+
' A cry of fear escaped Bastian. '
|
41
|
+
}
|
42
|
+
alternating_color_string {
|
43
|
+
' A cry of terror passed through the ravine and echoed from ' \
|
44
|
+
'side to side. Ygramul turned her eye to left and right, to see if ' \
|
45
|
+
'someone else had arrived, for that sound could not have been ' \
|
46
|
+
'made by the boy who stood there as though paralyzed with ' \
|
47
|
+
'horror. '
|
48
|
+
}
|
49
|
+
alternating_color_string {
|
50
|
+
' Could she have heard my cry? Bastion wondered in alarm. ' \
|
51
|
+
"But that's not possible. "
|
52
|
+
}
|
53
|
+
alternating_color_string {
|
54
|
+
' And then Atreyu heard Ygramuls voice. It was very high ' \
|
55
|
+
'and slightly hoarse, not at all the right kind of voice for that ' \
|
56
|
+
'enormous face. Her lips did not move as she spoke. It was the ' \
|
57
|
+
'buzzing of a great swarm of hornets that shaped itself into ' \
|
58
|
+
'words. '
|
59
|
+
}
|
60
|
+
}
|
61
|
+
end
|
62
|
+
}
|
63
|
+
}.show
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
BasicDrawText.new.launch
|
@@ -0,0 +1,220 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
|
3
|
+
class ColorTheCircles
|
4
|
+
include Glimmer
|
5
|
+
|
6
|
+
WINDOW_WIDTH = 800
|
7
|
+
WINDOW_HEIGHT = 600
|
8
|
+
CIRCLE_MIN_RADIUS = 15
|
9
|
+
CIRCLE_MAX_RADIUS = 50
|
10
|
+
MARGIN_WIDTH = 55
|
11
|
+
MARGIN_HEIGHT = 155
|
12
|
+
TIME_MAX_EASY = 4
|
13
|
+
TIME_MAX_MEDIUM = 3
|
14
|
+
TIME_MAX_HARD = 2
|
15
|
+
TIME_MAX_INSANE = 1
|
16
|
+
|
17
|
+
attr_accessor :score
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@circles_data = []
|
21
|
+
@score = 0
|
22
|
+
@time_max = TIME_MAX_HARD
|
23
|
+
@game_over = false
|
24
|
+
register_observers
|
25
|
+
setup_circle_factory
|
26
|
+
end
|
27
|
+
|
28
|
+
def register_observers
|
29
|
+
observer = Glimmer::DataBinding::Observer.proc do |new_score|
|
30
|
+
@score_label.text = new_score.to_s
|
31
|
+
if new_score == -20
|
32
|
+
@game_over = true
|
33
|
+
msg_box('You Lost!', 'Sorry! Your score reached -20')
|
34
|
+
restart_game
|
35
|
+
elsif new_score == 0
|
36
|
+
@game_over = true
|
37
|
+
msg_box('You Won!', 'Congratulations! Your score reached 0')
|
38
|
+
restart_game
|
39
|
+
end
|
40
|
+
end
|
41
|
+
observer.observe(self, :score) # automatically enhances self to become Glimmer::DataBinding::ObservableModel and notify observer on score attribute changes
|
42
|
+
end
|
43
|
+
|
44
|
+
def setup_circle_factory
|
45
|
+
consumer = Proc.new do
|
46
|
+
unless @game_over
|
47
|
+
if @circles_data.empty?
|
48
|
+
# start with 3 circles to make more challenging
|
49
|
+
add_circle until @circles_data.size > 3
|
50
|
+
else
|
51
|
+
add_circle
|
52
|
+
end
|
53
|
+
end
|
54
|
+
delay = rand * @time_max
|
55
|
+
Glimmer::LibUI.timer(delay, repeat: false, &consumer)
|
56
|
+
end
|
57
|
+
Glimmer::LibUI.queue_main(&consumer)
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_circle
|
61
|
+
circle_x_center = rand * (WINDOW_WIDTH - MARGIN_WIDTH - CIRCLE_MAX_RADIUS) + CIRCLE_MAX_RADIUS
|
62
|
+
circle_y_center = rand * (WINDOW_HEIGHT - MARGIN_HEIGHT - CIRCLE_MAX_RADIUS) + CIRCLE_MAX_RADIUS
|
63
|
+
circle_radius = rand * (CIRCLE_MAX_RADIUS - CIRCLE_MIN_RADIUS) + CIRCLE_MIN_RADIUS
|
64
|
+
stroke_color = Glimmer::LibUI.x11_colors.sample
|
65
|
+
@circles_data << {
|
66
|
+
args: [circle_x_center, circle_y_center, circle_radius],
|
67
|
+
fill: nil,
|
68
|
+
stroke: stroke_color
|
69
|
+
}
|
70
|
+
@area.queue_redraw_all
|
71
|
+
self.score -= 1 # notifies score observers automatically of change
|
72
|
+
end
|
73
|
+
|
74
|
+
def restart_game
|
75
|
+
@score = 0 # update variable directly to avoid notifying observers
|
76
|
+
@circles_data.clear
|
77
|
+
@game_over = false
|
78
|
+
end
|
79
|
+
|
80
|
+
def color_circle(x, y)
|
81
|
+
clicked_circle_data = @circles_data.find do |circle_data|
|
82
|
+
circle_data[:fill].nil? && circle_data[:circle].include?(x, y)
|
83
|
+
end
|
84
|
+
if clicked_circle_data
|
85
|
+
clicked_circle_data[:fill] = clicked_circle_data[:stroke]
|
86
|
+
push_colored_circle_behind_uncolored_circles(clicked_circle_data)
|
87
|
+
@area.queue_redraw_all
|
88
|
+
self.score += 1 # notifies score observers automatically of change
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def push_colored_circle_behind_uncolored_circles(colored_circle_data)
|
93
|
+
removed_colored_circle_data = @circles_data.delete(colored_circle_data)
|
94
|
+
last_colored_circle_data = @circles_data.select {|cd| cd[:fill]}.last
|
95
|
+
last_colored_circle_data_index = @circles_data.index(last_colored_circle_data) || -1
|
96
|
+
@circles_data.insert(last_colored_circle_data_index + 1, removed_colored_circle_data)
|
97
|
+
end
|
98
|
+
|
99
|
+
def launch
|
100
|
+
menu('Actions') {
|
101
|
+
menu_item('Restart') {
|
102
|
+
on_clicked do
|
103
|
+
restart_game
|
104
|
+
end
|
105
|
+
}
|
106
|
+
|
107
|
+
quit_menu_item
|
108
|
+
}
|
109
|
+
|
110
|
+
menu('Difficulty') {
|
111
|
+
radio_menu_item('Easy') {
|
112
|
+
on_clicked do
|
113
|
+
@time_max = TIME_MAX_EASY
|
114
|
+
end
|
115
|
+
}
|
116
|
+
|
117
|
+
radio_menu_item('Medium') {
|
118
|
+
on_clicked do
|
119
|
+
@time_max = TIME_MAX_MEDIUM
|
120
|
+
end
|
121
|
+
}
|
122
|
+
|
123
|
+
radio_menu_item('Hard') {
|
124
|
+
checked true
|
125
|
+
|
126
|
+
on_clicked do
|
127
|
+
@time_max = TIME_MAX_HARD
|
128
|
+
end
|
129
|
+
}
|
130
|
+
|
131
|
+
radio_menu_item('Insane') {
|
132
|
+
on_clicked do
|
133
|
+
@time_max = TIME_MAX_INSANE
|
134
|
+
end
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
menu('Help') {
|
139
|
+
menu_item('Instructions') {
|
140
|
+
on_clicked do
|
141
|
+
msg_box('Instructions', "Score goes down as circles are added.\nIf it reaches -20, you lose!\n\nClick circles to color and score!\nOnce score reaches 0, you win!\n\nBeware of concealed light-colored circles!\nThey are revealed once darker circles intersect them.\n\nThere are four levels of difficulty.\nChange via difficulty menu if the game gets too tough.")
|
142
|
+
end
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
window('Color The Circles', WINDOW_WIDTH, WINDOW_HEIGHT) {
|
147
|
+
margined true
|
148
|
+
|
149
|
+
grid {
|
150
|
+
button('Restart') {
|
151
|
+
left 0
|
152
|
+
top 0
|
153
|
+
halign :center
|
154
|
+
|
155
|
+
on_clicked do
|
156
|
+
restart_game
|
157
|
+
end
|
158
|
+
}
|
159
|
+
|
160
|
+
label('Score goes down as circles are added. If it reaches -20, you lose!') {
|
161
|
+
left 0
|
162
|
+
top 1
|
163
|
+
halign :center
|
164
|
+
}
|
165
|
+
|
166
|
+
label('Click circles to color and score! Once score reaches 0, you win!') {
|
167
|
+
left 0
|
168
|
+
top 2
|
169
|
+
halign :center
|
170
|
+
}
|
171
|
+
|
172
|
+
horizontal_box {
|
173
|
+
left 0
|
174
|
+
top 3
|
175
|
+
halign :center
|
176
|
+
|
177
|
+
label('Score:') {
|
178
|
+
stretchy false
|
179
|
+
}
|
180
|
+
|
181
|
+
@score_label = label(@score.to_s) {
|
182
|
+
stretchy false
|
183
|
+
}
|
184
|
+
}
|
185
|
+
|
186
|
+
@area = area {
|
187
|
+
left 0
|
188
|
+
top 4
|
189
|
+
hexpand true
|
190
|
+
vexpand true
|
191
|
+
halign :fill
|
192
|
+
valign :fill
|
193
|
+
|
194
|
+
on_draw do |area_draw_params|
|
195
|
+
path {
|
196
|
+
rectangle(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
|
197
|
+
|
198
|
+
fill :white
|
199
|
+
}
|
200
|
+
|
201
|
+
@circles_data.each do |circle_data|
|
202
|
+
path {
|
203
|
+
circle_data[:circle] = circle(*circle_data[:args])
|
204
|
+
|
205
|
+
fill circle_data[:fill]
|
206
|
+
stroke circle_data[:stroke]
|
207
|
+
}
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
on_mouse_down do |area_mouse_event|
|
212
|
+
color_circle(area_mouse_event[:x], area_mouse_event[:y])
|
213
|
+
end
|
214
|
+
}
|
215
|
+
}
|
216
|
+
}.show
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
ColorTheCircles.new.launch
|
data/examples/midi_player.rb
CHANGED
@@ -9,7 +9,7 @@ class TinyMidiPlayer
|
|
9
9
|
|
10
10
|
def initialize
|
11
11
|
@pid = nil
|
12
|
-
@music_directory = File.expand_path(
|
12
|
+
@music_directory = File.expand_path('../sounds', __dir__)
|
13
13
|
@midi_files = Dir.glob(File.join(@music_directory, '**/*.mid'))
|
14
14
|
.sort_by { |path| File.basename(path) }
|
15
15
|
at_exit { stop_midi }
|
@@ -48,7 +48,7 @@ class TinyMidiPlayer
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def create_gui
|
51
|
-
menu('Help') {
|
51
|
+
menu('Help') {
|
52
52
|
menu_item('Version') {
|
53
53
|
on_clicked do
|
54
54
|
show_version
|
data/examples/timer.rb
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'glimmer-dsl-libui'
|
4
|
+
|
5
|
+
class Timer
|
6
|
+
include Glimmer
|
7
|
+
|
8
|
+
SECOND_MAX = 59
|
9
|
+
MINUTE_MAX = 59
|
10
|
+
HOUR_MAX = 23
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@pid = nil
|
14
|
+
@alarm_file = File.expand_path('../sounds/AlanWalker-Faded.mid', __dir__)
|
15
|
+
at_exit { stop_alarm }
|
16
|
+
setup_timer
|
17
|
+
create_gui
|
18
|
+
end
|
19
|
+
|
20
|
+
def stop_alarm
|
21
|
+
if @pid
|
22
|
+
if @th.alive?
|
23
|
+
Process.kill(:SIGKILL, @pid)
|
24
|
+
@pid = nil
|
25
|
+
else
|
26
|
+
@pid = nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def play_alarm
|
32
|
+
stop_alarm
|
33
|
+
if @pid.nil?
|
34
|
+
begin
|
35
|
+
@pid = spawn "timidity -G 0.0-10.0 #{@alarm_file}"
|
36
|
+
@th = Process.detach @pid
|
37
|
+
rescue Errno::ENOENT
|
38
|
+
warn 'Timidty++ not found. Please install Timidity++.'
|
39
|
+
warn 'https://sourceforge.net/projects/timidity/'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def setup_timer
|
45
|
+
unless @setup_timer
|
46
|
+
Glimmer::LibUI.timer(1) do
|
47
|
+
if @started
|
48
|
+
seconds = @sec_spinbox.value
|
49
|
+
minutes = @min_spinbox.value
|
50
|
+
hours = @hour_spinbox.value
|
51
|
+
if seconds > 0
|
52
|
+
@sec_spinbox.value = seconds -= 1
|
53
|
+
end
|
54
|
+
if seconds == 0
|
55
|
+
if minutes > 0
|
56
|
+
@min_spinbox.value = minutes -= 1
|
57
|
+
@sec_spinbox.value = seconds = SECOND_MAX
|
58
|
+
end
|
59
|
+
if minutes == 0
|
60
|
+
if hours > 0
|
61
|
+
@hour_spinbox.value = hours -= 1
|
62
|
+
@min_spinbox.value = minutes = MINUTE_MAX
|
63
|
+
@sec_spinbox.value = seconds = SECOND_MAX
|
64
|
+
end
|
65
|
+
if hours == 0 && minutes == 0 && seconds == 0
|
66
|
+
@start_button.enabled = true
|
67
|
+
@stop_button.enabled = false
|
68
|
+
@started = false
|
69
|
+
unless @played
|
70
|
+
play_alarm
|
71
|
+
msg_box('Alarm', 'Countdown Is Finished!')
|
72
|
+
@played = true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
@setup_timer = true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def create_gui
|
84
|
+
window('Timer') {
|
85
|
+
margined true
|
86
|
+
|
87
|
+
group('Countdown') {
|
88
|
+
vertical_box {
|
89
|
+
horizontal_box {
|
90
|
+
@hour_spinbox = spinbox(0, HOUR_MAX) {
|
91
|
+
stretchy false
|
92
|
+
value 0
|
93
|
+
}
|
94
|
+
label(':') {
|
95
|
+
stretchy false
|
96
|
+
}
|
97
|
+
@min_spinbox = spinbox(0, MINUTE_MAX) {
|
98
|
+
stretchy false
|
99
|
+
value 0
|
100
|
+
}
|
101
|
+
label(':') {
|
102
|
+
stretchy false
|
103
|
+
}
|
104
|
+
@sec_spinbox = spinbox(0, SECOND_MAX) {
|
105
|
+
stretchy false
|
106
|
+
value 0
|
107
|
+
}
|
108
|
+
}
|
109
|
+
horizontal_box {
|
110
|
+
@start_button = button('Start') {
|
111
|
+
on_clicked do
|
112
|
+
@start_button.enabled = false
|
113
|
+
@stop_button.enabled = true
|
114
|
+
@started = true
|
115
|
+
@played = false
|
116
|
+
end
|
117
|
+
}
|
118
|
+
|
119
|
+
@stop_button = button('Stop') {
|
120
|
+
enabled false
|
121
|
+
|
122
|
+
on_clicked do
|
123
|
+
@start_button.enabled = true
|
124
|
+
@stop_button.enabled = false
|
125
|
+
@started = false
|
126
|
+
end
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
}.show
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
Timer.new
|
data/glimmer-dsl-libui.gemspec
CHANGED
Binary file
|
@@ -22,6 +22,7 @@
|
|
22
22
|
require 'glimmer/dsl/expression'
|
23
23
|
require 'glimmer/libui/control_proxy'
|
24
24
|
require 'glimmer/libui/shape'
|
25
|
+
require 'glimmer/libui/attributed_string'
|
25
26
|
|
26
27
|
module Glimmer
|
27
28
|
module DSL
|
@@ -30,7 +31,8 @@ module Glimmer
|
|
30
31
|
def can_interpret?(parent, keyword, *args, &block)
|
31
32
|
(
|
32
33
|
parent.is_a?(Glimmer::LibUI::ControlProxy) or
|
33
|
-
parent.is_a?(Glimmer::LibUI::Shape)
|
34
|
+
parent.is_a?(Glimmer::LibUI::Shape) or
|
35
|
+
parent.is_a?(Glimmer::LibUI::AttributedString)
|
34
36
|
) and
|
35
37
|
block.nil? and
|
36
38
|
parent.respond_to?(keyword, *args)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Copyright (c) 2021 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'glimmer/dsl/static_expression'
|
23
|
+
require 'glimmer/dsl/parent_expression'
|
24
|
+
require 'glimmer/libui/control_proxy/text_proxy'
|
25
|
+
require 'glimmer/libui/attributed_string'
|
26
|
+
|
27
|
+
module Glimmer
|
28
|
+
module DSL
|
29
|
+
module Libui
|
30
|
+
class StringExpression < StaticExpression
|
31
|
+
include ParentExpression
|
32
|
+
|
33
|
+
def can_interpret?(parent, keyword, *args, &block)
|
34
|
+
super and
|
35
|
+
parent.is_a?(Glimmer::LibUI::ControlProxy::TextProxy)
|
36
|
+
end
|
37
|
+
|
38
|
+
def interpret(parent, keyword, *args, &block)
|
39
|
+
Glimmer::LibUI::AttributedString.new(keyword, parent, args, &block)
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_content(parent, keyword, *args, &block)
|
43
|
+
parent.post_add_content
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|