glimmer-dsl-libui 0.4.1 → 0.4.5
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 +32 -1
- data/README.md +1628 -204
- data/VERSION +1 -1
- data/examples/basic_entry.rb +27 -24
- data/examples/basic_entry2.rb +31 -0
- data/examples/button_counter.rb +27 -0
- data/examples/dynamic_area.rb +77 -90
- data/examples/dynamic_area2.rb +14 -12
- data/examples/dynamic_area3.rb +90 -0
- data/examples/dynamic_area4.rb +95 -0
- data/examples/form.rb +42 -30
- data/examples/form2.rb +37 -0
- data/examples/form_table.rb +100 -87
- data/examples/form_table2.rb +93 -0
- data/examples/histogram.rb +98 -91
- data/examples/histogram2.rb +109 -0
- data/examples/login.rb +45 -39
- data/examples/login2.rb +55 -0
- data/examples/login3.rb +65 -0
- data/examples/login4.rb +61 -0
- data/examples/login5.rb +43 -0
- data/examples/meta_example.rb +10 -7
- data/examples/method_based_custom_keyword.rb +8 -15
- data/examples/method_based_custom_keyword2.rb +97 -0
- data/examples/snake.rb +1 -1
- data/examples/timer.rb +28 -31
- data/examples/timer2.rb +129 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/dsl/libui/data_binding_expression.rb +4 -6
- data/lib/glimmer/libui/attributed_string.rb +3 -0
- data/lib/glimmer/libui/control_proxy/area_proxy.rb +52 -46
- data/lib/glimmer/libui/control_proxy/entry_proxy.rb +5 -0
- data/lib/glimmer/libui/control_proxy/image_proxy.rb +4 -5
- data/lib/glimmer/libui/control_proxy/multiline_entry_proxy.rb +5 -0
- data/lib/glimmer/libui/control_proxy/spinbox_proxy.rb +38 -0
- data/lib/glimmer/libui/control_proxy/table_proxy.rb +1 -1
- data/lib/glimmer/libui/control_proxy.rb +8 -1
- data/lib/glimmer/libui/data_bindable.rb +39 -0
- data/lib/glimmer/libui/shape.rb +7 -2
- metadata +17 -2
data/examples/form_table.rb
CHANGED
@@ -1,95 +1,108 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require 'glimmer-dsl-libui'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
data = [
|
8
|
-
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO', '80014'],
|
9
|
-
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA', '02101'],
|
10
|
-
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL', '60007'],
|
11
|
-
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA', '98101'],
|
12
|
-
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA', '90001'],
|
13
|
-
]
|
14
|
-
|
15
|
-
window('Contacts', 600, 600) { |w|
|
16
|
-
margined true
|
3
|
+
class FormTable
|
4
|
+
include Glimmer
|
17
5
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
@
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
@
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@city_entry = entry {
|
35
|
-
label 'City'
|
36
|
-
}
|
37
|
-
|
38
|
-
@state_entry = entry {
|
39
|
-
label 'State'
|
40
|
-
}
|
41
|
-
}
|
42
|
-
|
43
|
-
button('Save Contact') {
|
44
|
-
stretchy false
|
45
|
-
|
46
|
-
on_clicked do
|
47
|
-
new_row = [@name_entry.text, @email_entry.text, @phone_entry.text, @city_entry.text, @state_entry.text]
|
48
|
-
if new_row.include?('')
|
49
|
-
msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
50
|
-
else
|
51
|
-
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
52
|
-
@unfiltered_data = data.dup
|
53
|
-
@name_entry.text = ''
|
54
|
-
@email_entry.text = ''
|
55
|
-
@phone_entry.text = ''
|
56
|
-
@city_entry.text = ''
|
57
|
-
@state_entry.text = ''
|
58
|
-
end
|
59
|
-
end
|
60
|
-
}
|
61
|
-
|
62
|
-
search_entry { |se|
|
63
|
-
stretchy false
|
6
|
+
attr_accessor :name, :email, :phone, :city, :state, :filter_value
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@data = [
|
10
|
+
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO', '80014'],
|
11
|
+
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA', '02101'],
|
12
|
+
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL', '60007'],
|
13
|
+
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA', '98101'],
|
14
|
+
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA', '90001'],
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
def launch
|
19
|
+
window('Contacts', 600, 600) { |w|
|
20
|
+
margined true
|
64
21
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
22
|
+
vertical_box {
|
23
|
+
form {
|
24
|
+
stretchy false
|
25
|
+
|
26
|
+
entry {
|
27
|
+
label 'Name'
|
28
|
+
text <=> [self, :name]
|
29
|
+
}
|
30
|
+
|
31
|
+
entry {
|
32
|
+
label 'Email'
|
33
|
+
text <=> [self, :email]
|
34
|
+
}
|
35
|
+
|
36
|
+
entry {
|
37
|
+
label 'Phone'
|
38
|
+
text <=> [self, :phone]
|
39
|
+
}
|
40
|
+
|
41
|
+
entry {
|
42
|
+
label 'City'
|
43
|
+
text <=> [self, :city]
|
44
|
+
}
|
45
|
+
|
46
|
+
entry {
|
47
|
+
label 'State'
|
48
|
+
text <=> [self, :state]
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
button('Save Contact') {
|
53
|
+
stretchy false
|
54
|
+
|
55
|
+
on_clicked do
|
56
|
+
new_row = [name, email, phone, city, state]
|
57
|
+
if new_row.include?('')
|
58
|
+
msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
59
|
+
else
|
60
|
+
@data << new_row # automatically inserts a row into the table due to implicit data-binding
|
61
|
+
@unfiltered_data = @data.dup
|
62
|
+
self.name = '' # automatically clears name entry through explicit data-binding
|
63
|
+
self.email = ''
|
64
|
+
self.phone = ''
|
65
|
+
self.city = ''
|
66
|
+
self.state = ''
|
75
67
|
end
|
76
68
|
end
|
77
|
-
|
78
|
-
|
79
|
-
|
69
|
+
}
|
70
|
+
|
71
|
+
search_entry {
|
72
|
+
stretchy false
|
73
|
+
text <=> [self, :filter_value, # bidirectional data-binding of text to self.filter_value with after_write option
|
74
|
+
after_write: ->(filter_value) { # execute after write to self.filter_value
|
75
|
+
@unfiltered_data ||= @data.dup
|
76
|
+
# Unfilter first to remove any previous filters
|
77
|
+
@data.replace(@unfiltered_data) # affects table indirectly through implicit data-binding
|
78
|
+
# Now, apply filter if entered
|
79
|
+
unless filter_value.empty?
|
80
|
+
@data.filter! do |row_data| # affects table indirectly through implicit data-binding
|
81
|
+
row_data.any? do |cell|
|
82
|
+
cell.to_s.downcase.include?(filter_value.downcase)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
}
|
87
|
+
]
|
88
|
+
}
|
89
|
+
|
90
|
+
table {
|
91
|
+
text_column('Name')
|
92
|
+
text_column('Email')
|
93
|
+
text_column('Phone')
|
94
|
+
text_column('City')
|
95
|
+
text_column('State')
|
80
96
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
97
|
+
cell_rows @data # implicit data-binding
|
98
|
+
|
99
|
+
on_changed do |row, type, row_data|
|
100
|
+
puts "Row #{row} #{type}: #{row_data}"
|
101
|
+
end
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}.show
|
105
|
+
end
|
106
|
+
end
|
87
107
|
|
88
|
-
|
89
|
-
|
90
|
-
on_changed do |row, type, row_data|
|
91
|
-
puts "Row #{row} #{type}: #{row_data}"
|
92
|
-
end
|
93
|
-
}
|
94
|
-
}
|
95
|
-
}.show
|
108
|
+
FormTable.new.launch
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
|
3
|
+
include Glimmer
|
4
|
+
|
5
|
+
data = [
|
6
|
+
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO', '80014'],
|
7
|
+
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA', '02101'],
|
8
|
+
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL', '60007'],
|
9
|
+
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA', '98101'],
|
10
|
+
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA', '90001'],
|
11
|
+
]
|
12
|
+
|
13
|
+
window('Contacts', 600, 600) { |w|
|
14
|
+
margined true
|
15
|
+
|
16
|
+
vertical_box {
|
17
|
+
form {
|
18
|
+
stretchy false
|
19
|
+
|
20
|
+
@name_entry = entry {
|
21
|
+
label 'Name'
|
22
|
+
}
|
23
|
+
|
24
|
+
@email_entry = entry {
|
25
|
+
label 'Email'
|
26
|
+
}
|
27
|
+
|
28
|
+
@phone_entry = entry {
|
29
|
+
label 'Phone'
|
30
|
+
}
|
31
|
+
|
32
|
+
@city_entry = entry {
|
33
|
+
label 'City'
|
34
|
+
}
|
35
|
+
|
36
|
+
@state_entry = entry {
|
37
|
+
label 'State'
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
button('Save Contact') {
|
42
|
+
stretchy false
|
43
|
+
|
44
|
+
on_clicked do
|
45
|
+
new_row = [@name_entry.text, @email_entry.text, @phone_entry.text, @city_entry.text, @state_entry.text]
|
46
|
+
if new_row.include?('')
|
47
|
+
msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
48
|
+
else
|
49
|
+
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
50
|
+
@unfiltered_data = data.dup
|
51
|
+
@name_entry.text = ''
|
52
|
+
@email_entry.text = ''
|
53
|
+
@phone_entry.text = ''
|
54
|
+
@city_entry.text = ''
|
55
|
+
@state_entry.text = ''
|
56
|
+
end
|
57
|
+
end
|
58
|
+
}
|
59
|
+
|
60
|
+
search_entry { |se|
|
61
|
+
stretchy false
|
62
|
+
|
63
|
+
on_changed do
|
64
|
+
filter_value = se.text
|
65
|
+
@unfiltered_data ||= data.dup
|
66
|
+
# Unfilter first to remove any previous filters
|
67
|
+
data.replace(@unfiltered_data) # affects table indirectly through implicit data-binding
|
68
|
+
# Now, apply filter if entered
|
69
|
+
unless filter_value.empty?
|
70
|
+
data.filter! do |row_data| # affects table indirectly through implicit data-binding
|
71
|
+
row_data.any? do |cell|
|
72
|
+
cell.to_s.downcase.include?(filter_value.downcase)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
}
|
78
|
+
|
79
|
+
table {
|
80
|
+
text_column('Name')
|
81
|
+
text_column('Email')
|
82
|
+
text_column('Phone')
|
83
|
+
text_column('City')
|
84
|
+
text_column('State')
|
85
|
+
|
86
|
+
cell_rows data # implicit data-binding
|
87
|
+
|
88
|
+
on_changed do |row, type, row_data|
|
89
|
+
puts "Row #{row} #{type}: #{row_data}"
|
90
|
+
end
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}.show
|
data/examples/histogram.rb
CHANGED
@@ -2,106 +2,113 @@
|
|
2
2
|
|
3
3
|
require 'glimmer-dsl-libui'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
def point_locations(width, height)
|
23
|
-
xincr = width / 9.0 # 10 - 1 to make the last point be at the end
|
24
|
-
yincr = height / 100.0
|
25
|
-
|
26
|
-
@datapoints.each_with_index.map do |value, i|
|
27
|
-
val = 100 - value
|
28
|
-
[xincr * i, yincr * val]
|
5
|
+
class Histogram
|
6
|
+
include Glimmer
|
7
|
+
|
8
|
+
X_OFF_LEFT = 20
|
9
|
+
Y_OFF_TOP = 20
|
10
|
+
X_OFF_RIGHT = 20
|
11
|
+
Y_OFF_BOTTOM = 20
|
12
|
+
POINT_RADIUS = 5
|
13
|
+
COLOR_BLUE = Glimmer::LibUI.interpret_color(0x1E90FF)
|
14
|
+
|
15
|
+
attr_accessor :datapoints, :histogram_color
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@datapoints = 10.times.map {Random.new.rand(90)}
|
19
|
+
@histogram_color = COLOR_BLUE
|
29
20
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
21
|
+
|
22
|
+
def graph_size(area_width, area_height)
|
23
|
+
graph_width = area_width - X_OFF_LEFT - X_OFF_RIGHT
|
24
|
+
graph_height = area_height - Y_OFF_TOP - Y_OFF_BOTTOM
|
25
|
+
[graph_width, graph_height]
|
26
|
+
end
|
27
|
+
|
28
|
+
def point_locations(width, height)
|
29
|
+
xincr = width / 9.0 # 10 - 1 to make the last point be at the end
|
30
|
+
yincr = height / 100.0
|
31
|
+
|
32
|
+
@datapoints.each_with_index.map do |value, i|
|
33
|
+
val = 100 - value
|
34
|
+
[xincr * i, yincr * val]
|
40
35
|
end
|
41
|
-
|
42
|
-
# apply a transform to the coordinate space for this path so (0, 0) is the top-left corner of the graph
|
43
|
-
transform {
|
44
|
-
translate X_OFF_LEFT, Y_OFF_TOP
|
45
|
-
}
|
46
|
-
|
47
|
-
block.call
|
48
|
-
}
|
49
|
-
end
|
50
|
-
|
51
|
-
window('histogram example', 640, 480) {
|
52
|
-
margined true
|
36
|
+
end
|
53
37
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
on_changed do
|
64
|
-
@datapoints[i] = sb.value
|
65
|
-
@area.queue_redraw_all
|
66
|
-
end
|
67
|
-
}
|
38
|
+
# method-based custom control representing a graph path
|
39
|
+
def graph_path(width, height, should_extend, &block)
|
40
|
+
locations = point_locations(width, height).flatten
|
41
|
+
path {
|
42
|
+
if should_extend
|
43
|
+
polygon(locations + [width, height, 0, height])
|
44
|
+
else
|
45
|
+
polyline(locations)
|
68
46
|
end
|
69
47
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
on_changed do
|
75
|
-
@area.queue_redraw_all
|
76
|
-
end
|
48
|
+
# apply a transform to the coordinate space for this path so (0, 0) is the top-left corner of the graph
|
49
|
+
transform {
|
50
|
+
translate X_OFF_LEFT, Y_OFF_TOP
|
77
51
|
}
|
52
|
+
|
53
|
+
block.call
|
78
54
|
}
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
}
|
85
|
-
|
86
|
-
graph_width, graph_height = *graph_size(area_draw_params[:area_width], area_draw_params[:area_height])
|
55
|
+
end
|
56
|
+
|
57
|
+
def launch
|
58
|
+
window('histogram example', 640, 480) {
|
59
|
+
margined true
|
87
60
|
|
88
|
-
|
89
|
-
|
90
|
-
|
61
|
+
horizontal_box {
|
62
|
+
vertical_box {
|
63
|
+
stretchy false
|
91
64
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
65
|
+
10.times do |i|
|
66
|
+
spinbox(0, 100) { |sb|
|
67
|
+
stretchy false
|
68
|
+
value <=> [self, "datapoints[#{i}]", after_write: -> { @area.queue_redraw_all }]
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
color_button { |cb|
|
73
|
+
stretchy false
|
74
|
+
color COLOR_BLUE
|
75
|
+
|
76
|
+
on_changed do
|
77
|
+
@histogram_color = cb.color
|
78
|
+
@area.queue_redraw_all
|
79
|
+
end
|
80
|
+
}
|
98
81
|
}
|
99
82
|
|
100
|
-
|
101
|
-
|
102
|
-
|
83
|
+
@area = area {
|
84
|
+
on_draw do |area_draw_params|
|
85
|
+
rectangle(0, 0, area_draw_params[:area_width], area_draw_params[:area_height]) {
|
86
|
+
fill 0xFFFFFF
|
87
|
+
}
|
88
|
+
|
89
|
+
graph_width, graph_height = *graph_size(area_draw_params[:area_width], area_draw_params[:area_height])
|
90
|
+
|
91
|
+
figure(X_OFF_LEFT, Y_OFF_TOP) {
|
92
|
+
line(X_OFF_LEFT, Y_OFF_TOP + graph_height)
|
93
|
+
line(X_OFF_LEFT + graph_width, Y_OFF_TOP + graph_height)
|
94
|
+
|
95
|
+
stroke 0x000000, thickness: 2, miter_limit: 10
|
96
|
+
}
|
97
|
+
|
98
|
+
# now create the fill for the graph below the graph line
|
99
|
+
graph_path(graph_width, graph_height, true) {
|
100
|
+
fill @histogram_color.merge(a: 0.5)
|
101
|
+
}
|
102
|
+
|
103
|
+
# now draw the histogram line
|
104
|
+
graph_path(graph_width, graph_height, false) {
|
105
|
+
stroke @histogram_color.merge(thickness: 2, miter_limit: 10)
|
106
|
+
}
|
107
|
+
end
|
103
108
|
}
|
104
|
-
|
105
|
-
}
|
106
|
-
|
107
|
-
|
109
|
+
}
|
110
|
+
}.show
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
Histogram.new.launch
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# https://github.com/jamescook/libui-ruby/blob/master/example/histogram.rb
|
2
|
+
|
3
|
+
require 'glimmer-dsl-libui'
|
4
|
+
|
5
|
+
include Glimmer
|
6
|
+
|
7
|
+
X_OFF_LEFT = 20
|
8
|
+
Y_OFF_TOP = 20
|
9
|
+
X_OFF_RIGHT = 20
|
10
|
+
Y_OFF_BOTTOM = 20
|
11
|
+
POINT_RADIUS = 5
|
12
|
+
COLOR_BLUE = Glimmer::LibUI.interpret_color(0x1E90FF)
|
13
|
+
|
14
|
+
@datapoints = 10.times.map {Random.new.rand(90)}
|
15
|
+
@color = COLOR_BLUE
|
16
|
+
|
17
|
+
def graph_size(area_width, area_height)
|
18
|
+
graph_width = area_width - X_OFF_LEFT - X_OFF_RIGHT
|
19
|
+
graph_height = area_height - Y_OFF_TOP - Y_OFF_BOTTOM
|
20
|
+
[graph_width, graph_height]
|
21
|
+
end
|
22
|
+
|
23
|
+
def point_locations(width, height)
|
24
|
+
xincr = width / 9.0 # 10 - 1 to make the last point be at the end
|
25
|
+
yincr = height / 100.0
|
26
|
+
|
27
|
+
@datapoints.each_with_index.map do |value, i|
|
28
|
+
val = 100 - value
|
29
|
+
[xincr * i, yincr * val]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# method-based custom control representing a graph path
|
34
|
+
def graph_path(width, height, should_extend, &block)
|
35
|
+
locations = point_locations(width, height).flatten
|
36
|
+
path {
|
37
|
+
if should_extend
|
38
|
+
polygon(locations + [width, height, 0, height])
|
39
|
+
else
|
40
|
+
polyline(locations)
|
41
|
+
end
|
42
|
+
|
43
|
+
# apply a transform to the coordinate space for this path so (0, 0) is the top-left corner of the graph
|
44
|
+
transform {
|
45
|
+
translate X_OFF_LEFT, Y_OFF_TOP
|
46
|
+
}
|
47
|
+
|
48
|
+
block.call
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
window('histogram example', 640, 480) {
|
53
|
+
margined true
|
54
|
+
|
55
|
+
horizontal_box {
|
56
|
+
vertical_box {
|
57
|
+
stretchy false
|
58
|
+
|
59
|
+
10.times do |i|
|
60
|
+
spinbox(0, 100) { |sb|
|
61
|
+
stretchy false
|
62
|
+
value @datapoints[i]
|
63
|
+
|
64
|
+
on_changed do
|
65
|
+
@datapoints[i] = sb.value
|
66
|
+
@area.queue_redraw_all
|
67
|
+
end
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
color_button { |cb|
|
72
|
+
stretchy false
|
73
|
+
color COLOR_BLUE
|
74
|
+
|
75
|
+
on_changed do
|
76
|
+
@color = cb.color
|
77
|
+
@area.queue_redraw_all
|
78
|
+
end
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
@area = area {
|
83
|
+
on_draw do |area_draw_params|
|
84
|
+
rectangle(0, 0, area_draw_params[:area_width], area_draw_params[:area_height]) {
|
85
|
+
fill 0xFFFFFF
|
86
|
+
}
|
87
|
+
|
88
|
+
graph_width, graph_height = *graph_size(area_draw_params[:area_width], area_draw_params[:area_height])
|
89
|
+
|
90
|
+
figure(X_OFF_LEFT, Y_OFF_TOP) {
|
91
|
+
line(X_OFF_LEFT, Y_OFF_TOP + graph_height)
|
92
|
+
line(X_OFF_LEFT + graph_width, Y_OFF_TOP + graph_height)
|
93
|
+
|
94
|
+
stroke 0x000000, thickness: 2, miter_limit: 10
|
95
|
+
}
|
96
|
+
|
97
|
+
# now create the fill for the graph below the graph line
|
98
|
+
graph_path(graph_width, graph_height, true) {
|
99
|
+
fill @color.merge(a: 0.5)
|
100
|
+
}
|
101
|
+
|
102
|
+
# now draw the histogram line
|
103
|
+
graph_path(graph_width, graph_height, false) {
|
104
|
+
stroke @color.merge(thickness: 2, miter_limit: 10)
|
105
|
+
}
|
106
|
+
end
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}.show
|
data/examples/login.rb
CHANGED
@@ -1,45 +1,51 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require 'glimmer-dsl-libui'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
window('Login') {
|
8
|
-
margined true
|
3
|
+
class Login
|
4
|
+
include Glimmer
|
9
5
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@password_entry = password_entry {
|
17
|
-
label 'Password:'
|
18
|
-
}
|
19
|
-
}
|
20
|
-
|
21
|
-
horizontal_box {
|
22
|
-
@login_button = button('Login') {
|
23
|
-
on_clicked do
|
24
|
-
@username_entry.enabled = false
|
25
|
-
@password_entry.enabled = false
|
26
|
-
@login_button.enabled = false
|
27
|
-
@logout_button.enabled = true
|
28
|
-
end
|
29
|
-
}
|
6
|
+
attr_accessor :username, :password, :logged_in
|
7
|
+
|
8
|
+
def launch
|
9
|
+
window('Login') {
|
10
|
+
margined true
|
30
11
|
|
31
|
-
|
32
|
-
|
12
|
+
vertical_box {
|
13
|
+
form {
|
14
|
+
entry {
|
15
|
+
label 'Username:'
|
16
|
+
text <=> [self, :username]
|
17
|
+
enabled <= [self, :logged_in, on_read: :!] # `on_read: :!` negates read value
|
18
|
+
}
|
19
|
+
|
20
|
+
password_entry {
|
21
|
+
label 'Password:'
|
22
|
+
text <=> [self, :password]
|
23
|
+
enabled <= [self, :logged_in, on_read: :!]
|
24
|
+
}
|
25
|
+
}
|
33
26
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
27
|
+
horizontal_box {
|
28
|
+
button('Login') {
|
29
|
+
enabled <= [self, :logged_in, on_read: :!]
|
30
|
+
|
31
|
+
on_clicked do
|
32
|
+
self.logged_in = true
|
33
|
+
end
|
34
|
+
}
|
35
|
+
|
36
|
+
button('Logout') {
|
37
|
+
enabled <= [self, :logged_in]
|
38
|
+
|
39
|
+
on_clicked do
|
40
|
+
self.logged_in = false
|
41
|
+
self.username = ''
|
42
|
+
self.password = ''
|
43
|
+
end
|
44
|
+
}
|
45
|
+
}
|
42
46
|
}
|
43
|
-
}
|
44
|
-
|
45
|
-
|
47
|
+
}.show
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
Login.new.launch
|