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
Highlighted
Developer
Posts: 185
Registered: ‎04-05-2011
My Device: PlayBook
My Carrier: Bouygues Telecom
Accepted Solution

Creating Custom UIComponent

[ Edited ]

Hello,

 

I am looking at creating custom UI controls. What I need is not just skinning or changing the appearance but creating new types of controls (these controls could also be eventually skinnable components).

 

What I am aiming at is to have for instance controls such as a vertical sliders, or potentiometers. I am wondering if these could be achieved by skinning a slider.

 

Ultimately I'd like a Jog Wheel or rotary encoder, with a button in the center, something like the old ipod's.

 

I have made several searches about custom components or UI controls etc but so far could only find info about skinning.

Anybody has experience about creating new reusable UIComponents or know of some good examples or tutorials?

 

Thanks!

Julien
Web: smugrik.org Follow: @Smugrik
PlayBook apps:
OSCream
kiPass
Developer
Posts: 409
Registered: ‎12-10-2010
My Device: PlayBook
My Carrier: N/A

Re: Creating Custom UIComponent

in ActionScript 3.0 you're probably looking at simply creating your own class that extends sprite, is added to the display list.  this class, of course, can be instantiated and will have its own event dispatchers and listeners - such as mouse events.  you're probably also looking at creating your own custom event class for the class so that other objects can interact with the class's custom events.

 

if you're using Flash Professional CS5 and want to create an actual component for the IDE, you can follow this detailed tutorial on how to do so:  Creating ActionScript 3.0 components in Flash


PlayBook Applications:
Drop Swatch
Developer
Posts: 185
Registered: ‎04-05-2011
My Device: PlayBook
My Carrier: Bouygues Telecom

Re: Creating Custom UIComponent

Thanks TheDarkIn1978, I havn't yet had time to review all the articles series, but it seems to be a good starting point.

Unfortunately I don't have Flash Professional yet, still working on Flash Builder Burrito demo and only 11 days left...

Julien
Web: smugrik.org Follow: @Smugrik
PlayBook apps:
OSCream
kiPass
Developer
Posts: 1,280
Registered: ‎03-03-2011
My Device: Playbook, Z10, Q10, Z30 with Files & Folders and Orbit of course
My Carrier: Vodafone

Re: Creating Custom UIComponent

Something like these?

 

screenshot1.png

 

The sliders are simply skinned VSliders (with skinned Thumbs and Tracks).

 

The rotary pot is an extended UIComponent that listends for mouse events and calculates the angle between the mouse and the center of the circle. It updates the value, which in turn redraws the indicator.

 

You could also take a look at this example which uses a slightly different approach: it rotates the knob based on the mouse position. Works fine, but because the component (even though it is round) has square bounds and because a square rotated 45 degrees takes up more space than one that is not rotated, it tends to mess up Flex's layout mechanism. You could probably fix that in the measuring phase of the components lifetime.

 

More info about the Feedback Frequency Trainer app here.

 

Cheers,          - Jon -

Files & Folders, the unified file & cloud manager for PlayBook and BB10 with SkyDrive, SugarSync, Box, Dropbox, Google Drive, Google Docs. Free 3-day trial! - Jon Webb - Innovatology - Utrecht, Netherlands
Developer
Posts: 185
Registered: ‎04-05-2011
My Device: PlayBook
My Carrier: Bouygues Telecom

Re: Creating Custom UIComponent

Hi Jon. Thanks for replying

I suppose you use the slider from flex packages eg mx.controls.slider.
Is there any way to have the bbpb slider and volume from qnx.ui.slider drawn vertically?
For the knob, your solution is similar to what I imagined, would you have some code examples?
The solution with rotating the knob widget is not that satisfying...
Julien
Web: smugrik.org Follow: @Smugrik
PlayBook apps:
OSCream
kiPass
Developer
Posts: 30
Registered: ‎03-31-2011
My Device: Curve
My Carrier: Rogers

Re: Creating Custom UIComponent

Hi! I wrote up a custom knob control for my app based on a whole bunch of tutorials I found on the web, and I will try to get some code samples posted when I can get it cleaned up. Logic-wise, I do some simple calculations to find out where the mouse is relative to the centre of the knob, and use that to figure out if I should spin or not. I also restrict it from rotating within certain bounds, so it behaves a bit more like an audio panning knob would on a physical device.

 

For vertical sliders, use the QNX control! You can set its rotation property to -90 if you want the bottom to be the 0 position.

 

You can check out the picture attached to my profile for a screenshot of my app with both of the controls in action Smiley Happy

Developer
Posts: 1,280
Registered: ‎03-03-2011
My Device: Playbook, Z10, Q10, Z30 with Files & Folders and Orbit of course
My Carrier: Vodafone

Re: Creating Custom UIComponent

I'm not sure about the qnx.ui.slider. Personally I tend to avoid the qnx libs for portability reasons, and as I've skinned my components anyway there is little reason to use them.

 

Here is my code for the basic rotary knob. Its value goes from 0 (all the way left) to 100 (all the way right). It is not skinnable and probably not usable in design mode, but it should get you started.

 

Cheers, - Jon -

 

/**
 * TKnob
 * Rotary knob component
 * 
 * @author Jon Webb, http://www.webbsites.nl
 * @version 1.0.0
* @date 06-apr-2011 * * Licensed under MPL - Mozilla Public License - http://www.mozilla.org/MPL/ */ package components { import flash.events.Event; import flash.events.MouseEvent; import flash.filters.DropShadowFilter; import flash.geom.Point; import mx.core.UIComponent; import mx.managers.IFocusManagerComponent; [Event(name="change", type="flash.events.Event")] public class TKnob extends UIComponent implements IFocusManagerComponent { private const DEGTORAD:Number = Math.PI/180; // used for angle conversion private const _maxAngle:Number = 180; // maximum angle private const _minAngle:Number = 0; // minimum angle private var _currentAngle:Number = 0; // current angle private var _value:Number = 0; // current value private var _valueChanged:Boolean; // track when value is changed // constructor public function TKnob() { super(); this.buttonMode=true; this.filters = [new DropShadowFilter(5,70,0, 0.66,4,4,3,3)]; this.addEventListener(MouseEvent.MOUSE_DOWN, handleMouseDown); } // value property setter public function set value(v:Number):void { if(v != _value) { // if changed if(!isNaN(v)) { // if valid _value = v; _valueChanged = true; invalidateProperties(); invalidateDisplayList(); dispatchEvent(new Event(Event.CHANGE, true, false)); } } } // value property getter public function get value():Number { return _value; } // mouse event handlers protected function handleMouseDown(e:MouseEvent):void { stage.addEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove); stage.addEventListener(MouseEvent.MOUSE_UP, handleMouseUp); } protected function handleMouseMove(e:MouseEvent):void { _currentAngle = calculateAngle(e); value = (calculateValue (_currentAngle)); // use setter } protected function handleMouseUp(e:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove); stage.removeEventListener(MouseEvent.MOUSE_UP, handleMouseUp); } // calculate angle of mouse relative to center point private function calculateAngle(e:MouseEvent):Number { var cp:Point; var mp:Point; // get center point cp = new Point (this.x+this.width/2, this.y+this.height/2); // convert to global cp = this.parent.localToGlobal(cp) // get mouse point mp = new Point(e.stageX, e.stageY); // freedom of movement is limited to top half of knob, similar to mixer if(mp.y<cp.y) { var delta:Point = cp.subtract(mp); // use some math to calculate angle var a:Number = Math.atan2(delta.y, delta.x); var r:Number = (180/Math.PI) * a; // limit to min/max if (r > _maxAngle || r < -90) { r = _maxAngle; } else if (r < _minAngle && r > -90) { r = _minAngle; } return r; } else { return _currentAngle; } } // convert angle to value private function calculateValue(rotation:Number):Number { return (_currentAngle - _minAngle) / (_maxAngle - _minAngle) * 100; } // convert value to angle override protected function commitProperties():void { if (_valueChanged) { _currentAngle = _value/100 * (_maxAngle - _minAngle); _valueChanged = false; } super.commitProperties(); } // redraw component override protected function updateDisplayList(uw:Number, uh:Number):void { super.updateDisplayList(uw, uh); var hw:Number = this.width/2; // half width var hh:Number = this.height/2; // half height var sx:Number = Math.cos(_currentAngle*DEGTORAD); // indicator x var sy:Number = Math.sin(_currentAngle*DEGTORAD); // indicator y graphics.clear(); // draw the knob graphics.lineStyle(0,0); graphics.beginFill(0xDCDEE7, 1); graphics.drawCircle(hw, hh, hw*0.9); graphics.endFill(); // draw the indicator graphics.lineStyle(2,0); graphics.moveTo(hw-(sx*hw/2), hh-(sy*hh/2)); graphics.lineTo(hw-(sx*hw), hh-(sy*hh)); } } }

 

Files & Folders, the unified file & cloud manager for PlayBook and BB10 with SkyDrive, SugarSync, Box, Dropbox, Google Drive, Google Docs. Free 3-day trial! - Jon Webb - Innovatology - Utrecht, Netherlands
Developer
Posts: 185
Registered: ‎04-05-2011
My Device: PlayBook
My Carrier: Bouygues Telecom

Re: Creating Custom UIComponent

Thanks to all for nice replies

 

it seems both @erasmus and @webbsites did control the rotation in the same way, e.g. mouse position relative to center of knob, and I'll probably just do the same ;-) though for the encoder I need to be able to register not the actual position but the angle by which it was changed, and also support possibility to make several turns.

 

Thanks @webbsites for code example, gives a good idea.

By the way, I'll certainly give a try to both your apps once I get the tablet, a 4 track recorder and an ear trainer if I guessed right; I'm working on an Open Sound Control based controller, seems musicians won't be at rest with the PlayBook.

 

OK, now coding...

Julien
Web: smugrik.org Follow: @Smugrik
PlayBook apps:
OSCream
kiPass