IMPORTANT: All new Indicators architecture
--this huge commit contains all the changes needed in order for Latte to load Indicators dynamically from their own packagespull/5/head
parent
e9599218a2
commit
0b90411b1d
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Latte-Dock
|
||||||
|
*
|
||||||
|
* Latte-Dock 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 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Latte-Dock 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 "factory.h"
|
||||||
|
|
||||||
|
// local
|
||||||
|
#include "../importer.h"
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
#include <KPluginMetaData>
|
||||||
|
|
||||||
|
namespace Latte {
|
||||||
|
namespace Indicator {
|
||||||
|
|
||||||
|
Factory::Factory(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
reload();
|
||||||
|
|
||||||
|
qDebug() << m_plugins["org.kde.latte.indicator.default"].name();
|
||||||
|
}
|
||||||
|
|
||||||
|
Factory::~Factory()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
KPluginMetaData Factory::metadata(QString pluginId)
|
||||||
|
{
|
||||||
|
if (m_plugins.contains(pluginId)) {
|
||||||
|
return m_plugins[pluginId];
|
||||||
|
}
|
||||||
|
|
||||||
|
return KPluginMetaData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Factory::reload()
|
||||||
|
{
|
||||||
|
QStringList standardPaths = Latte::Importer::standardPaths();
|
||||||
|
|
||||||
|
m_plugins.clear();
|
||||||
|
|
||||||
|
foreach(auto path, standardPaths) {
|
||||||
|
QDir standard(path + "/latte/indicators");
|
||||||
|
|
||||||
|
if (standard.exists()) {
|
||||||
|
QStringList pluginDirs = standard.entryList(QStringList(),QDir::AllDirs | QDir::NoSymLinks);
|
||||||
|
|
||||||
|
foreach (auto pluginDir, pluginDirs) {
|
||||||
|
if (pluginDir != "." && pluginDir != "..") {
|
||||||
|
QString metadataFile = standard.absolutePath() + "/" + pluginDir + "/metadata.desktop";
|
||||||
|
|
||||||
|
if (QFileInfo(metadataFile).exists()) {
|
||||||
|
|
||||||
|
KPluginMetaData metadata = KPluginMetaData::fromDesktopFile(metadataFile);
|
||||||
|
QString uiFile = standard.absolutePath() + "/" + pluginDir + "/package/" + metadata.value("X-Latte-MainScript");
|
||||||
|
|
||||||
|
if (metadata.isValid() && QFileInfo(uiFile).exists() && !m_plugins.contains(metadata.pluginId())) {
|
||||||
|
m_plugins[metadata.pluginId()] = metadata;
|
||||||
|
QString pluginPath = metadata.fileName().remove("metadata.desktop");
|
||||||
|
qDebug() << " Indicator Package Loaded ::: " << metadata.name() << " [" << metadata.pluginId() << "]" << " - [" <<pluginPath<<"]";
|
||||||
|
/*qDebug() << " Indicator value ::: " << metadata.pluginId();
|
||||||
|
qDebug() << " Indicator value ::: " << metadata.fileName();
|
||||||
|
qDebug() << " Indicator value ::: " << metadata.value("X-Latte-MainScript");
|
||||||
|
qDebug() << " Indicator value ::: " << metadata.value("X-Latte-ConfigUi");
|
||||||
|
qDebug() << " Indicator value ::: " << metadata.value("X-Latte-ConfigXml");*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,329 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Latte-Dock
|
||||||
|
*
|
||||||
|
* Latte-Dock 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 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Latte-Dock 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 "indicator.h"
|
||||||
|
|
||||||
|
// local
|
||||||
|
#include "view.h"
|
||||||
|
#include "../lattecorona.h"
|
||||||
|
#include "../indicator/factory.h"
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
#include <KPluginMetaData>
|
||||||
|
#include <KDeclarative/ConfigPropertyMap>
|
||||||
|
#include <KDeclarative/QmlObjectSharedEngine>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Latte {
|
||||||
|
namespace ViewPart {
|
||||||
|
|
||||||
|
Indicator::Indicator(Latte::View *parent)
|
||||||
|
: QObject(parent),
|
||||||
|
m_view(parent)
|
||||||
|
{
|
||||||
|
m_corona = qobject_cast<Latte::Corona *>(m_view->corona());
|
||||||
|
loadConfig();
|
||||||
|
|
||||||
|
connect(this, &Indicator::enabledChanged, this, &Indicator::saveConfig);
|
||||||
|
connect(this, &Indicator::enabledForAppletsChanged, this, &Indicator::saveConfig);
|
||||||
|
connect(this, &Indicator::paddingChanged, this, &Indicator::saveConfig);
|
||||||
|
connect(this, &Indicator::reversedChanged, this, &Indicator::saveConfig);
|
||||||
|
connect(this, &Indicator::typeChanged, this, &Indicator::saveConfig);
|
||||||
|
|
||||||
|
connect(m_view, &Latte::View::latteTasksArePresentChanged, this, &Indicator::latteTasksArePresentChanged);
|
||||||
|
|
||||||
|
load(m_type);
|
||||||
|
|
||||||
|
loadPlasmaComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
Indicator::~Indicator()
|
||||||
|
{
|
||||||
|
if (m_component) {
|
||||||
|
m_component->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_configLoader) {
|
||||||
|
m_configLoader->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_configuration) {
|
||||||
|
m_configuration->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Indicator::enabled() const
|
||||||
|
{
|
||||||
|
return m_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Indicator::setEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
if (m_enabled == enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_enabled = enabled;
|
||||||
|
emit enabledChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Indicator::enabledForApplets() const
|
||||||
|
{
|
||||||
|
return m_enabledForApplets;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Indicator::setEnabledForApplets(bool enabled)
|
||||||
|
{
|
||||||
|
if (m_enabledForApplets == enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_enabledForApplets = enabled;
|
||||||
|
emit enabledForAppletsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Indicator::latteTasksArePresent()
|
||||||
|
{
|
||||||
|
return m_view->latteTasksArePresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Indicator::providesConfigUi() const
|
||||||
|
{
|
||||||
|
return m_providesConfigUi;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Indicator::setProvidesConfigUi(bool provides)
|
||||||
|
{
|
||||||
|
if (m_providesConfigUi == provides) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_providesConfigUi = provides;
|
||||||
|
emit providesConfigUiChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Indicator::reversed() const
|
||||||
|
{
|
||||||
|
return m_reversed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Indicator::setReversed(bool reversed)
|
||||||
|
{
|
||||||
|
if (m_reversed == reversed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_reversed = reversed;
|
||||||
|
emit reversedChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
float Indicator::padding() const
|
||||||
|
{
|
||||||
|
return m_padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Indicator::setPadding(float padding)
|
||||||
|
{
|
||||||
|
if (m_padding == padding) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_padding = padding;
|
||||||
|
emit paddingChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Indicator::type() const
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Indicator::setType(QString type)
|
||||||
|
{
|
||||||
|
if (m_type == type) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
load(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
QQmlComponent *Indicator::component() const
|
||||||
|
{
|
||||||
|
return m_component;
|
||||||
|
}
|
||||||
|
|
||||||
|
QQmlComponent *Indicator::plasmaComponent() const
|
||||||
|
{
|
||||||
|
return m_plasmaComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject *Indicator::configuration() const
|
||||||
|
{
|
||||||
|
return m_configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Indicator::load(QString type)
|
||||||
|
{
|
||||||
|
KPluginMetaData metadata = m_corona->indicatorFactory()->metadata(type);
|
||||||
|
|
||||||
|
if (metadata.isValid()) {
|
||||||
|
m_metadata = metadata;
|
||||||
|
m_type = type;
|
||||||
|
|
||||||
|
QString path = m_metadata.fileName();
|
||||||
|
m_pluginPath = path.remove("metadata.desktop");
|
||||||
|
|
||||||
|
updateScheme();
|
||||||
|
updateComponent();
|
||||||
|
|
||||||
|
emit typeChanged();
|
||||||
|
} else if (type!="org.kde.latte.indicator.default") {
|
||||||
|
setType("org.kde.latte.indicator.default");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Indicator::updateComponent()
|
||||||
|
{
|
||||||
|
auto prevComponent = m_component;
|
||||||
|
|
||||||
|
QString uiPath = m_metadata.value("X-Latte-MainScript");
|
||||||
|
|
||||||
|
if (!uiPath.isEmpty()) {
|
||||||
|
uiPath = m_pluginPath + "package/" + uiPath;
|
||||||
|
m_component = new QQmlComponent(m_view->engine(), uiPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevComponent) {
|
||||||
|
prevComponent->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
emit componentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Indicator::loadPlasmaComponent()
|
||||||
|
{
|
||||||
|
auto prevComponent = m_plasmaComponent;
|
||||||
|
|
||||||
|
KPluginMetaData metadata = m_corona->indicatorFactory()->metadata("org.kde.latte.indicator.plasma");
|
||||||
|
QString uiPath = metadata.value("X-Latte-MainScript");
|
||||||
|
|
||||||
|
if (!uiPath.isEmpty()) {
|
||||||
|
QString path = metadata.fileName();
|
||||||
|
path = path.remove("metadata.desktop");
|
||||||
|
|
||||||
|
uiPath = path + "package/" + uiPath;
|
||||||
|
m_plasmaComponent = new QQmlComponent(m_view->engine(), uiPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevComponent) {
|
||||||
|
prevComponent->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
emit plasmaComponentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Indicator::configUiFor(QString type, QQuickItem *parent)
|
||||||
|
{
|
||||||
|
if (m_lastCreatedConfigUi) {
|
||||||
|
delete m_lastCreatedConfigUi;
|
||||||
|
m_lastCreatedConfigUi = nullptr;
|
||||||
|
}
|
||||||
|
auto prevConfigUi = m_lastCreatedConfigUi;
|
||||||
|
|
||||||
|
KPluginMetaData metadata;
|
||||||
|
|
||||||
|
if (m_metadata.pluginId() == type) {
|
||||||
|
metadata = m_metadata;
|
||||||
|
} else {
|
||||||
|
metadata = m_corona->indicatorFactory()->metadata(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metadata.isValid()) {
|
||||||
|
QString uiPath = metadata.value("X-Latte-ConfigUi");
|
||||||
|
|
||||||
|
if (!uiPath.isEmpty()) {
|
||||||
|
m_lastCreatedConfigUi = new KDeclarative::QmlObjectSharedEngine(parent);
|
||||||
|
m_lastCreatedConfigUi->setInitializationDelayed(true);
|
||||||
|
uiPath = m_pluginPath + "package/" + uiPath;
|
||||||
|
m_lastCreatedConfigUi->setSource(QUrl::fromLocalFile(uiPath));
|
||||||
|
m_lastCreatedConfigUi->rootContext()->setContextProperty(QStringLiteral("indicator"), this);
|
||||||
|
m_lastCreatedConfigUi->completeInitialization();
|
||||||
|
|
||||||
|
m_lastCreatedConfigUi->setTranslationDomain(QLatin1String("latte_indicator_") + m_metadata.pluginId());
|
||||||
|
|
||||||
|
QQuickItem *qmlItem = qobject_cast<QQuickItem*>(m_lastCreatedConfigUi->rootObject());
|
||||||
|
qmlItem->setParentItem(parent);
|
||||||
|
|
||||||
|
setProvidesConfigUi(true);
|
||||||
|
} else {
|
||||||
|
setProvidesConfigUi(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Indicator::updateScheme()
|
||||||
|
{
|
||||||
|
auto prevConfigLoader = m_configLoader;
|
||||||
|
auto prevConfiguration = m_configuration;
|
||||||
|
|
||||||
|
QString xmlPath = m_metadata.value("X-Latte-ConfigXml");
|
||||||
|
|
||||||
|
if (!xmlPath.isEmpty()) {
|
||||||
|
QFile file(m_pluginPath + "package/" + xmlPath);
|
||||||
|
m_configLoader = new KConfigLoader(m_view->containment()->config().group("Indicator").group(m_metadata.pluginId()), &file);
|
||||||
|
m_configuration = new KDeclarative::ConfigPropertyMap(m_configLoader, this);
|
||||||
|
} else {
|
||||||
|
m_configLoader = nullptr;
|
||||||
|
m_configuration = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevConfigLoader) {
|
||||||
|
prevConfigLoader->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevConfiguration) {
|
||||||
|
prevConfiguration->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
emit configurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Indicator::loadConfig()
|
||||||
|
{
|
||||||
|
auto config = m_view->containment()->config().group("Indicator");
|
||||||
|
m_enabled = config.readEntry("enabled", true);
|
||||||
|
m_enabledForApplets = config.readEntry("enabledForApplets", true);
|
||||||
|
m_padding = config.readEntry("padding", (float)0.08);
|
||||||
|
m_reversed = config.readEntry("reversed", false);
|
||||||
|
m_type = config.readEntry("type", "org.kde.latte.indicator.default");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Indicator::saveConfig()
|
||||||
|
{
|
||||||
|
auto config = m_view->containment()->config().group("Indicator");
|
||||||
|
config.writeEntry("enabled", m_enabled);
|
||||||
|
config.writeEntry("enabledForApplets", m_enabledForApplets);
|
||||||
|
config.writeEntry("padding", m_padding);
|
||||||
|
config.writeEntry("reversed", m_reversed);
|
||||||
|
config.writeEntry("type", m_type);
|
||||||
|
|
||||||
|
config.sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Latte-Dock
|
||||||
|
*
|
||||||
|
* Latte-Dock 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 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Latte-Dock 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 VIEWINDICATOR_H
|
||||||
|
#define VIEWINDICATOR_H
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QQmlComponent>
|
||||||
|
#include <QQmlContext>
|
||||||
|
#include <QQuickItem>
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
#include <KConfigLoader>
|
||||||
|
#include <KPluginMetaData>
|
||||||
|
|
||||||
|
namespace KDeclarative
|
||||||
|
{
|
||||||
|
class ConfigPropertyMap;
|
||||||
|
class QmlObjectSharedEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Latte {
|
||||||
|
class Corona;
|
||||||
|
class View;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Latte {
|
||||||
|
namespace ViewPart {
|
||||||
|
|
||||||
|
class Indicator: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
|
||||||
|
Q_PROPERTY(bool enabledForApplets READ enabledForApplets WRITE setEnabledForApplets NOTIFY enabledForAppletsChanged)
|
||||||
|
Q_PROPERTY(bool latteTasksArePresent READ latteTasksArePresent NOTIFY latteTasksArePresentChanged)
|
||||||
|
Q_PROPERTY(bool providesConfigUi READ providesConfigUi NOTIFY providesConfigUiChanged)
|
||||||
|
Q_PROPERTY(bool reversed READ reversed WRITE setReversed NOTIFY reversedChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(float padding READ padding WRITE setPadding NOTIFY paddingChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(QString type READ type WRITE setType NOTIFY typeChanged)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration object: each config key will be a writable property of this object. property bindings work.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY(QObject *configuration READ configuration NOTIFY configurationChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(QQmlComponent *component READ component NOTIFY componentChanged)
|
||||||
|
Q_PROPERTY(QQmlComponent *plasmaComponent READ plasmaComponent NOTIFY plasmaComponentChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
Indicator(Latte::View *parent);
|
||||||
|
virtual ~Indicator();
|
||||||
|
|
||||||
|
bool enabled() const;
|
||||||
|
void setEnabled(bool enabled);
|
||||||
|
|
||||||
|
bool enabledForApplets() const;
|
||||||
|
void setEnabledForApplets(bool enabled);
|
||||||
|
|
||||||
|
bool latteTasksArePresent();
|
||||||
|
bool providesConfigUi() const;
|
||||||
|
|
||||||
|
bool reversed() const;
|
||||||
|
void setReversed(bool reversed);
|
||||||
|
|
||||||
|
float padding() const;
|
||||||
|
void setPadding(float padding);
|
||||||
|
|
||||||
|
QString type() const;
|
||||||
|
void setType(QString type);
|
||||||
|
|
||||||
|
QObject *configuration() const;
|
||||||
|
QQmlComponent *component() const;
|
||||||
|
QQmlComponent *plasmaComponent() const;
|
||||||
|
|
||||||
|
void load(QString type);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
Q_INVOKABLE void configUiFor(QString type, QQuickItem *parent);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void componentChanged();
|
||||||
|
void configurationChanged();
|
||||||
|
void enabledChanged();
|
||||||
|
void enabledForAppletsChanged();
|
||||||
|
void latteTasksArePresentChanged();
|
||||||
|
void paddingChanged();
|
||||||
|
void plasmaComponentChanged();
|
||||||
|
void providesConfigUiChanged();
|
||||||
|
void reversedChanged();
|
||||||
|
void typeChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void loadConfig();
|
||||||
|
void saveConfig();
|
||||||
|
|
||||||
|
void setProvidesConfigUi(bool provides);
|
||||||
|
|
||||||
|
void loadPlasmaComponent();
|
||||||
|
void updateComponent();
|
||||||
|
void updateScheme();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_enabled{true};
|
||||||
|
bool m_enabledForApplets{true};
|
||||||
|
bool m_providesConfigUi{true};
|
||||||
|
bool m_reversed{false};
|
||||||
|
|
||||||
|
float m_padding{0.08};
|
||||||
|
|
||||||
|
QString m_pluginPath;
|
||||||
|
QString m_type{"org.kde.latte.indicator.default"};
|
||||||
|
|
||||||
|
QPointer<QQmlComponent> m_component;
|
||||||
|
QPointer<QQmlComponent> m_plasmaComponent;
|
||||||
|
QPointer<QQmlComponent> m_configUi;
|
||||||
|
QPointer<KConfigLoader> m_configLoader;
|
||||||
|
QPointer<Latte::Corona> m_corona;
|
||||||
|
QPointer<Latte::View> m_view;
|
||||||
|
|
||||||
|
KPluginMetaData m_metadata;
|
||||||
|
|
||||||
|
QPointer<KDeclarative::ConfigPropertyMap> m_configuration;
|
||||||
|
QPointer<KDeclarative::QmlObjectSharedEngine> m_lastCreatedConfigUi;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
|
|
||||||
*
|
|
||||||
* This file is part of Latte-Dock
|
|
||||||
*
|
|
||||||
* Latte-Dock 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 2 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Latte-Dock 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.7
|
|
||||||
|
|
||||||
import org.kde.plasma.plasmoid 2.0
|
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
|
||||||
|
|
||||||
import org.kde.latte 0.2 as Latte
|
|
||||||
|
|
||||||
Item{
|
|
||||||
readonly property string styleName: "Latte"
|
|
||||||
|
|
||||||
readonly property bool dotsOnActive: plasmoid.configuration.dotsOnActive
|
|
||||||
readonly property bool multiColorEnabled: plasmoid.configuration.threeColorsWindows
|
|
||||||
readonly property int activeIndicatorType: plasmoid.configuration.activeIndicatorType
|
|
||||||
|
|
||||||
//!glow options
|
|
||||||
readonly property bool glowEnabled: plasmoid.configuration.showGlow
|
|
||||||
readonly property bool glow3D: plasmoid.configuration.glow3D
|
|
||||||
readonly property int glowOption: plasmoid.configuration.glowOption
|
|
||||||
readonly property real glowOpacity: plasmoid.configuration.glowOpacity/100
|
|
||||||
}
|
|
@ -0,0 +1,3 @@
|
|||||||
|
install(DIRECTORY org.kde.latte.indicator.default DESTINATION ${CMAKE_INSTALL_PREFIX}/share/latte/indicators)
|
||||||
|
install(DIRECTORY org.kde.latte.indicator.plasma DESTINATION ${CMAKE_INSTALL_PREFIX}/share/latte/indicators)
|
||||||
|
install(DIRECTORY org.kde.latte.indicator.unity DESTINATION ${CMAKE_INSTALL_PREFIX}/share/latte/indicators)
|
@ -0,0 +1,4 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
|
||||||
|
$XGETTEXT `find org.kde.latte.indicator.default -name \*.js -o -name \*.qml -o -name \*.cpp` -o $podir/latte_indicator_org.kde.latte.indicator.default.pot
|
||||||
|
$XGETTEXT `find org.kde.latte.indicator.plasma -name \*.js -o -name \*.qml -o -name \*.cpp` -o $podir/latte_indicator_org.kde.latte.indicator.plasma.pot
|
@ -0,0 +1,19 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Name=Latte
|
||||||
|
Comment=Latte default indicator
|
||||||
|
|
||||||
|
Type=Service
|
||||||
|
Icon=latte-dock
|
||||||
|
X-Plasma-API=declarativeappletscript
|
||||||
|
X-Latte-MainScript=ui/main.qml
|
||||||
|
X-Latte-ConfigUi=config/config.qml
|
||||||
|
X-Latte-ConfigXml=config/main.xml
|
||||||
|
|
||||||
|
X-KDE-PluginInfo-Author=Michail Vourlakos
|
||||||
|
X-KDE-PluginInfo-Email=mvourlakos@gmail.com
|
||||||
|
X-KDE-PluginInfo-Name=org.kde.latte.indicator.default
|
||||||
|
X-KDE-PluginInfo-Version=0.1
|
||||||
|
X-KDE-PluginInfo-Category=Windows and Tasks
|
||||||
|
X-KDE-PluginInfo-License=GPL v2+
|
||||||
|
X-KDE-PluginInfo-EnabledByDefault=true
|
||||||
|
|
@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
||||||
|
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
|
||||||
|
<kcfgfile name=""/>
|
||||||
|
<group name="General">
|
||||||
|
<entry name="activeStyle" type="Enum">
|
||||||
|
<label>Active indicator style</label>
|
||||||
|
<choices>
|
||||||
|
<choice name="Line"/>
|
||||||
|
<choice name="Dot"/>
|
||||||
|
</choices>
|
||||||
|
<default>0</default>
|
||||||
|
</entry>
|
||||||
|
<entry name="minimizedTaskColoredDifferently" type="Bool">
|
||||||
|
<default>false</default>
|
||||||
|
</entry>
|
||||||
|
<entry name="extraDotOnActive" type="Bool">
|
||||||
|
<default>false</default>
|
||||||
|
</entry>
|
||||||
|
<entry name="glowEnabled" type="Bool">
|
||||||
|
<default>false</default>
|
||||||
|
</entry>
|
||||||
|
<entry name="glowApplyTo" type="Enum">
|
||||||
|
<label>Glow for active indicators</label>
|
||||||
|
<choices>
|
||||||
|
<choice name="None"/>
|
||||||
|
<choice name="OnActive"/>
|
||||||
|
<choice name="All"/>
|
||||||
|
</choices>
|
||||||
|
<default>2</default>
|
||||||
|
</entry>
|
||||||
|
<entry name="glow3D" type="Bool">
|
||||||
|
<default>true</default>
|
||||||
|
</entry>
|
||||||
|
<entry name="glowOpacity" type="Double">
|
||||||
|
<default>0.35</default>
|
||||||
|
</entry>
|
||||||
|
</group>
|
||||||
|
</kcfg>
|
||||||
|
|
@ -0,0 +1,291 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Latte-Dock
|
||||||
|
*
|
||||||
|
* Latte-Dock 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 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Latte-Dock 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
import org.kde.plasma.plasmoid 2.0
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
|
|
||||||
|
import org.kde.latte 0.2 as Latte
|
||||||
|
import org.kde.latte.components 1.0 as LatteComponents
|
||||||
|
|
||||||
|
LatteComponents.IndicatorItem{
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property real factor: 0.08
|
||||||
|
readonly property int size: factor * indicator.currentIconSize
|
||||||
|
readonly property int extraMaskThickness: reversedEnabled && glowEnabled ? 1.7 * (factor * indicator.maxIconSize) : 0
|
||||||
|
|
||||||
|
property real textColorBrightness: colorBrightness(theme.textColor)
|
||||||
|
|
||||||
|
property color isActiveColor: theme.buttonFocusColor
|
||||||
|
property color minimizedColor: {
|
||||||
|
if (minimizedTaskColoredDifferently) {
|
||||||
|
return (textColorBrightness > 127.5 ? Qt.darker(theme.textColor, 1.7) : Qt.lighter(theme.textColor, 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
return isActiveColor;
|
||||||
|
}
|
||||||
|
property color notActiveColor: indicator.isMinimized ? minimizedColor : isActiveColor
|
||||||
|
|
||||||
|
//! Common Options
|
||||||
|
readonly property bool reversedEnabled: indicator.shared.reversed
|
||||||
|
|
||||||
|
//! Configuration Options
|
||||||
|
readonly property bool extraDotOnActive: indicator.configuration.extraDotOnActive
|
||||||
|
readonly property bool minimizedTaskColoredDifferently: indicator.configuration.minimizedTaskColoredDifferently
|
||||||
|
readonly property int activeStyle: indicator.configuration.activeStyle
|
||||||
|
//!glow options
|
||||||
|
readonly property bool glowEnabled: indicator.configuration.glowEnabled
|
||||||
|
readonly property bool glow3D: indicator.configuration.glow3D
|
||||||
|
readonly property int glowApplyTo: indicator.configuration.glowApplyTo
|
||||||
|
readonly property real glowOpacity: indicator.configuration.glowOpacity
|
||||||
|
|
||||||
|
/*Rectangle{
|
||||||
|
anchors.fill: parent
|
||||||
|
border.width: 1
|
||||||
|
border.color: "yellow"
|
||||||
|
color: "transparent"
|
||||||
|
opacity:0.6
|
||||||
|
}*/
|
||||||
|
|
||||||
|
function colorBrightness(color) {
|
||||||
|
return colorBrightnessFromRGB(color.r * 255, color.g * 255, color.b * 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
// formula for brightness according to:
|
||||||
|
// https://www.w3.org/TR/AERT/#color-contrast
|
||||||
|
function colorBrightnessFromRGB(r, g, b) {
|
||||||
|
return (r * 299 + g * 587 + b * 114) / 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
Item{
|
||||||
|
id: mainIndicatorElement
|
||||||
|
|
||||||
|
width: flowItem.width
|
||||||
|
height: flowItem.height
|
||||||
|
|
||||||
|
Flow{
|
||||||
|
id: flowItem
|
||||||
|
flow: plasmoid.formFactor === PlasmaCore.Types.Vertical ? Flow.TopToBottom : Flow.LeftToRight
|
||||||
|
|
||||||
|
LatteComponents.GlowPoint{
|
||||||
|
id:firstPoint
|
||||||
|
opacity: {
|
||||||
|
if (indicator.isTask) {
|
||||||
|
return indicator.isLauncher || (indicator.inRemoving && !activeAndReverseAnimation.running) ? 0 : 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indicator.isApplet) {
|
||||||
|
return (indicator.isActive || activeAndReverseAnimation.running) ? 1 : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
basicColor: indicator.isActive || (indicator.isGroup && indicator.hasShown) ? root.isActiveColor : root.notActiveColor
|
||||||
|
|
||||||
|
size: root.size
|
||||||
|
glow3D: glow3D
|
||||||
|
animation: Math.max(1.65*3*units.longDuration,indicator.durationTime*3*units.longDuration)
|
||||||
|
location: plasmoid.location
|
||||||
|
glowOpacity: root.glowOpacity
|
||||||
|
contrastColor: indicator.shadowColor
|
||||||
|
attentionColor: theme.negativeTextColor
|
||||||
|
|
||||||
|
roundCorners: true
|
||||||
|
showAttention: indicator.inAttention
|
||||||
|
showGlow: {
|
||||||
|
if (glowEnabled && (glowApplyTo === 2 /*All*/ || showAttention ))
|
||||||
|
return true;
|
||||||
|
else if (glowEnabled && glowApplyTo === 1 /*OnActive*/ && indicator.hasActive)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
showBorder: glowEnabled && glow3D
|
||||||
|
|
||||||
|
property int stateWidth: indicator.isGroup ? root.width - secondPoint.width : root.width - spacer.width
|
||||||
|
property int stateHeight: indicator.isGroup ? root.height - secondPoint.height : root.width - spacer.height
|
||||||
|
|
||||||
|
property int animationTime: indicator.durationTime* (0.7*units.longDuration)
|
||||||
|
|
||||||
|
property bool isActive: indicator.hasActive || indicator.isActive
|
||||||
|
|
||||||
|
property bool vertical: plasmoid.formFactor === PlasmaCore.Types.Vertical
|
||||||
|
|
||||||
|
property real scaleFactor: indicator.scaleFactor
|
||||||
|
|
||||||
|
function updateInitialSizes(){
|
||||||
|
if(root){
|
||||||
|
if(vertical)
|
||||||
|
width = root.size;
|
||||||
|
else
|
||||||
|
height = root.size;
|
||||||
|
|
||||||
|
if(vertical && isActive && activeStyle === 0 /*Line*/)
|
||||||
|
height = stateHeight;
|
||||||
|
else
|
||||||
|
height = root.size;
|
||||||
|
|
||||||
|
if(!vertical && isActive && activeStyle === 0 /*Line*/)
|
||||||
|
width = stateWidth;
|
||||||
|
else
|
||||||
|
width = root.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onIsActiveChanged: {
|
||||||
|
if (activeStyle === 0 /*Line*/)
|
||||||
|
activeAndReverseAnimation.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
onScaleFactorChanged: {
|
||||||
|
if(!activeAndReverseAnimation.running && !vertical && isActive && activeStyle === 0 /*Line*/){
|
||||||
|
width = stateWidth;
|
||||||
|
}
|
||||||
|
else if (!activeAndReverseAnimation.running && vertical && isActive && activeStyle === 0 /*Line*/){
|
||||||
|
height = stateHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onStateWidthChanged:{
|
||||||
|
if(!activeAndReverseAnimation.running && !vertical && isActive && activeStyle === 0 /*Line*/)
|
||||||
|
width = stateWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
onStateHeightChanged:{
|
||||||
|
if(!activeAndReverseAnimation.running && vertical && isActive && activeStyle === 0 /*Line*/)
|
||||||
|
height = stateHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
onVerticalChanged: updateInitialSizes();
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
updateInitialSizes();
|
||||||
|
|
||||||
|
if (indicator) {
|
||||||
|
indicator.onCurrentIconSizeChanged.connect(updateInitialSizes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onDestruction: {
|
||||||
|
if (indicator) {
|
||||||
|
indicator.onCurrentIconSizeChanged.disconnect(updateInitialSizes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation{
|
||||||
|
id: activeAndReverseAnimation
|
||||||
|
target: firstPoint
|
||||||
|
property: plasmoid.formFactor === PlasmaCore.Types.Vertical ? "height" : "width"
|
||||||
|
to: indicator.hasActive && activeStyle === 0 /*Line*/
|
||||||
|
? (plasmoid.formFactor === PlasmaCore.Types.Vertical ? firstPoint.stateHeight : firstPoint.stateWidth) : root.size
|
||||||
|
duration: firstPoint.animationTime
|
||||||
|
easing.type: Easing.InQuad
|
||||||
|
|
||||||
|
onStopped: firstPoint.updateInitialSizes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item{
|
||||||
|
id:spacer
|
||||||
|
width: secondPoint.visible ? 0.5*root.size : 0
|
||||||
|
height: secondPoint.visible ? 0.5*root.size : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
LatteComponents.GlowPoint{
|
||||||
|
id:secondPoint
|
||||||
|
width: visible ? root.size : 0
|
||||||
|
height: width
|
||||||
|
|
||||||
|
size: root.size
|
||||||
|
glow3D: glow3D
|
||||||
|
animation: Math.max(1.65*3*units.longDuration,indicator.durationTime*3*units.longDuration)
|
||||||
|
location: plasmoid.location
|
||||||
|
glowOpacity: root.glowOpacity
|
||||||
|
contrastColor: indicator.shadowColor
|
||||||
|
showBorder: glowEnabled && glow3D
|
||||||
|
|
||||||
|
basicColor: state2Color
|
||||||
|
roundCorners: true
|
||||||
|
showGlow: glowEnabled && glowApplyTo === 2 /*All*/
|
||||||
|
visible: ( indicator.isGroup && ((extraDotOnActive && activeStyle === 0) /*Line*/
|
||||||
|
|| activeStyle === 1 /*Dot*/
|
||||||
|
|| !indicator.hasActive) ) ? true: false
|
||||||
|
|
||||||
|
//when there is no active window
|
||||||
|
property color state1Color: indicator.hasShown ? root.isActiveColor : root.minimizedColor
|
||||||
|
//when there is active window
|
||||||
|
property color state2Color: indicator.hasMinimized ? root.minimizedColor : root.isActiveColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "left"
|
||||||
|
when: ((plasmoid.location === PlasmaCore.Types.LeftEdge && !reversedEnabled) ||
|
||||||
|
(plasmoid.location === PlasmaCore.Types.RightEdge && reversedEnabled))
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: mainIndicatorElement
|
||||||
|
anchors{ verticalCenter:parent.verticalCenter; horizontalCenter:undefined;
|
||||||
|
top:undefined; bottom:undefined; left:parent.left; right:undefined;}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "bottom"
|
||||||
|
when: (plasmoid.location === PlasmaCore.Types.Floating ||
|
||||||
|
(plasmoid.location === PlasmaCore.Types.BottomEdge && !reversedEnabled) ||
|
||||||
|
(plasmoid.location === PlasmaCore.Types.TopEdge && reversedEnabled))
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: mainIndicatorElement
|
||||||
|
anchors{ verticalCenter:undefined; horizontalCenter:parent.horizontalCenter;
|
||||||
|
top:undefined; bottom:parent.bottom; left:undefined; right:undefined;}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "top"
|
||||||
|
when: ((plasmoid.location === PlasmaCore.Types.TopEdge && !reversedEnabled) ||
|
||||||
|
(plasmoid.location === PlasmaCore.Types.BottomEdge && reversedEnabled))
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: mainIndicatorElement
|
||||||
|
anchors{ verticalCenter:undefined; horizontalCenter:parent.horizontalCenter;
|
||||||
|
top:parent.top; bottom:undefined; left:undefined; right:undefined;}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "right"
|
||||||
|
when: ((plasmoid.location === PlasmaCore.Types.RightEdge && !reversedEnabled) ||
|
||||||
|
(plasmoid.location === PlasmaCore.Types.LeftEdge && reversedEnabled))
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: mainIndicatorElement
|
||||||
|
anchors{ verticalCenter:parent.verticalCenter; horizontalCenter:undefined;
|
||||||
|
top:undefined; bottom:undefined; left:undefined; right:parent.right;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}// number of windows indicator
|
||||||
|
|
@ -0,0 +1,17 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Name=Plasma
|
||||||
|
Comment=Latte Plasma style indicator
|
||||||
|
|
||||||
|
Type=Service
|
||||||
|
Icon=latte-dock
|
||||||
|
X-Plasma-API=declarativeappletscript
|
||||||
|
X-Latte-MainScript=ui/main.qml
|
||||||
|
|
||||||
|
X-KDE-PluginInfo-Author=Michail Vourlakos
|
||||||
|
X-KDE-PluginInfo-Email=mvourlakos@gmail.com
|
||||||
|
X-KDE-PluginInfo-Name=org.kde.latte.indicator.plasma
|
||||||
|
X-KDE-PluginInfo-Version=0.1
|
||||||
|
X-KDE-PluginInfo-Category=Windows and Tasks
|
||||||
|
X-KDE-PluginInfo-License=GPL v2+
|
||||||
|
X-KDE-PluginInfo-EnabledByDefault=true
|
||||||
|
|
@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Latte-Dock
|
||||||
|
*
|
||||||
|
* Latte-Dock 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 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Latte-Dock 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
|
||||||
|
import org.kde.latte 0.2 as Latte
|
||||||
|
|
||||||
|
PlasmaCore.FrameSvgItem {
|
||||||
|
id: frame
|
||||||
|
property string basePrefix: "normal"
|
||||||
|
|
||||||
|
imagePath: indicator.usePlasmaTabsStyle ? "widgets/tabbar" : "widgets/tasks"
|
||||||
|
|
||||||
|
prefix: {
|
||||||
|
if (indicator.usePlasmaTabsStyle) {
|
||||||
|
if (!indicator.isActive) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((plasmoid.location === PlasmaCore.Types.LeftEdge && !indicator.shared.reversed)
|
||||||
|
|| (plasmoid.location === PlasmaCore.Types.RightEdge && indicator.shared.reversed)) {
|
||||||
|
return "west-active-tab";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((plasmoid.location === PlasmaCore.Types.TopEdge && !indicator.shared.reversed)
|
||||||
|
|| (plasmoid.location === PlasmaCore.Types.BottomEdge && indicator.shared.reversed)) {
|
||||||
|
return "north-active-tab";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((plasmoid.location === PlasmaCore.Types.RightEdge && !indicator.shared.reversed)
|
||||||
|
|| (plasmoid.location === PlasmaCore.Types.LeftEdge && indicator.shared.reversed)) {
|
||||||
|
return "east-active-tab";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((plasmoid.location === PlasmaCore.Types.BottomEdge && !indicator.shared.reversed)
|
||||||
|
|| (plasmoid.location === PlasmaCore.Types.TopEdge && indicator.shared.reversed)) {
|
||||||
|
return "south-active-tab";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "south-active-tab";
|
||||||
|
} else {
|
||||||
|
return taskPrefix(basePrefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function taskPrefix(prefix) {
|
||||||
|
var effectivePrefix;
|
||||||
|
|
||||||
|
if ((plasmoid.location === PlasmaCore.Types.LeftEdge && !indicator.shared.reversed)
|
||||||
|
|| (plasmoid.location === PlasmaCore.Types.RightEdge && indicator.shared.reversed)) {
|
||||||
|
effectivePrefix = "west-" + prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((plasmoid.location === PlasmaCore.Types.TopEdge && !indicator.shared.reversed)
|
||||||
|
|| (plasmoid.location === PlasmaCore.Types.BottomEdge && indicator.shared.reversed)) {
|
||||||
|
effectivePrefix = "north-" + prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((plasmoid.location === PlasmaCore.Types.RightEdge && !indicator.shared.reversed)
|
||||||
|
|| (plasmoid.location === PlasmaCore.Types.LeftEdge && indicator.shared.reversed)) {
|
||||||
|
effectivePrefix = "east-" + prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((plasmoid.location === PlasmaCore.Types.BottomEdge && !indicator.shared.reversed)
|
||||||
|
|| (plasmoid.location === PlasmaCore.Types.TopEdge && indicator.shared.reversed)) {
|
||||||
|
effectivePrefix = "south-" + prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [effectivePrefix, prefix];
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "launcher"
|
||||||
|
when: indicator.isLauncher || (indicator.isApplet && !indicator.isActive)
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: frame
|
||||||
|
basePrefix: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "hovered"
|
||||||
|
when: indicator.isHovered && frame.hasElementPrefix("hover")
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: frame
|
||||||
|
basePrefix: "hover"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "attention"
|
||||||
|
when: indicator.inAttention
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: frame
|
||||||
|
basePrefix: "attention"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "minimized"
|
||||||
|
when: indicator.isMinimized
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: frame
|
||||||
|
basePrefix: "minimized"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "active"
|
||||||
|
when: indicator.isActive
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: frame
|
||||||
|
basePrefix: "focus"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Latte-Dock
|
||||||
|
*
|
||||||
|
* Latte-Dock 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 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Latte-Dock 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
|
||||||
|
import org.kde.latte 0.2 as Latte
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
PlasmaCore.Svg {
|
||||||
|
id: taskSvg
|
||||||
|
imagePath: "widgets/tasks"
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: iconBox
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: indicator.currentIconSize
|
||||||
|
height: width
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaCore.SvgItem {
|
||||||
|
id: arrow
|
||||||
|
|
||||||
|
implicitWidth: 0.25 * iconBox.width
|
||||||
|
implicitHeight: implicitWidth
|
||||||
|
|
||||||
|
svg: taskSvg
|
||||||
|
elementId: elementForLocation(plasmoid.location)
|
||||||
|
|
||||||
|
function elementForLocation(location) {
|
||||||
|
switch (location) {
|
||||||
|
case PlasmaCore.Types.LeftEdge:
|
||||||
|
return "group-expander-left";
|
||||||
|
case PlasmaCore.Types.TopEdge:
|
||||||
|
return "group-expander-top";
|
||||||
|
case PlasmaCore.Types.RightEdge:
|
||||||
|
return "group-expander-right";
|
||||||
|
case PlasmaCore.Types.BottomEdge:
|
||||||
|
default:
|
||||||
|
return "group-expander-bottom";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "bottom"
|
||||||
|
when: plasmoid.location === PlasmaCore.Types.BottomEdge
|
||||||
|
AnchorChanges {
|
||||||
|
target: arrow
|
||||||
|
anchors.top: undefined; anchors.left: undefined; anchors.right: undefined; anchors.bottom: arrow.parent.bottom;
|
||||||
|
anchors.horizontalCenter: iconBox.horizontalCenter; anchors.verticalCenter: undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "top"
|
||||||
|
when: plasmoid.location === PlasmaCore.Types.TopEdge
|
||||||
|
AnchorChanges {
|
||||||
|
target: arrow
|
||||||
|
anchors.top: arrow.parent.top; anchors.left: undefined; anchors.right: undefined; anchors.bottom: undefined;
|
||||||
|
anchors.horizontalCenter: iconBox.horizontalCenter; anchors.verticalCenter: undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "left"
|
||||||
|
when: plasmoid.location === PlasmaCore.Types.LeftEdge
|
||||||
|
AnchorChanges {
|
||||||
|
target: arrow
|
||||||
|
anchors.top: undefined; anchors.left: arrow.parent.left; anchors.right: undefined; anchors.bottom: undefined;
|
||||||
|
anchors.horizontalCenter: undefined; anchors.verticalCenter: iconBox.verticalCenter;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "right"
|
||||||
|
when: plasmoid.location === PlasmaCore.Types.RightEdge
|
||||||
|
AnchorChanges {
|
||||||
|
target: arrow
|
||||||
|
anchors.top: undefined; anchors.left: undefined; anchors.right: arrow.parent.right; anchors.bottom: undefined;
|
||||||
|
anchors.horizontalCenter: undefined; anchors.verticalCenter: iconBox.verticalCenter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Name=Unity
|
||||||
|
Comment=Latte Unity style indicator
|
||||||
|
|
||||||
|
Type=Service
|
||||||
|
Icon=latte-dock
|
||||||
|
X-Plasma-API=declarativeappletscript
|
||||||
|
X-Latte-MainScript=ui/main.qml
|
||||||
|
|
||||||
|
X-KDE-PluginInfo-Author=Michail Vourlakos
|
||||||
|
X-KDE-PluginInfo-Email=mvourlakos@gmail.com
|
||||||
|
X-KDE-PluginInfo-Name=org.kde.latte.indicator.unity
|
||||||
|
X-KDE-PluginInfo-Version=0.1
|
||||||
|
X-KDE-PluginInfo-Category=Windows and Tasks
|
||||||
|
X-KDE-PluginInfo-License=GPL v2+
|
||||||
|
X-KDE-PluginInfo-EnabledByDefault=true
|
||||||
|
|
@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Latte-Dock
|
||||||
|
*
|
||||||
|
* Latte-Dock 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 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Latte-Dock 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
import org.kde.plasma.plasmoid 2.0
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
|
||||||
|
Item{
|
||||||
|
Item{
|
||||||
|
id: rectangleItem
|
||||||
|
width: indicator.isTask ? Math.min(parent.width, parent.height) : parent.width
|
||||||
|
height: indicator.isTask ? width : parent.height
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
property bool isActive: indicator.isActive || (indicator.isWindow && indicator.hasActive)
|
||||||
|
readonly property int size: Math.min(parent.width, parent.height)
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: unityRect
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: indicator.isActive || (indicator.isWindow && indicator.hasShown)
|
||||||
|
|
||||||
|
radius: indicator.currentIconSize / 12
|
||||||
|
color: indicator.backgroundColor
|
||||||
|
clip: true
|
||||||
|
}
|
||||||
|
|
||||||
|
RadialGradient{
|
||||||
|
id: glowGradient
|
||||||
|
anchors.verticalCenter: parent.top
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: parent.width - unityRect.anchors.margins * 2 - 1
|
||||||
|
height: (width * 0.85) - unityRect.anchors.margins * 2 - 1
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop { position: 0.0;
|
||||||
|
color: {
|
||||||
|
if (indicator.isMinimized) {
|
||||||
|
return "#aafcfcfc";
|
||||||
|
}
|
||||||
|
|
||||||
|
return indicator.glowColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GradientStop { position: 0.6; color: "transparent" }
|
||||||
|
}
|
||||||
|
//! States
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "top"
|
||||||
|
when: !indicator.shared.reversed
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: glowGradient
|
||||||
|
anchors{horizontalCenter:parent.horizontalCenter; verticalCenter:parent.top}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "bottom"
|
||||||
|
when: indicator.shared.reversed
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: glowGradient
|
||||||
|
anchors{horizontalCenter:parent.horizontalCenter; verticalCenter:parent.bottom}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: gradientMask
|
||||||
|
anchors.fill: glowGradient
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: glowMaskRect
|
||||||
|
width: glowGradient.width
|
||||||
|
height: glowGradient.height / 2
|
||||||
|
radius: unityRect.radius
|
||||||
|
|
||||||
|
//! States
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "top"
|
||||||
|
when: !indicator.shared.reversed
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: glowMaskRect
|
||||||
|
anchors{bottom: undefined; top: parent.verticalCenter;}
|
||||||
|
}
|
||||||
|
PropertyChanges{
|
||||||
|
target: gradientMask
|
||||||
|
anchors{bottomMargin: undefined; topMargin: unityRect.anchors.margins}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "bottom"
|
||||||
|
when: indicator.shared.reversed
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: glowMaskRect
|
||||||
|
anchors{bottom: parent.verticalCenter; top: undefined;}
|
||||||
|
}
|
||||||
|
PropertyChanges{
|
||||||
|
target: gradientMask
|
||||||
|
anchors{bottomMargin: unityRect.anchors.margins; topMargin: undefined}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
OpacityMask {
|
||||||
|
anchors.fill: glowGradient
|
||||||
|
source: glowGradient
|
||||||
|
maskSource: gradientMask
|
||||||
|
visible: unityRect.visible || borderRectangle.visible
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: borderRectangle
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: (indicator.isTask && indicator.isWindow) || (indicator.isApplet && indicator.isActive)
|
||||||
|
color: "transparent"
|
||||||
|
border.width: 1
|
||||||
|
border.color: "#303030"
|
||||||
|
radius: unityRect.radius
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: parent.border.width
|
||||||
|
radius: unityRect.radius
|
||||||
|
color: "transparent"
|
||||||
|
border.width: 1
|
||||||
|
border.color: "#25dedede"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,206 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Latte-Dock
|
||||||
|
*
|
||||||
|
* Latte-Dock 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 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Latte-Dock 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
import org.kde.plasma.plasmoid 2.0
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: upperIndicators
|
||||||
|
spacing: 2
|
||||||
|
readonly property bool alwaysActive: true
|
||||||
|
readonly property bool reversed: true
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: indicator.isTask && (indicator.isActive || indicator.hasActive) ? 1 : 0
|
||||||
|
delegate: triangleComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Grid {
|
||||||
|
id: lowerIndicators
|
||||||
|
rows: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? 1 : Math.min(3, indicator.windowsCount)
|
||||||
|
columns: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? Math.min(3, indicator.windowsCount) : 1
|
||||||
|
rowSpacing: 2
|
||||||
|
columnSpacing: 2
|
||||||
|
|
||||||
|
readonly property bool alwaysActive: false
|
||||||
|
readonly property bool reversed: false
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: Math.min(3, indicator.windowsCount)
|
||||||
|
delegate: triangleComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Triangle Indicator Component
|
||||||
|
Component {
|
||||||
|
id: triangleComponent
|
||||||
|
Canvas {
|
||||||
|
id: canvas
|
||||||
|
width: indicator.currentIconSize / 6
|
||||||
|
height: width
|
||||||
|
|
||||||
|
rotation: {
|
||||||
|
if (!parent.reversed) {
|
||||||
|
if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
|
||||||
|
return 0;
|
||||||
|
} else if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
|
||||||
|
return 90;
|
||||||
|
} else if (plasmoid.location === PlasmaCore.Types.TopEdge) {
|
||||||
|
return 180;
|
||||||
|
} else if (plasmoid.location === PlasmaCore.Types.RightEdge) {
|
||||||
|
return 270;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
|
||||||
|
return 180;
|
||||||
|
} else if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
|
||||||
|
return 270;
|
||||||
|
} else if (plasmoid.location === PlasmaCore.Types.TopEdge) {
|
||||||
|
return 0;
|
||||||
|
} else if (plasmoid.location === PlasmaCore.Types.RightEdge) {
|
||||||
|
return 90;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool fillTriangle: {
|
||||||
|
if (!parent.alwaysActive && indicator.windowsMinimizedCount!==0
|
||||||
|
&& ((index < maxDrawnMinimizedWindows)
|
||||||
|
|| (indicator.windowsCount === indicator.windowsMinimizedCount))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property int lineWidth: 2
|
||||||
|
|
||||||
|
onFillTriangleChanged: requestPaint();
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
onActiveColorChanged: canvas.requestPaint();
|
||||||
|
onBackgroundColorChanged: canvas.requestPaint();
|
||||||
|
onOutlineColorChanged: canvas.requestPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onPaint: {
|
||||||
|
var ctx = getContext('2d');
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
ctx.strokeStyle = root.outlineColor;
|
||||||
|
ctx.lineWidth = lineWidth;
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(0, canvas.height);
|
||||||
|
ctx.lineTo(canvas.width/2, 0);
|
||||||
|
ctx.lineTo(canvas.width, canvas.height);
|
||||||
|
ctx.lineTo(0, canvas.height);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
ctx.strokeStyle = root.activeColor;
|
||||||
|
ctx.fillStyle = fillTriangle ? root.activeColor : root.backgroundColor;
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(lineWidth, canvas.height - lineWidth);
|
||||||
|
ctx.lineTo(canvas.width/2, lineWidth);
|
||||||
|
ctx.lineTo(canvas.width - lineWidth, canvas.height - lineWidth);
|
||||||
|
ctx.lineTo(lineWidth, canvas.height - lineWidth);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! States
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "bottom"
|
||||||
|
when: (plasmoid.location === PlasmaCore.Types.BottomEdge)
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: lowerIndicators
|
||||||
|
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined;
|
||||||
|
horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
|
||||||
|
}
|
||||||
|
AnchorChanges {
|
||||||
|
target: upperIndicators
|
||||||
|
anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined;
|
||||||
|
horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "top"
|
||||||
|
when: (plasmoid.location === PlasmaCore.Types.TopEdge)
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: lowerIndicators
|
||||||
|
anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined;
|
||||||
|
horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
|
||||||
|
}
|
||||||
|
AnchorChanges {
|
||||||
|
target: upperIndicators
|
||||||
|
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined;
|
||||||
|
horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "left"
|
||||||
|
when: (plasmoid.location === PlasmaCore.Types.LeftEdge)
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: lowerIndicators
|
||||||
|
anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined;
|
||||||
|
horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
|
||||||
|
}
|
||||||
|
AnchorChanges {
|
||||||
|
target: upperIndicators
|
||||||
|
anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right;
|
||||||
|
horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "right"
|
||||||
|
when: (plasmoid.location === PlasmaCore.Types.RightEdge)
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: lowerIndicators
|
||||||
|
anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right;
|
||||||
|
horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
|
||||||
|
}
|
||||||
|
AnchorChanges {
|
||||||
|
target: upperIndicators
|
||||||
|
anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined;
|
||||||
|
horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Latte-Dock
|
||||||
|
*
|
||||||
|
* Latte-Dock 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 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Latte-Dock 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
import org.kde.plasma.plasmoid 2.0
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
|
||||||
|
import org.kde.latte.components 1.0 as LatteComponents
|
||||||
|
|
||||||
|
LatteComponents.IndicatorItem {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property bool needsIconColors: true
|
||||||
|
readonly property bool providesFrontLayer: true
|
||||||
|
|
||||||
|
readonly property int thickness: plasmoid.formFactor === PlasmaCore.Types.Vertical ? width : height
|
||||||
|
|
||||||
|
readonly property int shownWindows: indicator.windowsCount - indicator.windowsMinimizedCount
|
||||||
|
readonly property int maxDrawnMinimizedWindows: shownWindows > 0 ? Math.min(indicator.windowsMinimizedCount,2) : 3
|
||||||
|
|
||||||
|
readonly property real backColorBrightness: colorBrightness(indicator.palette.backgroundColor)
|
||||||
|
readonly property color activeColor: indicator.palette.buttonFocusColor
|
||||||
|
readonly property color outlineColor: backColorBrightness < 127 ? indicator.palette.backgroundColor : indicator.palette.textColor
|
||||||
|
readonly property color backgroundColor: indicator.palette.backgroundColor
|
||||||
|
|
||||||
|
function colorBrightness(color) {
|
||||||
|
return colorBrightnessFromRGB(color.r * 255, color.g * 255, color.b * 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
// formula for brightness according to:
|
||||||
|
// https://www.w3.org/TR/AERT/#color-contrast
|
||||||
|
function colorBrightnessFromRGB(r, g, b) {
|
||||||
|
return (r * 299 + g * 587 + b * 114) / 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Background Layer
|
||||||
|
Loader{
|
||||||
|
id: backLayer
|
||||||
|
anchors.fill: parent
|
||||||
|
active: attributes.isBackground
|
||||||
|
|
||||||
|
sourceComponent: BackLayer{}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Foreground Layer to draw Triangles
|
||||||
|
Loader{
|
||||||
|
id: frontLayer
|
||||||
|
anchors.fill: parent
|
||||||
|
active: attributes.isForeground
|
||||||
|
|
||||||
|
sourceComponent:FrontLayer{}
|
||||||
|
}
|
||||||
|
}
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com>
|
|
||||||
*
|
|
||||||
* This file is part of Latte-Dock
|
|
||||||
*
|
|
||||||
* Latte-Dock 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 2 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Latte-Dock 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function colorBrightness(color) {
|
|
||||||
return colorBrightnessFromRGB(color.r * 255, color.g * 255, color.b * 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
// formula for brightness according to:
|
|
||||||
// https://www.w3.org/TR/AERT/#color-contrast
|
|
||||||
function colorBrightnessFromRGB(r, g, b) {
|
|
||||||
return (r * 299 + g * 587 + b * 114) / 1000
|
|
||||||
}
|
|
||||||
|
|
||||||
function colorLuminas(color) {
|
|
||||||
return colorLuminasFromRGB(color.r, color.g, color.b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// formula for luminance according to:
|
|
||||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
|
|
||||||
function colorLuminasFromRGB(r, g, b) {
|
|
||||||
var rS = (r <= 0.03928) ? ( r / 12.92) : Math.pow( ((r + 0.055) / 1.055), 2.4 );
|
|
||||||
var gS = (g <= 0.03928) ? ( g / 12.92) : Math.pow( ((g + 0.055) / 1.055), 2.4 );
|
|
||||||
var bS = (b <= 0.03928) ? ( b / 12.92) : Math.pow( ((b + 0.055) / 1.055), 2.4 );
|
|
||||||
|
|
||||||
return 0.2126*rS + 0.7152*gS + 0.0722*bS;
|
|
||||||
}
|
|
@ -1,238 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
|
|
||||||
*
|
|
||||||
* This file is part of Latte-Dock
|
|
||||||
*
|
|
||||||
* Latte-Dock 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 2 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Latte-Dock 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.0
|
|
||||||
|
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
|
||||||
|
|
||||||
import org.kde.latte 0.2 as Latte
|
|
||||||
|
|
||||||
Item {
|
|
||||||
readonly property Item options: parent.manager
|
|
||||||
readonly property Item rootItem: parent
|
|
||||||
|
|
||||||
readonly property bool providesFrontLayer: true
|
|
||||||
|
|
||||||
//! Background Layer
|
|
||||||
Loader{
|
|
||||||
id: backLayer
|
|
||||||
anchors.fill: parent
|
|
||||||
active: rootItem.isBackLayer
|
|
||||||
|
|
||||||
sourceComponent: PlasmaCore.FrameSvgItem {
|
|
||||||
id: frame
|
|
||||||
property string basePrefix: "normal"
|
|
||||||
|
|
||||||
imagePath: options.explicit.usePlasmaTabsStyle ? "widgets/tabbar" : "widgets/tasks"
|
|
||||||
|
|
||||||
prefix: {
|
|
||||||
if (options.explicit.usePlasmaTabsStyle) {
|
|
||||||
if (!options.isActive) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((plasmoid.location === PlasmaCore.Types.LeftEdge && !options.common.reversedEnabled)
|
|
||||||
|| (plasmoid.location === PlasmaCore.Types.RightEdge && options.common.reversedEnabled)) {
|
|
||||||
return "west-active-tab";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((plasmoid.location === PlasmaCore.Types.TopEdge && !options.common.reversedEnabled)
|
|
||||||
|| (plasmoid.location === PlasmaCore.Types.BottomEdge && options.common.reversedEnabled)) {
|
|
||||||
return "north-active-tab";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((plasmoid.location === PlasmaCore.Types.RightEdge && !options.common.reversedEnabled)
|
|
||||||
|| (plasmoid.location === PlasmaCore.Types.LeftEdge && options.common.reversedEnabled)) {
|
|
||||||
return "east-active-tab";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((plasmoid.location === PlasmaCore.Types.BottomEdge && !options.common.reversedEnabled)
|
|
||||||
|| (plasmoid.location === PlasmaCore.Types.TopEdge && options.common.reversedEnabled)) {
|
|
||||||
return "south-active-tab";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "south-active-tab";
|
|
||||||
} else {
|
|
||||||
return taskPrefix(basePrefix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function taskPrefix(prefix) {
|
|
||||||
var effectivePrefix;
|
|
||||||
|
|
||||||
if ((plasmoid.location === PlasmaCore.Types.LeftEdge && !options.common.reversedEnabled)
|
|
||||||
|| (plasmoid.location === PlasmaCore.Types.RightEdge && options.common.reversedEnabled)) {
|
|
||||||
effectivePrefix = "west-" + prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((plasmoid.location === PlasmaCore.Types.TopEdge && !options.common.reversedEnabled)
|
|
||||||
|| (plasmoid.location === PlasmaCore.Types.BottomEdge && options.common.reversedEnabled)) {
|
|
||||||
effectivePrefix = "north-" + prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((plasmoid.location === PlasmaCore.Types.RightEdge && !options.common.reversedEnabled)
|
|
||||||
|| (plasmoid.location === PlasmaCore.Types.LeftEdge && options.common.reversedEnabled)) {
|
|
||||||
effectivePrefix = "east-" + prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((plasmoid.location === PlasmaCore.Types.BottomEdge && !options.common.reversedEnabled)
|
|
||||||
|| (plasmoid.location === PlasmaCore.Types.TopEdge && options.common.reversedEnabled)) {
|
|
||||||
effectivePrefix = "south-" + prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [effectivePrefix, prefix];
|
|
||||||
}
|
|
||||||
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: "launcher"
|
|
||||||
when: options.isLauncher || (options.isApplet && !options.isActive)
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
target: frame
|
|
||||||
basePrefix: ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "hovered"
|
|
||||||
when: options.isHovered && frame.hasElementPrefix("hover")
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
target: frame
|
|
||||||
basePrefix: "hover"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "attention"
|
|
||||||
when: options.inAttention
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
target: frame
|
|
||||||
basePrefix: "attention"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "minimized"
|
|
||||||
when: options.isMinimized
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
target: frame
|
|
||||||
basePrefix: "minimized"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "active"
|
|
||||||
when: options.isActive
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
target: frame
|
|
||||||
basePrefix: "focus"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Foreground Layer to draw arrows
|
|
||||||
Loader{
|
|
||||||
id: frontLayer
|
|
||||||
anchors.fill: parent
|
|
||||||
active: !rootItem.isBackLayer && !options.isApplet && options.isGroup
|
|
||||||
|
|
||||||
sourceComponent: Item {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
PlasmaCore.Svg {
|
|
||||||
id: taskSvg
|
|
||||||
imagePath: "widgets/tasks"
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: iconBox
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: options.currentIconSize
|
|
||||||
height: width
|
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaCore.SvgItem {
|
|
||||||
id: arrow
|
|
||||||
|
|
||||||
implicitWidth: 0.25 * iconBox.width
|
|
||||||
implicitHeight: implicitWidth
|
|
||||||
|
|
||||||
svg: taskSvg
|
|
||||||
elementId: elementForLocation(plasmoid.location)
|
|
||||||
|
|
||||||
function elementForLocation(location) {
|
|
||||||
switch (location) {
|
|
||||||
case PlasmaCore.Types.LeftEdge:
|
|
||||||
return "group-expander-left";
|
|
||||||
case PlasmaCore.Types.TopEdge:
|
|
||||||
return "group-expander-top";
|
|
||||||
case PlasmaCore.Types.RightEdge:
|
|
||||||
return "group-expander-right";
|
|
||||||
case PlasmaCore.Types.BottomEdge:
|
|
||||||
default:
|
|
||||||
return "group-expander-bottom";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: "bottom"
|
|
||||||
when: plasmoid.location == PlasmaCore.Types.BottomEdge
|
|
||||||
AnchorChanges {
|
|
||||||
target: arrow
|
|
||||||
anchors.top: undefined; anchors.left: undefined; anchors.right: undefined; anchors.bottom: arrow.parent.bottom;
|
|
||||||
anchors.horizontalCenter: iconBox.horizontalCenter; anchors.verticalCenter: undefined;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "top"
|
|
||||||
when: plasmoid.location == PlasmaCore.Types.TopEdge
|
|
||||||
AnchorChanges {
|
|
||||||
target: arrow
|
|
||||||
anchors.top: arrow.parent.top; anchors.left: undefined; anchors.right: undefined; anchors.bottom: undefined;
|
|
||||||
anchors.horizontalCenter: iconBox.horizontalCenter; anchors.verticalCenter: undefined;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "left"
|
|
||||||
when: plasmoid.location == PlasmaCore.Types.LeftEdge
|
|
||||||
AnchorChanges {
|
|
||||||
target: arrow
|
|
||||||
anchors.top: undefined; anchors.left: arrow.parent.left; anchors.right: undefined; anchors.bottom: undefined;
|
|
||||||
anchors.horizontalCenter: undefined; anchors.verticalCenter: iconBox.verticalCenter;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "right"
|
|
||||||
when: plasmoid.location == PlasmaCore.Types.RightEdge
|
|
||||||
AnchorChanges {
|
|
||||||
target: arrow
|
|
||||||
anchors.top: undefined; anchors.left: undefined; anchors.right: arrow.parent.right; anchors.bottom: undefined;
|
|
||||||
anchors.horizontalCenter: undefined; anchors.verticalCenter: iconBox.verticalCenter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,372 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
|
|
||||||
*
|
|
||||||
* This file is part of Latte-Dock
|
|
||||||
*
|
|
||||||
* Latte-Dock 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 2 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Latte-Dock 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.0
|
|
||||||
import QtGraphicalEffects 1.0
|
|
||||||
|
|
||||||
import org.kde.plasma.plasmoid 2.0
|
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
|
||||||
|
|
||||||
import org.kde.latte 0.2 as Latte
|
|
||||||
|
|
||||||
import "../code/ColorizerTools.js" as ColorizerTools
|
|
||||||
|
|
||||||
Item{
|
|
||||||
id: indicatorItem
|
|
||||||
readonly property Item options: parent.manager
|
|
||||||
readonly property Item rootItem: parent
|
|
||||||
|
|
||||||
readonly property bool needsIconColors: true
|
|
||||||
readonly property bool providesFrontLayer: true
|
|
||||||
|
|
||||||
readonly property int thickness: plasmoid.formFactor === PlasmaCore.Types.Vertical ? width : height
|
|
||||||
|
|
||||||
readonly property int shownWindows: options.windowsCount - options.windowsMinimizedCount
|
|
||||||
readonly property int maxDrawnMinimizedWindows: shownWindows > 0 ? Math.min(options.windowsMinimizedCount,2) : 3
|
|
||||||
|
|
||||||
readonly property real backColorBrightness: ColorizerTools.colorBrightness(theme.backgroundColor)
|
|
||||||
readonly property color backgroundColor: backColorBrightness < 127 ? theme.backgroundColor : theme.textColor
|
|
||||||
|
|
||||||
//! Background Layer
|
|
||||||
Loader{
|
|
||||||
id: backLayer
|
|
||||||
anchors.fill: parent
|
|
||||||
active: rootItem.isBackLayer
|
|
||||||
|
|
||||||
sourceComponent: Item{
|
|
||||||
Item{
|
|
||||||
id: rectangleItem
|
|
||||||
width: options.isTask ? Math.min(parent.width, parent.height) : parent.width
|
|
||||||
height: options.isTask ? width : parent.height
|
|
||||||
anchors.centerIn: parent
|
|
||||||
|
|
||||||
property bool isActive: options.isActive || (options.isWindow && options.hasActive)
|
|
||||||
readonly property int size: Math.min(parent.width, parent.height)
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: unityRect
|
|
||||||
anchors.fill: parent
|
|
||||||
visible: options.isActive || (options.isWindow && options.hasShown)
|
|
||||||
|
|
||||||
radius: options.currentIconSize / 12
|
|
||||||
color: options.backgroundColor
|
|
||||||
clip: true
|
|
||||||
}
|
|
||||||
|
|
||||||
RadialGradient{
|
|
||||||
id: glowGradient
|
|
||||||
anchors.verticalCenter: parent.top
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
width: parent.width - unityRect.anchors.margins * 2 - 1
|
|
||||||
height: (width * 0.85) - unityRect.anchors.margins * 2 - 1
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
gradient: Gradient {
|
|
||||||
GradientStop { position: 0.0;
|
|
||||||
color: {
|
|
||||||
if (options.isMinimized) {
|
|
||||||
return "#aafcfcfc";
|
|
||||||
}
|
|
||||||
|
|
||||||
return options.glowColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GradientStop { position: 0.6; color: "transparent" }
|
|
||||||
}
|
|
||||||
//! States
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: "top"
|
|
||||||
when: !options.common.reversedEnabled
|
|
||||||
|
|
||||||
AnchorChanges {
|
|
||||||
target: glowGradient
|
|
||||||
anchors{horizontalCenter:parent.horizontalCenter; verticalCenter:parent.top}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "bottom"
|
|
||||||
when: options.common.reversedEnabled
|
|
||||||
|
|
||||||
AnchorChanges {
|
|
||||||
target: glowGradient
|
|
||||||
anchors{horizontalCenter:parent.horizontalCenter; verticalCenter:parent.bottom}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: gradientMask
|
|
||||||
anchors.fill: glowGradient
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: glowMaskRect
|
|
||||||
width: glowGradient.width
|
|
||||||
height: glowGradient.height / 2
|
|
||||||
radius: unityRect.radius
|
|
||||||
|
|
||||||
//! States
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: "top"
|
|
||||||
when: !options.common.reversedEnabled
|
|
||||||
|
|
||||||
AnchorChanges {
|
|
||||||
target: glowMaskRect
|
|
||||||
anchors{bottom: undefined; top: parent.verticalCenter;}
|
|
||||||
}
|
|
||||||
PropertyChanges{
|
|
||||||
target: gradientMask
|
|
||||||
anchors{bottomMargin: undefined; topMargin: unityRect.anchors.margins}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "bottom"
|
|
||||||
when: options.common.reversedEnabled
|
|
||||||
|
|
||||||
AnchorChanges {
|
|
||||||
target: glowMaskRect
|
|
||||||
anchors{bottom: parent.verticalCenter; top: undefined;}
|
|
||||||
}
|
|
||||||
PropertyChanges{
|
|
||||||
target: gradientMask
|
|
||||||
anchors{bottomMargin: unityRect.anchors.margins; topMargin: undefined}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
visible: false
|
|
||||||
}
|
|
||||||
|
|
||||||
OpacityMask {
|
|
||||||
anchors.fill: glowGradient
|
|
||||||
source: glowGradient
|
|
||||||
maskSource: gradientMask
|
|
||||||
visible: unityRect.visible || borderRectangle.visible
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: borderRectangle
|
|
||||||
anchors.fill: parent
|
|
||||||
visible: (options.isTask && options.isWindow) || (options.isApplet && options.isActive)
|
|
||||||
color: "transparent"
|
|
||||||
border.width: 1
|
|
||||||
border.color: "#303030"
|
|
||||||
radius: unityRect.radius
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: parent.border.width
|
|
||||||
radius: unityRect.radius
|
|
||||||
color: "transparent"
|
|
||||||
border.width: 1
|
|
||||||
border.color: "#25dedede"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Foreground Layer to draw Triangles
|
|
||||||
Loader{
|
|
||||||
id: frontLayer
|
|
||||||
anchors.fill: parent
|
|
||||||
active: !rootItem.isBackLayer
|
|
||||||
|
|
||||||
sourceComponent: Item {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: upperIndicators
|
|
||||||
spacing: 2
|
|
||||||
readonly property bool alwaysActive: true
|
|
||||||
readonly property bool reversed: true
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: options.isTask && (options.isActive || options.hasActive) ? 1 : 0
|
|
||||||
delegate: triangleComponent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Grid {
|
|
||||||
id: lowerIndicators
|
|
||||||
rows: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? 1 : Math.min(3, options.windowsCount)
|
|
||||||
columns: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? Math.min(3, options.windowsCount) : 1
|
|
||||||
rowSpacing: 2
|
|
||||||
columnSpacing: 2
|
|
||||||
|
|
||||||
readonly property bool alwaysActive: false
|
|
||||||
readonly property bool reversed: false
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: Math.min(3, options.windowsCount)
|
|
||||||
delegate: triangleComponent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Triangle Indicator Component
|
|
||||||
Component {
|
|
||||||
id: triangleComponent
|
|
||||||
Canvas {
|
|
||||||
id: canvas
|
|
||||||
width: options.currentIconSize / 6
|
|
||||||
height: width
|
|
||||||
|
|
||||||
rotation: {
|
|
||||||
if (!parent.reversed) {
|
|
||||||
if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
|
|
||||||
return 0;
|
|
||||||
} else if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
|
|
||||||
return 90;
|
|
||||||
} else if (plasmoid.location === PlasmaCore.Types.TopEdge) {
|
|
||||||
return 180;
|
|
||||||
} else if (plasmoid.location === PlasmaCore.Types.RightEdge) {
|
|
||||||
return 270;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
|
|
||||||
return 180;
|
|
||||||
} else if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
|
|
||||||
return 270;
|
|
||||||
} else if (plasmoid.location === PlasmaCore.Types.TopEdge) {
|
|
||||||
return 0;
|
|
||||||
} else if (plasmoid.location === PlasmaCore.Types.RightEdge) {
|
|
||||||
return 90;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
property color drawColor: theme.buttonFocusColor;
|
|
||||||
property bool fillTriangle: {
|
|
||||||
if (!parent.alwaysActive && options.windowsMinimizedCount!==0
|
|
||||||
&& ((index < maxDrawnMinimizedWindows)
|
|
||||||
|| (options.windowsCount === options.windowsMinimizedCount))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property int lineWidth: 2
|
|
||||||
|
|
||||||
onFillTriangleChanged: requestPaint();
|
|
||||||
onDrawColorChanged: requestPaint();
|
|
||||||
|
|
||||||
onPaint: {
|
|
||||||
var ctx = getContext('2d');
|
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
ctx.strokeStyle = indicatorItem.backgroundColor;
|
|
||||||
ctx.lineWidth = lineWidth;
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(0, canvas.height);
|
|
||||||
ctx.lineTo(canvas.width/2, 0);
|
|
||||||
ctx.lineTo(canvas.width, canvas.height);
|
|
||||||
ctx.lineTo(0, canvas.height);
|
|
||||||
ctx.closePath();
|
|
||||||
ctx.stroke();
|
|
||||||
|
|
||||||
ctx.strokeStyle = drawColor;
|
|
||||||
ctx.fillStyle = fillTriangle ? drawColor : indicatorItem.backgroundColor;
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(lineWidth, canvas.height - lineWidth);
|
|
||||||
ctx.lineTo(canvas.width/2, lineWidth);
|
|
||||||
ctx.lineTo(canvas.width - lineWidth, canvas.height - lineWidth);
|
|
||||||
ctx.lineTo(lineWidth, canvas.height - lineWidth);
|
|
||||||
ctx.closePath();
|
|
||||||
ctx.stroke();
|
|
||||||
ctx.fill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//! States
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: "bottom"
|
|
||||||
when: (plasmoid.location === PlasmaCore.Types.BottomEdge)
|
|
||||||
|
|
||||||
AnchorChanges {
|
|
||||||
target: lowerIndicators
|
|
||||||
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined;
|
|
||||||
horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
|
|
||||||
}
|
|
||||||
AnchorChanges {
|
|
||||||
target: upperIndicators
|
|
||||||
anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined;
|
|
||||||
horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "top"
|
|
||||||
when: (plasmoid.location === PlasmaCore.Types.TopEdge)
|
|
||||||
|
|
||||||
AnchorChanges {
|
|
||||||
target: lowerIndicators
|
|
||||||
anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined;
|
|
||||||
horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
|
|
||||||
}
|
|
||||||
AnchorChanges {
|
|
||||||
target: upperIndicators
|
|
||||||
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined;
|
|
||||||
horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "left"
|
|
||||||
when: (plasmoid.location === PlasmaCore.Types.LeftEdge)
|
|
||||||
|
|
||||||
AnchorChanges {
|
|
||||||
target: lowerIndicators
|
|
||||||
anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined;
|
|
||||||
horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
|
|
||||||
}
|
|
||||||
AnchorChanges {
|
|
||||||
target: upperIndicators
|
|
||||||
anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right;
|
|
||||||
horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "right"
|
|
||||||
when: (plasmoid.location === PlasmaCore.Types.RightEdge)
|
|
||||||
|
|
||||||
AnchorChanges {
|
|
||||||
target: lowerIndicators
|
|
||||||
anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right;
|
|
||||||
horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
|
|
||||||
}
|
|
||||||
AnchorChanges {
|
|
||||||
target: upperIndicators
|
|
||||||
anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined;
|
|
||||||
horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue