glimmer-dsl-swt 0.1.0
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 +7 -0
- data/LICENSE.txt +20 -0
- data/README.md +47 -0
- data/RUBY_VERSION +1 -0
- data/VERSION +1 -0
- data/bin/girb +10 -0
- data/bin/girb_runner.rb +13 -0
- data/bin/glimmer +5 -0
- data/icons/scaffold_app.icns +0 -0
- data/lib/ext/glimmer.rb +13 -0
- data/lib/ext/glimmer/config.rb +18 -0
- data/lib/glimmer-dsl-swt.rb +12 -0
- data/lib/glimmer/data_binding/list_selection_binding.rb +52 -0
- data/lib/glimmer/data_binding/model_binding.rb +248 -0
- data/lib/glimmer/data_binding/observable.rb +21 -0
- data/lib/glimmer/data_binding/observable_array.rb +107 -0
- data/lib/glimmer/data_binding/observable_model.rb +108 -0
- data/lib/glimmer/data_binding/observable_widget.rb +17 -0
- data/lib/glimmer/data_binding/observer.rb +124 -0
- data/lib/glimmer/data_binding/shine.rb +23 -0
- data/lib/glimmer/data_binding/table_items_binding.rb +56 -0
- data/lib/glimmer/data_binding/tree_items_binding.rb +71 -0
- data/lib/glimmer/data_binding/widget_binding.rb +33 -0
- data/lib/glimmer/dsl/swt/async_exec_expression.rb +14 -0
- data/lib/glimmer/dsl/swt/bind_expression.rb +37 -0
- data/lib/glimmer/dsl/swt/color_expression.rb +19 -0
- data/lib/glimmer/dsl/swt/column_properties_expression.rb +24 -0
- data/lib/glimmer/dsl/swt/combo_selection_data_binding_expression.rb +42 -0
- data/lib/glimmer/dsl/swt/custom_widget_expression.rb +39 -0
- data/lib/glimmer/dsl/swt/data_binding_expression.rb +34 -0
- data/lib/glimmer/dsl/swt/dialog_expression.rb +26 -0
- data/lib/glimmer/dsl/swt/display_expression.rb +19 -0
- data/lib/glimmer/dsl/swt/dsl.rb +34 -0
- data/lib/glimmer/dsl/swt/exec_expression.rb +28 -0
- data/lib/glimmer/dsl/swt/layout_data_expression.rb +25 -0
- data/lib/glimmer/dsl/swt/layout_expression.rb +27 -0
- data/lib/glimmer/dsl/swt/list_selection_data_binding_expression.rb +44 -0
- data/lib/glimmer/dsl/swt/menu_bar_expression.rb +33 -0
- data/lib/glimmer/dsl/swt/menu_expression.rb +32 -0
- data/lib/glimmer/dsl/swt/message_box_expression.rb +29 -0
- data/lib/glimmer/dsl/swt/observe_expression.rb +32 -0
- data/lib/glimmer/dsl/swt/property_expression.rb +22 -0
- data/lib/glimmer/dsl/swt/rgb_expression.rb +12 -0
- data/lib/glimmer/dsl/swt/rgba_expression.rb +12 -0
- data/lib/glimmer/dsl/swt/shell_expression.rb +25 -0
- data/lib/glimmer/dsl/swt/swt_expression.rb +25 -0
- data/lib/glimmer/dsl/swt/sync_exec_expression.rb +15 -0
- data/lib/glimmer/dsl/swt/tab_item_expression.rb +33 -0
- data/lib/glimmer/dsl/swt/table_items_data_binding_expression.rb +31 -0
- data/lib/glimmer/dsl/swt/tree_items_data_binding_expression.rb +31 -0
- data/lib/glimmer/dsl/swt/tree_properties_expression.rb +26 -0
- data/lib/glimmer/dsl/swt/widget_expression.rb +35 -0
- data/lib/glimmer/dsl/swt/widget_listener_expression.rb +32 -0
- data/lib/glimmer/launcher.rb +196 -0
- data/lib/glimmer/package.rb +57 -0
- data/lib/glimmer/rake_task.rb +62 -0
- data/lib/glimmer/scaffold.rb +582 -0
- data/lib/glimmer/swt/color_proxy.rb +53 -0
- data/lib/glimmer/swt/display_proxy.rb +88 -0
- data/lib/glimmer/swt/font_proxy.rb +72 -0
- data/lib/glimmer/swt/layout_data_proxy.rb +84 -0
- data/lib/glimmer/swt/layout_proxy.rb +82 -0
- data/lib/glimmer/swt/menu_proxy.rb +101 -0
- data/lib/glimmer/swt/message_box_proxy.rb +48 -0
- data/lib/glimmer/swt/packages.rb +13 -0
- data/lib/glimmer/swt/shell_proxy.rb +152 -0
- data/lib/glimmer/swt/swt_proxy.rb +106 -0
- data/lib/glimmer/swt/tab_item_proxy.rb +65 -0
- data/lib/glimmer/swt/table_proxy.rb +150 -0
- data/lib/glimmer/swt/tree_proxy.rb +120 -0
- data/lib/glimmer/swt/widget_listener_proxy.rb +34 -0
- data/lib/glimmer/swt/widget_proxy.rb +489 -0
- data/lib/glimmer/ui/custom_shell.rb +45 -0
- data/lib/glimmer/ui/custom_widget.rb +244 -0
- data/lib/glimmer/util/proc_tracker.rb +16 -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 +307 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'glimmer/swt/swt_proxy'
|
2
|
+
require 'glimmer/swt/display_proxy'
|
3
|
+
|
4
|
+
module Glimmer
|
5
|
+
module SWT
|
6
|
+
# Proxy for org.eclipse.swt.graphics.Color
|
7
|
+
#
|
8
|
+
# Invoking `#swt_color` returns the SWT color object wrapped by this proxy
|
9
|
+
#
|
10
|
+
# Follows the Proxy Design Pattern
|
11
|
+
class ColorProxy
|
12
|
+
include_package 'org.eclipse.swt.graphics'
|
13
|
+
|
14
|
+
# Initializes a proxy for an SWT Color object
|
15
|
+
#
|
16
|
+
# Takes a standard color single argument, rgba 3 args, or rgba 4 args
|
17
|
+
#
|
18
|
+
# A standard color is a string/symbol representing one of the
|
19
|
+
# SWT.COLOR_*** constants like SWT.COLOR_RED, but in underscored string
|
20
|
+
# format (e.g :color_red).
|
21
|
+
# Glimmer can also accept standard color names without the color_ prefix,
|
22
|
+
# and it will automatically figure out the SWT.COLOR_*** constant
|
23
|
+
# (e.g. :red)
|
24
|
+
#
|
25
|
+
# rgb is 3 arguments representing Red, Green, Blue numeric values
|
26
|
+
#
|
27
|
+
# rgba is 4 arguments representing Red, Green, Blue, and Alpha numeric values
|
28
|
+
#
|
29
|
+
def initialize(*args)
|
30
|
+
@args = args
|
31
|
+
end
|
32
|
+
|
33
|
+
def swt_color
|
34
|
+
unless @swt_color
|
35
|
+
case @args.size
|
36
|
+
when 1
|
37
|
+
if @args.first.is_a?(String) || @args.first.is_a?(Symbol)
|
38
|
+
standard_color = @args.first
|
39
|
+
standard_color = "color_#{standard_color}".to_sym unless standard_color.to_s.downcase.include?('color_')
|
40
|
+
@swt_color = DisplayProxy.instance.swt_display.getSystemColor(SWTProxy[standard_color])
|
41
|
+
else
|
42
|
+
@swt_color = @args.first
|
43
|
+
end
|
44
|
+
when 3..4
|
45
|
+
red, green, blue, alpha = @args
|
46
|
+
@swt_color = Color.new(DisplayProxy.instance.swt_display, *[red, green, blue, alpha].compact)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
@swt_color
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'glimmer/swt/widget_listener_proxy'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module SWT
|
5
|
+
# Proxy for org.eclipse.swt.widgets.Display
|
6
|
+
#
|
7
|
+
# Maintains a singleton instance since SWT only supports
|
8
|
+
# a single active display at a time.
|
9
|
+
#
|
10
|
+
# Supports SWT Display's very useful asyncExec and syncExec methods
|
11
|
+
# to support proper multi-threaded manipulation of SWT UI objects
|
12
|
+
#
|
13
|
+
# Invoking `#swt_display` returns the SWT Display object wrapped by this proxy
|
14
|
+
#
|
15
|
+
# Follows the Proxy Design Pattern
|
16
|
+
class DisplayProxy
|
17
|
+
include_package 'org.eclipse.swt.widgets'
|
18
|
+
|
19
|
+
OBSERVED_MENU_ITEMS = ['about', 'preferences']
|
20
|
+
|
21
|
+
class << self
|
22
|
+
# Returns singleton instance
|
23
|
+
def instance(*args)
|
24
|
+
if @instance.nil? || @instance.swt_display.isDisposed
|
25
|
+
@instance = new(*args)
|
26
|
+
end
|
27
|
+
@instance
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# SWT Display object wrapped
|
32
|
+
attr_reader :swt_display
|
33
|
+
|
34
|
+
def initialize(*args)
|
35
|
+
@swt_display = Display.new(*args)
|
36
|
+
end
|
37
|
+
|
38
|
+
def dispose
|
39
|
+
@swt_display.dispose
|
40
|
+
end
|
41
|
+
|
42
|
+
# Executes code block asynchronously with respect to SWT UI thread
|
43
|
+
def async_exec(&block)
|
44
|
+
@swt_display.asyncExec(&block)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Executes code block synchronously with respect to SWT UI thread
|
48
|
+
def sync_exec(&block)
|
49
|
+
@swt_display.syncExec(&block)
|
50
|
+
end
|
51
|
+
|
52
|
+
def can_handle_observation_request?(observation_request)
|
53
|
+
observation_request = observation_request.to_s
|
54
|
+
if observation_request.start_with?('on_event_')
|
55
|
+
constant_name = observation_request.sub(/^on_event_/, '')
|
56
|
+
SWTProxy.has_constant?(constant_name)
|
57
|
+
elsif observation_request.start_with?('on_')
|
58
|
+
event_name = observation_request.sub(/^on_/, '')
|
59
|
+
OBSERVED_MENU_ITEMS.include?(event_name)
|
60
|
+
else
|
61
|
+
false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def handle_observation_request(observation_request, &block)
|
66
|
+
if observation_request.start_with?('on_event_')
|
67
|
+
constant_name = observation_request.sub(/^on_event_/, '')
|
68
|
+
add_swt_event_listener(constant_name, &block)
|
69
|
+
elsif observation_request.start_with?('on_')
|
70
|
+
event_name = observation_request.sub(/^on_/, '')
|
71
|
+
if OBSERVED_MENU_ITEMS.include?(event_name)
|
72
|
+
if OS.mac?
|
73
|
+
system_menu = swt_display.getSystemMenu
|
74
|
+
menu_item = system_menu.getItems.find {|menu_item| menu_item.getID == SWTProxy["ID_#{event_name.upcase}"]}
|
75
|
+
menu_item.addListener(SWTProxy[:Selection], &block)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def add_swt_event_listener(swt_constant, &block)
|
82
|
+
event_type = SWTProxy[swt_constant]
|
83
|
+
@swt_display.addFilter(event_type, &block)
|
84
|
+
#WidgetListenerProxy.new(@swt_display.getListeners(event_type).last)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'glimmer/error'
|
2
|
+
require 'glimmer/swt/swt_proxy'
|
3
|
+
require 'glimmer/swt/display_proxy'
|
4
|
+
|
5
|
+
module Glimmer
|
6
|
+
module SWT
|
7
|
+
# Proxy for org.eclipse.swt.graphics.Font
|
8
|
+
#
|
9
|
+
# This class is meant to be used with WidgetProxy to manipulate
|
10
|
+
# an SWT widget font.
|
11
|
+
#
|
12
|
+
# It is not meant to create new SWT fonts form scratch without
|
13
|
+
# a widget proxy.
|
14
|
+
#
|
15
|
+
# Invoking `#swt_font` returns the SWT Font object wrapped by this proxy
|
16
|
+
#
|
17
|
+
# Follows the Proxy Design Pattern
|
18
|
+
class FontProxy
|
19
|
+
ERROR_INVALID_FONT_STYLE = " is an invalid font style! Valid values are :normal, :bold, and :italic"
|
20
|
+
FONT_STYLES = [:normal, :bold, :italic]
|
21
|
+
|
22
|
+
include_package 'org.eclipse.swt.graphics'
|
23
|
+
|
24
|
+
attr_reader :widget_proxy, :swt_font
|
25
|
+
|
26
|
+
# Builds a new font proxy from passed in widget_proxy and font_properties hash,
|
27
|
+
#
|
28
|
+
# It begins with existing SWT widget font and amends it with font properties.
|
29
|
+
#
|
30
|
+
# Font properties consist of: :name, :height, and :style (one needed minimum)
|
31
|
+
#
|
32
|
+
# Style (:style value) can only be one of FontProxy::FONT_STYLES values:
|
33
|
+
# that is :normal, :bold, or :italic
|
34
|
+
def initialize(widget_proxy, font_properties)
|
35
|
+
@widget_proxy = widget_proxy
|
36
|
+
detect_invalid_font_property(font_properties)
|
37
|
+
font_properties[:style] = SWTProxy[*font_properties[:style]]
|
38
|
+
font_data_args = [:name, :height, :style].map do |font_property_name|
|
39
|
+
font_properties[font_property_name] || send(font_property_name)
|
40
|
+
end
|
41
|
+
font_datum = FontData.new(*font_data_args)
|
42
|
+
@swt_font = Font.new(DisplayProxy.instance.swt_display, font_datum)
|
43
|
+
end
|
44
|
+
|
45
|
+
def name
|
46
|
+
font_datum.getName
|
47
|
+
end
|
48
|
+
|
49
|
+
def height
|
50
|
+
font_datum.getHeight
|
51
|
+
end
|
52
|
+
|
53
|
+
def style
|
54
|
+
font_datum.getStyle
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def font_datum
|
60
|
+
@font_datum ||= @widget_proxy.swt_widget.getFont.getFontData[0]
|
61
|
+
end
|
62
|
+
|
63
|
+
def detect_invalid_font_property(font_properties)
|
64
|
+
[font_properties[:style]].flatten.select do |style|
|
65
|
+
style.is_a?(Symbol) || style.is_a?(String)
|
66
|
+
end.each do |style|
|
67
|
+
raise Error, style.to_s + ERROR_INVALID_FONT_STYLE if !FONT_STYLES.include?(style.to_sym)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'glimmer'
|
2
|
+
require 'glimmer/swt/swt_proxy'
|
3
|
+
|
4
|
+
module Glimmer
|
5
|
+
module SWT
|
6
|
+
# Generic proxy for all SWT layout data objects, such as GridData & RowData
|
7
|
+
#
|
8
|
+
# This class is meant to be used with an existing WidgetProxy
|
9
|
+
# as it figures out the right SWT layout data class name
|
10
|
+
# by convention from the parent SWT widget layout class name
|
11
|
+
#
|
12
|
+
# The convention is:
|
13
|
+
# - Start with the parent widget layout package/class name (e.g. org.eclipse.swt.layout.RowLayout)
|
14
|
+
# - Replace the word "Layout" with "Data" in the class name
|
15
|
+
#
|
16
|
+
# Examples of figuring out SWT layout data class:
|
17
|
+
# - org.eclipse.swt.layout.RowData for org.eclipse.swt.layout.RowLayout
|
18
|
+
# - org.eclipse.swt.layout.GridData for org.eclipse.swt.layout.GridLayout
|
19
|
+
#
|
20
|
+
# Follows the Proxy Design Pattern
|
21
|
+
class LayoutDataProxy
|
22
|
+
include_package 'org.eclipse.swt.layout'
|
23
|
+
|
24
|
+
attr_reader :widget_proxy
|
25
|
+
attr_reader :swt_layout_data
|
26
|
+
|
27
|
+
# Inititalizes with owning widget proxy and layout data arguments
|
28
|
+
def initialize(widget_proxy, args)
|
29
|
+
@widget_proxy = widget_proxy
|
30
|
+
args = SWTProxy.constantify_args(args)
|
31
|
+
begin
|
32
|
+
@swt_layout_data = swt_layout_data_class.new(*args)
|
33
|
+
rescue => e
|
34
|
+
Glimmer::Config.logger&.debug "#{e.message}\n#{e.backtrace.join("\n")}"
|
35
|
+
@swt_layout_data = args.first if args.count == 1
|
36
|
+
end
|
37
|
+
@widget_proxy.swt_widget.setLayoutData(@swt_layout_data)
|
38
|
+
end
|
39
|
+
|
40
|
+
# This figures out the right SWT layout data class name
|
41
|
+
# by convention from the parent SWT widget layout class name
|
42
|
+
#
|
43
|
+
# Supports layout data classes in and out of basic SWT library
|
44
|
+
#
|
45
|
+
# The convention is:
|
46
|
+
# - Start with the parent widget layout package/class name (e.g. org.eclipse.swt.layout.RowLayout)
|
47
|
+
# - Replace the word "Layout" with "Data" in the class name
|
48
|
+
#
|
49
|
+
# Examples of figuring out SWT layout data class:
|
50
|
+
# - org.eclipse.swt.layout.RowData for org.eclipse.swt.layout.RowLayout
|
51
|
+
# - org.eclipse.swt.layout.GridData for org.eclipse.swt.layout.GridLayout
|
52
|
+
#
|
53
|
+
def swt_layout_data_class
|
54
|
+
parent_layout_class_name = @widget_proxy.swt_widget.getParent.getLayout.class.name
|
55
|
+
layout_data_class_name = parent_layout_class_name.sub(/Layout$/, 'Data')
|
56
|
+
eval(layout_data_class_name)
|
57
|
+
end
|
58
|
+
|
59
|
+
def has_attribute?(attribute_name, *args)
|
60
|
+
@swt_layout_data.respond_to?(attribute_setter(attribute_name), args)
|
61
|
+
end
|
62
|
+
|
63
|
+
def set_attribute(attribute_name, *args)
|
64
|
+
args = SWTProxy.constantify_args(args)
|
65
|
+
if args.first != @swt_layout_data.send(attribute_getter(attribute_name))
|
66
|
+
@swt_layout_data.send(attribute_setter(attribute_name), *args)
|
67
|
+
@widget_proxy.swt_widget.getShell.pack
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_attribute(attribute_name)
|
72
|
+
@swt_layout_data.send(attribute_getter(attribute_name))
|
73
|
+
end
|
74
|
+
|
75
|
+
def attribute_setter(attribute_name)
|
76
|
+
"#{attribute_name.to_s.camelcase(:lower)}="
|
77
|
+
end
|
78
|
+
|
79
|
+
def attribute_getter(attribute_name)
|
80
|
+
"#{attribute_name.to_s.camelcase(:lower)}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'glimmer'
|
2
|
+
require 'glimmer/swt/swt_proxy'
|
3
|
+
|
4
|
+
module Glimmer
|
5
|
+
module SWT
|
6
|
+
# Proxy for org.eclipse.swt.widgets.Layout
|
7
|
+
#
|
8
|
+
# This is meant to be used with a WidgetProxy where it will
|
9
|
+
# set the layout in the SWT widget upon instantiation.
|
10
|
+
#
|
11
|
+
# Follows the Proxy Design Pattern
|
12
|
+
class LayoutProxy
|
13
|
+
attr_reader :widget_proxy, :swt_layout
|
14
|
+
|
15
|
+
class << self
|
16
|
+
include_package 'org.eclipse.swt.layout'
|
17
|
+
include_package 'org.eclipse.swt.widgets'
|
18
|
+
|
19
|
+
def layout_exists?(underscored_layout_name)
|
20
|
+
begin
|
21
|
+
swt_layout_class_for(underscored_layout_name)
|
22
|
+
true
|
23
|
+
rescue NameError => e
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# This supports layouts in and out of basic SWT library
|
29
|
+
def swt_layout_class_for(underscored_layout_name)
|
30
|
+
swt_layout_name = underscored_layout_name.camelcase(:upper)
|
31
|
+
swt_layout_class = eval(swt_layout_name)
|
32
|
+
unless swt_layout_class.ancestors.include?(Layout)
|
33
|
+
raise NameError, "Class #{swt_layout_class} matching #{underscored_layout_name} is not a subclass of org.eclipse.swt.widgets.Layout"
|
34
|
+
end
|
35
|
+
swt_layout_class
|
36
|
+
rescue => e
|
37
|
+
Glimmer::Config.logger&.debug e.message
|
38
|
+
# Glimmer::Config.logger&.debug "#{e.message}\n#{e.backtrace.join("\n")}"
|
39
|
+
raise e
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def initialize(underscored_layout_name, widget_proxy, args)
|
44
|
+
@underscored_layout_name = underscored_layout_name
|
45
|
+
@widget_proxy = widget_proxy
|
46
|
+
args = SWTProxy.constantify_args(args)
|
47
|
+
@swt_layout = self.class.swt_layout_class_for(underscored_layout_name).new(*args)
|
48
|
+
@widget_proxy.swt_widget.setLayout(@swt_layout)
|
49
|
+
end
|
50
|
+
|
51
|
+
def has_attribute?(attribute_name, *args)
|
52
|
+
@swt_layout.respond_to?(attribute_setter(attribute_name), args)
|
53
|
+
end
|
54
|
+
|
55
|
+
def set_attribute(attribute_name, *args)
|
56
|
+
apply_property_type_converters(attribute_name, args)
|
57
|
+
if args.first != @swt_layout.send(attribute_getter(attribute_name))
|
58
|
+
@swt_layout.send(attribute_setter(attribute_name), *args)
|
59
|
+
@widget_proxy.swt_widget.getShell.pack
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_attribute(attribute_name)
|
64
|
+
@swt_layout.send(attribute_getter(attribute_name))
|
65
|
+
end
|
66
|
+
|
67
|
+
def apply_property_type_converters(attribute_name, args)
|
68
|
+
if args.count == 1 && SWTProxy.has_constant?(args.first)
|
69
|
+
args[0] = SWTProxy.constant(args.first)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def attribute_setter(attribute_name)
|
74
|
+
"#{attribute_name.to_s.camelcase(:lower)}="
|
75
|
+
end
|
76
|
+
|
77
|
+
def attribute_getter(attribute_name)
|
78
|
+
"#{attribute_name.to_s.camelcase(:lower)}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'glimmer/swt/widget_proxy'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module SWT
|
5
|
+
# Proxy for org.eclipse.swt.widgets.Menu
|
6
|
+
#
|
7
|
+
# Functions differently from other widget proxies.
|
8
|
+
#
|
9
|
+
# Glimmer automatically detects if this is a drop down menu
|
10
|
+
# or pop up menu from its parent if no SWT style is passed in.
|
11
|
+
#
|
12
|
+
# There are 3 possibilities:
|
13
|
+
# - SWT :bar style is passed in: Menu Bar
|
14
|
+
# - Parent is ShellProxy: Pop Up Menu (having style :pop_up)
|
15
|
+
# - Parent is another Menu: Drop Down Menu (having style :drop_down)
|
16
|
+
#
|
17
|
+
# In order to get the SWT Menu object, one must call `#swt_widget`.
|
18
|
+
#
|
19
|
+
# In the case of a Drop Down menu, this automatically creates an
|
20
|
+
# SWT MenuItem object with style :cascade
|
21
|
+
#
|
22
|
+
# In order to retrieve the menu item widget proxy, one must call `#menu_item_proxy`
|
23
|
+
#
|
24
|
+
# Follows the Proxy Design Pattern
|
25
|
+
class MenuProxy < WidgetProxy
|
26
|
+
include_package 'org.eclipse.swt.widgets'
|
27
|
+
|
28
|
+
attr_reader :menu_item_proxy, :swt_menu_item, :menu_parent
|
29
|
+
|
30
|
+
def initialize(parent, args)
|
31
|
+
index = args.delete(args.last) if args.last.is_a?(Numeric)
|
32
|
+
styles = args.map(&:to_sym)
|
33
|
+
if !styles.include?(:bar) && !parent.swt_widget.is_a?(Menu)
|
34
|
+
styles = styles.unshift(:pop_up)
|
35
|
+
end
|
36
|
+
|
37
|
+
swt_widget_class = self.class.swt_widget_class_for('menu')
|
38
|
+
if parent.swt_widget.is_a?(Menu)
|
39
|
+
@menu_item_proxy = SWT::WidgetProxy.new('menu_item', parent, [:cascade] + [index].compact)
|
40
|
+
@swt_menu_item = @menu_item_proxy.swt_widget
|
41
|
+
@swt_widget = swt_widget_class.new(@menu_item_proxy.swt_widget)
|
42
|
+
@swt_menu_item.setMenu(swt_widget)
|
43
|
+
elsif parent.swt_widget.is_a?(Shell)
|
44
|
+
@swt_widget = swt_widget_class.new(parent.swt_widget, style('menu', styles))
|
45
|
+
else
|
46
|
+
@swt_widget = swt_widget_class.new(parent.swt_widget)
|
47
|
+
end
|
48
|
+
DEFAULT_INITIALIZERS['menu']&.call(swt_widget)
|
49
|
+
|
50
|
+
if styles.include?(:bar)
|
51
|
+
parent.swt_widget.setMenuBar(swt_widget)
|
52
|
+
elsif styles.include?(:pop_up)
|
53
|
+
parent.swt_widget.setMenu(swt_widget)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def has_attribute?(attribute_name, *args)
|
58
|
+
if attribute_name.to_s == "text"
|
59
|
+
true
|
60
|
+
else
|
61
|
+
super(attribute_name, *args)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def set_attribute(attribute_name, *args)
|
66
|
+
attribute_name
|
67
|
+
if attribute_name.to_s == "text"
|
68
|
+
text_value = args[0]
|
69
|
+
@swt_menu_item.setText text_value
|
70
|
+
else
|
71
|
+
super(attribute_name, *args)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_attribute(attribute_name)
|
76
|
+
if attribute_name.to_s == "text"
|
77
|
+
@swt_menu_item.getText
|
78
|
+
else
|
79
|
+
super(attribute_name)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def can_handle_observation_request?(observation_request, super_only: false)
|
84
|
+
super_result = super(observation_request)
|
85
|
+
if observation_request.start_with?('on_') && !super_result && !super_only
|
86
|
+
return menu_item_proxy.can_handle_observation_request?(observation_request)
|
87
|
+
else
|
88
|
+
super_result
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def handle_observation_request(observation_request, &block)
|
93
|
+
if can_handle_observation_request?(observation_request, super_only: true)
|
94
|
+
super
|
95
|
+
else
|
96
|
+
menu_item_proxy.handle_observation_request(observation_request, &block)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|