PDA

View Full Version : Using ignorelayout in a class


sfarrow
07-17-2003, 05:03 AM
We have been putting together our own version of a combobox component and have encountered a problem with layouts as they apply to the dropdown view of the component. Here are a couple examples to illustrate the problem.

In this first example, clicking on the red box presents a green dropdown. Clicking again dismisses it. The green dropdown view has been told to ignore layouts and as such overlaps the blue view as expected. All is good!

<view name="spike1" x="0" >
<simplelayout spacing="2"/>
<view width="200" height="25" bgcolor="yellow" />
<view name="red" width="200" height="25"
bgcolor="red" clickable="true">
<method event="onclick">
canvas.spike1.green.bringToFront();
canvas.spike1.green.setHeight(
canvas.spike1.green.getHeight() == 0 ? 80 : 0 );
</method>
</view>
<view name="green"
y="canvas.spike1.red.y+canvas.spike1.red.height"
width="200" height="0" bgcolor="green"
options="ignorelayout"/>
<view width="200" height="25" bgcolor="blue" />
</view>

I now take the red view and the green dropdown view and wrap them in a class as I move toward creating a reusable component. Clicking on the red view now inserts the green view in the layout and pushes the blue view down to accommodate it. Not what I was hoping for.

<class name="dropdown">
<view name="red" width="200" height="25"
bgcolor="red" clickable="true">
<method event="onclick">
classroot.green.bringToFront();
classroot.green.setHeight(
classroot.green.getHeight() == 0 ? 80 : 0 );
</method>
</view>
<view name="green"
y="classroot.red.y+classroot.red.height"
width="200" height="0" bgcolor="green"
options="ignorelayout"/>
</class>

<view name="spike2" x="250">
<simplelayout spacing="2"/>
<view width="200" height="25" bgcolor="yellow" />
<dropdown />
<view width="200" height="25" bgcolor="blue" />
</view>

Is there any way to get the class to behave in the same way as the non-class version and still retain the encapsulation required for a component?

Thanks.

antun
07-17-2003, 09:16 AM
When you create a view it has 0 height and 0 width:


<view name="myView" />


If you put something in the above view that's 100px high, then it will stretch to accomodate its contents unless you explicitly set its height, so:


<view name="myView">
<view height="100" width="100" />
</view>


In the above case myView will be 100px high by 100px wide, but:


<view height="10" name="myView">
<view height="100" width="100" />
</view>


Now myView will be 10px high. You'll still be able to see its child view in its entirety, unless you set myView's clip attribute to true.

This was happening in your code, and because of the <simplelayout /> the blue view would move down, because the dropdown's encasing view (i.e. the <class> tag) would stretch. To avoid this:


<canvas>
<class name="dropdown" height="25">
<view name="red" width="200" height="25"
bgcolor="red" clickable="true">
<method event="onclick">
classroot.bringToFront();
// not sure you need this:
classroot.green.bringToFront();
classroot.green.setHeight(
classroot.green.getHeight() == 0 ? 80 : 0 );
</method>
</view>
<view name="green"
y="classroot.red.y+classroot.red.height"
width="200" height="0" bgcolor="green"
options="ignorelayout"/>
</class>

<view name="spike2" x="250">
<simplelayout spacing="2"/>
<view width="200" height="25" bgcolor="yellow" />
<dropdown />
<view width="200" height="25" bgcolor="blue" />
</view>
</canvas>


-Antun

sfarrow
07-17-2003, 09:29 AM
Embarassingly simple solution! Thanks antun.

Next hurdle: How do I bring the green view up in front of the blue view?

antun
07-17-2003, 09:33 AM
If you look in my previous post, the second red-highlighted bit is what you need, i.e.


classroot.bringToFront();


It was there originally, but I messed up the forums-markup feature so it didn't come out red the first time you looked at it. I've edited the post.

On that note, when you're posting code, it helps to wrap it in code tags - see here:

http://www.laszlosystems.com/developers/community/forums/misc.php?action=bbcode#buttons

-Antun

sfarrow
07-17-2003, 09:33 AM
Sorry antun, I now see it in your reply. Works great!

sfarrow
07-17-2003, 12:13 PM
Ran into another snag with the zorder of the green view. If the dropdown is within another view (or any number of views), how can I ensure that my green view appears in front of all of them?


<canvas>
<class name="dropdown" height="25">
<view name="red" width="200" height="25"
bgcolor="red" clickable="true">
<method event="onclick">
classroot.bringToFront();
classroot.green.bringToFront();
classroot.green.setHeight(
classroot.green.getHeight() == 0 ? 80 : 0 );
</method>
</view>
<view name="green"
y="classroot.red.y+classroot.red.height"
width="200" height="0" bgcolor="green"
options="ignorelayout"/>
</class>

<view name="spike2" x="250">
<simplelayout spacing="2"/>
<view width="200" height="25" bgcolor="yellow" />
<view>
<dropdown />
</view>
<view width="200" height="25" bgcolor="blue" />
</view>
</canvas>

antun
07-17-2003, 01:56 PM
This is really similar to the following issue:

http://www.laszlosystems.com/developers/community/forums/showthread.php?s=&threadid=229#post773

Basically when you declare your new combobox class, you'll have to pass it a pointer to the view it needs to bring to the front of all views, as right now there isn't a way to break a view out of the view hierarchy altogether.

You no longer need to use the very verbose <attribute> syntax in every declaration of your <dropdown> class, you should just be able to use the $once{} syntax. See here for more on that:

http://www.laszlosystems.com/developers/community/forums/showthread.php?s=&threadid=263

-Antun