Thanks to visit codestin.com
Credit goes to github.com

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
4 changes: 3 additions & 1 deletion lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ set(SOURCES
src/Scene/Mock/MockScene.h
src/Scene/Mock/MockItem.cpp
src/Scene/Mock/MockItem.h
src/Scene/Qt/QtEventFilter.cpp
src/Scene/Qt/QtEventFilter.h
src/Scene/Qt/QtEvents.cpp
src/Scene/Qt/QtEvents.h
src/Scene/Qt/QtItem.cpp
Expand All @@ -114,7 +116,7 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX source FILES ${SOURCES})
#
# Qt MOC Files
#
cmake_language(CALL "qt${SPIX_QT_MAJOR}_wrap_cpp" MOC_FILES "include/Spix/QtQmlBot.h")
cmake_language(CALL "qt${SPIX_QT_MAJOR}_wrap_cpp" MOC_FILES "include/Spix/QtQmlBot.h" "src/Scene/Qt/QtEventFilter.h")


#
Expand Down
14 changes: 14 additions & 0 deletions lib/src/Data/ItemPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@ ItemPath::ItemPath(const std::string& path)

while (pathss) {
std::string component;
if (pathss.peek() == '\"') {
getline(pathss, component, '\"');
getline(pathss, component, '\"');
component = '\"' + component + '\"';
m_components.push_back(std::move(component));
}

if (pathss.peek() == '(') {
getline(pathss, component, '(');
getline(pathss, component, ')');
component = '(' + component + ')';
m_components.push_back(std::move(component));
}

getline(pathss, component, '/');
if (component.length() > 0) {
m_components.push_back(std::move(component));
Expand Down
43 changes: 43 additions & 0 deletions lib/src/Scene/Qt/QtEventFilter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// Created by sebastian on 28.02.24.
//

#include <QEvent>
#include <QObject>

#include "QtEventFilter.h"
#include <QDebug>
namespace spix {

QtEventFilter::QtEventFilter(QObject* parent)
: QObject(parent)
{
}

bool QtEventFilter::eventFilter(QObject* obj, QEvent* event)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->modifiers() == QFlags<Qt::KeyboardModifier>(Qt::ShiftModifier | Qt::ControlModifier)) {
emit pickerModeEntered(keyEvent);
return false;
}
} else if (event->type() == QEvent::KeyRelease) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == 16777249 || keyEvent->key() == 16777248) {
emit pickerModeExited(keyEvent);
return false;
}
} else if (event->type() == QEvent::MouseButtonPress) {
QMouseEvent* mouseClick = static_cast<QMouseEvent*>(event);
if (mouseClick->modifiers() == QFlags<Qt::KeyboardModifier>(Qt::ShiftModifier | Qt::ControlModifier)) {
emit pickClick(mouseClick);
return true;
}
return false;
}

return QObject::eventFilter(obj, event);
}

} // namespace spix
26 changes: 26 additions & 0 deletions lib/src/Scene/Qt/QtEventFilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Created by sebastian on 28.02.24.
//

#pragma once
#include <QKeyEvent>
#include <QMouseEvent>
#include <QObject>

namespace spix {

class QtEventFilter : public QObject {
Q_OBJECT
public:
QtEventFilter(QObject* parent);

signals:
void pickerModeEntered(QKeyEvent* event);
void pickerModeExited(QKeyEvent* event);
void pickClick(QMouseEvent* event);

protected:
bool eventFilter(QObject* obj, QEvent* event) override;
};

} // namespace spix
102 changes: 97 additions & 5 deletions lib/src/Scene/Qt/QtItemTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <QDateTime>
#include <QQmlContext>
#include <QQuickItem>
#include <QRegularExpression>
#include <optional>
#include <stdexcept>

namespace spix {
Expand Down Expand Up @@ -62,7 +64,39 @@ QString GetObjectName(QObject* object)
return object->objectName();
}

QObject* FindChildItem(QObject* object, const QString& name)
QString PropertValueByObject(QObject* object, QString propertyName)
{
if (object == nullptr) {
return "";
}

auto property = object->property(propertyName.toStdString().c_str());
auto objectVisible = object->property("visible");

if (property.isNull() || objectVisible.isNull()) {
return "";
}

if (property.isValid() && objectVisible.toBool()) {
return property.toString();
}

return "";
}

QString TypeByObject(QObject* object)
{
if (object == nullptr) {
return "";
}

auto typeName = QString(object->metaObject()->className());
typeName.replace(QRegularExpression("QQuick|_QML.*"), "");
return typeName;
}

QObject* FindChildItem(QObject* object, const QString& name, const std::optional<QString>& propertyName = {},
const std::optional<QString>& propertyValue = {}, const std::optional<QString>& type = {})
{
if (object == nullptr) {
return nullptr;
Expand All @@ -75,8 +109,27 @@ QObject* FindChildItem(QObject* object, const QString& name)
if (GetObjectName(child) == name) {
return child;
}
if (auto item = FindChildItem(child, name)) {
return item;
if (propertyName.has_value() && propertyValue.has_value()) {
if (PropertValueByObject(child, propertyName.value()) == propertyValue.value()) {
return child;
}

if (auto item = FindChildItem(child, name, propertyName.value(), propertyValue.value(), {})) {
return item;
}
} else if (type.has_value()) {
if (TypeByObject(child) == type.value()) {
return child;
}

if (auto item = FindChildItem(child, name, {}, {}, type)) {
return item;
}

} else {
if (auto item = FindChildItem(child, name)) {
return item;
}
}
}
} else {
Expand All @@ -85,15 +138,54 @@ QObject* FindChildItem(QObject* object, const QString& name)
if (GetObjectName(child) == name) {
return child;
}
if (auto item = FindChildItem(child, name)) {
return item;

if (propertyValue.has_value() && propertyName.has_value()) {
if (auto item = FindChildItem(child, name, propertyName.value(), propertyValue.value(), {})) {
return item;
}
} else if (type.has_value()) {
if (auto item = FindChildItem(child, name, {}, {}, type)) {
return item;
}
} else {
if (auto item = FindChildItem(child, name)) {
return item;
}
}
}
}

return nullptr;
}

QVector<QObject*> FindChildItems(QObject* object, const std::optional<QString>& type = {})
{
QVector<QObject*> result = {};
if (object == nullptr) {
return {};
}

using Index = QObjectList::size_type;
if (auto qquickitem = qobject_cast<const QQuickItem*>(object)) {
for (Index i = 0; i < qquickitem->childItems().size(); ++i) {
auto child = qquickitem->childItems().at(i);
result = result + FindChildItems(child, type);
if (type.has_value() && TypeByObject(child) == type.value()) {
result.push_back(child);
}
}
} else {
for (Index i = 0; i < object->children().size(); ++i) {
auto child = object->children().at(i);
result = result + FindChildItems(child, type);
if (type.has_value() && TypeByObject(child) == type.value()) {
result.push_back(child);
}
}
}
return result;
}

QGenericReturnArgument GetReturnArgForQMetaType(int type, QMLReturnVariant& retVar)
{
switch (type) {
Expand Down
16 changes: 14 additions & 2 deletions lib/src/Scene/Qt/QtItemTools.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <QObject>
#include <QQuickItem>
#include <QVariant>
#include <optional>

class QString;

Expand All @@ -25,6 +26,8 @@ QQuickItem* RepeaterChildAtIndex(QQuickItem* repeater, int index);
QQuickItem* RepeaterChildWithName(QQuickItem* repeater, const QString& name);

QString GetObjectName(QObject* object);
QString PropertValueByObject(QObject* object, QString propertyName);
QString TypeByObject(QObject* object);

/**
* @brief Find a child object with the given name.
Expand All @@ -33,12 +36,21 @@ QString GetObjectName(QObject* object);
* encounters a `QQuickItem`, it no longer iterates over the object's
* `children()`, but rather its `childItems()`.
*/
QObject* FindChildItem(QObject* object, const QString& name);
QObject* FindChildItem(QObject* object, const QString& name, const std::optional<QString>& propertyName,
const std::optional<QString>& propertyValue, const std::optional<QString>& type);
QVector<QObject*> FindChildItems(QObject* object, const std::optional<QString>& type);

template <typename T>
T FindChildItem(QObject* object, const QString& name, const std::optional<QString>& propertyName,
const std::optional<QString>& propertyValue, const std::optional<QString>& type)
{
return qobject_cast<T>(FindChildItem(object, name, propertyName, propertyValue, type));
}

template <typename T>
T FindChildItem(QObject* object, const QString& name)
{
return qobject_cast<T>(FindChildItem(object, name));
return qobject_cast<T>(FindChildItem(object, name, {}, {}, {}));
}

using QMLReturnVariant = std::variant<std::nullptr_t, bool, int, float, double, QString, QDateTime, QVariant>;
Expand Down
Loading
Loading