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