new procedure of widget explorer

similar to activity switcher
This commit is contained in:
Marco Martin 2013-10-23 18:42:41 +02:00
parent daa747d0a6
commit e495c7cde4
5 changed files with 320 additions and 324 deletions

View File

@ -24,232 +24,154 @@ import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.qtextracomponents 2.0 import org.kde.qtextracomponents 2.0
import QtQuick.Window 2.1 import QtQuick.Window 2.1
PlasmaCore.Dialog {
id: dialog
location: PlasmaCore.Types.LeftEdge
Component.onCompleted: dialog.visible = true; Item {
onVisibleChanged: { id: main
if (!visible) {
widgetExplorer.close(); width: 240
height: 800//Screen.height
//this is used to perfectly align the filter field and delegates
property int cellWidth: theme.mSize(defaultFont).width * 10
property int minimumWidth: theme.mSize(defaultFont).width * 12
property int minimumHeight: 800//topBar.height + list.delegateHeight + (widgetExplorer.orientation == Qt.Horizontal ? scrollBar.height : 0) + 4
property Item getWidgetsButton
property Item categoryButton
PlasmaComponents.ContextMenu {
id: categoriesDialog
visualParent: main.categoryButton
}
Repeater {
parent: categoriesDialog
model: widgetExplorer.filterModel
delegate: Item {
PlasmaComponents.MenuItem {
text: display
separator: model["separator"] != undefined ? model["separator"] : false
onClicked: {
list.contentX = 0
list.contentY = 0
main.categoryButton.text = display
widgetExplorer.widgetsModel.filterQuery = model["filterData"]
widgetExplorer.widgetsModel.filterType = model["filterType"]
}
Component.onCompleted: {
parent = categoriesDialog
}
}
} }
} }
mainItem: Item {
id: main
Text { PlasmaComponents.ContextMenu {
text: Screen.height+" "+main.height id: getWidgetsDialog
} visualParent: main.getWidgetsButton
width: 240 }
height: 800//Screen.height Repeater {
//this is used to perfectly align the filter field and delegates parent: getWidgetsDialog
property int cellWidth: theme.mSize(defaultFont).width * 10 model: widgetExplorer.widgetsMenuActions
delegate: Item {
property int minimumWidth: theme.mSize(defaultFont).width * 12 PlasmaComponents.MenuItem {
property int minimumHeight: 800//topBar.height + list.delegateHeight + (widgetExplorer.orientation == Qt.Horizontal ? scrollBar.height : 0) + 4 icon: modelData.icon
text: modelData.text
property Item getWidgetsButton separator: modelData.separator
property Item categoryButton onClicked: modelData.trigger()
Component.onCompleted: {
PlasmaComponents.ContextMenu { parent = getWidgetsDialog
id: categoriesDialog
visualParent: main.categoryButton
}
Repeater {
parent: categoriesDialog
model: widgetExplorer.filterModel
delegate: Item {
PlasmaComponents.MenuItem {
text: display
separator: model["separator"] != undefined ? model["separator"] : false
onClicked: {
list.contentX = 0
list.contentY = 0
main.categoryButton.text = display
widgetExplorer.widgetsModel.filterQuery = model["filterData"]
widgetExplorer.widgetsModel.filterType = model["filterType"]
}
Component.onCompleted: {
parent = categoriesDialog
}
} }
} }
} }
}
PlasmaComponents.ContextMenu { PlasmaCore.Dialog {
id: getWidgetsDialog id: tooltipDialog
visualParent: main.getWidgetsButton property Item appletDelegate
}
Repeater { Component.onCompleted: {
parent: getWidgetsDialog tooltipDialog.setAttribute(Qt.WA_X11NetWmWindowTypeToolTip, true)
model: widgetExplorer.widgetsMenuActions tooltipDialog.windowFlags = Qt.Window|Qt.WindowStaysOnTopHint|Qt.X11BypassWindowManagerHint
delegate: Item {
PlasmaComponents.MenuItem {
icon: modelData.icon
text: modelData.text
separator: modelData.separator
onClicked: modelData.trigger()
Component.onCompleted: {
parent = getWidgetsDialog
}
}
}
} }
PlasmaCore.Dialog { onAppletDelegateChanged: {
id: tooltipDialog if (!appletDelegate) {
property Item appletDelegate toolTipHideTimer.restart()
toolTipShowTimer.running = false
Component.onCompleted: { } else if (tooltipDialog.visible) {
tooltipDialog.setAttribute(Qt.WA_X11NetWmWindowTypeToolTip, true)
tooltipDialog.windowFlags = Qt.Window|Qt.WindowStaysOnTopHint|Qt.X11BypassWindowManagerHint
}
onAppletDelegateChanged: {
if (!appletDelegate) {
toolTipHideTimer.restart()
toolTipShowTimer.running = false
} else if (tooltipDialog.visible) {
var point = main.tooltipPosition()
tooltipDialog.x = point.x
tooltipDialog.y = point.y
} else {
toolTipShowTimer.restart()
toolTipHideTimer.running = false
}
}
mainItem: Tooltip { id: tooltipWidget }
Behavior on x {
enabled: widgetExplorer.orientation == Qt.Horizontal
NumberAnimation { duration: 250 }
}
Behavior on y {
enabled: widgetExplorer.orientation == Qt.Vertical
NumberAnimation { duration: 250 }
}
}
Timer {
id: toolTipShowTimer
interval: 500
repeat: false
onTriggered: {
var point = main.tooltipPosition() var point = main.tooltipPosition()
tooltipDialog.x = point.x tooltipDialog.x = point.x
tooltipDialog.y = point.y tooltipDialog.y = point.y
tooltipDialog.visible = true } else {
toolTipShowTimer.restart()
toolTipHideTimer.running = false
} }
} }
Timer { mainItem: Tooltip { id: tooltipWidget }
id: toolTipHideTimer Behavior on x {
interval: 1000 enabled: widgetExplorer.orientation == Qt.Horizontal
repeat: false NumberAnimation { duration: 250 }
onTriggered: tooltipDialog.visible = false
} }
function tooltipPosition() { Behavior on y {
return widgetExplorer.tooltipPosition(tooltipDialog.appletDelegate, tooltipDialog.width, tooltipDialog.height); enabled: widgetExplorer.orientation == Qt.Vertical
NumberAnimation { duration: 250 }
} }
}
Timer {
id: toolTipShowTimer
interval: 500
repeat: false
onTriggered: {
var point = main.tooltipPosition()
tooltipDialog.x = point.x
tooltipDialog.y = point.y
tooltipDialog.visible = true
}
}
Timer {
id: toolTipHideTimer
interval: 1000
repeat: false
onTriggered: tooltipDialog.visible = false
}
function tooltipPosition() {
return widgetExplorer.tooltipPosition(tooltipDialog.appletDelegate, tooltipDialog.width, tooltipDialog.height);
}
Loader { Loader {
id: topBar id: topBar
property Item categoryButton property Item categoryButton
sourceComponent: (widgetExplorer.orientation == Qt.Horizontal) ? horizontalTopBarComponent : verticalTopBarComponent sourceComponent: (widgetExplorer.orientation == Qt.Horizontal) ? horizontalTopBarComponent : verticalTopBarComponent
height: item.height + 2 height: item.height + 2
anchors {
top: parent.top
left: parent.left
right: parent.right
topMargin: widgetExplorer.orientation == Qt.Horizontal ? 4 : 0
leftMargin: 4
}
}
Component {
id: horizontalTopBarComponent
Item {
anchors { anchors {
top: parent.top top: parent.top
left: parent.left left: parent.left
right: parent.right right: parent.right
topMargin: widgetExplorer.orientation == Qt.Horizontal ? 4 : 0
leftMargin: 4
} }
} height: filterField.height
Row {
Component { spacing: 5
id: horizontalTopBarComponent
Item {
anchors { anchors {
top: parent.top
left: parent.left left: parent.left
right: parent.right leftMargin: 2
}
height: filterField.height
Row {
spacing: 5
anchors {
left: parent.left
leftMargin: 2
}
PlasmaComponents.TextField {
id: filterField
width: list.width / Math.floor(list.width / cellWidth) - 4
clearButtonShown: true
placeholderText: i18n("Enter search term...")
onTextChanged: {
list.contentX = 0
list.contentY = 0
widgetExplorer.widgetsModel.searchTerm = text
}
Component.onCompleted: forceActiveFocus()
}
PlasmaComponents.Button {
id: categoryButton
text: i18n("Categories")
onClicked: categoriesDialog.open(0, categoryButton.height)
}
}
Row {
anchors.right: parent.right
spacing: 5
PlasmaComponents.Button {
id: getWidgetsButton
iconSource: "get-hot-new-stuff"
text: i18n("Get new widgets")
onClicked: getWidgetsDialog.open()
}
Repeater {
model: widgetExplorer.extraActions.length
PlasmaComponents.Button {
iconSource: widgetExplorer.extraActions[modelData].icon
text: widgetExplorer.extraActions[modelData].text
onClicked: {
widgetExplorer.extraActions[modelData].trigger()
}
}
}
PlasmaComponents.ToolButton {
iconSource: "window-close"
onClicked: widgetExplorer.close()
}
}
Component.onCompleted: {
main.getWidgetsButton = getWidgetsButton
main.categoryButton = categoryButton
}
}
}
Component {
id: verticalTopBarComponent
Column {
anchors.top: parent.top
anchors.left:parent.left
anchors.right: parent.right
spacing: 4
PlasmaComponents.ToolButton {
anchors.right: parent.right
iconSource: "window-close"
onClicked: widgetExplorer.close()
} }
PlasmaComponents.TextField { PlasmaComponents.TextField {
anchors { id: filterField
left: parent.left width: list.width / Math.floor(list.width / cellWidth) - 4
right: parent.right
}
clearButtonShown: true clearButtonShown: true
placeholderText: i18n("Enter search term...") placeholderText: i18n("Enter search term...")
onTextChanged: { onTextChanged: {
@ -260,90 +182,15 @@ PlasmaCore.Dialog {
Component.onCompleted: forceActiveFocus() Component.onCompleted: forceActiveFocus()
} }
PlasmaComponents.Button { PlasmaComponents.Button {
anchors {
left: parent.left
right: parent.right
}
id: categoryButton id: categoryButton
text: i18n("Categories") text: i18n("Categories")
onClicked: categoriesDialog.open(0, categoryButton.height) onClicked: categoriesDialog.open(0, categoryButton.height)
} }
Component.onCompleted: {
main.categoryButton = categoryButton
}
} }
} Row {
anchors.right: parent.right
MouseEventListener { spacing: 5
id: listParent
anchors {
top: topBar.bottom
left: parent.left
right: parent.right
bottom: widgetExplorer.orientation == Qt.Horizontal ? parent.bottom : bottomBar.top
leftMargin: 4
bottomMargin: 4
}
onWheelMoved: {
//use this only if the wheel orientation is vertical and the list orientation is horizontal, otherwise will be the list itself managing the wheel
if (wheel.orientation == Qt.Vertical && list.orientation == ListView.Horizontal) {
var delta = wheel.delta > 0 ? 20 : -20
list.contentX = Math.min(Math.max(0, list.contentWidth - list.width),
Math.max(0, list.contentX - delta))
}
}
PlasmaExtras.ScrollArea {
anchors.fill: parent
ListView {
id: list
property int delegateWidth: (widgetExplorer.orientation == Qt.Horizontal) ? (list.width / Math.floor(list.width / cellWidth)) : list.width
property int delegateHeight: theme.defaultFont.pixelSize * 7 - 4
anchors.fill: parent
orientation: widgetExplorer.orientation == Qt.Horizontal ? ListView.Horizontal : ListView.Vertical
snapMode: ListView.SnapToItem
model: widgetExplorer.widgetsModel
clip: widgetExplorer.orientation == Qt.Vertical
delegate: AppletDelegate {}
}
}
}
Loader {
id: bottomBar
sourceComponent: (widgetExplorer.orientation == Qt.Horizontal) ? undefined : verticalBottomBarComponent
//height: item.height
height: 48 // FIXME
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
leftMargin: 4
}
}
Component {
id: verticalBottomBarComponent
Column {
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
}
spacing: 4
PlasmaComponents.Button { PlasmaComponents.Button {
anchors {
left: parent.left
right: parent.right
}
id: getWidgetsButton id: getWidgetsButton
iconSource: "get-hot-new-stuff" iconSource: "get-hot-new-stuff"
text: i18n("Get new widgets") text: i18n("Get new widgets")
@ -353,10 +200,6 @@ PlasmaCore.Dialog {
Repeater { Repeater {
model: widgetExplorer.extraActions.length model: widgetExplorer.extraActions.length
PlasmaComponents.Button { PlasmaComponents.Button {
anchors {
left: parent.left
right: parent.right
}
iconSource: widgetExplorer.extraActions[modelData].icon iconSource: widgetExplorer.extraActions[modelData].icon
text: widgetExplorer.extraActions[modelData].text text: widgetExplorer.extraActions[modelData].text
onClicked: { onClicked: {
@ -364,11 +207,156 @@ PlasmaCore.Dialog {
} }
} }
} }
PlasmaComponents.ToolButton {
Component.onCompleted: { iconSource: "window-close"
main.getWidgetsButton = getWidgetsButton onClicked: widgetExplorer.close()
} }
} }
Component.onCompleted: {
main.getWidgetsButton = getWidgetsButton
main.categoryButton = categoryButton
}
}
}
Component {
id: verticalTopBarComponent
Column {
anchors.top: parent.top
anchors.left:parent.left
anchors.right: parent.right
spacing: 4
PlasmaComponents.ToolButton {
anchors.right: parent.right
iconSource: "window-close"
onClicked: widgetExplorer.close()
}
PlasmaComponents.TextField {
anchors {
left: parent.left
right: parent.right
}
clearButtonShown: true
placeholderText: i18n("Enter search term...")
onTextChanged: {
list.contentX = 0
list.contentY = 0
widgetExplorer.widgetsModel.searchTerm = text
}
Component.onCompleted: forceActiveFocus()
}
PlasmaComponents.Button {
anchors {
left: parent.left
right: parent.right
}
id: categoryButton
text: i18n("Categories")
onClicked: categoriesDialog.open(0, categoryButton.height)
}
Component.onCompleted: {
main.categoryButton = categoryButton
}
}
}
MouseEventListener {
id: listParent
anchors {
top: topBar.bottom
left: parent.left
right: parent.right
bottom: widgetExplorer.orientation == Qt.Horizontal ? parent.bottom : bottomBar.top
leftMargin: 4
bottomMargin: 4
}
onWheelMoved: {
//use this only if the wheel orientation is vertical and the list orientation is horizontal, otherwise will be the list itself managing the wheel
if (wheel.orientation == Qt.Vertical && list.orientation == ListView.Horizontal) {
var delta = wheel.delta > 0 ? 20 : -20
list.contentX = Math.min(Math.max(0, list.contentWidth - list.width),
Math.max(0, list.contentX - delta))
}
}
PlasmaExtras.ScrollArea {
anchors.fill: parent
ListView {
id: list
property int delegateWidth: (widgetExplorer.orientation == Qt.Horizontal) ? (list.width / Math.floor(list.width / cellWidth)) : list.width
property int delegateHeight: theme.defaultFont.pixelSize * 7 - 4
anchors.fill: parent
orientation: widgetExplorer.orientation == Qt.Horizontal ? ListView.Horizontal : ListView.Vertical
snapMode: ListView.SnapToItem
model: widgetExplorer.widgetsModel
clip: widgetExplorer.orientation == Qt.Vertical
delegate: AppletDelegate {}
}
}
}
Loader {
id: bottomBar
sourceComponent: (widgetExplorer.orientation == Qt.Horizontal) ? undefined : verticalBottomBarComponent
//height: item.height
height: 48 // FIXME
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
leftMargin: 4
}
}
Component {
id: verticalBottomBarComponent
Column {
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
}
spacing: 4
PlasmaComponents.Button {
anchors {
left: parent.left
right: parent.right
}
id: getWidgetsButton
iconSource: "get-hot-new-stuff"
text: i18n("Get new widgets")
onClicked: getWidgetsDialog.open()
}
Repeater {
model: widgetExplorer.extraActions.length
PlasmaComponents.Button {
anchors {
left: parent.left
right: parent.right
}
iconSource: widgetExplorer.extraActions[modelData].icon
text: widgetExplorer.extraActions[modelData].text
onClicked: {
widgetExplorer.extraActions[modelData].trigger()
}
}
}
Component.onCompleted: {
main.getWidgetsButton = getWidgetsButton
}
} }
} }
} }

View File

@ -30,6 +30,20 @@ Rectangle {
property Item containment property Item containment
function toggleWidgetExplorer(explorerObject) {
console.log("Widget Explorer toggled");
if (0&&sidePanel.visible) {
explorerObject.close()
sidePanel.visible = false;
} else {
explorerObject.parent = sidePanelStack
explorerObject.anchors.fill = parent;
sidePanel.visible = true;
sidePanel.height = containment.availableScreenRegion(containment.screen)[0].height;
}
}
function toggleActivityManager() { function toggleActivityManager() {
console.log("Activity manger toggled"); console.log("Activity manger toggled");

View File

@ -464,22 +464,31 @@ void ShellCorona::handleContainmentAdded(Plasma::Containment* c)
void ShellCorona::showWidgetExplorer() void ShellCorona::showWidgetExplorer()
{ {
if (!d->widgetExplorer) { QPoint cursorPos = QCursor::pos();
foreach (DesktopView *view, d->views) {
if (view->screen()->geometry().contains(cursorPos)) {
if (!d->widgetExplorer) {
QString expqml = package().filePath("widgetexplorer");
qDebug() << "Script to load for WidgetExplorer: " << expqml;
d->widgetExplorer = new WidgetExplorer();
d->widgetExplorer.data()->setSource(QUrl::fromLocalFile(expqml));
}
Plasma::Containment *c = 0;
c = dynamic_cast<Plasma::Containment*>(sender());
if (c) {
qDebug() << "Found containment.";
d->widgetExplorer.data()->setContainment(c);
} else {
// FIXME: try harder to find a suitable containment?
qWarning() << "containment not set, don't know where to add the applet.";
}
//The view QML has to provide something to display the activity explorer
view->rootObject()->metaObject()->invokeMethod(view->rootObject(), "toggleWidgetExplorer", Q_ARG(QVariant, QVariant::fromValue(d->widgetExplorer.data())));
return;
}
}
QString expqml = package().filePath("widgetexplorer");
qDebug() << "Script to load for WidgetExplorer: " << expqml;
d->widgetExplorer = new WidgetExplorer();
d->widgetExplorer.data()->setSource(QUrl::fromLocalFile(expqml));
}
Plasma::Containment *c = 0;
c = dynamic_cast<Plasma::Containment*>(sender());
if (c) {
qDebug() << "Found containment.";
d->widgetExplorer.data()->setContainment(c);
} else {
// FIXME: try harder to find a suitable containment?
qWarning() << "containment not set, don't know where to add the applet.";
}
} }
void ShellCorona::toggleActivityManager() void ShellCorona::toggleActivityManager()

View File

@ -302,8 +302,8 @@ void WidgetExplorerPrivate::appletRemoved(Plasma::Applet *applet)
//WidgetExplorer //WidgetExplorer
WidgetExplorer::WidgetExplorer(QObject *parent) WidgetExplorer::WidgetExplorer(QQuickItem *parent)
:QObject(parent), :QQuickItem(parent),
d(new WidgetExplorerPrivate(this)) d(new WidgetExplorerPrivate(this))
{ {
setLocation(Plasma::Types::LeftEdge); setLocation(Plasma::Types::LeftEdge);
@ -326,9 +326,9 @@ void WidgetExplorer::setLocation(Plasma::Types::Location loc)
emit(locationChanged(loc)); emit(locationChanged(loc));
} }
WidgetExplorer::Location WidgetExplorer::location() Plasma::Types::Location WidgetExplorer::location() const
{ {
return (WidgetExplorer::Location)d->location; return d->location;
} }
Qt::Orientation WidgetExplorer::orientation() const Qt::Orientation WidgetExplorer::orientation() const
@ -357,6 +357,8 @@ void WidgetExplorer::setSource(const QUrl &source)
d->qmlObject->setSource(source); d->qmlObject->setSource(source);
d->qmlObject->engine()->rootContext()->setContextProperty("widgetExplorer", this); d->qmlObject->engine()->rootContext()->setContextProperty("widgetExplorer", this);
d->qmlObject->completeInitialization(); d->qmlObject->completeInitialization();
QQuickItem *i = qobject_cast<QQuickItem *>(d->qmlObject->rootObject());
i->setParentItem(this);
} }
QUrl WidgetExplorer::source() const QUrl WidgetExplorer::source() const

View File

@ -24,7 +24,7 @@
#define WIDGETEXPLORER_H #define WIDGETEXPLORER_H
#include <QAction> #include <QAction>
#include <QObject> #include <QQuickItem>
#include "plasmaappletitemmodel_p.h" #include "plasmaappletitemmodel_p.h"
@ -49,7 +49,7 @@ Q_SIGNALS:
void separatorChanged(); void separatorChanged();
}; };
class WidgetExplorer : public QObject class WidgetExplorer : public QQuickItem
{ {
Q_OBJECT Q_OBJECT
@ -77,7 +77,7 @@ class WidgetExplorer : public QObject
/** /**
* Plasma location of the panel containment the controller is associated to * Plasma location of the panel containment the controller is associated to
*/ */
Q_PROPERTY(Location location READ location NOTIFY locationChanged) Q_PROPERTY(Plasma::Types::Location location READ location NOTIFY locationChanged)
Q_ENUMS(Location) Q_ENUMS(Location)
/** /**
@ -86,23 +86,7 @@ class WidgetExplorer : public QObject
Q_PROPERTY(Qt::Orientation orientation READ orientation NOTIFY orientationChanged) Q_PROPERTY(Qt::Orientation orientation READ orientation NOTIFY orientationChanged)
public: public:
/** explicit WidgetExplorer(QQuickItem *parent = 0);
* The Location enumeration describes where on screen an element, such as an
* Applet or its managing container, is positioned on the screen.
**/
enum Location {
Floating = 0, /**< Free floating. Neither geometry or z-ordering
is described precisely by this value. */
Desktop, /**< On the planar desktop layer, extending across
the full screen from edge to edge */
FullScreen, /**< Full screen */
TopEdge, /**< Along the top of the screen*/
BottomEdge, /**< Along the bottom of the screen*/
LeftEdge, /**< Along the left side of the screen */
RightEdge /**< Along the right side of the screen */
};
explicit WidgetExplorer(QObject *parent = 0);
~WidgetExplorer(); ~WidgetExplorer();
QString application(); QString application();
@ -146,8 +130,7 @@ public:
void setLocation(const Plasma::Types::Location loc); void setLocation(const Plasma::Types::Location loc);
//FIXME: it's asymmetric due to the problems of QML of exporting enums Plasma::Types::Location location() const;
WidgetExplorer::Location location();
Qt::Orientation orientation() const; Qt::Orientation orientation() const;