Module: Glimmer::SWT::Custom::Drawable

Included in:
DisplayProxy, ImageProxy, WidgetProxy
Defined in:
lib/glimmer/swt/custom/drawable.rb

Overview

Represents SWT drawable controls (widgets like canvas) and display

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#image_double_bufferedObject Also known as: image_double_buffered?

Returns the value of attribute image_double_buffered.



27
28
29
# File 'lib/glimmer/swt/custom/drawable.rb', line 27

def image_double_buffered
  @image_double_buffered
end

#requires_shape_disposalObject Also known as: requires_shape_disposal?

Returns the value of attribute requires_shape_disposal.



27
28
29
# File 'lib/glimmer/swt/custom/drawable.rb', line 27

def requires_shape_disposal
  @requires_shape_disposal
end

Instance Method Details

#add_shape(shape) ⇒ Object



53
54
55
56
57
58
59
# File 'lib/glimmer/swt/custom/drawable.rb', line 53

def add_shape(shape)
  if !@image_double_buffered || shape.args.first == @image_proxy_buffer
    shapes << shape
  else
    image_buffered_shapes << shape
  end
end

#clear_shapes(dispose_images: true, dispose_patterns: true) ⇒ Object Also known as: dispose_shapes



61
62
63
64
# File 'lib/glimmer/swt/custom/drawable.rb', line 61

def clear_shapes(dispose_images: true, dispose_patterns: true)
  # Optimize further by having a collection of disposable_shapes independent of shapes, which is much smaller and only has shapes that require disposal (shapes with patterns or image)
  shapes.dup.each {|s| s.dispose(dispose_images: dispose_images, dispose_patterns: dispose_patterns) } if requires_shape_disposal?
end

#deregister_shape_paintingObject



111
112
113
# File 'lib/glimmer/swt/custom/drawable.rb', line 111

def deregister_shape_painting
  @paint_listener_proxy&.deregister
end

#expanded_shapesObject



37
38
39
40
41
# File 'lib/glimmer/swt/custom/drawable.rb', line 37

def expanded_shapes
  @shapes.map do |shape|
    [shape] + shape.expanded_shapes
  end.flatten
end

#image_buffered_shapesObject



43
44
45
# File 'lib/glimmer/swt/custom/drawable.rb', line 43

def image_buffered_shapes
  @image_buffered_shapes ||= []
end

#paint_pixel_by_pixel(width = nil, height = nil, &each_pixel_color) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/glimmer/swt/custom/drawable.rb', line 67

def paint_pixel_by_pixel(width = nil, height = nil, &each_pixel_color)
  if @image_double_buffered
    work = lambda do |paint_event|
      width ||= swt_drawable.bounds.width
      height ||= swt_drawable.bounds.height
      @image_proxy_buffer ||= ImageProxy.create_pixel_by_pixel(width, height, &each_pixel_color)
      @image_proxy_buffer.shape(self).paint(paint_event)
    end
  else
    work = lambda do |paint_event_or_image|
      the_gc = paint_event_or_image.gc
      current_foreground = nil
      width ||= swt_drawable.bounds.width
      height ||= swt_drawable.bounds.height
      height.times do |y|
        width.times do |x|
          new_foreground = each_pixel_color.call(x, y)
          new_foreground = Glimmer::SWT::ColorProxy.create(new_foreground, ensure_bounds: false) unless new_foreground.is_a?(ColorProxy) || new_foreground.is_a?(Color)
          new_foreground = new_foreground.swt_color if new_foreground.is_a?(Glimmer::SWT::ColorProxy)
          the_gc.foreground = current_foreground = new_foreground unless new_foreground == current_foreground
          the_gc.draw_point x, y
        end
      end
    end
  end
  if respond_to?(:gc)
    work.call(self)
  else
    on_swt_paint(&work)
  end
end

#setup_shape_paintingObject Also known as: resetup_shape_painting



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/glimmer/swt/custom/drawable.rb', line 115

def setup_shape_painting
  # TODO consider performance optimization relating to order of shape rendering (affecting only further shapes not previous ones)
  if @paint_listener_proxy.nil?
    shape_painter = lambda do |paint_event|
      shape_painting_work = lambda do |paint_event|
        paintable_shapes = @image_double_buffered ? image_buffered_shapes : shapes
        paintable_shapes.each do |shape|
          shape.paint(paint_event)
        end
        # When dragging, render dragged shape again on top of everything else.
        if !@image_double_buffered && Glimmer::SWT::Custom::Shape.dragging?
          Glimmer::SWT::Custom::Shape.dragged_shape.paint(paint_event)
        end
      end
      if @image_double_buffered
        if @image_proxy_buffer.nil?
          swt_image = Image.new(DisplayProxy.instance.swt_display, bounds.width, bounds.height)
          @image_proxy_buffer = ImageProxy.new(swt_image: swt_image)
          shape_painting_work.call(@image_proxy_buffer)
        end
        @image_proxy_buffer.shape(self).paint(paint_event)
      else
        shape_painting_work.call(paint_event)
      end
    end
    
    # TODO consider making this logic polymorphic (image vs other)
    if respond_to?(:swt_image)
      shape_painter.call(self) # treat self as paint event since image has its own gc and doesn't do repaints (it's a one time deal for now though could be adjusted in the future.)
    else
      @paint_listener_proxy = on_swt_paint(&shape_painter)
    end
  else
    redraw if respond_to?(:redraw) && @finished_add_content && !is_disposed
  end
end

#shape_at_location(x, y) ⇒ Object

TODO add a method like shapes that specifies drawable_properties to be able to adjust properties like transform in between shapes



49
50
51
# File 'lib/glimmer/swt/custom/drawable.rb', line 49

def shape_at_location(x, y)
  expanded_shapes.reverse.detect {|shape| shape.include?(x, y)}
end

#shapesObject



33
34
35
# File 'lib/glimmer/swt/custom/drawable.rb', line 33

def shapes
  @shapes ||= []
end

#swt_drawableObject



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/glimmer/swt/custom/drawable.rb', line 99

def swt_drawable
  swt_drawable = nil
  if respond_to?(:swt_image)
    swt_drawable = swt_image
  elsif respond_to?(:swt_display)
    swt_drawable = swt_display
  elsif respond_to?(:swt_widget)
    swt_drawable = swt_widget
  end
  swt_drawable
end