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