lib/glimmer/swt/custom/shape.rb in glimmer-dsl-swt-4.18.2.4 vs lib/glimmer/swt/custom/shape.rb in glimmer-dsl-swt-4.18.2.5
- old
+ new
@@ -41,26 +41,44 @@
def valid?(parent, keyword, *args, &block)
gc_instance_methods.include?(method_name(keyword, args))
end
def gc_instance_methods
- org.eclipse.swt.graphics.GC.instance_methods.map(&:to_s)
+ @gc_instance_methods ||= org.eclipse.swt.graphics.GC.instance_methods.map(&:to_s)
end
+ def keywords
+ @keywords ||= gc_instance_methods.select do |method_name|
+ !method_name.end_with?('=') && (method_name.start_with?('draw_') || method_name.start_with?('fill_'))
+ end.reject do |method_name|
+ gc_instance_methods.include?("#{method_name}=") || gc_instance_methods.include?("set_#{method_name}")
+ end.map do |method_name|
+ method_name.gsub(/(draw|fill|gradient|round)_/, '')
+ end.uniq.compact.to_a
+ end
+
def arg_options(args, extract: false)
arg_options_method = extract ? :pop : :last
options = args.send(arg_options_method) if args.last.is_a?(Hash)
options.nil? ? {} : options.symbolize_keys
end
def method_name(keyword, args)
- keyword = keyword.to_s
- gradient = 'gradient_' if arg_options(args)[:gradient]
- round = 'round_' if arg_options(args)[:round]
- gc_instance_method_name_prefix = !['polyline', 'point', 'image', 'focus'].include?(keyword) && (arg_options(args)[:fill] || arg_options(args)[:gradient]) ? 'fill_' : 'draw_'
- "#{gc_instance_method_name_prefix}#{gradient}#{round}#{keyword}"
+ method_arg_options = arg_options(args)
+ unless flyweight_method_names.keys.include?([keyword, method_arg_options])
+ keyword = keyword.to_s
+ gradient = 'gradient_' if method_arg_options[:gradient]
+ round = 'round_' if method_arg_options[:round]
+ gc_instance_method_name_prefix = !['polyline', 'point', 'image', 'focus'].include?(keyword) && (method_arg_options[:fill] || method_arg_options[:gradient]) ? 'fill_' : 'draw_'
+ flyweight_method_names[[keyword, method_arg_options]] = "#{gc_instance_method_name_prefix}#{gradient}#{round}#{keyword}"
+ end
+ flyweight_method_names[[keyword, method_arg_options]]
end
+
+ def flyweight_method_names
+ @flyweight_method_names ||= {}
+ end
end
attr_reader :parent, :name, :args, :options, :swt_widget, :paint_listener_proxy
def initialize(parent, keyword, *args, &property_block)
@@ -90,31 +108,15 @@
def round?
@options[:round]
end
def post_add_content
- event_handler = lambda do |event|
- @properties['background'] = [@parent.background] if fill? && !@properties.keys.map(&:to_s).include?('background')
- @properties['foreground'] = [@parent.foreground] if draw? && !@properties.keys.map(&:to_s).include?('foreground')
- @properties.each do |property, args|
- method_name = attribute_setter(property)
- apply_property_arg_conversions(method_name, args)
- event.gc.send(method_name, *args)
- end
- apply_shape_arg_conversions(@method_name, @args)
- apply_shape_arg_defaults(@method_name, @args)
- tolerate_shape_extra_args(@method_name, @args)
- event.gc.send(@method_name, *@args)
- end
- if parent.respond_to?(:swt_display)
- @paint_listener_proxy = @parent.on_swt_paint(&event_handler)
- else
- @paint_listener_proxy = @parent.on_paint_control(&event_handler)
- end
+ setup_paint_listener
+ @content_added = true
end
- def apply_property_arg_conversions(method_name, args)
+ def apply_property_arg_conversions(method_name, property, args)
the_java_method = org.eclipse.swt.graphics.GC.java_class.declared_instance_methods.detect {|m| m.name == method_name}
if (args.first.is_a?(Symbol) || args.first.is_a?(String))
if the_java_method.parameter_types.first == Color.java_class
args[0] = ColorProxy.new(args[0])
end
@@ -141,10 +143,11 @@
end
new_args = [DisplayProxy.instance.swt_display] + args
args[0] = org.eclipse.swt.graphics.Pattern.new(*new_args)
args[1..-1] = []
end
+ @properties[property] = args
end
def apply_shape_arg_conversions(method_name, args)
if args.size > 1 && (method_name.include?('polygon') || method_name.include?('polyline'))
args[0] = args.dup
@@ -183,13 +186,40 @@
self.class.gc_instance_methods.include?(attribute_setter(attribute_name))
end
def set_attribute(attribute_name, *args)
@properties[attribute_name] = args
+ if @content_added
+ @parent.resetup_shape_paint_listeners
+ @parent.redraw
+ end
end
def get_attribute(attribute_name)
@properties.symbolize_keys[attribute_name.to_s.to_sym]
+ end
+
+ def setup_paint_listener
+ if parent.respond_to?(:swt_display)
+ @paint_listener_proxy = @parent.on_swt_paint(&method(:paint))
+ else
+ @paint_listener_proxy = @parent.on_paint_control(&method(:paint))
+ end
+ end
+
+ def paint(paint_event)
+ @properties['background'] = [@parent.background] if fill? && !@properties.keys.map(&:to_s).include?('background')
+ @properties['foreground'] = [@parent.foreground] if draw? && !@properties.keys.map(&:to_s).include?('foreground')
+ @properties['font'] = [@parent.font] if draw? && !@properties.keys.map(&:to_s).include?('font')
+ @properties.each do |property, args|
+ method_name = attribute_setter(property)
+ apply_property_arg_conversions(method_name, property, args)
+ paint_event.gc.send(method_name, *args)
+ end
+ apply_shape_arg_conversions(@method_name, @args)
+ apply_shape_arg_defaults(@method_name, @args)
+ tolerate_shape_extra_args(@method_name, @args)
+ paint_event.gc.send(@method_name, *@args)
end
end
end