glimmer-dsl-tk 0.0.35 → 0.0.39
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -0
- data/README.md +473 -22
- data/VERSION +1 -1
- data/glimmer-dsl-tk.gemspec +0 -0
- data/lib/glimmer/dsl/tk/widget_expression.rb +1 -1
- data/lib/glimmer/tk/menu_item_proxy.rb +202 -0
- data/lib/glimmer/tk/menu_proxy.rb +88 -0
- data/lib/glimmer/tk/root_proxy.rb +1 -16
- data/lib/glimmer/tk/text_proxy.rb +18 -18
- data/lib/glimmer/tk/toplevel_proxy.rb +40 -0
- data/lib/glimmer/tk/widget_proxy.rb +18 -8
- data/lib/glimmer-dsl-tk.rb +12 -0
- data/samples/hello/hello_button.rb +1 -1
- data/samples/hello/hello_checkbutton.rb +1 -1
- data/samples/hello/hello_menu_bar.rb +260 -0
- data/samples/hello/hello_text.rb +5 -5
- data/samples/hello/hello_toplevel.rb +178 -0
- metadata +6 -2
@@ -0,0 +1,202 @@
|
|
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/tk/widget_proxy'
|
23
|
+
|
24
|
+
module Glimmer
|
25
|
+
module Tk
|
26
|
+
class MenuItemProxy < WidgetProxy
|
27
|
+
ACCELERATOR_MODIFIER_EVENT_MAP = {
|
28
|
+
'Command' => 'Command',
|
29
|
+
'Cmd' => 'Command',
|
30
|
+
'Meta' => 'Command',
|
31
|
+
'Option' => 'Option',
|
32
|
+
'Opt' => 'Option',
|
33
|
+
'Alt' => 'Option',
|
34
|
+
'Shift' => 'Shift',
|
35
|
+
'Ctrl' => 'Control',
|
36
|
+
'Control' => 'Control',
|
37
|
+
}
|
38
|
+
|
39
|
+
attr_reader :options
|
40
|
+
|
41
|
+
def initialize(underscored_widget_name, parent_proxy, args, &block)
|
42
|
+
@options = args.last.is_a?(Hash) ? args.last : {}
|
43
|
+
super
|
44
|
+
end
|
45
|
+
|
46
|
+
def accelerator=(value)
|
47
|
+
@accelerator = value
|
48
|
+
configure_menu_item_attribute(accelerator: value)
|
49
|
+
root_parent_proxy.bind(accelerator_event) do |event|
|
50
|
+
@command_block&.call(event)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def accelerator
|
55
|
+
@accelerator
|
56
|
+
end
|
57
|
+
|
58
|
+
def accelerator_event
|
59
|
+
accelerator_parts = @accelerator.split('+')
|
60
|
+
accelerator_parts.map do |accelerator_part|
|
61
|
+
ACCELERATOR_MODIFIER_EVENT_MAP[accelerator_part.capitalize] || accelerator_part.downcase
|
62
|
+
end.join('-')
|
63
|
+
end
|
64
|
+
|
65
|
+
def state=(value)
|
66
|
+
@state = value
|
67
|
+
configure_menu_item_attribute(state: value)
|
68
|
+
end
|
69
|
+
|
70
|
+
def state
|
71
|
+
@state
|
72
|
+
end
|
73
|
+
|
74
|
+
def label
|
75
|
+
@options[:label]
|
76
|
+
end
|
77
|
+
|
78
|
+
def image=(*args)
|
79
|
+
@image = image_argument(args)
|
80
|
+
configure_menu_item_attribute(image: @image)
|
81
|
+
end
|
82
|
+
|
83
|
+
def image
|
84
|
+
@image
|
85
|
+
end
|
86
|
+
|
87
|
+
def compound=(value)
|
88
|
+
@compound = value
|
89
|
+
configure_menu_item_attribute(compound: @compound)
|
90
|
+
end
|
91
|
+
|
92
|
+
def compound
|
93
|
+
@compound
|
94
|
+
end
|
95
|
+
|
96
|
+
def command_block=(proc)
|
97
|
+
@command_block = proc
|
98
|
+
configure_menu_item_attribute(command: @command_block)
|
99
|
+
end
|
100
|
+
|
101
|
+
def handle_listener(listener_name, &listener)
|
102
|
+
case listener_name.to_s.downcase
|
103
|
+
when 'command'
|
104
|
+
self.command_block = listener
|
105
|
+
else
|
106
|
+
super
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def command?
|
111
|
+
@args.first.nil? || @args.first == :command || @args.first.is_a?(Hash)
|
112
|
+
end
|
113
|
+
|
114
|
+
def radiobutton?
|
115
|
+
@args.first == :radiobutton
|
116
|
+
end
|
117
|
+
|
118
|
+
def checkbutton?
|
119
|
+
@args.first == :radiobutton
|
120
|
+
end
|
121
|
+
|
122
|
+
def separator?
|
123
|
+
@args.first == :separator
|
124
|
+
end
|
125
|
+
|
126
|
+
def about?
|
127
|
+
@args.first == :about
|
128
|
+
end
|
129
|
+
|
130
|
+
def preferences?
|
131
|
+
@args.first == :preferences
|
132
|
+
end
|
133
|
+
|
134
|
+
def help?
|
135
|
+
@args.first == :help
|
136
|
+
end
|
137
|
+
|
138
|
+
def quit?
|
139
|
+
@args.first == :quit
|
140
|
+
end
|
141
|
+
|
142
|
+
def variable(auto_create: true)
|
143
|
+
if @variable.nil? && auto_create
|
144
|
+
sibling_variable = sibling_radio_menu_items.map {|mi| mi.variable(auto_create: false)}.compact.first
|
145
|
+
@variable = sibling_variable.nil? ? ::TkVariable.new : sibling_variable
|
146
|
+
else
|
147
|
+
@variable
|
148
|
+
end
|
149
|
+
@variable
|
150
|
+
end
|
151
|
+
|
152
|
+
def selection=(value)
|
153
|
+
if value
|
154
|
+
variable.value = label
|
155
|
+
elsif checkbutton?
|
156
|
+
variable.value = ''
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def selection
|
161
|
+
variable.value == label
|
162
|
+
end
|
163
|
+
|
164
|
+
# configures menu item attribute through parent menu
|
165
|
+
def configure_menu_item_attribute(attribute_value_hash)
|
166
|
+
if preferences? && attribute_value_hash[:command]
|
167
|
+
::Tk.ip_eval("proc ::tk::mac::ShowPreferences {} {#{::Tk.install_cmd(attribute_value_hash[:command])}}")
|
168
|
+
elsif help? && attribute_value_hash[:command]
|
169
|
+
::Tk.ip_eval("proc ::tk::mac::ShowHelp {} {#{::Tk.install_cmd(attribute_value_hash[:command])}}")
|
170
|
+
elsif quit? && attribute_value_hash[:command]
|
171
|
+
::Tk.ip_eval("proc ::tk::mac::Quit {} {#{::Tk.install_cmd(attribute_value_hash[:command])}}")
|
172
|
+
else
|
173
|
+
@parent_proxy.tk.entryconfigure label, attribute_value_hash
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
private
|
178
|
+
|
179
|
+
def sibling_radio_menu_items
|
180
|
+
@parent_proxy.children.select {|child| child.is_a?(MenuItemProxy) && radiobutton? && child != self}
|
181
|
+
end
|
182
|
+
|
183
|
+
def build_widget
|
184
|
+
@args.prepend(:command) if @args.first.is_a?(Hash)
|
185
|
+
@args.append({}) if !@args.last.is_a?(Hash)
|
186
|
+
@args.last.merge!(variable: variable, value: label) if radiobutton? || checkbutton?
|
187
|
+
case @parent_proxy
|
188
|
+
when MenuProxy
|
189
|
+
if @parent_proxy.application?
|
190
|
+
if OS.mac?
|
191
|
+
if about?
|
192
|
+
@parent_proxy.tk.add :command, :label => label
|
193
|
+
end
|
194
|
+
end
|
195
|
+
else
|
196
|
+
@parent_proxy.tk.add(*@args) unless help?
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,88 @@
|
|
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/tk/widget_proxy'
|
23
|
+
|
24
|
+
module Glimmer
|
25
|
+
module Tk
|
26
|
+
class MenuProxy < WidgetProxy
|
27
|
+
attr_reader :options
|
28
|
+
|
29
|
+
def initialize(underscored_widget_name, parent_proxy, args, &block)
|
30
|
+
@options = args.last.is_a?(Hash) ? args.last : {}
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
def post_add_content
|
35
|
+
case @parent_proxy
|
36
|
+
when ToplevelProxy
|
37
|
+
@parent_proxy.tk['menu'] = @tk
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def label
|
42
|
+
@options[:label]
|
43
|
+
end
|
44
|
+
|
45
|
+
def help?
|
46
|
+
label == 'Help'
|
47
|
+
end
|
48
|
+
|
49
|
+
def window?
|
50
|
+
label == 'Window'
|
51
|
+
end
|
52
|
+
|
53
|
+
def system?
|
54
|
+
label == 'System'
|
55
|
+
end
|
56
|
+
|
57
|
+
def application?
|
58
|
+
@args.first == :application
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def build_widget
|
64
|
+
if application?
|
65
|
+
if OS.mac?
|
66
|
+
@tk = ::TkSysMenu_Apple.new(@parent_proxy.tk)
|
67
|
+
@parent_proxy.tk.add :cascade, :menu => @tk
|
68
|
+
end
|
69
|
+
else
|
70
|
+
if @parent_proxy.parent_proxy.is_a?(ToplevelProxy) && (OS.mac? || OS.linux?) && help?
|
71
|
+
@tk = ::TkSysMenu_Help.new(@parent_proxy.tk)
|
72
|
+
elsif @parent_proxy.parent_proxy.is_a?(ToplevelProxy) && OS.mac? && window?
|
73
|
+
@tk = ::Tk::TkSysMenu_Window.new(@parent_proxy.tk)
|
74
|
+
elsif @parent_proxy.parent_proxy.is_a?(ToplevelProxy) && OS.windows? && system?
|
75
|
+
@tk = ::TkSysMenu_System.new(@parent_proxy.tk)
|
76
|
+
else
|
77
|
+
tk_widget_class = self.class.tk_widget_class_for(@keyword)
|
78
|
+
@tk = tk_widget_class.new(@parent_proxy.tk)
|
79
|
+
end
|
80
|
+
case @parent_proxy
|
81
|
+
when MenuProxy
|
82
|
+
@parent_proxy.tk.add(:cascade, {menu: @tk}.merge(@options))
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -36,6 +36,7 @@ module Glimmer
|
|
36
36
|
|
37
37
|
def post_add_content
|
38
38
|
set_attribute('iconphoto', File.expand_path('../../../icons/glimmer.png', __dir__)) if @tk.iconphoto.nil?
|
39
|
+
super
|
39
40
|
end
|
40
41
|
|
41
42
|
def open
|
@@ -46,22 +47,6 @@ module Glimmer
|
|
46
47
|
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Tk::RootExpression.new, keyword, *args, &block)
|
47
48
|
end
|
48
49
|
|
49
|
-
def set_attribute(attribute, *args)
|
50
|
-
case attribute.to_s
|
51
|
-
when 'iconphoto'
|
52
|
-
args[0..-1] = [image_argument(args)]
|
53
|
-
super
|
54
|
-
when 'resizable'
|
55
|
-
if args.size == 1 && !args.first.is_a?(Array)
|
56
|
-
self.resizable = [args.first]*2
|
57
|
-
else
|
58
|
-
super
|
59
|
-
end
|
60
|
-
else
|
61
|
-
super
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
50
|
def handle_listener(listener_name, &listener)
|
66
51
|
case listener_name.to_s.upcase
|
67
52
|
when 'WM_OPEN_WINDOW', 'OPEN_WINDOW'
|
@@ -92,31 +92,31 @@ module Glimmer
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
-
def add_selection_format(option, value, no_selection_default: :insert_word)
|
96
|
-
process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| add_format(range_start, range_end, option, value) }
|
95
|
+
def add_selection_format(option, value, no_selection_default: :insert_word, focus: true)
|
96
|
+
process_selection_ranges(no_selection_default: no_selection_default, focus: focus) { |range_start, range_end| add_format(range_start, range_end, option, value) }
|
97
97
|
end
|
98
98
|
|
99
|
-
def remove_selection_format(option, value, no_selection_default: :insert_word)
|
100
|
-
process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| remove_format(range_start, range_end, option, value) }
|
99
|
+
def remove_selection_format(option, value, no_selection_default: :insert_word, focus: true)
|
100
|
+
process_selection_ranges(no_selection_default: no_selection_default, focus: focus) { |range_start, range_end| remove_format(range_start, range_end, option, value) }
|
101
101
|
end
|
102
102
|
|
103
|
-
def toggle_selection_format(option, value, no_selection_default: :insert_word)
|
104
|
-
process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| toggle_format(range_start, range_end, option, value) }
|
103
|
+
def toggle_selection_format(option, value, no_selection_default: :insert_word, focus: true)
|
104
|
+
process_selection_ranges(no_selection_default: no_selection_default, focus: focus) { |range_start, range_end| toggle_format(range_start, range_end, option, value) }
|
105
105
|
end
|
106
106
|
|
107
|
-
def add_selection_font_format(option, value, no_selection_default: :insert_word)
|
108
|
-
process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| add_font_format(range_start, range_end, option, value) }
|
107
|
+
def add_selection_font_format(option, value, no_selection_default: :insert_word, focus: true)
|
108
|
+
process_selection_ranges(no_selection_default: no_selection_default, focus: focus) { |range_start, range_end| add_font_format(range_start, range_end, option, value) }
|
109
109
|
end
|
110
110
|
|
111
|
-
def remove_selection_font_format(option, value, no_selection_default: :insert_word)
|
112
|
-
process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| remove_font_format(range_start, range_end, option, value) }
|
111
|
+
def remove_selection_font_format(option, value, no_selection_default: :insert_word, focus: true)
|
112
|
+
process_selection_ranges(no_selection_default: no_selection_default, focus: focus) { |range_start, range_end| remove_font_format(range_start, range_end, option, value) }
|
113
113
|
end
|
114
114
|
|
115
|
-
def toggle_selection_font_format(option, value, no_selection_default: :insert_word)
|
116
|
-
process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| toggle_font_format(range_start, range_end, option, value) }
|
115
|
+
def toggle_selection_font_format(option, value, no_selection_default: :insert_word, focus: true)
|
116
|
+
process_selection_ranges(no_selection_default: no_selection_default, focus: focus) { |range_start, range_end| toggle_font_format(range_start, range_end, option, value) }
|
117
117
|
end
|
118
118
|
|
119
|
-
def process_selection_ranges(no_selection_default: :insert_word, &processor)
|
119
|
+
def process_selection_ranges(no_selection_default: :insert_word, focus: true, &processor)
|
120
120
|
regions = @tk.tag_ranges('sel')
|
121
121
|
if regions.empty?
|
122
122
|
case no_selection_default
|
@@ -131,6 +131,11 @@ module Glimmer
|
|
131
131
|
range_end = region.last
|
132
132
|
processor.call(range_start, range_end)
|
133
133
|
end
|
134
|
+
if focus == true
|
135
|
+
@tk.focus
|
136
|
+
elsif focus.is_a?(Integer)
|
137
|
+
::Tk.after(focus) { @tk.focus }
|
138
|
+
end
|
134
139
|
end
|
135
140
|
|
136
141
|
def applied_format?(region_start, region_end, option, value)
|
@@ -432,16 +437,11 @@ module Glimmer
|
|
432
437
|
self.wrap = 'none'
|
433
438
|
self.padx = 5
|
434
439
|
self.pady = 5
|
435
|
-
# on('Modified') { apply_all_tag }
|
436
440
|
end
|
437
441
|
|
438
442
|
def clone_font(font)
|
439
443
|
::TkFont.new(Hash[font.actual])
|
440
444
|
end
|
441
|
-
|
442
|
-
# def apply_all_tag
|
443
|
-
# @tk.tag_add(ALL_TAG, '1.0', 'end')
|
444
|
-
# end
|
445
445
|
end
|
446
446
|
end
|
447
447
|
end
|
@@ -32,11 +32,40 @@ module Glimmer
|
|
32
32
|
DEFAULT_HEIGHT = 95
|
33
33
|
|
34
34
|
attr_reader :tk
|
35
|
+
attr_accessor :escapable
|
36
|
+
alias escapable? escapable
|
37
|
+
|
38
|
+
def post_add_content
|
39
|
+
if escapable?
|
40
|
+
on('KeyPress') do |event|
|
41
|
+
if event.keysym == 'Escape'
|
42
|
+
grab_release
|
43
|
+
destroy
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
35
48
|
|
36
49
|
def has_attribute?(attribute, *args)
|
37
50
|
%w[width height x y].include?(attribute.to_s) || super
|
38
51
|
end
|
39
52
|
|
53
|
+
def set_attribute(attribute, *args)
|
54
|
+
case attribute.to_s
|
55
|
+
when 'iconphoto'
|
56
|
+
args[0..-1] = [image_argument(args)]
|
57
|
+
super
|
58
|
+
when 'resizable'
|
59
|
+
if args.size == 1 && !args.first.is_a?(Array)
|
60
|
+
self.resizable = [args.first]*2
|
61
|
+
else
|
62
|
+
super
|
63
|
+
end
|
64
|
+
else
|
65
|
+
super
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
40
69
|
def width
|
41
70
|
geometry.split(REGEX_GEOMETRY)[0].to_i
|
42
71
|
end
|
@@ -114,6 +143,17 @@ module Glimmer
|
|
114
143
|
destroy
|
115
144
|
end
|
116
145
|
end
|
146
|
+
|
147
|
+
def mac_style=(mac_class, mac_attribute_list = nil)
|
148
|
+
if OS.mac?
|
149
|
+
@mac_style = [mac_class, mac_attribute_list]
|
150
|
+
::Tk.tk_call("::tk::unsupported::MacWindowStyle", "style", @tk, *@mac_style.compact)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def mac_style
|
155
|
+
@mac_style
|
156
|
+
end
|
117
157
|
end
|
118
158
|
end
|
119
159
|
end
|
@@ -77,8 +77,7 @@ module Glimmer
|
|
77
77
|
@args = args
|
78
78
|
@keyword = underscored_widget_name
|
79
79
|
@block = block
|
80
|
-
|
81
|
-
@tk = tk_widget_class.new(@parent_proxy.tk, *args)
|
80
|
+
build_widget
|
82
81
|
# a common widget initializer
|
83
82
|
@parent_proxy.post_initialize_child(self)
|
84
83
|
initialize_defaults
|
@@ -121,7 +120,7 @@ module Glimmer
|
|
121
120
|
end
|
122
121
|
|
123
122
|
def self.widget_exists?(underscored_widget_name)
|
124
|
-
!!tk_widget_class_for(underscored_widget_name)
|
123
|
+
!!tk_widget_class_for(underscored_widget_name) || (Glimmer::Tk.constants.include?("#{underscored_widget_name.camelcase(:upper)}Proxy".to_sym) && Glimmer::Tk.const_get("#{underscored_widget_name.camelcase(:upper)}Proxy".to_sym).respond_to?(:new))
|
125
124
|
end
|
126
125
|
|
127
126
|
def tk_widget_has_attribute_setter?(attribute)
|
@@ -213,8 +212,8 @@ module Glimmer
|
|
213
212
|
raise "#{self} cannot handle attribute #{attribute} with args #{args.inspect}"
|
214
213
|
end
|
215
214
|
rescue => e
|
216
|
-
Glimmer::Config.logger.
|
217
|
-
Glimmer::Config.logger.
|
215
|
+
Glimmer::Config.logger.error {"Failed to set attribute #{attribute} with args #{args.inspect}. Attempting to set through style instead..."}
|
216
|
+
Glimmer::Config.logger.error {e.full_message}
|
218
217
|
apply_style(attribute => args.first)
|
219
218
|
end
|
220
219
|
end
|
@@ -460,14 +459,20 @@ module Glimmer
|
|
460
459
|
parent_proxy.handle_listener(listener_name, &listener) if parent_proxy
|
461
460
|
# TODO return a listener registration object that has a deregister method
|
462
461
|
else
|
462
|
+
@listeners ||= {}
|
463
463
|
begin
|
464
|
-
@
|
464
|
+
@listeners[listener_name] ||= []
|
465
|
+
@tk.bind(listener_name) { |event| @listeners[listener_name].each {|l| l.call(event)} } if @listeners[listener_name].empty?
|
466
|
+
@listeners[listener_name] << listener
|
465
467
|
rescue => e
|
468
|
+
@listeners.delete(listener_name)
|
466
469
|
Glimmer::Config.logger.debug {"Unable to bind to #{listener_name} .. attempting to surround with <>"}
|
467
470
|
Glimmer::Config.logger.debug {e.full_message}
|
468
471
|
listener_name = "<#{listener_name}" if !listener_name.start_with?('<')
|
469
472
|
listener_name = "#{listener_name}>" if !listener_name.end_with?('>')
|
470
|
-
@
|
473
|
+
@listeners[listener_name] ||= []
|
474
|
+
@tk.bind(listener_name) { |event| @listeners[listener_name].each {|l| l.call(event)} } if @listeners[listener_name].empty?
|
475
|
+
@listeners[listener_name] << listener
|
471
476
|
end
|
472
477
|
end
|
473
478
|
end
|
@@ -501,11 +506,16 @@ module Glimmer
|
|
501
506
|
|
502
507
|
private
|
503
508
|
|
509
|
+
def build_widget
|
510
|
+
tk_widget_class = self.class.tk_widget_class_for(@keyword)
|
511
|
+
@tk = tk_widget_class.new(@parent_proxy.tk, *args)
|
512
|
+
end
|
513
|
+
|
504
514
|
def initialize_defaults
|
505
515
|
options = {}
|
506
516
|
options[:sticky] = 'nsew'
|
507
517
|
options[:column_weight] = 1 if @parent_proxy.children.count == 1
|
508
|
-
grid(options) unless @tk.is_a?(::Tk::Toplevel)
|
518
|
+
grid(options) unless @tk.is_a?(::Tk::Toplevel) || @tk.is_a?(::Tk::Menu) || @tk.nil? # TODO refactor by adding a griddable? method that could be overriden by subclasses to consult for this call
|
509
519
|
end
|
510
520
|
end
|
511
521
|
end
|
data/lib/glimmer-dsl-tk.rb
CHANGED
@@ -29,14 +29,26 @@ require 'puts_debuggerer' if ENV['pd'].to_s.downcase == 'true'
|
|
29
29
|
require 'tk'
|
30
30
|
require 'os'
|
31
31
|
require 'facets/hash/symbolize_keys'
|
32
|
+
require 'facets/string/underscore'
|
33
|
+
require 'facets/string/camelcase'
|
34
|
+
require 'delegate'
|
32
35
|
|
33
36
|
# Internal requires
|
34
37
|
# require 'ext/glimmer/config'
|
35
38
|
# require 'ext/glimmer'
|
36
39
|
require 'glimmer/dsl/tk/dsl'
|
40
|
+
|
37
41
|
Glimmer::Config.loop_max_count = -1
|
42
|
+
|
38
43
|
Glimmer::Config.excluded_keyword_checkers << lambda do |method_symbol, *args|
|
39
44
|
method = method_symbol.to_s
|
40
45
|
result = false
|
41
46
|
result ||= method == 'load_iseq'
|
42
47
|
end
|
48
|
+
|
49
|
+
::TkOption.add '*tearOff', 0
|
50
|
+
|
51
|
+
class ::Tk::TkSysMenu_Window < Tk::Menu
|
52
|
+
include Tk::SystemMenu
|
53
|
+
SYSMENU_NAME = 'window'
|
54
|
+
end
|
@@ -81,7 +81,7 @@ class HelloButton
|
|
81
81
|
['center', 'top', 'bottom', 'left', 'right'].each do |compound_option|
|
82
82
|
button {
|
83
83
|
image File.expand_path('../../icons/glimmer.png', __dir__), subsample: 5
|
84
|
-
text
|
84
|
+
text "#{compound_option.capitalize} Image"
|
85
85
|
compound compound_option
|
86
86
|
|
87
87
|
command {
|