librelist archives

« back to archive

widget flow weirdness...

widget flow weirdness...

From:
J. Kaiden
Date:
2011-08-18 @ 12:43
hey folks -

  noticed something interesting while fiddling around with widgets.  if i do
this:
#
class StarBox < Shoes::Widget
def initialize
stack height: 130, fill: red do
star(50, 60, 5, 25, 10)
end
self.style(width: 160)
end
end

Shoes.app do
9.times{star_box}
end
#

  ...the widgets are laid out in the Shoes.app flow as i would expect them
to be - flowing from left to right until there's no more room, then moving
down and continuing.  that's great, but notice that i've split up the way
the width and height are defined for the widget.  the height is declared as
an attribute in the StarBox stack, and the width with the #style method...
strange things happen if i declare the width and height in what would seem
to me to be a more 'normal' way.  if both are declared as attributes to the
StarBox stack like so:
#
...
     stack width: 160, height: 130, fill: red do
...
#

  ...the widgets are laid out top to bottom, and do not flow left to right.

   if both width and height are declared in the call to #style, like this:
#
...
     self.style(width: 160, height: 130)
...
#

  ...the widgets are laid out left to right - but instead of moving down and
continuing when out of window space, they are hidden until the window is
made wider.

  furthermore, if i switch and declare the width as an attribute to the
StarBox stack, and the height with a call to #style, the widgets are all
placed on top of each other in the top left corner of the window.

  what the heck's going on here?  i'm happy that the first example gives me
a widget that behaves like, well, a widget - but i don't understand why the
other examples don't.

  any ideas/explanations?

  thanks,

 - j

Re: [shoes] widget flow weirdness...

From:
Steve Klabnik
Date:
2011-08-18 @ 13:29
I'm not sure, looks like you're finding some edge cases and some
bugs... I'd have to do some source diving to figure this one out, I
think.

Re: [shoes] widget flow weirdness...

From:
J. Kaiden
Date:
2011-08-18 @ 13:59
On Thu, Aug 18, 2011 at 3:29 PM, Steve Klabnik <steve@steveklabnik.com>wrote:

> I'm not sure, looks like you're finding some edge cases and some
> bugs... I'd have to do some source diving to figure this one out, I
> think.
>

  I'm happy to accept a bit of weirdness - just didn't know if I was missing
something obvious!

  I've got another question - sorry if in trying to help out with
documentation I'm ending up being a pain in the arse  ;)

  When I call #click on a newly created widget instance from within the
Shoes.app, it affects all of the instances of that widget:

  Shoes.app do
a = star_box
b = star_box
a.click{para "A", stroke: red}
  end


  Both a & b react to the click.  If I add another line:

b.click{para "B", stroke: green}

  Both a & b return a green B...  I'm somehow defining #click for the whole
StarBox class rather than for individual instances.  This seems strange to
me.... what am I missing here?

  thanks again,

  - J

Re: [shoes] widget flow weirdness...

From:
J. Kaiden
Date:
2011-08-18 @ 15:17
>
>
>   When I call #click on a newly created widget instance from within the
> Shoes.app, it affects all of the instances of that widget:
>
> ...  I'm somehow defining #click for the whole StarBox class rather than
> for individual instances.  This seems strange to me.... what am I missing
> here?
>
>
  worked around this problem like this:

class StarBox < Shoes::Widget
def initialize
stack height: 130, fill: red do
star(50, 60, 5, 25, 10)
end
self.style(width: 160)
self.click{yield if block_given?}
end
end

Shoes.app do
a = star_box{para "A", stroke: yellow}
b = star_box{para "B", stroke: green}
end
#

  ...though I still don't understand why calling #click{} from within the
Shoes.app works the way it does...

 - j

Re: [shoes] widget flow weirdness...

From:
Steve Klabnik
Date:
2011-08-18 @ 16:54
>   I've got another question - sorry if in trying to help out with
> documentation I'm ending up being a pain in the arse  ;)

There is never any reason to be sorry. :) Nailing down exactly where
there's weirdness is the first step towards fixing it.

Re: [shoes] widget flow weirdness...

From:
ashbb
Date:
2011-08-19 @ 12:01
Hi J, Steve and folks,

I think that the widgets are laid out by the rules of Red Shoes.
So, what rules? .... It's not easy to explain in English for me. :(

At first, the stack is not the widget itself, just an element within the
widget.
Hence, look at the following, a) and c) are equivalent, but b) is different.

a)
 def initialize
   stack width: 160 do
   end
 end

b)
 def initialize
   stack do
   end
   self.style width: 160
 end

c)
 def initialize
   s = stack do
   end
   s.style width: 160
 end

And then, Shoes calculates the values of width/height for the stack and the
widget itself. But if Shoes can't understand the values, Shoes uses 0 (zero)
value.
So, it's better to set the values explicitly like this:

d)
 def initialize
   stack width: 160, height: 130 do
   end
   self.style width: 160, height: 130
 end

Umm,... sorry, my poor English...

Hope this helps,
ashbb

Re: [shoes] widget flow weirdness...

From:
J. Kaiden
Date:
2011-08-19 @ 21:46
hey ashbb -

  your english is great, and MUCH better than my japanese - so don't worry!

  thanks for answering - your explanation makes good sense, and declaring
both the width and the height in both places - i.e.:

class StarBox < Shoes::Widget
def initialize
stack width: 160, height: 130, fill: red do
star(50, 60, 5, 25, 10)
end
self.style(width: 160, height: 130)
end
end

  ...lays out the widgets as i would expect them to be, and somehow seems
more satisfying to me than putting the height in one place and the width in
another - i'll roll with that.

  i guess what i found was a quirk in which you can declare the height in
the stack, and the width with #style, and still have it lay out correctly...
 go figure ;)

  thanks again - i've got something of a widget tutorial going that should
be ready soon...  i'll let you all know when it's done.

  - j

Re: [shoes] widget flow weirdness...

From:
ashbb
Date:
2011-08-19 @ 12:03
Hi J and folks,

About your 'another question'.
I think that it also not a bug. But it's a more deep question. ;-)

At first, your StarBox widget has no `click` method.
Because you didn't define `click` method within class StarBox.

Why does it work?
Because Shoes defines method_missing method for Widget class.
And it passes `click` method to the app object.
So, even if you write the following two lines,

  a.click{para "A", stroke: red}
  b.click{para "B", stroke: green}

Shoes thinks that you order twice (override the orders).
Hence, it works, when you click anywhere on the whole window.

So, if you define `click` method for StarBox class like this,
it will work as you expect. ;-)

class StarBox < Shoes::Widget
 def initialize
   @s = stack height: 130, width: 160, fill: red do
     border green
     star(50, 60, 5, 25, 10)
   end
   self.style width: 160, height: 130
 end
 def click
   @s.click{yield}
 end
end

Shoes.app do
 a = star_box
 b = star_box
 a.click{para "A", stroke: red}
 b.click{para "B", stroke: green}
end

Hope you understand my poor English,
ashbb

Re: [shoes] widget flow weirdness...

From:
J. Kaiden
Date:
2011-08-19 @ 21:51
On Fri, Aug 19, 2011 at 2:03 PM, ashbb <ashbbb@gmail.com> wrote:

> Hi J and folks,
>
> About your 'another question'.
> I think that it also not a bug. But it's a more deep question. ;-)
>
> At first, your StarBox widget has no `click` method.
> Because you didn't define `click` method within class StarBox.
>
> Why does it work?
> Because Shoes defines method_missing method for Widget class.
> And it passes `click` method to the app object.
>


hey ashbb -

  thanks for getting back about this one too - and again, the explanation
makes perfect sense...

  thanks again for the help -

  - j