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

Reply
Contributor
germama
Posts: 22
Registered: ‎12-17-2010
My Device: Not Specified
Accepted Solution

App specific system menu

Hello everybody,

 

In one of the nice videos about the tablet, I saw some kind of system menu which could be used by any app to put menu items in it, to keep thew main window design clear.

 

Does anybody know how to accomplish this? My intension is to put some items like "configuration" and "about" to not overload my main UI.

 

Thanks in advance

Marco

 

Developer
JRab
Posts: 2,462
Registered: ‎11-04-2010
My Device: Bold 9700

Re: App specific system menu

[ Edited ]

hey germama,

 

in the webcast's they recommended that we not put any "title bars" in our apps to save space for content. so what they recommended was that we use a optional menu to be "dragged" out of hiding from the top of the playbook. you can go to this video and see it in action and see some source code (a glimpse really) here:

 

http://2010.max.adobe.com/online/2010/MAX260_1288217641375UQJD

 

if you go to about 13:45 minutes into the presentation they start talking about the menu. after you get a good idea, take a look at the code below and see if you can kind of get an idea about how to approach this:

 

SwipeDownTest.as (Main application file):

 

 

package
{
	import caurina.transitions.Tweener;
	
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.ui.Mouse;
	
	import qnx.events.QNXApplicationEvent;
	import qnx.system.QNXApplication;
	
	
	// The following metadata specifies the size and properties of the canvas that
	// this application should occupy on the BlackBerry PlayBook screen.
	[SWF(width="1024", height="600", backgroundColor="#CCCCCC", frameRate="30")]
	public class SwipeDownTest extends Sprite
	{
		private var ui:UI;
		
		public function SwipeDownTest()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			ui = new UI();
			
			addChild(ui);
			
			QNXApplication.qnxApplication.addEventListener(QNXApplicationEvent.SWIPE_DOWN, onSwipeStart);
		}
		
		private function onSwipeStart( e:QNXApplicationEvent ):void
		{
			stage.addEventListener( Event.ENTER_FRAME, showNavigation );
		}
		
		private function showNavigation( e:Event ):void
		{
			Tweener.addTween(ui, {y: 0, time: .3, transition: "linear"});
			stage.removeEventListener(Event.ENTER_FRAME, showNavigation);
			stage.addEventListener(MouseEvent.CLICK, hideNavigation);
			
		}
		public function onMouseUp(e:MouseEvent):void
		{
			stage.addEventListener(MouseEvent.CLICK, hideNavigation);
			stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		}
		public function hideNavigation(e:MouseEvent):void
		{
			if (stage.mouseY > 123)
			{
				Tweener.addTween(ui, {y: -123, time: .3, transition: "linear"});
				stage.removeEventListener(MouseEvent.CLICK, hideNavigation);
			}
		}
	}
}

 

 

 

UI.as (Navigation bar class):

 

 

package
{
	import flash.display.Shape;
	import flash.display.Sprite;
	
	
	public class UI extends Sprite
	{
		private var navBar:Shape;
		
		public function UI()
		{
			//set it up with two sections
			
			navBar = new Shape();
			navBar.graphics.beginFill(0x333333, 1);
			navBar.graphics.drawRect(0,0,1024,123);
			navBar.graphics.endFill();
			
			this.y = -123;
			
			addChild(navBar);
			
			
			
			
		}
	}
}

 

 

 

i tried to mimic their menu as best as i could and thats the result. it involves the application listening to the SWIPE_START event and then proceed with showing a menu. the example is very crude but it gets hte point across. hope that helps! good luck!

 

EDIT: Modified both AS files due to some odd errors. new code should work without a hitch. sorry about that. thanks for the pointing it out peter!

J. Rab (Blog) (Twitter)
--
1. If you liked my post or found it useful please click on the thumbs up and provide a Like!
2. If my post solved your problem please click on the Accept as Solution button. Much appreciated!

Approved Apps: OnTrack | ssShots | Hangman
Developer
gluth
Posts: 192
Registered: ‎09-23-2009
My Device: 9860/PlayBook/Dev Alpha
My Carrier: Plus GSM

Re: App specific system menu

React to this event:

http://www.blackberry.com/developers/docs/airapi/1.0.0/qnx/system/QNXApplication.html#event:swipeSta...

 

Show your menu, or about screen or configuration, anything. This event informs application that user has done top down swipe starting from top bezel (the only one bezel swipe to which app has access). Search the forum to know how to use Tweener to give your app nice screen flow.

 

Found my post helpfull? Like it! It solves your trouble? Help others and accept it as solution. Search before asking.
My apps: Secret Cod3s | Should my tablet be banned?
--
Jakub Nietrzeba
PGS Software S.A.
Your reliable partner in Poland - IT Outsourcing - BlackBerry, iPhone, Web and Standalone applications
Contributor
germama
Posts: 22
Registered: ‎12-17-2010
My Device: Not Specified

Re: App specific system menu

Thank you very much for the quick reply! This helped alot!

Developer
peter9477
Posts: 6,473
Registered: ‎12-08-2010
My Device: PlayBook, Z10

Re: App specific system menu

 


JRab wrote:
i tried to mimic their menu as best as i could and thats the result. it involves the application listening to the SWIPE_START event and then proceed with showing a menu. the example is very crude but it gets hte point across.

J.Rab, does that example actually work fully for you?  One my simulator, I can drag down nicely, but when I release the mouse button it doesn't "roll up" again.  Instead I have to press the mouse button down and then release again before it registers. 
Basically it's missing the first mouse up, possibly (wild guess) because the original mouse down wasn't within the area of the stage, but was up in the bezel.  Just wondering if it works properly for anyone other than me.

 


Peter Hansen -- (BB10 and dev-related blog posts at http://peterhansen.ca.)
Author of White Noise and Battery Guru for BB10 and for PlayBook | Get more from your battery!
Developer
JRab
Posts: 2,462
Registered: ‎11-04-2010
My Device: Bold 9700

Re: App specific system menu

hey peter,

 

thanks for catching that bug. wats weird is that the code was working perfectly for me before. maybe the new sdk changed something and things happen a little differently. either way i changed the code to work now. here is the modified code:

 

SwipeDownTest.as (Main application class):

 

 

package
{
	import caurina.transitions.Tweener;
	
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.ui.Mouse;
	
	import qnx.events.QNXApplicationEvent;
	import qnx.system.QNXApplication;
	
	
	// The following metadata specifies the size and properties of the canvas that
	// this application should occupy on the BlackBerry PlayBook screen.
	[SWF(width="1024", height="600", backgroundColor="#CCCCCC", frameRate="30")]
	public class SwipeDownTest extends Sprite
	{
		private var ui:UI;
		
		public function SwipeDownTest()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			ui = new UI();
			
			addChild(ui);
			
			QNXApplication.qnxApplication.addEventListener(QNXApplicationEvent.SWIPE_DOWN, onSwipeStart);
		}
		
		private function onSwipeStart( e:QNXApplicationEvent ):void
		{
			stage.addEventListener( Event.ENTER_FRAME, showNavigation );
		}
		
		private function showNavigation( e:Event ):void
		{
			Tweener.addTween(ui, {y: 0, time: .3, transition: "linear"});
			stage.removeEventListener(Event.ENTER_FRAME, showNavigation);
			stage.addEventListener(MouseEvent.CLICK, hideNavigation);
			
		}
		public function onMouseUp(e:MouseEvent):void
		{
			stage.addEventListener(MouseEvent.CLICK, hideNavigation);
			stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		}
		public function hideNavigation(e:MouseEvent):void
		{
			if (stage.mouseY > 123)
			{
				Tweener.addTween(ui, {y: -123, time: .3, transition: "linear"});
				stage.removeEventListener(MouseEvent.CLICK, hideNavigation);
			}
		}
	}
}

 

 

UI.as (Navigation Class):

 

 

package
{
	import flash.display.Shape;
	import flash.display.Sprite;
	
	
	public class UI extends Sprite
	{
		private var navBar:Shape;
		
		public function UI()
		{
			//setup the "nav bar"
			
			navBar = new Shape();
			navBar.graphics.beginFill(0x333333, 1);
			navBar.graphics.drawRect(0,0,1024,123);
			navBar.graphics.endFill();
			
			this.y = -123;
			
			addChild(navBar);
			
			
			
			
		}
	}
}

 

it works a little differently but gets the job down. lemme know if this works for you. again thanks! good luck!

 

J. Rab (Blog) (Twitter)
--
1. If you liked my post or found it useful please click on the thumbs up and provide a Like!
2. If my post solved your problem please click on the Accept as Solution button. Much appreciated!

Approved Apps: OnTrack | ssShots | Hangman
Developer
peter9477
Posts: 6,473
Registered: ‎12-08-2010
My Device: PlayBook, Z10

Re: App specific system menu

[ Edited ]

At first I thought that didn't work at all, but that's just because I was using debug mode and timer-based stuff (setTimeout, Timer, or enter_frame events) never works when I'm doing that for some reason. 

 

I played a bit and got the following working too, which I think is closer to what you were trying to do before.  This more closely mimics the system menu.  I used roughly the same Y value as SWIPE_DOWN triggers at.  If you release the mouse when still above that the menu retracts, but if you're below it locks it into position.

 

Sliding the menu back up is considered an app-specific behaviour here... maybe you want to just click below it, but maybe some other behaviour is better for you... depends on what you have in the menu. 

 

 

package
{
    import caurina.transitions.Tweener;

    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.display.Sprite;

    import qnx.events.QNXApplicationEvent;
    import qnx.system.QNXApplication;

    [SWF(height="600", width="1024", frameRate="30", backgroundColor="#cccccc")]
    public class MenuTest extends Sprite
    {
        private var ui:UI;
        private var swiping:int;

        // rough numbers eyeballed from system menu
        public const SWIPE_REGION:int = 23;
        public const MENU_HEIGHT:int = 62;

        public function MenuTest()
        {
            ui = new UI(stage.stageWidth, MENU_HEIGHT)
            addChild(ui);

            QNXApplication.qnxApplication.addEventListener(QNXApplicationEvent.SWIPE_START, swipeMenu);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, swipeMenu);
            stage.addEventListener(MouseEvent.MOUSE_UP, swipeMenu);
        }

        private function swipeMenu(e:Event):void
        {
            if (e.type == QNXApplicationEvent.SWIPE_START)
            {
                trace("prepare to swipe");
                swiping = 1;
            }
            else if (e.type == MouseEvent.MOUSE_UP)
            {
                if (swiping == 2)
                {
                    if (stage.mouseY >= SWIPE_REGION)
                    {
                        function now_showing():void {
                            trace("menu now visible");
                            // in real code could be a method on the class
                        }
                        Tweener.addTween(ui, {y: 0, time: .3, transition: "linear",
                            onComplete: now_showing});
                    }
                    else
                    {
                        trace("swipe cancelled");
                        Tweener.addTween(ui, {y: -MENU_HEIGHT, time: .3, transition: "linear"});
                    }

                // either way, we're done swiping
                stage.removeEventListener(Event.ENTER_FRAME, swipingMenu);
                swiping = 0;
                }
            }
            else if (e.type == MouseEvent.MOUSE_DOWN)
            {
                if (swiping == 1)
                {
                    trace("swiping");
                    swiping = 2;
                    stage.addEventListener(Event.ENTER_FRAME, swipingMenu);
                }
            }
        }

        private function swipingMenu(e:Event):void
        {
            var y:int = stage.mouseY >= MENU_HEIGHT ? MENU_HEIGHT : stage.mouseY;
            ui.y = y - MENU_HEIGHT;
            trace(e, y);
        }
    }
}

import flash.display.Shape;
import flash.display.Sprite;
import qnx.ui.text.Label;

class UI extends Sprite
    {
        public function UI(width:int, height:int)
        {
            var navBar:Shape = new Shape();
            navBar.graphics.beginFill(0x333333, 1);
            navBar.graphics.drawRect(0, 0, width, height);
            navBar.graphics.endFill();

            var title:Label = new Label();
            title.text = "App Menu";
            title.y = (height - title.textHeight) / 2;

            this.y = -height;

            addChild(navBar);
            addChild(title);
        }
    }

 

That's all in one file for ease of use...

 

 

It occurs to me that we maybe shouldn't be thinking of these in the same way as drop-down menus in desktop operating systems (i.e. where you get a vertical selection of choices as you wave the mouse around).  Here we probably are getting more like a panel of choices with buttons, ala the Navigator's system menu.

 

(Edited: The code is now what I initially had, before I simplified for posting and didn't test adequately.  This one uses a small state machine to ensure that you are still holding the mouse button down.  The previous one may work okay on the tablet, but this one is required for use with a mouse.  Otherwise you can click-and-release on the bezel, then see the menu being dragged down as you move the mouse down even though you aren't holding the mouse button down.  Yet another case where not having a real tablet makes testing difficult.)

 


Peter Hansen -- (BB10 and dev-related blog posts at http://peterhansen.ca.)
Author of White Noise and Battery Guru for BB10 and for PlayBook | Get more from your battery!
Developer
peter9477
Posts: 6,473
Registered: ‎12-08-2010
My Device: PlayBook, Z10

Re: App specific system menu

 


peter9477 wrote: 

This more closely mimics the system menu.


 

Maybe "more closely" but not perfectly, yet. 

 

I just noticed that the system menu actually pushes the contents of the screen down as it comes down, whereas the latest menu code above slides down over the content.

 

There's other interesting differences that I've discovered now that I've also found how to show the system menu while in an application.  I haven't seen it reported elsewhere yet, but -- similar to the swipe-from-lower-left-bezel gesture to show the keyboard -- you can swipe from either upper corner to show the system menu at any time.

 

Actually it's not even necessary to move in from the corner, as there seems to be a region that extends about 50 pixels into area above the screen where you can swipe from.  That means the swiping region for your application menu is only about 924 pixels wide, not the full 1024.

 

I also think I've discovered what the SWIPE_DOWN event is used for, at least in the case of the system menu.  If you swipe slowly down in Navigator (the thing that launches your apps) from the top bezel, you'll see that around Y=23 or so the System Menu suddenly extends down to cover the entire screen.  (You'll see the content corresponding to whatever widget you have most recently clicked on in the menu bar.)

 

Interestingly, this SWIPE_DOWN event doesn't appear to be used when you use the corner areas to swipe into an application.  Instead you have to drag about a third of the way down the screen before the menu will take over the screen. Release anywhere above that and it rolls itself back up like a window blind.

 

My guess is we'll see many tweaks in all this before release. :smileyhappy:


Peter Hansen -- (BB10 and dev-related blog posts at http://peterhansen.ca.)
Author of White Noise and Battery Guru for BB10 and for PlayBook | Get more from your battery!
New Contributor
osuthorpe
Posts: 2
Registered: ‎12-18-2010
My Device: Playbook

Re: App specific system menu

I'm new t developing applications and I am building a playbook app in adobe flex and was wondering if there is a way to implament this code in flex. When I try to import the qnx.events.QNXApplicationEvent it says the namespace was not found

Developer
p3pp3r
Posts: 157
Registered: ‎12-16-2010
My Device: Torch 9800, PlayBook

Re: App specific system menu

 


osuthorpe wrote:

I'm new t developing applications and I am building a playbook app in adobe flex and was wondering if there is a way to implament this code in flex. When I try to import the qnx.events.QNXApplicationEvent it says the namespace was not found


 

I am struggling with the same thing. I have added 

 

QNXApplication.qnxApplication.addEventListener(QNXApplicationEvent.SWIPE_START, onSwipeStart);

 to my "sudo" init function (there is no init function in flex --- but I have the creationComplete event of the view run a custom init() and it is throwing 

 

VerifyError: Error #1079: Native methods are not allowed in loaded code.

 

at run time.

I am wondering if anyone managed to get this working in Flex...

 

----------
If you find this post helpful please "like" it and accept as a solution.