diff options
author | Slávek Banko <slavek.banko@axis.cz> | 2016-03-26 20:11:54 +0100 |
---|---|---|
committer | Slávek Banko <slavek.banko@axis.cz> | 2016-03-26 20:11:54 +0100 |
commit | b0263695595db848002728b3ebbd8b27fd08ca8c (patch) | |
tree | 085d0b4a9f07462145c0cd6d15b306fe5ad2c1bc /src/kwin | |
download | tde-style-ia-ora-b0263695595db848002728b3ebbd8b27fd08ca8c.tar.gz tde-style-ia-ora-b0263695595db848002728b3ebbd8b27fd08ca8c.zip |
Initial import of ia-ora 1.0.8
Diffstat (limited to 'src/kwin')
-rw-r--r-- | src/kwin/Makefile.am | 19 | ||||
-rw-r--r-- | src/kwin/config/Makefile.am | 14 | ||||
-rw-r--r-- | src/kwin/config/config.cpp | 102 | ||||
-rw-r--r-- | src/kwin/config/config.h | 55 | ||||
-rw-r--r-- | src/kwin/config/configdialog.ui | 53 | ||||
-rw-r--r-- | src/kwin/iaora.cpp | 665 | ||||
-rw-r--r-- | src/kwin/iaora.desktop | 5 | ||||
-rw-r--r-- | src/kwin/iaora.h | 126 | ||||
-rw-r--r-- | src/kwin/iaorabutton.cpp | 528 | ||||
-rw-r--r-- | src/kwin/iaorabutton.h | 85 | ||||
-rw-r--r-- | src/kwin/iaoraclient.cpp | 514 | ||||
-rw-r--r-- | src/kwin/iaoraclient.h | 73 | ||||
-rw-r--r-- | src/kwin/misc.cpp | 49 | ||||
-rw-r--r-- | src/kwin/misc.h | 28 |
14 files changed, 2316 insertions, 0 deletions
diff --git a/src/kwin/Makefile.am b/src/kwin/Makefile.am new file mode 100644 index 0000000..5e52b07 --- /dev/null +++ b/src/kwin/Makefile.am @@ -0,0 +1,19 @@ +AUTOMAKE_OPTIONS = foreign + +SUBDIRS = config + +KDE_CXXFLAGS = -DQT_PLUGIN + +INCLUDES = -I$(srcdir)/../../lib $(all_includes) + +kwindir = $(kde_datadir)/kwin/ +kwin_DATA = iaora.desktop + +kde_module_LTLIBRARIES = kwin3_iaora.la +kwin3_iaora_la_SOURCES = iaora.cpp iaoraclient.cpp iaorabutton.cpp misc.cpp +kwin3_iaora_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +kwin3_iaora_la_LIBADD = $(LIB_KDEUI) -lkdecorations -lqt-mt -lkdecore -lkdefx +kwin3_iaora_la_METASOURCES = AUTO + +DISTCLEANFILES = $(kwin3_iaora_la_METASOURCES) + diff --git a/src/kwin/config/Makefile.am b/src/kwin/config/Makefile.am new file mode 100644 index 0000000..e4f9c03 --- /dev/null +++ b/src/kwin/config/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = $(all_includes) + +kde_module_LTLIBRARIES = kwin_iaora_config.la + +kwin_iaora_config_la_SOURCES = config.cpp configdialog.ui +kwin_iaora_config_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +kwin_iaora_config_la_LIBADD = $(LIB_KDEUI) -lqt-mt -lkdecore + +METASOURCES = AUTO +noinst_HEADERS = config.h +DISTCLEANFILES = $(METASOURCES) + +lnkdir = $(kde_datadir)/kwin + diff --git a/src/kwin/config/config.cpp b/src/kwin/config/config.cpp new file mode 100644 index 0000000..6320c23 --- /dev/null +++ b/src/kwin/config/config.cpp @@ -0,0 +1,102 @@ +/* + Copyright (C) 2006 Montel Laurent <lmontel@mandriva.com> + based on plastik + Copyright (C) 2003 Sandro Giessl <ceebx@users.sourceforge.net> + + 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 <qbuttongroup.h> +#include <qcheckbox.h> +#include <qradiobutton.h> +#include <qslider.h> +#include <qspinbox.h> +#include <qwhatsthis.h> + +#include <kconfig.h> +#include <klocale.h> +#include <kglobal.h> + +#include "config.h" +#include "configdialog.h" + +IaOraConfig::IaOraConfig(KConfig* config, QWidget* parent) + : QObject(parent), m_config(0), m_dialog(0) +{ + // create the configuration object + m_config = new KConfig("kwiniaorarc"); + KGlobal::locale()->insertCatalogue("kwin_clients"); + + // create and show the configuration dialog + m_dialog = new ConfigDialog(parent); + m_dialog->show(); + + // load the configuration + load(config); + + // setup the connections + connect(m_dialog->menuClose, SIGNAL(toggled(bool)), + this, SIGNAL(changed())); + connect(m_dialog->titleShadow, SIGNAL(toggled(bool)), + this, SIGNAL(changed())); +} + +IaOraConfig::~IaOraConfig() +{ + delete m_dialog; + delete m_config; +} + +void IaOraConfig::load(KConfig*) +{ + m_config->setGroup("General"); + + bool menuClose = m_config->readBoolEntry("CloseOnMenuDoubleClick", true); + m_dialog->menuClose->setChecked(menuClose); + bool titleShadow = m_config->readBoolEntry("TitleShadow", true); + m_dialog->titleShadow->setChecked(titleShadow); +} + +void IaOraConfig::save(KConfig*) +{ + m_config->setGroup("General"); + + m_config->writeEntry("CloseOnMenuDoubleClick", m_dialog->menuClose->isChecked() ); + m_config->writeEntry("TitleShadow", m_dialog->titleShadow->isChecked() ); + m_config->sync(); +} + +void IaOraConfig::defaults() +{ + m_dialog->menuClose->setChecked(false); + m_dialog->titleShadow->setChecked(true); +} + +////////////////////////////////////////////////////////////////////////////// +// Plugin Stuff // +////////////////////////////////////////////////////////////////////////////// + +extern "C" +{ + KDE_EXPORT QObject* allocate_config(KConfig* config, QWidget* parent) { + return (new IaOraConfig(config, parent)); + } +} + +#include "config.moc" diff --git a/src/kwin/config/config.h b/src/kwin/config/config.h new file mode 100644 index 0000000..9be0ea5 --- /dev/null +++ b/src/kwin/config/config.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2006 Montel Laurent <lmontel@mandriva.com> + based on plastik + Copyright (C) 2003 Sandro Giessl <ceebx@users.sourceforge.net> + + 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. + */ + +#ifndef KNIFTYCONFIG_H +#define KNIFTYCONFIG_H + +#include <qobject.h> + +class QButtonGroup; +class QGroupBox; +class KConfig; +class ConfigDialog; + +class IaOraConfig : public QObject +{ + Q_OBJECT +public: + IaOraConfig(KConfig* config, QWidget* parent); + ~IaOraConfig(); + +signals: + void changed(); + +public slots: + void load(KConfig *config); + void save(KConfig *config); + void defaults(); + +private: + KConfig *m_config; + ConfigDialog *m_dialog; +}; + +#endif // KNIFTYCONFIG_H diff --git a/src/kwin/config/configdialog.ui b/src/kwin/config/configdialog.ui new file mode 100644 index 0000000..a6167b4 --- /dev/null +++ b/src/kwin/config/configdialog.ui @@ -0,0 +1,53 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ConfigDialog</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ConfigDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>535</width> + <height>88</height> + </rect> + </property> + <property name="caption"> + <string>Config Dialog</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>titleShadow</cstring> + </property> + <property name="text"> + <string>Use shadowed &text</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Check this option if you want the titlebar text to have a 3D look with a shadow behind it.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>menuClose</cstring> + </property> + <property name="text"> + <string>Close windows by double clicking the menu button</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Check this option if you want windows to be closed when you double click the menu button, similar to Microsoft Windows.</string> + </property> + </widget> + </vbox> +</widget> +<tabstops> + <tabstop>titleShadow</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +</UI> 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; + } +} diff --git a/src/kwin/iaora.desktop b/src/kwin/iaora.desktop new file mode 100644 index 0000000..7bece01 --- /dev/null +++ b/src/kwin/iaora.desktop @@ -0,0 +1,5 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon= +Name=Ia ora +X-KDE-Library=kwin3_iaora diff --git a/src/kwin/iaora.h b/src/kwin/iaora.h new file mode 100644 index 0000000..3f8d757 --- /dev/null +++ b/src/kwin/iaora.h @@ -0,0 +1,126 @@ +/* IaOra KWin window decoration + Based on plastik theme + 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. + */ + +#ifndef IAORA_H +#define IAORA_H + +#include <qfont.h> + +#include <kdecoration.h> +#include <kdecorationfactory.h> + +namespace KWinIaOra { + +enum ColorType { + TitleGradient1 = 0, // top + TitleGradient2, + TitleGradient3, // bottom + TitleGradient4, + ShadeTitleLight, + ShadeTitleDark, + Border1, + Border2, + Border3, + TitleFont, + TitleBorder +}; + +enum Pixmaps { + TitleBarTileTop=0, + TitleBarTile, + TitleBarLeft, + TitleBarRight, + BorderLeftTile, + BorderRightTile, + BorderBottomTile, + BorderBottomLeft, + BorderBottomRight, + NumPixmaps +}; + +enum ButtonIcon { + CloseIcon = 0, + MaxIcon, + MaxRestoreIcon, + MinIcon, + HelpIcon, + OnAllDesktopsIcon, + NotOnAllDesktopsIcon, + KeepAboveIcon, + NoKeepAboveIcon, + KeepBelowIcon, + NoKeepBelowIcon, + ShadeIcon, + UnShadeIcon, + NumButtonIcons +}; + +class IaOraHandler: public QObject, public KDecorationFactory +{ + Q_OBJECT +public: + IaOraHandler(); + ~IaOraHandler(); + virtual bool reset( unsigned long changed ); + + virtual KDecoration* createDecoration( KDecorationBridge* ); + virtual bool supports( Ability ability ); + + const QPixmap &pixmap(Pixmaps type, bool active, bool toolWindow); + const QBitmap &buttonBitmap(ButtonIcon type, const QSize &size, bool toolWindow); + + int titleHeight()const { return m_titleHeight; } + int titleHeightTool()const { return m_titleHeightTool; } + const QFont &titleFont() { return m_titleFont; } + const QFont &titleFontTool() { return m_titleFontTool; } + bool titleShadow()const { return m_titleShadow; } + bool menuClose()const { return m_menuClose; } + bool reverseLayout()const { return m_reverse; } + QColor getColor(KWinIaOra::ColorType type, const bool active = true); + QColor getGradientColor( KWinIaOra::ColorType type, const bool active); + QColor getBorderColor( KWinIaOra::ColorType type, const bool active); + QColor getShadowColor(); + +private: + void readConfig(); + + void pretile(QPixmap *&pix, int size, Qt::Orientation dir) const; + + bool m_titleShadow; + bool m_menuClose; + bool m_reverse; + int m_titleHeight; + int m_titleHeightTool; + QFont m_titleFont; + QFont m_titleFontTool; + + // pixmap cache + QPixmap *m_pixmaps[2][2][NumPixmaps]; // button pixmaps have normal+pressed state... + QBitmap *m_bitmaps[2][NumButtonIcons]; +}; + +IaOraHandler* Handler(); + +} // KWinPlastik + +#endif // IAORA_H diff --git a/src/kwin/iaorabutton.cpp b/src/kwin/iaorabutton.cpp new file mode 100644 index 0000000..fe9c3a6 --- /dev/null +++ b/src/kwin/iaorabutton.cpp @@ -0,0 +1,528 @@ +/* IaOra 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 <qpixmap.h> +#include <kpixmap.h> +#include <kpixmapeffect.h> +#include <qtimer.h> + +#include "iaorabutton.h" +#include "iaorabutton.moc" +#include "iaoraclient.h" +#include "misc.h" + +namespace KWinIaOra +{ + + +IaOraButton::IaOraButton(ButtonType type, IaOraClient *parent, const char *name) + : KCommonDecorationButton(type, parent, name), + m_client(parent), + m_iconType(NumButtonIcons), + hover(false) +{ + setBackgroundMode(NoBackground); + +} + +IaOraButton::~IaOraButton() +{ +} + +void IaOraButton::reset(unsigned long changed) +{ + if (changed&DecorationReset || changed&ManualReset || changed&SizeChange || changed&StateChange) { + switch (type() ) { + case CloseButton: + m_iconType = CloseIcon; + break; + case HelpButton: + m_iconType = HelpIcon; + break; + case MinButton: + m_iconType = MinIcon; + break; + case MaxButton: + if (isOn()) { + m_iconType = MaxRestoreIcon; + } else { + m_iconType = MaxIcon; + } + break; + case OnAllDesktopsButton: + if (isOn()) { + m_iconType = NotOnAllDesktopsIcon; + } else { + m_iconType = OnAllDesktopsIcon; + } + break; + case ShadeButton: + if (isOn()) { + m_iconType = UnShadeIcon; + } else { + m_iconType = ShadeIcon; + } + break; + case AboveButton: + if (isOn()) { + m_iconType = NoKeepAboveIcon; + } else { + m_iconType = KeepAboveIcon; + } + break; + case BelowButton: + if (isOn()) { + m_iconType = NoKeepBelowIcon; + } else { + m_iconType = KeepBelowIcon; + } + break; + default: + m_iconType = NumButtonIcons; // empty... + break; + } + + this->update(); + } +} + + +void IaOraButton::enterEvent(QEvent *e) +{ + QButton::enterEvent(e); + + hover = true; + repaint(false); +} + +void IaOraButton::leaveEvent(QEvent *e) +{ + QButton::leaveEvent(e); + + hover = false; + repaint(false); +} + +void IaOraButton::drawButton(QPainter *painter) +{ + QRect r(0,0,width(),height()); + + bool active = m_client->isActive(); + KPixmap tempKPixmap; + + QPixmap buffer; + buffer.resize(width(), height()); + QPainter bP(&buffer); + + // fake the titlebar background + bP.drawTiledPixmap(0, 0, width(), width(), /*define color*/m_client->getTitleBarTile(active) ); + if (type() == MenuButton) + { + QPixmap menuIcon(m_client->icon().pixmap( QIconSet::Small, QIconSet::Normal)); + if (width() < menuIcon.width() || height() < menuIcon.height() ) { + menuIcon.convertFromImage( menuIcon.convertToImage().smoothScale(width(), height())); + } + bP.drawPixmap((width()-menuIcon.width())/2, (height()-menuIcon.height())/2, menuIcon); + } + else + { + int dX,dY; + const QBitmap &icon = Handler()->buttonBitmap(m_iconType, size(), decoration()->isToolWindow() ); + dX = r.x()+(r.width()-icon.width())/2; + dY = r.y()+(r.height()-icon.height())/2; + if (isDown() ) { + dY++; + } +#if 0 + if(!isDown() && Handler()->titleShadow() ) { + QColor shadowColor; + if (qGray(Handler()->getColor(TitleFont,active).rgb()) < 100) + shadowColor = QColor(255, 255, 255); + else + shadowColor = QColor(0,0,0); + //bP.setPen(alphaBlendColors(sourfaceTop, shadowColor, 180) ); + bP.drawPixmap(dX+1, dY+1, icon); + } +#endif + bP.setPen(Handler()->getColor(TitleFont,hover ? false : active) ); + bP.drawPixmap(dX, dY, icon,0,0,icon.width(),icon.height()/2); + bP.setPen(QColor("#CFD7DF") ); + bP.drawPixmap(dX, dY+icon.height()/2, icon,0,icon.height()/2,icon.width(),icon.height()); + } + bP.end(); + painter->drawPixmap(0, 0, buffer); +} + +QBitmap IconEngine::icon(ButtonIcon icon, int size) +{ + if (size%2 == 0) + --size; + + QBitmap bitmap(size,size); + bitmap.fill(Qt::color0); + QPainter p(&bitmap); + + p.setPen(Qt::color1); + + QRect r = bitmap.rect(); + + // line widths + int lwTitleBar = 1; + if (r.width() > 16) { + lwTitleBar = 4; + } else if (r.width() > 4) { + lwTitleBar = 2; + } + int lwArrow = 1; + if (r.width() > 16) { + lwArrow = 4; + } else if (r.width() > 7) { + lwArrow = 2; + } + + //QColor col1( "#FFFFFF" ); + //QColor col2( "#CFD7DF" ); + + switch(icon) { + case CloseIcon: + { + int lineWidth = 1; + if (r.width() > 16) { + lineWidth = 3; + } else if (r.width() > 4) { + lineWidth = 2; + } + + drawObject(p, DiagonalLine, r.x(), r.y(), r.width(), lineWidth); + drawObject(p, CrossDiagonalLine, r.x(), r.bottom(), r.width(), lineWidth); + + break; + } + + case MaxIcon: + { + int lineWidth2 = 1; // frame + if (r.width() > 16) { + lineWidth2 = 2; + } else if (r.width() > 4) { + lineWidth2 = 1; + } + + drawObject(p, HorizontalLine, r.x(), r.top(), r.width(), lwTitleBar); + drawObject(p, HorizontalLine, r.x(), r.bottom()-(lineWidth2-1), r.width(), lineWidth2); + drawObject(p, VerticalLine, r.x(), r.top(), r.height(), lineWidth2); + drawObject(p, VerticalLine, r.right()-(lineWidth2-1), r.top(), r.height(), lineWidth2); + + break; + } + + case MaxRestoreIcon: + { + int lineWidth2 = 1; // frame + if (r.width() > 16) { + lineWidth2 = 2; + } else if (r.width() > 4) { + lineWidth2 = 1; + } + + int margin1, margin2; + margin1 = margin2 = lineWidth2*2; + if (r.width() < 8) + margin1 = 1; + + // background window + drawObject(p, HorizontalLine, r.x(), r.top(), r.width()-margin1+1 +3 , lineWidth2); + drawObject(p, HorizontalLine, r.right()-margin2, r.bottom()-(lineWidth2-1)/*-margin1*/, margin2, lineWidth2); + drawObject(p, VerticalLine, r.x(), r.top(), margin2+3, lineWidth2); + drawObject(p, VerticalLine, r.right()-(lineWidth2-1), r.top(), r.height()-margin1+3, lineWidth2); + + // foreground window + drawObject(p, HorizontalLine, r.x(), r.top()+margin2, r.width()-margin2, lwTitleBar); + drawObject(p, HorizontalLine, r.x(), r.bottom()-(lineWidth2-1), r.width()-margin2, lineWidth2); + drawObject(p, VerticalLine, r.x(), r.top()+margin2, r.height(), lineWidth2); + drawObject(p, VerticalLine, r.right()-(lineWidth2-1)-margin2, r.top()+margin2, r.height(), lineWidth2); + break; + } + + case MinIcon: + { + int posY = r.height()/2-(lwTitleBar-1); + + drawObject(p, HorizontalLine, r.x()+1,posY, r.width()-2, lwTitleBar); + //grey 2 + //p.setPen( col2 ); + p.drawLine(r.x(),posY+1, r.x()+r.width()-1, posY+1); + p.drawLine(r.x()+1, posY+2, r.x()+r.width()-2, posY+2); + + break; + } + + case HelpIcon: + { + int center = r.x()+r.width()/2 -1; + int side = r.width()/4; + + // paint a question mark... code is quite messy, to be cleaned up later...! :o + + if (r.width() > 16) { + int lineWidth = 3; + + // top bar + drawObject(p, HorizontalLine, center-side+3, r.y(), 2*side-3-1, lineWidth); + // top bar rounding + drawObject(p, CrossDiagonalLine, center-side-1, r.y()+5, 6, lineWidth); + drawObject(p, DiagonalLine, center+side-3, r.y(), 5, lineWidth); + // right bar + drawObject(p, VerticalLine, center+side+2-lineWidth, r.y()+3, r.height()-(2*lineWidth+side+2+1), lineWidth); + // bottom bar + drawObject(p, CrossDiagonalLine, center, r.bottom()-2*lineWidth, side+2, lineWidth); + drawObject(p, HorizontalLine, center, r.bottom()-3*lineWidth+2, lineWidth, lineWidth); + // the dot + drawObject(p, HorizontalLine, center, r.bottom()-(lineWidth-1), lineWidth, lineWidth); + } else if (r.width() > 8) { + int lineWidth = 2; + + // top bar + drawObject(p, HorizontalLine, center-(side-1), r.y(), 2*side-1, lineWidth); + // top bar rounding + if (r.width() > 9) { + drawObject(p, CrossDiagonalLine, center-side-1, r.y()+3, 3, lineWidth); + } else { + drawObject(p, CrossDiagonalLine, center-side-1, r.y()+2, 3, lineWidth); + } + drawObject(p, DiagonalLine, center+side-1, r.y(), 3, lineWidth); + // right bar + drawObject(p, VerticalLine, center+side+2-lineWidth, r.y()+2, r.height()-(2*lineWidth+side+1), lineWidth); + // bottom bar + drawObject(p, CrossDiagonalLine, center, r.bottom()-2*lineWidth+1, side+2, lineWidth); + // the dot + drawObject(p, HorizontalLine, center, r.bottom()-(lineWidth-1), lineWidth, lineWidth); + } else { + int lineWidth = 1; + + // top bar + drawObject(p, HorizontalLine, center-(side-1), r.y(), 2*side, lineWidth); + // top bar rounding + drawObject(p, CrossDiagonalLine, center-side-1, r.y()+1, 2, lineWidth); + // right bar + drawObject(p, VerticalLine, center+side+1, r.y(), r.height()-(side+2+1), lineWidth); + // bottom bar + drawObject(p, CrossDiagonalLine, center, r.bottom()-2, side+2, lineWidth); + // the dot + drawObject(p, HorizontalLine, center, r.bottom(), 1, 1); + } + + break; + } + + case NotOnAllDesktopsIcon: + { + int lwMark = r.width()-lwTitleBar*2-2; + if (lwMark < 1) + lwMark = 3; + + drawObject(p, HorizontalLine, r.x()+(r.width()-lwMark)/2, r.y()+(r.height()-lwMark)/2, lwMark, lwMark); + + // Fall through to OnAllDesktopsIcon intended! + } + case OnAllDesktopsIcon: + { + // horizontal bars + drawObject(p, HorizontalLine, r.x()+lwTitleBar, r.y(), r.width()-2*lwTitleBar, lwTitleBar); + drawObject(p, HorizontalLine, r.x()+lwTitleBar, r.bottom()-(lwTitleBar-1), r.width()-2*lwTitleBar, lwTitleBar); + // vertical bars + drawObject(p, VerticalLine, r.x(), r.y()+lwTitleBar, r.height()-2*lwTitleBar, lwTitleBar); + drawObject(p, VerticalLine, r.right()-(lwTitleBar-1), r.y()+lwTitleBar, r.height()-2*lwTitleBar, lwTitleBar); + + + break; + } + + case NoKeepAboveIcon: + { + int center = r.x()+r.width()/2; + + // arrow + drawObject(p, CrossDiagonalLine, r.x(), center+2*lwArrow, center-r.x(), lwArrow); + drawObject(p, DiagonalLine, r.x()+center, r.y()+1+2*lwArrow, center-r.x(), lwArrow); + if (lwArrow>1) + drawObject(p, HorizontalLine, center-(lwArrow-2), r.y()+2*lwArrow, (lwArrow-2)*2, lwArrow); + + // Fall through to KeepAboveIcon intended! + } + case KeepAboveIcon: + { + int center = r.x()+r.width()/2; + + // arrow + drawObject(p, CrossDiagonalLine, r.x(), center, center-r.x(), lwArrow); + drawObject(p, DiagonalLine, r.x()+center, r.y()+1, center-r.x(), lwArrow); + if (lwArrow>1) + drawObject(p, HorizontalLine, center-(lwArrow-2), r.y(), (lwArrow-2)*2, lwArrow); + + break; + } + + case NoKeepBelowIcon: + { + int center = r.x()+r.width()/2; + + // arrow + drawObject(p, DiagonalLine, r.x(), center-2*lwArrow, center-r.x(), lwArrow); + drawObject(p, CrossDiagonalLine, r.x()+center, r.bottom()-1-2*lwArrow, center-r.x(), lwArrow); + if (lwArrow>1) + drawObject(p, HorizontalLine, center-(lwArrow-2), r.bottom()-(lwArrow-1)-2*lwArrow, (lwArrow-2)*2, lwArrow); + + // Fall through to KeepBelowIcon intended! + } + case KeepBelowIcon: + { + int center = r.x()+r.width()/2; + + // arrow + drawObject(p, DiagonalLine, r.x(), center, center-r.x(), lwArrow); + drawObject(p, CrossDiagonalLine, r.x()+center, r.bottom()-1, center-r.x(), lwArrow); + if (lwArrow>1) + drawObject(p, HorizontalLine, center-(lwArrow-2), r.bottom()-(lwArrow-1), (lwArrow-2)*2, lwArrow); + + break; + } + + case ShadeIcon: + { + drawObject(p, HorizontalLine, r.x(), r.y(), r.width(), lwTitleBar); + + break; + } + + case UnShadeIcon: + { + int lw1 = 1; + int lw2 = 1; + if (r.width() > 16) { + lw1 = 4; + lw2 = 2; + } else if (r.width() > 7) { + lw1 = 2; + lw2 = 1; + } + + int h = QMAX( (r.width()/2), (lw1+2*lw2) ); + + // horizontal bars + drawObject(p, HorizontalLine, r.x(), r.y(), r.width(), lw1); + drawObject(p, HorizontalLine, r.x(), r.x()+h-(lw2-1), r.width(), lw2); + // vertical bars + drawObject(p, VerticalLine, r.x(), r.y(), h, lw2); + drawObject(p, VerticalLine, r.right()-(lw2-1), r.y(), h, lw2); + + break; + } + + default: + break; + } + + p.end(); + + bitmap.setMask(bitmap); + + return bitmap; +} + +void IconEngine::drawObject(QPainter &p, Object object, int x, int y, int length, int lineWidth) +{ + switch(object) { + case DiagonalLine: + if (lineWidth <= 1) { + for (int i = 0; i < length; ++i) { + p.drawPoint(x+i,y+i); + } + } else if (lineWidth <= 2) { + for (int i = 0; i < length; ++i) { + p.drawPoint(x+i,y+i); + } + for (int i = 0; i < (length-1); ++i) { + p.drawPoint(x+1+i,y+i); + p.drawPoint(x+i,y+1+i); + } + } else { + for (int i = 1; i < (length-1); ++i) { + p.drawPoint(x+i,y+i); + } + for (int i = 0; i < (length-1); ++i) { + p.drawPoint(x+1+i,y+i); + p.drawPoint(x+i,y+1+i); + } + for (int i = 0; i < (length-2); ++i) { + p.drawPoint(x+2+i,y+i); + p.drawPoint(x+i,y+2+i); + } + } + break; + case CrossDiagonalLine: + if (lineWidth <= 1) { + for (int i = 0; i < length; ++i) { + p.drawPoint(x+i,y-i); + } + } else if (lineWidth <= 2) { + for (int i = 0; i < length; ++i) { + p.drawPoint(x+i,y-i); + } + for (int i = 0; i < (length-1); ++i) { + p.drawPoint(x+1+i,y-i); + p.drawPoint(x+i,y-1-i); + } + } else { + for (int i = 1; i < (length-1); ++i) { + p.drawPoint(x+i,y-i); + } + for (int i = 0; i < (length-1); ++i) { + p.drawPoint(x+1+i,y-i); + p.drawPoint(x+i,y-1-i); + } + for (int i = 0; i < (length-2); ++i) { + p.drawPoint(x+2+i,y-i); + p.drawPoint(x+i,y-2-i); + } + } + break; + case HorizontalLine: + for (int i = 0; i < lineWidth; ++i) { + p.drawLine(x,y+i, x+length-1, y+i); + } + break; + case VerticalLine: + for (int i = 0; i < lineWidth; ++i) { + p.drawLine(x+i,y, x+i, y+length-1); + } + break; + default: + break; + } +} + +} // KWinIaOra diff --git a/src/kwin/iaorabutton.h b/src/kwin/iaorabutton.h new file mode 100644 index 0000000..12e9a53 --- /dev/null +++ b/src/kwin/iaorabutton.h @@ -0,0 +1,85 @@ +/* Plastik KWin window decoration + 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. + */ + +#ifndef IAORABUTTON_H +#define IAORABUTTON_H + +#include <qbutton.h> +#include <qimage.h> +#include "iaora.h" + +#include <kcommondecoration.h> + +class QTimer; + +namespace KWinIaOra { + +class IaOraClient; + +class IaOraButton : public KCommonDecorationButton +{ + Q_OBJECT +public: + IaOraButton(ButtonType type, IaOraClient *parent, const char *name); + ~IaOraButton(); + + void reset(unsigned long changed); + IaOraClient * client() { return m_client; } + + +private: + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); + void drawButton(QPainter *painter); + +private: + IaOraClient *m_client; + ButtonIcon m_iconType; + bool hover; +}; + +/** + * This class creates bitmaps which can be used as icons on buttons. The icons + * are "hardcoded". + * Over the previous "Gimp->xpm->QImage->recolor->SmoothScale->QPixmap" solution + * it has the important advantage that icons are more scalable and at the same + * time sharp and not blurred. + */ +class IconEngine +{ + public: + static QBitmap icon(ButtonIcon icon, int size); + + private: + enum Object { + HorizontalLine, + VerticalLine, + DiagonalLine, + CrossDiagonalLine + }; + + static void drawObject(QPainter &p, Object object, int x, int y, int length, int lineWidth); +}; + +} // namespace KWinIaOra + +#endif // IAORABUTTON_H diff --git a/src/kwin/iaoraclient.cpp b/src/kwin/iaoraclient.cpp new file mode 100644 index 0000000..7c1af84 --- /dev/null +++ b/src/kwin/iaoraclient.cpp @@ -0,0 +1,514 @@ +/* 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 <klocale.h> + +#include <qbitmap.h> +#include <qdatetime.h> +#include <qfontmetrics.h> +#include <qimage.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qpainter.h> +#include <qpixmap.h> +#include <qdesktopwidget.h> + +#include "iaoraclient.h" +#include "iaorabutton.h" +#include "misc.h" + +namespace KWinIaOra +{ + +IaOraClient::IaOraClient(KDecorationBridge* bridge, KDecorationFactory* factory) + : KCommonDecoration (bridge, factory), + s_titleFont(QFont() ) +{ + memset(m_captionPixmaps, 0, sizeof(QPixmap*)*2); +} + +IaOraClient::~IaOraClient() +{ + clearCaptionPixmaps(); +} + +QString IaOraClient::visibleName() const +{ + return i18n("Ia Ora"); +} + +QString IaOraClient::defaultButtonsLeft() const +{ + return "M"; +} + +QString IaOraClient::defaultButtonsRight() const +{ + return "IAX"; +} + +bool IaOraClient::decorationBehaviour(DecorationBehaviour behaviour) const +{ + switch (behaviour) { + case DB_MenuClose: + return Handler()->menuClose(); + + case DB_WindowMask: + return true; + + default: + return KCommonDecoration::decorationBehaviour(behaviour); + } +} + +int IaOraClient::layoutMetric(LayoutMetric lm, bool respectWindowState, const KCommonDecorationButton *btn) const +{ + bool maximized = maximizeMode()==MaximizeFull && !options()->moveResizeMaximizedWindows(); + + switch (lm) { + case LM_BorderLeft: + case LM_BorderRight: + case LM_BorderBottom: + { + if (respectWindowState && maximized) { + return 0; + } else { + return 3; + } + } + + case LM_TitleEdgeTop: + { + if (respectWindowState && maximized) { + return 0; + } else { + return 3; + } + } + + case LM_TitleEdgeBottom: + { + if (respectWindowState && maximized) { + return 1; + } else { + return 2; + } + } + + case LM_TitleEdgeLeft: + case LM_TitleEdgeRight: + { + //if (respectWindowState && maximized) { + return 1; + //} else { + //return 3; + //} + } + + case LM_TitleBorderLeft: + case LM_TitleBorderRight: + return 0; + + case LM_ButtonWidth: + case LM_ButtonHeight: + case LM_TitleHeight: + { + if (respectWindowState && isToolWindow()) { + return Handler()->titleHeightTool(); + } else { + return Handler()->titleHeight(); + } + } + + case LM_ButtonSpacing: + return 1; + + case LM_ButtonMarginTop: + return 0; + + case LM_ExplicitButtonSpacer: + return 3; + + default: + return KCommonDecoration::layoutMetric(lm, respectWindowState, btn); + } +} + +KCommonDecorationButton *IaOraClient::createButton(ButtonType type) +{ + switch (type) { + case MenuButton: + return new IaOraButton(MenuButton, this, "menu"); + + case OnAllDesktopsButton: + return new IaOraButton(OnAllDesktopsButton, this, "on_all_desktops"); + + case HelpButton: + return new IaOraButton(HelpButton, this, "help"); + + case MinButton: + return new IaOraButton(MinButton, this, "minimize"); + + case MaxButton: + return new IaOraButton(MaxButton, this, "maximize"); + + case CloseButton: + return new IaOraButton(CloseButton, this, "close"); + + case AboveButton: + return new IaOraButton(AboveButton, this, "above"); + + case BelowButton: + return new IaOraButton(BelowButton, this, "below"); + + case ShadeButton: + return new IaOraButton(ShadeButton, this, "shade"); + + default: + return 0; + } +} + +void IaOraClient::init() +{ + s_titleFont = isToolWindow() ? Handler()->titleFontTool() : Handler()->titleFont(); + + clearCaptionPixmaps(); + + KCommonDecoration::init(); +} + +QRegion IaOraClient::cornerShape(WindowCorner corner) +{ + int w = widget()->width(); + int h = widget()->height(); + + switch (corner) { + case WC_TopLeft: + if (layoutMetric(LM_TitleEdgeLeft) > 0) + return QRegion(0, 0, 1, 1);// + QRegion(1, 0, 1, 1); + else + return QRegion(); + + case WC_TopRight: + if (layoutMetric(LM_TitleEdgeRight) > 0) + return QRegion(w-1, 0, 1, 1);// + QRegion(w-2, 0, 1, 1); + else + return QRegion(); + + case WC_BottomLeft: + if (layoutMetric(LM_BorderBottom) > 0) + return QRegion(0, h-1, 1, 1); + else + return QRegion(); + + case WC_BottomRight: + if (layoutMetric(LM_BorderBottom) > 0) + return QRegion(w-1, h-1, 1, 1); + else + return QRegion(); + + default: + return QRegion(); + } + +} + +void IaOraClient::paintEvent(QPaintEvent *e) +{ + QRegion region = e->region(); + + IaOraHandler *handler = Handler(); + + if (oldCaption != caption() ) + clearCaptionPixmaps(); + + bool active = isActive(); + bool toolWindow = isToolWindow(); + + QPainter painter(widget() ); + + // often needed coordinates + QRect r = widget()->rect(); + + int r_w = r.width(); +// int r_h = r.height(); + int r_x, r_y, r_x2, r_y2; + r.coords(&r_x, &r_y, &r_x2, &r_y2); + const int borderLeft = layoutMetric(LM_BorderLeft); + const int borderRight = layoutMetric(LM_BorderRight); + const int borderBottom = layoutMetric(LM_BorderBottom); + const int titleHeight = layoutMetric(LM_TitleHeight); + const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop); + const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom); + const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft); + const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight); + + const int borderBottomTop = r_y2-borderBottom+1; + const int borderLeftRight = r_x+borderLeft-1; + const int borderRightLeft = r_x2-borderRight+1; + const int titleEdgeBottomBottom = r_y+titleEdgeTop+titleHeight+titleEdgeBottom-1; + + const int sideHeight = borderBottomTop-titleEdgeBottomBottom-1; + + QRect Rtitle = QRect(r_x+titleEdgeLeft+buttonsLeftWidth(), r_y+titleEdgeTop, + r_x2-titleEdgeRight-buttonsRightWidth()-(r_x+titleEdgeLeft+buttonsLeftWidth()), + titleEdgeBottomBottom-(r_y+titleEdgeTop) ); + + QRect tempRect; + + // topSpacer + if(titleEdgeTop > 0) + { + tempRect.setRect(r_x+2, r_y, r_w-2*2, titleEdgeTop ); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(TitleBarTileTop, active, toolWindow) ); + } + } + + // leftTitleSpacer + int titleMarginLeft = 0; + int titleMarginRight = 0; + if(titleEdgeLeft > 0) + { + tempRect.setRect(r_x, r_y, borderLeft, titleEdgeTop+titleHeight+titleEdgeBottom); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(TitleBarLeft, active, toolWindow) ); + titleMarginLeft = borderLeft; + } + } + + // rightTitleSpacer + if(titleEdgeRight > 0) + { + tempRect.setRect(borderRightLeft, r_y, borderRight, titleEdgeTop+titleHeight+titleEdgeBottom); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(TitleBarRight, active, toolWindow) ); + titleMarginRight = borderRight; + } + } + + // titleSpacer + const QPixmap &caption = captionPixmap(); + if(Rtitle.width() > 0) + { + m_captionRect = captionRect(); // also update m_captionRect! + if (m_captionRect.isValid() && region.contains(m_captionRect) ) + { + painter.drawTiledPixmap(m_captionRect, caption); + } + + // left to the title + tempRect.setRect(r_x+titleMarginLeft, m_captionRect.top(), + m_captionRect.left() - (r_x+titleMarginLeft), m_captionRect.height() ); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(TitleBarTile, active, toolWindow) ); + } + + // right to the title + tempRect.setRect(m_captionRect.right()+1, m_captionRect.top(), + (r_x2-titleMarginRight) - m_captionRect.right(), m_captionRect.height() ); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(TitleBarTile, active, toolWindow) ); + } + + } + + // leftSpacer + if(borderLeft > 0 && sideHeight > 0) + { + tempRect.setCoords(r_x, titleEdgeBottomBottom+1, borderLeftRight, borderBottomTop-1); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(BorderLeftTile, active, toolWindow) ); + } + } + + // rightSpacer + if(borderRight > 0 && sideHeight > 0) + { + tempRect.setCoords(borderRightLeft, titleEdgeBottomBottom+1, r_x2, borderBottomTop-1); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(BorderRightTile, active, toolWindow) ); + } + } + + // bottomSpacer + if(borderBottom > 0) + { + int l = r_x; + int r = r_x2; + + tempRect.setRect(r_x, borderBottomTop, borderLeft, borderBottom); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(BorderBottomLeft, active, toolWindow) ); + l = tempRect.right()+1; + } + + tempRect.setRect(borderRightLeft, borderBottomTop, borderLeft, borderBottom); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(BorderBottomRight, active, toolWindow) ); + r = tempRect.left()-1; + } + + tempRect.setCoords(l, borderBottomTop, r, r_y2); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(BorderBottomTile, active, toolWindow) ); + } + } +} + +QRect IaOraClient::captionRect() const +{ + const QPixmap &caption = captionPixmap(); + QRect r = widget()->rect(); + + const int titleHeight = layoutMetric(LM_TitleHeight); + const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom); + const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop); + const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft); + const int marginLeft = layoutMetric(LM_TitleBorderLeft); + const int marginRight = layoutMetric(LM_TitleBorderRight); + + const int titleLeft = r.left() + titleEdgeLeft + buttonsLeftWidth() + marginLeft; + const int titleWidth = r.width() - + titleEdgeLeft - layoutMetric(LM_TitleEdgeRight) - + buttonsLeftWidth() - buttonsRightWidth() - + marginLeft - marginRight; + int tX, tW; // position/width of the title buffer + if (caption.width() > titleWidth) { + tW = titleWidth; + } else { + tW = caption.width(); + } + + if (caption.width() > titleWidth ) { + // Align left + tX = titleLeft; + } + else + tX = titleLeft+(titleWidth- caption.width() )/2; + return QRect(tX, r.top()+titleEdgeTop, tW, titleHeight+titleEdgeBottom); +} + +void IaOraClient::updateCaption() +{ + QRect oldCaptionRect = m_captionRect; + + if (oldCaption != caption() ) + clearCaptionPixmaps(); + + m_captionRect = IaOraClient::captionRect(); + + if (oldCaptionRect.isValid() && m_captionRect.isValid() ) + widget()->update(oldCaptionRect|m_captionRect); + else + widget()->update(); +} + +void IaOraClient::reset( unsigned long changed ) +{ + if (changed & SettingColors) + { + // repaint the whole thing + clearCaptionPixmaps(); + widget()->update(); + updateButtons(); + } else if (changed & SettingFont) { + // font has changed -- update title height and font + s_titleFont = isToolWindow() ? Handler()->titleFontTool() : Handler()->titleFont(); + + updateLayout(); + + // then repaint + clearCaptionPixmaps(); + widget()->update(); + } + + KCommonDecoration::reset(changed); +} + +const QPixmap &IaOraClient::getTitleBarTile(bool active) const +{ + return Handler()->pixmap(TitleBarTile, active, isToolWindow() ); +} + +const QPixmap &IaOraClient::captionPixmap() const +{ + bool active = isActive(); + + if (m_captionPixmaps[active]) { + return *m_captionPixmaps[active]; + } + + // not found, create new pixmap... + + const uint maxCaptionLength = 300; // truncate captions longer than this! + QString c(caption() ); + if (c.length() > maxCaptionLength) { + c.truncate(maxCaptionLength); + c.append(" [...]"); + } + + QFontMetrics fm(s_titleFont); + int captionWidth = fm.width(c); + int captionHeight = fm.height(); + + const int th = layoutMetric(LM_TitleHeight, false) + layoutMetric(LM_TitleEdgeBottom, false); + + QPainter painter; + + const int thickness = 2; + + QPixmap *captionPixmap = new QPixmap(captionWidth+2*thickness, th); + + painter.begin(captionPixmap); + painter.drawTiledPixmap(captionPixmap->rect(), + Handler()->pixmap(TitleBarTile, active, isToolWindow()) ); + + painter.setFont(s_titleFont); + QPoint tp(1, captionHeight-1); +// if(Handler()->titleShadow()) +// { +// painter.setPen(Handler()->getShadowColor()); +// painter.drawText(tp+QPoint(2,2), c); +// } + painter.setPen(Handler()->getColor(TitleFont,active) ); + painter.drawText(tp, c ); + painter.end(); + + m_captionPixmaps[active] = captionPixmap; + return *captionPixmap; +} + +void IaOraClient::clearCaptionPixmaps() +{ + for (int i = 0; i < 2; ++i) { + delete m_captionPixmaps[i]; + m_captionPixmaps[i] = 0; + } + + oldCaption = caption(); +} + +} // KWinIaOra diff --git a/src/kwin/iaoraclient.h b/src/kwin/iaoraclient.h new file mode 100644 index 0000000..5c66194 --- /dev/null +++ b/src/kwin/iaoraclient.h @@ -0,0 +1,73 @@ +/* Plastik KWin window decoration + 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. + */ + +#ifndef IAORACLIENT_H +#define IAORACLIENT_H + +#include <kcommondecoration.h> + +#include "iaora.h" + +namespace KWinIaOra { + +class IaOraButton; + +class IaOraClient : public KCommonDecoration +{ +public: + IaOraClient(KDecorationBridge* bridge, KDecorationFactory* factory); + ~IaOraClient(); + + virtual QString visibleName() const; + virtual QString defaultButtonsLeft() const; + virtual QString defaultButtonsRight() const; + virtual bool decorationBehaviour(DecorationBehaviour behaviour) const; + virtual int layoutMetric(LayoutMetric lm, bool respectWindowState = true, const KCommonDecorationButton * = 0) const; + virtual QRegion cornerShape(WindowCorner corner); + virtual KCommonDecorationButton *createButton(ButtonType type); + + virtual void init(); + virtual void reset( unsigned long changed ); + + virtual void paintEvent(QPaintEvent *e); + virtual void updateCaption(); + + const QPixmap &getTitleBarTile(bool active) const; + +private: + QRect captionRect() const; + + const QPixmap &captionPixmap() const; + void clearCaptionPixmaps(); + + mutable QPixmap *m_captionPixmaps[2]; + + QRect m_captionRect; + QString oldCaption; + + // settings... + QFont s_titleFont; +}; + +} // KwinIaora + +#endif // IAORACLIENT_H diff --git a/src/kwin/misc.cpp b/src/kwin/misc.cpp new file mode 100644 index 0000000..f050975 --- /dev/null +++ b/src/kwin/misc.cpp @@ -0,0 +1,49 @@ +/* Plastik KWin window decoration + Copyright (C) 2003 Sandro Giessl <ceebx@users.sourceforge.net> + + 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 <kpixmap.h> +#include <kpixmapeffect.h> + +#include <qcolor.h> +#include <qimage.h> +#include <qpainter.h> + +#include "misc.h" + +QColor alphaBlendColors(const QColor &bgColor, const QColor &fgColor, const int a) +{ + + // normal button... + QRgb rgb = bgColor.rgb(); + QRgb rgb_b = fgColor.rgb(); + int alpha = a; + if(alpha>255) alpha = 255; + if(alpha<0) alpha = 0; + int inv_alpha = 255 - alpha; + + QColor result = QColor( qRgb(qRed(rgb_b)*inv_alpha/255 + qRed(rgb)*alpha/255, + qGreen(rgb_b)*inv_alpha/255 + qGreen(rgb)*alpha/255, + qBlue(rgb_b)*inv_alpha/255 + qBlue(rgb)*alpha/255) ); + + return result; +} + diff --git a/src/kwin/misc.h b/src/kwin/misc.h new file mode 100644 index 0000000..b304513 --- /dev/null +++ b/src/kwin/misc.h @@ -0,0 +1,28 @@ +/* Plastik KWin window decoration + Copyright (C) 2003 Sandro Giessl <ceebx@users.sourceforge.net> + + 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. + */ + +#ifndef MISC_H +#define MISC_H + +QColor alphaBlendColors(const QColor &backgroundColor, const QColor &foregroundColor, const int alpha); + +#endif // MISC_H |