Qt-based BB10 API Examples Documentation

Contents

Image Rotation Example

Files:

Description

The Image Rotation example demonstrates how to use sensors from the QtSensors module to always show an image upright on the screen independently of the current device orientation.

Overview

In this example we'll learn how to use the QRotationSensor, QRotationFilter and QRotationReading classes calculate the angle between the reference position of the device and its current position to display an image upright on the screen.

The UI

The UI of this sample application simply consists of an ImageView that shows the image in the center of the screen.

The business logic of the application is encapsulated in the RotationSensor class which is made available to the UI under the name '_sensor'.

    ImageView {
        horizontalAlignment: HorizontalAlignment.Center
        verticalAlignment: VerticalAlignment.Center

        imageSource: "asset:///images/mona_lisa.jpg"

        // Bind the rotation of the image against the rotation property of the sensor object
        rotationZ: _sensor.rotation

        // Disable implicit animations to avoid ugly 'jumps' when switching from 180 degree to -180 degree and vice versa
        attachedObjects: [
            ImplicitAnimationController {
                propertyName: "rotationZ"
                enabled: false
            }
        ]
    }

The image is rotated according to the rotation angle as reported by the sensor object. To avoid the implicit animation on the 0 <-> 360 degree switch, we disable the implicit animation for the 'rotationZ' property explicitly.

RotationSensor

The RotationSensor encapsulates the business logic of the application. It contains a QRotationSensor object, which does the low-level communication with the rotation sensor of the device, and provides a property 'rotation' to make the calculated angle available to the UI. It inherits from QRotationFilter and reimplements the 'bool filter(QRotationReading*)' method to retrieve the sensor data from the QRotationSensor object.

    class RotationSensor : public QObject, public QRotationFilter
    {
        Q_OBJECT

        // The property to access the rotation angle
        Q_PROPERTY(qreal rotation READ rotation NOTIFY rotationChanged)

    public:
        RotationSensor(QObject *parent = 0);

        // The accessor methods for the properties
        qreal rotation() const;

    Q_SIGNALS:
        // The change notification signals of the properties
        void rotationChanged();

    protected:
        /**
         * This method is reimplemented from the QRotationFilter interface and is
         * called by the QRotationSensor whenever new values are available.
         */
        bool filter(QRotationReading *reading);

    private:
        // The rotation sensor
        QRotationSensor m_rotationSensor;

        // The rotation property
        qreal m_rotation;
    };

Inside the constructor we try to connect the QRotationSensor object to the hardware backend. If that's successful, we register the RotationSensor class as filter for the QRotationSensor object and start the sensor to gather data.

    RotationSensor::RotationSensor(QObject *parent)
        : QObject(parent)
        , m_rotation(0)
    {
        // We'd like to lock to the initial orientation
        OrientationSupport::instance()->setSupportedDisplayOrientation(SupportedDisplayOrientation::CurrentLocked);

        // At first we have to connect to the sensor backend...
        if (!m_rotationSensor.connectToBackend()) {
            qWarning() << "Cannot connect to rotation sensor backend!";
        }

        // ... and then add a filter that will process the read data
        m_rotationSensor.addFilter(this);

        // Start gathering the data
        m_rotationSensor.start();
    }

The 'bool filter(QRotationReading*)' method is called whenever the QRotationSensor object retrieved new data from the hardware sensor. Inside this method we calculate the rotation angle by comparing the reported x and y values.

    bool RotationSensor::filter(QRotationReading *reading)
    {
        const qreal x = reading->x();
        const qreal y = reading->y();

        if (x > 0 && x < 90) {
            if (y > 0) { // top-left quadrant
                m_rotation = (x - 90);
            } else { // top-right quadrant
                m_rotation = (90 - x);
            }
        } else { // bottom-left quadrant
            if (y > 0) {
                m_rotation = (-90 + x);
            } else { // bottom right quadrant
                m_rotation = (90 - x);
            }
        }

        emit rotationChanged();

        // Do no further processing of the sensor data
        return false;
    }