/* Ia Ora KWin window decoration Copyright (C) 2006 Laurent Montel Based on plastik code Copyright (C) 2003-2005 Sandro Giessl based on the window decoration "Web": Copyright (C) 2001 Rik Hemsley (rikkus) 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 #include #include #include #include #include #include #include "misc.h" #include "iaora.h" #include "iaora.moc" #include "iaoraclient.h" #include "iaorabutton.h" namespace KWinIaOra { IaOraHandler::IaOraHandler() { memset(m_pixmaps, 0, sizeof(TQPixmap*)*NumPixmaps*2*2); // set elements to 0 memset(m_bitmaps, 0, sizeof(TQBitmap*)*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 = TQApplication::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); TQFontMetrics fm(m_titleFont); // active font = inactive font int titleHeightMin = config.readNumEntry("MinTitleHeight", 22); // The title should strech with bigger font sizes! m_titleHeight = TQMAX(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 = TQFontMetrics(m_titleFontTool); // active font = inactive font int titleHeightToolMin = config.readNumEntry("MinTitleHeightTool", 22); // The title should strech with bigger font sizes! m_titleHeightTool = TQMAX(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); } TQColor IaOraHandler::getBorderColor( KWinIaOra::ColorType type, const bool active) { //Force colors switch (type) { case Border1: return TQColor( "#EFF3F7" ); break; case Border2: return TQColor( "#DFE7EF" ); break; case Border3: return TQColor( "#C7D3DF" ); break; default: return TQt::black; } return TQt::black; } TQColor IaOraHandler::getShadowColor() { TQColor col = KDecoration::options()->color(ColorTitleBar, true); if ( col == TQColor("#4964AE") ) { return TQColor( "#000000" ); } //default Arctic color else if ( col == TQColor("#8ec7ff") ) { return TQColor( "#666666" ); } else if ( col == TQColor("7BAAE7") ) { return TQColor( "#666666" ); } //default Orange color else if ( col == TQColor("#F7B610") ) { return TQColor( "#666666" ); } //default Gray color else if ( col == TQColor("#c7d3df") ) { return TQColor( "#333333" ); } return TQColor( "#666666" ); } TQColor IaOraHandler::getGradientColor( KWinIaOra::ColorType type, const bool active) { TQColor col = KDecoration::options()->color(ColorTitleBar, active); //default Blue color if ( active ) { if ( col == TQColor("#4964AE") ) { switch (type) { case TitleGradient1: return TQColor("#8EA2CF"); break; case TitleGradient2: return TQColor("#415DA6"); break; case TitleGradient4: return TQColor("#4964AE"); break; case TitleGradient3: return TQColor("#21459C"); break; default: return TQt::black; } } //default Smooth color else if ( col == TQColor("#7BAAE7") ) { switch (type) { case TitleGradient1: return TQColor("#ADCFFF"); break; case TitleGradient2: return TQColor("#5A8AD6"); break; case TitleGradient4: return TQColor("#7BAAE7"); break; case TitleGradient3: return TQColor("#427DC6"); break; default: return TQt::black; } } //default Orange color else if ( col == TQColor("#F7B610") ) { switch (type) { case TitleGradient1: return TQColor("#FFCB10"); break; case TitleGradient2: return TQColor("#ffa208"); break; case TitleGradient4: return TQColor("#f7b610"); break; case TitleGradient3: return TQColor("#f79600"); break; default: return TQt::black; } } //default Arctic color else if ( col == TQColor("#8ec7ff") ) { switch (type) { case TitleGradient1: return TQColor("#c7dfff"); break; case TitleGradient2: return TQColor("#79beff"); break; case TitleGradient4: return TQColor("#8ec7ff"); break; case TitleGradient3: return TQColor("#69b6ff"); break; default: return TQt::black; } } //default Gray color else if ( col == TQColor("#c7d3df") ) { switch (type) { case TitleGradient1: return TQColor("#cfd7df"); break; case TitleGradient2: return TQColor("#a6b2c7"); break; case TitleGradient4: return TQColor("#c7d3df"); break; case TitleGradient3: return TQColor("#8692a6"); break; default: return TQt::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 TQt::black; } } } else { if ( col == TQColor( "#EFF3F7" ) ) { switch (type) { case TitleGradient1: return TQColor( "#DFE7EF" ); break; case TitleGradient2: return TQColor( "#C7D3DF" ); break; case TitleGradient4: return TQColor( "#CFD7DF" ); break; case TitleGradient3: return TQColor( "#B6C3CF" ); break; default: return TQt::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 TQt::black; } } } return TQt::black; } TQColor 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), TQt::white, active?205:215); //todo verify case ShadeTitleDark: return alphaBlendColors(KDecoration::options()->color(ColorTitleBar, active), TQt::black, active?205:215); break; case TitleFont: return KDecoration::options()->color(ColorFont, active); default: return TQt::black; } } void IaOraHandler::pretile( TQPixmap *&pix, int size, TQt::Orientation dir ) const { TQPixmap *newpix; TQPainter p; if ( dir == TQt::Horizontal ) newpix = new TQPixmap( size, pix->height() ); else newpix = new TQPixmap( pix->width(), size ); p.begin( newpix ); p.drawTiledPixmap( newpix->rect(), *pix ) ; p.end(); delete pix; pix = newpix; } const TQPixmap &IaOraHandler::pixmap(Pixmaps type, bool active, bool toolWindow) { if (m_pixmaps[toolWindow][active][type]) return *m_pixmaps[toolWindow][active][type]; TQPixmap *pm = 0; switch (type) { case TitleBarTileTop: { pm = new TQPixmap(1, 3); TQPainter 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, TQt::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; TQPixmap gradient(1, gradientHeight); TQPainter 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 TQPixmap(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, TQt::Horizontal); break; } case TitleBarLeft: { const int h = 4 + (toolWindow ? m_titleHeightTool : m_titleHeight) + 2; pm = new TQPixmap(3, h); TQPainter 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 TQPixmap(3, h); TQPainter 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 TQPixmap(3, 1); TQPainter 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, TQt::Vertical); break; } case BorderRightTile: { pm = new TQPixmap(3, 1); TQPainter 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, TQt::Vertical); break; } case BorderBottomLeft: { pm = new TQPixmap(3, 3); TQPainter 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 TQPixmap(3, 3); TQPainter 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 TQPixmap(1, 3); TQPainter 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, TQt::Horizontal); break; } } m_pixmaps[toolWindow][active][type] = pm; return *pm; } const TQBitmap &IaOraHandler::buttonBitmap(ButtonIcon type, const TQSize &size, bool toolWindow) { int typeIndex = type; // btn icon size... int reduceW = 0, reduceH = 0; if(size.width()>14) { reduceW = static_cast(2*(size.width()/3.5) ); } else reduceW = 6; if(size.height()>14) reduceH = static_cast(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()==TQSize(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; TQBitmap bmp = IconEngine::icon(type /*icon*/, TQMIN(w,h) ); TQBitmap *bitmap = new TQBitmap(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; } }