summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@qt.io>2016-11-29 13:27:22 +0100
committerPaul Olav Tvete <paul.tvete@qt.io>2017-01-02 12:49:47 +0000
commit2240e6c4c1d69189e1369aaf1999a86d13513537 (patch)
treef25a7faf6749290c784e016bb7ae142cbe565658
parent85a78f883929b54213c37a1cfcc00d5d34c66ebb (diff)
Add animations to the C++ example
Show how to use setBufferLocked() from C++. Change-Id: I43be7dcf8f44fd80dd0d4977e38a0d8ff3339432 Reviewed-by: Johan Helsing <johan.helsing@qt.io>
-rw-r--r--examples/wayland/qwindow-compositor/compositor.cpp79
-rw-r--r--examples/wayland/qwindow-compositor/compositor.h31
-rw-r--r--examples/wayland/qwindow-compositor/window.cpp19
3 files changed, 110 insertions, 19 deletions
diff --git a/examples/wayland/qwindow-compositor/compositor.cpp b/examples/wayland/qwindow-compositor/compositor.cpp
index 4878c373e..8d0db5258 100644
--- a/examples/wayland/qwindow-compositor/compositor.cpp
+++ b/examples/wayland/qwindow-compositor/compositor.cpp
@@ -56,13 +56,15 @@
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
#endif
-View::View()
- : m_textureTarget(GL_TEXTURE_2D)
+View::View(Compositor *compositor)
+ : m_compositor(compositor)
+ , m_textureTarget(GL_TEXTURE_2D)
, m_texture(0)
, m_wlShellSurface(nullptr)
, m_xdgSurface(nullptr)
, m_xdgPopup(nullptr)
, m_parentView(nullptr)
+ , m_animationFactor(1.0)
{}
QOpenGLTexture *View::getTexture()
@@ -70,16 +72,33 @@ QOpenGLTexture *View::getTexture()
if (advance()) {
QWaylandBufferRef buf = currentBuffer();
m_texture = buf.toOpenGLTexture();
+ if (surface()) {
+ m_size = surface()->size();
+ m_origin = buf.origin() == QWaylandSurface::OriginTopLeft
+ ? QOpenGLTextureBlitter::OriginTopLeft
+ : QOpenGLTextureBlitter::OriginBottomLeft;
+ }
}
return m_texture;
}
+QOpenGLTextureBlitter::Origin View::textureOrigin() const
+{
+ return m_origin;
+}
+
+QSize View::size() const
+{
+ return surface() ? surface()->size() : m_size;
+}
+
bool View::isCursor() const
{
- return surface()->isCursorSurface();
+ return surface() && surface()->isCursorSurface();
}
+
void View::onXdgSetMaximized()
{
m_xdgSurface->sendMaximized(output()->geometry().size());
@@ -117,6 +136,44 @@ void View::onOffsetForNextFrame(const QPoint &offset)
setPosition(position() + offset);
}
+
+void View::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() != m_animationTimer.timerId())
+ return;
+
+ m_compositor->triggerRender();
+
+ if (m_animationCountUp) {
+ m_animationFactor += .08;
+ if (m_animationFactor > 1.0) {
+ m_animationFactor = 1.0;
+ m_animationTimer.stop();
+ emit animationDone();
+ }
+ } else {
+ m_animationFactor -= .08;
+ if (m_animationFactor < 0.01) {
+ m_animationFactor = 0.01;
+ m_animationTimer.stop();
+ emit animationDone();
+ }
+ }
+}
+
+void View::startAnimation(bool countUp)
+{
+ m_animationCountUp = countUp;
+ m_animationFactor = countUp ? .1 : 1.0;
+ m_animationTimer.start(20, this);
+}
+
+void View::cancelAnimation()
+{
+ m_animationFactor = 1.0;
+ m_animationTimer.stop();
+}
+
void View::onXdgUnsetFullscreen()
{
onXdgUnsetMaximized();
@@ -159,8 +216,7 @@ void Compositor::onSurfaceCreated(QWaylandSurface *surface)
connect(surface, &QWaylandSurface::redraw, this, &Compositor::triggerRender);
connect(surface, &QWaylandSurface::subsurfacePositionChanged, this, &Compositor::onSubsurfacePositionChanged);
-
- View *view = new View;
+ View *view = new View(this);
view->setSurface(surface);
view->setOutput(outputFor(m_window));
m_views << view;
@@ -189,10 +245,20 @@ void Compositor::surfaceDestroyed()
void Compositor::viewSurfaceDestroyed()
{
View *view = qobject_cast<View*>(sender());
+ view->setBufferLocked(true);
+ view->startAnimation(false);
+ connect(view, &View::animationDone, this, &Compositor::viewAnimationDone);
+}
+
+
+void Compositor::viewAnimationDone()
+{
+ View *view = qobject_cast<View*>(sender());
m_views.removeAll(view);
delete view;
}
+
View * Compositor::findView(const QWaylandSurface *s) const
{
Q_FOREACH (View* view, m_views) {
@@ -212,6 +278,7 @@ void Compositor::onWlShellSurfaceCreated(QWaylandWlShellSurface *wlShellSurface)
View *view = findView(wlShellSurface->surface());
Q_ASSERT(view);
view->m_wlShellSurface = wlShellSurface;
+ view->startAnimation(true);
}
void Compositor::onXdgSurfaceCreated(QWaylandXdgSurfaceV5 *xdgSurface)
@@ -227,6 +294,7 @@ void Compositor::onXdgSurfaceCreated(QWaylandXdgSurfaceV5 *xdgSurface)
connect(xdgSurface, &QWaylandXdgSurfaceV5::setFullscreen, view, &View::onXdgSetFullscreen);
connect(xdgSurface, &QWaylandXdgSurfaceV5::unsetMaximized, view, &View::onXdgUnsetMaximized);
connect(xdgSurface, &QWaylandXdgSurfaceV5::unsetFullscreen, view, &View::onXdgUnsetFullscreen);
+ view->startAnimation(true);
}
void Compositor::onXdgPopupRequested(QWaylandSurface *surface, QWaylandSurface *parent,
@@ -291,6 +359,7 @@ void Compositor::onSetPopup(QWaylandSeat *seat, QWaylandSurface *parent, const Q
View *parentView = findView(parent);
if (parentView)
view->setPosition(parentView->position() + relativeToParent);
+ view->cancelAnimation();
}
}
diff --git a/examples/wayland/qwindow-compositor/compositor.h b/examples/wayland/qwindow-compositor/compositor.h
index bf52c8c7e..83a76b80a 100644
--- a/examples/wayland/qwindow-compositor/compositor.h
+++ b/examples/wayland/qwindow-compositor/compositor.h
@@ -47,6 +47,7 @@
#include <QtWaylandCompositor/QWaylandWlShellSurface>
#include <QtWaylandCompositor/QWaylandXdgSurfaceV5>
#include <QTimer>
+#include <QOpenGLTextureBlitter>
QT_BEGIN_NAMESPACE
@@ -54,33 +55,51 @@ class QWaylandWlShell;
class QWaylandWlShellSurface;
class QWaylandXdgShellV5;
class QOpenGLTexture;
+class Compositor;
class View : public QWaylandView
{
Q_OBJECT
public:
- View();
+ View(Compositor *compositor);
QOpenGLTexture *getTexture();
+ QOpenGLTextureBlitter::Origin textureOrigin() const;
QPointF position() const { return m_position; }
void setPosition(const QPointF &pos) { m_position = pos; }
+ QSize size() const;
bool isCursor() const;
bool hasShell() const { return m_wlShellSurface; }
void setParentView(View *parent) { m_parentView = parent; }
View *parentView() const { return m_parentView; }
QPointF parentPosition() const { return m_parentView ? (m_parentView->position() + m_parentView->parentPosition()) : QPointF(); }
- QSize windowSize() { return m_xdgSurface ? m_xdgSurface->windowGeometry().size() : surface()->size(); }
+ QSize windowSize() { return m_xdgSurface ? m_xdgSurface->windowGeometry().size() : surface() ? surface()->size() : m_size; }
QPoint offset() const { return m_offset; }
+ qreal animationFactor() const {return m_animationFactor; }
+ void setAnimationFactor(qreal f) {m_animationFactor = f; }
+
+signals:
+ void animationDone();
+
+protected:
+ void timerEvent(QTimerEvent *event);
+
private:
friend class Compositor;
+ Compositor *m_compositor;
GLenum m_textureTarget;
QOpenGLTexture *m_texture;
+ QOpenGLTextureBlitter::Origin m_origin;
QPointF m_position;
+ QSize m_size;
QWaylandWlShellSurface *m_wlShellSurface;
QWaylandXdgSurfaceV5 *m_xdgSurface;
QWaylandXdgPopupV5 *m_xdgPopup;
View *m_parentView;
QPoint m_offset;
+ qreal m_animationFactor;
+ QBasicTimer m_animationTimer;
+ bool m_animationCountUp;
public slots:
void onXdgSetMaximized();
@@ -88,6 +107,9 @@ public slots:
void onXdgSetFullscreen(QWaylandOutput *output);
void onXdgUnsetFullscreen();
void onOffsetForNextFrame(const QPoint &offset);
+
+ void startAnimation(bool countUp);
+ void cancelAnimation();
};
class Compositor : public QWaylandCompositor
@@ -119,6 +141,9 @@ signals:
void dragStarted(View *dragIcon);
void frameOffset(const QPoint &offset);
+public slots:
+ void triggerRender();
+
private slots:
void surfaceHasContentChanged();
void surfaceDestroyed();
@@ -129,7 +154,6 @@ private slots:
void startDrag();
- void triggerRender();
void onSurfaceCreated(QWaylandSurface *surface);
void onWlShellSurfaceCreated(QWaylandWlShellSurface *wlShellSurface);
@@ -143,6 +167,7 @@ private slots:
void onSubsurfacePositionChanged(const QPoint &position);
void updateCursor();
+ void viewAnimationDone();
private:
View *findView(const QWaylandSurface *s) const;
QWindow *m_window;
diff --git a/examples/wayland/qwindow-compositor/window.cpp b/examples/wayland/qwindow-compositor/window.cpp
index 59ef1d56a..fcb5fd474 100644
--- a/examples/wayland/qwindow-compositor/window.cpp
+++ b/examples/wayland/qwindow-compositor/window.cpp
@@ -129,18 +129,17 @@ void Window::paintGL()
m_textureBlitter.bind(currentTarget);
}
QWaylandSurface *surface = view->surface();
- if (surface && surface->hasContent()) {
- QSize s = surface->size();
+ if ((surface && surface->hasContent()) || view->isBufferLocked()) {
+ QSize s = view->size();
if (!s.isEmpty()) {
if (m_mouseView == view && m_grabState == ResizeGrab && m_resizeAnchored)
view->setPosition(getAnchoredPosition(m_resizeAnchorPosition, m_resizeEdge, s));
QPointF pos = view->position() + view->parentPosition();
QRectF surfaceGeometry(pos, s);
- QOpenGLTextureBlitter::Origin surfaceOrigin =
- view->currentBuffer().origin() == QWaylandSurface::OriginTopLeft
- ? QOpenGLTextureBlitter::OriginTopLeft
- : QOpenGLTextureBlitter::OriginBottomLeft;
- QMatrix4x4 targetTransform = QOpenGLTextureBlitter::targetTransform(surfaceGeometry, QRect(QPoint(), size()));
+ auto surfaceOrigin = view->textureOrigin();
+ auto sf = view->animationFactor();
+ QRectF targetRect(surfaceGeometry.topLeft() * sf, surfaceGeometry.size() * sf);
+ QMatrix4x4 targetTransform = QOpenGLTextureBlitter::targetTransform(targetRect, QRect(QPoint(), size()));
m_textureBlitter.blit(texture->textureId(), targetTransform, surfaceOrigin);
}
}
@@ -157,10 +156,8 @@ View *Window::viewAt(const QPointF &point)
Q_FOREACH (View *view, m_compositor->views()) {
if (view == m_dragIconView)
continue;
- QPointF topLeft = view->position();
- QWaylandSurface *surface = view->surface();
- QRectF geo(topLeft, surface->size());
- if (geo.contains(point))
+ QRectF geom(view->position(), view->size());
+ if (geom.contains(point))
ret = view;
}
return ret;