Hello,
I liked Oscar Lindberg's ScreenTransition very much, but I found that, while it runs fine inside the emulator, on a real device (at least on low-end devices, like my Nokia 5800) it can get jerky, especially if the screen is big and/or has many widgets, because the whole source and destination screens are redrawn at every step.
So, taking inspiration from Oscar's implementation, I wrote my own version where the screens are first converted to images which are then used to display the transition.
Since each step now only involves at most two Gfx_drawImageRegion() calls, the result is much smoother and virtually independent of the screen complexity (and it opens up the possibility, I suppose, of using OpenGL to make 3D transitions).
You can now also add listeners which will be notified when a transition completes, so you know that the new screen is in place and ready to work.
Another feature of this version is the ability to have "floating" widgets, that is a widget on the source screen which remains fixed while the transition takes place and is replaced by a companion widget on the destination screen after the transition is completed. You can use this, for example, to have the soft keys stay in place while the screens change place.
Finally, a screen transition can be "interactive", that is it can be driven by pointer events. This allows you, for example, to "drag" screens in and out.
The code is split into two main classes and a helper class:
- TransitionScreen is the class which handles the screen transition.
- TransitionImage is the widget which actually displays the transition, and it can also be used independently of TransitionScreen to make e.g. a slideshow with transition effects.
- TScreen is a helper class designed to aid in adding transition effects to existing applications.
The simplest way to add transitions to your own custom screen is to make it inherit from TScreen instead of Screen.
Simply change your class declaration from:
class MyCustomScreen : public Screen, ...
to:
#include "Transitions/TScreen.h" class MyCustomScreen : public TScreen, ...
Now the Screen::show() method has been overridden and when MyCustomScreen is shown it will display a nice push transition from right to left .
If your class already overrides the show() method and then calls Screen::show(), simply change it to call TScreen::show() instead. Be warned that your show() method will now be called two times: the first one by your application to start the transition and the second one by TransitionScreen to actually display the screen. If you need to distinguish the two cases, you can call t_.isRunning(): if it returns false, this is the first call; if it returns true this is the second and last call.
To get more control over the transition, you can call one of the following overloaded versions of show():
void show(TransitionType type, int dx = -1, int dy = 0, ScreenTransitionListener *listener = NULL, MAPoint2d *refPoint = NULL); void show(ScreenTransitionListener *listener, MAPoint2d *refPoint = NULL);
Here 'type' is one of TT_PUSH, TT_SLIDE_IN, TT_SLIDE_OUT, TT_WIPE, TT_WIPE_CENTER (see TransitionImage.h ), 'dx' is the horizontal direction (1 = left to right; -1 = right to left) and 'dy' is the vertical direction (1 = top to bottom; -1 = bottom to top).
To be notified when the transition in completed, you can pass a 'listener' object.
Finally, if you want the transition to be interactive, you can pass a reference point 'refPoint': all following pointer events will then be captured by TransitionScreen and the transition will progress according to the distance the pointer moves relative to the reference point.
If you cannot or do not want to change you screen class definition, you can you can also call methods of the global TransitionScreen object, which you can obtain with TransitionScreen::get().
For example, to have a fixed widget while a left-to-right slide transition takes place, simply call:
TransitionScreen::get().setFloatingWidgets(fromWidget, toWidget); TransitionScreen::get().startTransition(toScreen, TT_SLIDE_IN, 1, 0);
where 'fromWidget' is the floating widget on the source screen, 'toWidget' is the companion widget on the destination screen and 'toScreen' is the new screen to display.
Hope someone will find this useful.
Alessandro
Edit: just a quick fix to allow for better diagonal transitions (dx != 0 and dy != 0 ).
| Attachment | Size |
|---|---|
| Transitions_1.01.zip | 20.38 KB |