diff --git a/app/iconitem.cpp b/app/iconitem.cpp new file mode 100644 index 000000000..b155ebb69 --- /dev/null +++ b/app/iconitem.cpp @@ -0,0 +1,404 @@ +/* +* Copyright 2012 Marco Martin +* Copyright 2014 David Edmundson +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#include "iconitem.h" +#include "../liblattedock/extras.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace Latte { + +IconItem::IconItem(QQuickItem *parent) + : QQuickItem(parent), + m_smooth(false), + m_active(false), + m_textureChanged(false), + m_sizeChanged(false) +{ + setFlag(ItemHasContents, true); + + connect(KIconLoader::global(), SIGNAL(iconLoaderSettingsChanged()), + this, SIGNAL(implicitWidthChanged())); + + connect(KIconLoader::global(), SIGNAL(iconLoaderSettingsChanged()), + this, SIGNAL(implicitHeightChanged())); + + connect(this, &QQuickItem::enabledChanged, + this, &IconItem::enabledChanged); + + connect(this, &QQuickItem::windowChanged, + this, &IconItem::schedulePixmapUpdate); + + connect(this, SIGNAL(overlaysChanged()), + this, SLOT(schedulePixmapUpdate())); + + //initialize implicit size to the Dialog size + setImplicitWidth(KIconLoader::global()->currentSize(KIconLoader::Dialog)); + setImplicitHeight(KIconLoader::global()->currentSize(KIconLoader::Dialog)); +} + +IconItem::~IconItem() +{ +} + +void IconItem::setSource(const QVariant &source) +{ + if (source == m_source) { + return; + } + + m_source = source; + QString sourceString = source.toString(); + + // If the QIcon was created with QIcon::fromTheme(), try to load it as svg + if (source.canConvert() && !source.value().name().isEmpty()) { + sourceString = source.value().name(); + } + + if (!sourceString.isEmpty()) { + //If a url in the form file:// is passed, take the image pointed by that from disk + QUrl url(sourceString); + + if (url.isLocalFile()) { + m_icon = QIcon(); + m_imageIcon = QImage(url.path()); + m_svgIconName.clear(); + m_svgIcon.reset(); + } else { + if (!m_svgIcon) { + m_svgIcon = std::make_unique(this); + m_svgIcon->setColorGroup(Plasma::Theme::NormalColorGroup); + m_svgIcon->setStatus(Plasma::Svg::Normal); + m_svgIcon->setDevicePixelRatio((window() ? window()->devicePixelRatio() : qApp->devicePixelRatio())); + connect(m_svgIcon.get(), &Plasma::Svg::repaintNeeded, this, &IconItem::schedulePixmapUpdate); + } + + //success? + if (m_svgIcon->isValid() && m_svgIcon->hasElement(sourceString)) { + m_icon = QIcon(); + m_svgIconName = sourceString; + + //ok, svg not available from the plasma theme + } else { + //try to load from iconloader an svg with Plasma::Svg + const auto *iconTheme = KIconLoader::global()->theme(); + QString iconPath; + + if (iconTheme) { + iconPath = iconTheme->iconPath(sourceString + QLatin1String(".svg") + , static_cast(qMin(width(), height())) + , KIconLoader::MatchBest); + + if (iconPath.isEmpty()) { + iconPath = iconTheme->iconPath(sourceString + QLatin1String(".svgz") + , static_cast(qMin(width(), height())) + , KIconLoader::MatchBest); + } + } else { + qWarning() << "KIconLoader has no theme set"; + } + + if (!iconPath.isEmpty()) { + m_svgIcon->setImagePath(iconPath); + m_svgIconName = sourceString; + //fail, use QIcon + } else { + //if we started with a QIcon use that. + m_icon = source.value(); + + if (m_icon.isNull()) { + m_icon = QIcon::fromTheme(sourceString); + } + + m_svgIconName.clear(); + m_svgIcon.reset(); + m_imageIcon = QImage(); + } + } + } + + } else if (source.canConvert()) { + m_icon = source.value(); + m_imageIcon = QImage(); + m_svgIconName.clear(); + m_svgIcon.reset(); + } else if (source.canConvert()) { + m_icon = QIcon(); + m_imageIcon = source.value(); + m_svgIconName.clear(); + m_svgIcon.reset(); + } else { + m_icon = QIcon(); + m_imageIcon = QImage(); + m_svgIconName.clear(); + m_svgIcon.reset(); + } + + if (width() > 0 && height() > 0) { + schedulePixmapUpdate(); + } + + emit sourceChanged(); + emit validChanged(); +} + +QVariant IconItem::source() const +{ + return m_source; +} + +void IconItem::setOverlays(const QStringList &overlays) +{ + if (overlays == m_overlays) { + return; + } + + m_overlays = overlays; + emit overlaysChanged(); +} + +QStringList IconItem::overlays() const +{ + return m_overlays; +} + + +bool IconItem::isActive() const +{ + return m_active; +} + +void IconItem::setActive(bool active) +{ + if (m_active == active) { + return; + } + + m_active = active; + + if (isComponentComplete()) { + schedulePixmapUpdate(); + } + + emit activeChanged(); +} + +void IconItem::setSmooth(const bool smooth) +{ + if (smooth == m_smooth) { + return; + } + + m_smooth = smooth; + update(); +} + +bool IconItem::smooth() const +{ + return m_smooth; +} + +bool IconItem::isValid() const +{ + return !m_icon.isNull() || m_svgIcon || !m_imageIcon.isNull(); +} + +int IconItem::paintedWidth() const +{ + return boundingRect().size().toSize().width(); +} + +int IconItem::paintedHeight() const +{ + return boundingRect().size().toSize().height(); +} + +void IconItem::updatePolish() +{ + QQuickItem::updatePolish(); + loadPixmap(); +} + +QSGNode *IconItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) +{ + Q_UNUSED(updatePaintNodeData) + + if (m_iconPixmap.isNull() || width() < 1.0 || height() < 1.0) { + delete oldNode; + return nullptr; + } + + ManagedTextureNode *textureNode = dynamic_cast(oldNode); + + if (!textureNode || m_textureChanged) { + if (oldNode) + delete oldNode; + + textureNode = new ManagedTextureNode; + textureNode->setTexture(QSharedPointer(window()->createTextureFromImage(m_iconPixmap.toImage()))); + m_sizeChanged = true; + m_textureChanged = false; + } + + if (m_sizeChanged) { + const auto iconSize = qMin(boundingRect().size().width(), boundingRect().size().height()); + const QRectF destRect(QPointF(boundingRect().center() - QPointF(iconSize / 2, iconSize / 2)), QSizeF(iconSize, iconSize)); + + textureNode->setRect(destRect); + m_sizeChanged = false; + } + + return textureNode; +} + +void IconItem::schedulePixmapUpdate() +{ + polish(); +} + +void IconItem::enabledChanged() +{ + schedulePixmapUpdate(); +} + +void IconItem::loadPixmap() +{ + if (!isComponentComplete()) { + return; + } + + const auto size = static_cast(qMin(width(), height())); + + //final pixmap to paint + QPixmap result; + + if (size <= 0) { + m_iconPixmap = QPixmap(); + update(); + return; + } else if (m_svgIcon) { + m_svgIcon->resize(size, size); + + if (m_svgIcon->hasElement(m_svgIconName)) { + result = m_svgIcon->pixmap(m_svgIconName); + } else if (!m_svgIconName.isEmpty()) { + const auto *iconTheme = KIconLoader::global()->theme(); + QString iconPath; + + if (iconTheme) { + iconPath = iconTheme->iconPath(m_svgIconName + QLatin1String(".svg") + , static_cast(qMin(width(), height())) + , KIconLoader::MatchBest); + + if (iconPath.isEmpty()) { + iconPath = iconTheme->iconPath(m_svgIconName + QLatin1String(".svgz"), + static_cast(qMin(width(), height())) + , KIconLoader::MatchBest); + } + } else { + qWarning() << "KIconLoader has no theme set"; + } + + if (!iconPath.isEmpty()) { + m_svgIcon->setImagePath(iconPath); + } + + result = m_svgIcon->pixmap(); + } + } else if (!m_icon.isNull()) { + result = m_icon.pixmap(QSize(size, size) * (window() ? window()->devicePixelRatio() : qApp->devicePixelRatio())); + } else if (!m_imageIcon.isNull()) { + result = QPixmap::fromImage(m_imageIcon); + } else { + m_iconPixmap = QPixmap(); + update(); + return; + } + + // Strangely KFileItem::overlays() returns empty string-values, so + // we need to check first whether an overlay must be drawn at all. + // It is more efficient to do it here, as KIconLoader::drawOverlays() + // assumes that an overlay will be drawn and has some additional + // setup time. + foreach (const QString &overlay, m_overlays) { + if (!overlay.isEmpty()) { + // There is at least one overlay, draw all overlays above m_pixmap + // and cancel the check + KIconLoader::global()->drawOverlays(m_overlays, result, KIconLoader::Desktop); + break; + } + } + + if (!isEnabled()) { + result = KIconLoader::global()->iconEffect()->apply(result, KIconLoader::Desktop, KIconLoader::DisabledState); + } else if (m_active) { + result = KIconLoader::global()->iconEffect()->apply(result, KIconLoader::Desktop, KIconLoader::ActiveState); + } + + m_iconPixmap = result; + m_textureChanged = true; + + //don't animate initial setting + update(); +} + +void IconItem::itemChange(ItemChange change, const ItemChangeData &value) +{ + QQuickItem::itemChange(change, value); +} + +void IconItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + if (newGeometry.size() != oldGeometry.size()) { + m_sizeChanged = true; + + if (newGeometry.width() > 1 && newGeometry.height() > 1) { + schedulePixmapUpdate(); + } else { + update(); + } + + const auto oldSize = qMin(oldGeometry.size().width(), oldGeometry.size().height()); + const auto newSize = qMin(newGeometry.size().width(), newGeometry.size().height()); + + if (!almost_equal(oldSize, newSize, 2)) { + emit paintedSizeChanged(); + } + } + + QQuickItem::geometryChanged(newGeometry, oldGeometry); +} + +void IconItem::componentComplete() +{ + QQuickItem::componentComplete(); + schedulePixmapUpdate(); +} + +} diff --git a/app/iconitem.h b/app/iconitem.h new file mode 100644 index 000000000..d242fca10 --- /dev/null +++ b/app/iconitem.h @@ -0,0 +1,148 @@ +/* +* Copyright 2012 Marco Martin +* Copyright 2014 David Edmundson +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef ICONITEM_H +#define ICONITEM_H + +#include + +#include +#include +#include +#include + +#include + +// this file is based on PlasmaCore::IconItem class, thanks to KDE +namespace Latte { +class IconItem : public QQuickItem { + Q_OBJECT + + /** + * Sets the icon to be displayed. Source can be one of: + * - iconName (as a string) + * - URL + * - QImage + * - QPixmap + * - QIcon + * + * When passing an icon name (or a QIcon with an icon name set) it will: + * - load the plasma variant if usesPlasmaTheme is set and exists + * - otherwise try to load the icon as an SVG so colorscopes apply + * - load the icon as normal + */ + Q_PROPERTY(QVariant source READ source WRITE setSource NOTIFY sourceChanged) + + /** + * Specifies the overlay(s) for this icon + */ + Q_PROPERTY(QStringList overlays READ overlays WRITE setOverlays NOTIFY overlaysChanged) + + /** + * See QQuickItem::smooth + */ + Q_PROPERTY(bool smooth READ smooth WRITE setSmooth NOTIFY smoothChanged) + + /** + * Apply a visual indication that this icon is active. + * Typically used to indicate that it is hovered + */ + Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged) + + /** + * True if a valid icon is set. False otherwise. + */ + Q_PROPERTY(bool valid READ isValid NOTIFY validChanged) + + /** + * The width of the icon that is actually painted + */ + Q_PROPERTY(int paintedWidth READ paintedWidth NOTIFY paintedSizeChanged) + + /** + * The height of the icon actually being drawn. + */ + Q_PROPERTY(int paintedHeight READ paintedHeight NOTIFY paintedSizeChanged) + +public: + IconItem(QQuickItem *parent = nullptr); + virtual ~IconItem(); + + void setSource(const QVariant &source); + QVariant source() const; + + void setOverlays(const QStringList &overlays); + QStringList overlays() const; + + bool isActive() const; + void setActive(bool active); + + void setSmooth(const bool smooth); + bool smooth() const; + + bool isValid() const; + + int paintedWidth() const; + int paintedHeight() const; + + void updatePolish() Q_DECL_OVERRIDE; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) override; + + void itemChange(ItemChange change, const ItemChangeData &value) override; + void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; + + void componentComplete() Q_DECL_OVERRIDE; + +signals: + void overlaysChanged(); + void activeChanged(); + void sourceChanged(); + void smoothChanged(); + void validChanged(); + void paintedSizeChanged(); + +private slots: + void schedulePixmapUpdate(); + void enabledChanged(); + +private: + void loadPixmap(); + + QIcon m_icon; + QPixmap m_iconPixmap; + QImage m_imageIcon; + std::unique_ptr m_svgIcon; + QString m_svgIconName; + QStringList m_overlays; + //this contains the raw variant it was passed + QVariant m_source; + + QSizeF m_implicitSize; + + bool m_smooth; + bool m_active; + + bool m_textureChanged; + bool m_sizeChanged; + + +}; +} +#endif // ICONITEM_H diff --git a/app/nowdockconfigview.h.autosave b/app/nowdockconfigview.h.autosave new file mode 100644 index 000000000..04ceed6c6 --- /dev/null +++ b/app/nowdockconfigview.h.autosave @@ -0,0 +1,73 @@ +/* +* Copyright 2016 Smith AR +* +* This file is part of Candil-Dock +* +* Candil-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 3 of +* the License, or (at your option) any later version. +* +* Candil-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 . +*/ + +#ifndef NOWDOCKCONFIGVIEW_H +#define NOWDOCKCONFIGVIEW_H + +#include "plasmaquick/configview.h" +#include + +#include +#include +#include +#include + +namespace Plasma { +class Applet; +class Containment; +class Types; +} + +namespace Latte { + +class NowDockView; + +class DockConfigView : public PlasmaQuick::ConfigView { + Q_OBJECT + +public: + DockConfigView(Plasma::Containment *containment, NowDockView *dockView, QWindow *parent = nullptr); + ~DockConfigView() override; + + void init() override; + Qt::WindowFlags wFlags() const; + +protected: + void showEvent(QShowEvent *ev) override; + void hideEvent(QHideEvent *ev) override; + void focusOutEvent(QFocusEvent *ev) override; + + void syncGeometry(); + void syncSlideEffect(); + +private Q_SLOTS: + void immutabilityChanged(Plasma::Types::ImmutabilityType type); + void configurationShown(PlasmaQuick::ConfigView *configView); + +private: + Plasma::Containment *m_containment{nullptr}; + QPointer m_dockView; + QTimer m_deleterTimer; + QTimer m_screenSyncTimer; + +}; + +} +#endif //DOCKCONFIGVIEW_H +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/app/nowdockview.cpp.autosave b/app/nowdockview.cpp.autosave new file mode 100644 index 000000000..5383bd86c --- /dev/null +++ b/app/nowdockview.cpp.autosave @@ -0,0 +1,572 @@ +/* + * Copyright 2014 Bhushan Shah + * Copyright 2014 Marco Martin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +#include "nowdockview.h" +#include "nowdockconfigview.h" +#include "visibilitymanager.h" + +#include +#include +#include +#include +#include +#include +//#include + +#include +#include +#include +#include +#include + +#include "nowdockcorona.h" + +namespace Latte { + +NowDockView::NowDockView(Plasma::Corona *corona, QScreen *targetScreen) + : PlasmaQuick::ContainmentView(corona), + m_corona(corona) +{ + KWindowSystem::setType(winId(), NET::Dock); + KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager); + + setVisible(false); + setTitle(corona->kPackage().metadata().name()); + setIcon(QIcon::fromTheme(corona->kPackage().metadata().iconName())); + + setResizeMode(QuickViewSharedEngine::SizeRootObjectToView); + setClearBeforeRendering(true); + /* setFlags(Qt::FramelessWindowHint + | Qt::WindowStaysOnTopHint + | Qt::NoDropShadowWindowHint + | Qt::WindowDoesNotAcceptFocus);*/ + + // NETWinInfo winfo(QX11Info::connection(), winId(), winId(), 0, 0); + // winfo.setAllowedActions(NET::ActionChangeDesktop); + + if (targetScreen) + adaptToScreen(targetScreen); + else + adaptToScreen(qGuiApp->primaryScreen()); + + m_timerGeometry.setSingleShot(true); + m_timerGeometry.setInterval(400); + + m_lockGeometry.setSingleShot(true); + m_lockGeometry.setInterval(700); + + connect(this, &NowDockView::containmentChanged + , this, [&]() { + if (!containment()) + return; + + if (!m_visibility) { + m_visibility = new VisibilityManager(this); + } + + }, Qt::DirectConnection); +} + +NowDockView::~NowDockView() +{ +} + +void NowDockView::init() +{ + connect(this, &NowDockView::screenChanged + , this, &NowDockView::adaptToScreen + , Qt::QueuedConnection); + + + connect(&m_timerGeometry, &QTimer::timeout, [&]() { + initWindow(); + }); + + connect(this, &NowDockView::locationChanged, [&]() { + //! avoid glitches + m_timerGeometry.start(); + }); + + connect(KWindowSystem::self(), &KWindowSystem::compositingChanged + , this, [&]() { + emit compositingChanged(); + } , Qt::QueuedConnection); + + connect(this, &NowDockView::screenGeometryChanged + , this, &NowDockView::updateDockPosition + , Qt::QueuedConnection); + + connect(this, SIGNAL(widthChanged(int)), this, SIGNAL(widthChanged())); + connect(this, SIGNAL(heightChanged(int)), this, SIGNAL(heightChanged())); + + rootContext()->setContextProperty(QStringLiteral("dock"), this); + engine()->rootContext()->setContextObject(new KLocalizedContext(this)); + + // engine()->rootContext()->setContextProperty(QStringLiteral("dock"), this); + setSource(corona()->kPackage().filePath("nowdockui")); + + + connect(this, SIGNAL(xChanged(int)), this, SLOT(updateDockPositionSlot())); + connect(this, SIGNAL(yChanged(int)), this, SLOT(updateDockPositionSlot())); + + connect(&m_lockGeometry, &QTimer::timeout, [&]() { + updateDockPosition(); + }); + + qDebug() << "SOURCE:" << source(); + + initialize(); +} + + +void NowDockView::initialize() +{ + m_secondInitPass = true; + m_timerGeometry.start(); +} + +void NowDockView::initWindow() +{ + // m_visibility->updateVisibilityFlags(); + + updateDockPosition(); + resizeWindow(); + + // The initialization phase makes two passes because + // changing the window style and type wants a small delay + // and afterwards the second pass positions them correctly + if (m_secondInitPass) { + m_timerGeometry.start(); + m_secondInitPass = false; + setVisible(true); + } +} + +void NowDockView::updateDockPositionSlot() +{ + if (!m_lockGeometry.isActive()) { + m_lockGeometry.start(); + } +} + +//!BEGIN SLOTS +void NowDockView::adaptToScreen(QScreen *screen) +{ + setScreen(screen); + + if (formFactor() == Plasma::Types::Vertical) + m_maxLength = screen->size().height(); + else + m_maxLength = screen->size().width(); + +// KWindowSystem::setOnAllDesktops(winId(), true); +// KWindowSystem::setType(winId(), NET::Dock); + + if (containment()) + containment()->reactToScreenChange(); + + m_timerGeometry.start(); +} + +void NowDockView::addNewDock() +{ + NowDockCorona *corona = dynamic_cast(m_corona); + + if (corona) { + corona->loadDefaultLayout(); + } +} + +void NowDockView::removeDock() +{ + NowDockCorona *corona = dynamic_cast(m_corona); + + if (corona->containments().count() > 1) { + QAction *removeAct = containment()->actions()->action(QStringLiteral("remove")); + + if (removeAct) { + removeAct->trigger(); + } + } +} + +QQmlListProperty NowDockView::screens() +{ + return QQmlListProperty(this, nullptr, &countScreens, &atScreens); +} + +int NowDockView::countScreens(QQmlListProperty *property) +{ + Q_UNUSED(property) + return qGuiApp->screens().count(); +} + +QScreen *NowDockView::atScreens(QQmlListProperty *property, int index) +{ + Q_UNUSED(property) + return qGuiApp->screens().at(index); +} + +void NowDockView::showConfigurationInterface(Plasma::Applet *applet) +{ + if (!applet || !applet->containment()) + return; + + Plasma::Containment *c = qobject_cast(applet); + + if (m_configView && c && c->isContainment() && c == containment()) { + if (m_configView->isVisible()) { + m_configView->hide(); + } else { + m_configView->show(); + m_configView->requestActivate(); + } + + return; + } else if (m_configView) { + if (m_configView->applet() == applet) { + m_configView->show(); + m_configView->requestActivate(); + return; + } else { + m_configView->hide(); + m_configView->deleteLater(); + } + } + + if (c && containment() && c->isContainment() && c->id() == containment()->id()) { + m_configView = new DockConfigView(c, this); + } else { + m_configView = new PlasmaQuick::ConfigView(applet); + } + + m_configView->init(); + m_configView->show(); + m_configView->requestActivate(); +} + +void NowDockView::resizeWindow() +{ + setVisible(true); + + QSize screenSize = screen()->size(); + + if (formFactor() == Plasma::Types::Vertical) { + const QSize size{maxThickness(), screenSize.height()}; + setMinimumSize(size); + setMaximumSize(size); + resize(size); + + qDebug() << "dock size:" << size; + } else { + const QSize size{screenSize.width(), maxThickness()}; + setMinimumSize(size); + setMaximumSize(size); + resize(size); + + qDebug() << "dock size:" << size; + } +} + +inline void NowDockView::updateDockPosition() +{ + if (!containment()) + return; + + const QRect screenGeometry = screen()->geometry(); + QPoint position; + + qDebug() << "current dock geometry: " << geometry(); + + // containment()->setFormFactor(Plasma::Types::Horizontal); + position = {0, 0}; + m_maxLength = screenGeometry.width(); + + switch (location()) { + case Plasma::Types::TopEdge: + containment()->setFormFactor(Plasma::Types::Horizontal); + position = {screenGeometry.x(), screenGeometry.y()}; + m_maxLength = screenGeometry.width(); + break; + + case Plasma::Types::BottomEdge: + containment()->setFormFactor(Plasma::Types::Horizontal); + position = {screenGeometry.x(), screenGeometry.y() + screenGeometry.height() - height()}; + m_maxLength = screenGeometry.width(); + break; + + case Plasma::Types::RightEdge: + containment()->setFormFactor(Plasma::Types::Vertical); + position = {screenGeometry.x() + screenGeometry.width() - width(), screenGeometry.y()}; + m_maxLength = screenGeometry.height(); + break; + + case Plasma::Types::LeftEdge: + containment()->setFormFactor(Plasma::Types::Vertical); + position = {screenGeometry.x(), screenGeometry.y()}; + m_maxLength = screenGeometry.height(); + break; + + default: + qWarning() << "wrong location, couldn't update the panel position" + << location(); + } + + emit maxLengthChanged(); + setX(position.x()); + setY(position.y()); + //setPosition(position); + qDebug() << "dock position:" << position; +} + +int NowDockView::currentThickness() const +{ + if (containment()->formFactor() == Plasma::Types::Vertical) { + return m_maskArea.isNull() ? width() : m_maskArea.width(); + } else { + return m_maskArea.isNull() ? height() : m_maskArea.height(); + } +} + +bool NowDockView::compositing() const +{ + return KWindowSystem::compositingActive(); +} + +/*Candil::VisibilityManager *NowDockView::visibility() +{ + return m_visibility.data(); +}*/ + +int NowDockView::maxThickness() const +{ + return m_maxThickness; +} + +void NowDockView::setMaxThickness(int thickness) +{ + if (m_maxThickness == thickness) + return; + + m_maxThickness = thickness; + m_timerGeometry.start(); + emit maxThicknessChanged(); +} + +int NowDockView::length() const +{ + return m_length; +} + +void NowDockView::setLength(int length) +{ + if (m_length == length) + return; + + if (length > m_maxLength) + m_length = m_maxLength; + else + m_length = length; + + m_timerGeometry.start(); + emit lengthChanged(); +} + +int NowDockView::maxLength() const +{ + return m_maxLength; +} + +void NowDockView::setMaxLength(int maxLength) +{ + if (m_maxLength == maxLength) + return; + + m_maxLength = maxLength; + emit maxLengthChanged(); +} + + +QRect NowDockView::maskArea() const +{ + return m_maskArea; +} + +void NowDockView::setMaskArea(QRect area) +{ + if (m_maskArea == area) { + return; + } + + m_maskArea = area; + + setMask(m_maskArea); + + //qDebug() << "dock mask set:" << m_maskArea; + emit maskAreaChanged(); +} + +/*Dock::Alignment NowDockView::alignment() const +{ + return m_alignment; +} + +void NowDockView::setAlignment(Dock::Alignment align) +{ + if (m_alignment == align) + return; + + m_alignment = align; + emit alignmentChanged(); +} +*/ +int NowDockView::offset() const +{ + return m_offset; +} + +void NowDockView::setOffset(int offset) +{ + if (m_offset == offset) + return; + + m_offset = offset; + m_timerGeometry.start(); + emit offsetChanged(); +} + +void NowDockView::updateOffset() +{ + if (!containment()) + return; + + const float offsetPercent = containment()->config().readEntry("offset").toFloat(); + const int offset = offsetPercent * (m_maxLength - m_length) / 2; + + if (offset == m_offset) + return; + + m_offset = offset; + emit offsetChanged(); +} + +VisibilityManager *NowDockView::visibility() +{ + return m_visibility; +} + +bool NowDockView::event(QEvent *e) +{ + emit eventTriggered(e); + + return ContainmentView::event(e); +} + +/*void NowDockView::showEvent(QShowEvent *ev) +{ + KWindowSystem::setType(winId(), NET::Dock); + KWindowSystem::setOnAllDesktops(winId(), true); + + //QQuickWindow::showEvent(ev); + ContainmentView::showEvent(ev); +}*/ + +bool NowDockView::containmentContainsPosition(const QPointF &point) const +{ + QQuickItem *containmentItem = containment()->property("_plasma_graphicObject").value(); + + if (!containmentItem) { + return false; + } + + return QRectF(containmentItem->mapToScene(QPoint(0, 0)), QSizeF(containmentItem->width(), containmentItem->height())).contains(point); +} + +QPointF NowDockView::positionAdjustedForContainment(const QPointF &point) const +{ + QQuickItem *containmentItem = containment()->property("_plasma_graphicObject").value(); + + if (!containmentItem) { + return point; + } + + QRectF containmentRect(containmentItem->mapToScene(QPoint(0, 0)), QSizeF(containmentItem->width(), containmentItem->height())); + + return QPointF(qBound(containmentRect.left() + 2, point.x(), containmentRect.right() - 2), + qBound(containmentRect.top() + 2, point.y(), containmentRect.bottom() - 2)); +} + +QList NowDockView::freeEdges() const +{ + QList edges = m_corona->freeEdges(containment()->screen()); + + QList edgesInt; + + foreach (Plasma::Types::Location edge, edges) { + edgesInt.append((int)edge); + } + + return edgesInt; +} + +void NowDockView::saveConfig() +{ + if (!containment()) + return; + + const auto writeEntry = [&](const char *entry, const QVariant & value) { + containment()->config().writeEntry(entry, value); + }; + + //! convert offset to percent, range [-1,1] 0 is Centered + //! offsetPercent = offset * 2 / (maxLength - length) + // const float offsetPercent = m_offset * 2.0f / (m_maxLength - m_length); + // writeEntry("offset", offsetPercent); + // writeEntry("iconSize", m_iconSize); + // writeEntry("zoomFactor", m_zoomFactor); + // writeEntry("alignment", static_cast(m_alignment)); +} + +void NowDockView::restoreConfig() +{ + if (!containment()) + return; + + const auto readEntry = [&](const char *entry, QVariant defaultValue) -> QVariant { + return containment()->config().readEntry(entry, defaultValue); + }; + //! convert offset-percent to pixels + //! offset = offsetPercent * (maxLength - length) / 2 +// const float offsetPercent {readEntry("offset", 0).toFloat()}; + // const int offset {static_cast(offsetPercent * (m_maxLength - m_length) / 2)}; + // setOffset(offset); + + // setIconSize(readEntry("iconSize", 32).toInt()); + // setZoomFactor(readEntry("zoomFactor", 1.0).toFloat()); + // setAlignment(static_cast(readEntry("alignment", Dock::Center).toInt())); +} + +} + +//!END SLOTS + + +//!END namespace diff --git a/install.sh b/install.sh old mode 100644 new mode 100755