# label msg = TkLabel.new($goldberg_demo) {

font 'Arial 10'
wraplength '4i'
justify 'left'
text "This is a demonstration of just how complex you can make your animations become. Click the ball to start things moving!\n\n\"Man will always find a difficult means to perform a simple task\"\n - Rube Goldberg"

} msg.pack('side'=>'top')

# frame TkFrame.new($goldberg_demo) {|frame|

TkButton.new(frame) {
  text 'Dismiss'
  command proc{
    tmppath = $goldberg_demo
    $goldberg_demo = nil
    tmppath.destroy
  }
}.pack('side'=>'left', 'expand'=>'yes')

TkButton.new(frame) {
  text 'See Code'
  command proc{showCode 'goldberg'}
}.pack('side'=>'left', 'expand'=>'yes')

}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')

#########################################

# label msg = TkLabel.new($goldberg_demo) {

font 'Arial 10'
wraplength '4i'
justify 'left'
text "これは、あなたが自分のアニメーションをいかに入り組んだものにできるかを示すというだけのためのデモです。ボールをクリックすれば物が動き始めます!\n\n\"Man will always find a difficult means to perform a simple task\"\n - Rube Goldberg"

} msg.pack('side'=>'top')

# frame TkFrame.new($goldberg_demo) {|frame|

TkButton.new(frame) {
  text '閉じる'
  command proc{
    tmppath = $goldberg_demo
    $goldberg_demo = nil
    tmppath.destroy
  }
}.pack('side'=>'left', 'expand'=>'yes')

TkButton.new(frame) {
  text 'コード参照'
  command proc{showCode 'goldberg'}
}.pack('side'=>'left', 'expand'=>'yes')

}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')

#########################################

Methods
#
A
B
C
D
G
H
M
N
R
S
Class Public methods
new(parent)
# File ext/tk/sample/demos-en/goldberg.rb, line 93
def initialize(parent)
  @parent = parent

  @S = {}
  @S['title']   = 'Tk Goldberg'
  @S['speed']   = TkVariable.new(5)
  @S['cnt']     = TkVariable.new(0)
  @S['message'] = TkVariable.new("\\nWelcome\\nto\\nRuby/Tk")
  @S['pause']   = TkVariable.new
  @S['details'] = TkVariable.new(true)

  @S['mode'] = TkVariable.new(:MSTART, :symbol)
  #            :MSTART, :MGO, :MPAUSE, :MSSTEP, :MBSTEP, :MDONE, :MDEBUG

  #         0,  1,  2,  3,  4,  5,   6,   7,   8,   9,  10
  @speed = [1, 10, 20, 50, 80, 100, 150, 200, 300, 400, 500]

  # colors
  @C = {}
  @C['fg'] = 'black'
  # @C['bg'] = 'gray75'
  @C['bg'] = 'cornflowerblue'

  @C['0'] = 'white';         @C['1a'] = 'darkgreen';   @C['1b'] = 'yellow'
  @C['2'] = 'red';           @C['3a'] = 'green';       @C['3b'] = 'darkblue'
  @C['4'] = @C['fg'];        @C['5a'] = 'brown';       @C['5b'] = 'white'
  @C['6'] = 'magenta';       @C['7'] = 'green';        @C['8'] = @C['fg']
  @C['9'] = 'blue4';         @C['10a'] = 'white';      @C['10b'] = 'cyan'
  @C['11a'] = 'yellow';      @C['11b'] = 'mediumblue'; @C['12'] = 'tan2'
  @C['13a'] = 'yellow';      @C['13b'] = 'red';        @C['14'] = 'white'
  @C['15a'] = 'green';       @C['15b'] = 'yellow';     @C['16'] = 'gray65'
  @C['17'] = '#A65353';     @C['18'] = @C['fg'];      @C['19'] = 'gray50'
  @C['20'] = 'cyan';         @C['21'] = 'gray65';      @C['22'] = @C['20']
  @C['23a'] = 'blue';        @C['23b'] = 'red';        @C['23c'] = 'yellow'
  @C['24a'] = 'red';         @C['24b'] = 'white';

  @STEP = TkVariable.new_hash
  @STEP.default_value_type = :numeric

  @XY = {}

  @XY6 = {
    '-1'=>[366, 207], '-2'=>[349, 204], '-3'=>[359, 193], '-4'=>[375, 192],
    '-5'=>[340, 190], '-6'=>[349, 177], '-7'=>[366, 177], '-8'=>[380, 176],
    '-9'=>[332, 172], '-10'=>[342, 161], '-11'=>[357, 164],
    '-12'=>[372, 163], '-13'=>[381, 149], '-14'=>[364, 151],
    '-15'=>[349, 146], '-16'=>[333, 148], '0'=>[357, 219],
    '1'=>[359, 261], '2'=>[359, 291], '3'=>[359, 318], '4'=>[361, 324],
    '5'=>[365, 329], '6'=>[367, 334], '7'=>[367, 340], '8'=>[366, 346],
    '9'=>[364, 350], '10'=>[361, 355], '11'=>[359, 370], '12'=>[359, 391],
    '13,0'=>[360, 456], '13,1'=>[376, 456], '13,2'=>[346, 456],
    '13,3'=>[330, 456], '13,4'=>[353, 444], '13,5'=>[368, 443],
    '13,6'=>[339, 442], '13,7'=>[359, 431], '13,8'=>[380, 437],
    '13,9'=>[345, 428], '13,10'=>[328, 434], '13,11'=>[373, 424],
    '13,12'=>[331, 420], '13,13'=>[360, 417], '13,14'=>[345, 412],
    '13,15'=>[376, 410], '13,16'=>[360, 403]
  }

  @timer = TkTimer.new(@speed[@S['speed'].numeric]){|timer|
    timer.set_interval(go)
  }

  do_display
  reset

  # Start everything going
  @timer.start
end
Instance Public methods
_round_poly2(x0, y0, x1, y1, x2, y2, radius)
# File ext/tk/sample/demos-en/goldberg.rb, line 1941
def _round_poly2(x0, y0, x1, y1, x2, y2, radius)
  d = 2 * radius
  maxr = 0.75

  v1x = x0 - x1
  v1y = y0 - y1
  v2x = x2 - x1
  v2y = y2 - y1

  vlen1 = Math.sqrt(v1x*v1x + v1y*v1y)
  vlen2 = Math.sqrt(v2x*v2x + v2y*v2y)

  if d > maxr * vlen1
    d = maxr * vlen1
  end
  if d > maxr * vlen2
    d = maxr * vlen2
  end

  xy = []
  xy << (x1 + d * v1x / vlen1) << (y1 + d * v1y / vlen1)
  xy << x1 << y1
  xy << (x1 + d * v2x / vlen2) << (y1 + d * v2y / vlen2)

  return xy
end
about()
# File ext/tk/sample/demos-en/goldberg.rb, line 402
def about
  msg = "Ruby/Tk Version ::\nby Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n\n"
  msg += "Original Version ::\n"
  msg += "#{@S['title']}\nby Keith Vetter, March 2003\n(Reproduced by kind permission of the author)\n\n"
  msg += "Man will always find a difficult means to perform a simple task"
  msg += "\nRube Goldberg"
  Tk.messageBox(:message=>msg, :title=>'About')
end
active_GUI(var1, var2, op)
# File ext/tk/sample/demos-en/goldberg.rb, line 315
def active_GUI(var1, var2, op)
  st = {false=>:disabled, true=>:normal}

  m = @S['mode'].to_sym
  @S['pause'].value = (m == :MPAUSE)
  @start.state(st[m != :MGO])
  @pause.state(st[m != :MSTART && m != :MDONE])
  @step.state(st[m != :MGO && m != :MDONE])
  @bstep.state(st[m != :MGO && m != :MDONE])
  @reset.state(st[m != :MSTART])

  if @S['details'].bool
    Tk.grid(@f_details, :in=>@details, :row=>2, :sticky=>:ew)
  else
    Tk.grid_forget(@f_details)
  end
  @speed_scale.label("Speed: #{@S['speed'].value}")
end
anchor(item, where)
# File ext/tk/sample/demos-en/goldberg.rb, line 1984
def anchor(item, where)
  x1, y1, x2, y2 = @canvas.bbox(item)
  case(where)
  when :n
    y = y1
  when :s
    y = y2
  else
    y = (y1 + y2) / 2.0
  end
  case(where)
  when :w
    x = x1
  when :e
    x = x2
  else
    x = (x1 + x2) / 2.0
  end
  return [x, y]
end
box(x, y, r)

Helper functions

# File ext/tk/sample/demos-en/goldberg.rb, line 1807
def box(x, y, r)
  [x - r, y - r, x + r, y + r]
end
centroid(item)
# File ext/tk/sample/demos-en/goldberg.rb, line 1980
def centroid(item)
  anchor(item, :c)
end
do_button(what)
# File ext/tk/sample/demos-en/goldberg.rb, line 338
def do_button(what)
  case what
  when 0  # Start
    reset if @S['mode'].to_sym == :MDONE
    @S['mode'].value = :MGO

  when 1  # Pause
    @S['mode'].value = ((@S['pause'].bool)? :MPAUSE: :MGO)

  when 2  # Step
    @S['mode'].value = :MSSTEP

  when 3  # Reset
    reset

  when 4  # Big step
    @S['mode'].value = :MBSTEP
  end
end
do_ctrl_frame()
# File ext/tk/sample/demos-en/goldberg.rb, line 216
def do_ctrl_frame
  @start = Tk::Button.new(@parent, :text=>'Start', :bd=>6,
                        :command=>proc{do_button(0)})
  if font = @start['font']
    @start.font(font.weight('bold'))
  end

  @pause = TkCheckbutton.new(@parent, :text=>'Pause', :font=>font,
                             :command=>proc{do_button(1)}, :relief=>:raised,
                             :variable=>@S['pause'])

  @step  = TkButton.new(@parent, :text=>'Single Step', :font=>font,
                        :command=>proc{do_button(2)})
  @bstep = TkButton.new(@parent, :text=>'Big Step', :font=>font,
                        :command=>proc{do_button(4)})
  @reset = TkButton.new(@parent, :text=>'Reset', :font=>font,
                        :command=>proc{do_button(3)})

  @details = TkFrame.new(@parent, :bd=>2, :relief=>:ridge)
  @detail = TkCheckbutton.new(@parent, :text=>'Details', :font=>font,
                             :relief=>:raised, :variable=>@S['details'])

  @msg_entry = TkEntry.new(@parent, :textvariable=>@S['message'],
                           :justify=>:center)
  @speed_scale = TkScale.new(@parent, :orient=>:horizontal,
                             :from=>1, :to=>10, :font=>font,
                             :variable=>@S['speed'], :bd=>2,
                             :relief=>:ridge, :showvalue=>false)
  @about = TkButton.new(@parent, :text=>'About',
                        :command=>proc{about}, :font=>font)

  Tk.grid(@start, :in=>@ctrl, :row=>0, :sticky=>:ew)
  @ctrl.grid_rowconfigure(1, :minsize=>10)
  Tk.grid(@pause, :in=>@ctrl, :row=>2, :sticky=>:ew)
  Tk.grid(@step,  :in=>@ctrl, :sticky=>:ew)
  Tk.grid(@bstep, :in=>@ctrl, :sticky=>:ew)
  Tk.grid(@reset, :in=>@ctrl, :sticky=>:ew)
  @ctrl.grid_rowconfigure(10, :minsize=>20)
  Tk.grid(@details, :in=>@ctrl, :row=>11, :sticky=>:ew)
  Tk.grid(@detail, :in=>@details, :row=>0, :sticky=>:ew)
  @ctrl.grid_rowconfigure(50, :weight=>1)

  @S['mode'].trace('w', proc{|*args| active_GUI(*args)})
  @S['details'].trace('w', proc{|*args| active_GUI(*args)})
  @S['speed'].trace('w', proc{|*args| active_GUI(*args)})

  Tk.grid(@msg_entry, :in=>@ctrl, :row=>98, :sticky=>:ew, :pady=>5)
  Tk.grid(@speed_scale, :in=>@ctrl, :row=>99, :sticky=>:ew)
  Tk.grid(@about, :in=>@ctrl, :row=>100, :sticky=>:ew)

  @reset.bind('3'){@S['mode'].value = -1}  # Debugging
end
do_detail_frame()
# File ext/tk/sample/demos-en/goldberg.rb, line 269
def do_detail_frame
  @f_details = TkFrame.new(@details)

  @label = TkLabel.new(@f_details, :textvariable=>@S['cnt'],
                       :bd=>1, :relief=>:solid, :bg=>'white')
  Tk.grid(@label, '-', '-', '-', :sticky=>:ew, :row=>0)

  idx = 1
  loop {
    break unless respond_to?("move#{idx}")
    l = TkLabel.new(@f_details, :text=>idx, :anchor=>:e,
                    :width=>2, :bd=>1, :relief=>:solid, :bg=>'white')
    @STEP[idx] = 0
    ll = TkLabel.new(@f_details, :textvariable=>@STEP.ref(idx),
                     :width=>5, :bd=>1, :relief=>:solid, :bg=>'white')
    row = (idx + 1)/2
    col = ((idx + 1) & 1) * 2
    Tk.grid(l, :sticky=>:ew, :row=>row, :column=>col)
    Tk.grid(ll, :sticky=>:ew, :row=>row, :column=>(col + 1))
    idx += 1
  }
  @f_details.grid_columnconfigure(1, :weight=>1)
end
do_display()
# File ext/tk/sample/demos-en/goldberg.rb, line 162
def do_display()
  @ctrl = TkFrame.new(@parent, :relief=>:ridge, :bd=>2, :padx=>5, :pady=>5)
  @screen = TkFrame.new(@parent, :bd=>2,
                       :relief=>:raised).pack(:side=>:left, :fill=>:both,
                                              :expand=>true)

  @canvas = TkCanvas.new(@parent, :width=>850, :height=>700,
                        :bg=>@C['bg'], :highlightthickness=>0){
    scrollregion([0, 0, 1000, 1000]) # Kludge to move everything up
    yview_moveto(0.05)
  }.pack(:in=>@screen, :side=>:top, :fill=>:both, :expand=>true)

  @canvas.bind('3'){ @pause.invoke }
  @canvas.bind('Destroy'){ @timer.stop }

  do_ctrl_frame
  do_detail_frame

  # msg = TkLabel.new(@parent, :bg=>@C['bg'], :fg=>'white') {
  msg = Tk::Label.new(@parent, :bg=>@C['bg'], :fg=>'white') {
    font 'Arial 10'
    wraplength 600
    justify 'left'
    text "This is a demonstration of just how complex you can make your animations become. Click the ball to start things moving!\n\"Man will always find a difficult means to perform a simple task\" - Rube Goldberg"
  }
  msg.place(:in=>@canvas, :relx=>0, :rely=>0, :anchor=>:nw)

  frame = TkFrame.new(@parent, :bg=>@C['bg'])

  # TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) {
  Tk::Button.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) {
    text 'Dismiss'
    command proc{
      tmppath = $goldberg_demo
      $goldberg_demo = nil
      tmppath.destroy
    }
  }.pack('side'=>'left')

  # TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) {
  Tk::Button.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) {
    text 'See Code'
    command proc{showCode 'goldberg'}
  }.pack('side'=>'left', 'padx'=>5)

  # @show = TkButton.new(frame, :text=>'>>', :command=>proc{show_ctrl},
  @show = Tk::Button.new(frame, :text=>'>>', :command=>proc{show_ctrl},
                       :bg=>@C['bg'], :activebackground=>@C['bg'])
  @show.pack('side'=>'left')
  frame.place(:in=>@canvas, :relx=>1, :rely=>0, :anchor=>:ne)

  Tk.update
end
draw0()

START HERE! banner

# File ext/tk/sample/demos-en/goldberg.rb, line 417
def draw0
  color = @C['0']
  TkcText.new(@canvas, [579, 119], :text=>'START HERE!',
              :fill=>color, :anchor=>:w,
              :tag=>'I0', :font=>['Times Roman', 12, :italic, :bold])
  TkcLine.new(@canvas, [719, 119, 763, 119], :tag=>'I0', :fill=>color,
              :width=>5, :arrow=>:last, :arrowshape=>[18, 18, 5])
  @canvas.itembind('I0', '1'){ start }
end
draw1()

Dropping ball

# File ext/tk/sample/demos-en/goldberg.rb, line 445
def draw1
  color = @C['1a']
  color2 = @C['1b']
  TkcPolygon.new(@canvas,
                 [ 844, 133, 800, 133, 800, 346, 820, 346,
                   820, 168, 844, 168, 844, 133 ],
                 :width=>3, :fill=>color, :outline=>'')
  TkcPolygon.new(@canvas,
                 [ 771, 133, 685, 133, 685, 168, 751, 168,
                   751, 346, 771, 346, 771, 133 ],
                 :width=>3, :fill=>color, :outline=>'')
  TkcOval.new(@canvas, box(812, 122, 9),
              :tag=>'I1', :fill=>color2, :outline=>'')

  @canvas.itembind('I1', '1'){ start }
end
draw10()

Boat

# File ext/tk/sample/demos-en/goldberg.rb, line 957
def draw10
  color  = @C['10a']
  color2 = @C['10b']
  xy = [191, 230, 233, 230, 233, 178, 191, 178]  # Sail
  TkcPolygon.new(@canvas, xy, :fill=>color, :width=>3, :outline=>@C['fg'],
                 :tag=>'I10')
  xy = box(209, 204, 31)  # Front
  TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :style=>:pie,
             :start=>120, :extent=>120, :tag=>'I10')
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc,
             :start=>120, :extent=>120, :tag=>'I10')
  xy = box(249, 204, 31)  # Back
  TkcArc.new(@canvas, xy, :outline=>'', :fill=>@C['bg'], :width=>3,
             :style=>:pie, :start=>120, :extent=>120, :tag=>'I10')
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc,
             :start=>120, :extent=>120, :tag=>'I10')

  xy = [200, 171, 200, 249]  # Mast
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I10')
  xy = [159, 234, 182, 234]  # Bow sprit
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I10')
  xy = [180, 234, 180, 251, 220, 251]  # Hull
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>6, :tag=>'I10')

  xy = [92, 255, 221, 255]  # Waves
  sine(xy, 2, 25, :fill=>color2, :width=>1, :tag=>'I10w')

  xy = @canvas.coords('I10w')[4..-5]  # Water
  xy.concat([222, 266, 222, 277, 99, 277])
  TkcPolygon.new(@canvas, xy, :fill=>color2, :outline=>color2)
  xy = [222, 266, 222, 277, 97, 277, 97, 266]  # Water bottom
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)

  xy = box(239, 262, 17)
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc,
             :start=>95, :extent=>103)
  xy = box(76, 266, 21)
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc,
             :extent=>190)
end
draw11()

2nd ball drop

# File ext/tk/sample/demos-en/goldberg.rb, line 1018
def draw11
  color  = @C['11a']
  color2 = @C['11b']
  xy = [23, 264, 55, 591]  # Color the down tube
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>'')
  xy = box(71, 460, 48)    # Color the outer loop
  TkcOval.new(@canvas, xy, :fill=>color, :outline=>'')

  xy = [55, 264, 55, 458]  # Top right side
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)
  xy = [55, 504, 55, 591]  # Bottom right side
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)
  xy = box(71, 460, 48)    # Outer loop
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc,
             :start=>110, :extent=>-290, :tag=>'I11i')
  xy = box(71, 460, 16)    # Inner loop
  TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>'',
              :width=>3, :tag=>'I11i')
  TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>@C['bg'], :width=>3)

  xy = [23, 264, 23, 591]  # Left side
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)
  xy = box(1, 266, 23)     # Top left curve
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3,
             :style=>:arc, :extent=>90)

  xy = box(75, 235, 9)     # The ball
  TkcOval.new(@canvas, xy, :fill=>color2, :outline=>'',
              :width=>3, :tag=>'I11')
end
draw12()

Hand

# File ext/tk/sample/demos-en/goldberg.rb, line 1066
def draw12
  xy = [
    20, 637, 20, 617, 20, 610, 20, 590, 40, 590, 40, 590,
    60, 590, 60, 610, 60, 610
  ]
  xy.concat([60, 610, 65, 620, 60, 631])  # Thumb
  xy.concat([60, 631, 60, 637, 60, 662, 60, 669, 52, 669,
              56, 669, 50, 669, 50, 662, 50, 637])

  y0 = 637  # Bumps for fingers
  y1 = 645
  50.step(21, -10){|x|
    x1 = x - 5
    x2 = x - 10
    xy << x << y0 << x1 << y1 << x2 << y0
  }
  TkcPolygon.new(@canvas, xy, :fill=>@C['12'], :outline=>@C['fg'],
                 :smooth=>true, :tag=>'I12', :width=>3)
end
draw13()

Fax

# File ext/tk/sample/demos-en/goldberg.rb, line 1098
def draw13
  color = @C['13a']
  xy = [86, 663, 149, 663, 149, 704, 50, 704, 50, 681, 64, 681, 86, 671]
  xy2 = [
    784, 663, 721, 663, 721, 704, 820, 704, 820, 681, 806, 681, 784, 671
  ]
  radii = [2, 9, 9, 8, 5, 5, 2]

  round_poly(@canvas, xy, radii, :width=>3,
             :outline=>@C['fg'], :fill=>color)
  round_poly(@canvas, xy2, radii, :width=>3,
             :outline=>@C['fg'], :fill=>color)

  xy = [56, 677]
  x, y = xy
  TkcRectangle.new(@canvas, box(x, y, 4), :fill=>'', :outline=>@C['fg'],
                   :width=>3, :tag=>'I13')
  xy = [809, 677]
  x, y = xy
  TkcRectangle.new(@canvas, box(x, y, 4), :fill=>'', :outline=>@C['fg'],
                   :width=>3, :tag=>'I13R')

  xy = [112, 687]  # Label
  TkcText.new(@canvas, xy, :text=>'FAX', :fill=>@C['fg'],
              :font=>['Times Roman', 12, :bold])
  xy = [762, 687]
  TkcText.new(@canvas, xy, :text=>'FAX', :fill=>@C['fg'],
              :font=>['Times Roman', 12, :bold])

  xy = [138, 663, 148, 636, 178, 636]  # Paper guide
  TkcLine.new(@canvas, xy, :smooth=>true, :fill=>@C['fg'], :width=>3)
  xy = [732, 663, 722, 636, 692, 636]
  TkcLine.new(@canvas, xy, :smooth=>true, :fill=>@C['fg'], :width=>3)

  sine([149, 688, 720, 688], 5, 15,
       :tag=>'I13_s', :fill=>@C['fg'],  :width=>3)
end
draw14()

Paper in fax

# File ext/tk/sample/demos-en/goldberg.rb, line 1159
def draw14
  color = @C['14']
  xy = [102, 661, 113, 632, 130, 618]  # Left paper edge
  TkcLine.new(@canvas, xy, :smooth=>true, :fill=>color,
              :width=>3, :tag=>'I14L_0')
  xy = [148, 629, 125, 640, 124, 662]  # Right paper edge
  TkcLine.new(@canvas, xy, :smooth=>true, :fill=>color,
              :width=>3, :tag=>'I14L_1')
  draw14a('L')

  xy = [
    768.0, 662.5, 767.991316225, 662.433786215, 767.926187912, 662.396880171
  ]
  TkcLine.new(@canvas, xy, :smooth=>true, :fill=>color,
              :width=>3, :tag=>'I14R_0')
  @canvas.lower('I14R_0')
  # NB. these numbers are VERY sensitive, you must start with final size
  # and shrink down to get the values
  xy = [
    745.947897349, 662.428358855, 745.997829056, 662.452239237, 746.0, 662.5
  ]
  TkcLine.new(@canvas, xy, :smooth=>true, :fill=>color,
              :width=>3, :tag=>'I14R_1')
  @canvas.lower('I14R_1')
end
draw14a(side)
# File ext/tk/sample/demos-en/goldberg.rb, line 1185
def draw14a(side)
  color = @C['14']
  xy = @canvas.coords("I14#{side}_0")
  xy2 = @canvas.coords("I14#{side}_1")
  x0, y0, x1, y1, x2, y2 = xy
  x3, y3, x4, y4, x5, y5 = xy2

  zz = [
    x0, y0, x0, y0, xy, x2, y2, x2, y2,
    x3, y3, x3, y3, xy2, x5, y5, x5, y5
  ].flatten
  @canvas.delete("I14#{side}")
  TkcPolygon.new(@canvas, zz, :tag=>"I14#{side}", :smooth=>true,
                 :fill=>color, :outline=>color, :width=>3)
  @canvas.lower("I14#{side}")
end
draw15()

Light beam

# File ext/tk/sample/demos-en/goldberg.rb, line 1232
def draw15
  color = @C['15a']
  xy = [824, 599, 824, 585, 820, 585, 829, 585]
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I15a')
  xy = [789, 599, 836, 643]
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>3)
  xy = [778, 610, 788, 632]
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>3)
  xy = [766, 617, 776, 625]
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>3)

  xy = [633, 600, 681, 640]
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>3)
  xy = [635, 567, 657, 599]
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>2)
  xy = [765, 557, 784, 583]
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>2)

  sine([658, 580, 765, 580], 3, 15,
       :tag=>'I15_s', :fill=>@C['fg'], :width=>3)
end
draw16()

Bell

# File ext/tk/sample/demos-en/goldberg.rb, line 1284
def draw16
  color = @C['16']
  xy = [722, 485, 791, 556]
  TkcRectangle.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], :width=>3)
  xy = box(752, 515, 25)  # Bell
  TkcOval.new(@canvas, xy, :fill=>color, :outline=>'black',
              :tag=>'I16b', :width=>2)
  xy = box(752, 515, 5)   # Bell button
  TkcOval.new(@canvas, xy, :fill=>'black', :outline=>'black', :tag=>'I16b')

  xy = [784, 523, 764, 549]  # Clapper
  TkcLine.new(@canvas, xy, :width=>3, :tag=>'I16c', :fill=>@C['fg'])
  xy = box(784, 523, 4)
  TkcOval.new(@canvas, xy, :fill=>@C['fg'], :outline=>@C['fg'], :tag=>'I16d')
end
draw17()

Cat

# File ext/tk/sample/demos-en/goldberg.rb, line 1319
def draw17
  color = @C['17']

  xy = [584, 556, 722, 556]
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)
  xy = [584, 485, 722, 485]
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)

  xy = [664, 523, 717, 549]  # Body
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :fill=>color, :width=>3,
             :style=>:chord, :start=>128, :extent=>260, :tag=>'I17')

  xy = [709, 554, 690, 543]  # Paw
  TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>color,
              :width=>3, :tag=>'I17')
  xy = [657, 544, 676, 555]
  TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>color,
              :width=>3, :tag=>'I17')

  xy = box(660, 535, 15)     # Lower face
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc,
             :start=>150, :extent=>240, :tag=>'I17_')
  TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :width=>1,
             :style=>:chord, :start=>150, :extent=>240, :tag=>'I17_')
  xy = [674, 529, 670, 513, 662, 521, 658, 521, 650, 513, 647, 529]  # Ears
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')
  TkcPolygon.new(@canvas, xy, :fill=>color, :outline=>'', :width=>1,
                 :tag=>['I17_', 'I17_c'])
  xy = [652, 542, 628, 539]  # Whiskers
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')
  xy = [652, 543, 632, 545]
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')
  xy = [652, 546, 632, 552]
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')

  xy = [668, 543, 687, 538]
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3,
              :tag=>['I17_', 'I17_w'])
  xy = [668, 544, 688, 546]
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3,
              :tag=>['I17_', 'I17_w'])
  xy = [668, 547, 688, 553]
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3,
              :tag=>['I17_', 'I17_w'])

  xy = [649, 530, 654, 538, 659, 530]  # Left eye
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2,
              :smooth=>true, :tag=>'I17')
  xy = [671, 530, 666, 538, 661, 530]  # Right eye
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2,
              :smooth=>true, :tag=>'I17')
  xy = [655, 543, 660, 551, 665, 543]  # Mouth
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2,
              :smooth=>true, :tag=>'I17')
end
draw18()

Sling shot

# File ext/tk/sample/demos-en/goldberg.rb, line 1420
def draw18
  color = @C['18']
  xy = [721, 506, 627, 506]  # Sling hold
  TkcLine.new(@canvas, xy, :width=>4, :fill=>@C['fg'], :tag=>'I18')

  xy = [607, 500, 628, 513]  # Sling rock
  TkcOval.new(@canvas, xy, :fill=>color, :outline=>'', :tag=>'I18a')

  xy = [526, 513, 606, 507, 494, 502]  # Sling band
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>4, :tag=>'I18b')
  xy = [485, 490, 510, 540, 510, 575, 510, 540, 535, 491]  # Sling
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>6)
end
draw19()

Water pipe

# File ext/tk/sample/demos-en/goldberg.rb, line 1472
def draw19
  color = @C['19']
  xx = [[249, 181], [155, 118], [86, 55], [22, 0]]
  xx.each{|x1, x2|
    TkcRectangle.new(@canvas, x1, 453, x2, 467,
                     :fill=>color, :outline=>'', :tag=>'I19')
    TkcLine.new(@canvas, x1, 453, x2, 453,
                :fill=>@C['fg'], :width=>1) # Pipe top
    TkcLine.new(@canvas, x1, 467, x2, 467,
                :fill=>@C['fg'], :width=>1) # Pipe bottom
  }
  @canvas.raise('I11i')

  xy = box(168, 460, 16)  # Bulge by the joint
  TkcOval.new(@canvas, xy, :fill=>color, :outline=>'')
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, :style=>:arc,
             :start=>21, :extent=>136)
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, :style=>:arc,
             :start=>-21, :extent=>-130)

  xy = [249, 447, 255, 473]  # First joint 26x6
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)

  xy = box(257, 433, 34)     # Bend up
  TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :width=>1,
             :style=>:pie, :start=>0, :extent=>-91)
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1,
             :style=>:arc, :start=>0, :extent=>-90)
  xy = box(257, 433, 20)
  TkcArc.new(@canvas, xy, :outline=>'', :fill=>@C['bg'], :width=>1,
             :style=>:pie, :start=>0, :extent=>-92)
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1,
             :style=>:arc, :start=>0, :extent=>-90)
  xy = box(257, 421, 34)     # Bend left
  TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :width=>1,
             :style=>:pie, :start=>0, :extent=>91)
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1,
             :style=>:arc, :start=>0, :extent=>90)
  xy = box(257, 421, 20)
  TkcArc.new(@canvas, xy, :outline=>'', :fill=>@C['bg'], :width=>1,
             :style=>:pie, :start=>0, :extent=>90)
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1,
             :style=>:arc, :start=>0, :extent=>90)
  xy = box(243, 421, 34)     # Bend down
  TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :width=>1,
             :style=>:pie, :start=>90, :extent=>90)
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1,
             :style=>:arc, :start=>90, :extent=>90)
  xy = box(243, 421, 20)
  TkcArc.new(@canvas, xy, :outline=>'', :fill=>@C['bg'], :width=>1,
             :style=>:pie, :start=>90, :extent=>90)
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1,
             :style=>:arc, :start=>90, :extent=>90)

  xy = [270, 427, 296, 433]  # 2nd joint bottom
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)
  xy = [270, 421, 296, 427]  # 2nd joint top
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)
  xy = [249, 382, 255, 408]  # Third joint right
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)
  xy = [243, 382, 249, 408]  # Third joint left
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)
  xy = [203, 420, 229, 426]  # Last joint
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)

  xy = box(168, 460, 6)      # Handle joint
  TkcOval.new(@canvas, xy, :fill=>@C['fg'], :outline=>'', :tag=>'I19a')
  xy = [168, 460, 168, 512]  # Handle bar
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>5, :tag=>'I19b')
end
draw2()

Lighting the match

# File ext/tk/sample/demos-en/goldberg.rb, line 479
def draw2
  color = @C['2']

  # Fulcrum
  TkcPolygon.new(@canvas, [750, 369, 740, 392, 760, 392],
                 :fill=>@C['fg'], :outline=>@C['fg'])

  # Strike box
  TkcRectangle.new(@canvas, [628, 335, 660, 383],
                   :fill=>'', :outline=>@C['fg'])
  (0..2).each{|y|
    yy = 335 + y*16
    TkcBitmap.new(@canvas, [628, yy], :bitmap=>'gray25',
                  :anchor=>:nw, :foreground=>@C['fg'])
    TkcBitmap.new(@canvas, [644, yy], :bitmap=>'gray25',
                  :anchor=>:nw, :foreground=>@C['fg'])
  }

  # Lever
  TkcLine.new(@canvas, [702, 366, 798, 366],
              :fill=>@C['fg'], :width=>6, :tag=>'I2_0')

  # R strap
  TkcLine.new(@canvas, [712, 363, 712, 355],
              :fill=>@C['fg'], :width=>3, :tag=>'I2_1')

  # L strap
  TkcLine.new(@canvas, [705, 363, 705, 355],
              :fill=>@C['fg'], :width=>3, :tag=>'I2_2')

  # Match stick
  TkcLine.new(@canvas, [679, 356, 679, 360, 717, 360, 717, 356, 679, 356],
              :fill=>@C['fg'], :width=>3, :tag=>'I2_3')

  # Match head
  TkcPolygon.new(@canvas,
                 [ 671, 352, 677.4, 353.9, 680, 358.5, 677.4, 363.1,
                   671, 365, 664.6, 363.1, 662, 358.5, 664.6, 353.9 ],
                 :fill=>color, :outline=>color, :tag=>'I2_4')
end
draw20()

Water pouring

# File ext/tk/sample/demos-en/goldberg.rb, line 1555
def draw20
  # do nothing
end
draw21()

Bucket

# File ext/tk/sample/demos-en/goldberg.rb, line 1593
def draw21
  color = @C['21']
  xy = [217, 451, 244, 490]  # Right handle
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, :tag=>'I21_a')
  xy = [201, 467, 182, 490]  # Left handle
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, :tag=>'I21_a')

  xy = [245, 490, 237, 535]  # Right side
  xy2 = [189, 535, 181, 490] # Left side
  TkcPolygon.new(@canvas, xy + xy2, :fill=>color, :outline=>'',
                 :tag=>['I21', 'I21f'])
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, :tag=>'I21')
  TkcLine.new(@canvas, xy2, :fill=>@C['fg'], :width=>2, :tag=>'I21')

  xy = [182, 486, 244, 498]  # Top
  TkcOval.new(@canvas, xy, :fill=>color, :outline=>'', :width=>2,
              :tag=>['I21', 'I21f'])
  TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], :width=>2,
              :tag=>['I21', 'I21t'])
  xy = [189, 532, 237, 540]  # Bottom
  TkcOval.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>2,
              :tag=>['I21', 'I21b'])
end
draw22()

Bucket drop

# File ext/tk/sample/demos-en/goldberg.rb, line 1646
def draw22
  # do nothing
end
draw23()

Blow dart

# File ext/tk/sample/demos-en/goldberg.rb, line 1666
def draw23
  color  = @C['23a']
  color2 = @C['23b']
  color3 = @C['23c']

  xy = [185, 623, 253, 650]  # Block
  TkcRectangle.new(@canvas, xy, :fill=>'black', :outline=>@C['fg'],
                   :width=>2, :tag=>'I23a')
  xy = [187, 592, 241, 623]  # Balloon
  TkcOval.new(@canvas, xy, :outline=>'', :fill=>color, :tag=>'I23b')
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :tag=>'I23b',
             :style=>:arc, :start=>12, :extent=>336)
  xy = [239, 604, 258, 589, 258, 625, 239, 610]  # Balloon nozzle
  TkcPolygon.new(@canvas, xy, :outline=>'', :fill=>color, :tag=>'I23b')
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I23b')

  xy = [285, 611, 250, 603]  # Dart body
  TkcOval.new(@canvas, xy, :fill=>color2, :outline=>@C['fg'],
              :width=>3, :tag=>'I23d')
  xy = [249, 596, 249, 618, 264, 607, 249, 596]  # Dart tail
  TkcPolygon.new(@canvas, xy, :fill=>color3, :outline=>@C['fg'],
                 :width=>3, :tag=>'I23d')
  xy = [249, 607, 268, 607]  # Dart detail
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I23d')
  xy = [285, 607, 305, 607]  # Dart needle
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I23d')
end
draw24()

Balloon

# File ext/tk/sample/demos-en/goldberg.rb, line 1715
def draw24
  color = @C['24a']
  xy = [366, 518, 462, 665]  # Balloon
  TkcOval.new(@canvas, xy, :fill=>color, :outline=>@C['fg'],
              :width=>3, :tag=>'I24')
  xy = [414, 666, 414, 729]  # String
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I24')
  xy = [410, 666, 404, 673, 422, 673, 418, 666]  # Nozzle
  TkcPolygon.new(@canvas, xy, :fill=>color, :outline=>@C['fg'],
                 :width=>3, :tag=>'I24')

  xy = [387, 567, 390, 549, 404, 542]  # Reflections
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :smooth=>true,
              :width=>2, :tag=>'I24')
  xy = [395, 568, 399, 554, 413, 547]
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :smooth=>true,
              :width=>2, :tag=>'I24')
  xy = [403, 570, 396, 555, 381, 553]
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :smooth=>true,
              :width=>2, :tag=>'I24')
  xy = [408, 564, 402, 547, 386, 545]
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :smooth=>true,
              :width=>2, :tag=>'I24')
end
draw3()

Weight and pulleys

# File ext/tk/sample/demos-en/goldberg.rb, line 564
def draw3
  color = @C['3a']
  color2 = @C['3b']

  xy = [ [602, 296], [577, 174], [518, 174] ]
  xy.each{|x, y| # 3 Pulleys
    TkcOval.new(@canvas, box(x, y, 13),
                :fill=>color, :outline=>@C['fg'], :width=>3)
    TkcOval.new(@canvas, box(x, y, 2), :fill=>@C['fg'], :outline=>@C['fg'])
  }

  # Wall to flame
  TkcLine.new(@canvas, [750, 309, 670, 309], :tag=>'I3_s',
              :width=>3, :fill=>@C['fg'], :smooth=>true)

  # Flame to pulley 1
  TkcLine.new(@canvas, [670, 309, 650, 309], :tag=>'I3_0',
              :width=>3, :fill=>@C['fg'], :smooth=>true)
  TkcLine.new(@canvas, [650, 309, 600, 309], :tag=>'I3_1',
              :width=>3, :fill=>@C['fg'], :smooth=>true)

  # Pulley 1 half way to 2
  TkcLine.new(@canvas, [589, 296, 589, 235], :tag=>'I3_2',
              :width=>3, :fill=>@C['fg'])

  # Pulley 1 other half to 2
  TkcLine.new(@canvas, [589, 235, 589, 174], :width=>3, :fill=>@C['fg'])

  # Across the top
  TkcLine.new(@canvas, [577, 161, 518, 161], :width=>3, :fill=>@C['fg'])

  # Down to weight
  TkcLine.new(@canvas, [505, 174, 505, 205], :tag=>'I3_w',
              :width=>3, :fill=>@C['fg'])

  # Draw the weight as 2 circles, two rectangles and 1 rounded rectangle
  x1, y1, x2, y2 = [515, 207, 495, 207]
  TkcOval.new(@canvas, box(x1, y1, 6),
              :tag=>'I3_', :fill=>color2, :outline=>color2)
  TkcOval.new(@canvas, box(x2, y2, 6),
              :tag=>'I3_', :fill=>color2, :outline=>color2)
  TkcRectangle.new(@canvas, x1, y1 - 6, x2, y2 + 6,
                   :tag=>'I3_', :fill=>color2, :outline=>color2)

  TkcPolygon.new(@canvas, round_rect([492, 220, 518, 263], 15),
                 :smooth=>true, :tag=>'I3_', :fill=>color2, :outline=>color2)

  TkcLine.new(@canvas, [500, 217, 511, 217],
              :tag=>'I3_', :fill=>color2, :width=>10)

  # Bottom weight target
  TkcLine.new(@canvas, [502, 393, 522, 393, 522, 465],
              :tag=>'I3__', :fill=>@C['fg'], :joinstyle=>:miter, :width=>10)
end
draw4()

Cage and door

# File ext/tk/sample/demos-en/goldberg.rb, line 643
def draw4
  color = @C['4']
  x0, y0, x1, y1 = [527, 356, 611, 464]

  # Horizontal bars
  y0.step(y1, 12){|y|
    TkcLine.new(@canvas, [x0, y, x1, y], :fill=>color, :width=>1)
  }

  # Vertical bars
  x0.step(x1, 12){|x|
    TkcLine.new(@canvas, [x, y0, x, y1], :fill=>color, :width=>1)
  }

  # Swing gate
  TkcLine.new(@canvas, [518, 464, 518, 428],
              :tag=>'I4', :fill=>color, :width=>1)
end
draw5()

Mouse

# File ext/tk/sample/demos-en/goldberg.rb, line 675
def draw5
  color  = @C['5a']
  color2 = @C['5b']

  xy = [377, 248, 410, 248, 410, 465, 518, 465]  # Mouse course
  xy.concat [518, 428, 451, 428, 451, 212, 377, 212]

  TkcPolygon.new(@canvas, xy, :fill=>color2, :outline=>@C['fg'], :width=>3)

  xy = [
    534.5, 445.5, 541, 440, 552, 436, 560, 436, 569, 440, 574, 446,
    575, 452, 574, 454, 566, 456, 554, 456, 545, 456, 537, 454, 530, 452
  ]
  TkcPolygon.new(@canvas, xy, :tag=>['I5', 'I5_0'], :fill=>color)

  TkcLine.new(@canvas, [573, 452, 592, 458, 601, 460, 613, 456], # Tail
              :tag=>['I5', 'I5_1'], :fill=>color, :smooth=>true, :width=>3)

  xy = box(540, 446, 2)   # Eye
  xy = [540, 444, 541, 445, 541, 447, 540, 448, 538, 447, 538, 445]
  TkcPolygon.new(@canvas, xy, :tag=>['I5', 'I5_2'], :fill=>@C['bg'],
                 :outline=>'', :smooth=>true)

  xy = [538, 454, 535, 461] # Front leg
  TkcLine.new(@canvas, xy, :tag=>['I5', 'I5_3'], :fill=>color, :width=>2)

  xy = [566, 455, 569, 462] # Back leg
  TkcLine.new(@canvas, xy, :tag=>['I5', 'I5_4'], :fill=>color, :width=>2)

  xy = [544, 455, 545, 460] # 2nd front leg
  TkcLine.new(@canvas, xy, :tag=>['I5', 'I5_5'], :fill=>color, :width=>2)

  xy = [560, 455, 558, 460] # 2nd back leg
  TkcLine.new(@canvas, xy, :tag=>['I5', 'I5_6'], :fill=>color, :width=>2)
end
draw6()

Dropping gumballs

# File ext/tk/sample/demos-en/goldberg.rb, line 734
def draw6
  color = @C['6']
  xy = [324, 130, 391, 204] # Ball holder
  xy = round_rect(xy, 10)
  TkcPolygon.new(@canvas, xy, :smooth=>true,
                 :outline=>@C['fg'], :width=>3, :fill=>color)
  xy = [339, 204, 376, 253] # Below the ball holder
  TkcRectangle.new(@canvas, xy, :outline=>@C['fg'], :width=>3,
                   :fill=>color, :tag=>'I6c')
  xy = box(346, 339, 28)
  TkcOval.new(@canvas, xy, :fill=>color, :outline=>'') # Roter
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>2, :style=>:arc,
             :start=>80, :extent=>205)
  TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>2, :style=>:arc,
             :start=>-41, :extent=>85)

  xy = box(346, 339, 15) # Center of rotor
  TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>@C['fg'], :tag=>'I6m')
  xy = [352, 312, 352, 254, 368, 254, 368, 322] # Top drop to rotor
  TkcPolygon.new(@canvas, xy, :fill=>color, :outline=>'')
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2)

  xy = [353, 240, 367, 300] # Poke bottom hole
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>'')
  xy = [341, 190, 375, 210] # Poke another hole
  TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>'')

  xy = [
    368, 356, 368, 403, 389, 403, 389, 464, 320, 464, 320, 403,
    352, 403, 352, 366
  ]
  TkcPolygon.new(@canvas, xy, :fill=>color, :outline=>'',
                 :width=>2) # Below rotor
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2)
  xy = box(275, 342, 7) # On/off rotor
  TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>@C['fg'])
  xy = [276, 334, 342, 325] # Fan belt top
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)
  xy = [276, 349, 342, 353] # Fan belt bottom
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)

  xy = [337, 212, 337, 247] # What the mouse pushes
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I6_')
  xy = [392, 212, 392, 247]
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I6_')
  xy = [337, 230, 392, 230]
  TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>7, :tag=>'I6_')

  who = -1 # All the balls
  colors = %w(red cyan orange green blue darkblue)
  colors *= 3

  (0..16).each{|i|
    loc = -i
    color = colors[i]
    x, y = @XY6["#{loc}"]
    TkcOval.new(@canvas, box(x, y, 5),
                :fill=>color, :outline=>color, :tag=>"I6_b#{i}")
  }
  draw6a(12) # The wheel
end
draw6a(beta)
# File ext/tk/sample/demos-en/goldberg.rb, line 796
def draw6a(beta)
  @canvas.delete('I6_0')
  ox, oy = [346, 339]
  (0..3).each{|i|
    b = beta + i * 45
    x, y = rotate_c(28, 0, 0, 0, b)
    xy = [ox + x, oy + y, ox - x, oy - y]
    TkcLine.new(@canvas, xy, :tag=>'I6_0', :fill=>@C['fg'], :width=>2)
  }
end
draw7()

On/off switch

# File ext/tk/sample/demos-en/goldberg.rb, line 853
def draw7
  color = @C['7']
  xy = [198, 306, 277, 374]  # Box
  TkcRectangle.new(@canvas, xy, :outline=>@C['fg'], :width=>2,
                   :fill=>color, :tag=>'I7z')
  @canvas.lower('I7z')
  xy = [275, 343, 230, 349]
  TkcLine.new(@canvas, xy, :tag=>'I7', :fill=>@C['fg'], :arrow=>:last,
              :arrowshape=>[23, 23, 8], :width=>6)
  xy = [225, 324]  # On button
  x, y = xy
  TkcOval.new(@canvas, box(x, y, 3), :fill=>@C['fg'], :outline=>@C['fg'])
  xy = [218, 323]  # On text
  font = ['Times Roman', 8]
  TkcText.new(@canvas, xy, :text=>'on', :anchor=>:e,
              :fill=>@C['fg'], :font=>font)
  xy = [225, 350]  # Off button
  x, y = xy
  TkcOval.new(@canvas, box(x, y, 3), :fill=>@C['fg'], :outline=>@C['fg'])
  xy = [218, 349]  # Off text
  TkcText.new(@canvas, xy, :text=>'off', :anchor=>:e,
              :fill=>@C['fg'], :font=>font)
end
draw8()

Electricity to the fan

# File ext/tk/sample/demos-en/goldberg.rb, line 889
def draw8
  sine([271, 248, 271, 306], 5, 8, :tag=>'I8_s', :fill=>@C['8'], :width=>3)
end
draw9()

Fan

# File ext/tk/sample/demos-en/goldberg.rb, line 911
def draw9
  color = @C['9']
  xy = [266, 194, 310, 220]
  TkcOval.new(@canvas, xy, :outline=>color, :fill=>color)
  xy = [280, 209, 296, 248]
  TkcOval.new(@canvas, xy, :outline=>color, :fill=>color)
  xy = [
    288, 249, 252, 249, 260, 240, 280, 234,
    296, 234, 316, 240, 324, 249, 288, 249
  ]
  TkcPolygon.new(@canvas, xy, :fill=>color, :smooth=>true)

  xy = [248, 205, 265, 214, 264, 205, 265, 196]  # Spinner
  TkcPolygon.new(@canvas, xy, :fill=>color)

  xy = [255, 206, 265, 234]  # Fan blades
  TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'],
              :width=>3, :tag=>'I9_0')
  xy = [255, 176, 265, 204]
  TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'],
              :width=>3, :tag=>'I9_0')
  xy = [255, 206, 265, 220]
  TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'],
              :width=>1, :tag=>'I9_1')
  xy = [255, 190, 265, 204]
  TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'],
              :width=>1, :tag=>'I9_1')
end
draw_all()
# File ext/tk/sample/demos-en/goldberg.rb, line 303
def draw_all
  reset_step
  @canvas.delete(:all)
  idx = 0
  loop{
    m = "draw#{idx}"
    break unless respond_to?(m)
    send(m)
    idx += 1
  }
end
get_step(who, step)

Each Move## keeps its state info in STEP, this retrieves and increments it

# File ext/tk/sample/demos-en/goldberg.rb, line 1853
def get_step(who, step)
  if step
    @STEP[who] = step
  else
    if !@STEP.exist?(who) || @STEP[who] == ""
      @STEP[who] = 0
    else
      @STEP[who] += 1
    end
  end
  @STEP[who]
end
go(who = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 358
def go(who = nil)
  now = Tk::Clock.clicks(:miliseconds)
  if who  # Start here for debugging
    @S['active'] = [who]
    @S['mode'].value = :MGO
  end
  return if @S['mode'].to_sym == :MDEBUG  # Debugging
  # If not paused, do the next move
  n = next_step if @S['mode'].to_sym != :MPAUSE
  @S['mode'].value = :MPAUSE if @S['mode'].to_sym == :MSSTEP  # Single step
  @S['mode'].value = :MSSTEP if @S['mode'].to_sym == :MBSTEP && n  # big step
  elapsed = Tk::Clock.clicks(:miliseconds) - now
  delay = @speed[@S['speed'].to_i] - elapsed
  delay = 1 if delay <= 0
  return delay
end
h20(y, f)
# File ext/tk/sample/demos-en/goldberg.rb, line 1578
def h20(y, f)
  color = @C['20']
  @canvas.delete('I20')

  sine([208, 428, 208, y], 4, f, :tag=>['I20', 'I20s'],
       :width=>3, :fill=>color, :smooth=>true)
  TkcLine.new(@canvas, @canvas.coords('I20s'), :width=>3,
              :fill=>color, :smooth=>1, :tag=>['I20', 'I20a'])
  TkcLine.new(@canvas, @canvas.coords('I20s'), :width=>3,
              :fill=>color, :smooth=>1, :tag=>['I20', 'I20b'])
  @canvas.move('I20a', 8, 0)
  @canvas.move('I20b', 16, 0)
end
move0(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 427
def move0(step = nil)
  step = get_step(0, step)

  if @S['mode'].to_sym != :MSTART    # Start the ball rolling
    move_abs('I0', [-100, -100])     # Hide the banner
    return 2
  end

  pos = [
    [673, 119], [678, 119], [683, 119], [688, 119],
    [693, 119], [688, 119], [683, 119], [678, 119]
  ]
  step = step % pos.length
  move_abs('I0', pos[step])
  return 1
end
move1(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 462
def move1(step = nil)
  step = get_step(1, step)
  pos = [
    [807, 122], [802, 122], [797, 123], [793, 124], [789, 129], [785, 153],
    [785, 203], [785, 278, :x], [785, 367], [810, 392], [816, 438],
    [821, 503], [824, 585, :y], [838, 587], [848, 593], [857, 601],
    [-100, -100]
  ]
  return 0 if step >= pos.length
  where = pos[step]
  move_abs('I1', where)
  move15a if where[2] == :y
  return 3 if where[2] == :x
  return 1
end
move10(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 998
def move10(step = nil)
  step = get_step(10, step)

  pos = [
    [195, 212], [193, 212], [190, 212], [186, 212], [181, 212], [176, 212],
    [171, 212], [166, 212], [161, 212], [156, 212], [151, 212], [147, 212],
    [142, 212], [137, 212], [132, 212, :x], [127, 212], [121, 212],
    [116, 212], [111, 212]
  ]

  return 0 if step >= pos.length

  where = pos[step]
  move_abs('I10', where)

  return 3 if where[2] == :x
  return 1
end
move11(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1049
def move11(step = nil)
  step = get_step(11, step)

  pos = [
    [75, 235], [70, 235], [65, 237], [56, 240], [46, 247], [38, 266],
    [38, 296], [38, 333], [38, 399], [38, 475], [74, 496], [105, 472],
    [100, 437], [65, 423], [-100, -100], [38, 505], [38, 527, :x], [38, 591]
  ]

  return 0 if step >= pos.length
  where = pos[step]
  move_abs('I11', where)
  return 3 if where[2] == :x
  return 1
end
move12(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1086
def move12(step = nil)
  step = get_step(12, step)

  pos = [[42.5, 641, :x]]
  return 0 if step >= pos.length
  where = pos[step]
  move_abs('I12', where)
  return 3 if where[2] == :x
  return 1
end
move13(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1136
def move13(step = nil)
  step = get_step(13, step)

  numsteps = 7

  if step == numsteps + 2
    move_abs('I13_star', [-100, -100])
    @canvas.itemconfigure('I13R', :fill=>@C['13b'], :width=>2)
    return 2
  end
  if step == 0  # Button down
    @canvas.delete('I13')
    sparkle([-100, -100], 'I13_star')  # Create off screen
    return 1
  end
  x0, y0 = anchor('I13_s', :w)
  x1, y1 = anchor('I13_s', :e)
  x = x0 + (x1 - x0) * (step - 1) / numsteps.to_f
  move_abs('I13_star', [x, y0])
  return 1
end
move14(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1202
def move14(step = nil)
  step = get_step(14, step)

  # Paper going down
  sc = 0.9 - 0.05*step
  if sc < 0.3
    @canvas.delete('I14L')
    return 0
  end

  ox, oy = @canvas.coords('I14L_0')
  @canvas.scale('I14L_0', ox, oy, sc, sc)
  ox, oy = @canvas.coords('I14L_1')[-2..-1]
  @canvas.scale('I14L_1', ox, oy, sc, sc)
  draw14a('L')

  # Paper going up
  sc = 0.35 + 0.05*step
  sc = 1/sc

  ox, oy = @canvas.coords('I14R_0')
  @canvas.scale('I14R_0', ox, oy, sc, sc)
  ox, oy = @canvas.coords('I14R_1')[-2..-1]
  @canvas.scale('I14R_1', ox, oy, sc, sc)
  draw14a('R')

  return((step == 10)? 3: 1)
end
move15(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1261
def move15(step = nil)
  step = get_step(15, step)

  numsteps = 6

  if step == numsteps + 2
    move_abs('I15_star', [-100, -100])
    return 2
  end
  if step == 0  # Break the light beam
    sparkle([-100, -100], 'I15_star')
    xy = [765, 621, 745, 621]
    @canvas.coords('I15', xy)
    return 1
  end
  x0, y0 = anchor('I15_s', :w)
  x1, y1 = anchor('I15_s', :e)
  x = x0 + (x1 - x0) * (step - 1) / numsteps.to_f
  move_abs('I15_star', [x, y0])
  return 1
end
move15a()
# File ext/tk/sample/demos-en/goldberg.rb, line 1254
def move15a
  color = @C['15b']
  @canvas.scale('I15a', 824, 599, 1, 0.3)  # Button down
  xy = [765, 621, 681, 621]
  TkcLine.new(@canvas, xy, :dash=>'-', :width=>3, :fill=>color, :tag=>'I15')
end
move16(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1300
def move16(step = nil)
  step = get_step(16, step)

  # Note: we never stop
  ox, oy = [760, 553]
  if (step & 1).nonzero?
    beta = 12
    @canvas.move('I16b', 3, 0)
  else
    beta = -12
    @canvas.move('I16b', -3, 0)
  end
  rotate_item('I16c', ox, oy, beta)
  rotate_item('I16d', ox, oy, beta)

  return ((step == 1)? 3: 1)
end
move17(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1375
def move17(step = nil)
  step = get_step(17, step)

  if step == 0
    @canvas.delete('I17')  # Delete most of the cat
    xy = [655, 543, 660, 535, 665, 543]  # Mouth
    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3,
                :smooth=>true, :tag=>'I17_')
    xy = box(654, 530, 4)  # Left eye
    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :fill=>'',
                :tag=>'I17_')
    xy = box(666, 530, 4)  # Right eye
    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :fill=>'',
                :tag=>'I17_')

    @canvas.move('I17_', 0, -20) # Move face up
    xy = [652, 528, 652, 554]    # Front leg
    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')
    xy = [670, 528, 670, 554]    # 2nd front leg
    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')

    xy = [ # Body
      675, 506, 694, 489, 715, 513, 715, 513, 715, 513, 716, 525,
      716, 525, 716, 525, 706, 530, 695, 530, 679, 535, 668, 527,
      668, 527, 668, 527, 675, 522, 676, 517, 677, 512
    ]
    TkcPolygon.new(@canvas, xy, :fill=>@canvas.itemcget('I17_c', :fill),
                   :outline=>@C['fg'], :width=>3, :smooth=>true,
                   :tag=>'I17_')
    xy = [716, 514, 716, 554]  # Back leg
    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')
    xy = [694, 532, 694, 554]  # 2nd back leg
    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')
    xy = [715, 514, 718, 506, 719, 495, 716, 488]  # Tail
    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3,
                :smooth=>true, :tag=>'I17_')

    @canvas.raise('I17w')       # Make whiskers visible
    @canvas.move('I17_', -5, 0) # Move away from the wall a bit
    return 2
  end
  return 0
end
move18(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1434
def move18(step = nil)
  step = get_step(18, step)

  pos = [
    [587, 506], [537, 506], [466, 506], [376, 506], [266, 506, :x],
    [136, 506], [16, 506], [-100, -100]
  ]

  b = []
  b[0] = [490, 502, 719, 507, 524, 512]  # Band collapsing
  b[1] = [
    491, 503, 524, 557, 563, 505, 559, 496, 546, 506, 551, 525,
    553, 536, 538, 534, 532, 519, 529, 499
  ]
  b[2] = [
    491, 503, 508, 563, 542, 533, 551, 526, 561, 539, 549, 550, 530, 500
  ]
  b[3] = [
    491, 503, 508, 563, 530, 554, 541, 562, 525, 568, 519, 544, 530, 501
  ]

  return 0 if step >= pos.length

  if step == 0
    @canvas.delete('I18')
    @canvas.itemconfigure('I18b', :smooth=>true)
  end
  if b[step]
    @canvas.coords('I18b', b[step])
  end

  where = pos[step]
  move_abs('I18a', where)
  return 3 if where[2] == :x
  return 1
end
move19(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1543
def move19(step = nil)
  step = get_step(19, step)

   angles = [30, 30, 30]
  return 2 if step == angles.length
  ox, oy = centroid('I19a')
  rotate_item('I19b', ox, oy, angles[step])

  return 1
end
move2(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 520
def move2(step = nil)
  step = get_step(2, step)

  stages = [0, 0, 1, 2, 0, 2, 1, 0, 1, 2, 0, 2, 1]
  xy = []
  xy[0] = [
    686, 333, 692, 323, 682, 316, 674, 309, 671, 295, 668, 307,
    662, 318, 662, 328, 671, 336
  ]
  xy[1] = [
    687, 331, 698, 322, 703, 295, 680, 320, 668, 297, 663, 311,
    661, 327, 671, 335
  ]
  xy[2] = [
    686, 331, 704, 322, 688, 300, 678, 283, 678, 283, 674, 298,
    666, 309, 660, 324, 672, 336
  ]

  if step >= stages.length
    @canvas.delete('I2')
    return 0
  end

  if step == 0  # Rotate the match
    beta = 20

    ox, oy = anchor('I2_0', :s)  # Where to pivot

    i = 0
    until @canvas.find_withtag("I2_#{i}").empty?
      rotate_item("I2_#{i}", ox, oy, beta)
      i += 1
    end

    # For the flame
    TkcPolygon.new(@canvas, [], :tag=>'I2', :smooth=>true, :fill=>@C['2'])

    return 1
  end
  @canvas.coords('I2', xy[stages[step]])
  return ((step == 7)? 3: 1)
end
move20(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1559
def move20(step = nil)
  step = get_step(20, step)

  pos  = [451, 462, 473, 484, 496, 504, 513, 523, 532]
  freq  = [20,  40,  40,  40,  40,  40,  40,  40,  40]
  pos = [
    [451, 20], [462, 40], [473, 40], [484, 40], [496, 40],
    [504, 40], [513, 40], [523, 40], [532, 40, :x]
  ]
  return 0 if step >= pos.length

  @canvas.delete('I20')
  where = pos[step]
  y, f = where
  h20(y, f)
  return 3 if where[2] == :x
  return 1
end
move21(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1617
def move21(step = nil)
  step = get_step(21, step)

  numsteps = 30
  return 0 if step >= numsteps

  x1, y1, x2, y2 = @canvas.coords('I21b')
  # lx1, ly1, lx2, ly2 = @canvas.coords('I21t')
  lx1, ly1, lx2, ly2 = [183, 492, 243, 504]

  f = step / numsteps.to_f
  y2 = y2 - 3
  xx1 = x1 + (lx1 - x1) * f
  yy1 = y1 + (ly1 - y1) * f
  xx2 = x2 + (lx2 - x2) * f
  yy2 = y2 + (ly2 - y2) * f

  @canvas.itemconfigure('I21b', :fill=>@C['20'])
  @canvas.delete('I21w')
  TkcPolygon.new(@canvas, x2, y2, x1, y1, xx1, yy1, xx2, yy1,
                 :tag=>['I21', 'I21w'], :outline=>'', :fill=>@C['20'])
  @canvas.lower('I21w', 'I21')
  @canvas.raise('I21b')
  @canvas.lower('I21f')

  return((step == numsteps - 1)? 3: 1)
end
move22(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1650
def move22(step = nil)
  step = get_step(22, step)
  pos = [[213, 513], [213, 523], [213, 543, :x], [213, 583], [213, 593]]

  @canvas.itemconfigure('I21f', :fill=>@C['22']) if step == 0
  return 0 if step >= pos.length
  where = pos[step]
  move_abs('I21', where)
  h20(where[1], 40)
  @canvas.delete('I21_a')  # Delete handles

  return 3 if where[2] == :x
  return 1
end
move23(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1694
def move23(step = nil)
  step = get_step(23, step)

  pos = [
    [277, 607], [287, 607], [307, 607, :x], [347, 607], [407, 607],
    [487, 607], [587, 607], [687, 607], [787, 607], [-100, -100]
  ]

  return 0 if step >= pos.length
  if step <= 1
    ox, oy = anchor('I23a', :n)
    @canvas.scale('I23b', ox, oy, 0.9, 0.5)
  end
  where = pos[step]
  move_abs('I23d', where)

  return 3 if where[2] == :x
  return 1
end
move24(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 1740
def move24(step = nil)
  step = get_step(24, step)

  return 0 if step > 4
  return 2 if step == 4

  if step == 0
    @canvas.delete('I24')  # Exploding balloon
    xy = [
      347, 465, 361, 557, 271, 503, 272, 503, 342, 574, 259, 594,
      259, 593, 362, 626, 320, 737, 320, 740, 398, 691, 436, 738,
      436, 739, 476, 679, 528, 701, 527, 702, 494, 627, 548, 613,
      548, 613, 480, 574, 577, 473, 577, 473, 474, 538, 445, 508,
      431, 441, 431, 440, 400, 502, 347, 465, 347, 465
    ]
    TkcPolygon.new(@canvas, xy, :tag=>'I24', :fill=>@C['24b'],
                   :outline=>@C['24a'], :width=>10, :smooth=>true)
    msg = Tk.subst(@S['message'].value)
    TkcText.new(@canvas, centroid('I24'), :text=>msg, :tag=>['I24', 'I24t'],
                :justify=>:center, :font=>['Times Roman', 18, :bold])
    return 1
  end

  @canvas.itemconfigure('I24t', :font=>['Times Roman', 18 + 6*step, :bold])
  @canvas.move('I24', 0, -60)
  ox, oy = centroid('I24')
  @canvas.scale('I24', ox, oy, 1.25, 1.25)
  return 1
end
move25(step = nil)

Displaying the message

# File ext/tk/sample/demos-en/goldberg.rb, line 1771
def move25(step = nil)
  step = get_step(25, step)

  if step == 0
    @XY['25'] = Tk::Clock.clicks(:miliseconds)
    return 1
  end
  elapsed = Tk::Clock.clicks(:miliseconds) - @XY['25']
  return 1 if elapsed < 5000
  return 2
end
move26(step = nil)

Collapsing balloon

# File ext/tk/sample/demos-en/goldberg.rb, line 1784
def move26(step = nil)
  step = get_step(26, step)

  if step >= 3
    @canvas.delete('I24', 'I26')
    TkcText.new(@canvas, 430, 740, :anchor=>:s, :tag=>'I26',
                :text=>'click to continue',
                :font=>['Times Roman', 24, :bold])
    @canvas.bind('1', proc{reset})
    return 4
  end

  ox, oy = centroid('I24')
  @canvas.scale('I24', ox, oy, 0.8, 0.8)
  @canvas.move('I24', 0, 60)
  @canvas.itemconfigure('I24t', :font=>['Times Roman', 30 - 6*step, :bold])
  return 1
end
move3(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 619
def move3(step = nil)
  step = get_step(3, step)

  pos = [ [505, 247], [505, 297], [505, 386.5], [505, 386.5] ]
  rope = []
  rope[0] = [750, 309, 729, 301, 711, 324, 690, 300]
  rope[1] = [750, 309, 737, 292, 736, 335, 717, 315, 712, 320]
  rope[2] = [750, 309, 737, 309, 740, 343, 736, 351, 725, 340]
  rope[3] = [750, 309, 738, 321, 746, 345, 742, 356]

  return 0 if step >= pos.length

  @canvas.delete("I3_#{step}")        # Delete part of the rope
  move_abs('I3_', pos[step])          # Move weight down
  @canvas.coords('I3_s', rope[step])  # Flapping rope end
  @canvas.coords('I3_w', [505, 174].concat(pos[step]))
  if step == 2
    @canvas.move('I3__', 0, 30)
    return 2
  end
  return 1
end
move4(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 662
def move4(step = nil)
  step = get_step(4, step)

  angles = [-10, -20, -30, -30]
  return 0 if step >= angles.length

  rotate_item('I4', 518, 464, angles[step])
  @canvas.raise('I4')

  return((step == 3)? 3: 1)
end
move5(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 711
def move5(step = nil)
  step = get_step(5, step)

  pos = [
    [553, 452], [533, 452], [513, 452], [493, 452], [473, 452],
    [463, 442, 30], [445.5, 441.5, 30], [425.5, 434.5, 30], [422, 414],
    [422, 394], [422, 374], [422, 354], [422, 334], [422, 314], [422, 294],
    [422, 274, -30], [422, 260.5, -30, :x], [422.5, 248.5, -28], [425, 237]
  ]

  return 0 if step >= pos.length

  x, y, beta, nxt = pos[step]
  move_abs('I5', [x, y])
  if beta
    ox, oy = centroid('I5_0')
    (0..6).each{|id| rotate_item("I5_#{id}", ox, oy, beta) }
  end
  return 3 if nxt == :x
  return 1
end
move6(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 807
def move6(step = nil)
  step = get_step(6, step)

  return 0 if step > 62

  if step < 2  # Open gate for balls to drop
    @canvas.move('I6_', -7, 0)
    if step == 1  # Poke a hole
      xy = [348, 226, 365, 240]
      TkcRectangle.new(@canvas, xy, :fill=>@canvas.itemcget('I6c', :fill),
                       :outline=>'')
    end
    return 1
  end

  s = step - 1  # Do the gumball drop dance
  (0..(((s - 1)/3).to_i)).each{|i|
    tag = "I6_b#{i}"
    break if @canvas.find_withtag(tag).empty?
    loc = s - 3*i

    if @XY6["#{loc},#{i}"]
      move_abs(tag, @XY6["#{loc},#{i}"])
    elsif @XY6["#{loc}"]
      move_abs(tag, @XY6["#{loc}"])
    end
  }
  if s % 3 == 1
    first = (s + 2)/3
    i = first
    loop {
      tag = "I6_b#{i}"
      break if @canvas.find_withtag(tag).empty?
      loc = first - i
      move_abs(tag, @XY6["#{loc}"])
      i += 1
    }
  end
  if s >= 3  # Rotate the motor
    idx = s % 3
    draw6a(12 + s * 15)
  end
  return((s == 3)? 3 : 1)
end
move7(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 877
def move7(step = nil)
  step = get_step(7, step)

  numsteps = 30
  return 0 if step > numsteps
  beta = 30.0 / numsteps
  rotate_item('I7', 275, 343, beta)

  return((step == numsteps)? 3: 1)
end
move8(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 893
def move8(step = nil)
  step = get_step(8, step)

  return 0 if step > 3
  if step == 0
    sparkle(anchor('I8_s', :s), 'I8')
    return 1
  elsif step == 1
    move_abs('I8', anchor('I8_s', :c))
  elsif step == 2
    move_abs('I8', anchor('I8_s', :n))
  else
    @canvas.delete('I8')
  end
  return((step == 2)? 3: 1)
end
move9(step = nil)
# File ext/tk/sample/demos-en/goldberg.rb, line 940
def move9(step = nil)
  step = get_step(9, step)

  if (step & 1).nonzero?
    @canvas.itemconfigure('I9_0', :width=>4)
    @canvas.itemconfigure('I9_1', :width=>1)
    @canvas.lower('I9_1', 'I9_0')
  else
    @canvas.itemconfigure('I9_0', :width=>1)
    @canvas.itemconfigure('I9_1', :width=>4)
    @canvas.lower('I9_0', 'I9_1')
  end
  return 3 if step == 0
  return 1
end
move_abs(item, xy)
# File ext/tk/sample/demos-en/goldberg.rb, line 1811
def move_abs(item, xy)
  x, y = xy
  ox, oy = centroid(item)
  dx = x - ox
  dy = y - oy
  @canvas.move(item, dx, dy)
end
next_step()
# File ext/tk/sample/demos-en/goldberg.rb, line 375
def next_step
  retval = false   # Return value

  if @S['mode'].to_sym != :MSTART && @S['mode'].to_sym != :MDONE
    @S['cnt'].numeric += 1
  end
  alive = []
  @S['active'].each{|who|
    who = who.to_i
    n = send("move#{who}")
    if (n & 1).nonzero?          # This guy still alive
      alive << who
    end
    if (n & 2).nonzero?          # Next guy is active
      alive << (who + 1)
      retval = true
    end
    if (n & 4).nonzero?          # End of puzzle flag
      @S['mode'].value = :MDONE  # Done mode
      @S['active'] = []          # No more animation
      return true
    end
  }
  @S['active'] = alive
  return retval
end
reset()
# File ext/tk/sample/demos-en/goldberg.rb, line 1845
def reset
  draw_all
  @canvas.bind_remove('1')
  @S['mode'].value = :MSTART
  @S['active'] = [0]
end
reset_step()
# File ext/tk/sample/demos-en/goldberg.rb, line 1866
def reset_step
  @S['cnt'].value = 0
  @STEP.keys.each{|k| @STEP[k] = ''}
end
rotate_c(x, y, ox, oy, beta)
# File ext/tk/sample/demos-en/goldberg.rb, line 1829
def rotate_c(x, y, ox, oy, beta)
  # rotates vector (ox,oy)->(x,y) by beta degrees clockwise

  x -= ox    # Shift to origin
  y -= oy

  beta = beta * Math.atan(1) * 4 / 180.0        # Radians
  xx = x * Math.cos(beta) - y * Math.sin(beta)  # Rotate
  yy = x * Math.sin(beta) + y * Math.cos(beta)

  xx += ox  # Shift back
  yy += oy

  [xx, yy]
end
rotate_item(item, ox, oy, beta)
# File ext/tk/sample/demos-en/goldberg.rb, line 1819
def rotate_item(item, ox, oy, beta)
  xy = @canvas.coords(item)
  xy2 = []
  0.step(xy.length - 1, 2){|idx|
    x, y = xy[idx, 2]
    xy2.concat(rotate_c(x, y, ox, oy, beta))
  }
  @canvas.coords(item, xy2)
end
round_poly(canv, xy, radii, opts)
# File ext/tk/sample/demos-en/goldberg.rb, line 1915
def round_poly(canv, xy, radii, opts)
  lenXY = xy.length
  lenR = radii.length
  if lenXY != 2*lenR
    raise "wrong number of vertices and radii"
  end

  knots = []
  x0 = xy[-2]; y0 = xy[-1]
  x1 = xy[0];  y1 = xy[1]
  xy << xy[0] << xy[1]

  0.step(lenXY - 1, 2){|i|
    radius = radii[i/2]
    r = canv.winfo_pixels(radius)

    x2 = xy[i+2];  y2 = xy[i+3]
    z = _round_poly2(x0, y0, x1, y1, x2, y2, r)
    knots.concat(z)

    x0 = x1;  y0 = y1
    x1 = x2;  y1 = y2
  }
  TkcPolygon.new(canv, knots, {:smooth=>true}.update(opts))
end
round_rect(xy, radius, opts={})
# File ext/tk/sample/demos-en/goldberg.rb, line 1891
def round_rect(xy, radius, opts={})
  x0, y0, x3, y3 = xy
  r = @canvas.winfo_pixels(radius)
  d = 2 * r

  # Make sure that the radius of the curve is less than 3/8 size of the box!
  maxr = 0.75
  if d > maxr * (x3 - x0)
    d = maxr * (x3 - x0)
  end
  if d > maxr * (y3 - y0)
    d = maxr * (y3 - y0)
  end

  x1 = x0 + d
  x2 = x3 - d
  y1 = y0 + d
  y2 = y3 - d

  xy = [x0, y0, x1, y0, x2, y0, x3, y0, x3, y1, x3, y2]
  xy.concat([x3, y3, x2, y3, x1, y3, x0, y3, x0, y2, x0, y1])
  return xy
end
show_ctrl()
# File ext/tk/sample/demos-en/goldberg.rb, line 293
def show_ctrl
  if @ctrl.winfo_mapped?
    @ctrl.pack_forget
    @show.text('>>')
  else
    @ctrl.pack(:side=>:right, :fill=>:both, :ipady=>5)
    @show.text('<<')
  end
end
sine(xy0, amp, freq, opts = {})
# File ext/tk/sample/demos-en/goldberg.rb, line 1871
def sine(xy0, amp, freq, opts = {})
  x0, y0, x1, y1 = xy0
  step = 2
  xy = []
  if y0 == y1  # Horizontal
    x0.step(x1, step){|x|
      beta = (x - x0) * 2 * Math::PI / freq
      y = y0 + amp * Math.sin(beta)
      xy << x << y
    }
  else
    y0.step(y1, step){|y|
      beta = (y - y0) * 2 * Math::PI / freq
      x = x0 + amp * Math.sin(beta)
      xy << x << y
    }
  end
  TkcLine.new(@canvas, xy, opts)
end
sparkle(oxy, tag)
# File ext/tk/sample/demos-en/goldberg.rb, line 1968
def sparkle(oxy, tag)
  xy = [
    [299, 283], [298, 302], [295, 314], [271, 331],
    [239, 310], [242, 292], [256, 274], [281, 273]
  ]
  xy.each{|x, y|
    TkcLine.new(@canvas, 271, 304, x, y,
                :fill=>'white', :width=>3, :tag=>tag)
  }
  move_abs(tag, oxy)
end
start()
# File ext/tk/sample/demos-en/goldberg.rb, line 334
def start
  @S['mode'].value = :MGO
end