# Wx::SF::RoundRectShape - rounded rectangle shape class # Copyright (c) M.J.N. Corino, The Netherlands module Wx::SF # Class encapsulating rounded rectangle. It extends the basic rectangular shape. class RoundRectShape < RectShape # Default values module DEFAULT # Default corner radius RADIUS = 20 end property :radius # Constructor. # @param [Wx::RealPoint,Wx::Point] pos Initial position # @param [Wx::RealPoint,Wx::Size,Wx::Point] size Initial size # @param [Float] radius Corner radius # @param [Wx::SF::Diagram] diagram parent diagram def initialize(pos = Shape::DEFAULT::POSITION, size = RectShape::DEFAULT::SIZE, radius: DEFAULT::RADIUS, diagram: nil) super(pos, size, diagram: diagram) @radius = radius end # Access (get/set) radius. attr_accessor :radius # Test whether the given point is inside the shape. The function # can be overridden if necessary. # @param [Wx::Point] pos Examined point # @return [Boolean] true if the point is inside the shape area, otherwise false def contains?(pos) return super if @radius == 0.0 pos = pos.to_point # get original bounding box shp_bb = get_bounding_box # calculate modified boxes hr = shp_bb.deflate(0, @radius.to_i) vr = shp_bb.deflate(@radius.to_i, 0) # test whether given position is inside body rect or rounded corners if hr.contains?(pos) return true elsif vr.contains?(pos) return true elsif in_circle?(pos, shp_bb.top_left + [@radius, @radius.to_i]) return true elsif in_circle?(pos, shp_bb.bottom_left + [@radius.to_i, -@radius.to_i]) return true elsif in_circle?(pos, shp_bb.top_right + [-@radius.to_i, @radius.to_i]) return true elsif in_circle?(pos, shp_bb.bottom_right + [-@radius.to_i, -@radius.to_i]) return true end return false end protected # Draw the shape in the normal way. The function can be overridden if necessary. # @param [Wx::DC] dc Reference to device context where the shape will be drawn to def draw_normal(dc) if @radius == 0.0 super return end dc.with_pen(border) do dc.with_brush(fill) do dc.draw_rounded_rectangle(get_absolute_position.to_point, @rect_size.to_size, @radius) end end end # Draw the shape in the hover mode (the mouse cursor is above the shape). # The function can be overridden if necessary. # @param [Wx::DC] dc Reference to device context where the shape will be drawn to def draw_hover(dc) if @radius == 0.0 super return end dc.with_pen(Wx::Pen.new(hover_colour, 1)) do dc.with_brush(fill) do dc.draw_rounded_rectangle(get_absolute_position.to_point, @rect_size.to_size, @radius) end end end # Draw the shape in the highlighted mode (another shape is dragged over this # shape and this shape will accept the dragged one if it will be dropped on it). # The function can be overridden if necessary. # @param [Wx::DC] dc Reference to device context where the shape will be drawn to def draw_highlighted(dc) if @radius == 0.0 super return end dc.with_pen(Wx::Pen.new(hover_colour, 2)) do dc.with_brush(fill) do dc.draw_rounded_rectangle(get_absolute_position.to_point, @rect_size.to_size, @radius) end end end # Draw shadow under the shape. The function can be overridden if necessary. # @param [Wx::DC] dc Reference to device context where the shadow will be drawn to def draw_shadow(dc) if @radius == 0.0 super return end if fill.style != Wx::BrushStyle::BRUSHSTYLE_TRANSPARENT dc.with_pen(Wx::TRANSPARENT_PEN) do dc.with_brush(get_parent_canvas.get_shadow_fill) do dc.draw_rounded_rectangle((get_absolute_position + get_parent_canvas.get_shadow_offset).to_point, @rect_size.to_size, @radius) end end end end # Auxiliary function. Checks whether the point is inside a circle with given center. The circle's radius # is the rounded rect corner radius. # @param [Wx::Point] pos Examined point # @param [Wx::Point] center Circle center # @return [Boolean] def in_circle?(pos, center) center.to_real_point.distance_to(pos.to_real_point) <= @radius end end end