Fluent-Qt

Spatial

SpatialItem

Position, rotate and scale a widget inside SpatialView.

Example

SpatialItem: Card finish and pose

Usage

Card finish and pose

Adjust one card while the controls keep their own position.

#include <FluentQt/Spatial.h>
using namespace fluent::spatial;

using namespace fluent;
// Keep the control card independent of the card it adjusts.
class WorkbenchView final : public spatial::SpatialView {
public:
    using SpatialView::SpatialView;
    void arrange()
    {
        if (itemCount() != 2)
            return;
        const bool stacked = width() < 720;
        setFixedHeight(!isSpatialEnabled() ? 520 : (stacked ? 560 : 360));
        auto* preview = items().first();
        preview->setPosition(QVector3D(stacked ? 0 : -164, stacked ? -140 : 0,
                                      preview->position().z()));
        items().last()->setPosition(QVector3D(stacked ? 0 : 164, stacked ? 110 : 0, -50));
    }
protected:
    void resizeEvent(QResizeEvent* event) override
    {
        SpatialView::resizeEvent(event);
        // Update the responsive height after the current layout pass.
        QTimer::singleShot(0, this, [this] { arrange(); });
    }
};
auto* panel = new SpatialPreviewPanel(parent);
auto* column = new QVBoxLayout(panel);
column->setContentsMargins(0, 0, 0, 0);
column->setSpacing(12);
auto* session = new spatial::SpatialSession(panel, panel);
const bool active = session->activate();
auto* view = new WorkbenchView(panel);
if (!active || !session->attachView(view)) {
    view->setSpatialEnabled(false);
    view->setRenderMode(spatial::SpatialView::RenderMode::Raster);
}
view->setObjectName("spatialPreviewView");
view->setCameraDistance(1400);
view->setZoom(0.92);
view->setMaximumTilt(QPointF(4, 6));
column->addWidget(view);
auto* card = new layout::Card;
card->setObjectName("spatialDemoCard");
card->setFixedSize(280, 180);
auto* content = new QVBoxLayout(card);
content->setContentsMargins(20, 16, 20, 16);
content->setSpacing(8);
auto* title = new textfields::Label("Activity", card);
title->setFluentTypography(Typography::FontRole::Subtitle);
title->setTextColorRole(textfields::Label::TextColorRole::Primary);
content->addWidget(title);
auto* chart = new charts::Sparkline(card);
chart->setAccessibleName("Activity trend, demo data");
auto* model = new charts::ChartModel(card);
model->setPoints({{0, 12}, {1, 24}, {2, 18}, {3, 38}, {4, 32}, {5, 54}});
chart->setModel(model);
content->addWidget(chart, 1);
auto* caption = new textfields::Label("Last 6 days · demo data", card);
caption->setTextColorRole(textfields::Label::TextColorRole::Secondary);
content->addWidget(caption);
spatial::SpatialItem* item = view->addWidget(card, WidgetOwnership::Owned);
item->setSurfaceIntensity(0.75);
item->setHoverLift(5);
item->setRotation(QVector3D(0, -18, 0));
// Scale, pivot and visibility retain their defaults; see SpatialItem.h.
auto* settings = new layout::Card;
settings->setObjectName("spatialParameterCard");
settings->setFixedSize(280, 260);
auto* controls = new QVBoxLayout(settings);
controls->setContentsMargins(20, 16, 20, 16);
controls->setSpacing(8);
auto* heading = new textfields::Label("Card", settings);
heading->setFluentTypography(Typography::FontRole::Subtitle);
heading->setTextColorRole(textfields::Label::TextColorRole::Primary);
controls->addWidget(heading);
const auto addSlider = [settings, controls](const QString& name, const QString& label,
                                           const QString& unit, int minimum, int maximum,
                                           int initial) {
    auto* group = new QVBoxLayout;
    group->setSpacing(4);
    auto* text = new textfields::Label(settings);
    text->setTextColorRole(textfields::Label::TextColorRole::Primary);
    auto* slider = new basicinput::Slider(settings);
    slider->setObjectName(name);
    slider->setAccessibleName(label);
    slider->setRange(minimum, maximum);
    slider->setValue(initial);
    const auto updateText = [text, label, unit](int value) {
        text->setText(QString("%1: %2%3").arg(label).arg(value).arg(unit));
    };
    updateText(initial);
    QObject::connect(slider, &basicinput::Slider::valueChanged, text, updateText);
    group->addWidget(text);
    group->addWidget(slider);
    controls->addLayout(group);
    return slider;
};
auto* finish = addSlider("spatialItemSurfaceIntensity", "Surface", "%", 0, 100, 75);
auto* angle = addSlider("spatialItemRotation", "Rotation", "°", -35, 35, -18);
auto* depth = addSlider("spatialItemDepth", "Depth", " px", -120, 120, 0);
QObject::connect(finish, &basicinput::Slider::valueChanged, item,
                 [item](int value) { item->setSurfaceIntensity(value / 100.0); });
QObject::connect(angle, &basicinput::Slider::valueChanged, item,
                 [item](int value) { item->setRotation(QVector3D(0, value, 0)); });
QObject::connect(depth, &basicinput::Slider::valueChanged, item, [item](int value) {
    auto position = item->position();
    position.setZ(value);
    item->setPosition(position);
});
auto* controlItem = view->addWidget(settings, WidgetOwnership::Owned);
controlItem->setSurfaceIntensity(0.75);
controlItem->setRotation(QVector3D(0, -6, 0));
// No hover lift for the parameter card: keep its drag targets steady.
QObject::connect(view, &spatial::SpatialView::spatialEnabledChanged,
                 view, [view] { view->arrange(); });
view->arrange();

fluent::spatial::SpatialItem

Inherits QObject

One live widget surface positioned in a SpatialView.

Properties

QVector3D position

Pivot position relative to view center in logical pixels; default (0, 0, 0). X points right, Y down and positive Z toward the camera.

Read position()Write setPosition()Notify positionChanged()
QVector3D rotation

Rotation about the pivot in X/Y/Z degrees, applied in order; default (0, 0, 0).

Read rotation()Write setRotation()Notify rotationChanged()
qreal scale

Uniform size multiplier for this surface [0.05, 8]; default 1.

Read scale()Write setScale()Notify scaleChanged()
QPointF pivot

Normalized anchor and rotation origin, each axis [0, 1]; default center (0.5, 0.5).

Read pivot()Write setPivot()Notify pivotChanged()
bool visible

Visibility in both spatial and native layouts; default true. Use this property instead of hiding the hosted root widget directly.

Read isVisible()Write setVisible()Notify visibleChanged()
qreal surfaceIntensity

Strength of the rounded surface shadow and rim, clamped to [0, 1]; default 0. Intended for an intact rectangular Card; decoration does not change content or hit areas. Only drawn in spatial mode.

Read surfaceIntensity()Write setSurfaceIntensity()Notify surfaceIntensityChanged()
qreal hoverLift

Temporary upward pointer-hover offset in logical pixels [0, 16]; default 0. Motion freezes during pointer input. Native mode removes it.

Read hoverLift()Write setHoverLift()Notify hoverLiftChanged()

Methods

QVector3D position() const

Pivot position relative to view center in logical pixels; default (0, 0, 0). X points right, Y down and positive Z toward the camera.

void setPosition(const QVector3D& position)

Pivot position relative to view center in logical pixels; default (0, 0, 0). X points right, Y down and positive Z toward the camera.

QVector3D rotation() const

Rotation about the pivot in X/Y/Z degrees, applied in order; default (0, 0, 0).

void setRotation(const QVector3D& rotation)

Rotation about the pivot in X/Y/Z degrees, applied in order; default (0, 0, 0).

qreal scale() const

Uniform size multiplier for this surface [0.05, 8]; default 1.

void setScale(qreal scale)

Uniform size multiplier for this surface [0.05, 8]; default 1.

QPointF pivot() const

Normalized anchor and rotation origin, each axis [0, 1]; default center (0.5, 0.5).

void setPivot(const QPointF& pivot)

Normalized anchor and rotation origin, each axis [0, 1]; default center (0.5, 0.5).

bool isVisible() const

Visibility in both spatial and native layouts; default true. Use this property instead of hiding the hosted root widget directly.

void setVisible(bool visible)

Visibility in both spatial and native layouts; default true. Use this property instead of hiding the hosted root widget directly.

qreal surfaceIntensity() const

Strength of the rounded surface shadow and rim, clamped to [0, 1]; default 0. Intended for an intact rectangular Card; decoration does not change content or hit areas. Only drawn in spatial mode.

void setSurfaceIntensity(qreal intensity)

Strength of the rounded surface shadow and rim, clamped to [0, 1]; default 0. Intended for an intact rectangular Card; decoration does not change content or hit areas. Only drawn in spatial mode.

qreal hoverLift() const

Temporary upward pointer-hover offset in logical pixels [0, 16]; default 0. Motion freezes during pointer input. Native mode removes it.

void setHoverLift(qreal pixels)

Temporary upward pointer-hover offset in logical pixels [0, 16]; default 0. Motion freezes during pointer input. Native mode removes it.

QPolygonF projectedPolygon() const

Current projected corners in SpatialView coordinates; empty when not projectable.

Signals

void positionChanged(const QVector3D& position)

Pivot position relative to view center in logical pixels; default (0, 0, 0). X points right, Y down and positive Z toward the camera.

void rotationChanged(const QVector3D& rotation)

Rotation about the pivot in X/Y/Z degrees, applied in order; default (0, 0, 0).

void scaleChanged(qreal scale)

Uniform size multiplier for this surface [0.05, 8]; default 1.

void pivotChanged(const QPointF& pivot)

Normalized anchor and rotation origin, each axis [0, 1]; default center (0.5, 0.5).

void visibleChanged(bool visible)

Visibility in both spatial and native layouts; default true. Use this property instead of hiding the hosted root widget directly.

void surfaceIntensityChanged(qreal intensity)

Strength of the rounded surface shadow and rim, clamped to [0, 1]; default 0. Intended for an intact rectangular Card; decoration does not change content or hit areas. Only drawn in spatial mode.

void hoverLiftChanged(qreal pixels)

Temporary upward pointer-hover offset in logical pixels [0, 16]; default 0. Motion freezes during pointer input. Native mode removes it.

Destructors

All inherited Qt members:QObject