# -*- indent-tabs-mode: nil -*- class CanvasSamplePrimitives < Gtk::VBox private def item_event(item, event) case event.event_type when Gdk::Event::BUTTON_PRESS item_x, item_y = item.parent.w2i(event.x, event.y) case event.button when 1 if event.state & Gdk::Window::SHIFT_MASK == Gdk::Window::SHIFT_MASK item.destroy() else @x = item_x; @y = item_y; fleur = Gdk::Cursor.new(Gdk::Cursor::FLEUR) item.grab(Gdk::Event::POINTER_MOTION_MASK | Gdk::Event::BUTTON_RELEASE_MASK, fleur, event.time) @dragging = true end when 2 if event.state & Gdk::Window::SHIFT_MASK == Gdk::Window::SHIFT_MASK item.lower_to_bottom() else item.lower(1) end when 3 if event.state & Gdk::Window::SHIFT_MASK == Gdk::Window::SHIFT_MASK item.raise_to_top() else item.raise(1) end end when Gdk::Event::MOTION_NOTIFY item_x, item_y = item.parent.w2i(event.x, event.y) if @dragging && (event.state & Gdk::Window::BUTTON1_MASK == Gdk::Window::BUTTON1_MASK) item.move(item_x - @x, item_y - @y) @x = item_x; @y = item_y; end when Gdk::Event::BUTTON_RELEASE item.ungrab(event.time) @dragging = false; end end def setup_item(item) item.signal_connect("event") do |item, event| item_event(item, event) end end def setup_heading(root, text, pos) Gnome::CanvasText.new(root, {:text => text, :x => (pos % 3) * 200 + 100, :y => (pos / 3) * 150 + 5, :font => "Sans 12", :anchor => Gtk::ANCHOR_N, :fill_color => "black"}) end def setup_divisions(root) group = Gnome::CanvasGroup.new(root, {:x => 0.0, :y => 0.0}) setup_item(group) Gnome::CanvasRect.new(group, {:x1 => 0.0, :y1 => 0.0, :x2 => 600.0, :y2 => 450.0, :outline_color => "black", :width_units => 4.0}) Gnome::CanvasLine.new(group, {:points => [[0.0, 150.0], [600.0, 150.0]], :fill_color => "black", :width_units => 4.0}) Gnome::CanvasLine.new(group, {:points => [[0.0, 300.0], [600.0, 300.0]], :fill_color => "black", :width_units => 4.0}) Gnome::CanvasLine.new(group, {:points => [[200.0, 0.0], [200.0, 450.0]], :fill_color => "black", :width_units => 4.0}) Gnome::CanvasLine.new(group, {:points => [[400.0, 0.0], [400.0, 450.0]], :fill_color => "black", :width_units => 4.0}) setup_heading(group, "Rectangles", 0) setup_heading(group, "Ellipses", 1) setup_heading(group, "Texts", 2) setup_heading(group, "Images", 3) setup_heading(group, "Lines", 4) setup_heading(group, "Curves", 5) setup_heading(group, "Arcs", 6) setup_heading(group, "Polygons", 7) setup_heading(group, "Widgets", 8) end Gray50_Width = 2 Gray50_Height = 2 Gray50_Bits = [0x02, 0x01].pack("CC") def setup_rectangles(root) setup_item(Gnome::CanvasRect.new(root, {:x1 => 20.0, :y1 => 30.0, :x2 => 70.0, :y2 => 60.0, :outline_color => "red", :width_pixels => 8})) if root.canvas.aa? setup_item(Gnome::CanvasRect.new(root, {:x1 => 90.0, :y1 => 40.0, :x2 => 180.0, :y2 => 100.0, :fill_color_rgba => 0x3cb37180, :outline_color => "black", :width_units => 4.0})) else stipple = Gdk::Pixmap.create_from_data(nil, Gray50_Bits, Gray50_Width, Gray50_Height) setup_item(Gnome::CanvasRect.new(root, {:x1 => 90.0, :y1 => 40.0, :x2 => 180.0, :y2 => 100.0, :fill_color => "mediumseagreen", :fill_stipple => stipple, :outline_color => "black", :width_units => 4.0})) end setup_item(Gnome::CanvasRect.new(root, {:x1 => 10.0, :y1 => 80.0, :x2 => 80.0, :y2 => 140.0, :fill_color => "steelblue"})) end def setup_ellipses(root) setup_item(Gnome::CanvasEllipse.new(root, {:x1 => 220.0, :y1 => 30.0, :x2 => 270.0, :y2 => 60.0, :outline_color => "goldenrod", :width_pixels => 8})) setup_item(Gnome::CanvasEllipse.new(root, {:x1 => 290.0, :y1 => 40.0, :x2 => 380.0, :y2 => 100.0, :fill_color => "wheat", :outline_color => "midnightblue", :width_units => 4.0})) if root.canvas.aa? setup_item(Gnome::CanvasEllipse.new(root, {:x1 => 210.0, :y1 => 80.0, :x2 => 280.0, :y2 => 140.0, :fill_color_rgba => 0x5f9ea080, :outline_color => "black", :width_pixels => 0})) else stipple = Gdk::Pixmap.create_from_data(nil, Gray50_Bits, Gray50_Width, Gray50_Height) setup_item(Gnome::CanvasEllipse.new(root, {:x1 => 210.0, :y1 => 80.0, :x2 => 280.0, :y2 => 140.0, :fill_color => "cadetblue", :fill_stipple => stipple, :outline_color => "black", :width_pixels => 0})) end end def make_anchor(root, x, y) group = Gnome::CanvasGroup.new(root, {:x => x, :y => y}) setup_item(group) Gnome::CanvasRect.new(group, {:x1 => -2.0, :y1 => -2.0, :x2 => 2.0, :y2 => 2.0, :outline_color => "black", :width_pixels => 1}) group end def setup_texts(root) if root.canvas.aa? Gnome::CanvasText.new(make_anchor(root, 420.0, 20.0), {:text => "Anchor NW", :x => 0.0, :y => 0.0, :font => "Sans Bold 24", :anchor => Gtk::ANCHOR_NW, :fill_color_rgba => 0x0000ff80}) else stipple = Gdk::Pixmap.create_from_data(nil, Gray50_Bits, Gray50_Width, Gray50_Height) Gnome::CanvasText.new(make_anchor(root, 420.0, 20.0), {:text => "Anchor NW", :x => 0.0, :y => 0.0, :font => "Sans Bold 24", :anchor => Gtk::ANCHOR_NW, :fill_color => "blue", :fill_stipple => stipple}) end Gnome::CanvasText.new(make_anchor(root, 470.0, 75.0), {:text => "Anchor center\nJustify center\nMultiline text", :x => 0.0, :y => 0.0, :font => "monospace bold 14", :anchor => Gtk::ANCHOR_CENTER, :justification => Gtk::JUSTIFY_CENTER, :fill_color => "firebrick"}) Gnome::CanvasText.new(make_anchor(root, 590.0, 140.0), {:text => "Clipped text\nClipped text\nClipped text\nClipped text\nClipped text\nClipped text", :x => 0.0, :y => 0.0, :font => "Sans 12", :anchor => Gtk::ANCHOR_SE, :clip => true, :clip_width => 50.0, :clip_height => 55.0, :x_offset => 10.0, :fill_color => "darkgreen"}) end def plant_flower(root, x, y, anchor, aa) im = Gdk::Pixbuf.new("flower.png") unless im.nil? image = Gnome::CanvasPixbuf.new(root, :pixbuf => im, :x => x, :y => y, :width => im.width, :height => im.height, :anchor => anchor) setup_item(image) image.signal_connect("destroy", im) do |item, im| end end end def setup_images(root, aa) im = Gdk::Pixbuf.new("toroid.png") unless im.nil? image = Gnome::CanvasPixbuf.new(root, {:pixbuf => im, :x => 100.0, :y => 225.0, :width => im.width, :height => im.height, :anchor => Gtk::ANCHOR_CENTER}) setup_item(image) image.signal_connect("destroy", im) do |item, im| end end plant_flower(root, 20.0, 170.0, Gtk::ANCHOR_NW, aa); plant_flower(root, 180.0, 170.0, Gtk::ANCHOR_NE, aa); plant_flower(root, 20.0, 280.0, Gtk::ANCHOR_SW, aa); plant_flower(root, 180.0, 280.0, Gtk::ANCHOR_SE, aa); end VERTICES = 10 RADIUS = 60.0 def polish_diamond(root) group = Gnome::CanvasGroup.new(root, {:x => 270.0, :y => 230.0}) setup_item(group) points = [] 0.upto(VERTICES - 1) do |i| a = 2.0 * Math::PI * i / VERTICES points[0] = [RADIUS * Math::cos(a), RADIUS * Math::sin(a)] (i + 1).upto(VERTICES - 1) do |j| a = 2.0 * Math::PI * j / VERTICES points[1] = [RADIUS * Math::cos(a), RADIUS * Math::sin(a)] Gnome::CanvasLine.new(group, {:points => points, :fill_color => "black", :width_units => 1.0, :cap_style => Gdk::GC::CAP_ROUND}) end end end SCALE = 7.0 def make_hilbert(root) hilbert = "urdrrulurulldluuruluurdrurddldrrruluurdrurddldrddlulldrdldrrurd" points = [] points << [340.0, 290.0] hilbert.split(//).each_with_index do |c, i| case c when 'u' points << [points.last[0], points.last[1] - SCALE] when 'd' points << [points.last[0], points.last[1] + SCALE] when 'l' points << [points.last[0] - SCALE, points.last[1]] when 'r' points << [points.last[0] + SCALE, points.last[1]] end end if root.canvas.aa? setup_item(Gnome::CanvasLine.new(root, {:points => points, :fill_color_rgba => 0xff000080, :width_units => 4.0, :cap_style => Gdk::GC::CAP_PROJECTING, :join_style => Gdk::GC::JOIN_MITER})) else stipple = Gdk::Pixmap.create_from_data(nil, Gray50_Bits, Gray50_Width, Gray50_Height) setup_item(Gnome::CanvasLine.new(root, {:points => points, :fill_color => "red", :fill_stipple => stipple, :width_units => 4.0, :cap_style => Gdk::GC::CAP_PROJECTING, :join_style => Gdk::GC::JOIN_MITER})) end end def setup_lines(root) polish_diamond(root) make_hilbert(root) # Arrow tests points = [[340.0, 170.0], [340.0, 230.0], [390.0, 230.0], [390.0, 170.0]] setup_item(Gnome::CanvasLine.new(root, {:points => points, :fill_color => "midnightblue", :width_units => 3.0, :first_arrowhead => true, :last_arrowhead => true, :arrow_shape_a => 8.0, :arrow_shape_b => 12.0, :arrow_shape_c => 4.0})) points = [[356.0, 180.0], [374.0, 220.0]] setup_item(Gnome::CanvasLine.new(root, {:points => points, :fill_color => "blue", :width_pixels => 0, :first_arrowhead => true, :last_arrowhead => true, :arrow_shape_a => 6.0, :arrow_shape_b => 6.0, :arrow_shape_c => 4.0})) points = [[356.0, 220.0], [374.0, 180.0]] setup_item(Gnome::CanvasLine.new(root, {:points => points, :fill_color => "blue", :width_pixels => 0, :first_arrowhead => true, :last_arrowhead => true, :arrow_shape_a => 6.0, :arrow_shape_b => 6.0, :arrow_shape_c => 4.0})) end def setup_curves(root) path_def = Gnome::CanvasPathDef.new() path_def.moveto(500.0, 175.0) path_def.curveto(550.0, 175.0, 550.0, 275.0, 500.0, 275.0) setup_item(Gnome::CanvasBpath.new(root, {:bpath => path_def, :outline_color => "black", :width_pixels => 4})) end def setup_polygons(root) points = [[210.0, 320.0], [210.0, 380.0], [260.0, 350.0]] if root.canvas.aa? setup_item(Gnome::CanvasPolygon.new(root, {:points => points, :fill_color_rgba => 0x0000ff80, :outline_color => "black"})) else stipple = Gdk::Pixmap.create_from_data(nil, Gray50_Bits, Gray50_Width, Gray50_Height) setup_item(Gnome::CanvasPolygon.new(root, {:points => points, :fill_color => "blue", :fill_stipple => stipple, :outline_color => "black"})) end points = [] points << [270.0, 330.0] points << [270.0, 430.0] points << [390.0, 430.0] points << [390.0, 330.0] points << [310.0, 330.0] points << [310.0, 390.0] points << [350.0, 390.0] points << [350.0, 370.0] points << [330.0, 370.0] points << [330.0, 350.0] points << [370.0, 350.0] points << [370.0, 410.0] points << [290.0, 410.0] points << [290.0, 330.0] setup_item(Gnome::CanvasPolygon.new(root, {:points => points, :fill_color => "tan", :outline_color => "black", :width_units => 3.0})) end def setup_widgets(root) w = Gtk::Button.new("Hello world!") setup_item(Gnome::CanvasWidget.new(root, {:widget => w, :x => 420.0, :y => 330.0, :width => 100.0, :height => 40.0, :anchor => Gtk::ANCHOR_NW, :size_pixels => FALSE})) w.show() end def key_press(canvas, event) x, y = canvas.scroll_offsets case event.keyval when Gdk::Keyval::GDK_Up canvas.scroll_to(x, y - 20) when Gdk::Keyval::GDK_Down canvas.scroll_to(x, y + 20) when Gdk::Keyval::GDK_Left canvas.scroll_to(x - 10, y) when Gdk::Keyval::GDK_Right canvas.scroll_to(x + 10, y) end end def initialize(aa) super(false, 4) @dragging = false border_width = 4 show() w = Gtk::Label.new(<<EOS) Drag an item with button 1. Click button 2 on an item to lower it, or button 3 to raise it. Shift+click with buttons 2 or 3 to send an item to the bottom or top, respectively. EOS pack_start(w, false, false, 0) w.show() hbox = Gtk::HBox.new(false, 4) pack_start(hbox, false, false, 0) hbox.show() # Create the canvas canvas = Gnome::Canvas.new(aa) # Setup canvas items root = canvas.root setup_divisions(root) setup_rectangles(root) setup_ellipses(root) setup_texts(root) setup_images(root, aa) setup_lines(root) setup_curves(root) setup_polygons(root) setup_widgets(root) # Zoom w = Gtk::Label.new("Zoom:") hbox.pack_start(w, false, false, 0) w.show() adj = Gtk::Adjustment.new(1.00, 0.05, 5.00, 0.05, 0.50, 0.50) adj.signal_connect("value_changed") do canvas.set_pixels_per_unit(adj.value) end w = Gtk::SpinButton.new(adj, 0.0, 2) w.set_size_request(50, -1) hbox.pack_start(w, false, false, 0) w.show() # Layout the stuff table = Gtk::Table.new(2, 2, false) table.set_row_spacings(4) table.set_column_spacings(4) pack_start(table, true, true, 0) table.show() frame = Gtk::Frame.new() frame.set_shadow_type(Gtk::SHADOW_IN); table.attach(frame, 0, 1, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, 0, 0) frame.show() canvas.set_size_request(600, 450) canvas.set_scroll_region(0, 0, 600, 450); frame.add(canvas) canvas.show() canvas.signal_connect_after("key_press_event") do |item, event| key_press(item, event) end w = Gtk::HScrollbar.new(canvas.hadjustment) table.attach(w, 0, 1, 1, 2, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::FILL, 0, 0); w.show() w = Gtk::VScrollbar.new(canvas.vadjustment) table.attach(w, 1, 2, 0, 1, Gtk::FILL, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, 0, 0); w.show() canvas.flags = Gtk::Widget::CAN_FOCUS canvas.grab_focus() end end