Bada tutorial: simple screen orientation example
You might have already tested the previous examples of our simple bada map application (if you were lucky enough to get the SDK/IDE). There is one thing you’d notice right away if you were testing on a device – something not that obvious when you simulate your app on the bada simulator – what happens if you rotate your device to landscape mode instead of holding it in portrait mode? Right click on the simulator window Rotate->Landscape.
Pathetic, isn’t it?
Our map still seems to be drawn in portrait mode. This is due to the sizes we specified in the OnAppInitializing() function, do you remember?
// Specify map size (the whole space) // we take the whole available space on the form width=pForm->GetCanvasN()->GetBounds().width; height=pForm->GetCanvasN()->GetBounds().height; r = pMap->Construct(Osp::Graphics::Rectangle(0, 0, width, height), *pProvider); if (IsFailed(r)) goto CATCH;
Now, those sizes, of course, will not change all by themselves. What we need here is (surprise!) another listener that would receive the orientation of the device (or better said: the orientation of the parent form) as soon as it changes. I will go the same direction here and simply implement the interface (again) into the class of our app. Nevertheless, you must keep in mind that I do it due to practicability and chronic laziness
– just to give a quick example. I am well aware that such dramatic multiple-inheritance is a capital sin in modern C++ design. My focus right now is not a beautiful, flexible design, but rather quick demonstration of the API. So bear with me.
Now we will need to implement the IOrientationEventListener and add a handler function for the orientation event.
class SimpleLocation :
public Application, IActionEventListener, ILocationListener, IOrientationEventListener
{
private:
Frame *pFrame;
Form *pForm;
Map *pMap;
// Lot's of declarations here [...]
void OnOrientationChanged(const Control& source, OrientationStatus orientationStatus);
};
#endif
We will need to register the listener with the parent form of the map. If you remember the GUI designer, when looking at the properties of a form, you had a chance to set the Orientation property. There are six different values you may choose:
- Automatic:2Dir
- Automatic:4Dir
- Landscape
- Landscape:Reverse
- Portrait
- Portrait:Reverse
The default value is Automatic:2Dir, which basically says that the form can handle two orientations (Landscape and Portrait) and will adapt itself accordingly when such an event happens. If you changed the orientation property to portrait, the form would always stay the same (in portrait mode), regardless of the orientation of the device. No orientation event would be fired through it. It would have been one of the possible solutions to the problem we are dealing with. Nevertheless, we are interested in a rich user experience and so we leave this orientation at its default value.
Now let’s register our listener in OnAppInitializing()…
pForm->AddOrientationEventListener(*this);
… and define the handler function
void
SimpleLocation::OnOrientationChanged(const Control& source, OrientationStatus orientationStatus)
{
int width, height;
width=pForm->GetCanvasN()->GetBounds().width;
height=pForm->GetCanvasN()->GetBounds().height;
pMap->SetBounds(0,0,width,height);
pMap->SetSize(width, height);
RedrawMap();
}
Usually you would want to deal with the orientationStatus in here. It gives you the basic info about the orientation:
enum OrientationStatus
{
ORIENTATION_STATUS_PORTRAIT = ORIENTATION_PORTRAIT, /**< The control is set to vertical orientation */
ORIENTATION_STATUS_LANDSCAPE = ORIENTATION_LANDSCAPE, /**< The control is set to horizontal orientation */
ORIENTATION_STATUS_PORTRAIT_REVERSE = ORIENTATION_PORTRAIT_REVERSE, /**< The control is set to vertical upside-down orientation */
ORIENTATION_STATUS_LANDSCAPE_REVERSE = ORIENTATION_LANDSCAPE_REVERSE, /**< The control is set to horizontal reverse orientation */
};
I chose to go another way and simply read the dimensions of the parent form. Then I use those to set the bounds and the size of the map. Redraw the thing, and we are ready!
Now, in more complex applications you would want to do this differently. For each form you’d have a different class with two standardized functions: one to draw all the child elements and one for geometry (to position the child elements according to the geometry/orientation of the parent form). Then you’d simply call the geometry function on each orientation update.
Nevertheless, I hope this small tutorial was somewhat helpful to give you the general idea of how to deal with device orientation in your apps. Have fun!
Related posts:
the Flagship blog & community for App Developers with main focus on Samsung's bada and cross-platform technologies 






8 Responses to “Bada tutorial: simple screen orientation example”
By malloth on Jun 22, 2010 | Reply
I had a problem with this one. Each time I resized my list in OnOrientationChanged even I get an empty space right after form title.
To override this You need to add this->Draw() as a first line in OnOrientationChanged(). This causes form to draw in its new orientation first and only then You will have the rest of Your controls placed right.
As a curiocity, I’d like to add that You shouldn’t use RequestRedraw after resizing controls in this event, because it won’t look well. Use Draw instead.
By wit on Jun 24, 2010 | Reply
Thanks for that insight, malloth! I have noticed that RequestRedraw does not work in certain callback functions, too (maybe because it runs on a separate thread then)! Adding OnOrientationChanged to the list of those callbacks
By malloth on Jun 24, 2010 | Reply
I’d like to also mention that the idea of making two separate forms for portrait and landscape – posted on http://developer.bada.com/blog/?cat=1&paged=3 – is not worth it. It’s much faster and safer (no need of controling handles from two forms) to resize controls in simple switch inside OnOrientationChanged event.
Because Bada has a request-to-draw mechanism (don’t count on auto drawing) it allows us to draw only when needed – when every control has been resized and placed in its location (using fast SetBounds method).
By Slicer on Aug 1, 2010 | Reply
Hello! My form layout depends on an orientation (even a set of controls depends on it – not just their positions). In simulator, I execute this:
m_form = new MyForm(this);
m_form->Construct(Osp::Ui::Controls::FORM_STYLE_INDICATOR);
m_form->SetOrientation(ORIENTATION_AUTOMATIC);
GetAppFrame()->GetFrame()->AddControl(*m_form);
But, after that, getOrientationStatus returns a value which IS NOT IN AN ENUMERATION! How do I find an actual orientation of a device?
By Slicer on Aug 1, 2010 | Reply
Sorry, i’d like to recall the last question =)
By Slicer on Aug 1, 2010 | Reply
Added SetCurrentForm, and still GetOrientationStatus returns an invalid value.
m_form = new MyForm(this);
m_form->Construct(Osp::Ui::Controls::FORM_STYLE_INDICATOR);
m_form->SetOrientation(ORIENTATION_AUTOMATIC);
GetAppFrame()->GetFrame()->AddControl(*m_form);
GetAppFrame()->GetFrame()->SetCurrentForm(*m_form);
m_form->OnOrientationChanged(*m_form, m_form->GetOrientationStatus());
By Laymain on May 26, 2011 | Reply
Care of memory leaks
width=pForm->GetCanvasN()->GetBounds().width;
height=pForm->GetCanvasN()->GetBounds().height;
The ‘N’ suffix of “GetCanvasN()” means that you must free the returned result.
Quoting Bada documentation :
“If a method has an „N‟ postfix, the caller MUST delete the returned instance after the caller is finished with the object. Otherwise, the memory for the object is leaked.”