glimmer-dsl-tk 0.0.25 → 0.0.29
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 +40 -0
- data/README.md +835 -122
- data/VERSION +1 -1
- data/glimmer-dsl-tk.gemspec +0 -0
- data/lib/glimmer/dsl/tk/built_in_dialog_expression.rb +57 -0
- data/lib/glimmer/dsl/tk/dsl.rb +1 -0
- data/lib/glimmer/tk/drag_and_drop_extension.rb +112 -0
- data/lib/glimmer/tk/label_proxy.rb +0 -9
- data/lib/glimmer/tk/root_proxy.rb +10 -34
- data/lib/glimmer/tk/text_proxy.rb +285 -9
- data/lib/glimmer/tk/widget_proxy.rb +88 -34
- data/samples/elaborate/meta_sample.rb +6 -6
- data/samples/hello/hello_built_in_dialog.rb +68 -0
- data/samples/hello/hello_combobox.rb +2 -1
- data/samples/hello/hello_drag_and_drop.rb +159 -0
- data/samples/hello/hello_entry.rb +2 -2
- data/samples/hello/hello_message_box.rb +0 -4
- data/samples/hello/hello_separator.rb +69 -0
- data/samples/hello/hello_text.rb +246 -0
- data/samples/hello/images/copy.png +0 -0
- data/samples/hello/images/cut.png +0 -0
- data/samples/hello/images/paste.png +0 -0
- data/samples/hello/images/picture.png +0 -0
- data/samples/hello/images/redo.png +0 -0
- data/samples/hello/images/search.png +0 -0
- data/samples/hello/images/undo.png +0 -0
- metadata +19 -6
@@ -34,7 +34,9 @@ module Glimmer
|
|
34
34
|
begin
|
35
35
|
class_name = "#{keyword.camelcase(:upper)}Proxy".to_sym
|
36
36
|
Glimmer::Tk.const_get(class_name)
|
37
|
-
rescue
|
37
|
+
rescue => e
|
38
|
+
Glimmer::Config.logger.debug {"Unable to instantiate custom class name for #{keyword} ... defaulting to Glimmer::Tk::WidgetProxy"}
|
39
|
+
Glimmer::Config.logger.debug {e.full_message}
|
38
40
|
Glimmer::Tk::WidgetProxy
|
39
41
|
end
|
40
42
|
end
|
@@ -54,13 +56,15 @@ module Glimmer
|
|
54
56
|
tk_widget_class = eval(tk_widget_name)
|
55
57
|
break
|
56
58
|
rescue RuntimeError, SyntaxError, NameError => e
|
57
|
-
Glimmer::Config.logger.debug e.full_message
|
59
|
+
Glimmer::Config.logger.debug {e.full_message}
|
58
60
|
end
|
59
61
|
end
|
60
|
-
tk_widget_class
|
62
|
+
tk_widget_class if tk_widget_class.respond_to?(:new)
|
61
63
|
end
|
62
64
|
end
|
63
65
|
|
66
|
+
FONTS_PREDEFINED = %w[default text fixed menu heading caption small_caption icon tooltip]
|
67
|
+
|
64
68
|
attr_reader :parent_proxy, :tk, :args, :keyword, :children
|
65
69
|
|
66
70
|
# Initializes a new Tk Widget
|
@@ -104,6 +108,8 @@ module Glimmer
|
|
104
108
|
@tk.send(attribute_setter(attribute), @tk.send(attribute))
|
105
109
|
result = true
|
106
110
|
rescue => e
|
111
|
+
Glimmer::Config.logger.debug { "No tk attribute setter for #{attribute}" }
|
112
|
+
Glimmer::Config.logger.debug { e.full_message }
|
107
113
|
result = false
|
108
114
|
end
|
109
115
|
result
|
@@ -114,7 +120,8 @@ module Glimmer
|
|
114
120
|
# TK Widget currently doesn't support respond_to? properly, so I have to resort to this trick for now
|
115
121
|
@tk.send(attribute)
|
116
122
|
true
|
117
|
-
rescue
|
123
|
+
rescue => e
|
124
|
+
Glimmer::Config.logger.debug { "No tk attribute getter setter for #{attribute}" }
|
118
125
|
false
|
119
126
|
end
|
120
127
|
end
|
@@ -125,7 +132,8 @@ module Glimmer
|
|
125
132
|
begin
|
126
133
|
@tk.tile_instate(attribute)
|
127
134
|
true
|
128
|
-
rescue
|
135
|
+
rescue => e
|
136
|
+
Glimmer::Config.logger.debug { "No tk state for #{attribute}" }
|
129
137
|
false
|
130
138
|
end
|
131
139
|
else
|
@@ -144,45 +152,55 @@ module Glimmer
|
|
144
152
|
tk_widget_has_attribute_getter_setter?(attribute) or
|
145
153
|
has_state?(attribute) or
|
146
154
|
has_attributes_attribute?(attribute) or
|
147
|
-
respond_to?(attribute_setter(attribute), args)
|
155
|
+
respond_to?(attribute_setter(attribute), args) or
|
156
|
+
respond_to?(attribute_setter(attribute), *args, super_only: true) or
|
157
|
+
respond_to?(attribute, *args, super_only: true)
|
148
158
|
end
|
149
159
|
|
150
160
|
def set_attribute(attribute, *args)
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
widget_custom_attribute
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
161
|
+
begin
|
162
|
+
widget_custom_attribute = widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s]
|
163
|
+
if respond_to?(attribute_setter(attribute), super_only: true)
|
164
|
+
send(attribute_setter(attribute), *args)
|
165
|
+
elsif respond_to?(attribute, super_only: true) && self.class.instance_method(attribute).parameters.size > 0
|
166
|
+
send(attribute, *args)
|
167
|
+
elsif widget_custom_attribute
|
168
|
+
widget_custom_attribute[:setter][:invoker].call(@tk, args)
|
169
|
+
elsif tk_widget_has_attribute_setter?(attribute)
|
170
|
+
unless args.size == 1 && @tk.send(attribute) == args.first
|
171
|
+
if args.size == 1
|
172
|
+
@tk.send(attribute_setter(attribute), *args)
|
173
|
+
else
|
174
|
+
@tk.send(attribute_setter(attribute), args)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
elsif tk_widget_has_attribute_getter_setter?(attribute)
|
178
|
+
@tk.send(attribute, *args)
|
179
|
+
elsif has_state?(attribute)
|
180
|
+
attribute = attribute.sub(/=$/, '')
|
181
|
+
if !!args.first
|
182
|
+
@tk.tile_state(attribute)
|
162
183
|
else
|
163
|
-
@tk.
|
184
|
+
@tk.tile_state("!#{attribute}")
|
164
185
|
end
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
elsif has_state?(attribute)
|
169
|
-
attribute = attribute.sub(/=$/, '')
|
170
|
-
if !!args.first
|
171
|
-
@tk.tile_state(attribute)
|
186
|
+
elsif has_attributes_attribute?(attribute)
|
187
|
+
attribute = attribute.sub(/=$/, '')
|
188
|
+
@tk.attributes(attribute, args.first)
|
172
189
|
else
|
173
|
-
|
190
|
+
raise "#{self} cannot handle attribute #{attribute} with args #{args.inspect}"
|
174
191
|
end
|
175
|
-
|
176
|
-
attribute
|
177
|
-
|
178
|
-
|
179
|
-
send(attribute_setter(attribute), args)
|
192
|
+
rescue => e
|
193
|
+
Glimmer::Config.logger.debug {"Failed to set attribute #{attribute} with args #{args.inspect}. Attempting to set through style instead..."}
|
194
|
+
Glimmer::Config.logger.debug {e.full_message}
|
195
|
+
apply_style(attribute => args.first)
|
180
196
|
end
|
181
197
|
end
|
182
198
|
|
183
199
|
def get_attribute(attribute)
|
184
200
|
widget_custom_attribute = widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s]
|
185
|
-
if
|
201
|
+
if respond_to?(attribute, super_only: true)
|
202
|
+
send(attribute)
|
203
|
+
elsif widget_custom_attribute
|
186
204
|
widget_custom_attribute[:getter][:invoker].call(@tk, args)
|
187
205
|
elsif tk_widget_has_attribute_getter_setter?(attribute)
|
188
206
|
@tk.send(attribute)
|
@@ -201,9 +219,17 @@ module Glimmer
|
|
201
219
|
"#{attribute}="
|
202
220
|
end
|
203
221
|
|
222
|
+
def style=(styles)
|
223
|
+
styles.each do |attribute, value|
|
224
|
+
apply_style(attribute => value)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
204
228
|
def grid(options = {})
|
205
229
|
options = options.stringify_keys
|
206
230
|
index_in_parent = @parent_proxy.children.index(self)
|
231
|
+
options['rowspan'] = options.delete('row_span') if options.keys.include?('row_span')
|
232
|
+
options['columnspan'] = options.delete('column_span') if options.keys.include?('column_span')
|
207
233
|
options['rowweight'] = options.delete('row_weight') if options.keys.include?('row_weight')
|
208
234
|
options['columnweight'] = options.delete('column_weight') if options.keys.include?('column_weight')
|
209
235
|
options['columnweight'] = options['rowweight'] = options.delete('weight') if options.keys.include?('weight')
|
@@ -221,6 +247,25 @@ module Glimmer
|
|
221
247
|
@tk.grid(options)
|
222
248
|
end
|
223
249
|
|
250
|
+
def font=(value)
|
251
|
+
if (value.is_a?(Symbol) || value.is_a?(String)) && FONTS_PREDEFINED.include?(value.to_s.downcase)
|
252
|
+
@tk.font = "tk_#{value}_font".camelcase(:upper)
|
253
|
+
else
|
254
|
+
@tk.font = value.is_a?(TkFont) ? value : TkFont.new(value)
|
255
|
+
end
|
256
|
+
rescue => e
|
257
|
+
Glimmer::Config.logger.debug {"Failed to set attribute #{attribute} with args #{args.inspect}. Attempting to set through style instead..."}
|
258
|
+
Glimmer::Config.logger.debug {e.full_message}
|
259
|
+
apply_style({"font" => value})
|
260
|
+
end
|
261
|
+
|
262
|
+
def apply_style(options)
|
263
|
+
@@style_number = 0 unless defined?(@@style_number)
|
264
|
+
style = "style#{@@style_number += 1}.#{@tk.class.name.split('::').last}"
|
265
|
+
::Tk::Tile::Style.configure(style, options)
|
266
|
+
@tk.style = style
|
267
|
+
end
|
268
|
+
|
224
269
|
def widget_custom_attribute_mapping
|
225
270
|
# TODO consider extracting to modules/subclasses
|
226
271
|
@widget_custom_attribute_mapping ||= {
|
@@ -325,12 +370,20 @@ module Glimmer
|
|
325
370
|
@tk.command {
|
326
371
|
observer.call(@tk.textvariable&.value)
|
327
372
|
}
|
373
|
+
@tk.validate('key')
|
374
|
+
@tk.validatecommand { |validate_args|
|
375
|
+
observer.call(validate_args.value)
|
376
|
+
new_icursor = validate_args.index
|
377
|
+
new_icursor += validate_args.string.size if validate_args.action == 1
|
378
|
+
@tk.icursor = new_icursor
|
379
|
+
true
|
380
|
+
}
|
328
381
|
end,
|
329
382
|
},
|
330
383
|
::Tk::Text => {
|
331
|
-
'
|
384
|
+
'value' => lambda do |observer|
|
332
385
|
handle_listener('modified') do
|
333
|
-
observer.call(
|
386
|
+
observer.call(value)
|
334
387
|
end
|
335
388
|
end,
|
336
389
|
},
|
@@ -371,6 +424,7 @@ module Glimmer
|
|
371
424
|
begin
|
372
425
|
@tk.bind(listener_name, &listener)
|
373
426
|
rescue => e
|
427
|
+
Glimmer::Config.logger.debug {"Unable to bind to #{listener_name} .. attempting to surround with <>"}
|
374
428
|
Glimmer::Config.logger.debug {e.full_message}
|
375
429
|
listener_name = "<#{listener_name}" if !listener_name.start_with?('<')
|
376
430
|
listener_name = "#{listener_name}>" if !listener_name.end_with?('>')
|
@@ -74,8 +74,8 @@ class MetaSample
|
|
74
74
|
def launch
|
75
75
|
@root = root {
|
76
76
|
title 'Glimmer Meta-Sample'
|
77
|
-
width
|
78
|
-
height
|
77
|
+
width 1280
|
78
|
+
height 720
|
79
79
|
|
80
80
|
frame {
|
81
81
|
grid row: 0, column: 0, column_weight: 0, row_weight: 1
|
@@ -87,7 +87,7 @@ class MetaSample
|
|
87
87
|
|
88
88
|
on('command') do
|
89
89
|
@selected_sample_index = index
|
90
|
-
@code_text.
|
90
|
+
@code_text.value = File.read(file_path_for(selected_sample))
|
91
91
|
end
|
92
92
|
}
|
93
93
|
end
|
@@ -102,7 +102,7 @@ class MetaSample
|
|
102
102
|
parent_dir = File.join(Dir.home, '.glimmer-dsl-tk', 'samples', 'hello')
|
103
103
|
FileUtils.mkdir_p(parent_dir)
|
104
104
|
sample_file = File.join(parent_dir, "#{selected_sample.underscore}.rb")
|
105
|
-
File.write(sample_file, @code_text.
|
105
|
+
File.write(sample_file, @code_text.value)
|
106
106
|
FileUtils.cp_r(File.expand_path('../../icons', __dir__), File.dirname(File.dirname(parent_dir)))
|
107
107
|
FileUtils.cp_r(File.expand_path('../hello/images', __dir__), parent_dir)
|
108
108
|
sample_namespace_directory = File.expand_path("../hello/#{selected_sample.underscore}", __dir__)
|
@@ -120,7 +120,7 @@ class MetaSample
|
|
120
120
|
text 'Reset'
|
121
121
|
|
122
122
|
on('command') do
|
123
|
-
@code_text.
|
123
|
+
@code_text.value = File.read(file_path_for(selected_sample))
|
124
124
|
end
|
125
125
|
}
|
126
126
|
}
|
@@ -128,7 +128,7 @@ class MetaSample
|
|
128
128
|
|
129
129
|
@code_text = text {
|
130
130
|
grid row: 0, column: 1, column_weight: 1
|
131
|
-
|
131
|
+
value File.read(file_path_for(selected_sample))
|
132
132
|
}
|
133
133
|
}
|
134
134
|
@root.open
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Copyright (c) 2020-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-tk'
|
23
|
+
|
24
|
+
include Glimmer
|
25
|
+
|
26
|
+
root { |w|
|
27
|
+
title 'Hello, Built-in Dialog!'
|
28
|
+
width 400
|
29
|
+
height 400
|
30
|
+
x 150
|
31
|
+
y 150
|
32
|
+
|
33
|
+
frame {
|
34
|
+
%w[get_open_file get_multiple_open_file get_save_file choose_directory choose_color].each do |dialog|
|
35
|
+
button {
|
36
|
+
text dialog.split('_').map(&:capitalize).join(' ')
|
37
|
+
|
38
|
+
on('command') do
|
39
|
+
result = send(dialog, parent: w)
|
40
|
+
@result_label.text = [result].flatten.join("\n")
|
41
|
+
end
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
button {
|
46
|
+
text 'Choose Font'
|
47
|
+
|
48
|
+
on('command') do
|
49
|
+
choose_font(family: 'Courier New', size: '30', weight: 'bold') do |chosen_font|
|
50
|
+
@result_label.text = chosen_font(parent: w)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
frame {
|
57
|
+
grid sticky: 'nsew', padx: 15, pady: 15
|
58
|
+
|
59
|
+
label {
|
60
|
+
grid row: 0, column: 0
|
61
|
+
text 'Result:'
|
62
|
+
}
|
63
|
+
|
64
|
+
@result_label = label {
|
65
|
+
grid row: 0, column: 1
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}.open
|
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
# Copyright (c) 2020-2021 Andy Maleh
|
2
3
|
#
|
3
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
@@ -44,7 +45,7 @@ class HelloCombobox
|
|
44
45
|
title 'Hello, Combobox!'
|
45
46
|
|
46
47
|
combobox {
|
47
|
-
|
48
|
+
readonly true # this applies to text editing only (item selection still triggers a write to model)
|
48
49
|
text <=> [person, :country]
|
49
50
|
}
|
50
51
|
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# Copyright (c) 2020-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-tk"
|
23
|
+
require "glimmer/tk/drag_and_drop_extension"
|
24
|
+
|
25
|
+
include Glimmer
|
26
|
+
|
27
|
+
root {
|
28
|
+
title "Hello, Drag and Drop!"
|
29
|
+
frame {
|
30
|
+
padding 5
|
31
|
+
labelframe {
|
32
|
+
text "Drag sources"
|
33
|
+
padding 5
|
34
|
+
label {
|
35
|
+
text "Entry"
|
36
|
+
grid :row => 0, :column => 0
|
37
|
+
}
|
38
|
+
entry {
|
39
|
+
text "Drag entry text"
|
40
|
+
width 30
|
41
|
+
grid :row => 0, :column => 1, :pady => 5, :sticky => "e"
|
42
|
+
on_drag_start { |event|
|
43
|
+
event.data = event.source.textvariable&.value
|
44
|
+
event.source.configure(:cursor => "hand2")
|
45
|
+
TkLabel.new(event.tooltip) {
|
46
|
+
text event.data + " "
|
47
|
+
bg "yellow"
|
48
|
+
bitmap "warning"
|
49
|
+
compound "right"
|
50
|
+
}.pack
|
51
|
+
}
|
52
|
+
on_drag_motion { |event|
|
53
|
+
if event.drop_accepted
|
54
|
+
event.source.configure(:cursor => "hand1")
|
55
|
+
else
|
56
|
+
event.source.configure(:cursor => "hand2")
|
57
|
+
end
|
58
|
+
event.tooltip.geometry("+#{event.x_root + 10}+#{event.y_root - 4}")
|
59
|
+
}
|
60
|
+
}
|
61
|
+
label {
|
62
|
+
text "Label"
|
63
|
+
grid :row => 1, :column => 0
|
64
|
+
}
|
65
|
+
label {
|
66
|
+
text "Drag label text"
|
67
|
+
width 30
|
68
|
+
grid :row => 1, :column => 1, :pady => 10, :sticky => "e"
|
69
|
+
drag_source true
|
70
|
+
}
|
71
|
+
label {
|
72
|
+
text "Combobox"
|
73
|
+
grid :row => 2, :column => 0
|
74
|
+
}
|
75
|
+
combobox {
|
76
|
+
text "Spain"
|
77
|
+
values %w[USA Canada Mexico Columbia UK Australia Germany Italy Spain]
|
78
|
+
width 27
|
79
|
+
grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
|
80
|
+
on_drag_start { |event|
|
81
|
+
event.data = event.source.textvariable&.value
|
82
|
+
}
|
83
|
+
}
|
84
|
+
label {
|
85
|
+
text "Button"
|
86
|
+
grid :row => 3, :column => 0
|
87
|
+
}
|
88
|
+
button {
|
89
|
+
text "Drag it"
|
90
|
+
grid :row => 3, :column => 1, :pady => 5, :sticky => "w"
|
91
|
+
drag_source true
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
labelframe {
|
96
|
+
text "Drop targets"
|
97
|
+
grid :sticky => "nsew", :pady => 15
|
98
|
+
padding 5
|
99
|
+
label {
|
100
|
+
text "Entry"
|
101
|
+
grid :row => 0, :column => 0
|
102
|
+
}
|
103
|
+
entry {
|
104
|
+
width 30
|
105
|
+
grid :row => 0, :column => 1, :pady => 5, :sticky => "e"
|
106
|
+
on_drop { |event|
|
107
|
+
event.target.textvariable.value = event.data
|
108
|
+
}
|
109
|
+
}
|
110
|
+
label {
|
111
|
+
text "Label"
|
112
|
+
grid :row => 1, :column => 0
|
113
|
+
}
|
114
|
+
label {
|
115
|
+
width 30
|
116
|
+
grid :row => 1, :column => 1, :pady => 10, :sticky => "e"
|
117
|
+
borderwidth 2
|
118
|
+
relief "solid"
|
119
|
+
on_drop { |event|
|
120
|
+
event.target.textvariable.value = event.data
|
121
|
+
}
|
122
|
+
}
|
123
|
+
label {
|
124
|
+
text "Combobox"
|
125
|
+
grid :row => 2, :column => 0
|
126
|
+
}
|
127
|
+
combobox {
|
128
|
+
width 27
|
129
|
+
grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
|
130
|
+
on_drop { |event|
|
131
|
+
event.target.textvariable.value = event.data
|
132
|
+
}
|
133
|
+
}
|
134
|
+
label {
|
135
|
+
text "Button"
|
136
|
+
grid :row => 3, :column => 0
|
137
|
+
}
|
138
|
+
button {
|
139
|
+
text "Drop here"
|
140
|
+
grid :row => 3, :column => 1, :pady => 5, :sticky => "w"
|
141
|
+
on_drop { |event|
|
142
|
+
event.target.text = event.data
|
143
|
+
}
|
144
|
+
}
|
145
|
+
label {
|
146
|
+
text "Checkbutton"
|
147
|
+
grid :row => 4, :column => 0
|
148
|
+
}
|
149
|
+
checkbutton {
|
150
|
+
text "Drop here to destroy a widget\n(except button)"
|
151
|
+
grid :row => 4, :column => 1, :pady => 5, :sticky => "w"
|
152
|
+
on_drop { |event|
|
153
|
+
event.target.text = event.data
|
154
|
+
event.source.destroy unless event.source.is_a? Tk::Button
|
155
|
+
}
|
156
|
+
}
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}.open
|
@@ -38,7 +38,7 @@ class HelloEntry
|
|
38
38
|
title 'Hello, Entry!'
|
39
39
|
|
40
40
|
label {
|
41
|
-
grid sticky: 'ew'
|
41
|
+
grid sticky: 'ew'
|
42
42
|
text 'default entry'
|
43
43
|
}
|
44
44
|
entry {
|
@@ -72,7 +72,7 @@ class HelloEntry
|
|
72
72
|
|
73
73
|
## this event kicks in just after the text variable is validated and before it is modified
|
74
74
|
on('invalid') do |validate_args|
|
75
|
-
@validated_entry_label.text = "#{validate_args.
|
75
|
+
@validated_entry_label.text = "#{validate_args.value} is not valid!"
|
76
76
|
@validated_entry_label.foreground = 'red'
|
77
77
|
end
|
78
78
|
|
@@ -27,8 +27,6 @@ root { |r|
|
|
27
27
|
title 'Hello, Message Box!'
|
28
28
|
|
29
29
|
frame {
|
30
|
-
grid sticky: 'nsew', padx: 15, pady: 15
|
31
|
-
|
32
30
|
button {
|
33
31
|
text 'Please Click To Win a Surprise'
|
34
32
|
|
@@ -80,8 +78,6 @@ root { |r|
|
|
80
78
|
}
|
81
79
|
|
82
80
|
frame {
|
83
|
-
grid sticky: 'nsew', padx: 15, pady: 15
|
84
|
-
|
85
81
|
label {
|
86
82
|
grid row: 0, column: 0
|
87
83
|
text 'Result:'
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# Copyright (c) 2020-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-tk'
|
23
|
+
|
24
|
+
include Glimmer
|
25
|
+
|
26
|
+
root {
|
27
|
+
title 'Hello, Separator!'
|
28
|
+
width 200
|
29
|
+
height 200
|
30
|
+
|
31
|
+
label {
|
32
|
+
grid row: 0, column: 0, min_width: 100, min_height: 100, column_weight: 0, sticky: 'nsew'
|
33
|
+
text 'Label 1'
|
34
|
+
anchor 'center'
|
35
|
+
}
|
36
|
+
|
37
|
+
separator {
|
38
|
+
grid row: 0, column: 1
|
39
|
+
orient 'vertical'
|
40
|
+
}
|
41
|
+
|
42
|
+
label {
|
43
|
+
grid row: 0, column: 2, min_width: 100, min_height: 100, sticky: 'nsew'
|
44
|
+
text 'Label 2'
|
45
|
+
anchor 'center'
|
46
|
+
}
|
47
|
+
|
48
|
+
separator {
|
49
|
+
grid row: 1, column: 0, column_span: 3
|
50
|
+
orient 'horizontal'
|
51
|
+
}
|
52
|
+
|
53
|
+
label {
|
54
|
+
grid row: 2, column: 0, min_width: 100, min_height: 100, sticky: 'nsew'
|
55
|
+
text 'Label 3'
|
56
|
+
anchor 'center'
|
57
|
+
}
|
58
|
+
|
59
|
+
separator {
|
60
|
+
grid row: 2, column: 1
|
61
|
+
orient 'vertical'
|
62
|
+
}
|
63
|
+
|
64
|
+
label {
|
65
|
+
grid row: 2, column: 2, min_width: 100, min_height: 100, sticky: 'nsew'
|
66
|
+
text 'Label 4'
|
67
|
+
anchor 'center'
|
68
|
+
}
|
69
|
+
}.open
|