class Glimmer::Gtk::Shape
Represents Gtk
shape objects drawn on area widget, like rectangle, arc, and path
Represents Gtk
shape objects drawn on area widget, like rectangle, arc, and path
Represents Gtk
shape objects drawn on area widget, like rectangle, arc, and path
Represents Gtk
shape objects drawn on area widget, like rectangle, arc, and path
Represents Gtk
shape objects drawn on area widget, like rectangle, arc, and path
Represents Gtk
shape objects drawn on area widget, like rectangle, arc, and path
Constants
- SHAPE_FILL_PROPERTIES
- SHAPE_FONT_PROPERTIES
- SHAPE_GENERAL_PROPERTIES
- SHAPE_STROKE_PROPERTIES
Attributes
Public Class Methods
# File lib/glimmer/gtk/shape.rb, line 79 def constant_symbol(keyword) keyword.camelcase(:upper).to_sym end
# File lib/glimmer/gtk/shape.rb, line 71 def create(keyword, parent, args, &block) shape_class(keyword).new(keyword, parent, args, &block) end
# File lib/glimmer/gtk/shape.rb, line 87 def descendant_keyword_constant_map @descendant_keyword_constant_map ||= map_descendant_keyword_constants_for(self) end
# File lib/glimmer/gtk/shape.rb, line 67 def exist?(keyword) shape_class(keyword) end
# File lib/glimmer/gtk/shape.rb, line 83 def keyword(constant_symbol) constant_symbol.to_s.underscore end
# File lib/glimmer/gtk/shape.rb, line 96 def map_descendant_keyword_constants_for(klass, accumulator: {}) klass.constants.map do |constant_symbol| [constant_symbol, klass.const_get(constant_symbol)] end.select do |constant_symbol, constant| constant.is_a?(Module) && !accumulator.values.include?(constant) end.each do |constant_symbol, constant| accumulator[keyword(constant_symbol)] = constant map_descendant_keyword_constants_for(constant, accumulator: accumulator) end accumulator end
TODO consider automatically setting attribute accessors by looking up set_xyz methods on cairo context
# File lib/glimmer/gtk/shape.rb, line 137 def initialize(keyword, parent, args, &block) @keyword = keyword @parent = parent @args = args @block = block post_add_content if @block.nil? end
# File lib/glimmer/gtk/shape.rb, line 108 def one_based_color_rgb(rgb) return rgb if rgb.is_a?(Cairo::Pattern) || rgb.first.is_a?(Cairo::ImageSurface) rgb.each_with_index.map {|single_color, i| i == 3 ? single_color : single_color / 255.0} end
# File lib/glimmer/gtk/shape.rb, line 91 def reset_descendant_keyword_constant_map @descendant_keyword_constant_map = nil descendant_keyword_constant_map end
# File lib/glimmer/gtk/shape.rb, line 113 def set_source_dynamically(cairo_context, source_args) source_args = one_based_color_rgb(source_args) if source_args.is_a?(Cairo::Pattern) || source_args.first.is_a?(Cairo::ImageSurface) cairo_context.set_source(*source_args) elsif source_args.size == 3 cairo_context.set_source_rgb(*source_args) elsif source_args.size == 4 cairo_context.set_source_rgba(*source_args) end end
# File lib/glimmer/gtk/shape.rb, line 75 def shape_class(keyword) descendant_keyword_constant_map[keyword] end
Public Instance Methods
# File lib/glimmer/gtk/shape.rb, line 235 def apply_property(cairo_context, property) if send(property) if property == :font_face cairo_context.send("select_#{property}", *send(property)) else cairo_context.send("set_#{property}", *send(property)) end end end
# File lib/glimmer/gtk/shape.rb, line 159 def content(&block) Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Gtk::ShapeExpression.new, @keyword, &block) end
Subclasses must either implement draw_shape
hook method or override this method directly
# File lib/glimmer/gtk/shape.rb, line 164 def draw(drawing_area_widget, cairo_context) if fill draw_font(drawing_area_widget, cairo_context) draw_shape(drawing_area_widget, cairo_context) draw_fill(drawing_area_widget, cairo_context) end if stroke draw_font(drawing_area_widget, cairo_context) draw_shape(drawing_area_widget, cairo_context) draw_stroke(drawing_area_widget, cairo_context) end if clip draw_font(drawing_area_widget, cairo_context) draw_shape(drawing_area_widget, cairo_context) draw_clip(drawing_area_widget, cairo_context) end end
# File lib/glimmer/gtk/shape.rb, line 225 def draw_clip(drawing_area_widget, cairo_context) previous_matrix = cairo_context.matrix apply_transforms(cairo_context, target: :clip) SHAPE_GENERAL_PROPERTIES.each do |property| apply_property(cairo_context, property) end cairo_context.clip cairo_context.set_matrix(previous_matrix) end
# File lib/glimmer/gtk/shape.rb, line 197 def draw_fill(drawing_area_widget, cairo_context) previous_matrix = cairo_context.matrix apply_transforms(cairo_context, target: :fill) self.class.set_source_dynamically(cairo_context, fill) (SHAPE_GENERAL_PROPERTIES + SHAPE_FILL_PROPERTIES).each do |property| apply_property(cairo_context, property) end cairo_context.fill cairo_context.set_matrix(previous_matrix) end
# File lib/glimmer/gtk/shape.rb, line 208 def draw_font(drawing_area_widget, cairo_context) SHAPE_FONT_PROPERTIES.each do |property| apply_property(cairo_context, property) end end
Invokes cairo_context#underscored_shape_class_name method by default e.g. cairo_context.rectangle(0, 0, 200, 100) for Glimmer::Gtk::Shape::Rectangle
(‘rectangle` keyword)
Subclasses can override
# File lib/glimmer/gtk/shape.rb, line 188 def draw_shape(drawing_area_widget, cairo_context) previous_matrix = cairo_context.matrix apply_transforms(cairo_context, target: :shape) class_symbol = self.class.name.split('::').last keyword = self.class.keyword(class_symbol) cairo_context.send(keyword, *args) cairo_context.set_matrix(previous_matrix) end
# File lib/glimmer/gtk/shape.rb, line 214 def draw_stroke(drawing_area_widget, cairo_context) previous_matrix = cairo_context.matrix apply_transforms(cairo_context, target: :stroke) self.class.set_source_dynamically(cairo_context, stroke) (SHAPE_GENERAL_PROPERTIES + SHAPE_STROKE_PROPERTIES).each do |property| apply_property(cairo_context, property) end cairo_context.stroke cairo_context.set_matrix(previous_matrix) end
# File lib/glimmer/gtk/shape.rb, line 251 def method_missing(method_name, *args, &block) method_name = method_name.to_s if (method_name.start_with?('set_') && respond_to?("#{method_name.sub('set_', '')}=", true)) args = [args] if args.size > 1 send("#{method_name.sub('set_', '')}=", *args, &block) else super(method_name.to_sym, *args, &block) end end
Subclasses may override to perform post add_content work (normally must call super)
# File lib/glimmer/gtk/shape.rb, line 146 def post_add_content @parent&.post_initialize_child(self) end
Subclasses may override to perform post initialization work on an added child (normally must also call super)
# File lib/glimmer/gtk/shape.rb, line 151 def post_initialize_child(child) # No Op for now. In the future, if we support relative-positioning nesting of shapes, this can be used/overridden end
# File lib/glimmer/gtk/shape.rb, line 245 def respond_to?(method_name, include_private = false, &block) method_name = method_name.to_s (method_name.start_with?('set_') && super("#{method_name.sub('set_', '')}=", include_private)) || super(method_name, include_private) end
# File lib/glimmer/gtk/shape.rb, line 155 def window_proxy @parent&.window_proxy end