mirror of
https://github.com/wownero/wowlet.git
synced 2026-10-17 07:11:29 +02:00
feat: ambient scene system + unlock-screen banner (reduced-motion aware)
Reusable SceneWidget (QQuickWidget host) loads scene.qml — dusk sky, tiled grass, running doge, bouncing WOW coins (slowed per feedback), drifting money — and feeds it Config::reducedMotion so it freezes to a still when that's set. First placement: a banner atop the unlock form. Scene rendered & verified at banner + screensaver aspects via local qml6 harness. Assets from wow-lite-wallet (friend's). Home banner / idle screensaver / per-tab idle to follow on the same SceneWidget.
This commit is contained in:
+1
-1
@@ -34,7 +34,7 @@ if (CHECK_UPDATES)
|
|||||||
add_subdirectory(openpgp)
|
add_subdirectory(openpgp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
qt_add_resources(RESOURCES assets.qrc assets_tor.qrc assets_wownerod.qrc assets_docs.qrc mining.qrc silly.qrc)
|
qt_add_resources(RESOURCES assets.qrc assets_tor.qrc assets_wownerod.qrc assets_docs.qrc mining.qrc silly.qrc scene.qrc)
|
||||||
|
|
||||||
# Compile source files (.h/.cpp)
|
# Compile source files (.h/.cpp)
|
||||||
file(GLOB SOURCE_FILES
|
file(GLOB SOURCE_FILES
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 131 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1,49 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
// wowlet ambient scene — dusk sky, tiled grass, a running doge, bouncing WOW
|
||||||
|
// coins, drifting money. All motion gates on `scene.reducedMotion` (exposed by
|
||||||
|
// the host SceneBackend); frozen it is the reduced-motion still.
|
||||||
|
Rectangle {
|
||||||
|
id: scene
|
||||||
|
property bool reducedMotion: (typeof sceneCtx !== 'undefined' && sceneCtx) ? sceneCtx.reducedMotion : false
|
||||||
|
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop { position: 0.0; color: "#160d2b" }
|
||||||
|
GradientStop { position: 0.5; color: "#5b2f6e" }
|
||||||
|
GradientStop { position: 0.82; color: "#c96aa0" }
|
||||||
|
GradientStop { position: 1.0; color: "#f2adc9" }
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle { x: parent.width*0.74; y: parent.height*0.14; width: 62; height: 62; radius: 31; color: "#ffe9b0"; opacity: 0.9 }
|
||||||
|
|
||||||
|
AnimatedImage {
|
||||||
|
source: "qrc:/scene/flyingmoney.gif"; playing: !scene.reducedMotion
|
||||||
|
width: 70; height: 64; y: 30; x: 120; opacity: 0.9
|
||||||
|
NumberAnimation on x { running: !scene.reducedMotion; from: -80; to: scene.width; duration: 11000; loops: Animation.Infinite }
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
Repeater { model: Math.ceil(scene.width/180)+1
|
||||||
|
Image { source: "qrc:/scene/grass.png"; width: 180; height: 46; smooth: false } }
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: 3
|
||||||
|
AnimatedImage {
|
||||||
|
source: "qrc:/scene/goldcoin.gif"; playing: !scene.reducedMotion
|
||||||
|
width: 34; height: 34; x: 150 + index*170; y: scene.height*0.46
|
||||||
|
SequentialAnimation on y {
|
||||||
|
running: !scene.reducedMotion; loops: Animation.Infinite
|
||||||
|
NumberAnimation { to: scene.height*0.36; duration: 1050 + index*170; easing.type: Easing.OutQuad }
|
||||||
|
NumberAnimation { to: scene.height*0.5; duration: 1050 + index*170; easing.type: Easing.InQuad }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimatedImage {
|
||||||
|
source: "qrc:/scene/dog.gif"; playing: !scene.reducedMotion
|
||||||
|
width: 104; height: 83; y: scene.height - 46 - 62; x: 70
|
||||||
|
NumberAnimation on x { running: !scene.reducedMotion; from: -110; to: scene.width; duration: 6500; loops: Animation.Infinite }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE RCC><RCC version="1.0">
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file alias="qml/scene.qml">assets/qml/scene.qml</file>
|
||||||
|
<file alias="scene/dog2.gif">assets/images/scene/dog2.gif</file>
|
||||||
|
<file alias="scene/dog.gif">assets/images/scene/dog.gif</file>
|
||||||
|
<file alias="scene/flyingmoney.gif">assets/images/scene/flyingmoney.gif</file>
|
||||||
|
<file alias="scene/goldcoin.gif">assets/images/scene/goldcoin.gif</file>
|
||||||
|
<file alias="scene/grass.png">assets/images/scene/grass.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
// SPDX-FileCopyrightText: The Monero Project
|
||||||
|
|
||||||
|
#include "SceneWidget.h"
|
||||||
|
|
||||||
|
#include <QQmlContext>
|
||||||
|
|
||||||
|
#include "utils/config.h"
|
||||||
|
|
||||||
|
SceneWidget::SceneWidget(QWidget *parent)
|
||||||
|
: QQuickWidget(parent)
|
||||||
|
, m_backend(new SceneBackend(this))
|
||||||
|
{
|
||||||
|
m_backend->setReducedMotion(conf()->get(Config::reducedMotion).toBool());
|
||||||
|
this->rootContext()->setContextProperty("sceneCtx", m_backend);
|
||||||
|
this->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
|
this->setSource(QUrl("qrc:/qml/scene.qml"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneWidget::refreshReducedMotion() {
|
||||||
|
m_backend->setReducedMotion(conf()->get(Config::reducedMotion).toBool());
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
// SPDX-FileCopyrightText: The Monero Project
|
||||||
|
|
||||||
|
#ifndef WOWLET_SCENEWIDGET_H
|
||||||
|
#define WOWLET_SCENEWIDGET_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QQuickWidget>
|
||||||
|
|
||||||
|
// Context object exposed to scene.qml as `sceneCtx`. Carries the reduced-motion
|
||||||
|
// setting so the scene freezes into its still (reduced-motion) form.
|
||||||
|
class SceneBackend : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool reducedMotion READ reducedMotion NOTIFY reducedMotionChanged)
|
||||||
|
public:
|
||||||
|
explicit SceneBackend(QObject *parent = nullptr) : QObject(parent) {}
|
||||||
|
bool reducedMotion() const { return m_reducedMotion; }
|
||||||
|
void setReducedMotion(bool r) { if (m_reducedMotion != r) { m_reducedMotion = r; emit reducedMotionChanged(); } }
|
||||||
|
signals:
|
||||||
|
void reducedMotionChanged();
|
||||||
|
private:
|
||||||
|
bool m_reducedMotion = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// wowlet: reusable ambient-scene surface. Hosts scene.qml and reads the
|
||||||
|
// reduced-motion preference from Config. Drop it behind a form, into a banner,
|
||||||
|
// or over the window as an idle screensaver.
|
||||||
|
class SceneWidget : public QQuickWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit SceneWidget(QWidget *parent = nullptr);
|
||||||
|
void refreshReducedMotion();
|
||||||
|
private:
|
||||||
|
SceneBackend *m_backend;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //WOWLET_SCENEWIDGET_H
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "utils/Utils.h"
|
#include "utils/Utils.h"
|
||||||
#include "libwalletqt/Wallet.h"
|
#include "libwalletqt/Wallet.h"
|
||||||
|
#include "widgets/SceneWidget.h"
|
||||||
|
|
||||||
WalletUnlockWidget::WalletUnlockWidget(QWidget *parent, Wallet *wallet)
|
WalletUnlockWidget::WalletUnlockWidget(QWidget *parent, Wallet *wallet)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
@@ -18,6 +19,13 @@ WalletUnlockWidget::WalletUnlockWidget(QWidget *parent, Wallet *wallet)
|
|||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
this->reset();
|
this->reset();
|
||||||
|
|
||||||
|
// wowlet: ambient scene banner above the unlock form (freezes itself into a
|
||||||
|
// still when "Prefer reduced motion" is set).
|
||||||
|
auto *scene = new SceneWidget(this);
|
||||||
|
scene->setMinimumHeight(120);
|
||||||
|
scene->setMaximumHeight(140);
|
||||||
|
ui->verticalLayout->insertWidget(0, scene);
|
||||||
|
|
||||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setAutoDefault(true);
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setAutoDefault(true);
|
||||||
|
|
||||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &WalletUnlockWidget::tryUnlock);
|
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &WalletUnlockWidget::tryUnlock);
|
||||||
|
|||||||
Reference in New Issue
Block a user