Template stripped to the overlay platform (examples, demo UI and Frame test package removed), renamed to FrameAssistant, and working rules for the project recorded in CLAUDE.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
84 lines
3.0 KiB
C++
84 lines
3.0 KiB
C++
#pragma once
|
|
|
|
#include <QImage>
|
|
#include <QObject>
|
|
#include <QSize>
|
|
#include <QString>
|
|
#include <functional>
|
|
#include <memory>
|
|
|
|
class OffscreenQuickRenderer;
|
|
class Overlay;
|
|
class QQmlEngine;
|
|
class QQuickWindow;
|
|
class RenderBackend;
|
|
class Surface;
|
|
class VrRuntime;
|
|
|
|
// Configuration of one view of the app (see DashboardApplication::addSurface).
|
|
// Members not given (designated initializers) keep their defaults.
|
|
struct SurfaceConfig {
|
|
// Unique within the app; the overlay key is "<app key>.<id>", or the app key
|
|
// itself for an empty id (allowed for one surface).
|
|
QString id = {};
|
|
// Root type in the app's QML module (required).
|
|
QString qmlRootType = {};
|
|
// Tab name; default: the app's display name.
|
|
QString displayName = {};
|
|
// Texture size in pixels; default: AppConfig (VRDASH_TEXTURE_*).
|
|
QSize textureSize = {};
|
|
// Dashboard tab icon; default: the display name's initials.
|
|
std::function<QImage(const Surface&)> thumbnail = {};
|
|
};
|
|
|
|
// One view of the app: its QML scene, rendered offscreen by its own renderer
|
|
// and render backend, shown in SteamVR by its overlay (a dashboard tab).
|
|
// A component: configure it (SurfaceConfig) and connect to its signals; it is
|
|
// created and driven by DashboardApplication.
|
|
//
|
|
// Lifetime rule (enforced by DashboardApplication): the overlay goes before
|
|
// SteamVR shuts down, SteamVR shuts down before the render backend goes.
|
|
class Surface : public QObject {
|
|
Q_OBJECT
|
|
public:
|
|
Surface(SurfaceConfig config, QString overlayKey, QString displayName,
|
|
QSize textureSize, QObject* parent = nullptr);
|
|
~Surface() override;
|
|
|
|
const SurfaceConfig& config() const { return m_config; }
|
|
QString id() const { return m_config.id; }
|
|
QString overlayKey() const { return m_overlayKey; }
|
|
QString displayName() const { return m_displayName; }
|
|
QSize textureSize() const { return m_textureSize; }
|
|
|
|
RenderBackend* backend() const { return m_backend.get(); }
|
|
OffscreenQuickRenderer* renderer() const { return m_renderer.get(); }
|
|
QQuickWindow* window() const;
|
|
Overlay* overlay() const { return m_overlay.get(); } // overlay mode only
|
|
bool isVisible() const;
|
|
|
|
// --- Driven by DashboardApplication ---
|
|
// Takes the initialized backend and creates the renderer (no QML yet).
|
|
void setBackend(std::unique_ptr<RenderBackend> backend, int maxFps);
|
|
bool loadQml(QQmlEngine& engine, const QString& qmlModule, QString* error);
|
|
bool createDashboardOverlay(VrRuntime& runtime, const QImage& thumbnail,
|
|
QString* error);
|
|
void destroyOverlay();
|
|
|
|
signals:
|
|
void visibilityChanged(bool visible);
|
|
// Became the surface the user interacts with: the laser entered it, or
|
|
// its dashboard tab was opened.
|
|
void activated();
|
|
|
|
private:
|
|
SurfaceConfig m_config;
|
|
QString m_overlayKey;
|
|
QString m_displayName;
|
|
QSize m_textureSize;
|
|
// Destruction order: overlay, renderer, backend.
|
|
std::unique_ptr<RenderBackend> m_backend;
|
|
std::unique_ptr<OffscreenQuickRenderer> m_renderer;
|
|
std::unique_ptr<Overlay> m_overlay;
|
|
};
|