Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Adobe AIR Development

by Retired ‎01-20-2011 02:26 PM - edited ‎10-26-2011 09:18 AM (12,397 Views)

Have you been wondering what you can do with the touch-sensitive bezel around the screen of the BlackBerry® PlayBook™ tablet? When a user swipes down from the top edge of the screen, the BlackBerry® Tablet OS reports that gesture to the active application.

 

What you do with that gesture is up to you, and depends heavily on the context of your application. One idea is to display an application menu. This gives you the opportunity to enhance your UI without crowding your limited screen real estate. Let’s create a simple app that drops a menu down from the top edge of the screen when a user swipes down, and hides it again when they touch anywhere else.

 

Our application needs two classes:

 

  • A main application class that simulates the primary application UI and listens for the QNXApplicationEvent.SWIPE_DOWN event.
  • A MenuBar class that contains our UI controls. Our MenuBar should also hide and show itself on demand.

Application class


In your editor, create a file named AppMenuDemo.as. In AppMenuDemo.as, start by importing the packages we’ll need.

 

 

package
{
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import qnx.events.QNXApplicationEvent;
    import qnx.system.QNXApplication;

 

Declare the size of the tablet screen, and the application class.

 

 

    [SWF(width="1024", height="600", backgroundColor="#cccccc", frameRate="30")]

    public class AppMenuDemo extends Sprite
    {

 

Create an instance variable to keep track of your MenuBar.

 

 

private var _menu:MenuBar;

 

In the constructor, invoke a function to initialize your UI, and create an event listener to receive notifications that the user has swiped down from the top edge of the screen.

 

 

        public AppMenuDemo()
        {
            initializeUI();
            QNXApplication.qnxApplication.addEventListener(QNXApplicationEvent.SWIPE_DOWN, showAppMenu);
        }

 

Create an initializeUI() method. In initializeUI(), create a Sprite and draw a background on it (blue, in this case).

 

public function initializeUI():void
        {
            var ground:Sprite = new Sprite();
            ground.graphics.beginFill(0x5CACEE,1.0);
            ground.graphics.drawRect(0,0,1024,600);
            ground.graphics.endFill();

 

Since we're overlaying two active UI components (the main UI, and the menu bar), we need to decide how to process user interactions when they're both visible. Let's add an event listener to the main UI. In our case, we created a Sprite for our UI (ground), so we're adding the event listener to that object.

 

            ground.addEventListener(MouseEvent.MOUSE_DOWN, groundClick);
            addChild(ground);

 

Instantiate your MenuBar object and add it to the screen. We add it last so that it is the element that displays on top.

 

            _menu = new MenuBar();
            addChild(_menu);
        }

 

Create a showAppMenu() method to respond to a SWIPE_DOWN event.

 

 

        private function showAppMenu(event:QNXApplicationEvent):void
        {

 

If the menu is not currently visible, tell the menu to display itself. Otherwise, do nothing.

 

 

            if(! _menu.isVisible())
            {
                _menu.show();
            }
        }

 

Create a groundClick() method to decide what to do when a user interacts with the application's main UI (the ground object we created above). If the menu is visible, let the logic in the MenuBar class decide how to process the event. Otherwise, pass it to the main logic of your application.

 

 

        private function groundClick(event:MouseEvent):void
        {
            if(_menu.isVisible())
            {
                _menu.processEvent(event);
                
            } else
            {
                // process the event in your main UI
            }
        }
    }
}

 

MenuBar class


The menu bar is another Sprite that we overlay on top of our main UI. We animate the menu bar sliding down from the top edge of the screen when we display it, and back up into the top edge of the screen when we hide it. Another Sprite _clickArea is going to encompass the remaining screen under MenuBar to give a true modal behaviour. We control the animation using the Tweener class in the caurina.transitions package, which is included in the BlackBerry® Tablet OS SDK for Adobe® AIR®.

 

In your editor, create another file named MenuBar.as. Again, in MenuBar.as, let's import the packages we need.

 

 

package
{
    import caurina.transitions.Tweener;

    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.utils.Timer;

    import qnx.ui.buttons.LabelButton;

 

Declare the MenuBar class, and create a few constants to define the size of the menu. This makes it easy to play with different settings, and reuse this class.

 

 

    public class MenuBar
    {
        public static const WIDTH:int = 1024;
        public static const HEIGHT:int = 80;
        public static const VISIBLE_Y:int = 0;
        public static const HIDDEN_Y:int = -HEIGHT;
        public static const SLIDE_TIME:Number = 0.5;

 

Create an instance variable to keep track of the menu state.

 

	_active = false;
	_clickArea = new Sprite();

 

 

 

In the constructor, invoke the initializeUI() method.

 

 

        public MenuBar()
        {
            initializeUI();
        }

 

In initializeUI(), ensure that the menu is inactive, and hidden.

 

        private function initializeUI():void
        {
            _active = false;
            _clickArea = new Sprite();

            // set default position (HIDDEN_Y)
            this.x = 0;
            this.y = HIDDEN_Y;
            _clickArea.x = 0;
	    _clickArea.y = HEIGHT;
	    _clickArea.width = WIDTH;
	    _clickArea.height = 600 - HEIGHT;
	    _clickArea.visible = _active;
	    _clickArea.addEventListener(MouseEvent.CLICK, hide);
	    addChild(_clickArea);

 

In this example, we draw a slightly transparent, gray rectangle to visually define the menu bar. This bar will hold other UI components:

 

 

            this.graphics.beginFill(0x222222,0.7);
            this.graphics.drawRect(0,0,WIDTH,HEIGHT);
            this.graphics.endFill();

 

Let’s place a button control on the menu bar. 

 

            var egButton:LabelButton = new LabelButton();
            egButton.label = "Example button";
            egButton.height = 64;
            // set the button in 10 pixels from the left, and center it vertically in the menu bar
            egButton.x = 10;
            egButton.y = 6;
            this.addChild(egButton);
        }

 

Create an isVisible() method so that other objects can check the visibility of the menu.

 

        public function isVisible():Boolean
        {
            return _active;
        }

 

Create a show() method to display the menu bar. The Tweener class animates the menu sliding down from HIDDEN_Y to VISIBLE_Y.   

 

        public function show():void
        {
            _active = true;
            _clickArea.visible = true;
            Tweener.addTween(this, {y:VISIBLE_Y, time:SLIDE_TIME, transition:"linear"});
            
        }

 

 

Create a hide() method to remove the menu bar. The Tweener class animates the menu sliding up from VISIBLE_Y to HIDDEN_Y.

 \

        public function hide():void
        {
            _active = false;	
            _clickArea.visible = false;		
            Tweener.addTween(this, {y:HIDDEN_Y, time:SLIDE_TIME, transition:"linear"});
        }

 

 

In our application class, we allowed the MenuBar to decide how to handle touch events that were not directed at the menu. This allows us to make the menu bar modal by ignoring clicks outside the bounds of the menu when it's active, or close it, or whatever. In this case, we close the menu.

 

        public function processEvent(event:MouseEvent):void
        {
            if(event.stagelY > HEIGHT)
            {
                hide();
            }
        }
    }
}

 

You can test your application now in the simulator. When the application starts, the screen area is blue. Swipe down from the top bezel. You should see a menu slide down from the top edge, and look like this:

 

app.jpg

 

Our implementation is simple, but I hope helps you get you started with the SWIPE_DOWN event and simple animations. The source files are available for download. There's still time to submit your application to the BlackBerry App World™ storefront for the free BlackBerry PlayBook tablet offer, so don't miss it!

 

What have you been doing with the swipe down gesture?

Comments
by Developer ‎02-24-2011 03:33 PM - edited ‎02-24-2011 04:32 PM

Hello,

 

I tried to adjust your sample code and run my application, but got an exception on app start:

VerifyError: Error #1014: Class qnx.pps::smileytongue:PSChannel could not be found.

 

Any ideas what's the reason?

 

SOLVED: The exception only is raised when debugging on desktop, no exception when debugging in emulator.

I think this is due to limited capabilities of the desktop-level debugger.

 

Thanks,

Ivan.

by Developer ‎01-20-2012 04:04 AM - edited ‎01-21-2012 12:38 AM

If you'd like to continue to test on the desktop you can use the code below to check if the QNX class definitions are available (or accessable). Add this to the addedToStage event on your Flex Application:

 

            import qnx.system.QNXApplication;
            public var classReference:QNXApplication;


            protected function view1_addedToStageHandler(event:Event):void {
                
                // Test if we are on the device
                
                // Throws VerifyError: Error #1014: Class qnx.pps::smileytongue:PSChannel could not be found.
                // when testing locally
                var classDefinition:smileyfrustrated:tring = "qnx.system.QNXApplication";
                var applicationDomain:ApplicationDomain = SystemManager.getSWFRoot(this).loaderInfo.applicationDomain;
                var classFound:Boolean = applicationDomain.hasDefinition(classDefinition);
                
                // add swipe down handler
                if (classFound) {
                    var definition:smileysurprised:bject;    
                    definition = applicationDomain.getDefinition(classDefinition);
                    // QNXApplicationEvent.SWIPE_DOWN;
                    definition.qnxApplication.addEventListener("swipeDown", showAppMenu);
                }
                
            }

Users Online
Currently online: 10 members 1,097 guests
Please welcome our newest community members: