Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add AppletBridge to connect applets #819

Merged
merged 1 commit into from
Oct 21, 2024
Merged
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
7 changes: 6 additions & 1 deletion example/applet-example-data/exampleapplet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ bool ExampleApplet::load()
{
DCORE_USE_NAMESPACE;
std::unique_ptr<DConfig> config(DConfig::create("org.deepin.dde.shell", "org.deepin.ds.example"));
return config->value("loadAppletExampleData").toBool();
return config->value("loadAppletExampleData", true).toBool();
}

bool ExampleApplet::init()
Expand Down Expand Up @@ -56,6 +56,11 @@ void ExampleApplet::setUserData(bool newUserData)
emit userDataChanged();
}

QString ExampleApplet::call(const QString &id)
{
return id + QString("-done");
}

D_APPLET_CLASS(ExampleApplet)

#include "exampleapplet.moc"
3 changes: 3 additions & 0 deletions example/applet-example-data/exampleapplet.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ class ExampleApplet : public DApplet
bool userData() const;
void setUserData(bool newUserData);

Q_INVOKABLE QString call(const QString &id);

Q_SIGNALS:
void mainTextChanged();
void userDataChanged();
void sendSignal(const QString &id);
private:
QString m_mainText;
bool m_userData;
Expand Down
6 changes: 6 additions & 0 deletions example/containment-example/examplecontainment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "pluginfactory.h"
#include "pluginloader.h"
#include "appletproxy.h"
#include <DConfig>
#include <QJsonDocument>
#include <QJsonArray>
Expand Down Expand Up @@ -67,6 +68,11 @@
return DApplet::load();
}

QObject *ExampleContainment::createProxyMeta()

Check warning on line 71 in example/containment-example/examplecontainment.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'createProxyMeta' is never used.
{
return new ExampleAppletProxy(this);
}

DPluginMetaData ExampleContainment::targetPlugin() const
{
auto children = DPluginLoader::instance()->childrenPlugin(pluginId());
Expand Down
17 changes: 17 additions & 0 deletions example/containment-example/examplecontainment.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@

DS_USE_NAMESPACE

class ExampleAppletProxy : public QObject
{
Q_OBJECT
public:
ExampleAppletProxy(QObject *parent = nullptr)
: QObject(parent)
{

}
Q_INVOKABLE QString call(const QString &id)
{
return id + QString("-done");
}
};

class ExampleContainment : public DContainment
{
Q_OBJECT
Expand All @@ -16,6 +31,8 @@ class ExampleContainment : public DContainment
~ExampleContainment();

virtual bool load() override;
protected:
virtual QObject *createProxyMeta() override;
private:
DPluginMetaData targetPlugin() const;
};
35 changes: 35 additions & 0 deletions example/panel-example/examplepanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "examplepanel.h"

#include "pluginfactory.h"
#include "appletbridge.h"

ExamplePanel::ExamplePanel(QObject *parent)
: DPanel(parent)
Expand All @@ -19,6 +20,35 @@
bool ExamplePanel::init()
{
DPanel::init();

DAppletBridge bridge("org.deepin.ds.example.applet-data");

Check warning on line 24 in example/panel-example/examplepanel.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Local variable 'bridge' shadows outer variable

qDebug() << "It's state of the bridge:" << bridge.isValid();
if (auto applet = bridge.applet()) {
qDebug() << "Get property:" << applet->property("mainText");
QString id("call");
qDebug() << "Invoke argument:" << id;
qDebug() << "Invoke method staus:" << QMetaObject::invokeMethod(applet, "call", Qt::DirectConnection,
Q_RETURN_ARG(QString, id), Q_ARG(const QString&, id));
qDebug() << "Invoked returd value:" << id;

QObject::connect(applet, SIGNAL(sendSignal(const QString &)), SLOT(onReceivedSignal(const QString &)));

QMetaObject::invokeMethod(applet, "sendSignal", Qt::DirectConnection, Q_ARG(const QString&, id));
}

{
DAppletBridge bridge("org.deepin.ds.example.containment");
qDebug() << "Customize MetaObject of the applet:" << bridge.isValid();
if (auto applet = bridge.applet()) {
QString id("call");
qDebug() << "Invoke argument:" << id;
qDebug() << "Invoke method staus:" << QMetaObject::invokeMethod(applet, "call", Qt::DirectConnection,
Q_RETURN_ARG(QString, id), Q_ARG(const QString&, id));
qDebug() << "Invoked returd value:" << id;
}
}

QObject::connect(this, &DApplet::rootObjectChanged, this, [this]() {
Q_ASSERT(rootObject());
Q_ASSERT(window());
Expand All @@ -27,6 +57,11 @@
return true;
}

void ExamplePanel::onReceivedSignal(const QString &id)

Check warning on line 60 in example/panel-example/examplepanel.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'onReceivedSignal' is never used.
{
qDebug() << "Received signal:" << id;
}

D_APPLET_CLASS(ExamplePanel)

#include "examplepanel.moc"
4 changes: 4 additions & 0 deletions example/panel-example/examplepanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@ class ExamplePanel : public DPanel
virtual bool load() override;

virtual bool init() override;

private slots:
void onReceivedSignal(const QString &id);

};
6 changes: 6 additions & 0 deletions frame/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ set(PUBLIC_HEADERS
appletdata.h
containment.h
panel.h
appletproxy.h
appletbridge.h
qmlengine.h
layershell/dlayershellwindow.h
dsutility.h
Expand All @@ -21,6 +23,8 @@ set(PRIVATE_HEADERS
private/containment_p.h
private/panel_p.h
private/appletitem_p.h
private/appletproxy_p.h
private/appletbridge_p.h
private/dsqmlglobal_p.h
layershell/qwaylandlayershellsurface_p.h
layershell/qwaylandlayershellintegration_p.h
Expand Down Expand Up @@ -50,6 +54,8 @@ add_library(dde-shell-frame SHARED
applet.cpp
containment.cpp
panel.cpp
appletproxy.cpp
appletbridge.cpp
appletitem.cpp
containmentitem.cpp
qmlengine.cpp
Expand Down
17 changes: 17 additions & 0 deletions frame/applet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "applet.h"
#include "private/applet_p.h"
#include "private/appletproxy_p.h"

#include <QLoggingCategory>
#include <QUuid>
Expand All @@ -26,6 +27,16 @@ DAppletPrivate::~DAppletPrivate()
}
}

DAppletProxy *DAppletPrivate::appletProxy() const
{
if (!m_proxy) {
auto meta = const_cast<DAppletPrivate *>(this)->q_func()->createProxyMeta();
const_cast<DAppletPrivate *>(this)->m_proxy =
new DAppletMetaProxy(meta, const_cast<DAppletPrivate *>(this)->q_func());
}
return m_proxy;
}

DApplet::DApplet(QObject *parent)
: DApplet(*new DAppletPrivate(this), parent)
{
Expand Down Expand Up @@ -109,4 +120,10 @@ bool DApplet::init()
return true;
}

QObject *DApplet::createProxyMeta()
{
D_DC(DApplet);
return this;
}

DS_END_NAMESPACE
3 changes: 3 additions & 0 deletions frame/applet.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
class DAppletPrivate;
class DPluginLoader;
class DAppletBridge;
class DS_SHARE DApplet : public QObject, public DTK_CORE_NAMESPACE::DObject
{
Q_OBJECT
Expand All @@ -24,8 +25,9 @@
Q_PROPERTY(QString pluginId READ pluginId CONSTANT FINAL)
Q_PROPERTY(DApplet *parent READ parentApplet CONSTANT FINAL)
Q_PROPERTY(QObject *rootObject READ rootObject NOTIFY rootObjectChanged)
D_DECLARE_PRIVATE(DApplet)

Check warning on line 28 in frame/applet.h

View workflow job for this annotation

GitHub Actions / cppcheck

There is an unknown macro here somewhere. Configuration is required. If D_DECLARE_PRIVATE is a macro then please configure it.
friend class DPluginLoader;
friend class DAppletBridge;
public:
explicit DApplet(QObject *parent = nullptr);
virtual ~DApplet() override;
Expand All @@ -48,6 +50,7 @@

protected:
explicit DApplet(DAppletPrivate &dd, QObject *parent = nullptr);
virtual QObject *createProxyMeta();

private:
void setMetaData(const DPluginMetaData &metaData);
Expand Down
95 changes: 95 additions & 0 deletions frame/appletbridge.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "appletbridge.h"
#include "containment.h"
#include "private/appletbridge_p.h"
#include "private/applet_p.h"

#include "pluginloader.h"
#include <QQueue>

DS_BEGIN_NAMESPACE

DAppletBridgePrivate::DAppletBridgePrivate(DAppletBridge *qq)
: DTK_CORE_NAMESPACE::DObjectPrivate(qq)
{
}

DAppletBridgePrivate::~DAppletBridgePrivate()
{
}

QList<DApplet *> DAppletBridgePrivate::applets() const
{
QList<DApplet *> applets;
auto rootApplet = DPluginLoader::instance()->rootApplet();
auto root = qobject_cast<DContainment *>(rootApplet);

QQueue<DContainment *> containments;
containments.enqueue(root);
while (!containments.isEmpty()) {
DContainment *containment = containments.dequeue();
for (const auto applet : containment->applets()) {
if (auto item = qobject_cast<DContainment *>(applet)) {
containments.enqueue(item);
}
if (applet->pluginId() == m_pluginId)
applets << applet;
}
}
return applets;
}

DAppletBridge::DAppletBridge(const QString &pluginId, QObject *parent)
: DAppletBridge(*new DAppletBridgePrivate(this), parent)
{
d_func()->m_pluginId = pluginId;
}

DAppletBridge::DAppletBridge(DAppletBridgePrivate &dd, QObject *parent)
: QObject(parent)
, DObject(dd)
{
}

DAppletBridge::~DAppletBridge()
{
}

bool DAppletBridge::isValid() const
{
D_DC(DAppletBridge);
const auto plugin = DPluginLoader::instance()->plugin(d->m_pluginId);
return plugin.isValid();
}

QList<DAppletProxy *> DAppletBridge::applets() const
{
D_DC(DAppletBridge);
if (!isValid())
return {};
QList<DAppletProxy *> ret;
for (const auto item : d->applets()) {
if (auto proxy = item->d_func()->appletProxy()) {
ret << proxy;
}
}
return ret;
}

DAppletProxy *DAppletBridge::applet() const
{
D_DC(DAppletBridge);
if (!isValid())
return {};
for (const auto item : d->applets()) {
if (auto proxy = item->d_func()->appletProxy()) {
return proxy;
}
}
return nullptr;
}

DS_END_NAMESPACE
35 changes: 35 additions & 0 deletions frame/appletbridge.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include "dsglobal.h"
#include "appletproxy.h"

#include <QObject>
#include <DObject>

DS_BEGIN_NAMESPACE
/**
* @brief Interacting with other applets
*/
class DAppletBridgePrivate;
class DS_SHARE DAppletBridge : public QObject, public DTK_CORE_NAMESPACE::DObject
{
Q_OBJECT
D_DECLARE_PRIVATE(DAppletBridge)
public:
explicit DAppletBridge(const QString &pluginId, QObject *parent = nullptr);
virtual ~DAppletBridge() override;

bool isValid() const;

QList<DAppletProxy *> applets() const;
DAppletProxy *applet() const;

protected:
explicit DAppletBridge(DAppletBridgePrivate &dd, QObject *parent = nullptr);
};

DS_END_NAMESPACE
Loading
Loading