/******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2010 Thomas Lübking 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 . *********************************************************************/ #include "windowgeometry.h" #include #include #include #include #include #include using namespace KWin; KWIN_EFFECT( windowgeometry, WindowGeometry ) WindowGeometry::WindowGeometry() { iAmActivated = true; iAmActive = false; myResizeWindow = 0L; myResizeString = i18nc("Window geometry display, %1 and %2 are the new size," " %3 and %4 are pixel increments - avoid reformatting or suffixes like 'px'", "Width: %1 (%3)\nHeight: %2 (%4)"); myCoordString[0] = i18nc("Window geometry display, %1 and %2 are the cartesian x and y coordinates" " - avoid reformatting or suffixes like 'px'", "X: %1\nY: %2"); myCoordString[1] = i18nc("Window geometry display, %1 and %2 are the cartesian x and y coordinates," " %3 and %4 are the resp. increments - avoid reformatting or suffixes like 'px'", "X: %1 (%3)\nY: %2 (%4)"); reconfigure( ReconfigureAll ); QFont fnt; fnt.setBold(true); fnt.setPointSize(12); for ( int i = 0; i < 3; ++i ) { myMeasure[i] = effects->effectFrame( EffectFrameUnstyled, false ); myMeasure[i]->setFont( fnt ); } myMeasure[0]->setAlignment( Qt::AlignLeft|Qt::AlignTop ); myMeasure[1]->setAlignment( Qt::AlignCenter ); myMeasure[2]->setAlignment( Qt::AlignRight|Qt::AlignBottom ); KActionCollection* actionCollection = new KActionCollection( this ); KAction* a = static_cast< KAction* >( actionCollection->addAction( "WindowGeometry" )); a->setText( i18n("Toggle window geometry display (effect only)" )); a->setGlobalShortcut( KShortcut( Qt::CTRL + Qt::SHIFT + Qt::Key_F11 )); connect( a, SIGNAL( triggered(bool) ), this, SLOT( toggle() ) ); } WindowGeometry::~WindowGeometry() { for ( int i = 0; i < 3; ++i ) delete myMeasure[i]; } void WindowGeometry::reconfigure( ReconfigureFlags ) { KConfigGroup conf = effects->effectConfig( "WindowGeometry" ); iHandleMoves = conf.readEntry( "Move", true ); iHandleResizes = conf.readEntry( "Resize", true ); } void WindowGeometry::paintScreen(int mask, QRegion region, ScreenPaintData &data) { effects->paintScreen( mask, region, data ); if ( iAmActivated && iAmActive ) { for ( int i = 0; i < 3; ++i ) myMeasure[i]->render(infiniteRegion(), 1.0, .66); } } void WindowGeometry::toggle() { iAmActivated = !iAmActivated; } void WindowGeometry::windowUserMovedResized( EffectWindow* w, bool first, bool last ) { if (first && last) // "maximized" return; if ( first ) { if ( !iAmActivated ) return; if ( w->isUserResize() && !iHandleResizes ) return; if ( w->isUserMove() && !iHandleMoves) return; iAmActive = true; myResizeWindow = w; myOriginalGeometry = w->geometry(); myCurrentGeometry = w->geometry(); effects->addRepaint( myCurrentGeometry.adjusted(-20, -20, 20, 20) ); } if ( iAmActive && w == myResizeWindow && last ) { iAmActive = false; myResizeWindow = 0L; effects->addRepaint( myCurrentGeometry.adjusted(-20, -20, 20, 20) ); } } static inline QString number(int n) { if ( n >= 0 ) return "+" + QString::number(n); return QString::number(n); // "-" is auto-applied } void WindowGeometry::windowMoveResizeGeometryUpdate( EffectWindow* w, const QRect& geometry ) { if ( iAmActivated && iAmActive && w == myResizeWindow ) { myCurrentGeometry = geometry; const QRect &r = geometry; const QRect &r2 = myOriginalGeometry; // sufficient for moves, resizes calculated otherwise int dx = r.x() - r2.x(); int dy = r.y() - r2.y(); // upper left ---------------------- if ( w->isUserResize() ) myMeasure[0]->setText( myCoordString[1].arg( r.x() ).arg( r.y() ).arg( number(dx) ).arg( number(dy) ) ); else myMeasure[0]->setText( myCoordString[0].arg( r.x() ).arg( r.y() ) ); myMeasure[0]->setPosition( geometry.topLeft() ); // center ---------------------- if ( w->isUserResize() ) { // calc width for center element, otherwise the current dx/dx remains right dx = r.width() - r2.width(); dy = r.height() - r2.height(); // TODO: i hate this. anyone got a nice idea to invoke the stringbuilder or otherwise avoid // dogslow QString::arg() system here? myMeasure[1]->setText( myResizeString.arg( r.width() ).arg( r.height() ).arg( number(dx) ).arg( number(dy) ) ); // calc width for bottomright element, superflous otherwise dx = r.right() - r2.right(); dy = r.bottom() - r2.bottom(); } else myMeasure[1]->setText( myCoordString[0].arg( number(dx) ).arg( number(dy) ) ); myMeasure[1]->setPosition( geometry.center() ); // lower right ---------------------- if ( w->isUserResize() ) myMeasure[2]->setText( myCoordString[1].arg( r.right() ).arg( r.bottom() ).arg( number(dx) ).arg( number(dy) ) ); else myMeasure[2]->setText( myCoordString[0].arg( r.right() ).arg( r.bottom() ) ); myMeasure[2]->setPosition( geometry.bottomRight() ); effects->addRepaint( geometry.adjusted(-20, -20, 20, 20) ); } }