IMPORTANT: All new Indicators architecture

--this huge commit contains all the changes needed
in order for Latte to load Indicators dynamically
from their own packages
pull/5/head
Michail Vourlakos 6 years ago
parent e9599218a2
commit 0b90411b1d

@ -68,6 +68,7 @@ include(Definitions.cmake)
add_subdirectory(declarativeimports) add_subdirectory(declarativeimports)
add_subdirectory(liblatte2) add_subdirectory(liblatte2)
add_subdirectory(indicators)
add_subdirectory(app) add_subdirectory(app)
add_subdirectory(containmentactions) add_subdirectory(containmentactions)
add_subdirectory(containment) add_subdirectory(containment)

@ -9,6 +9,7 @@ set(lattedock-app_SRCS
layoutmanager.cpp layoutmanager.cpp
schemecolors.cpp schemecolors.cpp
screenpool.cpp screenpool.cpp
indicator/factory.cpp
layout/layout.cpp layout/layout.cpp
layout/shortcuts.cpp layout/shortcuts.cpp
package/lattepackage.cpp package/lattepackage.cpp
@ -26,6 +27,7 @@ set(lattedock-app_SRCS
shortcuts/shortcutstracker.cpp shortcuts/shortcutstracker.cpp
view/contextmenu.cpp view/contextmenu.cpp
view/effects.cpp view/effects.cpp
view/indicator.cpp
view/panelshadows.cpp view/panelshadows.cpp
view/positioner.cpp view/positioner.cpp
view/screenedgeghostwindow.cpp view/screenedgeghostwindow.cpp

@ -184,10 +184,27 @@ bool Importer::importOldLayout(QString oldAppletsPath, QString newName, bool alt
return true; return true;
} }
QString Importer::standardPath(QString subPath, bool localfirst) QStringList Importer::standardPaths(bool localfirst)
{ {
QStringList paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); QStringList paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
if (localfirst) {
return paths;
} else {
QStringList reversed;
for (int i=paths.count()-1; i>=0; i--) {
reversed << paths[i];
}
return reversed;
}
}
QString Importer::standardPath(QString subPath, bool localfirst)
{
QStringList paths = standardPaths(localfirst);
if (localfirst) { if (localfirst) {
foreach (auto pt, paths) { foreach (auto pt, paths) {
QString ptF = pt + "/" +subPath; QString ptF = pt + "/" +subPath;

@ -74,6 +74,9 @@ public:
//! returns the standard path found that contains the subPath //! returns the standard path found that contains the subPath
//! local paths have higher priority by default //! local paths have higher priority by default
static QString standardPath(QString subPath, bool localFirst = true); static QString standardPath(QString subPath, bool localFirst = true);
//! returns all application data standard paths
//! local paths have higher priority by default
static QStringList standardPaths(bool localfirst = true);
//! check if this layout exists already in the latte directory //! check if this layout exists already in the latte directory
static bool layoutExists(QString layoutName); static bool layoutExists(QString layoutName);

@ -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");*/
}
}
}
}
}
}
}
}
}

@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com> * Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
* *
* This file is part of Latte-Dock * This file is part of Latte-Dock
* *
@ -17,18 +17,36 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import QtQuick 2.7 #ifndef INDICATORFACTORY_H
#define INDICATORFACTORY_H
import org.kde.plasma.plasmoid 2.0 // Qt
import org.kde.plasma.core 2.0 as PlasmaCore #include <QHash>
#include <QObject>
import org.kde.latte 0.2 as Latte class KPluginMetaData;
Item{ namespace Latte {
id: common namespace Indicator {
readonly property bool indicatorsEnabled: true class Factory : public QObject
readonly property bool reversedEnabled: plasmoid.configuration.reverseLinesPosition {
Q_OBJECT
readonly property int indicatorStyle: Latte.Types.LatteIndicator public:
Factory(QObject *parent);
~Factory() override;
void reload();
KPluginMetaData metadata(QString pluginId);
private:
QHash<QString, KPluginMetaData> m_plugins;
};
}
} }
#endif

@ -27,6 +27,7 @@
#include "launcherssignals.h" #include "launcherssignals.h"
#include "layoutmanager.h" #include "layoutmanager.h"
#include "screenpool.h" #include "screenpool.h"
#include "indicator/factory.h"
#include "shortcuts/globalshortcuts.h" #include "shortcuts/globalshortcuts.h"
#include "package/lattepackage.h" #include "package/lattepackage.h"
#include "plasma/extended/screenpool.h" #include "plasma/extended/screenpool.h"
@ -79,6 +80,7 @@ Corona::Corona(bool defaultLayoutOnStartup, QString layoutNameOnStartUp, int use
m_layoutNameOnStartUp(layoutNameOnStartUp), m_layoutNameOnStartUp(layoutNameOnStartUp),
m_activityConsumer(new KActivities::Consumer(this)), m_activityConsumer(new KActivities::Consumer(this)),
m_screenPool(new ScreenPool(KSharedConfig::openConfig(), this)), m_screenPool(new ScreenPool(KSharedConfig::openConfig(), this)),
m_indicatorFactory(new Indicator::Factory(this)),
m_universalSettings(new UniversalSettings(KSharedConfig::openConfig(), this)), m_universalSettings(new UniversalSettings(KSharedConfig::openConfig(), this)),
m_globalShortcuts(new GlobalShortcuts(this)), m_globalShortcuts(new GlobalShortcuts(this)),
m_plasmaScreenPool(new PlasmaExtended::ScreenPool(this)), m_plasmaScreenPool(new PlasmaExtended::ScreenPool(this)),
@ -178,6 +180,7 @@ Corona::~Corona()
m_plasmaScreenPool->deleteLater(); m_plasmaScreenPool->deleteLater();
m_backgroundTracer->deleteLater(); m_backgroundTracer->deleteLater();
m_themeExtended->deleteLater(); m_themeExtended->deleteLater();
m_indicatorFactory->deleteLater();
disconnect(m_activityConsumer, &KActivities::Consumer::serviceStatusChanged, this, &Corona::load); disconnect(m_activityConsumer, &KActivities::Consumer::serviceStatusChanged, this, &Corona::load);
delete m_activityConsumer; delete m_activityConsumer;
@ -392,6 +395,11 @@ AbstractWindowInterface *Corona::wm() const
return m_wm; return m_wm;
} }
Indicator::Factory *Corona::indicatorFactory() const
{
return m_indicatorFactory;
}
PlasmaExtended::ScreenPool *Corona::plasmaScreenPool() const PlasmaExtended::ScreenPool *Corona::plasmaScreenPool() const
{ {
return m_plasmaScreenPool; return m_plasmaScreenPool;

@ -66,6 +66,9 @@ class GlobalShortcuts;
class UniversalSettings; class UniversalSettings;
class LayoutManager; class LayoutManager;
class LaunchersSignals; class LaunchersSignals;
namespace Indicator{
class Factory;
}
namespace PlasmaExtended{ namespace PlasmaExtended{
class ScreenPool; class ScreenPool;
class Theme; class Theme;
@ -111,6 +114,8 @@ public:
UniversalSettings *universalSettings() const; UniversalSettings *universalSettings() const;
LayoutManager *layoutManager() const; LayoutManager *layoutManager() const;
Indicator::Factory *indicatorFactory() const;
PlasmaExtended::ScreenPool *plasmaScreenPool() const; PlasmaExtended::ScreenPool *plasmaScreenPool() const;
PlasmaExtended::Theme *themeExtended() const; PlasmaExtended::Theme *themeExtended() const;
@ -189,6 +194,8 @@ private:
GlobalShortcuts *m_globalShortcuts{nullptr}; GlobalShortcuts *m_globalShortcuts{nullptr};
LayoutManager *m_layoutManager{nullptr}; LayoutManager *m_layoutManager{nullptr};
Indicator::Factory *m_indicatorFactory{nullptr};
PlasmaExtended::ScreenPool *m_plasmaScreenPool{nullptr}; PlasmaExtended::ScreenPool *m_plasmaScreenPool{nullptr};
PlasmaExtended::Theme *m_themeExtended{nullptr}; PlasmaExtended::Theme *m_themeExtended{nullptr};

@ -398,7 +398,7 @@ void GlobalShortcuts::activateEntry(int index, Qt::Key modifier)
continue; continue;
} }
if ((!view->latteTasksPresent() && view->tasksPresent() && if ((!view->latteTasksArePresent() && view->tasksPresent() &&
activatePlasmaTaskManagerEntryAtContainment(view->containment(), index, modifier)) activatePlasmaTaskManagerEntryAtContainment(view->containment(), index, modifier))
|| activateLatteEntryAtContainment(view, index, modifier)) { || activateLatteEntryAtContainment(view, index, modifier)) {
@ -475,7 +475,7 @@ void GlobalShortcuts::updateViewItemBadge(QString identifier, QString value)
bool GlobalShortcuts::isCapableToShowShortcutBadges(Latte::View *view) bool GlobalShortcuts::isCapableToShowShortcutBadges(Latte::View *view)
{ {
if (!view->latteTasksPresent() && view->tasksPresent()) { if (!view->latteTasksArePresent() && view->tasksPresent()) {
return false; return false;
} }

@ -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

@ -74,9 +74,9 @@ View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassWM)
setClearBeforeRendering(true); setClearBeforeRendering(true);
const auto flags = Qt::FramelessWindowHint const auto flags = Qt::FramelessWindowHint
| Qt::WindowStaysOnTopHint | Qt::WindowStaysOnTopHint
| Qt::NoDropShadowWindowHint | Qt::NoDropShadowWindowHint
| Qt::WindowDoesNotAcceptFocus; | Qt::WindowDoesNotAcceptFocus;
if (byPassWM) { if (byPassWM) {
setFlags(flags | Qt::BypassWindowManagerHint); setFlags(flags | Qt::BypassWindowManagerHint);
@ -92,7 +92,7 @@ View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassWM)
m_positioner->setScreenToFollow(qGuiApp->primaryScreen()); m_positioner->setScreenToFollow(qGuiApp->primaryScreen());
connect(this, &View::containmentChanged connect(this, &View::containmentChanged
, this, [ &, byPassWM]() { , this, [ &, byPassWM]() {
qDebug() << "dock view c++ containment changed 1..."; qDebug() << "dock view c++ containment changed 1...";
if (!this->containment()) if (!this->containment())
@ -112,6 +112,7 @@ View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassWM)
//! needs to be created before visibility creation because visibility uses it //! needs to be created before visibility creation because visibility uses it
if (!m_windowsTracker) { if (!m_windowsTracker) {
m_windowsTracker = new ViewPart::WindowsTracker(this); m_windowsTracker = new ViewPart::WindowsTracker(this);
emit windowsTrackerChanged();
} }
if (!m_visibility) { if (!m_visibility) {
@ -122,6 +123,13 @@ View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassWM)
deactivateApplets(); deactivateApplets();
} }
}); });
emit visibilityChanged();
}
if (!m_indicator) {
m_indicator = new ViewPart::Indicator(this);
emit indicatorChanged();
} }
connect(this->containment(), SIGNAL(statusChanged(Plasma::Types::ItemStatus)), SLOT(statusChanged(Plasma::Types::ItemStatus))); connect(this->containment(), SIGNAL(statusChanged(Plasma::Types::ItemStatus)), SLOT(statusChanged(Plasma::Types::ItemStatus)));
@ -168,6 +176,10 @@ View::~View()
delete m_positioner; delete m_positioner;
} }
if (m_indicator) {
delete m_indicator;
}
if (m_effects) { if (m_effects) {
delete m_effects; delete m_effects;
} }
@ -414,7 +426,7 @@ void View::updateAbsDockGeometry(bool bypassChecks)
//! behavior and keeping this comment in order to check for //! behavior and keeping this comment in order to check for
//! multi-screen breakage //! multi-screen breakage
QRect absGeometry {x() + m_localGeometry.x(), y() + m_localGeometry.y() QRect absGeometry {x() + m_localGeometry.x(), y() + m_localGeometry.y()
, m_localGeometry.width(), m_localGeometry.height()}; , m_localGeometry.width(), m_localGeometry.height()};
if (m_absGeometry == absGeometry && !bypassChecks) if (m_absGeometry == absGeometry && !bypassChecks)
return; return;
@ -433,7 +445,7 @@ void View::statusChanged(Plasma::Types::ItemStatus status)
{ {
if (containment()) { if (containment()) {
if (containment()->status() >= Plasma::Types::NeedsAttentionStatus && if (containment()->status() >= Plasma::Types::NeedsAttentionStatus &&
containment()->status() != Plasma::Types::HiddenStatus) { containment()->status() != Plasma::Types::HiddenStatus) {
setBlockHiding(true); setBlockHiding(true);
} else if (!containment()->isUserConfiguring()){ } else if (!containment()->isUserConfiguring()){
setBlockHiding(false); setBlockHiding(false);
@ -578,6 +590,21 @@ void View::setIsPreferredForShortcuts(bool preferred)
} }
} }
bool View::latteTasksArePresent() const
{
return m_latteTasksArePresent;
}
void View::setLatteTasksArePresent(bool present)
{
if (m_latteTasksArePresent == present) {
return;
}
m_latteTasksArePresent = present;
emit latteTasksArePresentChanged();
}
void View::preferredViewForShortcutsChangedSlot(Latte::View *view) void View::preferredViewForShortcutsChangedSlot(Latte::View *view)
{ {
if (view != this) { if (view != this) {
@ -920,26 +947,6 @@ bool View::tasksPresent()
return false; return false;
} }
//! check if the tasks plasmoid exist in the dock
bool View::latteTasksPresent()
{
if (!this->containment()) {
return false;
}
foreach (Plasma::Applet *applet, this->containment()->applets()) {
KPluginMetaData metadata = applet->pluginMetaData();
if (metadata.pluginId() == "org.kde.latte.plasmoid") {
return true;
}
}
return false;
}
//!check if the plasmoid with _name_ exists in the midedata //!check if the plasmoid with _name_ exists in the midedata
bool View::mimeContainsPlasmoid(QMimeData *mimeData, QString name) bool View::mimeContainsPlasmoid(QMimeData *mimeData, QString name)
{ {
@ -965,6 +972,11 @@ ViewPart::Effects *View::effects() const
return m_effects; return m_effects;
} }
ViewPart::Indicator *View::indicator() const
{
return m_indicator;
}
ViewPart::Positioner *View::positioner() const ViewPart::Positioner *View::positioner() const
{ {
return m_positioner; return m_positioner;
@ -986,56 +998,56 @@ bool View::event(QEvent *e)
emit eventTriggered(e); emit eventTriggered(e);
switch (e->type()) { switch (e->type()) {
case QEvent::Enter: case QEvent::Enter:
m_containsMouse = true; m_containsMouse = true;
if (m_configView && KWindowSystem::isPlatformX11()) {
ViewPart::PrimaryConfigView *primaryConfigView = qobject_cast<ViewPart::PrimaryConfigView *>(m_configView);
if (primaryConfigView) { if (m_configView && KWindowSystem::isPlatformX11()) {
if (primaryConfigView->secondaryWindow()) { ViewPart::PrimaryConfigView *primaryConfigView = qobject_cast<ViewPart::PrimaryConfigView *>(m_configView);
primaryConfigView->secondaryWindow()->requestActivate();
}
primaryConfigView->requestActivate(); if (primaryConfigView) {
if (primaryConfigView->secondaryWindow()) {
primaryConfigView->secondaryWindow()->requestActivate();
} }
primaryConfigView->requestActivate();
} }
break; }
break;
case QEvent::Leave:
m_containsMouse = false; case QEvent::Leave:
engine()->trimComponentCache(); m_containsMouse = false;
break; engine()->trimComponentCache();
break;
case QEvent::PlatformSurface:
if (auto pe = dynamic_cast<QPlatformSurfaceEvent *>(e)) { case QEvent::PlatformSurface:
switch (pe->surfaceEventType()) { if (auto pe = dynamic_cast<QPlatformSurfaceEvent *>(e)) {
case QPlatformSurfaceEvent::SurfaceCreated: switch (pe->surfaceEventType()) {
setupWaylandIntegration(); case QPlatformSurfaceEvent::SurfaceCreated:
setupWaylandIntegration();
if (m_shellSurface) {
m_positioner->syncGeometry(); if (m_shellSurface) {
m_effects->updateShadows(); m_positioner->syncGeometry();
} m_effects->updateShadows();
break;
case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed:
if (m_shellSurface) {
delete m_shellSurface;
m_shellSurface = nullptr;
qDebug() << "WAYLAND dock window surface was deleted...";
m_effects->clearShadows();
}
break;
} }
break;
case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed:
if (m_shellSurface) {
delete m_shellSurface;
m_shellSurface = nullptr;
qDebug() << "WAYLAND dock window surface was deleted...";
m_effects->clearShadows();
}
break;
} }
}
break; break;
default: default:
break; break;
} }
} }

@ -23,6 +23,7 @@
// local // local
#include "effects.h" #include "effects.h"
#include "indicator.h"
#include "positioner.h" #include "positioner.h"
#include "visibilitymanager.h" #include "visibilitymanager.h"
#include "windowstracker.h" #include "windowstracker.h"
@ -80,6 +81,7 @@ class View : public PlasmaQuick::ContainmentView
//! when the isUserConfiguring changes value //! when the isUserConfiguring changes value
Q_PROPERTY(bool inEditMode READ inEditMode WRITE setInEditMode NOTIFY inEditModeChanged) Q_PROPERTY(bool inEditMode READ inEditMode WRITE setInEditMode NOTIFY inEditModeChanged)
Q_PROPERTY(bool isPreferredForShortcuts READ isPreferredForShortcuts WRITE setIsPreferredForShortcuts NOTIFY isPreferredForShortcutsChanged) Q_PROPERTY(bool isPreferredForShortcuts READ isPreferredForShortcuts WRITE setIsPreferredForShortcuts NOTIFY isPreferredForShortcutsChanged)
Q_PROPERTY(bool latteTasksArePresent READ latteTasksArePresent WRITE setLatteTasksArePresent NOTIFY latteTasksArePresentChanged)
Q_PROPERTY(bool onPrimary READ onPrimary WRITE setOnPrimary NOTIFY onPrimaryChanged) Q_PROPERTY(bool onPrimary READ onPrimary WRITE setOnPrimary NOTIFY onPrimaryChanged)
Q_PROPERTY(int alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged) Q_PROPERTY(int alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged)
@ -95,8 +97,9 @@ class View : public PlasmaQuick::ContainmentView
Q_PROPERTY(float maxLength READ maxLength WRITE setMaxLength NOTIFY maxLengthChanged) Q_PROPERTY(float maxLength READ maxLength WRITE setMaxLength NOTIFY maxLengthChanged)
Q_PROPERTY(Latte::ViewPart::Effects *effects READ effects NOTIFY effectsChanged)
Q_PROPERTY(Layout *managedLayout READ managedLayout WRITE setManagedLayout NOTIFY managedLayoutChanged) Q_PROPERTY(Layout *managedLayout READ managedLayout WRITE setManagedLayout NOTIFY managedLayoutChanged)
Q_PROPERTY(Latte::ViewPart::Effects *effects READ effects NOTIFY effectsChanged)
Q_PROPERTY(Latte::ViewPart::Indicator *indicator READ indicator NOTIFY indicatorChanged)
Q_PROPERTY(Latte::ViewPart::Positioner *positioner READ positioner NOTIFY positionerChanged) Q_PROPERTY(Latte::ViewPart::Positioner *positioner READ positioner NOTIFY positionerChanged)
Q_PROPERTY(Latte::ViewPart::VisibilityManager *visibility READ visibility NOTIFY visibilityChanged) Q_PROPERTY(Latte::ViewPart::VisibilityManager *visibility READ visibility NOTIFY visibilityChanged)
Q_PROPERTY(Latte::ViewPart::WindowsTracker *windowsTracker READ windowsTracker NOTIFY windowsTrackerChanged) Q_PROPERTY(Latte::ViewPart::WindowsTracker *windowsTracker READ windowsTracker NOTIFY windowsTrackerChanged)
@ -140,6 +143,9 @@ public:
bool isPreferredForShortcuts() const; bool isPreferredForShortcuts() const;
void setIsPreferredForShortcuts(bool preferred); void setIsPreferredForShortcuts(bool preferred);
bool latteTasksArePresent() const;
void setLatteTasksArePresent(bool present);
float maxLength() const; float maxLength() const;
void setMaxLength(float length); void setMaxLength(float length);
@ -173,6 +179,7 @@ public:
PlasmaQuick::ConfigView *configView(); PlasmaQuick::ConfigView *configView();
ViewPart::Effects *effects() const; ViewPart::Effects *effects() const;
ViewPart::Indicator *indicator() const;
ViewPart::Positioner *positioner() const; ViewPart::Positioner *positioner() const;
ViewPart::VisibilityManager *visibility() const; ViewPart::VisibilityManager *visibility() const;
ViewPart::WindowsTracker *windowsTracker() const; ViewPart::WindowsTracker *windowsTracker() const;
@ -202,7 +209,6 @@ public slots:
Q_INVOKABLE bool mimeContainsPlasmoid(QMimeData *mimeData, QString name); Q_INVOKABLE bool mimeContainsPlasmoid(QMimeData *mimeData, QString name);
Q_INVOKABLE bool tasksPresent(); Q_INVOKABLE bool tasksPresent();
Q_INVOKABLE bool latteTasksPresent();
void updateAbsDockGeometry(bool bypassChecks = false); void updateAbsDockGeometry(bool bypassChecks = false);
@ -237,7 +243,9 @@ signals:
void widthChanged(); void widthChanged();
void heightChanged(); void heightChanged();
void inEditModeChanged(); void inEditModeChanged();
void indicatorChanged();
void isPreferredForShortcutsChanged(); void isPreferredForShortcutsChanged();
void latteTasksArePresentChanged();
void localGeometryChanged(); void localGeometryChanged();
void managedLayoutChanged(); void managedLayoutChanged();
void maxLengthChanged(); void maxLengthChanged();
@ -281,6 +289,7 @@ private:
bool m_inDelete{false}; bool m_inDelete{false};
bool m_inEditMode{false}; bool m_inEditMode{false};
bool m_isPreferredForShortcuts{false}; bool m_isPreferredForShortcuts{false};
bool m_latteTasksArePresent{false};
bool m_onPrimary{true}; bool m_onPrimary{true};
int m_fontPixelSize{ -1}; int m_fontPixelSize{ -1};
int m_editThickness{24}; int m_editThickness{24};
@ -300,6 +309,7 @@ private:
QPointer<ViewPart::ContextMenu> m_contextMenu; QPointer<ViewPart::ContextMenu> m_contextMenu;
QPointer<ViewPart::Effects> m_effects; QPointer<ViewPart::Effects> m_effects;
QPointer<ViewPart::Indicator> m_indicator;
QPointer<ViewPart::Positioner> m_positioner; QPointer<ViewPart::Positioner> m_positioner;
QPointer<ViewPart::VisibilityManager> m_visibility; QPointer<ViewPart::VisibilityManager> m_visibility;
QPointer<ViewPart::WindowsTracker> m_windowsTracker; QPointer<ViewPart::WindowsTracker> m_windowsTracker;

@ -41,10 +41,6 @@
<default>20</default> <default>20</default>
<label>this is a percentage value</label> <label>this is a percentage value</label>
</entry> </entry>
<entry name="lengthIntMargin" type="Int">
<default>8</default>
<label>this is a percentage value</label>
</entry>
<entry name="lengthExtMargin" type="Int"> <entry name="lengthExtMargin" type="Int">
<default>0</default> <default>0</default>
<label>this is a percentage value</label> <label>this is a percentage value</label>
@ -153,44 +149,6 @@
<entry name="showGlow" type="Bool"> <entry name="showGlow" type="Bool">
<default>false</default> <default>false</default>
</entry> </entry>
<entry name="glowOption" type="Enum">
<label>Glow for active indicators</label>
<choices>
<choice name="None"/>
<choice name="OnActive"/>
<choice name="All"/>
</choices>
<default>0</default>
</entry>
<entry name="glow3D" type="Bool">
<default>true</default>
</entry>
<entry name="glowOpacity" type="Int">
<default>30</default>
</entry>
<entry name="indicatorsEnabled" type="Bool">
<default>true</default>
</entry>
<entry name="indicatorsForApplets" type="Bool">
<default>false</default>
</entry>
<entry name="indicatorStyle" type="Enum">
<label>Indicator style</label>
<choices>
<choice name="LatteIndicator"/>
<choice name="PlasmaIndicator"/>
<choice name="UnityIndicator"/>
</choices>
<default>0</default>
</entry>
<entry name="activeIndicatorType" type="Enum">
<label>Active indicator style</label>
<choices>
<choice name="LineIndicator"/>
<choice name="DotIndicator"/>
</choices>
<default>0</default>
</entry>
<entry name="maxLength" type="Int"> <entry name="maxLength" type="Int">
<default>100</default> <default>100</default>
</entry> </entry>

@ -136,6 +136,13 @@ Item{
value: root.editMode value: root.editMode
} }
Binding{
target: latteView
property:"latteTasksArePresent"
when: latteView
value: latteApplet !== null
}
Binding{ Binding{
target: latteView target: latteView
property: "maxLength" property: "maxLength"
@ -221,7 +228,7 @@ Item{
target: latteView && latteView.windowsTracker ? latteView.windowsTracker : null target: latteView && latteView.windowsTracker ? latteView.windowsTracker : null
property: "enabled" property: "enabled"
when: latteView && latteView.windowsTracker when: latteView && latteView.windowsTracker
value: (latteView.visibility && latteView.visibility.mode === Latte.Types.DodgeAllWindows) value: (latteView && latteView.visibility && latteView.visibility.mode === Latte.Types.DodgeAllWindows)
|| ((root.backgroundOnlyOnMaximized || ((root.backgroundOnlyOnMaximized
|| plasmoid.configuration.solidBackgroundForMaximized || plasmoid.configuration.solidBackgroundForMaximized
|| root.disablePanelShadowMaximized || root.disablePanelShadowMaximized

@ -331,6 +331,12 @@ Item {
if (isHidden) if (isHidden)
parabolicManager.setHidden(previousIndex, -1); parabolicManager.setHidden(previousIndex, -1);
if(root.latteAppletPos>=0 && root.latteAppletPos === index){
root.latteApplet = null;
root.latteAppletContainer = null;
root.latteAppletPos = -1;
}
root.updateIndexes.disconnect(checkIndex); root.updateIndexes.disconnect(checkIndex);
root.clearZoomSignal.disconnect(clearZoom); root.clearZoomSignal.disconnect(clearZoom);
@ -494,14 +500,15 @@ Item {
width: wrapper.width width: wrapper.width
height: wrapper.height height: wrapper.height
Indicator.Manager{ Indicator.Bridge{
id: indicatorManager id: indicatorBridge
} }
//! Indicator Back Layer //! Indicator Back Layer
Indicator.Loader{ Indicator.Loader{
id: indicatorBackLayer id: indicatorBackLayer
manager: indicatorManager bridge: indicatorBridge
isBackground: true
} }
ItemWrapper{ ItemWrapper{
@ -534,8 +541,8 @@ Item {
//! Indicator Front Layer //! Indicator Front Layer
Indicator.Loader{ Indicator.Loader{
id: indicatorFrontLayer id: indicatorFrontLayer
manager: indicatorManager bridge: indicatorBridge
isBackLayer: false isBackground: false
} }
//! Applet Shortcut Visual Badge //! Applet Shortcut Visual Badge
@ -584,7 +591,7 @@ Item {
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
elide: Text.ElideRight elide: Text.ElideRight
fontSizeMode: Text.Fit fontSizeMode: Text.Fit
color: colorizerManager.applyTheme.textColor color: colorizerManager.textColor
rotation: { rotation: {
if (root.isHorizontal) if (root.isHorizontal)

@ -22,16 +22,16 @@ import QtQuick 2.7
import org.kde.latte 0.2 as Latte import org.kde.latte 0.2 as Latte
Item{ Item{
id: indicatorManager id: indicatorBridge
anchors.fill: parent anchors.fill: parent
property bool appletIsValid: true property bool appletIsValid: true
readonly property bool active: appletIsValid && readonly property bool active: appletIsValid &&
((indicators.common.indicatorsEnabled ((indicators.isEnabled
&& appletItem.communicatorAlias.activeIndicatorEnabled && appletItem.communicatorAlias.activeIndicatorEnabled
&& indicators.common.indicatorsForApplets) && indicators.enabledForApplets)
|| (!indicators.common.indicatorsForApplets && appletItem.communicatorAlias.overlayLatteIconIsActive)) || (!indicators.enabledForApplets && appletItem.communicatorAlias.overlayLatteIconIsActive))
/* Indicators Properties in order use them*/ /* Indicators Properties in order use them*/
readonly property bool isTask: false readonly property bool isTask: false
@ -60,11 +60,15 @@ Item{
readonly property real scaleFactor: appletIsValid ? appletItem.wrapperAlias.zoomScale : 1 readonly property real scaleFactor: appletIsValid ? appletItem.wrapperAlias.zoomScale : 1
readonly property color shadowColor: root.appShadowColorSolid readonly property color shadowColor: root.appShadowColorSolid
readonly property bool usePlasmaTabsStyle: !indicators.enabledForApplets
readonly property QtObject palette: colorizerManager.applyTheme
//!icon colors //!icon colors
property color backgroundColor: appletIsValid ? appletItem.wrapperAlias.overlayIconLoader.backgroundColor : "black" property color backgroundColor: appletIsValid ? appletItem.wrapperAlias.overlayIconLoader.backgroundColor : "black"
property color glowColor: appletIsValid ? appletItem.wrapperAlias.overlayIconLoader.glowColor : "white" property color glowColor: appletIsValid ? appletItem.wrapperAlias.overlayIconLoader.glowColor : "white"
//! grouped options //! grouped options
readonly property Item common: indicators.common readonly property Item shared: indicators
readonly property Item explicit: indicators.explicit readonly property QtObject configuration: indicators.configuration
} }

@ -25,15 +25,16 @@ Loader{
id: indicatorLoader id: indicatorLoader
anchors.fill: parent anchors.fill: parent
active: manager && manager.active && (isBackLayer || (!isBackLayer && indicators.info.providesFrontLayer)) active: bridge && bridge.active && (isBackground || (isForeground && indicators.info.providesFrontLayer))
sourceComponent: { sourceComponent: {
if (!indicators.common.indicatorsForApplets && appletItem.communicatorAlias.overlayLatteIconIsActive) { if (!indicators.enabledForApplets && appletItem.communicatorAlias.overlayLatteIconIsActive) {
return indicators.plasmaStyleComponent; return indicators.plasmaStyleComponent;
} }
return indicators.indicatorComponent; return indicators.indicatorComponent;
} }
property bool isBackLayer: true property bool isBackground: true
property Item manager readonly property bool isForeground: !isBackground
property Item bridge
} }

@ -59,11 +59,13 @@ Loader{
readonly property real currentBackgroundBrightness: item ? item.currentBrightness : -1000 readonly property real currentBackgroundBrightness: item ? item.currentBrightness : -1000
readonly property bool applyingWindowColors: (root.windowColors === Latte.Types.ActiveWindowColors && latteView.windowsTracker.activeWindowScheme) readonly property bool applyingWindowColors: (root.windowColors === Latte.Types.ActiveWindowColors && latteView && latteView.windowsTracker
|| (root.windowColors === Latte.Types.TouchingWindowColors && latteView.windowsTracker.touchingWindowScheme) && latteView.windowsTracker.activeWindowScheme)
|| (root.windowColors === Latte.Types.TouchingWindowColors && latteView && latteView.windowsTracker
&& latteView.windowsTracker.touchingWindowScheme)
property QtObject applyTheme: { property QtObject applyTheme: {
if (!root.hasExpandedApplet) { if (latteView && latteView.windowsTracker && !root.hasExpandedApplet) {
if (root.windowColors === Latte.Types.ActiveWindowColors && latteView.windowsTracker.activeWindowScheme) { if (root.windowColors === Latte.Types.ActiveWindowColors && latteView.windowsTracker.activeWindowScheme) {
return latteView.windowsTracker.activeWindowScheme; return latteView.windowsTracker.activeWindowScheme;
} }
@ -110,7 +112,7 @@ Loader{
readonly property color backgroundColor:applyTheme.backgroundColor readonly property color backgroundColor:applyTheme.backgroundColor
readonly property color textColor: { readonly property color textColor: {
if (root.inConfigureAppletsMode && (root.themeColors === Latte.Types.SmartThemeColors)) { if (latteView && latteView.managedLayout && root.inConfigureAppletsMode && (root.themeColors === Latte.Types.SmartThemeColors)) {
return latteView.managedLayout.textColor; return latteView.managedLayout.textColor;
} }

@ -24,29 +24,21 @@ import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.latte 0.2 as Latte import org.kde.latte 0.2 as Latte
import "options" as Options
import "../applet/indicator" as AppletIndicator import "../applet/indicator" as AppletIndicator
Item{ Item{
id: managerIndicator id: managerIndicator
readonly property Item common: commonOptions readonly property QtObject configuration: latteView && latteView.indicator ? latteView.indicator.configuration : null
readonly property Item explicit: explicitOptions.item
readonly property Component plasmaStyleComponent: plasmaStyleIndicator readonly property bool isEnabled: latteView && latteView.indicator ? latteView.indicator.enabled : false
readonly property bool enabledForApplets: latteView && latteView.indicator ? latteView.indicator.enabledForApplets : true
readonly property bool reversed: latteView && latteView.indicator ? latteView.indicator.reversed : false
readonly property real padding: latteView && latteView.indicator ? latteView.indicator.padding: 0.08
readonly property string type: latteView && latteView.indicator ? latteView.indicator.type : "org.kde.latte.indicator.default"
readonly property Component indicatorComponent: { readonly property Component plasmaStyleComponent: latteView && latteView.indicator ? latteView.indicator.plasmaComponent : null
switch (indicators.common.indicatorStyle) { readonly property Component indicatorComponent: latteView && latteView.indicator ? latteView.indicator.component : null
case Latte.Types.LatteIndicator:
return latteStyleIndicator;
case Latte.Types.PlasmaIndicator:
return plasmaStyleIndicator;
case Latte.Types.UnityIndicator:
return unityStyleIndicator;
default:
return latteStyleIndicator;
};
}
readonly property Item info: Item{ readonly property Item info: Item{
readonly property bool needsIconColors: metricsLoader.active && metricsLoader.item && metricsLoader.item.hasOwnProperty("needsIconColors") readonly property bool needsIconColors: metricsLoader.active && metricsLoader.item && metricsLoader.item.hasOwnProperty("needsIconColors")
@ -63,48 +55,14 @@ Item{
} }
} }
Options.Common {
id: commonOptions
}
Loader{
id: explicitOptions
active: true
source: {
if (commonOptions.indicatorStyle === Latte.Types.LatteIndicator) {
return "options/Latte.qml";
} else if (commonOptions.indicatorStyle === Latte.Types.PlasmaIndicator) {
return "options/Plasma.qml";
}
return "options/Latte.qml";
}
}
//! Indicators Components
Component {
id: latteStyleIndicator
Latte.LatteIndicator{}
}
Component {
id: plasmaStyleIndicator
Latte.PlasmaIndicator{}
}
Component{
id:unityStyleIndicator
Latte.UnityIndicator{}
}
//! Metrics and values provided from an invisible indicator //! Metrics and values provided from an invisible indicator
Loader{ Loader{
id: metricsLoader id: metricsLoader
opacity: 0 opacity: 0
active: managerIndicator.isEnabled
readonly property bool isBackLayer: true readonly property bool isBackground: true
readonly property Item manager: AppletIndicator.Manager{ readonly property Item bridge: AppletIndicator.Bridge{
appletIsValid: false appletIsValid: false
} }

@ -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
}

@ -19,6 +19,7 @@
import QtQuick 2.7 import QtQuick 2.7
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.private.pager 2.0 import org.kde.plasma.private.pager 2.0
import org.kde.latte 0.2 as Latte import org.kde.latte 0.2 as Latte
@ -35,7 +36,7 @@ Loader {
enabled: true enabled: true
showDesktop: true showDesktop: true
showOnlyCurrentScreen: true showOnlyCurrentScreen: true
screenGeometry: latteView.screenGeometry screenGeometry: latteView ? latteView.screenGeometry : plasmoid.screenGeometry
pagerType: root.scrollAction === Latte.Types.ScrollDesktops ? PagerModel.VirtualDesktops : PagerModel.Activities pagerType: root.scrollAction === Latte.Types.ScrollDesktops ? PagerModel.VirtualDesktops : PagerModel.Activities
} }

@ -241,7 +241,8 @@ DragDrop.DropArea {
if (( (plasmoid.configuration.panelShadows && !root.backgroundOnlyOnMaximized) if (( (plasmoid.configuration.panelShadows && !root.backgroundOnlyOnMaximized)
|| (plasmoid.configuration.panelShadows && root.backgroundOnlyOnMaximized && !root.forceTransparentPanel)) || (plasmoid.configuration.panelShadows && root.backgroundOnlyOnMaximized && !root.forceTransparentPanel))
&& !(disablePanelShadowMaximized && latteView.windowsTracker.activeWindowMaximized)) { && !(disablePanelShadowMaximized && latteView && latteView.windowsTracker
&& latteView.windowsTracker.activeWindowMaximized)) {
return true; return true;
} }
@ -317,7 +318,7 @@ DragDrop.DropArea {
property int lengthIntMargin: lengthIntMarginFactor * root.iconSize property int lengthIntMargin: lengthIntMarginFactor * root.iconSize
property int lengthExtMargin: lengthExtMarginFactor * root.iconSize property int lengthExtMargin: lengthExtMarginFactor * root.iconSize
property real lengthIntMarginFactor: indicators.common.indicatorsEnabled ? plasmoid.configuration.lengthIntMargin / 100 : 0 property real lengthIntMarginFactor: indicators.isEnabled ? indicators.padding : 0
property real lengthExtMarginFactor: plasmoid.configuration.lengthExtMargin / 100 property real lengthExtMarginFactor: plasmoid.configuration.lengthExtMargin / 100
property real thickMarginFactor: { property real thickMarginFactor: {
@ -1434,7 +1435,7 @@ DragDrop.DropArea {
function updateContainsOnlyPlasmaTasks() { function updateContainsOnlyPlasmaTasks() {
if (latteView) { if (latteView) {
root.containsOnlyPlasmaTasks = (latteView.tasksPresent() && !latteView.latteTasksPresent()); root.containsOnlyPlasmaTasks = (latteView.tasksPresent() && !latteApplet);
} else { } else {
root.containsOnlyPlasmaTasks = false; root.containsOnlyPlasmaTasks = false;
} }

@ -205,24 +205,27 @@ Item{
//! add border around indicator without reducing its size //! add border around indicator without reducing its size
Loader{ Loader{
anchors.centerIn: mainElement anchors.centerIn: mainElement
active: glowItem.showBorder && !glowItem.showGlow active: glowItem.showBorder
sourceComponent:Rectangle { sourceComponent:Rectangle {
width: size width: mainElement.width + size
height: size height: mainElement.height + size
anchors.centerIn: parent anchors.centerIn: parent
color: contrastColorAlpha2 color: contrastColorAlpha2
radius: glowItem.roundCorners ? Math.min(width,height) / 2 : 0 radius: glowItem.roundCorners ? Math.min(width,height) / 2 : 0
property int size: Math.min(mainElement.width + 2*Math.max(1,mainElement.width/5 ), property int size: Math.min(2*Math.max(1,mainElement.width/5 ),
mainElement.height + 2*Math.max(1,mainElement.height/5 )) 2*Math.max(1,mainElement.height/5 ))
} }
} }
Item{ Item{
id:mainElement id:mainElement
anchors.fill: parent
width: Math.max(glowItem.size, parent.width)
height: Math.max(glowItem.size, parent.height)
anchors.centerIn: parent
Rectangle { Rectangle {
id: smallCircle id: smallCircle

@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com> * Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
* *
* This file is part of Latte-Dock * This file is part of Latte-Dock
* *
@ -19,14 +19,7 @@
import QtQuick 2.7 import QtQuick 2.7
import org.kde.plasma.plasmoid 2.0 Item {
import org.kde.plasma.core 2.0 as PlasmaCore readonly property Item indicator: parent && parent.hasOwnProperty("bridge") ? parent.bridge : null
readonly property Item attributes: parent
import org.kde.latte 0.2 as Latte
Item{
readonly property string styleName: "Plasma"
readonly property bool usePlasmaTabsStyle: !commonOptions.indicatorsForApplets
} }

@ -6,6 +6,7 @@ ExternalShadow 1.0 ExternalShadow.qml
GlowPoint 1.0 GlowPoint.qml GlowPoint 1.0 GlowPoint.qml
Header 1.0 Header.qml Header 1.0 Header.qml
HeaderSwitch 1.0 HeaderSwitch.qml HeaderSwitch 1.0 HeaderSwitch.qml
IndicatorItem 1.0 IndicatorItem.qml
Slider 1.0 Slider.qml Slider 1.0 Slider.qml
SpinBox 1.0 SpinBox.qml SpinBox 1.0 SpinBox.qml
SubHeader 1.0 SubHeader.qml SubHeader 1.0 SubHeader.qml

@ -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

@ -31,6 +31,8 @@ import org.kde.latte 0.2 as Latte
import org.kde.latte.components 1.0 as LatteComponents import org.kde.latte.components 1.0 as LatteComponents
ColumnLayout { ColumnLayout {
Layout.fillWidth: true
LatteComponents.SubHeader { LatteComponents.SubHeader {
text: i18nc("active indicator style","Style For Active") text: i18nc("active indicator style","Style For Active")
} }
@ -39,13 +41,13 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
spacing: 2 spacing: 2
property int indicatorType: plasmoid.configuration.activeIndicatorType property int indicatorType: indicator.configuration.activeStyle
ExclusiveGroup { ExclusiveGroup {
id: activeIndicatorTypeGroup id: activeIndicatorTypeGroup
onCurrentChanged: { onCurrentChanged: {
if (current.checked) { if (current.checked) {
plasmoid.configuration.activeIndicatorType = current.indicatorType; indicator.configuration.activeStyle = current.indicatorType;
} }
} }
} }
@ -59,7 +61,7 @@ ColumnLayout {
exclusiveGroup: activeIndicatorTypeGroup exclusiveGroup: activeIndicatorTypeGroup
tooltip: i18n("Show a line indicator for active items") tooltip: i18n("Show a line indicator for active items")
readonly property int indicatorType: Latte.Types.LineIndicator readonly property int indicatorType: 0 /*Line*/
} }
PlasmaComponents.Button { PlasmaComponents.Button {
@ -71,38 +73,38 @@ ColumnLayout {
exclusiveGroup: activeIndicatorTypeGroup exclusiveGroup: activeIndicatorTypeGroup
tooltip: i18n("Show a dot indicator for active items") tooltip: i18n("Show a dot indicator for active items")
readonly property int indicatorType: Latte.Types.DotIndicator readonly property int indicatorType: 1 /*Dot*/
} }
} }
LatteComponents.HeaderSwitch { LatteComponents.HeaderSwitch {
id: showGlow id: glowEnabled
Layout.fillWidth: true Layout.fillWidth: true
Layout.minimumHeight: implicitHeight Layout.minimumHeight: implicitHeight
Layout.bottomMargin: units.smallSpacing Layout.bottomMargin: units.smallSpacing
checked: plasmoid.configuration.showGlow checked: indicator.configuration.glowEnabled
level: 2 level: 2
text: i18n("Glow") text: i18n("Glow")
tooltip: i18n("Enable/disable indicator glow") tooltip: i18n("Enable/disable indicator glow")
onPressed: { onPressed: {
plasmoid.configuration.showGlow = !plasmoid.configuration.showGlow; indicator.configuration.glowEnabled = !indicator.configuration.glowEnabled;
} }
} }
RowLayout { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
spacing: 2 spacing: 2
enabled: plasmoid.configuration.showGlow enabled: indicator.configuration.glowEnabled
property int option: plasmoid.configuration.glowOption property int option: indicator.configuration.glowApplyTo
ExclusiveGroup { ExclusiveGroup {
id: glowGroup id: glowGroup
onCurrentChanged: { onCurrentChanged: {
if (current.checked) if (current.checked)
plasmoid.configuration.glowOption = current.option indicator.configuration.glowApplyTo = current.option
} }
} }
@ -114,7 +116,7 @@ ColumnLayout {
exclusiveGroup: glowGroup exclusiveGroup: glowGroup
tooltip: i18n("Add glow only to active task/applet indicator") tooltip: i18n("Add glow only to active task/applet indicator")
readonly property int option: Latte.Types.GlowOnlyOnActive readonly property int option: 1 /*OnActive*/
} }
PlasmaComponents.Button { PlasmaComponents.Button {
@ -125,7 +127,7 @@ ColumnLayout {
exclusiveGroup: glowGroup exclusiveGroup: glowGroup
tooltip: i18n("Add glow to all task/applet indicators") tooltip: i18n("Add glow to all task/applet indicators")
readonly property int option: Latte.Types.GlowAll readonly property int option: 2 /*All*/
} }
} }
@ -133,7 +135,7 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
spacing: 2 spacing: 2
enabled: plasmoid.configuration.showGlow enabled: indicator.configuration.glowEnabled
PlasmaComponents.Label { PlasmaComponents.Label {
Layout.minimumWidth: implicitWidth Layout.minimumWidth: implicitWidth
@ -147,7 +149,7 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
leftPadding: 0 leftPadding: 0
value: plasmoid.configuration.glowOpacity value: indicator.configuration.glowOpacity * 100
from: 0 from: 0
to: 100 to: 100
stepSize: 5 stepSize: 5
@ -155,7 +157,7 @@ ColumnLayout {
function updateGlowOpacity() { function updateGlowOpacity() {
if (!pressed) if (!pressed)
plasmoid.configuration.glowOpacity = value; indicator.configuration.glowOpacity = value/100;
} }
onPressedChanged: { onPressedChanged: {
@ -181,32 +183,32 @@ ColumnLayout {
ColumnLayout { ColumnLayout {
spacing: 0 spacing: 0
visible: latteView.latteTasksPresent() visible: indicator.latteTasksArePresent
LatteComponents.SubHeader { LatteComponents.SubHeader {
enabled: plasmoid.configuration.glowOption!==Latte.Types.GlowNone enabled: indicator.configuration.glowApplyTo!==0/*None*/
text: i18n("Tasks") text: i18n("Tasks")
} }
PlasmaComponents.CheckBox { PlasmaComponents.CheckBox {
id: threeColorsWindows id: threeColorsWindows
text: i18n("Different color for minimized windows") text: i18n("Different color for minimized windows")
checked: plasmoid.configuration.threeColorsWindows checked: indicator.configuration.minimizedTaskColoredDifferently
onClicked: { onClicked: {
plasmoid.configuration.threeColorsWindows = checked indicator.configuration.minimizedTaskColoredDifferently = checked;
} }
} }
PlasmaComponents.CheckBox { PlasmaComponents.CheckBox {
id: dotsOnActive id: dotsOnActive
text: i18n("Show an extra dot for grouped windows when active") text: i18n("Show an extra dot for grouped windows when active")
checked: plasmoid.configuration.dotsOnActive checked: indicator.configuration.extraDotOnActive
tooltip: i18n("Grouped windows show both a line and a dot when one of them is active and the Line Active Indicator is enabled") tooltip: i18n("Grouped windows show both a line and a dot when one of them is active and the Line Active Indicator is enabled")
enabled: plasmoid.configuration.activeIndicatorType === Latte.Types.LineIndicator enabled: indicator.configuration.activeStyle === 0 /*Line*/
onClicked: { onClicked: {
plasmoid.configuration.dotsOnActive = checked indicator.configuration.extraDotOnActive = checked;
} }
} }
} }

@ -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;
}
}
]
}

@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com> * Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
* *
* This file is part of Latte-Dock * This file is part of Latte-Dock
* *
@ -17,19 +17,32 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import QtQuick 2.7 import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.latte 0.2 as Latte import org.kde.latte 0.2 as Latte
import org.kde.latte.components 1.0 as LatteComponents
Item{ LatteComponents.IndicatorItem {
id: common readonly property bool providesFrontLayer: true
readonly property bool indicatorsEnabled: plasmoid.configuration.indicatorsEnabled //! Background Layer
readonly property bool indicatorsForApplets: plasmoid.configuration.indicatorsForApplets Loader{
readonly property bool reversedEnabled: plasmoid.configuration.reverseLinesPosition id: backLayer
anchors.fill: parent
active: attributes.isBackground
sourceComponent: BackLayer{}
}
//! Foreground Layer to draw arrows
Loader{
id: frontLayer
anchors.fill: parent
active: attributes.isForeground && !indicator.isApplet && indicator.isGroup
sourceComponent: FrontLayer{}
}
readonly property int indicatorStyle: plasmoid.configuration.indicatorStyle
} }

@ -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{}
}
}

@ -29,6 +29,4 @@ endif()
install(TARGETS latte2plugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/latte) install(TARGETS latte2plugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/latte)
install(DIRECTORY qml/ DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/latte)
install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/latte) install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/latte)

@ -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}
}
}
]
}
}
}

@ -1,6 +1,2 @@
module org.kde.latte module org.kde.latte
plugin latte2plugin plugin latte2plugin
LatteIndicator 0.2 indicators/LatteIndicator.qml
PlasmaIndicator 0.2 indicators/PlasmaIndicator.qml
UnityIndicator 0.2 indicators/UnityIndicator.qml

@ -24,57 +24,35 @@ import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.latte 0.2 as Latte import org.kde.latte 0.2 as Latte
import "options" as Options import "options" as IndicatorOptions
import "styles" as IndicatorStyles
import "../task/indicator" as TaskIndicator import "../task/indicator" as TaskIndicator
Item{ Item{
id: managerIndicator id: managerIndicator
readonly property Item common: commonOptions readonly property Item configuration: explicitOptions
readonly property Item explicit: explicitOptions
readonly property bool isEnabled: true
readonly property bool reversed: plasmoid.configuration.reverseLinesPosition
readonly property string type: "org.kde.latte.indicator.default"
readonly property Component indicatorComponent: latteStyleIndicator readonly property Component indicatorComponent: latteStyleIndicator
readonly property Item info: Item{ readonly property Item info: Item{
readonly property bool needsIconColors: metricsLoader.active && metricsLoader.item && metricsLoader.item.hasOwnProperty("needsIconColors") readonly property bool needsIconColors: false
&& metricsLoader.item.needsIconColors readonly property bool providesFrontLayer: false
readonly property bool providesFrontLayer: metricsLoader.active && metricsLoader.item && metricsLoader.item.hasOwnProperty("providesFrontLayer") readonly property int extraMaskThickness: 0
&& metricsLoader.item.providesFrontLayer
readonly property int extraMaskThickness: {
if (metricsLoader.active && metricsLoader.item && metricsLoader.item.hasOwnProperty("extraMaskThickness")) {
return metricsLoader.item.extraMaskThickness;
}
return 0;
}
}
Options.Common {
id: commonOptions
} }
Options.Latte { IndicatorOptions.Latte {
id : explicitOptions id : explicitOptions
} }
//! Indicators Components //! Indicators Components
Component { Component {
id: latteStyleIndicator id: latteStyleIndicator
Latte.LatteIndicator{} IndicatorStyles.LatteIndicator{}
}
//! Metrics and values provided from an invisible indicator
Loader{
id: metricsLoader
opacity: 0
readonly property bool isBackLayer: true
readonly property Item manager: TaskIndicator.Manager{
taskIsValid: false
}
sourceComponent: managerIndicator.indicatorComponent
} }
} }

@ -27,13 +27,13 @@ import org.kde.latte 0.2 as Latte
Item{ Item{
readonly property string styleName: "Latte" readonly property string styleName: "Latte"
readonly property bool dotsOnActive: plasmoid.configuration.dotsOnActive readonly property bool extraDotOnActive: plasmoid.configuration.dotsOnActive
readonly property bool multiColorEnabled: plasmoid.configuration.threeColorsWindows readonly property bool minimizedTaskColoredDifferently: plasmoid.configuration.threeColorsWindows
readonly property int activeIndicatorType: Latte.Types.LineIndicator readonly property int activeStyle: Latte.Types.LineIndicator
//!glow options //!glow options
readonly property bool glowEnabled: plasmoid.configuration.showGlow readonly property bool glowEnabled: plasmoid.configuration.showGlow
readonly property bool glow3D: false readonly property bool glow3D: false
readonly property int glowOption: Latte.Types.GlowAll readonly property int glowApplyTo: 2 /*All*/
readonly property real glowOpacity: 0.35 readonly property real glowOpacity: 0.35
} }

@ -1,6 +1,5 @@
/* /*
* Copyright 2016 Smith AR <audoban@openmailbox.org> * Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
* Michail Vourlakos <mvourlakos@gmail.com>
* *
* This file is part of Latte-Dock * This file is part of Latte-Dock
* *
@ -29,45 +28,39 @@ import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.latte 0.2 as Latte import org.kde.latte 0.2 as Latte
import org.kde.latte.components 1.0 as LatteComponents import org.kde.latte.components 1.0 as LatteComponents
import "../code/ColorizerTools.js" as ColorizerTools LatteComponents.IndicatorItem{
id: root
Item{
id: indicatorRoot
readonly property Item options: parent.manager
readonly property real factor: 0.08 readonly property real factor: 0.08
readonly property int size: factor * options.currentIconSize readonly property int size: indicator ? factor * indicator.currentIconSize : factor * 64
readonly property int extraMaskThickness: reversedEnabled && glowEnabled ? 1.7 * (factor * options.maxIconSize) : 0 readonly property int extraMaskThickness: reversedEnabled && glowEnabled ? 1.7 * (factor * indicator.maxIconSize) : 0
property real textColorBrightness: ColorizerTools.colorBrightness(theme.textColor) property real textColorBrightness: colorBrightness(theme.textColor)
property color isActiveColor: theme.buttonFocusColor property color isActiveColor: theme.buttonFocusColor
property color minimizedColor: { property color minimizedColor: {
if (multiColorEnabled) { if (minimizedTaskColoredDifferently) {
return (textColorBrightness > 127.5 ? Qt.darker(theme.textColor, 1.7) : Qt.lighter(theme.textColor, 7)); return (textColorBrightness > 127.5 ? Qt.darker(theme.textColor, 1.7) : Qt.lighter(theme.textColor, 7));
} }
return isActiveColor; return isActiveColor;
} }
property color notActiveColor: options.isMinimized ? minimizedColor : isActiveColor property color notActiveColor: indicator && indicator.isMinimized ? minimizedColor : isActiveColor
//! Common Options //! Common Options
readonly property bool reversedEnabled: options && options.common && options.common.hasOwnProperty("reversedEnabled") ? readonly property bool reversedEnabled: indicator && indicator.general ? indicator.general.reversed : false
options.common.reversedEnabled : false
//! Explicit Options //! Configuration Options
readonly property bool explicitOptionsEnabled: options.explicit readonly property bool configurationEnabled: (indicator!==null) && (indicator.configuration !== null)
&& options.explicit.hasOwnProperty("styleName")
&& options.explicit.styleName === "Latte"
readonly property bool dotsOnActive: explicitOptionsEnabled ? options.explicit.dotsOnActive : true readonly property bool extraDotOnActive: configurationEnabled ? indicator.configuration.extraDotOnActive : true
readonly property bool multiColorEnabled: explicitOptionsEnabled ? options.explicit.multiColorEnabled : false readonly property bool minimizedTaskColoredDifferently: configurationEnabled ? indicator.configuration.minimizedTaskColoredDifferently : false
readonly property int activeIndicatorType: explicitOptionsEnabled ? options.explicit.activeIndicatorType : Latte.Types.LineIndicator readonly property int activeStyle: configurationEnabled ? indicator.configuration.activeStyle : 0 /*Line*/
//!glow options //!glow options
readonly property bool glowEnabled: explicitOptionsEnabled ? options.explicit.glowEnabled : true readonly property bool glowEnabled: configurationEnabled ? indicator.configuration.glowEnabled : true
readonly property bool glow3D: explicitOptionsEnabled ? options.explicit.glow3D : false readonly property bool glow3D: configurationEnabled ? indicator.configuration.glow3D : false
readonly property int glowOption: explicitOptionsEnabled ? options.explicit.glowOption : Latte.Types.GlowAll readonly property int glowApplyTo: configurationEnabled ? indicator.configuration.glowApplyTo : 2 /*All*/
readonly property real glowOpacity: explicitOptionsEnabled ? options.explicit.glowOpacity : 0.35 readonly property real glowOpacity: configurationEnabled ? indicator.configuration.glowOpacity : 0.35
/*Rectangle{ /*Rectangle{
anchors.fill: parent anchors.fill: parent
@ -77,6 +70,16 @@ Item{
opacity:0.6 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{ Item{
id: mainIndicatorElement id: mainIndicatorElement
@ -90,89 +93,89 @@ Item{
LatteComponents.GlowPoint{ LatteComponents.GlowPoint{
id:firstPoint id:firstPoint
opacity: { opacity: {
if (options.isTask) { if (indicator.isTask) {
return options.isLauncher || (options.inRemoving && !activeAndReverseAnimation.running) ? 0 : 1 return indicator.isLauncher || (indicator.inRemoving && !activeAndReverseAnimation.running) ? 0 : 1
} }
if (options.isApplet) { if (indicator.isApplet) {
return (options.isActive || activeAndReverseAnimation.running) ? 1 : 0 return (indicator.isActive || activeAndReverseAnimation.running) ? 1 : 0
} }
} }
basicColor: options.isActive || (options.isGroup && options.hasShown) ? indicatorRoot.isActiveColor : indicatorRoot.notActiveColor basicColor: indicator.isActive || (indicator.isGroup && indicator.hasShown) ? root.isActiveColor : root.notActiveColor
size: indicatorRoot.size size: root.size
glow3D: glow3D glow3D: glow3D
animation: Math.max(1.65*3*units.longDuration,options.durationTime*3*units.longDuration) animation: Math.max(1.65*3*units.longDuration,indicator.durationTime*3*units.longDuration)
location: plasmoid.location location: plasmoid.location
glowOpacity: indicatorRoot.glowOpacity glowOpacity: root.glowOpacity
contrastColor: options.shadowColor contrastColor: indicator.shadowColor
attentionColor: theme.negativeTextColor attentionColor: theme.negativeTextColor
roundCorners: true roundCorners: true
showAttention: options.inAttention showAttention: indicator.inAttention
showGlow: { showGlow: {
if (glowEnabled && (glowOption === Latte.Types.GlowAll || showAttention )) if (glowEnabled && (glowApplyTo === 2 /*All*/ || showAttention ))
return true; return true;
else if (glowEnabled && glowOption === Latte.Types.GlowOnlyOnActive && options.hasActive) else if (glowEnabled && glowApplyTo === 1 /*OnActive*/ && indicator.hasActive)
return true; return true;
else else
return false; return false;
} }
showBorder: glowEnabled && glow3D showBorder: glowEnabled && glow3D
property int stateWidth: options.isGroup ? indicatorRoot.width - secondPoint.width : indicatorRoot.width - spacer.width property int stateWidth: indicator.isGroup ? root.width - secondPoint.width : root.width - spacer.width
property int stateHeight: options.isGroup ? indicatorRoot.height - secondPoint.height : indicatorRoot.width - spacer.height property int stateHeight: indicator.isGroup ? root.height - secondPoint.height : root.width - spacer.height
property int animationTime: options.durationTime* (0.7*units.longDuration) property int animationTime: indicator.durationTime* (0.7*units.longDuration)
property bool isActive: options.hasActive || options.isActive property bool isActive: indicator.hasActive || indicator.isActive
property bool vertical: plasmoid.formFactor === PlasmaCore.Types.Vertical property bool vertical: plasmoid.formFactor === PlasmaCore.Types.Vertical
property real scaleFactor: options.scaleFactor property real scaleFactor: indicator.scaleFactor
function updateInitialSizes(){ function updateInitialSizes(){
if(indicatorRoot){ if(root){
if(vertical) if(vertical)
width = indicatorRoot.size; width = root.size;
else else
height = indicatorRoot.size; height = root.size;
if(vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator) if(vertical && isActive && activeStyle === 0 /*Line*/)
height = stateHeight; height = stateHeight;
else else
height = indicatorRoot.size; height = root.size;
if(!vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator) if(!vertical && isActive && activeStyle === 0 /*Line*/)
width = stateWidth; width = stateWidth;
else else
width = indicatorRoot.size; width = root.size;
} }
} }
onIsActiveChanged: { onIsActiveChanged: {
if (activeIndicatorType === Latte.Types.LineIndicator) if (activeStyle === 0 /*Line*/)
activeAndReverseAnimation.start(); activeAndReverseAnimation.start();
} }
onScaleFactorChanged: { onScaleFactorChanged: {
if(!activeAndReverseAnimation.running && !vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator){ if(!activeAndReverseAnimation.running && !vertical && isActive && activeStyle === 0 /*Line*/){
width = stateWidth; width = stateWidth;
} }
else if (!activeAndReverseAnimation.running && vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator){ else if (!activeAndReverseAnimation.running && vertical && isActive && activeStyle === 0 /*Line*/){
height = stateHeight; height = stateHeight;
} }
} }
onStateWidthChanged:{ onStateWidthChanged:{
if(!activeAndReverseAnimation.running && !vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator) if(!activeAndReverseAnimation.running && !vertical && isActive && activeStyle === 0 /*Line*/)
width = stateWidth; width = stateWidth;
} }
onStateHeightChanged:{ onStateHeightChanged:{
if(!activeAndReverseAnimation.running && vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator) if(!activeAndReverseAnimation.running && vertical && isActive && activeStyle === 0 /*Line*/)
height = stateHeight; height = stateHeight;
} }
@ -181,14 +184,14 @@ Item{
Component.onCompleted: { Component.onCompleted: {
updateInitialSizes(); updateInitialSizes();
if (options) { if (indicator) {
options.onCurrentIconSizeChanged.connect(updateInitialSizes); indicator.onCurrentIconSizeChanged.connect(updateInitialSizes);
} }
} }
Component.onDestruction: { Component.onDestruction: {
if (options) { if (indicator) {
options.onCurrentIconSizeChanged.disconnect(updateInitialSizes); indicator.onCurrentIconSizeChanged.disconnect(updateInitialSizes);
} }
} }
@ -196,8 +199,8 @@ Item{
id: activeAndReverseAnimation id: activeAndReverseAnimation
target: firstPoint target: firstPoint
property: plasmoid.formFactor === PlasmaCore.Types.Vertical ? "height" : "width" property: plasmoid.formFactor === PlasmaCore.Types.Vertical ? "height" : "width"
to: options.hasActive && activeIndicatorType === Latte.Types.LineIndicator to: indicator.hasActive && activeStyle === 0 /*Line*/
? (plasmoid.formFactor === PlasmaCore.Types.Vertical ? firstPoint.stateHeight : firstPoint.stateWidth) : indicatorRoot.size ? (plasmoid.formFactor === PlasmaCore.Types.Vertical ? firstPoint.stateHeight : firstPoint.stateWidth) : root.size
duration: firstPoint.animationTime duration: firstPoint.animationTime
easing.type: Easing.InQuad easing.type: Easing.InQuad
@ -207,34 +210,34 @@ Item{
Item{ Item{
id:spacer id:spacer
width: secondPoint.visible ? 0.5*indicatorRoot.size : 0 width: secondPoint.visible ? 0.5*root.size : 0
height: secondPoint.visible ? 0.5*indicatorRoot.size : 0 height: secondPoint.visible ? 0.5*root.size : 0
} }
LatteComponents.GlowPoint{ LatteComponents.GlowPoint{
id:secondPoint id:secondPoint
width: visible ? indicatorRoot.size : 0 width: visible ? root.size : 0
height: width height: width
size: indicatorRoot.size size: root.size
glow3D: glow3D glow3D: glow3D
animation: Math.max(1.65*3*units.longDuration,options.durationTime*3*units.longDuration) animation: Math.max(1.65*3*units.longDuration,indicator.durationTime*3*units.longDuration)
location: plasmoid.location location: plasmoid.location
glowOpacity: indicatorRoot.glowOpacity glowOpacity: root.glowOpacity
contrastColor: options.shadowColor contrastColor: indicator.shadowColor
showBorder: glowEnabled && glow3D showBorder: glowEnabled && glow3D
basicColor: state2Color basicColor: state2Color
roundCorners: true roundCorners: true
showGlow: glowEnabled && glowOption === Latte.Types.GlowAll showGlow: glowEnabled && glowApplyTo === 2 /*All*/
visible: ( options.isGroup && ((dotsOnActive && activeIndicatorType === Latte.Types.LineIndicator) visible: ( indicator.isGroup && ((extraDotOnActive && activeStyle === 0) /*Line*/
|| activeIndicatorType === Latte.Types.DotIndicator || activeStyle === 1 /*Dot*/
|| !options.hasActive) )? true: false || !indicator.hasActive) ) ? true: false
//when there is no active window //when there is no active window
property color state1Color: options.hasShown ? indicatorRoot.isActiveColor : indicatorRoot.minimizedColor property color state1Color: indicator.hasShown ? root.isActiveColor : root.minimizedColor
//when there is active window //when there is active window
property color state2Color: options.hasMinimized ? indicatorRoot.minimizedColor : indicatorRoot.isActiveColor property color state2Color: indicator.hasMinimized ? root.minimizedColor : root.isActiveColor
} }
} }

@ -63,7 +63,7 @@ Item {
property bool editMode: latteView ? latteView.editMode : plasmoid.userConfiguring property bool editMode: latteView ? latteView.editMode : plasmoid.userConfiguring
property bool disableRestoreZoom: false //blocks restore animation in rightClick property bool disableRestoreZoom: false //blocks restore animation in rightClick
property bool disableAllWindowsFunctionality: root.showWindowsOnlyFromLaunchers && !indicatorsEnabled property bool disableAllWindowsFunctionality: root.showWindowsOnlyFromLaunchers && !indicators.isEnabled
property bool dropNewLauncher: false property bool dropNewLauncher: false
readonly property bool hasInternalSeparator: parabolicManager.hasInternalSeparator readonly property bool hasInternalSeparator: parabolicManager.hasInternalSeparator
property bool inActivityChange: false property bool inActivityChange: false
@ -349,7 +349,7 @@ Item {
Loader { Loader {
id: indicatorsStandaloneLoader id: indicatorsStandaloneLoader
active: !latteView active: !latteView && !plasmoid.configuration.isInLatteDock
source: "indicators/Manager.qml" source: "indicators/Manager.qml"
} }

@ -421,21 +421,22 @@ MouseArea{
width: wrapper.width width: wrapper.width
height: wrapper.height height: wrapper.height
Indicator.Manager{ Indicator.Bridge{
id: indicatorManager id: indicatorBridge
} }
Indicator.Loader{ Indicator.Loader{
id: indicatorBackLayer id: indicatorBackLayer
manager: indicatorManager bridge: indicatorBridge
isBackground: true
} }
Wrapper{id: wrapper} Wrapper{id: wrapper}
Indicator.Loader{ Indicator.Loader{
id: indicatorFrontLayer id: indicatorFrontLayer
manager: indicatorManager bridge: indicatorBridge
isBackLayer: false isBackground: false
} }
} }

@ -26,10 +26,10 @@ import org.kde.latte 0.2 as Latte
import "../../indicators/options" as TaskIndicator import "../../indicators/options" as TaskIndicator
Item { Item {
id: indicatorManager id: indicatorBridge
property bool taskIsValid: true property bool taskIsValid: true
readonly property bool active: indicators && indicators.common ? indicators.common.indicatorsEnabled : true readonly property bool active: indicators ? indicators.isEnabled : false
readonly property bool locked: taskIsValid ? (inAttentionAnimation || inNewWindowAnimation) : false readonly property bool locked: taskIsValid ? (inAttentionAnimation || inNewWindowAnimation) : false
/* Indicators Properties in order for indicators to use them*/ /* Indicators Properties in order for indicators to use them*/
@ -63,13 +63,17 @@ Item {
readonly property real scaleFactor: taskIsValid ? taskItem.wrapperAlias.mScale : 1 readonly property real scaleFactor: taskIsValid ? taskItem.wrapperAlias.mScale : 1
readonly property color shadowColor: root.appShadowColorSolid readonly property color shadowColor: root.appShadowColorSolid
readonly property bool usePlasmaTabsStyle: false
readonly property QtObject palette: enforceLattePalette ? latteBridge.palette.applyTheme : theme
//!icon colors //!icon colors
property color backgroundColor: taskIsValid ? taskItem.wrapperAlias.backgroundColor : "black" property color backgroundColor: taskIsValid ? taskItem.wrapperAlias.backgroundColor : "black"
property color glowColor: taskIsValid ? taskItem.wrapperAlias.glowColor : "white" property color glowColor: taskIsValid ? taskItem.wrapperAlias.glowColor : "white"
//! grouped options //! grouped options
readonly property Item common: indicators ? indicators.common : emptyOptions readonly property Item shared: indicators ? indicators : emptyOptions
readonly property Item explicit: indicators ? indicators.explicit : emptyOptions readonly property QtObject configuration: indicators ? indicators.configuration : null
Item{id: emptyOptions} Item{id: emptyOptions}
} }

@ -19,6 +19,7 @@
import QtQuick 2.7 import QtQuick 2.7
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.latte 0.2 as Latte import org.kde.latte 0.2 as Latte
@ -33,10 +34,11 @@ Loader {
anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined
anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined
property bool isBackLayer: true property bool isBackground: true
property Item manager readonly property bool isForeground: !isBackground
property Item bridge
active: manager && manager.active && (isBackLayer || (!isBackLayer && indicators.info.providesFrontLayer)) active: bridge && bridge.active && (isBackground || (isForeground && indicators.info.providesFrontLayer))
sourceComponent: indicators.indicatorComponent sourceComponent: indicators.indicatorComponent
width: { width: {

@ -388,7 +388,7 @@ FocusScope {
text: i18n("Tasks") text: i18n("Tasks")
tab: tasksPage tab: tasksPage
visible: latteView.latteTasksPresent() visible: latteView.latteTasksArePresent
} }
} }

@ -384,7 +384,7 @@ PlasmaComponents.Page {
ColumnLayout { ColumnLayout {
spacing: units.smallSpacing spacing: units.smallSpacing
visible: latteView.latteTasksPresent() visible: latteView.latteTasksArePresent
LatteComponents.SubHeader { LatteComponents.SubHeader {
Layout.leftMargin: units.smallSpacing * 2 Layout.leftMargin: units.smallSpacing * 2
@ -451,12 +451,12 @@ PlasmaComponents.Page {
Layout.fillWidth: true Layout.fillWidth: true
Layout.minimumHeight: implicitHeight Layout.minimumHeight: implicitHeight
checked: plasmoid.configuration.indicatorsEnabled checked: latteView.indicator.enabled
text: i18n("Indicators") text: i18n("Indicators")
tooltip: i18n("Enable/disable indicators") tooltip: i18n("Enable/disable indicators")
onPressed: { onPressed: {
plasmoid.configuration.indicatorsEnabled = !plasmoid.configuration.indicatorsEnabled; latteView.indicator.enabled = !latteView.indicator.enabled;
} }
} }
@ -473,13 +473,13 @@ PlasmaComponents.Page {
Layout.fillWidth: true Layout.fillWidth: true
spacing: 2 spacing: 2
property int style: plasmoid.configuration.indicatorStyle property string type: latteView.indicator.type
ExclusiveGroup { ExclusiveGroup {
id: indicatorStyleGroup id: indicatorStyleGroup
onCurrentChanged: { onCurrentChanged: {
if (current.checked) { if (current.checked) {
plasmoid.configuration.indicatorStyle = current.style latteView.indicator.type = current.type
} }
} }
} }
@ -487,34 +487,34 @@ PlasmaComponents.Page {
PlasmaComponents.Button { PlasmaComponents.Button {
Layout.fillWidth: true Layout.fillWidth: true
text: i18nc("latte indicator style", "Latte") text: i18nc("latte indicator style", "Latte")
checked: parent.style === style checked: parent.type === type
checkable: true checkable: true
exclusiveGroup: indicatorStyleGroup exclusiveGroup: indicatorStyleGroup
tooltip: i18n("Use Latte style for your indicators") tooltip: i18n("Use Latte style for your indicators")
readonly property int style: Latte.Types.LatteIndicator readonly property string type: "org.kde.latte.indicator.default"
} }
PlasmaComponents.Button { PlasmaComponents.Button {
Layout.fillWidth: true Layout.fillWidth: true
text: i18nc("plasma indicator style", "Plasma") text: i18nc("plasma indicator style", "Plasma")
checked: parent.style === style checked: parent.type === type
checkable: true checkable: true
exclusiveGroup: indicatorStyleGroup exclusiveGroup: indicatorStyleGroup
tooltip: i18n("Use Plasma style for your indicators") tooltip: i18n("Use Plasma style for your indicators")
readonly property int style: Latte.Types.PlasmaIndicator readonly property string type: "org.kde.latte.indicator.plasma"
} }
PlasmaComponents.Button { PlasmaComponents.Button {
Layout.fillWidth: true Layout.fillWidth: true
text: i18nc("unity indicator style", "Unity") text: i18nc("unity indicator style", "Unity")
checked: parent.style === style checked: parent.type === type
checkable: true checkable: true
exclusiveGroup: indicatorStyleGroup exclusiveGroup: indicatorStyleGroup
tooltip: i18n("Use Unity style for your indicators") tooltip: i18n("Use Unity style for your indicators")
readonly property int style: Latte.Types.UnityIndicator readonly property string type: "org.kde.latte.indicator.unity"
} }
} }
@ -537,7 +537,7 @@ PlasmaComponents.Page {
id: lengthIntMarginSlider id: lengthIntMarginSlider
Layout.fillWidth: true Layout.fillWidth: true
value: plasmoid.configuration.lengthIntMargin value: Math.round(latteView.indicator.padding * 100)
from: 0 from: 0
to: maxMargin to: maxMargin
stepSize: 1 stepSize: 1
@ -547,7 +547,7 @@ PlasmaComponents.Page {
onPressedChanged: { onPressedChanged: {
if (!pressed) { if (!pressed) {
plasmoid.configuration.lengthIntMargin = value; latteView.indicator.padding = value / 100;
} }
} }
} }
@ -568,21 +568,21 @@ PlasmaComponents.Page {
PlasmaComponents.CheckBox { PlasmaComponents.CheckBox {
text: i18n("Show indicators for applets") text: i18n("Show indicators for applets")
checked: plasmoid.configuration.indicatorsForApplets checked: latteView.indicator.enabledForApplets
tooltip: i18n("Indicators are shown for applets") tooltip: i18n("Indicators are shown for applets")
onClicked: { onClicked: {
plasmoid.configuration.indicatorsForApplets = !plasmoid.configuration.indicatorsForApplets; latteView.indicator.enabledForApplets = !latteView.indicator.enabledForApplets;
} }
} }
PlasmaComponents.CheckBox { PlasmaComponents.CheckBox {
text: i18n("Reverse indicator style") text: i18n("Reverse indicator style")
checked: plasmoid.configuration.reverseLinesPosition checked: latteView.indicator.reversed
tooltip: i18n("Reverse indicator style e.g. from bottom to top") tooltip: i18n("Reverse indicator style e.g. from bottom to top")
onClicked: { onClicked: {
plasmoid.configuration.reverseLinesPosition = !plasmoid.configuration.reverseLinesPosition; latteView.indicator.reversed = !latteView.indicator.reversed;
} }
} }
} }
@ -595,18 +595,26 @@ PlasmaComponents.Page {
Layout.topMargin: units.smallSpacing Layout.topMargin: units.smallSpacing
Layout.rightMargin: units.smallSpacing Layout.rightMargin: units.smallSpacing
spacing: units.smallSpacing spacing: units.smallSpacing
visible: plasmoid.configuration.indicatorStyle === Latte.Types.LatteIndicator visible: latteView.indicator.providesConfigUi
enabled: indicatorsSwitch.checked
LatteComponents.Header { LatteComponents.Header {
text: i18n("%0 Indicator Options").arg(indicatorStyleGroup.current.text) text: i18n("%0 Indicator Options").arg(indicatorStyleGroup.current.text)
} }
Loader{ ColumnLayout {
id: indicatorSpecificOptions
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: units.smallSpacing * 2 Layout.leftMargin: units.smallSpacing * 2
active: plasmoid.configuration.indicatorStyle === Latte.Types.LatteIndicator spacing: 0
source: "indicator/LatteOptions.qml"
Component.onCompleted: {
latteView.indicator.configUiFor(latteView.indicator.type, indicatorSpecificOptions);
}
Connections {
target: latteView.indicator
onTypeChanged: latteView.indicator.configUiFor(latteView.indicator.type, indicatorSpecificOptions);
}
} }
} }
//! END: Indicator specific sub-options //! END: Indicator specific sub-options

@ -475,7 +475,7 @@ PlasmaComponents.Page {
Layout.fillWidth: true Layout.fillWidth: true
text: i18n("Remove Latte Tasks Applet") text: i18n("Remove Latte Tasks Applet")
enabled: latteView.latteTasksPresent() enabled: latteView.latteTasksArePresent
tooltip: i18n("Remove Latte Tasks plasmoid") tooltip: i18n("Remove Latte Tasks plasmoid")
onClicked: { onClicked: {

Loading…
Cancel
Save