librelist archives

« back to archive

How can I generate multiple rectangles

How can I generate multiple rectangles

From:
Filemon Salas
Date:
2012-01-10 @ 02:17
Hi,

How can I generate multiple rectangles when a button is clicked?

I would like to generate rectangles when a button is clicked but in
different locations. In other words what I'm trying to do is display
an array of squares but with a gap in between each square.

Shoes.app do
  button "Action" do
    def rectangle
    fill red
    rect 30, 30, 40, 40
    end

 5.times do
   rectangle
   para rectangle.width
   end
 end
end

Can someone be so kind and help me with this?

Thanks

Re: [shoes] How can I generate multiple rectangles

From:
Peter Fitzgibbons
Date:
2012-01-10 @ 03:07
You look like you have a good start.  You're drawing 5 rectangles on top of
each other.

You need to introduce a variable (x) so you can do some math between
iterations on 5.times.  Also, times will "yield" the index of the iteration
if you want, like this :

5.times do |x|
  rectangle(x)
end

def rectangle(x)
  fill red
  rectangle 30 + x * 3, 30 + x * 3, 40, 40
end


My pseudo-code probably has bugs.  Does it work for you?!

Peter Fitzgibbons
(847) 859-9550
Email: peter.fitzgibbons@gmail.com
IM GTalk: peter.fitzgibbons
IM AOL: peter.fitzgibbons@gmail.com


On Mon, Jan 9, 2012 at 8:17 PM, Filemon Salas <fs.dolphin@gmail.com> wrote:

> Hi,
>
> How can I generate multiple rectangles when a button is clicked?
>
> I would like to generate rectangles when a button is clicked but in
> different locations. In other words what I'm trying to do is display
> an array of squares but with a gap in between each square.
>
> Shoes.app do
>  button "Action" do
>    def rectangle
>    fill red
>    rect 30, 30, 40, 40
>    end
>
>  5.times do
>   rectangle
>   para rectangle.width
>   end
>  end
> end
>
> Can someone be so kind and help me with this?
>
> Thanks
>

Re: [shoes] How can I generate multiple rectangles

From:
Date:
2012-01-10 @ 10:29
Tried this example, it needs still some window height manipulation since 
eventually the rectangles scroll of the screen and there is no scrollbar.

 

Shoes.app do

  

  y=0

  

  def rectangle(x, y)

    rect x*50, y*50, 40, 40, :fill => red

  end

  

  button "Action" do

    y=y+1

    5.times do |x|

      rectangle(x, y)

    end

  end

 

end

 

Peter

Re: [shoes] How can I generate multiple rectangles

From:
Date:
2012-01-10 @ 10:57
And this is a more funny and educational example I adapted from the widget
example in  the wiki.

 

class StarMonkey < Shoes::Widget

  attr_reader :name

  def initialize(name)

    @name = name

    stack(:width => 140, :height => 200, :stroke => red, :fill => blue) do

      r = star(70, 65, 5, 60, 40)

      r.style(:stroke => blue, :fill => black)

      star(40, 60, 5, 25, 10)

      star(100, 60, 5, 25, 10)

      a = arc(70, 90, 100, 20, 90, 180)

      para name, :align => "center", :displace_top => 150, :stroke=> blue

    end

    self.style(:width => 140, :height => 200)

    self.click{yield if block_given?}

  end

end

 

Shoes.app do

  sm1 = star_monkey("Laverne"){para "#{sm1.name} to sew L's on my 
sweaters.  ", :stroke => green}

  sm2 = star_monkey("Shirley"){para "#{sm2.name} to keep BooBoo Kitty 
company.  ", :stroke => orange}

  sm3 = star_monkey("Lenny"){para "#{sm3.name} to drive the truck.  ", 
:stroke => red}

  sm4 = star_monkey("Squiggy"){para "#{sm4.name} to collect moths.  ", 
:stroke => blue}

end

 

Peter

Re: [shoes] How can I generate multiple rectangles

From:
Filemon Salas
Date:
2012-01-10 @ 12:41
Thank you all very much for your help!

On Tue, Jan 10, 2012 at 4:57 AM,  <peter.marien@cm.be> wrote:
> And this is a more funny and educational example I adapted from the widget
> example in  the wiki.
>
>
>
> class StarMonkey < Shoes::Widget
>
>   attr_reader :name
>
>   def initialize(name)
>
>     @name = name
>
>     stack(:width => 140, :height => 200, :stroke => red, :fill => blue) do
>
>       r = star(70, 65, 5, 60, 40)
>
>       r.style(:stroke => blue, :fill => black)
>
>       star(40, 60, 5, 25, 10)
>
>       star(100, 60, 5, 25, 10)
>
>       a = arc(70, 90, 100, 20, 90, 180)
>
>       para name, :align => "center", :displace_top => 150, :stroke=> blue
>
>     end
>
>     self.style(:width => 140, :height => 200)
>
>     self.click{yield if block_given?}
>
>   end
>
> end
>
>
>
> Shoes.app do
>
>   sm1 = star_monkey("Laverne"){para "#{sm1.name} to sew L's on my sweaters.
> ", :stroke => green}
>
>   sm2 = star_monkey("Shirley"){para "#{sm2.name} to keep BooBoo Kitty
> company.  ", :stroke => orange}
>
>   sm3 = star_monkey("Lenny"){para "#{sm3.name} to drive the truck.  ",
> :stroke => red}
>
>   sm4 = star_monkey("Squiggy"){para "#{sm4.name} to collect moths.  ",
> :stroke => blue}
>
> end
>
>
>
> Peter

Re: [shoes] How can I generate multiple rectangles

From:
Filemon Salas
Date:
2012-01-11 @ 00:00
Shoes.app do
  y=0
  def rectangle(x, y)
    rect x*50, y*50, 40, 40, :fill => red
  end

  button "Action" do
    y=y+1
    5.times do |x|
      rectangle(x, y)
    end
  end
end

Grrr, I'm so confused trying to understand how this code is working.
y=0 (why?)
rect x*50, y*50 (why?)
y=y+1 ?
rectangle(x, y) ?

soorrry, in genereal I dont know understand the whole code (I know, I
know), can someone be so kind and explain line by line?

are x and y some how the current position or something like that or
whats the value?

Thanks a lot


On Tue, Jan 10, 2012 at 4:29 AM,  <peter.marien@cm.be> wrote:
> Tried this example, it needs still some window height manipulation since
> eventually the rectangles scroll of the screen and there is no scrollbar.
>
>
>
> Shoes.app do
>
>
>
>   y=0
>
>
>
>   def rectangle(x, y)
>
>     rect x*50, y*50, 40, 40, :fill => red
>
>   end
>
>
>
>   button "Action" do
>
>     y=y+1
>
>     5.times do |x|
>
>       rectangle(x, y)
>
>     end
>
>   end
>
>
>
> end
>
>
>
> Peter

Re: [shoes] How can I generate multiple rectangles

From:
J. Kaiden
Date:
2012-01-11 @ 01:08
hi Fily,

  so here's the thing (and it's a bit confusing, so don't be frustrated...)

  there are two ways to keep your rectangles from being drawn on top of
each other.

  one, as Peter suggested, is to move each rectangle to a new position when
it is created...  you could do what Peter mentioned, or something like this
(basically the same)...

Shoes.app do

@x = 0  # this is the horizontal position, that will be changed

def rectangle
     fill red
r = rect 30, 30, 40, 40
r.move(@x, 0)  # the first rectangle is drawn at @x,0  (@x is initially
zero)
@x += 50  # and the next will be drawn at the current position +50 pixels
end
 button "Action" do
5.times do
rectangle
end
para rectangle.width
end

end

  ...so, this works - but the problem is that the red rectangles you draw
don't flow naturally - they just keep marching off to the right into
infinity, and you end up not being able to see them all.

  the way to think of this is that you want each rectangle to be drawn in
its own container (a stack or flow,) and that way, when they reach the edge
of the window, they will automagically scroll to the next row in typical
Shoes awesomeness - something simple like this could be a HUGE deal in
other gui toolkits!

  so, like i mentioned before - think of the method where you define the
red rectangle as a factory, where you crank out red rectangles to order.

  if you had a factory where you manufactured rubber chickens, you wouldn't
just send your rubber chickens all over the world for distribution without
some kind of packaging...  you'd need a nice package, maybe a piece of
brightly colored cardboard that read "Fily's Freakin' Plastic Chicken' with
some shrink wrapped plastic over it.

  the 'packaging' in Shoes is typically a slot (that is to say a `flow` or
a `stack`) with some dimensions assigned to it.  the dimensions are
important.  you can't just package your rubber chickens on any old size
piece of colored cardboard and expect them to ship well.   you want each
package to be the same size, so that they fit well into the containers that
take them all over the world (in this case the Shoes.app...)

  let's package the red rectangles, they deserve it...  create a slot - in
this case it doesn't matter whether we choose a flow or a stack, but in
some cases it does.  a flow is basically a horizontal box that fills from
left to right, and a stack is more or less a vertical box that fills from
top to bottom.  anyway, let's choose a flow in this case...  so, instead of
just calling the rectangle method, we put that call inside a flow:

Shoes.app do
 def rectangle
         ##  THIS NEXT LINE IS IMPORTANT!
 flow width: 60, height: 60 do
        ## the above line sets the dimensions of our `package`, so that
everything works nicely
fill red
r = rect 30, 30, 40, 40
end
end
 button "Action" do
5.times do
rectangle
end
para rectangle.width
end

end

  run this script...

  see the difference?  now our red rectangles are nicely packaged in
cardboard and shrinkwrap, and pack into the main app just the way we would
expect.

  this stuff can be kind of confusing...  don't be discouraged - Shoes is
awesome...  really awesome - you just have to get the hang of it.

  make sure to check out ash's awesome samples here -
http://shoes-tutorial-note.heroku.com/.  you could also take a look at the
widget wiki here - https://github.com/lljk/shoes-stuff/wiki/Shoes-Widgets -
and the random stuff here - https://github.com/lljk/shoes-stuff - sorry if
the last two are shameless ;)

  get back with any other questions you have - to me the best thing about
Shoes is the community...

  rock and roll,

  - j





On Wed, Jan 11, 2012 at 1:00 AM, Filemon Salas <fs.dolphin@gmail.com> wrote:

> Shoes.app do
>   y=0
>   def rectangle(x, y)
>     rect x*50, y*50, 40, 40, :fill => red
>   end
>
>   button "Action" do
>     y=y+1
>     5.times do |x|
>       rectangle(x, y)
>     end
>   end
> end
>
> Grrr, I'm so confused trying to understand how this code is working.
> y=0 (why?)
> rect x*50, y*50 (why?)
> y=y+1 ?
> rectangle(x, y) ?
>
> soorrry, in genereal I dont know understand the whole code (I know, I
> know), can someone be so kind and explain line by line?
>
> are x and y some how the current position or something like that or
> whats the value?
>
> Thanks a lot
>
>
> On Tue, Jan 10, 2012 at 4:29 AM,  <peter.marien@cm.be> wrote:
> > Tried this example, it needs still some window height manipulation since
> > eventually the rectangles scroll of the screen and there is no scrollbar.
> >
> >
> >
> > Shoes.app do
> >
> >
> >
> >   y=0
> >
> >
> >
> >   def rectangle(x, y)
> >
> >     rect x*50, y*50, 40, 40, :fill => red
> >
> >   end
> >
> >
> >
> >   button "Action" do
> >
> >     y=y+1
> >
> >     5.times do |x|
> >
> >       rectangle(x, y)
> >
> >     end
> >
> >   end
> >
> >
> >
> > end
> >
> >
> >
> > Peter
>

Re: [shoes] How can I generate multiple rectangles

From:
Filemon Salas
Date:
2012-01-11 @ 02:31
As always thank a lot for helping me.

I think the main think I dont know understand is what properties of
the rect are available and what properties of the stage itself are
also available. The sample below kind of make sense since you are
using the method "move".

Shoes.app do
	@xPos = 0
        @yPos = 0
      	def rectangle
	     fill red
		r = rect 30, 30, 40, 40
		r.move(@xPos, @yPos)
		@xPos += 50
                @yPos += 50
	end
	button "Action" do
10.times do
    rectangle
   end
 end
end

But I'm still wondering about how does Shoes know that we are
referring to the x and y position of our rectanlges...

Shoes.app do
  y=0
  def rectangle(x, y) #How does Shoes know that we are referring to
the x and y position of the rectangle?
    rect x*50, y*50, 40, 40 # Whats the value of x and y?
  end

  button "Action" do
    y=y+1 # is this the same variable from the top, shouldn't this be
an instance variable(@y)?
    5.times do |x|
      rectangle(x, y) #again x and y?
    end
  end
end

I love how simple Shoes is but I need to understand it better.

Thanks





On Tue, Jan 10, 2012 at 7:08 PM, J. Kaiden <jakekaiden@gmail.com> wrote:
> hi Fily,
>
>   so here's the thing (and it's a bit confusing, so don't be frustrated...)
>
>   there are two ways to keep your rectangles from being drawn on top of each
> other.
>
>   one, as Peter suggested, is to move each rectangle to a new position when
> it is created...  you could do what Peter mentioned, or something like this
> (basically the same)...
>
> Shoes.app do
>
> @x = 0  # this is the horizontal position, that will be changed
>
> def rectangle
>      fill red
> r = rect 30, 30, 40, 40
> r.move(@x, 0)  # the first rectangle is drawn at @x,0  (@x is initially
> zero)
> @x += 50  # and the next will be drawn at the current position +50 pixels
> end
> button "Action" do
> 5.times do
> rectangle
> end
> para rectangle.width
> end
>
> end
>
>   ...so, this works - but the problem is that the red rectangles you draw
> don't flow naturally - they just keep marching off to the right into
> infinity, and you end up not being able to see them all.
>
>   the way to think of this is that you want each rectangle to be drawn in
> its own container (a stack or flow,) and that way, when they reach the edge
> of the window, they will automagically scroll to the next row in typical
> Shoes awesomeness - something simple like this could be a HUGE deal in other
> gui toolkits!
>
>   so, like i mentioned before - think of the method where you define the red
> rectangle as a factory, where you crank out red rectangles to order.
>
>   if you had a factory where you manufactured rubber chickens, you wouldn't
> just send your rubber chickens all over the world for distribution without
> some kind of packaging...  you'd need a nice package, maybe a piece of
> brightly colored cardboard that read "Fily's Freakin' Plastic Chicken' with
> some shrink wrapped plastic over it.
>
>   the 'packaging' in Shoes is typically a slot (that is to say a `flow` or a
> `stack`) with some dimensions assigned to it.  the dimensions are important.
>  you can't just package your rubber chickens on any old size piece of
> colored cardboard and expect them to ship well.   you want each package to
> be the same size, so that they fit well into the containers that take them
> all over the world (in this case the Shoes.app...)
>
>   let's package the red rectangles, they deserve it...  create a slot - in
> this case it doesn't matter whether we choose a flow or a stack, but in some
> cases it does.  a flow is basically a horizontal box that fills from left to
> right, and a stack is more or less a vertical box that fills from top to
> bottom.  anyway, let's choose a flow in this case...  so, instead of just
> calling the rectangle method, we put that call inside a flow:
>
> Shoes.app do
> def rectangle
>          ##  THIS NEXT LINE IS IMPORTANT!
> flow width: 60, height: 60 do
>         ## the above line sets the dimensions of our `package`, so that
> everything works nicely
> fill red
> r = rect 30, 30, 40, 40
> end
> end
> button "Action" do
> 5.times do
> rectangle
> end
> para rectangle.width
> end
>
> end
>
>   run this script...
>
>   see the difference?  now our red rectangles are nicely packaged in
> cardboard and shrinkwrap, and pack into the main app just the way we would
> expect.
>
>   this stuff can be kind of confusing...  don't be discouraged - Shoes is
> awesome...  really awesome - you just have to get the hang of it.
>
>   make sure to check out ash's awesome samples here -
>  http://shoes-tutorial-note.heroku.com/.  you could also take a look at the
> widget wiki here - https://github.com/lljk/shoes-stuff/wiki/Shoes-Widgets -
> and the random stuff here - https://github.com/lljk/shoes-stuff - sorry if
> the last two are shameless ;)
>
>   get back with any other questions you have - to me the best thing about
> Shoes is the community...
>
>   rock and roll,
>
>   - j
>
>
>
>
>
> On Wed, Jan 11, 2012 at 1:00 AM, Filemon Salas <fs.dolphin@gmail.com> wrote:
>>
>> Shoes.app do
>>   y=0
>>   def rectangle(x, y)
>>     rect x*50, y*50, 40, 40, :fill => red
>>   end
>>
>>   button "Action" do
>>     y=y+1
>>     5.times do |x|
>>       rectangle(x, y)
>>     end
>>   end
>> end
>>
>> Grrr, I'm so confused trying to understand how this code is working.
>> y=0 (why?)
>> rect x*50, y*50 (why?)
>> y=y+1 ?
>> rectangle(x, y) ?
>>
>> soorrry, in genereal I dont know understand the whole code (I know, I
>> know), can someone be so kind and explain line by line?
>>
>> are x and y some how the current position or something like that or
>> whats the value?
>>
>> Thanks a lot
>>
>>
>> On Tue, Jan 10, 2012 at 4:29 AM,  <peter.marien@cm.be> wrote:
>> > Tried this example, it needs still some window height manipulation since
>> > eventually the rectangles scroll of the screen and there is no
>> > scrollbar.
>> >
>> >
>> >
>> > Shoes.app do
>> >
>> >
>> >
>> >   y=0
>> >
>> >
>> >
>> >   def rectangle(x, y)
>> >
>> >     rect x*50, y*50, 40, 40, :fill => red
>> >
>> >   end
>> >
>> >
>> >
>> >   button "Action" do
>> >
>> >     y=y+1
>> >
>> >     5.times do |x|
>> >
>> >       rectangle(x, y)
>> >
>> >     end
>> >
>> >   end
>> >
>> >
>> >
>> > end
>> >
>> >
>> >
>> > Peter
>
>

Re: [shoes] How can I generate multiple rectangles

From:
J. Kaiden
Date:
2012-01-11 @ 03:47
hey Fily -

  some of these are kind of ruby questions, but that's no problem - Shoes
is ruby is Shoes!

  others can probably explain this better, but i'll give it a shot...

But I'm still wondering about how does Shoes know that we are
> referring to the x and y position of our rectanlges...
>
> Shoes.app do
>  y=0
>  def rectangle(x, y) #How does Shoes know that we are referring to
> the x and y position of the rectangle?
>

  this is not a Shoes thing, but a ruby thing.  how does ruby know that we
are referring to x and y position?  because we're telling it so!  ;)

  before we get to that, it's important to note that in the bit above the
 `y`  in `y = 0`, and the  `y`  in  `def rectangle(x, y)`  are not in any
way related.  this is really important!!

  in `y = 0`, you are assigning a local variable `y` the value 0.

  in `def rectangle(x, y)`  you are declaring the name of a method, and the
parameters that it will take - in this case `x`, and `y`...  look at this:

def draw_a_rectangle_somewhere(pixels_from_left, pixels_from_top)
fill red
r = rect(30, 30, 40, 40)
r.move(pixels_from_left, pixels_from_top)
end

  now you could do something like this:

draw_a_rectangle_somewhere(120, 50)

  ruby doesn't tell you what `pixels_from_left` and `pixels_from_right` are
- you tell ruby what they are!  they're just variables that you're going to
use in your method definition.

  so, using this method, we could do something like this:

Shoes.app do
 def draw_a_rectangle_somewhere(pixels_from_left, pixels_from_top)
fill red
r = rect(30, 30, 40, 40)
r.move(pixels_from_left, pixels_from_top)
end
 button("rectangle army") do
50.times do
draw_a_rectangle_somewhere(rand(560), rand(460))
end
end
end

  each time (of the 50 times) that we call the rectangle method, we assign
a random number to the `pixels_from_left` and `pixels_from_top` variables,
and draw the sucker.  cool right?


   y=y+1 # is this the same variable from the top, shouldn't this be
> an instance variable(@y)?


  exactly!  your confusion actually means that you are understanding things
better!  ;)

  `y` is _not_ the same variable from the top if it is inside a method
definition.  check out some stuff about variable scope in ruby (like this
for example: http://www.techotopia.com/index.php/Ruby_Variable_Scope )

  another way to approach this is to pass variables into the rectangle
method definition, and if we do that, they've got to be instance variables
as you noted.  so you could do something like this:

Shoes.app do

@x = 0
@y = 0
 def draw_a_rectangle_somewhere
fill red
r = rect(30, 30, 40, 40)
r.move(@x, @y)  # the first rectangle will be drawn at 0, 0
@x = rand(560)  # and then we reset the instance variables
@y = rand(460)  # @x and @y to random values
end
 button("rectangle army") do
50.times do
draw_a_rectangle_somewhere
end
end
end

  same result, different way of getting there...

  is it making any more sense?


> I love how simple Shoes is but I need to understand it better.
>

  me too!

  - j

Re: [shoes] How can I generate multiple rectangles

From:
Filemon Salas
Date:
2012-01-11 @ 11:12
It starting to make sense, I just wanted to make sure the x and y
parameters were not Shoes' stage properties, as is in Flash.

Thanks a lot for your help!


On Tue, Jan 10, 2012 at 9:47 PM, J. Kaiden <jakekaiden@gmail.com> wrote:
> hey Fily -
>
>   some of these are kind of ruby questions, but that's no problem - Shoes is
> ruby is Shoes!
>
>   others can probably explain this better, but i'll give it a shot...
>
>> But I'm still wondering about how does Shoes know that we are
>> referring to the x and y position of our rectanlges...
>>
>> Shoes.app do
>>  y=0
>>  def rectangle(x, y) #How does Shoes know that we are referring to
>> the x and y position of the rectangle?
>
>
>   this is not a Shoes thing, but a ruby thing.  how does ruby know that we
> are referring to x and y position?  because we're telling it so!  ;)
>
>   before we get to that, it's important to note that in the bit above the
>  `y`  in `y = 0`, and the  `y`  in  `def rectangle(x, y)`  are not in any
> way related.  this is really important!!
>
>   in `y = 0`, you are assigning a local variable `y` the value 0.
>
>   in `def rectangle(x, y)`  you are declaring the name of a method, and the
> parameters that it will take - in this case `x`, and `y`...  look at this:
>
> def draw_a_rectangle_somewhere(pixels_from_left, pixels_from_top)
> fill red
> r = rect(30, 30, 40, 40)
> r.move(pixels_from_left, pixels_from_top)
> end
>
>   now you could do something like this:
>
> draw_a_rectangle_somewhere(120, 50)
>
>   ruby doesn't tell you what `pixels_from_left` and `pixels_from_right` are
> - you tell ruby what they are!  they're just variables that you're going to
> use in your method definition.
>
>   so, using this method, we could do something like this:
>
> Shoes.app do
> def draw_a_rectangle_somewhere(pixels_from_left, pixels_from_top)
> fill red
> r = rect(30, 30, 40, 40)
> r.move(pixels_from_left, pixels_from_top)
> end
> button("rectangle army") do
> 50.times do
> draw_a_rectangle_somewhere(rand(560), rand(460))
> end
> end
> end
>
>   each time (of the 50 times) that we call the rectangle method, we assign a
> random number to the `pixels_from_left` and `pixels_from_top` variables, and
> draw the sucker.  cool right?
>
>
>>    y=y+1 # is this the same variable from the top, shouldn't this be
>> an instance variable(@y)?
>
>
>   exactly!  your confusion actually means that you are understanding things
> better!  ;)
>
>   `y` is _not_ the same variable from the top if it is inside a method
> definition.  check out some stuff about variable scope in ruby (like this
> for example: http://www.techotopia.com/index.php/Ruby_Variable_Scope )
>
>   another way to approach this is to pass variables into the rectangle
> method definition, and if we do that, they've got to be instance variables
> as you noted.  so you could do something like this:
>
> Shoes.app do
>
> @x = 0
> @y = 0
> def draw_a_rectangle_somewhere
> fill red
> r = rect(30, 30, 40, 40)
> r.move(@x, @y)  # the first rectangle will be drawn at 0, 0
> @x = rand(560)  # and then we reset the instance variables
> @y = rand(460)  # @x and @y to random values
> end
> button("rectangle army") do
> 50.times do
> draw_a_rectangle_somewhere
> end
> end
> end
>
>   same result, different way of getting there...
>
>   is it making any more sense?
>
>>
>> I love how simple Shoes is but I need to understand it better.
>
>
>   me too!
>
>   - j

Re: [shoes] How can I generate multiple rectangles

From:
J. Kaiden
Date:
2012-01-10 @ 03:27
hi Fily,

  your code is close... but i would take the rectangle definition out of
the button click event, think of the rectangle method as a rectangle making
machine that will churn out as many rectangles as you want...

  ...so, you might do something like this:

Shoes.app do
 def rectangle
fill red
rect 30, 30, 40, 40
end
 button "Action" do
5.times do
rectangle
end
para rectangle.width
end

end

  ...(i moved the para call out of the 5.times loop so it would only print
once...)

  anyway, now you've got the rectangle method outside of the button click,
just waiting to be called on and draw rectangles.  this is great.  so you
click on the button, hoping to create 5 rectangles and...  what the heck?
 there's only one...

  actually, there are 5 (if you only clicked once!)  it's just that they've
all been drawn on  top of each other in the same spot.  this might seem a
bit strange, but if you just stick the rectangle inside a slot (a flow or a
stack,) and give that slot some dimensions - then your rectangles will line
up nicely side by side...

  change `def rectangle` to look like this:

def rectangle
 flow width: 60, height: 60 do
fill red
rect 30, 30, 40, 40
end
end

  ...and i think you'll see more what you expected.

  hth -

  - j