diff options
Diffstat (limited to 'kwin/clients/keramik/keramik.cpp')
-rw-r--r-- | kwin/clients/keramik/keramik.cpp | 1854 |
1 files changed, 0 insertions, 1854 deletions
diff --git a/kwin/clients/keramik/keramik.cpp b/kwin/clients/keramik/keramik.cpp deleted file mode 100644 index e514e3a20..000000000 --- a/kwin/clients/keramik/keramik.cpp +++ /dev/null @@ -1,1854 +0,0 @@ -/* - * - * Keramik KWin client (version 0.8) - * - * Copyright (C) 2002 Fredrik H�lund <[email protected]> - * - * 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 <kconfig.h> -#include <klocale.h> -#include <kiconeffect.h> - -#include <tqpainter.h> -#include <tqlayout.h> -#include <tqbitmap.h> -#include <tqstyle.h> -#include <tqtooltip.h> -#include <tqwidget.h> -#include <tqlabel.h> - -#include <X11/Xlib.h> -#include <X11/Xatom.h> - -#include "keramik.h" -#include "keramik.moc" - - - -// ------------------------------------------------------------------------------------------- - -static void flip( TQPixmap *&pix ) -{ - TQPixmap *tmp = new TQPixmap( pix->xForm( TQWMatrix(-1,0,0,1,pix->width(),0) ) ); - delete pix; - pix = tmp; -} - -static void flip( TQBitmap *&pix ) -{ - TQBitmap *tmp = new TQBitmap( pix->xForm( TQWMatrix(-1,0,0,1,pix->width(),0) ) ); - delete pix; - pix = tmp; -} - -namespace Keramik -{ - - const int buttonMargin = 9; // Margin between the window edge and the buttons - const int buttonSpacing = 4; // Spacing between the titlebar buttons - const int iconSpacing = 5; // Spacing between the icon and the text label - - // Default button layout - const char default_left[] = "M"; - const char default_right[] = "HIAX"; - - // Titlebar button bitmaps - const unsigned char menu_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0xf0, 0x07, 0x00, - 0xe0, 0x03, 0x00, 0xc0, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00}; - - const unsigned char on_all_desktops_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0xf0, 0x0f, 0x00, - 0xf0, 0x0f, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00}; - - const unsigned char not_on_all_desktops_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, - 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00}; - - const unsigned char help_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, - 0xf0, 0x07, 0x00, 0x30, 0x06, 0x00, 0x00, 0x07, 0x00, 0x80, 0x03, 0x00, - 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00}; - - const unsigned char minimize_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00}; - - const unsigned char maximize_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x01, 0x00, 0xc0, 0x03, 0x00, 0xe0, 0x07, 0x00, 0xf0, 0x0f, 0x00, - 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00}; - - const unsigned char restore_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, - 0xf0, 0x0f, 0x00, 0xe0, 0x07, 0x00, 0xc0, 0x03, 0x00, 0x80, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00}; - - const unsigned char close_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x0c, 0x00, 0x70, 0x0e, 0x00, 0xe0, 0x07, 0x00, 0xc0, 0x03, 0x00, - 0xc0, 0x03, 0x00, 0xe0, 0x07, 0x00, 0x70, 0x0e, 0x00, 0x30, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00}; - - const unsigned char above_on_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, - 0x80, 0x01, 0x00, 0xe0, 0x07, 0x00, 0xc0, 0x03, 0x00, 0x80, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 }; - - const unsigned char above_off_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xc0, 0x03, 0x00, - 0xe0, 0x07, 0x00, 0x80, 0x01, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 }; - - const unsigned char below_on_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xc0, 0x03, 0x00, - 0xe0, 0x07, 0x00, 0x80, 0x01, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 }; - - const unsigned char below_off_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, - 0x80, 0x01, 0x00, 0xe0, 0x07, 0x00, 0xc0, 0x03, 0x00, 0x80, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 }; - - const unsigned char shade_on_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, - 0x10, 0x08, 0x00, 0x10, 0x08, 0x00, 0x10, 0x08, 0x00, 0x10, 0x08, 0x00, - 0x10, 0x08, 0x00, 0x10, 0x08, 0x00, 0x10, 0x08, 0x00, 0xf0, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 }; - - const unsigned char shade_off_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 }; - - KeramikHandler *clientHandler = NULL; - bool keramik_initialized = false; - - - -// ------------------------------------------------------------------------------------------- - - - -KeramikHandler::KeramikHandler() -{ - for ( int i = 0; i < NumTiles; i++ ) { - activeTiles[i] = NULL; - inactiveTiles[i] = NULL; - } - - settings_cache = NULL; - - imageDb = KeramikImageDb::instance(); - - // Create the button deco bitmaps - buttonDecos[ Menu ] = new TQBitmap( 17, 17, menu_bits, true ); - buttonDecos[ OnAllDesktops ] = new TQBitmap( 17, 17, on_all_desktops_bits, true ); - buttonDecos[ NotOnAllDesktops ] = new TQBitmap( 17, 17, not_on_all_desktops_bits, true ); - buttonDecos[ Help ] = new TQBitmap( 17, 17, help_bits, true ); - buttonDecos[ Minimize ] = new TQBitmap( 17, 17, minimize_bits, true ); - buttonDecos[ Maximize ] = new TQBitmap( 17, 17, maximize_bits, true ); - buttonDecos[ Restore ] = new TQBitmap( 17, 17, restore_bits, true ); - buttonDecos[ Close ] = new TQBitmap( 17, 17, close_bits, true ); - buttonDecos[ AboveOn ] = new TQBitmap( 17, 17, above_on_bits, true ); - buttonDecos[ AboveOff ] = new TQBitmap( 17, 17, above_off_bits, true ); - buttonDecos[ BelowOn ] = new TQBitmap( 17, 17, below_on_bits, true ); - buttonDecos[ BelowOff ] = new TQBitmap( 17, 17, below_off_bits, true ); - buttonDecos[ ShadeOn ] = new TQBitmap( 17, 17, shade_on_bits, true ); - buttonDecos[ ShadeOff ] = new TQBitmap( 17, 17, shade_off_bits, true ); - - // Selfmask the bitmaps - for ( int i = 0; i < NumButtonDecos; i++ ) - buttonDecos[i]->setMask( *buttonDecos[i] ); - - // Flip the bitmaps horizontally in right-to-left mode - if ( TQApplication::reverseLayout() ) { - for ( int i = 0; i < Help; ++i ) - ::flip( buttonDecos[i] ); - - for ( int i = Help + 1; i < NumButtonDecos; ++i ) - ::flip( buttonDecos[i] ); - } - - readConfig(); - createPixmaps(); - - keramik_initialized = true; -} - - -KeramikHandler::~KeramikHandler() -{ - keramik_initialized = false; - destroyPixmaps(); - - for ( int i = 0; i < NumButtonDecos; i++ ) - delete buttonDecos[i]; - - delete settings_cache; - - KeramikImageDb::release(); - imageDb = NULL; - clientHandler = NULL; -} - - -void KeramikHandler::createPixmaps() -{ - int heightOffset; - int widthOffset; - switch(options()->preferredBorderSize(this)) { - case BorderLarge: - widthOffset = 4; - heightOffset = 0; - break; - case BorderVeryLarge: - widthOffset = 8; - heightOffset = 0; - break; - case BorderHuge: - widthOffset = 14; - heightOffset = 0; - break; - case BorderVeryHuge: - widthOffset = 23; - heightOffset = 10; - break; - case BorderOversized: - widthOffset = 36; - heightOffset = 25; - break; - case BorderTiny: - case BorderNormal: - default: - widthOffset = 0; - heightOffset = 0; - } - int fontHeight = TQFontMetrics(options()->font(true)).height(); - if (fontHeight > heightOffset + 20) - heightOffset = fontHeight - 20; - - TQString size = (heightOffset < 8) ? "" : (heightOffset < 20) ? "-large" : "-huge"; - - TQColor titleColor, captionColor, buttonColor; - TQImage *titleCenter = NULL, *captionLeft = NULL, - *captionRight = NULL, *captionCenter = NULL; - - - // Active tiles - // ------------------------------------------------------------------------- - captionColor = KDecoration::options()->color( ColorTitleBar, true ); - titleColor = KDecoration::options()->color( ColorTitleBlend, true ); - - // Load the titlebar corners. - activeTiles[ TitleLeft ] = loadPixmap( "titlebar-left", titleColor ); - activeTiles[ TitleRight ] = loadPixmap( "titlebar-right", titleColor ); - - // Load the titlebar center tile image (this will be used as - // the background for the caption bubble tiles). - titleCenter = loadImage( "titlebar-center", titleColor ); - - // Load the small version of the caption bubble corner & center images. - captionLeft = loadImage( "caption-small-left", captionColor ); - captionRight = loadImage( "caption-small-right", captionColor ); - captionCenter = loadImage( "caption-small-center", captionColor ); - - // Create the caption bubble tiles (by blending the images onto the titlebar) - activeTiles[ CaptionSmallLeft ] = composite( captionLeft, titleCenter ); - activeTiles[ CaptionSmallRight ] = composite( captionRight, titleCenter ); - activeTiles[ CaptionSmallCenter ] = composite( captionCenter, titleCenter ); - - delete captionLeft; - delete captionRight; - delete captionCenter; - - // Now do the same with the large version - captionLeft = loadImage( "caption-large-left", captionColor ); - captionRight = loadImage( "caption-large-right", captionColor ); - captionCenter = loadImage( "caption-large-center", captionColor ); - - activeTiles[ CaptionLargeLeft ] = composite( captionLeft, titleCenter ); - activeTiles[ CaptionLargeRight ] = composite( captionRight, titleCenter ); - activeTiles[ CaptionLargeCenter ] = composite( captionCenter, titleCenter ); - - delete captionLeft; - delete captionRight; - delete captionCenter; - - // Create the titlebar center tile - activeTiles[ TitleCenter ] = new TQPixmap( *titleCenter ); - - delete titleCenter; - - // Load the left & right border pixmaps - activeTiles[ BorderLeft ] = loadPixmap( "border-left", titleColor ); - activeTiles[ BorderRight ] = loadPixmap( "border-right", titleColor ); - - // Load the bottom grabbar pixmaps - if ( largeGrabBars ) { - activeTiles[ GrabBarLeft ] = loadPixmap( "grabbar-left", titleColor ); - activeTiles[ GrabBarRight ] = loadPixmap( "grabbar-right", titleColor ); - activeTiles[ GrabBarCenter ] = loadPixmap( "grabbar-center", titleColor ); - } else { - activeTiles[ GrabBarLeft ] = loadPixmap( "bottom-left", titleColor ); - activeTiles[ GrabBarRight ] = loadPixmap( "bottom-right", titleColor ); - activeTiles[ GrabBarCenter ] = loadPixmap( "bottom-center", titleColor ); - } - - // Inactive tiles - // ------------------------------------------------------------------------- - captionColor = KDecoration::options()->color( ColorTitleBar, false ); - titleColor = KDecoration::options()->color( ColorTitleBlend, false ); - - inactiveTiles[ TitleLeft ] = loadPixmap( "titlebar-left", titleColor ); - inactiveTiles[ TitleRight ] = loadPixmap( "titlebar-right", titleColor ); - - titleCenter = loadImage( "titlebar-center", titleColor ); - - captionLeft = loadImage( "caption-small-left", captionColor ); - captionRight = loadImage( "caption-small-right", captionColor ); - captionCenter = loadImage( "caption-small-center", captionColor ); - - inactiveTiles[ CaptionSmallLeft ] = composite( captionLeft, titleCenter ); - inactiveTiles[ CaptionSmallRight ] = composite( captionRight, titleCenter ); - inactiveTiles[ CaptionSmallCenter ] = composite( captionCenter, titleCenter ); - - delete captionLeft; - delete captionRight; - delete captionCenter; - - inactiveTiles[ TitleCenter ] = new TQPixmap( *titleCenter ); - - delete titleCenter; - - inactiveTiles[ BorderLeft ] = loadPixmap( "border-left", titleColor ); - inactiveTiles[ BorderRight ] = loadPixmap( "border-right", titleColor ); - - if ( largeGrabBars ) { - inactiveTiles[ GrabBarLeft ] = loadPixmap( "grabbar-left", titleColor ); - inactiveTiles[ GrabBarRight ] = loadPixmap( "grabbar-right", titleColor ); - inactiveTiles[ GrabBarCenter ] = loadPixmap( "grabbar-center", titleColor ); - } else { - inactiveTiles[ GrabBarLeft ] = loadPixmap( "bottom-left", titleColor ); - inactiveTiles[ GrabBarRight ] = loadPixmap( "bottom-right", titleColor ); - inactiveTiles[ GrabBarCenter ] = loadPixmap( "bottom-center", titleColor ); - } - - // Buttons - // ------------------------------------------------------------------------- - buttonColor = TQColor(); //KDecoration::options()->color( ButtonBg, true ); - - titleButtonRound = loadPixmap( "titlebutton-round"+size, buttonColor ); - titleButtonSquare = loadPixmap( "titlebutton-square"+size, buttonColor ); - - - // Prepare the tiles for use - // ------------------------------------------------------------------------- - if ( TQApplication::reverseLayout() ) { - - // Fix lighting - flip( activeTiles[CaptionSmallLeft], activeTiles[CaptionSmallRight] ); - flip( inactiveTiles[CaptionSmallLeft], inactiveTiles[CaptionSmallRight] ); - - flip( activeTiles[CaptionLargeLeft], activeTiles[CaptionLargeRight] ); - - flip( activeTiles[TitleLeft], activeTiles[TitleRight] ); - flip( inactiveTiles[TitleLeft], inactiveTiles[TitleRight] ); - - flip( activeTiles[BorderLeft], activeTiles[BorderRight] ); - flip( inactiveTiles[BorderLeft], inactiveTiles[BorderRight] ); - - flip( activeTiles[GrabBarLeft], activeTiles[GrabBarRight] ); - flip( inactiveTiles[GrabBarLeft], inactiveTiles[GrabBarRight] ); - - ::flip( titleButtonRound ); - ::flip( titleButtonSquare ); - } - - // Pretile the center & border tiles for optimal performance - pretile( activeTiles[ CaptionSmallCenter ], 64, Qt::Horizontal ); - pretile( activeTiles[ CaptionLargeCenter ], 64, Qt::Horizontal ); - pretile( activeTiles[ TitleCenter ], 64, Qt::Horizontal ); - pretile( activeTiles[ GrabBarCenter ], 128, Qt::Horizontal ); - pretile( activeTiles[ BorderLeft ], 128, Qt::Vertical ); - pretile( activeTiles[ BorderRight ], 128, Qt::Vertical ); - - pretile( inactiveTiles[ CaptionSmallCenter ], 64, Qt::Horizontal ); - pretile( inactiveTiles[ TitleCenter ], 64, Qt::Horizontal ); - pretile( inactiveTiles[ GrabBarCenter ], 128, Qt::Horizontal ); - pretile( inactiveTiles[ BorderLeft ], 128, Qt::Vertical ); - pretile( inactiveTiles[ BorderRight ], 128, Qt::Vertical ); - - if (heightOffset > 0) { - addHeight (heightOffset, activeTiles[TitleLeft]); - addHeight (heightOffset, activeTiles[TitleCenter]); - addHeight (heightOffset, activeTiles[TitleRight]); - addHeight (heightOffset, activeTiles[CaptionSmallLeft]); - addHeight (heightOffset, activeTiles[CaptionSmallCenter]); - addHeight (heightOffset, activeTiles[CaptionSmallRight]); - addHeight (heightOffset, activeTiles[CaptionLargeLeft]); - addHeight (heightOffset, activeTiles[CaptionLargeCenter]); - addHeight (heightOffset, activeTiles[CaptionLargeRight]); - - addHeight (heightOffset, inactiveTiles[TitleLeft]); - addHeight (heightOffset, inactiveTiles[TitleCenter]); - addHeight (heightOffset, inactiveTiles[TitleRight]); - addHeight (heightOffset, inactiveTiles[CaptionSmallLeft]); - addHeight (heightOffset, inactiveTiles[CaptionSmallCenter]); - addHeight (heightOffset, inactiveTiles[CaptionSmallRight]); - } - - if (widthOffset > 0) { - addWidth (widthOffset, activeTiles[BorderLeft], true, activeTiles[GrabBarCenter]); - addWidth (widthOffset, activeTiles[BorderRight], false, activeTiles[GrabBarCenter]); - addWidth (widthOffset, inactiveTiles[BorderLeft], true, inactiveTiles[GrabBarCenter]); - addWidth (widthOffset, inactiveTiles[BorderRight], false, inactiveTiles[GrabBarCenter]); - - if (largeGrabBars) - widthOffset = widthOffset*3/2; - - addHeight (widthOffset, activeTiles[GrabBarLeft]); - addHeight (widthOffset, activeTiles[GrabBarCenter]); - addHeight (widthOffset, activeTiles[GrabBarRight]); - addHeight (widthOffset, inactiveTiles[GrabBarLeft]); - addHeight (widthOffset, inactiveTiles[GrabBarCenter]); - addHeight (widthOffset, inactiveTiles[GrabBarRight]); - } -} - - - -void KeramikHandler::destroyPixmaps() -{ - for ( int i = 0; i < NumTiles; i++ ) { - delete activeTiles[i]; - delete inactiveTiles[i]; - activeTiles[i] = NULL; - inactiveTiles[i] = NULL; - } - - delete titleButtonRound; - delete titleButtonSquare; -} - - -void KeramikHandler::addWidth (int width, TQPixmap *&pix, bool left, TQPixmap *bottomPix) { - int w = pix->width()+width; - int h = pix->height(); - - TQPixmap *tmp = new TQPixmap (w, h); - tmp->fill (); - TQPainter p; - p.begin (tmp); - - for (int i = 0; i < h; i++) - p.drawPixmap (0, i, *bottomPix, i%2, 0, w,1); - - if (left) - p.drawPixmap(0, 0, *pix); - else - p.drawPixmap(width, 0, *pix); - - p.end(); - - delete pix; - pix = tmp; -} - - -void KeramikHandler::addHeight (int height, TQPixmap *&pix) { - int w = pix->width(); - int h = pix->height()+height; - - TQPixmap *tmp = new TQPixmap (w, h); - TQPainter p; - p.begin (tmp); - if (pix->height() > 10) { - p.drawPixmap(0, 0, *pix, 0, 0, w, 11); - for (int i = 0; i < height; i+=2) - p.drawPixmap(0, 11+i, *pix, 0, 11, w, 2); - p.drawPixmap(0, 11+height, *pix, 0, 11, w, -1); - } - else { - int lines = h-3; - int factor = pix->height()-3; - for (int i = 0; i < lines; i++) - p.drawPixmap(0, i, *pix, 0, i*factor/lines, w, 1); - p.drawPixmap(0, lines, *pix, 0, factor, w, 3); - } - p.end(); - - delete pix; - pix = tmp; -} - - -void KeramikHandler::flip( TQPixmap *&pix1, TQPixmap *&pix2 ) -{ - // Flip the pixmaps horizontally - TQPixmap *tmp = new TQPixmap( pix1->xForm( TQWMatrix(-1,0,0,1,pix1->width(),0) ) ); - - delete pix1; - pix1 = new TQPixmap( pix2->xForm( TQWMatrix(-1,0,0,1,pix2->width(),0) ) ); - - delete pix2; - pix2 = tmp; -} - - -void KeramikHandler::pretile( TQPixmap *&pix, int size, Qt::Orientation dir ) -{ - TQPixmap *newpix; - TQPainter p; - - if ( dir == Qt::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; -} - - -void KeramikHandler::readConfig() -{ - KConfig *c = new KConfig( "twinkeramikrc" ); - - c->setGroup( "General" ); - showIcons = c->readBoolEntry( "ShowAppIcons", true ); - shadowedText = c->readBoolEntry( "UseShadowedText", true ); - smallCaptionBubbles = c->readBoolEntry( "SmallCaptionBubbles", false ); - largeGrabBars = c->readBoolEntry( "LargeGrabBars", true ); - - if ( ! settings_cache ) { - settings_cache = new SettingsCache; - settings_cache->largeGrabBars = largeGrabBars; - settings_cache->smallCaptionBubbles = smallCaptionBubbles; - } - - delete c; -} - - -TQPixmap *KeramikHandler::composite( TQImage *over, TQImage *under ) -{ - TQImage dest( over->width(), over->height(), 32 ); - int width = over->width(), height = over->height(); - - // Clear the destination image - TQ_UINT32 *data = reinterpret_cast<TQ_UINT32*>( dest.bits() ); - for (int i = 0; i < width * height; i++) - *(data++) = 0; - - // Copy the under image (bottom aligned) to the destination image - for (int y1 = height - under->height(), y2 = 0; y1 < height; y1++, y2++ ) - { - register TQ_UINT32 *dst = reinterpret_cast<TQ_UINT32*>( dest.scanLine(y1) ); - register TQ_UINT32 *src = reinterpret_cast<TQ_UINT32*>( under->scanLine(y2) ); - - for ( int x = 0; x < width; x++ ) - *(dst++) = *(src++); - } - - // Blend the over image onto the destination - register TQ_UINT32 *dst = reinterpret_cast<TQ_UINT32*>( dest.bits() ); - register TQ_UINT32 *src = reinterpret_cast<TQ_UINT32*>( over->bits() ); - for ( int i = 0; i < width * height; i++ ) - { - int r1 = tqRed( *dst ), g1 = tqGreen( *dst ), b1 = tqBlue( *dst ); - int r2 = tqRed( *src ), g2 = tqGreen( *src ), b2 = tqBlue( *src ); - int a = tqAlpha( *src ); - - if ( a == 0xff ) - *dst = *src; - - else if ( a != 0x00 ) - *dst = tqRgba( TQ_UINT8( r1 + (((r2 - r1) * a) >> 8) ), - TQ_UINT8( g1 + (((g2 - g1) * a) >> 8) ), - TQ_UINT8( b1 + (((b2 - b1) * a) >> 8) ), - 0xff ); - - else if ( tqAlpha(*dst) == 0x00 ) - *dst = 0; - - src++; dst++; - } - - // Create the final pixmap and return it - return new TQPixmap( dest ); -} - - -TQImage *KeramikHandler::loadImage( const TQString &name, const TQColor &col ) -{ - if ( col.isValid() ) { - TQImage *img = new TQImage( imageDb->image(name)->copy() ); - KIconEffect::colorize( *img, col, 1.0 ); - return img; - } else - return new TQImage( imageDb->image(name)->copy() ); -} - - -TQPixmap *KeramikHandler::loadPixmap( const TQString &name, const TQColor &col ) -{ - TQImage *img = loadImage( name, col ); - TQPixmap *pix = new TQPixmap( *img ); - delete img; - - return pix; -} - - -bool KeramikHandler::reset( unsigned long changed ) -{ - keramik_initialized = false; - - bool needHardReset = false; - bool pixmapsInvalid = false; - - // Re-read the config file - readConfig(); - - if ( changed & SettingBorder ) - { - pixmapsInvalid = true; - needHardReset = true; - } - if ( changed & SettingFont ) - { - pixmapsInvalid = true; - needHardReset = true; - } - // Check if the color scheme has changed - if ( changed & SettingColors ) - { - pixmapsInvalid = true; - } - // Check if button positions have changed - - if ( changed & SettingButtons ) { - needHardReset = true; - } - - // Check if tooltips options have changed - if ( changed & SettingTooltips ) { - needHardReset = true; - } - - if ( (settings_cache->largeGrabBars != largeGrabBars) ) { - pixmapsInvalid = true; - needHardReset = true; - } - - if ( (settings_cache->smallCaptionBubbles != smallCaptionBubbles) ) { - needHardReset = true; - } - - // Update our config cache - settings_cache->largeGrabBars = largeGrabBars; - settings_cache->smallCaptionBubbles = smallCaptionBubbles; - - // Do we need to recreate the pixmaps? - if ( pixmapsInvalid ) { - destroyPixmaps(); - createPixmaps(); - } - - keramik_initialized = true; - - // Do we need to "hit the wooden hammer" ? - if ( !needHardReset ) - resetDecorations( changed ); - return needHardReset; -} - - -bool KeramikHandler::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; - }; -} - - -const TQPixmap *KeramikHandler::tile( TilePixmap tilePix, bool active ) const -{ - return ( active ? activeTiles[ tilePix ] : inactiveTiles[ tilePix ] ); -} - -KDecoration* KeramikHandler::createDecoration( KDecorationBridge* bridge ) -{ - return new KeramikClient( bridge, this ); -} - -TQValueList< KeramikHandler::BorderSize > KeramikHandler::borderSizes() const -{ // the list must be sorted - return TQValueList< BorderSize >() << BorderNormal << BorderLarge << - BorderVeryLarge << BorderHuge << BorderVeryHuge << BorderOversized; -} - - -// ------------------------------------------------------------------------------------------- - - - -KeramikButton::KeramikButton( KeramikClient* c, const char *name, Button btn, const TQString &tip, const int realizeBtns ) - : TQButton( c->widget(), name ), - client( c ), button( btn ), hover( false ), lastbutton( Qt::NoButton ) -{ - realizeButtons = realizeBtns; - - TQToolTip::add( this, tip ); // FRAME - setBackgroundMode( NoBackground ); - setCursor( tqarrowCursor ); - int size = clientHandler->roundButton()->height(); - setFixedSize( size, size ); - - setToggleButton( (button == OnAllDesktopsButton) ); -} - - -KeramikButton::~KeramikButton() -{ - // Empty. -} - - -void KeramikButton::enterEvent( TQEvent *e ) -{ - TQButton::enterEvent( e ); - - hover = true; - tqrepaint( false ); -} - - -void KeramikButton::leaveEvent( TQEvent *e ) -{ - TQButton::leaveEvent( e ); - - hover = false; - tqrepaint( false ); -} - - -void KeramikButton::mousePressEvent( TQMouseEvent *e ) -{ - lastbutton = e->button(); - TQMouseEvent me( e->type(), e->pos(), e->globalPos(), (e->button()&realizeButtons)?Qt::LeftButton:Qt::NoButton, e->state() ); - TQButton::mousePressEvent( &me ); -} - - -void KeramikButton::mouseReleaseEvent( TQMouseEvent *e ) -{ - lastbutton = e->button(); - TQMouseEvent me( e->type(), e->pos(), e->globalPos(), (e->button()&realizeButtons)?Qt::LeftButton:Qt::NoButton, e->state() ); - TQButton::mouseReleaseEvent( &me ); -} - - -void KeramikButton::drawButton( TQPainter *p ) -{ - const TQPixmap *pix; - const TQBitmap *deco; - int size = clientHandler->roundButton()->height(); - - // Get the bevel from the client handler - if ( button == MenuButton || button == OnAllDesktopsButton || button == HelpButton ) - pix = clientHandler->roundButton(); - else - pix = clientHandler->squareButton(); - - // Draw the button background - const TQPixmap *background = clientHandler->tile( TitleCenter, client->isActive() ); - p->drawPixmap( 0, 0, *background, - 0, (background->height()-size+1)/2, size, size ); - - if ( isDown() ) { - // Pressed - p->drawPixmap( TQPoint(), *pix, TQStyle::tqvisualRect( TQRect(2*size, 0, size, size), pix->rect() ) ); - p->translate( TQApplication::reverseLayout() ? -1 : 1, 1 ); - } else if ( hover ) - // Mouse over - p->drawPixmap( TQPoint(), *pix, TQStyle::tqvisualRect( TQRect(size, 0, size, size), pix->rect() ) ); - else - // Normal - p->drawPixmap( TQPoint(), *pix, TQStyle::tqvisualRect( TQRect(0, 0, size, size), pix->rect() ) ); - - - // Draw the button deco on the bevel - switch ( button ) { - case MenuButton: - deco = clientHandler->buttonDeco( Menu ); - break; - - case OnAllDesktopsButton: - deco = clientHandler->buttonDeco( client->isOnAllDesktops() ? NotOnAllDesktops : OnAllDesktops ); - break; - - case HelpButton: - deco = clientHandler->buttonDeco( Help ); - // The '?' won't be flipped around in the ctor, so we need to - // shift it to the right to compensate for the button shadow - // being on the left side of the button in RTL mode. - if ( TQApplication::reverseLayout() ) - p->translate( 2, 0 ); - break; - - case MinButton: - deco = clientHandler->buttonDeco( Minimize ); - break; - - case MaxButton: - deco = clientHandler->buttonDeco( client->maximizeMode() == KeramikClient::MaximizeFull ? Restore : Maximize ); - break; - - case CloseButton: - deco = clientHandler->buttonDeco( Close ); - break; - - case AboveButton: - deco = clientHandler->buttonDeco( client->keepAbove() ? AboveOn : AboveOff ); - break; - - case BelowButton: - deco = clientHandler->buttonDeco( client->keepBelow() ? BelowOn : BelowOff ); - break; - - case ShadeButton: - deco = clientHandler->buttonDeco( client->isSetShade() ? ShadeOn : ShadeOff ); - break; - - default: - deco = NULL; - } - - p->setPen( Qt::black ); // ### hardcoded color - p->drawPixmap( (size-17)/2, (size-17)/2, *deco ); -} - - - -// ------------------------------------------------------------------------------------------ - - - -KeramikClient::KeramikClient( KDecorationBridge* bridge, KDecorationFactory* factory ) - : KDecoration( bridge, factory ), - activeIcon( NULL ), inactiveIcon( NULL ), captionBufferDirty( true ), maskDirty( true ) -{ -} - -void KeramikClient::init() -{ - connect( this, TQT_SIGNAL( keepAboveChanged( bool )), TQT_SLOT( keepAboveChange( bool ))); - connect( this, TQT_SIGNAL( keepBelowChanged( bool )), TQT_SLOT( keepBelowChange( bool ))); - - createMainWidget( (WFlags)(WStaticContents | WResizeNoErase | WRepaintNoErase) ); - widget()->installEventFilter( this ); - - // Minimize flicker - widget()->setBackgroundMode( NoBackground ); - - for ( int i=0; i < NumButtons; i++ ) - button[i] = NULL; - - createLayout(); -} - -void KeramikClient::createLayout() -{ - - TQVBoxLayout *mainLayout = new TQVBoxLayout( widget() ); - TQBoxLayout *titleLayout = new TQBoxLayout( 0, TQBoxLayout::LeftToRight, 0, 0, 0 ); - TQHBoxLayout *windowLayout = new TQHBoxLayout(); - - largeTitlebar = ( !maximizedVertical() && clientHandler->largeCaptionBubbles() ); - largeCaption = ( isActive() && largeTitlebar ); - - int grabBarHeight = clientHandler->grabBarHeight(); - int topSpacing = ( largeTitlebar ? 4 : 1 ); - int leftBorderWidth = clientHandler->tile( BorderLeft, true )->width(); - int rightBorderWidth = clientHandler->tile( BorderRight, true )->width(); - topSpacer = new TQSpacerItem( 10, topSpacing, - TQSizePolicy::Expanding, TQSizePolicy::Minimum ); - - mainLayout->addItem( topSpacer ); - - mainLayout->addLayout( titleLayout ); // Titlebar - mainLayout->addLayout( windowLayout, 1 ); // Left border + window + right border - mainLayout->addSpacing( grabBarHeight ); // Bottom grab bar - - titleLayout->setSpacing( buttonSpacing ); - - titleLayout->addSpacing( buttonMargin ); // Left button margin - addButtons( titleLayout, options()->customButtonPositions() ? - options()->titleButtonsLeft() : TQString(default_left) ); - - titlebar = new TQSpacerItem( 10, clientHandler->titleBarHeight(largeTitlebar) - - topSpacing, TQSizePolicy::Expanding, TQSizePolicy::Minimum ); - titleLayout->addItem( titlebar ); - - titleLayout->addSpacing( buttonSpacing ); - addButtons( titleLayout, options()->customButtonPositions() ? - options()->titleButtonsRight() : TQString(default_right) ); - titleLayout->addSpacing( buttonMargin - 1 ); // Right button margin - - windowLayout->addSpacing( leftBorderWidth ); // Left border - if( isPreview()) - windowLayout->addWidget( new TQLabel( i18n( "<center><b>Keramik preview</b></center>" ), widget())); - else - windowLayout->addItem( new TQSpacerItem( 0, 0 )); //no widget in the middle - windowLayout->addSpacing( rightBorderWidth ); // Right border -} - - -KeramikClient::~KeramikClient() -{ - delete activeIcon; - delete inactiveIcon; - - activeIcon = inactiveIcon = NULL; -} - - -void KeramikClient::reset( unsigned long ) -{ - if ( clientHandler->largeCaptionBubbles() && !largeTitlebar ) - { - // We're switching from small caption bubbles to large - if ( !maximizedVertical() ) { - topSpacer->changeSize( 10, 4, TQSizePolicy::Expanding, TQSizePolicy::Minimum ); - largeTitlebar = true; - largeCaption = isActive(); - - widget()->layout()->activate(); - - // Compensate for the titlebar size change - - // TODO This is wrong, this may break size increments (see bug #53784). - // FRAME - widget()->setGeometry( widget()->x(), widget()->y() - 3, width(), height() + 3 ); - } - } - else if ( !clientHandler->largeCaptionBubbles() && largeTitlebar ) - { - // We're switching from large caption bubbles to small - topSpacer->changeSize( 10, 1, TQSizePolicy::Expanding, TQSizePolicy::Minimum ); - largeTitlebar = largeCaption = false; - - widget()->layout()->activate(); - - // Compensate for the titlebar size change - // FRAME - widget()->setGeometry( widget()->x(), widget()->y() + 3, width(), height() - 3 ); - } - - calculateCaptionRect(); - - captionBufferDirty = maskDirty = true; - - // Only tqrepaint the window if it's visible - // (i.e. not minimized and on the current desktop) - if ( widget()->isVisible() ) { - widget()->tqrepaint( false ); - - for ( int i = 0; i < NumButtons; i++ ) - if ( button[i] ) button[i]->tqrepaint( false ); - } -} - -bool KeramikClient::isModalSystemNotification() -{ - unsigned char *data = 0; - Atom actual; - int format, result; - unsigned long n, left; - Atom kde_wm_system_modal_notification; - kde_wm_system_modal_notification = XInternAtom(qt_xdisplay(), "_KDE_WM_MODAL_SYS_NOTIFICATION", False); - result = XGetWindowProperty(qt_xdisplay(), windowId(), kde_wm_system_modal_notification, 0L, 1L, False, XA_CARDINAL, &actual, &format, &n, &left, /*(unsigned char **)*/ &data); - if (result == Success && data != None && format == 32 ) - { - return TRUE; - } - return FALSE; -} - -void KeramikClient::addButtons( TQBoxLayout *layout, const TQString &s ) -{ - for ( uint i=0; i < s.length(); i++ ) - { - switch ( s[i].latin1() ) - { - // Menu button - case 'M' : - if (!isModalSystemNotification()) { - if ( !button[MenuButton] ) { - button[MenuButton] = new KeramikButton( this, "menu", MenuButton, i18n("Menu"), Qt::LeftButton|Qt::RightButton ); - connect( button[MenuButton], TQT_SIGNAL( pressed() ), TQT_SLOT( menuButtonPressed() ) ); - layout->addWidget( button[MenuButton] ); - } - } - break; - - // OnAllDesktops button - case 'S' : - if (!isModalSystemNotification()) { - if ( !button[OnAllDesktopsButton] ) { - button[OnAllDesktopsButton] = new KeramikButton( this, "on_all_desktops", - OnAllDesktopsButton, isOnAllDesktops()?i18n("Not on all desktops"):i18n("On all desktops") ); - if(isOnAllDesktops()) - button[OnAllDesktopsButton]->toggle(); - connect( button[OnAllDesktopsButton], TQT_SIGNAL( clicked() ), TQT_SLOT( toggleOnAllDesktops() ) ); - layout->addWidget( button[OnAllDesktopsButton] ); - } - } - break; - - // Help button - case 'H' : - if ( !button[HelpButton] && providesContextHelp() ) { - button[HelpButton] = new KeramikButton( this, "help", HelpButton, i18n("Help") ); - connect( button[HelpButton], TQT_SIGNAL( clicked() ), TQT_SLOT( showContextHelp() ) ); - layout->addWidget( button[HelpButton] ); - } - break; - - // Minimize button - case 'I' : - if ( !button[MinButton] && isMinimizable() ) { - button[MinButton] = new KeramikButton( this, "minimize", MinButton, i18n("Minimize") ); - connect( button[MinButton], TQT_SIGNAL( clicked() ), TQT_SLOT( minimize() ) ); - layout->addWidget( button[MinButton] ); - } - break; - - // Maximize button - case 'A' : - if ( !button[MaxButton] && isMaximizable() ) { - button[MaxButton] = new KeramikButton( this, "maximize", MaxButton, i18n("Maximize"), Qt::LeftButton|Qt::MidButton|Qt::RightButton ); - connect( button[MaxButton], TQT_SIGNAL( clicked() ), TQT_SLOT( slotMaximize() ) ); - layout->addWidget( button[MaxButton] ); - } - break; - - // Close button - case 'X' : - if ( !button[CloseButton] && isCloseable() ) { - button[CloseButton] = new KeramikButton( this, "close", CloseButton, i18n("Close") ); - connect( button[CloseButton], TQT_SIGNAL( clicked() ), TQT_SLOT( closeWindow() ) ); - layout->addWidget( button[CloseButton] ); - } - break; - - // Above button - case 'F' : - if ( !button[AboveButton]) { - button[AboveButton] = new KeramikButton( this, "above", AboveButton, i18n("Keep Above Others") ); - connect( button[AboveButton], TQT_SIGNAL( clicked() ), TQT_SLOT( slotAbove() ) ); - layout->addWidget( button[AboveButton] ); - } - break; - - // Below button - case 'B' : - if ( !button[BelowButton]) { - button[BelowButton] = new KeramikButton( this, "below", BelowButton, i18n("Keep Below Others") ); - connect( button[BelowButton], TQT_SIGNAL( clicked() ), TQT_SLOT( slotBelow() ) ); - layout->addWidget( button[BelowButton] ); - } - break; - - // Shade button - case 'L' : - if ( !button[ShadeButton] && isShadeable() ) { - button[ShadeButton] = new KeramikButton( this, "shade", ShadeButton, - isSetShade() ? i18n("Unshade") : i18n( "Shade" )); - connect( button[ShadeButton], TQT_SIGNAL( clicked() ), TQT_SLOT( slotShade() ) ); - layout->addWidget( button[ShadeButton] ); - } - break; - - // Additional spacing - case '_' : - layout->addSpacing( buttonSpacing ); - break; - } - } -} - - -void KeramikClient::updateMask() -{ - if ( !keramik_initialized ) - return; - - // To maximize performance this code uses precalculated bounding rects - // to set the window mask. This saves us from having to allocate a 1bpp - // pixmap, paint the mask on it and then have the X server iterate - // over the pixels to compute the bounding rects from it. - - TQRegion r; - register int w, y = 0; - int nrects; - - if ( TQApplication::reverseLayout() ) { - - // If the caption bubble is visible and extends above the titlebar - if ( largeCaption && captionRect.width() >= 25 ) { - register int x = captionRect.left(); - w = captionRect.width(); - r += TQRegion( x + 11, y++, w - 19, 1 ); - r += TQRegion( x + 9, y++, w - 15, 1 ); - r += TQRegion( x + 7, y++, w - 12, 1 ); - } else { - nrects = 8; - - // Do we have a large titlebar with a retracted caption bubble? - // (i.e. the style is set to use large caption bubbles, we're - // not maximized and not active) - if ( largeTitlebar ) - y = 3; - } - - w = width(); // FRAME - - // The rounded titlebar corners - r += TQRegion( 9, y++, w - 17, 1 ); - r += TQRegion( 7, y++, w - 13, 1 ); - r += TQRegion( 5, y++, w - 9, 1 ); - r += TQRegion( 4, y++, w - 7, 1 ); - r += TQRegion( 3, y++, w - 5, 1 ); - r += TQRegion( 2, y++, w - 4, 1 ); - r += TQRegion( 1, y++, w - 2, 2 ); - } else { - - // If the caption bubble is visible and extends above the titlebar - if ( largeCaption && captionRect.width() >= 25 ) { - nrects = 11; - register int x = captionRect.left(); - w = captionRect.width(); - r += TQRegion( x + 8, y++, w - 19, 1 ); - r += TQRegion( x + 6, y++, w - 15, 1 ); - r += TQRegion( x + 5, y++, w - 12, 1 ); - } else { - nrects = 8; - - // Do we have a large titlebar with a retracted caption bubble? - // (i.e. the style is set to use large caption bubbles, we're - // not maximized and not active) - if ( largeTitlebar ) - y = 3; - } - - w = width(); // FRAME - - // The rounded titlebar corners - r += TQRegion( 8, y++, w - 17, 1 ); - r += TQRegion( 6, y++, w - 13, 1 ); - r += TQRegion( 4, y++, w - 9, 1 ); - r += TQRegion( 3, y++, w - 7, 1 ); - r += TQRegion( 2, y++, w - 5, 1 ); - r += TQRegion( 2, y++, w - 4, 1 ); - r += TQRegion( 1, y++, w - 2, 2 ); - } - - y++; - - // The part of the window below the titlebar - r += TQRegion( 0, y, w, height() - y ); - - setMask( r, YXBanded ); - - maskDirty = false; -} - - -void KeramikClient::updateCaptionBuffer() -{ - if ( !keramik_initialized ) - return; - - bool active = isActive(); - TQPixmap *icon = NULL; - - if ( captionBuffer.size() != captionRect.size() ) - captionBuffer.resize( captionRect.size() ); - - if ( captionBuffer.isNull() ) - return; - - TQPainter p( &captionBuffer ); - - // Draw the caption bubble - if ( active && largeCaption ) { - p.drawPixmap( 0, 0, *clientHandler->tile( CaptionLargeLeft, true ) ); - p.drawTiledPixmap( 15, 0, captionRect.width() - 30, captionRect.height(), - *clientHandler->tile( CaptionLargeCenter, true ) ); - p.drawPixmap( captionRect.width() - 15, 0, *clientHandler->tile( CaptionLargeRight, true ) ); - } else { - p.drawPixmap( 0, 0, *clientHandler->tile( CaptionSmallLeft, active ) ); - p.drawTiledPixmap( 15, 0, captionRect.width() - 30, captionRect.height(), - *clientHandler->tile( CaptionSmallCenter, active ) ); - p.drawPixmap( captionRect.width() - 15, 0, *clientHandler->tile( CaptionSmallRight, active ) ); - } - - if ( clientHandler->showAppIcons() ) - { - if ( active ) { - if ( ! activeIcon ) - activeIcon = new TQPixmap( this->icon().pixmap( TQIconSet::Small, TQIconSet::Normal )); // FRAME - icon = activeIcon; - } else { - if ( ! inactiveIcon ) { - TQImage img = this->icon().pixmap( TQIconSet::Small, TQIconSet::Normal ).convertToImage(); - KIconEffect::semiTransparent( img ); - inactiveIcon = new TQPixmap( img ); - } - icon = inactiveIcon; - } - } - - p.setFont( options()->font( active ) ); - int tw = p.fontMetrics().width( caption() ) + - ( clientHandler->showAppIcons() ? 16 + iconSpacing : 0 ); - - int xpos = QMAX( (captionRect.width() - tw) / 3, 8 ); - TQRect tr = TQStyle::tqvisualRect( TQRect(xpos, 1, captionRect.width() - xpos - 10, - captionRect.height() - 4), captionBuffer.rect() ); - - //p.setPen( Qt::red ); // debug - //p.drawRect( tr ); // debug - - // Application icon - if ( clientHandler->showAppIcons() ) - { - TQRect iconRect = TQStyle::tqvisualRect( TQRect(tr.x(), - 1 + (captionRect.height() - 4 - 16) / 2, 16, 16), tr ); - TQRect r( icon->rect() ); - r.moveCenter( iconRect.center() ); - - if ( tr.width() > 16 ) { - p.drawPixmap( r, *icon ); - } else { - TQRect sr( 0, 0, icon->width(), icon->height() ); - - if ( TQApplication::reverseLayout() ) - sr.addCoords( icon->width() - tr.width(), 0, 0, 0 ); - else - sr.addCoords( 0, 0, -( icon->width() - tr.width() ), 0 ); - - p.drawPixmap( r.x() + sr.x(), r.y() + sr.y(), *icon, - sr.x(), sr.y(), sr.width(), sr.height() ); - } - - //p.drawRect( r ); // debug - - if ( TQApplication::reverseLayout() ) - tr.addCoords( 0, 0, -(16 + iconSpacing), 0 ); - else - tr.addCoords( (16 + iconSpacing), 0, 0, 0 ); - } - - // Draw the titlebar text - int flags = AlignVCenter | SingleLine; - flags |= ( TQApplication::reverseLayout() ? AlignRight : AlignLeft ); - - if ( clientHandler->useShadowedText() ) - { - p.translate( TQApplication::reverseLayout() ? -1 : 1, 1 ); - //p.setPen( options()->color(ColorTitleBar, active).dark() ); - if (tqGray(options()->color(ColorFont, active).rgb()) < 100) - p.setPen( TQColor(200,200,200) ); - else - p.setPen( black ); - p.drawText( tr, flags, caption() ); - p.translate( TQApplication::reverseLayout() ? 1 : -1, -1 ); - } - - p.setPen( options()->color( ColorFont, active ) ); - p.drawText( tr, flags, caption() ); - - captionBufferDirty = false; -} - - -void KeramikClient::calculateCaptionRect() -{ - TQFontMetrics fm( options()->font(isActive()) ); - int cw = fm.width( caption() ) + 95; - int titleBaseY = ( largeTitlebar ? 3 : 0 ); - - if ( clientHandler->showAppIcons() ) - cw += 16 + 4; // icon width + space - - cw = QMIN( cw, titlebar->geometry().width() ); - captionRect = TQStyle::tqvisualRect( TQRect(titlebar->geometry().x(), (largeCaption ? 0 : titleBaseY), - cw, clientHandler->titleBarHeight(largeCaption) ), - titlebar->geometry() ); -} - - -void KeramikClient::captionChange() -{ - TQRect r( captionRect ); - calculateCaptionRect(); - - if ( r.size() != captionRect.size() ) - maskDirty = true; - - captionBufferDirty = true; - - widget()->tqrepaint( r | captionRect, false ); -} - - -void KeramikClient::iconChange() -{ - if ( clientHandler->showAppIcons() ) { - - // Force updateCaptionBuffer() to recreate the cached icons - delete activeIcon; - - delete inactiveIcon; - - activeIcon = inactiveIcon = NULL; - - captionBufferDirty = true; - widget()->tqrepaint( captionRect, false ); - } -} - - -void KeramikClient::activeChange() -{ - bool active = isActive(); - // Note: It's assumed that the same font will always be used for both active - // and inactive windows, since the fonts kcm hasn't supported setting - // different fonts for different window states for some time. - if ( largeTitlebar ) { - largeCaption = ( active && !maximizedVertical() ); - calculateCaptionRect(); - maskDirty = true; - } - - captionBufferDirty = true; - - widget()->tqrepaint( false ); - - for ( int i=0; i < NumButtons; i++ ) - if ( button[i] ) button[i]->tqrepaint( false ); -} - - -void KeramikClient::maximizeChange() -{ - if ( clientHandler->largeCaptionBubbles() ) - { - if ( maximizeMode() & MaximizeVertical ) { - // We've been maximized - shrink the titlebar by 3 pixels - topSpacer->changeSize( 10, 1, TQSizePolicy::Expanding, TQSizePolicy::Minimum ); - largeCaption = largeTitlebar = false; - - calculateCaptionRect(); - captionBufferDirty = maskDirty = true; - - widget()->layout()->activate(); - widget()->tqrepaint( false ); - } else if (( maximizeMode() & MaximizeVertical ) == 0 && !largeTitlebar ) { - // We've been restored - enlarge the titlebar by 3 pixels - topSpacer->changeSize( 10, 4, TQSizePolicy::Expanding, TQSizePolicy::Minimum ); - largeCaption = largeTitlebar = true; - - calculateCaptionRect(); - captionBufferDirty = maskDirty = true; - - widget()->layout()->activate(); - widget()->tqrepaint( false ); - } - } - - if ( button[ MaxButton ] ) { - TQToolTip::remove( button[ MaxButton ] ); - TQToolTip::add( button[ MaxButton ], maximizeMode() == MaximizeFull ? i18n("Restore") : i18n("Maximize") ); - button[ MaxButton ]->tqrepaint(); - } -} - - -void KeramikClient::desktopChange() -{ - if ( button[ OnAllDesktopsButton ] ) - { - button[ OnAllDesktopsButton ]->tqrepaint( true ); - TQToolTip::remove( button[ OnAllDesktopsButton ] ); - TQToolTip::add( button[ OnAllDesktopsButton ], isOnAllDesktops() ? i18n("Not on all desktops") : i18n("On all desktops") ); - } -} - - -void KeramikClient::shadeChange() -{ - if ( button[ ShadeButton ] ) - { - button[ ShadeButton ]->tqrepaint( true ); - TQToolTip::remove( button[ ShadeButton ] ); - TQToolTip::add( button[ ShadeButton ], isSetShade() ? i18n("Unshade") : i18n("Shade") ); - } -} - - -void KeramikClient::keepAboveChange( bool ) -{ - if ( button[ AboveButton ] ) - button[ AboveButton ]->tqrepaint( true ); -} - - -void KeramikClient::keepBelowChange( bool ) -{ - if ( button[ BelowButton ] ) - button[ BelowButton ]->tqrepaint( true ); -} - - -void KeramikClient::menuButtonPressed() -{ - TQPoint menuTop ( button[MenuButton]->rect().topLeft() ); - TQPoint menuBottom ( button[MenuButton]->rect().bottomRight() ); - menuTop += TQPoint(-6, -3); - menuBottom += TQPoint(6, 3); - KDecorationFactory* f = factory(); - showWindowMenu( TQRect( button[MenuButton]->mapToGlobal( menuTop ), - button[MenuButton]->mapToGlobal( menuBottom )) ); - if( !f->exists( this )) // 'this' was destroyed - return; - button[MenuButton]->setDown(false); -} - - -void KeramikClient::slotMaximize() -{ - maximize( button[ MaxButton ]->lastButton() ); -} - - -void KeramikClient::slotAbove() -{ - setKeepAbove( !keepAbove()); - button[ AboveButton ]->tqrepaint( true ); -} - - -void KeramikClient::slotBelow() -{ - setKeepBelow( !keepBelow()); - button[ BelowButton ]->tqrepaint( true ); -} - - -void KeramikClient::slotShade() -{ - setShade( !isSetShade()); - button[ ShadeButton ]->tqrepaint( true ); -} - - -void KeramikClient::paintEvent( TQPaintEvent *e ) -{ - if ( !keramik_initialized ) - return; - - TQPainter p( widget()); - TQRect updateRect( e->rect() ); - bool active = isActive(); - - int titleBaseY = ( largeTitlebar ? 3 : 0 ); - int titleBarHeight = clientHandler->titleBarHeight( largeTitlebar ); - int grabBarHeight = clientHandler->grabBarHeight(); - int leftBorderWidth = clientHandler->tile( BorderLeft, active )->width(); - int rightBorderWidth = clientHandler->tile( BorderRight, active )->width(); - - if ( maskDirty ) - updateMask(); - - // Titlebar - // ----------------------------------------------------------------------- - if ( updateRect.y() < titleBarHeight ) - { - int titleBarBaseHeight = titleBarHeight - titleBaseY; - - if ( captionBufferDirty ) - updateCaptionBuffer(); - - // Top left corner - if ( updateRect.x() < 15 ) - p.drawPixmap( 0, titleBaseY, - *clientHandler->tile( TitleLeft, active ) ); - - // Space between the top left corner and the caption bubble - if ( updateRect.x() < captionRect.left() && updateRect.right() >= 15 ) { - int x1 = QMAX( 15, updateRect.x() ); - int x2 = QMIN( captionRect.left(), updateRect.right() ); - - p.drawTiledPixmap( x1, titleBaseY, x2 - x1 + 1, titleBarBaseHeight, - *clientHandler->tile( TitleCenter, active ) ); - } - - // Caption bubble - if ( updateRect.x() <= captionRect.right() && updateRect.right() > 15 ) { - if ( captionRect.width() >= 25 ) - p.drawPixmap( captionRect.left(), active ? 0 : titleBaseY, captionBuffer ); - else - p.drawTiledPixmap( captionRect.x(), titleBaseY, captionRect.width(), - titleBarBaseHeight, *clientHandler->tile( TitleCenter, active ) ); - } - - // Space between the caption bubble and the top right corner - if ( updateRect.right() > captionRect.right() && updateRect.x() < width() - 15 ) { // FRAME - int x1 = QMAX( captionRect.right() + 1, updateRect.x() ); - int x2 = QMIN( width() - 15, updateRect.right() ); - - p.drawTiledPixmap( x1, titleBaseY, x2 - x1 + 1, titleBarBaseHeight, - *clientHandler->tile( TitleCenter, active ) ); - } - - // Top right corner - if ( updateRect.right() >= width() - 15 ) - p.drawPixmap( width() - 15, titleBaseY, - *clientHandler->tile( TitleRight, active ) ); - } - - // Borders - // ----------------------------------------------------------------------- - if ( updateRect.bottom() >= titleBarHeight && - updateRect.top() < height() - grabBarHeight ) - { - int top = QMAX( titleBarHeight, updateRect.top() ); - int bottom = QMIN( updateRect.bottom(), height() - grabBarHeight ); - - // Left border - if ( updateRect.x() < leftBorderWidth ) - p.drawTiledPixmap( 0, top, leftBorderWidth, bottom - top + 1, - *clientHandler->tile( BorderLeft, active ) ); - - // Right border - if ( e->rect().right() > width() - rightBorderWidth - 1 ) - p.drawTiledPixmap( width() - rightBorderWidth, top, rightBorderWidth, - bottom - top + 1, *clientHandler->tile( BorderRight, active ) ); - } - - // Bottom grab bar - // ----------------------------------------------------------------------- - if ( updateRect.bottom() >= height() - grabBarHeight ) { - // Bottom left corner - if ( updateRect.x() < 9 ) - p.drawPixmap( 0, height() - grabBarHeight, - *clientHandler->tile( GrabBarLeft, active ) ); - - // Space between the left corner and the right corner - if ( updateRect.x() < width() - 9 ) { - int x1 = QMAX( 9, updateRect.x() ); - int x2 = QMIN( width() - 9, updateRect.right() ); - - p.drawTiledPixmap( x1, height() - grabBarHeight, x2 - x1 + 1, - grabBarHeight, *clientHandler->tile( GrabBarCenter, active ) ); - } - - // Bottom right corner - if ( updateRect.right() > width() - 9 ) - p.drawPixmap( width() - 9, height() - grabBarHeight, - *clientHandler->tile( GrabBarRight, active ) ); - } - - // Extra drawline for the 1 pixel empty space TQLayout leaves when a window is shaded. - p.setPen( options()->color( ColorTitleBlend, active ) ); - p.drawLine( leftBorderWidth, height() - grabBarHeight - 1, - width() - rightBorderWidth - 1, height() - grabBarHeight - 1 ); -} - - -void KeramikClient::resizeEvent( TQResizeEvent *e ) -{ -// FRAME Client::resizeEvent( e ); - - TQRect r( captionRect ); - calculateCaptionRect(); - - if ( r.size() != captionRect.size() ) - captionBufferDirty = true; - - maskDirty = true; - - if ( widget()->isVisible() ) - { - widget()->update( widget()->rect() ); - int dx = 0; - int dy = 0; - - if ( e->oldSize().width() != width() ) - dx = 32 + QABS( e->oldSize().width() - width() ); - - if ( e->oldSize().height() != height() ) - dy = 8 + QABS( e->oldSize().height() - height() ); - - if ( dy ) - widget()->update( 0, height() - dy + 1, width(), dy ); - - if ( dx ) - { - widget()->update( width() - dx + 1, 0, dx, height() ); - widget()->update( TQRect( TQPoint(4,4), titlebar->geometry().bottomLeft() - TQPoint(1,0) ) ); - widget()->update( TQRect( titlebar->geometry().topRight(), TQPoint( width() - 4, - titlebar->geometry().bottom() ) ) ); - // Titlebar needs no paint event - TQApplication::postEvent( this, new TQPaintEvent( titlebar->geometry(), FALSE ) ); - } - } -} - - -void KeramikClient::mouseDoubleClickEvent( TQMouseEvent *e ) -{ - if ( e->button() == Qt::LeftButton - && TQRect( 0, 0, width(), clientHandler->titleBarHeight( largeTitlebar ) ).contains( e->pos() ) ) - titlebarDblClickOperation(); -} - -void KeramikClient::wheelEvent( TQWheelEvent *e ) -{ - if (isSetShade() - || TQRect( 0, 0, width(), clientHandler->titleBarHeight( largeTitlebar ) ).contains( e->pos() ) ) - titlebarMouseWheelOperation( e->delta()); -} - -KeramikClient::Position KeramikClient::mousePosition( const TQPoint &p ) const -{ - int titleBaseY = (largeTitlebar ? 3 : 0); - - int leftBorder = clientHandler->tile( BorderLeft, true )->width(); - int rightBorder = width() - clientHandler->tile( BorderRight, true )->width() - 1; - int bottomBorder = height() - clientHandler->grabBarHeight() - 1; - int bottomCornerSize = 3*clientHandler->tile( BorderRight, true )->width()/2 + 24; - - // Test if the mouse is over the titlebar area - if ( p.y() < titleBaseY + 11 ) { - // Test for the top left corner - if ( p.x() < leftBorder + 11 ) { - if ( (p.y() < titleBaseY + 3 && p.x() < leftBorder + 11) || - (p.y() < titleBaseY + 6 && p.x() < leftBorder + 6) || - (p.y() < titleBaseY + 11 && p.x() < leftBorder + 3) ) - return PositionTopLeft; - } - - // Test for the top right corner - if ( p.x() > rightBorder - 11 ) { - if ( (p.y() < titleBaseY + 3 && p.x() > rightBorder - 11) || - (p.y() < titleBaseY + 6 && p.x() > rightBorder - 6) || - (p.y() < titleBaseY + 11 && p.x() > rightBorder - 3) ) - return PositionTopRight; - } - - // Test for the top border - if ( p.y() <= 3 || (p.y() <= titleBaseY+3 && - (p.x() < captionRect.left() || p.x() > captionRect.right()) ) ) - return PositionTop; - - // The cursor must be over the center of the titlebar. - return PositionCenter; - } - - // Test the sides - else if ( p.y() < bottomBorder ) { - // Test for the left side - if ( p.x() < leftBorder ) { - if ( p.y() < height() - bottomCornerSize ) - return PositionLeft; - else - return PositionBottomLeft; - } - - // Test for the right side - else if ( p.x() > rightBorder ) { - if ( p.y() < height() - bottomCornerSize ) - return PositionRight; - else - return PositionBottomRight; - } - - // The cursor must be over the center of the window - return PositionCenter; - } - - // Test the grab bar / bottom border - else { - // Test for the bottom left corner - if ( p.x() < bottomCornerSize ) - return PositionBottomLeft; - - // Test for the bottom right corner - else if ( p.x() > width() - bottomCornerSize - 1 ) - return PositionBottomRight; - - // The cursor must be over the bottom border - return PositionBottom; - } - - // We should never get here - return PositionCenter; -} - - -void KeramikClient::resize( const TQSize& s ) -{ - widget()->resize( s ); -} - - -void KeramikClient::borders( int& left, int& right, int& top, int& bottom ) const -{ - int titleBarHeight = clientHandler->titleBarHeight( clientHandler->largeCaptionBubbles() ); - int grabBarHeight = clientHandler->grabBarHeight(); - int leftBorderWidth = clientHandler->tile( BorderLeft, isActive() )->width(); - int rightBorderWidth = clientHandler->tile( BorderRight, isActive() )->width(); - - left = leftBorderWidth; - right = rightBorderWidth; - top = titleBarHeight; - bottom = grabBarHeight; - - if ( ( maximizeMode() & MaximizeHorizontal ) && !options()->moveResizeMaximizedWindows()) - left = right = 0; - if( maximizeMode() & MaximizeVertical) - { - top = clientHandler->titleBarHeight( false ); - if( !options()->moveResizeMaximizedWindows()) - bottom = 0; - } -} - - -TQSize KeramikClient::tqminimumSize() const -{ - return widget()->tqminimumSize(); -} - - -bool KeramikClient::eventFilter( TQObject* o, TQEvent* e ) -{ - if ( TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(widget()) ) - return false; - - switch ( e->type() ) - { - case TQEvent::Resize: - resizeEvent( TQT_TQRESIZEEVENT( e ) ); - return true; - - case TQEvent::Paint: - paintEvent( TQT_TQPAINTEVENT( e ) ); - return true; - - case TQEvent::MouseButtonDblClick: - mouseDoubleClickEvent( TQT_TQMOUSEEVENT( e ) ); - return true; - - case TQEvent::MouseButtonPress: - processMousePressEvent( TQT_TQMOUSEEVENT( e ) ); - return true; - - case TQEvent::Wheel: - wheelEvent( TQT_TQWHEELEVENT( e )); - return true; - - default: - return false; - } -} - -} // namespace Keramik - - - -// ------------------------------------------------------------------------------------------- - - - -extern "C" -{ - KDE_EXPORT KDecorationFactory *create_factory() - { - Keramik::clientHandler = new Keramik::KeramikHandler(); - return Keramik::clientHandler; - } -} - - - -// vim: set noet ts=4 sw=4: |