fix: 修复任务栏bug,优化代码

1.增加license
2.修复bug
3.UI调整

Log: 优化任务栏代码
Influence: v23任务栏
Task: https://pms.uniontech.com/task-view-112073.html
Change-Id: Ic66428699f6060d8b0baefa3dbc2d3603d320242
This commit is contained in:
donghualin 2022-05-17 20:57:09 +08:00
parent 4e7b27a395
commit 6d209d8ddb
53 changed files with 2077 additions and 1187 deletions

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "quicksettingcontroller.h"
#include "quicksettingitem.h"
@ -26,7 +46,7 @@ void QuickSettingController::itemAdded(PluginsItemInterface * const itemInter, c
m_quickSettingItems << quickItem;
emit pluginInsert(quickItem);
emit pluginInserted(quickItem);
}
void QuickSettingController::itemUpdate(PluginsItemInterface * const itemInter, const QString &)
@ -51,7 +71,7 @@ void QuickSettingController::itemRemoved(PluginsItemInterface * const itemInter,
if (findItemIterator != m_quickSettingItems.end()) {
QuickSettingItem *quickItem = *findItemIterator;
m_quickSettingItems.removeOne(quickItem);
Q_EMIT pluginRemove(quickItem);
Q_EMIT pluginRemoved(quickItem);
quickItem->deleteLater();
}
}

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QUICKSETTINGCONTROLLER_H
#define QUICKSETTINGCONTROLLER_H
@ -14,12 +34,12 @@ public:
const QList<QuickSettingItem *> &settingItems() const { return m_quickSettingItems; }
Q_SIGNALS:
void pluginInsert(QuickSettingItem *);
void pluginRemove(QuickSettingItem *);
void pluginInserted(QuickSettingItem *);
void pluginRemoved(QuickSettingItem *);
protected:
void startLoader();
QuickSettingController(QObject *parent = Q_NULLPTR);
explicit QuickSettingController(QObject *parent = Q_NULLPTR);
~QuickSettingController() override;
protected:

View File

@ -24,6 +24,8 @@
#include "pluginsiteminterface.h"
#include "utils.h"
#include <DFontSizeManager>
#include <QPainter>
#include <QBoxLayout>
#include <QMouseEvent>
@ -328,10 +330,13 @@ StretchPluginsItem::StretchPluginsItem(PluginsItemInterface * const pluginInter,
: PluginsItem (pluginInter, itemKey, plginApi, parent)
, m_nameLabel(new QLabel(this))
{
m_nameLabel->setFont(DFontSizeManager::instance()->t10());
m_nameLabel->setText(pluginInter->pluginDisplayName());
m_nameLabel->setAlignment(Qt::AlignCenter);
QBoxLayout *mainLayout = static_cast<QHBoxLayout *>(layout());
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setDirection(QBoxLayout::Direction::TopToBottom);
mainLayout->addSpacing(10);
mainLayout->addWidget(m_nameLabel);
}

View File

@ -1,4 +1,24 @@
#include "quicksettingitem.h"
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "quicksettingitem.h"
#include "pluginsiteminterface.h"
#include <DGuiApplicationHelper>

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QUICKSETTINGITEM_H
#define QUICKSETTINGITEM_H

View File

@ -43,10 +43,11 @@ BrightnessModel::BrightnessModel(QObject *parent)
QDBusInterface dbusInter(serviceName, servicePath, serviceInterface, QDBusConnection::sessionBus());
if (dbusInter.isValid()) {
// 读取所有的屏幕的信息
QString primaryScreenName = qApp->primaryScreen() ? qApp->primaryScreen()->name() : QString();
QString primaryScreenName = dbusInter.property("Primary").value<QString>();
QList<QDBusObjectPath> paths = dbusInter.property("Monitors").value<QList<QDBusObjectPath>>();
for (QDBusObjectPath path : paths) {
BrightMonitor *monitor = new BrightMonitor(path.path(), this);
monitor->setPrimary(primaryScreenName == monitor->name());
m_monitor << monitor;
connect(monitor, &BrightMonitor::brightnessChanged, this, [ = ] {
Q_EMIT brightnessChanged(monitor);
@ -54,8 +55,7 @@ BrightnessModel::BrightnessModel(QObject *parent)
}
}
QDBusConnection::sessionBus().connect(serviceName, servicePath, propertiesInterface,
"PropertiesChanged", "sa{sv}as", this, SLOT(onPropertyChanged(const QDBusMessage &)));
connect(qApp, &QApplication::primaryScreenChanged, this, &BrightnessModel::primaryScreenChanged);
}
BrightnessModel::~BrightnessModel()
@ -67,6 +67,16 @@ QList<BrightMonitor *> BrightnessModel::monitors()
return m_monitor;
}
BrightMonitor *BrightnessModel::primaryMonitor() const
{
for (BrightMonitor *monitor : m_monitor) {
if (monitor->isPrimary())
return monitor;
}
return nullptr;
}
void BrightnessModel::setBrightness(BrightMonitor *monitor, int brightness)
{
setBrightness(monitor->name(), brightness);
@ -88,19 +98,17 @@ QDBusMessage BrightnessModel::callMethod(const QString &methodName, const QList<
return QDBusMessage();
}
void BrightnessModel::onPropertyChanged(const QDBusMessage &msg)
void BrightnessModel::primaryScreenChanged(QScreen *screen)
{
QList<QVariant> arguments = msg.arguments();
if (3 != arguments.count())
return;
QString interfaceName = msg.arguments().at(0).toString();
if (interfaceName != serviceInterface)
return;
QVariantMap changedProps = qdbus_cast<QVariantMap>(arguments.at(1).value<QDBusArgument>());
if (changedProps.contains("Brightness")) {
BrightMonitor *defaultMonitor = nullptr;
for (BrightMonitor *monitor : m_monitor) {
monitor->setPrimary(monitor->name() == screen->name());
if (monitor->isPrimary())
defaultMonitor = monitor;
}
if (defaultMonitor)
Q_EMIT primaryChanged(defaultMonitor);
}
/**
@ -111,6 +119,7 @@ BrightMonitor::BrightMonitor(QString path, QObject *parent)
, m_path(path)
, m_brightness(100)
, m_enabled(false)
, m_isPrimary(false)
{
QDBusInterface dbusInter(serviceName, path, serviceInterface + QString(".Monitor"), QDBusConnection::sessionBus());
if (dbusInter.isValid()) {
@ -128,6 +137,11 @@ BrightMonitor::~BrightMonitor()
{
}
void BrightMonitor::setPrimary(bool primary)
{
m_isPrimary = primary;
}
int BrightMonitor::brihtness()
{
return m_brightness;
@ -143,6 +157,11 @@ QString BrightMonitor::name()
return m_name;
}
bool BrightMonitor::isPrimary()
{
return m_isPrimary;
}
void BrightMonitor::onPropertyChanged(const QDBusMessage &msg)
{
QList<QVariant> arguments = msg.arguments();

View File

@ -26,27 +26,30 @@
class BrightMonitor;
class QDBusMessage;
class QScreen;
class BrightnessModel : public QObject
{
Q_OBJECT
Q_SIGNALS:
void brightnessChanged(BrightMonitor *);
public:
explicit BrightnessModel(QObject *parent = nullptr);
~BrightnessModel();
QList<BrightMonitor *> monitors();
BrightMonitor *primaryMonitor() const;
void setBrightness(BrightMonitor *monitor, int brightness);
void setBrightness(QString name, int brightness);
Q_SIGNALS:
void brightnessChanged(BrightMonitor *);
void primaryChanged(BrightMonitor *);
protected:
QDBusMessage callMethod(const QString &methodName, const QList<QVariant> &argument);
protected Q_SLOTS:
void onPropertyChanged(const QDBusMessage &msg);
void primaryScreenChanged(QScreen *screen);
private:
QList<BrightMonitor *> m_monitor;
@ -67,12 +70,14 @@ public:
int brihtness();
bool enabled();
QString name();
//bool isDefault();
bool isPrimary();
protected:
explicit BrightMonitor(QString path, QObject *parent);
~BrightMonitor();
void setPrimary(bool primary);
protected Q_SLOTS:
void onPropertyChanged(const QDBusMessage &msg);
@ -81,6 +86,7 @@ private:
QString m_name;
int m_brightness;
bool m_enabled;
bool m_isPrimary;
};
#endif // DISPLAYMODEL_H

View File

@ -24,11 +24,6 @@ public:
Stop
};
Q_SIGNALS:
void startStop(bool);
void statusChanged(const PlayStatus &);
void metadataChanged();
public:
static MediaPlayerModel *instance();
bool isActived();
@ -45,6 +40,11 @@ public:
void setStatus(const PlayStatus &stat);
void playNext();
Q_SIGNALS:
void startStop(bool);
void statusChanged(const PlayStatus &);
void metadataChanged();
protected:
explicit MediaPlayerModel(QObject *parent = nullptr);
~MediaPlayerModel();

View File

@ -1,17 +1,10 @@
#include "volumemodel.h"
#include <QDBusArgument>
#include <QDBusConnection>
#include <QDBusConnectionInterface>
#include <QDBusInterface>
#include <QDBusMessage>
#include <QDBusObjectPath>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QVariantMap>
#include <QDebug>
#include <QDBusMetaType>
/**
* @brief
@ -20,13 +13,14 @@
static const QString serviceName = QString("com.deepin.daemon.Audio");
static const QString servicePath = QString("/com/deepin/daemon/Audio");
static const QString interfaceName = QString("com.deepin.daemon.Audio");
static const QString propertiesInterface = QString("org.freedesktop.DBus.Properties");
VolumeModel::VolumeModel(QObject *parent)
: QObject(parent)
, m_audio(new DBusAudio(serviceName, servicePath, QDBusConnection::sessionBus(), this))
{
initService();
reloadSinks();
reloadPorts();
connect(m_audio, &DBusAudio::DefaultSinkChanged, this, &VolumeModel::onDefaultSinkChanged);
}
VolumeModel::~VolumeModel()
@ -37,7 +31,7 @@ VolumeModel::~VolumeModel()
void VolumeModel::setActivePort(AudioPorts *port)
{
callMethod("SetPort", { port->cardId(), port->name(), port->direction() });
m_audio->SetPort(port->cardId(), port->name(), port->direction());
}
QList<AudioSink *> VolumeModel::sinks() const
@ -110,62 +104,14 @@ bool VolumeModel::existActiveOutputDevice()
return false;
}
void VolumeModel::onPropertyChanged(const QDBusMessage &msg)
{
QList<QVariant> arguments = msg.arguments();
if (3 != arguments.count())
return;
QString interName = msg.arguments().at(0).toString();
if (interName != interfaceName)
return;
QVariantMap changedProps = qdbus_cast<QVariantMap>(arguments.at(1).value<QDBusArgument>());
if (changedProps.contains("DefaultSink")) {
QVariant defaultSink = changedProps.value("DefaultSink");
QString defaultSinkPath = defaultSink.value<QDBusObjectPath>().path();
for (AudioSink *audioSink : m_sinks) {
if (audioSink->m_devicePath == defaultSinkPath) {
updateDefaultSink(audioSink);
Q_EMIT defaultSinkChanged(audioSink);
break;
}
}
}
}
void VolumeModel::initService()
{
QDBusConnection::sessionBus().connect(serviceName, servicePath, propertiesInterface,
"PropertiesChanged", "sa{sv}as", this, SLOT(onPropertyChanged(const QDBusMessage &)));
reloadSinks();
reloadPorts();
QDBusConnectionInterface *dbusInterface = QDBusConnection::sessionBus().interface();
connect(dbusInterface, &QDBusConnectionInterface::serviceOwnerChanged, this,
[ = ](const QString &name, const QString &, const QString &newOwner) {
if (name == serviceName) {
if (newOwner.isEmpty()) {
QDBusConnection::sessionBus().disconnect(serviceName, servicePath, propertiesInterface,
"PropertiesChanged", "sa{sv}as", this, SLOT(onPropertyChanged(const QDBusMessage &)));
clearSinks();
} else {
QDBusConnection::sessionBus().connect(serviceName, servicePath, propertiesInterface,
"PropertiesChanged", "sa{sv}as", this, SLOT(onPropertyChanged(const QDBusMessage &)));
reloadSinks();
reloadPorts();
}
}
});
}
void VolumeModel::reloadSinks()
{
clearSinks();
QList<QDBusObjectPath> sinkPaths = properties<QList<QDBusObjectPath>>("Sinks");
const QString defaultSinkPath = m_audio->defaultSink().path();
QList<QDBusObjectPath> sinkPaths = m_audio->sinks();
for (const QDBusObjectPath &sinkPath : sinkPaths) {
AudioSink *sink = new AudioSink(sinkPath.path(), this);
const QString path = sinkPath.path();
AudioSink *sink = new AudioSink(path, (path == defaultSinkPath), this);
connect(sink, &AudioSink::volumeChanged, this, [ = ](int volume) {
if (sink->isDefault())
Q_EMIT volumeChanged(volume);
@ -182,13 +128,13 @@ void VolumeModel::reloadSinks()
void VolumeModel::reloadPorts()
{
clearPorts();
QString cards = properties<QString>("CardsWithoutUnavailable");
QString cards = m_audio->cardsWithoutUnavailable();
QJsonParseError error;
QJsonDocument json = QJsonDocument::fromJson(cards.toLocal8Bit(), &error);
if (error.error != QJsonParseError::NoError)
return;
int sinkCardId = -1;
uint sinkCardId = 0;
QString sinkCardName;
AudioSink *sink = defaultSink();
if (sink) {
@ -199,7 +145,7 @@ void VolumeModel::reloadPorts()
QJsonArray array = json.array();
for (const QJsonValue value : array) {
QJsonObject cardObject = value.toObject();
int cardId = cardObject.value("Id").toInt();
uint cardId = static_cast<uint>(cardObject.value("Id").toInt());
QString cardName = cardObject.value("Name").toString();
QJsonArray jPorts = cardObject.value("Ports").toArray();
for (const QJsonValue jPortValue : jPorts) {
@ -223,8 +169,19 @@ void VolumeModel::reloadPorts()
}
}
void VolumeModel::updateDefaultSink(AudioSink *audioSink)
void VolumeModel::onDefaultSinkChanged(const QDBusObjectPath &value)
{
AudioSink *audioSink = nullptr;
const QString defaultPath = value.path();
for (AudioSink *sink : m_sinks) {
sink->setDefault(defaultPath == sink->m_devicePath);
if (sink->isDefault())
audioSink = sink;
}
if (!audioSink)
return;
bool checkChanged = false;
for (AudioPorts *port : m_ports) {
bool oldChecked = port->isChecked();
@ -237,6 +194,8 @@ void VolumeModel::updateDefaultSink(AudioSink *audioSink)
if (checkChanged)
Q_EMIT checkPortChanged();
Q_EMIT defaultSinkChanged(audioSink);
}
void VolumeModel::clearSinks()
@ -255,56 +214,35 @@ void VolumeModel::clearPorts()
m_ports.clear();
}
QDBusMessage VolumeModel::callMethod(const QString &methodName, const QList<QVariant> &argument)
{
QDBusInterface dbusInter(serviceName, servicePath, interfaceName, QDBusConnection::sessionBus());
if (dbusInter.isValid()) {
QDBusPendingCall reply = dbusInter.asyncCallWithArgumentList(methodName, argument);
reply.waitForFinished();
return reply.reply();
}
return QDBusMessage();
}
template<typename T>
T VolumeModel::properties(const QString &propName)
{
QDBusInterface dbusInter(serviceName, servicePath, interfaceName, QDBusConnection::sessionBus());
if (dbusInter.isValid()) {
QByteArray ba = propName.toLatin1();
const char *prop = ba.data();
return dbusInter.property(prop).value<T>();
}
return T();
}
/**
* @brief
* @param parent
*/
AudioSink::AudioSink(QString path, QObject *parent)
AudioSink::AudioSink(QString path, bool isDefault, QObject *parent)
: QObject(parent)
, m_devicePath(path)
, m_sink(new DBusSink(serviceName, path, QDBusConnection::sessionBus(), this))
, m_isDefault(isDefault)
{
QDBusConnection::sessionBus().connect(serviceName, path, propertiesInterface,
"PropertiesChanged", "sa{sv}as", this, SLOT(onPropertyChanged(const QDBusMessage&)));
connect(m_sink, &DBusSink::MuteChanged, this, &AudioSink::muteChanged);
connect(m_sink, &DBusSink::VolumeChanged, this, [ this ](double value) {
Q_EMIT this->volumeChanged(static_cast<int>(value * 100));
});
}
AudioSink::~AudioSink()
{
}
void AudioSink::setDefault(bool isDefaultSink)
{
m_isDefault = isDefaultSink;
}
bool AudioSink::isDefault()
{
QDBusInterface dbusInter(serviceName, servicePath, interfaceName, QDBusConnection::sessionBus());
if (dbusInter.isValid()) {
QString defaultSink = dbusInter.property("DefaultSink").value<QDBusObjectPath>().path();
return defaultSink == m_devicePath;
}
return false;
return m_isDefault;
}
bool AudioSink::isHeadPhone()
@ -314,216 +252,83 @@ bool AudioSink::isHeadPhone()
void AudioSink::setBalance(double value, bool isPlay)
{
callMethod("SetBalance", { value, isPlay });
m_sink->SetBalance(value, isPlay);
}
void AudioSink::setFade(double value)
{
callMethod("SetFade", { value });
m_sink->SetFade(value);
}
void AudioSink::setMute(bool mute)
{
callMethod("SetMute", { mute });
m_sink->SetMute(mute);
}
void AudioSink::setPort(QString name)
{
callMethod("SetPort", { name });
m_sink->SetPort(name);
}
void AudioSink::setVolume(double value, bool isPlay)
void AudioSink::setVolume(int value, bool isPlay)
{
callMethod("SetVolume", { value * 0.01, isPlay });
m_sink->SetVolume((value * 0.01), isPlay);
}
bool AudioSink::isMute()
{
return getProperties<bool>("Mute");
return m_sink->mute();
}
bool AudioSink::supportBalance()
{
return getProperties<bool>("SupportBalance");
return m_sink->supportBalance();
}
bool AudioSink::suoportFade()
{
return getProperties<bool>("SupportFade");
return m_sink->supportFade();
}
double AudioSink::balance()
{
return getProperties<double>("Balance");
return m_sink->balance();
}
double AudioSink::baseVolume()
{
return getProperties<double>("BaseVolume");
return m_sink->baseVolume();
}
double AudioSink::fade()
{
return getProperties<double>("Fade");
return m_sink->fade();
}
int AudioSink::volume()
{
return static_cast<int>(getProperties<double>("Volume") * 100);
return static_cast<int>(m_sink->volume() * 100);
}
QString AudioSink::description()
{
QVariantList value = getPropertiesByFreeDesktop("ActivePort");
if (value.size() >= 2)
return value[1].toString();
return getProperties<QString>("Description");
return m_sink->activePort().description;
}
QString AudioSink::name()
{
QVariantList value = getPropertiesByFreeDesktop("ActivePort");
if (value.size() >= 2)
return value[0].toString();
return getProperties<QString>("Name");
return m_sink->activePort().name;
}
int AudioSink::cardId()
uint AudioSink::cardId()
{
return getProperties<int>("Card");
return m_sink->card();
}
void AudioSink::onPropertyChanged(const QDBusMessage &msg)
{
QList<QVariant> arguments = msg.arguments();
if (3 != arguments.count())
return;
QString interfaceName = msg.arguments().at(0).toString();
if (interfaceName != propertiesInterface)
return;
QVariantMap changedProps = qdbus_cast<QVariantMap>(arguments.at(1).value<QDBusArgument>());
if (changedProps.contains("Volume"))
Q_EMIT volumeChanged(static_cast<int>(changedProps.value("Volume").toDouble() * 100));
if (changedProps.contains("Mute"))
Q_EMIT muteChanged(changedProps.value("Mute").toBool());
}
template<typename T>
T AudioSink::getProperties(const QString &propName)
{
QDBusInterface dbusInter(serviceName, m_devicePath, interfaceName + QString(".Sink"), QDBusConnection::sessionBus());
if (dbusInter.isValid()) {
QByteArray ba = propName.toLatin1();
const char *prop = ba.data();
return dbusInter.property(prop).value<T>();
}
return T();
}
QDBusMessage AudioSink::callMethod(const QString &methodName, const QList<QVariant> &argument)
{
QDBusInterface dbusInter(serviceName, m_devicePath, interfaceName + QString(".Sink"), QDBusConnection::sessionBus());
if (dbusInter.isValid()) {
QDBusPendingCall reply = dbusInter.asyncCallWithArgumentList(methodName, argument);
reply.waitForFinished();
return reply.reply();
}
return QDBusMessage();
}
static QVariantList argToString(const QDBusArgument &busArg)
{
QVariantList out;
QString busSig = busArg.currentSignature();
bool doIterate = false;
QDBusArgument::ElementType elementType = busArg.currentType();
switch (elementType) {
case QDBusArgument::BasicType:
case QDBusArgument::VariantType: {
QVariant value = busArg.asVariant();
switch (value.type()) {
case QVariant::Bool:
out << value.toBool();
break;
case QVariant::Int:
out << value.toInt();
break;
case QVariant::String:
out << value.toString();
break;
case QVariant::UInt:
out << value.toUInt();
break;
case QVariant::ULongLong:
out << value.toULongLong();
break;
case QMetaType::UChar:
out << value.toUInt();
break;
default:
out << QVariant();
break;
}
out += busArg.asVariant().toString();
break;
}
case QDBusArgument::StructureType:
busArg.beginStructure();
doIterate = true;
break;
case QDBusArgument::ArrayType:
busArg.beginArray();
doIterate = true;
break;
case QDBusArgument::MapType:
busArg.beginMap();
doIterate = true;
break;
case QDBusArgument::UnknownType:
default:
out << QVariant();
return out;
}
if (doIterate && !busArg.atEnd()) {
while (!busArg.atEnd()) {
out << argToString(busArg);
if (out.isEmpty())
break;
}
}
return out;
}
QVariantList AudioSink::getPropertiesByFreeDesktop(const QString &propName)
{
QDBusInterface dbusInter(serviceName, m_devicePath, "org.freedesktop.DBus.Properties", QDBusConnection::sessionBus());
if (dbusInter.isValid()) {
QDBusPendingCall reply = dbusInter.asyncCallWithArgumentList("Get", { interfaceName + ".Sink", propName });
reply.waitForFinished();
QVariantList lists = reply.reply().arguments();
for (QVariantList::ConstIterator it = lists.begin(); it != lists.end(); ++it) {
QVariant arg = (*it);
const QVariant v = qvariant_cast<QDBusVariant>(arg).variant();
return argToString(v.value<QDBusArgument>());
}
}
return QVariantList();
}
AudioPorts::AudioPorts(int cardId, QString cardName)
AudioPorts::AudioPorts(uint cardId, QString cardName)
: m_cardId(cardId)
, m_cardName(cardName)
, m_direction(0)
, m_isCheck(false)
, m_isHeadPhone(false)
{
@ -533,7 +338,7 @@ AudioPorts::~AudioPorts()
{
}
int AudioPorts::cardId() const
uint AudioPorts::cardId() const
{
return m_cardId;
}

View File

@ -3,6 +3,12 @@
#include <QObject>
#include <com_deepin_daemon_audio.h>
#include <com_deepin_daemon_audio_sink.h>
using DBusAudio = com::deepin::daemon::Audio;
using DBusSink = com::deepin::daemon::audio::Sink;
class QDBusMessage;
class AudioSink;
class AudioPorts;
@ -11,12 +17,6 @@ class VolumeModel : public QObject
{
Q_OBJECT
Q_SIGNALS:
void defaultSinkChanged(AudioSink *);
void volumeChanged(int);
void muteChanged(bool);
void checkPortChanged();
public:
explicit VolumeModel(QObject *parent);
~VolumeModel();
@ -35,25 +35,26 @@ public:
bool isMute();
bool existActiveOutputDevice();
Q_SIGNALS:
void defaultSinkChanged(AudioSink *);
void volumeChanged(int);
void muteChanged(bool);
void checkPortChanged();
private Q_SLOTS:
void onPropertyChanged(const QDBusMessage& msg);
void onDefaultSinkChanged(const QDBusObjectPath & value);
private:
void initService();
void reloadSinks();
void reloadPorts();
void clearSinks();
void clearPorts();
void updateDefaultSink(AudioSink *audioSink);
private:
QDBusMessage callMethod(const QString &methodName, const QList<QVariant> &argument);
template<typename T>
T properties(const QString &propName);
private:
QList<AudioSink *> m_sinks;
QList<AudioPorts *> m_ports;
DBusAudio *m_audio;
};
class AudioSink : public QObject
@ -74,7 +75,7 @@ public:
void setFade(double value);
void setMute(bool mute);
void setPort(QString name);
void setVolume(double value, bool isPlay);
void setVolume(int value, bool isPlay);
bool isMute();
bool supportBalance();
@ -85,24 +86,17 @@ public:
int volume();
QString description();
QString name();
int cardId();
private Q_SLOTS:
void onPropertyChanged(const QDBusMessage& msg);
uint cardId();
protected:
explicit AudioSink(QString path, QObject *parent = nullptr);
explicit AudioSink(QString path, bool isDefault, QObject *parent = nullptr);
~AudioSink();
private:
QDBusMessage callMethod(const QString &methodName, const QList<QVariant> &argument);
template<typename T>
T getProperties(const QString &propName);
QList<QVariant> getPropertiesByFreeDesktop(const QString &propName);
void setDefault(bool isDefaultSink);
private:
QString m_devicePath;
DBusSink *m_sink;
bool m_isDefault;
};
class AudioPorts : public QObject
@ -112,7 +106,7 @@ class AudioPorts : public QObject
friend class VolumeModel;
public:
int cardId() const;
uint cardId() const;
QString cardName() const;
QString name() const;
QString description() const;
@ -121,7 +115,7 @@ public:
bool isHeadPhone() const;
protected:
AudioPorts(int cardId, QString cardName);
AudioPorts(uint cardId, QString cardName);
~AudioPorts();
void setName(const QString &name);
void setDescription(const QString &desc);
@ -129,7 +123,7 @@ protected:
void setIsChecked(bool isChecked);
private:
int m_cardId;
uint m_cardId;
QString m_cardName;
QString m_portName;
QString m_description;

View File

@ -234,6 +234,17 @@ void AbstractPluginsController::loadPlugin(const QString &pluginFile)
return;
}
if (!needLoad(interface)) {
// 对于一些固定的插件是不需要加载的,例如在特效模式下,只需要加载电源插件,其他的是无需加载的
for (const QPair<QString, PluginsItemInterface *> &pair : m_pluginLoadMap.keys()) {
if (pair.first == pluginFile)
m_pluginLoadMap.remove(pair);
}
pluginLoader->unload();
pluginLoader->deleteLater();
return;
}
if (interface->pluginName() == "multitasking") {
if (Utils::IS_WAYLAND_DISPLAY || Dtk::Core::DSysInfo::deepinType() == Dtk::Core::DSysInfo::DeepinServer) {
for (auto &pair : m_pluginLoadMap.keys()) {

View File

@ -51,6 +51,9 @@ public:
signals:
void pluginLoaderFinished();
protected:
virtual bool needLoad(PluginsItemInterface *) { return true; }
protected:
QMap<PluginsItemInterface *, QMap<QString, QObject *>> &pluginsMap();
QObject *pluginItemAt(PluginsItemInterface * const itemInter, const QString &itemKey) const;

View File

@ -1,9 +1,30 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "brightnessmonitorwidget.h"
#include "brightnessmodel.h"
#include "customslider.h"
#include "settingdelegate.h"
#include <DListView>
#include <DDBusSender>
#include <QScrollBar>
#include <QLabel>
@ -21,7 +42,7 @@ BrightnessMonitorWidget::BrightnessMonitorWidget(BrightnessModel *model, QWidget
: QWidget(parent)
, m_sliderWidget(new QWidget(this))
, m_sliderLayout(new QVBoxLayout(m_sliderWidget))
, m_descriptionLabel(new QLabel(tr("Output Device"), this))
, m_descriptionLabel(new QLabel(tr("Collaboration"), this))
, m_deviceList(new DListView(this))
, m_brightModel(model)
, m_model(new QStandardItemModel(this))
@ -92,15 +113,17 @@ void BrightnessMonitorWidget::initConnection()
// 更新滚动条的内容
onBrightChanged(monitor);
} else {
QDBusInterface controlcenter("com.deepin.dde.ControlCenter", "/com/deepin/dde/ControlCenter",
"com.deepin.dde.ControlCenter", QDBusConnection::sessionBus());
controlcenter.call("ShowModule", "display");
DDBusSender().service("com.deepin.dde.ControlCenter")
.path("/com/deepin/dde/ControlCenter")
.interface("com.deepin.dde.ControlCenter")
.method("ShowModule").arg(QString("display")).call();
hide();
}
});
for (QPair<BrightMonitor *, SliderContainer *> container : m_sliderContainers) {
SliderContainer *slider = container.second;
slider->slider()->setValue(container.first->brihtness());
connect(slider->slider(), &CustomSlider::valueChanged, this, [ = ](int value) {
m_brightModel->setBrightness(container.first, value);
});
@ -112,16 +135,7 @@ void BrightnessMonitorWidget::initConnection()
void BrightnessMonitorWidget::reloadMonitor()
{
m_model->clear();
QList<BrightMonitor *> monitots = m_brightModel->monitors();
for (BrightMonitor *monitor : monitots) {
DStandardItem *item = new DStandardItem;
item->setIcon(QIcon(":/icons/resources/laptop.svg"));
item->setText(monitor->name());
item->setFlags(Qt::NoItemFlags);
item->setData(QVariant::fromValue(monitor), itemDataRole);
m_model->appendRow(item);
onBrightChanged(monitor);
}
// 跨端协同列表,后续会新增该功能
// 显示设置
DStandardItem *settingItem = new DStandardItem;
settingItem->setIcon(QIcon(""));

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BRIGHTNESSMONITORWIDGET_H
#define BRIGHTNESSMONITORWIDGET_H

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "brightnesswidget.h"
#include "customslider.h"
#include "brightnessmodel.h"
@ -13,7 +33,6 @@ BrightnessWidget::BrightnessWidget(QWidget *parent)
{
initUi();
initConenction();
onUpdateBright();
}
BrightnessWidget::~BrightnessWidget()
@ -57,14 +76,24 @@ void BrightnessWidget::initConenction()
if (icon == DSlider::SliderIcons::RightIcon)
Q_EMIT rightIconClicked();
});
connect(m_slider, &CustomSlider::valueChanged, this, [ this ](int value) {
connect(m_slider, &CustomSlider::valueChanged, this, [ this ](int value) {
BrightMonitor *monitor = m_model->primaryMonitor();
if (monitor)
m_model->setBrightness(monitor, value);
});
connect(m_model, &BrightnessModel::brightnessChanged, this, &BrightnessWidget::onUpdateBright);
BrightMonitor *monitor = m_model->primaryMonitor();
if (monitor)
onUpdateBright(monitor);
}
void BrightnessWidget::onUpdateBright()
void BrightnessWidget::onUpdateBright(BrightMonitor *monitor)
{
if (!monitor->isPrimary())
return;
// 此处只显示主屏的亮度
m_slider->setValue(monitor->brihtness());
}

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BRIGHTNESSWIDGET_H
#define BRIGHTNESSWIDGET_H
@ -27,7 +47,7 @@ protected:
void hideEvent(QHideEvent *event) override;
private Q_SLOTS:
void onUpdateBright();
void onUpdateBright(BrightMonitor *monitor);
private:
void initUi();

View File

@ -1,6 +1,27 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "datetimedisplayer.h"
#include <DFontSizeManager>
#include <DDBusSender>
#include <QHBoxLayout>
#include <QPainter>
@ -9,6 +30,11 @@
DWIDGET_USE_NAMESPACE
#define DATETIMESIZE 40
#define ITEMSPACE 8
static QMap<int, QString> dateFormat{{ 0,"yyyy/M/d" }, { 1,"yyyy-M-d" }, { 2,"yyyy.M.d" }, { 3,"yyyy/MM/dd" },
{ 4,"yyyy-MM-dd" }, { 5,"yyyy.MM.dd" }, { 6,"yy/M/d" }, { 7,"yy-M-d" }, { 8,"yy.M.d" }};
static QMap<int, QString> timeFormat{{0, "h:mm"}, {1, "hh:mm"}};
DateTimeDisplayer::DateTimeDisplayer(QWidget *parent)
: QWidget (parent)
@ -17,15 +43,12 @@ DateTimeDisplayer::DateTimeDisplayer(QWidget *parent)
, m_timeFont(DFontSizeManager::instance()->t6())
, m_dateFont(DFontSizeManager::instance()->t10())
{
initUi();
setShortDateFormat(m_timedateInter->shortDateFormat());
setShortTimeFormat(m_timedateInter->shortTimeFormat());
connect(m_timedateInter, &Timedate::ShortDateFormatChanged, this, &DateTimeDisplayer::setShortDateFormat);
connect(m_timedateInter, &Timedate::ShortTimeFormatChanged, this, &DateTimeDisplayer::setShortTimeFormat);
// 日期格式变化的时候,需要重绘
connect(m_timedateInter, &Timedate::ShortDateFormatChanged, this, [ this ] { update(); });
// 时间格式变化的时候,需要重绘
connect(m_timedateInter, &Timedate::ShortTimeFormatChanged, this, [ this ] { update(); });
// 连接日期时间修改信号,更新日期时间插件的布局
connect(m_timedateInter, &Timedate::TimeUpdate, this, [ this ] {
update();
});
connect(m_timedateInter, &Timedate::TimeUpdate, this, [ this ] { update(); });
}
DateTimeDisplayer::~DateTimeDisplayer()
@ -39,6 +62,7 @@ void DateTimeDisplayer::setPositon(Dock::Position position)
m_position = position;
setCurrentPolicy();
update();
}
void DateTimeDisplayer::setCurrentPolicy()
@ -57,20 +81,25 @@ void DateTimeDisplayer::setCurrentPolicy()
}
}
void DateTimeDisplayer::initUi()
{
QHBoxLayout *layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
}
QSize DateTimeDisplayer::suitableSize()
{
DateTimeInfo info = dateTimeInfo();
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom)
return QSize(info.m_dateRect.right(), height());
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) {
int width = info.m_timeRect.width() + info.m_dateRect.width() + 16;
return QSize(width, height());
}
return QSize(width(), info.m_dateRect.bottom());
return QSize(width(), info.m_timeRect.height() + info.m_dateRect.height());
}
void DateTimeDisplayer::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event);
DDBusSender().service("com.deepin.Calendar")
.path("/com/deepin/Calendar")
.interface("com.deepin.Calendar")
.method("RaiseWindow").call();
}
DateTimeDisplayer::DateTimeInfo DateTimeDisplayer::dateTimeInfo()
@ -78,35 +107,67 @@ DateTimeDisplayer::DateTimeInfo DateTimeDisplayer::dateTimeInfo()
DateTimeInfo info;
const QDateTime current = QDateTime::currentDateTime();
const Dock::Position position = qApp->property(PROP_POSITION).value<Dock::Position>();
info.m_timeRect = rect();
info.m_dateRect = rect();
QString format = m_shortTimeFormat;
QString format = getTimeFormat();
if (!m_timedateInter->use24HourFormat()) {
if (position == Dock::Top || position == Dock::Bottom)
if (m_position == Dock::Top || m_position == Dock::Bottom)
format = format.append(" AP");
else
format = format.append("\nAP");
}
info.m_time = current.toString(format);
info.m_date = current.toString(m_shortDateFormat);
int timeWidth = QFontMetrics(m_timeFont).boundingRect(info.m_time).width() + 12 * 2;
int dateWidth = QFontMetrics(m_dateFont).boundingRect(info.m_date).width() + 2;
info.m_date = current.toString(getDateFormat());
if (position == Dock::Top || position == Dock::Bottom) {
info.m_timeRect = QRect(10, 0, timeWidth, height());
int right = rect().width() - QFontMetrics(m_dateFont).width(info.m_date) - 2;
info.m_dateRect = QRect(right, 0, dateWidth, height());
if (m_position == Dock::Top || m_position == Dock::Bottom) {
int timeWidth = QFontMetrics(m_timeFont).boundingRect(info.m_time).width() + 10;
int dateWidth = QFontMetrics(m_dateFont).boundingRect(info.m_date).width() + 2;
info.m_timeRect = QRect(ITEMSPACE, 0, timeWidth, height());
int dateX = rect().width() - QFontMetrics(m_dateFont).width(info.m_date) - 2 - ITEMSPACE;
// 如果时间的X坐标小于日期的X坐标需要手动设置坐标在日期坐标的右侧
if (dateX < info.m_timeRect.right())
dateX = info.m_timeRect.right();
info.m_dateRect = QRect(dateX, 0, dateWidth, height());
} else {
info.m_timeRect = QRect(0, 0, timeWidth, DATETIMESIZE / 2);
info.m_dateRect = QRect(0, DATETIMESIZE / 2 + 1, dateWidth, DATETIMESIZE / 2);
int textWidth = rect().width();
info.m_timeRect = QRect(0, 0, textWidth, DATETIMESIZE / 2);
info.m_dateRect = QRect(0, DATETIMESIZE / 2 + 1, textWidth, DATETIMESIZE / 2);
}
return info;
}
QString DateTimeDisplayer::getDateFormat() const
{
int type = m_timedateInter->shortDateFormat();
QString shortDateFormat = "yyyy-MM-dd";
if (dateFormat.contains(type))
shortDateFormat = dateFormat.value(type);
// 如果是左右方向,则不显示年份
if (m_position == Dock::Position::Left || m_position == Dock::Position::Right) {
static QStringList yearStrList{"yyyy/", "yyyy-", "yyyy.", "yy/", "yy-", "yy."};
for (int i = 0; i < yearStrList.size() ; i++) {
const QString &yearStr = yearStrList[i];
if (shortDateFormat.contains(yearStr)) {
shortDateFormat = shortDateFormat.remove(yearStr);
break;
}
}
}
return shortDateFormat;
}
QString DateTimeDisplayer::getTimeFormat() const
{
int type = m_timedateInter->shortTimeFormat();
if (timeFormat.contains(type))
return timeFormat[type];
return QString("hh:mm");
}
void DateTimeDisplayer::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e);
@ -117,37 +178,14 @@ void DateTimeDisplayer::paintEvent(QPaintEvent *e)
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(palette().brightText(), 1));
painter.drawText(info.m_timeRect, Qt::AlignLeft | Qt::AlignVCenter, info.m_time);
int timeTextFlag = Qt::AlignCenter;
int dateTextFlag = Qt::AlignCenter;
if (m_position == Dock::Top || m_position == Dock::Bottom) {
timeTextFlag = Qt::AlignLeft | Qt::AlignVCenter;
dateTextFlag = Qt::AlignRight | Qt::AlignVCenter;
}
painter.setFont(m_timeFont);
painter.drawText(info.m_timeRect, timeTextFlag, info.m_time);
painter.setFont(m_dateFont);
painter.drawText(info.m_dateRect, Qt::AlignLeft | Qt::AlignVCenter, info.m_date);
}
void DateTimeDisplayer::setShortDateFormat(int type)
{
switch (type) {
case 0: m_shortDateFormat = "yyyy/M/d"; break;
case 1: m_shortDateFormat = "yyyy-M-d"; break;
case 2: m_shortDateFormat = "yyyy.M.d"; break;
case 3: m_shortDateFormat = "yyyy/MM/dd"; break;
case 4: m_shortDateFormat = "yyyy-MM-dd"; break;
case 5: m_shortDateFormat = "yyyy.MM.dd"; break;
case 6: m_shortDateFormat = "yy/M/d"; break;
case 7: m_shortDateFormat = "yy-M-d"; break;
case 8: m_shortDateFormat = "yy.M.d"; break;
default: m_shortDateFormat = "yyyy-MM-dd"; break;
}
update();
}
void DateTimeDisplayer::setShortTimeFormat(int type)
{
switch (type) {
case 0: m_shortTimeFormat = "h:mm"; break;
case 1: m_shortTimeFormat = "hh:mm"; break;
default: m_shortTimeFormat = "hh:mm"; break;
}
update();
painter.drawText(info.m_dateRect, dateTextFlag, info.m_date);
}

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DATETIMEDISPLAYER_H
#define DATETIMEDISPLAYER_H
@ -25,27 +45,25 @@ private:
public:
explicit DateTimeDisplayer(QWidget *parent = nullptr);
~DateTimeDisplayer() override;
void setPositon(Dock::Position position);
QSize suitableSize();
void setPositon(Dock::Position position);
QSize suitableSize();
private:
void initUi();
void setCurrentPolicy();
DateTimeInfo dateTimeInfo();
protected:
void mouseReleaseEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *e) override;
void paintEvent(QPaintEvent *e) override;
private:
void setCurrentPolicy();
DateTimeInfo dateTimeInfo();
private Q_SLOTS:
void setShortDateFormat(int type);
void setShortTimeFormat(int type);
QString getDateFormat() const;
QString getTimeFormat() const;
private:
Timedate *m_timedateInter;
QString m_shortDateFormat;
QString m_shortTimeFormat;
Dock::Position m_position;
mutable QFont m_timeFont;
mutable QFont m_dateFont;
private:
Timedate *m_timedateInter;
Dock::Position m_position;
mutable QFont m_timeFont;
mutable QFont m_dateFont;
};
#endif // DATETIMEDISPLAYER_H

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mediawidget.h"
#include <DFontSizeManager>

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MEDIAWIDGET_H
#define MEDIAWIDGET_H

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "settingdelegate.h"
#include <DListView>

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SETTINGDELEGATE_H
#define SETTINGDELEGATE_H
@ -12,13 +32,13 @@ class SettingDelegate : public DStyledItemDelegate
{
Q_OBJECT
Q_SIGNALS:
void selectIndexChanged(const QModelIndex &);
public:
explicit SettingDelegate(QAbstractItemView *parent = nullptr);
~SettingDelegate() override;
Q_SIGNALS:
void selectIndexChanged(const QModelIndex &);
protected:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override;

View File

@ -1,4 +1,24 @@
#include "volumedeviceswidget.h"
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "volumedeviceswidget.h"
#include "customslider.h"
#include "volumemodel.h"
#include "settingdelegate.h"
@ -7,6 +27,7 @@
#include <DPushButton>
#include <DLabel>
#include <DGuiApplicationHelper>
#include <DDBusSender>
#include <QVBoxLayout>
#include <QScrollBar>
@ -140,9 +161,10 @@ void VolumeDevicesWidget::initConnection()
m_deviceList->update();
} else {
// 打开控制中心的声音模块
QDBusInterface controlcenter("com.deepin.dde.ControlCenter", "/com/deepin/dde/ControlCenter",
"com.deepin.dde.ControlCenter", QDBusConnection::sessionBus());
controlcenter.call("ShowModule", "sound");
DDBusSender().service("com.deepin.dde.ControlCenter")
.path("/com/deepin/dde/ControlCenter")
.interface("com.deepin.dde.ControlCenter")
.method("ShowModule").arg(QString("sound")).call();
hide();
}
});

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VOLUMEDEVICESWIDGET_H
#define VOLUMEDEVICESWIDGET_H

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "volumewidget.h"
#include "customslider.h"
#include "imageutil.h"

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VOLUMEWIDGET_H
#define VOLUMEWIDGET_H

View File

@ -976,10 +976,10 @@ QPainterPath MainPanelControl::areaPath()
return QPainterPath();
QPainterPath path;
int leftWidth = m_fixedAreaWidget->width() + m_fixedSpliter->width() + m_appAreaWidget->width() + 10;
int leftWidth = m_fixedAreaWidget->width() + m_fixedSpliter->width() + m_appAreaWidget->width();
int roundHeight = height();
path.addRoundedRect(QRect(0, 0, leftWidth, roundHeight), 18, 18);
path.addRoundedRect(QRect(leftWidth + 10, 0, m_trayManagerWidget->width(), roundHeight), 18, 18);
path.addRoundedRect(QRect(m_trayManagerWidget->x(), 0, m_trayManagerWidget->width(), roundHeight), 18, 18);
return path;
}

View File

@ -0,0 +1,116 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pluginchildpage.h"
#include <QLabel>
#include <QVBoxLayout>
#include <QEvent>
PluginChildPage::PluginChildPage(QWidget *parent)
: QWidget(parent)
, m_headerWidget(new QWidget(this))
, m_back(new QLabel(m_headerWidget))
, m_title(new QLabel(m_headerWidget))
, m_container(new QWidget(this))
, m_topWidget(nullptr)
, m_containerLayout(new QVBoxLayout(m_container))
, m_isBack(false)
{
initUi();
m_back->installEventFilter(this);
}
PluginChildPage::~PluginChildPage()
{
}
void PluginChildPage::pushWidget(QWidget *widget)
{
// 首先将界面其他的窗体移除
for (int i = m_containerLayout->count() - 1; i >= 0; i--) {
QLayoutItem *item = m_containerLayout->itemAt(i);
item->widget()->removeEventFilter(this);
item->widget()->hide();
m_containerLayout->removeItem(item);
}
m_topWidget = widget;
widget->installEventFilter(this);
m_containerLayout->addWidget(widget);
widget->show();
m_isBack = false;
QMetaObject::invokeMethod(this, &PluginChildPage::resetHeight, Qt::QueuedConnection);
}
void PluginChildPage::setTitle(const QString &text)
{
m_title->setText(text);
}
bool PluginChildPage::isBack()
{
return m_isBack;
}
void PluginChildPage::initUi()
{
m_back->setFixedWidth(24);
m_title->setAlignment(Qt::AlignCenter);
QHBoxLayout *headerLayout = new QHBoxLayout(m_headerWidget);
headerLayout->setContentsMargins(11, 12, 24 + 11, 12);
headerLayout->setSpacing(0);
headerLayout->addWidget(m_back);
headerLayout->addWidget(m_title);
m_headerWidget->setFixedHeight(48);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSpacing(0);
mainLayout->addWidget(m_headerWidget);
mainLayout->addWidget(m_container);
m_containerLayout->setContentsMargins(11, 0, 11, 0);
m_containerLayout->setSpacing(0);
}
bool PluginChildPage::eventFilter(QObject *watched, QEvent *event)
{
if (watched == m_back && event->type() == QEvent::MouseButtonRelease) {
m_isBack = true;
Q_EMIT back();
return true;
}
if (watched == m_topWidget) {
if (event->type() == QEvent::Hide) {
Q_EMIT closeSelf();
return true;
}
if (event->type() == QEvent::Resize)
resetHeight();
}
return QWidget::eventFilter(watched, event);
}
void PluginChildPage::resetHeight()
{
QMargins m = m_containerLayout->contentsMargins();
m_container->setFixedHeight(m.top() + m.bottom() + m_topWidget->height());
setFixedHeight(m_headerWidget->height() + m_container->height());
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PLUGINCHILDPAGE_H
#define PLUGINCHILDPAGE_H
#include <QWidget>
class QLabel;
class QVBoxLayout;
class PluginChildPage : public QWidget
{
Q_OBJECT
public:
explicit PluginChildPage(QWidget *parent);
~PluginChildPage() override;
void pushWidget(QWidget *widget);
void setTitle(const QString &text);
bool isBack();
Q_SIGNALS:
void back();
void closeSelf();
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
private:
void initUi();
void resetHeight();
private:
QWidget *m_headerWidget;
QLabel *m_back;
QLabel *m_title;
QWidget *m_container;
QWidget *m_topWidget;
QVBoxLayout *m_containerLayout;
bool m_isBack;
};
#endif // PLUGINCHILDPAGE_H

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "quickpluginwindow.h"
#include "quicksettingcontroller.h"
#include "quicksettingitem.h"
@ -13,9 +33,11 @@
#include <QStringList>
#include <QSize>
#include <QMouseEvent>
#include <QBoxLayout>
#define ITEMSIZE 22
#define ITEMSPACE 6
#define ICONSIZE 16
static QStringList fixedPluginKeys{ "network-item-key", "sound-item-key", "power" };
const int itemDataRole = Dtk::UserRole + 1;
@ -23,8 +45,7 @@ const int itemSortRole = Dtk::UserRole + 2;
QuickPluginWindow::QuickPluginWindow(QWidget *parent)
: QWidget(parent)
, m_listView(new DListView(this))
, m_model(new QStandardItemModel(this))
, m_mainLayout(new QBoxLayout(QBoxLayout::LeftToRight, this))
, m_position(Dock::Position::Bottom)
{
initUi();
@ -32,8 +53,6 @@ QuickPluginWindow::QuickPluginWindow(QWidget *parent)
setAcceptDrops(true);
setMouseTracking(true);
this->installEventFilter(this);
}
QuickPluginWindow::~QuickPluginWindow()
@ -42,28 +61,16 @@ QuickPluginWindow::~QuickPluginWindow()
void QuickPluginWindow::initUi()
{
m_listView->setModel(m_model);
m_listView->setViewMode(QListView::IconMode);
m_listView->setMovement(QListView::Free);
m_listView->setWordWrap(false);
m_listView->verticalScrollBar()->setVisible(false);
m_listView->horizontalScrollBar()->setVisible(false);
m_listView->setOrientation(QListView::Flow::LeftToRight, false);
m_listView->setGridSize(QSize(ITEMSIZE + 10, ITEMSIZE + 10));
m_listView->setSpacing(ITEMSPACE);
m_listView->setContentsMargins(0,0,0,0);
m_model->setSortRole(itemSortRole);
QHBoxLayout *layout = new QHBoxLayout(this);
layout->setContentsMargins(0,0,0,0);
layout->setSpacing(0);
layout->addWidget(m_listView);
setAcceptDrops(true);
m_mainLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
m_mainLayout->setDirection(QBoxLayout::Direction::RightToLeft);
m_mainLayout->setContentsMargins(ITEMSPACE, 0, ITEMSPACE, 0);
m_mainLayout->setSpacing(ITEMSPACE);
const QList<QuickSettingItem *> &items = QuickSettingController::instance()->settingItems();
for (QuickSettingItem *settingItem : items) {
const QString itemKey = settingItem->itemKey();
if (!fixedPluginKeys.contains(itemKey))
return;
continue;
addPlugin(settingItem);
}
@ -75,228 +82,243 @@ void QuickPluginWindow::setPositon(Position position)
return;
m_position = position;
QuickSettingContainer::setPosition(position);
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom)
m_listView->setOrientation(QListView::Flow::LeftToRight, false);
m_mainLayout->setDirection(QBoxLayout::RightToLeft);
else
m_listView->setOrientation(QListView::Flow::TopToBottom, false);
m_mainLayout->setDirection(QBoxLayout::BottomToTop);
}
int QuickPluginWindow::findActiveTargetIndex(QWidget *widget)
{
for (int i = 0; i < m_activeSettingItems.size(); i++) {
QuickSettingItem *settingItem = m_activeSettingItems[i];
if (settingItem->pluginItem()->itemWidget(settingItem->itemKey()) == widget)
return i;
}
return -1;
}
void QuickPluginWindow::dragPlugin(QuickSettingItem *item)
{
// 释放插件,一般是从快捷设置面板区域移动到这里的,固定插件不支持拖动
if (fixedPluginKeys.contains(item->itemKey()))
return;
QPoint itemPoint = mapFromGlobal(QCursor::pos());
// 查找移动后的位置,如果移动后的插件找不到,就直接放到最后
QWidget *targetWidget = childAt(itemPoint);
if (!targetWidget) {
m_activeSettingItems << item;
} else {
// 如果是拖动到固定插件区域,也放到最后
int targetIndex = findActiveTargetIndex(targetWidget);
if (targetIndex < 0)
m_activeSettingItems << item;
else
m_activeSettingItems.insert(targetIndex, item);
}
//排序插入到当前窗体
resetPluginDisplay();
Q_EMIT itemCountChanged();
}
void QuickPluginWindow::addPlugin(QuickSettingItem *item)
{
// 判断当前的插件是否存在,如果存在,则不插入
for (int i = 0; i < m_model->rowCount(); i++) {
QStandardItem *myItem = m_model->item(i, 0);
QuickSettingItem *settingItem = myItem->data(itemDataRole).value<QuickSettingItem *>();
if (settingItem == item) {
m_model->sort(0);
for (int i = 0; i < m_mainLayout->count(); i++) {
QWidget *widget = m_mainLayout->itemAt(i)->widget();
if (item == widget) {
resetPluginDisplay();
return;
}
}
DStandardItem *standItem = createStandItem(item);
if (!standItem)
QWidget *widget = item->pluginItem()->itemWidget(item->itemKey());
if (!widget)
return;
m_model->appendRow(standItem);
resetSortRole();
m_model->sort(0);
widget->installEventFilter(this);
if (fixedPluginKeys.contains(item->itemKey())) {
// 新插入的插件如果是固定插件,则将其插入到固定插件列表中,并对其进行排序
m_fixedSettingItems << item;
qSort(m_fixedSettingItems.begin(), m_fixedSettingItems.end(), [](QuickSettingItem *item1, QuickSettingItem *item2) {
int index1 = fixedPluginKeys.indexOf(item1->itemKey());
int index2 = fixedPluginKeys.indexOf(item2->itemKey());
return index1 < index2;
});
} else {
// 如果是非固定插件,则直接插入到末尾
m_activeSettingItems << item;
}
resetPluginDisplay();
Q_EMIT itemCountChanged();
}
QSize QuickPluginWindow::suitableSize()
{
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom)
return QSize((ITEMSIZE + ITEMSPACE) * m_model->rowCount() + ITEMSPACE, ITEMSIZE);
return QSize((ITEMSPACE + ICONSIZE) * m_mainLayout->count() + ITEMSIZE, ITEMSIZE);
return QSize(ITEMSIZE, (ITEMSIZE + ITEMSPACE) * m_model->rowCount() + ITEMSPACE);
return QSize(ITEMSIZE, (ITEMSIZE + ITEMSPACE) * m_mainLayout->count() + ITEMSPACE);
}
void QuickPluginWindow::removePlugin(QuickSettingItem *item)
{
for (int i = 0; i < m_model->rowCount(); i++) {
QModelIndex index = m_model->index(i, 0);
QuickSettingItem *quickItem = index.data(itemDataRole).value<QuickSettingItem *>();
if (quickItem == item) {
m_model->removeRow(i);
break;
}
}
m_model->sort(0);
if (m_fixedSettingItems.contains(item))
m_fixedSettingItems.removeOne(item);
else if (m_activeSettingItems.contains(item))
m_activeSettingItems.removeOne(item);
else
return;
resetPluginDisplay();
Q_EMIT itemCountChanged();
}
void QuickPluginWindow::resetSortRole()
QuickSettingItem *QuickPluginWindow::findQuickSettingItem(const QPoint &mousePoint, const QList<QuickSettingItem *> &settingItems)
{
QList<QPair<QStandardItem *, int>> fixedItems;
QList<QStandardItem *> activeItems;
for (int i = 0; i < m_model->rowCount(); i++) {
QModelIndex index = m_model->index(i, 0);
if (!index.data(itemDataRole).canConvert<QuickSettingItem *>())
continue;
QuickSettingItem *settingItem = index.data(itemDataRole).value<QuickSettingItem *>();
if (fixedPluginKeys.contains(settingItem->itemKey()))
fixedItems.push_back({ m_model->item(i, 0), fixedPluginKeys.indexOf(settingItem->itemKey()) });
else
activeItems << m_model->item(i, 0);
}
for (int i = 0; i < activeItems.size(); i++) {
QStandardItem *item = activeItems[i];
item->setData(i, itemSortRole);
}
for (QPair<QStandardItem *, int> item : fixedItems)
item.first->setData(activeItems.size() + item.second, itemSortRole);
}
DStandardItem *QuickPluginWindow::createStandItem(QuickSettingItem *item)
{
const QString itemKey = item->itemKey();
QWidget *itemWidget = item->pluginItem()->itemWidget(itemKey);
if (!itemWidget)
QWidget *selectWidget = childAt(mousePoint);
if (!selectWidget)
return nullptr;
itemWidget->setParent(m_listView);
DStandardItem *standItem = new DStandardItem;
standItem->setFlags(Qt::ItemIsEnabled);
standItem->setBackground(Qt::transparent);
standItem->setData(QVariant::fromValue(item), itemDataRole);
DViewItemAction *action = new DViewItemAction(Qt::AlignCenter, QSize(ITEMSIZE, ITEMSIZE), QSize(ITEMSIZE, ITEMSIZE), true);
action->setWidget(itemWidget);
connect(action, &DViewItemAction::triggered, this, [ this ] {
QPoint ptCurrent = pos();
QWidget *callWidget = parentWidget();
if (callWidget)
ptCurrent = callWidget->mapToGlobal(ptCurrent);
QuickSettingContainer::popWindow()->show(ptCurrent);
});
connect(action, &DViewItemAction::destroyed, this, [ itemWidget ] {
itemWidget->setParent(nullptr);
itemWidget->hide();
});
standItem->setActionList(Qt::LeftEdge, { action });
return standItem;
}
void QuickPluginWindow::mouseReleaseEvent(QMouseEvent *event)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
QModelIndex selectedIndex = m_listView->indexAt(mouseEvent->pos());
if (!selectedIndex.isValid())
return;
QuickSettingItem *moveItem = selectedIndex.data(itemDataRole).value<QuickSettingItem *>();
if (!moveItem)
return;
if (fixedPluginKeys.contains(moveItem->itemKey())) {
QPoint currentPoint = pos();
QWidget *callWidget = parentWidget();
if (callWidget)
currentPoint = callWidget->mapToGlobal(currentPoint);
QuickSettingContainer::popWindow()->show(currentPoint);
for (int i = 0; i < settingItems.size(); i++) {
QuickSettingItem *settingItem = settingItems[i];
QWidget *widget = settingItem->pluginItem()->itemWidget(settingItem->itemKey());
if (selectWidget == widget)
return settingItem;
}
return nullptr;
}
void QuickPluginWindow::mousePressEvent(QMouseEvent *event)
{
QModelIndex selectedIndex = m_listView->indexAt(event->pos());
if (!selectedIndex.isValid()) {
QWidget::mousePressEvent(event);
// 查找非固定的图标,然后执行拖动
QuickSettingItem *quickItem = findQuickSettingItem(event->pos(), m_activeSettingItems);
if (!quickItem)
return;
// 如果不是固定图标,则让其拖动
startDrag(quickItem);
}
void QuickPluginWindow::mouseReleaseEvent(QMouseEvent *event)
{
// 查找固定团图标,然后点击弹出快捷面板
QuickSettingItem *quickItem = findQuickSettingItem(event->pos(), m_fixedSettingItems);
if (!quickItem)
return;
// 如果是固定图标,则让其弹出列表
QPoint currentPoint = pos();
QWidget *callWidget = parentWidget();
if (callWidget) {
currentPoint = callWidget->mapToGlobal(currentPoint);
// 如果是向上的方向,则需要减去高度
if (m_position == Dock::Position::Top)
currentPoint.setY(currentPoint.y() + callWidget->height());
else if (m_position == Dock::Position::Left)
currentPoint.setX(currentPoint.x() + callWidget->width());
}
QuickSettingItem *moveItem = selectedIndex.data(itemDataRole).value<QuickSettingItem *>();
if (!moveItem) {
QWidget::mousePressEvent(event);
return;
}
if (fixedPluginKeys.contains(moveItem->itemKey())) {
QWidget::mousePressEvent(event);
return;
}
startDrag(moveItem);
DockPopupWindow *popWindow = QuickSettingContainer::popWindow();
popWindow->show(currentPoint);
}
void QuickPluginWindow::startDrag(QuickSettingItem *moveItem)
{
AppDrag *drag = new AppDrag(this, new QuickDragWidget);
CustomMimeData *mimedata = new CustomMimeData;
mimedata->setData(moveItem);
QuickPluginMimeData *mimedata = new QuickPluginMimeData(moveItem);
drag->setMimeData(mimedata);
drag->appDragWidget()->setDockInfo(m_position, QRect(mapToGlobal(pos()), size()));
QPixmap dragPixmap = moveItem->pluginItem()->icon()->pixmap(QSize(ITEMSIZE, ITEMSIZE));
drag->setPixmap(dragPixmap);
drag->setHotSpot(QPoint(dragPixmap.width() / 2, dragPixmap.height() / 2));
drag->setHotSpot(QPoint(0, 0));
connect(drag->appDragWidget(), &AppDragWidget::requestRemoveItem, this, [ this, moveItem ] {
removePlugin(moveItem);
});
connect(static_cast<QuickDragWidget *>(drag->appDragWidget()), &QuickDragWidget::requestDropItem, this, [ this, moveItem ](){
addPlugin(moveItem);
});
connect(static_cast<QuickDragWidget *>(drag->appDragWidget()), &QuickDragWidget::requestDragMove, this, [ this ](QDragMoveEvent *eve){
QPoint ptCurrent = m_listView->mapFromGlobal(QCursor::pos());
QModelIndex index = m_listView->indexAt(ptCurrent);
if (!index.isValid())
return;
CustomMimeData *data = const_cast<CustomMimeData *>(qobject_cast<const CustomMimeData *>(eve->mimeData()));
if (!data)
return;
QuickSettingItem *sourceItem = static_cast<QuickSettingItem *>(data->data());
if (!sourceItem)
return;
QuickSettingItem *targetItem = index.data(itemDataRole).value<QuickSettingItem *>();
if (!targetItem || fixedPluginKeys.contains(targetItem->itemKey()) || sourceItem == targetItem)
return;
// recall all sortroles
QList<QPair<QModelIndex, QuickSettingItem *>> allItems;
for (int i = 0; i < m_model->rowCount(); i++) {
QModelIndex rowIndex = m_model->index(i, 0);
allItems.push_back({ rowIndex, rowIndex.data(itemDataRole).value<QuickSettingItem *>() });
}
auto findIndex = [ allItems ](QuickSettingItem *item) {
for (int i = 0; i < allItems.size(); i++) {
const QPair<QModelIndex, QuickSettingItem *> &rowItem = allItems[i];
if (rowItem.second == item)
return i;
}
return -1;
};
int sourceIndex = findIndex(sourceItem);
int targetIndex = findIndex(targetItem);
if (sourceIndex < 0 || targetIndex < 0 || sourceIndex == targetIndex)
return;
allItems.move(sourceIndex, targetIndex);
for (int i = 0; i < allItems.size(); i++) {
const QPair<QModelIndex, QuickSettingItem *> &rowItem = allItems[i];
m_model->setData(rowItem.first, i, itemSortRole);
}
eve->accept();
connect(static_cast<QuickDragWidget *>(drag->appDragWidget()), &QuickDragWidget::requestDropItem, this, [ this] {
resetPluginDisplay();
Q_EMIT itemCountChanged();
});
connect(static_cast<QuickDragWidget *>(drag->appDragWidget()), &QuickDragWidget::requestDragMove, this, &QuickPluginWindow::onPluginDragMove);
drag->exec(Qt::MoveAction | Qt::CopyAction);
}
void QuickPluginWindow::onPluginDragMove(QDragMoveEvent *event)
{
QPoint currentPoint = mapFromGlobal(QCursor::pos());
const QuickPluginMimeData *data = qobject_cast<const QuickPluginMimeData *>(event->mimeData());
if (!data)
return;
QuickSettingItem *sourceItem = data->quickSettingItem();
if (!sourceItem)
return;
QWidget *sourceMoveWidget = sourceItem->pluginItem()->itemWidget(sourceItem->itemKey());
QuickSettingItem *targetItem = findQuickSettingItem(currentPoint, m_activeSettingItems);
// 如果未找到要移动的目标位置,或者移动的目标位置是固定插件,或者原插件和目标插件是同一个插件,则不做任何操作
if (!sourceMoveWidget || !targetItem || sourceItem == targetItem)
return;
// 重新对所有的插件进行排序
QMap<QWidget *, int> allItems;
for (int i = 0; i < m_mainLayout->count(); i++) {
QWidget *childWidget = m_mainLayout->itemAt(i)->widget();
allItems[childWidget] = i;
}
// 调整列表中的位置
int sourceIndex = m_activeSettingItems.indexOf(sourceItem);
int targetIndex = m_activeSettingItems.indexOf(targetItem);
if (sourceIndex >= 0)
m_activeSettingItems.move(sourceIndex, targetIndex);
else
m_activeSettingItems.insert(targetIndex, sourceItem);
event->accept();
}
QList<QuickSettingItem *> QuickPluginWindow::settingItems()
{
QList<QuickSettingItem *> items;
for (int i = 0; i < m_mainLayout->count(); i++) {
qInfo() << m_mainLayout->itemAt(i)->widget();
QuickSettingItem *item = qobject_cast<QuickSettingItem *>(m_mainLayout->itemAt(i)->widget());
if (item)
items << item;
}
return items;
}
void QuickPluginWindow::resetPluginDisplay()
{
// 先删除所有的widget
for (int i = m_mainLayout->count() - 1; i >= 0; i--) {
QLayoutItem *layoutItem = m_mainLayout->itemAt(i);
if (layoutItem) {
layoutItem->widget()->setParent(nullptr);
m_mainLayout->removeItem(layoutItem);
}
}
// 将列表中所有的控件按照顺序添加到布局上
auto addWidget = [ this ](const QList<QuickSettingItem *> &items) {
for (QuickSettingItem *item : items) {
QWidget *itemWidget = item->pluginItem()->itemWidget(item->itemKey());
itemWidget->setParent(this);
m_mainLayout->addWidget(itemWidget);
}
};
addWidget(m_activeSettingItems);
addWidget(m_fixedSettingItems);
}
void QuickPluginWindow::initConnection()
{
connect(QuickSettingController::instance(), &QuickSettingController::pluginInsert, this, [ this ](QuickSettingItem * settingItem) {
connect(QuickSettingController::instance(), &QuickSettingController::pluginInserted, this, [ this ](QuickSettingItem * settingItem) {
const QString itemKey = settingItem->itemKey();
if (!fixedPluginKeys.contains(itemKey))
return;
@ -304,20 +326,5 @@ void QuickPluginWindow::initConnection()
addPlugin(settingItem);
});
connect(QuickSettingController::instance(), &QuickSettingController::pluginRemove, this, [ this ](QuickSettingItem *settingItem) {
removePlugin(settingItem);
});
}
int QuickPluginWindow::fixedItemCount()
{
int count = 0;
for (int i = 0; i < m_model->rowCount(); i++) {
QModelIndex index = m_model->index(i, 0);
QuickSettingItem *item = index.data(itemDataRole).value<QuickSettingItem *>();
if (item && fixedPluginKeys.contains(item->itemKey()))
count++;
}
return count;
connect(QuickSettingController::instance(), &QuickSettingController::pluginRemoved, this, &QuickPluginWindow::removePlugin);
}

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QUICKPLUGINWINDOW_H
#define QUICKPLUGINWINDOW_H
@ -12,6 +32,7 @@ class QuickSettingContainer;
class QStandardItemModel;
class QStandardItem;
class QMouseEvent;
class QBoxLayout;
namespace Dtk { namespace Gui { class DRegionMonitor; }
namespace Widget { class DListView; class DStandardItem; } }
@ -22,35 +43,41 @@ class QuickPluginWindow : public QWidget
{
Q_OBJECT
Q_SIGNALS:
void itemCountChanged();
public:
explicit QuickPluginWindow(QWidget *parent = nullptr);
~QuickPluginWindow() override;
void setPositon(Dock::Position position);
void addPlugin(QuickSettingItem *item);
void dragPlugin(QuickSettingItem *item);
QSize suitableSize();
Q_SIGNALS:
void itemCountChanged();
protected:
void mouseReleaseEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
private Q_SLOTS:
void addPlugin(QuickSettingItem *item);
void removePlugin(QuickSettingItem *item);
void onPluginDragMove(QDragMoveEvent *event);
private:
void initUi();
void initConnection();
void resetSortRole();
int fixedItemCount();
DStandardItem *createStandItem(QuickSettingItem *item);
void removePlugin(QuickSettingItem *item);
void startDrag(QuickSettingItem *moveItem);
QList<QuickSettingItem *> settingItems();
QuickSettingItem *findQuickSettingItem(const QPoint &mousePoint, const QList<QuickSettingItem *> &settingItems);
int findActiveTargetIndex(QWidget *widget);
void resetPluginDisplay();
private:
DListView *m_listView;
QStandardItemModel *m_model;
QBoxLayout *m_mainLayout;
Dock::Position m_position;
QList<QuickSettingItem *> m_activeSettingItems;
QList<QuickSettingItem *> m_fixedSettingItems;
};
#endif // QUICKPLUGINWINDOW_H

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "quicksettingcontainer.h"
#include "quicksettingcontroller.h"
#include "pluginsiteminterface.h"
@ -8,6 +28,7 @@
#include "volumewidget.h"
#include "volumedeviceswidget.h"
#include "brightnessmonitorwidget.h"
#include "pluginchildpage.h"
#include <DListView>
#include <DStyle>
@ -27,6 +48,9 @@ static const int QuickItemRole = Dtk::UserRole + 10;
#define ITEMSPACE 10
#define COLUMNCOUNT 4
DockPopupWindow *QuickSettingContainer::m_popWindow = nullptr;
Dock::Position QuickSettingContainer::m_position = Dock::Position::Bottom;
QuickSettingContainer::QuickSettingContainer(QWidget *parent)
: QWidget(parent)
, m_switchLayout(new QStackedLayout(this))
@ -40,9 +64,12 @@ QuickSettingContainer::QuickSettingContainer(QWidget *parent)
, m_volumeSettingWidget(new VolumeDevicesWidget(m_volumnWidget->model(), this))
, m_brightSettingWidget(new BrightnessMonitorWidget(m_brihtnessWidget->model(), this))
, m_childPage(new PluginChildPage(this))
, m_dragPluginPosition(QPoint(0, 0))
{
initUi();
initConnection();
m_childPage->installEventFilter(this);
setMouseTracking(true);
}
QuickSettingContainer::~QuickSettingContainer()
@ -54,27 +81,53 @@ void QuickSettingContainer::showHomePage()
m_switchLayout->setCurrentIndex(0);
}
DockPopupWindow *QuickSettingContainer::popWindow()
// 根据位置获取箭头的方向
static DArrowRectangle::ArrowDirection getDirection(const Dock::Position &position)
{
static DockPopupWindow *popView = nullptr;
if (!popView) {
popView = new DockPopupWindow;
popView->setWindowFlag(Qt::Popup);
popView->setShadowBlurRadius(20);
popView->setRadius(18);
popView->setShadowYOffset(2);
popView->setShadowXOffset(0);
popView->setArrowWidth(18);
popView->setArrowHeight(10);
QuickSettingContainer *container = new QuickSettingContainer(popView);
popView->setContent(container);
} else {
QuickSettingContainer *container = static_cast<QuickSettingContainer *>(popView->getContent());
container->showHomePage();
switch (position) {
case Dock::Position::Top:
return DArrowRectangle::ArrowDirection::ArrowTop;
case Dock::Position::Left:
return DArrowRectangle::ArrowDirection::ArrowLeft;
case Dock::Position::Right:
return DArrowRectangle::ArrowDirection::ArrowRight;
default:
return DArrowRectangle::ArrowDirection::ArrowBottom;
}
return popView;
return DArrowRectangle::ArrowDirection::ArrowBottom;
}
DockPopupWindow *QuickSettingContainer::popWindow()
{
if (m_popWindow) {
QuickSettingContainer *container = static_cast<QuickSettingContainer *>(m_popWindow->getContent());
container->showHomePage();
return m_popWindow;
}
m_popWindow = new DockPopupWindow;
m_popWindow->setWindowFlag(Qt::Popup);
m_popWindow->setShadowBlurRadius(20);
m_popWindow->setRadius(18);
m_popWindow->setShadowYOffset(2);
m_popWindow->setShadowXOffset(0);
m_popWindow->setArrowWidth(18);
m_popWindow->setArrowHeight(10);
m_popWindow->setContent(new QuickSettingContainer(m_popWindow));
m_popWindow->setArrowDirection(getDirection(m_position));
return m_popWindow;
}
void QuickSettingContainer::setPosition(Position position)
{
if (m_position == position)
return;
m_position = position;
if (m_popWindow)
m_popWindow->setArrowDirection(getDirection(m_position));
}
void QuickSettingContainer::initQuickItem(QuickSettingItem *quickItem)
@ -147,21 +200,51 @@ void QuickSettingContainer::onPluginRemove(QuickSettingItem *quickItem)
void QuickSettingContainer::mousePressEvent(QMouseEvent *event)
{
if (event->button() != Qt::LeftButton)
return;
return QWidget::mousePressEvent(event);
QuickSettingItem *moveItem = qobject_cast<QuickSettingItem *>(childAt(event->pos()));
if (!moveItem || moveItem->pluginItem()->isPrimary())
return QWidget::mousePressEvent(event);
QDrag *drag = new QDrag(this);
CustomMimeData *mimedata = new CustomMimeData;
mimedata->setData(moveItem);
drag->setMimeData(mimedata);
QPixmap dragPixmap = moveItem->dragPixmap();
drag->setPixmap(dragPixmap);
drag->setHotSpot(QPoint(dragPixmap.width() / 2, dragPixmap.height() / 2));
m_dragPluginPosition = event->pos();
}
drag->exec(Qt::MoveAction | Qt::CopyAction);
void QuickSettingContainer::clearDragPoint()
{
m_dragPluginPosition.setX(0);
m_dragPluginPosition.setY(0);
}
void QuickSettingContainer::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event);
clearDragPoint();
}
void QuickSettingContainer::mouseMoveEvent(QMouseEvent *event)
{
if (m_dragPluginPosition.isNull())
return;
QuickSettingItem *moveItem = qobject_cast<QuickSettingItem *>(childAt(m_dragPluginPosition));
if (!moveItem) {
clearDragPoint();
return;
}
QPoint pointCurrent = event->pos();
if (qAbs(m_dragPluginPosition.x() - pointCurrent.x()) > 5
|| qAbs(m_dragPluginPosition.y() - pointCurrent.y()) > 5) {
clearDragPoint();
QDrag *drag = new QDrag(this);
QuickPluginMimeData *mimedata = new QuickPluginMimeData(moveItem);
drag->setMimeData(mimedata);
QPixmap dragPixmap = moveItem->dragPixmap();
drag->setPixmap(dragPixmap);
drag->setHotSpot(QPoint(dragPixmap.width() / 2, dragPixmap.height() / 2));
drag->exec(Qt::MoveAction | Qt::CopyAction);
}
}
void QuickSettingContainer::resetItemPosition()
@ -183,9 +266,8 @@ void QuickSettingContainer::resetItemPosition()
qSort(primaryQuickItems.begin(), primaryQuickItems.end(), [ = ](QuickSettingItem *item1, QuickSettingItem *item2) {
int index1 = existKeys.indexOf(item1->itemKey());
int index2 = existKeys.indexOf(item2->itemKey());
if (index1 >= 0 || index2 >= 0) {
if (index1 >= 0 || index2 >= 0)
return index1 < index2;
}
return true;
});
int primaryColumnCount = COLUMNCOUNT / 2;
@ -265,8 +347,8 @@ void QuickSettingContainer::initUi()
void QuickSettingContainer::initConnection()
{
connect(m_pluginLoader, &QuickSettingController::pluginInsert, this, &QuickSettingContainer::onPluginInsert);
connect(m_pluginLoader, &QuickSettingController::pluginRemove, this, &QuickSettingContainer::onPluginRemove);
connect(m_pluginLoader, &QuickSettingController::pluginInserted, this, &QuickSettingContainer::onPluginInsert);
connect(m_pluginLoader, &QuickSettingController::pluginRemoved, this, &QuickSettingContainer::onPluginRemove);
connect(m_playerWidget, &MediaWidget::visibleChanged, this, [ this ] { resizeView(); });
connect(m_volumnWidget, &VolumeWidget::visibleChanged, this, [ this ] { resizeView(); });
connect(m_volumnWidget, &VolumeWidget::rightIconClick, this, [ this ] {
@ -285,7 +367,6 @@ void QuickSettingContainer::initConnection()
if (!m_childPage->isBack())
topLevelWidget()->hide();
});
m_childPage->installEventFilter(this);
}
void QuickSettingContainer::resizeView()
@ -318,98 +399,3 @@ void QuickSettingContainer::resizeView()
setFixedHeight(m_childPage->height());
}
}
/**
* @brief PluginChildPage::PluginChildPage
* @param parent
*/
PluginChildPage::PluginChildPage(QWidget *parent)
: QWidget(parent)
, m_headerWidget(new QWidget(this))
, m_back(new QLabel(m_headerWidget))
, m_title(new QLabel(m_headerWidget))
, m_container(new QWidget(this))
, m_topWidget(nullptr)
, m_containerLayout(new QVBoxLayout(m_container))
, m_isBack(false)
{
initUi();
m_back->installEventFilter(this);
}
PluginChildPage::~PluginChildPage()
{
}
void PluginChildPage::pushWidget(QWidget *widget)
{
// 首先将界面其他的窗体移除
for (int i = m_containerLayout->count() - 1; i >= 0; i--) {
QLayoutItem *item = m_containerLayout->itemAt(i);
item->widget()->removeEventFilter(this);
item->widget()->hide();
m_containerLayout->removeItem(item);
}
m_topWidget = widget;
widget->installEventFilter(this);
m_containerLayout->addWidget(widget);
widget->show();
m_isBack = false;
QMetaObject::invokeMethod(this, &PluginChildPage::resetHeight, Qt::QueuedConnection);
}
void PluginChildPage::setTitle(const QString &text)
{
m_title->setText(text);
}
bool PluginChildPage::isBack()
{
return m_isBack;
}
void PluginChildPage::initUi()
{
m_back->setFixedWidth(24);
m_title->setAlignment(Qt::AlignCenter);
QHBoxLayout *headerLayout = new QHBoxLayout(m_headerWidget);
headerLayout->setContentsMargins(11, 12, 24 + 11, 12);
headerLayout->setSpacing(0);
headerLayout->addWidget(m_back);
headerLayout->addWidget(m_title);
m_headerWidget->setFixedHeight(48);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSpacing(0);
mainLayout->addWidget(m_headerWidget);
mainLayout->addWidget(m_container);
m_containerLayout->setContentsMargins(11, 0, 11, 0);
m_containerLayout->setSpacing(0);
}
bool PluginChildPage::eventFilter(QObject *watched, QEvent *event)
{
if (watched == m_back && event->type() == QEvent::MouseButtonRelease) {
m_isBack = true;
Q_EMIT back();
return true;
}
if (watched == m_topWidget) {
if (event->type() == QEvent::Hide) {
Q_EMIT closeSelf();
return true;
}
if (event->type() == QEvent::Resize)
resetHeight();
}
return QWidget::eventFilter(watched, event);
}
void PluginChildPage::resetHeight()
{
QMargins m = m_containerLayout->contentsMargins();
m_container->setFixedHeight(m.top() + m.bottom() + m_topWidget->height());
setFixedHeight(m_headerWidget->height() + m_container->height());
}

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QUICKSETTINGCONTAINER_H
#define QUICKSETTINGCONTAINER_H
@ -31,9 +51,13 @@ class QuickSettingContainer : public QWidget
public:
static DockPopupWindow *popWindow();
static void setPosition(Dock::Position position);
protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
explicit QuickSettingContainer(QWidget *parent = nullptr);
~QuickSettingContainer() override;
void showHomePage();
@ -57,8 +81,12 @@ private:
void initQuickItem(QuickSettingItem *quickItem);
// 显示具体的窗体
void showWidget(QWidget *widget, const QString &title);
// 清除移动轨迹
void clearDragPoint();
private:
static DockPopupWindow *m_popWindow;
static Dock::Position m_position;
QStackedLayout *m_switchLayout;
QWidget *m_mainWidget;
QWidget *m_pluginWidget;
@ -71,52 +99,20 @@ private:
VolumeDevicesWidget *m_volumeSettingWidget;
BrightnessMonitorWidget *m_brightSettingWidget;
PluginChildPage *m_childPage;
QPoint m_dragPluginPosition;
};
class CustomMimeData : public QMimeData
class QuickPluginMimeData : public QMimeData
{
Q_OBJECT
public:
CustomMimeData() : QMimeData(), m_data(nullptr) {}
~CustomMimeData() {}
void setData(void *data) { m_data = data; }
void *data() { return m_data; }
explicit QuickPluginMimeData(QuickSettingItem *item) : QMimeData(), m_item(item) {}
~QuickPluginMimeData() {}
QuickSettingItem *quickSettingItem() const { return m_item; }
private:
void *m_data;
};
class PluginChildPage : public QWidget
{
Q_OBJECT
Q_SIGNALS:
void back();
void closeSelf();
public:
explicit PluginChildPage(QWidget *parent);
~PluginChildPage() override;
void pushWidget(QWidget *widget);
void setTitle(const QString &text);
bool isBack();
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
private:
void initUi();
void resetHeight();
private:
QWidget *m_headerWidget;
QLabel *m_back;
QLabel *m_title;
QWidget *m_container;
QWidget *m_topWidget;
QVBoxLayout *m_containerLayout;
bool m_isBack;
QuickSettingItem *m_item;
};
#endif // PLUGINCONTAINER_H

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "systempluginwindow.h"
#include "systemplugincontroller.h"
#include "systempluginitem.h"
@ -110,7 +130,6 @@ int SystemPluginWindow::calcIconSize() const
if (height() <= 40)
return MINICONSIZE;
return height() - ICONMARGIN * 2;
break;
}
case Dock::Position::Left:
case Dock::Position::Right: {
@ -153,15 +172,12 @@ FixedPluginController::FixedPluginController(QObject *parent)
{
}
const QVariant FixedPluginController::getValue(PluginsItemInterface * const itemInter, const QString &key, const QVariant &fallback)
{
if (key == "enable")
return (itemInter->pluginName().compare("shutdown") == 0);
return AbstractPluginsController::getValue(itemInter, key, fallback);
}
PluginsItem *FixedPluginController::createPluginsItem(PluginsItemInterface * const itemInter, const QString &itemKey, const QString &pluginApi)
{
return new StretchPluginsItem(itemInter, itemKey, pluginApi);
}
bool FixedPluginController::needLoad(PluginsItemInterface *itemInter)
{
return (itemInter->pluginName().compare("shutdown") == 0);
}

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SYSTEMPLUGINWINDOW_H
#define SYSTEMPLUGINWINDOW_H
@ -18,15 +38,15 @@ class SystemPluginWindow : public DBlurEffectWidget
{
Q_OBJECT
Q_SIGNALS:
void pluginSizeChanged();
public:
explicit SystemPluginWindow(QWidget *parent = nullptr);
~SystemPluginWindow() override;
void setPositon(Dock::Position position);
QSize suitableSize();
Q_SIGNALS:
void pluginSizeChanged();
private:
void initUi();
int calcIconSize() const;
@ -49,11 +69,11 @@ class FixedPluginController : public DockPluginsController
Q_OBJECT
public:
FixedPluginController(QObject *parent);
explicit FixedPluginController(QObject *parent);
protected:
const QVariant getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback = QVariant()) override;
PluginsItem *createPluginsItem(PluginsItemInterface *const itemInter, const QString &itemKey, const QString &pluginApi) override;
bool needLoad(PluginsItemInterface *itemInter) override;
};
#endif // SYSTEMPLUGINWINDOW_H

View File

@ -28,18 +28,22 @@
#include "widgets/expandiconwidget.h"
#include "utils.h"
#include <DGuiApplicationHelper>
#include <QPointer>
#include <QDebug>
#include <QEvent>
#include <QKeyEvent>
#include <QApplication>
#include <QPainterPath>
#include <xcb/xcb_icccm.h>
#include <X11/Xlib.h>
TrayDelegate::TrayDelegate(QObject *parent)
TrayDelegate::TrayDelegate(QListView *view, QObject *parent)
: QStyledItemDelegate(parent)
, m_position(Dock::Position::Bottom)
, m_listView(view)
{
}
@ -65,7 +69,7 @@ QWidget *TrayDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem
int screenp = 0;
static xcb_connection_t *xcb_connection = xcb_connect(qgetenv("DISPLAY"), &screenp);
static Display *m_display = XOpenDisplay(nullptr);
trayWidget = new XEmbedTrayItemWidget(winId, xcb_connection, m_display, parent) ;
trayWidget = new XEmbedTrayItemWidget(winId, xcb_connection, m_display, parent);
}
const TrayModel *model = qobject_cast<const TrayModel *>(index.model());
@ -74,40 +78,53 @@ QWidget *TrayDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem
} else if (type == TrayIconType::SNI) {
trayWidget = new SNITrayItemWidget(servicePath, parent);
} else if (type == TrayIconType::EXPANDICON) {
ExpandIconWidget *widget = new ExpandIconWidget(parent);
widget->setPositonValue(m_position);
connect(widget, &ExpandIconWidget::trayVisbleChanged, this, [ = ](bool visible) {
ExpandIconWidget *expandWidget = new ExpandIconWidget(parent);
expandWidget->setPositonValue(m_position);
connect(expandWidget, &ExpandIconWidget::trayVisbleChanged, this, [ = ](bool visible) {
Q_EMIT visibleChanged(index, visible);
});
connect(this, &TrayDelegate::requestDrag, this, [ = ](bool on) {
if (on) {
widget->setTrayPanelVisible(true);
} else {
// 如果释放鼠标,则判断当前鼠标的位置是否在托盘内部,如果在,则无需隐藏
QPoint currentPoint = QCursor::pos();
TrayGridView *view = widget->popupTrayView();
if (view->geometry().contains(currentPoint))
widget->setTrayPanelVisible(true);
else
widget->setTrayPanelVisible(false);
}
});
trayWidget = widget;
connect(this, &TrayDelegate::requestDrag, this, &TrayDelegate::onRequestDrag);
trayWidget = expandWidget;
} else if (type == TrayIconType::INDICATOR) {
QString indicateName = key;
int flagIndex = indicateName.indexOf("indicator:");
if (flagIndex >= 0)
indicateName = indicateName.right(indicateName.length() - QString("indicator:").length());
IndicatorTrayItem *indicatorWidget = new IndicatorTrayItem(indicateName, parent);
connect(indicatorWidget, &IndicatorTrayItem::removed, this, [ = ]{
Q_EMIT removeRow(index);
});
TrayModel *dataModel = qobject_cast<TrayModel *>(m_listView->model());
if (IndicatorTrayItem *sourceIndicatorWidget = dataModel->indicatorWidget(key)) {
const QByteArray pixmapData = sourceIndicatorWidget->pixmapData();
if (!pixmapData.isEmpty())
indicatorWidget->setPixmapData(pixmapData);
const QString text = sourceIndicatorWidget->text();
if (!text.isEmpty())
indicatorWidget->setText(text);
}
trayWidget = indicatorWidget;
}
if (trayWidget)
trayWidget->setFixedSize(16, 16);
return trayWidget;
}
void TrayDelegate::onRequestDrag(bool on)
{
ExpandIconWidget *expandwidget = expandWidget();
if (!expandwidget)
return;
if (on) {
expandwidget->setTrayPanelVisible(true);
} else {
// 如果释放鼠标,则判断当前鼠标的位置是否在托盘内部,如果在,则无需隐藏
QPoint currentPoint = QCursor::pos();
QWidget *view = expandwidget->popupTrayView();
expandwidget->setTrayPanelVisible(view->geometry().contains(currentPoint));
}
}
void TrayDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
BaseTrayWidget *widget = static_cast<BaseTrayWidget *>(editor);
@ -128,5 +145,67 @@ void TrayDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewI
{
Q_UNUSED(index);
QRect rect = option.rect;
editor->setGeometry(rect.x() + ITEM_SPACING, rect.y() + ITEM_SPACING, ITEM_SIZE - (2 * ITEM_SPACING), ITEM_SIZE - 2 * ITEM_SPACING);
// 让控件居中显示
editor->setGeometry(rect.x() + (rect.width() - ICON_SIZE) / 2,
rect.y() + (rect.height() - ICON_SIZE) / 2,
ICON_SIZE, ICON_SIZE);
}
void TrayDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (needDrawBackground()) {
QColor borderColor;
QColor backColor;
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) {
// 白色主题的情况下
borderColor = Qt::black;
borderColor.setAlpha(static_cast<int>(255 * 0.05));
backColor = Qt::white;
backColor.setAlpha(static_cast<int>(255 * 0.4));
} else {
borderColor = Qt::black;
borderColor.setAlpha(static_cast<int>(255 * 0.2));
backColor = Qt::black;
backColor.setAlpha(static_cast<int>(255 * 0.4));
}
painter->save();
QPainterPath path;
path.addRoundedRect(option.rect, 8, 8);
painter->setRenderHint(QPainter::Antialiasing);
painter->fillPath(path, backColor);
painter->setPen(borderColor);
painter->drawPath(path);
painter->restore();
}
}
ExpandIconWidget *TrayDelegate::expandWidget()
{
if (!m_listView)
return nullptr;
QAbstractItemModel *dataModel = m_listView->model();
if (!dataModel)
return nullptr;
for (int i = 0; i < dataModel->rowCount() - 1; i++) {
QModelIndex index = dataModel->index(i, 0);
ExpandIconWidget *widget = qobject_cast<ExpandIconWidget *>(m_listView->indexWidget(index));
if (widget)
return widget;
}
return nullptr;
}
bool TrayDelegate::needDrawBackground() const
{
if (!m_listView)
return false;
TrayModel *dataModel = qobject_cast<TrayModel *>(m_listView->model());
if (!dataModel)
return false;
return dataModel->isIconTray();
}

View File

@ -26,31 +26,44 @@
#include <QStyledItemDelegate>
#define ITEM_SIZE 30
// 托盘图标固定16个像素
#define ICON_SIZE 16
#define ITEM_SPACING 5
struct WinInfo;
class ExpandIconWidget;
class QListView;
class TrayDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit TrayDelegate(QListView *view, QObject *parent = nullptr);
void setPositon(Dock::Position position);
Q_SIGNALS:
void removeRow(const QModelIndex &) const;
void visibleChanged(const QModelIndex &, bool) const;
void requestDrag(bool) const;
public:
explicit TrayDelegate(QObject *parent = nullptr);
void setPositon(Dock::Position position);
private Q_SLOTS:
void onRequestDrag(bool on);
protected:
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
void setEditorData(QWidget *editor, const QModelIndex &index) const override ;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
private:
ExpandIconWidget *expandWidget();
bool needDrawBackground() const;
private:
Dock::Position m_position;
QListView *m_listView;
};
#endif // TRAYDELEGATE_H

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tray_gridview.h"
#include <QMouseEvent>
@ -23,10 +43,66 @@ TrayGridView::TrayGridView(QWidget *parent)
, m_aniStartTime(new QTimer(this))
, m_pressed(false)
, m_aniRunning(false)
, m_positon(Dock::Position::Bottom)
{
initUi();
}
void TrayGridView::setPosition(Dock::Position position)
{
m_positon = position;
}
QSize TrayGridView::suitableSize() const
{
TrayModel *dataModel = qobject_cast<TrayModel *>(model());
if (!dataModel)
return QSize(-1, -1);
if (dataModel->isIconTray()) {
// 如果是托盘图标
int width = 2;
int height = 0;
int count = dataModel->rowCount();
if (count > 0) {
int columnCount = qMin(count, 3);
for (int i = 0; i < columnCount; i ++) {
QModelIndex index = dataModel->index(i, 0);
width += visualRect(index).width() + spacing() * 2; // 左右边距加上单元格宽度
}
int rowCount = count / 3;
if (count % 3 > 0)
rowCount++;
for (int i = 0; i < rowCount; i++) {
QModelIndex index = dataModel->index(i * 3);
height += visualRect(index).height() + spacing() * 2;
}
} else {
width = spacing() * 2 + 30;
height = spacing() * 2 + 30;
}
return QSize(width, height);
}
if (m_positon == Dock::Position::Top || m_positon == Dock::Position::Bottom) {
int length = spacing() + 2;
for (int i = 0; i < dataModel->rowCount(); i++) {
QModelIndex index = dataModel->index(i, 0);
QRect indexRect = visualRect(index);
length += indexRect.width() + spacing();
}
return QSize(length, -1);
}
int height = spacing() + 2;
for (int i = 0; i < dataModel->rowCount(); i++) {
QModelIndex index = dataModel->index(i, 0);
QRect indexRect = visualRect(index);
height += indexRect.height() + spacing();
}
return QSize(-1, height);
}
void TrayGridView::setDragDistance(int pixel)
{
m_dragDistance = pixel;
@ -171,6 +247,9 @@ void TrayGridView::mousePressEvent(QMouseEvent *e)
void TrayGridView::mouseMoveEvent(QMouseEvent *e)
{
if (!m_pressed)
return DListView::mouseMoveEvent(e);
setState(QAbstractItemView::NoState);
e->accept();
@ -181,15 +260,22 @@ void TrayGridView::mouseMoveEvent(QMouseEvent *e)
if (!index.isValid())
return DListView::mouseMoveEvent(e);
if (m_pressed && (qAbs(e->pos().x() - m_dragPos.x()) > m_dragDistance ||
// 如果当前拖动的位置是托盘展开按钮,则不让其拖动
TrayIconType iconType = index.data(TrayModel::Role::TypeRole).value<TrayIconType>();
if (iconType == TrayIconType::EXPANDICON)
return DListView::mouseMoveEvent(e);
if ((qAbs(e->pos().x() - m_dragPos.x()) > m_dragDistance ||
qAbs(e->pos().y() - m_dragPos.y()) > m_dragDistance)) {
qDebug() << "start drag";
beginDrag(Qt::CopyAction | Qt::MoveAction);
if (!beginDrag(Qt::CopyAction | Qt::MoveAction))
DListView::mouseMoveEvent(e);
}
}
void TrayGridView::mouseReleaseEvent(QMouseEvent *e)
{
Q_UNUSED(e);
m_pressed = false;
}
@ -198,7 +284,7 @@ void TrayGridView::dragEnterEvent(QDragEnterEvent *e)
const QModelIndex index = indexAt(e->pos());
if (model()->canDropMimeData(e->mimeData(), e->dropAction(), index.row(),
index.column(), QModelIndex()))
index.column(), index))
e->accept();
else
e->ignore();
@ -219,9 +305,13 @@ void TrayGridView::dragMoveEvent(QDragMoveEvent *e)
if (m_aniRunning)
return;
QModelIndex index = indexAt(e->pos());
if (!model()->canDropMimeData(e->mimeData(), e->dropAction(), index.row(),
index.column(), index))
return;
setState(QAbstractItemView::DraggingState);
QModelIndex index = indexAt(e->pos());
if (index.isValid()) {
if (m_dropPos != indexRect(index).center()) {
qDebug() << "update drop position: " << index.row();
@ -233,6 +323,43 @@ void TrayGridView::dragMoveEvent(QDragMoveEvent *e)
m_aniStartTime->start();
}
const QModelIndex TrayGridView::getIndexFromPos(QPoint currentPoint) const
{
QModelIndex index = indexAt(currentPoint);
if (index.isValid())
return index;
if (model()->rowCount() == 0)
return index;
// 如果在第一个之前,则认为拖到了第一个的位置
QRect indexRect0 = visualRect(model()->index(0, 0));
if (currentPoint.x() < indexRect0.x() || currentPoint.y() < indexRect0.y())
return model()->index(0, 0);
// 如果从指定的位置没有找到索引则依次从每个index中查找先横向查找
for (int i = 1; i < model()->rowCount(); i++) {
QModelIndex lastIndex = model()->index(i - 1, 0);
QModelIndex currentIndex = model()->index(i, 0);
QRect lastIndexRect = visualRect(lastIndex);
QRect indexRect = visualRect(currentIndex);
if (lastIndexRect.x() + lastIndexRect.width() <= currentPoint.x()
&& indexRect.x() >= currentPoint.x())
return currentIndex;
}
// 如果鼠标位置刚好在上下两个索引中间
for (int i = 0; i < model()->rowCount(); i++) {
QModelIndex currentIndex = model()->index(i, 0);
QRect indexRect = visualRect(currentIndex);
if (currentPoint.y() >= indexRect.y() - spacing() && currentPoint.y() < indexRect.y()
&& currentPoint.x() >= indexRect.x() - spacing() && currentPoint.x() < indexRect.x())
return currentIndex;
}
return QModelIndex();
}
void TrayGridView::dropEvent(QDropEvent *e)
{
setState(DListView::NoState);
@ -245,39 +372,45 @@ void TrayGridView::dropEvent(QDropEvent *e)
e->setDropAction(Qt::CopyAction);
e->accept();
TrayModel *m = qobject_cast<TrayModel *>(model());
if (m) {
TrayModel *dataModel = qobject_cast<TrayModel *>(model());
if (dataModel) {
WinInfo info;
info.type = static_cast<TrayIconType>(e->mimeData()->data("type").toInt());
info.key = static_cast<QString>(e->mimeData()->data("key"));
info.winId = static_cast<quint32>(e->mimeData()->data("winId").toInt());
info.servicePath = static_cast<QString>(e->mimeData()->data("servicePath"));
m->addRow(info);
QModelIndex targetIndex = getIndexFromPos(e->pos());
if (targetIndex.isValid() && targetIndex.row() < dataModel->rowCount() - 1) {
// 如果拖动的位置是合法的位置,则让其插入到当前的位置
dataModel->insertRow(targetIndex.row(), info);
} else {
// 在其他的情况下,让其插入到最后
dataModel->addRow(info);
}
}
} else {
e->ignore();
DListView::dropEvent(e);
}
DListView::dropEvent(e);
}
void TrayGridView::beginDrag(Qt::DropActions supportedActions)
bool TrayGridView::beginDrag(Qt::DropActions supportedActions)
{
QModelIndex modelIndex = indexAt(m_dragPos);
TrayIconType trayType = modelIndex.data(TrayModel::Role::TypeRole).value<TrayIconType>();
// 展开图标不能移动
if (trayType == TrayIconType::EXPANDICON)
return;
return false;
m_dropPos = indexRect(modelIndex).center();
TrayModel *listModel = qobject_cast<TrayModel *>(model());
if (!listModel)
return;
return false;
BaseTrayWidget *widget = qobject_cast<BaseTrayWidget *>(indexWidget(modelIndex));
if (!widget)
return;
return false;
auto pixmap = widget->icon();
@ -315,7 +448,7 @@ void TrayGridView::beginDrag(Qt::DropActions supportedActions)
Q_EMIT dragEntered();
if (dropAct == Qt::IgnoreAction) {
QPropertyAnimation *posAni = new QPropertyAnimation(pixLabel, "pos", pixLabel);
connect(posAni, &QPropertyAnimation::finished, [&, listModel, pixLabel] () {
connect(posAni, &QPropertyAnimation::finished, [ &, listModel, pixLabel ] () {
pixLabel->hide();
pixLabel->deleteLater();
listModel->setDragKey(QString());
@ -339,6 +472,8 @@ void TrayGridView::beginDrag(Qt::DropActions supportedActions)
Q_EMIT requestRemove(itemKey);
}
return true;
}
void TrayGridView::initUi()

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TRAYGRIDVIEW_H
#define TRAYGRIDVIEW_H
@ -14,8 +34,10 @@ class TrayGridView : public DListView
Q_OBJECT
public:
TrayGridView(QWidget *parent = Q_NULLPTR);
explicit TrayGridView(QWidget *parent = Q_NULLPTR);
void setPosition(Dock::Position position);
QSize suitableSize() const;
void setDragDistance(int pixel);
void setAnimationProperty(const QEasingCurve::Type easing, const int duringTime = 250);
void moveAnimation();
@ -40,11 +62,12 @@ protected:
void dragLeaveEvent(QDragLeaveEvent *e) Q_DECL_OVERRIDE;
void dragMoveEvent(QDragMoveEvent *e) Q_DECL_OVERRIDE;
void dropEvent(QDropEvent *e) Q_DECL_OVERRIDE;
void beginDrag(Qt::DropActions supportedActions);
bool beginDrag(Qt::DropActions supportedActions);
private:
void initUi();
void createAnimation(const int pos, const bool moveNext, const bool isLastAni);
const QModelIndex getIndexFromPos(QPoint currentPoint) const;
private:
QEasingCurve::Type m_aniCurveType;
@ -58,6 +81,7 @@ private:
QTimer *m_aniStartTime;
bool m_pressed;
bool m_aniRunning;
Dock::Position m_positon;
};
#endif // GRIDVIEW_H

View File

@ -1,4 +1,24 @@
#include "tray_model.h"
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tray_model.h"
#include "tray_monitor.h"
#include "indicatortrayitem.h"
@ -104,6 +124,16 @@ bool TrayModel::indexDragging(const QModelIndex &index) const
|| (start >= end && current <= start && current >= end);
}
IndicatorTrayItem *TrayModel::indicatorWidget(const QString &indicatorName) const
{
QString indicatorKey = indicatorName;
indicatorKey = indicatorKey.remove(0, QString("indicator:").length());
if (m_indicatorMap.contains(indicatorKey))
return m_indicatorMap.value(indicatorKey)->widget();
return nullptr;
}
QMimeData *TrayModel::mimeData(const QModelIndexList &indexes) const
{
Q_ASSERT(indexes.size() == 1);
@ -132,7 +162,7 @@ QVariant TrayModel::data(const QModelIndex &index, int role) const
return QVariant();
int itemIndex = index.row();
auto info = m_winInfos.at(itemIndex);
const WinInfo &info = m_winInfos[itemIndex];
switch (role) {
case Role::TypeRole:
@ -170,7 +200,10 @@ bool TrayModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, in
Q_UNUSED(action)
Q_UNUSED(row)
Q_UNUSED(column)
Q_UNUSED(parent)
TrayIconType iconType = parent.data(TrayModel::Role::TypeRole).value<TrayIconType>();
if (iconType == TrayIconType::EXPANDICON)
return false;
return data->formats().contains(TRAY_DRAG_FALG);
}
@ -186,7 +219,6 @@ Qt::ItemFlags TrayModel::flags(const QModelIndex &index) const
int TrayModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_winInfos.size();
}
@ -204,7 +236,7 @@ void TrayModel::clear()
void TrayModel::onXEmbedTrayAdded(quint32 winId)
{
for (auto info : m_winInfos) {
for (const WinInfo &info : m_winInfos) {
if (info.winId == winId)
return;
}
@ -260,7 +292,7 @@ QString TrayModel::fileNameByServiceName(const QString &serviceName)
bool TrayModel::isTypeWriting(const QString &servicePath)
{
const QString appFilePath = fileNameByServiceName(servicePath);
return appFilePath.startsWith("/usr/bin/fcitx");
return (appFilePath.startsWith("/usr/bin/fcitx") || appFilePath.endsWith("chinime-qim"));
}
void TrayModel::onSniTrayAdded(const QString &servicePath)
@ -304,7 +336,7 @@ void TrayModel::onSniTrayAdded(const QString &servicePath)
void TrayModel::onSniTrayRemoved(const QString &servicePath)
{
for (WinInfo info : m_winInfos) {
for (const WinInfo &info : m_winInfos) {
if (info.servicePath == servicePath) {
int index = m_winInfos.indexOf(info);
@ -356,7 +388,7 @@ void TrayModel::onIndicatorFounded(const QString &indicatorName)
void TrayModel::onIndicatorAdded(const QString &indicatorName)
{
const QString &itemKey = IndicatorTrayItem::toIndicatorKey(indicatorName);
for (auto info : m_winInfos) {
for (const WinInfo &info : m_winInfos) {
if (info.key == itemKey)
return;
}
@ -377,7 +409,7 @@ void TrayModel::onIndicatorRemoved(const QString &indicatorName)
void TrayModel::removeRow(const QString &itemKey)
{
for (auto info : m_winInfos) {
for (const WinInfo &info : m_winInfos) {
if (info.key == itemKey) {
int index = m_winInfos.indexOf(info);
beginRemoveRows(QModelIndex(), index, index);
@ -390,8 +422,8 @@ void TrayModel::removeRow(const QString &itemKey)
void TrayModel::addRow(WinInfo info)
{
for (auto i : m_winInfos) {
if (i.key == info.key)
for (const WinInfo &winInfo : m_winInfos) {
if (winInfo.key == info.key)
return;
}
@ -400,10 +432,26 @@ void TrayModel::addRow(WinInfo info)
endInsertRows();
}
void TrayModel::insertRow(int index, WinInfo info)
{
for (int i = 0; i < m_winInfos.size(); i++) {
const WinInfo &wininfo = m_winInfos[i];
if (wininfo.key == info.key) {
beginResetModel();
m_winInfos.swap(index, i);
endResetModel();
return;
}
}
beginInsertRows(QModelIndex(), index, index);
m_winInfos.insert(index, info);
endInsertRows();
}
bool TrayModel::exist(const QString &itemKey)
{
for (auto w : m_winInfos) {
if (w.key == itemKey)
for (const WinInfo &winInfo : m_winInfos) {
if (winInfo.key == itemKey)
return true;
}

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TRAYMODEL_H
#define TRAYMODEL_H
@ -7,6 +27,7 @@
class TrayMonitor;
class IndicatorPlugin;
class IndicatorTrayItem;
enum TrayIconType {
UNKNOW,
@ -23,13 +44,12 @@ struct WinInfo {
QString servicePath;
bool isTypeWriting;
WinInfo() {
type = UNKNOW;
key = QString();
winId = 0;
servicePath = QString();
isTypeWriting = false;
}
WinInfo() : type(UNKNOW)
, key(QString())
, winId(0)
, servicePath(QString())
, isTypeWriting(false) {}
bool operator==(const WinInfo &other) {
return this->type == other.type
&& this->key == other.key
@ -67,19 +87,22 @@ public:
bool indexDragging(const QModelIndex &index) const;
IndicatorTrayItem *indicatorWidget(const QString &indicatorName) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
bool isIconTray();
void clear();
public Q_SLOTS:
void removeRow(const QString &itemKey);
void addRow(WinInfo info);
Q_SIGNALS:
void requestUpdateIcon(quint32);
void requestUpdateWidget(const QList<int> &);
public Q_SLOTS:
void removeRow(const QString &itemKey);
void addRow(WinInfo info);
void insertRow(int index, WinInfo info);
private Q_SLOTS:
void onXEmbedTrayAdded(quint32 winId);
void onXEmbedTrayRemoved(quint32 winId);

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tray_monitor.h"
TrayMonitor::TrayMonitor(QObject *parent)

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TRAYMONITOR_H
#define TRAYMONITOR_H
@ -14,12 +34,6 @@ class TrayMonitor : public QObject
public:
explicit TrayMonitor(QObject *parent = nullptr);
public Q_SLOTS:
void onTrayIconsChanged();
void onSniItemsChanged();
void startLoadIndicators();
Q_SIGNALS:
void requestUpdateIcon(quint32);
void xEmbedTrayAdded(quint32);
@ -30,6 +44,12 @@ Q_SIGNALS:
void indicatorFounded(const QString &);
public Q_SLOTS:
void onTrayIconsChanged();
void onSniItemsChanged();
void startLoadIndicators();
private:
DBusTrayManager *m_trayInter;
StatusNotifierWatcher *m_sniWatcher;

View File

@ -1,9 +1,9 @@
/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: sbw <sbw@sbw.so>
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -18,7 +18,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "constants.h"
#include "basetraywidget.h"
@ -40,7 +39,6 @@ BaseTrayWidget::BaseTrayWidget(QWidget *parent, Qt::WindowFlags f)
BaseTrayWidget::~BaseTrayWidget()
{
}
void BaseTrayWidget::mousePressEvent(QMouseEvent *event)
@ -60,7 +58,6 @@ void BaseTrayWidget::mousePressEvent(QMouseEvent *event)
void BaseTrayWidget::mouseReleaseEvent(QMouseEvent *e)
{
//e->accept();
// 由于 XWindowTrayWidget 中对 发送鼠标事件到X窗口的函数, 如 sendClick/sendHoverEvent 中
// 使用了 setX11PassMouseEvent, 而每次调用 setX11PassMouseEvent 时都会导致产生 mousePress 和 mouseRelease 事件
// 因此如果直接在这里处理事件会导致一些问题, 所以使用 Timer 来延迟处理 100 毫秒内的最后一个事件

View File

@ -1,9 +1,9 @@
/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: sbw <sbw@sbw.so>
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -18,7 +18,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QWidget>

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "expandiconwidget.h"
#include "tray_gridview.h"
#include "tray_model.h"
@ -6,7 +26,9 @@
#include <DGuiApplicationHelper>
#include <DRegionMonitor>
#include <QBitmap>
#include <QPainter>
#include <QPainterPath>
#include <xcb/xproto.h>
@ -16,17 +38,25 @@ ExpandIconWidget::ExpandIconWidget(QWidget *parent, Qt::WindowFlags f)
: BaseTrayWidget(parent, f)
, m_regionInter(new DRegionMonitor(this))
, m_position(Dock::Position::Bottom)
, m_trayView(nullptr)
, m_gridParentView(new RoundWidget(nullptr))
, m_trayView(new TrayGridView(m_gridParentView))
, m_trayDelegate(new TrayDelegate(m_trayView, m_trayView))
, m_trayModel(new TrayModel(m_trayView, true, false))
{
connect(m_regionInter, &DRegionMonitor::buttonPress, this, &ExpandIconWidget::onGlobMousePress);
initUi();
initConnection();
}
ExpandIconWidget::~ExpandIconWidget()
{
m_gridParentView->deleteLater();
}
void ExpandIconWidget::setPositonValue(Dock::Position position)
{
if (m_position == position)
return;
m_position = position;
}
@ -38,19 +68,17 @@ void ExpandIconWidget::sendClick(uint8_t mouseButton, int x, int y)
if (mouseButton != XCB_BUTTON_INDEX_1)
return;
TrayGridView *trayIcon = popupTrayView();
setTrayPanelVisible(!trayIcon->isVisible());
setTrayPanelVisible(!m_gridParentView->isVisible());
}
void ExpandIconWidget::setTrayPanelVisible(bool visible)
{
TrayGridView *trayIcon = popupTrayView();
if (visible) {
resetPosition();
trayIcon->show();
m_gridParentView->show();
m_regionInter->registerRegion();
} else {
trayIcon->hide();
m_gridParentView->hide();
m_regionInter->unregisterRegion();
}
}
@ -98,42 +126,9 @@ const QString ExpandIconWidget::dropIconFile() const
return iconFile + ".svg";
}
TrayGridView *ExpandIconWidget::popupTrayView()
QWidget *ExpandIconWidget::popupTrayView()
{
if (m_trayView)
return m_trayView;
m_trayView = new TrayGridView(nullptr);
TrayModel *model = new TrayModel(m_trayView, true, false);
TrayDelegate *trayDelegate = new TrayDelegate(m_trayView);
m_trayView->setWindowFlags(Qt::FramelessWindowHint | Qt::Popup);
m_trayView->setModel(model);
m_trayView->setItemDelegate(trayDelegate);
m_trayView->setSpacing(3);
m_trayView->setDragDistance(5);
connect(m_trayView, &TrayGridView::rowCountChanged, this, [ this ] {
int count = m_trayView->model()->rowCount();
if (count > 0) {
int lineCount = (count % 3) != 0 ? (count / 3 + 1) : (count / 3);
// 如果只有一行,则根据实际的数量显示宽度
int columnCount = qMin(count, 3);
int width = ITEM_SIZE * columnCount + m_trayView->spacing() * 2;;
int height = lineCount * ITEM_SIZE + m_trayView->spacing() * (lineCount - 1) + ITEM_SPACING;
m_trayView->setFixedSize(width, height);
resetPosition();
} else if (m_trayView->isVisible()) {
m_trayView->hide();
}
Q_EMIT trayVisbleChanged(count > 0);
});
connect(trayDelegate, &TrayDelegate::removeRow, this, [ = ](const QModelIndex &index) {
QAbstractItemModel *abModel = model;
abModel->removeRow(index.row(),index.parent());
});
connect(m_trayView, &TrayGridView::requestRemove, model, &TrayModel::removeRow);
return m_trayView;
return m_gridParentView;
}
void ExpandIconWidget::resetPosition()
@ -141,27 +136,122 @@ void ExpandIconWidget::resetPosition()
if (!parentWidget())
return;
TrayGridView *trayView = popupTrayView();
QPoint ptPos = parentWidget()->mapToGlobal(this->pos());
ptPos.setY(ptPos.y() - trayView->height());
ptPos.setX(ptPos.x() - trayView->width());
trayView->move(ptPos);
switch (m_position) {
case Dock::Position::Bottom: {
ptPos.setY(ptPos.y() - m_gridParentView->height());
ptPos.setX(ptPos.x() - m_gridParentView->width());
break;
}
case Dock::Position::Top: {
ptPos.setY(ptPos.y() + m_gridParentView->height());
ptPos.setX(ptPos.x() - m_gridParentView->width());
break;
}
case Dock::Position::Left: {
ptPos.setX(ptPos.x() + m_gridParentView->width() / 2);
break;
}
case Dock::Position::Right: {
ptPos.setX(ptPos.x() - m_gridParentView->width() / 2);
break;
}
}
m_gridParentView->move(ptPos);
}
void ExpandIconWidget::initUi()
{
m_gridParentView->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
m_trayView->setModel(m_trayModel);
m_trayView->setItemDelegate(m_trayDelegate);
m_trayView->setSpacing(ITEM_SPACING);
m_trayView->setDragDistance(2);
QVBoxLayout *layout = new QVBoxLayout(m_gridParentView);
layout->setContentsMargins(ITEM_SPACING, ITEM_SPACING, ITEM_SPACING, ITEM_SPACING);
layout->setSpacing(0);
layout->addWidget(m_trayView);
}
void ExpandIconWidget::initConnection()
{
connect(m_trayView, &TrayGridView::rowCountChanged, this, &ExpandIconWidget::onRowCountChanged);
connect(m_trayDelegate, &TrayDelegate::removeRow, this, [ = ](const QModelIndex &index) {
m_trayView->model()->removeRow(index.row(),index.parent());
});
connect(m_trayView, &TrayGridView::requestRemove, m_trayModel, &TrayModel::removeRow);
connect(m_regionInter, &DRegionMonitor::buttonPress, this, &ExpandIconWidget::onGlobMousePress);
QMetaObject::invokeMethod(this, &ExpandIconWidget::onRowCountChanged, Qt::QueuedConnection);
}
void ExpandIconWidget::onRowCountChanged()
{
int count = m_trayModel->rowCount();
m_trayView->setFixedSize(m_trayView->suitableSize());
m_gridParentView->setFixedSize(m_trayView->size() + QSize(ITEM_SPACING * 2, ITEM_SPACING * 2));
if (count > 0)
resetPosition();
else if (m_gridParentView->isVisible())
m_gridParentView->hide();
Q_EMIT trayVisbleChanged(count > 0);
}
void ExpandIconWidget::onGlobMousePress(const QPoint &mousePos, const int flag)
{
if (!isVisible() || !((flag == DRegionMonitor::WatchedFlags::Button_Left) || (flag == DRegionMonitor::WatchedFlags::Button_Right)))
// 如果当前是隐藏,那么在点击任何地方都隐藏
if (!isVisible()) {
m_gridParentView->hide();
return;
}
if ((flag != DRegionMonitor::WatchedFlags::Button_Left) && (flag != DRegionMonitor::WatchedFlags::Button_Right))
return;
TrayGridView *trayView = popupTrayView();
QPoint ptPos = parentWidget()->mapToGlobal(this->pos());
const QRect rect = QRect(ptPos, size());
if (rect.contains(mousePos))
return;
const QRect rctView(trayView->pos(), trayView->size());
const QRect rctView(m_gridParentView->pos(), m_gridParentView->size());
if (rctView.contains(mousePos))
return;
trayView->hide();
m_gridParentView->hide();
}
/**
* @brief
* @param parent
*/
RoundWidget::RoundWidget(QWidget *parent)
: QWidget (parent)
, m_dockInter(new DBusDock("com.deepin.dde.daemon.Dock", "/com/deepin/dde/daemon/Dock", QDBusConnection::sessionBus(), this))
{
setAttribute(Qt::WA_TranslucentBackground);
}
void RoundWidget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
path.addRoundedRect(rect(), 18, 18);
painter.setCompositionMode(QPainter::CompositionMode_Xor);
painter.setClipPath(path);
painter.fillPath(path, maskColor());
}
QColor RoundWidget::maskColor() const
{
QColor color = DGuiApplicationHelper::standardPalette(DGuiApplicationHelper::instance()->themeType()).window().color();
int maskAlpha(static_cast<int>(255 * m_dockInter->opacity()));
color.setAlpha(maskAlpha);
return color;
}

View File

@ -1,11 +1,36 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EXPANDICONWIDGET_H
#define EXPANDICONWIDGET_H
#include "constants.h"
#include "basetraywidget.h"
#include <com_deepin_dde_daemon_dock.h>
class TrayGridView;
class TrayModel;
class TrayDelegate;
using DBusDock = com::deepin::dde::daemon::Dock;
namespace Dtk { namespace Gui { class DRegionMonitor; } }
@ -13,9 +38,6 @@ class ExpandIconWidget : public BaseTrayWidget
{
Q_OBJECT
Q_SIGNALS:
void trayVisbleChanged(bool);
public:
explicit ExpandIconWidget(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
~ExpandIconWidget() override;
@ -26,10 +48,14 @@ public:
QString itemKeyForConfig() override { return "Expand"; }
void updateIcon() override {}
QPixmap icon() override;
TrayGridView *popupTrayView();
QWidget *popupTrayView();
Q_SIGNALS:
void trayVisbleChanged(bool);
private Q_SLOTS:
void onGlobMousePress(const QPoint &mousePos, const int flag);
void onRowCountChanged();
protected:
void paintEvent(QPaintEvent *e) override;
@ -37,10 +63,35 @@ protected:
void resetPosition();
private:
void initUi();
void initConnection();
private:
Dtk::Gui::DRegionMonitor *m_regionInter;
Dock::Position m_position;
QWidget *m_gridParentView;
TrayGridView *m_trayView;
TrayDelegate *m_trayDelegate;
TrayModel *m_trayModel;
};
// 绘制圆角窗体
class RoundWidget : public QWidget
{
Q_OBJECT
public:
explicit RoundWidget(QWidget *parent);
protected:
void paintEvent(QPaintEvent *event) override;
private:
QColor maskColor() const;
private:
DBusDock *m_dockInter;
};
#endif // EXPANDICONWIDGET_H

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "indicatorplugin.h"
#include <QLabel>
@ -148,17 +168,11 @@ void IndicatorPluginPrivate::initDBus(const QString &indicatorName)
if (data.contains("text")) {
featData("text", data, SLOT(textPropertyChanged(QDBusMessage)), [ = ](QVariant v) {
#ifdef QT_DEBUG // TODO
if (!v.toString().isEmpty()) {
#else
if (v.toString().isEmpty()) {
#endif
Q_EMIT q->removed();
return;
}
else {
Q_EMIT q->delayLoaded();
}
Q_EMIT q->delayLoaded();
indicatorTrayWidget->setText(v.toString());
updateContent();
});
@ -170,9 +184,7 @@ void IndicatorPluginPrivate::initDBus(const QString &indicatorName)
Q_EMIT q->removed();
return;
}
else {
Q_EMIT q->delayLoaded();
}
Q_EMIT q->delayLoaded();
indicatorTrayWidget->setPixmapData(v.toByteArray());
updateContent();
});
@ -181,7 +193,7 @@ void IndicatorPluginPrivate::initDBus(const QString &indicatorName)
const QJsonObject action = config.value("action").toObject();
if (!action.isEmpty() && indicatorTrayWidget)
q->connect(indicatorTrayWidget, &IndicatorTrayItem::clicked, q, [ = ](uint8_t button_index, int x, int y) {
/*std::thread t([=]() -> void {
std::thread t([ = ] ()-> void {
auto triggerConfig = action.value("trigger").toObject();
auto dbusService = triggerConfig.value("dbus_service").toString();
auto dbusPath = triggerConfig.value("dbus_path").toString();
@ -192,14 +204,9 @@ void IndicatorPluginPrivate::initDBus(const QString &indicatorName)
QDBusInterface interface(dbusService, dbusPath, dbusInterface, bus);
QDBusReply<void> reply = interface.call(methodName, button_index, x, y);
if (!reply.isValid()) {
qDebug() << interface.call(methodName);
}
else {
qDebug() << reply.error();
}
qDebug() << (reply.isValid() ? reply.error() : interface.call(methodName));
});
t.detach();*/
t.detach();
});
});
}

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "indicatortrayitem.h"

View File

@ -20,7 +20,6 @@
*/
#include "indicatortrayitem.h"
//#include "util/utils.h"
#include <QLabel>
#include <QBoxLayout>
@ -39,7 +38,6 @@
IndicatorTrayItem::IndicatorTrayItem(const QString &indicatorName, QWidget *parent, Qt::WindowFlags f)
: BaseTrayWidget(parent, f)
, m_indicatorName(indicatorName)
// , m_gsettings(Utils::ModuleSettingsPtr("keyboard", QByteArray(), this))
, m_enableClick(true)
{
setAttribute(Qt::WA_TranslucentBackground);
@ -66,15 +64,6 @@ IndicatorTrayItem::IndicatorTrayItem(const QString &indicatorName, QWidget *pare
interface,
this,
QDBusConnection::ExportScriptableSlots);
initDBus(m_indicatorName);
// if (m_gsettings) {
// // 显示键盘布局时更新label的状态
// if (m_gsettings->keys().contains("itemEnable"))
// enableLabel(m_gsettings->get("itemEnable").toBool());
// connect(m_gsettings, &QGSettings::changed, this, &IndicatorTrayWidget::onGSettingsChanged);
// }
}
IndicatorTrayItem::~IndicatorTrayItem()
@ -121,8 +110,19 @@ QPixmap IndicatorTrayItem::icon()
return QPixmap();
}
const QByteArray &IndicatorTrayItem::pixmapData() const
{
return m_pixmapData;
}
const QString IndicatorTrayItem::text() const
{
return m_label->text();
}
void IndicatorTrayItem::setPixmapData(const QByteArray &data)
{
m_pixmapData = data;
auto rawPixmap = QPixmap::fromImage(QImage::fromData(data));
rawPixmap.setDevicePixelRatio(devicePixelRatioF());
m_label->setPixmap(rawPixmap);
@ -132,127 +132,3 @@ void IndicatorTrayItem::setText(const QString &text)
{
m_label->setText(text);
}
void IndicatorTrayItem::onGSettingsChanged(const QString &key)
{
Q_UNUSED(key);
// if (m_gsettings && m_gsettings->keys().contains("itemEnable")) {
// const bool itemEnable = m_gsettings->get("itemEnable").toBool();
// enableLabel(itemEnable);
// }
}
template<typename Func>
void IndicatorTrayItem::featData(const QString &key,
const QJsonObject &data,
const char *propertyChangedSlot,
Func const &callback)
{
auto dataConfig = data.value(key).toObject();
auto dbusService = dataConfig.value("dbus_service").toString();
auto dbusPath = dataConfig.value("dbus_path").toString();
auto dbusInterface = dataConfig.value("dbus_interface").toString();
auto isSystemBus = dataConfig.value("system_dbus").toBool(false);
auto bus = isSystemBus ? QDBusConnection::systemBus() : QDBusConnection::sessionBus();
QDBusInterface interface(dbusService, dbusPath, dbusInterface, bus, this);
if (dataConfig.contains("dbus_method")) {
QString methodName = dataConfig.value("dbus_method").toString();
auto ratio = qApp->devicePixelRatio();
QDBusReply<QByteArray> reply = interface.call(methodName.toStdString().c_str(), ratio);
callback(reply.value());
}
qInfo() << dataConfig;
if (dataConfig.contains("dbus_properties")) {
auto propertyName = dataConfig.value("dbus_properties").toString();
auto propertyNameCStr = propertyName.toStdString();
//propertyInterfaceNames.insert(key, dbusInterface);
//propertyNames.insert(key, QString::fromStdString(propertyNameCStr));
QDBusConnection::sessionBus().connect(dbusService,
dbusPath,
"org.freedesktop.DBus.Properties",
"PropertiesChanged",
"sa{sv}as",
this,
propertyChangedSlot);
// FIXME(sbw): hack for qt dbus property changed signal.
// see: https://bugreports.qt.io/browse/QTBUG-48008
QDBusConnection::sessionBus().connect(dbusService,
dbusPath,
dbusInterface,
QString("%1Changed").arg(propertyName),
"s",
this,
propertyChangedSlot);
qInfo() << dbusService << dbusPath << dbusInterface;
qInfo() << propertyName << propertyNameCStr.c_str();
callback(interface.property(propertyNameCStr.c_str()));
}
}
void IndicatorTrayItem::initDBus(const QString &indicatorName)
{
QString filepath = QString("/etc/dde-dock/indicator/%1.json").arg(indicatorName);
QFile confFile(filepath);
if (!confFile.open(QIODevice::ReadOnly)) {
qInfo() << "read indicator config Error";
}
QJsonDocument doc = QJsonDocument::fromJson(confFile.readAll());
confFile.close();
QJsonObject config = doc.object();
auto delay = config.value("delay").toInt(0);
QTimer::singleShot(delay, [ = ]() {
QJsonObject data = config.value("data").toObject();
if (data.contains("text")) {
featData("text", data, SLOT(textPropertyChanged(QDBusMessage)), [ = ](QVariant v) {
if (v.toString().isEmpty()) {
Q_EMIT removed();
return;
}
Q_EMIT delayLoaded();
setText(v.toString());
//updateContent();
});
}
if (data.contains("icon")) {
featData("icon", data, SLOT(iconPropertyChanged(QDBusMessage)), [ = ](QVariant v) {
if (v.toByteArray().isEmpty()) {
Q_EMIT removed();
return;
}
Q_EMIT delayLoaded();
setPixmapData(v.toByteArray());
//updateContent();
});
}
const QJsonObject action = config.value("action").toObject();
if (!action.isEmpty())
connect(this, &IndicatorTrayItem::clicked, this, [ = ](uint8_t button_index, int x, int y) {
std::thread t([=]() -> void {
auto triggerConfig = action.value("trigger").toObject();
auto dbusService = triggerConfig.value("dbus_service").toString();
auto dbusPath = triggerConfig.value("dbus_path").toString();
auto dbusInterface = triggerConfig.value("dbus_interface").toString();
auto methodName = triggerConfig.value("dbus_method").toString();
auto isSystemBus = triggerConfig.value("system_dbus").toBool(false);
auto bus = isSystemBus ? QDBusConnection::systemBus() : QDBusConnection::sessionBus();
QDBusInterface interface(dbusService, dbusPath, dbusInterface, bus);
interface.call(methodName, button_index, x, y);
});
t.detach();
});
});
}

View File

@ -32,10 +32,6 @@ class IndicatorTrayItem: public BaseTrayWidget
{
Q_OBJECT
Q_SIGNALS:
void removed();
void delayLoaded();
public:
explicit IndicatorTrayItem(const QString &indicatorName, QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
~IndicatorTrayItem() override;
@ -47,27 +43,20 @@ public:
static QString toIndicatorKey(const QString &indicatorName) { return QString("indicator:%1").arg(indicatorName); }
static bool isIndicatorKey(const QString &itemKey) { return itemKey.startsWith("indicator:"); }
QPixmap icon() override;
const QByteArray &pixmapData() const;
const QString text() const;
public Q_SLOTS:
Q_SCRIPTABLE void setPixmapData(const QByteArray &data);
Q_SCRIPTABLE void setText(const QString &text);
private slots:
void onGSettingsChanged(const QString &key);
private:
void initDBus(const QString &indicatorName);
template<typename Func>
void featData(const QString &key, const QJsonObject &data, const char *propertyChangedSlot, Func const &callback);
Q_SIGNALS:
void clicked(uint8_t, int, int);
private:
QLabel *m_label;
QString m_indicatorName;
// const QGSettings *m_gsettings;
bool m_enableClick; // 置灰时设置为false不触发click信号
QByteArray m_pixmapData;
};

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "traymanagerwindow.h"
#include "quickpluginwindow.h"
#include "tray_gridview.h"
@ -33,7 +53,9 @@ TrayManagerWindow::TrayManagerWindow(QWidget *parent)
, m_mainLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight, this))
, m_trayView(new TrayGridView(this))
, m_model(new TrayModel(m_trayView, false, true))
, m_delegate(new TrayDelegate(m_trayView, m_trayView))
, m_postion(Dock::Position::Bottom)
, m_splitLine(new QLabel(m_appPluginDatetimeWidget))
{
initUi();
initConnection();
@ -52,42 +74,48 @@ void TrayManagerWindow::setPositon(Dock::Position position)
return;
m_postion = position;
if (position == Dock::Position::Top || position == Dock::Position::Bottom)
m_trayView->setOrientation(QListView::Flow::LeftToRight, false);
else
m_trayView->setOrientation(QListView::Flow::TopToBottom, false);
QModelIndex index = m_model->index(0, 0);
m_trayView->closePersistentEditor(index);
TrayDelegate *delegate = static_cast<TrayDelegate *>(m_trayView->itemDelegate());
delegate->setPositon(position);
m_trayView->openPersistentEditor(index);
m_trayView->setPosition(position);
m_quickIconWidget->setPositon(position);
m_dateTimeWidget->setPositon(position);
m_systemPluginWidget->setPositon(position);
QTimer::singleShot(0, this, [ this ]{
QMetaObject::invokeMethod(this, [ this ]{
if (showSingleRow())
resetSingleDirection();
else
resetMultiDirection();
resetChildWidgetSize();
});
}, Qt::QueuedConnection);
}
int TrayManagerWindow::appDatetimeSize()
{
int count = m_trayView->model()->rowCount();
if (m_postion == Dock::Position::Top || m_postion == Dock::Position::Bottom) {
QMargins m = m_appDatetimeLayout->contentsMargins();
int trayWidth = count * ITEM_SIZE + m_trayView->spacing() * (count - 1) + 5;
int topWidth = trayWidth + m_quickIconWidget->suitableSize().width() + m.left() + m.right() + m_appPluginLayout->spacing();
int spacing = m.left() + m.right() + m_appPluginLayout->spacing();
if (m_appDatetimeLayout->direction() == QBoxLayout::Direction::LeftToRight)
return topWidth + m_appDatetimeLayout->spacing() + m_dateTimeWidget->suitableSize().width() + m_appDatetimeLayout->spacing() + 10;
// 如果是一行
if (m_appDatetimeLayout->direction() == QBoxLayout::Direction::LeftToRight) {
return m_trayView->suitableSize().width() + m_quickIconWidget->suitableSize().width()
+ m_dateTimeWidget->suitableSize().width();
}
//如果是两行
int topWidth = m_trayView->suitableSize().width() + m_quickIconWidget->width();
int bottomWidth = m_dateTimeWidget->suitableSize().width();
return (topWidth > bottomWidth ? topWidth : bottomWidth) + m_appDatetimeLayout->spacing() + spacing + 10;
return qMax(topWidth, bottomWidth);
}
int trayHeight = count * ITEM_SIZE + m_trayView->spacing() * (count - 1) + 5;
int trayHeight = m_trayView->suitableSize().height();
int datetimeHeight = m_dateTimeWidget->suitableSize().height();
QMargins m = m_appDatetimeLayout->contentsMargins();
int traypluginHeight = trayHeight + m_quickIconWidget->suitableSize().height() + m.top() + m.bottom() + m_appPluginLayout->spacing();
@ -124,9 +152,17 @@ void TrayManagerWindow::resizeEvent(QResizeEvent *event)
void TrayManagerWindow::initUi()
{
TrayDelegate *delegate = new TrayDelegate(m_trayView);
m_trayView->setModel(m_model);
m_trayView->setItemDelegate(delegate);
m_trayView->setItemDelegate(m_delegate);
m_trayView->setDragDistance(2);
m_splitLine->setFixedHeight(1);
QPalette pal;
QColor lineColor(Qt::black);
lineColor.setAlpha(static_cast<int>(255 * 0.2));
pal.setColor(QPalette::Background, lineColor);
m_splitLine->setAutoFillBackground(true);
m_splitLine->setPalette(pal);
WinInfo info;
info.type = TrayIconType::EXPANDICON;
@ -139,6 +175,7 @@ void TrayManagerWindow::initUi()
m_appPluginDatetimeWidget->setMaskAlpha(uint8_t(0.1 * 255));
m_appPluginDatetimeWidget->installEventFilter(this);
m_appPluginLayout->setContentsMargins(0, 0, 0, 0);
m_appPluginLayout->setSpacing(0);
m_appPluginWidget->setLayout(m_appPluginLayout);
m_appPluginLayout->addWidget(m_trayView);
@ -146,8 +183,9 @@ void TrayManagerWindow::initUi()
m_appPluginDatetimeWidget->setLayout(m_appDatetimeLayout);
m_appDatetimeLayout->setContentsMargins(0, 0, 0, 0);
m_appDatetimeLayout->setSpacing(3);
m_appDatetimeLayout->setSpacing(0);
m_appDatetimeLayout->addWidget(m_appPluginWidget);
m_appDatetimeLayout->addWidget(m_splitLine);
m_appDatetimeLayout->addWidget(m_dateTimeWidget);
m_systemPluginWidget->setBlurRectXRadius(10);
@ -157,7 +195,7 @@ void TrayManagerWindow::initUi()
setLayout(m_mainLayout);
m_mainLayout->setContentsMargins(8, 8, 8, 8);
m_mainLayout->setSpacing(10);
m_mainLayout->setSpacing(7);
m_mainLayout->addWidget(m_appPluginDatetimeWidget);
m_mainLayout->addWidget(m_systemPluginWidget);
}
@ -165,8 +203,20 @@ void TrayManagerWindow::initUi()
void TrayManagerWindow::initConnection()
{
connect(m_trayView, &TrayGridView::requestRemove, m_model, &TrayModel::removeRow);
connect(m_trayView, &TrayGridView::rowCountChanged, this, &TrayManagerWindow::sizeChanged);
connect(m_trayView, &TrayGridView::rowCountChanged, this, [ this ] {
if (m_quickIconWidget->x() == 0) {
// 在加载界面的时候,会出现快捷设置区域的图标和左侧的托盘图标挤在一起(具体原因未知)此时需要延时50毫秒重新刷新界面来保证界面布局正常(临时解决方案)
QTimer::singleShot(50, this, [ this ] {
resetChildWidgetSize();
Q_EMIT sizeChanged();
});
} else {
resetChildWidgetSize();
Q_EMIT sizeChanged();
}
});
connect(m_quickIconWidget, &QuickPluginWindow::itemCountChanged, this, [ this ] {
// 当插件数量发生变化的时候,需要调整尺寸
m_quickIconWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
if (m_postion == Dock::Position::Top || m_postion == Dock::Position::Bottom)
m_quickIconWidget->setFixedWidth(m_quickIconWidget->suitableSize().width());
@ -177,6 +227,7 @@ void TrayManagerWindow::initConnection()
});
connect(m_systemPluginWidget, &SystemPluginWindow::pluginSizeChanged, this, [ this ] {
// 当系统插件发生变化的时候,同样需要调整尺寸
m_systemPluginWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
if (m_postion == Dock::Position::Top || m_postion == Dock::Position::Bottom)
m_systemPluginWidget->setFixedWidth(m_systemPluginWidget->suitableSize().width());
@ -186,18 +237,17 @@ void TrayManagerWindow::initConnection()
Q_EMIT sizeChanged();
});
TrayDelegate *trayDelegate = static_cast<TrayDelegate *>(m_trayView->itemDelegate());
connect(trayDelegate, &TrayDelegate::visibleChanged, this, [ this ](const QModelIndex &index, bool visible) {
connect(m_delegate, &TrayDelegate::visibleChanged, this, [ this ](const QModelIndex &index, bool visible) {
m_trayView->setRowHidden(index.row(), !visible);
resetChildWidgetSize();
Q_EMIT sizeChanged();
});
connect(m_trayView, &TrayGridView::dragLeaved, trayDelegate, [ trayDelegate ]{
Q_EMIT trayDelegate->requestDrag(true);
connect(m_trayView, &TrayGridView::dragLeaved, m_delegate, [ this ]{
Q_EMIT m_delegate->requestDrag(true);
});
connect(m_trayView, &TrayGridView::dragEntered, trayDelegate, [ trayDelegate ]{
Q_EMIT trayDelegate->requestDrag(false);
connect(m_trayView, &TrayGridView::dragEntered, m_delegate, [ this ]{
Q_EMIT m_delegate->requestDrag(false);
});
connect(m_model, &TrayModel::requestUpdateWidget, this, [ this ](const QList<int> &idxs) {
for (int i = 0; i < idxs.size(); i++) {
@ -235,7 +285,7 @@ void TrayManagerWindow::resetChildWidgetSize()
switch (m_postion) {
case Dock::Position::Top:
case Dock::Position::Bottom: {
int trayWidth = count * ITEM_SIZE + m_trayView->spacing() * (count - 1) + 5;
int trayWidth = m_trayView->suitableSize().width();
QMargins m = m_appPluginLayout->contentsMargins();
m_appPluginDatetimeWidget->setFixedHeight(QWIDGETSIZE_MAX);// 取消固定高度显示
if (m_appDatetimeLayout->direction() == QBoxLayout::Direction::LeftToRight) {
@ -243,37 +293,33 @@ void TrayManagerWindow::resetChildWidgetSize()
int trayHeight = m_appPluginDatetimeWidget->height() - m.top() - m.bottom();
m_trayView->setFixedSize(trayWidth, trayHeight);
m_quickIconWidget->setFixedSize(m_quickIconWidget->suitableSize().width(), trayHeight);
m_appPluginWidget->setFixedSize(trayWidth + m_quickIconWidget->suitableSize().width(), trayHeight);
m_dateTimeWidget->setFixedSize(m_dateTimeWidget->suitableSize().width(), trayHeight);
} else {
// 多行显示
int trayHeight = m_appPluginDatetimeWidget->height() / 2 - m.top() - m.bottom();
m_trayView->setFixedSize(trayWidth, trayHeight);
m_quickIconWidget->setFixedSize(m_quickIconWidget->suitableSize().width(), trayHeight);
m_dateTimeWidget->setFixedSize(m_dateTimeWidget->suitableSize().width(), m_appPluginDatetimeWidget->height() / 2);
m_appPluginWidget->setFixedSize(trayWidth + m_quickIconWidget->suitableSize().width(), trayHeight);
// 因为是两行,所以对于时间控件的尺寸,只能设置最小值
m_dateTimeWidget->setMinimumSize(m_dateTimeWidget->suitableSize().width(), m_appPluginDatetimeWidget->height() / 2);
}
m_appPluginDatetimeWidget->setFixedWidth(appDatetimeSize());
break;
}
case Dock::Position::Left:
case Dock::Position::Right: {
int trayHeight = count * ITEM_SIZE + m_trayView->spacing() * (count - 1) + 5;
int trayHeight = m_trayView->suitableSize().height();
int quickAreaHeight = m_quickIconWidget->suitableSize().height();
QMargins m = m_appPluginLayout->contentsMargins();
m_appPluginDatetimeWidget->setFixedWidth(QWIDGETSIZE_MAX);// 取消固定宽度显示
if (m_appDatetimeLayout->direction() == QBoxLayout::Direction::TopToBottom) {
// 宽度较小的情况下,显示一列
int datetimeHeight = m_dateTimeWidget->suitableSize().height();
int sizeWidth = m_appPluginDatetimeWidget->width() - m.left() - m.right();
m_trayView->setFixedSize(sizeWidth, trayHeight);
m_quickIconWidget->setFixedSize(sizeWidth, quickAreaHeight);
m_dateTimeWidget->setFixedSize(sizeWidth, datetimeHeight);
} else {
// 显示两列
int trayWidth = m_appPluginDatetimeWidget->width() / 2 - m.left() - m.right();
m_trayView->setFixedSize(trayWidth, trayHeight);
m_quickIconWidget->setFixedSize(trayWidth, quickAreaHeight);
m_dateTimeWidget->setFixedSize(m_appPluginDatetimeWidget->width() / 2, m_dateTimeWidget->suitableSize().height());
}
// 左右方向始终只有一列
int datetimeHeight = m_dateTimeWidget->suitableSize().height();
int sizeWidth = m_appPluginDatetimeWidget->width() - m.left() - m.right();
m_trayView->setFixedSize(sizeWidth, trayHeight);
m_quickIconWidget->setFixedSize(sizeWidth, quickAreaHeight);
m_dateTimeWidget->setFixedSize(sizeWidth, datetimeHeight);
m_appPluginWidget->setFixedSize(sizeWidth, trayHeight + quickAreaHeight);
m_appPluginDatetimeWidget->setFixedHeight(appDatetimeSize());
break;
}
@ -283,33 +329,19 @@ void TrayManagerWindow::resetChildWidgetSize()
void TrayManagerWindow::resetSingleDirection()
{
switch (m_postion) {
case Dock::Position::Top: {
case Dock::Position::Top:
case Dock::Position::Bottom: {
m_appPluginLayout->setDirection(QBoxLayout::Direction::LeftToRight);
// 应用和时间在一行显示
m_appDatetimeLayout->setDirection(QBoxLayout::Direction::LeftToRight);
m_mainLayout->setDirection(QBoxLayout::Direction::LeftToRight);
m_appPluginLayout->setContentsMargins(2, 2, 2, 4);
break;
}
case Dock::Position::Bottom: {
m_appPluginLayout->setDirection(QBoxLayout::Direction::LeftToRight);
m_appDatetimeLayout->setDirection(QBoxLayout::Direction::LeftToRight);
m_mainLayout->setDirection(QBoxLayout::Direction::LeftToRight);
m_appPluginLayout->setContentsMargins(2, 4, 2, 2);
break;
}
case Dock::Position::Left: {
case Dock::Position::Left:
case Dock::Position::Right:{
m_appPluginLayout->setDirection(QBoxLayout::Direction::TopToBottom);
m_appDatetimeLayout->setDirection(QBoxLayout::Direction::TopToBottom);
m_mainLayout->setDirection(QBoxLayout::Direction::TopToBottom);
m_appPluginLayout->setContentsMargins(2, 2, 4, 2);
break;
}
case Dock::Position::Right: {
m_appPluginLayout->setDirection(QBoxLayout::Direction::TopToBottom);
m_appDatetimeLayout->setDirection(QBoxLayout::Direction::TopToBottom);
m_mainLayout->setDirection(QBoxLayout::Direction::TopToBottom);
m_appPluginLayout->setContentsMargins(4, 2, 2, 2);
break;
}
}
@ -322,28 +354,19 @@ void TrayManagerWindow::resetMultiDirection()
m_appPluginLayout->setDirection(QBoxLayout::Direction::LeftToRight);
m_appDatetimeLayout->setDirection(QBoxLayout::Direction::BottomToTop);
m_mainLayout->setDirection(QBoxLayout::Direction::LeftToRight);
m_appPluginLayout->setContentsMargins(2, 2, 2, 4);
break;
}
case Dock::Position::Bottom: {
m_appPluginLayout->setDirection(QBoxLayout::Direction::LeftToRight);
m_appDatetimeLayout->setDirection(QBoxLayout::Direction::TopToBottom);
m_mainLayout->setDirection(QBoxLayout::Direction::LeftToRight);
m_appPluginLayout->setContentsMargins(2, 4, 2, 2);
break;
}
case Dock::Position::Left: {
m_appPluginLayout->setDirection(QBoxLayout::Direction::TopToBottom);
m_appDatetimeLayout->setDirection(QBoxLayout::Direction::TopToBottom);
m_mainLayout->setDirection(QBoxLayout::Direction::TopToBottom);
m_appPluginLayout->setContentsMargins(2, 2, 4, 2);
break;
}
case Dock::Position::Left:
case Dock::Position::Right: {
m_appPluginLayout->setDirection(QBoxLayout::Direction::TopToBottom);
m_appDatetimeLayout->setDirection(QBoxLayout::Direction::TopToBottom);
m_mainLayout->setDirection(QBoxLayout::Direction::TopToBottom);
m_appPluginLayout->setContentsMargins(4, 2, 2, 2);
break;
}
}
@ -363,16 +386,16 @@ void TrayManagerWindow::dragMoveEvent(QDragMoveEvent *e)
void TrayManagerWindow::dropEvent(QDropEvent *e)
{
CustomMimeData *mimeData = const_cast<CustomMimeData *>(qobject_cast<const CustomMimeData *>(e->mimeData()));
const QuickPluginMimeData *mimeData = qobject_cast<const QuickPluginMimeData *>(e->mimeData());
if (!mimeData)
return;
if (e->source() == this)
return;
QuickSettingItem *pluginItem = static_cast<QuickSettingItem *>(mimeData->data());
QuickSettingItem *pluginItem = static_cast<QuickSettingItem *>(mimeData->quickSettingItem());
if (pluginItem)
m_quickIconWidget->addPlugin(pluginItem);
m_quickIconWidget->dragPlugin(pluginItem);
}
void TrayManagerWindow::dragLeaveEvent(QDragLeaveEvent *event)

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TRAYMANAGERWINDOW_H
#define TRAYMANAGERWINDOW_H
@ -18,6 +38,7 @@ class QuickPluginWindow;
class QBoxLayout;
class TrayGridView;
class TrayModel;
class TrayDelegate;
class SystemPluginWindow;
class QLabel;
class QDropEvent;
@ -66,7 +87,9 @@ private:
QBoxLayout *m_mainLayout;
TrayGridView *m_trayView;
TrayModel *m_model;
TrayDelegate *m_delegate;
Dock::Position m_postion;
QLabel *m_splitLine;
};
#endif // PLUGINWINDOW_H