You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
381 lines
13 KiB
381 lines
13 KiB
/******************************************************************** |
|
KWin - the KDE window manager |
|
This file is part of the KDE project. |
|
|
|
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.com> |
|
|
|
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/>. |
|
*********************************************************************/ |
|
|
|
// own |
|
#include "tabboxview.h" |
|
// tabbox |
|
#include "clientitemdelegate.h" |
|
#include "clientmodel.h" |
|
#include "desktopitemdelegate.h" |
|
#include "desktopmodel.h" |
|
#include "tabboxconfig.h" |
|
#include "tabboxhandler.h" |
|
|
|
// Qt |
|
#include <QTextStream> |
|
#include <QGridLayout> |
|
#include <QHeaderView> |
|
#include <QKeyEvent> |
|
#include <QSizePolicy> |
|
#include <QPainter> |
|
|
|
// KDE |
|
#include <kephal/screens.h> |
|
#include <Plasma/FrameSvg> |
|
|
|
namespace KWin |
|
{ |
|
namespace TabBox |
|
{ |
|
|
|
TabBoxView::TabBoxView( QWidget* parent ) |
|
: QWidget( parent ) |
|
{ |
|
setWindowFlags( Qt::X11BypassWindowManagerHint ); |
|
setAttribute( Qt::WA_TranslucentBackground ); |
|
setAutoFillBackground( false ); |
|
m_clientModel = new ClientModel( this ); |
|
m_desktopModel = new DesktopModel( this ); |
|
m_delegate = new ClientItemDelegate( this ); |
|
m_additionalClientDelegate = new ClientItemDelegate( this ); |
|
m_additionalClientDelegate->setShowSelection( false ); |
|
m_desktopItemDelegate = new DesktopItemDelegate( this ); |
|
m_additionalDesktopDelegate = new DesktopItemDelegate( this ); |
|
m_tableView = new TabBoxMainView( this ); |
|
m_additionalView = new TabBoxAdditionalView( this ); |
|
|
|
// FrameSvg |
|
m_frame = new Plasma::FrameSvg( this ); |
|
m_frame->setImagePath( "dialogs/background" ); |
|
m_frame->setCacheAllRenderedFrames( true ); |
|
m_frame->setEnabledBorders( Plasma::FrameSvg::AllBorders ); |
|
|
|
connect( tabBox, SIGNAL(configChanged()), this, SLOT(configChanged())); |
|
} |
|
|
|
TabBoxView::~TabBoxView() |
|
{ |
|
} |
|
|
|
void TabBoxView::paintEvent(QPaintEvent* e) |
|
{ |
|
// paint the background |
|
QPainter painter( this ); |
|
painter.save(); |
|
painter.setCompositionMode( QPainter::CompositionMode_Source ); |
|
m_frame->resizeFrame( geometry().size() ); |
|
painter.setClipRegion( m_frame->mask() ); |
|
m_frame->paintFrame( &painter ); |
|
painter.restore(); |
|
QWidget::paintEvent(e); |
|
} |
|
|
|
void TabBoxView::updateGeometry() |
|
{ |
|
if( m_tableView->model()->columnCount() == 0 || m_tableView->model()->rowCount() == 0 ) |
|
return; |
|
QSize hint = sizeHint(); |
|
QRect screenRect = Kephal::ScreenUtils::screenGeometry( tabBox->activeScreen() ); |
|
int x = screenRect.x() + screenRect.width() * 0.5 - hint.width() * 0.5; |
|
int y = screenRect.y() + screenRect.height() * 0.5 - hint.height() * 0.5; |
|
|
|
setGeometry( x, y, hint.width(), hint.height() ); |
|
m_frame->resizeFrame( hint ); |
|
} |
|
|
|
QSize TabBoxView::sizeHint() const |
|
{ |
|
if( m_tableView->model()->columnCount() == 0 || m_tableView->model()->rowCount() == 0 ) |
|
return QSize( 0, 0 ); |
|
// calculate width and height |
|
QSize tabBoxSize = m_tableView->sizeHint(); |
|
qreal columnWidth = tabBoxSize.width() / m_tableView->model()->columnCount(); |
|
qreal rowHeight = tabBoxSize.height() / m_tableView->model()->rowCount(); |
|
for( int i=0; i<m_tableView->model()->columnCount(); i++ ) |
|
m_tableView->setColumnWidth( i, columnWidth ); |
|
for( int i=0; i<m_tableView->model()->rowCount(); i++ ) |
|
m_tableView->setRowHeight( i, rowHeight ); |
|
|
|
// additional view |
|
QSize additionalSize = m_additionalView->sizeHint(); |
|
for( int i=0; i<m_additionalView->model()->columnCount(); i++ ) |
|
m_additionalView->setColumnWidth( i, additionalSize.width() ); |
|
for( int i=0; i<m_additionalView->model()->rowCount(); i++ ) |
|
m_additionalView->setRowHeight( i, additionalSize.height() ); |
|
|
|
// reserve some space for borders |
|
qreal top, bottom, left, right; |
|
m_frame->getMargins( left, top, right, bottom ); |
|
int width = columnWidth * m_tableView->model()->columnCount() + left + right; |
|
int height = rowHeight * m_tableView->model()->rowCount() + top + bottom; |
|
|
|
// depending on layout of additional view we have to add some width or height |
|
switch( tabBox->config().selectedItemViewPosition() ) |
|
{ |
|
case TabBoxConfig::AbovePosition: // fall through |
|
case TabBoxConfig::BelowPosition: |
|
width = qMax( width, additionalSize.width() + int(left + right) ); |
|
height = height + additionalSize.height(); |
|
break; |
|
case TabBoxConfig::LeftPosition: // fall through |
|
case TabBoxConfig::RightPosition: |
|
width = width + additionalSize.width(); |
|
height = qMax( height, additionalSize.height() + int(top + bottom) ); |
|
break; |
|
default: |
|
// don't add |
|
break; |
|
} |
|
|
|
QRect screenRect = Kephal::ScreenUtils::screenGeometry( tabBox->activeScreen() ); |
|
width = qBound( screenRect.width() * tabBox->config().minWidth() / 100, width, |
|
screenRect.width() ); |
|
height = qBound( screenRect.height() * tabBox->config().minHeight() / 100, height, |
|
screenRect.height() ); |
|
return QSize( width, height ); |
|
} |
|
|
|
void TabBoxView::setCurrentIndex( QModelIndex index ) |
|
{ |
|
if( index.isValid() ) |
|
{ |
|
m_tableView->setCurrentIndex( index ); |
|
m_additionalView->setCurrentIndex( index ); |
|
} |
|
} |
|
|
|
void TabBoxView::configChanged() |
|
{ |
|
switch( tabBox->config().tabBoxMode() ) |
|
{ |
|
case TabBoxConfig::ClientTabBox: |
|
m_tableView->setModel( m_clientModel ); |
|
m_tableView->setItemDelegate( m_delegate ); |
|
m_additionalView->setModel( m_clientModel ); |
|
m_additionalView->setItemDelegate( m_additionalClientDelegate ); |
|
break; |
|
case TabBoxConfig::DesktopTabBox: |
|
m_tableView->setModel( m_desktopModel ); |
|
m_tableView->setItemDelegate( m_desktopItemDelegate ); |
|
m_additionalView->setModel( m_desktopModel ); |
|
m_additionalView->setItemDelegate( m_additionalDesktopDelegate ); |
|
break; |
|
} |
|
QLayout* old = layout(); |
|
QLayoutItem *child; |
|
while( old && (child = old->takeAt( 0 )) != 0 ) |
|
{ |
|
delete child; |
|
} |
|
delete old; |
|
QBoxLayout *layout; |
|
switch( tabBox->config().selectedItemViewPosition() ) |
|
{ |
|
case TabBoxConfig::AbovePosition: |
|
{ |
|
layout = new QVBoxLayout(); |
|
QHBoxLayout* horizontalLayout1 = new QHBoxLayout(); |
|
horizontalLayout1->addStretch(); |
|
horizontalLayout1->addWidget( m_additionalView ); |
|
horizontalLayout1->addStretch(); |
|
layout->addLayout( horizontalLayout1 ); |
|
layout->addStretch(); |
|
QHBoxLayout* horizontalLayout2 = new QHBoxLayout(); |
|
horizontalLayout2->addStretch(); |
|
horizontalLayout2->addWidget( m_tableView ); |
|
horizontalLayout2->addStretch(); |
|
layout->addLayout( horizontalLayout2 ); |
|
m_additionalView->show(); |
|
break; |
|
} |
|
case TabBoxConfig::BelowPosition: |
|
{ |
|
layout = new QVBoxLayout(); |
|
QHBoxLayout* horizontalLayout1 = new QHBoxLayout(); |
|
horizontalLayout1->addStretch(); |
|
horizontalLayout1->addWidget( m_tableView ); |
|
horizontalLayout1->addStretch(); |
|
layout->addLayout( horizontalLayout1 ); |
|
layout->addStretch(); |
|
QHBoxLayout* horizontalLayout2 = new QHBoxLayout(); |
|
horizontalLayout2->addStretch(); |
|
horizontalLayout2->addWidget( m_additionalView ); |
|
horizontalLayout2->addStretch(); |
|
layout->addLayout( horizontalLayout2 ); |
|
m_additionalView->show(); |
|
break; |
|
} |
|
case TabBoxConfig::LeftPosition: |
|
{ |
|
layout = new QHBoxLayout(); |
|
QVBoxLayout* verticalLayout1 = new QVBoxLayout(); |
|
verticalLayout1->addStretch(); |
|
verticalLayout1->addWidget( m_additionalView ); |
|
verticalLayout1->addStretch(); |
|
layout->addLayout( verticalLayout1 ); |
|
layout->addStretch(); |
|
QVBoxLayout* verticalLayout2 = new QVBoxLayout(); |
|
verticalLayout2->addStretch(); |
|
verticalLayout2->addWidget( m_tableView ); |
|
verticalLayout2->addStretch(); |
|
layout->addLayout( verticalLayout2 ); |
|
m_additionalView->show(); |
|
break; |
|
} |
|
case TabBoxConfig::RightPosition: |
|
{ |
|
layout = new QHBoxLayout(); |
|
QVBoxLayout* verticalLayout1 = new QVBoxLayout(); |
|
verticalLayout1->addStretch(); |
|
verticalLayout1->addWidget( m_tableView ); |
|
verticalLayout1->addStretch(); |
|
layout->addLayout( verticalLayout1 ); |
|
layout->addStretch(); |
|
QVBoxLayout* verticalLayout2 = new QVBoxLayout(); |
|
verticalLayout2->addStretch(); |
|
verticalLayout2->addWidget( m_additionalView ); |
|
verticalLayout2->addStretch(); |
|
layout->addLayout( verticalLayout2 ); |
|
m_additionalView->show(); |
|
break; |
|
} |
|
default: |
|
{ |
|
layout = new QVBoxLayout(); |
|
layout->addWidget( m_tableView ); |
|
m_additionalView->hide(); |
|
break; |
|
} |
|
} |
|
setLayout( layout ); |
|
} |
|
|
|
QModelIndex TabBoxView::indexAt( QPoint pos ) |
|
{ |
|
return m_tableView->indexAt( pos ); |
|
} |
|
|
|
void TabBoxView::setPreview( bool preview ) |
|
{ |
|
m_preview = preview; |
|
m_frame->setImagePath( "dialogs/opaque/background" ); |
|
} |
|
|
|
/******************************************************** |
|
* TabBoxMainView |
|
********************************************************/ |
|
|
|
TabBoxMainView::TabBoxMainView(QWidget* parent) |
|
: QTableView(parent) |
|
{ |
|
setFrameStyle( QFrame::NoFrame ); |
|
setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); |
|
setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); |
|
viewport()->setAutoFillBackground( false ); |
|
|
|
// adjust table view to needs of tabbox |
|
setShowGrid( false ); |
|
horizontalHeader()->hide(); |
|
verticalHeader()->hide(); |
|
setSelectionMode( QAbstractItemView::SingleSelection ); |
|
setSelectionBehavior( QAbstractItemView::SelectItems ); |
|
setHorizontalScrollMode( QAbstractItemView::ScrollPerItem ); |
|
setVerticalScrollMode( QAbstractItemView::ScrollPerItem ); |
|
setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ); |
|
} |
|
|
|
TabBoxMainView::~TabBoxMainView() |
|
{ |
|
} |
|
|
|
QSize TabBoxMainView::sizeHint() const |
|
{ |
|
int maxWidth = 0; |
|
int minWidth = sizeHintForColumn( 0 ); |
|
int maxHeight = 0; |
|
int minHeight = sizeHintForRow( 0 ); |
|
for( int i=0; i<model()->columnCount(); i++ ) |
|
{ |
|
minWidth = qMin( minWidth, sizeHintForColumn( i ) ); |
|
maxWidth = qMax( maxWidth, sizeHintForColumn( i ) ); |
|
} |
|
for( int i=0; i<model()->rowCount(); i++ ) |
|
{ |
|
minHeight = qMin( minHeight, sizeHintForRow( i ) ); |
|
maxHeight = qMax( maxHeight, sizeHintForRow( i ) ); |
|
} |
|
qreal columnWidth = (minWidth + qreal(maxWidth - minWidth) / 2.0 ); |
|
qreal rowHeight = (minHeight + qreal(maxHeight - minHeight) / 2.0 ); |
|
return QSize( columnWidth * model()->columnCount(), |
|
rowHeight * model()->rowCount() ); |
|
} |
|
|
|
/******************************************************** |
|
* TabBoxAdditonalView |
|
********************************************************/ |
|
|
|
TabBoxAdditionalView::TabBoxAdditionalView(QWidget* parent) |
|
: QTableView(parent) |
|
{ |
|
setFrameStyle( QFrame::NoFrame ); |
|
setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); |
|
setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); |
|
viewport()->setAutoFillBackground( false ); |
|
|
|
// adjust table view to needs of tabbox |
|
setShowGrid( false ); |
|
horizontalHeader()->hide(); |
|
verticalHeader()->hide(); |
|
setSelectionMode( QAbstractItemView::SingleSelection ); |
|
setSelectionBehavior( QAbstractItemView::SelectItems ); |
|
setHorizontalScrollMode( QAbstractItemView::ScrollPerItem ); |
|
setVerticalScrollMode( QAbstractItemView::ScrollPerItem ); |
|
setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); |
|
} |
|
|
|
TabBoxAdditionalView::~TabBoxAdditionalView() |
|
{ |
|
} |
|
|
|
QSize TabBoxAdditionalView::sizeHint() const |
|
{ |
|
int maxWidth = 0; |
|
int minWidth = sizeHintForColumn( 0 ); |
|
int maxHeight = 0; |
|
int minHeight = sizeHintForRow( 0 ); |
|
for( int i=0; i<model()->columnCount(); i++ ) |
|
{ |
|
minWidth = qMin( minWidth, sizeHintForColumn( i ) ); |
|
maxWidth = qMax( maxWidth, sizeHintForColumn( i ) ); |
|
} |
|
for( int i=0; i<model()->rowCount(); i++ ) |
|
{ |
|
minHeight = qMin( minHeight, sizeHintForRow( i ) ); |
|
maxHeight = qMax( maxHeight, sizeHintForRow( i ) ); |
|
} |
|
qreal columnWidth = (minWidth + qreal(maxWidth - minWidth) / 2.0 ); |
|
qreal rowHeight = (minHeight + qreal(maxHeight - minHeight) / 2.0 ); |
|
return QSize( columnWidth, rowHeight ); |
|
} |
|
|
|
} // namespace Tabbox |
|
} // namespace KWin |
|
|
|
#include "tabboxview.moc"
|
|
|