Desktop Box support for QML based TabBox
First very simple layout just rendering icon and name. Good enough for the start.
This commit is contained in:
parent
1f07877adb
commit
e1cbb33631
5 changed files with 220 additions and 11 deletions
|
@ -246,6 +246,7 @@ install( FILES
|
|||
tabbox/qml/informative.qml
|
||||
tabbox/qml/big_icons.qml
|
||||
tabbox/qml/compact.qml
|
||||
tabbox/qml/desktop.qml
|
||||
tabbox/qml/small_icons.qml
|
||||
tabbox/qml/tabbox.qml
|
||||
tabbox/qml/text.qml
|
||||
|
|
|
@ -101,9 +101,10 @@ QPixmap ImageProvider::requestPixmap(const QString &id, QSize *size, const QSize
|
|||
return icon;
|
||||
}
|
||||
|
||||
DeclarativeView::DeclarativeView(QAbstractItemModel *model, QWidget *parent)
|
||||
DeclarativeView::DeclarativeView(QAbstractItemModel *model, TabBoxConfig::TabBoxMode mode, QWidget *parent)
|
||||
: QDeclarativeView(parent)
|
||||
, m_model(model)
|
||||
, m_mode(mode)
|
||||
, m_currentScreenGeometry()
|
||||
, m_frame(new Plasma::FrameSvg(this))
|
||||
, m_currentLayout()
|
||||
|
@ -130,7 +131,11 @@ DeclarativeView::DeclarativeView(QAbstractItemModel *model, QWidget *parent)
|
|||
kdeclarative.setupBindings();
|
||||
qmlRegisterType<ThumbnailItem>("org.kde.kwin", 0, 1, "ThumbnailItem");
|
||||
rootContext()->setContextProperty("viewId", static_cast<qulonglong>(winId()));
|
||||
rootContext()->setContextProperty("clientModel", model);
|
||||
if (m_mode == TabBoxConfig::ClientTabBox) {
|
||||
rootContext()->setContextProperty("clientModel", model);
|
||||
} else if (m_mode == TabBoxConfig::DesktopTabBox) {
|
||||
rootContext()->setContextProperty("clientModel", model);
|
||||
}
|
||||
setSource(QUrl(KStandardDirs::locate("data", "kwin/tabbox/tabbox.qml")));
|
||||
|
||||
// FrameSvg
|
||||
|
@ -139,7 +144,9 @@ DeclarativeView::DeclarativeView(QAbstractItemModel *model, QWidget *parent)
|
|||
m_frame->setEnabledBorders(Plasma::FrameSvg::AllBorders);
|
||||
|
||||
connect(tabBox, SIGNAL(configChanged()), SLOT(updateQmlSource()));
|
||||
connect(tabBox, SIGNAL(embeddedChanged(bool)), SLOT(slotEmbeddedChanged(bool)));
|
||||
if (m_mode == TabBoxConfig::ClientTabBox) {
|
||||
connect(tabBox, SIGNAL(embeddedChanged(bool)), SLOT(slotEmbeddedChanged(bool)));
|
||||
}
|
||||
}
|
||||
|
||||
void DeclarativeView::showEvent(QShowEvent *event)
|
||||
|
@ -154,7 +161,9 @@ void DeclarativeView::showEvent(QShowEvent *event)
|
|||
rootObject()->setProperty("allDesktops", tabBox->config().tabBoxMode() == TabBoxConfig::ClientTabBox &&
|
||||
((tabBox->config().clientListMode() == TabBoxConfig::AllDesktopsClientList) ||
|
||||
(tabBox->config().clientListMode() == TabBoxConfig::AllDesktopsApplicationList)));
|
||||
rootObject()->setProperty("longestCaption", static_cast<ClientModel*>(m_model)->longestCaption());
|
||||
if (ClientModel *clientModel = qobject_cast<ClientModel*>(m_model)) {
|
||||
rootObject()->setProperty("longestCaption", clientModel->longestCaption());
|
||||
}
|
||||
|
||||
if (QObject *item = rootObject()->findChild<QObject*>("listView")) {
|
||||
item->setProperty("currentIndex", tabBox->first().row());
|
||||
|
@ -254,6 +263,9 @@ void DeclarativeView::slotUpdateGeometry()
|
|||
|
||||
void DeclarativeView::setCurrentIndex(const QModelIndex &index)
|
||||
{
|
||||
if (tabBox->config().tabBoxMode() != m_mode) {
|
||||
return;
|
||||
}
|
||||
if (QObject *item = rootObject()->findChild<QObject*>("listView")) {
|
||||
item->setProperty("currentIndex", index.row());
|
||||
}
|
||||
|
@ -281,14 +293,22 @@ void DeclarativeView::currentIndexChanged(int row)
|
|||
|
||||
void DeclarativeView::updateQmlSource(bool force)
|
||||
{
|
||||
if (tabBox->config().tabBoxMode() != m_mode) {
|
||||
return;
|
||||
}
|
||||
if (!force && tabBox->config().layoutName() == m_currentLayout) {
|
||||
return;
|
||||
}
|
||||
m_currentLayout = tabBox->config().layoutName();
|
||||
QString file = KStandardDirs::locate("data", "kwin/tabbox/" + m_currentLayout.toLower().replace(' ', '_') + ".qml");
|
||||
if (m_mode == TabBoxConfig::DesktopTabBox) {
|
||||
file = KStandardDirs::locate("data", "kwin/tabbox/desktop.qml");
|
||||
}
|
||||
if (file.isNull()) {
|
||||
// fallback to default
|
||||
file = KStandardDirs::locate("data", "kwin/tabbox/informative.qml");
|
||||
if (m_mode == TabBoxConfig::ClientTabBox) {
|
||||
file = KStandardDirs::locate("data", "kwin/tabbox/informative.qml");
|
||||
}
|
||||
}
|
||||
rootObject()->setProperty("source", QUrl(file));
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
// includes
|
||||
#include <QtDeclarative/QDeclarativeImageProvider>
|
||||
#include <QtDeclarative/QDeclarativeView>
|
||||
#include "tabboxconfig.h"
|
||||
|
||||
// forward declaration
|
||||
class QAbstractItemModel;
|
||||
|
@ -52,7 +53,7 @@ class DeclarativeView : public QDeclarativeView
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DeclarativeView(QAbstractItemModel *model, QWidget *parent = NULL);
|
||||
DeclarativeView(QAbstractItemModel *model, TabBoxConfig::TabBoxMode mode, QWidget *parent = NULL);
|
||||
virtual void showEvent(QShowEvent *event);
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
void setCurrentIndex(const QModelIndex &index);
|
||||
|
@ -71,6 +72,7 @@ private Q_SLOTS:
|
|||
void slotWindowChanged(WId wId, unsigned int properties);
|
||||
private:
|
||||
QAbstractItemModel *m_model;
|
||||
TabBoxConfig::TabBoxMode m_mode;
|
||||
QRect m_currentScreenGeometry;
|
||||
/**
|
||||
* Background Frame required for setting the blur mask
|
||||
|
|
174
tabbox/qml/desktop.qml
Normal file
174
tabbox/qml/desktop.qml
Normal file
|
@ -0,0 +1,174 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
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) 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 General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
import QtQuick 1.0
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
import org.kde.qtextracomponents 0.1
|
||||
|
||||
Item {
|
||||
id: desktopTabBox
|
||||
property int screenWidth : 0
|
||||
property int screenHeight : 0
|
||||
property bool allDesktops: true
|
||||
property string longestCaption: ""
|
||||
property int optimalWidth: listView.maxRowWidth
|
||||
property int optimalHeight: listView.rowHeight * listView.count + background.margins.top + background.margins.bottom
|
||||
property bool canStretchX: true
|
||||
property bool canStretchY: false
|
||||
width: Math.min(Math.max(screenWidth * 0.2, optimalWidth), screenWidth * 0.8)
|
||||
height: Math.min(optimalHeight, screenHeight * 0.8)
|
||||
|
||||
property int textMargin: 2
|
||||
|
||||
onLongestCaptionChanged: {
|
||||
listView.maxRowWidth = listView.calculateMaxRowWidth();
|
||||
}
|
||||
|
||||
function setModel(model) {
|
||||
listView.model = model;
|
||||
listView.maxRowWidth = listView.calculateMaxRowWidth();
|
||||
}
|
||||
|
||||
PlasmaCore.Theme {
|
||||
id: theme
|
||||
}
|
||||
|
||||
// just to get the margin sizes
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: hoverItem
|
||||
imagePath: "widgets/viewitem"
|
||||
prefix: "hover"
|
||||
visible: false
|
||||
}
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
imagePath: "dialogs/background"
|
||||
}
|
||||
|
||||
// delegate
|
||||
Component {
|
||||
id: listDelegate
|
||||
Item {
|
||||
id: delegateItem
|
||||
width: listView.width
|
||||
height: listView.rowHeight
|
||||
QIconItem {
|
||||
id: iconElement
|
||||
icon: "user-desktop"
|
||||
width: 32
|
||||
height: 32
|
||||
anchors {
|
||||
topMargin: (listView.rowHeight - 32) / 2
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
leftMargin: hoverItem.margins.left
|
||||
}
|
||||
}
|
||||
Text {
|
||||
id: captionItem
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: display
|
||||
font.bold: true
|
||||
color: theme.textColor
|
||||
elide: Text.ElideMiddle
|
||||
anchors {
|
||||
left: iconElement.right
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
topMargin: desktopTabBox.textMargin + hoverItem.margins.top
|
||||
rightMargin: hoverItem.margins.right
|
||||
leftMargin: desktopTabBox.textMargin
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
listView.currentIndex = index;
|
||||
listView.currentIndexChanged(listView.currentIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ListView {
|
||||
function calculateMaxRowWidth() {
|
||||
var width = 0;
|
||||
var textElement = Qt.createQmlObject(
|
||||
'import Qt 4.7;'
|
||||
+ 'Text {\n'
|
||||
+ ' text: "' + desktopTabBox.longestCaption + '"\n'
|
||||
+ ' font.bold: true\n'
|
||||
+ ' visible: false\n'
|
||||
+ '}',
|
||||
listView, "calculateMaxRowWidth");
|
||||
width = Math.max(textElement.width, width);
|
||||
textElement.destroy();
|
||||
return width + 32 + hoverItem.margins.right + hoverItem.margins.left + background.margins.left + background.margins.right;
|
||||
}
|
||||
/**
|
||||
* Calculates the height of one row based on the text height and icon size.
|
||||
* @return Row height
|
||||
**/
|
||||
function calcRowHeight() {
|
||||
var textElement = Qt.createQmlObject(
|
||||
'import Qt 4.7;'
|
||||
+ 'Text {\n'
|
||||
+ ' text: "Some Text"\n'
|
||||
+ ' font.bold: true\n'
|
||||
+ ' visible: false\n'
|
||||
+ '}',
|
||||
listView, "calcRowHeight");
|
||||
var height = textElement.height;
|
||||
textElement.destroy();
|
||||
// icon size or two text elements and margins and hoverItem margins
|
||||
return Math.max(32, height + desktopTabBox.textMargin * 2 + hoverItem.margins.top + hoverItem.margins.bottom);
|
||||
}
|
||||
/**
|
||||
* Called from C++ to get the index at a mouse pos.
|
||||
**/
|
||||
function indexAtMousePos(pos) {
|
||||
return listView.indexAt(pos.x, pos.y);
|
||||
}
|
||||
signal currentIndexChanged(int index)
|
||||
id: listView
|
||||
objectName: "listView"
|
||||
// the maximum text width + icon item width (32 + 4 margin) + margins for hover item + margins for background
|
||||
property int maxRowWidth: calculateMaxRowWidth()
|
||||
property int rowHeight: calcRowHeight()
|
||||
// used for image provider URL to trick Qt into reloading icons when the model changes
|
||||
property int imageId: 0
|
||||
anchors {
|
||||
fill: parent
|
||||
topMargin: background.margins.top
|
||||
leftMargin: background.margins.left
|
||||
rightMargin: background.margins.right
|
||||
bottomMargin: background.margins.bottom
|
||||
}
|
||||
clip: true
|
||||
delegate: listDelegate
|
||||
highlight: PlasmaCore.FrameSvgItem {
|
||||
id: highlightItem
|
||||
imagePath: "widgets/viewitem"
|
||||
prefix: "hover"
|
||||
width: listView.width
|
||||
}
|
||||
highlightMoveDuration: 250
|
||||
}
|
||||
}
|
|
@ -79,6 +79,7 @@ public:
|
|||
TabBoxConfig config;
|
||||
TabBoxView* view;
|
||||
DeclarativeView *m_declarativeView;
|
||||
DeclarativeView *m_declarativeDesktopView;
|
||||
ClientModel* m_clientModel;
|
||||
DesktopModel* m_desktopModel;
|
||||
QModelIndex index;
|
||||
|
@ -98,6 +99,7 @@ public:
|
|||
TabBoxHandlerPrivate::TabBoxHandlerPrivate(TabBoxHandler *q)
|
||||
: view(NULL)
|
||||
, m_declarativeView(NULL)
|
||||
, m_declarativeDesktopView(NULL)
|
||||
, m_embedded(0)
|
||||
, m_embeddedOffset(QPoint(0, 0))
|
||||
, m_embeddedSize(QSize(0, 0))
|
||||
|
@ -121,6 +123,7 @@ TabBoxHandlerPrivate::~TabBoxHandlerPrivate()
|
|||
{
|
||||
delete view;
|
||||
delete m_declarativeView;
|
||||
delete m_declarativeDesktopView;
|
||||
}
|
||||
|
||||
void TabBoxHandlerPrivate::createView()
|
||||
|
@ -421,16 +424,16 @@ void TabBoxHandler::show()
|
|||
if (d->config.tabBoxMode() == TabBoxConfig::ClientTabBox) {
|
||||
// use declarative view
|
||||
if (!d->m_declarativeView) {
|
||||
d->m_declarativeView = new DeclarativeView(d->clientModel());
|
||||
d->m_declarativeView = new DeclarativeView(d->clientModel(), TabBoxConfig::ClientTabBox);
|
||||
}
|
||||
d->m_declarativeView->show();
|
||||
d->m_declarativeView->setCurrentIndex(d->index);
|
||||
} else {
|
||||
if (!d->view) {
|
||||
d->createView();
|
||||
if (!d->m_declarativeDesktopView) {
|
||||
d->m_declarativeDesktopView = new DeclarativeView(d->desktopModel(), TabBoxConfig::DesktopTabBox);
|
||||
}
|
||||
d->view->show();
|
||||
d->view->updateGeometry();
|
||||
d->m_declarativeDesktopView->show();
|
||||
d->m_declarativeDesktopView->setCurrentIndex(d->index);
|
||||
}
|
||||
}
|
||||
if (d->config.isHighlightWindows()) {
|
||||
|
@ -453,6 +456,9 @@ void TabBoxHandler::hide(bool abort)
|
|||
if (d->m_declarativeView) {
|
||||
d->m_declarativeView->hide();
|
||||
}
|
||||
if (d->m_declarativeDesktopView) {
|
||||
d->m_declarativeDesktopView->hide();
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex TabBoxHandler::nextPrev(bool forward) const
|
||||
|
@ -550,6 +556,9 @@ void TabBoxHandler::setCurrentIndex(const QModelIndex& index)
|
|||
if (d->m_declarativeView) {
|
||||
d->m_declarativeView->setCurrentIndex(index);
|
||||
}
|
||||
if (d->m_declarativeDesktopView) {
|
||||
d->m_declarativeDesktopView->setCurrentIndex(index);
|
||||
}
|
||||
d->index = index;
|
||||
if (d->config.tabBoxMode() == TabBoxConfig::ClientTabBox) {
|
||||
if (d->config.isShowOutline()) {
|
||||
|
@ -639,6 +648,9 @@ QModelIndex TabBoxHandler::indexAt(const QPoint& pos) const
|
|||
} else if (d->m_declarativeView && d->m_declarativeView->isVisible()) {
|
||||
QPoint widgetPos = d->m_declarativeView->mapFromGlobal(pos);
|
||||
return d->m_declarativeView->indexAt(widgetPos);
|
||||
} else if (d->m_declarativeDesktopView && d->m_declarativeDesktopView->isVisible()) {
|
||||
QPoint widgetPos = d->m_declarativeDesktopView->mapFromGlobal(pos);
|
||||
return d->m_declarativeDesktopView->indexAt(widgetPos);
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue