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(liblatte2)
add_subdirectory(indicators)
add_subdirectory(app)
add_subdirectory(containmentactions)
add_subdirectory(containment)

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

@ -184,10 +184,27 @@ bool Importer::importOldLayout(QString oldAppletsPath, QString newName, bool alt
return true;
}
QString Importer::standardPath(QString subPath, bool localfirst)
QStringList Importer::standardPaths(bool localfirst)
{
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) {
foreach (auto pt, paths) {
QString ptF = pt + "/" +subPath;

@ -74,6 +74,9 @@ public:
//! returns the standard path found that contains the subPath
//! local paths have higher priority by default
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
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
*
@ -17,18 +17,36 @@
* 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
import org.kde.plasma.core 2.0 as PlasmaCore
// Qt
#include <QHash>
#include <QObject>
import org.kde.latte 0.2 as Latte
class KPluginMetaData;
Item{
id: common
namespace Latte {
namespace Indicator {
readonly property bool indicatorsEnabled: true
readonly property bool reversedEnabled: plasmoid.configuration.reverseLinesPosition
class Factory : public QObject
{
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 "layoutmanager.h"
#include "screenpool.h"
#include "indicator/factory.h"
#include "shortcuts/globalshortcuts.h"
#include "package/lattepackage.h"
#include "plasma/extended/screenpool.h"
@ -79,6 +80,7 @@ Corona::Corona(bool defaultLayoutOnStartup, QString layoutNameOnStartUp, int use
m_layoutNameOnStartUp(layoutNameOnStartUp),
m_activityConsumer(new KActivities::Consumer(this)),
m_screenPool(new ScreenPool(KSharedConfig::openConfig(), this)),
m_indicatorFactory(new Indicator::Factory(this)),
m_universalSettings(new UniversalSettings(KSharedConfig::openConfig(), this)),
m_globalShortcuts(new GlobalShortcuts(this)),
m_plasmaScreenPool(new PlasmaExtended::ScreenPool(this)),
@ -178,6 +180,7 @@ Corona::~Corona()
m_plasmaScreenPool->deleteLater();
m_backgroundTracer->deleteLater();
m_themeExtended->deleteLater();
m_indicatorFactory->deleteLater();
disconnect(m_activityConsumer, &KActivities::Consumer::serviceStatusChanged, this, &Corona::load);
delete m_activityConsumer;
@ -392,6 +395,11 @@ AbstractWindowInterface *Corona::wm() const
return m_wm;
}
Indicator::Factory *Corona::indicatorFactory() const
{
return m_indicatorFactory;
}
PlasmaExtended::ScreenPool *Corona::plasmaScreenPool() const
{
return m_plasmaScreenPool;

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

@ -398,7 +398,7 @@ void GlobalShortcuts::activateEntry(int index, Qt::Key modifier)
continue;
}
if ((!view->latteTasksPresent() && view->tasksPresent() &&
if ((!view->latteTasksArePresent() && view->tasksPresent() &&
activatePlasmaTaskManagerEntryAtContainment(view->containment(), index, modifier))
|| activateLatteEntryAtContainment(view, index, modifier)) {
@ -475,7 +475,7 @@ void GlobalShortcuts::updateViewItemBadge(QString identifier, QString value)
bool GlobalShortcuts::isCapableToShowShortcutBadges(Latte::View *view)
{
if (!view->latteTasksPresent() && view->tasksPresent()) {
if (!view->latteTasksArePresent() && view->tasksPresent()) {
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);
const auto flags = Qt::FramelessWindowHint
| Qt::WindowStaysOnTopHint
| Qt::NoDropShadowWindowHint
| Qt::WindowDoesNotAcceptFocus;
| Qt::WindowStaysOnTopHint
| Qt::NoDropShadowWindowHint
| Qt::WindowDoesNotAcceptFocus;
if (byPassWM) {
setFlags(flags | Qt::BypassWindowManagerHint);
@ -92,7 +92,7 @@ View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassWM)
m_positioner->setScreenToFollow(qGuiApp->primaryScreen());
connect(this, &View::containmentChanged
, this, [ &, byPassWM]() {
, this, [ &, byPassWM]() {
qDebug() << "dock view c++ containment changed 1...";
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
if (!m_windowsTracker) {
m_windowsTracker = new ViewPart::WindowsTracker(this);
emit windowsTrackerChanged();
}
if (!m_visibility) {
@ -122,6 +123,13 @@ View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassWM)
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)));
@ -168,6 +176,10 @@ View::~View()
delete m_positioner;
}
if (m_indicator) {
delete m_indicator;
}
if (m_effects) {
delete m_effects;
}
@ -414,7 +426,7 @@ void View::updateAbsDockGeometry(bool bypassChecks)
//! behavior and keeping this comment in order to check for
//! multi-screen breakage
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)
return;
@ -433,7 +445,7 @@ void View::statusChanged(Plasma::Types::ItemStatus status)
{
if (containment()) {
if (containment()->status() >= Plasma::Types::NeedsAttentionStatus &&
containment()->status() != Plasma::Types::HiddenStatus) {
containment()->status() != Plasma::Types::HiddenStatus) {
setBlockHiding(true);
} else if (!containment()->isUserConfiguring()){
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)
{
if (view != this) {
@ -920,26 +947,6 @@ bool View::tasksPresent()
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
bool View::mimeContainsPlasmoid(QMimeData *mimeData, QString name)
{
@ -965,6 +972,11 @@ ViewPart::Effects *View::effects() const
return m_effects;
}
ViewPart::Indicator *View::indicator() const
{
return m_indicator;
}
ViewPart::Positioner *View::positioner() const
{
return m_positioner;
@ -986,56 +998,56 @@ bool View::event(QEvent *e)
emit eventTriggered(e);
switch (e->type()) {
case QEvent::Enter:
m_containsMouse = true;
if (m_configView && KWindowSystem::isPlatformX11()) {
ViewPart::PrimaryConfigView *primaryConfigView = qobject_cast<ViewPart::PrimaryConfigView *>(m_configView);
case QEvent::Enter:
m_containsMouse = true;
if (primaryConfigView) {
if (primaryConfigView->secondaryWindow()) {
primaryConfigView->secondaryWindow()->requestActivate();
}
if (m_configView && KWindowSystem::isPlatformX11()) {
ViewPart::PrimaryConfigView *primaryConfigView = qobject_cast<ViewPart::PrimaryConfigView *>(m_configView);
primaryConfigView->requestActivate();
if (primaryConfigView) {
if (primaryConfigView->secondaryWindow()) {
primaryConfigView->secondaryWindow()->requestActivate();
}
primaryConfigView->requestActivate();
}
break;
case QEvent::Leave:
m_containsMouse = false;
engine()->trimComponentCache();
break;
case QEvent::PlatformSurface:
if (auto pe = dynamic_cast<QPlatformSurfaceEvent *>(e)) {
switch (pe->surfaceEventType()) {
case QPlatformSurfaceEvent::SurfaceCreated:
setupWaylandIntegration();
if (m_shellSurface) {
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 QEvent::Leave:
m_containsMouse = false;
engine()->trimComponentCache();
break;
case QEvent::PlatformSurface:
if (auto pe = dynamic_cast<QPlatformSurfaceEvent *>(e)) {
switch (pe->surfaceEventType()) {
case QPlatformSurfaceEvent::SurfaceCreated:
setupWaylandIntegration();
if (m_shellSurface) {
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;
break;
default:
break;
default:
break;
}
}

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

@ -41,10 +41,6 @@
<default>20</default>
<label>this is a percentage value</label>
</entry>
<entry name="lengthIntMargin" type="Int">
<default>8</default>
<label>this is a percentage value</label>
</entry>
<entry name="lengthExtMargin" type="Int">
<default>0</default>
<label>this is a percentage value</label>
@ -153,44 +149,6 @@
<entry name="showGlow" type="Bool">
<default>false</default>
</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">
<default>100</default>
</entry>

@ -136,6 +136,13 @@ Item{
value: root.editMode
}
Binding{
target: latteView
property:"latteTasksArePresent"
when: latteView
value: latteApplet !== null
}
Binding{
target: latteView
property: "maxLength"
@ -221,7 +228,7 @@ Item{
target: latteView && latteView.windowsTracker ? latteView.windowsTracker : null
property: "enabled"
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
|| plasmoid.configuration.solidBackgroundForMaximized
|| root.disablePanelShadowMaximized

@ -331,6 +331,12 @@ Item {
if (isHidden)
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.clearZoomSignal.disconnect(clearZoom);
@ -494,14 +500,15 @@ Item {
width: wrapper.width
height: wrapper.height
Indicator.Manager{
id: indicatorManager
Indicator.Bridge{
id: indicatorBridge
}
//! Indicator Back Layer
Indicator.Loader{
id: indicatorBackLayer
manager: indicatorManager
bridge: indicatorBridge
isBackground: true
}
ItemWrapper{
@ -534,8 +541,8 @@ Item {
//! Indicator Front Layer
Indicator.Loader{
id: indicatorFrontLayer
manager: indicatorManager
isBackLayer: false
bridge: indicatorBridge
isBackground: false
}
//! Applet Shortcut Visual Badge
@ -584,7 +591,7 @@ Item {
wrapMode: Text.WordWrap
elide: Text.ElideRight
fontSizeMode: Text.Fit
color: colorizerManager.applyTheme.textColor
color: colorizerManager.textColor
rotation: {
if (root.isHorizontal)

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

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

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

@ -24,29 +24,21 @@ import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.latte 0.2 as Latte
import "options" as Options
import "../applet/indicator" as AppletIndicator
Item{
id: managerIndicator
readonly property Item common: commonOptions
readonly property Item explicit: explicitOptions.item
readonly property QtObject configuration: latteView && latteView.indicator ? latteView.indicator.configuration : null
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: {
switch (indicators.common.indicatorStyle) {
case Latte.Types.LatteIndicator:
return latteStyleIndicator;
case Latte.Types.PlasmaIndicator:
return plasmaStyleIndicator;
case Latte.Types.UnityIndicator:
return unityStyleIndicator;
default:
return latteStyleIndicator;
};
}
readonly property Component plasmaStyleComponent: latteView && latteView.indicator ? latteView.indicator.plasmaComponent : null
readonly property Component indicatorComponent: latteView && latteView.indicator ? latteView.indicator.component : null
readonly property Item info: Item{
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
Loader{
id: metricsLoader
opacity: 0
active: managerIndicator.isEnabled
readonly property bool isBackLayer: true
readonly property Item manager: AppletIndicator.Manager{
readonly property bool isBackground: true
readonly property Item bridge: AppletIndicator.Bridge{
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 org.kde.plasma.plasmoid 2.0
import org.kde.plasma.private.pager 2.0
import org.kde.latte 0.2 as Latte
@ -35,7 +36,7 @@ Loader {
enabled: true
showDesktop: true
showOnlyCurrentScreen: true
screenGeometry: latteView.screenGeometry
screenGeometry: latteView ? latteView.screenGeometry : plasmoid.screenGeometry
pagerType: root.scrollAction === Latte.Types.ScrollDesktops ? PagerModel.VirtualDesktops : PagerModel.Activities
}

@ -241,7 +241,8 @@ DragDrop.DropArea {
if (( (plasmoid.configuration.panelShadows && !root.backgroundOnlyOnMaximized)
|| (plasmoid.configuration.panelShadows && root.backgroundOnlyOnMaximized && !root.forceTransparentPanel))
&& !(disablePanelShadowMaximized && latteView.windowsTracker.activeWindowMaximized)) {
&& !(disablePanelShadowMaximized && latteView && latteView.windowsTracker
&& latteView.windowsTracker.activeWindowMaximized)) {
return true;
}
@ -317,7 +318,7 @@ DragDrop.DropArea {
property int lengthIntMargin: lengthIntMarginFactor * 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 thickMarginFactor: {
@ -1434,7 +1435,7 @@ DragDrop.DropArea {
function updateContainsOnlyPlasmaTasks() {
if (latteView) {
root.containsOnlyPlasmaTasks = (latteView.tasksPresent() && !latteView.latteTasksPresent());
root.containsOnlyPlasmaTasks = (latteView.tasksPresent() && !latteApplet);
} else {
root.containsOnlyPlasmaTasks = false;
}

@ -205,24 +205,27 @@ Item{
//! add border around indicator without reducing its size
Loader{
anchors.centerIn: mainElement
active: glowItem.showBorder && !glowItem.showGlow
active: glowItem.showBorder
sourceComponent:Rectangle {
width: size
height: size
width: mainElement.width + size
height: mainElement.height + size
anchors.centerIn: parent
color: contrastColorAlpha2
radius: glowItem.roundCorners ? Math.min(width,height) / 2 : 0
property int size: Math.min(mainElement.width + 2*Math.max(1,mainElement.width/5 ),
mainElement.height + 2*Math.max(1,mainElement.height/5 ))
property int size: Math.min(2*Math.max(1,mainElement.width/5 ),
2*Math.max(1,mainElement.height/5 ))
}
}
Item{
id:mainElement
anchors.fill: parent
width: Math.max(glowItem.size, parent.width)
height: Math.max(glowItem.size, parent.height)
anchors.centerIn: parent
Rectangle {
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
*
@ -19,14 +19,7 @@
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: "Plasma"
readonly property bool usePlasmaTabsStyle: !commonOptions.indicatorsForApplets
Item {
readonly property Item indicator: parent && parent.hasOwnProperty("bridge") ? parent.bridge : null
readonly property Item attributes: parent
}

@ -6,6 +6,7 @@ ExternalShadow 1.0 ExternalShadow.qml
GlowPoint 1.0 GlowPoint.qml
Header 1.0 Header.qml
HeaderSwitch 1.0 HeaderSwitch.qml
IndicatorItem 1.0 IndicatorItem.qml
Slider 1.0 Slider.qml
SpinBox 1.0 SpinBox.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
ColumnLayout {
Layout.fillWidth: true
LatteComponents.SubHeader {
text: i18nc("active indicator style","Style For Active")
}
@ -39,13 +41,13 @@ ColumnLayout {
Layout.fillWidth: true
spacing: 2
property int indicatorType: plasmoid.configuration.activeIndicatorType
property int indicatorType: indicator.configuration.activeStyle
ExclusiveGroup {
id: activeIndicatorTypeGroup
onCurrentChanged: {
if (current.checked) {
plasmoid.configuration.activeIndicatorType = current.indicatorType;
indicator.configuration.activeStyle = current.indicatorType;
}
}
}
@ -59,7 +61,7 @@ ColumnLayout {
exclusiveGroup: activeIndicatorTypeGroup
tooltip: i18n("Show a line indicator for active items")
readonly property int indicatorType: Latte.Types.LineIndicator
readonly property int indicatorType: 0 /*Line*/
}
PlasmaComponents.Button {
@ -71,38 +73,38 @@ ColumnLayout {
exclusiveGroup: activeIndicatorTypeGroup
tooltip: i18n("Show a dot indicator for active items")
readonly property int indicatorType: Latte.Types.DotIndicator
readonly property int indicatorType: 1 /*Dot*/
}
}
LatteComponents.HeaderSwitch {
id: showGlow
id: glowEnabled
Layout.fillWidth: true
Layout.minimumHeight: implicitHeight
Layout.bottomMargin: units.smallSpacing
checked: plasmoid.configuration.showGlow
checked: indicator.configuration.glowEnabled
level: 2
text: i18n("Glow")
tooltip: i18n("Enable/disable indicator glow")
onPressed: {
plasmoid.configuration.showGlow = !plasmoid.configuration.showGlow;
indicator.configuration.glowEnabled = !indicator.configuration.glowEnabled;
}
}
RowLayout {
Layout.fillWidth: true
spacing: 2
enabled: plasmoid.configuration.showGlow
enabled: indicator.configuration.glowEnabled
property int option: plasmoid.configuration.glowOption
property int option: indicator.configuration.glowApplyTo
ExclusiveGroup {
id: glowGroup
onCurrentChanged: {
if (current.checked)
plasmoid.configuration.glowOption = current.option
indicator.configuration.glowApplyTo = current.option
}
}
@ -114,7 +116,7 @@ ColumnLayout {
exclusiveGroup: glowGroup
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 {
@ -125,7 +127,7 @@ ColumnLayout {
exclusiveGroup: glowGroup
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
spacing: 2
enabled: plasmoid.configuration.showGlow
enabled: indicator.configuration.glowEnabled
PlasmaComponents.Label {
Layout.minimumWidth: implicitWidth
@ -147,7 +149,7 @@ ColumnLayout {
Layout.fillWidth: true
leftPadding: 0
value: plasmoid.configuration.glowOpacity
value: indicator.configuration.glowOpacity * 100
from: 0
to: 100
stepSize: 5
@ -155,7 +157,7 @@ ColumnLayout {
function updateGlowOpacity() {
if (!pressed)
plasmoid.configuration.glowOpacity = value;
indicator.configuration.glowOpacity = value/100;
}
onPressedChanged: {
@ -181,32 +183,32 @@ ColumnLayout {
ColumnLayout {
spacing: 0
visible: latteView.latteTasksPresent()
visible: indicator.latteTasksArePresent
LatteComponents.SubHeader {
enabled: plasmoid.configuration.glowOption!==Latte.Types.GlowNone
enabled: indicator.configuration.glowApplyTo!==0/*None*/
text: i18n("Tasks")
}
PlasmaComponents.CheckBox {
id: threeColorsWindows
text: i18n("Different color for minimized windows")
checked: plasmoid.configuration.threeColorsWindows
checked: indicator.configuration.minimizedTaskColoredDifferently
onClicked: {
plasmoid.configuration.threeColorsWindows = checked
indicator.configuration.minimizedTaskColoredDifferently = checked;
}
}
PlasmaComponents.CheckBox {
id: dotsOnActive
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")
enabled: plasmoid.configuration.activeIndicatorType === Latte.Types.LineIndicator
enabled: indicator.configuration.activeStyle === 0 /*Line*/
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
*
@ -17,19 +17,32 @@
* 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.latte 0.2 as Latte
import org.kde.latte.components 1.0 as LatteComponents
Item{
id: common
LatteComponents.IndicatorItem {
readonly property bool providesFrontLayer: true
readonly property bool indicatorsEnabled: plasmoid.configuration.indicatorsEnabled
readonly property bool indicatorsForApplets: plasmoid.configuration.indicatorsForApplets
readonly property bool reversedEnabled: plasmoid.configuration.reverseLinesPosition
//! Background Layer
Loader{
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(DIRECTORY qml/ 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
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 "options" as Options
import "options" as IndicatorOptions
import "styles" as IndicatorStyles
import "../task/indicator" as TaskIndicator
Item{
id: managerIndicator
readonly property Item common: commonOptions
readonly property Item explicit: explicitOptions
readonly property Item configuration: 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 Item info: Item{
readonly property bool needsIconColors: metricsLoader.active && metricsLoader.item && metricsLoader.item.hasOwnProperty("needsIconColors")
&& metricsLoader.item.needsIconColors
readonly property bool providesFrontLayer: metricsLoader.active && metricsLoader.item && metricsLoader.item.hasOwnProperty("providesFrontLayer")
&& 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
readonly property bool needsIconColors: false
readonly property bool providesFrontLayer: false
readonly property int extraMaskThickness: 0
}
Options.Latte {
IndicatorOptions.Latte {
id : explicitOptions
}
//! Indicators Components
Component {
id: latteStyleIndicator
Latte.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
IndicatorStyles.LatteIndicator{}
}
}

@ -27,13 +27,13 @@ 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: Latte.Types.LineIndicator
readonly property bool extraDotOnActive: plasmoid.configuration.dotsOnActive
readonly property bool minimizedTaskColoredDifferently: plasmoid.configuration.threeColorsWindows
readonly property int activeStyle: Latte.Types.LineIndicator
//!glow options
readonly property bool glowEnabled: plasmoid.configuration.showGlow
readonly property bool glow3D: false
readonly property int glowOption: Latte.Types.GlowAll
readonly property int glowApplyTo: 2 /*All*/
readonly property real glowOpacity: 0.35
}

@ -1,6 +1,5 @@
/*
* Copyright 2016 Smith AR <audoban@openmailbox.org>
* Michail Vourlakos <mvourlakos@gmail.com>
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
*
* 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.components 1.0 as LatteComponents
import "../code/ColorizerTools.js" as ColorizerTools
Item{
id: indicatorRoot
readonly property Item options: parent.manager
LatteComponents.IndicatorItem{
id: root
readonly property real factor: 0.08
readonly property int size: factor * options.currentIconSize
readonly property int extraMaskThickness: reversedEnabled && glowEnabled ? 1.7 * (factor * options.maxIconSize) : 0
readonly property int size: indicator ? factor * indicator.currentIconSize : factor * 64
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 minimizedColor: {
if (multiColorEnabled) {
if (minimizedTaskColoredDifferently) {
return (textColorBrightness > 127.5 ? Qt.darker(theme.textColor, 1.7) : Qt.lighter(theme.textColor, 7));
}
return isActiveColor;
}
property color notActiveColor: options.isMinimized ? minimizedColor : isActiveColor
property color notActiveColor: indicator && indicator.isMinimized ? minimizedColor : isActiveColor
//! Common Options
readonly property bool reversedEnabled: options && options.common && options.common.hasOwnProperty("reversedEnabled") ?
options.common.reversedEnabled : false
readonly property bool reversedEnabled: indicator && indicator.general ? indicator.general.reversed : false
//! Explicit Options
readonly property bool explicitOptionsEnabled: options.explicit
&& options.explicit.hasOwnProperty("styleName")
&& options.explicit.styleName === "Latte"
//! Configuration Options
readonly property bool configurationEnabled: (indicator!==null) && (indicator.configuration !== null)
readonly property bool dotsOnActive: explicitOptionsEnabled ? options.explicit.dotsOnActive : true
readonly property bool multiColorEnabled: explicitOptionsEnabled ? options.explicit.multiColorEnabled : false
readonly property int activeIndicatorType: explicitOptionsEnabled ? options.explicit.activeIndicatorType : Latte.Types.LineIndicator
readonly property bool extraDotOnActive: configurationEnabled ? indicator.configuration.extraDotOnActive : true
readonly property bool minimizedTaskColoredDifferently: configurationEnabled ? indicator.configuration.minimizedTaskColoredDifferently : false
readonly property int activeStyle: configurationEnabled ? indicator.configuration.activeStyle : 0 /*Line*/
//!glow options
readonly property bool glowEnabled: explicitOptionsEnabled ? options.explicit.glowEnabled : true
readonly property bool glow3D: explicitOptionsEnabled ? options.explicit.glow3D : false
readonly property int glowOption: explicitOptionsEnabled ? options.explicit.glowOption : Latte.Types.GlowAll
readonly property real glowOpacity: explicitOptionsEnabled ? options.explicit.glowOpacity : 0.35
readonly property bool glowEnabled: configurationEnabled ? indicator.configuration.glowEnabled : true
readonly property bool glow3D: configurationEnabled ? indicator.configuration.glow3D : false
readonly property int glowApplyTo: configurationEnabled ? indicator.configuration.glowApplyTo : 2 /*All*/
readonly property real glowOpacity: configurationEnabled ? indicator.configuration.glowOpacity : 0.35
/*Rectangle{
anchors.fill: parent
@ -77,6 +70,16 @@ Item{
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
@ -90,89 +93,89 @@ Item{
LatteComponents.GlowPoint{
id:firstPoint
opacity: {
if (options.isTask) {
return options.isLauncher || (options.inRemoving && !activeAndReverseAnimation.running) ? 0 : 1
if (indicator.isTask) {
return indicator.isLauncher || (indicator.inRemoving && !activeAndReverseAnimation.running) ? 0 : 1
}
if (options.isApplet) {
return (options.isActive || activeAndReverseAnimation.running) ? 1 : 0
if (indicator.isApplet) {
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
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
glowOpacity: indicatorRoot.glowOpacity
contrastColor: options.shadowColor
glowOpacity: root.glowOpacity
contrastColor: indicator.shadowColor
attentionColor: theme.negativeTextColor
roundCorners: true
showAttention: options.inAttention
showAttention: indicator.inAttention
showGlow: {
if (glowEnabled && (glowOption === Latte.Types.GlowAll || showAttention ))
if (glowEnabled && (glowApplyTo === 2 /*All*/ || showAttention ))
return true;
else if (glowEnabled && glowOption === Latte.Types.GlowOnlyOnActive && options.hasActive)
else if (glowEnabled && glowApplyTo === 1 /*OnActive*/ && indicator.hasActive)
return true;
else
return false;
}
showBorder: glowEnabled && glow3D
property int stateWidth: options.isGroup ? indicatorRoot.width - secondPoint.width : indicatorRoot.width - spacer.width
property int stateHeight: options.isGroup ? indicatorRoot.height - secondPoint.height : indicatorRoot.width - spacer.height
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: 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 real scaleFactor: options.scaleFactor
property real scaleFactor: indicator.scaleFactor
function updateInitialSizes(){
if(indicatorRoot){
if(root){
if(vertical)
width = indicatorRoot.size;
width = root.size;
else
height = indicatorRoot.size;
height = root.size;
if(vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator)
if(vertical && isActive && activeStyle === 0 /*Line*/)
height = stateHeight;
else
height = indicatorRoot.size;
height = root.size;
if(!vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator)
if(!vertical && isActive && activeStyle === 0 /*Line*/)
width = stateWidth;
else
width = indicatorRoot.size;
width = root.size;
}
}
onIsActiveChanged: {
if (activeIndicatorType === Latte.Types.LineIndicator)
if (activeStyle === 0 /*Line*/)
activeAndReverseAnimation.start();
}
onScaleFactorChanged: {
if(!activeAndReverseAnimation.running && !vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator){
if(!activeAndReverseAnimation.running && !vertical && isActive && activeStyle === 0 /*Line*/){
width = stateWidth;
}
else if (!activeAndReverseAnimation.running && vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator){
else if (!activeAndReverseAnimation.running && vertical && isActive && activeStyle === 0 /*Line*/){
height = stateHeight;
}
}
onStateWidthChanged:{
if(!activeAndReverseAnimation.running && !vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator)
if(!activeAndReverseAnimation.running && !vertical && isActive && activeStyle === 0 /*Line*/)
width = stateWidth;
}
onStateHeightChanged:{
if(!activeAndReverseAnimation.running && vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator)
if(!activeAndReverseAnimation.running && vertical && isActive && activeStyle === 0 /*Line*/)
height = stateHeight;
}
@ -181,14 +184,14 @@ Item{
Component.onCompleted: {
updateInitialSizes();
if (options) {
options.onCurrentIconSizeChanged.connect(updateInitialSizes);
if (indicator) {
indicator.onCurrentIconSizeChanged.connect(updateInitialSizes);
}
}
Component.onDestruction: {
if (options) {
options.onCurrentIconSizeChanged.disconnect(updateInitialSizes);
if (indicator) {
indicator.onCurrentIconSizeChanged.disconnect(updateInitialSizes);
}
}
@ -196,8 +199,8 @@ Item{
id: activeAndReverseAnimation
target: firstPoint
property: plasmoid.formFactor === PlasmaCore.Types.Vertical ? "height" : "width"
to: options.hasActive && activeIndicatorType === Latte.Types.LineIndicator
? (plasmoid.formFactor === PlasmaCore.Types.Vertical ? firstPoint.stateHeight : firstPoint.stateWidth) : indicatorRoot.size
to: indicator.hasActive && activeStyle === 0 /*Line*/
? (plasmoid.formFactor === PlasmaCore.Types.Vertical ? firstPoint.stateHeight : firstPoint.stateWidth) : root.size
duration: firstPoint.animationTime
easing.type: Easing.InQuad
@ -207,34 +210,34 @@ Item{
Item{
id:spacer
width: secondPoint.visible ? 0.5*indicatorRoot.size : 0
height: secondPoint.visible ? 0.5*indicatorRoot.size : 0
width: secondPoint.visible ? 0.5*root.size : 0
height: secondPoint.visible ? 0.5*root.size : 0
}
LatteComponents.GlowPoint{
id:secondPoint
width: visible ? indicatorRoot.size : 0
width: visible ? root.size : 0
height: width
size: indicatorRoot.size
size: root.size
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
glowOpacity: indicatorRoot.glowOpacity
contrastColor: options.shadowColor
glowOpacity: root.glowOpacity
contrastColor: indicator.shadowColor
showBorder: glowEnabled && glow3D
basicColor: state2Color
roundCorners: true
showGlow: glowEnabled && glowOption === Latte.Types.GlowAll
visible: ( options.isGroup && ((dotsOnActive && activeIndicatorType === Latte.Types.LineIndicator)
|| activeIndicatorType === Latte.Types.DotIndicator
|| !options.hasActive) )? true: false
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: options.hasShown ? indicatorRoot.isActiveColor : indicatorRoot.minimizedColor
property color state1Color: indicator.hasShown ? root.isActiveColor : root.minimizedColor
//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 disableRestoreZoom: false //blocks restore animation in rightClick
property bool disableAllWindowsFunctionality: root.showWindowsOnlyFromLaunchers && !indicatorsEnabled
property bool disableAllWindowsFunctionality: root.showWindowsOnlyFromLaunchers && !indicators.isEnabled
property bool dropNewLauncher: false
readonly property bool hasInternalSeparator: parabolicManager.hasInternalSeparator
property bool inActivityChange: false
@ -349,7 +349,7 @@ Item {
Loader {
id: indicatorsStandaloneLoader
active: !latteView
active: !latteView && !plasmoid.configuration.isInLatteDock
source: "indicators/Manager.qml"
}

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

@ -26,10 +26,10 @@ import org.kde.latte 0.2 as Latte
import "../../indicators/options" as TaskIndicator
Item {
id: indicatorManager
id: indicatorBridge
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
/* 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 color shadowColor: root.appShadowColorSolid
readonly property bool usePlasmaTabsStyle: false
readonly property QtObject palette: enforceLattePalette ? latteBridge.palette.applyTheme : theme
//!icon colors
property color backgroundColor: taskIsValid ? taskItem.wrapperAlias.backgroundColor : "black"
property color glowColor: taskIsValid ? taskItem.wrapperAlias.glowColor : "white"
//! grouped options
readonly property Item common: indicators ? indicators.common : emptyOptions
readonly property Item explicit: indicators ? indicators.explicit : emptyOptions
readonly property Item shared: indicators ? indicators : emptyOptions
readonly property QtObject configuration: indicators ? indicators.configuration : null
Item{id: emptyOptions}
}

@ -19,6 +19,7 @@
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
@ -33,10 +34,11 @@ Loader {
anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined
anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined
property bool isBackLayer: true
property Item manager
property bool isBackground: true
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
width: {

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

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

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

Loading…
Cancel
Save