2

我最近重新发现了 Ruby Shoes 框架,它是一个小型图形框架,使用 Ruby 内部 DSL 功能,更具体地说,这里是 Shoes4

其中一个示例(位于 ./samples 中)给我留下了特别深刻的印象:sample13.rb,我无法完全理解。

运行此示例,您将获得一个带有名为“new”的按钮的画布。每次按下此按钮时,都会将一个新图形(在程序中命名为框)添加到画布(形状和颜色随机)。但更重要的是,您可以在之后单击这些数字,然后将它们移开。

代码非常短:

Shoes.app :width => 300, :height => 300 do
  COLORS = Shoes::COLORS
  i = 45

  button 'new' do
    i += 5
    box = rand(2) == 0 ? rect(i, i, 20) : oval(i, i, 20)
    box.style :fill => send(COLORS.keys[rand(COLORS.keys.size)])
    @flag = false
    box.click{@flag = true; @box = box}
    box.release{@flag = false}
  end

  motion{|left, top| @box.move(left-10, top-10) if @flag}
end

我想解释一下这段代码是如何工作的。

似乎创建的每个图形都存储在某个地方,但究竟在哪里?有没有办法访问新创建的人物集合?

而且,如图所示,图中还添加了clickrelease等方法。一般来说,鞋子中的每个对象都是这种情况吗(我在鞋子网站上找不到)?

4

1 回答 1

2

所以这些数字没有存储在任何地方,但有相当多的范围魔法正在发生。click 和 release 元素在相当多的元素上可用,应该是这里提到的所有元素 :click但该列表在 Shoes4 中不完全支持(尚)。

那么让我们一一来看这个:

box.click{@flag = true; @box = box}
box.release{@flag = false}

所以当一个元素被点击时@flag被设置为真(那个标志似乎标志着一个元素当前正在被拖动),这就是为什么当鼠标点击被释放时标志被设置为假的原因。此外,单击时发生的情况是实例变量@box设置为刚刚单击的框。这是可能的,因为块保留了它们在其中创建的范围。这意味着范围会记住box指的是单击框时调用的块的已创建框。这是可能的,因为在创建块期间将引用保存在局部变量box中,并且块捕获此范围。

现在开始议案:

motion{|left, top| @box.move(left-10, top-10) if @flag}

Motion 捕捉鼠标的移动。它的作用是将当前单击的框(如果有,则为@flag)移动到当前鼠标光标的位置(由顶部和左侧指定)。我不知道为什么需要 -10,但我似乎记得我们在其他地方遇到过问题。我会尝试调查并打开问题,但这在这里并不重要:-)

哦,谢谢你试鞋!:-) 另外感谢您告诉我您实际上可以拖动它们,我什至不知道!

于 2013-07-25T09:14:59.267 回答