glimmer-dsl-swt 0.5.6 → 0.6.4
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/README.md +1 -1
- data/RUBY_VERSION +1 -1
- data/VERSION +1 -1
- data/bin/girb +1 -1
- data/bin/glimmer +1 -1
- data/icons/scaffold_app.ico +0 -0
- data/icons/scaffold_app.png +0 -0
- data/lib/ext/glimmer/config.rb +5 -1
- data/lib/glimmer/Rakefile +5 -0
- data/lib/glimmer/dsl/swt/cursor_expression.rb +23 -0
- data/lib/glimmer/dsl/swt/dsl.rb +3 -0
- data/lib/glimmer/dsl/swt/font_expression.rb +26 -0
- data/lib/glimmer/dsl/swt/image_expression.rb +21 -0
- data/lib/glimmer/dsl/swt/message_box_expression.rb +9 -1
- data/lib/glimmer/dsl/swt/widget_expression.rb +7 -7
- data/lib/glimmer/launcher.rb +36 -8
- data/lib/glimmer/package.rb +31 -7
- data/lib/glimmer/rake_task.rb +111 -6
- data/lib/glimmer/scaffold.rb +98 -62
- data/lib/glimmer/swt/cursor_proxy.rb +45 -0
- data/lib/glimmer/swt/display_proxy.rb +13 -2
- data/lib/glimmer/swt/font_proxy.rb +7 -7
- data/lib/glimmer/swt/image_proxy.rb +16 -23
- data/lib/glimmer/swt/layout_proxy.rb +2 -0
- data/lib/glimmer/swt/message_box_proxy.rb +23 -5
- data/lib/glimmer/swt/scrolled_composite_proxy.rb +6 -11
- data/lib/glimmer/swt/style_constantizable.rb +11 -1
- data/lib/glimmer/swt/table_proxy.rb +50 -2
- data/lib/glimmer/swt/widget_proxy.rb +79 -18
- data/samples/elaborate/contact_manager.rb +121 -0
- data/samples/elaborate/contact_manager/contact.rb +11 -0
- data/samples/elaborate/contact_manager/contact_manager_presenter.rb +26 -0
- data/samples/elaborate/contact_manager/contact_repository.rb +244 -0
- data/samples/elaborate/login.rb +108 -0
- data/samples/elaborate/tic_tac_toe.rb +55 -0
- data/samples/elaborate/tic_tac_toe/board.rb +124 -0
- data/samples/elaborate/tic_tac_toe/cell.rb +27 -0
- data/samples/hello/hello_browser.rb +8 -0
- data/samples/hello/hello_combo.rb +38 -0
- data/samples/hello/hello_computed.rb +69 -0
- data/samples/hello/hello_computed/contact.rb +21 -0
- data/samples/hello/hello_drag_and_drop.rb +29 -0
- data/samples/hello/hello_list_multi_selection.rb +48 -0
- data/samples/hello/hello_list_single_selection.rb +37 -0
- data/samples/hello/hello_menu_bar.rb +64 -0
- data/samples/hello/hello_message_box.rb +15 -0
- data/samples/hello/hello_pop_up_context_menu.rb +36 -0
- data/samples/hello/hello_tab.rb +24 -0
- data/samples/hello/hello_world.rb +8 -0
- data/vendor/swt/linux/swt.jar +0 -0
- data/vendor/swt/mac/swt.jar +0 -0
- data/vendor/swt/windows/swt.jar +0 -0
- metadata +48 -7
@@ -45,6 +45,8 @@ module Glimmer
|
|
45
45
|
@widget_proxy = widget_proxy
|
46
46
|
args = SWTProxy.constantify_args(args)
|
47
47
|
@swt_layout = self.class.swt_layout_class_for(underscored_layout_name).new(*args)
|
48
|
+
@swt_layout.marginWidth = 15 if @swt_layout.respond_to?(:marginWidth)
|
49
|
+
@swt_layout.marginHeight = 15 if @swt_layout.respond_to?(:marginHeight)
|
48
50
|
@widget_proxy.swt_widget.setLayout(@swt_layout)
|
49
51
|
end
|
50
52
|
|
@@ -14,16 +14,22 @@ module Glimmer
|
|
14
14
|
attr_reader :swt_widget
|
15
15
|
|
16
16
|
def initialize(parent, style)
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
if parent.nil?
|
18
|
+
@temporary_parent = parent = Glimmer::SWT::ShellProxy.new.swt_widget
|
19
|
+
end
|
20
|
+
@swt_widget = MessageBox.new(parent, style)
|
20
21
|
end
|
21
22
|
|
22
23
|
def open
|
23
|
-
@swt_widget.open
|
24
|
-
|
24
|
+
@swt_widget.open.tap do |result|
|
25
|
+
@temporary_parent&.dispose
|
26
|
+
end
|
25
27
|
end
|
26
28
|
|
29
|
+
def content(&block)
|
30
|
+
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::MessageBoxExpression.new, &block)
|
31
|
+
end
|
32
|
+
|
27
33
|
# TODO refactor the following methods to put in a JavaBean mixin or somethin (perhaps contribute to OSS project too)
|
28
34
|
|
29
35
|
def attribute_setter(attribute_name)
|
@@ -44,6 +50,18 @@ module Glimmer
|
|
44
50
|
|
45
51
|
def get_attribute(attribute_name)
|
46
52
|
@swt_widget.send(attribute_getter(attribute_name))
|
53
|
+
end
|
54
|
+
|
55
|
+
def method_missing(method, *args, &block)
|
56
|
+
swt_widget.send(method, *args, &block)
|
57
|
+
rescue => e
|
58
|
+
Glimmer::Config.logger.debug {"Neither MessageBoxProxy nor #{swt_widget.class.name} can handle the method ##{method}"}
|
59
|
+
super
|
60
|
+
end
|
61
|
+
|
62
|
+
def respond_to?(method, *args, &block)
|
63
|
+
super ||
|
64
|
+
swt_widget.respond_to?(method, *args, &block)
|
47
65
|
end
|
48
66
|
end
|
49
67
|
end
|
@@ -1,21 +1,16 @@
|
|
1
1
|
require 'glimmer/swt/widget_proxy'
|
2
|
+
require 'glimmer/swt/swt_proxy'
|
2
3
|
|
3
4
|
module Glimmer
|
4
5
|
module SWT
|
5
|
-
class ScrolledCompositeProxy < Glimmer::SWT::WidgetProxy
|
6
|
-
def initialize(underscored_widget_name, parent, args)
|
7
|
-
unless args.first.is_a?(Numeric)
|
8
|
-
args.unshift(:h_scroll)
|
9
|
-
args.unshift(:v_scroll)
|
10
|
-
end
|
11
|
-
super
|
12
|
-
swt_widget.expand_horizontal = true
|
13
|
-
swt_widget.expand_vertical = true
|
14
|
-
end
|
15
|
-
|
6
|
+
class ScrolledCompositeProxy < Glimmer::SWT::WidgetProxy
|
16
7
|
def post_initialize_child(child)
|
17
8
|
swt_widget.content = child.swt_widget
|
18
9
|
end
|
10
|
+
|
11
|
+
def post_add_content
|
12
|
+
swt_widget.set_min_size(swt_widget.computeSize(SWTProxy[:default], SWTProxy[:default]))
|
13
|
+
end
|
19
14
|
end
|
20
15
|
end
|
21
16
|
end
|
@@ -106,7 +106,17 @@ module Glimmer
|
|
106
106
|
def deconstruct(integer)
|
107
107
|
constant_source_class.constants.reduce([]) do |found, c|
|
108
108
|
constant_value = constant_source_class.const_get(c) rescue -1
|
109
|
-
is_found = constant_value.is_a?(Integer) && (
|
109
|
+
is_found = constant_value.is_a?(Integer) && (integer & constant_value) == integer
|
110
|
+
is_found ? found += [c] : found
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Reverse engineer a style integer into a symbol
|
115
|
+
# Useful for debugging
|
116
|
+
def reverse_lookup(integer)
|
117
|
+
constant_source_class.constants.reduce([]) do |found, c|
|
118
|
+
constant_value = constant_source_class.const_get(c) rescue -1
|
119
|
+
is_found = constant_value.is_a?(Integer) && integer == constant_value
|
110
120
|
is_found ? found += [c] : found
|
111
121
|
end
|
112
122
|
end
|
@@ -85,7 +85,55 @@ module Glimmer
|
|
85
85
|
}
|
86
86
|
table_editor_widget_proxy
|
87
87
|
end,
|
88
|
-
}
|
88
|
+
},
|
89
|
+
checkbox: {
|
90
|
+
widget_value_property: :selection,
|
91
|
+
editor_gui: lambda do |args, model, property, table_proxy|
|
92
|
+
first_time = true
|
93
|
+
table_proxy.table_editor.minimumHeight = 25
|
94
|
+
checkbox(*args) {
|
95
|
+
selection model.send(property)
|
96
|
+
focus true
|
97
|
+
on_widget_selected {
|
98
|
+
table_proxy.finish_edit!
|
99
|
+
}
|
100
|
+
on_focus_lost {
|
101
|
+
table_proxy.finish_edit!
|
102
|
+
}
|
103
|
+
on_key_pressed { |key_event|
|
104
|
+
if key_event.keyCode == swt(:cr)
|
105
|
+
table_proxy.finish_edit!
|
106
|
+
elsif key_event.keyCode == swt(:esc)
|
107
|
+
table_proxy.cancel_edit!
|
108
|
+
end
|
109
|
+
}
|
110
|
+
}
|
111
|
+
end,
|
112
|
+
},
|
113
|
+
radio: {
|
114
|
+
widget_value_property: :selection,
|
115
|
+
editor_gui: lambda do |args, model, property, table_proxy|
|
116
|
+
first_time = true
|
117
|
+
table_proxy.table_editor.minimumHeight = 25
|
118
|
+
radio(*args) {
|
119
|
+
selection model.send(property)
|
120
|
+
focus true
|
121
|
+
on_widget_selected {
|
122
|
+
table_proxy.finish_edit!
|
123
|
+
}
|
124
|
+
on_focus_lost {
|
125
|
+
table_proxy.finish_edit!
|
126
|
+
}
|
127
|
+
on_key_pressed { |key_event|
|
128
|
+
if key_event.keyCode == swt(:cr)
|
129
|
+
table_proxy.finish_edit!
|
130
|
+
elsif key_event.keyCode == swt(:esc)
|
131
|
+
table_proxy.cancel_edit!
|
132
|
+
end
|
133
|
+
}
|
134
|
+
}
|
135
|
+
end,
|
136
|
+
}
|
89
137
|
}
|
90
138
|
end
|
91
139
|
end
|
@@ -276,7 +324,7 @@ module Glimmer
|
|
276
324
|
new_value = @table_editor_widget_proxy&.swt_widget&.send(widget_value_property)
|
277
325
|
if table_item.isDisposed
|
278
326
|
@cancel_edit.call
|
279
|
-
elsif new_value && !action_taken && !@edit_in_progress && !@cancel_in_progress
|
327
|
+
elsif !new_value.nil? && !action_taken && !@edit_in_progress && !@cancel_in_progress
|
280
328
|
action_taken = true
|
281
329
|
@edit_in_progress = true
|
282
330
|
if new_value == model.send(model_editing_property)
|
@@ -22,21 +22,39 @@ module Glimmer
|
|
22
22
|
include Packages
|
23
23
|
|
24
24
|
DEFAULT_STYLES = {
|
25
|
-
"
|
26
|
-
"
|
27
|
-
"
|
28
|
-
"
|
29
|
-
"
|
30
|
-
"list"
|
31
|
-
"
|
32
|
-
"
|
33
|
-
"
|
34
|
-
"
|
25
|
+
"arrow" => [:arrow],
|
26
|
+
"button" => [:push],
|
27
|
+
"checkbox" => [:check],
|
28
|
+
"drag_source" => [:drop_copy],
|
29
|
+
"drop_target" => [:drop_copy],
|
30
|
+
"list" => [:border, :v_scroll],
|
31
|
+
"menu_item" => [:push],
|
32
|
+
"radio" => [:radio],
|
33
|
+
"scrolled_composite" => [:border, :h_scroll, :v_scroll],
|
34
|
+
"spinner" => [:border],
|
35
|
+
"styled_text" => [:border],
|
36
|
+
"table" => [:virtual, :border, :full_selection],
|
37
|
+
"text" => [:border],
|
38
|
+
"toggle" => [:toggle],
|
39
|
+
"tree" => [:virtual, :border, :h_scroll, :v_scroll],
|
35
40
|
}
|
36
41
|
|
37
42
|
DEFAULT_INITIALIZERS = {
|
38
43
|
"composite" => lambda do |composite|
|
39
|
-
|
44
|
+
layout = GridLayout.new
|
45
|
+
layout.marginWidth = 15
|
46
|
+
layout.marginHeight = 15
|
47
|
+
composite.layout = layout
|
48
|
+
end,
|
49
|
+
"scrolled_composite" => lambda do |scrolled_composite|
|
50
|
+
scrolled_composite.expand_horizontal = true
|
51
|
+
scrolled_composite.expand_vertical = true
|
52
|
+
end,
|
53
|
+
"shell" => lambda do |shell|
|
54
|
+
layout = FillLayout.new
|
55
|
+
layout.marginWidth = 15
|
56
|
+
layout.marginHeight = 15
|
57
|
+
shell.layout = layout
|
40
58
|
end,
|
41
59
|
"table" => lambda do |table|
|
42
60
|
table.setHeaderVisible(true)
|
@@ -49,19 +67,47 @@ module Glimmer
|
|
49
67
|
group.setLayout(GridLayout.new)
|
50
68
|
end,
|
51
69
|
}
|
70
|
+
|
71
|
+
class << self
|
72
|
+
def create(keyword, parent, args)
|
73
|
+
widget_proxy_class(keyword).new(keyword, parent, args)
|
74
|
+
end
|
75
|
+
|
76
|
+
def widget_proxy_class(keyword)
|
77
|
+
begin
|
78
|
+
class_name = "#{keyword.camelcase(:upper)}Proxy".to_sym
|
79
|
+
Glimmer::SWT.const_get(class_name)
|
80
|
+
rescue
|
81
|
+
Glimmer::SWT::WidgetProxy
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def underscored_widget_name(swt_widget)
|
86
|
+
swt_widget.class.name.split(/::|\./).last.underscore
|
87
|
+
end
|
88
|
+
end
|
52
89
|
|
53
|
-
attr_reader :swt_widget, :drag_source_proxy, :drop_target_proxy, :drag_source_style, :drag_source_transfer, :drop_target_transfer
|
90
|
+
attr_reader :parent_proxy, :swt_widget, :drag_source_proxy, :drop_target_proxy, :drag_source_style, :drag_source_transfer, :drop_target_transfer
|
54
91
|
|
55
92
|
# Initializes a new SWT Widget
|
56
93
|
#
|
57
94
|
# Styles is a comma separate list of symbols representing SWT styles in lower case
|
58
|
-
def initialize(
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
95
|
+
def initialize(*init_args, swt_widget: nil)
|
96
|
+
if swt_widget.nil?
|
97
|
+
underscored_widget_name, parent, args = init_args
|
98
|
+
@parent_proxy = parent
|
99
|
+
styles, extra_options = extract_args(underscored_widget_name, args)
|
100
|
+
swt_widget_class = self.class.swt_widget_class_for(underscored_widget_name)
|
101
|
+
@swt_widget = swt_widget_class.new(@parent_proxy.swt_widget, style(underscored_widget_name, styles), *extra_options)
|
102
|
+
else
|
103
|
+
@swt_widget = swt_widget
|
104
|
+
underscored_widget_name = self.class.underscored_widget_name(@swt_widget)
|
105
|
+
parent_proxy_class = self.class.widget_proxy_class(self.class.underscored_widget_name(@swt_widget.parent))
|
106
|
+
@parent_proxy = parent_proxy_class.new(swt_widget: swt_widget.parent)
|
107
|
+
end
|
108
|
+
@swt_widget.set_data('proxy', self)
|
63
109
|
DEFAULT_INITIALIZERS[underscored_widget_name]&.call(@swt_widget)
|
64
|
-
|
110
|
+
@parent_proxy.post_initialize_child(self)
|
65
111
|
end
|
66
112
|
|
67
113
|
# Subclasses may override to perform post initialization work on an added child
|
@@ -69,6 +115,11 @@ module Glimmer
|
|
69
115
|
# No Op by default
|
70
116
|
end
|
71
117
|
|
118
|
+
# Subclasses may override to perform post add_content work
|
119
|
+
def post_add_content
|
120
|
+
# No Op by default
|
121
|
+
end
|
122
|
+
|
72
123
|
def extract_args(underscored_widget_name, args)
|
73
124
|
@arg_extractor_mapping ||= {
|
74
125
|
'menu_item' => lambda do |args|
|
@@ -264,6 +315,7 @@ module Glimmer
|
|
264
315
|
|
265
316
|
# This supports widgets in and out of basic SWT
|
266
317
|
def self.swt_widget_class_for(underscored_widget_name)
|
318
|
+
underscored_widget_name = 'button' if %w[radio checkbox toggle arrow].include?(underscored_widget_name)
|
267
319
|
swt_widget_name = underscored_widget_name.camelcase(:upper)
|
268
320
|
swt_widget_class = eval(swt_widget_name)
|
269
321
|
unless swt_widget_class.ancestors.include?(org.eclipse.swt.widgets.Widget)
|
@@ -607,6 +659,15 @@ module Glimmer
|
|
607
659
|
value
|
608
660
|
end
|
609
661
|
end,
|
662
|
+
:cursor => lambda do |value|
|
663
|
+
cursor_proxy = nil
|
664
|
+
if value.is_a?(CursorProxy)
|
665
|
+
cursor_proxy = value
|
666
|
+
elsif value.is_a?(Symbol) || value.is_a?(String) || value.is_a?(Integer)
|
667
|
+
cursor_proxy = CursorProxy.new(value)
|
668
|
+
end
|
669
|
+
cursor_proxy ? cursor_proxy.swt_cursor : value
|
670
|
+
end,
|
610
671
|
:foreground => color_converter,
|
611
672
|
:font => lambda do |value|
|
612
673
|
if value.is_a?(Hash)
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require_relative "contact_manager/contact_manager_presenter"
|
2
|
+
|
3
|
+
class ContactManager
|
4
|
+
include Glimmer
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@contact_manager_presenter = ContactManagerPresenter.new
|
8
|
+
@contact_manager_presenter.list
|
9
|
+
end
|
10
|
+
|
11
|
+
def launch
|
12
|
+
shell {
|
13
|
+
text "Contact Manager"
|
14
|
+
composite {
|
15
|
+
group {
|
16
|
+
grid_layout(2, false) {
|
17
|
+
margin_width 0
|
18
|
+
margin_height 0
|
19
|
+
}
|
20
|
+
layout_data :fill, :center, true, false
|
21
|
+
text 'Lookup Contacts'
|
22
|
+
font height: 24
|
23
|
+
|
24
|
+
label {
|
25
|
+
layout_data :right, :center, false, false
|
26
|
+
text "First &Name: "
|
27
|
+
font height: 16
|
28
|
+
}
|
29
|
+
text {
|
30
|
+
layout_data :fill, :center, true, false
|
31
|
+
text bind(@contact_manager_presenter, :first_name)
|
32
|
+
on_key_pressed {|key_event|
|
33
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
label {
|
38
|
+
layout_data :right, :center, false, false
|
39
|
+
text "&Last Name: "
|
40
|
+
font height: 16
|
41
|
+
}
|
42
|
+
text {
|
43
|
+
layout_data :fill, :center, true, false
|
44
|
+
text bind(@contact_manager_presenter, :last_name)
|
45
|
+
on_key_pressed {|key_event|
|
46
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
label {
|
51
|
+
layout_data :right, :center, false, false
|
52
|
+
text "&Email: "
|
53
|
+
font height: 16
|
54
|
+
}
|
55
|
+
text {
|
56
|
+
layout_data :fill, :center, true, false
|
57
|
+
text bind(@contact_manager_presenter, :email)
|
58
|
+
on_key_pressed {|key_event|
|
59
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
composite {
|
64
|
+
row_layout {
|
65
|
+
margin_width 0
|
66
|
+
margin_height 0
|
67
|
+
}
|
68
|
+
layout_data(:right, :center, false, false) {
|
69
|
+
horizontal_span 2
|
70
|
+
}
|
71
|
+
|
72
|
+
button {
|
73
|
+
text "&Find"
|
74
|
+
on_widget_selected { @contact_manager_presenter.find }
|
75
|
+
on_key_pressed {|key_event|
|
76
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
button {
|
81
|
+
text "&List All"
|
82
|
+
on_widget_selected { @contact_manager_presenter.list }
|
83
|
+
on_key_pressed {|key_event|
|
84
|
+
@contact_manager_presenter.list if key_event.keyCode == swt(:cr)
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
table(:multi) { |table_proxy|
|
91
|
+
layout_data {
|
92
|
+
horizontal_alignment :fill
|
93
|
+
vertical_alignment :fill
|
94
|
+
grab_excess_horizontal_space true
|
95
|
+
grab_excess_vertical_space true
|
96
|
+
height_hint 200
|
97
|
+
}
|
98
|
+
table_column {
|
99
|
+
text "First Name"
|
100
|
+
width 80
|
101
|
+
}
|
102
|
+
table_column {
|
103
|
+
text "Last Name"
|
104
|
+
width 80
|
105
|
+
}
|
106
|
+
table_column {
|
107
|
+
text "Email"
|
108
|
+
width 200
|
109
|
+
}
|
110
|
+
items bind(@contact_manager_presenter, :results),
|
111
|
+
column_properties(:first_name, :last_name, :email)
|
112
|
+
on_mouse_up { |event|
|
113
|
+
table_proxy.edit_table_item(event.table_item, event.column_index)
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
}.open
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
ContactManager.new.launch
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative "contact_repository"
|
2
|
+
|
3
|
+
class ContactManager
|
4
|
+
class ContactManagerPresenter
|
5
|
+
attr_accessor :results
|
6
|
+
@@contact_attributes = [:first_name, :last_name, :email]
|
7
|
+
@@contact_attributes.each {|attribute_name| attr_accessor attribute_name}
|
8
|
+
|
9
|
+
def initialize(contact_repository = nil)
|
10
|
+
@contact_repository = contact_repository || ContactRepository.new
|
11
|
+
@results = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def list
|
15
|
+
self.results = @contact_repository.find({})
|
16
|
+
end
|
17
|
+
|
18
|
+
def find
|
19
|
+
filter_map = {}
|
20
|
+
@@contact_attributes.each do |attribute_name|
|
21
|
+
filter_map[attribute_name] = self.send(attribute_name) if self.send(attribute_name)
|
22
|
+
end
|
23
|
+
self.results = @contact_repository.find(filter_map)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|