Skip to content

Commit

Permalink
feat(device): Implement Device in C++
Browse files Browse the repository at this point in the history
  • Loading branch information
iBelieve committed Mar 22, 2016
1 parent df2f16f commit 05691d8
Show file tree
Hide file tree
Showing 12 changed files with 276 additions and 134 deletions.
File renamed without changes.
Empty file added LICENSE.MPL
Empty file.
10 changes: 10 additions & 0 deletions material.pri
@@ -1 +1,11 @@
QT += qml quick

HEADERS += src/plugin.h \
src/core/device.h

SOURCES += src/plugin.cpp \
src/core/device.cpp

RESOURCES += src/material.qrc

OTHER_FILES = README.md CHANGELOG.md
4 changes: 4 additions & 0 deletions qml-material.pro
@@ -0,0 +1,4 @@
include(material.pri)

TEMPLATE = lib
TARGET = material
80 changes: 0 additions & 80 deletions src/core/Device.qml

This file was deleted.

141 changes: 141 additions & 0 deletions src/core/device.cpp
@@ -0,0 +1,141 @@
/*
* QML Material - An application framework implementing Material Design.
*
* Copyright (C) 2016 Michael Spencer <sonrisesoftware@gmail.com>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "device.h"

Device::Device(QObject *parent)
: QObject(parent)
{
QGuiApplication *app = (QGuiApplication *) QGuiApplication::instance();
m_screen = app->primaryScreen();

connect(app, &QGuiApplication::primaryScreenChanged,
this, &Device::screenChanged);
}

QObject *Device::qmlSingleton(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)

return new Device();
}

Device::FormFactor Device::formFactor() const
{
float diagonal = calculateDiagonal();

if (diagonal >= 3.5 && diagonal < 5) { //iPhone 1st generation to phablet
return Device::Phone;
} else if (diagonal >= 5 && diagonal < 6.5) {
return Device::Phablet;
} else if (diagonal >= 6.5 && diagonal < 10.1) {
return Device::Tablet;
} else if (diagonal >= 10.1 && diagonal < 29) {
return Device::Computer;
} else if (diagonal >= 29 && diagonal < 92) {
return Device::TV;
} else {
return Device::Unknown;
}
}

QString Device::name() const
{
switch (formFactor()) {
case Phone:
return tr("phone");
case Phablet:
return tr("phablet");
case Tablet:
return tr("tablet");
case Computer:
return tr("computer");
case TV:
return tr("TV");
case Unknown:
return tr("device");
}
}

QString Device::iconName() const
{
switch (formFactor()) {
case Phone:
return "hardware/smartphone";
case Phablet:
return "hardware/tablet";
case Tablet:
return "hardware/tablet";
case Computer:
return "hardware/desktop_windows";
case TV:
return "hardware/tv";
case Unknown:
return "hardware/computer";
}
}

bool Device::hasTouchScreen() const
{
// QTBUG-36007
#if defined(Q_OS_ANDROID)
return true;
#else
const auto devices = QTouchDevice::devices();
for (const QTouchDevice *dev : devices)
if (dev->type() == QTouchDevice::TouchScreen)
return true;
return false;
#endif
}

bool Device::isMobile() const
{
#if defined(Q_OS_IOS) || defined(Q_OS_ANDROID) || defined(Q_OS_BLACKBERRY) || defined(Q_OS_QNX) || defined(Q_OS_WINRT)
return true;
#else
if (qEnvironmentVariableIsSet("QT_QUICK_CONTROLS_MOBILE")) {
return true;
}
return false;
#endif
}

bool Device::hoverEnabled() const
{
return !isMobile() || !hasTouchScreen();
}

void Device::screenChanged()
{
if (m_screen)
m_screen->disconnect(this);

QGuiApplication *app = (QGuiApplication *) QGuiApplication::instance();
m_screen = app->primaryScreen();

connect(m_screen, &QScreen::geometryChanged, this, &Device::geometryChanged);

geometryChanged();
}

void Device::geometryChanged()
{
emit formFactorChanged();
emit nameChanged();
emit iconNameChanged();
}

float Device::calculateDiagonal() const
{
return sqrt(pow((m_screen->physicalSize().width()), 2) +
pow((m_screen->physicalSize().height()), 2)) * 0.039370;
}
73 changes: 73 additions & 0 deletions src/core/device.h
@@ -0,0 +1,73 @@
/*
* QML Material - An application framework implementing Material Design.
*
* Copyright (C) 2016 Michael Spencer <sonrisesoftware@gmail.com>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#ifndef DEVICE_H
#define DEVICE_H

#include <QObject>

#include <cmath>
#include <QQmlEngine>
#include <QGuiApplication>
#include <QScreen>
#include <QTouchDevice>

class Device : public QObject {
Q_OBJECT

Q_PROPERTY(FormFactor formFactor READ formFactor NOTIFY formFactorChanged)
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(QString iconName READ iconName NOTIFY iconNameChanged)
Q_PROPERTY(bool isMobile READ isMobile CONSTANT)
Q_PROPERTY(bool hasTouchScreen READ hasTouchScreen CONSTANT)
Q_PROPERTY(bool hoverEnabled READ hoverEnabled CONSTANT)

public:
enum FormFactor {
Phone,
Phablet,
Tablet,
Computer,
TV,
Unknown
};
Q_ENUM(FormFactor)

Device(QObject *parent = nullptr);

static QObject *qmlSingleton(QQmlEngine *engine, QJSEngine *scriptEngine);

FormFactor formFactor() const;
QString name() const;
QString iconName() const;

bool hasTouchScreen() const;
bool isMobile() const;
bool hoverEnabled() const;

signals:
void formFactorChanged();
void nameChanged();
void iconNameChanged();
void isMobileChanged();
void hasTouchScreenChanged();
void hoverEnabledChanged();

private slots:
void screenChanged();
void geometryChanged();

private:
QScreen *m_screen;

float calculateDiagonal() const;
};

#endif // DEVICE_H
23 changes: 23 additions & 0 deletions src/plugin.cpp
@@ -0,0 +1,23 @@
/*
* QML Material - An application framework implementing Material Design.
*
* Copyright (C) 2016 Michael Spencer <sonrisesoftware@gmail.com>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "plugin.h"

#include <QtQml>

#include "core/device.h"

void Plugin::registerTypes(const char *uri)
{
// @uri Material
Q_ASSERT(uri == QStringLiteral("Material"));

qmlRegisterSingletonType<Device>(uri, 0, 1, "Device", Device::qmlSingleton);
}
25 changes: 25 additions & 0 deletions src/plugin.h
@@ -0,0 +1,25 @@
/*
* QML Material - An application framework implementing Material Design.
*
* Copyright (C) 2016 Michael Spencer <sonrisesoftware@gmail.com>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#ifndef PLUGIN_H
#define PLUGIN_H

#include <QQmlExtensionPlugin>

class Plugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "io.papyros.Material")

public:
void registerTypes(const char *uri);
};

#endif // PLUGIN_H
18 changes: 0 additions & 18 deletions src/window/ApplicationWindow.qml
Expand Up @@ -204,24 +204,6 @@ Controls.ApplicationWindow {
}
});

Device.type = Qt.binding(function () {
var diagonal = calculateDiagonal();

if (diagonal >= 3.5 && diagonal < 5) { //iPhone 1st generation to phablet
return Device.phone;
} else if (diagonal >= 5 && diagonal < 6.5) {
return Device.phablet;
} else if (diagonal >= 6.5 && diagonal < 10.1) {
return Device.tablet;
} else if (diagonal >= 10.1 && diagonal < 29) {
return Device.desktop;
} else if (diagonal >= 29 && diagonal < 92) {
return Device.tv;
} else {
return Device.unknown;
}
});

// Nasty hack because singletons cannot import the module they were declared in, so
// the grid unit cannot be defined in either Device or Units, because it requires both.
Units.gridUnit = Qt.binding(function() {
Expand Down

0 comments on commit 05691d8

Please sign in to comment.