Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions examples/QRhiVideoDemo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
cmake_minimum_required(VERSION 3.27)
project(QRhiVideoDemo C CXX)

set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 6.9 COMPONENTS Gui GuiPrivate Quick ShaderTools REQUIRED)

qt_standard_project_setup(REQUIRES 6.9)

add_executable(${PROJECT_NAME}
clayimplementation.c
clayqquickitem.cpp
clay_renderer_qrhi_impl.cpp
main.cpp
videodemoitem.cpp
)

target_include_directories(${PROJECT_NAME} PUBLIC
.
../..
../../renderers/QRhi
)

target_link_libraries(${PROJECT_NAME} PRIVATE
Qt6::Gui
Qt6::GuiPrivate
Qt6::Quick
)

qt_add_qml_module(${PROJECT_NAME}
URI com.${PROJECT_NAME}
VERSION 1.0
QML_FILES
main.qml
NO_GENERATE_EXTRA_QMLDIRS
)

qt6_add_shaders(${PROJECT_NAME} "shaders"
# gl_VertexId is in earliest OpenGL ES 3.00, and GLSL 130
GLSL "300 es,130"
PREFIX
"/qt/qml/com/clay"
FILES
"../../renderers/QRhi/clayquad.vert"
"../../renderers/QRhi/clayquad.frag"
)
2 changes: 2 additions & 0 deletions examples/QRhiVideoDemo/clay_renderer_qrhi_impl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#define CLAY_RENDERER_QRHI_IMPLEMENTATION
#include "clay_renderer_qrhi.h"
2 changes: 2 additions & 0 deletions examples/QRhiVideoDemo/clayimplementation.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#define CLAY_IMPLEMENTATION
#include <clay.h>
51 changes: 51 additions & 0 deletions examples/QRhiVideoDemo/clayqquickitem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "clayqquickitem.h"

static inline void clayErrorHandler(Clay_ErrorData errorData) {
qCritical() << "Clay error:" << QString::fromUtf8(errorData.errorText.chars, errorData.errorText.length);
}

ClayQQuickItem::ClayQQuickItem(QQuickItem *parent) : QQuickItem(parent), m_textures(), m_clayImageConfigs() {
setFlag(ItemHasContents, true);

size_t clayRequiredMemory = Clay_MinMemorySize();
m_clayMemory = (Clay_Arena){
.capacity = clayRequiredMemory,
.memory = (char *)malloc(clayRequiredMemory),
};
m_clayCtx = Clay_Initialize(
m_clayMemory,
Clay_Dimensions{},
Clay_ErrorHandler{
.errorHandlerFunction = clayErrorHandler,
});
}

QSGNode *ClayQQuickItem::updatePaintNode(QSGNode *old, UpdatePaintNodeData *) {
ClayFastQSGRenderNode *node = static_cast<ClayFastQSGRenderNode *>(old);
bool nodeCreated = false;

if (!node) {
node = new ClayFastQSGRenderNode(window());
nodeCreated = true;
}

// Note that MeasureText has to be set after the Context is set!
Clay_SetCurrentContext(m_clayCtx);
Clay_SetMeasureTextFunction(clayRendererQRhiMeasureText, &m_fonts);

Clay_SetLayoutDimensions((Clay_Dimensions){(float)width(), (float)height()});

bool texturesStale;

node->setCmds(doLayout(m_textures, &texturesStale), *m_fonts);

if (nodeCreated || texturesStale) {
node->setTextures(m_textures);
}

return node;
}

void ClayQQuickItem::setFontsPtr(QList<QFont> *fonts) {
m_fonts = fonts;
}
40 changes: 40 additions & 0 deletions examples/QRhiVideoDemo/clayqquickitem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#ifdef __cplusplus
#include <QQuickItem>
#endif

#include "clay_renderer_qrhi.h"

typedef struct ImageConfig ImageConfig;

typedef struct ImageConfigs {
size_t capacity;
size_t count;
ImageConfig *cfgs;
} ImageConfigs;

#ifdef __cplusplus
class ClayQQuickItem : public QQuickItem {
Q_OBJECT

public:
explicit ClayQQuickItem(QQuickItem *parent = nullptr);

protected:
QSGNode *updatePaintNode(QSGNode *old, UpdatePaintNodeData *) override;

void setFontsPtr(QList<QFont> *fonts);

virtual Clay_RenderCommandArray
doLayout(QRhiTexture *textures[CLAY_RENDERER_QRHI_TEX_COUNT], bool *texturesStale) = 0;

QRhiTexture *m_textures[CLAY_RENDERER_QRHI_TEX_COUNT];

ImageConfigs m_clayImageConfigs;

Clay_Arena m_clayMemory;
Clay_Context *m_clayCtx;
QList<QFont> *m_fonts;
};
#endif
11 changes: 11 additions & 0 deletions examples/QRhiVideoDemo/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char **argv) {
QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/qt/qml/com/QRhiVideoDemo/main.qml")));

return app.exec();
}
13 changes: 13 additions & 0 deletions examples/QRhiVideoDemo/main.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import QtQuick.Window

import com.QRhiVideoDemo

Window {
visible: true
width: 640
height: 480

VideoDemoItem {
anchors.fill: parent
}
}
17 changes: 17 additions & 0 deletions examples/QRhiVideoDemo/videodemoitem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "videodemoitem.h"

#include <memory.h>

extern "C" {
#include "../shared-layouts/clay-video-demo.c"
}

VideoDemoItem::VideoDemoItem(QQuickItem *parent) : ClayQQuickItem(parent), m_data(malloc(sizeof(ClayVideoDemo_Data)), free) {
*(ClayVideoDemo_Data*)m_data.get() = ClayVideoDemo_Initialize();
setFontsPtr(&m_fonts);
}

Clay_RenderCommandArray VideoDemoItem::doLayout(QRhiTexture *textures[CLAY_RENDERER_QRHI_TEX_COUNT], bool *texturesStale) {
*texturesStale = false;
return ClayVideoDemo_CreateLayout((ClayVideoDemo_Data*)m_data.get());
}
20 changes: 20 additions & 0 deletions examples/QRhiVideoDemo/videodemoitem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include <memory>

#include "clayqquickitem.h"

class VideoDemoItem : public ClayQQuickItem {
Q_OBJECT
QML_ELEMENT

public:
explicit VideoDemoItem(QQuickItem *parent = nullptr);

protected:
Clay_RenderCommandArray doLayout(QRhiTexture *textures[CLAY_RENDERER_QRHI_TEX_COUNT], bool *texturesStale) override;

std::unique_ptr<void, void (*)(void*)> m_data;

QList<QFont> m_fonts = QList<QFont>{QFont()};
};
67 changes: 34 additions & 33 deletions examples/shared-layouts/clay-video-demo.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ void RenderHeaderButton(Clay_String text) {
.cornerRadius = CLAY_CORNER_RADIUS(5)
}) {
CLAY_TEXT(text, CLAY_TEXT_CONFIG({
.textColor = { 255, 255, 255, 255 },
.fontId = FONT_ID_BODY_16,
.fontSize = 16,
.textColor = { 255, 255, 255, 255 }
}));
}
}

void RenderDropdownMenuItem(Clay_String text) {
CLAY_AUTO_ID({.layout = { .padding = CLAY_PADDING_ALL(16)}}) {
CLAY_TEXT(text, CLAY_TEXT_CONFIG({
.textColor = { 255, 255, 255, 255 },
.fontId = FONT_ID_BODY_16,
.fontSize = 16,
.textColor = { 255, 255, 255, 255 }
}));
}
}
Expand All @@ -41,8 +41,8 @@ typedef struct {
Document documentsRaw[5];

DocumentArray documents = {
.documents = documentsRaw,
.length = 5,
.documents = documentsRaw
};

typedef struct {
Expand Down Expand Up @@ -103,20 +103,20 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {

// Build UI here
CLAY(CLAY_ID("OuterContainer"), {
.backgroundColor = {43, 41, 51, 255 },
.layout = {
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.sizing = layoutExpand,
.padding = CLAY_PADDING_ALL(16),
.childGap = 16
}
.childGap = 16,
.layoutDirection = CLAY_TOP_TO_BOTTOM,
},
.backgroundColor = {43, 41, 51, 255 },
}) {
// Child elements go inside braces
CLAY(CLAY_ID("HeaderBar"), {
.layout = {
.sizing = {
.width = CLAY_SIZING_GROW(0),
.height = CLAY_SIZING_FIXED(60),
.width = CLAY_SIZING_GROW(0)
},
.padding = { 16, 16, 0, 0 },
.childGap = 16,
Expand All @@ -134,9 +134,9 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
.cornerRadius = CLAY_CORNER_RADIUS(5)
}) {
CLAY_TEXT(CLAY_STRING("File"), CLAY_TEXT_CONFIG({
.textColor = { 255, 255, 255, 255 },
.fontId = FONT_ID_BODY_16,
.fontSize = 16,
.textColor = { 255, 255, 255, 255 }
}));

bool fileMenuVisible =
Expand All @@ -146,22 +146,22 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {

if (fileMenuVisible) { // Below has been changed slightly to fix the small bug where the menu would dismiss when mousing over the top gap
CLAY(CLAY_ID("FileMenu"), {
.layout = {
.padding = {0, 0, 8, 8 }
},
.floating = {
.attachTo = CLAY_ATTACH_TO_PARENT,
.attachPoints = {
.parent = CLAY_ATTACH_POINT_LEFT_BOTTOM
},
.attachTo = CLAY_ATTACH_TO_PARENT,
},
.layout = {
.padding = {0, 0, 8, 8 }
}
}) {
CLAY_AUTO_ID({
.layout = {
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.sizing = {
.width = CLAY_SIZING_FIXED(200)
.width = CLAY_SIZING_FIXED(200)
},
.layoutDirection = CLAY_TOP_TO_BOTTOM,
},
.backgroundColor = {40, 40, 40, 255 },
.cornerRadius = CLAY_CORNER_RADIUS(8)
Expand All @@ -185,16 +185,16 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
.layout = { .sizing = layoutExpand, .childGap = 16 }
}) {
CLAY(CLAY_ID("Sidebar"), {
.backgroundColor = contentBackgroundColor,
.layout = {
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.padding = CLAY_PADDING_ALL(16),
.childGap = 8,
.sizing = {
.width = CLAY_SIZING_FIXED(250),
.width = CLAY_SIZING_PERCENT(.3),
.height = CLAY_SIZING_GROW(0)
}
}
},
.padding = CLAY_PADDING_ALL(16),
.childGap = 8,
.layoutDirection = CLAY_TOP_TO_BOTTOM,
},
.backgroundColor = contentBackgroundColor,
}) {
for (int i = 0; i < documents.length; i++) {
Document document = documents.documents[i];
Expand All @@ -210,9 +210,9 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
.cornerRadius = CLAY_CORNER_RADIUS(8)
}) {
CLAY_TEXT(document.title, CLAY_TEXT_CONFIG({
.textColor = { 255, 255, 255, 255 },
.fontId = FONT_ID_BODY_16,
.fontSize = 20,
.textColor = { 255, 255, 255, 255 }
}));
}
} else {
Expand All @@ -222,35 +222,36 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
CLAY_AUTO_ID({ .layout = sidebarButtonLayout, .backgroundColor = (Clay_Color) { 120, 120, 120, (float)(Clay_Hovered() ? 120 : 0) }, .cornerRadius = CLAY_CORNER_RADIUS(8) }) {
Clay_OnHover(HandleSidebarInteraction, clickData);
CLAY_TEXT(document.title, CLAY_TEXT_CONFIG({
.textColor = { 255, 255, 255, 255 },
.fontId = FONT_ID_BODY_16,
.fontSize = 20,
.textColor = { 255, 255, 255, 255 }
.wrapMode = CLAY_TEXT_WRAP_NONE,
}));
}
}
}
}

CLAY(CLAY_ID("MainContent"), {
.backgroundColor = contentBackgroundColor,
.clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
.layout = {
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.childGap = 16,
.sizing = layoutExpand,
.padding = CLAY_PADDING_ALL(16),
.sizing = layoutExpand
}
.childGap = 16,
.layoutDirection = CLAY_TOP_TO_BOTTOM,
},
.backgroundColor = contentBackgroundColor,
.clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
}) {
Document selectedDocument = documents.documents[data->selectedDocumentIndex];
CLAY_TEXT(selectedDocument.title, CLAY_TEXT_CONFIG({
.textColor = COLOR_WHITE,
.fontId = FONT_ID_BODY_16,
.fontSize = 24,
.textColor = COLOR_WHITE
}));
CLAY_TEXT(selectedDocument.contents, CLAY_TEXT_CONFIG({
.textColor = { 255, 255, 255, 255 },
.fontId = FONT_ID_BODY_16,
.fontSize = 24,
.textColor = COLOR_WHITE
}));
}
}
Expand All @@ -261,4 +262,4 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
Clay_RenderCommandArray_Get(&renderCommands, i)->boundingBox.y += data->yOffset;
}
return renderCommands;
}
}
Loading