diff options
Diffstat (limited to 'src/kwin/iaora.cpp')
-rw-r--r-- | src/kwin/iaora.cpp | 665 |
1 files changed, 665 insertions, 0 deletions
diff --git a/src/kwin/iaora.cpp b/src/kwin/iaora.cpp new file mode 100644 index 0000000..887baff --- /dev/null +++ b/src/kwin/iaora.cpp @@ -0,0 +1,665 @@ +/* Ia Ora KWin window decoration + Copyright (C) 2006 Laurent Montel <lmontel@mandriva.com> + Based on plastik code + Copyright (C) 2003-2005 Sandro Giessl <sandro@giessl.com> + + based on the window decoration "Web": + Copyright (C) 2001 Rik Hemsley (rikkus) <rik@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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include <qbitmap.h> +#include <qpainter.h> +#include <qimage.h> +#include <qapplication.h> +#include <kconfig.h> +#include <kpixmap.h> +#include <kpixmapeffect.h> + +#include "misc.h" +#include "iaora.h" +#include "iaora.moc" +#include "iaoraclient.h" +#include "iaorabutton.h" + +namespace KWinIaOra +{ + +IaOraHandler::IaOraHandler() +{ + memset(m_pixmaps, 0, sizeof(QPixmap*)*NumPixmaps*2*2); // set elements to 0 + memset(m_bitmaps, 0, sizeof(QBitmap*)*NumButtonIcons*2); + + reset(0); +} + +IaOraHandler::~IaOraHandler() +{ + for (int t=0; t < 2; ++t) + for (int a=0; a < 2; ++a) + for (int i=0; i < NumPixmaps; ++i) + delete m_pixmaps[t][a][i]; + for (int t=0; t < 2; ++t) + for (int i=0; i < NumButtonIcons; ++i) + delete m_bitmaps[t][i]; +} + +bool IaOraHandler::reset(unsigned long changed) +{ + // we assume the active font to be the same as the inactive font since the control + // center doesn't offer different settings anyways. + m_titleFont = KDecoration::options()->font(true, false); // not small + m_titleFontTool = KDecoration::options()->font(true, true); // small + + // check if we are in reverse layout mode + m_reverse = QApplication::reverseLayout(); + + // read in the configuration + readConfig(); + + // pixmaps probably need to be updated, so delete the cache. + for (int t=0; t < 2; ++t) { + for (int a=0; a < 2; ++a) { + for (int i=0; i < NumPixmaps; i++) { + if (m_pixmaps[t][a][i]) { + delete m_pixmaps[t][a][i]; + m_pixmaps[t][a][i] = 0; + } + } + } + } + for (int t=0; t < 2; ++t) { + for (int i=0; i < NumButtonIcons; i++) { + if (m_bitmaps[t][i]) { + delete m_bitmaps[t][i]; + m_bitmaps[t][i] = 0; + } + } + } + + // Do we need to "hit the wooden hammer" ? + bool needHardReset = true; + // TODO: besides the Color and Font settings I can maybe handle more changes + // without a hard reset. I will do this later... + if (changed & SettingColors || changed & SettingFont) + { + needHardReset = false; + } else if (changed & SettingButtons) { + // handled by KCommonDecoration + needHardReset = false; + } + + if (needHardReset) { + return true; + } else { + resetDecorations(changed); + return false; + } +} + +KDecoration* IaOraHandler::createDecoration( KDecorationBridge* bridge ) +{ + return new IaOraClient( bridge, this ); +} + +bool IaOraHandler::supports( Ability ability ) +{ + switch( ability ) + { + case AbilityAnnounceButtons: + case AbilityButtonMenu: + case AbilityButtonOnAllDesktops: + case AbilityButtonSpacer: + case AbilityButtonHelp: + case AbilityButtonMinimize: + case AbilityButtonMaximize: + case AbilityButtonClose: + case AbilityButtonAboveOthers: + case AbilityButtonBelowOthers: + case AbilityButtonShade: + return true; + default: + return false; + }; +} + +void IaOraHandler::readConfig() +{ + // create a config object + KConfig config("kwiniaorarc"); + config.setGroup("General"); + + // grab settings + m_titleShadow = config.readBoolEntry("TitleShadow", true); + + QFontMetrics fm(m_titleFont); // active font = inactive font + int titleHeightMin = config.readNumEntry("MinTitleHeight", 22); + // The title should strech with bigger font sizes! + m_titleHeight = QMAX(titleHeightMin, fm.height() + 4); // 4 px for the shadow etc. + // have an even title/button size so the button icons are fully centered... + if ( m_titleHeight%2 == 0) + m_titleHeight++; + + fm = QFontMetrics(m_titleFontTool); // active font = inactive font + int titleHeightToolMin = config.readNumEntry("MinTitleHeightTool", 22); + // The title should strech with bigger font sizes! + m_titleHeightTool = QMAX(titleHeightToolMin, fm.height() ); // don't care about the shadow etc. + // have an even title/button size so the button icons are fully centered... + if ( m_titleHeightTool%2 == 0) + m_titleHeightTool++; + + m_menuClose = config.readBoolEntry("CloseOnMenuDoubleClick", true); +} + +QColor IaOraHandler::getBorderColor( KWinIaOra::ColorType type, const bool active) +{ + //Force colors + switch (type) { + case Border1: + return QColor( "#EFF3F7" ); + break; + case Border2: + return QColor( "#DFE7EF" ); + break; + case Border3: + return QColor( "#C7D3DF" ); + break; + default: + return Qt::black; + } + return Qt::black; +} + +QColor IaOraHandler::getShadowColor() +{ + QColor col = KDecoration::options()->color(ColorTitleBar, true); + if ( col == QColor("#4964AE") ) + { + return QColor( "#000000" ); + } + //default Arctic color + else if ( col == QColor("#8ec7ff") ) + { + return QColor( "#666666" ); + } + else if ( col == QColor("7BAAE7") ) + { + return QColor( "#666666" ); + } + //default Orange color + else if ( col == QColor("#F7B610") ) + { + return QColor( "#666666" ); + } + //default Gray color + else if ( col == QColor("#c7d3df") ) + { + return QColor( "#333333" ); + } + return QColor( "#666666" ); +} + +QColor IaOraHandler::getGradientColor( KWinIaOra::ColorType type, const bool active) +{ + QColor col = KDecoration::options()->color(ColorTitleBar, active); + //default Blue color + if ( active ) + { + if ( col == QColor("#4964AE") ) + { + switch (type) { + case TitleGradient1: + return QColor("#8EA2CF"); + break; + case TitleGradient2: + return QColor("#415DA6"); + break; + case TitleGradient4: + return QColor("#4964AE"); + break; + case TitleGradient3: + return QColor("#21459C"); + break; + default: + return Qt::black; + } + } + //default Smooth color + else if ( col == QColor("#7BAAE7") ) + { + switch (type) { + case TitleGradient1: + return QColor("#ADCFFF"); + break; + case TitleGradient2: + return QColor("#5A8AD6"); + break; + case TitleGradient4: + return QColor("#7BAAE7"); + break; + case TitleGradient3: + return QColor("#427DC6"); + break; + default: + return Qt::black; + } + } + //default Orange color + else if ( col == QColor("#F7B610") ) + { + switch (type) { + case TitleGradient1: + return QColor("#FFCB10"); + break; + case TitleGradient2: + return QColor("#ffa208"); + break; + case TitleGradient4: + return QColor("#f7b610"); + break; + case TitleGradient3: + return QColor("#f79600"); + break; + default: + return Qt::black; + } + } + //default Arctic color + else if ( col == QColor("#8ec7ff") ) + { + switch (type) { + case TitleGradient1: + return QColor("#c7dfff"); + break; + case TitleGradient2: + return QColor("#79beff"); + break; + case TitleGradient4: + return QColor("#8ec7ff"); + break; + case TitleGradient3: + return QColor("#69b6ff"); + break; + default: + return Qt::black; + } + } + //default Gray color + else if ( col == QColor("#c7d3df") ) + { + switch (type) { + case TitleGradient1: + return QColor("#cfd7df"); + break; + case TitleGradient2: + return QColor("#a6b2c7"); + break; + case TitleGradient4: + return QColor("#c7d3df"); + break; + case TitleGradient3: + return QColor("#8692a6"); + break; + default: + return Qt::black; + } + } + else + { + switch (type) { + case TitleGradient1: + return col.light( 150 ); + break; + case TitleGradient2: + return col.dark( 112 ); + break; + case TitleGradient4: + return col; + break; + case TitleGradient3: + return col.dark( 130 ); + break; + default: + return Qt::black; + } + } + } + else + { + if ( col == QColor( "#EFF3F7" ) ) + { + switch (type) { + case TitleGradient1: + return QColor( "#DFE7EF" ); + break; + case TitleGradient2: + return QColor( "#C7D3DF" ); + break; + case TitleGradient4: + return QColor( "#CFD7DF" ); + break; + case TitleGradient3: + return QColor( "#B6C3CF" ); + break; + default: + return Qt::black; + } + } + else + { + //create algo + switch (type) { + case TitleGradient1: + return col.dark(107); + break; + case TitleGradient2: + return col.dark( 117 ); + break; + case TitleGradient4: + return col.dark( 115 ); + break; + case TitleGradient3: + return col.dark( 131 ); + break; + default: + return Qt::black; + } + } + + } + return Qt::black; +} + +QColor IaOraHandler::getColor(KWinIaOra::ColorType type, const bool active) +{ + switch (type) { + case TitleBorder: + return KDecoration::options()->color(ColorTitleBar, active); + case TitleGradient1: + case TitleGradient2: + case TitleGradient4: + case TitleGradient3: + return getGradientColor( type, active); + case Border1: + case Border2: + case Border3: + return getBorderColor( type, active); + case ShadeTitleLight: + return alphaBlendColors(KDecoration::options()->color(ColorTitleBar, active), + Qt::white, active?205:215); + //todo verify + case ShadeTitleDark: + return alphaBlendColors(KDecoration::options()->color(ColorTitleBar, active), + Qt::black, active?205:215); + break; + case TitleFont: + return KDecoration::options()->color(ColorFont, active); + default: + return Qt::black; + } +} + +void IaOraHandler::pretile( QPixmap *&pix, int size, Qt::Orientation dir ) const +{ + QPixmap *newpix; + QPainter p; + + if ( dir == Qt::Horizontal ) + newpix = new QPixmap( size, pix->height() ); + else + newpix = new QPixmap( pix->width(), size ); + + p.begin( newpix ); + p.drawTiledPixmap( newpix->rect(), *pix ) ; + p.end(); + + delete pix; + pix = newpix; +} + +const QPixmap &IaOraHandler::pixmap(Pixmaps type, bool active, bool toolWindow) +{ + if (m_pixmaps[toolWindow][active][type]) + return *m_pixmaps[toolWindow][active][type]; + + QPixmap *pm = 0; + + switch (type) { + case TitleBarTileTop: + { + pm = new QPixmap(1, 3); + QPainter painter(pm); + painter.setPen(getColor(TitleBorder, active)); + painter.drawPoint(0,0); + + painter.fillRect(0,1,pm->width(),pm->height()-1,getColor(TitleGradient1, active)); + painter.end(); + pretile(pm, 64, Qt::Horizontal); + break; + } + case TitleBarTile: + { + const int titleBarTileHeight = (toolWindow ? m_titleHeightTool : m_titleHeight) + 2; + // gradient used as well in TitleBarTileTop as TitleBarTile + const int gradientHeight = 2 + titleBarTileHeight; + QPixmap gradient(1, gradientHeight); + QPainter painter(&gradient); + KPixmap tempPixmap; + tempPixmap.resize(1, gradientHeight/2); + KPixmapEffect::gradient(tempPixmap, + getColor(TitleGradient1, active), + getColor(TitleGradient2, active), + KPixmapEffect::VerticalGradient); + painter.drawPixmap(0,0, tempPixmap); + tempPixmap.resize(1, gradientHeight - (gradientHeight/2)); + KPixmapEffect::gradient(tempPixmap, + getColor(TitleGradient3, active) , + getColor(TitleGradient4, active), + KPixmapEffect::VerticalGradient); + painter.drawPixmap(0,gradientHeight/2, tempPixmap); + painter.end(); + + pm = new QPixmap(1, titleBarTileHeight); + painter.begin(pm); + painter.drawPixmap(0, 0, gradient, 0,2); + painter.setPen(getColor(TitleGradient3, active).dark(110) ); + painter.drawPoint(0,titleBarTileHeight-1); + + painter.end(); + + pretile(pm, 64, Qt::Horizontal); + + break; + } + + case TitleBarLeft: + { + const int h = 4 + (toolWindow ? m_titleHeightTool : m_titleHeight) + 2; + + pm = new QPixmap(3, h); + QPainter painter(pm); + + painter.drawTiledPixmap(0,0, 3, 3, pixmap(TitleBarTileTop, active, toolWindow) ); + painter.drawTiledPixmap(0,3, 3, h-3, pixmap(TitleBarTile, active, toolWindow) ); + + painter.setPen(getColor(TitleBorder, active) ); + painter.drawLine(0,0, 0,h); + + break; + } + case TitleBarRight: + { + const int h = 4 + (toolWindow ? m_titleHeightTool : m_titleHeight) + 2; + + pm = new QPixmap(3, h); + QPainter painter(pm); + + painter.drawTiledPixmap(0,0, 3, 3, pixmap(TitleBarTileTop, active, toolWindow) ); + painter.drawTiledPixmap(0,3, 3, h-3, pixmap(TitleBarTile, active, toolWindow) ); + + painter.setPen(getColor(TitleBorder, active)); + painter.drawLine(2,0, 2,h); + + break; + } + + case BorderLeftTile: + { + pm = new QPixmap(3, 1); + QPainter painter(pm); + painter.setPen(getColor(Border3, active) ); + painter.drawPoint(0, 0); + painter.setPen(getColor(Border2, active) ); + painter.drawPoint(1, 0); + + painter.setPen(getColor(Border1, active) ); + painter.drawPoint(2,0); + painter.end(); + pretile(pm, 64, Qt::Vertical); + break; + } + + case BorderRightTile: + { + + pm = new QPixmap(3, 1); + QPainter painter(pm); + painter.setPen(getColor(Border1, active) ); + painter.drawPoint(0,0); + painter.setPen(getColor(Border2, active) ); + painter.drawPoint(1, 0); + painter.setPen(getColor(Border3, active) ); + painter.drawPoint(2, 0); + painter.end(); + pretile(pm, 64, Qt::Vertical); + + break; + } + + case BorderBottomLeft: + { + pm = new QPixmap(3, 3); + QPainter painter(pm); + painter.drawTiledPixmap(0,0,3,3, pixmap(BorderBottomTile, active, toolWindow) ); + painter.setPen(getColor(Border3, active) ); + painter.drawLine(0,0, 0,3); + + painter.setPen(getColor(Border1, active) ); + painter.drawLine(2,0, 2,0); + painter.end(); + + break; + } + + case BorderBottomRight: + { + + pm = new QPixmap(3, 3); + QPainter painter(pm); + painter.drawTiledPixmap(0,0,3,3, pixmap(BorderBottomTile, active, toolWindow) ); + painter.setPen(getColor(Border3, active) ); + painter.drawLine(2,0, 2,3); + painter.setPen(getColor(Border2, active) ); + painter.drawLine(1,0, 1,1); + + painter.setPen(getColor(Border1, active) ); + painter.drawLine(0,0, 0,0); + + painter.end(); + + break; + } + + case BorderBottomTile: + default: + { + pm = new QPixmap(1, 3); + QPainter painter(pm); + + painter.setPen(getColor(Border1, active) ); + painter.drawPoint(0,0); + painter.setPen(getColor(Border2, active) ); + painter.drawPoint(0,1); + painter.setPen(getColor(Border3, active) ); + painter.drawPoint(0, 2); + painter.end(); + + pretile(pm, 64, Qt::Horizontal); + + break; + } + } + + m_pixmaps[toolWindow][active][type] = pm; + return *pm; +} + +const QBitmap &IaOraHandler::buttonBitmap(ButtonIcon type, const QSize &size, bool toolWindow) +{ + int typeIndex = type; + + // btn icon size... + int reduceW = 0, reduceH = 0; + if(size.width()>14) { + reduceW = static_cast<int>(2*(size.width()/3.5) ); + } + else + reduceW = 6; + if(size.height()>14) + reduceH = static_cast<int>(2*(size.height()/3.5) ); + else + reduceH = 6; + + int w = size.width() - reduceW; + int h = size.height() - reduceH; + + if (m_bitmaps[toolWindow][typeIndex] && m_bitmaps[toolWindow][typeIndex]->size()==QSize(w,h) ) + return *m_bitmaps[toolWindow][typeIndex]; + + // no matching pixmap found, create a new one... + + delete m_bitmaps[toolWindow][typeIndex]; + m_bitmaps[toolWindow][typeIndex] = 0; + + QBitmap bmp = IconEngine::icon(type /*icon*/, QMIN(w,h) ); + QBitmap *bitmap = new QBitmap(bmp); + m_bitmaps[toolWindow][typeIndex] = bitmap; + return *bitmap; +} + + +// make the handler accessible to other classes... +static IaOraHandler *handler = 0; +IaOraHandler* Handler() +{ + return handler; +} + +} // KWinPlastik + +////////////////////////////////////////////////////////////////////////////// +// Plugin Stuff // +////////////////////////////////////////////////////////////////////////////// + +extern "C" +{ + KDE_EXPORT KDecorationFactory *create_factory() + { + KWinIaOra::handler = new KWinIaOra::IaOraHandler(); + return KWinIaOra::handler; + } +} |