Skip to content

Commit

Permalink
feat: Add InitTools class for visualizing overdraw, batches, and clip (
Browse files Browse the repository at this point in the history
…#136)

* feat: Add InitTools class for visualizing overdraw, batches, and clip

- Added InitTools class with functions to visualize overdraw, batches, and clip
- Created init_tools.cpp and init_tools.h files
- Updated CMakeLists.txt to include init_tools.cpp and init_tools.h
- Added canExecute and execute functions to InitTools class
- Added visualizeOverdraw, visualizeBatches, and visualizeClip functions to InitTools class
- Created qml_engine_controller.cpp and qml_engine_controller.h files
- Added canExecute and execute functions to QmlEngineController class
- Added initQmlEngine function to QmlEngineController class
- Updated main.cpp to include init_tools.h and qml_engine_controller.h
- Added InitTools and QmlEngineController instances to main.cpp
- Added QTimer to main.cpp to send qtLoaded signal to extension

* Update Changelog
  • Loading branch information
SavenkovIgor committed Jun 24, 2024
1 parent 0d7d30a commit 542b321
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 34 deletions.
4 changes: 1 addition & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@

* [refactor] Project script cleanup ([#130](https://github.com/SavenkovIgor/QmlSandboxExtension/pull/130))
* [refactor] Split emscripten interaction into two separate classes ([#131](https://github.com/SavenkovIgor/QmlSandboxExtension/pull/131))

### Changed

* Replace eye icon with run icon at file title ([#123](https://github.com/SavenkovIgor/QmlSandboxExtension/pull/123))
* Switch to Qt 6.6.3 ([#120](https://github.com/SavenkovIgor/QmlSandboxExtension/pull/120))
* Tool version update
* Added new QmlEngine modes: Overdraw, Batches and Clip ([#136](https://github.com/SavenkovIgor/QmlSandboxExtension/pull/136))

## v7.0.1

Expand Down
4 changes: 4 additions & 0 deletions QmlSandbox/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ qt_standard_project_setup(REQUIRES 6.6)
qt_add_executable (QmlSandbox
emscripten_api.cpp
emscripten_api.h
init_tools.cpp
init_tools.h
log_catcher.cpp
log_catcher.h
main.cpp
qml_emscripten_api.cpp
qml_emscripten_api.h
qml_engine_controller.cpp
qml_engine_controller.h
sandbox_tools.cpp
sandbox_tools.h)

Expand Down
4 changes: 2 additions & 2 deletions QmlSandbox/emscripten_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ void EmscriptenApi::removeExecutor(CommandExecutor *executor) {
void EmscriptenApi::onReceiveJRpcFromExtension(std::string jRpc) {
auto doc = QJsonDocument::fromJson(QByteArray::fromStdString(jRpc));
auto jRpcObj = doc.object();
QString cmd_name = jRpcObj["command"].toString();
QString cmd_name = jRpcObj["method"].toString();
bool received = false;
for (auto *executor : command_executors) {
if (executor->canExecute(cmd_name)) {
executor->execute(jRpcObj);
received = true;
}
}
assert(received);
if (!received) {
qWarning() << "No executor found for command" << cmd_name;
}
assert(received);
}
27 changes: 27 additions & 0 deletions QmlSandbox/init_tools.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "init_tools.h"

#include <QJsonDocument>

void InitTools::visualizeOverdraw() { qputenv("QSG_VISUALIZE", "overdraw"); }

void InitTools::visualizeBatches() { qputenv("QSG_VISUALIZE", "batches"); }

void InitTools::visualizeClip() { qputenv("QSG_VISUALIZE", "clip"); }

bool InitTools::canExecute(QString command_name) {
return command_name == "qt.setVisualizeMode";
}

void InitTools::execute(QJsonObject command) {
const auto method = command["method"].toString();
assert(method == "qt.setVisualizeMode");

const auto mode = command["params"].toString();
if (mode == "overdraw") {
visualizeOverdraw();
} else if (mode == "batches") {
visualizeBatches();
} else if (mode == "clip") {
visualizeClip();
}
}
15 changes: 15 additions & 0 deletions QmlSandbox/init_tools.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include "emscripten_api.h"

class InitTools : public CommandExecutor {

public:
void visualizeOverdraw();
void visualizeBatches();
void visualizeClip();

private:
bool canExecute(QString command_name) final;
void execute(QJsonObject command) final;
};
17 changes: 15 additions & 2 deletions QmlSandbox/main.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QTimer>

#include "init_tools.h"
#include "emscripten_api.h"
#include "qml_engine_controller.h"

int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
auto &api = EmscriptenApi::getInstance();

engine.loadFromModule("QmlSandboxModule", "QmlSandboxMain");
InitTools initTools;
api.addExecutor(&initTools);

auto &engineController = QmlEngineController::getInstance();
api.addExecutor(&engineController);

QTimer::singleShot(0, []() {
auto &api = EmscriptenApi::getInstance();
api.sendJRpcToExtension({{"method", "ext.qtLoaded"}, {"params", ""}});
});

return app.exec();
}
18 changes: 18 additions & 0 deletions QmlSandbox/qml_engine_controller.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "qml_engine_controller.h"

#include <QJsonDocument>

bool QmlEngineController::canExecute(QString command_name) {
return command_name == "qt.initQml";
}

void QmlEngineController::execute(QJsonObject command) {
const auto method = command["method"].toString();
assert(method == "qt.initQml");
initQmlEngine();
}

void QmlEngineController::initQmlEngine() {
qml_engine = std::make_unique<QQmlApplicationEngine>();
qml_engine->loadFromModule("QmlSandboxModule", "QmlSandboxMain");
}
23 changes: 23 additions & 0 deletions QmlSandbox/qml_engine_controller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include <memory>

#include <QQmlApplicationEngine>

#include "emscripten_api.h"

class QmlEngineController : public CommandExecutor {
public:
static QmlEngineController &getInstance() {
static QmlEngineController instance;
return instance;
}

private:
bool canExecute(QString command_name) final;
void execute(QJsonObject command) final;

void initQmlEngine();

std::unique_ptr<QQmlApplicationEngine> qml_engine;
};
42 changes: 39 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,40 @@
"contributes": {
"commands": [
{
"category": "Qml Sandbox",
"command": "QmlSandboxExtension.openQmlSandbox",
"title": "Open Qml Sandbox",
"icon": "$(run)"
"icon": "$(play)"
},
{
"category": "Qml Sandbox",
"command": "QmlSandboxExtension.openQmlSandbox.withOverdraw",
"title": "Open Qml Sandbox in Overdraw mode",
"icon": "$(debug-alt)"
},
{
"category": "Qml Sandbox",
"command": "QmlSandboxExtension.openQmlSandbox.withBatches",
"title": "Open Qml Sandbox in Batches mode",
"icon": "$(debug-alt)"
},
{
"category": "Qml Sandbox",
"command": "QmlSandboxExtension.openQmlSandbox.withClip",
"title": "Open Qml Sandbox in Clip mode",
"icon": "$(debug-alt)"
},
{
"category": "Qml Sandbox",
"command": "QmlSandboxExtension.screenshotQml",
"title": "Screenshot Qml Scene",
"icon": "$(device-camera)"
},
{
"category": "Qml Sandbox",
"command": "QmlSandboxExtension.updateWebView",
"title": "Update Qml WebView",
"icon": "$(sync)"
"icon": "$(refresh)"
}
],
"menus": {
Expand All @@ -50,7 +71,22 @@
"editor/title/run": [
{
"command": "QmlSandboxExtension.openQmlSandbox",
"group": "navigation",
"group": "1_run@0",
"when": "editorLangId == qml"
},
{
"command": "QmlSandboxExtension.openQmlSandbox.withOverdraw",
"group": "1_run@1",
"when": "editorLangId == qml"
},
{
"command": "QmlSandboxExtension.openQmlSandbox.withBatches",
"group": "1_run@2",
"when": "editorLangId == qml"
},
{
"command": "QmlSandboxExtension.openQmlSandbox.withClip",
"group": "1_run@3",
"when": "editorLangId == qml"
}
]
Expand Down
29 changes: 28 additions & 1 deletion src/QmlWebView.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import * as vscode from 'vscode';
import { JRpcController } from './JRpcController';

export enum ViewMode {
none = 'none',
overdraw = 'overdraw',
batches = 'batches',
clip = 'clip',
}

export class QmlWebView {
private defaultTitle = 'Qml Sandbox';
private jRpcController = new JRpcController();
private qmlEngineDir: vscode.Uri;
private disposeHandler: Function = () => { };
private view: vscode.WebviewPanel;
private viewMode: ViewMode = ViewMode.none;
// https://code.visualstudio.com/api/references/theme-color
private vscodeColorKeys: string[] = [
'editor.background',
Expand All @@ -19,7 +27,7 @@ export class QmlWebView {
'button.hoverBackground',
];

constructor(qmlEngineDir: vscode.Uri, subscriptions: vscode.Disposable[]) {
constructor(qmlEngineDir: vscode.Uri, subscriptions: vscode.Disposable[], mode: ViewMode = ViewMode.none) {
this.qmlEngineDir = qmlEngineDir;
this.view = vscode.window.createWebviewPanel(
'qmlSandbox',
Expand All @@ -30,6 +38,7 @@ export class QmlWebView {
localResourceRoots: [qmlEngineDir]
}
);
this.viewMode = mode;

this.view.webview.onDidReceiveMessage(jRpc => {
this.jRpcController.receiveJRcpFromQml(jRpc);
Expand All @@ -40,6 +49,7 @@ export class QmlWebView {
vscode.commands.executeCommand('setContext', 'QmlSandbox.isActive', isActive);
});

this.jRpcController.setHandler('ext.qtLoaded', this.onQtLoaded.bind(this));
this.jRpcController.setHandler('ext.qmlLoaded', this.onQmlLoaded.bind(this));
this.jRpcController.setHandler('ext.webViewThemeInfo', this.sendColorThemeToQml.bind(this));

Expand Down Expand Up @@ -82,6 +92,10 @@ export class QmlWebView {
});
}

public currentViewMode(): ViewMode {
return this.viewMode;
}

public reveal() {
this.view.reveal();
}
Expand All @@ -90,12 +104,25 @@ export class QmlWebView {
this.sendJRpc('qml.makeScreenshot', []);
}

public sendVisualizeMode() {
this.sendJRpc('qt.setVisualizeMode', this.viewMode);
}

public setQml(filename: string, qmlSource: string) {
// Set title of current file
this.view.title = `${this.defaultTitle} - ${filename}`;
this.sendJRpc('qml.update', { file: filename, source: qmlSource });
}

public dispose() {
this.view.dispose();
}

private onQtLoaded() {
this.sendVisualizeMode();
this.sendJRpc('qt.initQml', {});
}

private onQmlLoaded() {
this.requestWebViewTheme();
}
Expand Down
Loading

0 comments on commit 542b321

Please sign in to comment.