mirror of
https://github.com/KDE/latte-dock.git
synced 2025-01-10 21:18:19 +03:00
provide latte internal widget explorer
This commit is contained in:
parent
3ec62e6ecc
commit
84d4d4cef7
@ -45,6 +45,7 @@ void Package::initPackage(KPackage::Package *package)
|
|||||||
package->setPath("org.kde.latte.shell");
|
package->setPath("org.kde.latte.shell");
|
||||||
package->addFileDefinition("defaults", QStringLiteral("defaults"), i18n("Latte Dock defaults"));
|
package->addFileDefinition("defaults", QStringLiteral("defaults"), i18n("Latte Dock defaults"));
|
||||||
package->addFileDefinition("lattedockui", QStringLiteral("views/Panel.qml"), i18n("Latte Dock panel"));
|
package->addFileDefinition("lattedockui", QStringLiteral("views/Panel.qml"), i18n("Latte Dock panel"));
|
||||||
|
package->addFileDefinition("widgetexplorerui", QStringLiteral("views/WidgetExplorer.qml"), i18n("Widget Explorer"));
|
||||||
//Configuration
|
//Configuration
|
||||||
package->addFileDefinition("lattedockconfigurationui", QStringLiteral("configuration/LatteDockConfiguration.qml"), i18n("Dock configuration UI"));
|
package->addFileDefinition("lattedockconfigurationui", QStringLiteral("configuration/LatteDockConfiguration.qml"), i18n("Dock configuration UI"));
|
||||||
package->addFileDefinition("lattedocksecondaryconfigurationui", QStringLiteral("configuration/LatteDockSecondaryConfiguration.qml"), i18n("Dock secondary configuration UI"));
|
package->addFileDefinition("lattedocksecondaryconfigurationui", QStringLiteral("configuration/LatteDockSecondaryConfiguration.qml"), i18n("Dock secondary configuration UI"));
|
||||||
|
@ -6,5 +6,6 @@ set(lattedock-app_SRCS
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/secondaryconfigview.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/secondaryconfigview.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/subconfigview.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/subconfigview.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/viewsettingsfactory.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/viewsettingsfactory.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/widgetexplorerview.cpp
|
||||||
PARENT_SCOPE
|
PARENT_SCOPE
|
||||||
)
|
)
|
||||||
|
@ -78,7 +78,7 @@ signals:
|
|||||||
void enabledBordersChanged();
|
void enabledBordersChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void syncSlideEffect();
|
virtual void syncSlideEffect();
|
||||||
|
|
||||||
virtual void init();
|
virtual void init();
|
||||||
virtual void initParentView(Latte::View *view);
|
virtual void initParentView(Latte::View *view);
|
||||||
@ -87,7 +87,7 @@ protected:
|
|||||||
void showEvent(QShowEvent *ev) override;
|
void showEvent(QShowEvent *ev) override;
|
||||||
bool event(QEvent *e) override;
|
bool event(QEvent *e) override;
|
||||||
|
|
||||||
Qt::WindowFlags wFlags() const;
|
virtual Qt::WindowFlags wFlags() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool m_isNormalWindow{true};
|
bool m_isNormalWindow{true};
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "viewsettingsfactory.h"
|
#include "viewsettingsfactory.h"
|
||||||
|
|
||||||
#include "primaryconfigview.h"
|
#include "primaryconfigview.h"
|
||||||
|
#include "widgetexplorerview.h"
|
||||||
#include "../view.h"
|
#include "../view.h"
|
||||||
|
|
||||||
// Plasma
|
// Plasma
|
||||||
@ -81,5 +82,16 @@ ViewPart::PrimaryConfigView *ViewSettingsFactory::primaryConfigView(Latte::View
|
|||||||
return m_primaryConfigView;
|
return m_primaryConfigView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ViewPart::WidgetExplorerView *ViewSettingsFactory::widgetExplorerView(Latte::View *view)
|
||||||
|
{
|
||||||
|
if (!m_widgetExplorerView) {
|
||||||
|
m_widgetExplorerView = new ViewPart::WidgetExplorerView(view);
|
||||||
|
} else {
|
||||||
|
m_widgetExplorerView->setParentView(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_widgetExplorerView;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ class View;
|
|||||||
|
|
||||||
namespace ViewPart {
|
namespace ViewPart {
|
||||||
class PrimaryConfigView;
|
class PrimaryConfigView;
|
||||||
|
class WidgetExplorerView;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -55,9 +56,11 @@ public:
|
|||||||
|
|
||||||
Plasma::Containment *lastContainment();
|
Plasma::Containment *lastContainment();
|
||||||
ViewPart::PrimaryConfigView *primaryConfigView(Latte::View *view);
|
ViewPart::PrimaryConfigView *primaryConfigView(Latte::View *view);
|
||||||
|
ViewPart::WidgetExplorerView *widgetExplorerView(Latte::View *view);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPointer<ViewPart::PrimaryConfigView> m_primaryConfigView;
|
QPointer<ViewPart::PrimaryConfigView> m_primaryConfigView;
|
||||||
|
QPointer<ViewPart::WidgetExplorerView> m_widgetExplorerView;
|
||||||
QPointer<Plasma::Containment> m_lastContainment;
|
QPointer<Plasma::Containment> m_lastContainment;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
287
app/view/settings/widgetexplorerview.cpp
Normal file
287
app/view/settings/widgetexplorerview.cpp
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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 "widgetexplorerview.h"
|
||||||
|
|
||||||
|
// local
|
||||||
|
#include "../panelshadows_p.h"
|
||||||
|
#include "../view.h"
|
||||||
|
#include "../../lattecorona.h"
|
||||||
|
#include "../../wm/abstractwindowinterface.h"
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QQuickItem>
|
||||||
|
#include <QScreen>
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
#include <KWindowEffects>
|
||||||
|
#include <KWindowSystem>
|
||||||
|
#include <KWayland/Client/plasmashell.h>
|
||||||
|
|
||||||
|
// Plasma
|
||||||
|
#include <Plasma/Package>
|
||||||
|
|
||||||
|
namespace Latte {
|
||||||
|
namespace ViewPart {
|
||||||
|
|
||||||
|
WidgetExplorerView::WidgetExplorerView(Latte::View *view)
|
||||||
|
: SubConfigView(view, QString("#widgetexplorerview#"), true)
|
||||||
|
{
|
||||||
|
setResizeMode(QQuickView::SizeRootObjectToView);
|
||||||
|
|
||||||
|
connect(this, &QQuickView::widthChanged, this, &WidgetExplorerView::updateEffects);
|
||||||
|
connect(this, &QQuickView::heightChanged, this, &WidgetExplorerView::updateEffects);
|
||||||
|
|
||||||
|
connect(this, &QQuickView::statusChanged, [&](QQuickView::Status status) {
|
||||||
|
if (status == QQuickView::Ready) {
|
||||||
|
updateEffects();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setParentView(view);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetExplorerView::init()
|
||||||
|
{
|
||||||
|
SubConfigView::init();
|
||||||
|
|
||||||
|
QByteArray tempFilePath = "widgetexplorerui";
|
||||||
|
|
||||||
|
updateEnabledBorders();
|
||||||
|
|
||||||
|
auto source = QUrl::fromLocalFile(m_latteView->containment()->corona()->kPackage().filePath(tempFilePath));
|
||||||
|
setSource(source);
|
||||||
|
syncGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WidgetExplorerView::hideOnWindowDeactivate() const
|
||||||
|
{
|
||||||
|
return m_hideOnWindowDeactivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetExplorerView::setHideOnWindowDeactivate(bool hide)
|
||||||
|
{
|
||||||
|
if (m_hideOnWindowDeactivate == hide) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_hideOnWindowDeactivate = hide;
|
||||||
|
emit hideOnWindowDeactivateChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::WindowFlags WidgetExplorerView::wFlags() const
|
||||||
|
{
|
||||||
|
return (flags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect WidgetExplorerView::geometryWhenVisible() const
|
||||||
|
{
|
||||||
|
return m_geometryWhenVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetExplorerView::initParentView(Latte::View *view)
|
||||||
|
{
|
||||||
|
SubConfigView::initParentView(view);
|
||||||
|
|
||||||
|
rootContext()->setContextProperty(QStringLiteral("containmentFromView"), m_latteView->containment());
|
||||||
|
|
||||||
|
updateEnabledBorders();
|
||||||
|
syncGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect WidgetExplorerView::availableScreenGeometry() const
|
||||||
|
{
|
||||||
|
int currentScrId = m_latteView->positioner()->currentScreenId();
|
||||||
|
|
||||||
|
QList<Latte::Types::Visibility> ignoreModes{Latte::Types::SidebarOnDemand,Latte::Types::SidebarAutoHide};
|
||||||
|
|
||||||
|
if (m_latteView->visibility() && m_latteView->visibility()->isSidebar()) {
|
||||||
|
ignoreModes.removeAll(Latte::Types::SidebarOnDemand);
|
||||||
|
ignoreModes.removeAll(Latte::Types::SidebarAutoHide);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString activityid = m_latteView->layout()->lastUsedActivity();
|
||||||
|
|
||||||
|
return m_corona->availableScreenRectWithCriteria(currentScrId, activityid, ignoreModes, {}, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetExplorerView::syncGeometry()
|
||||||
|
{
|
||||||
|
if (!m_latteView || !m_latteView->layout() || !m_latteView->containment() || !rootObject()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QSize size(rootObject()->width(), rootObject()->height());
|
||||||
|
auto availGeometry = availableScreenGeometry();
|
||||||
|
|
||||||
|
int margin = availGeometry.height() == m_latteView->screenGeometry().height() ? 100 : 0;
|
||||||
|
auto geometry = QRect(availGeometry.x(), availGeometry.y(), size.width(), availGeometry.height()-margin);
|
||||||
|
|
||||||
|
updateEnabledBorders();
|
||||||
|
|
||||||
|
if (m_geometryWhenVisible == geometry) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_geometryWhenVisible = geometry;
|
||||||
|
|
||||||
|
setPosition(geometry.topLeft());
|
||||||
|
|
||||||
|
if (m_shellSurface) {
|
||||||
|
m_shellSurface->setPosition(geometry.topLeft());
|
||||||
|
}
|
||||||
|
|
||||||
|
setMaximumSize(geometry.size());
|
||||||
|
setMinimumSize(geometry.size());
|
||||||
|
resize(geometry.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetExplorerView::showEvent(QShowEvent *ev)
|
||||||
|
{
|
||||||
|
if (m_shellSurface) {
|
||||||
|
//! under wayland it needs to be set again after its hiding
|
||||||
|
m_shellSurface->setPosition(m_geometryWhenVisible.topLeft());
|
||||||
|
}
|
||||||
|
|
||||||
|
SubConfigView::showEvent(ev);
|
||||||
|
|
||||||
|
if (!m_latteView) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
syncGeometry();
|
||||||
|
|
||||||
|
requestActivate();
|
||||||
|
|
||||||
|
m_screenSyncTimer.start();
|
||||||
|
QTimer::singleShot(400, this, &WidgetExplorerView::syncGeometry);
|
||||||
|
|
||||||
|
emit showSignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetExplorerView::focusOutEvent(QFocusEvent *ev)
|
||||||
|
{
|
||||||
|
Q_UNUSED(ev);
|
||||||
|
|
||||||
|
if (!m_latteView) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hideConfigWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetExplorerView::updateEffects()
|
||||||
|
{
|
||||||
|
//! Don't apply any effect before the wayland surface is created under wayland
|
||||||
|
//! https://bugs.kde.org/show_bug.cgi?id=392890
|
||||||
|
if (KWindowSystem::isPlatformWayland() && !m_shellSurface) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_background) {
|
||||||
|
m_background = new Plasma::FrameSvg(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_background->imagePath() != "dialogs/background") {
|
||||||
|
m_background->setImagePath(QStringLiteral("dialogs/background"));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_background->setEnabledBorders(m_enabledBorders);
|
||||||
|
m_background->resizeFrame(size());
|
||||||
|
|
||||||
|
QRegion mask = m_background->mask();
|
||||||
|
|
||||||
|
QRegion fixedMask = mask.isNull() ? QRegion(QRect(0,0,width(),height())) : mask;
|
||||||
|
|
||||||
|
if (!fixedMask.isEmpty()) {
|
||||||
|
setMask(fixedMask);
|
||||||
|
} else {
|
||||||
|
setMask(QRegion());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KWindowSystem::compositingActive()) {
|
||||||
|
KWindowEffects::enableBlurBehind(winId(), true, fixedMask);
|
||||||
|
} else {
|
||||||
|
KWindowEffects::enableBlurBehind(winId(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetExplorerView::hideConfigWindow()
|
||||||
|
{
|
||||||
|
if (!m_hideOnWindowDeactivate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_shellSurface) {
|
||||||
|
//!NOTE: Avoid crash in wayland environment with qt5.9
|
||||||
|
close();
|
||||||
|
} else {
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetExplorerView::syncSlideEffect()
|
||||||
|
{
|
||||||
|
if (!m_latteView || !m_latteView->containment()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto slideLocation = WindowSystem::AbstractWindowInterface::Slide::Left;
|
||||||
|
|
||||||
|
m_corona->wm()->slideWindow(*this, slideLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
//!BEGIN borders
|
||||||
|
void WidgetExplorerView::updateEnabledBorders()
|
||||||
|
{
|
||||||
|
if (!this->screen()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Plasma::FrameSvg::EnabledBorders borders = Plasma::FrameSvg::AllBorders;
|
||||||
|
|
||||||
|
if (!m_geometryWhenVisible.isEmpty()) {
|
||||||
|
if (m_geometryWhenVisible.x() == m_latteView->screenGeometry().x()) {
|
||||||
|
borders &= ~Plasma::FrameSvg::LeftBorder;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_geometryWhenVisible.y() == m_latteView->screenGeometry().y()) {
|
||||||
|
borders &= ~Plasma::FrameSvg::TopBorder;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_geometryWhenVisible.height() == m_latteView->screenGeometry().height()) {
|
||||||
|
borders &= ~Plasma::FrameSvg::BottomBorder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_enabledBorders != borders) {
|
||||||
|
if (isVisible()) {
|
||||||
|
m_enabledBorders = borders;
|
||||||
|
}
|
||||||
|
m_corona->dialogShadows()->addWindow(this, m_enabledBorders);
|
||||||
|
|
||||||
|
emit enabledBordersChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//!END borders
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
105
app/view/settings/widgetexplorerview.h
Normal file
105
app/view/settings/widgetexplorerview.h
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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 WIDGETEXPLORERVIEW_H
|
||||||
|
#define WIDGETEXPLORERVIEW_H
|
||||||
|
|
||||||
|
// local
|
||||||
|
#include "subconfigview.h"
|
||||||
|
|
||||||
|
//Qt
|
||||||
|
#include <QObject>
|
||||||
|
#include <QQuickView>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
// Plasma
|
||||||
|
#include <plasma/package.h>
|
||||||
|
#include <Plasma/FrameSvg>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Plasma {
|
||||||
|
class Applet;
|
||||||
|
class Containment;
|
||||||
|
class FrameSvg;
|
||||||
|
class Types;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace KWayland {
|
||||||
|
namespace Client {
|
||||||
|
class PlasmaShellSurface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Latte {
|
||||||
|
class Corona;
|
||||||
|
class View;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Latte {
|
||||||
|
namespace ViewPart {
|
||||||
|
|
||||||
|
class WidgetExplorerView : public SubConfigView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool hideOnWindowDeactivate READ hideOnWindowDeactivate WRITE setHideOnWindowDeactivate NOTIFY hideOnWindowDeactivateChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
WidgetExplorerView(Latte::View *view);
|
||||||
|
|
||||||
|
bool hideOnWindowDeactivate() const;
|
||||||
|
void setHideOnWindowDeactivate(bool hide);
|
||||||
|
|
||||||
|
QRect geometryWhenVisible() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
Q_INVOKABLE void hideConfigWindow();
|
||||||
|
Q_INVOKABLE void syncGeometry() override;
|
||||||
|
Q_INVOKABLE void updateEffects();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void hideOnWindowDeactivateChanged();
|
||||||
|
void showSignal();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void showEvent(QShowEvent *ev) override;
|
||||||
|
void syncSlideEffect() override;
|
||||||
|
void focusOutEvent(QFocusEvent *ev) override;
|
||||||
|
|
||||||
|
void init() override;
|
||||||
|
void initParentView(Latte::View *view) override;
|
||||||
|
void updateEnabledBorders() override;
|
||||||
|
|
||||||
|
Qt::WindowFlags wFlags() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QRect availableScreenGeometry() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_hideOnWindowDeactivate{true};
|
||||||
|
QRect m_geometryWhenVisible;
|
||||||
|
|
||||||
|
//only for the mask on disabled compositing, not to actually paint
|
||||||
|
Plasma::FrameSvg *m_background{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //WIDGETEXPLORERVIEW_H
|
||||||
|
|
@ -28,6 +28,7 @@
|
|||||||
#include "settings/primaryconfigview.h"
|
#include "settings/primaryconfigview.h"
|
||||||
#include "settings/secondaryconfigview.h"
|
#include "settings/secondaryconfigview.h"
|
||||||
#include "settings/viewsettingsfactory.h"
|
#include "settings/viewsettingsfactory.h"
|
||||||
|
#include "settings/widgetexplorerview.h"
|
||||||
#include "../apptypes.h"
|
#include "../apptypes.h"
|
||||||
#include "../lattecorona.h"
|
#include "../lattecorona.h"
|
||||||
#include "../data/layoutdata.h"
|
#include "../data/layoutdata.h"
|
||||||
@ -178,6 +179,7 @@ View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassWM)
|
|||||||
}
|
}
|
||||||
|
|
||||||
connect(this->containment(), SIGNAL(statusChanged(Plasma::Types::ItemStatus)), SLOT(statusChanged(Plasma::Types::ItemStatus)));
|
connect(this->containment(), SIGNAL(statusChanged(Plasma::Types::ItemStatus)), SLOT(statusChanged(Plasma::Types::ItemStatus)));
|
||||||
|
connect(this->containment(), &Plasma::Containment::showAddWidgetsInterface, this, &View::showWidgetExplorer);
|
||||||
connect(this->containment(), &Plasma::Containment::userConfiguringChanged, this, [&]() {
|
connect(this->containment(), &Plasma::Containment::userConfiguringChanged, this, [&]() {
|
||||||
emit inEditModeChanged();
|
emit inEditModeChanged();
|
||||||
});
|
});
|
||||||
@ -523,6 +525,16 @@ void View::showConfigurationInterface(Plasma::Applet *applet)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void View::showWidgetExplorer(const QPointF &point)
|
||||||
|
{
|
||||||
|
auto widgetExplorerView = m_corona->viewSettingsFactory()->widgetExplorerView(this);
|
||||||
|
|
||||||
|
if (!widgetExplorerView->isVisible()) {
|
||||||
|
// widgetExplorerView->syncSlideEffect();
|
||||||
|
widgetExplorerView->showAfter(400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QRect View::localGeometry() const
|
QRect View::localGeometry() const
|
||||||
{
|
{
|
||||||
return m_localGeometry;
|
return m_localGeometry;
|
||||||
|
@ -279,6 +279,7 @@ public slots:
|
|||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void showConfigurationInterface(Plasma::Applet *applet) override;
|
void showConfigurationInterface(Plasma::Applet *applet) override;
|
||||||
|
void showWidgetExplorer(const QPointF &point);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool event(QEvent *ev) override;
|
bool event(QEvent *ev) override;
|
||||||
|
@ -88,14 +88,15 @@ void Menu::makeActions()
|
|||||||
});
|
});
|
||||||
|
|
||||||
m_addWidgetsAction = new QAction(QIcon::fromTheme("list-add"), i18n("&Add Widgets..."), this);
|
m_addWidgetsAction = new QAction(QIcon::fromTheme("list-add"), i18n("&Add Widgets..."), this);
|
||||||
m_addWidgetsAction->setStatusTip(i18n("Show Plasma Widget Explorer"));
|
m_addWidgetsAction->setStatusTip(i18n("Show Widget Explorer"));
|
||||||
connect(m_addWidgetsAction, &QAction::triggered, [ = ]() {
|
connect(m_addWidgetsAction, &QAction::triggered, this, &Menu::requestWidgetExplorer);
|
||||||
|
/*connect(m_addWidgetsAction, &QAction::triggered, [ = ]() {
|
||||||
QDBusInterface iface("org.kde.plasmashell", "/PlasmaShell", "", QDBusConnection::sessionBus());
|
QDBusInterface iface("org.kde.plasmashell", "/PlasmaShell", "", QDBusConnection::sessionBus());
|
||||||
|
|
||||||
if (iface.isValid()) {
|
if (iface.isValid()) {
|
||||||
iface.call("toggleWidgetExplorer");
|
iface.call("toggleWidgetExplorer");
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
|
|
||||||
m_configureAction = new QAction(QIcon::fromTheme("document-edit"), i18nc("view settings window", "View &Settings..."), this);
|
m_configureAction = new QAction(QIcon::fromTheme("document-edit"), i18nc("view settings window", "View &Settings..."), this);
|
||||||
connect(m_configureAction, &QAction::triggered, this, &Menu::requestConfiguration);
|
connect(m_configureAction, &QAction::triggered, this, &Menu::requestConfiguration);
|
||||||
@ -137,6 +138,12 @@ void Menu::requestConfiguration()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::requestWidgetExplorer()
|
||||||
|
{
|
||||||
|
if (this->containment()) {
|
||||||
|
emit this->containment()->showAddWidgetsInterface(QPointF());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QList<QAction *> Menu::contextualActions()
|
QList<QAction *> Menu::contextualActions()
|
||||||
{
|
{
|
||||||
|
@ -43,8 +43,9 @@ public:
|
|||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void makeActions();
|
void makeActions();
|
||||||
void populateLayouts();
|
void populateLayouts();
|
||||||
void requestConfiguration();
|
|
||||||
void quitApplication();
|
void quitApplication();
|
||||||
|
void requestConfiguration();
|
||||||
|
void requestWidgetExplorer();
|
||||||
void switchToLayout(QAction *action);
|
void switchToLayout(QAction *action);
|
||||||
|
|
||||||
|
|
||||||
|
236
shell/package/contents/views/AppletDelegate.qml
Normal file
236
shell/package/contents/views/AppletDelegate.qml
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 Marco Martin <mart@kde.org>
|
||||||
|
* Copyright 2015 Kai Uwe Broulik <kde@privat.broulik.de>
|
||||||
|
* Copyright 2021 Michail Vourlakos <mvourlakos@gmail.com>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.4
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
|
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.draganddrop 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: delegate
|
||||||
|
|
||||||
|
readonly property string pluginName: model.pluginName
|
||||||
|
readonly property bool pendingUninstall: pendingUninstallTimer.applets.indexOf(pluginName) > -1
|
||||||
|
|
||||||
|
width: list.cellWidth
|
||||||
|
height: list.cellHeight
|
||||||
|
|
||||||
|
DragArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
supportedActions: Qt.MoveAction | Qt.LinkAction
|
||||||
|
//onDragStarted: tooltipDialog.visible = false
|
||||||
|
delegateImage: decoration
|
||||||
|
enabled: !delegate.pendingUninstall
|
||||||
|
mimeData {
|
||||||
|
source: parent
|
||||||
|
}
|
||||||
|
Component.onCompleted: mimeData.setData("text/x-plasmoidservicename", pluginName)
|
||||||
|
|
||||||
|
onDragStarted: {
|
||||||
|
kwindowsystem.showingDesktop = true;
|
||||||
|
main.draggingWidget = true;
|
||||||
|
}
|
||||||
|
onDrop: {
|
||||||
|
main.draggingWidget = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onDoubleClicked: {
|
||||||
|
if (!delegate.pendingUninstall) {
|
||||||
|
widgetExplorer.addApplet(pluginName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onEntered: delegate.GridView.view.currentIndex = index
|
||||||
|
onExited: delegate.GridView.view.currentIndex = - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: mainLayout
|
||||||
|
spacing: units.smallSpacing
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
//bottom: parent.bottom
|
||||||
|
margins: units.smallSpacing * 2
|
||||||
|
rightMargin: units.smallSpacing * 2 // don't cram the text to the border too much
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: iconContainer
|
||||||
|
width: units.iconSizes.enormous
|
||||||
|
height: width
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
opacity: delegate.pendingUninstall ? 0.6 : 1
|
||||||
|
Behavior on opacity {
|
||||||
|
OpacityAnimator {
|
||||||
|
duration: units.longDuration
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: iconWidget
|
||||||
|
anchors.fill: parent
|
||||||
|
PlasmaCore.IconItem {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: model.decoration
|
||||||
|
visible: model.screenshot === ""
|
||||||
|
}
|
||||||
|
Image {
|
||||||
|
width: units.iconSizes.enormous
|
||||||
|
height: width
|
||||||
|
anchors.fill: parent
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: model.screenshot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: badgeMask
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
x: Math.round(-units.smallSpacing * 1.5 / 2)
|
||||||
|
y: x
|
||||||
|
width: runningBadge.width + Math.round(units.smallSpacing * 1.5)
|
||||||
|
height: width
|
||||||
|
radius: height
|
||||||
|
visible: running && delegate.GridView.isCurrentItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: runningBadge
|
||||||
|
width: height
|
||||||
|
height: Math.round(theme.mSize(countLabel.font).height * 1.3)
|
||||||
|
radius: height
|
||||||
|
color: theme.highlightColor
|
||||||
|
visible: running && delegate.GridView.isCurrentItem
|
||||||
|
onVisibleChanged: maskShaderSource.scheduleUpdate()
|
||||||
|
|
||||||
|
PlasmaComponents.Label {
|
||||||
|
id: countLabel
|
||||||
|
anchors.fill: parent
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
text: running
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
anchors.fill: parent
|
||||||
|
property var source: ShaderEffectSource {
|
||||||
|
sourceItem: iconWidget
|
||||||
|
hideSource: true
|
||||||
|
live: false
|
||||||
|
}
|
||||||
|
property var mask: ShaderEffectSource {
|
||||||
|
id: maskShaderSource
|
||||||
|
sourceItem: badgeMask
|
||||||
|
hideSource: true
|
||||||
|
live: false
|
||||||
|
}
|
||||||
|
|
||||||
|
supportsAtlasTextures: true
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp sampler2D mask;
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = texture2D(source, qt_TexCoord0.st) * (1.0 - (texture2D(mask, qt_TexCoord0.st).a)) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaComponents.ToolButton {
|
||||||
|
id: uninstallButton
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
iconSource: delegate.pendingUninstall ? "edit-undo" : "edit-delete"
|
||||||
|
// we don't really "undo" anything but we'll pretend to the user that we do
|
||||||
|
tooltip: delegate.pendingUninstall ? i18nd("plasma_shell_org.kde.plasma.desktop", "Undo uninstall")
|
||||||
|
: i18nd("plasma_shell_org.kde.plasma.desktop", "Uninstall widget")
|
||||||
|
flat: false
|
||||||
|
visible: model.local && delegate.GridView.isCurrentItem
|
||||||
|
|
||||||
|
onHoveredChanged: {
|
||||||
|
if (hovered) {
|
||||||
|
// hovering the uninstall button triggers onExited of the main mousearea
|
||||||
|
delegate.GridView.view.currentIndex = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
var pending = installTimer.applets
|
||||||
|
if (delegate.pendingUninstall) {
|
||||||
|
var index = pending.indexOf(pluginName)
|
||||||
|
if (index > -1) {
|
||||||
|
pending.splice(index, 1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pending.push(pluginName)
|
||||||
|
}
|
||||||
|
pendingUninstallTimer.applets = pending
|
||||||
|
|
||||||
|
if (pending.length) {
|
||||||
|
pendingUninstallTimer.restart()
|
||||||
|
} else {
|
||||||
|
pendingUninstallTimer.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlasmaExtras.Heading {
|
||||||
|
id: heading
|
||||||
|
Layout.fillWidth: true
|
||||||
|
level: 4
|
||||||
|
text: model.name
|
||||||
|
elide: Text.ElideRight
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
maximumLineCount: 2
|
||||||
|
lineHeight: 0.95
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
PlasmaComponents.Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
// otherwise causes binding loop due to the way the Plasma sets the height
|
||||||
|
height: implicitHeight
|
||||||
|
text: model.description
|
||||||
|
font: theme.smallestFont
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: heading.lineCount === 1 ? 3 : 2
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
389
shell/package/contents/views/WidgetExplorer.qml
Normal file
389
shell/package/contents/views/WidgetExplorer.qml
Normal file
@ -0,0 +1,389 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 Marco Martin <mart@kde.org>
|
||||||
|
* Copyright 2021 Michail Vourlakos <mvourlakos@gmail.com>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Controls 2.5 as QQC2
|
||||||
|
|
||||||
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||||
|
import org.kde.kquickcontrolsaddons 2.0
|
||||||
|
import org.kde.kwindowsystem 1.0
|
||||||
|
|
||||||
|
import QtQuick.Window 2.1
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
|
import org.kde.plasma.private.shell 2.0 as PlasmaShell
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: main
|
||||||
|
width: Math.max(heading.paintedWidth, units.iconSizes.enormous * 3 + units.smallSpacing * 4 + units.gridUnit * 2)
|
||||||
|
// height: 800//Screen.height
|
||||||
|
|
||||||
|
opacity: draggingWidget ? 0.3 : 1
|
||||||
|
|
||||||
|
//property QtObject containment
|
||||||
|
|
||||||
|
//external drop events can cause a raise event causing us to lose focus and
|
||||||
|
//therefore get deleted whilst we are still in a drag exec()
|
||||||
|
//this is a clue to the owning dialog that hideOnWindowDeactivate should be deleted
|
||||||
|
//See https://bugs.kde.org/show_bug.cgi?id=332733
|
||||||
|
property bool preventWindowHide: draggingWidget
|
||||||
|
|| categoriesDialog.status !== PlasmaComponents.DialogStatus.Closed
|
||||||
|
|| getWidgetsDialog.status !== PlasmaComponents.DialogStatus.Closed
|
||||||
|
|
||||||
|
property bool outputOnly: draggingWidget
|
||||||
|
|
||||||
|
property Item categoryButton
|
||||||
|
|
||||||
|
property bool draggingWidget: false
|
||||||
|
|
||||||
|
signal closed();
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
if (main.preventWindowHide) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
viewConfig.hideConfigWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (!visible) {
|
||||||
|
kwindowsystem.showingDesktop = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onDestruction: {
|
||||||
|
if (pendingUninstallTimer.running) {
|
||||||
|
// we're not being destroyed so at least reset the filters
|
||||||
|
widgetExplorer.widgetsModel.filterQuery = ""
|
||||||
|
widgetExplorer.widgetsModel.filterType = ""
|
||||||
|
widgetExplorer.widgetsModel.searchTerm = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addCurrentApplet() {
|
||||||
|
var pluginName = list.currentItem ? list.currentItem.pluginName : ""
|
||||||
|
if (pluginName) {
|
||||||
|
widgetExplorer.addApplet(pluginName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KWindowSystem {
|
||||||
|
id: kwindowsystem
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.Action {
|
||||||
|
shortcut: "Escape"
|
||||||
|
onTriggered: {
|
||||||
|
if (searchInput.length > 0) {
|
||||||
|
searchInput.text = ""
|
||||||
|
} else {
|
||||||
|
main.closed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.Action {
|
||||||
|
shortcut: "Up"
|
||||||
|
onTriggered: list.currentIndex = (list.count + list.currentIndex - 1) % list.count
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.Action {
|
||||||
|
shortcut: "Down"
|
||||||
|
onTriggered: list.currentIndex = (list.currentIndex + 1) % list.count
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.Action {
|
||||||
|
shortcut: "Enter"
|
||||||
|
onTriggered: addCurrentApplet()
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.Action {
|
||||||
|
shortcut: "Return"
|
||||||
|
onTriggered: addCurrentApplet()
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaCore.FrameSvgItem{
|
||||||
|
id: backgroundFrameSvgItem
|
||||||
|
anchors.fill: parent
|
||||||
|
imagePath: "dialogs/background"
|
||||||
|
enabledBorders: viewConfig.enabledBorders
|
||||||
|
|
||||||
|
onEnabledBordersChanged: viewConfig.updateEffects()
|
||||||
|
Component.onCompleted: viewConfig.updateEffects()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PlasmaShell.WidgetExplorer {
|
||||||
|
id:widgetExplorer
|
||||||
|
//view: desktop
|
||||||
|
containment: containmentFromView
|
||||||
|
onShouldClose: main.closed();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PlasmaComponents.ModelContextMenu {
|
||||||
|
id: categoriesDialog
|
||||||
|
visualParent: categoryButton
|
||||||
|
// model set on first invocation
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
list.contentX = 0
|
||||||
|
list.contentY = 0
|
||||||
|
categoryButton.text = (model.filterData ? model.display : i18nd("plasma_shell_org.kde.plasma.desktop", "All Widgets"))
|
||||||
|
widgetExplorer.widgetsModel.filterQuery = model.filterData
|
||||||
|
widgetExplorer.widgetsModel.filterType = model.filterType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaComponents.ModelContextMenu {
|
||||||
|
id: getWidgetsDialog
|
||||||
|
visualParent: getWidgetsButton
|
||||||
|
placement: PlasmaCore.Types.TopPosedLeftAlignedPopup
|
||||||
|
// model set on first invocation
|
||||||
|
onClicked: model.trigger()
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
PlasmaCore.Dialog {
|
||||||
|
id: tooltipDialog
|
||||||
|
property Item appletDelegate
|
||||||
|
location: PlasmaCore.Types.RightEdge //actually we want this to be the opposite location of the explorer itself
|
||||||
|
type: PlasmaCore.Dialog.Tooltip
|
||||||
|
flags:Qt.Window|Qt.WindowStaysOnTopHint|Qt.X11BypassWindowManagerHint
|
||||||
|
onAppletDelegateChanged: {
|
||||||
|
if (!appletDelegate) {
|
||||||
|
toolTipHideTimer.restart()
|
||||||
|
toolTipShowTimer.running = false
|
||||||
|
} else if (tooltipDialog.visible) {
|
||||||
|
tooltipDialog.visualParent = appletDelegate
|
||||||
|
} else {
|
||||||
|
tooltipDialog.visualParent = appletDelegate
|
||||||
|
toolTipShowTimer.restart()
|
||||||
|
toolTipHideTimer.running = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mainItem: Tooltip { id: tooltipWidget }
|
||||||
|
Behavior on y {
|
||||||
|
NumberAnimation { duration: units.longDuration }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Timer {
|
||||||
|
id: toolTipShowTimer
|
||||||
|
interval: 500
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
tooltipDialog.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Timer {
|
||||||
|
id: toolTipHideTimer
|
||||||
|
interval: 1000
|
||||||
|
repeat: false
|
||||||
|
onTriggered: tooltipDialog.visible = false
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
PlasmaExtras.PlasmoidHeading {
|
||||||
|
id: topArea
|
||||||
|
implicitWidth: header.implicitWidth
|
||||||
|
implicitHeight: header.implicitHeight
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: header
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
PlasmaExtras.Heading {
|
||||||
|
id: heading
|
||||||
|
level: 1
|
||||||
|
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Widgets")
|
||||||
|
elide: Text.ElideRight
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
PlasmaComponents.ToolButton {
|
||||||
|
id: getWidgetsButton
|
||||||
|
iconSource: "get-hot-new-stuff"
|
||||||
|
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Get New Widgets...")
|
||||||
|
onClicked: {
|
||||||
|
getWidgetsDialog.model = widgetExplorer.widgetsMenuActions
|
||||||
|
getWidgetsDialog.openRelative()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlasmaComponents.ToolButton {
|
||||||
|
id: closeButton
|
||||||
|
iconSource: "window-close"
|
||||||
|
onClicked: main.closed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
PlasmaComponents.TextField {
|
||||||
|
id: searchInput
|
||||||
|
Layout.fillWidth: true
|
||||||
|
clearButtonShown: true
|
||||||
|
placeholderText: i18nd("plasma_shell_org.kde.plasma.desktop", "Search...")
|
||||||
|
onTextChanged: {
|
||||||
|
list.positionViewAtBeginning()
|
||||||
|
list.currentIndex = -1
|
||||||
|
widgetExplorer.widgetsModel.searchTerm = text
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: forceActiveFocus()
|
||||||
|
}
|
||||||
|
PlasmaComponents.ToolButton {
|
||||||
|
id: categoryButton
|
||||||
|
tooltip: i18nd("plasma_shell_org.kde.plasma.desktop", "Categories")
|
||||||
|
text: i18nd("plasma_shell_org.kde.plasma.desktop", "All Widgets")
|
||||||
|
iconSource: "view-filter"
|
||||||
|
onClicked: {
|
||||||
|
categoriesDialog.model = widgetExplorer.filterModel
|
||||||
|
categoriesDialog.open(0, categoryButton.height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
height: units.smallSpacing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: setModelTimer
|
||||||
|
interval: 20
|
||||||
|
running: true
|
||||||
|
onTriggered: list.model = widgetExplorer.widgetsModel
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaExtras.ScrollArea {
|
||||||
|
anchors {
|
||||||
|
top: topArea.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
|
||||||
|
verticalScrollBarPolicy: Qt.ScrollBarAlwaysOn
|
||||||
|
|
||||||
|
// hide the flickering by fading in nicely
|
||||||
|
opacity: setModelTimer.running ? 0 : 1
|
||||||
|
Behavior on opacity {
|
||||||
|
OpacityAnimator {
|
||||||
|
duration: units.longDuration
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridView {
|
||||||
|
id: list
|
||||||
|
|
||||||
|
// model set delayed by Timer above
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
keyNavigationWraps: true
|
||||||
|
cellWidth: Math.floor((width - units.smallSpacing) / 3)
|
||||||
|
cellHeight: cellWidth + units.gridUnit * 4 + units.smallSpacing * 2
|
||||||
|
|
||||||
|
delegate: AppletDelegate {}
|
||||||
|
highlight: PlasmaComponents.Highlight {}
|
||||||
|
highlightMoveDuration: 0
|
||||||
|
//highlightResizeDuration: 0
|
||||||
|
|
||||||
|
//slide in to view from the left
|
||||||
|
add: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
properties: "x"
|
||||||
|
from: -list.width
|
||||||
|
duration: units.shortDuration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//slide out of view to the right
|
||||||
|
remove: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
properties: "x"
|
||||||
|
to: list.width
|
||||||
|
duration: units.shortDuration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if we are adding other items into the view use the same animation as normal adding
|
||||||
|
//this makes everything slide in together
|
||||||
|
//if we make it move everything ends up weird
|
||||||
|
addDisplaced: list.add
|
||||||
|
|
||||||
|
//moved due to filtering
|
||||||
|
displaced: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
properties: "x,y"
|
||||||
|
duration: units.shortDuration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaExtras.Heading {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: units.largeSpacing
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
level: 2
|
||||||
|
text: searchInput.text.length > 0 ? i18n("No widgets matched the search terms") : i18n("No widgets available")
|
||||||
|
enabled: false
|
||||||
|
visible: list.count == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Bindings
|
||||||
|
Binding{
|
||||||
|
target: viewConfig
|
||||||
|
property: "hideOnWindowDeactivate"
|
||||||
|
value: !main.preventWindowHide
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Timers
|
||||||
|
Timer {
|
||||||
|
id: pendingUninstallTimer
|
||||||
|
// keeps track of the applets the user wants to uninstall
|
||||||
|
property var applets: []
|
||||||
|
|
||||||
|
interval: 60000 // one minute
|
||||||
|
onTriggered: {
|
||||||
|
for (var i = 0, length = applets.length; i < length; ++i) {
|
||||||
|
widgetExplorer.uninstall(applets[i])
|
||||||
|
}
|
||||||
|
applets = []
|
||||||
|
|
||||||
|
/*if (sidePanelStack.state !== "widgetExplorer" && widgetExplorer) {
|
||||||
|
widgetExplorer.destroy()
|
||||||
|
widgetExplorer = null
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user