Styles was added
@@ -16,9 +16,11 @@ set(TS_FILES beerlog_ru_RU.ts)
|
|||||||
|
|
||||||
set(PROJECT_SOURCES
|
set(PROJECT_SOURCES
|
||||||
main.cpp
|
main.cpp
|
||||||
qml.qrc
|
qml/qml.qrc
|
||||||
|
models/abstractmodel.h models/abstractmodel.cpp
|
||||||
models/summarymodel.h models/summarymodel.cpp
|
models/summarymodel.h models/summarymodel.cpp
|
||||||
models/usersmodel.h models/usersmodel.cpp
|
models/usersmodel.h models/usersmodel.cpp
|
||||||
|
viewmodels/usersviewmodel.h viewmodels/usersviewmodel.cpp
|
||||||
services/beerservice.h services/beerservice.cpp
|
services/beerservice.h services/beerservice.cpp
|
||||||
services/settingsservice.h services/settingsservice.cpp
|
services/settingsservice.h services/settingsservice.cpp
|
||||||
${TS_FILES}
|
${TS_FILES}
|
||||||
@@ -32,8 +34,8 @@ if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
|||||||
${PROJECT_SOURCES}
|
${PROJECT_SOURCES}
|
||||||
)
|
)
|
||||||
# Define target properties for Android with Qt 6 as:
|
# Define target properties for Android with Qt 6 as:
|
||||||
# set_property(TARGET beerlog APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
|
set_property(TARGET beerlog APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
|
||||||
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
|
${CMAKE_CURRENT_SOURCE_DIR}/android)
|
||||||
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
|
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
|
||||||
|
|
||||||
qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
|
qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ru.ded.beerlog" android:installLocation="auto" android:versionCode="0.0.1" android:versionName="-- %%INSERT_VERSION_NAME%% --">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ru.ded.beerlog" android:installLocation="auto" android:versionCode="1" android:versionName="0.1">
|
||||||
<!-- %%INSERT_PERMISSIONS -->
|
<!-- %%INSERT_PERMISSIONS -->
|
||||||
<!-- %%INSERT_FEATURES -->
|
<!-- %%INSERT_FEATURES -->
|
||||||
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true"/>
|
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true"/>
|
||||||
<application android:name="org.qtproject.qt.android.bindings.QtApplication" android:extractNativeLibs="true" android:hardwareAccelerated="true" android:label="BeerLog" android:requestLegacyExternalStorage="true" android:allowNativeHeapPointerTagging="false">
|
<application android:name="org.qtproject.qt.android.bindings.QtApplication" android:extractNativeLibs="true" android:hardwareAccelerated="true" android:label="BeerLog" android:requestLegacyExternalStorage="true" android:allowNativeHeapPointerTagging="false" android:icon="@drawable/icon">
|
||||||
<activity android:name="org.qtproject.qt.android.bindings.QtActivity" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:label="BeerLog" android:launchMode="singleTop" android:screenOrientation="unspecified">
|
<activity android:name="org.qtproject.qt.android.bindings.QtActivity" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:label="BeerLog" android:launchMode="singleTop" android:screenOrientation="unspecified">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|||||||
BIN
android/res/drawable-hdpi/icon.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
android/res/drawable-ldpi/icon.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
android/res/drawable-mdpi/icon.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
android/res/drawable-xhdpi/icon.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
android/res/drawable-xxhdpi/icon.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
android/res/drawable-xxxhdpi/icon.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
@@ -4,31 +4,25 @@
|
|||||||
<context>
|
<context>
|
||||||
<name>main</name>
|
<name>main</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="main.qml" line="13"/>
|
<location filename="qml/main.qml" line="14"/>
|
||||||
<source>Beer Log</source>
|
<source>Beer Log</source>
|
||||||
<translation></translation>
|
<translation></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="main.qml" line="19"/>
|
<location filename="qml/main.qml" line="77"/>
|
||||||
<source>‹</source>
|
<source>BeerLog v0.1</source>
|
||||||
<translation type="unfinished"></translation>
|
<oldsource>BeerLog v1.0.0</oldsource>
|
||||||
|
<translation></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="main.qml" line="28"/>
|
<location filename="qml/main.qml" line="82"/>
|
||||||
<source>⋮</source>
|
<source>Settings</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Настройки</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Summary: %1 р.</source>
|
<location filename="qml/main.qml" line="88"/>
|
||||||
<translation type="vanished">Итого: %1 р.</translation>
|
<source>Quit</source>
|
||||||
</message>
|
<translation>Выход</translation>
|
||||||
<message>
|
|
||||||
<source>Order</source>
|
|
||||||
<translation type="vanished">Заказать</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Ordered %1 items. Amount: %2 р.</source>
|
|
||||||
<translation type="vanished">Заказано %1 позиций на сумму %2 р.</translation>
|
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|||||||
8
main.cpp
@@ -5,8 +5,7 @@
|
|||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
|
|
||||||
#include "models/summarymodel.h"
|
#include "viewmodels/usersviewmodel.h"
|
||||||
#include "models/usersmodel.h"
|
|
||||||
#include "services/beerservice.h"
|
#include "services/beerservice.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@@ -34,9 +33,8 @@ int main(int argc, char *argv[])
|
|||||||
QCoreApplication::exit(-1);
|
QCoreApplication::exit(-1);
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
|
|
||||||
engine.rootContext()->setContextProperty("beerService", new BeerService(&engine));
|
engine.rootContext()->setContextProperty("beerService", BeerService::instance());
|
||||||
qmlRegisterType<SummaryModel>("ru.ded.beerlog", 1, 0, "SummaryModel");
|
qmlRegisterType<UsersViewModel>("ru.ded.beerlog", 1, 0, "UsersViewModel");
|
||||||
qmlRegisterType<UsersModel>("ru.ded.beerlog", 1, 0, "UsersModel");
|
|
||||||
|
|
||||||
engine.load(url);
|
engine.load(url);
|
||||||
|
|
||||||
|
|||||||
63
main.qml
@@ -1,63 +0,0 @@
|
|||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Window 2.15
|
|
||||||
import QtQuick.Controls 2.15
|
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
import QtWebSockets
|
|
||||||
|
|
||||||
import ru.ded.beerlog 1.0
|
|
||||||
|
|
||||||
ApplicationWindow {
|
|
||||||
width: 640
|
|
||||||
height: 480
|
|
||||||
visible: true
|
|
||||||
title: qsTr("Beer Log")
|
|
||||||
|
|
||||||
header: ToolBar {
|
|
||||||
RowLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
ToolButton {
|
|
||||||
text: qsTr("‹")
|
|
||||||
onClicked: stack.pop()
|
|
||||||
}
|
|
||||||
ToolButton {
|
|
||||||
text: usersModel.selectedUserName
|
|
||||||
Layout.fillWidth: true
|
|
||||||
onClicked: usersMenu.open()
|
|
||||||
}
|
|
||||||
ToolButton {
|
|
||||||
text: qsTr("⋮")
|
|
||||||
onClicked: menu.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu {
|
|
||||||
id: usersMenu
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: usersModel.users
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: modelData.name
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
usersModel.selectedUser = modelData.id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UsersModel {
|
|
||||||
id: usersModel
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
beerService.connectSrv(selectedUser)
|
|
||||||
beerService.connectListener(usersModel)
|
|
||||||
beerService.sendCommand("users", "get")
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelectedUserChanged: {
|
|
||||||
beerService.connectSrv(selectedUser)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
41
models/abstractmodel.cpp
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#include "abstractmodel.h"
|
||||||
|
|
||||||
|
#include "services/beerservice.h"
|
||||||
|
|
||||||
|
AbstractModel::AbstractModel(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractModel::created(const QVariant &data)
|
||||||
|
{
|
||||||
|
modified(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractModel::modified(const QVariant &data)
|
||||||
|
{
|
||||||
|
QVariantMap d = data.toMap();
|
||||||
|
m_data[d.value("id").toString()] = d;
|
||||||
|
|
||||||
|
emit dataChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractModel::deleted(const QVariant &data)
|
||||||
|
{
|
||||||
|
QString id = data.toString();
|
||||||
|
m_data.remove(id);
|
||||||
|
|
||||||
|
emit dataChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractModel::received(const QVariant &data)
|
||||||
|
{
|
||||||
|
m_data = data.toMap();
|
||||||
|
|
||||||
|
emit dataChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
BeerService *AbstractModel::service() const
|
||||||
|
{
|
||||||
|
return BeerService::instance();
|
||||||
|
}
|
||||||
34
models/abstractmodel.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef ABSTRACTMODEL_H
|
||||||
|
#define ABSTRACTMODEL_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QVariantMap>
|
||||||
|
|
||||||
|
class BeerService;
|
||||||
|
class AbstractModel : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QString entity READ entity CONSTANT)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AbstractModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
virtual QString entity() const = 0;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void created(const QVariant &data);
|
||||||
|
void modified(const QVariant &data);
|
||||||
|
void deleted(const QVariant &data);
|
||||||
|
void received(const QVariant &data);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void dataChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BeerService *service() const;
|
||||||
|
|
||||||
|
QVariantMap m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ABSTRACTMODEL_H
|
||||||
@@ -1,80 +1,42 @@
|
|||||||
#include "usersmodel.h"
|
#include "usersmodel.h"
|
||||||
|
|
||||||
|
#include "services/beerservice.h"
|
||||||
|
|
||||||
|
namespace Keys {
|
||||||
|
|
||||||
|
constexpr auto Users = "users";
|
||||||
|
constexpr auto Name = "name";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
UsersModel::UsersModel(QObject *parent)
|
UsersModel::UsersModel(QObject *parent)
|
||||||
: QObject{parent}
|
: AbstractModel{parent}
|
||||||
{
|
{
|
||||||
setSelectedUser(m_settings.value("selected_user").toString());
|
service()->connectListener(this);
|
||||||
}
|
service()->sendCommand(Keys::Users, "get");
|
||||||
|
|
||||||
void UsersModel::created(const QVariant &data)
|
|
||||||
{
|
|
||||||
modified(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UsersModel::modified(const QVariant &data)
|
|
||||||
{
|
|
||||||
QVariantMap user = data.toMap();
|
|
||||||
m_users[user.value("id").toString()] = user;
|
|
||||||
|
|
||||||
emit usersChanged();
|
|
||||||
emit selectedUserNameChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UsersModel::deleted(const QVariant &data)
|
|
||||||
{
|
|
||||||
QString userId = data.toString();
|
|
||||||
m_users.remove(userId);
|
|
||||||
|
|
||||||
emit usersChanged();
|
|
||||||
emit selectedUserNameChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UsersModel::received(const QVariant &data)
|
|
||||||
{
|
|
||||||
m_users = data.toMap();
|
|
||||||
|
|
||||||
emit usersChanged();
|
|
||||||
emit selectedUserNameChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UsersModel::connected(const QVariant &data)
|
|
||||||
{
|
|
||||||
qInfo() << data.toMap().value("name").toString() << "connected";
|
|
||||||
}
|
|
||||||
|
|
||||||
void UsersModel::disconnected(const QVariant &data)
|
|
||||||
{
|
|
||||||
qInfo() << data.toMap().value("name").toString() << "disconnected";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString UsersModel::entity() const
|
QString UsersModel::entity() const
|
||||||
{
|
{
|
||||||
return QStringLiteral("users");
|
return Keys::Users;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsersModel::connected(const QVariant &data)
|
||||||
|
{
|
||||||
|
qInfo() << data.toMap().value(Keys::Name).toString() << "connected";
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsersModel::disconnected(const QVariant &data)
|
||||||
|
{
|
||||||
|
qInfo() << data.toMap().value(Keys::Name).toString() << "disconnected";
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantList UsersModel::users() const
|
QVariantList UsersModel::users() const
|
||||||
{
|
{
|
||||||
return m_users.values();
|
return m_data.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString UsersModel::selectedUser() const
|
QString UsersModel::userName(const QString &userId) const
|
||||||
{
|
{
|
||||||
return m_selectedUser;
|
return m_data.value(userId).toMap().value(Keys::Name).toString();
|
||||||
}
|
|
||||||
|
|
||||||
void UsersModel::setSelectedUser(const QString &newSelectedUser)
|
|
||||||
{
|
|
||||||
if (m_selectedUser == newSelectedUser) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_selectedUser = newSelectedUser;
|
|
||||||
m_settings.setValue("selected_user", m_selectedUser);
|
|
||||||
emit selectedUserChanged();
|
|
||||||
emit selectedUserNameChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString UsersModel::selectedUserName() const
|
|
||||||
{
|
|
||||||
return m_users.value(m_selectedUser).toMap().value("name").toString();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,43 +5,23 @@
|
|||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
|
|
||||||
#include "services/settingsservice.h"
|
#include "services/settingsservice.h"
|
||||||
|
#include "models/abstractmodel.h"
|
||||||
|
|
||||||
class UsersModel : public QObject
|
class UsersModel : public AbstractModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(QString entity READ entity CONSTANT)
|
|
||||||
Q_PROPERTY(QVariantList users READ users NOTIFY usersChanged)
|
|
||||||
Q_PROPERTY(QString selectedUser READ selectedUser WRITE setSelectedUser NOTIFY selectedUserChanged)
|
|
||||||
Q_PROPERTY(QString selectedUserName READ selectedUserName NOTIFY selectedUserNameChanged)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit UsersModel(QObject *parent = nullptr);
|
explicit UsersModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
QString entity() const;
|
QString entity() const override;
|
||||||
|
|
||||||
QVariantList users() const;
|
QVariantList users() const;
|
||||||
QString selectedUser() const;
|
QString userName(const QString &userId) const;
|
||||||
void setSelectedUser(const QString &newSelectedUser);
|
|
||||||
QString selectedUserName() const;
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void created(const QVariant &data);
|
|
||||||
void modified(const QVariant &data);
|
|
||||||
void deleted(const QVariant &data);
|
|
||||||
void received(const QVariant &data);
|
|
||||||
void connected(const QVariant &data);
|
void connected(const QVariant &data);
|
||||||
void disconnected(const QVariant &data);
|
void disconnected(const QVariant &data);
|
||||||
|
|
||||||
signals:
|
|
||||||
void usersChanged();
|
|
||||||
void selectedUserChanged();
|
|
||||||
void selectedUserNameChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QVariantMap m_users;
|
|
||||||
QString m_selectedUser;
|
|
||||||
|
|
||||||
SettingsService m_settings;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // USERSMODEL_H
|
#endif // USERSMODEL_H
|
||||||
|
|||||||
84
qml/Components/MenuBackButton.qml
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
|
||||||
|
property double iconMarigns: 8
|
||||||
|
property double iconHeight: width - iconMarigns * 2
|
||||||
|
signal clicked()
|
||||||
|
signal back()
|
||||||
|
|
||||||
|
SystemPalette {
|
||||||
|
id: palette
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: ma
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: bar1
|
||||||
|
x: root.iconMarigns
|
||||||
|
y: root.iconMarigns + root.iconHeight / 6
|
||||||
|
width: root.iconHeight
|
||||||
|
height: root.iconHeight / 9
|
||||||
|
antialiasing: true
|
||||||
|
|
||||||
|
color: palette.button
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: bar2
|
||||||
|
x: root.iconMarigns
|
||||||
|
y: root.iconMarigns + root.iconHeight / 2 - height / 2
|
||||||
|
width: root.iconHeight
|
||||||
|
height: root.iconHeight / 9
|
||||||
|
antialiasing: true
|
||||||
|
|
||||||
|
color: palette.button
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: bar3
|
||||||
|
x: root.iconMarigns
|
||||||
|
y: root.iconMarigns + root.iconHeight / 2 + height * 2
|
||||||
|
width: root.iconHeight
|
||||||
|
height: root.iconHeight / 9
|
||||||
|
antialiasing: true
|
||||||
|
|
||||||
|
color: palette.button
|
||||||
|
}
|
||||||
|
|
||||||
|
property int animationDuration: 450
|
||||||
|
|
||||||
|
state: "menu"
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "menu"
|
||||||
|
PropertyChanges { target: ma; onClicked: root.clicked() }
|
||||||
|
},
|
||||||
|
|
||||||
|
State {
|
||||||
|
name: "back"
|
||||||
|
PropertyChanges { target: root; rotation: 180 }
|
||||||
|
PropertyChanges { target: bar1; rotation: 45; width: root.iconHeight / 3 * 2; x: root.iconMarigns + root.iconHeight / 2; y: root.iconMarigns + root.iconHeight / 4 }
|
||||||
|
PropertyChanges { target: bar2; width: root.iconHeight / 6 * 5 + 1; x: root.iconMarigns + root.iconHeight / 9 }
|
||||||
|
PropertyChanges { target: bar3; rotation: -45; width: root.iconHeight / 3 * 2; x: root.iconMarigns + root.iconHeight / 2; y: root.iconMarigns + root.iconHeight / 3 * 2 }
|
||||||
|
PropertyChanges { target: ma; onClicked: root.back() }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
transitions: [
|
||||||
|
Transition {
|
||||||
|
RotationAnimation { target: root; direction: RotationAnimation.Clockwise; duration: animationDuration; easing.type: Easing.InOutQuad }
|
||||||
|
PropertyAnimation { target: bar1; properties: "rotation, width, x, y"; duration: animationDuration; easing.type: Easing.InOutQuad }
|
||||||
|
PropertyAnimation { target: bar2; properties: "rotation, width, x, y"; duration: animationDuration; easing.type: Easing.InOutQuad }
|
||||||
|
PropertyAnimation { target: bar3; properties: "rotation, width, x, y"; duration: animationDuration; easing.type: Easing.InOutQuad }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
qml/logo.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
94
qml/main.qml
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtWebSockets
|
||||||
|
|
||||||
|
import ru.ded.beerlog 1.0
|
||||||
|
import "Components"
|
||||||
|
|
||||||
|
ApplicationWindow {
|
||||||
|
width: 640
|
||||||
|
height: 480
|
||||||
|
visible: true
|
||||||
|
title: qsTr("Beer Log")
|
||||||
|
|
||||||
|
header: ToolBar {
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
MenuBackButton {
|
||||||
|
state: "menu"//stackView.depth > 1 ? "back" : "menu"
|
||||||
|
onClicked: drawer.open()
|
||||||
|
onBack: {
|
||||||
|
state = "menu"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ToolButton {
|
||||||
|
text: usersModel.selectedUserName
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onClicked: usersMenu.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
id: usersMenu
|
||||||
|
|
||||||
|
UsersViewModel {
|
||||||
|
id: usersModel
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: usersModel.users
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: modelData.name
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
usersModel.selectedUser = modelData.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Drawer {
|
||||||
|
id: drawer
|
||||||
|
|
||||||
|
width: parent.width * 0.66
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
height: 100
|
||||||
|
|
||||||
|
Image {
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.margins: 10
|
||||||
|
source: "logo.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
font.pointSize: 20
|
||||||
|
text: qsTr("BeerLog v0.1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemDelegate {
|
||||||
|
text: qsTr("Settings")
|
||||||
|
width: parent.width
|
||||||
|
onClicked: stackView.openPage("SettingsForm.qml")
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemDelegate {
|
||||||
|
text: qsTr("Quit")
|
||||||
|
width: parent.width
|
||||||
|
onClicked: Qt.quit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file>main.qml</file>
|
<file>main.qml</file>
|
||||||
|
<file>Components/MenuBackButton.qml</file>
|
||||||
|
<file>qtquickcontrols2.conf</file>
|
||||||
|
<file>logo.png</file>
|
||||||
<file>beerlog_ru_RU.qm</file>
|
<file>beerlog_ru_RU.qm</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
13
qml/qtquickcontrols2.conf
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
; This file can be edited to change the style of the application
|
||||||
|
; Read "Qt Quick Controls 2 Configuration File" for details:
|
||||||
|
; http://doc.qt.io/qt-5/qtquickcontrols2-configuration.html
|
||||||
|
|
||||||
|
[Controls]
|
||||||
|
Style=Material
|
||||||
|
|
||||||
|
[Material]
|
||||||
|
Theme=Dark
|
||||||
|
Primary=BlueGrey
|
||||||
|
Accent=Grey
|
||||||
|
;Foreground=Brown
|
||||||
|
;Background=Steel
|
||||||
@@ -7,14 +7,8 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
namespace {
|
BeerService::BeerService()
|
||||||
|
: QObject{nullptr}
|
||||||
constexpr auto GuestUserId = "2641ffe8cd4311eda27f0242ac120002";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
BeerService::BeerService(QObject *parent)
|
|
||||||
: QObject{parent}
|
|
||||||
{
|
{
|
||||||
restoreStash();
|
restoreStash();
|
||||||
|
|
||||||
@@ -59,8 +53,7 @@ void BeerService::connectSrv(const QString &userId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QNetworkRequest request(QUrl("ws://195.133.196.161:8000"));
|
QNetworkRequest request(QUrl("ws://195.133.196.161:8000"));
|
||||||
QString authString = QString("%1:pass").arg(userId.isEmpty() ? GuestUserId : userId);
|
request.setRawHeader("Authorization", "Basic " + QString("%1:pass").arg(userId).toLatin1().toBase64());
|
||||||
request.setRawHeader("Authorization", "Basic " + authString.toLatin1().toBase64());
|
|
||||||
m_socket.open(request);
|
m_socket.open(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,14 +9,21 @@ class BeerService : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BeerService(QObject *parent = nullptr);
|
static BeerService *instance()
|
||||||
~BeerService();
|
{
|
||||||
|
static BeerService i;
|
||||||
|
return &i;
|
||||||
|
}
|
||||||
|
|
||||||
Q_INVOKABLE void connectSrv(const QString &userId = QString());
|
Q_INVOKABLE void connectSrv(const QString &userId = QString());
|
||||||
Q_INVOKABLE void sendCommand(const QString &entity, const QString &action, const QVariantMap &data = QVariantMap());
|
|
||||||
Q_INVOKABLE void connectListener(QObject *listener);
|
void sendCommand(const QString &entity, const QString &action, const QVariantMap &data = QVariantMap());
|
||||||
|
void connectListener(QObject *listener);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
BeerService();
|
||||||
|
~BeerService();
|
||||||
|
|
||||||
QString stashFileName() const;
|
QString stashFileName() const;
|
||||||
void saveStash() const;
|
void saveStash() const;
|
||||||
void restoreStash();
|
void restoreStash();
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
#include "settingsservice.h"
|
#include "settingsservice.h"
|
||||||
|
|
||||||
|
namespace Defaults {
|
||||||
|
|
||||||
|
constexpr auto GuestUserId = "2641ffe8cd4311eda27f0242ac120002";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QVariant SettingsService::value(const QString &key, const QVariant &defaultValue) const
|
QVariant SettingsService::value(const QString &key, const QVariant &defaultValue) const
|
||||||
{
|
{
|
||||||
return m_settings.value(key, defaultValue);
|
return m_settings.value(key, defaultValue);
|
||||||
@@ -9,3 +15,13 @@ void SettingsService::setValue(const QString &key, const QVariant &value)
|
|||||||
{
|
{
|
||||||
m_settings.setValue(key, value);
|
m_settings.setValue(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString SettingsService::selectedUserId() const
|
||||||
|
{
|
||||||
|
return m_settings.value("selected_user", Defaults::GuestUserId).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsService::setSelectedUserId(const QString &userId)
|
||||||
|
{
|
||||||
|
m_settings.setValue("selected_user", userId);
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ public:
|
|||||||
QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
|
QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
|
||||||
void setValue(const QString &key, const QVariant &value);
|
void setValue(const QString &key, const QVariant &value);
|
||||||
|
|
||||||
|
QString selectedUserId() const;
|
||||||
|
void setSelectedUserId(const QString &userId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSettings m_settings = QSettings("DedSoft", "BeerLog");
|
QSettings m_settings = QSettings("DedSoft", "BeerLog");
|
||||||
};
|
};
|
||||||
|
|||||||
43
viewmodels/usersviewmodel.cpp
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#include "usersviewmodel.h"
|
||||||
|
|
||||||
|
#include "services/beerservice.h"
|
||||||
|
|
||||||
|
UsersViewModel::UsersViewModel(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
connect(this, &UsersViewModel::selectedUserChanged, this, [this]() {
|
||||||
|
BeerService::instance()->connectSrv(m_selectedUser);
|
||||||
|
});
|
||||||
|
|
||||||
|
setSelectedUser(m_settings.selectedUserId());
|
||||||
|
|
||||||
|
connect(&m_usersModel, &AbstractModel::dataChanged, this, &UsersViewModel::usersChanged);
|
||||||
|
connect(&m_usersModel, &AbstractModel::dataChanged, this, &UsersViewModel::selectedUserNameChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantList UsersViewModel::users() const
|
||||||
|
{
|
||||||
|
return m_usersModel.users();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UsersViewModel::selectedUser() const
|
||||||
|
{
|
||||||
|
return m_selectedUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsersViewModel::setSelectedUser(const QString &newSelectedUser)
|
||||||
|
{
|
||||||
|
if (m_selectedUser == newSelectedUser) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_selectedUser = newSelectedUser;
|
||||||
|
m_settings.setSelectedUserId(m_selectedUser);
|
||||||
|
emit selectedUserChanged();
|
||||||
|
emit selectedUserNameChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UsersViewModel::selectedUserName() const
|
||||||
|
{
|
||||||
|
return m_usersModel.userName(m_selectedUser);
|
||||||
|
}
|
||||||
36
viewmodels/usersviewmodel.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef USERSVIEWMODEL_H
|
||||||
|
#define USERSVIEWMODEL_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "models/usersmodel.h"
|
||||||
|
|
||||||
|
class UsersViewModel : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QVariantList users READ users NOTIFY usersChanged)
|
||||||
|
Q_PROPERTY(QString selectedUser READ selectedUser WRITE setSelectedUser NOTIFY selectedUserChanged)
|
||||||
|
Q_PROPERTY(QString selectedUserName READ selectedUserName NOTIFY selectedUserNameChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit UsersViewModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QVariantList users() const;
|
||||||
|
QString selectedUser() const;
|
||||||
|
void setSelectedUser(const QString &newSelectedUser);
|
||||||
|
QString selectedUserName() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void usersChanged();
|
||||||
|
void selectedUserChanged();
|
||||||
|
void selectedUserNameChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_selectedUser;
|
||||||
|
|
||||||
|
UsersModel m_usersModel;
|
||||||
|
SettingsService m_settings;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // USERSVIEWMODEL_H
|
||||||