summaryrefslogtreecommitdiffstats
path: root/src/kwin/iaoraclient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/kwin/iaoraclient.cpp')
-rw-r--r--src/kwin/iaoraclient.cpp514
1 files changed, 514 insertions, 0 deletions
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