[Fxruby-commits] CVS: FXRuby/lib/fox canvas.rb,NONE,1.1.2.1
Status: Inactive
Brought to you by:
lyle
From: Lyle J. <ly...@us...> - 2002-05-24 23:03:18
|
Update of /cvsroot/fxruby/FXRuby/lib/fox In directory usw-pr-cvs1:/tmp/cvs-serv23945/lib/fox Added Files: Tag: release10 canvas.rb Log Message: --- NEW FILE: canvas.rb --- require 'fox' include Fox # # The Canvas module defines a framework similar to that provided by Tk's Canvas # widget (and subsequent improvements, such as GNOME's Canvas and wxWindows' # Object Graphics Library). # # Links # ===== # # Tk's Canvas Widget # http://starship.python.net/crew/fredrik/tkmanual/canvas.html # http://www.dci.clrc.ac.uk/Publications/Cookbook/chap4.html # # GNOME's Canvas Widget # http://developer.gnome.org/doc/whitepapers/canvas/canvas.html # module Canvas class Shape attr_accessor :x, :y, :foreground, :target, :selector def initialize(x, y) @visible = true @selected = false @draggable = false @x = x @y = y @foreground = FXRGB(0, 0, 0) @target = nil @selector = 0 end # Return the bounding box for this shape def bounds FXRectangle.new(x, y, width, height) end # Hit test def hit?(xpos, ypos) (xpos >= x) && (xpos < x+width) && (ypos >= y) && (ypos < y+height) end # Move shape to specified position def move(x, y) @x, @y = x, y end # Resize shape to specified width and height def resize(w, h) end # Move and resize the shape def position(x, y, w, h) move(x, y) resize(w, h) end # Set the visibility of this shape def visible=(visible) @visible = visible end # Is this shape visible? def visible? @visible end # Select this shape def select @selected = true end # Deselect this shape def deselect @selected = false end # Is this shape selected? def selected? @selected end # Set this shape's draggability def draggable=(d) @draggable = d end # Is this shape draggable? def draggable? @draggable end # Draw this shape into the specificed device context def draw(dc) end end class ShapeGroup include Enumerable def initialize @shapes = [] end # Add a shape to this group def addShape(shape) @shapes << shape end # Remove a shape from this group def removeShape(shape) @shapes.remove(shape) end def each @shapes.each { |shape| yield shape } end def reverse_each @shapes.reverse_each { |shape| yield shape } end end class LineShape < Shape attr_accessor :lineWidth, :lineCap, :lineJoin, :lineStyle attr_accessor :x1, :y1, :x2, :y2 def initialize(x1, y1, x2, y2) super(x1, y1) @x1, @y1, @x2, @y2 = x1, y1, x2, y2 @lineWidth = 1 @lineCap = CAP_NOT_LAST @lineJoin = JOIN_MITER @lineStyle = LINE_SOLID end def width 0 end def height 0 end def draw(dc) # Save old values oldForeground = dc.foreground oldLineWidth = dc.lineWidth oldLineCap = dc.lineCap oldLineJoin = dc.lineJoin oldLineStyle = dc.lineStyle # Set properties for this line dc.foreground = foreground dc.lineWidth = lineWidth dc.lineCap = lineCap dc.lineJoin = lineJoin dc.lineStyle = lineStyle # Draw the line dc.drawLine(x1, y1, x2, y2) # Restore old properties dc.lineWidth = oldLineWidth dc.lineCap = oldLineCap dc.lineJoin = oldLineJoin dc.lineStyle = oldLineStyle dc.foreground = oldForeground end end class RectangleShape < Shape attr_accessor :width, :height def initialize(x, y, w, h) super(x, y) @width = w @height = h end def draw(dc) oldForeground = dc.foreground dc.foreground = foreground dc.drawRectangle(x, y, width, height) dc.foreground = oldForeground end end class TextShape < RectangleShape attr_reader :font, :text def initialize(x, y, w, h, text=nil) super(x, y, w, h) @text = text @font = FXApp.instance.normalFont end def draw(dc) super(dc) oldForeground = dc.foreground oldTextFont = dc.textFont dc.textFont = @font dc.drawImageText(x, y, text) dc.textFont = oldTextFont if oldTextFont dc.foreground = oldForeground end end class CircleShape < Shape attr_accessor :radius def initialize(x, y, radius) super(x, y) @radius = radius end def width 2*radius end def height 2*radius end def draw(dc) oldForeground = dc.foreground oldLineWidth = dc.lineWidth dc.foreground = foreground dc.lineWidth = 5 if selected? dc.drawArc(x, y, width, height, 0, 64*180) dc.drawArc(x, y, width, height, 64*180, 64*360) dc.foreground = oldForeground dc.lineWidth = oldLineWidth end end class PolygonShape < Shape end class ImageShape < Shape attr_accessor :image def initialize(x, y, image) @image = image end def draw(dc) dc.drawImage(image) end end class ShapeCanvas < FXCanvas attr_accessor :scene def initialize(p, tgt=nil, sel=0, opts=FRAME_NORMAL, x=0, y=0, w=0, h=0) # Initialize base class super(p, tgt, sel, opts, x, y, w, h) # Start with an empty group @scene = ShapeGroup.new # Handle paint message self.connect(SEL_PAINT, method(:onPaint)) self.connect(SEL_LEFTBUTTONPRESS, method(:onLeftBtnPress)) self.connect(SEL_LEFTBUTTONRELEASE, method(:onLeftBtnRelease)) end # Find the shape of the least depth containing this point def findShape(x, y) @scene.reverse_each do |shape| return shape if shape.hit?(x, y) end end # Paint def onPaint(sender, sel, evt) dc = FXDCWindow.new(sender, evt) dc.foreground = sender.backColor dc.fillRectangle(evt.rect.x, evt.rect.y, evt.rect.w, evt.rect.h) @scene.each do |shape| shape.draw(dc) end dc.end return 1 end # Left button press def onLeftBtnPress(sender, sel, evt) return 1 end # Left button release def onLeftBtnRelease(sender, sel, evt) # First deselect every object in the scene @scene.each { |shape| shape.deselect } # Now select the object at the lowest depth shape = findShape(evt.win_x, evt.win_y) shape.select unless shape.nil? # Repaint update end end end |