Blind Effect

In LiveCode the use of groups of controls allows us to write general UI controls that can be easily extended by editing the content of the individual groups, without affecting any overall functionality. This lesson is about writing a blind effect, where one can click on a blind pane such that the blind opens up pushing the underlying blind panes down in the process.

You can download the sample stack from this url: https://tinyurl.com/y9a2blzg

Creating the basic elements

Creating the basic elements

First we need to start by creating a UI element template. We can then clone this template to create a list of elements making up our blind.

Open a new stack and start off by creating two rectangular graphics, that will form the backgrounds of our element. We place these underneath each other so that we can see what the blind element would look like in its extended form.

Grouping the elements

Grouping the elements

We then group both rectangles separately naming the top group "Main" and the lower one "Slider", as it will be the group that "slides" out. We group both of these groups together in an umbrella group we shall call "Element Template".

We do not wish our groups to have any visible margins, so we set the margins of all our groups to 0. (You can do this by going to the "Text Formatting" pane of the property inspector, or issuing the command directly in the message box).

set the margins of group "Element Template" to 0

Showing and hiding the sliding pane

Now we have the two groups inside the "Element Template" group, we wish to add the sliding functionality. To allow our groups to open and close we add a button to the "main" group, name it "slide", set its label to "+" and add a mouseUp handler to the button script.

The mouseUp handler toggles the label of the button between + and - and shows or hides the sliding pane.

on mouseUp
	if the label of me is "+" then
		showMe
		set the label of me to "-"
	else
		hideMe
		set the label of me to "+"
	end if
end mouseUp

Showing and hiding the sliding pane (2)

The showMe and hideMe handlers called in the "slide" button script are passed up the message path until they reach the "Element Template" group where they are handled.

on showMe 
	repeat while the top of group "Slider" of me < the bottom of group "Main" of me - 4
		set the bottom of group "Slider" of me to the bottom of group "Slider" of me + 4
		wait 10 milliseconds with messages 
	end repeat 
end showMe
on hideMe
	repeat while the bottom of group "Slider" of me > the bottom of group "Main" of me
		set the bottom of group "Slider" of me to the bottom of group "Slider" of me - 4
		wait 10 milliseconds with messages
	end repeat
end hideMe

Both handlers work similarly:

repeat whilst the slider is [in]visible

move slider up[down] by 4 pixels.

Notice that "me" here is the "Element Template" group, which contains the groups "Slider" and "Main". As we do not want to unnecessarily lock up messages we wait 10 milliseconds with messages, this allows normal processing to continue during the wait.

Using lockLocation

If the height of your "Slider" group is greater than the height of group "Main" you will notice that the slider group moves behind but past the "Main" group. Thus, in order to avoid this we will make some handy use of group clipping in LiveCode. In addition, we will also make use of the fact that if a group's "lockLoc" property is set to true and we set the height of the group to a lesser value, the top of the group remains the same.

Thus, make sure that lockLoc is set to true for group "Element Template". You can do this in the Size & Position pane of the Property Inspector of the group or in the message box

set the lockLoc of group "Element Template" to true

Unless otherwise required by your program, it is recommended you lockLoc all your controls in the template to avoid any unexpected results. If you need to temporarily move a control, you can unlock it in the property inspector, move the control, and lock it again.

In order to make the clipping work, when the slider is moving up or down, we need to adjust the height of the group "Element Template". By setting lockLoc to true, the top of this group stays fixed so that the Slider group can move past this top causing clipping to occur.

Updated showMe and hideMe

on showMe
	repeat while the top of group "Slider" of me < the bottom of group "Main" of me - 4
		lock screen
		set the bottom of group "Slider" of me to the bottom of group "Slider" of me + 4
		set the height of me to the height of me + 4
		layoutChanged the short name of me, 4
		unlock screen
		wait 10 milliseconds with messages
	end repeat
end showMe
on hideMe
	repeat while the bottom of group "Slider" of me > the bottom of group "Main" of me
		lock screen
		set the bottom of group "Slider" of me to the bottom of group "Slider" of me - 4
		set the height of me to the height of me - 4
		layoutChanged the short name of me, -4
		unlock screen
		wait 10 milliseconds with messages
	end repeat
end hideMe

Using multiple elements

Using multiple elements

We added the line layoutChanged, that can be intercepted higher up in the message path. So, in order to intercept this message, we first need to create a list of elements, group those and put a layoutChanged handler in this new group.

For reasons of simplicity we shall create a list manually, but this can of course be easily automated with individual list elements depending on certain data.

So, let's clone the "Element Template" group. You can do this very easily in the IDE by holding down Option on Mac or Ctrl on the PC and dragging the "Element Template" group to another location. You will see that instead a copy is made. Name this new copy "Element 1", we will make handy use of the fact that word 2 of the name is a number so that for all subsequent template clones we increment this number thus creating groups "Element 2" to "Element 4".

After having created 4 elements in this fashion, we group all of these together by selecting them in the IDE and clicking the "group" button. Call the new umbrella group "List". We may wish to make this "List" group slightly wider, so to allow space for a scrollbar for example. After having done this make sure you set the lockLoc property to true again.

A working blind effect

A working blind effect

We may now see a list of four elements, however, the sliding functionality no longer works, because the other elements do not yet move and thus overlap any sliders.

To make sure that the sliders work in group "List", we add the layoutChanged handler to its script:

on layoutChanged pGroup, pSize
	lock messages
       
	local tElementCount
       
	if pGroup is "Element Template" then 
		exit layoutChanged
	else
		put word 2 of pGroup into tElementCount
		add 1 to tElementCount -- look for the next one
		repeat while there is a group ("Element" && tElementCount)
			set the top of group ("Element" && tElementCount) to the top of group ("Element" && tElementCount) + pSize
			add 1 to tElementCount
		end repeat 
       
		set the vscroll of me to the vscroll of me
		unlock messages
	end if
end layoutChanged

pGroup is the group whose slider is moving by a number of pSize pixels (be it up or down). So, because the layout has changed by pSize, we need to adjust the top of each group coming after the one that sent the message layoutChanged accordingly.

We now have a working blind effect!

In order to speed things up it is a good idea to use "lock screen". This will defer a screen refresh until unlock screen or the end of a handler for that matter is encountered.

Adding a scrollbar to the list

Adding a scrollbar to the list

We may now have a blind effect, however, we are left with the problem of content moving out of view in the group "List". To resolve this, we need to update the scrolling of the "List" group accordingly in the layoutChanged handler of the card.

we add the following lines of code to the layoutChanged handler of the card at the end:

if the bottom of group pGroup of me > the bottom of me then
	set the scroll of me to the scroll of me + pSize
end if

Thus, if the bottom of one of our list elements becomes greater than the bottom of group "List", we need to update the scroll of the umbrella "List" group, so that the element stays in view.

Finally, we wish to make sure that the scrollbar is only present if we need it, to achieve this, we can add the following lines to the layoutChanged handler:

set the vScrollBar of group "List" to the formattedHeight of group "List" > the height of group "List"
set the vScroll of group "List" to the vScroll of group "List"

in other words, if the height of the contents in full is greater than the visible height of the group, we need to allow scrolling, else disallow it.

The second line makes sure that the scroll of the field gets updated correctly, as its contents change size. In other words this forces an update of the scrolling of the field.

Further improvements

Further improvements

It is really easy to create UI controls in LiveCode. The great advantage of the above example is that it mainly made use of group controls, this means that we can add anything we like to our "Main" and "Slider" groups, yet maintaining the functionality we created without any worry. We need simply edit the template, and we can then create an advanced UI list that looks good.

Skinning the template one can create all sorts of lists.

7 Comments

David Mc Dougall

Please note the error in the following passage:

Using multiple elements

"So, let's clone the "Element Template" group. You can do this very easily in the IDE by holding down Option on Mac or [Alt] on the PC and dragging the "Element Template" group to another location."

The Control key is the copy key in Windows, not the Alt key.

Hanson Schmidt-Cornelius

Hi David,

indeed. The lesson has been updated.

Kind Regards,

Hanson

Jean-Paul

Sorry, but the sentence after the second image: "We then group both rectangles seperately naming the top group "Main" and the lower one "Slider"" is not clear enough for me.
"group both rectangles seperately" ?????
How can I group separatly when the card contains only 2 objects ?
I can only group in that case rectangle1 with rectangle2, no?
Or do you mean I must group twice the same objects and give to each group the names "Main" and "Slider" ?

Thanks for your help.

Alejandro Tejada

Hi Jean Paul,

Effectively, each rectangle is grouped alone.
Each rectangle turns into a group of a single element.

Using the Project Browser (menu Tools>Project Browser)
open the Property Inspector and name each group,
following the tutorial instruction.

Select both groups and group them.
Now you have two groups within a single group.

Nested groups are very useful in LiveCode
and are very common in graphics applications.

Jean-Paul

Thanks Alejandro.

The: "Each rectangle turns into a group of a single element." was not obvious to deduct for me ;-)

Louis

Hi,

It would be better if this lesson provide a sample stack. Could it be possible to attach the sample stack for this lesson?

Best regards,

Louis

Louis Eo

Any example stack available for this lesson?

Cheers,

Louis

Add your comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.