the Flagship blog & community for App Developers with main focus on Samsung's bada and cross-platform technologies
Bada Tutorials, Communication & Location, Others, System & Device

Bada tutorial: simple screen orientation example

, December 18th, 2009

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.

bada_simulator_landscape_mode

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!

bada_simulator_landscape_mode2

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:

  1. bada Tutorial: zooming a map with softkeys
  2. Bada Tutorial: Option Menu
  3. Simple Finger Drawing App Update
  1. 8 Responses to “Bada tutorial: simple screen orientation example”

  2. 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.

  3. 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 :-)

  4. 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).

  5. 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?

  6. By Slicer on Aug 1, 2010 | Reply

    Sorry, i’d like to recall the last question =)

  7. 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());

  8. 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.”

  1. 1 Trackback(s)

  2. Dec 23, 2009: bada Dev » Blog Archive » Bada how-to: map marker overlay

Post a Comment

Editor's picks

Copyright 2009-2010 BadaDev.com (unless otherwise stated). All rights reserved! Powered by Wordpress!