Widgets — Creating a Sliding Panel

Today’s tutorial demonstrates how to create a sliding panel that has many uses, ranging from games to business applications. You might build an adventure game where the player’s inventory needs to slide on the screen, then hide itself when the user is done. Or you might build a menu that slides in when the player taps the infamous “hamburger” menu icon. Yet another possibility is sliding notices in and out.

As with the previous UI tutorials on navigation panels and text fields, this tutorial will extend the widget library, creating a new widget called widget.newPanel(). Let’s look at the entire function:

For consistency, this new widget will follow the coding standard of the other widgets in the Corona SDK open source widget library. Like other widgets, we begin by passing in a table of parameters necessary to create the panel (lines 5 through 27). These include:

location — where the panel originates from (left, right, top, or bottom).

onComplete — a function to execute when the panel completes showing and hiding.

All parameters are optional and are set to reasonable defaults. The location parameter is a string value of either "left", "right", "top" or "bottom" that defaults to "top". The speed parameter defaults to 500 milliseconds. inEasing and outEasing are linear by default but can be set to any of the standard easing methods.

onComplete is optional and defaults to nil. In the above example, we actually create two completion listeners, one for each of the actions the panel supports (panel:show() and panel:hide()).

Code Notes

Let’s step through the function code and inspect some important aspects:

When adding the code to define the listener (lines 23-27), it’s helpful to make sure that a parameter was passed, but also that it’s a function and not some other variable type.

If a panel slides in from the left or right, it’s reasonable to take up the full height of the visible screen, but the width would need to be specific to the app. Panels coming in from the top or bottom may take up the full width of the device but be limited to 1/3 of the screen.

Line 29 creates a display.newContainer(). This is similar to display.newGroup(), except that its bounds are automatically clipped to the defined width and height. This container object is returned on line 95 to the calling function.

The panel is positioned off screen based on the location specified. Since there are many ways to set up the size and scale in config.lua, this function uses display.screenOriginX and display.screenOriginY to reference the left and top of the screen. Likewise, display.actualContentWidth and display.actualContentHeight represents the right and bottom edges of the screen. By setting the anchor point to the side of the container that faces the content area, we can use these values to position it. The other value will simply center the container along that edge.

To show and hide the panel, two methods are included named show() and hide(). Lines 50-93 implement these two functions. The panels will be shown or hidden using a simple transition.to call, but first we need to determine where to move the panel to. If we’re sliding the panel in/out from the top or bottom, we need to transition the y value. If we’re sliding it in/out from either side, we need to use the x value. Again, we use the defined points for the sides of the screen and either add or subtract the width or height of the panel.

Using the “widget.newPanel()”

To use the panel, simply create a new object, in this case panel, and above that, the optional listener function that’s specified as the onComplete parameter:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

local functionpanelTransDone(target)

native.showAlert("Panel","Complete","Okay")

if(target.completeState)then

print("PANEL STATE IS: "..target.completeState)

end

end

local panel=widget.newPanel

location="top",

onComplete=panelTransDone,

width=display.contentWidth *0.8,

height=display.contentHeight *0.8,

speed=250,

inEasing=easing.outBack,

outEasing=easing.outCubic

When done, panel will be the container object to which we can add whatever content desired using the object:insert() call. To keep things more organized, display objects can optionally be added directly to the panel object:

1

2

3

4

5

6

7

panel.background=display.newRect(0,0,panel.width,panel.height)

panel.background:setFillColor(0,0.25,0.5)

panel:insert(panel.background)

panel.title=display.newText("menu",0,0,native.systemFontBold,18)

panel.title:setFillColor(1,1,1)

panel:insert(panel.title)

Showing/Hiding

When desired, we can show or hide the panel by simply calling the proper method:

1

2

3

panel:show()

panel:hide()

Composer Notes

If you’re using Composer, you may not want to insert the panel into the Composer group because the panel is generally intended to slide over anything else in the scene. However, if you choose to add it to the scene’s view, it should be the last thing inserted into the scene, or else you should call :toFront() to move it to the top of the scene’s view.

On the general topic of Composer, you may ask “shouldn’t this be done with an overlay?”. While that is a valid approach, overlays are individual scenes and it takes more effort to construct and deconstruct a scene. In contrast, widget.newPanel() yields a simple slide-in/out unit which can be used with or without Composer.

In Summary

This tutorial should get you started with implementing basic sliding panels in your app. With some clever adjustments to the various parameters, you can easily implement a wide variety of panels that appear from different sides of the screen and utilize unique easing transitions.

Disclaimer: SDKNews.com only syndicates the blog entries from various SDK blogs.
We are not the creator/author of these entries (posts). Product names, brand names
and company names mentioned on this site may be trademarks of their respective owners.