diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | ce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch) | |
tree | 5ac38a06f3dde268dc7927dc155896926aaf7012 /kstyles | |
download | tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kstyles')
312 files changed, 31533 insertions, 0 deletions
diff --git a/kstyles/Makefile.am b/kstyles/Makefile.am new file mode 100644 index 000000000..2bc20749a --- /dev/null +++ b/kstyles/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = plastik highcolor highcontrast themes light kthemestyle riscos utils keramik + +#kstyles should not be included in the apidocs +#include $(top_srcdir)/admin/Doxyfile.am diff --git a/kstyles/highcolor/Makefile.am b/kstyles/highcolor/Makefile.am new file mode 100644 index 000000000..a86199cce --- /dev/null +++ b/kstyles/highcolor/Makefile.am @@ -0,0 +1,29 @@ + +# This file is part of the KDE libraries +# Copyright (C) 1997 Matthias Kalle Dalheimer ([email protected]) +# (C) 1997 Stephan Kulow ([email protected]) + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. + +# This library 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 +# Library General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this library; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +AM_CPPFLAGS = -DQT_PLUGIN + +INCLUDES = -I$(top_srcdir)/kdefx $(all_includes) +noinst_HEADERS = highcolor.h bitmaps.h +kde_style_LTLIBRARIES = highcolor.la +highcolor_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +highcolor_la_LIBADD = ../../kdefx/libkdefx.la +highcolor_la_SOURCES = highcolor.cpp +highcolor_la_METASOURCES = AUTO diff --git a/kstyles/highcolor/bitmaps.h b/kstyles/highcolor/bitmaps.h new file mode 100644 index 000000000..43e96bd8e --- /dev/null +++ b/kstyles/highcolor/bitmaps.h @@ -0,0 +1,84 @@ +#ifndef __BITMAPS_H +#define __BITMAPS_H + +/* Image bits processed by KPixmap2Bitmaps */ +static const unsigned char radiooff_light_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, + 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x0c, 0x06, + 0xf0, 0x01}; + +static const unsigned char radiooff_gray_bits[] = { + 0xf0, 0x01, 0x0c, 0x06, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00}; + +static const unsigned char radiooff_dgray_bits[] = { + 0x00, 0x00, 0xf0, 0x01, 0x0c, 0x02, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00}; + +static const unsigned char radiooff_center_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xf8, 0x03, 0xfc, 0x07, 0xfc, 0x07, + 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07, 0xf8, 0x03, 0xf0, 0x01, 0x00, 0x00, + 0x00, 0x00}; + +static const unsigned char radiomask_bits[] = { + 0xf0, 0x01, 0xfc, 0x07, 0xfe, 0x0b, 0xfe, 0x0b, 0xff, 0x17, 0xff, 0x17, + 0xff, 0x17, 0xff, 0x17, 0xff, 0x17, 0xfe, 0x0b, 0xf2, 0x09, 0x0c, 0x06, + 0xf0, 0x01}; + +// Checkbox "checked" bitmap +static const unsigned char x_bits[] = {0x63, 0x77, 0x3e, 0x1c, 0x3e, 0x77, 0x63}; + +// Arrow bitmaps +static const QCOORD u_arrow[]={-1,-3, 0,-3, -2,-2, 1,-2, -3,-1, 2,-1, -4,0, 3,0, -4,1, 3,1}; +static const QCOORD d_arrow[]={-4,-2, 3,-2, -4,-1, 3,-1, -3,0, 2,0, -2,1, 1,1, -1,2, 0,2}; +static const QCOORD l_arrow[]={-3,-1, -3,0, -2,-2, -2,1, -1,-3, -1,2, 0,-4, 0,3, 1,-4, 1,3}; +static const QCOORD r_arrow[]={-2,-4, -2,3, -1,-4, -1,3, 0,-3, 0,2, 1,-2, 1,1, 2,-1, 2,0}; + +namespace B3 { + const QCOORD u_arrow[]={ 0,-2, 0,-2, -1,-1, 1,-1, -2,0, 2,0, -3,1, 3,1 }; + const QCOORD d_arrow[]={ -3,-2, 3,-2, -2,-1, 2,-1, -1,0, 1,0, 0,1, 0,1 }; + const QCOORD l_arrow[]={ 1,-3, 1,-3, 0,-2, 1,-2, -1,-1, 1,-1, -2,0, 1,0, -1,1, 1,1, 0,2, 1,2, 1,3, 1,3 }; + const QCOORD r_arrow[]={ -2,-3, -2,-3, -2,-2, -1,-2, -2,-1, 0,-1, -2,0, 1,0, -2,1, 0,1, -2,2, -1,2, -2,3, -2,3 }; +} + +#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) + + +// Fix Qt's wacky image positions +static const char * const hc_minimize_xpm[] = { +"12 12 2 1", +"# c #000000", +". c None", +"............", +"............", +"............", +"............", +"............", +"............", +"............", +"............", +"...######...", +"...######...", +"............", +"............"}; + +static const char * const hc_close_xpm[] = { +"12 12 2 1", +"# c #000000", +". c None", +"............", +"............", +"............", +"..##....##..", +"...##..##...", +"....####....", +".....##.....", +"....####....", +"...##..##...", +"..##....##..", +"............", +"............"}; + +#endif diff --git a/kstyles/highcolor/highcolor.cpp b/kstyles/highcolor/highcolor.cpp new file mode 100644 index 000000000..b033ea2d5 --- /dev/null +++ b/kstyles/highcolor/highcolor.cpp @@ -0,0 +1,2104 @@ +/* + * $Id$ + * + * KDE3 HighColor Style (version 1.0) + * Copyright (C) 2001-2002 Karol Szwed <[email protected]> + * (C) 2001-2002 Fredrik H�glund <[email protected]> + * + * Drawing routines adapted from the KDE2 HCStyle, + * Copyright (C) 2000 Daniel M. Duley <[email protected]> + * (C) 2000 Dirk Mueller <[email protected]> + * (C) 2001 Martijn Klingens <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <qdrawutil.h> +#include <qpainter.h> +#include <qpointarray.h> +#include <qstyleplugin.h> + +#include <qcombobox.h> +#include <qheader.h> +#include <qmenubar.h> +#include <qpushbutton.h> +#include <qscrollbar.h> +#include <qslider.h> +#include <qtabbar.h> +#include <qtoolbutton.h> +#include <qtoolbar.h> +#include <qpopupmenu.h> + +#include <kdrawutil.h> +#include <kpixmapeffect.h> + +#include "highcolor.h" +#include "highcolor.moc" +#include "bitmaps.h" + + +// -- Style Plugin Interface ------------------------- +class HighColorStylePlugin : public QStylePlugin +{ + public: + HighColorStylePlugin() {} + ~HighColorStylePlugin() {} + + QStringList keys() const + { + return QStringList() << "HighColor" << "Default" << "B3"; + } + + QStyle* create( const QString& key ) + { + if ( key == "highcolor" ) + return new HighColorStyle( HighColorStyle::HighColor ); + + else if ( key == "default" ) + return new HighColorStyle( HighColorStyle::Default ); + + else if ( key == "b3" ) + return new HighColorStyle( HighColorStyle::B3 ); + + return 0; + } +}; + +KDE_Q_EXPORT_PLUGIN( HighColorStylePlugin ) +// --------------------------------------------------- + + +static QBitmap lightBmp; +static QBitmap grayBmp; +static QBitmap dgrayBmp; +static QBitmap centerBmp; +static QBitmap maskBmp; +static QBitmap xBmp; +static QIntDict<GradientSet> gDict; + +static const int itemFrame = 1; +static const int itemHMargin = 3; +static const int itemVMargin = 0; +static const int arrowHMargin = 6; +static const int rightBorder = 12; +static const char* kdeToolbarWidget = "kde toolbar widget"; + +// --------------------------------------------------------------------------- + +GradientSet::GradientSet(const QColor &baseColor) +{ + c = baseColor; + for(int i=0; i < GradientCount; i++) + gradients[i] = NULL; +} + + +GradientSet::~GradientSet() +{ + for(int i=0; i < GradientCount; i++) + if(gradients[i]) + delete gradients[i]; +} + + +KPixmap* GradientSet::gradient(GradientType type) +{ + if (gradients[type]) + return gradients[type]; + + switch(type) + { + case VSmall: { + gradients[VSmall] = new KPixmap; + gradients[VSmall]->resize(18, 24); + KPixmapEffect::gradient(*gradients[VSmall], c.light(110), c.dark(110), + KPixmapEffect::VerticalGradient); + break; + } + + case VMed: { + gradients[VMed] = new KPixmap; + gradients[VMed]->resize(18, 34); + KPixmapEffect::gradient(*gradients[VMed], c.light(110), c.dark(110), + KPixmapEffect::VerticalGradient); + break; + } + + case VLarge: { + gradients[VLarge] = new KPixmap; + gradients[VLarge]->resize(18, 64); + KPixmapEffect::gradient(*gradients[VLarge], c.light(110), c.dark(110), + KPixmapEffect::VerticalGradient); + break; + } + + case HMed: { + gradients[HMed] = new KPixmap; + gradients[HMed]->resize(34, 18); + KPixmapEffect::gradient(*gradients[HMed], c.light(110), c.dark(110), + KPixmapEffect::HorizontalGradient); + break; + } + + case HLarge: { + gradients[HLarge] = new KPixmap; + gradients[HLarge]->resize(52, 18); + KPixmapEffect::gradient(*gradients[HLarge], c.light(110), c.dark(110), + KPixmapEffect::HorizontalGradient); + break; + } + + default: + break; + } + return(gradients[type]); +} + + + +// --------------------------------------------------------------------------- + +HighColorStyle::HighColorStyle( StyleType styleType ) + : KStyle( AllowMenuTransparency | FilledFrameWorkaround, ThreeButtonScrollBar ) +{ + type = styleType; + highcolor = (type == HighColor && QPixmap::defaultDepth() > 8); + gDict.setAutoDelete(true); + hoverWidget = 0L; + selectionBackground = false; +} + + +HighColorStyle::~HighColorStyle() +{ +} + + +void HighColorStyle::polish(QWidget* widget) +{ + // Put in order of highest occurrence to maximise hit rate + if (widget->inherits("QPushButton")) { + widget->installEventFilter(this); + } else if (widget->inherits("QMenuBar") || widget->inherits("QPopupMenu")) { + widget->setBackgroundMode(QWidget::NoBackground); + } else if (type == HighColor && widget->inherits("QToolBarExtensionWidget")) { + widget->installEventFilter(this); + } else if ( !qstrcmp( widget->name(), kdeToolbarWidget) ) { + widget->setBackgroundMode( NoBackground ); // We paint the whole background. + widget->installEventFilter(this); + } else if (widget->inherits("QToolBoxButton")) { + QFont font = widget->font(); + font.setBold(true); + widget->setFont(font); + } + + KStyle::polish( widget ); +} + + +void HighColorStyle::unPolish(QWidget* widget) +{ + if (widget->inherits("QPushButton")) { + widget->removeEventFilter(this); + } + else if (widget->inherits("QMenuBar") || widget->inherits("QPopupMenu")) { + widget->setBackgroundMode(QWidget::PaletteBackground); + } else if (type == HighColor && widget->inherits("QToolBarExtensionWidget")) { + widget->removeEventFilter(this); + } else if ( !qstrcmp( widget->name(), kdeToolbarWidget) ) { + widget->removeEventFilter(this); + widget->setBackgroundMode( PaletteBackground ); + } + + KStyle::unPolish( widget ); +} + + +/* reimp. */ +void HighColorStyle::renderMenuBlendPixmap( KPixmap& pix, const QColorGroup &cg, + const QPopupMenu* /* popup */ ) const +{ + QColor col = cg.button(); + +#ifdef Q_WS_X11 // Only draw menu gradients on TrueColor, X11 visuals + if ( QPaintDevice::x11AppDepth() >= 24 ) + KPixmapEffect::gradient( pix, col.light(120), col.dark(115), + KPixmapEffect::HorizontalGradient ); + else +#endif + pix.fill( col ); +} + + +// This function draws primitive elements as well as their masks. +void HighColorStyle::drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + bool down = flags & Style_Down; + bool on = flags & Style_On; + + switch(pe) + { + // BUTTONS + // ------------------------------------------------------------------- + case PE_ButtonDefault: { + if ( type != HighColor ) { + int x1, y1, x2, y2; + r.coords( &x1, &y1, &x2, &y2 ); + + // Button default indicator + p->setPen( cg.shadow() ); + p->drawLine( x1+1, y1, x2-1, y1 ); + p->drawLine( x1, y1+1, x1, y2-1 ); + p->drawLine( x1+1, y2, x2-1, y2 ); + p->drawLine( x2, y1+1, x2, y2-1 ); + } + break; + } + + case PE_ButtonDropDown: + case PE_ButtonTool: { + bool sunken = on || down; + int x,y,w,h; + r.rect(&x, &y, &w, &h); + int x2 = x+w-1; + int y2 = y+h-1; + QPen oldPen = p->pen(); + + // Outer frame (round style) + p->setPen(cg.shadow()); + p->drawLine(x+1,y,x2-1,y); + p->drawLine(x,y+1,x,y2-1); + p->drawLine(x+1,y2,x2-1,y2); + p->drawLine(x2,y+1,x2,y2-1); + + // Bevel + p->setPen(sunken ? cg.mid() : cg.light()); + p->drawLine(x+1, y+1, x2-1, y+1); + p->drawLine(x+1, y+1, x+1, y2-1); + p->setPen(sunken ? cg.light() : cg.mid()); + p->drawLine(x+2, y2-1, x2-1, y2-1); + p->drawLine(x2-1, y+2, x2-1, y2-1); + + p->fillRect(x+2, y+2, w-4, h-4, cg.button()); + + p->setPen( oldPen ); + break; + } + + // PUSH BUTTON + // ------------------------------------------------------------------- + case PE_ButtonCommand: { + bool sunken = on || down; + bool flat = !(flags & (Style_Raised | Style_Sunken)); + int x, y, w, h; + r.rect(&x, &y, &w, &h); + int x2 = x+w-1; + int y2 = y+h-1; + + if ( sunken ) + kDrawBeButton( p, x, y, w, h, cg, true, + &cg.brush(QColorGroup::Mid) ); + + else if ( flags & Style_MouseOver && !flat ) { + QBrush brush(cg.button().light(110)); + kDrawBeButton( p, x, y, w, h, cg, false, &brush ); + } + + // "Flat" button + else if ( flat ) { + if ( flags & Style_MouseOver ) + p->fillRect(r, cg.button().light(110)); + else + renderGradient(p, QRect(x, y, w-1, h-1), + cg.button(), false); + + p->setPen(cg.button().light(75)); + p->drawLine(x, y, x2, y); + p->drawLine(x, y, x, y2); + p->drawLine(x, y2, x2, y2); + p->drawLine(x2, y, x2, y2); + } + + else if( highcolor ) + { + int x2 = x+w-1; + int y2 = y+h-1; + p->setPen(cg.shadow()); + p->drawLine(x+1, y, x2-1, y); + p->drawLine(x+1, y2, x2-1, y2); + p->drawLine(x, y+1, x, y2-1); + p->drawLine(x2, y+1, x2, y2-1); + + p->setPen(cg.light()); + p->drawLine(x+2, y+2, x2-1, y+2); + p->drawLine(x+2, y+3, x2-2, y+3); + p->drawLine(x+2, y+4, x+2, y2-1); + p->drawLine(x+3, y+4, x+3, y2-2); + + p->setPen(cg.mid()); + p->drawLine(x2-1, y+2, x2-1, y2-1); + p->drawLine(x+2, y2-1, x2-1, y2-1); + + p->drawLine(x+1, y+1, x2-1, y+1); + p->drawLine(x+1, y+2, x+1, y2-1); + p->drawLine(x2-2, y+3, x2-2, y2-2); + + renderGradient(p, QRect(x+4, y+4, w-6, h-6), + cg.button(), false); + } else + kDrawBeButton(p, x, y, w, h, cg, false, + &cg.brush(QColorGroup::Button)); + break; + } + + + // BEVELS + // ------------------------------------------------------------------- + case PE_ButtonBevel: { + int x,y,w,h; + r.rect(&x, &y, &w, &h); + bool sunken = on || down; + int x2 = x+w-1; + int y2 = y+h-1; + + // Outer frame + p->setPen(cg.shadow()); + p->drawRect(r); + + // Bevel + p->setPen(sunken ? cg.mid() : cg.light()); + p->drawLine(x+1, y+1, x2-1, y+1); + p->drawLine(x+1, y+1, x+1, y2-1); + p->setPen(sunken ? cg.light() : cg.mid()); + p->drawLine(x+2, y2-1, x2-1, y2-1); + p->drawLine(x2-1, y+2, x2-1, y2-1); + + if (w > 4 && h > 4) { + if (sunken) + p->fillRect(x+2, y+2, w-4, h-4, cg.button()); + else + renderGradient( p, QRect(x+2, y+2, w-4, h-4), + cg.button(), flags & Style_Horizontal ); + } + break; + } + + + // FOCUS RECT + // ------------------------------------------------------------------- + case PE_FocusRect: { + p->drawWinFocusRect( r ); + break; + } + + + // HEADER SECTION + // ------------------------------------------------------------------- + case PE_HeaderSection: { + // Temporary solution for the proper orientation of gradients. + bool horizontal = true; + if (p && p->device()->devType() == QInternal::Widget) { + QHeader* hdr = dynamic_cast<QHeader*>(p->device()); + if (hdr) + horizontal = hdr->orientation() == Horizontal; + } + + int x,y,w,h; + r.rect(&x, &y, &w, &h); + bool sunken = on || down; + int x2 = x+w-1; + int y2 = y+h-1; + QPen oldPen = p->pen(); + + // Bevel + p->setPen(sunken ? cg.mid() : cg.light()); + p->drawLine(x, y, x2-1, y); + p->drawLine(x, y, x, y2-1); + p->setPen(sunken ? cg.light() : cg.mid()); + p->drawLine(x+1, y2-1, x2-1, y2-1); + p->drawLine(x2-1, y+1, x2-1, y2-1); + p->setPen(cg.shadow()); + p->drawLine(x, y2, x2, y2); + p->drawLine(x2, y, x2, y2); + + if (sunken) + p->fillRect(x+1, y+1, w-3, h-3, cg.button()); + else + renderGradient( p, QRect(x+1, y+1, w-3, h-3), + cg.button(), !horizontal ); + p->setPen( oldPen ); + break; + } + + + // SCROLLBAR + // ------------------------------------------------------------------- + case PE_ScrollBarSlider: { + // Small hack to ensure scrollbar gradients are drawn the right way. + flags ^= Style_Horizontal; + + drawPrimitive(PE_ButtonBevel, p, r, cg, flags | Style_Enabled | Style_Raised); + + // Draw a scrollbar riffle (note direction after above changes) + if ( type != B3 ) { + + // HighColor & Default scrollbar + if (flags & Style_Horizontal) { + if (r.height() >= 15) { + int x = r.x()+3; + int y = r.y() + (r.height()-7)/2; + int x2 = r.right()-3; + p->setPen(cg.light()); + p->drawLine(x, y, x2, y); + p->drawLine(x, y+3, x2, y+3); + p->drawLine(x, y+6, x2, y+6); + + p->setPen(cg.mid()); + p->drawLine(x, y+1, x2, y+1); + p->drawLine(x, y+4, x2, y+4); + p->drawLine(x, y+7, x2, y+7); + } + } else { + if (r.width() >= 15) { + int y = r.y()+3; + int x = r.x() + (r.width()-7)/2; + int y2 = r.bottom()-3; + p->setPen(cg.light()); + p->drawLine(x, y, x, y2); + p->drawLine(x+3, y, x+3, y2); + p->drawLine(x+6, y, x+6, y2); + + p->setPen(cg.mid()); + p->drawLine(x+1, y, x+1, y2); + p->drawLine(x+4, y, x+4, y2); + p->drawLine(x+7, y, x+7, y2); + } + } + } else { + + // B3 scrollbar + if (flags & Style_Horizontal) { + int buttons = 0; + + if (r.height() >= 36) buttons = 3; + else if (r.height() >=24) buttons = 2; + else if (r.height() >=16) buttons = 1; + + int x = r.x() + (r.width()-7) / 2; + int y = r.y() + (r.height() - (buttons * 5) - + (buttons-1)) / 2; + int x2 = x + 7; + + for ( int i=0; i<buttons; i++, y+=6 ) + { + p->setPen( cg.mid() ); + p->drawLine( x+1, y, x2-1, y ); + p->drawLine( x, y+1, x, y+3 ); + p->setPen( cg.light() ); + p->drawLine( x+1, y+1, x2-1, y+1 ); + p->drawLine( x+1, y+1, x+1, y+3 ); + p->setPen( cg.dark() ); + p->drawLine( x+1, y+4, x2-1, y+4 ); + p->drawLine( x2, y+1, x2, y+3 ); + } + } else { + int buttons = 0; + + if (r.width() >= 36) buttons = 3; + else if (r.width() >=24) buttons = 2; + else if (r.width() >=16) buttons = 1; + + int x = r.x() + (r.width() - (buttons * 5) - + (buttons-1)) / 2; + int y = r.y() + (r.height()-7) / 2; + int y2 = y + 7; + + for ( int i=0; i<buttons; i++, x+=6 ) + { + p->setPen( cg.mid() ); + p->drawLine( x+1, y, x+3, y ); + p->drawLine( x, y+1, x, y2-1 ); + p->setPen( cg.light() ); + p->drawLine( x+1, y+1, x+3, y+1 ); + p->drawLine( x+1, y+1, x+1, y2-1 ); + p->setPen( cg.dark() ); + p->drawLine( x+1, y2, x+3, y2 ); + p->drawLine( x+4, y+1, x+4, y2-1 ); + } + } + } + break; + } + + + case PE_ScrollBarAddPage: + case PE_ScrollBarSubPage: { + int x, y, w, h; + r.rect(&x, &y, &w, &h); + int x2 = x+w-1; + int y2 = y+h-1; + + if ( type != B3 ) { + // HighColor & Default scrollbar + + p->setPen(cg.shadow()); + + if (flags & Style_Horizontal) { + p->drawLine(x, y, x2, y); + p->drawLine(x, y2, x2, y2); + renderGradient(p, QRect(x, y+1, w, h-2), + cg.mid(), false); + } else { + p->drawLine(x, y, x, y2); + p->drawLine(x2, y, x2, y2); + renderGradient(p, QRect(x+1, y, w-2, h), + cg.mid(), true); + } + } else { + // B3 scrollbar + + p->setPen( cg.mid() ); + + if (flags & Style_Horizontal) { + p->drawLine(x, y, x2, y); + p->drawLine(x, y2, x2, y2); + p->fillRect( QRect(x, y+1, w, h-2), + flags & Style_Down ? cg.button() : cg.midlight() ); + } else { + p->drawLine(x, y, x, y2); + p->drawLine(x2, y, x2, y2); + p->fillRect( QRect(x+1, y, w-2, h), + flags & Style_Down ? cg.button() : cg.midlight() ); + } + } + break; + } + + + case PE_ScrollBarAddLine: { + drawPrimitive( PE_ButtonBevel, p, r, cg, (flags & Style_Enabled) | + ((flags & Style_Down) ? Style_Down : Style_Raised) ); + + drawPrimitive( ((flags & Style_Horizontal) ? PE_ArrowRight : PE_ArrowDown), + p, r, cg, flags ); + break; + } + + + case PE_ScrollBarSubLine: { + drawPrimitive( PE_ButtonBevel, p, r, cg, (flags & Style_Enabled) | + ((flags & Style_Down) ? Style_Down : Style_Raised) ); + + drawPrimitive( ((flags & Style_Horizontal) ? PE_ArrowLeft : PE_ArrowUp), + p, r, cg, flags ); + break; + } + + + // CHECKBOX (indicator) + // ------------------------------------------------------------------- + case PE_Indicator: { + + bool enabled = flags & Style_Enabled; + bool nochange = flags & Style_NoChange; + + if (xBmp.isNull()) { + xBmp = QBitmap(7, 7, x_bits, true); + xBmp.setMask(xBmp); + } + + int x,y,w,h; + x=r.x(); y=r.y(); w=r.width(); h=r.height(); + int x2 = x+w-1; + int y2 = y+h-1; + + p->setPen(cg.mid()); + p->drawLine(x, y, x2, y); + p->drawLine(x, y, x, y2); + + p->setPen(cg.light()); + p->drawLine(x2, y+1, x2, y2); + p->drawLine(x+1, y2, x2, y2); + + p->setPen(cg.shadow()); + p->drawLine(x+1, y+1, x2-1, y+1); + p->drawLine(x+1, y+1, x+1, y2-1); + + p->setPen(cg.midlight()); + p->drawLine(x2-1, y+2, x2-1, y2-1); + p->drawLine(x+2, y2-1, x2-1, y2-1); + + if ( enabled ) + p->fillRect(x+2, y+2, w-4, h-4, + down ? cg.button(): cg.base()); + else + p->fillRect(x+2, y+2, w-4, h-4, cg.background()); + + if (!(flags & Style_Off)) { + if (on) { + p->setPen(nochange ? cg.dark() : cg.text()); + p->drawPixmap(x+3, y+3, xBmp); + } + else { + p->setPen(cg.shadow()); + p->drawRect(x+2, y+2, w-4, h-4); + p->setPen(nochange ? cg.text() : cg.dark()); + p->drawLine(x+3, (y+h)/2-2, x+w-4, (y+h)/2-2); + p->drawLine(x+3, (y+h)/2, x+w-4, (y+h)/2); + p->drawLine(x+3, (y+h)/2+2, x+w-4, (y+h)/2+2); + } + } + break; + } + + + // RADIOBUTTON (exclusive indicator) + // ------------------------------------------------------------------- + case PE_ExclusiveIndicator: { + + if (lightBmp.isNull()) { + lightBmp = QBitmap(13, 13, radiooff_light_bits, true); + grayBmp = QBitmap(13, 13, radiooff_gray_bits, true); + dgrayBmp = QBitmap(13, 13, radiooff_dgray_bits, true); + centerBmp = QBitmap(13, 13, radiooff_center_bits, true); + centerBmp.setMask( centerBmp ); + } + + // Bevel + kColorBitmaps(p, cg, r.x(), r.y(), &lightBmp , &grayBmp, + NULL, &dgrayBmp); + + // The center fill of the indicator (grayed out when disabled) + if ( flags & Style_Enabled ) + p->setPen( down ? cg.button() : cg.base() ); + else + p->setPen( cg.background() ); + p->drawPixmap( r.x(), r.y(), centerBmp ); + + // Indicator "dot" + if ( on ) { + QColor color = flags & Style_NoChange ? + cg.dark() : cg.text(); + + p->setPen(color); + p->drawLine(5, 4, 7, 4); + p->drawLine(4, 5, 4, 7); + p->drawLine(5, 8, 7, 8); + p->drawLine(8, 5, 8, 7); + p->fillRect(5, 5, 3, 3, color); + } + + break; + } + + + // RADIOBUTTON (exclusive indicator) mask + // ------------------------------------------------------------------- + case PE_ExclusiveIndicatorMask: { + if (maskBmp.isNull()) { + maskBmp = QBitmap(13, 13, radiomask_bits, true); + maskBmp.setMask(maskBmp); + } + + p->setPen(Qt::color1); + p->drawPixmap(r.x(), r.y(), maskBmp); + break; + } + + + // SPLITTER/DOCKWINDOW HANDLES + // ------------------------------------------------------------------- + case PE_DockWindowResizeHandle: + case PE_Splitter: { + int x,y,w,h; + r.rect(&x, &y, &w, &h); + int x2 = x+w-1; + int y2 = y+h-1; + + p->setPen(cg.dark()); + p->drawRect(x, y, w, h); + p->setPen(cg.background()); + p->drawPoint(x, y); + p->drawPoint(x2, y); + p->drawPoint(x, y2); + p->drawPoint(x2, y2); + p->setPen(cg.light()); + p->drawLine(x+1, y+1, x+1, y2-1); + p->drawLine(x+1, y+1, x2-1, y+1); + p->setPen(cg.midlight()); + p->drawLine(x+2, y+2, x+2, y2-2); + p->drawLine(x+2, y+2, x2-2, y+2); + p->setPen(cg.mid()); + p->drawLine(x2-1, y+1, x2-1, y2-1); + p->drawLine(x+1, y2-1, x2-1, y2-1); + p->fillRect(x+3, y+3, w-5, h-5, cg.brush(QColorGroup::Background)); + break; + } + + + // GENERAL PANELS + // ------------------------------------------------------------------- + case PE_Panel: + case PE_PanelPopup: + case PE_WindowFrame: + case PE_PanelLineEdit: { + bool sunken = flags & Style_Sunken; + int lw = opt.isDefault() ? pixelMetric(PM_DefaultFrameWidth) + : opt.lineWidth(); + if (lw == 2) + { + QPen oldPen = p->pen(); + int x,y,w,h; + r.rect(&x, &y, &w, &h); + int x2 = x+w-1; + int y2 = y+h-1; + p->setPen(sunken ? cg.light() : cg.dark()); + p->drawLine(x, y2, x2, y2); + p->drawLine(x2, y, x2, y2); + p->setPen(sunken ? cg.mid() : cg.light()); + p->drawLine(x, y, x2, y); + p->drawLine(x, y, x, y2); + p->setPen(sunken ? cg.midlight() : cg.mid()); + p->drawLine(x+1, y2-1, x2-1, y2-1); + p->drawLine(x2-1, y+1, x2-1, y2-1); + p->setPen(sunken ? cg.dark() : cg.midlight()); + p->drawLine(x+1, y+1, x2-1, y+1); + p->drawLine(x+1, y+1, x+1, y2-1); + p->setPen(oldPen); + } else + KStyle::drawPrimitive(pe, p, r, cg, flags, opt); + + break; + } + + + // MENU / TOOLBAR PANEL + // ------------------------------------------------------------------- + case PE_PanelMenuBar: // Menu + case PE_PanelDockWindow: { // Toolbar + int x2 = r.x()+r.width()-1; + int y2 = r.y()+r.height()-1; + int lw = opt.isDefault() ? pixelMetric(PM_DefaultFrameWidth) + : opt.lineWidth(); + + if (lw) + { + p->setPen(cg.light()); + p->drawLine(r.x(), r.y(), x2-1, r.y()); + p->drawLine(r.x(), r.y(), r.x(), y2-1); + p->setPen(cg.dark()); + p->drawLine(r.x(), y2, x2, y2); + p->drawLine(x2, r.y(), x2, y2); + + // ### Qt should specify Style_Horizontal where appropriate + renderGradient( p, QRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2), + cg.button(), + (r.width() < r.height()) && (pe != PE_PanelMenuBar) ); + } + else + renderGradient( p, r, cg.button(), + (r.width() < r.height()) && (pe != PE_PanelMenuBar) ); + + break; + } + + + + // TOOLBAR SEPARATOR + // ------------------------------------------------------------------- + case PE_DockWindowSeparator: { + renderGradient( p, r, cg.button(), + !(flags & Style_Horizontal)); + if ( !(flags & Style_Horizontal) ) { + p->setPen(cg.mid()); + p->drawLine(4, r.height()/2, r.width()-5, r.height()/2); + p->setPen(cg.light()); + p->drawLine(4, r.height()/2+1, r.width()-5, r.height()/2+1); + } else { + p->setPen(cg.mid()); + p->drawLine(r.width()/2, 4, r.width()/2, r.height()-5); + p->setPen(cg.light()); + p->drawLine(r.width()/2+1, 4, r.width()/2+1, r.height()-5); + } + break; + } + + + default: + { + // ARROWS + // ------------------------------------------------------------------- + if (pe >= PE_ArrowUp && pe <= PE_ArrowLeft) + { + QPointArray a; + + if ( type != B3 ) { + // HighColor & Default arrows + switch(pe) { + case PE_ArrowUp: + a.setPoints(QCOORDARRLEN(u_arrow), u_arrow); + break; + + case PE_ArrowDown: + a.setPoints(QCOORDARRLEN(d_arrow), d_arrow); + break; + + case PE_ArrowLeft: + a.setPoints(QCOORDARRLEN(l_arrow), l_arrow); + break; + + default: + a.setPoints(QCOORDARRLEN(r_arrow), r_arrow); + } + } else { + // B3 arrows + switch(pe) { + case PE_ArrowUp: + a.setPoints(QCOORDARRLEN(B3::u_arrow), B3::u_arrow); + break; + + case PE_ArrowDown: + a.setPoints(QCOORDARRLEN(B3::d_arrow), B3::d_arrow); + break; + + case PE_ArrowLeft: + a.setPoints(QCOORDARRLEN(B3::l_arrow), B3::l_arrow); + break; + + default: + a.setPoints(QCOORDARRLEN(B3::r_arrow), B3::r_arrow); + } + } + + p->save(); + if ( flags & Style_Down ) + p->translate( pixelMetric( PM_ButtonShiftHorizontal ), + pixelMetric( PM_ButtonShiftVertical ) ); + + if ( flags & Style_Enabled ) { + a.translate( r.x() + r.width() / 2, r.y() + r.height() / 2 ); + p->setPen( cg.buttonText() ); + p->drawLineSegments( a ); + } else { + a.translate( r.x() + r.width() / 2 + 1, r.y() + r.height() / 2 + 1 ); + p->setPen( cg.light() ); + p->drawLineSegments( a ); + a.translate( -1, -1 ); + p->setPen( cg.mid() ); + p->drawLineSegments( a ); + } + p->restore(); + + } else + KStyle::drawPrimitive( pe, p, r, cg, flags, opt ); + } + } +} + + +void HighColorStyle::drawKStylePrimitive( KStylePrimitive kpe, + QPainter* p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption &opt ) const +{ + switch ( kpe ) + { + // TOOLBAR HANDLE + // ------------------------------------------------------------------- + case KPE_ToolBarHandle: { + int x = r.x(); int y = r.y(); + int x2 = r.x() + r.width()-1; + int y2 = r.y() + r.height()-1; + + if (flags & Style_Horizontal) { + + renderGradient( p, r, cg.button(), false); + p->setPen(cg.light()); + p->drawLine(x+1, y+4, x+1, y2-4); + p->drawLine(x+3, y+4, x+3, y2-4); + p->drawLine(x+5, y+4, x+5, y2-4); + + p->setPen(cg.mid()); + p->drawLine(x+2, y+4, x+2, y2-4); + p->drawLine(x+4, y+4, x+4, y2-4); + p->drawLine(x+6, y+4, x+6, y2-4); + + } else { + + renderGradient( p, r, cg.button(), true); + p->setPen(cg.light()); + p->drawLine(x+4, y+1, x2-4, y+1); + p->drawLine(x+4, y+3, x2-4, y+3); + p->drawLine(x+4, y+5, x2-4, y+5); + + p->setPen(cg.mid()); + p->drawLine(x+4, y+2, x2-4, y+2); + p->drawLine(x+4, y+4, x2-4, y+4); + p->drawLine(x+4, y+6, x2-4, y+6); + + } + break; + } + + + // GENERAL/KICKER HANDLE + // ------------------------------------------------------------------- + case KPE_GeneralHandle: { + int x = r.x(); int y = r.y(); + int x2 = r.x() + r.width()-1; + int y2 = r.y() + r.height()-1; + + if (flags & Style_Horizontal) { + + p->setPen(cg.light()); + p->drawLine(x+1, y, x+1, y2); + p->drawLine(x+3, y, x+3, y2); + p->drawLine(x+5, y, x+5, y2); + + p->setPen(cg.mid()); + p->drawLine(x+2, y, x+2, y2); + p->drawLine(x+4, y, x+4, y2); + p->drawLine(x+6, y, x+6, y2); + + } else { + + p->setPen(cg.light()); + p->drawLine(x, y+1, x2, y+1); + p->drawLine(x, y+3, x2, y+3); + p->drawLine(x, y+5, x2, y+5); + + p->setPen(cg.mid()); + p->drawLine(x, y+2, x2, y+2); + p->drawLine(x, y+4, x2, y+4); + p->drawLine(x, y+6, x2, y+6); + + } + break; + } + + + // SLIDER GROOVE + // ------------------------------------------------------------------- + case KPE_SliderGroove: { + const QSlider* slider = (const QSlider*)widget; + bool horizontal = slider->orientation() == Horizontal; + int gcenter = (horizontal ? r.height() : r.width()) / 2; + + QRect gr; + if (horizontal) + gr = QRect(r.x(), r.y()+gcenter-3, r.width(), 7); + else + gr = QRect(r.x()+gcenter-3, r.y(), 7, r.height()); + + int x,y,w,h; + gr.rect(&x, &y, &w, &h); + int x2=x+w-1; + int y2=y+h-1; + + // Draw the slider groove. + p->setPen(cg.dark()); + p->drawLine(x+2, y, x2-2, y); + p->drawLine(x, y+2, x, y2-2); + p->fillRect(x+2,y+2,w-4, h-4, + slider->isEnabled() ? cg.dark() : cg.mid()); + p->setPen(cg.shadow()); + p->drawRect(x+1, y+1, w-2, h-2); + p->setPen(cg.light()); + p->drawPoint(x+1,y2-1); + p->drawPoint(x2-1,y2-1); + p->drawLine(x2, y+2, x2, y2-2); + p->drawLine(x+2, y2, x2-2, y2); + break; + } + + // SLIDER HANDLE + // ------------------------------------------------------------------- + case KPE_SliderHandle: { + const QSlider* slider = (const QSlider*)widget; + bool horizontal = slider->orientation() == Horizontal; + int x,y,w,h; + r.rect(&x, &y, &w, &h); + int x2 = x+w-1; + int y2 = y+h-1; + + p->setPen(cg.mid()); + p->drawLine(x+1, y, x2-1, y); + p->drawLine(x, y+1, x, y2-1); + p->setPen(cg.shadow()); + p->drawLine(x+1, y2, x2-1, y2); + p->drawLine(x2, y+1, x2, y2-1); + + p->setPen(cg.light()); + p->drawLine(x+1, y+1, x2-1, y+1); + p->drawLine(x+1, y+1, x+1, y2-1); + p->setPen(cg.dark()); + p->drawLine(x+2, y2-1, x2-1, y2-1); + p->drawLine(x2-1, y+2, x2-1, y2-1); + p->setPen(cg.midlight()); + p->drawLine(x+2, y+2, x2-2, y+2); + p->drawLine(x+2, y+2, x+2, y2-2); + p->setPen(cg.mid()); + p->drawLine(x+3, y2-2, x2-2, y2-2); + p->drawLine(x2-2, y+3, x2-2, y2-2); + renderGradient(p, QRect(x+3, y+3, w-6, h-6), + cg.button(), !horizontal); + + // Paint riffles + if (horizontal) { + p->setPen(cg.light()); + p->drawLine(x+5, y+4, x+5, y2-4); + p->drawLine(x+8, y+4, x+8, y2-4); + p->drawLine(x+11,y+4, x+11, y2-4); + p->setPen(slider->isEnabled() ? cg.shadow(): cg.mid()); + p->drawLine(x+6, y+4, x+6, y2-4); + p->drawLine(x+9, y+4, x+9, y2-4); + p->drawLine(x+12,y+4, x+12, y2-4); + } else { + p->setPen(cg.light()); + p->drawLine(x+4, y+5, x2-4, y+5); + p->drawLine(x+4, y+8, x2-4, y+8); + p->drawLine(x+4, y+11, x2-4, y+11); + p->setPen(slider->isEnabled() ? cg.shadow() : cg.mid()); + p->drawLine(x+4, y+6, x2-4, y+6); + p->drawLine(x+4, y+9, x2-4, y+9); + p->drawLine(x+4, y+12, x2-4, y+12); + } + break; + } + + default: + KStyle::drawKStylePrimitive( kpe, p, widget, r, cg, flags, opt); + } +} + + +void HighColorStyle::drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + switch (element) + { + // PUSHBUTTON + // ------------------------------------------------------------------- + case CE_PushButton: { + if ( widget == hoverWidget ) + flags |= Style_MouseOver; + + if ( type != HighColor ) { + QPushButton *button = (QPushButton*) widget; + QRect br = r; + bool btnDefault = button->isDefault(); + + if ( btnDefault || button->autoDefault() ) { + // Compensate for default indicator + static int di = pixelMetric( PM_ButtonDefaultIndicator ); + br.addCoords( di, di, -di, -di ); + } + + if ( btnDefault ) + drawPrimitive( PE_ButtonDefault, p, r, cg, flags ); + + drawPrimitive( PE_ButtonCommand, p, br, cg, flags ); + + } else + drawPrimitive( PE_ButtonCommand, p, r, cg, flags ); + + break; + } + + + // PUSHBUTTON LABEL + // ------------------------------------------------------------------- + case CE_PushButtonLabel: { + const QPushButton* button = (const QPushButton*)widget; + bool active = button->isOn() || button->isDown(); + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + // Shift button contents if pushed. + if ( active ) { + x += pixelMetric(PM_ButtonShiftHorizontal, widget); + y += pixelMetric(PM_ButtonShiftVertical, widget); + flags |= Style_Sunken; + } + + // Does the button have a popup menu? + if ( button->isMenuButton() ) { + int dx = pixelMetric( PM_MenuButtonIndicator, widget ); + drawPrimitive( PE_ArrowDown, p, QRect(x + w - dx - 2, y + 2, dx, h - 4), + cg, flags, opt ); + w -= dx; + } + + // Draw the icon if there is one + if ( button->iconSet() && !button->iconSet()->isNull() ) { + QIconSet::Mode mode = QIconSet::Disabled; + QIconSet::State state = QIconSet::Off; + + if (button->isEnabled()) + mode = button->hasFocus() ? QIconSet::Active : QIconSet::Normal; + if (button->isToggleButton() && button->isOn()) + state = QIconSet::On; + + QPixmap pixmap = button->iconSet()->pixmap( QIconSet::Small, mode, state ); + + // Center the iconset if there's no text or pixmap + if (button->text().isEmpty() && !button->pixmap()) + p->drawPixmap( x + (w - pixmap.width()) / 2, + y + (h - pixmap.height()) / 2, pixmap ); + else + p->drawPixmap( x + 4, y + (h - pixmap.height()) / 2, pixmap ); + + int pw = pixmap.width(); + x += pw + 4; + w -= pw + 4; + } + + // Make the label indicate if the button is a default button or not + if ( active || button->isDefault() ) { + // Draw "fake" bold text - this enables the font metrics to remain + // the same as computed in QPushButton::sizeHint(), but gives + // a reasonable bold effect. + int i; + + // Text shadow + if (button->isEnabled()) // Don't draw double-shadow when disabled + for(i=0; i<2; i++) + drawItem( p, QRect(x+i+1, y+1, w, h), AlignCenter | ShowPrefix, + button->colorGroup(), button->isEnabled(), NULL, + button->text(), -1, + active ? &button->colorGroup().dark() : &button->colorGroup().mid() ); + + // Normal Text + for(i=0; i<2; i++) + drawItem( p, QRect(x+i, y, w, h), AlignCenter | ShowPrefix, + button->colorGroup(), button->isEnabled(), i == 0 ? button->pixmap() : NULL, + button->text(), -1, + active ? &button->colorGroup().light() : &button->colorGroup().buttonText() ); + } else + drawItem( p, QRect(x, y, w, h), AlignCenter | ShowPrefix, button->colorGroup(), + button->isEnabled(), button->pixmap(), button->text(), -1, + active ? &button->colorGroup().light() : &button->colorGroup().buttonText() ); + + // Draw a focus rect if the button has focus + if ( flags & Style_HasFocus ) + drawPrimitive( PE_FocusRect, p, + QStyle::visualRect(subRect(SR_PushButtonFocusRect, widget), widget), + cg, flags ); + break; + } + + // TOOLBOX TAB + // ------------------------------------------------------------------- + case CE_ToolBoxTab: + { + bool pressed = flags & Style_Down; + bool selected = flags & Style_Selected; + int x, y, x2, y2; + r.coords( &x, &y, &x2, &y2 ); + + p->setPen( pressed ? cg.shadow() : cg.light() ); + p->drawLine( x, y, x2-1, y ); + p->drawLine( x, y, x, y2-1 ); + + p->setPen( pressed ? cg.light() : cg.shadow() ); + p->drawLine( x, y2, x2, y2 ); + p->drawLine( x2, y, x2, y2 ); + + QColor fill = selected ? cg.highlight() : cg.button(); + selectionBackground = selected; + + if ( pressed ) + p->fillRect( QRect(x+1, y+1, r.width()-2, r.height()-2), fill ); + else + renderGradient(p, QRect(x+1, y+1, r.width()-2, r.height()-2), + fill, false); + break; + } + + // MENUBAR BACKGROUND + // ------------------------------------------------------------------- + case CE_MenuBarEmptyArea: + { + renderGradient(p, r, cg.button(), false); + break; + } + + // MENUBAR ITEM (sunken panel on mouse over) + // ------------------------------------------------------------------- + case CE_MenuBarItem: + { + QMenuBar *mb = (QMenuBar*)widget; + QMenuItem *mi = opt.menuItem(); + QRect pr = mb->rect(); + + bool active = flags & Style_Active; + bool focused = flags & Style_HasFocus; + + if ( active && focused ) + qDrawShadePanel(p, r.x(), r.y(), r.width(), r.height(), + cg, true, 1, &cg.brush(QColorGroup::Midlight)); + else + renderGradient( p, r, cg.button(), false, + r.x(), r.y()-1, pr.width()-2, pr.height()-2); + + drawItem( p, r, AlignCenter | AlignVCenter | ShowPrefix + | DontClip | SingleLine, cg, flags & Style_Enabled, + mi->pixmap(), mi->text() ); + + break; + } + + + // POPUPMENU ITEM + // ------------------------------------------------------------------- + case CE_PopupMenuItem: { + const QPopupMenu *popupmenu = (const QPopupMenu *) widget; + + QMenuItem *mi = opt.menuItem(); + if ( !mi ) { + // Don't leave blank holes if we set NoBackground for the QPopupMenu. + // This only happens when the popupMenu spans more than one column. + if (! (widget->erasePixmap() && !widget->erasePixmap()->isNull()) ) + p->fillRect(r, cg.brush(QColorGroup::Button) ); + break; + } + + int tab = opt.tabWidth(); + int checkcol = opt.maxIconWidth(); + bool enabled = mi->isEnabled(); + bool checkable = popupmenu->isCheckable(); + bool active = flags & Style_Active; + bool etchtext = styleHint( SH_EtchDisabledText ); + bool reverse = QApplication::reverseLayout(); + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + if ( checkable ) + checkcol = QMAX( checkcol, 20 ); + + // Are we a menu item separator? + if ( mi->isSeparator() ) { + p->setPen( cg.dark() ); + p->drawLine( x, y, x+w, y ); + p->setPen( cg.light() ); + p->drawLine( x, y+1, x+w, y+1 ); + break; + } + + // Draw the menu item background + if ( active ) + qDrawShadePanel( p, x, y, w, h, cg, true, 1, + &cg.brush(QColorGroup::Midlight) ); + // Draw the transparency pixmap + else if ( widget->erasePixmap() && !widget->erasePixmap()->isNull() ) + p->drawPixmap( x, y, *widget->erasePixmap(), x, y, w, h ); + // Draw a solid background + else + p->fillRect( r, cg.button() ); + + // Do we have an icon? + if ( mi->iconSet() ) { + QIconSet::Mode mode; + QRect cr = visualRect( QRect(x, y, checkcol, h), r ); + + // Select the correct icon from the iconset + if ( active ) + mode = enabled ? QIconSet::Active : QIconSet::Disabled; + else + mode = enabled ? QIconSet::Normal : QIconSet::Disabled; + + // Do we have an icon and are checked at the same time? + // Then draw a "pressed" background behind the icon + if ( checkable && !active && mi->isChecked() ) + qDrawShadePanel( p, cr.x(), cr.y(), cr.width(), cr.height(), + cg, true, 1, &cg.brush(QColorGroup::Midlight) ); + // Draw the icon + QPixmap pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode ); + QRect pmr( 0, 0, pixmap.width(), pixmap.height() ); + pmr.moveCenter( cr.center() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + } + + // Are we checked? (This time without an icon) + else if ( checkable && mi->isChecked() ) { + int cx = reverse ? x+w - checkcol : x; + + // We only have to draw the background if the menu item is inactive - + // if it's active the "pressed" background is already drawn + if ( ! active ) + qDrawShadePanel( p, cx, y, checkcol, h, cg, true, 1, + &cg.brush(QColorGroup::Midlight) ); + + // Draw the checkmark + SFlags cflags = Style_Default; + cflags |= active ? Style_Enabled : Style_On; + + drawPrimitive( PE_CheckMark, p, QRect( cx + itemFrame, y + itemFrame, + checkcol - itemFrame*2, h - itemFrame*2), cg, cflags ); + } + + // Time to draw the menu item label... + int xm = itemFrame + checkcol + itemHMargin; // X position margin + + int xp = reverse ? // X position + x + tab + rightBorder + itemHMargin + itemFrame - 1 : + x + xm; + + int offset = reverse ? -1 : 1; // Shadow offset for etched text + + // Label width (minus the width of the accelerator portion) + int tw = w - xm - tab - arrowHMargin - itemHMargin * 3 - itemFrame + 1; + + // Set the color for enabled and disabled text + // (used for both active and inactive menu items) + p->setPen( enabled ? cg.buttonText() : cg.mid() ); + + // This color will be used instead of the above if the menu item + // is active and disabled at the same time. (etched text) + QColor discol = cg.mid(); + + // Does the menu item draw it's own label? + if ( mi->custom() ) { + int m = itemVMargin; + // Save the painter state in case the custom + // paint method changes it in some way + p->save(); + + // Draw etched text if we're inactive and the menu item is disabled + if ( etchtext && !enabled && !active ) { + p->setPen( cg.light() ); + mi->custom()->paint( p, cg, active, enabled, xp+offset, y+m+1, tw, h-2*m ); + p->setPen( discol ); + } + mi->custom()->paint( p, cg, active, enabled, xp, y+m, tw, h-2*m ); + p->restore(); + } + else { + // The menu item doesn't draw it's own label + QString s = mi->text(); + + // Does the menu item have a text label? + if ( !s.isNull() ) { + int t = s.find( '\t' ); + int m = itemVMargin; + int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine; + text_flags |= reverse ? AlignRight : AlignLeft; + + // Does the menu item have a tabstop? (for the accelerator text) + if ( t >= 0 ) { + int tabx = reverse ? x + rightBorder + itemHMargin + itemFrame : + x + w - tab - rightBorder - itemHMargin - itemFrame; + + // Draw the right part of the label (accelerator text) + if ( etchtext && !enabled && !active ) { + // Draw etched text if we're inactive and the menu item is disabled + p->setPen( cg.light() ); + p->drawText( tabx+offset, y+m+1, tab, h-2*m, text_flags, s.mid( t+1 ) ); + p->setPen( discol ); + } + p->drawText( tabx, y+m, tab, h-2*m, text_flags, s.mid( t+1 ) ); + s = s.left( t ); + } + + // Draw the left part of the label (or the whole label + // if there's no accelerator) + if ( etchtext && !enabled && !active ) { + // Etched text again for inactive disabled menu items... + p->setPen( cg.light() ); + p->drawText( xp+offset, y+m+1, tw, h-2*m, text_flags, s, t ); + p->setPen( discol ); + } + + p->drawText( xp, y+m, tw, h-2*m, text_flags, s, t ); + + } + + // The menu item doesn't have a text label + // Check if it has a pixmap instead + else if ( mi->pixmap() ) { + QPixmap *pixmap = mi->pixmap(); + + // Draw the pixmap + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( OpaqueMode ); + + int diffw = ( ( w - pixmap->width() ) / 2 ) + + ( ( w - pixmap->width() ) % 2 ); + p->drawPixmap( x+diffw, y+itemFrame, *pixmap ); + + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( TransparentMode ); + } + } + + // Does the menu item have a submenu? + if ( mi->popup() ) { + PrimitiveElement arrow = reverse ? PE_ArrowLeft : PE_ArrowRight; + int dim = pixelMetric(PM_MenuButtonIndicator); + QRect vr = visualRect( QRect( x + w - arrowHMargin - 2*itemFrame - dim, + y + h / 2 - dim / 2, dim, dim), r ); + + // Draw an arrow at the far end of the menu item + if ( active ) { + if ( enabled ) + discol = cg.buttonText(); + + QColorGroup g2( discol, cg.highlight(), white, white, + enabled ? white : discol, discol, white ); + + drawPrimitive( arrow, p, vr, g2, Style_Enabled ); + } else + drawPrimitive( arrow, p, vr, cg, + enabled ? Style_Enabled : Style_Default ); + } + break; + } + + default: + KStyle::drawControl(element, p, widget, r, cg, flags, opt); + } +} + + +void HighColorStyle::drawControlMask( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& opt ) const +{ + switch (element) + { + // PUSHBUTTON MASK + // ---------------------------------------------------------------------- + case CE_PushButton: { + int x1, y1, x2, y2; + r.coords( &x1, &y1, &x2, &y2 ); + QCOORD corners[] = { x1,y1, x2,y1, x1,y2, x2,y2 }; + p->fillRect( r, color1 ); + p->setPen( color0 ); + p->drawPoints( QPointArray(4, corners) ); + break; + } + + default: + KStyle::drawControlMask(element, p, widget, r, opt); + } +} + + +void HighColorStyle::drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + SCFlags controls, + SCFlags active, + const QStyleOption& opt ) const +{ + switch(control) + { + // COMBOBOX + // ------------------------------------------------------------------- + case CC_ComboBox: { + + // Draw box and arrow + if ( controls & SC_ComboBoxArrow ) { + bool sunken = (active == SC_ComboBoxArrow); + + // Draw the combo + int x,y,w,h; + r.rect(&x, &y, &w, &h); + int x2 = x+w-1; + int y2 = y+h-1; + + p->setPen(cg.shadow()); + p->drawLine(x+1, y, x2-1, y); + p->drawLine(x+1, y2, x2-1, y2); + p->drawLine(x, y+1, x, y2-1); + p->drawLine(x2, y+1, x2, y2-1); + + // Ensure the edge notches are properly colored + p->setPen(cg.button()); + p->drawPoint(x,y); + p->drawPoint(x,y2); + p->drawPoint(x2,y); + p->drawPoint(x2,y2); + + renderGradient( p, QRect(x+2, y+2, w-4, h-4), + cg.button(), false); + + p->setPen(sunken ? cg.light() : cg.mid()); + p->drawLine(x2-1, y+2, x2-1, y2-1); + p->drawLine(x+1, y2-1, x2-1, y2-1); + + p->setPen(sunken ? cg.mid() : cg.light()); + p->drawLine(x+1, y+1, x2-1, y+1); + p->drawLine(x+1, y+2, x+1, y2-2); + + // Get the button bounding box + QRect ar = QStyle::visualRect( + querySubControlMetrics(CC_ComboBox, widget, SC_ComboBoxArrow), + widget ); + + // Are we enabled? + if ( widget->isEnabled() ) + flags |= Style_Enabled; + + // Are we "pushed" ? + if ( active & Style_Sunken ) + flags |= Style_Sunken; + + drawPrimitive(PE_ArrowDown, p, ar, cg, flags); + } + + // Draw an edit field if required + if ( controls & SC_ComboBoxEditField ) + { + const QComboBox * cb = (const QComboBox *) widget; + QRect re = QStyle::visualRect( + querySubControlMetrics( CC_ComboBox, widget, + SC_ComboBoxEditField), widget ); + + // Draw the indent + if (cb->editable()) { + p->setPen( cg.dark() ); + p->drawLine( re.x(), re.y()-1, re.x()+re.width(), re.y()-1 ); + p->drawLine( re.x()-1, re.y(), re.x()-1, re.y()+re.height() ); + } + + if ( cb->hasFocus() ) { + p->setPen( cg.highlightedText() ); + p->setBackgroundColor( cg.highlight() ); + } else { + p->setPen( cg.text() ); + p->setBackgroundColor( cg.button() ); + } + + if ( cb->hasFocus() && !cb->editable() ) { + // Draw the contents + p->fillRect( re.x(), re.y(), re.width(), re.height(), + cg.brush( QColorGroup::Highlight ) ); + + QRect re = QStyle::visualRect( + subRect(SR_ComboBoxFocusRect, cb), widget); + + drawPrimitive( PE_FocusRect, p, re, cg, + Style_FocusAtBorder, QStyleOption(cg.highlight())); + } + } + break; + } + + // TOOLBUTTON + // ------------------------------------------------------------------- + case CC_ToolButton: { + const QToolButton *toolbutton = (const QToolButton *) widget; + + QRect button, menuarea; + button = querySubControlMetrics(control, widget, SC_ToolButton, opt); + menuarea = querySubControlMetrics(control, widget, SC_ToolButtonMenu, opt); + + SFlags bflags = flags, + mflags = flags; + + if (active & SC_ToolButton) + bflags |= Style_Down; + if (active & SC_ToolButtonMenu) + mflags |= Style_Down; + + if (controls & SC_ToolButton) + { + // If we're pressed, on, or raised... + if (bflags & (Style_Down | Style_On | Style_Raised)) + drawPrimitive(PE_ButtonTool, p, button, cg, bflags, opt); + + // Check whether to draw a background pixmap + else if ( toolbutton->parentWidget() && + toolbutton->parentWidget()->backgroundPixmap() && + !toolbutton->parentWidget()->backgroundPixmap()->isNull() ) + { + QPixmap pixmap = *(toolbutton->parentWidget()->backgroundPixmap()); + p->drawTiledPixmap( r, pixmap, toolbutton->pos() ); + } + else if (widget->parent()) + { + if (widget->parent()->inherits("QToolBar")) + { + QToolBar* parent = (QToolBar*)widget->parent(); + QRect pr = parent->rect(); + + renderGradient( p, r, cg.button(), + parent->orientation() == Qt::Vertical, + r.x(), r.y(), pr.width()-2, pr.height()-2); + } + else if (widget->parent()->inherits("QToolBarExtensionWidget")) + { + QWidget* parent = (QWidget*)widget->parent(); + QToolBar* toolbar = (QToolBar*)parent->parent(); + QRect tr = toolbar->rect(); + + if ( toolbar->orientation() == Qt::Horizontal ) { + renderGradient( p, r, cg.button(), false, r.x(), r.y(), + r.width(), tr.height() ); + } else { + renderGradient( p, r, cg.button(), true, r.x(), r.y(), + tr.width(), r.height() ); + } + } + } + } + + // Draw a toolbutton menu indicator if required + if (controls & SC_ToolButtonMenu) + { + if (mflags & (Style_Down | Style_On | Style_Raised)) + drawPrimitive(PE_ButtonDropDown, p, menuarea, cg, mflags, opt); + drawPrimitive(PE_ArrowDown, p, menuarea, cg, mflags, opt); + } + + if (toolbutton->hasFocus() && !toolbutton->focusProxy()) { + QRect fr = toolbutton->rect(); + fr.addCoords(3, 3, -3, -3); + drawPrimitive(PE_FocusRect, p, fr, cg); + } + + break; + } + + + default: + KStyle::drawComplexControl(control, p, widget, + r, cg, flags, controls, active, opt); + break; + } +} + + +void HighColorStyle::drawComplexControlMask( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& opt ) const +{ + switch (control) + { + // COMBOBOX & TOOLBUTTON MASKS + // ------------------------------------------------------------------- + case CC_ComboBox: + case CC_ToolButton: { + int x1, y1, x2, y2; + r.coords( &x1, &y1, &x2, &y2 ); + QCOORD corners[] = { x1,y1, x2,y1, x1,y2, x2,y2 }; + p->fillRect( r, color1 ); + p->setPen( color0 ); + p->drawPoints( QPointArray(4, corners) ); + break; + } + + default: + KStyle::drawComplexControlMask(control, p, widget, r, opt); + } +} + + +void HighColorStyle::drawItem( QPainter *p, + const QRect &r, + int flags, + const QColorGroup &cg, + bool enabled, + const QPixmap *pixmap, + const QString &text, + int len, + const QColor *penColor ) const +{ + // We only reimplement this method this so we can override the + // text color used for widgets when we draw them with the selection + // color and Qt expects them to be drawn them with the button color. + // ------------------------------------------------------------------- + const QColor *col; + + if ( selectionBackground ) { + col = &cg.highlightedText(); + selectionBackground = false; + } else + col = penColor; + + KStyle::drawItem( p, r, flags, cg, enabled, pixmap, + text, len, col ); +} + + +QRect HighColorStyle::subRect(SubRect r, const QWidget *widget) const +{ + // We want the focus rect for buttons to be adjusted from + // the Qt3 defaults to be similar to Qt 2's defaults. + // ------------------------------------------------------------------- + if (r == SR_PushButtonFocusRect ) { + const QPushButton* button = (const QPushButton*) widget; + QRect wrect(widget->rect()); + int dbw1 = 0, dbw2 = 0; + + if (button->isDefault() || button->autoDefault()) { + dbw1 = pixelMetric(PM_ButtonDefaultIndicator, widget); + dbw2 = dbw1 * 2; + } + + int dfw1 = pixelMetric(PM_DefaultFrameWidth, widget) * 2, + dfw2 = dfw1 * 2; + + return QRect(wrect.x() + dfw1 + dbw1 + 1, + wrect.y() + dfw1 + dbw1 + 1, + wrect.width() - dfw2 - dbw2 - 1, + wrect.height() - dfw2 - dbw2 - 1); + } else + return KStyle::subRect(r, widget); +} + + +int HighColorStyle::pixelMetric(PixelMetric m, const QWidget *widget) const +{ + switch(m) + { + // BUTTONS + // ------------------------------------------------------------------- + case PM_ButtonMargin: // Space btw. frame and label + return 4; + + case PM_ButtonDefaultIndicator: { + if ( type == HighColor ) + return 0; // No indicator when highcolor + else + return 3; + } + + case PM_MenuButtonIndicator: { // Arrow width + if ( type != B3 ) + return 8; + else + return 7; + } + + // CHECKBOXES / RADIO BUTTONS + // ------------------------------------------------------------------- + case PM_ExclusiveIndicatorWidth: // Radiobutton size + case PM_ExclusiveIndicatorHeight: + case PM_IndicatorWidth: // Checkbox size + case PM_IndicatorHeight: { + return 13; // 13x13 + } + + default: + return KStyle::pixelMetric(m, widget); + } +} + + +QSize HighColorStyle::sizeFromContents( ContentsType contents, + const QWidget* widget, + const QSize &contentSize, + const QStyleOption& opt ) const +{ + switch (contents) + { + // PUSHBUTTON SIZE + // ------------------------------------------------------------------ + case CT_PushButton: { + const QPushButton* button = (const QPushButton*) widget; + int w = contentSize.width(); + int h = contentSize.height(); + int bm = pixelMetric( PM_ButtonMargin, widget ); + int fw = pixelMetric( PM_DefaultFrameWidth, widget ) * 2; + + w += bm + fw + 6; // ### Add 6 to make way for bold font. + h += bm + fw; + + // Ensure we stick to standard width and heights. + if ( button->isDefault() || button->autoDefault() ) { + if ( w < 80 && !button->text().isEmpty() ) + w = 80; + + if ( type != HighColor ) { + // Compensate for default indicator + int di = pixelMetric( PM_ButtonDefaultIndicator ); + w += di * 2; + h += di * 2; + } + } + + if ( h < 22 ) + h = 22; + + return QSize( w, h ); + } + + + // POPUPMENU ITEM SIZE + // ----------------------------------------------------------------- + case CT_PopupMenuItem: { + if ( ! widget || opt.isDefault() ) + return contentSize; + + const QPopupMenu *popup = (const QPopupMenu *) widget; + bool checkable = popup->isCheckable(); + QMenuItem *mi = opt.menuItem(); + int maxpmw = opt.maxIconWidth(); + int w = contentSize.width(), h = contentSize.height(); + + if ( mi->custom() ) { + w = mi->custom()->sizeHint().width(); + h = mi->custom()->sizeHint().height(); + if ( ! mi->custom()->fullSpan() ) + h += 2*itemVMargin + 2*itemFrame; + } + else if ( mi->widget() ) { + } else if ( mi->isSeparator() ) { + w = 10; // Arbitrary + h = 2; + } + else { + if ( mi->pixmap() ) + h = QMAX( h, mi->pixmap()->height() + 2*itemFrame ); + else { + // Ensure that the minimum height for text-only menu items + // is the same as the icon size used by KDE. + h = QMAX( h, 16 + 2*itemFrame ); + h = QMAX( h, popup->fontMetrics().height() + + 2*itemVMargin + 2*itemFrame ); + } + + if ( mi->iconSet() ) + h = QMAX( h, mi->iconSet()->pixmap( + QIconSet::Small, QIconSet::Normal).height() + + 2 * itemFrame ); + } + + if ( ! mi->text().isNull() && mi->text().find('\t') >= 0 ) + w += 12; + else if ( mi->popup() ) + w += 2 * arrowHMargin; + + if ( maxpmw ) + w += maxpmw + 6; + if ( checkable && maxpmw < 20 ) + w += 20 - maxpmw; + if ( checkable || maxpmw > 0 ) + w += 12; + + w += rightBorder; + + return QSize( w, h ); + } + + + default: + return KStyle::sizeFromContents( contents, widget, contentSize, opt ); + } +} + + +// Fix Qt's wacky image alignment +QPixmap HighColorStyle::stylePixmap(StylePixmap stylepixmap, + const QWidget* widget, + const QStyleOption& opt) const +{ + switch (stylepixmap) { + case SP_TitleBarMinButton: + return QPixmap((const char **)hc_minimize_xpm); + case SP_TitleBarCloseButton: + return QPixmap((const char **)hc_close_xpm); + default: + break; + } + + return KStyle::stylePixmap(stylepixmap, widget, opt); +} + + +bool HighColorStyle::eventFilter( QObject *object, QEvent *event ) +{ + if (KStyle::eventFilter( object, event )) + return true; + + QToolBar* toolbar; + + // Handle push button hover effects. + QPushButton* button = dynamic_cast<QPushButton*>(object); + if ( button ) + { + if ( (event->type() == QEvent::Enter) && + (button->isEnabled()) ) { + hoverWidget = button; + button->repaint( false ); + } + else if ( (event->type() == QEvent::Leave) && + (object == hoverWidget) ) { + hoverWidget = 0L; + button->repaint( false ); + } + } else if ( object->parent() && !qstrcmp( object->name(), kdeToolbarWidget ) ) + { + // Draw a gradient background for custom widgets in the toolbar + // that have specified a "kde toolbar widget" name. + + if (event->type() == QEvent::Paint ) { + // Find the top-level toolbar of this widget, since it may be nested in other + // widgets that are on the toolbar. + QWidget *widget = static_cast<QWidget*>(object); + QWidget *parent = static_cast<QWidget*>(object->parent()); + int x_offset = widget->x(), y_offset = widget->y(); + while (parent && parent->parent() && !qstrcmp( parent->name(), kdeToolbarWidget ) ) + { + x_offset += parent->x(); + y_offset += parent->y(); + parent = static_cast<QWidget*>(parent->parent()); + } + + QRect r = widget->rect(); + QRect pr = parent->rect(); + bool horiz_grad = pr.width() < pr.height(); + + // Check if the parent is a QToolbar, and use its orientation, else guess. + QToolBar* tb = dynamic_cast<QToolBar*>(parent); + if (tb) horiz_grad = tb->orientation() == Qt::Vertical; + + QPainter p( widget ); + renderGradient(&p, r, parent->colorGroup().button(), horiz_grad, + x_offset, y_offset, pr.width(), pr.height()); + + return false; // Now draw the contents + } + } else if ( object->parent() && + (toolbar = dynamic_cast<QToolBar*>(object->parent())) ) + { + // We need to override the paint event to draw a + // gradient on a QToolBarExtensionWidget. + if ( event->type() == QEvent::Paint ) { + QWidget *widget = static_cast<QWidget*>(object); + QRect wr = widget->rect(), tr = toolbar->rect(); + QPainter p( widget ); + renderGradient(&p, wr, toolbar->colorGroup().button(), + toolbar->orientation() == Qt::Vertical, + wr.x(), wr.y(), tr.width() - 2, tr.height() - 2); + + p.setPen( toolbar->colorGroup().dark() ); + if ( toolbar->orientation() == Qt::Horizontal ) + p.drawLine( wr.width()-1, 0, wr.width()-1, wr.height()-1 ); + else + p.drawLine( 0, wr.height()-1, wr.width()-1, wr.height()-1 ); + + return true; + } + } + + return false; +} + + +void HighColorStyle::renderGradient( QPainter* p, const QRect& r, + QColor clr, bool horizontal, int px, int py, int pwidth, int pheight) const +{ + // Make 8 bit displays happy + if (!highcolor) { + p->fillRect(r, clr); + return; + } + + // px, py specify the gradient pixmap offset relative to the top-left corner. + // pwidth, pheight specify the width and height of the parent's pixmap. + // We use these to draw parent-relative pixmaps for toolbar buttons + // and menubar items. + + GradientSet* grSet = gDict.find( clr.rgb() ); + + if (!grSet) { + grSet = new GradientSet(clr); + gDict.insert( clr.rgb(), grSet ); + } + + if (horizontal) { + int width = (pwidth != -1) ? pwidth : r.width(); + + if (width <= 34) + p->drawTiledPixmap(r, *grSet->gradient(HMed), QPoint(px, 0)); + else if (width <= 52) + p->drawTiledPixmap(r, *grSet->gradient(HLarge), QPoint(px, 0)); + else { + KPixmap *hLarge = grSet->gradient(HLarge); + + // Don't draw a gradient if we don't need to + if (hLarge->width() > px) + { + int pixmapWidth = hLarge->width() - px; + + // Draw the gradient + p->drawTiledPixmap( r.x(), r.y(), pixmapWidth, r.height(), + *hLarge, px, 0 ); + // Draw the remaining fill + p->fillRect(r.x()+pixmapWidth, r.y(), r.width()-pixmapWidth, + r.height(), clr.dark(110)); + + } else + p->fillRect(r, clr.dark(110)); + } + + } else { + // Vertical gradient + // ----------------- + int height = (pheight != -1) ? pheight : r.height(); + + if (height <= 24) + p->drawTiledPixmap(r, *grSet->gradient(VSmall), QPoint(0, py)); + else if (height <= 34) + p->drawTiledPixmap(r, *grSet->gradient(VMed), QPoint(0, py)); + else if (height <= 64) + p->drawTiledPixmap(r, *grSet->gradient(VLarge), QPoint(0, py)); + else { + KPixmap *vLarge = grSet->gradient(VLarge); + + // Only draw the upper gradient if we need to. + if (vLarge->height() > py) + { + int pixmapHeight = vLarge->height() - py; + + // Draw the gradient + p->drawTiledPixmap( r.x(), r.y(), r.width(), pixmapHeight, + *vLarge, 0, py ); + // Draw the remaining fill + p->fillRect(r.x(), r.y()+pixmapHeight, r.width(), + r.height()-pixmapHeight, clr.dark(110)); + + } else + p->fillRect(r, clr.dark(110)); + } + } +} + + +// vim: set noet ts=4 sw=4: + diff --git a/kstyles/highcolor/highcolor.h b/kstyles/highcolor/highcolor.h new file mode 100644 index 000000000..4841f92a7 --- /dev/null +++ b/kstyles/highcolor/highcolor.h @@ -0,0 +1,170 @@ +/* + * $Id$ + * + * KDE3 HighColor Style (version 1.0) + * Copyright (C) 2001-2002 Karol Szwed <[email protected]> + * (C) 2001-2002 Fredrik H�glund <[email protected]> + * + * Drawing routines adapted from the KDE2 HCStyle, + * Copyright (C) 2000 Daniel M. Duley <[email protected]> + * (C) 2000 Dirk Mueller <[email protected]> + * (C) 2001 Martijn Klingens <[email protected]> + * + * Many thanks to Bradley T. Hughes for the 3 button scrollbar code. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __HIGHCOLOR_H +#define __HIGHCOLOR_H + +#include <qbitmap.h> +#include <qintdict.h> +#include <kdrawutil.h> +#include <kpixmap.h> +#include <kstyle.h> + + +enum GradientType{ VSmall=0, VMed, VLarge, HMed, HLarge, GradientCount }; + +class GradientSet +{ + public: + GradientSet(const QColor &baseColor); + ~GradientSet(); + + KPixmap* gradient(GradientType type); + QColor* color() { return(&c); } + private: + KPixmap *gradients[5]; + QColor c; +}; + + +class QPopupMenu; + +class HighColorStyle : public KStyle +{ + Q_OBJECT + + public: + enum StyleType { HighColor = 0, Default, B3 }; + + HighColorStyle( StyleType ); + virtual ~HighColorStyle(); + + void polish( QWidget* widget ); + void unPolish( QWidget* widget ); + + void renderMenuBlendPixmap( KPixmap& pix, const QColorGroup &cg, + const QPopupMenu* popup ) const; + + void drawKStylePrimitive( KStylePrimitive kpe, + QPainter* p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawPrimitive( PrimitiveElement pe, + QPainter* p, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControlMask( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& = QStyleOption::Default ) const; + + void drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + SCFlags controls = SC_All, + SCFlags active = SC_None, + const QStyleOption& = QStyleOption::Default ) const; + + void drawComplexControlMask( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& = QStyleOption::Default ) const; + + void drawItem( QPainter *p, + const QRect &r, + int flags, + const QColorGroup &cg, + bool enabled, + const QPixmap *pixmap, + const QString &text, + int len = -1, + const QColor *penColor = 0 ) const; + + int pixelMetric( PixelMetric m, + const QWidget *widget = 0 ) const; + + QSize sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentSize, + const QStyleOption& opt ) const; + + QRect subRect( SubRect r, + const QWidget *widget ) const; + + // Fix Qt3's wacky image positions + QPixmap stylePixmap( StylePixmap stylepixmap, + const QWidget *widget = 0, + const QStyleOption& = QStyleOption::Default ) const; + + protected: + bool eventFilter( QObject *object, QEvent *event ); + + void renderGradient( QPainter* p, + const QRect& r, + QColor clr, + bool horizontal, + int px=0, + int py=0, + int pwidth=-1, + int pheight=-1 ) const; + + QWidget *hoverWidget; + StyleType type; + bool highcolor; + mutable bool selectionBackground; + + private: + // Disable copy constructor and = operator + HighColorStyle( const HighColorStyle & ); + HighColorStyle& operator=( const HighColorStyle & ); +}; + +// vim: set noet ts=4 sw=4: + +#endif diff --git a/kstyles/highcontrast/Makefile.am b/kstyles/highcontrast/Makefile.am new file mode 100644 index 000000000..9157e3488 --- /dev/null +++ b/kstyles/highcontrast/Makefile.am @@ -0,0 +1,41 @@ + +# This file is part of the KDE libraries +# Copyright (C) 2005 Olaf Schmidt ([email protected]) + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. + +# This library 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 +# Library General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this library; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +AUTOMAKE_OPTIONS = foreign + +SUBDIRS = config + +KDE_CXXFLAGS = -DQT_PLUGIN + +INCLUDES = $(all_includes) + +stylercdir = $(kde_datadir)/kstyle/themes +stylerc_DATA = highcontrast.themerc + +EXTRA_DIST = $(stylerc_DATA) + +noinst_HEADERS = highcontrast.h + +kde_style_LTLIBRARIES = highcontrast.la +highcontrast_la_SOURCES = highcontrast.cpp +highcontrast_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +highcontrast_la_LIBADD = ../../kdefx/libkdefx.la +highcontrast_la_METASOURCES = AUTO + +DISTCLEANFILES = $(highcontrast_la_METASOURCES) diff --git a/kstyles/highcontrast/TODO b/kstyles/highcontrast/TODO new file mode 100644 index 000000000..a7795bab8 --- /dev/null +++ b/kstyles/highcontrast/TODO @@ -0,0 +1,5 @@ +- QLineEdit are much taller than the other widgets. Check why. +- The QLineEdits background seem to bleed on the outside. +- Use a thicker dotted line (or a solid line?) for the TreView 'branches' + +- ListViewExpanders should get their size from the item text height. (done) diff --git a/kstyles/highcontrast/config/Makefile.am b/kstyles/highcontrast/config/Makefile.am new file mode 100644 index 000000000..23f9c6a81 --- /dev/null +++ b/kstyles/highcontrast/config/Makefile.am @@ -0,0 +1,12 @@ +INCLUDES = $(all_includes) + +noinst_HEADERS = highcontrastconfig.h +kde_module_LTLIBRARIES = kstyle_highcontrast_config.la +kstyle_highcontrast_config_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +kstyle_highcontrast_config_la_LIBADD = $(LIB_KDEUI) +kstyle_highcontrast_config_la_SOURCES = highcontrastconfig.cpp +kstyle_highcontrast_config_la_METASOURCES = AUTO + + +messages: + $(XGETTEXT) *.cpp *.h -o $(podir)/kstyle_highcontrast_config.pot diff --git a/kstyles/highcontrast/config/highcontrastconfig.cpp b/kstyles/highcontrast/config/highcontrastconfig.cpp new file mode 100644 index 000000000..33771f76c --- /dev/null +++ b/kstyles/highcontrast/config/highcontrastconfig.cpp @@ -0,0 +1,94 @@ +/* +Copyright (c) 2005 Luciano Montanaro <[email protected]> + +based on the Keramick configuration dialog +Copyright (c) 2003 Maksim Orlovich <[email protected]> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include <qcheckbox.h> +#include <qlayout.h> +#include <qsettings.h> +#include <kdialog.h> +#include <kglobal.h> +#include <klocale.h> + +#include "highcontrastconfig.h" + +extern "C" KDE_EXPORT QWidget* +allocate_kstyle_config(QWidget* parent) +{ + return new HighContrastStyleConfig(parent); +} + +HighContrastStyleConfig::HighContrastStyleConfig( + QWidget* parent): QWidget(parent) +{ + // Should have no margins here, the dialog provides them + QVBoxLayout* layout = new QVBoxLayout(this, 0, 0); + KGlobal::locale()->insertCatalogue("kstyle_highcontrast_config"); + + wideLinesBox = new QCheckBox(i18n("Use wider lines"), this); + + layout->add(wideLinesBox); + layout->addStretch(1); + + QSettings s; + + originalWideLinesState = s.readBoolEntry( + "/highcontraststyle/Settings/wideLines", false); + wideLinesBox->setChecked(originalWideLinesState); + + connect(wideLinesBox, SIGNAL(toggled(bool)), SLOT(updateChanged())); +} + +HighContrastStyleConfig::~HighContrastStyleConfig() +{ + KGlobal::locale()->removeCatalogue("kstyle_keramik_config"); +} + + +void +HighContrastStyleConfig::save() +{ + QSettings s; + s.writeEntry("/highcontraststyle/Settings/wideLines", + wideLinesBox->isChecked()); +} + +void +HighContrastStyleConfig::defaults() +{ + wideLinesBox->setChecked(false); + // updateChanged would be done by setChecked already +} + +void +HighContrastStyleConfig::updateChanged() +{ + if ((wideLinesBox->isChecked() == originalWideLinesState)) { + emit changed(false); + } else { + emit changed(true); + } +} + +#include "highcontrastconfig.moc" diff --git a/kstyles/highcontrast/config/highcontrastconfig.h b/kstyles/highcontrast/config/highcontrastconfig.h new file mode 100644 index 000000000..26d8a0593 --- /dev/null +++ b/kstyles/highcontrast/config/highcontrastconfig.h @@ -0,0 +1,61 @@ +/* +Copyright (c) 2005 Luciano Montanaro <[email protected]> + +based on the Keramick configuration dialog +Copyright (c) 2003 Maksim Orlovich <[email protected]> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#ifndef HIGHCONTRAST_CONF_H +#define HIGHCONTRAST_CONF_H + +class QCheckBox; + +class HighContrastStyleConfig: public QWidget +{ + Q_OBJECT +public: + HighContrastStyleConfig(QWidget* parent); + ~HighContrastStyleConfig(); + + // This signal and the next two slots are the plugin + // page interface +signals: + void changed(bool); + +public slots: + void save(); + void defaults(); + + // Everything below this is internal. +protected slots: + void updateChanged(); + +protected: + // We store settings directly in widgets to + // avoid the hassle of sync'ing things + QCheckBox* wideLinesBox; + + // Original settings, for accurate dirtiness tracking + bool originalWideLinesState; +}; + +#endif // HIGHCONTRAST_CONF_H diff --git a/kstyles/highcontrast/highcontrast.cpp b/kstyles/highcontrast/highcontrast.cpp new file mode 100644 index 000000000..d7669ff9d --- /dev/null +++ b/kstyles/highcontrast/highcontrast.cpp @@ -0,0 +1,1843 @@ +/* + * High Contrast Style (version 1.0) + * Copyright (C) 2004 Olaf Schmidt <[email protected]> + * + * Derived from Axes Style + * Copyright (C) 2003 Maksim Orlovich <[email protected]> + * + * Axes Style based on KDE 3 HighColor Style, + * Copyright (C) 2001-2002 Karol Szwed <[email protected]> + * (C) 2001-2002 Fredrik Höglund <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <qdrawutil.h> +#include <qpainter.h> +#include <qpointarray.h> +#include <qstyleplugin.h> + +#include <qfont.h> +#include <qcombobox.h> +#include <qheader.h> +#include <qmenubar.h> +#include <qpushbutton.h> +#include <qscrollbar.h> +#include <qslider.h> +#include <qtabbar.h> +#include <qtoolbutton.h> +#include <qtoolbar.h> +#include <qpopupmenu.h> +#include <qprogressbar.h> +#include <qlistview.h> +#include <qsettings.h> + +#include <kdrawutil.h> +#include <kpixmapeffect.h> + +#include "highcontrast.h" +#include "highcontrast.moc" + +// -- Style Plugin Interface ------------------------- +class HighContrastStylePlugin : public QStylePlugin +{ + public: + HighContrastStylePlugin() {} + ~HighContrastStylePlugin() {} + + QStringList keys() const + { + return QStringList() << "HighContrast"; + } + + QStyle* create( const QString& key ) + { + if ( key == "highcontrast" ) + return new HighContrastStyle(); + return 0; + } +}; + +KDE_Q_EXPORT_PLUGIN (HighContrastStylePlugin) +// --------------------------------------------------- + + + +static const int itemFrame = 1; +static const int itemHMargin = 3; +static const int itemVMargin = 0; +static const int arrowHMargin = 6; +static const int rightBorder = 12; + + +void addOffset (QRect* r, int offset, int lineWidth = 0) +{ + int offset1 = offset; + int offset2 = offset; + + *r = r->normalize(); + + if (lineWidth > 0) + { + offset1 += lineWidth/2; + offset2 += lineWidth - lineWidth/2 - 1; + } + + if (offset1 + offset2 > r->width()) + r->addCoords (r->width()/2, 0, - (r->width() - r->width()/2), 0); + else + r->addCoords (offset1, 0, -offset2, 0); + + if (offset1 + offset2 > r->height()) + r->addCoords (0, r->height()/2, 0, - (r->height() - r->height()/2)); + else + r->addCoords (0, offset1, 0, -offset2); +} + + +// --------------------------------------------------------------------------- + +HighContrastStyle::HighContrastStyle() + : KStyle( 0, ThreeButtonScrollBar ) +{ + QSettings settings; + settings.beginGroup("/highcontraststyle/Settings/"); + bool useWideLines = settings.readBoolEntry("wideLines", false); + hoverWidget = 0L; + basicLineWidth = useWideLines ? 4 : 2; +} + + +HighContrastStyle::~HighContrastStyle() +{ +} + + +void HighContrastStyle::polish( QPalette& pal ) +{ + //We do not want the disabled widgets to be greyed out, + //as that may be hard indeed (and since we use crossed-out text instead), + //so we make disabled colors be the same as active foreground and + //background colour + for (int c = 0; c < QColorGroup::NColorRoles; ++c) + switch (c) + { + case QColorGroup::Button: + case QColorGroup::Base: + case QColorGroup::Highlight: + pal.setColor(QPalette::Disabled, QColorGroup::ColorRole(c), pal.color(QPalette::Active, QColorGroup::Background)); + break; + case QColorGroup::ButtonText: + case QColorGroup::Text: + case QColorGroup::HighlightedText: + pal.setColor(QPalette::Disabled, QColorGroup::ColorRole(c), pal.color(QPalette::Active, QColorGroup::Foreground)); + break; + default: + pal.setColor(QPalette::Disabled, QColorGroup::ColorRole(c), pal.color(QPalette::Active, QColorGroup::ColorRole(c))); + } +} + + +void HighContrastStyle::polish (QWidget* widget) +{ + if (widget->inherits ("QButton") + || widget->inherits ("QComboBox") + || widget->inherits ("QSpinWidget") + || widget->inherits ("QLineEdit") + || widget->inherits ("QTextEdit")) + { + widget->installEventFilter (this); + + QSpinWidget* spinwidget = dynamic_cast<QSpinWidget*>(widget); + if (spinwidget && spinwidget->editWidget()) + spinwidget->editWidget()->installEventFilter (this); + } + + KStyle::polish (widget); +} + + +void HighContrastStyle::unPolish (QWidget* widget) +{ + if (widget->inherits ("QWidget") || widget->inherits ("QComboBox") || widget->inherits ("QSpinWidget") || widget->inherits ("QLineEdit") || widget->inherits ("QTextEdit")) + widget->removeEventFilter (this); + KStyle::unPolish (widget); +} + +void HighContrastStyle::setColorsNormal (QPainter* p, const QColorGroup& cg, int flags, int highlight) const +{ + setColorsByState (p, cg, cg.foreground(), cg.background(), flags, highlight); +} + +void HighContrastStyle::setColorsButton (QPainter* p, const QColorGroup& cg, int flags, int highlight) const +{ + setColorsByState (p, cg, cg.buttonText(), cg.button(), flags, highlight); +} + +void HighContrastStyle::setColorsText (QPainter* p, const QColorGroup& cg, int flags, int highlight) const +{ + setColorsByState (p, cg, cg.text(), cg.base(), flags, highlight); +} + +void HighContrastStyle::setColorsHighlight (QPainter* p, const QColorGroup& cg, int flags) const +{ + setColorsByState (p, cg, cg.highlightedText(), cg.highlight(), flags, 0); +} + +void HighContrastStyle::setColorsByState (QPainter* p, const QColorGroup& cg, const QColor& fg, const QColor& bg, int flags, int highlight) const +{ + QFont font = p->font(); + font.setStrikeOut (! (flags & Style_Enabled)); + p->setFont (font); + + if ((flags & Style_Enabled) && (flags & highlight)) + { + p->setPen (QPen (cg.highlightedText(), basicLineWidth, flags & Style_Enabled ? Qt::SolidLine : Qt::DotLine)); + p->setBackgroundColor (cg.highlight()); + } + else + { + p->setPen (QPen (fg, basicLineWidth, flags & Style_Enabled ? Qt::SolidLine : Qt::DotLine)); + p->setBackgroundColor (bg); + } + + p->setBrush (QBrush ()); +} + +void HighContrastStyle::drawRect (QPainter* p, QRect r, int offset, bool filled) const +{ + addOffset (&r, offset, p->pen().width()); + if (filled) + p->fillRect (r, p->backgroundColor()); + + p->drawRect (r); +} + +void HighContrastStyle::drawRoundRect (QPainter* p, QRect r, int offset, bool filled) const +{ + int lineWidth = p->pen().width(); + if ((r.width() >= 5*lineWidth + 2*offset) && (r.height() >= 5*lineWidth + 2*offset)) + { + QRect r2 (r); + addOffset (&r2, offset, lineWidth); + + addOffset (&r, offset); + QRect r3 (r); + addOffset (&r3, lineWidth); + + p->save(); + p->setPen (Qt::NoPen); + if (filled) + p->fillRect (r3, p->backgroundColor()); + p->drawRect (r3); + p->restore(); + + p->drawLine (r.left()+lineWidth, r2.top(), r.right()+1-lineWidth, r2.top()); + p->fillRect (r.left()+1, r.top()+1, lineWidth, lineWidth, p->pen().color()); + p->drawLine (r2.left(), r.top()+lineWidth, r2.left(), r.bottom()+1-lineWidth); + p->fillRect (r.left()+1, r.bottom()-lineWidth, lineWidth, lineWidth, p->pen().color()); + p->drawLine (r.left()+lineWidth, r2.bottom(), r.right()+1-lineWidth, r2.bottom()); + p->fillRect (r.right()-lineWidth, r.bottom()-lineWidth, lineWidth, lineWidth, p->pen().color()); + p->drawLine (r2.right(), r.top()+lineWidth, r2.right(), r.bottom()+1-lineWidth); + p->fillRect (r.right()-lineWidth, r.top()+1, lineWidth, lineWidth, p->pen().color()); + } + else + drawRect (p, r, offset, filled); +} + +void HighContrastStyle::drawEllipse (QPainter* p, QRect r, int offset, bool filled) const +{ + addOffset (&r, offset, p->pen().width()); + + if (filled) { + p->save(); + p->setBrush (p->backgroundColor()); + p->drawRoundRect (r, 99, 99); + p->restore(); + } + + p->drawRoundRect (r, 99, 99); +} + +void HighContrastStyle::drawArrow (QPainter* p, QRect r, PrimitiveElement arrow, int offset) const +{ + p->save(); + addOffset (&r, offset); + + QPoint center = r.center(); + if (r.height() < r.width()) + r.setWidth (r.height()); + if (r.width() % 2 != 0) + r.setWidth (r.width() - 1); + r.setHeight (r.width()); + r.moveCenter (center); + + QPointArray points (3); + switch (arrow) { + case PE_ArrowUp: + case PE_SpinWidgetUp: + case PE_SpinWidgetPlus: { + points.setPoint (0, r.bottomLeft()); + points.setPoint (1, r.bottomRight()); + points.setPoint (2, r.center().x(), r.top() + r.height()/7); + break; + } + case PE_ArrowDown: + case PE_SpinWidgetDown: + case PE_SpinWidgetMinus: { + points.setPoint (0, r.topLeft()); + points.setPoint (1, r.topRight()); + points.setPoint (2, r.center().x(), r.bottom() - r.height()/7); + break; + } + case PE_ArrowLeft: { + points.setPoint (0, r.topRight()); + points.setPoint (1, r.bottomRight()); + points.setPoint (2, r.left() + r.width()/7, r.center().y()); + break; + } + default: { + points.setPoint (0, r.topLeft()); + points.setPoint (1, r.bottomLeft()); + points.setPoint (2, r.right() - r.width()/7, r.center().y()); + } + } + + p->setPen (p->pen().color()); + p->setBrush (p->pen().color()); + p->drawPolygon (points); + p->restore(); +} + +// This function draws primitive elements +void HighContrastStyle::drawPrimitive (PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + switch(pe) + { + case PE_StatusBarSection: { + //### TODO: Not everything uses this! + setColorsNormal (p, cg, Style_Enabled); + drawRect (p, r); + break; + } + // BUTTONS + // ------------------------------------------------------------------- + case PE_ButtonDefault: + case PE_ButtonDropDown: + case PE_ButtonCommand: + case PE_ButtonTool: + case PE_ButtonBevel: { + setColorsButton (p, cg, flags, Style_On|Style_MouseOver|Style_Down); + drawRoundRect (p, r, 0, false); + break; + } + + // FOCUS RECT + // ------------------------------------------------------------------- + case PE_FocusRect: { + p->save(); + p->setBrush (QBrush ()); + p->setPen (QPen (cg.highlight(), basicLineWidth, Qt::SolidLine)); + drawRoundRect (p, r, basicLineWidth, false); + p->setPen (QPen (cg.highlightedText(), basicLineWidth, Qt::DashLine)); + drawRoundRect (p, r, basicLineWidth, false); + p->restore(); + break; + } + + case PE_HeaderArrow: { + setColorsButton (p, cg, flags, 0); + drawArrow (p, r, flags & Style_Down ? PE_ArrowDown : PE_ArrowUp, 2*basicLineWidth); + break; + } + // HEADER SECTION + // ------------------------------------------------------------------- + case PE_HeaderSection: { + setColorsButton (p, cg, flags, 0); + drawRect (p, r); + break; + } + + + // SCROLLBAR + // ------------------------------------------------------------------- + case PE_ScrollBarSlider: { + setColorsNormal (p, cg); + p->fillRect (r, p->backgroundColor()); + + if (flags & Style_Enabled) { + setColorsHighlight (p, cg, flags); + drawRoundRect (p, r); + + if (r.width() >= 7*basicLineWidth && r.height() >= 7*basicLineWidth) { + QRect r2 (r); + r2.setWidth (4*basicLineWidth); + r2.setHeight (4*basicLineWidth); + r2.moveCenter (r.center()); + drawRect (p, r2, 0, false); + } + } + break; + } + + case PE_ScrollBarAddPage: + case PE_ScrollBarSubPage: { + setColorsNormal (p, cg); + p->fillRect (r, p->backgroundColor()); + + QRect r2 (r); + if (flags & Style_Horizontal) + { + if (r2.height() > 5*basicLineWidth) + { + r2.setHeight (5*basicLineWidth); + r2.moveCenter (r.center()); + } + } + else + { + if (r2.width() > 5*basicLineWidth) + { + r2.setWidth (5*basicLineWidth); + r2.moveCenter (r.center()); + } + } + setColorsText (p, cg, flags); + drawRect (p, r2); + + if (flags & Style_Horizontal) + r2.addCoords (0, basicLineWidth, 0, -basicLineWidth); + else + r2.addCoords (basicLineWidth, 0, -basicLineWidth, 0); + QPen pen = p->pen(); + pen.setColor (p->backgroundColor()); + p->setPen (pen); + drawRect (p, r2); + + break; + } + + case PE_ScrollBarAddLine: + case PE_ScrollBarSubLine: + case PE_ScrollBarFirst: + case PE_ScrollBarLast: { + setColorsNormal (p, cg); + p->fillRect (r, p->backgroundColor()); + + if (flags & Style_Enabled) { + setColorsButton (p, cg, flags); + drawRoundRect (p, r); + if (pe == PE_ScrollBarAddLine) + drawArrow (p, r, flags & Style_Horizontal ? PE_ArrowRight : PE_ArrowDown, r.height()/3); + else if (pe == PE_ScrollBarSubLine) + drawArrow (p, r, flags & Style_Horizontal ? PE_ArrowLeft : PE_ArrowUp, r.height()/3); + } + break; + } + + + case PE_ProgressBarChunk: { + p->fillRect (r, Qt::color1); + break; + } + + + // CHECKBOX + // ------------------------------------------------------------------- + case PE_Indicator: { + setColorsText (p, cg, flags); + + //Draw the outer rect + drawRect (p, r); + + if (!(flags & Style_Off)) + { + QRect r2 (r); + addOffset (&r2, basicLineWidth); + if (flags & Style_On) + { + p->drawLine (r2.topLeft(), r2.bottomRight()); + p->drawLine (r2.bottomLeft(), r2.topRight()); + } + else + { // Tristate + p->drawLine (r2.left(), r2.top()+r2.width()/2, r2.right(), r2.top()+r2.width()/2); + } + QPen pen = p->pen(); + pen.setColor (p->backgroundColor()); + p->setPen (pen); + drawRect (p, r2, 0, false); + } + break; + } + case PE_IndicatorMask: { + p->fillRect (r, Qt::color1); + break; + } + case PE_CheckMark: { + setColorsText (p, cg, flags); + + if (flags & Style_On) + { + p->drawLine (r.topLeft(), r.bottomRight()); + p->drawLine (r.bottomLeft(), r.topRight()); + } + break; + } + + // RADIOBUTTON (exclusive indicator) + // ------------------------------------------------------------------- + case PE_ExclusiveIndicator: { + setColorsText (p, cg, flags); + drawEllipse (p, r); + + // Indicator "dot" + if (flags & Style_On) { + p->setBackgroundColor (p->pen().color()); + drawEllipse (p, r, 2*p->pen().width()); + } + + break; + } + case PE_ExclusiveIndicatorMask: { + p->fillRect (r, Qt::color0); + p->setBackgroundColor (Qt::color1); + p->setPen (Qt::NoPen); + p->setBrush (Qt::color1); + p->drawEllipse (r); + break; + } + + + // SPLITTER/DOCKWINDOW HANDLES + // ------------------------------------------------------------------- + case PE_DockWindowResizeHandle: + case PE_Splitter: { + setColorsButton (p, cg, flags); + p->fillRect (r, p->backgroundColor()); + + p->setPen (QPen (p->pen().color(), 1, Qt::DashLine)); + if (flags & Style_Horizontal) + p->drawLine (r.center().x(), r.top(), r.center().x(), r.bottom()); + else + p->drawLine (r.left(), r.center().y(), r.right(), r.center().y()); + break; + } + + + // GENERAL PANELS + // ------------------------------------------------------------------- + case PE_Panel: + case PE_GroupBoxFrame: + case PE_PanelPopup: { + setColorsNormal (p, cg, flags, 0); + if (!opt.isDefault()) + { + QPen pen = p->pen(); + pen.setWidth (opt.lineWidth()); + p->setPen (pen); + } + if (pe == PE_PanelPopup) + drawRect (p, r, 0, false); + else + drawRoundRect (p, r, 0, false); + break; + } + case PE_WindowFrame: + case PE_TabBarBase: { + setColorsNormal (p, cg, flags, 0); + drawRect (p, r, 0, false); + break; + } + case PE_PanelLineEdit: { + setColorsText (p, cg, flags, 0); + drawRoundRect (p, r); + if (flags & (Style_HasFocus | Style_Active)) + drawPrimitive (PE_FocusRect, p, r, cg, flags, QStyleOption (p->backgroundColor())); + break; + } + case PE_PanelTabWidget: + case PE_PanelGroupBox: { + setColorsNormal (p, cg, flags, 0); + drawRoundRect (p, r); + break; + } + case PE_PanelMenuBar: { // Menu + p->fillRect (r, cg.background()); + break; + } + case PE_PanelDockWindow: { // Toolbar + p->fillRect (r, cg.button()); + break; + } + + + + // SEPARATORS + // ------------------------------------------------------------------- + case PE_Separator: { + setColorsNormal (p, cg); + p->fillRect (r, p->backgroundColor()); + p->setPen (p->pen().color()); + if (flags & Style_Horizontal) + p->drawLine (r.center().x(), r.top()+basicLineWidth, r.center().x(), r.bottom()-basicLineWidth + 1); + else + p->drawLine (r.left()+basicLineWidth, r.center().y(), r.right()-basicLineWidth + 1, r.center().y()); + break; + } + case PE_DockWindowSeparator: { + setColorsButton (p, cg); + p->fillRect (r, p->backgroundColor()); + p->setPen (p->pen().color()); + if (flags & Style_Horizontal) + p->drawLine (r.center().x(), r.top()+basicLineWidth, r.center().x(), r.bottom()-basicLineWidth); + else + p->drawLine (r.left()+basicLineWidth, r.center().y(), r.right()-basicLineWidth, r.center().y()); + break; + } + + + // ARROWS + // ------------------------------------------------------------------- + case PE_ArrowUp: + case PE_ArrowDown: + case PE_ArrowRight: + case PE_ArrowLeft: + case PE_SpinWidgetPlus: + case PE_SpinWidgetUp: + case PE_SpinWidgetMinus: + case PE_SpinWidgetDown: { + setColorsNormal (p, cg, flags); + drawArrow (p, r, pe); + break; + } + + default: { + KStyle::drawPrimitive( pe, p, r, cg, flags, opt ); + } + } +} + + +void HighContrastStyle::drawKStylePrimitive (KStylePrimitive kpe, + QPainter* p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption &opt ) const +{ + if ( widget == hoverWidget ) + flags |= Style_MouseOver; + + switch ( kpe ) + { + // TOOLBAR HANDLE + // ------------------------------------------------------------------- + case KPE_ToolBarHandle: + case KPE_DockWindowHandle: + case KPE_GeneralHandle: + { + setColorsButton (p, cg); + p->fillRect (r, p->backgroundColor()); + p->setBrush (QBrush (p->pen().color(), Qt::BDiagPattern)); + drawRoundRect (p, r); + break; + } + + + // SLIDER GROOVE + // ------------------------------------------------------------------- + case KPE_SliderGroove: { + setColorsText (p, cg, flags); + QRect r2 (r); + const QSlider *slider = dynamic_cast<const QSlider*>(widget); + if (slider != 0) + { + if (slider->orientation() == Qt::Horizontal) + { + if (r2.height() > 5*basicLineWidth) + { + r2.setHeight (5*basicLineWidth); + r2.moveCenter (r.center()); + } + } + else + { + if (r2.width() > 5*basicLineWidth) + { + r2.setWidth (5*basicLineWidth); + r2.moveCenter (r.center()); + } + } + } + + drawRoundRect (p, r2); + break; + } + + // SLIDER HANDLE + // ------------------------------------------------------------------- + case KPE_SliderHandle: { + setColorsHighlight (p, cg, flags); + drawRoundRect (p, r); + break; + } + + case KPE_ListViewExpander: { + // TODO There is no pixelMetric associated with the + // ListViewExpander in KStyle. + // To have a properly large expander, the CC_ListView case of + // drawComplexControl should be handled. + // Probably it would be better to add a KPM_ListViewExpander metric + // to the KStyle KStylePixelMetric enum, and have the KStyle + // drawComplexControl handle it. + PrimitiveElement direction; + if (flags & Style_On) { // Collapsed = On + direction = PE_ArrowRight; + + } else { + direction = PE_ArrowDown; + } + setColorsText (p, cg, flags); + drawArrow (p, r, direction); + break; + } + case KPE_ListViewBranch: + // TODO Draw (thick) dotted line. Check kstyle.cpp + // Fall down for now + default: + KStyle::drawKStylePrimitive( kpe, p, widget, r, cg, flags, opt); + } +} + + +void HighContrastStyle::drawControl (ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + if ( widget == hoverWidget ) + flags |= Style_MouseOver; + + switch (element) + { + // TABS + // ------------------------------------------------------------------- + case CE_ToolBoxTab: { + setColorsNormal (p, cg, flags, Style_Selected); + drawRoundRect (p, r); + break; + } + + case CE_TabBarTab: { + setColorsNormal (p, cg, flags, Style_Selected); + drawRoundRect (p, r); + + const QTabBar *tb = static_cast< const QTabBar * >(widget); + QTabBar::Shape shape = tb->shape(); + if (shape == QTabBar::TriangularBelow || + shape == QTabBar::RoundedBelow) { + p->fillRect (r.left(), r.top(), + r.width(), 2*basicLineWidth, + p->pen().color()); + p->fillRect (r.left()+basicLineWidth, + flags & Style_Selected ? basicLineWidth : 2*basicLineWidth, + r.width()-2*basicLineWidth, + basicLineWidth, + p->backgroundColor()); + } else { + p->fillRect (r.left(), r.bottom()-2*basicLineWidth+1, + r.width(), 2*basicLineWidth, + p->pen().color()); + p->fillRect (r.left()+basicLineWidth, + r.bottom()-2*basicLineWidth+1, + r.width()-2*basicLineWidth, + flags & Style_Selected ? 2*basicLineWidth : basicLineWidth, + p->backgroundColor()); + } + break; + } + + + // PUSHBUTTON + // ------------------------------------------------------------------- + case CE_PushButton: { + QPushButton *button = (QPushButton*) widget; + QRect br = r; + bool btnDefault = button->isDefault(); + + if (( btnDefault || button->autoDefault() ) && (button->isEnabled())) { + // Compensate for default indicator + static int di = pixelMetric( PM_ButtonDefaultIndicator ); + addOffset (&br, di); + } + + if ( btnDefault && (button->isEnabled())) + drawPrimitive( PE_ButtonDefault, p, r, cg, flags ); + + drawPrimitive( PE_ButtonCommand, p, br, cg, flags ); + + break; + } + + + // LABEL + // ------------------------------------------------------------------- + case CE_ProgressBarLabel: + case CE_TabBarLabel: + case CE_RadioButtonLabel: + case CE_CheckBoxLabel: + case CE_ToolButtonLabel: + case CE_PushButtonLabel: { + const QPixmap* pixmap = 0; + QPixmap icon; + QString text; + bool popup = false; + + QIconSet::Mode mode = flags & Style_Enabled ? ((flags & Style_HasFocus) ? QIconSet::Active : QIconSet::Normal) : QIconSet::Disabled; + QIconSet::State state = flags & Style_On ? QIconSet::On : QIconSet::Off; + + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + if (element == CE_ProgressBarLabel) { + QProgressBar* progressbar = (QProgressBar*) widget; + text = progressbar->progressString(); + setColorsNormal (p, cg, flags); + } + else if (element == CE_TabBarLabel) { + if (!opt.isDefault()) { + QTab* tab = opt.tab(); + text = tab->text(); + } + setColorsNormal (p, cg, flags, Style_Selected); + } + else if (element == CE_ToolButtonLabel) { + QToolButton* toolbutton = (QToolButton*) widget; + text = toolbutton->text(); + pixmap = toolbutton->pixmap(); + if (!toolbutton->iconSet().isNull()) + icon = toolbutton->iconSet().pixmap (QIconSet::Small, mode, state); + popup = toolbutton->popup(); + setColorsButton (p, cg, flags); + } + else if (element == CE_PushButtonLabel) { + QPushButton* pushbutton = (QPushButton*) widget; + text = pushbutton->text(); + pixmap = pushbutton->pixmap(); + if (pushbutton->iconSet() && !pushbutton->iconSet()->isNull()) + icon = pushbutton->iconSet()->pixmap (QIconSet::Small, mode, state); + popup = pushbutton->popup(); + setColorsButton (p, cg, flags); + } + else { + const QButton* button = (const QButton*)widget; + pixmap = button->pixmap(); + text = button->text(); + setColorsNormal (p, cg); + } + + // Does the button have a popup menu? + if (popup) { + int dx = pixelMetric (PM_MenuButtonIndicator, widget); + drawArrow (p, QRect(x + w - dx - 2, y + 2, dx, h - 4), PE_ArrowDown); + w -= dx; + } + + // Draw the icon if there is one + if (!icon.isNull()) + { + // Center the iconset if there's no text or pixmap + if (text.isEmpty() && ((pixmap == 0) || pixmap->isNull())) + p->drawPixmap (x + (w - icon.width()) / 2, + y + (h - icon.height()) / 2, icon); + else + p->drawPixmap (x + 4, y + (h - icon.height()) / 2, icon); + + int pw = icon.width(); + x += pw + 4; + w -= pw + 4; + } + + // Draw a focus rect if the button has focus + if (flags & Style_HasFocus) + drawPrimitive (PE_FocusRect, p, r, cg, flags, QStyleOption (p->backgroundColor())); + + // Draw the label itself + QColor color = p->pen().color(); + drawItem (p, QRect(x, y, w, h), + (element == CE_RadioButtonLabel || element == CE_CheckBoxLabel || element == CE_ProgressBarLabel) ? AlignVCenter|AlignLeft|ShowPrefix : AlignCenter|ShowPrefix, + cg, flags & Style_Enabled, pixmap, text, -1, &color); + break; + } + + // MENUBAR BACKGROUND + // ------------------------------------------------------------------- + case CE_MenuBarEmptyArea: + { + p->fillRect (r, cg.background()); + break; + } + + // DOCKWINDOW BACKGROUND + // ------------------------------------------------------------------- + case CE_DockWindowEmptyArea: + { + p->fillRect (r, cg.button()); + break; + } + + // MENUBAR ITEM + // ------------------------------------------------------------------- + case CE_MenuBarItem: { + setColorsNormal (p, cg, flags, Style_Active|Style_MouseOver); + p->fillRect (r, p->backgroundColor ()); + if (!opt.isDefault()) { + QMenuItem *mi = opt.menuItem(); + + QColor color = p->pen().color(); + drawItem (p, r, AlignCenter | AlignVCenter | ShowPrefix + | DontClip | SingleLine, cg, flags, + mi->pixmap(), mi->text(), -1, &color); + } + break; + } + + // CHECKBOX + // ------------------------------------------------------------------- + case CE_CheckBox: { + drawPrimitive (PE_Indicator, p, r, cg, flags); + break; + } + + // RADIOBUTTON + // ------------------------------------------------------------------- + case CE_RadioButton: { + drawPrimitive (PE_ExclusiveIndicator, p, r, cg, flags); + break; + } + + // PROGRESSBAR + // ------------------------------------------------------------------- + case CE_ProgressBarGroove: { + setColorsText (p, cg, flags); + const QProgressBar *progressbar = dynamic_cast<const QProgressBar*>(widget); + if (progressbar) { + QRect r2 (r); + r2.setLeft (p->boundingRect (r, AlignVCenter|AlignLeft|ShowPrefix, progressbar->progressString()).right() + + 4*basicLineWidth); + drawRoundRect (p, r2); + } + break; + } + case CE_ProgressBarContents: { + const QProgressBar *progressbar = dynamic_cast<const QProgressBar*>(widget); + if (progressbar) + { + QRect r2 (r); + r2.setLeft (p->boundingRect (r, AlignVCenter|AlignLeft|ShowPrefix, progressbar->progressString()).right() + + 4*basicLineWidth); + long progress = r2.width() * progressbar->progress(); + if (progressbar->totalSteps() > 0) + { + r2.setWidth (progress / progressbar->totalSteps()); + } + else + { + int width = r2.width() / 5; + int left = progressbar->progress() % (2*(r2.width() - width)); + if (left > r2.width() - width) + left = 2*(r2.width() - width) - left; + r2.setLeft (r2.left() + left); + r2.setWidth (width); + } + setColorsHighlight (p, cg, flags); + if (r2.width() > 0) + drawRoundRect (p, r2); + } + break; + } + + // POPUPMENU ITEM + // ------------------------------------------------------------------- + case CE_PopupMenuItem: { + setColorsNormal (p, cg, flags, Style_Active|Style_MouseOver); + p->fillRect (r, p->backgroundColor ()); + + const QPopupMenu *popupmenu = (const QPopupMenu *) widget; + QMenuItem *mi = opt.menuItem(); + if (!mi) + break; + + int tab = opt.tabWidth(); + int checkcol = opt.maxIconWidth(); + bool checkable = popupmenu->isCheckable(); + bool reverse = QApplication::reverseLayout(); + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + if ( checkable ) + checkcol = QMAX( checkcol, 20 ); + + // Are we a menu item separator? + if ( mi->isSeparator() ) { + p->drawLine (r.left() + 1, r.center().y(), r.right(), r.center().y()); + break; + } + + // Do we have an icon? + if ( mi->iconSet() && !mi->iconSet()->isNull() ) { + QIconSet::Mode mode; + QRect cr = visualRect( QRect(x, y, checkcol, h), r ); + + // Select the correct icon from the iconset + if (!(flags & Style_Enabled)) + mode = QIconSet::Disabled; + else if (flags & Style_Active) + mode = QIconSet::Active; + else + mode = QIconSet::Normal; + + // Draw the icon + QPixmap pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode ); + QRect pmr( 0, 0, pixmap.width(), pixmap.height() ); + pmr.moveCenter( cr.center() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + + // Do we have an icon and are checked at the same time? + // Then draw a square border around the icon + if ( checkable && mi->isChecked() ) + { + drawRect (p, cr, 0, false); + } + } + + // Are we checked? (This time without an icon) + else if ( checkable && mi->isChecked() ) { + int cx = reverse ? x+w - checkcol : x; + + QRect rc (cx, y, checkcol, h); + addOffset (&rc, 2*basicLineWidth); + QPoint center = rc.center(); + if (rc.width() > rc.height()) + rc.setWidth (rc.height()); + else + rc.setHeight (rc.width()); + rc.moveCenter (center); + + p->drawLine (rc.topLeft(), rc.bottomRight()); + p->drawLine (rc.topRight(), rc.bottomLeft()); + } + + // Time to draw the menu item label... + int xm = itemFrame + checkcol + itemHMargin; // X position margin + + int xp = reverse ? // X position + x + tab + rightBorder + itemHMargin + itemFrame - 1 : + x + xm; + + // Label width (minus the width of the accelerator portion) + int tw = w - xm - tab - arrowHMargin - itemHMargin * 3 - itemFrame + 1; + + // Does the menu item draw it's own label? + if ( mi->custom() ) { + int m = itemVMargin; + // Save the painter state in case the custom + // paint method changes it in some way + p->save(); + mi->custom()->paint( p, cg, flags & Style_Active, flags & Style_Enabled, xp, y+m, tw, h-2*m ); + p->restore(); + } + else { + // The menu item doesn't draw it's own label + QString s = mi->text(); + + // Does the menu item have a text label? + if ( !s.isNull() ) { + int t = s.find( '\t' ); + int m = itemVMargin; + int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine; + text_flags |= reverse ? AlignRight : AlignLeft; + + // Does the menu item have a tabstop? (for the accelerator text) + if ( t >= 0 ) { + int tabx = reverse ? x + rightBorder + itemHMargin + itemFrame : + x + w - tab - rightBorder - itemHMargin - itemFrame; + + // Draw the right part of the label (accelerator text) + p->drawText( tabx, y+m, tab, h-2*m, text_flags, s.mid( t+1 ) ); + s = s.left( t ); + } + + // Draw the left part of the label (or the whole label + // if there's no accelerator) + + p->drawText( xp, y+m, tw, h-2*m, text_flags, s, t ); + + } + + // The menu item doesn't have a text label + // Check if it has a pixmap instead + else if ( mi->pixmap() ) { + QPixmap *pixmap = mi->pixmap(); + + // Draw the pixmap + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( OpaqueMode ); + + int diffw = ( ( w - pixmap->width() ) / 2 ) + + ( ( w - pixmap->width() ) % 2 ); + p->drawPixmap( x+diffw, y+itemFrame, *pixmap ); + + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( TransparentMode ); + } + } + + // Does the menu item have a submenu? + if ( mi->popup() ) { + PrimitiveElement arrow = reverse ? PE_ArrowLeft : PE_ArrowRight; + int dim = pixelMetric(PM_MenuButtonIndicator); + QRect vr = visualRect( QRect( x + w - arrowHMargin - 2*itemFrame - dim, + y + h / 2 - dim / 2, dim, dim), r ); + + // Draw an arrow at the far end of the menu item + drawArrow (p, vr, arrow); + } + break; + } + + default: + KStyle::drawControl(element, p, widget, r, cg, flags, opt); + } +} + +void HighContrastStyle::drawControlMask (ControlElement element, + QPainter *p, + const QWidget *w, + const QRect &r, + const QStyleOption &opt) const +{ + switch (element) { + case CE_PushButton: + case CE_ToolBoxTab: + case CE_TabBarTab: + case CE_ProgressBarLabel: + case CE_TabBarLabel: + case CE_RadioButtonLabel: + case CE_CheckBoxLabel: + case CE_ToolButtonLabel: + case CE_PushButtonLabel: + case CE_MenuBarEmptyArea: + case CE_MenuBarItem: + case CE_PopupMenuItem: { + p->fillRect (r, color0); + break; + } + + default: { + KStyle::drawControlMask (element, p, w, r, opt); + } + } +} + +// Helper to find the next sibling that's not hidden +// Lifted from kstyle.cpp +static QListViewItem* nextVisibleSibling(QListViewItem* item) +{ + QListViewItem* sibling = item; + do + { + sibling = sibling->nextSibling(); + } + while (sibling && !sibling->isVisible()); + + return sibling; +} + +void HighContrastStyle::drawComplexControl (ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + SCFlags controls, + SCFlags active, + const QStyleOption& opt ) const +{ + if ( widget == hoverWidget ) + flags |= Style_MouseOver; + + switch(control) + { + // COMBOBOX + // ------------------------------------------------------------------- + case CC_ComboBox: { + setColorsText (p, cg, flags); + drawRoundRect (p, r); + + QRect r2 = QStyle::visualRect (querySubControlMetrics (CC_ComboBox, widget, SC_ComboBoxArrow), widget); + if (flags & Style_HasFocus) { + QRect r3 (r); + if (r2.left() > 0) + r3.setRight (r2.left()+basicLineWidth-1); + else + r3.setLeft (r2.right()-basicLineWidth+1); + + drawPrimitive (PE_FocusRect, p, r3, cg, flags, QStyleOption (p->backgroundColor())); + } + + setColorsButton (p, cg, flags); + // Draw arrow if required + if (controls & SC_ComboBoxArrow) { + drawRoundRect (p, r2); + drawArrow (p, r2, PE_ArrowDown, 2*basicLineWidth); + } + + setColorsText (p, cg, flags); + break; + } + + // SPINWIDGET + // ------------------------------------------------------------------- + case CC_SpinWidget: { + if (controls & SC_SpinWidgetFrame) { + setColorsText (p, cg, flags); + drawRoundRect (p, r); + if (flags & Style_HasFocus) + drawPrimitive(PE_FocusRect, p, r, cg, flags, QStyleOption (p->backgroundColor())); + } + + setColorsButton (p, cg, flags); + // Draw arrows if required + if (controls & SC_SpinWidgetDown) { + QRect r2 = QStyle::visualRect (querySubControlMetrics (CC_SpinWidget, widget, SC_SpinWidgetDown), widget); + drawRoundRect (p, r2); + drawArrow (p, r2, PE_SpinWidgetDown, 2*basicLineWidth); + } + if (controls & SC_SpinWidgetUp) { + QRect r2 = QStyle::visualRect (querySubControlMetrics (CC_SpinWidget, widget, SC_SpinWidgetUp), widget); + drawRoundRect (p, r2); + drawArrow (p, r2, PE_SpinWidgetUp, 2*basicLineWidth); + } + + setColorsText (p, cg, flags); + break; + } + + // TOOLBUTTON + // ------------------------------------------------------------------- + case CC_ToolButton: { + const QToolButton *toolbutton = (const QToolButton *) widget; + + setColorsButton (p, cg, flags); + p->fillRect (r, p->backgroundColor ()); + + QRect button, menuarea; + button = querySubControlMetrics(control, widget, SC_ToolButton, opt); + menuarea = querySubControlMetrics(control, widget, SC_ToolButtonMenu, opt); + + SFlags bflags = flags, + mflags = flags; + + if (active & SC_ToolButton) + bflags |= Style_Down; + if (active & SC_ToolButtonMenu) + mflags |= Style_Down; + + if (controls & SC_ToolButton) + { + // If we're pressed, on, or raised... + if (bflags & (Style_Down | Style_On | Style_Raised)) + drawPrimitive(PE_ButtonTool, p, button, cg, bflags, opt); + + // Check whether to draw a background pixmap + else if ( toolbutton->parentWidget() && + toolbutton->parentWidget()->backgroundPixmap() && + !toolbutton->parentWidget()->backgroundPixmap()->isNull() ) + { + QPixmap pixmap = *(toolbutton->parentWidget()->backgroundPixmap()); + p->drawTiledPixmap( r, pixmap, toolbutton->pos() ); + } + } + + // Draw a toolbutton menu indicator if required + if (controls & SC_ToolButtonMenu) + { + if (mflags & (Style_Down | Style_On | Style_Raised)) + drawPrimitive(PE_ButtonDropDown, p, menuarea, cg, mflags, opt); + drawArrow (p, menuarea, PE_ArrowDown); + } + + if (toolbutton->hasFocus() && !toolbutton->focusProxy()) { + QRect fr = toolbutton->rect(); + addOffset (&fr, 3); + drawPrimitive(PE_FocusRect, p, fr, cg, flags, QStyleOption (p->backgroundColor())); + } + + break; + } + + // LISTVIEW + // ------------------------------------------------------------------- + case CC_ListView: { + /* + * Sigh... Lifted and modified from kstyle.cpp + */ + /* + * Many thanks to TrollTech AS for donating CC_ListView from QWindowsStyle. + * CC_ListView code is Copyright (C) 1998-2000 TrollTech AS. + */ + + // Paint the icon and text. + if ( controls & SC_ListView ) + QCommonStyle::drawComplexControl( control, p, widget, r, cg, flags, controls, active, opt ); + + // If we're have a branch or are expanded... + if ( controls & (SC_ListViewBranch | SC_ListViewExpand) ) + { + // If no list view item was supplied, break + if (opt.isDefault()) + break; + + QListViewItem *item = opt.listViewItem(); + QListViewItem *child = item->firstChild(); + + int y = r.y(); + int c; // dotline vertice count + int dotoffset = 0; + QPointArray dotlines; + + if ( active == SC_All && controls == SC_ListViewExpand ) { + // We only need to draw a vertical line + c = 2; + dotlines.resize(2); + dotlines[0] = QPoint( r.right(), r.top() ); + dotlines[1] = QPoint( r.right(), r.bottom() ); + + } else { + + int linetop = 0, linebot = 0; + // each branch needs at most two lines, ie. four end points + dotoffset = (item->itemPos() + item->height() - y) % 2; + dotlines.resize( item->childCount() * 4 ); + c = 0; + + // skip the stuff above the exposed rectangle + while ( child && y + child->height() <= 0 ) + { + y += child->totalHeight(); + child = nextVisibleSibling(child); + } + + int bx = r.width() / 2; + + // paint stuff in the magical area + QListView* v = item->listView(); + int lh = QMAX( p->fontMetrics().height() + 2 * v->itemMargin(), + QApplication::globalStrut().height() ); + if ( lh % 2 > 0 ) + lh++; + + // Draw all the expand/close boxes... + QRect boxrect; + QStyle::StyleFlags boxflags; + while ( child && y < r.height() ) + { + linebot = y + lh/2; + if ( (child->isExpandable() || child->childCount()) && + (child->height() > 0) ) + { + int h = QMIN(lh, 24) - 4*basicLineWidth; + if (h < 10) + h = 10; + else + h &= ~1; // Force an even number of pixels + + // The primitive requires a rect. + boxrect = QRect( bx-h/2, linebot-h/2, h, h ); + boxflags = child->isOpen() ? QStyle::Style_Off : QStyle::Style_On; + + // KStyle extension: Draw the box and expand/collapse indicator + drawKStylePrimitive( KPE_ListViewExpander, p, NULL, boxrect, cg, boxflags, opt ); + + // dotlinery + p->setPen( cg.mid() ); + dotlines[c++] = QPoint( bx, linetop ); + dotlines[c++] = QPoint( bx, linebot - 5 ); + dotlines[c++] = QPoint( bx + 5, linebot ); + dotlines[c++] = QPoint( r.width(), linebot ); + linetop = linebot + 5; + } else { + // just dotlinery + dotlines[c++] = QPoint( bx+1, linebot ); + dotlines[c++] = QPoint( r.width(), linebot ); + } + + y += child->totalHeight(); + child = nextVisibleSibling(child); + } + + if ( child ) // there's a child to draw, so move linebot to edge of rectangle + linebot = r.height(); + + if ( linetop < linebot ) + { + dotlines[c++] = QPoint( bx, linetop ); + dotlines[c++] = QPoint( bx, linebot ); + } + } + + // Draw all the branches... + static int thickness = kPixelMetric( KPM_ListViewBranchThickness ); + int line; // index into dotlines + QRect branchrect; + QStyle::StyleFlags branchflags; + for( line = 0; line < c; line += 2 ) + { + // assumptions here: lines are horizontal or vertical. + // lines always start with the numerically lowest + // coordinate. + + // point ... relevant coordinate of current point + // end ..... same coordinate of the end of the current line + // other ... the other coordinate of the current point/line + if ( dotlines[line].y() == dotlines[line+1].y() ) + { + // Horizontal branch + int end = dotlines[line+1].x(); + int point = dotlines[line].x(); + int other = dotlines[line].y(); + + branchrect = QRect( point, other-(thickness/2), end-point, thickness ); + branchflags = QStyle::Style_Horizontal; + + // KStyle extension: Draw the horizontal branch + drawKStylePrimitive( KPE_ListViewBranch, p, NULL, branchrect, cg, branchflags, opt ); + + } else { + // Vertical branch + int end = dotlines[line+1].y(); + int point = dotlines[line].y(); + int other = dotlines[line].x(); + int pixmapoffset = ((point & 1) != dotoffset ) ? 1 : 0; + + branchrect = QRect( other-(thickness/2), point, thickness, end-point ); + if (!pixmapoffset) // ### Hackish - used to hint the offset + branchflags = QStyle::Style_NoChange; + else + branchflags = QStyle::Style_Default; + + // KStyle extension: Draw the vertical branch + drawKStylePrimitive( KPE_ListViewBranch, p, NULL, branchrect, cg, branchflags, opt ); + } + } + } + break; + } + + default: + KStyle::drawComplexControl(control, p, widget, + r, cg, flags, controls, active, opt); + break; + } +} + +void HighContrastStyle::drawComplexControlMask(ComplexControl c, + QPainter *p, + const QWidget *w, + const QRect &r, + const QStyleOption &o) const +{ + switch (c) { + case CC_SpinWidget: + case CC_ToolButton: + case CC_ComboBox: { + p->fillRect (r, color0); + break; + } + default: { + KStyle::drawComplexControlMask (c, p, w, r, o); + } + } +} + +void HighContrastStyle::drawItem( QPainter *p, + const QRect &r, + int flags, + const QColorGroup &cg, + bool enabled, + const QPixmap *pixmap, + const QString &text, + int len, + const QColor *penColor ) const +{ + p->save(); + + // make the disabled things use the cross-line + QFont font = p->font(); + font.setStrikeOut (!enabled); + p->setFont (font); + + enabled = true; //do not ghost it in Qt + + KStyle::drawItem (p, r, flags, cg, enabled, pixmap, text, len, penColor); + + p->restore(); +} + +QRect HighContrastStyle::querySubControlMetrics( ComplexControl control, + const QWidget* widget, + SubControl subcontrol, + const QStyleOption& opt ) const +{ + switch (control) + { + case CC_ComboBox : { + int arrow = pixelMetric (PM_ScrollBarExtent, widget); + switch (subcontrol) + { + case SC_ComboBoxFrame: + return QRect (0, 0, widget->width(), widget->height()); + case SC_ComboBoxArrow: + return QRect (widget->width() - arrow, 0, arrow, widget->height()); + case SC_ComboBoxEditField: + return QRect (2*basicLineWidth, 2*basicLineWidth, + widget->width() - arrow - 3*basicLineWidth, widget->height() - 4*basicLineWidth); + + default: break; + } + break; + } + case CC_SpinWidget : { + int arrow = pixelMetric (PM_ScrollBarExtent, 0); + switch (subcontrol) + { + case SC_SpinWidgetFrame: + return QRect (0, 0, widget->width(), widget->height()); + case SC_SpinWidgetButtonField: + return QRect (widget->width() - arrow, 0, arrow, widget->height()); + case SC_SpinWidgetUp: + return QRect (widget->width() - arrow, 0, arrow, widget->height()/2); + case SC_SpinWidgetDown: + return QRect (widget->width() - arrow, widget->height()/2, + arrow, widget->height()-widget->height()/2); + case SC_SpinWidgetEditField: + return QRect (2*basicLineWidth, 2*basicLineWidth, + widget->width() - arrow - 3*basicLineWidth, widget->height() - 4*basicLineWidth); + + default: break; + } + break; + } + + default: break; + } + + return KStyle::querySubControlMetrics (control, widget, subcontrol, opt); +} + + +int HighContrastStyle::pixelMetric(PixelMetric m, const QWidget *widget) const +{ + //### TODO: Use the tab metrics changes from Ker. + switch(m) + { + // BUTTONS + // ------------------------------------------------------------------- + case PM_ButtonMargin: // Space btw. frame and label + return 2*basicLineWidth; + + case PM_ButtonDefaultIndicator: { + if ((widget != 0) && !widget->isEnabled()) + return 0; + else + return 2*basicLineWidth; + } + + case PM_ButtonShiftHorizontal: + case PM_ButtonShiftVertical: + return 0; + + case PM_ScrollBarExtent: { + int h = 0; + if (widget != 0) + h = (2*widget->fontMetrics().lineSpacing())/3; + + if (h > 9*basicLineWidth+4) + return h; + else + return 9*basicLineWidth+4; + } + + case PM_DefaultFrameWidth: { + if (widget && (widget->inherits ("QLineEdit") || widget->inherits ("QTextEdit"))) + return 2*basicLineWidth; + else + return basicLineWidth; + } + + case PM_SpinBoxFrameWidth: { + return 2*basicLineWidth; + } + + case PM_MenuButtonIndicator: { // Arrow width + int h = 0; + if (widget != 0) + h = widget->fontMetrics().lineSpacing()/2; + + if (h > 3*basicLineWidth) + return h; + else + return 3*basicLineWidth; + } + + // CHECKBOXES / RADIO BUTTONS + // ------------------------------------------------------------------- + case PM_ExclusiveIndicatorWidth: // Radiobutton size + case PM_ExclusiveIndicatorHeight: + case PM_IndicatorWidth: // Checkbox size + case PM_IndicatorHeight: { + int h = 0; + if (widget != 0) + h = widget->fontMetrics().lineSpacing()-2*basicLineWidth; + + if (h > 6*basicLineWidth) + return h; + else + return 6*basicLineWidth; + } + + case PM_DockWindowSeparatorExtent: { + return 2*basicLineWidth + 1; + } + case PM_DockWindowHandleExtent: { + int w = 0; + if (widget != 0) + w = widget->fontMetrics().lineSpacing()/4; + if (w > 5*basicLineWidth) + return w; + else + return 5*basicLineWidth; + } + + default: + return KStyle::pixelMetric(m, widget); + } +} + +int HighContrastStyle::kPixelMetric( KStylePixelMetric kpm, const QWidget *widget ) const +{ + switch (kpm) { + case KPM_ListViewBranchThickness: + // XXX Proper support of thick branches requires reimplementation of + // the drawKStylePrimitive KPE_ListViewBranch case. + return basicLineWidth; + default: + return KStyle::kPixelMetric(kpm, widget); + } +} + +QSize HighContrastStyle::sizeFromContents( ContentsType contents, + const QWidget* widget, + const QSize &contentSize, + const QStyleOption& opt ) const +{ + switch (contents) + { + // PUSHBUTTON SIZE + // ------------------------------------------------------------------ + case CT_PushButton: { + const QPushButton* button = (const QPushButton*) widget; + int w = contentSize.width(); + int h = contentSize.height(); + int bm = pixelMetric( PM_ButtonMargin, widget ); + int fw = pixelMetric( PM_DefaultFrameWidth, widget ) * 2; + + w += bm + fw + 6; // ### Add 6 to make way for bold font. + h += bm + fw; + + // Ensure we stick to standard width and heights. + if (( button->isDefault() || button->autoDefault() ) && (button->isEnabled())) { + if ( w < 80 && !button->text().isEmpty() ) + w = 80; + + // Compensate for default indicator + int di = pixelMetric( PM_ButtonDefaultIndicator ); + w += di * 2; + h += di * 2; + } + + if ( h < 22 ) + h = 22; + + return QSize( w + basicLineWidth*2, h + basicLineWidth*2 ); + } + + // TOOLBUTTON SIZE + // ----------------------------------------------------------------- + case CT_ToolButton: { + int w = contentSize.width(); + int h = contentSize.height(); + return QSize(w + basicLineWidth*2 + 6, h + basicLineWidth*2 + 5); + break; + } + + // COMBOBOX SIZE + // ----------------------------------------------------------------- + case CT_ComboBox: { + const QComboBox *cb = static_cast< const QComboBox* > (widget); + int borderSize = (cb->editable() ? 4 : 2) * basicLineWidth; + int arrowSize = pixelMetric (PM_ScrollBarExtent, cb); + return QSize(borderSize + basicLineWidth + arrowSize, borderSize) + contentSize; + } + + // POPUPMENU ITEM SIZE + // ----------------------------------------------------------------- + case CT_PopupMenuItem: { + if ( ! widget || opt.isDefault() ) + return contentSize; + + const QPopupMenu *popup = (const QPopupMenu *) widget; + bool checkable = popup->isCheckable(); + QMenuItem *mi = opt.menuItem(); + int maxpmw = opt.maxIconWidth(); + int w = contentSize.width(), h = contentSize.height(); + + if ( mi->custom() ) { + w = mi->custom()->sizeHint().width(); + h = mi->custom()->sizeHint().height(); + if ( ! mi->custom()->fullSpan() ) + h += 2*itemVMargin + 2*itemFrame; + } + else if ( mi->widget() ) { + } else if ( mi->isSeparator() ) { + w = 10; // Arbitrary + h = 4; + } + else { + if ( mi->pixmap() ) + h = QMAX( h, mi->pixmap()->height() + 2*itemFrame ); + else { + // Ensure that the minimum height for text-only menu items + // is the same as the icon size used by KDE. + h = QMAX( h, 16 + 2*itemFrame ); + h = QMAX( h, popup->fontMetrics().height() + + 2*itemVMargin + 2*itemFrame ); + } + + if ( mi->iconSet() && ! mi->iconSet()->isNull() ) + h = QMAX( h, mi->iconSet()->pixmap( + QIconSet::Small, QIconSet::Normal).height() + + 2 * itemFrame ); + } + + if ( ! mi->text().isNull() && mi->text().find('\t') >= 0 ) + w += 12; + else if ( mi->popup() ) + w += 2 * arrowHMargin; + + if ( maxpmw ) + w += maxpmw + 6; + if ( checkable && maxpmw < 20 ) + w += 20 - maxpmw; + if ( checkable || maxpmw > 0 ) + w += 12; + + w += rightBorder; + + return QSize( w, h ); + } + + + // LINEDIT SIZE + // ----------------------------------------------------------------- + case CT_LineEdit: { + return contentSize + QSize (4*basicLineWidth, 4*basicLineWidth); + } + + + default: + return KStyle::sizeFromContents( contents, widget, contentSize, opt ); + } +} + +QRect HighContrastStyle::subRect (SubRect subrect, const QWidget * widget) const +{ + switch (subrect) { + case SR_ProgressBarGroove: + case SR_ProgressBarContents: + case SR_ProgressBarLabel: + return widget->rect(); + default: + return KStyle::subRect (subrect, widget); + } +} + +bool HighContrastStyle::eventFilter (QObject *object, QEvent *event) +{ + QWidget* widget = dynamic_cast<QWidget*>(object); + if (widget) + { + // Handle hover effects. + if (event->type() == QEvent::Enter + && (widget->inherits ("QButton") + || widget->inherits ("QComboBox") + || widget->inherits ("QSpinWidget"))) + { + hoverWidget = widget; + widget->repaint (false); + } + else if (event->type() == QEvent::Leave + && (widget->inherits ("QButton") + || widget->inherits ("QComboBox") + || widget->inherits ("QSpinWidget"))) + { + if (object == hoverWidget) + hoverWidget = 0L; + widget->repaint (false); + } + // Make sure the focus rectangle is shown correctly. + else if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) + { + QWidget* widgetparent = dynamic_cast<QWidget*>(widget->parent()); + while (widgetparent + && ! widgetparent->inherits ("QComboBox") + && ! widgetparent->inherits ("QSpinWidget")) + { + widgetparent = dynamic_cast<QWidget*>(widgetparent->parent()); + } + + if (widgetparent) + widgetparent->repaint (false); + else + widget->repaint (false); + } + } + + return KStyle::eventFilter (object, event); +} + +// vim: set noet ts=4 sw=4: +// kate: indent-width 4; replace-tabs off; smart-indent on; tab-width 4; diff --git a/kstyles/highcontrast/highcontrast.h b/kstyles/highcontrast/highcontrast.h new file mode 100644 index 000000000..0758b806c --- /dev/null +++ b/kstyles/highcontrast/highcontrast.h @@ -0,0 +1,162 @@ +/* + * High Contrast Style (version 1.0) + * Copyright (C) 2004 Olaf Schmidt <[email protected]> + * + * Derived from Axes Style + * Copyright (C) 2003 Maksim Orlovich <[email protected]> + * + * Axes Style based on KDE 3 HighColor Style, + * Copyright (C) 2001-2002 Karol Szwed <[email protected]> + * (C) 2001-2002 Fredrik Höglund <[email protected]> + * + * KDE 3 HighColor Style drawing routines adapted from the KDE2 HCStyle, + * Copyright (C) 2000 Daniel M. Duley <[email protected]> + * (C) 2000 Dirk Mueller <[email protected]> + * (C) 2001 Martijn Klingens <[email protected]> + * + * Includes portions from KStyle, + * Copyright (C) 2001-2002 Karol Szwed <[email protected]> + * + * Many thanks to Bradley T. Hughes for the 3 button scrollbar code. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __HIGHCONTRAST_H +#define __HIGHCONTRAST_H + +#include <qbitmap.h> +#include <qintdict.h> +#include <kdrawutil.h> +#include <kpixmap.h> +#include <kstyle.h> + + +class QPopupMenu; + +class HighContrastStyle : public KStyle +{ + Q_OBJECT + + public: + HighContrastStyle(); + virtual ~HighContrastStyle(); + + void polish( QPalette& pal ); + + void polish( QWidget* widget ); + void unPolish( QWidget* widget ); + + void drawKStylePrimitive( KStylePrimitive kpe, + QPainter* p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawPrimitive( PrimitiveElement pe, + QPainter* p, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControlMask( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& = QStyleOption::Default ) const; + + void drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + SCFlags controls = SC_All, + SCFlags active = SC_None, + const QStyleOption& = QStyleOption::Default ) const; + + void drawComplexControlMask( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& = QStyleOption::Default ) const; + + QRect querySubControlMetrics( ComplexControl control, + const QWidget* widget, + SubControl subcontrol, + const QStyleOption& opt = QStyleOption::Default ) const; + + + void drawItem( QPainter *p, + const QRect &r, + int flags, + const QColorGroup &cg, + bool enabled, + const QPixmap *pixmap, + const QString &text, + int len = -1, + const QColor *penColor = 0 ) const; + + int pixelMetric( PixelMetric m, + const QWidget *widget = 0 ) const; + + int kPixelMetric( KStylePixelMetric m, + const QWidget *widget = 0 ) const; + + QSize sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentSize, + const QStyleOption& opt ) const; + + QRect subRect (SubRect subrect, const QWidget * widget) const; + + protected: + bool eventFilter( QObject *object, QEvent *event ); + + QWidget *hoverWidget; + + private: + void setColorsNormal (QPainter* p, const QColorGroup& cg, int flags = Style_Enabled, int highlight = Style_Down|Style_MouseOver) const; + void setColorsButton (QPainter* p, const QColorGroup& cg, int flags = Style_Enabled, int highlight = Style_Down|Style_MouseOver) const; + void setColorsText (QPainter* p, const QColorGroup& cg, int flags = Style_Enabled, int highlight = Style_Down|Style_MouseOver) const; + void setColorsHighlight (QPainter* p, const QColorGroup& cg, int flags = Style_Enabled) const; + void setColorsByState (QPainter* p, const QColorGroup& cg, const QColor& fg, const QColor& bg, int flags, int highlight) const; + + void drawRect (QPainter* p, QRect r, int offset = 0, bool filled = true) const; + void drawRoundRect (QPainter* p, QRect r, int offset = 0, bool filled = true) const; + void drawEllipse (QPainter* p, QRect r, int offset = 0, bool filled = true) const; + void drawArrow (QPainter* p, QRect r, PrimitiveElement arrow, int offset = 0) const; + + int basicLineWidth; + // Disable copy constructor and = operator + HighContrastStyle( const HighContrastStyle & ); + HighContrastStyle& operator=( const HighContrastStyle & ); +}; + +// vim: set noet ts=4 sw=4: +// kate: indent-width 4; replace-tabs off; smart-indent on; tab-width 4; + +#endif diff --git a/kstyles/highcontrast/highcontrast.themerc b/kstyles/highcontrast/highcontrast.themerc new file mode 100644 index 000000000..f7f30809c --- /dev/null +++ b/kstyles/highcontrast/highcontrast.themerc @@ -0,0 +1,127 @@ +[Misc] +Name=HighContrast +Name[af]=Hoë kontras +Name[be]=Высокі кантраст +Name[bn]=হাই কনট্রাস্ট +Name[br]=Dargemm uhel +Name[ca]=Contrast alt +Name[cs]=Vysoký kontrast +Name[csb]=Wësoczi kòntrast +Name[da]=Høj kontrast +Name[de]=Hoher Kontrast +Name[el]=Υψηλή φωτεινότητα +Name[eo]=Granda kontrasto +Name[es]=ContrasteAlto +Name[et]=Tugev kontrast +Name[eu]=Kontraste handia +Name[fa]=سایه روشن بالا +Name[fi]=KorkeaKontrasti +Name[fr]=Contraste fort +Name[fy]=Heechkontrast +Name[he]=ניגודיות גבוהה +Name[hr]=Visoki kontrast +Name[hu]=Erősen kontrasztos +Name[is]=Há birtuskil +Name[it]=Contrasto elevato +Name[ja]=高コントラスト +Name[ka]=კონტრასტი +Name[kk]=Жоғары контрасты +Name[km]=កម្រិតពណ៌ខ្ពស់ +Name[lb]=HéichKontrast +Name[lt]=Didelis kontrastas +Name[lv]=Augsts kontrasts +Name[mk]=Висок контраст +Name[ms]=Kontras Tinggi +Name[nb]=HøyKontrast +Name[nds]=HoochKontrast +Name[ne]=उच्च व्यतिरेक +Name[nl]=Hoogcontrast +Name[nn]=Høg kontrast +Name[pa]=ਗੂੜਾ +Name[pl]=Wysoki kontrast +Name[pt]=Alto Contraste +Name[pt_BR]=Alto Contraste +Name[ro]=Contrast mare +Name[ru]=Контраст +Name[rw]=InyuranyamigaragarireRihebuje +Name[se]=AllaVuostálasvuohta +Name[sl]=VisokKontrast +Name[sr]=Високи контраст +Name[sr@Latn]=Visoki kontrast +Name[sv]=Hög kontrast +Name[ta]=அதிக மாறுபாடு +Name[te]=ఎక్కువ వ్యత్యాసం +Name[tg]=БаландАкс +Name[th]=คอนทราสต์สูง +Name[tr]=Yüksek Kontrast +Name[tt]=KiskenTösle +Name[uk]=Висока контрастність +Name[vi]=Độ tương phản cao +Name[zh_CN]=高对比度 +Name[zh_HK]=高反差 +ConfigPage=kstyle_highcontrast_config +Comment=A style that works well with high contrast color schemes +Comment[af]=´n Styl wat goed werk met hoë kontras kleur skemas +Comment[be]=Стыль, які створаны для працы з высокакантрастнымі колернымі схемамі +Comment[bg]=Стил за схеми с висок контраст +Comment[bs]=Stil koji izgleda dobro sa šemama boja visokog kontrasta +Comment[ca]=Un estil que funciona bé amb esquemes de color de contrast alt +Comment[cs]=Styl vhodný pro barevná schémata s vysokým kontrastem +Comment[csb]=Sztél, jaczi dzejô pòprôwno z témama farwów ò wësoczim kòntrasce +Comment[da]=En stil der virker godt med farvesammensætninger med høj kontrast +Comment[de]=Ein Stil, der gut zu kontrastreichen Farbschemas passt +Comment[el]=Ένα στυλ που δουλεύει καλά με σχήματα υψηλής φωτεινότητας +Comment[en_GB]=A style that works well with high contrast colour schemes +Comment[eo]=Stilo kiu konvenas al kolor-etosoj kiuj havas grandajn kontrastojn +Comment[es]=Un estilo que funciona con esquemas de color de contraste alto +Comment[et]=Stiil, mis sobib hästi tugeva kontrastiga värviskeemidele +Comment[eu]=Kontraste handiko gaiekin ongi moldatzen den estiloa +Comment[fa]=سبکی که به خوبی با طرحهای رنگ، با سایه روشن بالا کار میکند +Comment[fi]=Tyyli joka toimii hyvin korkeakontrastisien väriteemojen kanssa +Comment[fr]=Un style se combinant bien avec les modèles de couleurs à fort contraste +Comment[fy]=In styl dy goed wurket mei hege kontrast kleureskema’s +Comment[gl]=Un estilo que traballa ben con esquemas de cor de alto contraste +Comment[hr]=Stil koji dobro fukcionira s shemama bojanja u visokom kontrastu +Comment[hu]=Erősen kontrasztos színsémákhoz jól illeszkedő stílus +Comment[id]=Gaya yang sesuai untuk skema warna kontras tinggi +Comment[is]=Stíll sem passar vel við litaskemu sem nota há birtuskil +Comment[it]=Uno stile che funziona bene con combinazioni di colori ad alto contrasto +Comment[ja]=高コントラストの色スキームにふさわしいスタイル +Comment[ka]=ფერების მაღალ კონტრასტული სქემების სტილი +Comment[kk]=Контрастығы жоғары түстер сұлбалы стиль +Comment[km]=រចនាប័ទ្មដែលធ្វើការយ៉ាងល្អជាមួយគ្រោងពណ៌កម្រិតខ្ពស់ +Comment[lb]=E Stil, dee gutt bei Faarfschemaë mat engem héiche Kontrast passt +Comment[lt]=Stilius, kuris labai tinka didelio kontrasto spalvų schemoms +Comment[mk]=Стил што добро работи со шеми на бои со висок контраст +Comment[ms]=Gaya yang berfungsi baik dengan skema warna kontras tinggi +Comment[nb]=En stil som passer bra sammen med temaer med høy kontrast +Comment[nds]=En Stil, de goot för Klöörschemas mit hogen Kontrast passt. +Comment[ne]=उच्च व्यतिरेक रङ स्कीमासँग राम्रो कार्य गर्ने शैली +Comment[nl]=Een stijl die goed werkt met hoog contrast kleurenschema's +Comment[nn]=Ein stil som fungerer bra når fargeoppsettet har høg kontrast +Comment[pa]= ਇੱਕ ਸ਼ੈਲੀ, ਜੋ ਕਿ ਗੂੜੀ ਰੰਗ ਸਕੀਮ ਨਾਲ ਵਧੀਆ ਕੰਮ ਕਰਦੀ ਹੈ +Comment[pl]=Styl, który działa dobrze z motywami kolorów o wysokim kontraście +Comment[pt]=Um estilo que funciona bem com esquemas de cores de alto contraste +Comment[pt_BR]=Um estilo que funciona bem com esquemas de cor de alto contraste +Comment[ro]=Un stil care se potriveşte cu schemele de culori cu contrast mare +Comment[ru]=Стиль с контрастными цветовыми схемами +Comment[rw]=Imisusire ikorana neza n'ibishushanyombonera by'ibara inyuranyamigaragarire yo hejuru +Comment[se]=Stiila mii doaibmá bures ovttas ivdnečoahkádusaiguin mas leat alla vuostálasvuohta +Comment[sk]=Štýl, ktorý funguje dobre pri schémach s vysokým kontrastom +Comment[sl]=Slog, ki se dobro obnese z visokokontrastnimi shemami +Comment[sr]=Стил који ради са високо контрастним шемама боја +Comment[sr@Latn]=Stil koji radi sa visoko kontrastnim šemama boja +Comment[sv]=En stil som fungerar bra med färgscheman för hög kontrast +Comment[ta]=அதிக மாறுபாட்டு வண்ண அமைப்புகளில் சரியாக இயங்கும் ஒரு பாணி +Comment[te]=ఎక్కువ వ్యత్యాసాల రంగుల పద్దతులతొ బాగా పనిచేయు ఒక శైలి +Comment[tg]=Услуб, ки бо истифодаи нақшаҳо бо рангҳои баландакс соз кор мекунад +Comment[th]=รูปแบบที่ทำงานได้ดีกับชุดสีคอนทราสต์สูง +Comment[tr]=Yüksek kontrast renk şemalarına uygun bir stil +Comment[tt]=Bu tışlaw bik kisken tösle köyläwlärgä yaxşı kileşä +Comment[uk]=Стиль, який підходить до схем кольорів з високою контрастністю +Comment[vi]=Kiểu dáng thích hợp với lược đồ màu có độ tương phản cao. +Comment[zh_CN]=在高对比度配色方案中适用的样式 +Comment[zh_HK]=適用於高反差色彩的佈景 +Comment[zh_TW]=在高彩度下可以使用的風格 +[KDE] +WidgetStyle=HighContrast diff --git a/kstyles/keramik/Makefile.am b/kstyles/keramik/Makefile.am new file mode 100644 index 000000000..a649c4eb7 --- /dev/null +++ b/kstyles/keramik/Makefile.am @@ -0,0 +1,90 @@ +AM_CPPFLAGS = -DQT_PLUGIN + +INCLUDES = -I$(top_srcdir)/kdefx $(all_includes) +# qembed's output needs that... +KDE_CXXFLAGS = -UQT_NO_ASCII_CAST +noinst_HEADERS = keramik.h pixmaploader.h keramikimage.h bitmaps.h gradients.h colorutil.h +kde_style_LTLIBRARIES = keramik.la +keramik_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +keramik_la_LIBADD = ../../kdefx/libkdefx.la +keramik_la_SOURCES = keramik.cpp pixmaploader.cpp gradients.cpp colorutil.cpp +keramik_la_COMPILE_FIRST = keramikrc.h +keramik_la_METASOURCES = AUTO + +noinst_PROGRAMS = genembed + +genembed_SOURCES = genembed.cpp +genembed_LDADD = ../../kdefx/libkdefx.la +genembed_LDFLAGS = $(all_libraries) $(KDE_RPATH) + +pixmaps.keramik: pics/checkbox-off.png pics/checkbox-on.png pics/combobox-list-bc.png\ + pics/combobox-list-bl.png pics/combobox-list-br.png pics/combobox-list-cl.png pics/combobox-list-cr.png\ + pics/combobox-list-tc.png pics/combobox-list-tl.png pics/combobox-list-tr.png pics/frame-shadow-cl.png\ + pics/frame-shadow-tc.png pics/frame-shadow-tl.png pics/listview-bc.png pics/listview-bl.png pics/listview-br.png\ + pics/listview-cc.png pics/listview-cl.png pics/listview-cr.png pics/listview-pressed-bc.png pics/listview-pressed-bl.png\ + pics/listview-pressed-br.png pics/listview-pressed-cc.png pics/listview-pressed-cl.png pics/listview-pressed-cr.png\ + pics/listview-pressed-tc.png pics/listview-pressed-tl.png pics/listview-pressed-tr.png pics/listview-tc.png pics/listview-tl.png\ + pics/listview-tr.png pics/pushbutton-bc.png pics/pushbutton-bl.png pics/pushbutton-br.png pics/pushbutton-cc.png\ + pics/pushbutton-cl.png pics/pushbutton-cr.png pics/pushbutton-default-bc.png pics/pushbutton-default-bl.png\ + pics/pushbutton-default-br.png pics/pushbutton-default-cc.png pics/pushbutton-default-cl.png pics/pushbutton-default-cr.png\ + pics/pushbutton-default-hov-tl.png pics/pushbutton-default-hov-tc.png pics/pushbutton-default-hov-tr.png\ + pics/pushbutton-default-hov-cl.png pics/pushbutton-default-hov-cc.png pics/pushbutton-default-hov-cr.png\ + pics/pushbutton-default-hov-bl.png pics/pushbutton-default-hov-bc.png pics/pushbutton-default-hov-br.png\ + pics/pushbutton-default-pressed-bc.png pics/pushbutton-default-pressed-bl.png pics/pushbutton-default-pressed-br.png\ + pics/pushbutton-default-pressed-cc.png pics/pushbutton-default-pressed-cl.png pics/pushbutton-default-pressed-cr.png\ + pics/pushbutton-default-pressed-tc.png pics/pushbutton-default-pressed-tl.png pics/pushbutton-default-pressed-tr.png\ + pics/pushbutton-default-tc.png pics/pushbutton-default-tl.png pics/pushbutton-default-tr.png \ + pics/pushbutton-pressed-bc.png pics/pushbutton-pressed-bl.png pics/pushbutton-pressed-br.png pics/pushbutton-pressed-cc.png\ + pics/pushbutton-pressed-cl.png pics/pushbutton-pressed-cr.png pics/pushbutton-pressed-tc.png pics/pushbutton-pressed-tl.png\ + pics/pushbutton-pressed-tr.png pics/pushbutton-small-bc.png pics/pushbutton-small-bl.png pics/pushbutton-small-br.png\ + pics/pushbutton-small-cc.png pics/pushbutton-small-cl.png pics/pushbutton-small-cr.png\ + pics/pushbutton-small-pressed-bc.png pics/pushbutton-small-pressed-bl.png pics/pushbutton-small-pressed-br.png\ + pics/pushbutton-small-pressed-cc.png pics/pushbutton-small-pressed-cl.png pics/pushbutton-small-pressed-cr.png\ + pics/pushbutton-small-pressed-tc.png pics/pushbutton-small-pressed-tl.png pics/pushbutton-small-pressed-tr.png\ + pics/pushbutton-small-tc.png pics/pushbutton-small-tl.png pics/pushbutton-small-tr.png pics/pushbutton-tc.png\ + pics/pushbutton-tl.png pics/pushbutton-tr.png pics/radiobutton-off.png pics/radiobutton-on.png pics/ripple.png\ + pics/scrollbar-hbar-arrow1.png \ + pics/scrollbar-hbar-arrow2.png pics/scrollbar-hbar-groove1.png pics/scrollbar-hbar-groove2.png\ + pics/scrollbar-hbar-slider1.png pics/scrollbar-hbar-slider2.png pics/scrollbar-hbar-slider3.png pics/scrollbar-hbar-slider4.png\ + pics/scrollbar-vbar-arrow1.png\ + pics/scrollbar-vbar-arrow2.png pics/scrollbar-vbar-groove1.png\ + pics/scrollbar-vbar-groove2.png pics/scrollbar-vbar-slider1.png pics/scrollbar-vbar-slider2.png\ + pics/menuitem-cl.png pics/menuitem-cc.png pics/menuitem-cr.png\ + pics/scrollbar-vbar-slider3.png pics/scrollbar-vbar-slider4.png pics/slider-hgroove-bc.png\ + pics/slider-hgroove-bl.png pics/slider-hgroove-br.png pics/slider-hgroove-cc.png pics/slider-hgroove-cl.png pics/slider-hgroove-cr.png\ + pics/slider-hgroove-tc.png pics/slider-hgroove-tl.png pics/slider-hgroove-tr.png pics/slider-vgroove-bc.png pics/slider-vgroove-bl.png\ + pics/slider-vgroove-br.png pics/slider-vgroove-cc.png pics/slider-vgroove-cl.png pics/slider-vgroove-cr.png pics/slider-vgroove-tc.png\ + pics/slider-vgroove-tl.png pics/slider-vgroove-tr.png pics/slider.png pics/spinbox-1.png pics/spinbox-2.png pics/spinbox-3.png\ + pics/spinbox-arrow-down.png pics/spinbox-arrow-up.png pics/spinbox-pressed-arrow-down.png pics/spinbox-pressed-arrow-up.png\ + pics/progressbar-cc.png pics/progressbar-cl.png pics/progressbar-cr.png\ + pics/toolbar-clk-bc.png pics/toolbar-clk-bl.png pics/toolbar-clk-br.png\ + pics/toolbar-clk-cc.png pics/toolbar-clk-cl.png pics/toolbar-clk-cr.png\ + pics/toolbar-clk-tc.png pics/toolbar-clk-tl.png pics/toolbar-clk-tr.png pics/checkbox-tri.png\ + pics/spinbox-pressed-down.png pics/spinbox-pressed-up.png \ + pics/tab-bottom-active-bc.png pics/tab-bottom-active-bl.png\ + pics/tab-bottom-active-br.png pics/tab-bottom-active-cc.png\ + pics/tab-bottom-active-cl.png pics/tab-bottom-active-cr.png\ + pics/tab-bottom-inactive-bc.png pics/tab-bottom-inactive-bl.png\ + pics/tab-bottom-inactive-br.png pics/tab-bottom-inactive-cc.png\ + pics/tab-bottom-inactive-cl.png pics/tab-bottom-inactive-cr.png\ + pics/tab-bottom-inactive-separator.png pics/tab-top-active-cc.png\ + pics/tab-top-active-cl.png pics/tab-top-active-cr.png\ + pics/tab-top-active-tc.png pics/tab-top-active-tl.png\ + pics/tab-top-active-tr.png pics/tab-top-inactive-cc.png\ + pics/tab-top-inactive-cl.png pics/tab-top-inactive-cr.png\ + pics/tab-top-inactive-separator.png pics/tab-top-inactive-tc.png\ + pics/tab-top-inactive-tl.png pics/tab-top-inactive-tr.png pics/vslider.png\ + pics/pushbutton-hov-tl.png pics/pushbutton-hov-tc.png pics/pushbutton-hov-tr.png\ + pics/pushbutton-hov-cl.png pics/pushbutton-hov-cc.png pics/pushbutton-hov-cr.png\ + pics/pushbutton-hov-bl.png pics/pushbutton-hov-bc.png pics/pushbutton-hov-br.png\ + pics/title-close-tiny.png pics/title-close.png pics/title-iconify.png\ + pics/title-maximize.png pics/title-restore.png pics/titlebutton-pressed.png\ + pics/titlebutton.png + + +pixmaps.keramik keramikrc.h: genembed + pics=`ls $(srcdir)/pics/*.png 2>/dev/null` ;\ + ./genembed $$pics > pixmaps.keramik + +pixmaploader.lo: pixmaps.keramik + diff --git a/kstyles/keramik/bitmaps.h b/kstyles/keramik/bitmaps.h new file mode 100644 index 000000000..fd5dcf327 --- /dev/null +++ b/kstyles/keramik/bitmaps.h @@ -0,0 +1,83 @@ +#ifndef __BITMAPS_H +#define __BITMAPS_H + +/* Image bits processed by KPixmap2Bitmaps */ +// Arrow bitmaps +static const QCOORD u_arrow[]={-1,-3, 0,-3, -2,-2, 1,-2, -3,-1, 2,-1, -4,0, 3,0, -4,1, 3,1}; +static const QCOORD d_arrow[]={-4,-2, 3,-2, -4,-1, 3,-1, -3,0, 2,0, -2,1, 1,1, -1,2, 0,2}; +static const QCOORD l_arrow[]={-3,-1, -3,0, -2,-2, -2,1, -1,-3, -1,2, 0,-4, 0,3, 1,-4, 1,3}; +static const QCOORD r_arrow[]={-2,-4, -2,3, -1,-4, -1,3, 0,-3, 0,2, 1,-2, 1,1, 2,-1, 2,0}; + +static const QCOORD keramik_combo_arrow[] = + {-4,-5, 4, -5, + -2 ,-2, 2, -2, + -2 ,-1, 2, -1, + -2 ,0, 2, 0, + -4, 1, 4, 1, + -3, 2, 3, 2, + -2 , 3, 2, 3, + -1 , 4, 1, 4, + 0 , 5, 0, 5 + }; + + +static const QCOORD keramik_up_arrow[] = + { + 0, -4, 0, -4, + -1, -3, 1, -3, + -2, -2, 2, -2, + -3, -1, 3, -1, + -4, 0, 4, 0, + -2, 1, 2, 1, + -2, 2, 2, 2, + -2, 3, 2, 3, + -2, 4, 2, 4 + }; + +static const QCOORD keramik_down_arrow[] = + { + 0, 4, 0, 4, + -1, 3, 1, 3, + -2, 2, 2, 2, + -3, 1, 3, 1, + -4, 0, 4, 0, + -2, -1, 2, -1, + -2, -2, 2, -2, + -2, -3, 2, -3, + -2, -4, 2, -4 + }; + + + static const QCOORD keramik_right_arrow[] = + { + 4, 0, 4, 0, + 3, -1, 3, 1, + 2, -2, 2, 2, + 1, -3, 1, 3, + 0, -4, 0, 4, + -1, -2, -1, 2, + -2, -2, -2, 2, + -3, -2, -3, 2, + -4, -2, -4, 2 + }; + + static const QCOORD keramik_left_arrow[] = + { + -4, 0, -4, 0, + -3, -1, -3, 1, + -2, -2, -2, 2, + -1, -3, -1, 3, + 0, -4, 0, 4, + 1, -2, 1, 2, + 2, -2, 2, 2, + 3, -2, 3, 2, + 4, -2, 4, 2 + }; + + + +#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) + + + +#endif diff --git a/kstyles/keramik/colorutil.cpp b/kstyles/keramik/colorutil.cpp new file mode 100644 index 000000000..71bf75873 --- /dev/null +++ b/kstyles/keramik/colorutil.cpp @@ -0,0 +1,65 @@ +/* Keramik Style for KDE3, color utility routines.. + Copyright (c) 2002 Malte Starostik <[email protected]> + (c) 2002 Maksim Orlovich <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +// $Id$ + +#include <qcolor.h> + +#include "colorutil.h" + +namespace Keramik +{ + QColor ColorUtil::lighten(QColor in, int factor) + { + if (factor > 100) + { + int h, s, v; + in.hsv(&h, &s, &v); + + float mShare = v/230.0; + if (mShare > 1) mShare = 1; + + mShare *= mShare; + + int diff = factor - 100; + int hd = int(mShare*diff); + int delta = int((diff - hd)*7.55); + + QColor wrk = in.light(100+hd); + + int r = wrk.red(); + int g = wrk.green(); + int b = wrk.blue(); + + r+=delta; + g+=delta; + b+=delta; + + if (r>255) r=255; + if (g>255) g=255; + if (b>255) b=255; + + return QColor(r,g,b); + } + + return in; + } +} + +// vim: ts=4 sw=4 noet diff --git a/kstyles/keramik/colorutil.h b/kstyles/keramik/colorutil.h new file mode 100644 index 000000000..ae01b450a --- /dev/null +++ b/kstyles/keramik/colorutil.h @@ -0,0 +1,37 @@ +/* Keramik Style for KDE3, color utility routines... + Copyright (c) 2002 Malte Starostik <[email protected]> + (c) 2002 Maksim Orlovich <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +// $Id$ + +#ifndef KERAMIK_COLORUTIL_H +#define KERAMIK_COLORUTIL_H + +class QPainter; + + +namespace Keramik +{ + class ColorUtil + { + public: + static QColor lighten(QColor in, int factor); + }; +} + +#endif diff --git a/kstyles/keramik/genembed.cpp b/kstyles/keramik/genembed.cpp new file mode 100644 index 000000000..2f9449406 --- /dev/null +++ b/kstyles/keramik/genembed.cpp @@ -0,0 +1,387 @@ +/** +A small utility to generate embedded images for Keramik, especially structured for easy recoloring... + +Copyright (c) 2002 Maksim Orlovich <[email protected]> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include <qfileinfo.h> +#include <qimage.h> +#include <qmap.h> +#include <qregexp.h> +#include <qtextstream.h> +#include <qvaluevector.h> + +#include <kimageeffect.h> + +#include <iostream> +using namespace std; + +#include <string.h> +#include <math.h> + +//NOTE: Use of old-style header is intentional for portability. See revisions 1.6 and 1.7 + +//Force-touch-embedded-revision: 2 + +#include "keramikimage.h" + +/** +Need to generate something like this: +TargetColorAlpha, GreyAdd, SrcAlpha; + +so that one can do (R*T+GreyAdd, G*T+GreyAdd, B*T+GreyAdd, SrcAlpha) as pixel values +*/ + + +int evalSuffix(QString suffix) +{ + if (suffix == "-tl") + return 0; + + if (suffix == "-tc") + return 1; + + if (suffix == "-tr") + return 2; + + if (suffix == "-cl") + return 3; + + if (suffix == "-cc") + return 4; + + if (suffix == "-cr") + return 5; + + if (suffix == "-bl") + return 6; + + if (suffix == "-bc") + return 7; + + if (suffix == "-br") + return 8; + + if (suffix == "-separator") + return KeramikTileSeparator; + + if (suffix == "-slider1") + return KeramikSlider1; + + if (suffix == "-slider2") + return KeramikSlider2; + + if (suffix == "-slider3") + return KeramikSlider3; + + if (suffix == "-slider4") + return KeramikSlider4; + + if (suffix == "-groove1") + return KeramikGroove1; + + if (suffix == "-groove2") + return KeramikGroove2; + + if (suffix == "-1") + return 1; + + if (suffix == "-2") + return 2; + + if (suffix == "-3") + return 3; + + return -1; +} + + +int main(int argc, char** argv) +{ + if (argc < 2) + return 0; + + QValueVector<KeramikEmbedImage> images; + + cout<<"#include <qintdict.h>\n\n"; + cout<<"#include \"keramikimage.h\"\n\n"; + + QMap<QString, int> assignID; + int nextID = 0; + + for (int c = 1; c<argc; c++) + { + + QImage input(argv[c]); + + + QFileInfo fi(argv[c]); + QString s = fi.baseName(); + + KeramikEmbedImage image; + + int pos; + + QString id = s; + + int readJustID = 0; + + + if ((pos = s.findRev("-")) != -1) + { + int suffix = evalSuffix(s.mid(pos)); + if (suffix !=-1 ) + { + id = s.mid(0,pos); + readJustID = suffix; + } + } + + if (!assignID.contains(id)) + { + assignID[id] = nextID; + nextID += 256; + } + + s.replace("-","_"); + + + if (s.contains("button")) + KImageEffect::contrastHSV(input); + + int fullID = assignID[id] + readJustID;//Subwidget.. + + bool highlights = true; + bool shadows = true; + + float gamma = 1.0; + int brightAdj = 0; + + + + if (s.contains("toolbar") || s.contains("tab-top-active") || s.contains("menubar") ) + { +// highlights = false; + gamma = 1/1.25f; + //brightAdj = 10; + shadows = false; + } + + if (s.contains("scrollbar") && s.contains("groove")) + { + //highlights = false; + //gamma = 1.5; + shadows = false; + } + //brightAdj = -10; + + if (s.contains("scrollbar") && s.contains("slider")) + { + //highlights = false; + gamma =1/0.7f; + //shadows = false; + } + + + if (s.contains("menuitem")) + { + //highlights = false; + gamma =1/0.6f; + //shadows = false; + } + + image.width = input.width(); + image.height = input.height(); + image.id = fullID; + image.data = reinterpret_cast<unsigned char*>(strdup(s.latin1())); + + + bool reallySolid = true; + + int pixCount = 0; + int pixSolid = 0; + + cout<<"static const unsigned char "<<s.latin1()<<"[]={\n"; + + Q_UINT32* read = reinterpret_cast< Q_UINT32* >(input.bits() ); + int size = input.width()*input.height(); + + for (int pos=0; pos<size; pos++) + { + QRgb basePix = (QRgb)*read; + + if (qAlpha(basePix) != 255) + reallySolid = false; + else + pixSolid++; + + pixCount++; + read++; + } + + image.haveAlpha = !reallySolid; + + images.push_back(image); + + read = reinterpret_cast< Q_UINT32* >(input.bits() ); + for (int pos=0; pos<size; pos++) + { + QRgb basePix = (QRgb)*read; + //cout<<(r*destAlpha.alphas[pos])<<"\n"; + //cout<<(int)destAlpha.alphas[pos]<<"\n"; + QColor clr(basePix); + int h,s,v; + clr.hsv(&h,&s,&v); + + v=qGray(basePix); + + int targetColorAlpha = 0 , greyAdd = 0; + //int srcAlpha = qAlpha(basePix); + + if (s>0 || v > 128) + { //Non-shadow + float fv = v/255.0; + fv = pow(fv, gamma); + v = int(255.5*fv); + + + if (s<17 && highlights) //A bit of a highligt.. + { + float effectPortion = (16 - s)/15.0; + + greyAdd = (int)(v/4.0 * effectPortion*1.2); + targetColorAlpha = v - greyAdd; + } + else + { + targetColorAlpha = v;//(int)(fv*255); + greyAdd = 0; + } + } + else + { + if (shadows) + { + targetColorAlpha = 0; + greyAdd = v; + } + else + { + targetColorAlpha = v;//(int)(fv*255); + greyAdd = 0; + } + } + + greyAdd+=brightAdj; + + if (reallySolid) + cout<<targetColorAlpha<<","<<greyAdd<<","; + else + cout<<targetColorAlpha<<","<<greyAdd<<","<<qAlpha(basePix)<<","; + //cout<<qRed(basePix)<<","<<qGreen(basePix)<<","<<qBlue(basePix)<<","<<qAlpha(basePix)<<","; + + if (pos%8 == 7) + cout<<"\n"; + + read++; + } + + cerr<<s.latin1()<<":"<<pixSolid<<"/"<<pixCount<<"("<<reallySolid<<")\n"; + + cout<<!reallySolid<<"\n"; + + cout<<"};\n\n"; + } + + cout<<"static const KeramikEmbedImage image_db[] = {\n"; + + for (unsigned int c=0; c<images.size(); c++) + { + cout<<"\t{ "<<(images[c].haveAlpha?"true":"false")<<","<<images[c].width<<", "<<images[c].height<<", "<<images[c].id<<", "<<(char *)images[c].data<<"},"; + cout<<"\n"; + } + cout<<"\t{0, 0, 0, 0, 0}\n"; + cout<<"};\n\n"; + + cout<<"class KeramikImageDb\n"; + cout<<"{\n"; + cout<<"public:\n"; + cout<<"\tstatic KeramikImageDb* getInstance()\n"; + cout<<"\t{\n"; + cout<<"\t\tif (!instance) instance = new KeramikImageDb;\n"; + cout<<"\t\treturn instance;\n"; + cout<<"\t}\n\n"; + cout<<"\tstatic void release()\n"; + cout<<"\t{\n"; + cout<<"\t\tdelete instance;\n"; + cout<<"\t\tinstance=0;\n"; + cout<<"\t}\n\n"; + cout<<"\tKeramikEmbedImage* getImage(int id)\n"; + cout<<"\t{\n"; + cout<<"\t\treturn images[id];\n"; + cout<<"\t}\n\n"; + cout<<"private:\n"; + cout<<"\tKeramikImageDb():images(503)\n"; + cout<<"\t{\n"; + cout<<"\t\tfor (int c=0; image_db[c].width; c++)\n"; + cout<<"\t\t\timages.insert(image_db[c].id, &image_db[c]);\n"; + cout<<"\t}\n"; + cout<<"\tstatic KeramikImageDb* instance;\n"; + cout<<"\tQIntDict<KeramikEmbedImage> images;\n"; + cout<<"};\n\n"; + cout<<"KeramikImageDb* KeramikImageDb::instance = 0;\n\n"; + + cout<<"KeramikEmbedImage* KeramikGetDbImage(int id)\n"; + cout<<"{\n"; + cout<<"\treturn KeramikImageDb::getInstance()->getImage(id);\n"; + cout<<"}\n\n"; + + cout<<"void KeramikDbCleanup()\n"; + cout<<"{\n"; + cout<<"\t\tKeramikImageDb::release();\n"; + cout<<"}\n"; + + + + + QFile file("keramikrc.h"); + file.open(IO_WriteOnly); + QTextStream ts( &file); + ts<<"#ifndef KERAMIK_RC_H\n"; + ts<<"#define KERAMIK_RC_H\n"; + + ts<<"enum KeramikWidget {\n"; + for (QMap<QString, int>::iterator i = assignID.begin(); i != assignID.end(); ++i) + { + QString name = "keramik_"+i.key(); + name.replace("-","_"); + ts<<"\t"<<name<<" = "<<i.data()<<",\n"; + } + ts<<"\tkeramik_last\n"; + ts<<"};\n"; + + ts<<"#endif\n"; + + return 0; +} + +// vim: ts=4 sw=4 noet diff --git a/kstyles/keramik/gradients.cpp b/kstyles/keramik/gradients.cpp new file mode 100644 index 000000000..cf18500bd --- /dev/null +++ b/kstyles/keramik/gradients.cpp @@ -0,0 +1,179 @@ +/* Keramik Style for KDE3, gradient routines.. + Copyright (c) 2002 Malte Starostik <[email protected]> + (c) 2002 Maksim Orlovich <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +// $Id$ + +#include <qpainter.h> +#include <qrect.h> +#include <qcolor.h> + +#include "gradients.h" +#include "colorutil.h" + +#include <qimage.h> +#include <qintcache.h> +#include <kimageeffect.h> + +namespace +{ + struct GradientCacheEntry + { + QPixmap* m_pixmap; + QRgb m_color; + bool m_menu; + int m_width; + int m_height; + + GradientCacheEntry(int width, int height, const QColor& color, bool menu): + m_pixmap(0), m_color(color.rgb()), m_menu(menu), m_width(width), m_height(height) + {} + + int key() + { + return (int)m_menu ^ m_width ^ (m_height << 16) ^ ((m_color)<<8); + } + + bool operator == (const GradientCacheEntry& other) + { + return ((m_width == other.m_width) && + (m_height == other.m_height) && + (m_menu == other.m_menu) && + (m_color == other.m_color)); + } + + ~GradientCacheEntry() + { + delete m_pixmap; + } + + }; + + + QIntCache<GradientCacheEntry> cache(65636, 17); + +} + +using namespace Keramik; + +void GradientPainter::releaseCache() +{ + cache.clear(); +} + +void GradientPainter::renderGradient( QPainter* p, const QRect& r, QColor c, + bool horizontal, bool menu, int px, int py, + int pwidth, int pheight) +{ + int width = r.width(), height = r.height(); + if (pwidth != -1) width = pwidth; + if (pheight != -1) height = pheight; + + if (horizontal) + width = 18; + else + height = 18; + + GradientCacheEntry entry (width, height, c, menu); + GradientCacheEntry* cacheEntry = 0; + + cache.setAutoDelete(true); + + int key = entry.key(); + + if ((cacheEntry = cache.find(key, false))) + { + if (entry == *cacheEntry) + { + p->drawTiledPixmap(r, *cacheEntry->m_pixmap, horizontal? QPoint(0,py): QPoint(px,0)); + return; + } + else + cache.remove(key); + //Remove old entry in case of conflicts.. otherwise we end up w/unreachable items in cache + } + + + if (horizontal) + { + QPixmap* pix = new QPixmap(18, height); + + if (menu) + { + QImage gr = KImageEffect::gradient(QSize(4,height), c.light(93), ColorUtil::lighten(c,109), KImageEffect::VerticalGradient ); + QPixmap grT(gr); + QPainter p2(pix); + p2.drawTiledPixmap(0,0, 18, height, grT); + p2.end(); + } + else + { + int h1 = 3 * height/4; + int h2 = height - h1; + + QImage top = KImageEffect::gradient(QSize(4,h1), ColorUtil::lighten(c,110), c.light(94), KImageEffect::VerticalGradient ); + QImage bot = KImageEffect::gradient(QSize(4,h2), c.light(94), ColorUtil::lighten(c,109), KImageEffect::VerticalGradient ); + + QPixmap topT(top); + QPixmap botT(bot); + + QPainter p2(pix); + p2.drawTiledPixmap(0, 0, 18, h1, topT); + p2.drawTiledPixmap(0, h1, 18, h2, botT); + p2.end(); + } + + entry.m_pixmap = pix; + } + else + { + QPixmap* pix = new QPixmap(width, 18); + + int h1 = 3 * width/4; + int h2 = width - h1; + + QImage top = KImageEffect::gradient(QSize(h1,4), ColorUtil::lighten(c,110), c.light(94), KImageEffect::HorizontalGradient ); + QImage bot = KImageEffect::gradient(QSize(h2,4), c.light(94), ColorUtil::lighten(c,109), KImageEffect::HorizontalGradient ); + + QPixmap topT(top); + QPixmap botT(bot); + + QPainter p2(pix); + p2.drawTiledPixmap(0, 0, h1, 18, topT); + p2.drawTiledPixmap(h1, 0, h2, 18, botT); + p2.end(); + + entry.m_pixmap = pix; + + } + + bool cacheOK = false; + GradientCacheEntry* imgToAdd = new GradientCacheEntry(entry); + cacheOK = cache.insert(imgToAdd->key(), imgToAdd, + imgToAdd->m_pixmap->width() * imgToAdd->m_pixmap->height()* + imgToAdd->m_pixmap->depth()/8); + + p->drawTiledPixmap(r, *imgToAdd->m_pixmap, horizontal? QPoint(0,py): QPoint(px,0)); + + if (!cacheOK) + delete imgToAdd; + + entry.m_pixmap = 0;//Don't free too early.. +} + +// vim: ts=4 sw=4 noet diff --git a/kstyles/keramik/gradients.h b/kstyles/keramik/gradients.h new file mode 100644 index 000000000..d4dfd2c95 --- /dev/null +++ b/kstyles/keramik/gradients.h @@ -0,0 +1,41 @@ +/* Keramik Style for KDE3, gradient routines.. + Copyright (c) 2002 Malte Starostik <[email protected]> + (c) 2002 Maksim Orlovich <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +// $Id$ + +#ifndef KERAMIK_GRADIENTS_H +#define KERAMIK_GRADIENTS_H + +class QPainter; + + +namespace Keramik +{ + class GradientPainter + { + public: + static void renderGradient( QPainter* p, const QRect& r, QColor cr, + bool horizontal, bool menu = false, + int px = 0, int py = 0, int pwidth = -1, int pheight = -1 ); + + static void releaseCache(); + }; +} + +#endif diff --git a/kstyles/keramik/keramik.cpp b/kstyles/keramik/keramik.cpp new file mode 100644 index 000000000..5157c34ed --- /dev/null +++ b/kstyles/keramik/keramik.cpp @@ -0,0 +1,2935 @@ +/* Keramik Style for KDE3 + Copyright (c) 2002 Malte Starostik <[email protected]> + (c) 2002,2003 Maksim Orlovich <[email protected]> + + based on the KDE3 HighColor Style + + Copyright (C) 2001-2002 Karol Szwed <[email protected]> + (C) 2001-2002 Fredrik H�glund <[email protected]> + + Drawing routines adapted from the KDE2 HCStyle, + Copyright (C) 2000 Daniel M. Duley <[email protected]> + (C) 2000 Dirk Mueller <[email protected]> + (C) 2001 Martijn Klingens <[email protected]> + + Progressbar code based on KStyle, Copyright (C) 2001-2002 Karol Szwed <[email protected]>, + Improvements to progressbar animation from Plastik, Copyright (C) 2003 Sandro Giessl <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// $Id$ + +#include <qbitmap.h> +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qdrawutil.h> +#include <qframe.h> +#include <qheader.h> +#include <qintdict.h> +#include <qlineedit.h> +#include <qlistbox.h> +#include <qmenubar.h> +#include <qpainter.h> +#include <qpointarray.h> +#include <qprogressbar.h> +#include <qpushbutton.h> +#include <qsettings.h> +#include <qslider.h> +#include <qstyleplugin.h> +#include <qtabbar.h> +#include <qtimer.h> +#include <qtoolbar.h> +#include <qtoolbutton.h> + +#include <kpixmap.h> +#include <kpixmapeffect.h> + +#include "keramik.moc" + +#include "gradients.h" +#include "colorutil.h" +#include "keramikrc.h" +#include "keramikimage.h" + +#include "bitmaps.h" +#include "pixmaploader.h" + +#define loader Keramik::PixmapLoader::the() + +// -- Style Plugin Interface ------------------------- +class KeramikStylePlugin : public QStylePlugin +{ +public: + KeramikStylePlugin() {} + ~KeramikStylePlugin() {} + + QStringList keys() const + { + if (QPixmap::defaultDepth() > 8) + return QStringList() << "Keramik"; + else + return QStringList(); + } + + QStyle* create( const QString& key ) + { + if ( key == "keramik" ) return new KeramikStyle(); + return 0; + } +}; + +KDE_Q_EXPORT_PLUGIN( KeramikStylePlugin ) +// --------------------------------------------------- + + +// ### Remove globals +/* +QBitmap lightBmp; +QBitmap grayBmp; +QBitmap dgrayBmp; +QBitmap centerBmp; +QBitmap maskBmp; +QBitmap xBmp; +*/ +namespace +{ + const int itemFrame = 2; + const int itemHMargin = 6; + const int itemVMargin = 0; + const int arrowHMargin = 6; + const int rightBorder = 12; + const char* kdeToolbarWidget = "kde toolbar widget"; + + const int smallButMaxW = 27; + const int smallButMaxH = 20; + const int titleBarH = 22; +} +// --------------------------------------------------------------------------- + +namespace +{ + void drawKeramikArrow(QPainter* p, QColorGroup cg, QRect r, QStyle::PrimitiveElement pe, bool down, bool enabled) + { + QPointArray a; + + switch(pe) + { + case QStyle::PE_ArrowUp: + a.setPoints(QCOORDARRLEN(keramik_up_arrow), keramik_up_arrow); + break; + + case QStyle::PE_ArrowDown: + a.setPoints(QCOORDARRLEN(keramik_down_arrow), keramik_down_arrow); + break; + + case QStyle::PE_ArrowLeft: + a.setPoints(QCOORDARRLEN(keramik_left_arrow), keramik_left_arrow); + break; + + default: + a.setPoints(QCOORDARRLEN(keramik_right_arrow), keramik_right_arrow); + } + + p->save(); + /*if ( down ) + p->translate( pixelMetric( PM_ButtonShiftHorizontal ), + pixelMetric( PM_ButtonShiftVertical ) ); + */ + + if ( enabled ) { + //CHECKME: Why is the -1 needed? + a.translate( r.x() + r.width() / 2 - 1, r.y() + r.height() / 2 ); + + if (!down) + p->setPen( cg.buttonText() ); + else + p->setPen ( cg.button() ); + p->drawLineSegments( a ); + } else { + a.translate( r.x() + r.width() / 2, r.y() + r.height() / 2 + 1 ); + p->setPen( cg.light() ); + p->drawLineSegments( a ); + a.translate( -1, -1 ); + p->setPen( cg.mid() ); + p->drawLineSegments( a ); + } + p->restore(); + } +} + +// XXX +/* reimp. */ +void KeramikStyle::renderMenuBlendPixmap( KPixmap& pix, const QColorGroup &cg, + const QPopupMenu* /* popup */ ) const +{ + QColor col = cg.button(); + +#ifdef Q_WS_X11 // Only draw menu gradients on TrueColor, X11 visuals + if ( QPaintDevice::x11AppDepth() >= 24 ) + KPixmapEffect::gradient( pix, col.light(120), col.dark(115), + KPixmapEffect::HorizontalGradient ); + else +#endif + pix.fill( col ); +} + +// XXX +QRect KeramikStyle::subRect(SubRect r, const QWidget *widget) const +{ + // We want the focus rect for buttons to be adjusted from + // the Qt3 defaults to be similar to Qt 2's defaults. + // ------------------------------------------------------------------- + switch ( r ) + { + case SR_PushButtonFocusRect: + { + const QPushButton* button = (const QPushButton*) widget; + QRect wrect(widget->rect()); + + if (button->isDefault() || button->autoDefault()) + { + return QRect(wrect.x() + 6, wrect.y() + 5, wrect.width() - 12, wrect.height() - 10); + } + else + { + return QRect(wrect.x() + 3, wrect.y() + 5, wrect.width() - 8, wrect.height() - 10); + } + + break; + } + + case SR_ComboBoxFocusRect: + { + return querySubControlMetrics( CC_ComboBox, widget, SC_ComboBoxEditField ); + } + + case SR_CheckBoxFocusRect: + { + const QCheckBox* cb = static_cast<const QCheckBox*>(widget); + + //Only checkbox, no label + if (cb->text().isEmpty() && (cb->pixmap() == 0) ) + { + QRect bounding = cb->rect(); + QSize checkDim = loader.size( keramik_checkbox_on); + int cw = checkDim.width(); + int ch = checkDim.height(); + + QRect checkbox(bounding.x() + 1, bounding.y() + 1 + (bounding.height() - ch)/2, + cw - 3, ch - 4); + + return checkbox; + } + + //Fallthrough intentional + } + + default: + return KStyle::subRect( r, widget ); + } +} + + +QPixmap KeramikStyle::stylePixmap(StylePixmap stylepixmap, + const QWidget* widget, + const QStyleOption& opt) const +{ + switch (stylepixmap) { + case SP_TitleBarMinButton: + return Keramik::PixmapLoader::the().pixmap(keramik_title_iconify, + Qt::black, Qt::black, false, false); + //return qpixmap_from_bits( iconify_bits, "title-iconify.png" ); + case SP_TitleBarMaxButton: + return Keramik::PixmapLoader::the().pixmap(keramik_title_maximize, + Qt::black, Qt::black, false, false); + case SP_TitleBarCloseButton: + if (widget && widget->inherits("KDockWidgetHeader")) + return Keramik::PixmapLoader::the().pixmap(keramik_title_close_tiny, + Qt::black, Qt::black, false, false); + else return Keramik::PixmapLoader::the().pixmap(keramik_title_close, + Qt::black, Qt::black, false, false); + case SP_TitleBarNormalButton: + return Keramik::PixmapLoader::the().pixmap(keramik_title_restore, + Qt::black, Qt::black, false, false); + default: + break; + } + + return KStyle::stylePixmap(stylepixmap, widget, opt); +} + + + + +KeramikStyle::KeramikStyle() + :KStyle( AllowMenuTransparency | FilledFrameWorkaround, ThreeButtonScrollBar ), + maskMode(false), formMode(false), + toolbarBlendWidget(0), titleBarMode(None), flatMode(false), customScrollMode(false), kickerMode(false) +{ + forceSmallMode = false; + hoverWidget = 0; + + QSettings settings; + + highlightScrollBar = settings.readBoolEntry("/keramik/Settings/highlightScrollBar", true); + animateProgressBar = settings.readBoolEntry("/keramik/Settings/animateProgressBar", false); + + if (animateProgressBar) + { + animationTimer = new QTimer( this ); + connect( animationTimer, SIGNAL(timeout()), this, SLOT(updateProgressPos()) ); + } + + firstComboPopupRelease = false; +} + +void KeramikStyle::updateProgressPos() +{ + //Update the registered progressbars. + QMap<QProgressBar*, int>::iterator iter; + bool visible = false; + for (iter = progAnimWidgets.begin(); iter != progAnimWidgets.end(); ++iter) + { + QProgressBar* pbar = iter.key(); + if (pbar->isVisible() && pbar->isEnabled() && + pbar->progress() != pbar->totalSteps()) + { + ++iter.data(); + if (iter.data() == 28) + iter.data() = 0; + iter.key()->update(); + } + if (iter.key()->isVisible()) + visible = true; + + } + if (!visible) + animationTimer->stop(); +} + +KeramikStyle::~KeramikStyle() +{ + Keramik::PixmapLoader::release(); + Keramik::GradientPainter::releaseCache(); + KeramikDbCleanup(); +} + +void KeramikStyle::polish(QApplication* app) +{ + if (!qstrcmp(app->argv()[0], "kicker")) + kickerMode = true; +} + +void KeramikStyle::polish(QWidget* widget) +{ + // Put in order of highest occurrence to maximise hit rate + if ( widget->inherits( "QPushButton" ) || widget->inherits( "QComboBox" ) || widget->inherits("QToolButton") ) + { + widget->installEventFilter(this); + if ( widget->inherits( "QComboBox" ) ) + widget->setBackgroundMode( NoBackground ); + } + else if ( widget->inherits( "QMenuBar" ) || widget->inherits( "QPopupMenu" ) ) + widget->setBackgroundMode( NoBackground ); + + else if ( widget->parentWidget() && + ( ( widget->inherits( "QListBox" ) && widget->parentWidget()->inherits( "QComboBox" ) ) || + widget->inherits( "KCompletionBox" ) ) ) { + QListBox* listbox = (QListBox*) widget; + listbox->setLineWidth( 4 ); + listbox->setBackgroundMode( NoBackground ); + widget->installEventFilter( this ); + + } else if (widget->inherits("QToolBarExtensionWidget")) { + widget->installEventFilter(this); + //widget->setBackgroundMode( NoBackground ); + } + else if ( !qstrcmp( widget->name(), kdeToolbarWidget ) ) { + widget->setBackgroundMode( NoBackground ); + widget->installEventFilter(this); + } + + if (animateProgressBar && ::qt_cast<QProgressBar*>(widget)) + { + widget->installEventFilter(this); + progAnimWidgets[static_cast<QProgressBar*>(widget)] = 0; + connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(progressBarDestroyed(QObject*))); + if (!animationTimer->isActive()) + animationTimer->start( 50, false ); + } + + KStyle::polish(widget); +} + +void KeramikStyle::unPolish(QWidget* widget) +{ + //### TODO: This needs major cleanup (and so does polish() ) + if ( widget->inherits( "QPushButton" ) || widget->inherits( "QComboBox" ) ) + { + if ( widget->inherits( "QComboBox" ) ) + widget->setBackgroundMode( PaletteButton ); + widget->removeEventFilter(this); + } + else if ( widget->inherits( "QMenuBar" ) || widget->inherits( "QPopupMenu" ) ) + widget->setBackgroundMode( PaletteBackground ); + + else if ( widget->parentWidget() && + ( ( widget->inherits( "QListBox" ) && widget->parentWidget()->inherits( "QComboBox" ) ) || + widget->inherits( "KCompletionBox" ) ) ) { + QListBox* listbox = (QListBox*) widget; + listbox->setLineWidth( 1 ); + listbox->setBackgroundMode( PaletteBackground ); + widget->removeEventFilter( this ); + widget->clearMask(); + } else if (widget->inherits("QToolBarExtensionWidget")) { + widget->removeEventFilter(this); + } + else if ( !qstrcmp( widget->name(), kdeToolbarWidget ) ) { + widget->setBackgroundMode( PaletteBackground ); + widget->removeEventFilter(this); + } + else if ( ::qt_cast<QProgressBar*>(widget) ) + { + progAnimWidgets.remove(static_cast<QProgressBar*>(widget)); + } + + KStyle::unPolish(widget); +} + +void KeramikStyle::progressBarDestroyed(QObject* obj) +{ + progAnimWidgets.remove(static_cast<QProgressBar*>(obj)); +} + + +void KeramikStyle::polish( QPalette& ) +{ + loader.clear(); +} + +/** + Draws gradient background for toolbar buttons, handles and spacers +*/ +static void renderToolbarEntryBackground(QPainter* paint, + const QToolBar* parent, QRect r, const QColorGroup& cg, bool horiz) +{ + int toolWidth, toolHeight; + + //Do we have a parent toolbar to use? + if (parent) + { + //Calculate the toolbar geometry. + //The initial guess is the size of the parent widget + toolWidth = parent->width(); + toolHeight = parent->height(); + + //If we're floating, however, wee need to fiddle + //with height to skip the titlebar + if (parent->place() == QDockWindow::OutsideDock) + { + toolHeight = toolHeight - titleBarH - 2*parent->frameWidth() + 2; + //2 at the end = the 2 pixels of border of a "regular" + //toolbar we normally paint over. + } + } + else + { + //No info, make a guess. + //We take the advantage of the fact that the non-major + //sizing direction parameter is ignored + toolWidth = r.width () + 2; + toolHeight = r.height() + 2; + } + + //Calculate where inside the toolbar we're + int xoff = 0, yoff = 0; + if (horiz) + yoff = (toolHeight - r.height())/2; + else + xoff = (toolWidth - r.width())/2; + + Keramik::GradientPainter::renderGradient( paint, r, cg.button(), + horiz, false /*Not a menubar*/, + xoff, yoff, + toolWidth, toolHeight); +} + +static void renderToolbarWidgetBackground(QPainter* painter, const QWidget* widget) +{ + // Draw a gradient background for custom widgets in the toolbar + // that have specified a "kde toolbar widget" name, or + // are caught as toolbar widgets otherwise + + // Find the top-level toolbar of this widget, since it may be nested in other + // widgets that are on the toolbar. + QWidget *parent = static_cast<QWidget*>(widget->parentWidget()); + int x_offset = widget->x(), y_offset = widget->y(); + while (parent && parent->parent() && !qstrcmp( parent->name(), kdeToolbarWidget ) ) + { + x_offset += parent->x(); + y_offset += parent->y(); + parent = static_cast<QWidget*>(parent->parent()); + } + + QRect pr = parent->rect(); + bool horiz_grad = pr.width() > pr.height(); + + int toolHeight = parent->height(); + int toolWidth = parent->width (); + + // Check if the parent is a QToolbar, and use its orientation, else guess. + //Also, get the height to use in the gradient from it. + QToolBar* tb = dynamic_cast<QToolBar*>(parent); + if (tb) + { + horiz_grad = tb->orientation() == Qt::Horizontal; + + //If floating, we need to skip the titlebar. + if (tb->place() == QDockWindow::OutsideDock) + { + toolHeight = tb->height() - titleBarH - 2*tb->frameWidth() + 2; + //Calculate offset here by looking at the bottom edge difference, and height. + //First, calculate by how much the widget needs to be extended to touch + //the bottom edge, minus the frame (except we use the current y_offset + // to map to parent coordinates) + int needToTouchBottom = tb->height() - tb->frameWidth() - + (widget->rect().bottom() + y_offset); + + //Now, with that, we can see which portion to skip in the full-height + //gradient -- which is the stuff other than the extended + //widget + y_offset = toolHeight - (widget->height() + needToTouchBottom) - 1; + } + } + + if (painter) + { + Keramik::GradientPainter::renderGradient( painter, widget->rect(), + widget->colorGroup().button(), horiz_grad, false, + x_offset, y_offset, toolWidth, toolHeight); + } + else + { + QPainter p( widget ); + Keramik::GradientPainter::renderGradient( &p, widget->rect(), + widget->colorGroup().button(), horiz_grad, false, + x_offset, y_offset, toolWidth, toolHeight); + } +} + +// This function draws primitive elements as well as their masks. +void KeramikStyle::drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + bool down = flags & Style_Down; + bool on = flags & Style_On; + bool disabled = ( flags & Style_Enabled ) == 0; + int x, y, w, h; + r.rect(&x, &y, &w, &h); + + int x2 = x+w-1; + int y2 = y+h-1; + + switch(pe) + { + // BUTTONS + // ------------------------------------------------------------------- + case PE_ButtonDefault: + { + bool sunken = on || down; + + int id; + if ( sunken ) id = keramik_pushbutton_default_pressed; + else id = keramik_pushbutton_default; + + if (flags & Style_MouseOver && id == keramik_pushbutton_default ) + id = keramik_pushbutton_default_hov; + + + //p->fillRect( r, cg.background() ); + Keramik::RectTilePainter( id, false ).draw(p, r, cg.button(), cg.background(), disabled, pmode() ); + break; + } + + case PE_ButtonDropDown: + case PE_ButtonTool: + { + if (titleBarMode) + { + QRect nr; + if (titleBarMode == Maximized) + { + //### What should we draw at sides? + nr = QRect(r.x(), r.y(), r.width()-1, r.height() ); + } + else + { + int offX = (r.width() - 15)/2; + int offY = (r.height() - 15)/2; + + if (flags & Style_Down) + offY += 1; + + nr = QRect(r.x()+offX, r.y()+offY, 15, 15); + } + + Keramik::ScaledPainter(flags & Style_Down ? keramik_titlebutton_pressed : keramik_titlebutton, + Keramik::ScaledPainter::Both).draw( p, nr, cg.button(), cg.background()); + return; + } + + if (on) + { + Keramik::RectTilePainter(keramik_toolbar_clk).draw(p, r, cg.button(), cg.background()); + p->setPen(cg.dark()); + p->drawLine(x, y, x2, y); + p->drawLine(x, y, x, y2); + } + else if (down) + { + Keramik::RectTilePainter(keramik_toolbar_clk).draw(p, r, cg.button(), cg.background()); + } + else { + if (flags & Style_MouseOver) + { + Keramik::GradientPainter::renderGradient( p, + QRect(r.x(), 0, r.width(), r.height()), + Keramik::ColorUtil::lighten(cg.button(), 115), flags & Style_Horizontal, false ); + } + else + Keramik::GradientPainter::renderGradient( p, + QRect(r.x(), 0, r.width(), r.height()), + cg.button(), flags & Style_Horizontal, false ); + + p->setPen(cg.button().light(70)); + p->drawLine(x, y, x2-1, y); + p->drawLine(x, y, x, y2-1); + p->drawLine(x+2, y2-1, x2-1, y2-1); + p->drawLine(x2-1, y+2, x2-1, y2-2); + + p->setPen(Keramik::ColorUtil::lighten(cg.button(), 115) ); + p->drawLine(x+1, y+1, x2-1, y+1); + p->drawLine(x+1, y+1, x+1, y2); + p->drawLine(x, y2, x2, y2); + p->drawLine(x2, y, x2, y2); + } + + break; + } + + // PUSH BUTTON + // ------------------------------------------------------------------- + case PE_ButtonCommand: + { + bool sunken = on || down; + + int name; + + if ( w <= smallButMaxW || h <= smallButMaxH || forceSmallMode) + { + if (sunken) + name = keramik_pushbutton_small_pressed; + else + name = keramik_pushbutton_small; + forceSmallMode = false; + } + else + { + if (sunken) + name = keramik_pushbutton_pressed; + else + name = keramik_pushbutton; + } + + if (flags & Style_MouseOver && name == keramik_pushbutton ) + name = keramik_pushbutton_hov; + + if (toolbarBlendWidget && !flatMode ) + { + //Render the toolbar gradient. + renderToolbarWidgetBackground(p, toolbarBlendWidget); + + //Draw and blend the actual bevel.. + Keramik::RectTilePainter( name, false ).draw(p, r, cg.button(), cg.background(), + disabled, Keramik::TilePainter::PaintFullBlend ); + } + else if (!flatMode) + Keramik::RectTilePainter( name, false ).draw(p, r, cg.button(), cg.background(), disabled, pmode() ); + else { + Keramik::ScaledPainter( name + KeramikTileCC, Keramik::ScaledPainter::Vertical).draw( + p, r, cg.button(), cg.background(), disabled, pmode() ); + + p->setPen(cg.button().light(75)); + + p->drawLine(x, y, x2, y); + p->drawLine(x, y, x, y2); + p->drawLine(x, y2, x2, y2); + p->drawLine(x2, y, x2, y2); + flatMode = false; + } + + break; + + } + + // BEVELS + // ------------------------------------------------------------------- + case PE_ButtonBevel: + { + int x,y,w,h; + r.rect(&x, &y, &w, &h); + bool sunken = on || down; + int x2 = x+w-1; + int y2 = y+h-1; + + // Outer frame + p->setPen(cg.shadow()); + p->drawRect(r); + + // Bevel + p->setPen(sunken ? cg.mid() : cg.light()); + p->drawLine(x+1, y+1, x2-1, y+1); + p->drawLine(x+1, y+1, x+1, y2-1); + p->setPen(sunken ? cg.light() : cg.mid()); + p->drawLine(x+2, y2-1, x2-1, y2-1); + p->drawLine(x2-1, y+2, x2-1, y2-1); + + if (w > 4 && h > 4) + { + if (sunken) + p->fillRect(x+2, y+2, w-4, h-4, cg.button()); + else + Keramik::GradientPainter::renderGradient( p, QRect(x+2, y+2, w-4, h-4), + cg.button(), flags & Style_Horizontal ); + } + break; + } + + + // FOCUS RECT + // ------------------------------------------------------------------- + case PE_FocusRect: + //Qt may pass the background color to use for the focus indicator + //here. This particularly happens within the iconview. + //If that happens, pass it on to drawWinFocusRect() so it can + //honor it + if ( opt.isDefault() ) + p->drawWinFocusRect( r ); + else + p->drawWinFocusRect( r, opt.color() ); + break; + + // HEADER SECTION + // ------------------------------------------------------------------- + case PE_HeaderSection: + if ( flags & Style_Down ) + Keramik::RectTilePainter( keramik_listview_pressed, false ).draw( p, r, cg.button(), cg.background() ); + else + Keramik::RectTilePainter( keramik_listview, false ).draw( p, r, cg.button(), cg.background() ); + break; + + case PE_HeaderArrow: + if ( flags & Style_Up ) + drawPrimitive( PE_ArrowUp, p, r, cg, Style_Enabled ); + else drawPrimitive( PE_ArrowDown, p, r, cg, Style_Enabled ); + break; + + + // // SCROLLBAR + // ------------------------------------------------------------------- + + case PE_ScrollBarSlider: + { + bool horizontal = flags & Style_Horizontal; + bool active = ( flags & Style_Active ) || ( flags & Style_Down ); + int name = KeramikSlider1; + unsigned int count = 3; + + + + if ( horizontal ) + { + if ( w > ( loader.size( keramik_scrollbar_hbar+KeramikSlider1 ).width() + + loader.size( keramik_scrollbar_hbar+KeramikSlider4 ).width() + + loader.size( keramik_scrollbar_hbar+KeramikSlider3 ).width() + 2 ) ) + count = 5; + } + else if ( h > ( loader.size( keramik_scrollbar_vbar+KeramikSlider1 ).height() + + loader.size( keramik_scrollbar_vbar+KeramikSlider4 ).height() + + loader.size( keramik_scrollbar_vbar+KeramikSlider3 ).height() + 2 ) ) + count = 5; + + QColor col = cg.highlight(); + + if (customScrollMode || !highlightScrollBar) + col = cg.button(); + + if (!active) + Keramik::ScrollBarPainter( name, count, horizontal ).draw( p, r, col, cg.background(), false, pmode() ); + else + Keramik::ScrollBarPainter( name, count, horizontal ).draw( p, r, Keramik::ColorUtil::lighten(col ,110), + cg.background(), false, pmode() ); + break; + } + + case PE_ScrollBarAddLine: + { + bool down = flags & Style_Down; + + if ( flags & Style_Horizontal ) + { + Keramik::CenteredPainter painter( keramik_scrollbar_hbar_arrow2 ); + painter.draw( p, r, down? cg.buttonText() : cg.button(), cg.background(), disabled, pmode() ); + + p->setPen( cg.buttonText() ); + p->drawLine(r.x()+r.width()/2 - 1, r.y() + r.height()/2 - 3, + r.x()+r.width()/2 - 1, r.y() + r.height()/2 + 3); + + + drawKeramikArrow(p, cg, QRect(r.x(), r.y(), r.width()/2, r.height()), PE_ArrowLeft, down, !disabled); + + drawKeramikArrow(p, cg, QRect(r.x()+r.width()/2, r.y(), r.width() - r.width()/2, r.height()), + PE_ArrowRight, down, !disabled); + } + else + { + Keramik::CenteredPainter painter( keramik_scrollbar_vbar_arrow2 ); + painter.draw( p, r, down? cg.buttonText() : cg.button(), cg.background(), disabled, pmode() ); + + p->setPen( cg.buttonText() ); + p->drawLine(r.x()+r.width()/2 - 4, r.y()+r.height()/2, + r.x()+r.width()/2 + 2, r.y()+r.height()/2); + + + drawKeramikArrow(p, cg, QRect(r.x(), r.y(), r.width(), r.height()/2), PE_ArrowUp, down, !disabled); + + drawKeramikArrow(p, cg, QRect(r.x(), r.y()+r.height()/2, r.width(), r.height() - r.height()/2), + PE_ArrowDown, down, !disabled); + //drawKeramikArrow(p, cg, r, PE_ArrowUp, down, !disabled); + } + + + break; + } + + case PE_ScrollBarSubLine: + { + bool down = flags & Style_Down; + + if ( flags & Style_Horizontal ) + { + Keramik::CenteredPainter painter(keramik_scrollbar_hbar_arrow1 ); + painter.draw( p, r, down? cg.buttonText() : cg.button(), cg.background(), disabled, pmode() ); + drawKeramikArrow(p, cg, r, PE_ArrowLeft, down, !disabled); + + } + else + { + Keramik::CenteredPainter painter( keramik_scrollbar_vbar_arrow1 ); + painter.draw( p, r, down? cg.buttonText() : cg.button(), cg.background(), disabled, pmode() ); + drawKeramikArrow(p, cg, r, PE_ArrowUp, down, !disabled); + } + break; + } + + // CHECKBOX (indicator) + // ------------------------------------------------------------------- + case PE_Indicator: + case PE_IndicatorMask: + + if (flags & Style_On) + Keramik::ScaledPainter( keramik_checkbox_on ).draw( p, r, cg.button(), cg.background(), disabled, pmode() ); + else if (flags & Style_Off) + Keramik::ScaledPainter( keramik_checkbox_off ).draw( p, r, cg.button(), cg.background(), disabled, pmode() ); + else + Keramik::ScaledPainter( keramik_checkbox_tri ).draw( p, r, cg.button(), cg.background(), disabled, pmode() ); + + break; + + // RADIOBUTTON (exclusive indicator) + // ------------------------------------------------------------------- + case PE_ExclusiveIndicator: + case PE_ExclusiveIndicatorMask: + { + + Keramik::ScaledPainter( on ? keramik_radiobutton_on : keramik_radiobutton_off ).draw( p, r, cg.button(), cg.background(), disabled, pmode() ); + break; + } + + // line edit frame + case PE_PanelLineEdit: + { + if ( opt.isDefault() || opt.lineWidth() == 1 ) + { + //1-pixel frames can not be simply clipped wider frames, as that would produce too little contrast on the lower border + p->setPen( cg.dark() ); + p->drawLine( x, y, x + w - 1, y ); + p->drawLine( x, y, x, y + h - 1 ); + + p->setPen( cg.light().dark( 110 ) ); + p->drawLine( x + w - 1, y, x + w - 1, y + h - 1 ); + p->drawLine( x, y + h - 1, x + w - 1, y + h - 1); + } + else + { + p->setPen( cg.dark() ); + p->drawLine( x, y, x + w - 1, y ); + p->drawLine( x, y, x, y + h - 1 ); + p->setPen( cg.mid() ); + p->drawLine( x + 1, y + 1, x + w - 1, y + 1 ); + p->drawLine( x + 1, y + 1, x + 1, y + h - 1 ); + p->setPen( cg.light() ); + p->drawLine( x + w - 1, y, x + w - 1, y + h - 1 ); + p->drawLine( x, y + h - 1, x + w - 1, y + h - 1); + p->setPen( cg.light().dark( 110 ) ); + p->drawLine( x + w - 2, y + 1, x + w - 2, y + h - 2 ); + p->drawLine( x + 1, y + h - 2, x + w - 2, y + h - 2); + } + break; + } + + // SPLITTER/DOCKWINDOW HANDLES + // ------------------------------------------------------------------- + case PE_DockWindowResizeHandle: + case PE_Splitter: + { + int x,y,w,h; + r.rect(&x, &y, &w, &h); + int x2 = x+w-1; + int y2 = y+h-1; + + p->setPen(cg.dark()); + p->drawRect( r ); + p->setPen(cg.background()); + p->drawPoint(x, y); + p->drawPoint(x2, y); + p->drawPoint(x, y2); + p->drawPoint(x2, y2); + p->setPen(cg.light()); + p->drawLine(x+1, y+1, x+1, y2-1); + p->drawLine(x+1, y+1, x2-1, y+1); + p->setPen(cg.midlight()); + p->drawLine(x+2, y+2, x+2, y2-2); + p->drawLine(x+2, y+2, x2-2, y+2); + p->setPen(cg.mid()); + p->drawLine(x2-1, y+1, x2-1, y2-1); + p->drawLine(x+1, y2-1, x2-1, y2-1); + p->fillRect(x+3, y+3, w-5, h-5, cg.brush(QColorGroup::Background)); + break; + } + + + //case PE_PanelPopup: + //p->setPen (cg.light() ); + //p->setBrush( cg.background().light( 110 ) ); + //p->drawRect( r ); + + //p->setPen( cg.shadow() ); + //p->drawRect( r.x()+1, r.y()+1, r.width()-2, r.height()-2); + //p->fillRect( visualRect( QRect( x + 1, y + 1, 23, h - 2 ), r ), cg.background().dark( 105 ) ); + //break; + + // GENERAL PANELS + // ------------------------------------------------------------------- + case PE_Panel: + { + if (kickerMode) + { + if (p->device() && p->device()->devType() == QInternal::Widget && + QCString(static_cast<QWidget*>(p->device())->className()) == "FittsLawFrame" ) + { + int x2 = x + r.width() - 1; + int y2 = y + r.height() - 1; + p->setPen(cg.dark()); + p->drawLine(x+1,y2,x2-1,y2); + p->drawLine(x2,y+1,x2,y2); + + p->setPen( cg.light() ); + p->drawLine(x, y, x2, y); + p->drawLine(x, y, x, y2); + + + return; + } + } + KStyle::drawPrimitive(pe, p, r, cg, flags, opt); + break; + } + case PE_WindowFrame: + { + bool sunken = flags & Style_Sunken; + int lw = opt.isDefault() ? pixelMetric(PM_DefaultFrameWidth) + : opt.lineWidth(); + if (lw == 2) + { + QPen oldPen = p->pen(); + int x,y,w,h; + r.rect(&x, &y, &w, &h); + int x2 = x+w-1; + int y2 = y+h-1; + p->setPen(sunken ? cg.light() : cg.dark()); + p->drawLine(x, y2, x2, y2); + p->drawLine(x2, y, x2, y2); + p->setPen(sunken ? cg.mid() : cg.light()); + p->drawLine(x, y, x2, y); + p->drawLine(x, y, x, y2); + p->setPen(sunken ? cg.midlight() : cg.mid()); + p->drawLine(x+1, y2-1, x2-1, y2-1); + p->drawLine(x2-1, y+1, x2-1, y2-1); + p->setPen(sunken ? cg.dark() : cg.midlight()); + p->drawLine(x+1, y+1, x2-1, y+1); + p->drawLine(x+1, y+1, x+1, y2-1); + p->setPen(oldPen); + } else + KStyle::drawPrimitive(pe, p, r, cg, flags, opt); + + break; + } + + + // MENU / TOOLBAR PANEL + // ------------------------------------------------------------------- + case PE_PanelMenuBar: // Menu + { + Keramik::GradientPainter::renderGradient( p, r, cg.button(), true, true); + //Keramik::ScaledPainter( keramik_menubar , Keramik::ScaledPainter::Vertical).draw( p, r, cg.button(), cg.background() ); + + int x2 = r.x()+r.width()-1; + int y2 = r.y()+r.height()-1; + int lw = opt.isDefault() ? pixelMetric(PM_DefaultFrameWidth) + : opt.lineWidth(); + if (lw) + { + p->setPen(cg.mid()); + p->drawLine(x2, y, x2, y2); + } + + break; + } + + case PE_PanelDockWindow: // Toolbar + { + bool horiz = r.width() > r.height(); + + //Here, we just draw the border. + int x = r.x(); + int y = r.y(); + int x2 = r.x() + r.width() - 1; + int y2 = r.y() + r.height() - 1; + int lw = opt.isDefault() ? pixelMetric(PM_DefaultFrameWidth) + : opt.lineWidth(); + + if (lw) + { + //Gradient border colors. + //(Same as in gradients.cpp) + QColor gradTop = Keramik::ColorUtil::lighten(cg.button(),110); + QColor gradBot = Keramik::ColorUtil::lighten(cg.button(),109); + if (horiz) + { + //Top line + p->setPen(gradTop); + p->drawLine(x, y, x2, y); + + //Bottom line + p->setPen(gradBot); + p->drawLine(x, y2, x2, y2); + + //Left line + Keramik::GradientPainter::renderGradient( + p, QRect(r.x(), r.y(), 1, r.height()), + cg.button(), true); + + //Right end-line + p->setPen(cg.mid()); + p->drawLine(x2, y, x2, y2); + } + else + { + //Left line + p->setPen(gradTop); + p->drawLine(x, y, x, y2); + + //Right line + p->setPen(gradBot); + p->drawLine(x2, y, x2, y2); + + //Top line + Keramik::GradientPainter::renderGradient( + p, QRect(r.x(), r.y(), r.width(), 1), + cg.button(), false); + + //Bottom end-line + p->setPen(cg.mid()); + p->drawLine(x, y2, x2, y2); + } + } + break; + } + + // TOOLBAR SEPARATOR + // ------------------------------------------------------------------- + case PE_DockWindowSeparator: + { + QWidget* paintWidget = dynamic_cast<QWidget*>(p->device()); + QToolBar* parent = 0; + if (paintWidget) + parent = ::qt_cast<QToolBar*>(paintWidget->parentWidget()); + + renderToolbarEntryBackground(p, parent, r, cg, (flags & Style_Horizontal) ); + if ( !(flags & Style_Horizontal) ) + { + p->setPen(cg.mid()); + p->drawLine(4, r.height()/2-1, r.width()-5, r.height()/2-1); + p->setPen(cg.light()); + p->drawLine(4, r.height()/2, r.width()-5, r.height()/2); + } + else + { + p->setPen(cg.mid()); + p->drawLine(r.width()/2-1, 4, r.width()/2-1, r.height()-5); + p->setPen(cg.light()); + p->drawLine(r.width()/2, 4, r.width()/2, r.height()-5); + } + break; + } + + default: + { + // ARROWS + // ------------------------------------------------------------------- + if (pe >= PE_ArrowUp && pe <= PE_ArrowLeft) + { + QPointArray a; + + switch(pe) + { + case PE_ArrowUp: + a.setPoints(QCOORDARRLEN(u_arrow), u_arrow); + break; + + case PE_ArrowDown: + a.setPoints(QCOORDARRLEN(d_arrow), d_arrow); + break; + + case PE_ArrowLeft: + a.setPoints(QCOORDARRLEN(l_arrow), l_arrow); + break; + + default: + a.setPoints(QCOORDARRLEN(r_arrow), r_arrow); + } + + p->save(); + if ( flags & Style_Down ) + p->translate( pixelMetric( PM_ButtonShiftHorizontal ), + pixelMetric( PM_ButtonShiftVertical ) ); + + if ( flags & Style_Enabled ) + { + a.translate( r.x() + r.width() / 2, r.y() + r.height() / 2 ); + p->setPen( cg.buttonText() ); + p->drawLineSegments( a ); + } + else + { + a.translate( r.x() + r.width() / 2 + 1, r.y() + r.height() / 2 + 1 ); + p->setPen( cg.light() ); + p->drawLineSegments( a ); + a.translate( -1, -1 ); + p->setPen( cg.mid() ); + p->drawLineSegments( a ); + } + p->restore(); + + } + else + KStyle::drawPrimitive( pe, p, r, cg, flags, opt ); + } + } +} + +void KeramikStyle::drawKStylePrimitive( KStylePrimitive kpe, + QPainter* p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption &opt ) const +{ + bool disabled = ( flags & Style_Enabled ) == 0; + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + switch ( kpe ) + { + // SLIDER GROOVE + // ------------------------------------------------------------------- + case KPE_SliderGroove: + { + const QSlider* slider = static_cast< const QSlider* >( widget ); + bool horizontal = slider->orientation() == Horizontal; + + Keramik::TilePainter::PaintMode pmod = Keramik::TilePainter::PaintNormal; + + if (slider->erasePixmap() && !slider->erasePixmap()->isNull()) + pmod = Keramik::TilePainter::PaintFullBlend; + + if ( horizontal ) + Keramik::RectTilePainter( keramik_slider_hgroove, false ).draw(p, r, cg.button(), cg.background(), disabled, pmod); + else + Keramik::RectTilePainter( keramik_slider_vgroove, true, false ).draw( p, r, cg.button(), cg.background(), disabled, pmod); + + break; + } + + // SLIDER HANDLE + // ------------------------------------------------------------------- + case KPE_SliderHandle: + { + const QSlider* slider = static_cast< const QSlider* >( widget ); + bool horizontal = slider->orientation() == Horizontal; + + QColor hl = cg.highlight(); + if (!disabled && flags & Style_Active) + hl = Keramik::ColorUtil::lighten(cg.highlight(),110); + + if (horizontal) + Keramik::ScaledPainter( keramik_slider ).draw( p, r, disabled ? cg.button() : hl, + Qt::black, disabled, Keramik::TilePainter::PaintFullBlend ); + else + Keramik::ScaledPainter( keramik_vslider ).draw( p, r, disabled ? cg.button() : hl, + Qt::black, disabled, Keramik::TilePainter::PaintFullBlend ); + break; + } + + // TOOLBAR HANDLE + // ------------------------------------------------------------------- + case KPE_ToolBarHandle: { + int x = r.x(); int y = r.y(); + int x2 = r.x() + r.width()-1; + int y2 = r.y() + r.height()-1; + + QToolBar* parent = 0; + + if (widget && widget->parent() && widget->parent()->inherits("QToolBar")) + parent = static_cast<QToolBar*>(widget->parent()); + + renderToolbarEntryBackground(p, parent, r, cg, (flags & Style_Horizontal)); + if (flags & Style_Horizontal) { + p->setPen(cg.light()); + p->drawLine(x+1, y+4, x+1, y2-4); + p->drawLine(x+3, y+4, x+3, y2-4); + p->drawLine(x+5, y+4, x+5, y2-4); + + p->setPen(cg.mid()); + p->drawLine(x+2, y+4, x+2, y2-4); + p->drawLine(x+4, y+4, x+4, y2-4); + p->drawLine(x+6, y+4, x+6, y2-4); + } else { + p->setPen(cg.light()); + p->drawLine(x+4, y+1, x2-4, y+1); + p->drawLine(x+4, y+3, x2-4, y+3); + p->drawLine(x+4, y+5, x2-4, y+5); + + p->setPen(cg.mid()); + p->drawLine(x+4, y+2, x2-4, y+2); + p->drawLine(x+4, y+4, x2-4, y+4); + p->drawLine(x+4, y+6, x2-4, y+6); + + } + break; + } + + + // GENERAL/KICKER HANDLE + // ------------------------------------------------------------------- + case KPE_GeneralHandle: { + int x = r.x(); int y = r.y(); + int x2 = r.x() + r.width()-1; + int y2 = r.y() + r.height()-1; + + if (flags & Style_Horizontal) { + + p->setPen(cg.light()); + p->drawLine(x+1, y, x+1, y2); + p->drawLine(x+3, y, x+3, y2); + p->drawLine(x+5, y, x+5, y2); + + p->setPen(cg.mid()); + p->drawLine(x+2, y, x+2, y2); + p->drawLine(x+4, y, x+4, y2); + p->drawLine(x+6, y, x+6, y2); + + } else { + + p->setPen(cg.light()); + p->drawLine(x, y+1, x2, y+1); + p->drawLine(x, y+3, x2, y+3); + p->drawLine(x, y+5, x2, y+5); + + p->setPen(cg.mid()); + p->drawLine(x, y+2, x2, y+2); + p->drawLine(x, y+4, x2, y+4); + p->drawLine(x, y+6, x2, y+6); + + } + break; + } + + + default: + KStyle::drawKStylePrimitive( kpe, p, widget, r, cg, flags, opt); + } +} + +bool KeramikStyle::isFormWidget(const QWidget* widget) const +{ + //Form widgets are in the KHTMLView, but that has 2 further inner levels + //of widgets - QClipperWidget, and outside of that, QViewportWidget + QWidget* potentialClipPort = widget->parentWidget(); + if ( !potentialClipPort || potentialClipPort->isTopLevel() ) + return false; + + QWidget* potentialViewPort = potentialClipPort->parentWidget(); + if (!potentialViewPort || potentialViewPort->isTopLevel() || + qstrcmp(potentialViewPort->name(), "qt_viewport") ) + return false; + + QWidget* potentialKHTML = potentialViewPort->parentWidget(); + if (!potentialKHTML || potentialKHTML->isTopLevel() || + qstrcmp(potentialKHTML->className(), "KHTMLView") ) + return false; + + + return true; +} + +void KeramikStyle::drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + bool disabled = ( flags & Style_Enabled ) == 0; + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + switch (element) + { + // PUSHBUTTON + // ------------------------------------------------------------------- + case CE_PushButton: + { + const QPushButton* btn = static_cast< const QPushButton* >( widget ); + + if (isFormWidget(btn)) + formMode = true; + + if ( widget == hoverWidget ) + flags |= Style_MouseOver; + + if ( btn->isFlat( ) ) + flatMode = true; + + if ( btn->isDefault( ) && !flatMode ) + { + drawPrimitive( PE_ButtonDefault, p, r, cg, flags ); + } + else + { + if (widget->parent() && widget->parent()->inherits("QToolBar")) + toolbarBlendWidget = widget; + + drawPrimitive( PE_ButtonCommand, p, r, cg, flags ); + toolbarBlendWidget = 0; + } + + formMode = false; + break; + } + + + // PUSHBUTTON LABEL + // ------------------------------------------------------------------- + case CE_PushButtonLabel: + { + const QPushButton* button = static_cast<const QPushButton *>( widget ); + bool active = button->isOn() || button->isDown(); + bool cornArrow = false; + + // Shift button contents if pushed. + if ( active ) + { + x += pixelMetric(PM_ButtonShiftHorizontal, widget); + y += pixelMetric(PM_ButtonShiftVertical, widget); + flags |= Style_Sunken; + } + + // Does the button have a popup menu? + if ( button->isMenuButton() ) + { + int dx = pixelMetric( PM_MenuButtonIndicator, widget ); + if ( button->iconSet() && !button->iconSet()->isNull() && + (dx + button->iconSet()->pixmap (QIconSet::Small, QIconSet::Normal, QIconSet::Off ).width()) >= w ) + { + cornArrow = true; //To little room. Draw the arrow in the corner, don't adjust the widget + } + else + { + drawPrimitive( PE_ArrowDown, p, visualRect( QRect(x + w - dx - 8, y + 2, dx, h - 4), r ), + cg, flags, opt ); + w -= dx; + } + } + + // Draw the icon if there is one + if ( button->iconSet() && !button->iconSet()->isNull() ) + { + QIconSet::Mode mode = QIconSet::Disabled; + QIconSet::State state = QIconSet::Off; + + if (button->isEnabled()) + mode = button->hasFocus() ? QIconSet::Active : QIconSet::Normal; + if (button->isToggleButton() && button->isOn()) + state = QIconSet::On; + + QPixmap icon = button->iconSet()->pixmap( QIconSet::Small, mode, state ); + + if (!button->text().isEmpty()) + { + const int TextToIconMargin = 6; + //Center text + icon w/margin in between.. + + //Calculate length of both. + int length = icon.width() + TextToIconMargin + + p->fontMetrics().size(ShowPrefix, button->text()).width(); + + //Calculate offset. + int offset = (w - length)/2; + + //draw icon + p->drawPixmap( x + offset, y + h / 2 - icon.height() / 2, icon ); + + //new bounding rect for the text + x += offset + icon.width() + TextToIconMargin; + w = length - icon.width() - TextToIconMargin; + } + else + { + //Icon only. Center it. + if (!button->pixmap()) + p->drawPixmap( x + w/2 - icon.width()/2, y + h / 2 - icon.height() / 2, + icon ); + else //icon + pixmap. Ugh. + p->drawPixmap( x + button->isDefault() ? 8 : 4 , y + h / 2 - icon.height() / 2, icon ); + } + + if (cornArrow) //Draw over the icon + drawPrimitive( PE_ArrowDown, p, visualRect( QRect(x + w - 6, x + h - 6, 7, 7), r ), + cg, flags, opt ); + } + + // Make the label indicate if the button is a default button or not + drawItem( p, QRect(x, y, w, h), AlignCenter | ShowPrefix, button->colorGroup(), + button->isEnabled(), button->pixmap(), button->text(), -1, + &button->colorGroup().buttonText() ); + + if ( flags & Style_HasFocus ) + drawPrimitive( PE_FocusRect, p, + visualRect( subRect( SR_PushButtonFocusRect, widget ), widget ), + cg, flags ); + break; + } + + case CE_ToolButtonLabel: + { + //const QToolButton *toolbutton = static_cast<const QToolButton * >(widget); + bool onToolbar = widget->parentWidget() && widget->parentWidget()->inherits( "QToolBar" ); + QRect nr = r; + + if (!onToolbar) + { + if (widget->parentWidget() && + !qstrcmp(widget->parentWidget()->name(),"qt_maxcontrols" ) ) + { + //Make sure we don't cut into the endline + if (!qstrcmp(widget->name(), "close")) + { + nr.addCoords(0,0,-1,0); + p->setPen(cg.dark()); + p->drawLine(r.x() + r.width() - 1, r.y(), + r.x() + r.width() - 1, r.y() + r.height() - 1 ); + } + } + //else if ( w > smallButMaxW && h > smallButMaxH ) + // nr.setWidth(r.width()-2); //Account for shadow + } + + KStyle::drawControl(element, p, widget, nr, cg, flags, opt); + break; + } + + case CE_TabBarTab: + { + const QTabBar* tabBar = static_cast< const QTabBar* >( widget ); + + bool bottom = tabBar->shape() == QTabBar::RoundedBelow || + tabBar->shape() == QTabBar::TriangularBelow; + + if ( flags & Style_Selected ) + { + QRect tabRect = r; + //If not the right-most tab, readjust the painting to be one pixel wider + //to avoid a doubled line + int rightMost = QApplication::reverseLayout() ? 0 : tabBar->count() - 1; + + if (tabBar->indexOf( opt.tab()->identifier() ) != rightMost) + tabRect.setWidth( tabRect.width() + 1); + Keramik::ActiveTabPainter( bottom ).draw( p, tabRect, cg.button().light(110), cg.background(), !tabBar->isEnabled(), pmode()); + } + else + { + Keramik::InactiveTabPainter::Mode mode; + int index = tabBar->indexOf( opt.tab()->identifier() ); + if ( index == 0 ) mode = Keramik::InactiveTabPainter::First; + else if ( index == tabBar->count() - 1 ) mode = Keramik::InactiveTabPainter::Last; + else mode = Keramik::InactiveTabPainter::Middle; + + if ( bottom ) + { + Keramik::InactiveTabPainter( mode, bottom ).draw( p, x, y, w, h - 3, cg.button(), cg.background(), disabled, pmode() ); + p->setPen( cg.dark() ); + p->drawLine( x, y, x + w, y ); + } + else + { + Keramik::InactiveTabPainter( mode, bottom ).draw( p, x, y + 3, w, h - 3, cg.button(), cg.background(), disabled, pmode() ); + p->setPen( cg.light() ); + p->drawLine( x, y + h - 1, x + w, y + h - 1 ); + } + } + + break; + } + + case CE_DockWindowEmptyArea: + { + QRect pr = r; + if (widget && widget->inherits("QToolBar")) + { + const QToolBar* tb = static_cast<const QToolBar*>(widget); + if (tb->place() == QDockWindow::OutsideDock) + { + //Readjust the paint rectangle to skip the titlebar + pr = QRect(r.x(), titleBarH + tb->frameWidth(), + r.width(), tb->height() - titleBarH - 2 * tb->frameWidth() + 2); + //2 at the end = the 2 pixels of border of a "regular" + //toolbar we normally paint over. + } + Keramik::GradientPainter::renderGradient( p, pr, cg.button(), + tb->orientation() == Qt::Horizontal); + } + else + KStyle::drawControl( CE_DockWindowEmptyArea, p, + widget, r, cg, flags, opt ); + break; + } + case CE_MenuBarEmptyArea: + { + Keramik::GradientPainter::renderGradient( p, r, cg.button(), true, true); + break; + } + // MENUBAR ITEM (sunken panel on mouse over) + // ------------------------------------------------------------------- + case CE_MenuBarItem: + { + QMenuBar *mb = (QMenuBar*)widget; + QMenuItem *mi = opt.menuItem(); + QRect pr = mb->rect(); + + bool active = flags & Style_Active; + bool focused = flags & Style_HasFocus; + + if ( active && focused ) + qDrawShadePanel(p, r.x(), r.y(), r.width(), r.height(), + cg, true, 1, &cg.brush(QColorGroup::Midlight)); + else + Keramik::GradientPainter::renderGradient( p, pr, cg.button(), true, true); + + drawItem( p, r, AlignCenter | AlignVCenter | ShowPrefix + | DontClip | SingleLine, cg, flags & Style_Enabled, + mi->pixmap(), mi->text() ); + + break; + } + + + // POPUPMENU ITEM + // ------------------------------------------------------------------- + case CE_PopupMenuItem: { + const QPopupMenu *popupmenu = static_cast< const QPopupMenu * >( widget ); + QRect main = r; + + QMenuItem *mi = opt.menuItem(); + + if ( !mi ) + { + // Don't leave blank holes if we set NoBackground for the QPopupMenu. + // This only happens when the popupMenu spans more than one column. + if (! ( widget->erasePixmap() && !widget->erasePixmap()->isNull() ) ) + p->fillRect( r, cg.background().light( 105 ) ); + + break; + } + int tab = opt.tabWidth(); + int checkcol = opt.maxIconWidth(); + bool enabled = mi->isEnabled(); + bool checkable = popupmenu->isCheckable(); + bool active = flags & Style_Active; + bool etchtext = styleHint( SH_EtchDisabledText ); + bool reverse = QApplication::reverseLayout(); + if ( checkable ) + checkcol = QMAX( checkcol, 20 ); + + // Draw the menu item background + if ( active ) + { + if ( enabled ) + Keramik::RowPainter( keramik_menuitem ).draw( p, main, cg.highlight(), cg.background() ); + else { + if ( widget->erasePixmap() && !widget->erasePixmap()->isNull() ) + p->drawPixmap( main.topLeft(), *widget->erasePixmap(), main ); + else p->fillRect( main, cg.background().light( 105 ) ); + p->drawWinFocusRect( r ); + } + } + // Draw the transparency pixmap + else if ( widget->erasePixmap() && !widget->erasePixmap()->isNull() ) + p->drawPixmap( main.topLeft(), *widget->erasePixmap(), main ); + // Draw a solid background + else + p->fillRect( main, cg.background().light( 105 ) ); + // Are we a menu item separator? + + if ( mi->isSeparator() ) + { + p->setPen( cg.mid() ); + p->drawLine( main.x()+5, main.y() + 1, main.right()-5, main.y() + 1 ); + p->setPen( cg.light() ); + p->drawLine( main.x()+5, main.y() + 2, main.right()-5, main.y() + 2 ); + break; + } + + QRect cr = visualRect( QRect( x + 2, y + 2, checkcol - 1, h - 4 ), r ); + // Do we have an icon? + if ( mi->iconSet() ) + { + QIconSet::Mode mode; + + + + // Select the correct icon from the iconset + if ( active ) + mode = enabled ? QIconSet::Active : QIconSet::Disabled; + else + mode = enabled ? QIconSet::Normal : QIconSet::Disabled; + + // Do we have an icon and are checked at the same time? + // Then draw a "pressed" background behind the icon + if ( checkable && /*!active &&*/ mi->isChecked() ) + qDrawShadePanel( p, cr.x(), cr.y(), cr.width(), cr.height(), + cg, true, 1, &cg.brush(QColorGroup::Midlight) ); + // Draw the icon + QPixmap pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode ); + QRect pmr( 0, 0, pixmap.width(), pixmap.height() ); + pmr.moveCenter( cr.center() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + } + + // Are we checked? (This time without an icon) + else if ( checkable && mi->isChecked() ) + { + // We only have to draw the background if the menu item is inactive - + // if it's active the "pressed" background is already drawn + // if ( ! active ) + qDrawShadePanel( p, cr.x(), cr.y(), cr.width(), cr.height(), cg, true, 1, + &cg.brush(QColorGroup::Midlight) ); + + // Draw the checkmark + SFlags cflags = Style_Default; + cflags |= active ? Style_Enabled : Style_On; + + drawPrimitive( PE_CheckMark, p, cr, cg, cflags ); + } + + // Time to draw the menu item label... + int xm = itemFrame + checkcol + itemHMargin; // X position margin + + int xp = reverse ? // X position + x + tab + rightBorder + itemHMargin + itemFrame - 1 : + x + xm; + + int offset = reverse ? -1 : 1; // Shadow offset for etched text + + // Label width (minus the width of the accelerator portion) + int tw = w - xm - tab - arrowHMargin - itemHMargin * 3 - itemFrame + 1; + + // Set the color for enabled and disabled text + // (used for both active and inactive menu items) + p->setPen( enabled ? cg.buttonText() : cg.mid() ); + + // This color will be used instead of the above if the menu item + // is active and disabled at the same time. (etched text) + QColor discol = cg.mid(); + + // Does the menu item draw it's own label? + if ( mi->custom() ) { + int m = itemVMargin; + // Save the painter state in case the custom + // paint method changes it in some way + p->save(); + + // Draw etched text if we're inactive and the menu item is disabled + if ( etchtext && !enabled && !active ) { + p->setPen( cg.light() ); + mi->custom()->paint( p, cg, active, enabled, xp+offset, y+m+1, tw, h-2*m ); + p->setPen( discol ); + } + mi->custom()->paint( p, cg, active, enabled, xp, y+m, tw, h-2*m ); + p->restore(); + } + else { + // The menu item doesn't draw it's own label + QString s = mi->text(); + // Does the menu item have a text label? + if ( !s.isNull() ) { + int t = s.find( '\t' ); + int m = itemVMargin; + int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine; + text_flags |= reverse ? AlignRight : AlignLeft; + + //QColor draw = cg.text(); + QColor draw = (active && enabled) ? cg.highlightedText () : cg.text(); + p->setPen(draw); + + + // Does the menu item have a tabstop? (for the accelerator text) + if ( t >= 0 ) { + int tabx = reverse ? x + rightBorder + itemHMargin + itemFrame : + x + w - tab - rightBorder - itemHMargin - itemFrame; + + // Draw the right part of the label (accelerator text) + if ( etchtext && !enabled ) { + // Draw etched text if we're inactive and the menu item is disabled + p->setPen( cg.light() ); + p->drawText( tabx+offset, y+m+1, tab, h-2*m, text_flags, s.mid( t+1 ) ); + p->setPen( discol ); + } + p->drawText( tabx, y+m, tab, h-2*m, text_flags, s.mid( t+1 ) ); + s = s.left( t ); + } + + // Draw the left part of the label (or the whole label + // if there's no accelerator) + if ( etchtext && !enabled ) { + // Etched text again for inactive disabled menu items... + p->setPen( cg.light() ); + p->drawText( xp+offset, y+m+1, tw, h-2*m, text_flags, s, t ); + p->setPen( discol ); + } + + + p->drawText( xp, y+m, tw, h-2*m, text_flags, s, t ); + + p->setPen(cg.text()); + + } + + // The menu item doesn't have a text label + // Check if it has a pixmap instead + else if ( mi->pixmap() ) { + QPixmap *pixmap = mi->pixmap(); + + // Draw the pixmap + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( OpaqueMode ); + + int diffw = ( ( w - pixmap->width() ) / 2 ) + + ( ( w - pixmap->width() ) % 2 ); + p->drawPixmap( x+diffw, y+itemFrame, *pixmap ); + + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( TransparentMode ); + } + } + + // Does the menu item have a submenu? + if ( mi->popup() ) { + PrimitiveElement arrow = reverse ? PE_ArrowLeft : PE_ArrowRight; + int dim = pixelMetric(PM_MenuButtonIndicator) - itemFrame; + QRect vr = visualRect( QRect( x + w - arrowHMargin - itemFrame - dim, + y + h / 2 - dim / 2, dim, dim), r ); + + // Draw an arrow at the far end of the menu item + if ( active ) { + if ( enabled ) + discol = cg.buttonText(); + + QColorGroup g2( discol, cg.highlight(), white, white, + enabled ? white : discol, discol, white ); + + drawPrimitive( arrow, p, vr, g2, Style_Enabled ); + } else + drawPrimitive( arrow, p, vr, cg, + enabled ? Style_Enabled : Style_Default ); + } + break; + } + case CE_ProgressBarContents: { + const QProgressBar* pb = (const QProgressBar*)widget; + QRect cr = subRect(SR_ProgressBarContents, widget); + double progress = pb->progress(); + bool reverse = QApplication::reverseLayout(); + int steps = pb->totalSteps(); + + if (!cr.isValid()) + return; + + // Draw progress bar + if (progress > 0 || steps == 0) { + double pg = (steps == 0) ? 0.1 : progress / steps; + int width = QMIN(cr.width(), (int)(pg * cr.width())); + if (steps == 0) + width = QMIN(width,20); //Don't cross squares + + if (steps == 0) { //Busy indicator + + if (width < 1) width = 1; //A busy indicator with width 0 is kind of useless + + int remWidth = cr.width() - width; //Never disappear completely + if (remWidth <= 0) remWidth = 1; //Do something non-crashy when too small... + + int pstep = int(progress) % ( 2 * remWidth ); + + if ( pstep > remWidth ) { + //Bounce about.. We're remWidth + some delta, we want to be remWidth - delta... + // - ( (remWidth + some delta) - 2* remWidth ) = - (some deleta - remWidth) = remWidth - some delta.. + pstep = - (pstep - 2 * remWidth ); + } + + //Store the progress rect. + QRect progressRect; + if (reverse) + progressRect = QRect(cr.x() + cr.width() - width - pstep, cr.y(), + width, cr.height()); + else + progressRect = QRect(cr.x() + pstep, cr.y(), width, cr.height()); + + Keramik::RowPainter(keramik_progressbar).draw(p, progressRect, + cg.highlight(), cg.background() ); + return; + } + + QRect progressRect; + + if (reverse) + progressRect = QRect(cr.x()+(cr.width()-width), cr.y(), width, cr.height()); + else + progressRect = QRect(cr.x(), cr.y(), width, cr.height()); + + //Apply the animation rectangle. + ////////////////////////////////////// + if (animateProgressBar) + { + int progAnimShift = progAnimWidgets[const_cast<QProgressBar*>(pb)]; + if (reverse) + { + //Here, we can't simply shift, as the painter code calculates everything based + //on the left corner, so we need to draw the 2 portions ourselves. + + //Start off by checking the geometry of the end pixmap - it introduces a bit of an offset + QSize endDim = loader.size(keramik_progressbar + 3); //3 = 3*1 + 0 = (1,0) = cl + + //We might not have anything to animate at all, though, if the ender is the only thing to paint + if (endDim.width() < progressRect.width()) + { + //OK, so we do have some stripes. + // Render the endline now - the clip region below will protect it from getting overwriten + QPixmap endline = loader.scale(keramik_progressbar + 3, endDim.width(), progressRect.height(), + cg.highlight(), cg.background()); + p->drawPixmap(progressRect.x(), progressRect.y(), endline); + + //Now, calculate where the stripes should be, and set a clip region to that + progressRect.setLeft(progressRect.x() + endline.width()); + p->setClipRect(progressRect, QPainter::CoordPainter); + + //Expand the paint region slightly to get the animation offset. + progressRect.setLeft(progressRect.x() - progAnimShift); + + //Paint the stripes. + QPixmap stripe = loader.scale(keramik_progressbar + 4, 28, progressRect.height(), + cg.highlight(), cg.background()); + //4 = 3*1 + 1 = (1,1) = cc + + p->drawTiledPixmap(progressRect, stripe); + //Exit out here to skip the regular paint path + return; + } + } + else + { + //Clip to the old rectangle + p->setClipRect(progressRect, QPainter::CoordPainter); + //Expand the paint region + progressRect.setLeft(progressRect.x() - 28 + progAnimShift); + } + } + + Keramik::ProgressBarPainter(keramik_progressbar, reverse).draw( p, + progressRect , cg.highlight(), cg.background()); + } + break; + } + + + default: + KStyle::drawControl(element, p, widget, r, cg, flags, opt); + } +} + +void KeramikStyle::drawControlMask( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& opt ) const +{ + p->fillRect(r, color1); + maskMode = true; + drawControl( element, p, widget, r, QApplication::palette().active(), QStyle::Style_Default, opt); + maskMode = false; +} + +bool KeramikStyle::isSizeConstrainedCombo(const QComboBox* combo) const +{ + if (combo->width() >= 80) + return false; + int suggestedWidth = combo->sizeHint().width(); + + if (combo->width() - suggestedWidth < -5) + return true; + + return false; +} + +void KeramikStyle::drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + SCFlags controls, + SCFlags active, + const QStyleOption& opt ) const +{ + bool disabled = ( flags & Style_Enabled ) == 0; + switch(control) + { + // COMBOBOX + // ------------------------------------------------------------------- + case CC_ComboBox: + { + bool toolbarMode = false; + const QComboBox* cb = static_cast< const QComboBox* >( widget ); + bool compact = isSizeConstrainedCombo(cb); + + if (isFormWidget(cb)) + formMode = true; + + QPixmap * buf = 0; + QPainter* p2 = p; + + QRect br = r; + + if (controls == SC_All) + { + //Double-buffer only when we are in the slower full-blend mode + if (widget->parent() && + ( widget->parent()->inherits("QToolBar")|| !qstrcmp(widget->parent()->name(), kdeToolbarWidget) ) ) + { + buf = new QPixmap( r.width(), r.height() ); + br.setX(0); + br.setY(0); + p2 = new QPainter(buf); + + //Ensure that we have clipping on, and have a sane base. + //If need be, Qt will shrink us to the paint region. + p->setClipRect(r); + toolbarMode = true; + } + } + + + if ( br.width() >= 28 && br.height() > 20 && !compact ) + br.addCoords( 0, -2, 0, 0 ); + + //When in compact mode, we force the shadow-less bevel mode, + //but that also alters height and not just width. + //readjust height to fake the other metrics (plus clear + //the other areas, as appropriate). The automasker + //will take care of the overall shape. + if ( compact ) + { + forceSmallMode = true; + br.setHeight( br.height() - 2); + p->fillRect ( r.x(), r.y() + br.height(), r.width(), 2, cg.background()); + } + + + if ( controls & SC_ComboBoxFrame ) + { + if (toolbarMode) + toolbarBlendWidget = widget; + + if ( widget == hoverWidget ) + flags |= Style_MouseOver; + + drawPrimitive( PE_ButtonCommand, p2, br, cg, flags ); + + toolbarBlendWidget = 0; + } + + // don't draw the focus rect etc. on the mask + if ( cg.button() == color1 && cg.background() == color0 ) + break; + + if ( controls & SC_ComboBoxArrow ) + { + if ( active ) + flags |= Style_On; + + QRect ar = querySubControlMetrics( CC_ComboBox, widget, + SC_ComboBoxArrow ); + if (!compact) + { + ar.setWidth(ar.width()-13); + QRect rr = visualRect( QRect( ar.x(), ar.y() + 4, + loader.size(keramik_ripple ).width(), ar.height() - 8 ), + widget ); + + ar = visualRect( QRect( ar.x() + loader.size( keramik_ripple ).width() + 4, ar.y(), + 11, ar.height() ), + widget ); + + QPointArray a; + + a.setPoints(QCOORDARRLEN(keramik_combo_arrow), keramik_combo_arrow); + + a.translate( ar.x() + ar.width() / 2, ar.y() + ar.height() / 2 ); + p2->setPen( cg.buttonText() ); + p2->drawLineSegments( a ); + + Keramik::ScaledPainter( keramik_ripple ).draw( p2, rr, cg.button(), Qt::black, disabled, Keramik::TilePainter::PaintFullBlend ); + } + else //Size-constrained combo -- loose the ripple. + { + ar.setWidth(ar.width() - 7); + ar = visualRect( QRect( ar.x(), ar.y(), 11, ar.height() ), widget); + QPointArray a; + + a.setPoints(QCOORDARRLEN(keramik_combo_arrow), keramik_combo_arrow); + + a.translate( ar.x() + ar.width() / 2, ar.y() + ar.height() / 2 ); + p2->setPen( cg.buttonText() ); + p2->drawLineSegments( a ); + } + } + + if ( controls & SC_ComboBoxEditField ) + { + if ( cb->editable() ) + { + QRect er = visualRect( querySubControlMetrics( CC_ComboBox, widget, SC_ComboBoxEditField ), widget ); + er.addCoords( -2, -2, 2, 2 ); + p2->fillRect( er, cg.base() ); + drawPrimitive( PE_PanelLineEdit, p2, er, cg ); + Keramik::RectTilePainter( keramik_frame_shadow, false, false, 2, 2 ).draw( p2, er, cg.button(), + Qt::black, false, pmodeFullBlend() ); + } + else if ( cb->hasFocus() ) + { + QRect re = QStyle::visualRect(subRect(SR_ComboBoxFocusRect, cb), widget); + if ( compact ) + re.addCoords( 3, 3, 0, -3 ); + p2->fillRect( re, cg.brush( QColorGroup::Highlight ) ); + drawPrimitive( PE_FocusRect, p2, re, cg, + Style_FocusAtBorder, QStyleOption( cg.highlight() ) ); + } + // QComboBox draws the text on its own and uses the painter's current colors + if ( cb->hasFocus() ) + { + p->setPen( cg.highlightedText() ); + p->setBackgroundColor( cg.highlight() ); + } + else + { + p->setPen( cg.text() ); + p->setBackgroundColor( cg.button() ); + } + } + + if (p2 != p) + { + p2->end(); + delete p2; + p->drawPixmap(r.x(), r.y(), *buf); + delete buf; + } + + formMode = false; + break; + } + + case CC_SpinWidget: + { + const QSpinWidget* sw = static_cast< const QSpinWidget* >( widget ); + QRect br = visualRect( querySubControlMetrics( CC_SpinWidget, widget, SC_SpinWidgetButtonField ), widget ); + if ( controls & SC_SpinWidgetButtonField ) + { + Keramik::SpinBoxPainter().draw( p, br, cg.button(), cg.background(), !sw->isEnabled() ); + if ( active & SC_SpinWidgetUp ) + Keramik::CenteredPainter( keramik_spinbox_pressed_arrow_up ).draw( p, br.x(), br.y() + 3, br.width(), br.height() / 2, cg.button(), cg.background() ); + else + Keramik::CenteredPainter( keramik_spinbox_arrow_up ).draw( p, br.x(), br.y() + 3, br.width(), br.height() / 2, cg.button(), cg.background(), !sw->isUpEnabled() ); + if ( active & SC_SpinWidgetDown ) + Keramik::CenteredPainter( keramik_spinbox_pressed_arrow_down ).draw( p, br.x(), br.y() + br.height() / 2 , br.width(), br.height() / 2 - 8, cg.button(), cg.background() ); + else + Keramik::CenteredPainter( keramik_spinbox_arrow_down ).draw( p, br.x(), br.y() + br.height() / 2, br.width(), br.height() / 2 - 8, cg.background(), cg.button(), !sw->isDownEnabled() ); + } + + if ( controls & SC_SpinWidgetFrame ) + drawPrimitive( PE_PanelLineEdit, p, r, cg ); + + break; + } + case CC_ScrollBar: + { + const QScrollBar* sb = static_cast< const QScrollBar* >( widget ); + if (highlightScrollBar && sb->parentWidget()) //Don't do the check if not highlighting anyway + { + if (sb->parentWidget()->colorGroup().button() != sb->colorGroup().button()) + customScrollMode = true; + } + bool horizontal = sb->orientation() == Horizontal; + QRect slider, subpage, addpage, subline, addline; + if ( sb->minValue() == sb->maxValue() ) flags &= ~Style_Enabled; + + slider = querySubControlMetrics( control, widget, SC_ScrollBarSlider, opt ); + subpage = querySubControlMetrics( control, widget, SC_ScrollBarSubPage, opt ); + addpage = querySubControlMetrics( control, widget, SC_ScrollBarAddPage, opt ); + subline = querySubControlMetrics( control, widget, SC_ScrollBarSubLine, opt ); + addline = querySubControlMetrics( control, widget, SC_ScrollBarAddLine, opt ); + + if ( controls & SC_ScrollBarSubLine ) + drawPrimitive( PE_ScrollBarSubLine, p, subline, cg, + flags | ( ( active & SC_ScrollBarSubLine ) ? Style_Down : 0 ) ); + + QRegion clip; + if ( controls & SC_ScrollBarSubPage ) clip |= subpage; + if ( controls & SC_ScrollBarAddPage ) clip |= addpage; + if ( horizontal ) + clip |= QRect( slider.x(), 0, slider.width(), sb->height() ); + else + clip |= QRect( 0, slider.y(), sb->width(), slider.height() ); + clip ^= slider; + + p->setClipRegion( clip ); + Keramik::ScrollBarPainter( KeramikGroove1, 2, horizontal ).draw( p, slider | subpage | addpage, cg.button(), cg.background(), disabled ); + + if ( controls & SC_ScrollBarSlider ) + { + if ( horizontal ) + p->setClipRect( slider.x(), slider.y(), addpage.right() - slider.x() + 1, slider.height() ); + else + p->setClipRect( slider.x(), slider.y(), slider.width(), addpage.bottom() - slider.y() + 1 ); + drawPrimitive( PE_ScrollBarSlider, p, slider, cg, + flags | ( ( active == SC_ScrollBarSlider ) ? Style_Down : 0 ) ); + } + p->setClipping( false ); + + if ( controls & ( SC_ScrollBarSubLine | SC_ScrollBarAddLine ) ) + { + drawPrimitive( PE_ScrollBarAddLine, p, addline, cg, flags ); + if ( active & SC_ScrollBarSubLine ) + { + if ( horizontal ) + p->setClipRect( QRect( addline.x(), addline.y(), addline.width() / 2, addline.height() ) ); + else + p->setClipRect( QRect( addline.x(), addline.y(), addline.width(), addline.height() / 2 ) ); + drawPrimitive( PE_ScrollBarAddLine, p, addline, cg, flags | Style_Down ); + } + else if ( active & SC_ScrollBarAddLine ) + { + if ( horizontal ) + p->setClipRect( QRect( addline.x() + addline.width() / 2, addline.y(), addline.width() / 2, addline.height() ) ); + else + p->setClipRect( QRect( addline.x(), addline.y() + addline.height() / 2, addline.width(), addline.height() / 2 ) ); + drawPrimitive( PE_ScrollBarAddLine, p, addline, cg, flags | Style_Down ); + } + } + + customScrollMode = false; + + + break; + } + + // TOOLBUTTON + // ------------------------------------------------------------------- + case CC_ToolButton: { + const QToolButton *toolbutton = (const QToolButton *) widget; + bool onToolbar = widget->parentWidget() && widget->parentWidget()->inherits( "QToolBar" ); + bool onExtender = !onToolbar && + widget->parentWidget() && widget->parentWidget()->inherits( "QToolBarExtensionWidget") && + widget->parentWidget()->parentWidget()->inherits( "QToolBar" ); + + bool onControlButtons = false; + if (!onToolbar && !onExtender && widget->parentWidget() && + !qstrcmp(widget->parentWidget()->name(),"qt_maxcontrols" ) ) + { + onControlButtons = true; + titleBarMode = Maximized; + } + + QRect button, menuarea; + button = querySubControlMetrics(control, widget, SC_ToolButton, opt); + menuarea = querySubControlMetrics(control, widget, SC_ToolButtonMenu, opt); + + SFlags bflags = flags, + mflags = flags; + + if (active & SC_ToolButton) + bflags |= Style_Down; + if (active & SC_ToolButtonMenu) + mflags |= Style_Down; + + if ( widget == hoverWidget ) + bflags |= Style_MouseOver; + + + if (onToolbar && static_cast<QToolBar*>(widget->parent())->orientation() == Qt::Horizontal) + bflags |= Style_Horizontal; + + if (controls & SC_ToolButton) + { + // If we're pressed, on, or raised... + if (bflags & (Style_Down | Style_On | Style_Raised) || onControlButtons) + { + //Make sure the standalone toolbuttons have a gradient in the right direction + if (!onToolbar && !onControlButtons) + bflags |= Style_Horizontal; + + drawPrimitive( PE_ButtonTool, p, button, cg, + bflags, opt); + } + + // Check whether to draw a background pixmap + else if ( toolbutton->parentWidget() && + toolbutton->parentWidget()->backgroundPixmap() && + !toolbutton->parentWidget()->backgroundPixmap()->isNull() ) + { + QPixmap pixmap = *(toolbutton->parentWidget()->backgroundPixmap()); + p->drawTiledPixmap( r, pixmap, toolbutton->pos() ); + } + else if (onToolbar) + { + renderToolbarWidgetBackground(p, widget); + } + else if (onExtender) + { + // This assumes floating toolbars can't have extenders, + //(so if we're on an extender, we're not floating) + QWidget* parent = static_cast<QWidget*> (widget->parent()); + QToolBar* toolbar = static_cast<QToolBar*>(parent->parent()); + QRect tr = toolbar->rect(); + bool horiz = toolbar->orientation() == Qt::Horizontal; + + //Calculate offset. We do this by translating our coordinates, + //which are relative to the parent, to be relative to the toolbar. + int xoff = 0, yoff = 0; + if (horiz) + yoff = parent->mapToParent(widget->pos()).y(); + else + xoff = parent->mapToParent(widget->pos()).x(); + + Keramik::GradientPainter::renderGradient( p, r, cg.button(), + horiz, false, /*Not a menubar*/ + xoff, yoff, + tr.width(), tr.height()); + } + } + + // Draw a toolbutton menu indicator if required + if (controls & SC_ToolButtonMenu) + { + if (mflags & (Style_Down | Style_On | Style_Raised)) + drawPrimitive(PE_ButtonDropDown, p, menuarea, cg, mflags, opt); + drawPrimitive(PE_ArrowDown, p, menuarea, cg, mflags, opt); + } + + if (toolbutton->hasFocus() && !toolbutton->focusProxy()) { + QRect fr = toolbutton->rect(); + fr.addCoords(3, 3, -3, -3); + drawPrimitive(PE_FocusRect, p, fr, cg); + } + + titleBarMode = None; + + break; + } + + case CC_TitleBar: + titleBarMode = Regular; //Handle buttons on titlebar different from toolbuttons + default: + KStyle::drawComplexControl( control, p, widget, + r, cg, flags, controls, active, opt ); + + titleBarMode = None; + } +} + +void KeramikStyle::drawComplexControlMask( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& opt ) const +{ + if (control == CC_ComboBox) + { + maskMode = true; + drawComplexControl(CC_ComboBox, p, widget, r, + QApplication::palette().active(), Style_Default, + SC_ComboBoxFrame,SC_None, opt); + maskMode = false; + + } + else + p->fillRect(r, color1); + +} + +int KeramikStyle::pixelMetric(PixelMetric m, const QWidget *widget) const +{ + switch(m) + { + // BUTTONS + // ------------------------------------------------------------------- + case PM_ButtonMargin: // Space btw. frame and label + return 4; + + case PM_SliderLength: + return 12; + case PM_SliderControlThickness: + return loader.size( keramik_slider ).height() - 4; + case PM_SliderThickness: + return loader.size( keramik_slider ).height(); + + case PM_ButtonShiftHorizontal: + return 0; + case PM_ButtonShiftVertical: // Offset by 1 + return 1; + + + // CHECKBOXES / RADIO BUTTONS + // ------------------------------------------------------------------- + case PM_ExclusiveIndicatorWidth: // Radiobutton size + return loader.size( keramik_radiobutton_on ).width(); + case PM_ExclusiveIndicatorHeight: + return loader.size( keramik_radiobutton_on ).height(); + case PM_IndicatorWidth: // Checkbox size + return loader.size( keramik_checkbox_on ).width(); + case PM_IndicatorHeight: + return loader.size( keramik_checkbox_on) .height(); + + case PM_ScrollBarExtent: + return loader.size( keramik_scrollbar_vbar + KeramikGroove1).width(); + case PM_ScrollBarSliderMin: + return loader.size( keramik_scrollbar_vbar + KeramikSlider1 ).height() + + loader.size( keramik_scrollbar_vbar + KeramikSlider3 ).height(); + + case PM_SpinBoxFrameWidth: + case PM_DefaultFrameWidth: + return 1; + + case PM_MenuButtonIndicator: + return 13; + + case PM_TabBarTabVSpace: + return 12; + + case PM_TabBarTabOverlap: + return 0; + + case PM_TabBarTabShiftVertical: + { + const QTabBar* tb = ::qt_cast<const QTabBar*>(widget); + if (tb) + { + if (tb->shape() == QTabBar::RoundedBelow || + tb->shape() == QTabBar::TriangularBelow) + return 0; + } + + return 2; //For top, or if not sure + } + + + case PM_TitleBarHeight: + return titleBarH; + + default: + return KStyle::pixelMetric(m, widget); + } +} + + +QSize KeramikStyle::sizeFromContents( ContentsType contents, + const QWidget* widget, + const QSize &contentSize, + const QStyleOption& opt ) const +{ + switch (contents) + { + // PUSHBUTTON SIZE + // ------------------------------------------------------------------ + case CT_PushButton: + { + const QPushButton* btn = static_cast< const QPushButton* >( widget ); + + int w = contentSize.width() + 2 * pixelMetric( PM_ButtonMargin, widget ); + int h = contentSize.height() + 2 * pixelMetric( PM_ButtonMargin, widget ); + if ( btn->text().isEmpty() && contentSize.width() < 32 ) return QSize( w, h ); + + + //For some reason kcontrol no longer does this... + //if ( btn->isDefault() || btn->autoDefault() ) + // w = QMAX( w, 40 ); + + return QSize( w + 30, h + 5 ); //MX: No longer blank space -- can make a bit smaller + } + + case CT_ToolButton: + { + bool onToolbar = widget->parentWidget() && widget->parentWidget()->inherits( "QToolBar" ); + if (!onToolbar) //Behaves like a button, so scale appropriately to the border + { + int w = contentSize.width(); + int h = contentSize.height(); + return QSize( w + 12, h + 10 ); + } + else + { + return KStyle::sizeFromContents( contents, widget, contentSize, opt ); + } + } + + case CT_ComboBox: { + int arrow = 11 + loader.size( keramik_ripple ).width(); + const QComboBox *cb = static_cast<const QComboBox*>( widget ); + return QSize( contentSize.width() + arrow + (cb->editable() ? 26 : 22), + contentSize.height() + 10 ); + } + + // POPUPMENU ITEM SIZE + // ----------------------------------------------------------------- + case CT_PopupMenuItem: { + if ( ! widget || opt.isDefault() ) + return contentSize; + + const QPopupMenu *popup = (const QPopupMenu *) widget; + bool checkable = popup->isCheckable(); + QMenuItem *mi = opt.menuItem(); + int maxpmw = opt.maxIconWidth(); + int w = contentSize.width(), h = contentSize.height(); + + if ( mi->custom() ) { + w = mi->custom()->sizeHint().width(); + h = mi->custom()->sizeHint().height(); + if ( ! mi->custom()->fullSpan() ) + h += 2*itemVMargin + 2*itemFrame; + } + else if ( mi->widget() ) { + } else if ( mi->isSeparator() ) { + w = 30; // Arbitrary + h = 3; + } + else { + if ( mi->pixmap() ) + h = QMAX( h, mi->pixmap()->height() + 2*itemFrame ); + else { + // Ensure that the minimum height for text-only menu items + // is the same as the icon size used by KDE. + h = QMAX( h, 16 + 2*itemFrame ); + h = QMAX( h, popup->fontMetrics().height() + + 2*itemVMargin + 2*itemFrame ); + } + + if ( mi->iconSet() ) + h = QMAX( h, mi->iconSet()->pixmap( + QIconSet::Small, QIconSet::Normal).height() + + 2 * itemFrame ); + } + + if ( ! mi->text().isNull() && mi->text().find('\t') >= 0 ) + w += itemHMargin + itemFrame*2 + 7; + else if ( mi->popup() ) + w += 2 * arrowHMargin; + + if ( maxpmw ) + w += maxpmw + 6; + if ( checkable && maxpmw < 20 ) + w += 20 - maxpmw; + if ( checkable || maxpmw > 0 ) + w += 12; + + w += rightBorder; + + return QSize( w, h ); + } + + default: + return KStyle::sizeFromContents( contents, widget, contentSize, opt ); + } +} + + +QStyle::SubControl KeramikStyle::querySubControl( ComplexControl control, + const QWidget* widget, + const QPoint& point, + const QStyleOption& opt ) const +{ + SubControl result = KStyle::querySubControl( control, widget, point, opt ); + if ( control == CC_ScrollBar && result == SC_ScrollBarAddLine ) + { + QRect addline = querySubControlMetrics( control, widget, result, opt ); + if ( static_cast< const QScrollBar* >( widget )->orientation() == Horizontal ) + { + if ( point.x() < addline.center().x() ) result = SC_ScrollBarSubLine; + } + else if ( point.y() < addline.center().y() ) result = SC_ScrollBarSubLine; + } + return result; +} + +QRect KeramikStyle::querySubControlMetrics( ComplexControl control, + const QWidget* widget, + SubControl subcontrol, + const QStyleOption& opt ) const +{ + switch ( control ) + { + case CC_ComboBox: + { + int arrow; + bool compact = false; + if ( isSizeConstrainedCombo(static_cast<const QComboBox*>(widget) ) ) //### constant + compact = true; + + if ( compact ) + arrow = 11; + else + arrow = 11 + loader.size( keramik_ripple ).width(); + + switch ( subcontrol ) + { + case SC_ComboBoxArrow: + if ( compact ) + return QRect( widget->width() - arrow - 7, 0, arrow + 6, widget->height() ); + else + return QRect( widget->width() - arrow - 14, 0, arrow + 13, widget->height() ); + + case SC_ComboBoxEditField: + { + if ( compact ) + return QRect( 2, 4, widget->width() - arrow - 2 - 7, widget->height() - 8 ); + else if ( widget->width() < 36 || widget->height() < 22 ) + return QRect( 4, 3, widget->width() - arrow - 20, widget->height() - 6 ); + else if ( static_cast< const QComboBox* >( widget )->editable() ) + return QRect( 8, 4, widget->width() - arrow - 26, widget->height() - 11 ); + else + return QRect( 6, 4, widget->width() - arrow - 22, widget->height() - 9 ); + } + + case SC_ComboBoxListBoxPopup: + { + //Note that the widget here == the combo, not the completion + //box, so we don't get any recursion + int suggestedWidth = widget->sizeHint().width(); + QRect def = opt.rect(); + def.addCoords( 4, -4, -6, 4 ); + + if ((def.width() - suggestedWidth < -12) && (def.width() < 80)) + def.setWidth(QMIN(80, suggestedWidth - 10)); + + return def; + } + + default: break; + } + break; + } + + case CC_ScrollBar: + { + const QScrollBar* sb = static_cast< const QScrollBar* >( widget ); + bool horizontal = sb->orientation() == Horizontal; + int addline, subline, sliderpos, sliderlen, maxlen, slidermin; + if ( horizontal ) + { + subline = loader.size( keramik_scrollbar_hbar_arrow1 ).width(); + addline = loader.size( keramik_scrollbar_hbar_arrow2 ).width(); + maxlen = sb->width() - subline - addline + 2; + } + else + { + subline = loader.size( keramik_scrollbar_vbar_arrow1 ).height(); + addline = loader.size( keramik_scrollbar_vbar_arrow2 ).height(); + maxlen = sb->height() - subline - addline + 2; + } + sliderpos = sb->sliderStart(); + if ( sb->minValue() != sb->maxValue() ) + { + int range = sb->maxValue() - sb->minValue(); + sliderlen = ( sb->pageStep() * maxlen ) / ( range + sb->pageStep() ); + slidermin = pixelMetric( PM_ScrollBarSliderMin, sb ); + if ( sliderlen < slidermin ) sliderlen = slidermin; + if ( sliderlen > maxlen ) sliderlen = maxlen; + } + else sliderlen = maxlen; + + switch ( subcontrol ) + { + case SC_ScrollBarGroove: + if ( horizontal ) return QRect( subline, 0, maxlen, sb->height() ); + else return QRect( 0, subline, sb->width(), maxlen ); + + case SC_ScrollBarSlider: + if (horizontal) return QRect( sliderpos, 0, sliderlen, sb->height() ); + else return QRect( 0, sliderpos, sb->width(), sliderlen ); + + case SC_ScrollBarSubLine: + if ( horizontal ) return QRect( 0, 0, subline, sb->height() ); + else return QRect( 0, 0, sb->width(), subline ); + + case SC_ScrollBarAddLine: + if ( horizontal ) return QRect( sb->width() - addline, 0, addline, sb->height() ); + else return QRect( 0, sb->height() - addline, sb->width(), addline ); + + case SC_ScrollBarSubPage: + if ( horizontal ) return QRect( subline, 0, sliderpos - subline, sb->height() ); + else return QRect( 0, subline, sb->width(), sliderpos - subline ); + + case SC_ScrollBarAddPage: + if ( horizontal ) return QRect( sliderpos + sliderlen, 0, sb->width() - addline - (sliderpos + sliderlen) , sb->height() ); + else return QRect( 0, sliderpos + sliderlen, sb->width(), sb->height() - addline - (sliderpos + sliderlen) + /*maxlen - sliderpos - sliderlen + subline - 5*/ ); + + default: break; + }; + break; + } + case CC_Slider: + { + const QSlider* sl = static_cast< const QSlider* >( widget ); + bool horizontal = sl->orientation() == Horizontal; + QSlider::TickSetting ticks = sl->tickmarks(); + int pos = sl->sliderStart(); + int size = pixelMetric( PM_SliderControlThickness, widget ); + int handleSize = pixelMetric( PM_SliderThickness, widget ); + int len = pixelMetric( PM_SliderLength, widget ); + + //Shrink the metrics if the widget is too small + //to fit our normal values for them. + if (horizontal) + handleSize = QMIN(handleSize, sl->height()); + else + handleSize = QMIN(handleSize, sl->width()); + + size = QMIN(size, handleSize); + + switch ( subcontrol ) + { + case SC_SliderGroove: + if ( horizontal ) + { + if ( ticks == QSlider::Both ) + return QRect( 0, ( sl->height() - size ) / 2, sl->width(), size ); + else if ( ticks == QSlider::Above ) + return QRect( 0, sl->height() - size - ( handleSize - size ) / 2, sl->width(), size ); + return QRect( 0, ( handleSize - size ) / 2, sl->width(), size ); + } + else + { + if ( ticks == QSlider::Both ) + return QRect( ( sl->width() - size ) / 2, 0, size, sl->height() ); + else if ( ticks == QSlider::Above ) + return QRect( sl->width() - size - ( handleSize - size ) / 2, 0, size, sl->height() ); + return QRect( ( handleSize - size ) / 2, 0, size, sl->height() ); + } + case SC_SliderHandle: + if ( horizontal ) + { + if ( ticks == QSlider::Both ) + return QRect( pos, ( sl->height() - handleSize ) / 2, len, handleSize ); + else if ( ticks == QSlider::Above ) + return QRect( pos, sl->height() - handleSize, len, handleSize ); + return QRect( pos, 0, len, handleSize ); + } + else + { + if ( ticks == QSlider::Both ) + return QRect( ( sl->width() - handleSize ) / 2, pos, handleSize, len ); + else if ( ticks == QSlider::Above ) + return QRect( sl->width() - handleSize, pos, handleSize, len ); + return QRect( 0, pos, handleSize, len ); + } + default: break; + } + break; + } + default: break; + } + return KStyle::querySubControlMetrics( control, widget, subcontrol, opt ); +} + + +#include <config.h> + +#if !defined Q_WS_X11 || defined K_WS_QTONLY +#undef HAVE_X11_EXTENSIONS_SHAPE_H +#endif + +#ifdef HAVE_X11_EXTENSIONS_SHAPE_H +//Xlib headers are a mess -> include them down here (any way to ensure that we go second in enable-final order?) +#include <X11/Xlib.h> +#include <X11/extensions/shape.h> +#undef KeyPress +#undef KeyRelease +#endif + +bool KeramikStyle::eventFilter( QObject* object, QEvent* event ) +{ + if (KStyle::eventFilter( object, event )) + return true; + + if ( !object->isWidgetType() ) return false; + + //Clear hover highlight when needed + if ( (event->type() == QEvent::Leave) && (object == hoverWidget) ) + { + QWidget* button = static_cast<QWidget*>(object); + hoverWidget = 0; + button->repaint( false ); + return false; + } + + //Hover highlight on buttons, toolbuttons and combos + if ( ::qt_cast<QPushButton*>(object) || ::qt_cast<QComboBox*>(object) || ::qt_cast<QToolButton*>(object) ) + { + if (event->type() == QEvent::Enter && static_cast<QWidget*>(object)->isEnabled() ) + { + hoverWidget = static_cast<QWidget*>(object); + hoverWidget->repaint( false ); + } + return false; + } + + //Combo line edits get special frames + if ( event->type() == QEvent::Paint && ::qt_cast<QLineEdit*>(object) ) + { + static bool recursion = false; + if (recursion ) + return false; + + recursion = true; + object->event( static_cast< QPaintEvent* >( event ) ); + QWidget* widget = static_cast< QWidget* >( object ); + QPainter p( widget ); + Keramik::RectTilePainter( keramik_frame_shadow, false, false, 2, 2 ).draw( &p, widget->rect(), + widget->palette().color( QPalette::Normal, QColorGroup::Button ), + Qt::black, false, Keramik::TilePainter::PaintFullBlend); + recursion = false; + return true; + } + else if ( ::qt_cast<QListBox*>(object) ) + { + //Handle combobox drop downs + switch (event->type()) + { +#ifdef HAVE_X11_EXTENSIONS_SHAPE_H + //Combo dropdowns are shaped + case QEvent::Resize: + { + QListBox* listbox = static_cast<QListBox*>(object); + QResizeEvent* resize = static_cast<QResizeEvent*>(event); + if (resize->size().height() < 6) + return false; + + //CHECKME: Not sure the rects are perfect.. + XRectangle rects[5] = { + {0, 0, resize->size().width()-2, resize->size().height()-6}, + {0, resize->size().height()-6, resize->size().width()-2, 1}, + {1, resize->size().height()-5, resize->size().width()-3, 1}, + {2, resize->size().height()-4, resize->size().width()-5, 1}, + {3, resize->size().height()-3, resize->size().width()-7, 1} + }; + + XShapeCombineRectangles(qt_xdisplay(), listbox->handle(), ShapeBounding, 0, 0, + rects, 5, ShapeSet, YXSorted); + } + break; +#endif + //Combo dropdowns get fancy borders + case QEvent::Paint: + { + static bool recursion = false; + if (recursion ) + return false; + QListBox* listbox = (QListBox*) object; + QPaintEvent* paint = (QPaintEvent*) event; + + + if ( !listbox->contentsRect().contains( paint->rect() ) ) + { + QPainter p( listbox ); + Keramik::RectTilePainter( keramik_combobox_list, false, false ).draw( &p, 0, 0, listbox->width(), listbox->height(), + listbox->palette().color( QPalette::Normal, QColorGroup::Button ), + listbox->palette().color( QPalette::Normal, QColorGroup::Background ) ); + + QPaintEvent newpaint( paint->region().intersect( listbox->contentsRect() ), paint->erased() ); + recursion = true; + object->event( &newpaint ); + recursion = false; + return true; + } + } + break; + + /** + Since our popup is shown a bit overlapping the combo body, a mouse click at the bottom of the + widget will result in the release going to the popup, which will cause it to close (#56435). + We solve it by filtering out the first release, if it's in the right area. To do this, we notices shows, + move ourselves to front of event filter list, and then capture the first release event, and if it's + in the overlap area, filter it out. + */ + case QEvent::Show: + //Prioritize ourselves to see the mouse events first + object->removeEventFilter(this); + object->installEventFilter(this); + firstComboPopupRelease = true; + break; + + //We need to filter some clicks out. + case QEvent::MouseButtonRelease: + if (firstComboPopupRelease) + { + firstComboPopupRelease = false; + + QMouseEvent* mev = static_cast<QMouseEvent*>(event); + QListBox* box = static_cast<QListBox*> (object); + + QWidget* parent = box->parentWidget(); + if (!parent) + return false; + + QPoint inParCoords = parent->mapFromGlobal(mev->globalPos()); + if (parent->rect().contains(inParCoords)) + return true; + } + break; + case QEvent::MouseButtonPress: + case QEvent::MouseButtonDblClick: + case QEvent::Wheel: + case QEvent::KeyPress: + case QEvent::KeyRelease: + firstComboPopupRelease = false; + default: + return false; + } + } + //Toolbar background gradient handling + else if (event->type() == QEvent::Paint && + object->parent() && !qstrcmp(object->name(), kdeToolbarWidget) ) + { + // Draw a gradient background for custom widgets in the toolbar + // that have specified a "kde toolbar widget" name. + renderToolbarWidgetBackground(0, static_cast<QWidget*>(object)); + + return false; // Now draw the contents + } + else if (event->type() == QEvent::Paint && object->parent() && ::qt_cast<QToolBar*>(object->parent()) + && !::qt_cast<QPopupMenu*>(object) ) + { + // We need to override the paint event to draw a + // gradient on a QToolBarExtensionWidget. + QToolBar* toolbar = static_cast<QToolBar*>(object->parent()); + QWidget* widget = static_cast<QWidget*>(object); + QRect wr = widget->rect (), tr = toolbar->rect(); + QPainter p( widget ); + + if ( toolbar->orientation() == Qt::Horizontal ) + { + Keramik::GradientPainter::renderGradient( &p, wr, widget->colorGroup().button(), + true /*horizontal*/, false /*not a menu*/, + 0, widget->y(), wr.width(), tr.height()); + } + else + { + Keramik::GradientPainter::renderGradient( &p, wr, widget->colorGroup().button(), + false /*vertical*/, false /*not a menu*/, + widget->x(), 0, tr.width(), wr.height()); + } + + + //Draw terminator line, too + p.setPen( toolbar->colorGroup().mid() ); + if ( toolbar->orientation() == Qt::Horizontal ) + p.drawLine( wr.width()-1, 0, wr.width()-1, wr.height()-1 ); + else + p.drawLine( 0, wr.height()-1, wr.width()-1, wr.height()-1 ); + return true; + + } + // Track show events for progress bars + if ( animateProgressBar && ::qt_cast<QProgressBar*>(object) ) + { + if ((event->type() == QEvent::Show) && !animationTimer->isActive()) + { + animationTimer->start( 50, false ); + } + } + return false; +} + +// vim: ts=4 sw=4 noet +// kate: indent-width 4; replace-tabs off; tab-width 4; space-indent off; diff --git a/kstyles/keramik/keramik.h b/kstyles/keramik/keramik.h new file mode 100644 index 000000000..1c1792fd3 --- /dev/null +++ b/kstyles/keramik/keramik.h @@ -0,0 +1,207 @@ +/* Keramik Style for KDE3 + Copyright (c) 2002 Malte Starostik <[email protected]> + + based on the KDE3 HighColor Style + + Copyright (C) 2001-2002 Karol Szwed <[email protected]> + (C) 2001-2002 Fredrik H�glund <[email protected]> + + Drawing routines adapted from the KDE2 HCStyle, + Copyright (C) 2000 Daniel M. Duley <[email protected]> + (C) 2000 Dirk Mueller <[email protected]> + (C) 2001 Martijn Klingens <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// $Id$ + +#ifndef __keramik_h__ +#define __keramik_h__ + +#include <qframe.h> +#include <kstyle.h> + +#include "pixmaploader.h" + +class QProgressBar; + +class KeramikStyle : public KStyle +{ + Q_OBJECT + +public: + KeramikStyle(); + virtual ~KeramikStyle(); + + void renderMenuBlendPixmap( KPixmap& pix, const QColorGroup &cg, const QPopupMenu* ) const; + QPixmap stylePixmap(StylePixmap stylepixmap, const QWidget* widget, const QStyleOption& opt) const; + + void polish( QWidget* widget ); + void unPolish( QWidget* widget ); + void polish( QPalette& ); + void polish( QApplication *app ); + + void drawKStylePrimitive( KStylePrimitive kpe, + QPainter* p, + const QWidget* widget, + const QRect& r, + const QColorGroup& cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawPrimitive( PrimitiveElement pe, + QPainter* p, + const QRect& r, + const QColorGroup& cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControl( ControlElement element, + QPainter* p, + const QWidget* widget, + const QRect& r, + const QColorGroup& cg, + SFlags flags = Style_Default, + const QStyleOption& opt = QStyleOption::Default ) const; + + void drawControlMask( ControlElement element, + QPainter* p, + const QWidget* widget, + const QRect& r, + const QStyleOption& opt = QStyleOption::Default ) const; + + void drawComplexControl( ComplexControl control, + QPainter* p, + const QWidget* widget, + const QRect& r, + const QColorGroup& cg, + SFlags flags = Style_Default, + SCFlags controls = SC_All, + SCFlags active = SC_None, + const QStyleOption& = QStyleOption::Default ) const; + + void drawComplexControlMask( ComplexControl control, + QPainter* p, + const QWidget* widget, + const QRect& r, + const QStyleOption& = QStyleOption::Default ) const; + + int pixelMetric( PixelMetric m, const QWidget* widget = 0 ) const; + + QSize sizeFromContents( ContentsType contents, + const QWidget* widget, + const QSize& contentSize, + const QStyleOption& opt ) const; + + SubControl querySubControl( ComplexControl control, + const QWidget* widget, + const QPoint& point, + const QStyleOption& opt = QStyleOption::Default ) const; + + QRect querySubControlMetrics( ComplexControl control, + const QWidget* widget, + SubControl subcontrol, + const QStyleOption& opt = QStyleOption::Default ) const; + +private slots: + //Animation slots. + void updateProgressPos(); + void progressBarDestroyed(QObject* bar); + +private: + + bool isSizeConstrainedCombo(const QComboBox* combo) const; + bool isFormWidget (const QWidget* widget) const; + + ///Configuration settings + bool animateProgressBar; + bool highlightScrollBar; + + //Rendering flags + mutable bool forceSmallMode; + mutable bool maskMode; //Ugly round trip flag to permit masking with little code; + mutable bool formMode; //Set when rendering form widgets + + mutable const QWidget* toolbarBlendWidget; //Ditto for blending with toolbars + + enum TitleBarMode + { + None = 0, + Regular, + Maximized + }; + + mutable TitleBarMode titleBarMode; //Set when passing back CC_TilteBar modes to handle + //PE_ButtonTool properly for them, as well as when handling CC_ToolButton from + //The maximized window controls. + + mutable bool flatMode; //Set when calling PE_PushButton or PE_ButtonDefault + // on a flat button. + + mutable bool customScrollMode; //Set when drawing scrollbars with custom colors. + + bool firstComboPopupRelease; + + //Animation support. + QMap<QProgressBar*, int> progAnimWidgets; + + bool eventFilter( QObject* object, QEvent* event ); + + Keramik::TilePainter::PaintMode pmode() const + { + if (formMode) + { + //If we're a form widget, we blend on painting, and consider ourselves + //not to have a mask (so we don't get clipped to it) + if (maskMode) + return Keramik::TilePainter::PaintTrivialMask; + else + return Keramik::TilePainter::PaintFullBlend; + } + else + { + if (maskMode) + return Keramik::TilePainter::PaintMask; + else + return Keramik::TilePainter::PaintNormal; + } + } + + Keramik::TilePainter::PaintMode pmodeFullBlend() const + { + return maskMode?Keramik::TilePainter::PaintMask : Keramik::TilePainter::PaintFullBlend; + } + + QWidget* hoverWidget; + + + bool kickerMode; + + // For progress bar animation + QTimer *animationTimer; + + QRect subRect(SubRect r, const QWidget *widget) const; + + // Disable copy constructor and = operator + KeramikStyle( const KeramikStyle& ); + KeramikStyle& operator=( const KeramikStyle& ); +}; + +#endif + +// vim: ts=4 sw=4 noet +// kate: indent-width 4; replace-tabs off; tab-width 4; diff --git a/kstyles/keramik/keramikimage.h b/kstyles/keramik/keramikimage.h new file mode 100644 index 000000000..c8e684a00 --- /dev/null +++ b/kstyles/keramik/keramikimage.h @@ -0,0 +1,69 @@ +/* Keramik Style for KDE3 + Copyright (c) 2002 Malte Starostik <[email protected]> + (c) 2002 Maksim Orlovich <[email protected]> + + based on the KDE3 HighColor Style + + Copyright (C) 2001-2002 Karol Szwed <[email protected]> + (C) 2001-2002 Fredrik H�glund <[email protected]> + + Drawing routines adapted from the KDE2 HCStyle, + Copyright (C) 2000 Daniel M. Duley <[email protected]> + (C) 2000 Dirk Mueller <[email protected]> + (C) 2001 Martijn Klingens <[email protected]> + + Progressbar code based on KStyle, Copyright (C) 2001-2002 Karol Szwed <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#ifndef KERAMIK_IMAGE_H +#define KERAMIK_IMAGE_H + +struct KeramikEmbedImage +{ + bool haveAlpha; + int width; + int height; + int id; + const unsigned char* data; +}; + +extern KeramikEmbedImage* KeramikGetDbImage(int id); +extern void KeramikDbCleanup(); + +enum KeramikTileType +{ + KeramikTileTL = 0, + KeramikTileTC = 1, + KeramikTileTR = 2, + KeramikTileCL = 3, + KeramikTileCC = 4, + KeramikTileCR = 5, + KeramikTileRL = 6, + KeramikTileRC = 7, + KeramikTileRR = 8, + KeramikTileSeparator = 16, + KeramikSlider1 = 32, + KeramikSlider2 = 48, + KeramikSlider3 = 64, + KeramikSlider4 = 80, + KeramikGroove1 = 96, + KeramikGroove2 = 112 +}; + +#endif diff --git a/kstyles/keramik/pics/checkbox-off.png b/kstyles/keramik/pics/checkbox-off.png Binary files differnew file mode 100644 index 000000000..0cade1079 --- /dev/null +++ b/kstyles/keramik/pics/checkbox-off.png diff --git a/kstyles/keramik/pics/checkbox-on.png b/kstyles/keramik/pics/checkbox-on.png Binary files differnew file mode 100644 index 000000000..69c1a7d83 --- /dev/null +++ b/kstyles/keramik/pics/checkbox-on.png diff --git a/kstyles/keramik/pics/checkbox-tri.png b/kstyles/keramik/pics/checkbox-tri.png Binary files differnew file mode 100644 index 000000000..c73ca8124 --- /dev/null +++ b/kstyles/keramik/pics/checkbox-tri.png diff --git a/kstyles/keramik/pics/combobox-list-bc.png b/kstyles/keramik/pics/combobox-list-bc.png Binary files differnew file mode 100644 index 000000000..609a72627 --- /dev/null +++ b/kstyles/keramik/pics/combobox-list-bc.png diff --git a/kstyles/keramik/pics/combobox-list-bl.png b/kstyles/keramik/pics/combobox-list-bl.png Binary files differnew file mode 100644 index 000000000..512bbeafe --- /dev/null +++ b/kstyles/keramik/pics/combobox-list-bl.png diff --git a/kstyles/keramik/pics/combobox-list-br.png b/kstyles/keramik/pics/combobox-list-br.png Binary files differnew file mode 100644 index 000000000..93151ffa6 --- /dev/null +++ b/kstyles/keramik/pics/combobox-list-br.png diff --git a/kstyles/keramik/pics/combobox-list-cl.png b/kstyles/keramik/pics/combobox-list-cl.png Binary files differnew file mode 100644 index 000000000..e0b29c26d --- /dev/null +++ b/kstyles/keramik/pics/combobox-list-cl.png diff --git a/kstyles/keramik/pics/combobox-list-cr.png b/kstyles/keramik/pics/combobox-list-cr.png Binary files differnew file mode 100644 index 000000000..33b9b7224 --- /dev/null +++ b/kstyles/keramik/pics/combobox-list-cr.png diff --git a/kstyles/keramik/pics/combobox-list-tc.png b/kstyles/keramik/pics/combobox-list-tc.png Binary files differnew file mode 100644 index 000000000..a3f5d7225 --- /dev/null +++ b/kstyles/keramik/pics/combobox-list-tc.png diff --git a/kstyles/keramik/pics/combobox-list-tl.png b/kstyles/keramik/pics/combobox-list-tl.png Binary files differnew file mode 100644 index 000000000..89d4b48d2 --- /dev/null +++ b/kstyles/keramik/pics/combobox-list-tl.png diff --git a/kstyles/keramik/pics/combobox-list-tr.png b/kstyles/keramik/pics/combobox-list-tr.png Binary files differnew file mode 100644 index 000000000..54e5d6032 --- /dev/null +++ b/kstyles/keramik/pics/combobox-list-tr.png diff --git a/kstyles/keramik/pics/frame-shadow-cl.png b/kstyles/keramik/pics/frame-shadow-cl.png Binary files differnew file mode 100644 index 000000000..d9b5edb1f --- /dev/null +++ b/kstyles/keramik/pics/frame-shadow-cl.png diff --git a/kstyles/keramik/pics/frame-shadow-tc.png b/kstyles/keramik/pics/frame-shadow-tc.png Binary files differnew file mode 100644 index 000000000..408e07314 --- /dev/null +++ b/kstyles/keramik/pics/frame-shadow-tc.png diff --git a/kstyles/keramik/pics/frame-shadow-tl.png b/kstyles/keramik/pics/frame-shadow-tl.png Binary files differnew file mode 100644 index 000000000..8e6e3a147 --- /dev/null +++ b/kstyles/keramik/pics/frame-shadow-tl.png diff --git a/kstyles/keramik/pics/listview-bc.png b/kstyles/keramik/pics/listview-bc.png Binary files differnew file mode 100644 index 000000000..fc615ea8a --- /dev/null +++ b/kstyles/keramik/pics/listview-bc.png diff --git a/kstyles/keramik/pics/listview-bl.png b/kstyles/keramik/pics/listview-bl.png Binary files differnew file mode 100644 index 000000000..efd68101a --- /dev/null +++ b/kstyles/keramik/pics/listview-bl.png diff --git a/kstyles/keramik/pics/listview-br.png b/kstyles/keramik/pics/listview-br.png Binary files differnew file mode 100644 index 000000000..7e35a14c8 --- /dev/null +++ b/kstyles/keramik/pics/listview-br.png diff --git a/kstyles/keramik/pics/listview-cc.png b/kstyles/keramik/pics/listview-cc.png Binary files differnew file mode 100644 index 000000000..9fa204bf4 --- /dev/null +++ b/kstyles/keramik/pics/listview-cc.png diff --git a/kstyles/keramik/pics/listview-cl.png b/kstyles/keramik/pics/listview-cl.png Binary files differnew file mode 100644 index 000000000..41850b2e6 --- /dev/null +++ b/kstyles/keramik/pics/listview-cl.png diff --git a/kstyles/keramik/pics/listview-cr.png b/kstyles/keramik/pics/listview-cr.png Binary files differnew file mode 100644 index 000000000..69b1cf8c6 --- /dev/null +++ b/kstyles/keramik/pics/listview-cr.png diff --git a/kstyles/keramik/pics/listview-pressed-bc.png b/kstyles/keramik/pics/listview-pressed-bc.png Binary files differnew file mode 100644 index 000000000..283fe7329 --- /dev/null +++ b/kstyles/keramik/pics/listview-pressed-bc.png diff --git a/kstyles/keramik/pics/listview-pressed-bl.png b/kstyles/keramik/pics/listview-pressed-bl.png Binary files differnew file mode 100644 index 000000000..a457f83a6 --- /dev/null +++ b/kstyles/keramik/pics/listview-pressed-bl.png diff --git a/kstyles/keramik/pics/listview-pressed-br.png b/kstyles/keramik/pics/listview-pressed-br.png Binary files differnew file mode 100644 index 000000000..a49203f89 --- /dev/null +++ b/kstyles/keramik/pics/listview-pressed-br.png diff --git a/kstyles/keramik/pics/listview-pressed-cc.png b/kstyles/keramik/pics/listview-pressed-cc.png Binary files differnew file mode 100644 index 000000000..63265116e --- /dev/null +++ b/kstyles/keramik/pics/listview-pressed-cc.png diff --git a/kstyles/keramik/pics/listview-pressed-cl.png b/kstyles/keramik/pics/listview-pressed-cl.png Binary files differnew file mode 100644 index 000000000..7dcc0540c --- /dev/null +++ b/kstyles/keramik/pics/listview-pressed-cl.png diff --git a/kstyles/keramik/pics/listview-pressed-cr.png b/kstyles/keramik/pics/listview-pressed-cr.png Binary files differnew file mode 100644 index 000000000..3a0b74f9a --- /dev/null +++ b/kstyles/keramik/pics/listview-pressed-cr.png diff --git a/kstyles/keramik/pics/listview-pressed-tc.png b/kstyles/keramik/pics/listview-pressed-tc.png Binary files differnew file mode 100644 index 000000000..1fa2e6905 --- /dev/null +++ b/kstyles/keramik/pics/listview-pressed-tc.png diff --git a/kstyles/keramik/pics/listview-pressed-tl.png b/kstyles/keramik/pics/listview-pressed-tl.png Binary files differnew file mode 100644 index 000000000..e58e62306 --- /dev/null +++ b/kstyles/keramik/pics/listview-pressed-tl.png diff --git a/kstyles/keramik/pics/listview-pressed-tr.png b/kstyles/keramik/pics/listview-pressed-tr.png Binary files differnew file mode 100644 index 000000000..bc33f3823 --- /dev/null +++ b/kstyles/keramik/pics/listview-pressed-tr.png diff --git a/kstyles/keramik/pics/listview-tc.png b/kstyles/keramik/pics/listview-tc.png Binary files differnew file mode 100644 index 000000000..09434cebb --- /dev/null +++ b/kstyles/keramik/pics/listview-tc.png diff --git a/kstyles/keramik/pics/listview-tl.png b/kstyles/keramik/pics/listview-tl.png Binary files differnew file mode 100644 index 000000000..d2ca26d7a --- /dev/null +++ b/kstyles/keramik/pics/listview-tl.png diff --git a/kstyles/keramik/pics/listview-tr.png b/kstyles/keramik/pics/listview-tr.png Binary files differnew file mode 100644 index 000000000..42c49a597 --- /dev/null +++ b/kstyles/keramik/pics/listview-tr.png diff --git a/kstyles/keramik/pics/menuitem-cc.png b/kstyles/keramik/pics/menuitem-cc.png Binary files differnew file mode 100644 index 000000000..29362ccc8 --- /dev/null +++ b/kstyles/keramik/pics/menuitem-cc.png diff --git a/kstyles/keramik/pics/menuitem-cl.png b/kstyles/keramik/pics/menuitem-cl.png Binary files differnew file mode 100644 index 000000000..c742516f4 --- /dev/null +++ b/kstyles/keramik/pics/menuitem-cl.png diff --git a/kstyles/keramik/pics/menuitem-cr.png b/kstyles/keramik/pics/menuitem-cr.png Binary files differnew file mode 100644 index 000000000..c742516f4 --- /dev/null +++ b/kstyles/keramik/pics/menuitem-cr.png diff --git a/kstyles/keramik/pics/progressbar-cc.png b/kstyles/keramik/pics/progressbar-cc.png Binary files differnew file mode 100644 index 000000000..e7881df47 --- /dev/null +++ b/kstyles/keramik/pics/progressbar-cc.png diff --git a/kstyles/keramik/pics/progressbar-cl.png b/kstyles/keramik/pics/progressbar-cl.png Binary files differnew file mode 100644 index 000000000..66824c873 --- /dev/null +++ b/kstyles/keramik/pics/progressbar-cl.png diff --git a/kstyles/keramik/pics/progressbar-cr.png b/kstyles/keramik/pics/progressbar-cr.png Binary files differnew file mode 100644 index 000000000..c6d61e75d --- /dev/null +++ b/kstyles/keramik/pics/progressbar-cr.png diff --git a/kstyles/keramik/pics/pushbutton-bc.png b/kstyles/keramik/pics/pushbutton-bc.png Binary files differnew file mode 100644 index 000000000..62f169aa2 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-bc.png diff --git a/kstyles/keramik/pics/pushbutton-bl.png b/kstyles/keramik/pics/pushbutton-bl.png Binary files differnew file mode 100644 index 000000000..ea17ef991 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-bl.png diff --git a/kstyles/keramik/pics/pushbutton-br.png b/kstyles/keramik/pics/pushbutton-br.png Binary files differnew file mode 100644 index 000000000..91703e742 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-br.png diff --git a/kstyles/keramik/pics/pushbutton-cc.png b/kstyles/keramik/pics/pushbutton-cc.png Binary files differnew file mode 100644 index 000000000..ac5a2fdc0 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-cc.png diff --git a/kstyles/keramik/pics/pushbutton-cl.png b/kstyles/keramik/pics/pushbutton-cl.png Binary files differnew file mode 100644 index 000000000..0a9c56630 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-cl.png diff --git a/kstyles/keramik/pics/pushbutton-cr.png b/kstyles/keramik/pics/pushbutton-cr.png Binary files differnew file mode 100644 index 000000000..68449467f --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-cr.png diff --git a/kstyles/keramik/pics/pushbutton-default-bc.png b/kstyles/keramik/pics/pushbutton-default-bc.png Binary files differnew file mode 100644 index 000000000..308020237 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-bc.png diff --git a/kstyles/keramik/pics/pushbutton-default-bl.png b/kstyles/keramik/pics/pushbutton-default-bl.png Binary files differnew file mode 100644 index 000000000..97c69cd1c --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-bl.png diff --git a/kstyles/keramik/pics/pushbutton-default-br.png b/kstyles/keramik/pics/pushbutton-default-br.png Binary files differnew file mode 100644 index 000000000..e084dca00 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-br.png diff --git a/kstyles/keramik/pics/pushbutton-default-cc.png b/kstyles/keramik/pics/pushbutton-default-cc.png Binary files differnew file mode 100644 index 000000000..51e655302 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-cc.png diff --git a/kstyles/keramik/pics/pushbutton-default-cl.png b/kstyles/keramik/pics/pushbutton-default-cl.png Binary files differnew file mode 100644 index 000000000..5c4c001b1 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-cl.png diff --git a/kstyles/keramik/pics/pushbutton-default-cr.png b/kstyles/keramik/pics/pushbutton-default-cr.png Binary files differnew file mode 100644 index 000000000..0b1ea243b --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-cr.png diff --git a/kstyles/keramik/pics/pushbutton-default-hov-bc.png b/kstyles/keramik/pics/pushbutton-default-hov-bc.png Binary files differnew file mode 100644 index 000000000..1c3f23766 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-hov-bc.png diff --git a/kstyles/keramik/pics/pushbutton-default-hov-bl.png b/kstyles/keramik/pics/pushbutton-default-hov-bl.png Binary files differnew file mode 100644 index 000000000..5072df3a7 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-hov-bl.png diff --git a/kstyles/keramik/pics/pushbutton-default-hov-br.png b/kstyles/keramik/pics/pushbutton-default-hov-br.png Binary files differnew file mode 100644 index 000000000..827df317d --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-hov-br.png diff --git a/kstyles/keramik/pics/pushbutton-default-hov-cc.png b/kstyles/keramik/pics/pushbutton-default-hov-cc.png Binary files differnew file mode 100644 index 000000000..ec57f7ed7 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-hov-cc.png diff --git a/kstyles/keramik/pics/pushbutton-default-hov-cl.png b/kstyles/keramik/pics/pushbutton-default-hov-cl.png Binary files differnew file mode 100644 index 000000000..09fdf4dfa --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-hov-cl.png diff --git a/kstyles/keramik/pics/pushbutton-default-hov-cr.png b/kstyles/keramik/pics/pushbutton-default-hov-cr.png Binary files differnew file mode 100644 index 000000000..131c96f55 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-hov-cr.png diff --git a/kstyles/keramik/pics/pushbutton-default-hov-tc.png b/kstyles/keramik/pics/pushbutton-default-hov-tc.png Binary files differnew file mode 100644 index 000000000..45f4e86c3 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-hov-tc.png diff --git a/kstyles/keramik/pics/pushbutton-default-hov-tl.png b/kstyles/keramik/pics/pushbutton-default-hov-tl.png Binary files differnew file mode 100644 index 000000000..13e2cdfa2 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-hov-tl.png diff --git a/kstyles/keramik/pics/pushbutton-default-hov-tr.png b/kstyles/keramik/pics/pushbutton-default-hov-tr.png Binary files differnew file mode 100644 index 000000000..0eb2d5f2d --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-hov-tr.png diff --git a/kstyles/keramik/pics/pushbutton-default-pressed-bc.png b/kstyles/keramik/pics/pushbutton-default-pressed-bc.png Binary files differnew file mode 100644 index 000000000..7d1f31b4b --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-pressed-bc.png diff --git a/kstyles/keramik/pics/pushbutton-default-pressed-bl.png b/kstyles/keramik/pics/pushbutton-default-pressed-bl.png Binary files differnew file mode 100644 index 000000000..05d432d3a --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-pressed-bl.png diff --git a/kstyles/keramik/pics/pushbutton-default-pressed-br.png b/kstyles/keramik/pics/pushbutton-default-pressed-br.png Binary files differnew file mode 100644 index 000000000..5ac4eb761 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-pressed-br.png diff --git a/kstyles/keramik/pics/pushbutton-default-pressed-cc.png b/kstyles/keramik/pics/pushbutton-default-pressed-cc.png Binary files differnew file mode 100644 index 000000000..a29eb9b26 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-pressed-cc.png diff --git a/kstyles/keramik/pics/pushbutton-default-pressed-cl.png b/kstyles/keramik/pics/pushbutton-default-pressed-cl.png Binary files differnew file mode 100644 index 000000000..1732ab586 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-pressed-cl.png diff --git a/kstyles/keramik/pics/pushbutton-default-pressed-cr.png b/kstyles/keramik/pics/pushbutton-default-pressed-cr.png Binary files differnew file mode 100644 index 000000000..3e52fd79f --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-pressed-cr.png diff --git a/kstyles/keramik/pics/pushbutton-default-pressed-tc.png b/kstyles/keramik/pics/pushbutton-default-pressed-tc.png Binary files differnew file mode 100644 index 000000000..a2774ed4d --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-pressed-tc.png diff --git a/kstyles/keramik/pics/pushbutton-default-pressed-tl.png b/kstyles/keramik/pics/pushbutton-default-pressed-tl.png Binary files differnew file mode 100644 index 000000000..209673d91 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-pressed-tl.png diff --git a/kstyles/keramik/pics/pushbutton-default-pressed-tr.png b/kstyles/keramik/pics/pushbutton-default-pressed-tr.png Binary files differnew file mode 100644 index 000000000..4b4d8bed1 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-pressed-tr.png diff --git a/kstyles/keramik/pics/pushbutton-default-tc.png b/kstyles/keramik/pics/pushbutton-default-tc.png Binary files differnew file mode 100644 index 000000000..e71531f73 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-tc.png diff --git a/kstyles/keramik/pics/pushbutton-default-tl.png b/kstyles/keramik/pics/pushbutton-default-tl.png Binary files differnew file mode 100644 index 000000000..02c8adb38 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-tl.png diff --git a/kstyles/keramik/pics/pushbutton-default-tr.png b/kstyles/keramik/pics/pushbutton-default-tr.png Binary files differnew file mode 100644 index 000000000..741dd67cb --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-default-tr.png diff --git a/kstyles/keramik/pics/pushbutton-hov-bc.png b/kstyles/keramik/pics/pushbutton-hov-bc.png Binary files differnew file mode 100644 index 000000000..1b7731085 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-hov-bc.png diff --git a/kstyles/keramik/pics/pushbutton-hov-bl.png b/kstyles/keramik/pics/pushbutton-hov-bl.png Binary files differnew file mode 100644 index 000000000..29f066774 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-hov-bl.png diff --git a/kstyles/keramik/pics/pushbutton-hov-br.png b/kstyles/keramik/pics/pushbutton-hov-br.png Binary files differnew file mode 100644 index 000000000..c7b045337 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-hov-br.png diff --git a/kstyles/keramik/pics/pushbutton-hov-cc.png b/kstyles/keramik/pics/pushbutton-hov-cc.png Binary files differnew file mode 100644 index 000000000..f57781d87 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-hov-cc.png diff --git a/kstyles/keramik/pics/pushbutton-hov-cl.png b/kstyles/keramik/pics/pushbutton-hov-cl.png Binary files differnew file mode 100644 index 000000000..1540ef437 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-hov-cl.png diff --git a/kstyles/keramik/pics/pushbutton-hov-cr.png b/kstyles/keramik/pics/pushbutton-hov-cr.png Binary files differnew file mode 100644 index 000000000..e105ae6f8 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-hov-cr.png diff --git a/kstyles/keramik/pics/pushbutton-hov-tc.png b/kstyles/keramik/pics/pushbutton-hov-tc.png Binary files differnew file mode 100644 index 000000000..fa2a00270 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-hov-tc.png diff --git a/kstyles/keramik/pics/pushbutton-hov-tl.png b/kstyles/keramik/pics/pushbutton-hov-tl.png Binary files differnew file mode 100644 index 000000000..9eddbf5f9 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-hov-tl.png diff --git a/kstyles/keramik/pics/pushbutton-hov-tr.png b/kstyles/keramik/pics/pushbutton-hov-tr.png Binary files differnew file mode 100644 index 000000000..c4ea2e1ae --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-hov-tr.png diff --git a/kstyles/keramik/pics/pushbutton-pressed-bc.png b/kstyles/keramik/pics/pushbutton-pressed-bc.png Binary files differnew file mode 100644 index 000000000..1e9097faa --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-pressed-bc.png diff --git a/kstyles/keramik/pics/pushbutton-pressed-bl.png b/kstyles/keramik/pics/pushbutton-pressed-bl.png Binary files differnew file mode 100644 index 000000000..ae8ad9ba3 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-pressed-bl.png diff --git a/kstyles/keramik/pics/pushbutton-pressed-br.png b/kstyles/keramik/pics/pushbutton-pressed-br.png Binary files differnew file mode 100644 index 000000000..8d1a62e7e --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-pressed-br.png diff --git a/kstyles/keramik/pics/pushbutton-pressed-cc.png b/kstyles/keramik/pics/pushbutton-pressed-cc.png Binary files differnew file mode 100644 index 000000000..09cb446ba --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-pressed-cc.png diff --git a/kstyles/keramik/pics/pushbutton-pressed-cl.png b/kstyles/keramik/pics/pushbutton-pressed-cl.png Binary files differnew file mode 100644 index 000000000..1291cf33f --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-pressed-cl.png diff --git a/kstyles/keramik/pics/pushbutton-pressed-cr.png b/kstyles/keramik/pics/pushbutton-pressed-cr.png Binary files differnew file mode 100644 index 000000000..6e35bd28b --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-pressed-cr.png diff --git a/kstyles/keramik/pics/pushbutton-pressed-tc.png b/kstyles/keramik/pics/pushbutton-pressed-tc.png Binary files differnew file mode 100644 index 000000000..ab1ccf476 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-pressed-tc.png diff --git a/kstyles/keramik/pics/pushbutton-pressed-tl.png b/kstyles/keramik/pics/pushbutton-pressed-tl.png Binary files differnew file mode 100644 index 000000000..41df0033f --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-pressed-tl.png diff --git a/kstyles/keramik/pics/pushbutton-pressed-tr.png b/kstyles/keramik/pics/pushbutton-pressed-tr.png Binary files differnew file mode 100644 index 000000000..fc83cfdef --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-pressed-tr.png diff --git a/kstyles/keramik/pics/pushbutton-small-bc.png b/kstyles/keramik/pics/pushbutton-small-bc.png Binary files differnew file mode 100644 index 000000000..b55ed441c --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-bc.png diff --git a/kstyles/keramik/pics/pushbutton-small-bl.png b/kstyles/keramik/pics/pushbutton-small-bl.png Binary files differnew file mode 100644 index 000000000..fc14a94c1 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-bl.png diff --git a/kstyles/keramik/pics/pushbutton-small-br.png b/kstyles/keramik/pics/pushbutton-small-br.png Binary files differnew file mode 100644 index 000000000..f24b47af1 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-br.png diff --git a/kstyles/keramik/pics/pushbutton-small-cc.png b/kstyles/keramik/pics/pushbutton-small-cc.png Binary files differnew file mode 100644 index 000000000..8f8d49964 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-cc.png diff --git a/kstyles/keramik/pics/pushbutton-small-cl.png b/kstyles/keramik/pics/pushbutton-small-cl.png Binary files differnew file mode 100644 index 000000000..9ce9e492f --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-cl.png diff --git a/kstyles/keramik/pics/pushbutton-small-cr.png b/kstyles/keramik/pics/pushbutton-small-cr.png Binary files differnew file mode 100644 index 000000000..db05257b2 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-cr.png diff --git a/kstyles/keramik/pics/pushbutton-small-pressed-bc.png b/kstyles/keramik/pics/pushbutton-small-pressed-bc.png Binary files differnew file mode 100644 index 000000000..560f17c5d --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-pressed-bc.png diff --git a/kstyles/keramik/pics/pushbutton-small-pressed-bl.png b/kstyles/keramik/pics/pushbutton-small-pressed-bl.png Binary files differnew file mode 100644 index 000000000..36e39f88d --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-pressed-bl.png diff --git a/kstyles/keramik/pics/pushbutton-small-pressed-br.png b/kstyles/keramik/pics/pushbutton-small-pressed-br.png Binary files differnew file mode 100644 index 000000000..d269e61bf --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-pressed-br.png diff --git a/kstyles/keramik/pics/pushbutton-small-pressed-cc.png b/kstyles/keramik/pics/pushbutton-small-pressed-cc.png Binary files differnew file mode 100644 index 000000000..abab3832c --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-pressed-cc.png diff --git a/kstyles/keramik/pics/pushbutton-small-pressed-cl.png b/kstyles/keramik/pics/pushbutton-small-pressed-cl.png Binary files differnew file mode 100644 index 000000000..8049bee04 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-pressed-cl.png diff --git a/kstyles/keramik/pics/pushbutton-small-pressed-cr.png b/kstyles/keramik/pics/pushbutton-small-pressed-cr.png Binary files differnew file mode 100644 index 000000000..ef13139c2 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-pressed-cr.png diff --git a/kstyles/keramik/pics/pushbutton-small-pressed-tc.png b/kstyles/keramik/pics/pushbutton-small-pressed-tc.png Binary files differnew file mode 100644 index 000000000..d10fc26a8 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-pressed-tc.png diff --git a/kstyles/keramik/pics/pushbutton-small-pressed-tl.png b/kstyles/keramik/pics/pushbutton-small-pressed-tl.png Binary files differnew file mode 100644 index 000000000..7f189e50d --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-pressed-tl.png diff --git a/kstyles/keramik/pics/pushbutton-small-pressed-tr.png b/kstyles/keramik/pics/pushbutton-small-pressed-tr.png Binary files differnew file mode 100644 index 000000000..5262f63a2 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-pressed-tr.png diff --git a/kstyles/keramik/pics/pushbutton-small-tc.png b/kstyles/keramik/pics/pushbutton-small-tc.png Binary files differnew file mode 100644 index 000000000..216126077 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-tc.png diff --git a/kstyles/keramik/pics/pushbutton-small-tl.png b/kstyles/keramik/pics/pushbutton-small-tl.png Binary files differnew file mode 100644 index 000000000..75d8052b1 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-tl.png diff --git a/kstyles/keramik/pics/pushbutton-small-tr.png b/kstyles/keramik/pics/pushbutton-small-tr.png Binary files differnew file mode 100644 index 000000000..18ac1208d --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-small-tr.png diff --git a/kstyles/keramik/pics/pushbutton-tc.png b/kstyles/keramik/pics/pushbutton-tc.png Binary files differnew file mode 100644 index 000000000..0d0e396d2 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-tc.png diff --git a/kstyles/keramik/pics/pushbutton-tl.png b/kstyles/keramik/pics/pushbutton-tl.png Binary files differnew file mode 100644 index 000000000..6904db252 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-tl.png diff --git a/kstyles/keramik/pics/pushbutton-tr.png b/kstyles/keramik/pics/pushbutton-tr.png Binary files differnew file mode 100644 index 000000000..b3e34dec2 --- /dev/null +++ b/kstyles/keramik/pics/pushbutton-tr.png diff --git a/kstyles/keramik/pics/radiobutton-off.png b/kstyles/keramik/pics/radiobutton-off.png Binary files differnew file mode 100644 index 000000000..6eefc781c --- /dev/null +++ b/kstyles/keramik/pics/radiobutton-off.png diff --git a/kstyles/keramik/pics/radiobutton-on.png b/kstyles/keramik/pics/radiobutton-on.png Binary files differnew file mode 100644 index 000000000..ab4dc6798 --- /dev/null +++ b/kstyles/keramik/pics/radiobutton-on.png diff --git a/kstyles/keramik/pics/ripple.png b/kstyles/keramik/pics/ripple.png Binary files differnew file mode 100644 index 000000000..6b7d04ef3 --- /dev/null +++ b/kstyles/keramik/pics/ripple.png diff --git a/kstyles/keramik/pics/scrollbar-hbar-arrow1.png b/kstyles/keramik/pics/scrollbar-hbar-arrow1.png Binary files differnew file mode 100644 index 000000000..af21cb269 --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-hbar-arrow1.png diff --git a/kstyles/keramik/pics/scrollbar-hbar-arrow2.png b/kstyles/keramik/pics/scrollbar-hbar-arrow2.png Binary files differnew file mode 100644 index 000000000..231520d12 --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-hbar-arrow2.png diff --git a/kstyles/keramik/pics/scrollbar-hbar-groove1.png b/kstyles/keramik/pics/scrollbar-hbar-groove1.png Binary files differnew file mode 100644 index 000000000..0219f2e28 --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-hbar-groove1.png diff --git a/kstyles/keramik/pics/scrollbar-hbar-groove2.png b/kstyles/keramik/pics/scrollbar-hbar-groove2.png Binary files differnew file mode 100644 index 000000000..990b5b06d --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-hbar-groove2.png diff --git a/kstyles/keramik/pics/scrollbar-hbar-slider1.png b/kstyles/keramik/pics/scrollbar-hbar-slider1.png Binary files differnew file mode 100644 index 000000000..6f0896ed9 --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-hbar-slider1.png diff --git a/kstyles/keramik/pics/scrollbar-hbar-slider2.png b/kstyles/keramik/pics/scrollbar-hbar-slider2.png Binary files differnew file mode 100644 index 000000000..c13ecc00c --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-hbar-slider2.png diff --git a/kstyles/keramik/pics/scrollbar-hbar-slider3.png b/kstyles/keramik/pics/scrollbar-hbar-slider3.png Binary files differnew file mode 100644 index 000000000..105718ba7 --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-hbar-slider3.png diff --git a/kstyles/keramik/pics/scrollbar-hbar-slider4.png b/kstyles/keramik/pics/scrollbar-hbar-slider4.png Binary files differnew file mode 100644 index 000000000..9d56a784c --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-hbar-slider4.png diff --git a/kstyles/keramik/pics/scrollbar-vbar-arrow1.png b/kstyles/keramik/pics/scrollbar-vbar-arrow1.png Binary files differnew file mode 100644 index 000000000..cb2f70aeb --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-vbar-arrow1.png diff --git a/kstyles/keramik/pics/scrollbar-vbar-arrow2.png b/kstyles/keramik/pics/scrollbar-vbar-arrow2.png Binary files differnew file mode 100644 index 000000000..4d36f077e --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-vbar-arrow2.png diff --git a/kstyles/keramik/pics/scrollbar-vbar-groove1.png b/kstyles/keramik/pics/scrollbar-vbar-groove1.png Binary files differnew file mode 100644 index 000000000..62ed6491d --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-vbar-groove1.png diff --git a/kstyles/keramik/pics/scrollbar-vbar-groove2.png b/kstyles/keramik/pics/scrollbar-vbar-groove2.png Binary files differnew file mode 100644 index 000000000..219781e23 --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-vbar-groove2.png diff --git a/kstyles/keramik/pics/scrollbar-vbar-slider1.png b/kstyles/keramik/pics/scrollbar-vbar-slider1.png Binary files differnew file mode 100644 index 000000000..29b85856c --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-vbar-slider1.png diff --git a/kstyles/keramik/pics/scrollbar-vbar-slider2.png b/kstyles/keramik/pics/scrollbar-vbar-slider2.png Binary files differnew file mode 100644 index 000000000..ebacc8e67 --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-vbar-slider2.png diff --git a/kstyles/keramik/pics/scrollbar-vbar-slider3.png b/kstyles/keramik/pics/scrollbar-vbar-slider3.png Binary files differnew file mode 100644 index 000000000..197be82c5 --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-vbar-slider3.png diff --git a/kstyles/keramik/pics/scrollbar-vbar-slider4.png b/kstyles/keramik/pics/scrollbar-vbar-slider4.png Binary files differnew file mode 100644 index 000000000..fdb931f4f --- /dev/null +++ b/kstyles/keramik/pics/scrollbar-vbar-slider4.png diff --git a/kstyles/keramik/pics/slider-hgroove-bc.png b/kstyles/keramik/pics/slider-hgroove-bc.png Binary files differnew file mode 100644 index 000000000..d509e8357 --- /dev/null +++ b/kstyles/keramik/pics/slider-hgroove-bc.png diff --git a/kstyles/keramik/pics/slider-hgroove-bl.png b/kstyles/keramik/pics/slider-hgroove-bl.png Binary files differnew file mode 100644 index 000000000..12cb99a5b --- /dev/null +++ b/kstyles/keramik/pics/slider-hgroove-bl.png diff --git a/kstyles/keramik/pics/slider-hgroove-br.png b/kstyles/keramik/pics/slider-hgroove-br.png Binary files differnew file mode 100644 index 000000000..c540bd09b --- /dev/null +++ b/kstyles/keramik/pics/slider-hgroove-br.png diff --git a/kstyles/keramik/pics/slider-hgroove-cc.png b/kstyles/keramik/pics/slider-hgroove-cc.png Binary files differnew file mode 100644 index 000000000..cad18f802 --- /dev/null +++ b/kstyles/keramik/pics/slider-hgroove-cc.png diff --git a/kstyles/keramik/pics/slider-hgroove-cl.png b/kstyles/keramik/pics/slider-hgroove-cl.png Binary files differnew file mode 100644 index 000000000..a261a086f --- /dev/null +++ b/kstyles/keramik/pics/slider-hgroove-cl.png diff --git a/kstyles/keramik/pics/slider-hgroove-cr.png b/kstyles/keramik/pics/slider-hgroove-cr.png Binary files differnew file mode 100644 index 000000000..601ff7d20 --- /dev/null +++ b/kstyles/keramik/pics/slider-hgroove-cr.png diff --git a/kstyles/keramik/pics/slider-hgroove-tc.png b/kstyles/keramik/pics/slider-hgroove-tc.png Binary files differnew file mode 100644 index 000000000..f8ee8d90b --- /dev/null +++ b/kstyles/keramik/pics/slider-hgroove-tc.png diff --git a/kstyles/keramik/pics/slider-hgroove-tl.png b/kstyles/keramik/pics/slider-hgroove-tl.png Binary files differnew file mode 100644 index 000000000..525242cf5 --- /dev/null +++ b/kstyles/keramik/pics/slider-hgroove-tl.png diff --git a/kstyles/keramik/pics/slider-hgroove-tr.png b/kstyles/keramik/pics/slider-hgroove-tr.png Binary files differnew file mode 100644 index 000000000..7fcd449ad --- /dev/null +++ b/kstyles/keramik/pics/slider-hgroove-tr.png diff --git a/kstyles/keramik/pics/slider-vgroove-bc.png b/kstyles/keramik/pics/slider-vgroove-bc.png Binary files differnew file mode 100644 index 000000000..d81815cbf --- /dev/null +++ b/kstyles/keramik/pics/slider-vgroove-bc.png diff --git a/kstyles/keramik/pics/slider-vgroove-bl.png b/kstyles/keramik/pics/slider-vgroove-bl.png Binary files differnew file mode 100644 index 000000000..5f7063525 --- /dev/null +++ b/kstyles/keramik/pics/slider-vgroove-bl.png diff --git a/kstyles/keramik/pics/slider-vgroove-br.png b/kstyles/keramik/pics/slider-vgroove-br.png Binary files differnew file mode 100644 index 000000000..80fbb0c38 --- /dev/null +++ b/kstyles/keramik/pics/slider-vgroove-br.png diff --git a/kstyles/keramik/pics/slider-vgroove-cc.png b/kstyles/keramik/pics/slider-vgroove-cc.png Binary files differnew file mode 100644 index 000000000..56c3e1665 --- /dev/null +++ b/kstyles/keramik/pics/slider-vgroove-cc.png diff --git a/kstyles/keramik/pics/slider-vgroove-cl.png b/kstyles/keramik/pics/slider-vgroove-cl.png Binary files differnew file mode 100644 index 000000000..cca74d7e3 --- /dev/null +++ b/kstyles/keramik/pics/slider-vgroove-cl.png diff --git a/kstyles/keramik/pics/slider-vgroove-cr.png b/kstyles/keramik/pics/slider-vgroove-cr.png Binary files differnew file mode 100644 index 000000000..5e0bba54f --- /dev/null +++ b/kstyles/keramik/pics/slider-vgroove-cr.png diff --git a/kstyles/keramik/pics/slider-vgroove-tc.png b/kstyles/keramik/pics/slider-vgroove-tc.png Binary files differnew file mode 100644 index 000000000..d381a1672 --- /dev/null +++ b/kstyles/keramik/pics/slider-vgroove-tc.png diff --git a/kstyles/keramik/pics/slider-vgroove-tl.png b/kstyles/keramik/pics/slider-vgroove-tl.png Binary files differnew file mode 100644 index 000000000..e2bb6ca4e --- /dev/null +++ b/kstyles/keramik/pics/slider-vgroove-tl.png diff --git a/kstyles/keramik/pics/slider-vgroove-tr.png b/kstyles/keramik/pics/slider-vgroove-tr.png Binary files differnew file mode 100644 index 000000000..03fe46405 --- /dev/null +++ b/kstyles/keramik/pics/slider-vgroove-tr.png diff --git a/kstyles/keramik/pics/slider.png b/kstyles/keramik/pics/slider.png Binary files differnew file mode 100644 index 000000000..6949eec33 --- /dev/null +++ b/kstyles/keramik/pics/slider.png diff --git a/kstyles/keramik/pics/spinbox-1.png b/kstyles/keramik/pics/spinbox-1.png Binary files differnew file mode 100644 index 000000000..728959423 --- /dev/null +++ b/kstyles/keramik/pics/spinbox-1.png diff --git a/kstyles/keramik/pics/spinbox-2.png b/kstyles/keramik/pics/spinbox-2.png Binary files differnew file mode 100644 index 000000000..8dcebdc47 --- /dev/null +++ b/kstyles/keramik/pics/spinbox-2.png diff --git a/kstyles/keramik/pics/spinbox-3.png b/kstyles/keramik/pics/spinbox-3.png Binary files differnew file mode 100644 index 000000000..43cdaf21d --- /dev/null +++ b/kstyles/keramik/pics/spinbox-3.png diff --git a/kstyles/keramik/pics/spinbox-arrow-down.png b/kstyles/keramik/pics/spinbox-arrow-down.png Binary files differnew file mode 100644 index 000000000..58d326e01 --- /dev/null +++ b/kstyles/keramik/pics/spinbox-arrow-down.png diff --git a/kstyles/keramik/pics/spinbox-arrow-up.png b/kstyles/keramik/pics/spinbox-arrow-up.png Binary files differnew file mode 100644 index 000000000..1e1f7a72b --- /dev/null +++ b/kstyles/keramik/pics/spinbox-arrow-up.png diff --git a/kstyles/keramik/pics/spinbox-pressed-arrow-down.png b/kstyles/keramik/pics/spinbox-pressed-arrow-down.png Binary files differnew file mode 100644 index 000000000..71ce2ff98 --- /dev/null +++ b/kstyles/keramik/pics/spinbox-pressed-arrow-down.png diff --git a/kstyles/keramik/pics/spinbox-pressed-arrow-up.png b/kstyles/keramik/pics/spinbox-pressed-arrow-up.png Binary files differnew file mode 100644 index 000000000..7fd277c26 --- /dev/null +++ b/kstyles/keramik/pics/spinbox-pressed-arrow-up.png diff --git a/kstyles/keramik/pics/spinbox-pressed-down.png b/kstyles/keramik/pics/spinbox-pressed-down.png Binary files differnew file mode 100644 index 000000000..47ac06d41 --- /dev/null +++ b/kstyles/keramik/pics/spinbox-pressed-down.png diff --git a/kstyles/keramik/pics/spinbox-pressed-up.png b/kstyles/keramik/pics/spinbox-pressed-up.png Binary files differnew file mode 100644 index 000000000..ed499f6ef --- /dev/null +++ b/kstyles/keramik/pics/spinbox-pressed-up.png diff --git a/kstyles/keramik/pics/tab-bottom-active-bc.png b/kstyles/keramik/pics/tab-bottom-active-bc.png Binary files differnew file mode 100644 index 000000000..2cc3e597a --- /dev/null +++ b/kstyles/keramik/pics/tab-bottom-active-bc.png diff --git a/kstyles/keramik/pics/tab-bottom-active-bl.png b/kstyles/keramik/pics/tab-bottom-active-bl.png Binary files differnew file mode 100644 index 000000000..2f28a1cfa --- /dev/null +++ b/kstyles/keramik/pics/tab-bottom-active-bl.png diff --git a/kstyles/keramik/pics/tab-bottom-active-br.png b/kstyles/keramik/pics/tab-bottom-active-br.png Binary files differnew file mode 100644 index 000000000..8d086710a --- /dev/null +++ b/kstyles/keramik/pics/tab-bottom-active-br.png diff --git a/kstyles/keramik/pics/tab-bottom-active-cc.png b/kstyles/keramik/pics/tab-bottom-active-cc.png Binary files differnew file mode 100644 index 000000000..29fa285ef --- /dev/null +++ b/kstyles/keramik/pics/tab-bottom-active-cc.png diff --git a/kstyles/keramik/pics/tab-bottom-active-cl.png b/kstyles/keramik/pics/tab-bottom-active-cl.png Binary files differnew file mode 100644 index 000000000..54c629b55 --- /dev/null +++ b/kstyles/keramik/pics/tab-bottom-active-cl.png diff --git a/kstyles/keramik/pics/tab-bottom-active-cr.png b/kstyles/keramik/pics/tab-bottom-active-cr.png Binary files differnew file mode 100644 index 000000000..f36039005 --- /dev/null +++ b/kstyles/keramik/pics/tab-bottom-active-cr.png diff --git a/kstyles/keramik/pics/tab-bottom-inactive-bc.png b/kstyles/keramik/pics/tab-bottom-inactive-bc.png Binary files differnew file mode 100644 index 000000000..538b0e20e --- /dev/null +++ b/kstyles/keramik/pics/tab-bottom-inactive-bc.png diff --git a/kstyles/keramik/pics/tab-bottom-inactive-bl.png b/kstyles/keramik/pics/tab-bottom-inactive-bl.png Binary files differnew file mode 100644 index 000000000..14e04519d --- /dev/null +++ b/kstyles/keramik/pics/tab-bottom-inactive-bl.png diff --git a/kstyles/keramik/pics/tab-bottom-inactive-br.png b/kstyles/keramik/pics/tab-bottom-inactive-br.png Binary files differnew file mode 100644 index 000000000..79298a562 --- /dev/null +++ b/kstyles/keramik/pics/tab-bottom-inactive-br.png diff --git a/kstyles/keramik/pics/tab-bottom-inactive-cc.png b/kstyles/keramik/pics/tab-bottom-inactive-cc.png Binary files differnew file mode 100644 index 000000000..e7fbaf864 --- /dev/null +++ b/kstyles/keramik/pics/tab-bottom-inactive-cc.png diff --git a/kstyles/keramik/pics/tab-bottom-inactive-cl.png b/kstyles/keramik/pics/tab-bottom-inactive-cl.png Binary files differnew file mode 100644 index 000000000..9d3aaed8f --- /dev/null +++ b/kstyles/keramik/pics/tab-bottom-inactive-cl.png diff --git a/kstyles/keramik/pics/tab-bottom-inactive-cr.png b/kstyles/keramik/pics/tab-bottom-inactive-cr.png Binary files differnew file mode 100644 index 000000000..e873688c8 --- /dev/null +++ b/kstyles/keramik/pics/tab-bottom-inactive-cr.png diff --git a/kstyles/keramik/pics/tab-bottom-inactive-separator.png b/kstyles/keramik/pics/tab-bottom-inactive-separator.png Binary files differnew file mode 100644 index 000000000..525341543 --- /dev/null +++ b/kstyles/keramik/pics/tab-bottom-inactive-separator.png diff --git a/kstyles/keramik/pics/tab-top-active-cc.png b/kstyles/keramik/pics/tab-top-active-cc.png Binary files differnew file mode 100644 index 000000000..494659c77 --- /dev/null +++ b/kstyles/keramik/pics/tab-top-active-cc.png diff --git a/kstyles/keramik/pics/tab-top-active-cl.png b/kstyles/keramik/pics/tab-top-active-cl.png Binary files differnew file mode 100644 index 000000000..b369f9570 --- /dev/null +++ b/kstyles/keramik/pics/tab-top-active-cl.png diff --git a/kstyles/keramik/pics/tab-top-active-cr.png b/kstyles/keramik/pics/tab-top-active-cr.png Binary files differnew file mode 100644 index 000000000..6cbf4238e --- /dev/null +++ b/kstyles/keramik/pics/tab-top-active-cr.png diff --git a/kstyles/keramik/pics/tab-top-active-tc.png b/kstyles/keramik/pics/tab-top-active-tc.png Binary files differnew file mode 100644 index 000000000..44cf7d16d --- /dev/null +++ b/kstyles/keramik/pics/tab-top-active-tc.png diff --git a/kstyles/keramik/pics/tab-top-active-tl.png b/kstyles/keramik/pics/tab-top-active-tl.png Binary files differnew file mode 100644 index 000000000..437f95bc2 --- /dev/null +++ b/kstyles/keramik/pics/tab-top-active-tl.png diff --git a/kstyles/keramik/pics/tab-top-active-tr.png b/kstyles/keramik/pics/tab-top-active-tr.png Binary files differnew file mode 100644 index 000000000..74cbc48e3 --- /dev/null +++ b/kstyles/keramik/pics/tab-top-active-tr.png diff --git a/kstyles/keramik/pics/tab-top-inactive-cc.png b/kstyles/keramik/pics/tab-top-inactive-cc.png Binary files differnew file mode 100644 index 000000000..1c2f0d47f --- /dev/null +++ b/kstyles/keramik/pics/tab-top-inactive-cc.png diff --git a/kstyles/keramik/pics/tab-top-inactive-cl.png b/kstyles/keramik/pics/tab-top-inactive-cl.png Binary files differnew file mode 100644 index 000000000..3f4a23136 --- /dev/null +++ b/kstyles/keramik/pics/tab-top-inactive-cl.png diff --git a/kstyles/keramik/pics/tab-top-inactive-cr.png b/kstyles/keramik/pics/tab-top-inactive-cr.png Binary files differnew file mode 100644 index 000000000..477af0bc7 --- /dev/null +++ b/kstyles/keramik/pics/tab-top-inactive-cr.png diff --git a/kstyles/keramik/pics/tab-top-inactive-separator.png b/kstyles/keramik/pics/tab-top-inactive-separator.png Binary files differnew file mode 100644 index 000000000..fc03d5dbb --- /dev/null +++ b/kstyles/keramik/pics/tab-top-inactive-separator.png diff --git a/kstyles/keramik/pics/tab-top-inactive-tc.png b/kstyles/keramik/pics/tab-top-inactive-tc.png Binary files differnew file mode 100644 index 000000000..41eda7245 --- /dev/null +++ b/kstyles/keramik/pics/tab-top-inactive-tc.png diff --git a/kstyles/keramik/pics/tab-top-inactive-tl.png b/kstyles/keramik/pics/tab-top-inactive-tl.png Binary files differnew file mode 100644 index 000000000..114d9e99a --- /dev/null +++ b/kstyles/keramik/pics/tab-top-inactive-tl.png diff --git a/kstyles/keramik/pics/tab-top-inactive-tr.png b/kstyles/keramik/pics/tab-top-inactive-tr.png Binary files differnew file mode 100644 index 000000000..04a9019f8 --- /dev/null +++ b/kstyles/keramik/pics/tab-top-inactive-tr.png diff --git a/kstyles/keramik/pics/title-close-tiny.png b/kstyles/keramik/pics/title-close-tiny.png Binary files differnew file mode 100644 index 000000000..1e497547b --- /dev/null +++ b/kstyles/keramik/pics/title-close-tiny.png diff --git a/kstyles/keramik/pics/title-close.png b/kstyles/keramik/pics/title-close.png Binary files differnew file mode 100644 index 000000000..b9a7a8f45 --- /dev/null +++ b/kstyles/keramik/pics/title-close.png diff --git a/kstyles/keramik/pics/title-iconify.png b/kstyles/keramik/pics/title-iconify.png Binary files differnew file mode 100644 index 000000000..6c87e05f3 --- /dev/null +++ b/kstyles/keramik/pics/title-iconify.png diff --git a/kstyles/keramik/pics/title-maximize.png b/kstyles/keramik/pics/title-maximize.png Binary files differnew file mode 100644 index 000000000..6a47ce12d --- /dev/null +++ b/kstyles/keramik/pics/title-maximize.png diff --git a/kstyles/keramik/pics/title-restore.png b/kstyles/keramik/pics/title-restore.png Binary files differnew file mode 100644 index 000000000..12d48df42 --- /dev/null +++ b/kstyles/keramik/pics/title-restore.png diff --git a/kstyles/keramik/pics/titlebutton-pressed.png b/kstyles/keramik/pics/titlebutton-pressed.png Binary files differnew file mode 100644 index 000000000..23587dd2f --- /dev/null +++ b/kstyles/keramik/pics/titlebutton-pressed.png diff --git a/kstyles/keramik/pics/titlebutton.png b/kstyles/keramik/pics/titlebutton.png Binary files differnew file mode 100644 index 000000000..bb99c9b30 --- /dev/null +++ b/kstyles/keramik/pics/titlebutton.png diff --git a/kstyles/keramik/pics/toolbar-clk-bc.png b/kstyles/keramik/pics/toolbar-clk-bc.png Binary files differnew file mode 100644 index 000000000..4d8acdcde --- /dev/null +++ b/kstyles/keramik/pics/toolbar-clk-bc.png diff --git a/kstyles/keramik/pics/toolbar-clk-bl.png b/kstyles/keramik/pics/toolbar-clk-bl.png Binary files differnew file mode 100644 index 000000000..891f380ed --- /dev/null +++ b/kstyles/keramik/pics/toolbar-clk-bl.png diff --git a/kstyles/keramik/pics/toolbar-clk-br.png b/kstyles/keramik/pics/toolbar-clk-br.png Binary files differnew file mode 100644 index 000000000..d2493b18e --- /dev/null +++ b/kstyles/keramik/pics/toolbar-clk-br.png diff --git a/kstyles/keramik/pics/toolbar-clk-cc.png b/kstyles/keramik/pics/toolbar-clk-cc.png Binary files differnew file mode 100644 index 000000000..0ae970f6b --- /dev/null +++ b/kstyles/keramik/pics/toolbar-clk-cc.png diff --git a/kstyles/keramik/pics/toolbar-clk-cl.png b/kstyles/keramik/pics/toolbar-clk-cl.png Binary files differnew file mode 100644 index 000000000..12467b4e7 --- /dev/null +++ b/kstyles/keramik/pics/toolbar-clk-cl.png diff --git a/kstyles/keramik/pics/toolbar-clk-cr.png b/kstyles/keramik/pics/toolbar-clk-cr.png Binary files differnew file mode 100644 index 000000000..75bea2f4c --- /dev/null +++ b/kstyles/keramik/pics/toolbar-clk-cr.png diff --git a/kstyles/keramik/pics/toolbar-clk-tc.png b/kstyles/keramik/pics/toolbar-clk-tc.png Binary files differnew file mode 100644 index 000000000..fcd0e8cd2 --- /dev/null +++ b/kstyles/keramik/pics/toolbar-clk-tc.png diff --git a/kstyles/keramik/pics/toolbar-clk-tl.png b/kstyles/keramik/pics/toolbar-clk-tl.png Binary files differnew file mode 100644 index 000000000..13625cf8e --- /dev/null +++ b/kstyles/keramik/pics/toolbar-clk-tl.png diff --git a/kstyles/keramik/pics/toolbar-clk-tr.png b/kstyles/keramik/pics/toolbar-clk-tr.png Binary files differnew file mode 100644 index 000000000..1b8c8f33d --- /dev/null +++ b/kstyles/keramik/pics/toolbar-clk-tr.png diff --git a/kstyles/keramik/pics/vslider.png b/kstyles/keramik/pics/vslider.png Binary files differnew file mode 100644 index 000000000..e43857388 --- /dev/null +++ b/kstyles/keramik/pics/vslider.png diff --git a/kstyles/keramik/pixmaploader.cpp b/kstyles/keramik/pixmaploader.cpp new file mode 100644 index 000000000..b3c4a8c47 --- /dev/null +++ b/kstyles/keramik/pixmaploader.cpp @@ -0,0 +1,629 @@ +/* + Copyright (c) 2002 Malte Starostik <[email protected]> + (c) 2002,2003 Maksim Orlovich <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// $Id$ + +#include <qapplication.h> +#include <qbitmap.h> +#include <qglobal.h> +#include <qimage.h> +#include <qpainter.h> +#include <qpixmap.h> +#include <qpixmapcache.h> + +#include "pixmaploader.h" + + +#include "pixmaps.keramik" + +using namespace Keramik; + +PixmapLoader* PixmapLoader::s_instance = 0; + +PixmapLoader::PixmapLoader(): m_pixmapCache(327680, 2017) + +{ + m_pixmapCache.setAutoDelete(true); + + for (int c=0; c<256; c++) + clamp[c]=static_cast<unsigned char>(c); + + for (int c=256; c<540; c++) + clamp[c] = 255; + +} + +void PixmapLoader::clear() +{ + //m_cache.clear(); +} + +QImage* PixmapLoader::getDisabled(int name, const QColor& color, const QColor& back, bool blend) +{ + KeramikEmbedImage* edata = KeramikGetDbImage(name); + if (!edata) + return 0; + + //Like getColored, but desaturate a bit, and lower gamma.. + + //Create a real image... + QImage* img = new QImage(edata->width, edata->height, 32); + + + + //OK, now, fill it in, using the color.. + Q_UINT32 r, g,b; + Q_UINT32 i = qGray(color.rgb()); + r = (3*color.red()+i)>>2; + g = (3*color.green()+i)>>2; + b = (3*color.blue()+i)>>2; + + Q_UINT32 br = back.red(), bg = back.green(), bb = back.blue(); + + + if (edata->haveAlpha) + { + if (blend) + { + img->setAlphaBuffer(false); + Q_UINT32* write = reinterpret_cast< Q_UINT32* >(img->bits() ); + int size = img->width()*img->height() * 3; + + for (int pos = 0; pos < size; pos+=3) + { + Q_UINT32 scale = edata->data[pos]; + Q_UINT32 add = (edata->data[pos+1]*i+127)>>8; + Q_UINT32 alpha = edata->data[pos+2]; + Q_UINT32 destAlpha = 256 - alpha; + + Q_UINT32 rr = clamp[((r*scale+127)>>8) + add]; + Q_UINT32 rg = clamp[((g*scale+127)>>8) + add]; + Q_UINT32 rb = clamp[((b*scale+127)>>8) + add]; + + *write =qRgb(((rr*alpha+127)>>8) + ((br*destAlpha+127)>>8), + ((rg*alpha+127)>>8) + ((bg*destAlpha+127)>>8), + ((rb*alpha+127)>>8) + ((bb*destAlpha+127)>>8)); + + write++; + } + } + else + { + img->setAlphaBuffer(true); + Q_UINT32* write = reinterpret_cast< Q_UINT32* >(img->bits() ); + int size = img->width()*img->height() * 3; + + for (int pos = 0; pos < size; pos+=3) + { + Q_UINT32 scale = edata->data[pos]; + Q_UINT32 add = (edata->data[pos+1]*i+127)>>8; + Q_UINT32 alpha = edata->data[pos+2]; + + Q_UINT32 rr = clamp[((r*scale+127)>>8) + add]; + Q_UINT32 rg = clamp[((g*scale+127)>>8) + add]; + Q_UINT32 rb = clamp[((b*scale+127)>>8) + add]; + + *write =qRgba(rr, rg, rb, alpha); + + write++; + } + + } + } + else + { + img->setAlphaBuffer(false); + Q_UINT32* write = reinterpret_cast< Q_UINT32* >(img->bits() ); + int size = img->width()*img->height() * 2; + + for (int pos = 0; pos < size; pos+=2) + { + Q_UINT32 scale = edata->data[pos]; + Q_UINT32 add = (edata->data[pos+1]*i+127)>>8; + Q_UINT32 rr = clamp[((r*scale+127)>>8) + add]; + Q_UINT32 rg = clamp[((g*scale+127)>>8) + add]; + Q_UINT32 rb = clamp[((b*scale+127)>>8) + add]; + *write =qRgb(rr, rg, rb); + write++; + } + } + + return img; +} + +QImage* PixmapLoader::getColored(int name, const QColor& color, const QColor& back, bool blend) +{ + KeramikEmbedImage* edata = KeramikGetDbImage(name); + if (!edata) + return 0; + + //Create a real image... + QImage* img = new QImage(edata->width, edata->height, 32); + + //OK, now, fill it in, using the color.. + Q_UINT32 r, g,b; + r = color.red() + 2; + g = color.green() + 2; + b = color.blue() + 2; + +// int i = qGray(color.rgb()); + + Q_UINT32 br = back.red(), bg = back.green(), bb = back.blue(); + + if (edata->haveAlpha) + { + if (blend) + { + img->setAlphaBuffer(false); + + Q_UINT32* write = reinterpret_cast< Q_UINT32* >(img->bits() ); + int size = img->width()*img->height() * 3; + for (int pos = 0; pos < size; pos+=3) + { + Q_UINT32 scale = edata->data[pos]; + Q_UINT32 add = edata->data[pos+1]; + Q_UINT32 alpha = edata->data[pos+2]; + Q_UINT32 destAlpha = 256 - alpha; + + if (scale != 0) + add = add*5/4; + + Q_UINT32 rr = clamp[((r*scale+127)>>8) + add]; + Q_UINT32 rg = clamp[((g*scale+127)>>8) + add]; + Q_UINT32 rb = clamp[((b*scale+127)>>8) + add]; + + *write =qRgb(((rr*alpha+127)>>8) + ((br*destAlpha+127)>>8), + ((rg*alpha+127)>>8) + ((bg*destAlpha+127)>>8), + ((rb*alpha+127)>>8) + ((bb*destAlpha+127)>>8)); + + write++; + } + } + else + { + img->setAlphaBuffer(true); + + Q_UINT32* write = reinterpret_cast< Q_UINT32* >(img->bits() ); + int size = img->width()*img->height() * 3; + + for (int pos = 0; pos < size; pos+=3) + { + Q_UINT32 scale = edata->data[pos]; + Q_UINT32 add = edata->data[pos+1]; + Q_UINT32 alpha = edata->data[pos+2]; + if (scale != 0) + add = add*5/4; + + Q_UINT32 rr = clamp[((r*scale+127)>>8) + add]; + Q_UINT32 rg = clamp[((g*scale+127)>>8) + add]; + Q_UINT32 rb = clamp[((b*scale+127)>>8) + add]; + + *write =qRgba(rr, rg, rb, alpha); + write++; + } + } + } + else + { + img->setAlphaBuffer(false); + + Q_UINT32* write = reinterpret_cast< Q_UINT32* >(img->bits() ); + int size = img->width()*img->height() * 2; + + for (int pos = 0; pos < size; pos+=2) + { + Q_UINT32 scale = edata->data[pos]; + Q_UINT32 add = edata->data[pos+1]; + if (scale != 0) + add = add*5/4; + + Q_UINT32 rr = clamp[((r*scale+127)>>8) + add]; + Q_UINT32 rg = clamp[((g*scale+127)>>8) + add]; + Q_UINT32 rb = clamp[((b*scale+127)>>8) + add]; + + + *write =qRgb(rr, rg, rb); + write++; + } + } + + return img; +} + +QPixmap PixmapLoader::pixmap( int name, const QColor& color, const QColor& bg, bool disabled, bool blend ) +{ + return scale(name, 0, 0, color, bg, disabled, blend); +} + + +QPixmap PixmapLoader::scale( int name, int width, int height, const QColor& color, const QColor& bg, bool disabled, bool blend ) +{ + KeramikCacheEntry entry(name, color, bg, disabled, blend, width, height); + KeramikCacheEntry* cacheEntry; + + int key = entry.key(); + + if ((cacheEntry = m_pixmapCache.find(key, true))) + { + if (entry == *cacheEntry) //True match! + return *cacheEntry->m_pixmap; + else //Remove old entry in case of a conflict! + m_pixmapCache.remove(key); + } + + + QImage* img = 0; + QPixmap* result = 0; + + if (disabled) + img = getDisabled(name, color, bg, blend); + else + img = getColored(name, color, bg, blend); + + if (!img) + { + KeramikCacheEntry* toAdd = new KeramikCacheEntry(entry); + toAdd->m_pixmap = new QPixmap(); + m_pixmapCache.insert(key, toAdd, 16); + return QPixmap(); + } + + if (width == 0 && height == 0) + result = new QPixmap(*img); + else + result = new QPixmap(img->smoothScale( width ? width : img->width(), + height ? height: img->height())); + delete img; + + KeramikCacheEntry* toAdd = new KeramikCacheEntry(entry); + toAdd->m_pixmap = result; + + if (!m_pixmapCache.insert(key, toAdd, result->width()*result->height()*result->depth()/8)) { + QPixmap toRet = *result; + delete toAdd; + return toRet; + } + + return *result; +} + +QSize PixmapLoader::size( int id ) +{ + KeramikEmbedImage* edata = KeramikGetDbImage(id); + if (!edata) + return QSize(0,0); + return QSize(edata->width, edata->height); +} + +void TilePainter::draw( QPainter *p, int x, int y, int width, int height, const QColor& color, const QColor& bg, bool disabled, PaintMode mode ) +{ + if (mode == PaintTrivialMask) + { + p->fillRect(x, y, width, height, Qt::color1); + return; + } + + bool swBlend = (mode != PaintFullBlend); + unsigned int scaledColumns = 0, scaledRows = 0, lastScaledColumn = 0, lastScaledRow = 0; + int scaleWidth = width, scaleHeight = height; + + //scaleWidth, scaleHeight are calculated to contain the area available + //for all tiled and stretched columns/rows respectively. + //This is need to redistribute the area remaining after painting + //the "fixed" elements. We also keep track of the last col and row + //being scaled so rounding errors don't cause us to be short a pixel or so. + for ( unsigned int col = 0; col < columns(); ++col ) + if ( columnMode( col ) != Fixed ) + { + scaledColumns++; + lastScaledColumn = col; + } + else scaleWidth -= PixmapLoader::the().size (absTileName( col, 0 ) ).width(); + + for ( unsigned int row = 0; row < rows(); ++row ) + if ( rowMode( row ) != Fixed ) + { + scaledRows++; + lastScaledRow = row; + } + else scaleHeight -= PixmapLoader::the().size (absTileName( 0, row ) ).height(); + + + if ( scaleWidth < 0 ) scaleWidth = 0; + if ( scaleHeight < 0 ) scaleHeight = 0; + + + int ypos = y; + + //Center vertically if everything is fixed but there is extra room remaining + if ( scaleHeight && !scaledRows ) + ypos += scaleHeight / 2; + + for ( unsigned int row = 0; row < rows(); ++row ) + { + int xpos = x; + + //Center horizontally if extra space and no where to redistribute it to... + if ( scaleWidth && !scaledColumns ) + xpos += scaleWidth / 2; + + //If not fixed vertically, calculate our share of space available + //for scalable rows. + int h = rowMode( row ) == Fixed ? 0 : scaleHeight / scaledRows; + + //Redistribute any "extra" pixels to the last scaleable row. + if ( scaledRows && row == lastScaledRow ) + { + int allocatedEvenly = scaleHeight / scaledRows * scaledRows; + h += scaleHeight - allocatedEvenly; + } + + + //If we're fixed, get the height from the pixmap itself. + int realH = h ? h : PixmapLoader::the().size (absTileName( 0, row ) ).height(); + + //Skip non-fitting stretched/tiled rows, too. + if (rowMode( row ) != Fixed && h == 0) + continue; + + + //Set h to 0 to denote that we aren't scaling + if ( rowMode( row ) == Tiled ) + h = 0; + + for ( unsigned int col = 0; col < columns(); ++col ) + { + //Calculate width for rows that aren't fixed. + int w = columnMode( col ) == Fixed ? 0 : scaleWidth / scaledColumns; + + //Get the width of the pixmap.. + int tileW = PixmapLoader::the().size (absTileName( col, row ) ).width(); + + //Redistribute any extra pixels.. + if ( scaledColumns && col == lastScaledColumn ) w += scaleWidth - scaleWidth / scaledColumns * scaledColumns; + + //The width to use... + int realW = w ? w : tileW; + + //Skip any non-fitting stretched/tiled columns + if (columnMode( col ) != Fixed && w == 0) + continue; + + //Set w to 0 to denote that we aren't scaling + if ( columnMode( col ) == Tiled ) + w = 0; + + //If we do indeed have a pixmap.. + if ( tileW ) + { + //If scaling in either direction. + if ( w || h ) + { + if (mode != PaintMask) + { + p->drawTiledPixmap( xpos, ypos, realW, realH, scale( col, row, w, h, color, bg, disabled, swBlend ) ); + } + else + { + const QBitmap* mask = scale( col, row, w, h, color, bg, disabled, false ).mask(); + if (mask) + { + p->setBackgroundColor(Qt::color0); + p->setPen(Qt::color1); + p->drawTiledPixmap( xpos, ypos, realW, realH, *mask); + } + else + p->fillRect ( xpos, ypos, realW, realH, Qt::color1); + } + } + else + { + //Tiling (or fixed, the same really) + if (mode != PaintMask) + { + p->drawTiledPixmap( xpos, ypos, realW, realH, tile( col, row, color, bg, disabled, swBlend ) ); + } + else + { + const QBitmap* mask = tile( col, row, color, bg, disabled, false ).mask(); + if (mask) + { + p->setBackgroundColor(Qt::color0); + p->setPen(Qt::color1); + p->drawTiledPixmap( xpos, ypos, realW, realH, *mask); + } + else + p->fillRect ( xpos, ypos, realW, realH, Qt::color1); + + } + } + } + + //Advance horizontal position + xpos += realW; + } + + //Advance vertical position + ypos += realH; + } +} + +RectTilePainter::RectTilePainter( int name, + bool scaleH, bool scaleV, + unsigned int columns, unsigned int rows ) + : TilePainter( name ), + m_scaleH( scaleH ), + m_scaleV( scaleV ) +{ + m_columns = columns; + m_rows = rows; + + TileMode mh = m_scaleH ? Scaled : Tiled; + TileMode mv = m_scaleV ? Scaled : Tiled; + for (int c=0; c<4; c++) + { + if (c != 1) + colMde[c] = Fixed; + else + colMde[c] = mh; + } + + for (int c=0; c<4; c++) + { + if (c != 1) + rowMde[c] = Fixed; + else + rowMde[c] = mv; + } + +} + +int RectTilePainter::tileName( unsigned int column, unsigned int row ) const +{ + return row *3 + column; +} + +ActiveTabPainter::ActiveTabPainter( bool bottom ) + : RectTilePainter( bottom? keramik_tab_bottom_active: keramik_tab_top_active, false), + m_bottom( bottom ) +{ + m_rows = 2; + if (m_bottom) + { + rowMde[0] = rowMde[2] = rowMde[3] = Scaled; + rowMde[1] = Fixed; + } + else + { + rowMde[0] = rowMde[2] = rowMde[3] = Fixed; + rowMde[1] = Scaled; + } +} + +int ActiveTabPainter::tileName( unsigned int column, unsigned int row ) const +{ + if ( m_bottom ) + return RectTilePainter::tileName( column, row + 1 ); + return RectTilePainter::tileName( column, row ); +} + +InactiveTabPainter::InactiveTabPainter( Mode mode, bool bottom ) + : RectTilePainter( bottom? keramik_tab_bottom_inactive: keramik_tab_top_inactive, false), + m_mode( mode ), m_bottom( bottom ) +{ + m_rows = 2; + if (m_bottom) + { + rowMde[0] = Scaled; + rowMde[1] = Fixed; + } + else + { + rowMde[0] = Fixed; + rowMde[1] = Scaled; + } + + /** + Most fully, inactive tabs look like this: + L C R + / --- \ + | === | + + Where L,C, and R denote the tile positions. Of course, we don't want to draw all of the rounding for all the tabs. + + We want the left-most tab to look like this: + + L C + / -- + | == + + "Middle" tabs look like this: + + L C + | -- + | == + + And the right most tab looks like this: + + L C R + | -- \ + | == | + + So we have to vary the number of columns, and for everything but left-most tab, the L tab gets the special separator + tile. + */ + + Mode rightMost = QApplication::reverseLayout() ? First : Last; + m_columns = (m_mode == rightMost ? 3 : 2); +} + +int InactiveTabPainter::tileName( unsigned int column, unsigned int row ) const +{ + Mode leftMost = QApplication::reverseLayout() ? Last : First; + if ( column == 0 && m_mode != leftMost ) + return KeramikTileSeparator; + if ( m_bottom ) + return RectTilePainter::tileName( column, row + 1 ); + return RectTilePainter::tileName( column, row ); +} + +ScrollBarPainter::ScrollBarPainter( int type, int count, bool horizontal ) + : TilePainter( name( horizontal ) ), + m_type( type ), + m_count( count ), + m_horizontal( horizontal ) +{ + for (int c=0; c<5; c++) + { + if ( !m_horizontal || !( c % 2 ) ) colMde[c] = Fixed; + else colMde[c] = Tiled; + + if ( m_horizontal || !( c % 2 ) ) rowMde[c] = Fixed; + else rowMde[c] = Tiled; + } + + m_columns = m_horizontal ? m_count : 1; + m_rows = m_horizontal ? 1 : m_count; + +} + +int ScrollBarPainter::name( bool horizontal ) +{ + return horizontal? keramik_scrollbar_hbar: keramik_scrollbar_vbar; +} + +int ScrollBarPainter::tileName( unsigned int column, unsigned int row ) const +{ + unsigned int num = ( column ? column : row ) + 1; + if ( m_count == 5 ) + if ( num == 3 ) num = 4; + else if ( num == 4 ) num = 2; + else if ( num == 5 ) num = 3; + + return m_type + (num-1)*16; +} + +int SpinBoxPainter::tileName( unsigned int column, unsigned int ) const +{ + return column + 1; +} + +// vim: ts=4 sw=4 noet +// kate: indent-width 4; replace-tabs off; tab-width 4; space-indent off; diff --git a/kstyles/keramik/pixmaploader.h b/kstyles/keramik/pixmaploader.h new file mode 100644 index 000000000..28b2afd78 --- /dev/null +++ b/kstyles/keramik/pixmaploader.h @@ -0,0 +1,367 @@ +/* + Copyright (c) 2002 Malte Starostik <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// $Id$ + +#ifndef __pixmaploader_h__ +#define __pixmaploader_h__ + +#include <qintcache.h> +#include <qdict.h> +#include <qimage.h> + +class QPixmap; +class QImage; + +#include "keramikrc.h" + +namespace Keramik +{ + class PixmapLoader + { + public: + PixmapLoader(); + + QPixmap pixmap( int name, const QColor& color, const QColor& bg, + bool disabled = false, bool blend = true ); + + QPixmap scale( int name, int width, int height, const QColor& color, const QColor& bg, + bool disabled = false, bool blend = true ); + QSize size( int id ); + + void clear(); + + static PixmapLoader& the() + { + if (!s_instance) + s_instance = new PixmapLoader; + return *s_instance; + } + + static void release() + { + delete s_instance; + s_instance = 0; + } + + private: + + struct KeramikCacheEntry + { + int m_id; + int m_width; + int m_height; + QRgb m_colorCode; + QRgb m_bgCode; + bool m_disabled; + bool m_blended; + + QPixmap* m_pixmap; + + KeramikCacheEntry(int id, const QColor& color, const QColor& bg, bool disabled, + bool blended, int width, int height, QPixmap* pixmap = 0 ): + m_id(id), m_width(width), m_height(height), m_colorCode(color.rgb()),m_bgCode(bg.rgb()), + m_disabled(disabled), m_blended(blended), m_pixmap(pixmap) + {} + + int key() + { + return (int)m_disabled ^ (m_blended << 1) ^ (m_id<<2) ^ (m_width<<14) ^ (m_height<<24) ^ m_colorCode ^ (m_bgCode<<8); + } + + bool operator == (const KeramikCacheEntry& other) + { + return (m_id == other.m_id) && + (m_width == other.m_width) && + (m_height == other.m_height) && + (m_blended == other.m_blended) && + (m_bgCode == other.m_bgCode) && + (m_colorCode == other.m_colorCode) && + (m_disabled == other.m_disabled); + } + + ~KeramikCacheEntry() + { + delete m_pixmap; + } + }; + + + + QImage* getColored(int id, const QColor& color, const QColor& bg, bool blended); + QImage* getDisabled(int id, const QColor& color, const QColor& bg, bool blended); + QIntCache <KeramikCacheEntry> m_pixmapCache; + + + unsigned char clamp[540]; + + static PixmapLoader* s_instance; + }; + + class TilePainter + { + public: + TilePainter( int name ) : m_columns(1),m_rows(1),m_name( name ) {}; + virtual ~TilePainter() {}; + + enum PaintMode + { + PaintNormal, + PaintMask, + PaintFullBlend, + PaintTrivialMask + }; + + void draw( QPainter *p, int x, int y, int width, int height, const QColor& color, const QColor& bg, + bool disabled = false, PaintMode mode = PaintNormal ); + void draw( QPainter *p, const QRect& rect, const QColor& color, const QColor& bg, bool disabled = false, PaintMode mode = PaintNormal ) + { + draw( p, rect.x(), rect.y(), rect.width(), rect.height(), color, bg, disabled, mode ); + } + + protected: + enum TileMode { Fixed, Scaled, Tiled }; + + unsigned int columns() const { return m_columns; } + unsigned int rows() const { return m_rows; } + + /** + The idea behind all this stuff is that for performance reasons, we want to + use only integers to refer to widgets. So we give each widget a base ID + that's divisible by 256, and have all the various tiles be referred to as that ID + + some small number. + + genembed generates and assigns the base widget IDs, and maps various pixmaps suffixes + into the adjustment numbers; using that info it writes out the tables mapping + the IDs to pixmaps, and keramikrc.h, which provides nice symbolic constants for base IDs. + + When painting, however, we essentially represent the widget as a table, providing + fixed/tiled/stretched modes for each column and row. So to draw the widget knowing its + base ID, we need to know how many rows and columns there, what the scaling modes + are, and how to get to each of the tiles -- i.e. the tiles' offset from the base ID. + + The various painter subclasses simply fill in most of that info into the members + here during their construction, and implement the virtual tileName to get the offsets. + + Note that the IDs and offsets are separated since we can reuse the same code in many + cases by splitting the widget identify from tile identity (as there are many + different widgets that have the same or similar tile layout) + */ + virtual int tileName( unsigned int, unsigned int ) const { return 0; } + + TileMode columnMode( unsigned int col) const + { + return colMde[col]; + } + + TileMode rowMode( unsigned int row) const + { + return rowMde[row]; + } + + protected: + TileMode colMde[5], rowMde[5]; + unsigned int m_columns; + unsigned int m_rows; + private: + + int absTileName( unsigned int column, unsigned int row ) const + { + int name = tileName( column, row ); + return m_name + name; + } + + + QPixmap tile( unsigned int column, unsigned int row, const QColor& color, const QColor& bg, bool disabled, bool blend) + { return PixmapLoader::the().pixmap( absTileName( column, row ), color, bg, disabled, blend ); } + QPixmap scale( unsigned int column, unsigned int row, int width, int height, const QColor& color, const QColor& bg, + bool disabled, bool blend ) + { return PixmapLoader::the().scale( absTileName( column, row ), width, height, color, + bg, disabled, blend ); } + + int m_name; + + }; + + class ScaledPainter : public TilePainter + { + public: + enum Direction { Horizontal = 1, Vertical = 2, Both = Horizontal | Vertical }; + ScaledPainter( int name, Direction direction = Both ) + : TilePainter( name ), m_direction( direction ) + { + colMde[0] = ( m_direction & Horizontal ) ? Scaled : Tiled; + rowMde[0] = ( m_direction & Vertical ) ? Scaled : Tiled; + } + + virtual ~ScaledPainter() {}; + + private: + Direction m_direction; + }; + + class CenteredPainter : public TilePainter + { + public: + CenteredPainter( int name ) : TilePainter( name ) { + colMde[0] = colMde[1] = colMde[2] = colMde[3] = Fixed; + rowMde[0] = rowMde[1] = rowMde[2] = rowMde[3] = Fixed; + }; + virtual ~CenteredPainter() {}; + + protected: + }; + + class RectTilePainter : public TilePainter + { + public: + RectTilePainter( int name, + bool scaleH = true, bool scaleV = true, + unsigned int columns = 3, unsigned int rows = 3 ); + + virtual ~RectTilePainter() {}; + + protected: + virtual int tileName( unsigned int column, unsigned int row ) const; + private: + bool m_scaleH; + bool m_scaleV; + }; + + class RowPainter: public TilePainter + { + public: + RowPainter(int name): TilePainter(name) + { + colMde[0] = colMde[2] = Fixed; + colMde[1] = Tiled; + rowMde[0] = Scaled; + m_columns = 3; + } + + virtual ~RowPainter() {}; + protected: + virtual int tileName( unsigned int column, unsigned int /*row*/) const + { + return column + 3; //So can use cl, cc, cr + } + }; + + class ProgressBarPainter: public TilePainter + { + public: + ProgressBarPainter(int name, bool reverse): TilePainter(name), m_reverse(reverse) + { + //We use only of the tip bitmaps.. + if (reverse) + { + colMde[0] = Fixed; + colMde[1] = Tiled; + } + else + { + colMde[0] = Tiled; + colMde[1] = Fixed; + } + rowMde[0] = Scaled; + + m_columns = 2; + } + + virtual ~ProgressBarPainter() {}; + protected: + virtual int tileName( unsigned int column, unsigned int /*row*/ ) const + { + if (m_reverse) + { + return column + 3; //So can use cl, cc, cr + } + else + return column + 4; //So can use cl, cc, cr + we start from cc. + + } + + bool m_reverse; + }; + + + class ActiveTabPainter : public RectTilePainter + { + public: + ActiveTabPainter( bool bottom ); + virtual ~ActiveTabPainter() {}; + + protected: + virtual int tileName( unsigned int column, unsigned int row ) const; + + private: + bool m_bottom; + }; + + class InactiveTabPainter : public RectTilePainter + { + public: + enum Mode { First, Middle, Last }; + InactiveTabPainter( Mode mode, bool bottom ); + virtual ~InactiveTabPainter() {}; + + protected: + virtual int tileName( unsigned int column, unsigned int row ) const; + + private: + Mode m_mode; + bool m_bottom; + }; + + class ScrollBarPainter : public TilePainter + { + public: + ScrollBarPainter( int type, int count, bool horizontal ); + virtual ~ScrollBarPainter() {}; + + static int name( bool horizontal ); + + protected: + virtual int tileName( unsigned int column, unsigned int row ) const; + private: + int m_type; + int m_count; + bool m_horizontal; + }; + + class SpinBoxPainter : public TilePainter + { + public: + SpinBoxPainter() : TilePainter( keramik_spinbox ) { + colMde[0] = colMde[2] = Fixed; + colMde[1] = Scaled; + rowMde[0]=rowMde[1]=rowMde[2] = Scaled; + m_columns = 3; + }; + virtual ~SpinBoxPainter() {}; + + protected: + virtual int tileName( unsigned int column, unsigned int row ) const; + }; +} + +#endif + +// vim: ts=4 sw=4 noet +// kate: indent-width 4; replace-tabs off; tab-width 4; diff --git a/kstyles/klegacy/Makefile.am b/kstyles/klegacy/Makefile.am new file mode 100644 index 000000000..872ccd75d --- /dev/null +++ b/kstyles/klegacy/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES= $(all_includes) + +noinst_HEADERS = klegacystyle.h +lib_LTLIBRARIES = klegacystyle.la +klegacystyle_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +klegacystyle_la_LIBADD = $(LIB_KDECORE) +klegacystyle_la_SOURCES = klegacystyle.cpp plugin.cpp +klegacystyle_la_METASOURCES = AUTO diff --git a/kstyles/klegacy/klegacystyle.cpp b/kstyles/klegacy/klegacystyle.cpp new file mode 100644 index 000000000..e3796a079 --- /dev/null +++ b/kstyles/klegacy/klegacystyle.cpp @@ -0,0 +1,3366 @@ +/* + + Copyright (c) 2000 KDE Project + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + */ + +#include "klegacystyle.h" +#include "klegacystyle.moc" +#include <klocale.h> +#include <kiconloader.h> + +#define INCLUDE_MENUITEM_DEF +#include <qapplication.h> +#include <qbitmap.h> +#include <qbuttongroup.h> +#include <qcanvas.h> +#include <qcheckbox.h> +#include <qcolor.h> +#include <qcolordialog.h> +#include <qcombobox.h> +#include <qdial.h> +#include <qdialog.h> +#include <qdict.h> +#include <qfile.h> +#include <qfiledialog.h> +#include <qfileinfo.h> +#include <qfont.h> +#include <qfontdialog.h> +#include <qframe.h> +#include <qguardedptr.h> +#include <qgrid.h> +#include <qgroupbox.h> +#include <qhbox.h> +#include <qhbuttongroup.h> +#include <qheader.h> +#include <qhgroupbox.h> +#include <qiconview.h> +#include <qimage.h> +#include <qinputdialog.h> +#include <qintdict.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qlcdnumber.h> +#include <qlineedit.h> +#include <qptrlist.h> +#include <qlistbox.h> +#include <qlistview.h> +#include <qmainwindow.h> +#include <qmenubar.h> +#include <qmenudata.h> +#include <qmessagebox.h> +#include <qmultilineedit.h> +#include <qobjectlist.h> +#include <qpainter.h> +#include <qpixmap.h> +#include <qpixmapcache.h> +#include <qpopupmenu.h> +#include <qprintdialog.h> +#include <qprogressbar.h> +#include <qprogressdialog.h> +#include <qpushbutton.h> +#include <qradiobutton.h> +#include <qregexp.h> +#include <qscrollbar.h> +#include <qscrollview.h> +#include <qsemimodal.h> +#include <qsizegrip.h> +#include <qslider.h> +#include <qspinbox.h> +#include <qsplitter.h> +#include <qstatusbar.h> +#include <qstring.h> +#include <qtabbar.h> +#include <qtabdialog.h> +#include <qtableview.h> +#include <qtabwidget.h> +#include <qtextbrowser.h> +#include <qtextstream.h> +#include <qtextview.h> +#include <qtoolbar.h> +#include <qtoolbutton.h> +#include <qtooltip.h> +#include <qvbox.h> +#include <qvbuttongroup.h> +#include <qvgroupbox.h> +#include <qwidget.h> +#include <qwidgetstack.h> +#include <qwizard.h> +#include <qworkspace.h> + +#include <stdlib.h> +#include <unistd.h> +#include <limits.h> +#include <sys/types.h> + +// forward declaration of classes +class KLegacyBorder; +class KLegacyStyleData; +class KLegacyImageData; +class GtkObject; + +// declaration of hidden functions +typedef void (QStyle::*QDrawMenuBarItemImpl) (QPainter *, int, int, int, int, + QMenuItem *, QColorGroup &, bool, bool); +extern QDrawMenuBarItemImpl qt_set_draw_menu_bar_impl(QDrawMenuBarItemImpl impl); + +// the addresses of the integers are used to place things in the +// style data dict +static int listviewitem_ptr = 0; +static int listboxitem_ptr = 1; +static int menuitem_ptr = 2; +static int separator_ptr = 3; +static int arrow_ptr = 4; +static int whatsthis_ptr = 5; +static int checkmenuitem_ptr = 6; +static int radiomenuitem_ptr = 7; +static int eventbox_ptr = 8; + +// a QImage cache, since we need to resize some images to different sizes, we +// will cache them, to save the overhead of loading the image from disk each +// time it's needed +static const int imageCacheSize = 61; +static QDict<QImage> *imageCache = 0; + + +class KLegacy { +public: + enum Function { Box = 1, FlatBox, Extension, Check, Option, + HLine, VLine, BoxGap, Slider, Tab, Arrow, Handle, FShadow, Focus }; + enum State { Normal = 1, Prelight, Active, Insensitive, Selected }; + enum Shadow { NoShadow = 0, In, Out, EtchedIn, EtchedOut }; + enum GapSide { Left = 1, Right, Top, Bottom }; +}; + + +class KLegacyBorder : public KLegacy { +private: + int l, r, t, b; + + +public: + KLegacyBorder(int ll = 0, int rr = 0, int tt = 0, int bb = 0) + : l(ll), r(rr), t(tt), b(bb) + { } + + KLegacyBorder(const KLegacyBorder &br) + : l(br.l), r(br.r), t(br.t), b(br.b) + { } + + inline int left(void) const + { return l; } + inline int right(void) const + { return r; } + inline int top(void) const + { return t; } + inline int bottom(void) const + { return b; } + + inline void setLeft(int ll) + { l = ll; } + inline void setRight(int rr) + { r = rr; } + inline void setTop(int tt) + { t = tt; } + inline void setBottom(int bb) + { b = bb; } +}; + + +struct KLegacyImageDataKeyField { + Q_INT8 function : 8; + Q_INT8 state : 8; + Q_INT8 shadow : 4; + Q_INT8 orientation : 4; + Q_INT8 arrowDirection : 4; + Q_INT8 gapSide : 4; +}; + + +union KLegacyImageDataKey { + KLegacyImageDataKeyField data; + long cachekey; +}; + + +class KLegacyImageData : public KLegacy { +public: + KLegacyImageDataKey key; + + QString file; + QString detail; + QString overlayFile; + QString gapFile; + QString gapStartFile; + QString gapEndFile; + + KLegacyBorder border; + KLegacyBorder overlayBorder; + KLegacyBorder gapBorder; + KLegacyBorder gapStartBorder; + KLegacyBorder gapEndBorder; + + bool recolorable; + bool stretch; + bool overlayStretch; + + KLegacyImageData() + : recolorable(false), + stretch(false), + overlayStretch(false) + { key.cachekey = 0; } +}; + + +class KLegacyStyleData : public KLegacy { +public: + // name of this style + QString name; + + // font to use + QFont *fn; + + // list of image datas (which tell us how to draw things) + QList<KLegacyImageData> imageList; + + // background, foreground and base colors for the 5 widget + //states that Gtk defines + QColor back[5], fore[5], base[5]; + + // reference count + int ref; + + KLegacyStyleData() + : fn(0), ref(0) + { + // have the imageList delete the items it holds when it's deleted + imageList.setAutoDelete(true); + } +}; + + +class GtkObject : public QObject { +private: + KLegacyStyleData *d; + + friend class KLegacyStylePrivate; + + +public: + GtkObject(GtkObject *parent, const char *name) + : QObject(parent, name) + { d = 0; } + + GtkObject *find(QRegExp &) const; + + QColor backColor(KLegacy::State); + QColor baseColor(KLegacy::State); + QColor foreColor(KLegacy::State); + + QFont *font(); + + inline QString styleName() + { return styleData()->name; } + + KLegacyStyleData *styleData(); + KLegacyImageData *getImageData(KLegacyImageDataKey, + const QString & = QString::null); + + QPixmap *draw(KLegacyImageDataKey, int, int, const QString & = QString::null); + QPixmap *draw(KLegacyImageData *, int, int); +}; + + +static QPixmap *drawImage(QImage *image, int width, int height, + KLegacyBorder border, bool scale) +{ + if ((! image) || (image->isNull()) || (width < 1) || (height < 1)) { + return (QPixmap *) 0; + } + + QPixmap *pixmap = new QPixmap(width, height); + + if (scale) { + if (width < 2) width = 2; + if (height < 2) height = 2; + + int x[3], y[3], w[3], h[3], x2[3], y2[3], w2[3], h2[3]; + + // left + x[0] = x2[0] = 0; + w[0] = (border.left() < 1) ? 1 : border.left(); + + // middle + x[1] = border.left(); + w[1] = image->width() - border.left() - border.right(); + if (w[1] < 1) w[1] = 1; + + // right + x[2] = image->width() - border.right(); + w[2] = (border.right() < 1) ? 1 : border.right(); + if (x[2] < 0) x[2] = 0; + + if ((border.left() + border.right()) > width) { + // left + x2[0] = 0; + w2[0] = (width / 2) + 1; + + // middle + x2[1] = w2[0] - 1; + w2[1] = 1; + + // right + x2[2] = x2[1]; + w2[2] = w2[0]; + } else { + // left + x2[0] = 0; + w2[0] = border.left(); + + // middle + x2[1] = w2[0]; + w2[1] = width - border.left() - border.right() + 1; + + // right + x2[2] = width - border.right(); + w2[2] = border.right(); + } + + // top + y[0] = 0; + h[0] = (border.top() < 1) ? 1 : border.top(); + + // middle + y[1] = border.top(); + h[1] = image->height() - border.top() - border.bottom(); + if (h[1] < 1) h[1] = 1; + + // bottom + y[2] = image->height() - border.bottom(); + h[2] = (border.bottom() < 1) ? 1 : border.bottom(); + if (y[2] < 0) y[2] = 0; + + if ((border.top() + border.bottom()) > height) { + // left + y2[0] = 0; + h2[0] = height / 2; + + // middle + y2[1] = h2[0]; + h2[1] = 1; + + // right + y2[2] = y2[1]; + h2[2] = h2[0]; + } else { + // left + y2[0] = 0; + h2[0] = border.top(); + + // middle + y2[1] = h2[0]; + h2[1] = height - border.top() - border.bottom() + 1; + + // bottom + y2[2] = height - border.bottom(); + h2[2] = border.bottom(); + } + + // draw the image + bool mask = image->hasAlphaBuffer(); + QBitmap bm(width, height); + bm.fill(Qt::color1); + + QImage nimage[3][3]; + int xx = -1, yy = -1; + while (++yy < 3) { + xx = -1; + while (++xx < 3) { + nimage[yy][xx] = image->copy(x[xx], y[yy], w[xx], h[yy]); + + if (nimage[yy][xx].isNull()) continue; + + if ((w[xx] != w2[xx]) || (h[yy] != h2[yy])) + nimage[yy][xx] = nimage[yy][xx].smoothScale(w2[xx], h2[yy]); + + if (nimage[yy][xx].isNull()) continue; + + bitBlt(pixmap, x2[xx], y2[yy], &nimage[yy][xx], + 0, 0, w2[xx], h2[yy], Qt::CopyROP); + + if (mask) { + QImage am = nimage[yy][xx].createAlphaMask(); + bitBlt(&bm, x2[xx], y2[yy], &am, + 0, 0, w2[xx], h2[yy], Qt::CopyROP); + } + } + } + + if (mask) + pixmap->setMask(bm); + } else { + for (int y = 0; y < height; y += image->height()) + for (int x = 0; x < width; x += image->width()) + bitBlt(pixmap, x, y, image, 0, 0, -1, -1, Qt::CopyROP); + + if (image->hasAlphaBuffer()) { + QImage mask = image->createAlphaMask(); + + if (! mask.isNull() && mask.depth() == 1) { + QBitmap bm(width, height); + bm.fill(Qt::color1); + bm = mask; + pixmap->setMask(bm); + } + } + } + + return pixmap; +} + + +// Generate an object tree for all the known Gtk widgets... +// returns a pointer to the bottom of the tree +static GtkObject *initialize(QPtrDict<GtkObject> &dict) { + // + // auto generated stuff from : + // -- + // #!/usr/bin/perl -w + // + // foreach $line ( <STDIN> ) { + // chomp $line; + // $line =~ s/[^\sa-zA-Z0-9]/ /g; + // $line =~ /^(\s*)(\S*)/; + // $prefixlength = length $1; + // $classname = $2; + // $class{$prefixlength} = $classname; + // $prefixlength--; + // while( $prefixlength >= 0 && !defined($class{$prefixlength}) ) { + // $prefixlength--; + // } + // $parent = $class{$prefixlength}; + // $parent = "0" if ( $parent eq $classname ); + // + // # for GtkBin: + // # myGtkBin = new GtkObject( myGtkWidget, "GtkBin" ); + // + // print "GtkObject * my$classname = + // new GtkObject( my$parent, \"$classname\" );\n"; + // } + // -- + + GtkObject * myGtkObject = + new GtkObject( 0, "GtkObject" ); + GtkObject * myGtkWidget = + new GtkObject( myGtkObject, "GtkWidget" ); + GtkObject * myGtkMisc = + new GtkObject( myGtkWidget, "GtkMisc" ); + GtkObject * myGtkLabel = + new GtkObject( myGtkMisc, "GtkLabel" ); + // GtkObject * myGtkAccelLabel = + // new GtkObject( myGtkLabel, "GtkAccelLabel" ); + GtkObject * myGtkTipsQuery = + new GtkObject( myGtkLabel, "GtkTipsQuery" ); + GtkObject * myGtkArrow = + new GtkObject( myGtkMisc, "GtkArrow" ); + // GtkObject * myGtkImage = + // new GtkObject( myGtkMisc, "GtkImage" ); + // GtkObject * myGtkPixmap = + // new GtkObject( myGtkMisc, "GtkPixmap" ); + GtkObject * myGtkContainer = + new GtkObject( myGtkWidget, "GtkContainer" ); + GtkObject * myGtkBin = + new GtkObject( myGtkContainer, "GtkBin" ); + // GtkObject * myGtkAlignment = + // new GtkObject( myGtkBin, "GtkAlignment" ); + GtkObject * myGtkFrame = + new GtkObject( myGtkBin, "GtkFrame" ); + // GtkObject * myGtkAspectFrame = + // new GtkObject( myGtkFrame, "GtkAspectFrame" ); + GtkObject * myGtkButton = + new GtkObject( myGtkBin, "GtkButton" ); + GtkObject * myGtkToggleButton = + new GtkObject( myGtkButton, "GtkToggleButton" ); + GtkObject * myGtkCheckButton = + new GtkObject( myGtkToggleButton, "GtkCheckButton" ); + GtkObject * myGtkRadioButton = + new GtkObject( myGtkCheckButton, "GtkRadioButton" ); + GtkObject * myGtkOptionMenu = + new GtkObject( myGtkButton, "GtkOptionMenu" ); + GtkObject * myGtkItem = + new GtkObject( myGtkBin, "GtkItem" ); + GtkObject * myGtkMenuItem = + new GtkObject( myGtkItem, "GtkMenuItem" ); + GtkObject * myGtkCheckMenuItem = + new GtkObject( myGtkMenuItem, "GtkCheckMenuItem" ); + GtkObject * myGtkRadioMenuItem = + new GtkObject( myGtkCheckMenuItem, "GtkRadioMenuItem" ); + // GtkObject * myGtkTearoffMenuItem = + // new GtkObject( myGtkMenuItem, "GtkTearoffMenuItem" ); + GtkObject * myGtkListItem = + new GtkObject( myGtkItem, "GtkListItem" ); + GtkObject * myGtkTreeItem = + new GtkObject( myGtkItem, "GtkTreeItem" ); + GtkObject * myGtkWindow = + new GtkObject( myGtkBin, "GtkWindow" ); + GtkObject * myGtkColorSelectionDialog = + new GtkObject( myGtkWindow, "GtkColorSelectionDialog" ); + GtkObject * myGtkDialog = + new GtkObject( myGtkWindow, "GtkDialog" ); + GtkObject * myGtkInputDialog = + new GtkObject( myGtkDialog, "GtkInputDialog" ); + // GtkObject * myGtkDrawWindow = + // new GtkObject( myGtkWindow, "GtkDrawWindow" ); + GtkObject * myGtkFileSelection = + new GtkObject( myGtkWindow, "GtkFileSelection" ); + GtkObject * myGtkFontSelectionDialog = + new GtkObject( myGtkWindow, "GtkFontSelectionDialog" ); + // GtkObject * myGtkPlug = + // new GtkObject( myGtkWindow, "GtkPlug" ); + GtkObject * myGtkEventBox = + new GtkObject( myGtkBin, "GtkEventBox" ); + // GtkObject * myGtkHandleBox = + // new GtkObject( myGtkBin, "GtkHandleBox" ); + // GtkObject * myGtkScrolledWindow = + // new GtkObject( myGtkBin, "GtkScrolledWindow" ); + GtkObject * myGtkViewport = + new GtkObject( myGtkBin, "GtkViewport" ); + GtkObject * myGtkBox = + new GtkObject( myGtkContainer, "GtkBox" ); + GtkObject * myGtkButtonBox = + new GtkObject( myGtkBox, "GtkButtonBox" ); + GtkObject * myGtkHButtonBox = + new GtkObject( myGtkButtonBox, "GtkHButtonBox" ); + GtkObject * myGtkVButtonBox = + new GtkObject( myGtkButtonBox, "GtkVButtonBox" ); + GtkObject * myGtkVBox = + new GtkObject( myGtkBox, "GtkVBox" ); + // GtkObject * myGtkColorSelection = + // new GtkObject( myGtkVBox, "GtkColorSelection" ); + // GtkObject * myGtkGammaCurve = + // new GtkObject( myGtkVBox, "GtkGammaCurve" ); + GtkObject * myGtkHBox = + new GtkObject( myGtkBox, "GtkHBox" ); + + + // CHANGED! It seems that the gtk optionmenu and gtk combobox aren't related, + // but in Qt they are the same class... so we have changed gth GtkCombo to inherit + // from GtkOptionMenu (so that Qt comboboxes look like the optionmenus by default) + GtkObject * myGtkCombo = + new GtkObject( myGtkOptionMenu, "GtkCombo" ); + + + GtkObject * myGtkStatusbar = + new GtkObject( myGtkHBox, "GtkStatusbar" ); + GtkObject * myGtkCList = + new GtkObject( myGtkContainer, "GtkCList" ); + GtkObject * myGtkCTree = + new GtkObject( myGtkCList, "GtkCTree" ); + // GtkObject * myGtkFixed = + // new GtkObject( myGtkContainer, "GtkFixed" ); + GtkObject * myGtkNotebook = + new GtkObject( myGtkContainer, "GtkNotebook" ); + // GtkObject * myGtkFontSelection = + // new GtkObject( myGtkNotebook, "GtkFontSelection" ); + GtkObject * myGtkPaned = + new GtkObject( myGtkContainer, "GtkPaned" ); + // GtkObject * myGtkHPaned = + // new GtkObject( myGtkPaned, "GtkHPaned" ); + // GtkObject * myGtkVPaned = + // new GtkObject( myGtkPaned, "GtkVPaned" ); + // GtkObject * myGtkLayout = + // new GtkObject( myGtkContainer, "GtkLayout" ); + // GtkObject * myGtkList = + // new GtkObject( myGtkContainer, "GtkList" ); + GtkObject * myGtkMenuShell = + new GtkObject( myGtkContainer, "GtkMenuShell" ); + GtkObject * myGtkMenuBar = + new GtkObject( myGtkMenuShell, "GtkMenuBar" ); + GtkObject * myGtkMenu = + new GtkObject( myGtkMenuShell, "GtkMenu" ); + // GtkObject * myGtkPacker = + // new GtkObject( myGtkContainer, "GtkPacker" ); + // GtkObject * myGtkSocket = + // new GtkObject( myGtkContainer, "GtkSocket" ); + GtkObject * myGtkTable = + new GtkObject( myGtkContainer, "GtkTable" ); + GtkObject * myGtkToolbar = + new GtkObject( myGtkContainer, "GtkToolbar" ); + // GtkObject * myGtkTree = + // new GtkObject( myGtkContainer, "GtkTree" ); + // GtkObject * myGtkCalendar = + // new GtkObject( myGtkWidget, "GtkCalendar" ); + GtkObject * myGtkDrawingArea = + new GtkObject( myGtkWidget, "GtkDrawingArea"); + // GtkObject * myGtkCurve = + // new GtkObject( myGtkDrawingArea, "GtkCurve" ); + GtkObject * myGtkEditable = + new GtkObject( myGtkWidget, "GtkEditable" ); + GtkObject * myGtkEntry = + new GtkObject( myGtkEditable, "GtkEntry" ); + GtkObject * myGtkSpinButton = + new GtkObject( myGtkEntry, "GtkSpinButton" ); + GtkObject * myGtkText = + new GtkObject( myGtkEditable, "GtkText" ); + GtkObject * myGtkRuler = + new GtkObject( myGtkWidget, "GtkRuler" ); + // GtkObject * myGtkHRuler = + // new GtkObject( myGtkRuler, "GtkHRuler" ); + // GtkObject * myGtkVRuler = + // new GtkObject( myGtkRuler, "GtkVRuler" ); + GtkObject * myGtkRange = + new GtkObject( myGtkWidget, "GtkRange" ); + GtkObject * myGtkScale = + new GtkObject( myGtkRange, "GtkScale" ); + // GtkObject * myGtkHScale = + // new GtkObject( myGtkScale, "GtkHScale" ); + // GtkObject * myGtkVScale = + // new GtkObject( myGtkScale, "GtkVScale" ); + GtkObject * myGtkScrollbar = + new GtkObject( myGtkRange, "GtkScrollbar" ); + // GtkObject * myGtkHScrollbar = + // new GtkObject( myGtkScrollbar, "GtkHScrollbar" ); + // GtkObject * myGtkVScrollbar = + // new GtkObject( myGtkScrollbar, "GtkVScrollbar" ); + GtkObject * myGtkSeparator = + new GtkObject( myGtkWidget, "GtkSeparator" ); + // GtkObject * myGtkHSeparator = + // new GtkObject( myGtkSeparator, "GtkHSeparator" ); + // GtkObject * myGtkVSeparator = + // new GtkObject( myGtkSeparator, "GtkVSeparator" ); + // GtkObject * myGtkPreview = + // new GtkObject( myGtkWidget, "GtkPreview" ); + GtkObject * myGtkProgress = + new GtkObject( myGtkWidget, "GtkProgress" ); + GtkObject * myGtkProgressBar = + new GtkObject( myGtkProgress, "GtkProgressBar" ); + //GtkObject * myGtkData = + // new GtkObject( myGtkObject, "GtkData" ); + // GtkObject * myGtkAdjustment = + // new GtkObject( myGtkData, "GtkAdjustment" ); + // GtkObject * myGtkTooltips = + // new GtkObject( myGtkData, "GtkTooltips" ); + // GtkObject * myGtkItemFactory = + // new GtkObject( myGtkObject, "GtkItemFactory" ); + + // Insert the above Gtk widgets into a dict, using meta data pointers for + // the different widgets in Qt + // + // verify with: + // -- + // egrep "::staticMetaObject\(\)$" **/*.cpp | fmt -1 | grep :: | + // sort | uniq > meta + //-- + + dict.insert(QButton::staticMetaObject(), myGtkButton); + dict.insert(QButtonGroup::staticMetaObject(), myGtkButtonBox); + dict.insert(QCanvas::staticMetaObject(), myGtkDrawingArea); + dict.insert(QCanvasView::staticMetaObject(), myGtkDrawingArea); + dict.insert(QCheckBox::staticMetaObject(), myGtkCheckButton); + dict.insert(QColorDialog::staticMetaObject(), myGtkColorSelectionDialog); + dict.insert(QComboBox::staticMetaObject(), myGtkCombo); + dict.insert(QDial::staticMetaObject(), myGtkWidget); + dict.insert(QDialog::staticMetaObject(), myGtkDialog); + dict.insert(QFileDialog::staticMetaObject(), myGtkFileSelection); + dict.insert(QFontDialog::staticMetaObject(), myGtkFontSelectionDialog); + dict.insert(QFrame::staticMetaObject(), myGtkFrame); + dict.insert(QGrid::staticMetaObject(), myGtkFrame); + dict.insert(QGroupBox::staticMetaObject(), myGtkBox); + dict.insert(QHBox::staticMetaObject(), myGtkHBox); + dict.insert(QHButtonGroup::staticMetaObject(), myGtkHButtonBox); + dict.insert(QHGroupBox::staticMetaObject(), myGtkHBox); + dict.insert(QHeader::staticMetaObject(), myGtkRuler); + dict.insert(QIconView::staticMetaObject(), myGtkCTree); + dict.insert(QInputDialog::staticMetaObject(), myGtkInputDialog); + dict.insert(QLCDNumber::staticMetaObject(), myGtkFrame); + dict.insert(QLabel::staticMetaObject(), myGtkLabel); + dict.insert(QLineEdit::staticMetaObject(), myGtkEntry); + dict.insert(QListBox::staticMetaObject(), myGtkCList); + dict.insert(QListView::staticMetaObject(), myGtkCTree); + dict.insert(QMainWindow::staticMetaObject(), myGtkWindow); + dict.insert(QMenuBar::staticMetaObject(), myGtkMenuBar); + dict.insert(QMessageBox::staticMetaObject(), myGtkDialog); + dict.insert(QMultiLineEdit::staticMetaObject(), myGtkText); + dict.insert(QPopupMenu::staticMetaObject(), myGtkMenu); + dict.insert(QPrintDialog::staticMetaObject(), myGtkDialog); + dict.insert(QProgressBar::staticMetaObject(), myGtkProgressBar); + dict.insert(QProgressDialog::staticMetaObject(), myGtkDialog); + dict.insert(QPushButton::staticMetaObject(), myGtkButton); + dict.insert(QRadioButton::staticMetaObject(), myGtkRadioButton); + dict.insert(QScrollBar::staticMetaObject(), myGtkScrollbar); + dict.insert(QScrollView::staticMetaObject(), myGtkViewport); + dict.insert(QSemiModal::staticMetaObject(), myGtkDialog); + dict.insert(QSizeGrip::staticMetaObject(), myGtkWidget); + dict.insert(QSlider::staticMetaObject(), myGtkScale); + dict.insert(QSpinBox::staticMetaObject(), myGtkSpinButton); + dict.insert(QSplitter::staticMetaObject(), myGtkPaned); + dict.insert(QStatusBar::staticMetaObject(), myGtkStatusbar); + dict.insert(QTabBar::staticMetaObject(), myGtkNotebook); + dict.insert(QTabDialog::staticMetaObject(), myGtkNotebook); + dict.insert(QTabWidget::staticMetaObject(), myGtkNotebook); + dict.insert(QTableView::staticMetaObject(), myGtkTable); + dict.insert(QTextBrowser::staticMetaObject(), myGtkText); + dict.insert(QTextView::staticMetaObject(), myGtkText); + dict.insert(QToolBar::staticMetaObject(), myGtkToolbar); + dict.insert(QToolButton::staticMetaObject(), myGtkButton); + dict.insert(QVBox::staticMetaObject(), myGtkVBox); + dict.insert(QVButtonGroup::staticMetaObject(), myGtkVButtonBox); + dict.insert(QVGroupBox::staticMetaObject(), myGtkVBox); + dict.insert(QWidget::staticMetaObject(), myGtkWidget); + dict.insert(QWidgetStack::staticMetaObject(), myGtkWidget); + dict.insert(QWizard::staticMetaObject(), myGtkWindow); + dict.insert(QWorkspace::staticMetaObject(), myGtkWindow); + + // stuff that we don't have meta data for, but want to know about + dict.insert(&listboxitem_ptr, myGtkListItem); + dict.insert(&listviewitem_ptr, myGtkTreeItem); + dict.insert(&menuitem_ptr, myGtkMenuItem); + dict.insert(&separator_ptr, myGtkSeparator); + dict.insert(&arrow_ptr, myGtkArrow); + dict.insert(&whatsthis_ptr, myGtkTipsQuery); + dict.insert(&checkmenuitem_ptr, myGtkCheckMenuItem); + dict.insert(&radiomenuitem_ptr, myGtkRadioMenuItem); + dict.insert(&eventbox_ptr, myGtkEventBox); + + return myGtkObject; +} + + +KLegacyImageData *GtkObject::getImageData(KLegacyImageDataKey key, const QString &detail) { + KLegacyImageData *imagedata = 0; + + if (styleData()) { + QListIterator<KLegacyImageData> it(styleData()->imageList); + + while ((imagedata = it.current()) != 0) { + ++it; + + if ((((imagedata->key.data.function != 0) && + (imagedata->key.data.function == key.data.function)) || + (imagedata->key.data.function == 0)) && + + (((imagedata->key.data.state != 0) && + (imagedata->key.data.state == key.data.state)) || + (imagedata->key.data.state == 0)) && + + (((imagedata->key.data.shadow != 0) && + (imagedata->key.data.shadow == key.data.shadow)) || + (imagedata->key.data.shadow == 0)) && + + (((imagedata->key.data.orientation != 0) && + (imagedata->key.data.orientation == key.data.orientation)) || + (imagedata->key.data.orientation == 0)) && + + (((imagedata->key.data.arrowDirection != 0) && + (imagedata->key.data.arrowDirection == key.data.arrowDirection)) || + (imagedata->key.data.arrowDirection == 0)) && + + (((imagedata->key.data.gapSide != 0) && + (imagedata->key.data.gapSide == key.data.gapSide)) || + (imagedata->key.data.gapSide == 0)) && + + (((!imagedata->detail.isNull()) && + (detail == imagedata->detail)) || + (imagedata->detail.isNull()))) { + // we have a winner + break; + } + } + } + + if ((! imagedata) && (parent())) { + imagedata = ((GtkObject *) parent())->getImageData(key, detail); + } + + return imagedata; +} + + +KLegacyStyleData *GtkObject::styleData() { + if ((! d) && parent()) { + d = ((GtkObject *) parent())->styleData(); + } + + return d; +} + + +QColor GtkObject::backColor(KLegacy::State s) { + if ((! styleData()->back[s].isValid()) && parent()) { + return ((GtkObject *) parent())->backColor(s); + } + + if (styleData()->back[s].isValid()) + return styleData()->back[s]; + + return white; +} + + +QColor GtkObject::baseColor(KLegacy::State s) { + if ((! styleData()->base[s].isValid()) && parent()) { + return ((GtkObject *) parent())->baseColor(s); + } + + if (styleData()->base[s].isValid()) + return styleData()->base[s]; + + return white; +} + + +QColor GtkObject::foreColor(KLegacy::State s) { + if ((! styleData()->fore[s].isValid()) && parent()) { + return ((GtkObject *) parent())->foreColor(s); + } + + if (styleData()->fore[s].isValid()) + return styleData()->fore[s]; + + return black; +} + + +QFont *GtkObject::font() { + if ((! styleData()->fn) && parent()) { + return ((GtkObject *) parent())->font(); + } + + return styleData()->fn; +} + + +GtkObject *GtkObject::find(QRegExp &r) const { + // if the regular expression matches the name of this widget, return + if (r.match(name()) != -1) { + return (GtkObject *) this; + } + + // regex doesn't match us, and we have no children, return 0 + if (! children()) return 0; + + QObject *o; + GtkObject *obj, *gobj; + + QObjectListIt ot(*children()); + + // search our children to see if any match the regex + while ((o = ot.current()) != 0) { + ++ot; + + // this would be nice if moc could parse this file :/ + // + // if (o->className() != "GtkObject") { + // qDebug("object is not a GtkObject (className = '%s')", + // o->className()); + // continue; + // } + + obj = (GtkObject *) o; + + // use obj->find(r) instead of r.match(obj->name()) so that this child's + // children will be searched as well... this allows us to search the entire + // object tree + if ((gobj = obj->find(r)) != 0) { + // found something! + return (GtkObject *) gobj; + } + } + + // found nothing + return 0; +} + + +QPixmap *GtkObject::draw(KLegacyImageDataKey key, int width, int height, + const QString &detail) +{ + KLegacyImageData *imagedata = getImageData(key, detail); + if (! imagedata) { + return 0; + } + + return draw(imagedata, width, height); +} + + +QPixmap *GtkObject::draw(KLegacyImageData *imagedata, int width, int height) { + QString pixmapKey; + QTextOStream(&pixmapKey) << "$KLegacy_Image_" << styleData()->name << "_" << + className() << "_" << width << "x" << height << "_" << + imagedata->key.cachekey << "_" << (uint) imagedata->recolorable << + (uint) imagedata->stretch << (uint) imagedata->overlayStretch; + + QPixmap *pixmap = QPixmapCache::find(pixmapKey); + if (pixmap) { + return pixmap; + } + + QPixmap *main = 0, *overlay = 0; + + if (! imagedata->file.isNull()) { + QImage *image = imageCache->find(imagedata->file); + bool found = true; + + if (! image) { + image = new QImage(imagedata->file); + + if (! image || image->isNull()) { + found = false; + } else { + imageCache->insert(imagedata->file, image); + } + } + + if (found) { + int w = ((imagedata->stretch) ? width : image->width()), + h = ((imagedata->stretch) ? height : image->height()); + main = drawImage(image, w, h, imagedata->border, imagedata->stretch); + } + } + + if (! imagedata->overlayFile.isNull()) { + QImage *image = imageCache->find(imagedata->overlayFile); + bool found = true; + + if (! image) { + image = new QImage(imagedata->overlayFile); + + if (! image || image->isNull()) { + found = false; + } else { + imageCache->insert(imagedata->overlayFile, image); + } + } + + if (found) { + int w = ((imagedata->overlayStretch) ? width : image->width()), + h = ((imagedata->overlayStretch) ? height : image->height()); + overlay = drawImage(image, w, h, imagedata->overlayBorder, + imagedata->overlayStretch); + } + } + + QSize sz; + if (main) { + sz = sz.expandedTo(main->size()); + } + + if (overlay) { + sz = sz.expandedTo(overlay->size()); + } + + if (sz.isEmpty()) { + return (QPixmap *) 0; + } + + pixmap = new QPixmap(sz); + pixmap->fill(QColor(192,192,176)); + QPainter p(pixmap); + + if (main && (! main->isNull())) { + p.drawTiledPixmap(0, 0, sz.width(), sz.height(), *main); + } + + if (overlay && (! overlay->isNull())) { + QPoint pt((sz.width() - overlay->width()) / 2, + (sz.height() - overlay->height()) / 2); + p.drawPixmap(pt, *overlay); + } + + p.end(); + + if (main) { + if (main->mask() && (! main->mask()->isNull())) { + QBitmap bm(sz); + QPainter m(&bm); + QRect r(0, 0, width, height); + + m.drawTiledPixmap(r, *(main->mask())); + m.end(); + + pixmap->setMask(bm); + } + } else if (overlay) { + if (overlay->mask() && (! overlay->mask()->isNull())) { + QBitmap bm(sz); + QPainter m(&bm); + QRect r((sz.width() - overlay->width()) / 2, + (sz.height() - overlay->height()) / 2, + sz.width(), sz.height()); + m.drawTiledPixmap(r, *(overlay->mask())); + m.end(); + + pixmap->setMask(bm); + } + } + + if (! QPixmapCache::insert(pixmapKey, pixmap)) { + delete pixmap; + pixmap = (QPixmap *) 0; + } + + return pixmap; +} + + +class KLegacyStylePrivate : public KLegacy { +private: + QDict<KLegacyStyleData> styleDict; + QStringList pixmapPath; + QTextStream filestream; + + QFont oldfont; + QPalette oldpalette; + + // pointer to the widget under the pointer + QGuardedPtr<QWidget> lastWidget; + + // current position of the mouse + QPoint mousePos; + bool hovering; + + QPtrDict<GtkObject> gtkDict; + GtkObject *gtktree; + + friend class KLegacyStyle; + + +public: + KLegacyStylePrivate(); + ~KLegacyStylePrivate(); + + // parse the filename passed + bool parse(const QString &filename); + + bool parseClass(); + bool parseEngine(KLegacyStyleData *); + bool parseImage(KLegacyStyleData *); + bool parsePixmapPath(); + bool parseStyle(); +}; + + +KLegacyStylePrivate::KLegacyStylePrivate() + : lastWidget(0), mousePos(-1, -1), hovering(false), gtktree(0) +{ + QPixmapCache::setCacheLimit(8192); + + if (! imageCache) { + imageCache = new QDict<QImage>(imageCacheSize); + CHECK_PTR(imageCache); + + imageCache->setAutoDelete(true); + } + + styleDict.setAutoDelete(true); + + gtktree = initialize(gtkDict); + CHECK_PTR(gtktree); + + if (! gtktree->d) { + gtktree->d = new KLegacyStyleData; + gtktree->d->name = "Default"; + } + + // get the path to this users .gtkrc + QString gtkrcFilename = getenv("HOME"); + gtkrcFilename += "/.gtkrc"; + + QFile gtkrc(gtkrcFilename); + + if (gtkrc.open(IO_ReadOnly)) { + filestream.setDevice(>krc); + + while (! filestream.atEnd()) { + QString next; + filestream >> next; + + if (next.isNull()) continue; + + // skip comments + if (next[0] == '#') { filestream.readLine(); continue; } + + if (next == "class" || next == "widget" || next == "widget_class") { + if (! parseClass()) + qWarning("\"class\" parse error"); + } else if (next == "pixmap_path") { + if (! parsePixmapPath()) + qWarning("\"pixmap_path\" parse error"); + } else if (next == "style") { + if (! parseStyle()) + qWarning("\"style\" parse error"); + } + } + + gtkrc.close(); + } else + qWarning("%s: failed to open", gtkrcFilename.latin1()); +} + + +KLegacyStylePrivate::~KLegacyStylePrivate() { + if (imageCache) { + delete imageCache; + imageCache = 0; + } + + if (gtktree) { + delete gtktree; + gtktree = 0; + } +} + + +bool KLegacyStylePrivate::parseClass() { + if (filestream.atEnd()) return false; + + QString classname, keyword, stylename; + filestream >> classname; + filestream >> keyword; + filestream >> stylename; + + if (classname.isNull() || keyword.isNull() || stylename.isNull() || + keyword != "style" || + classname[0] != '\"' || classname[classname.length() - 1] != '\"' || + stylename[0] != '\"' || stylename[stylename.length() - 1] != '\"') + return false; + + classname = classname.mid(1, classname.length() - 2); + stylename = stylename.mid(1, stylename.length() - 2); + + QRegExp r(classname); + r.setWildcard(true); + GtkObject *obj = gtktree->find(r); + + if (! obj) { + qWarning("unknown object '%s'", classname.latin1()); + return false; + } + + KLegacyStyleData *styledata = styleDict.find(stylename); + + if (! styledata) { + qWarning("no such style '%s' for class '%s' (%p)", stylename.latin1(), + classname.latin1(), styledata); + return false; + } + + obj->d = styledata; + styledata->ref++; + + return true; +} + + +bool KLegacyStylePrivate::parseImage(KLegacyStyleData *styledata) { + if (filestream.atEnd()) { + qWarning("parseImage: premature end of stream"); + return false; + } + + QString next, equals, parameter; + filestream >> next; + + // skip comments + while (next[0] == '#') { + filestream.readLine(); + filestream >> next; + } + + if (next.isNull() || next != "{") { + qWarning("parseImage: expected '{' after 'image'\n" + " in style '%s', after processing %d previous images\n", + styledata->name.latin1(), styledata->imageList.count()); + return false; + } + + KLegacyImageData *imagedata = new KLegacyImageData; + + int paren_count = 1; + while (paren_count) { + filestream >> next; + if (next.isNull()) continue; + + // skip comments + if (next[0] == '#') {filestream.readLine(); continue; } + + if (next == "arrow_direction") { + filestream >> equals; + filestream >> parameter; + + if (equals.isNull() || parameter.isNull() || equals != "=") continue; + + if (parameter == "UP") + imagedata->key.data.arrowDirection = Qt::UpArrow + 1; + else if (parameter == "DOWN") + imagedata->key.data.arrowDirection = Qt::DownArrow + 1; + else if (parameter == "LEFT") + imagedata->key.data.arrowDirection = Qt::LeftArrow + 1; + else if (parameter == "RIGHT") + imagedata->key.data.arrowDirection = Qt::RightArrow + 1; + } else if (next == "border") { + filestream >> equals; + filestream >> parameter; + + if (equals.isNull() || parameter.isNull() || equals != "=" || + parameter != "{") + continue; + QString border =filestream.readLine(); + + int lp, rp, tp, bp, l, r, t, b; + lp = border.find(','); + rp = border.find(',', lp + 1); + tp = border.find(',', rp + 1); + bp = border.find('}', tp + 1); + + l = border.left(lp).toUInt(); + r = border.mid(lp + 1, rp - lp - 1).toUInt(); + t = border.mid(rp + 1, tp - rp - 1).toUInt(); + b = border.mid(tp + 1, bp - tp - 1).toUInt(); + + imagedata->border.setLeft(l); + imagedata->border.setRight(r); + imagedata->border.setTop(t); + imagedata->border.setBottom(b); + } else if (next == "detail") { + filestream >> equals; + filestream >> parameter; + + if (equals.isNull() || parameter.isNull() || equals != "=" || + parameter[0] != '\"' || parameter[parameter.length() - 1] != '\"') + continue; + + parameter = parameter.mid(1, parameter.length() - 2); + imagedata->detail = parameter; + } else if (next == "file") { + filestream >> equals; + filestream >> parameter; + + if (equals.isNull() || parameter.isNull() || equals != "=" || + parameter[0] != '\"' || parameter[parameter.length() - 1] != '\"') { + qWarning("image: file parameter malformed"); + continue; + } + + parameter = parameter.mid(1, parameter.length() - 2); + + QStringList::Iterator it; + for (it = pixmapPath.begin(); it != pixmapPath.end(); ++it) { + QFileInfo fileinfo((*it) + parameter); + + if (fileinfo.exists()) { + imagedata->file = fileinfo.filePath(); + break; + } + } + } else if (next == "function") { + filestream >> equals; + filestream >> parameter; + + if (equals.isNull() || parameter.isNull() || equals != "=") continue; + + if (parameter == "BOX") + imagedata->key.data.function = Box; + else if (parameter == "FLAT_BOX") + imagedata->key.data.function = FlatBox; + else if (parameter == "EXTENSION") + imagedata->key.data.function = Extension; + else if (parameter == "CHECK") + imagedata->key.data.function = Check; + else if (parameter == "OPTION") + imagedata->key.data.function = Option; + else if (parameter == "HLINE") + imagedata->key.data.function = HLine; + else if (parameter == "VLINE") + imagedata->key.data.function = VLine; + else if (parameter == "BOX_GAP") + imagedata->key.data.function = BoxGap; + else if (parameter == "SLIDER") + imagedata->key.data.function = Slider; + else if (parameter == "TAB") + imagedata->key.data.function = Tab; + else if (parameter == "ARROW") + imagedata->key.data.function = Arrow; + else if (parameter == "HANDLE") + imagedata->key.data.function = Handle; + else if (parameter == "SHADOW") + imagedata->key.data.function = FShadow; + else if (parameter == "FOCUS") + imagedata->key.data.function = Focus; + } else if (next == "gap_side" ) { + filestream >> equals; + filestream >> parameter; + + if (equals.isNull() || parameter.isNull() || equals != "=") continue; + + if (parameter == "TOP") + imagedata->key.data.gapSide = KLegacy::Top; + else if (parameter == "BOTTOM") + imagedata->key.data.gapSide = KLegacy::Bottom; + } else if (next == "orientation") { + filestream >> equals; + filestream >> parameter; + + if (equals.isNull() || parameter.isNull() || equals != "=") continue; + + if (parameter == "VERTICAL") + imagedata->key.data.orientation = Qt::Vertical + 1; + else if (parameter == "HORIZONTAL") + imagedata->key.data.orientation = Qt::Horizontal + 1; + } else if (next == "overlay_border") { + filestream >> equals; + filestream >> parameter; + + if (equals.isNull() || parameter.isNull() || equals != "=" || + parameter != "{") + continue; + QString border = filestream.readLine(); + + int lp, rp, tp, bp, l, r, t, b; + lp = border.find(','); + rp = border.find(',', lp + 1); + tp = border.find(',', rp + 1); + bp = border.find('}', tp + 1); + + l = border.left(lp).toUInt(); + r = border.mid(lp + 1, rp - lp - 1).toUInt(); + t = border.mid(rp + 1, tp - rp - 1).toUInt(); + b = border.mid(tp + 1, bp - tp - 1).toUInt(); + + imagedata->overlayBorder.setLeft(l); + imagedata->overlayBorder.setRight(r); + imagedata->overlayBorder.setTop(t); + imagedata->overlayBorder.setBottom(b); + } else if (next == "overlay_file") { + filestream >> equals; + filestream >> parameter; + + if (equals.isNull() || parameter.isNull() || equals != "=" || + parameter[0] != '\"' || parameter[parameter.length() - 1] != '\"') { + qWarning("image: overlay_file parameter malformed"); + continue; + } + + parameter = parameter.mid(1, parameter.length() - 2); + + QStringList::Iterator it; + for (it = pixmapPath.begin(); it != pixmapPath.end(); ++it) { + QFileInfo fileinfo((*it) + parameter); + + if (fileinfo.exists()) { + imagedata->overlayFile = fileinfo.filePath(); + break; + } + } + } else if (next == "overlay_stretch") { + filestream >> equals; + filestream >> parameter; + + if (equals.isNull() || parameter.isNull() || equals != "=") continue; + + if (parameter == "TRUE") + imagedata->overlayStretch = true; + else + imagedata->overlayStretch = false; + } else if (next == "stretch") { + filestream >> equals; + filestream >> parameter; + + if (equals.isNull() || parameter.isNull() || equals != "=") continue; + + if (parameter == "TRUE") + imagedata->stretch = true; + else + imagedata->stretch = false; + } else if (next == "shadow") { + filestream >> equals; + filestream >> parameter; + + if (equals.isNull() || parameter.isNull() || equals != "=") continue; + + if (parameter == "NONE") + imagedata->key.data.shadow = NoShadow; + else if (parameter == "IN") + imagedata->key.data.shadow = In; + else if (parameter == "OUT") + imagedata->key.data.shadow = Out; + else if (parameter == "ETCHED_IN") + imagedata->key.data.shadow = EtchedIn; + else if (parameter == "ETCHED_OUT") + imagedata->key.data.shadow = EtchedOut; + } else if (next == "state") { + filestream >> equals; + filestream >> parameter; + + if (equals.isNull() || parameter.isNull() || equals != "=") continue; + + if (parameter == "NORMAL") + imagedata->key.data.state = Normal; + else if (parameter == "PRELIGHT") + imagedata->key.data.state = Prelight; + else if (parameter == "ACTIVE") + imagedata->key.data.state = Active; + else if (parameter == "INSENSITIVE") + imagedata->key.data.state = Insensitive; + else if (parameter == "SELECTED") + imagedata->key.data.state = Selected; + } else if (next == "{") paren_count++; + else if (next == "}") paren_count--; + } + + styledata->imageList.append(imagedata); + + return true; +} + + +bool KLegacyStylePrivate::parseEngine(KLegacyStyleData *styledata) { + if (filestream.atEnd()) return false; + + QString enginename, paren; + filestream >> enginename; + filestream >> paren; + + if (enginename.isNull() || paren.isNull() || + enginename[0] != '\"' || enginename[enginename.length() - 1] != '\"' || + paren != "{") { + return false; + } + + QString next; + int paren_count = 1; + while (paren_count) { + filestream >> next; + + // skip comments + if (next[0] == '#') { + filestream.readLine(); + continue; + } + + if (next == "image") { + if (! parseImage(styledata)) { + qWarning("image parse error"); + } + } else if (next == "{") { + paren_count++; + } else if (next == "}") { + paren_count--; + } + } + + return true; +} + + +bool KLegacyStylePrivate::parsePixmapPath() { + if (filestream.atEnd()) { + return false; + } + + QString next; + filestream >> next; + + if (next.isNull() || next[0] != '\"' || next[next.length() - 1] != '\"') { + return false; + } + + next = next.mid(1, next.length() - 2); + + int start = 0, end = next.find(":"); + while (end != -1) { + QString path(next.mid(start, end - start)); + + if (path[path.length() - 1] != '/') { + path += '/'; + } + + QFileInfo fileinfo(path); + if (fileinfo.exists() && fileinfo.isDir()) { + pixmapPath.append(path); + } + + start = end + 1; + end = next.find(":", start); + } + + // get the straggler + end = next.length(); + QString path(next.mid(start, end - start)); + + if (path[path.length() - 1] != '/') { + path += '/'; + } + + QFileInfo fileinfo(path); + if (fileinfo.exists() && fileinfo.isDir()) { + pixmapPath.append(path); + } + + return true; +} + + +bool KLegacyStylePrivate::parseStyle() { + if (filestream.atEnd()) return false; + + QString stylename, paren; + filestream >> stylename; + filestream >> paren; + + if (stylename.isNull() || paren.isNull() || + stylename[0] != '\"' || stylename[stylename.length() - 1] != '\"') + return false; + + stylename = stylename.mid(1, stylename.length() - 2); + + if (paren == "=") { + QString newstylename; + filestream >> newstylename; + + if (newstylename.isNull() || + newstylename[0] != '\"' || newstylename[newstylename.length() - 1] != '\"') + return false; + + newstylename = newstylename.mid(1, newstylename.length() - 2); + + KLegacyStyleData *styledata = styleDict.find(stylename); + + if (! styledata) return false; + + KLegacyStyleData *newstyledata = new KLegacyStyleData(*styledata); + newstyledata->name = newstylename; + styleDict.insert(newstylename, newstyledata); + + return true; + } else if (paren != "{") { + qWarning("parseStyle: expected '{' while parsing style %s", + stylename.latin1()); + return false; + } + + KLegacyStyleData *styledata = new KLegacyStyleData; + styledata->name = stylename; + + QString next, parameter; + int paren_count = 1; + while (paren_count) { + filestream >> next; + + // skip comments + if (next[0] == '#') { + filestream.readLine(); + continue; + } + + if (next.left(5) == "base[") { + int l = next.find('['), r = next.find(']'), state; + + if (l < 1 || r < 1 || r < l) continue; + + QString mode = next.mid(l + 1, r - l - 1); + if (mode == "ACTIVE") + state = Active; + else if (mode == "NORMAL") + state = Normal; + else if (mode == "INSENSITIVE") + state = Insensitive; + else if (mode == "PRELIGHT") + state = Prelight; + else if (mode == "SELECTED") + state = Selected; + + filestream >> next; + filestream >> parameter; + + if (next.isNull() || parameter.isNull() || next != "=") continue; + + if (parameter[0] == '\"') { // assume color of the form "#rrggbb" + QString colorname = parameter.mid(1, parameter.length() - 2); + if (colorname.isNull()) continue; + + styledata->base[state].setNamedColor(colorname); + } else if (parameter == "{") { // assume color of the form { ri, gi, bi } + QString color =filestream.readLine(); + + int rp, gp, bp; + float ri, gi, bi; + + rp = color.find(','); + gp = color.find(',', rp + 1); + bp = color.find('}', gp + 1); + + ri = color.left(rp).toFloat(); + gi = color.mid(rp + 1, gp - rp - 1).toFloat(); + bi = color.mid(gp + 1, bp - gp - 1).toFloat(); + + int red = (int) (255 * ri); + int green = (int) (255 * gi); + int blue = (int) (255 * bi); + styledata->base[state].setRgb(red, green, blue); + } + } else if (next.left(3) == "bg[") { + int l = next.find('['), r = next.find(']'), state; + + if (l < 1 || r < 1 || r < l) continue; + + QString mode = next.mid(l + 1, r - l - 1); + if (mode == "ACTIVE") + state = Active; + else if (mode == "NORMAL") + state = Normal; + else if (mode == "INSENSITIVE") + state = Insensitive; + else if (mode == "PRELIGHT") + state = Prelight; + else if (mode == "SELECTED") + state = Selected; + + filestream >> next; + filestream >> parameter; + + if (next.isNull() || parameter.isNull() || next != "=") continue; + + if (parameter[0] == '\"') { // assume color of the form "#rrggbb" + QString colorname = parameter.mid(1, parameter.length() - 2); + if (colorname.isNull()) continue; + + styledata->back[state].setNamedColor(colorname); + } else if (parameter == "{") { // assume color of the form { ri, gi, bi } + QString color =filestream.readLine(); + + int rp, gp, bp; + float ri, gi, bi; + + rp = color.find(','); + gp = color.find(',', rp + 1); + bp = color.find('}', gp + 1); + + ri = color.left(rp).toFloat(); + gi = color.mid(rp + 1, gp - rp - 1).toFloat(); + bi = color.mid(gp + 1, bp - gp - 1).toFloat(); + + int red = (int) (255 * ri); + int green = (int) (255 * gi); + int blue = (int) (255 * bi); + styledata->back[state].setRgb(red, green, blue); + } + } else if (next == "engine") { + if (! parseEngine(styledata)) + fprintf(stderr, "engine parse error\n"); + } else if (next.left(3) == "fg[") { + int l = next.find('['), r = next.find(']'), state; + + if (l < 1 || r < 1 || r < l) continue; + + QString mode = next.mid(l + 1, r - l - 1); + if (mode == "ACTIVE") + state = Active; + else if (mode == "NORMAL") + state = Normal; + else if (mode == "INSENSITIVE") + state = Insensitive; + else if (mode == "PRELIGHT") + state = Prelight; + else if (mode == "SELECTED") + state = Selected; + + filestream >> next; + filestream >> parameter; + + if (next.isNull() || parameter.isNull() || next != "=") continue; + + if (parameter[0] == '\"') { // assume color of the form "#rrggbb" + QString colorname = parameter.mid(1, parameter.length() - 2); + if (colorname.isNull()) continue; + + styledata->fore[state].setNamedColor(colorname); + } else if (parameter == "{") { // assume color of the form { ri, gi, bi } + QString color = filestream.readLine(); + + int rp, gp, bp; + float ri, gi, bi; + + rp = color.find(','); + gp = color.find(',', rp + 1); + bp = color.find('}', gp + 1); + + ri = color.left(rp).toFloat(); + gi = color.mid(rp + 1, gp - rp - 1).toFloat(); + bi = color.mid(gp + 1, bp - gp - 1).toFloat(); + + int red = (int) (255 * ri); + int green = (int) (255 * gi); + int blue = (int) (255 * bi); + styledata->fore[state].setRgb(red, green, blue); + } + } else if (next == "font") { + filestream >> next; + filestream >> parameter; + + if (next.isNull() || parameter.isNull() || next != "=" || + parameter[0] != '\"' || parameter[parameter.length() - 1] != '\"') { + qWarning("font parameter malformed '%s'", parameter.latin1()); + continue; + } + + parameter = parameter.mid(1, parameter.length() - 2); + + if (! styledata->fn) { + styledata->fn = new QFont; + } + + styledata->fn->setRawName(parameter); + } else if (next == "{") { + paren_count++; + } else if (next == "}") { + paren_count--; + } + } + + styleDict.insert(styledata->name, styledata); + + return true; +} + + +KLegacyStyle::KLegacyStyle(void) : KStyle() { + setButtonDefaultIndicatorWidth(6); + setScrollBarExtent(15, 15); + setButtonMargin(3); + setSliderThickness(15); + + priv = new KLegacyStylePrivate; +} + + +KLegacyStyle::~KLegacyStyle(void) { + delete priv; +} + + +int KLegacyStyle::defaultFrameWidth() const { + return 2; +} + + +void KLegacyStyle::polish(QApplication *app) { + priv->oldfont = app->font(); + priv->oldpalette = app->palette(); + + GtkObject *gobj = priv->gtkDict.find(QMainWindow::staticMetaObject()); + + if (gobj) { + if (gobj->font()) { + app->setFont(*gobj->font(), true); + } + + QPalette pal = app->palette(); + QBrush brush; + + // background + brush = pal.brush(QPalette::Active, QColorGroup::Background); + brush.setColor(gobj->backColor(KLegacy::Active)); + pal.setBrush(QPalette::Active, QColorGroup::Background, brush); + + brush = pal.brush(QPalette::Inactive, QColorGroup::Background); + brush.setColor(gobj->backColor(KLegacy::Normal)); + pal.setBrush(QPalette::Inactive, QColorGroup::Background, brush); + + brush = pal.brush(QPalette::Disabled, QColorGroup::Background); + brush.setColor(gobj->backColor(KLegacy::Insensitive)); + pal.setBrush(QPalette::Disabled, QColorGroup::Background, brush); + + // foreground + brush = pal.brush(QPalette::Active, QColorGroup::Foreground); + brush.setColor(gobj->foreColor(KLegacy::Active)); + pal.setBrush(QPalette::Active, QColorGroup::Foreground, brush); + + brush = pal.brush(QPalette::Inactive, QColorGroup::Foreground); + brush.setColor(gobj->foreColor(KLegacy::Normal)); + pal.setBrush(QPalette::Inactive, QColorGroup::Foreground, brush); + + brush = pal.brush(QPalette::Disabled, QColorGroup::Foreground); + brush.setColor(gobj->foreColor(KLegacy::Insensitive)); + pal.setBrush(QPalette::Disabled, QColorGroup::Foreground, brush); + + // base + brush = pal.brush(QPalette::Active, QColorGroup::Base); + brush.setColor(gobj->baseColor(KLegacy::Normal)); + pal.setBrush(QPalette::Active, QColorGroup::Base, brush); + + brush = pal.brush(QPalette::Inactive, QColorGroup::Base); + brush.setColor(gobj->baseColor(KLegacy::Normal)); + pal.setBrush(QPalette::Inactive, QColorGroup::Base, brush); + + brush = pal.brush(QPalette::Disabled, QColorGroup::Base); + brush.setColor(gobj->baseColor(KLegacy::Normal)); + pal.setBrush(QPalette::Disabled, QColorGroup::Base, brush); + + // button + brush = pal.brush(QPalette::Active, QColorGroup::Button); + brush.setColor(gobj->backColor(KLegacy::Active)); + pal.setBrush(QPalette::Active, QColorGroup::Button, brush); + + brush = pal.brush(QPalette::Normal, QColorGroup::Button); + brush.setColor(gobj->backColor(KLegacy::Normal)); + pal.setBrush(QPalette::Normal, QColorGroup::Button, brush); + + brush = pal.brush(QPalette::Disabled, QColorGroup::Button); + brush.setColor(gobj->backColor(KLegacy::Insensitive)); + pal.setBrush(QPalette::Disabled, QColorGroup::Button, brush); + + // text + brush = pal.brush(QPalette::Active, QColorGroup::Text); + brush.setColor(gobj->foreColor(KLegacy::Active)); + pal.setBrush(QPalette::Active, QColorGroup::Text, brush); + + brush = pal.brush(QPalette::Inactive, QColorGroup::Text); + brush.setColor(gobj->foreColor(KLegacy::Normal)); + pal.setBrush(QPalette::Inactive, QColorGroup::Text, brush); + + brush = pal.brush(QPalette::Disabled, QColorGroup::Text); + brush.setColor(gobj->foreColor(KLegacy::Insensitive)); + pal.setBrush(QPalette::Disabled, QColorGroup::Text, brush); + + // highlight + brush = pal.brush(QPalette::Active, QColorGroup::Highlight); + brush.setColor(gobj->backColor(KLegacy::Selected)); + pal.setBrush(QPalette::Active, QColorGroup::Highlight, brush); + + brush = pal.brush(QPalette::Active, QColorGroup::Highlight); + brush.setColor(gobj->backColor(KLegacy::Selected)); + pal.setBrush(QPalette::Active, QColorGroup::Highlight, brush); + + brush = pal.brush(QPalette::Active, QColorGroup::Highlight); + brush.setColor(gobj->backColor(KLegacy::Selected)); + pal.setBrush(QPalette::Active, QColorGroup::Highlight, brush); + + // highlight text + brush = pal.brush(QPalette::Active, QColorGroup::HighlightedText); + brush.setColor(gobj->foreColor(KLegacy::Selected)); + pal.setBrush(QPalette::Active, QColorGroup::HighlightedText, brush); + + brush = pal.brush(QPalette::Active, QColorGroup::HighlightedText); + brush.setColor(gobj->foreColor(KLegacy::Active)); + pal.setBrush(QPalette::Active, QColorGroup::HighlightedText, brush); + + brush = pal.brush(QPalette::Active, QColorGroup::HighlightedText); + brush.setColor(gobj->foreColor(KLegacy::Active)); + pal.setBrush(QPalette::Active, QColorGroup::HighlightedText, brush); + + app->setPalette(pal, true); + } + + qt_set_draw_menu_bar_impl((QDrawMenuBarItemImpl) &KLegacyStyle::drawMenuBarItem); + + KStyle::polish(app); +} + + +void KLegacyStyle::polish(QWidget *widget) { + if (qstrcmp(widget->name(), "qt_viewport") == 0 || + widget->testWFlags(WType_Popup) || + widget->inherits("KDesktop")) + return; + + if (widget->backgroundMode() == QWidget::PaletteBackground || + widget->backgroundMode() == QWidget::PaletteButton && + (! widget->ownPalette())) + widget->setBackgroundMode(QWidget::X11ParentRelative); + + QMetaObject *metaobject = 0; + QString detail; + KLegacyImageDataKey key; + key.cachekey = 0; + + bool eventFilter = false; + bool mouseTrack = false; + bool immediateRender = false; + bool bgPixmap = false; + + if (widget->inherits("QButton")) { + metaobject = QButton::staticMetaObject(); + eventFilter = true; + } + + if (widget->inherits("QComboBox")) { + metaobject = QComboBox::staticMetaObject(); + eventFilter = true; + } + + if (widget->inherits("QScrollBar")) { + metaobject = QScrollBar::staticMetaObject(); + eventFilter = true; + mouseTrack = true; + } + + if (widget->inherits("QMenuBar")) { + eventFilter = true; + immediateRender = true; + + metaobject = QMenuBar::staticMetaObject(); + + detail = "menubar"; + key.data.function = KLegacy::Box; + key.data.shadow = KLegacy::Out; + key.data.state = KLegacy::Normal; + + ((QMenuBar *) widget)->setFrameShape(QFrame::StyledPanel); + ((QMenuBar *) widget)->setLineWidth(0); + widget->setBackgroundMode(QWidget::PaletteBackground); + } + + if (widget->inherits("QToolBar")) { + metaobject = QToolBar::staticMetaObject(); + + eventFilter = true; + immediateRender = true; + + detail = "menubar"; + key.data.function = KLegacy::Box; + key.data.shadow = KLegacy::Out; + key.data.state = KLegacy::Normal; + + widget->setBackgroundMode(QWidget::PaletteBackground); + } + + if (widget->inherits("QLineEdit")) { + metaobject = QLineEdit::staticMetaObject(); + + eventFilter = true; + immediateRender = true; + + detail = "entry_bg"; + key.data.function = KLegacy::FlatBox; + key.data.shadow = KLegacy::NoShadow; + key.data.state = (widget->isEnabled()) ? KLegacy::Normal : KLegacy::Insensitive; + + widget->setBackgroundMode(QWidget::PaletteBase); + } + + if (widget->isTopLevel() || widget->inherits("QWorkspaceChild")) { + immediateRender = true; + + bgPixmap = true; + metaobject = QMainWindow::staticMetaObject(); + key.cachekey = 0; + key.data.function = KLegacy::FlatBox; + detail = "base"; + } + + if (widget->inherits("QPopupMenu")) { + qDebug("polishing popup '%s'", widget->className()); + metaobject = QPopupMenu::staticMetaObject(); + widget->setBackgroundMode(QWidget::PaletteBackground); + } + + GtkObject *gobj = gobj = priv->gtkDict.find(((metaobject) ? metaobject : + widget->metaObject())); + + if (gobj) { + if (gobj->font() && (*gobj->font() != QApplication::font())) + widget->setFont(*gobj->font()); + + if (immediateRender) { + QPixmap *pix = gobj->draw(key, widget->width(), widget->height(), detail); + + if (pix && ! pix->isNull()) { + if (! bgPixmap) { + QPalette pal = widget->palette(); + QBrush brush; + + // base + // active + brush = pal.brush(QPalette::Active, + QColorGroup::Base); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Active, + QColorGroup::Base, brush); + + // inactive + brush = pal.brush(QPalette::Inactive, + QColorGroup::Base); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Inactive, + QColorGroup::Base, brush); + + // disabled + brush = pal.brush(QPalette::Disabled, + QColorGroup::Base); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Disabled, + QColorGroup::Base, brush); + + // background - button + // active + brush = pal.brush(QPalette::Active, + QColorGroup::Background); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Active, + QColorGroup::Background, brush); + + brush = pal.brush(QPalette::Active, + QColorGroup::Button); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Active, + QColorGroup::Button, brush); + + // inactive + brush = pal.brush(QPalette::Inactive, + QColorGroup::Background); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Inactive, + QColorGroup::Background, brush); + + brush = pal.brush(QPalette::Inactive, + QColorGroup::Button); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Inactive, + QColorGroup::Button, brush); + + // disabled + brush = pal.brush(QPalette::Disabled, + QColorGroup::Background); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Disabled, + QColorGroup::Background, brush); + + brush = pal.brush(QPalette::Disabled, + QColorGroup::Button); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Disabled, + QColorGroup::Button, brush); + + widget->setPalette(pal); + } else + widget->setBackgroundPixmap(*pix); + } + } + } + + if (eventFilter) { + widget->installEventFilter(this); + } + + if (mouseTrack) { + widget->setMouseTracking(mouseTrack); + } + + KStyle::polish(widget); +} + + +void KLegacyStyle::polishPopupMenu(QPopupMenu *popup) { + KStyle::polishPopupMenu(popup); + + popup->setMouseTracking(true); + popup->setCheckable(true); + + popup->installEventFilter(this); +} + + +void KLegacyStyle::unPolish(QWidget *widget) { + if (widget->inherits("KDesktop")) + return; + + widget->setBackgroundOrigin(QWidget::WidgetOrigin); + widget->setBackgroundPixmap(QPixmap()); + widget->removeEventFilter(this); + widget->unsetPalette(); + widget->setAutoMask(false); + KStyle::unPolish(widget); +} + + +void KLegacyStyle::unPolish(QApplication *app) { + app->setFont(priv->oldfont, true); + app->setPalette(priv->oldpalette, true); + + qt_set_draw_menu_bar_impl(0); + + KStyle::unPolish(app); +} + + +void KLegacyStyle::drawKMenuItem(QPainter *p, int x, int y, int w, int h, const QColorGroup &g, + bool active, QMenuItem *mi, QBrush *) +{ + drawMenuBarItem(p, x, y, w, h, mi, (QColorGroup &) g, + (mi) ? mi->isEnabled() : false, active); +} + + +void KLegacyStyle::drawMenuBarItem(QPainter *p, int x, int y, int w, int h, QMenuItem *mi, + QColorGroup &g, bool enabled, bool active) +{ + if (enabled && active) { + GtkObject *gobj = priv->gtkDict.find(&menuitem_ptr); + + if (gobj) { + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Box; + key.data.state = KLegacy::Prelight; + key.data.shadow = KLegacy::Out; + + QPixmap *pix = gobj->draw(key, w, h, "menuitem"); + + if (pix && ! pix->isNull()) + p->drawPixmap(x, y, *pix); + } + } + + drawItem(p, x, y, w, h, AlignCenter|ShowPrefix|DontClip|SingleLine, + g, enabled, mi->pixmap(), mi->text(), -1, &g.buttonText()); +} + + +void KLegacyStyle::drawButton(QPainter *p, int x, int y , int w, int h, + const QColorGroup &g, bool sunken, const QBrush *fill) +{ + drawBevelButton(p, x, y, w, h, g, sunken, fill); +} + + +void KLegacyStyle::drawBevelButton(QPainter *p, int x, int y, int w, int h, + const QColorGroup & g, bool sunken, + const QBrush *fill) +{ + GtkObject *gobj = priv->gtkDict.find(QButton::staticMetaObject()); + + if (! gobj) { + KStyle::drawBevelButton(p, x, y, w, h, g, sunken, fill); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Box; + key.data.shadow = (sunken) ? KLegacy::In : KLegacy::Out; + key.data.state = (sunken) ? KLegacy::Active : KLegacy::Normal; + + QPixmap *pix = gobj->draw(key, w, h, "button"); + + if (pix && (! pix->isNull())) + p->drawPixmap(x, y, *pix); + else + KStyle::drawBevelButton(p, x, y, w, h, g, sunken, fill); +} + + +void KLegacyStyle::drawPushButton(QPushButton *btn, QPainter *p) { + GtkObject *gobj = priv->gtkDict.find(QPushButton::staticMetaObject()); + + if (! gobj) { + KStyle::drawPushButton(btn, p); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Box; + + QColorGroup g = btn->colorGroup(); + QBrush fill = g.brush(QColorGroup::Button); + int x1, y1, x2, y2; + btn->rect().coords(&x1, &y1, &x2, &y2); + + if (btn->isDefault()) { + // draw default button + key.data.state = (btn->isEnabled()) ? KLegacy::Normal : KLegacy::Insensitive; + key.data.shadow = KLegacy::In; + + QPixmap *pix = gobj->draw(key, x2 -x1 + 1, y2 - y1 + 1, "buttondefault"); + + if (! pix) + pix = gobj->draw(key, x2 - x1 + 1, y2 - y1 + 1, "button"); + + if (pix) + p->drawPixmap(x1, y1, *pix); + else + KStyle::drawBevelButton(p, x1, y1, x2 - x1 + 1, y2 - y1 + 1, + g, true, &fill); + } + + int diw = buttonDefaultIndicatorWidth(); + if (btn->isDefault() || btn->autoDefault()) { + x1 += diw; + y1 += diw; + x2 -= diw; + y2 -= diw; + } + + if (btn->isOn() || btn->isDown()) { + key.data.state = KLegacy::Active; + key.data.shadow = KLegacy::In; + } else { + key.data.state = ((btn->isEnabled()) ? + ((static_cast<QWidget *>( btn ) == priv->lastWidget) ? KLegacy::Prelight : KLegacy::Normal) : + KLegacy::Insensitive); + key.data.shadow = ((btn->isOn() || btn->isDown()) ? + KLegacy::In : KLegacy::Out); + } + + QPixmap *pix = gobj->draw(key, x2 - x1 + 1, y2 - y1 + 1, "button"); + + if (pix && ! pix->isNull()) + p->drawPixmap(x1, y1, *pix); + else { + KStyle::drawBevelButton(p, x1, y1, x2 - x1 + 1, y2 - y1 + 1, + g, btn->isOn() || btn->isDown(), &fill); + } +} + + +void KLegacyStyle::drawIndicator(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, int state, + bool down, bool enabled) +{ + GtkObject *gobj = priv->gtkDict.find(QCheckBox::staticMetaObject()); + + if (! gobj) { + KStyle::drawIndicator(p, x, y, w, h, g, state, down, enabled); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Check; + key.data.state = KLegacy::Normal; + key.data.shadow = ((state != QButton::Off) || down) ? KLegacy::In : KLegacy::Out; + + QPixmap *pix = gobj->draw(key, w, h, "checkbutton"); + + if (pix && (! pix->isNull())) + p->drawPixmap(x, y, *pix); + else + KStyle::drawIndicator(p, x, y, w, h, g, state, down, enabled); +} + + +void KLegacyStyle::drawIndicatorMask(QPainter *p, int x, int y, int w, int h, int state) { + GtkObject *gobj = priv->gtkDict.find(QCheckBox::staticMetaObject()); + + if (! gobj) { + KStyle::drawIndicatorMask(p, x, y, w, h, state); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Check; + key.data.state = KLegacy::Normal; + key.data.shadow = (state != QButton::Off) ? KLegacy::In : KLegacy::Out; + + QPixmap *pix = gobj->draw(key, w, h, "checkbutton"); + + if (pix && pix->mask() && ! pix->mask()->isNull()) + p->drawPixmap(x, y, *(pix->mask())); + else + KStyle::drawIndicatorMask(p, x, y, w, h, state); +} + + +QSize KLegacyStyle::indicatorSize(void) const { + GtkObject *gobj = priv->gtkDict.find(QCheckBox::staticMetaObject()); + + if (! gobj) return KStyle::indicatorSize(); + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Check; + key.data.shadow = KLegacy::Out; + KLegacyImageData *id = gobj->getImageData(key, "checkbutton"); + + if (! id) return KStyle::indicatorSize(); + + QString filename; + if (! id->file.isNull()) + filename = id->file; + else if (! id->overlayFile.isNull()) + filename = id->overlayFile; + else + return KStyle::indicatorSize(); + + QImage *image = imageCache->find(filename); + if (! image) { + image = new QImage(filename); + + if (! image) return KStyle::indicatorSize(); + + imageCache->insert(filename, image); + } + + return QSize(image->width(), image->height()); +} + + +void KLegacyStyle::drawExclusiveIndicator(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool on, + bool down, bool enabled) +{ + GtkObject *gobj = priv->gtkDict.find(QRadioButton::staticMetaObject()); + + if (! gobj) { + drawExclusiveIndicator(p, x, y, w, h, g, on, down, enabled); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Option; + key.data.state = KLegacy::Normal; + key.data.shadow = (on || down) ? KLegacy::In : KLegacy::Out; + + QPixmap *pix = gobj->draw(key, w, h, "radiobutton"); + + if (pix && (! pix->isNull())) + p->drawPixmap(x, y, *pix); + else + KStyle::drawExclusiveIndicator(p, x, y, w, h, g, down, enabled); +} + + +void KLegacyStyle::drawExclusiveIndicatorMask(QPainter *p, int x, int y, int w, int h, + bool on) +{ + GtkObject *gobj = priv->gtkDict.find(QRadioButton::staticMetaObject()); + + if (! gobj) { + KStyle::drawExclusiveIndicatorMask(p, x, y, w, h, on); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Option; + key.data.state = KLegacy::Normal; + key.data.shadow = (on) ? KLegacy::In : KLegacy::Out; + + QPixmap *pix = gobj->draw(key, w, h, "radiobutton"); + + if (pix && pix->mask() && ! pix->mask()->isNull()) + p->drawPixmap(x, y, *(pix->mask())); + else + KStyle::drawExclusiveIndicatorMask(p, x, y, w, h, on); +} + + +QSize KLegacyStyle::exclusiveIndicatorSize(void) const { + GtkObject *gobj = priv->gtkDict.find(QRadioButton::staticMetaObject()); + + if (! gobj) { + return KStyle::indicatorSize(); + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Option; + key.data.shadow = KLegacy::Out; + KLegacyImageData *id = gobj->getImageData(key, "radiobutton"); + + if (! id) return KStyle::indicatorSize(); + + QString filename; + if (! id->file.isNull()) { + filename = id->file; + } else if (! id->overlayFile.isNull()) { + filename = id->overlayFile; + } else { + return KStyle::indicatorSize(); + } + + QImage *image = imageCache->find(filename); + if (! image) { + image = new QImage(filename); + + if (! image) { + return KStyle::indicatorSize(); + } + + imageCache->insert(filename, image); + } + + return QSize(image->width(), image->height()); +} + + +void KLegacyStyle::drawPopupMenuItem(QPainter *p, bool checkable, int maxpmw, int tab, + QMenuItem *mi, const QPalette &pal, bool act, + bool enabled, int x, int y, int w, int h) +{ + const QColorGroup & g = pal.active(); + QColorGroup itemg = (! enabled) ? pal.disabled() : pal.active(); + + if (checkable) + maxpmw = QMAX(maxpmw, 15); + + int checkcol = maxpmw; + + if (mi && mi->isSeparator()) { + p->setPen( g.dark() ); + p->drawLine( x, y, x+w, y ); + p->setPen( g.light() ); + p->drawLine( x, y+1, x+w, y+1 ); + return; + } + + if ( act && enabled ) { + GtkObject *gobj = priv->gtkDict.find(&menuitem_ptr); + + if (gobj) { + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Box; + key.data.state = KLegacy::Prelight; + key.data.shadow = KLegacy::Out; + + QPixmap *pix = gobj->draw(key, w, h, "menuitem"); + + if (pix && ! pix->isNull()) + p->drawPixmap(x, y, *pix); + } + } else + p->fillRect(x, y, w, h, g.brush( QColorGroup::Button )); + + if ( !mi ) + return; + + if ( mi->isChecked() ) { + if ( mi->iconSet() ) { + qDrawShadePanel( p, x+2, y+2, checkcol, h-2*2, + g, true, 1, &g.brush( QColorGroup::Midlight ) ); + } + } else if ( !act ) { + p->fillRect(x+2, y+2, checkcol, h-2*2, + g.brush( QColorGroup::Button )); + } + + if ( mi->iconSet() ) { // draw iconset + QIconSet::Mode mode = (enabled) ? QIconSet::Normal : QIconSet::Disabled; + + if (act && enabled) + mode = QIconSet::Active; + + QPixmap pixmap = mi->iconSet()->pixmap(QIconSet::Small, mode); + + int pixw = pixmap.width(); + int pixh = pixmap.height(); + + QRect cr( x + 2, y+2, checkcol, h-2*2 ); + QRect pmr( 0, 0, pixw, pixh ); + + pmr.moveCenter(cr.center()); + + p->setPen( itemg.text() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + + } else if (checkable) { + int mw = checkcol; + int mh = h - 4; + + if (mi->isChecked()) + drawCheckMark(p, x+2, y+2, mw, mh, itemg, act, ! enabled); + } + + p->setPen( g.buttonText() ); + + QColor discol; + if (! enabled) { + discol = itemg.text(); + p->setPen( discol ); + } + + if (mi->custom()) { + p->save(); + mi->custom()->paint(p, itemg, act, enabled, x + checkcol + 4, y + 2, + w - checkcol - tab - 3, h - 4); + p->restore(); + } + + QString s = mi->text(); + if ( !s.isNull() ) { // draw text + int t = s.find( '\t' ); + int m = 2; + const int text_flags = AlignVCenter|ShowPrefix | DontClip | SingleLine; + if ( t >= 0 ) { // draw tab text + p->drawText( x+w-tab-2-2, + y+m, tab, h-2*m, text_flags, s.mid( t+1 ) ); + } + p->drawText(x + checkcol + 4, y + 2, w - checkcol -tab - 3, h - 4, + text_flags, s, t); + } else if (mi->pixmap()) { + QPixmap *pixmap = mi->pixmap(); + + if (pixmap->depth() == 1) p->setBackgroundMode(OpaqueMode); + p->drawPixmap(x + checkcol + 2, y + 2, *pixmap); + if (pixmap->depth() == 1) p->setBackgroundMode(TransparentMode); + } + + if (mi->popup()) { + int hh = h / 2; + + drawMenuArrow(p, RightArrow, (act) ? mi->isEnabled() : false, + x + w - hh - 6, y + (hh / 2), hh, hh, g, mi->isEnabled()); + } +} + + +void KLegacyStyle::drawComboButton(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool sunken, bool editable, + bool enabled, const QBrush *b) +{ + GtkObject *gobj = priv->gtkDict.find(QComboBox::staticMetaObject()); + + if (! gobj) { + KStyle::drawComboButton(p, x, y, w, h, g, sunken, editable, enabled, b); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Box; + key.data.state = KLegacy::Normal; + key.data.shadow = KLegacy::Out; + + if (priv->lastWidget && priv->lastWidget->inherits("QComboBox")) + key.data.state = KLegacy::Prelight; + + QPixmap *pix = gobj->draw(key, w, h, "optionmenu"); + + if (pix && ! pix->isNull()) { + p->drawPixmap(x, y, *pix); + } else { + KStyle::drawComboButton(p, x, y, w, h, g, sunken, editable, enabled, b); + return; + } + + QRect rect = comboButtonRect(x, y, w, h); + int tw = w - rect.width() - rect.right() - rect.left(); + int th = rect.height(); + + key.data.function = KLegacy::Tab; + key.data.state = KLegacy::Normal; + pix = gobj->draw(key, tw, th, "optionmenutab"); + + if (pix && ! pix->isNull()) + p->drawPixmap(x + rect.width() + rect.left() + ((18 - pix->width()) / 2), + y + rect.y() + ((rect.height() - pix->height()) / 2), *pix); +} + + +QRect KLegacyStyle::comboButtonRect(int x, int y, int w, int h) { + GtkObject *gobj = priv->gtkDict.find(QComboBox::staticMetaObject()); + + if (! gobj) { + return KStyle::comboButtonRect(x, y, w, h); + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Box; + KLegacyImageData *id = gobj->getImageData(key, "optionmenu"); + + if (! id) { + return KStyle::comboButtonRect(x, y, w, h); + } + + return QRect(x + id->border.left() + 1, y + id->border.top() + 1, + w - id->border.left() - id->border.right() - 18, + h - id->border.top() - id->border.bottom() - 2); +} + + +QRect KLegacyStyle::comboButtonFocusRect(int x, int y, int w, int h) { + return comboButtonRect(x, y, w, h); +} + + +QStyle::ScrollControl KLegacyStyle::scrollBarPointOver(const QScrollBar *scrollbar, + int sliderStart, const QPoint &p) +{ + return QCommonStyle::scrollBarPointOver(scrollbar, sliderStart, p); +} + + +void KLegacyStyle::scrollBarMetrics(const QScrollBar *scrollbar, int &sliderMin, + int &sliderMax, int &sliderLength, int &buttonDim) +{ + int maxLength; + int b = defaultFrameWidth(); + int length = ((scrollbar->orientation() == QScrollBar::Horizontal) ? + scrollbar->width() : scrollbar->height()); + int extent = ((scrollbar->orientation() == QScrollBar::Horizontal) ? + scrollbar->height() : scrollbar->width()); + + if (length > ((extent - (b * 2) - 1) * 2) + (b * 2)) + buttonDim = extent - (b * 2); + else + buttonDim = ((length - (b * 2)) / 2) - 1; + + sliderMin = b + buttonDim; + maxLength = length - (b * 2) - (buttonDim * 2); + + if (scrollbar->maxValue() == scrollbar->minValue()) { + sliderLength = maxLength - 2; + } else { + uint range = scrollbar->maxValue() - scrollbar->minValue(); + + sliderLength = (scrollbar->pageStep() * maxLength) / + (range + scrollbar->pageStep()); + + if (sliderLength < buttonDim || range > (INT_MAX / 2)) + sliderLength = buttonDim; + if (sliderLength >= maxLength) + sliderLength = maxLength - 2; + } + + sliderMax = sliderMin + maxLength - sliderLength; + + sliderMin += 1; + sliderMax -= 1; +} + + +void KLegacyStyle::drawScrollBarControls(QPainter *p, const QScrollBar *scrollbar, + int start, uint controls, uint active) +{ + if (! scrollbar->isVisible()) return; + + GtkObject *gobj = priv->gtkDict.find(QScrollBar::staticMetaObject()); + + if (! gobj) { + KStyle::drawScrollBarControls(p, scrollbar, start, controls, active); + return; + } + + KLegacyImageDataKey gkey; + gkey.cachekey = 0; + gkey.data.function = KLegacy::Box; + gkey.data.orientation = scrollbar->orientation() + 1; + + KLegacyImageData *groove_id = gobj->getImageData(gkey, "trough"); + + if (! groove_id) { + KStyle::drawScrollBarControls(p, scrollbar, start, controls, active); + return; + } + + int sliderMin; + int sliderMax; + int sliderLen; + int buttonDim; + scrollBarMetrics(scrollbar, sliderMin, sliderMax, sliderLen, buttonDim); + + // the rectangle for the slider + QRect slider( + // x + ((scrollbar->orientation() == Vertical) ? + defaultFrameWidth() : start), + + // y + ((scrollbar->orientation() == Vertical) ? + start : defaultFrameWidth()), + + // w + ((scrollbar->orientation() == Vertical) ? + buttonDim : sliderLen), + + // h + ((scrollbar->orientation() == Vertical) ? + sliderLen : buttonDim)); + + KLegacyImageDataKey skey; + skey.cachekey = 0; + skey.data.function = KLegacy::Box; + skey.data.orientation = scrollbar->orientation() + 1; + + if ((active & Slider) || (priv->hovering && slider.contains(priv->mousePos))) + skey.data.state = KLegacy::Prelight; + else + skey.data.state = KLegacy::Normal; + + KLegacyImageData *slider_id = gobj->getImageData(skey, "slider"); + + if (! slider_id) { + KStyle::drawScrollBarControls(p, scrollbar, start, controls, active); + return; + } + + QPixmap *groove_pm = gobj->draw(groove_id, scrollbar->width(), scrollbar->height()); + + if ((! groove_pm) || (groove_pm->isNull())) { + groove_pm = 0; + } + + QPixmap *slider_pm = gobj->draw(slider_id, slider.width(), slider.height()); + + if ((! slider_pm) || (slider_pm->isNull())) { + slider_pm = 0; + } + + QPixmap buf(scrollbar->size()); + { + QPainter p2(&buf); + + if (groove_pm) { + p2.drawTiledPixmap(scrollbar->rect(), *groove_pm); + } + + if (slider_pm) { + p2.drawTiledPixmap(slider, *slider_pm); + } + + // arrows + int x, y; + x = y = defaultFrameWidth(); + + drawArrow(&p2, ((scrollbar->orientation() == Vertical) ? + UpArrow : LeftArrow), + (active & SubLine), x, y, + buttonDim, + buttonDim, + scrollbar->colorGroup(), true); + + if (scrollbar->orientation() == Vertical) + y = scrollbar->height() - buttonDim - defaultFrameWidth(); + else + x = scrollbar->width() - buttonDim - defaultFrameWidth(); + + drawArrow(&p2, ((scrollbar->orientation() == Vertical) ? + DownArrow : RightArrow), + (active & AddLine), x, y, + buttonDim, + buttonDim, + scrollbar->colorGroup(), true); + } + p->drawPixmap(0, 0, buf); +} + + +void KLegacyStyle::drawSlider(QPainter *p, int x, int y, int w, int h, const QColorGroup &g, + Orientation orientation, bool tickAbove, bool tickBelow) +{ + GtkObject *gobj = priv->gtkDict.find(QSlider::staticMetaObject()); + + if (! gobj) { + KStyle::drawSlider(p, x, y, w, h, g, orientation, tickAbove, tickBelow); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Box; + key.data.shadow = KLegacy::Out; + key.data.state = KLegacy::Normal; + key.data.orientation = orientation + 1; + + QPixmap *pix = gobj->draw(key, w, h, "slider"); + + if (pix && ! pix->isNull()) + p->drawPixmap(x, y, *pix); + else + KStyle::drawSlider(p, x, y, w, h, g, orientation, tickAbove, tickBelow); +} + + + +void KLegacyStyle::drawSliderGroove(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, QCOORD c, Orientation o) +{ + GtkObject *gobj = priv->gtkDict.find(QSlider::staticMetaObject()); + + if (! gobj) { + KStyle::drawSliderGroove(p, x, y, w, h, g, c, o); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Box; + key.data.shadow = KLegacy::In; + key.data.state = KLegacy::Active; + key.data.orientation = o + 1; + + QPixmap *pix = gobj->draw(key, w, h, "trough"); + + if (pix && ! pix->isNull()) + p->drawPixmap(x, y, *pix); + else + KStyle::drawSliderGroove(p, x, y, w, h, g, c, o); +} + + +void KLegacyStyle::drawArrow(QPainter *p, ArrowType type, bool down, + int x, int y, int w, int h, + const QColorGroup &g, bool enabled, const QBrush *b) +{ + GtkObject *gobj = priv->gtkDict.find(&arrow_ptr); + + if (! gobj) { + KStyle::drawArrow(p, type, down, x, y, w, h, g, enabled, b); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Arrow; + key.data.state = (down) ? KLegacy::Active : KLegacy::Normal; + key.data.shadow = (down) ? KLegacy::In : KLegacy::NoShadow; + key.data.arrowDirection = type + 1; + + if ((! down) && priv->hovering && + QRect(x, y, w, h).contains(priv->mousePos)) { + key.data.state = KLegacy::Prelight; + } + + QPixmap *pix = gobj->draw(key, w, h, "arrow"); + + if (pix && ! pix->isNull()) + p->drawPixmap(x, y, *pix); + else + KStyle::drawArrow(p, type, down, x, y, w, h, g, enabled, b); +} + + +void KLegacyStyle::drawMenuArrow(QPainter *p, ArrowType type, bool down, + int x, int y, int w, int h, + const QColorGroup &g, bool enabled, const QBrush *b) +{ + GtkObject *gobj = priv->gtkDict.find(&menuitem_ptr); + + if (! gobj) { + KStyle::drawArrow(p, type, down, x, y, w, h, g, enabled, b); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Arrow; + key.data.state = (down) ? KLegacy::Active : KLegacy::Normal; + key.data.shadow = (down) ? KLegacy::In : KLegacy::NoShadow; + key.data.arrowDirection = type + 1; + + QPixmap *pix = gobj->draw(key, w, h, "arrow"); + + if (pix && ! pix->isNull()) + p->drawPixmap(x + ((w - pix->width()) / 2), + y + ((h - pix->height()) / 2), *pix); + else + KStyle::drawArrow(p, type, down, x, y, w, h, g, enabled, b); +} + + +void KLegacyStyle::drawPanel(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool sunken, int, const QBrush *brush) +{ + KStyle::drawPanel(p, x, y, w, h, g, sunken, 1, brush); +} + + +void KLegacyStyle::drawPopupPanel(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, int, const QBrush *fill) +{ + QBrush brush = (fill) ? *fill : g.brush(QColorGroup::Background); + + p->fillRect(x, y, w, h, brush); +} + + +void KLegacyStyle::drawCheckMark(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool activated, bool disabled) +{ + GtkObject *gobj = priv->gtkDict.find(&checkmenuitem_ptr); + + if (! gobj) { + KStyle::drawCheckMark(p, x, y, w, h, g, activated, disabled); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Check; + key.data.shadow = (disabled) ? KLegacy::Out : KLegacy::In; + + QPixmap *pix = gobj->draw(key, w, h); + + if (pix && (! pix->isNull())) { + x += (w - pix->width()) / 2; + y += (h - pix->height()) / 2; + p->drawPixmap(x, y, *pix); + } else { + KStyle::drawCheckMark(p, x, y, w, h, g, activated, disabled); + } +} + + +void KLegacyStyle::drawSplitter(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, Orientation orientation) +{ + if (orientation == Horizontal) { + int xpos = x + (w / 2); + int kpos = 10; + int ksize = splitterWidth() - 2; + + qDrawShadeLine(p, xpos, kpos + ksize - 1, xpos, h, g); + drawBevelButton(p, xpos - (splitterWidth() / 2) + 1, kpos, ksize, ksize, + g, false, &g.brush(QColorGroup::Button)); + qDrawShadeLine(p, xpos, 0, xpos, kpos, g); + } else { + int ypos = y + (h / 2); + int kpos = w - 10 - splitterWidth(); + int ksize = splitterWidth() - 2; + + qDrawShadeLine(p, 0, ypos, kpos, ypos, g); + drawBevelButton(p, kpos, ypos - (splitterWidth() / 2) + 1, ksize, ksize, + g, false, &g.brush(QColorGroup::Button)); + qDrawShadeLine(p, kpos + ksize - 1, ypos, w, ypos, g); + } +} + + +void KLegacyStyle::drawTab(QPainter *p, const QTabBar *tabbar, QTab *tab, bool selected) +{ + GtkObject *gobj = priv->gtkDict.find(QTabBar::staticMetaObject()); + + if (! gobj) { + KStyle::drawTab(p, tabbar, tab, selected); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Extension; + key.data.state = (! selected) ? KLegacy::Active : KLegacy::Normal; + key.data.shadow = KLegacy::Out; + key.data.gapSide = (tabbar->shape() == QTabBar::RoundedAbove || + tabbar->shape() == QTabBar::TriangularAbove) ? + KLegacy::Bottom : KLegacy::Top; + + int ry = tab->r.top(), rh = tab->r.height(); + + if (! selected) { + rh -= 2; + + if (tabbar->shape() == QTabBar::RoundedAbove || + tabbar->shape() == QTabBar::TriangularAbove) + ry += 2; + } + + QPixmap *pix = gobj->draw(key, tab->r.width(), rh, "tab"); + + + if (pix && ! pix->isNull()) + p->drawPixmap(tab->r.left(), ry, *pix); + else + KStyle::drawTab(p, tabbar, tab, selected); +} + + +void KLegacyStyle::drawKBarHandle(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, KToolBarPos type, QBrush *fill) +{ + GtkObject *gobj = priv->gtkDict.find(QToolBar::staticMetaObject()); + + if (! gobj) { + KStyle::drawKBarHandle(p, x, y, w, h, g, type, fill); + return; + } + + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Handle; + key.data.state = KLegacy::Normal; + key.data.shadow = KLegacy::Out; + key.data.orientation = (type == Left || type == Right) ? + Vertical + 1: Horizontal + 1; + + QPixmap *pix = gobj->draw(key, w, h, "handle"); + + if (pix && ! pix->isNull()) + p->drawPixmap(x, y, *pix); +} + + +void KLegacyStyle::drawKickerHandle(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, QBrush *fill) +{ + drawKBarHandle(p, x, y, w, h, g, Left, fill); +} + + +void KLegacyStyle::drawKickerAppletHandle(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, QBrush *fill) +{ + drawKBarHandle(p, x, y, w, h, g, Left, fill); +} + + +void KLegacyStyle::drawKickerTaskButton(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, const QString &title, + bool active, QPixmap *icon, QBrush *fill) +{ + drawBevelButton(p, x, y, w, h, g, active, fill); + + const int pxWidth = 20; + int textPos = pxWidth; + + QRect br(buttonRect(x, y, w, h)); + + if (active) + p->translate(1,1); + + if (icon && ! icon->isNull()) { + int dx = (pxWidth - icon->width()) / 2; + int dy = (h - icon->height()) / 2; + + p->drawPixmap(br.x() + dx, dy, *icon); + } + + QString s(title); + + static const QString &modStr = KGlobal::staticQString( + QString::fromUtf8("[") + i18n("modified") + QString::fromUtf8("]")); + + int modStrPos = s.find(modStr); + + if (modStrPos != -1) { + s.remove(modStrPos, modStr.length()+1); + + QPixmap modPixmap = SmallIcon("modified"); + + int dx = (pxWidth - modPixmap.width()) / 2; + int dy = (h - modPixmap.height()) / 2; + + p->drawPixmap(br.x() + textPos + dx, dy, modPixmap); + + textPos += pxWidth; + } + + if (! s.isEmpty()) { + if (p->fontMetrics().width(s) > br.width() - textPos) { + int maxLen = br.width() - textPos - p->fontMetrics().width("..."); + + while ( (! s.isEmpty()) && (p->fontMetrics().width(s) > maxLen)) + s.truncate(s.length() - 1); + + s.append("..."); + } + + p->setPen((active) ? g.foreground() : g.buttonText()); + + p->drawText(br.x() + textPos, -1, w - textPos, h, AlignVCenter | AlignLeft, s); + } +} + + +bool KLegacyStyle::eventFilter(QObject *obj, QEvent *e) { + switch (e->type()) { + case QEvent::Resize: + { + QWidget *w = (QWidget *) obj; + + if (w->inherits("QPopupMenu") && w->width() < 700) { + GtkObject *gobj = priv->gtkDict.find(QPopupMenu::staticMetaObject()); + + if (gobj) { + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Box; + key.data.state = KLegacy::Normal; + key.data.shadow = KLegacy::Out; + + QPixmap *pix = gobj->draw(key, w->width(), w->height(), "menu"); + + if (pix && ! pix->isNull()) { + QPalette pal = w->palette(); + + // active + QBrush brush = pal.brush(QPalette::Active, + QColorGroup::Background); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Active, + QColorGroup::Background, brush); + + brush = pal.brush(QPalette::Active, + QColorGroup::Button); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Active, + QColorGroup::Button, brush); + + // inactive + brush = pal.brush(QPalette::Inactive, + QColorGroup::Background); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Inactive, + QColorGroup::Background, brush); + + brush = pal.brush(QPalette::Inactive, + QColorGroup::Button); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Inactive, + QColorGroup::Button, brush); + + // disabled + brush = pal.brush(QPalette::Disabled, + QColorGroup::Background); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Disabled, + QColorGroup::Background, brush); + + brush = pal.brush(QPalette::Disabled, + QColorGroup::Button); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Disabled, + QColorGroup::Button, brush); + + w->setPalette(pal); + } + } + } else if (w->isTopLevel() || w->inherits("QWorkspaceChild")) { + GtkObject *gobj = priv->gtkDict.find(QMainWindow::staticMetaObject()); + + if (gobj) { + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::FlatBox; + + QPixmap *p = gobj->draw(key, w->width(), w->height(), "base"); + + if (p && (! p->isNull())) + w->setBackgroundPixmap(*p); + } + } else if (w->inherits("QLineEdit")) { + GtkObject *gobj = priv->gtkDict.find(QLineEdit::staticMetaObject()); + + if (gobj) { + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::FlatBox; + key.data.shadow = KLegacy::NoShadow; + key.data.state = (w->isEnabled()) ? KLegacy::Normal : KLegacy::Insensitive; + + QPixmap *pix = gobj->draw(key, w->width(), w->height(), + "entry_bg"); + + if (pix && (! pix->isNull())) { + QPalette pal = w->palette(); + + // active + QBrush brush = pal.brush(QPalette::Active, + QColorGroup::Base); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Active, + QColorGroup::Base, brush); + + // inactive + brush = pal.brush(QPalette::Inactive, + QColorGroup::Base); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Inactive, + QColorGroup::Base, brush); + + // disabled + brush = pal.brush(QPalette::Disabled, + QColorGroup::Base); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Disabled, + QColorGroup::Base, brush); + + w->setPalette(pal); + } + } + } else if (w->inherits("QMenuBar") || + w->inherits("QToolBar")) { + GtkObject *gobj = priv->gtkDict.find(QMenuBar::staticMetaObject()); + + if (gobj) { + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::Box; + key.data.state = KLegacy::Normal; + key.data.shadow = KLegacy::Out; + + QPixmap *pix = gobj->draw(key, w->width(), w->height(), + "menubar"); + if (pix && (! pix->isNull())) { + QPalette pal = w->palette(); + + // active + QBrush brush = pal.brush(QPalette::Active, + QColorGroup::Background); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Active, + QColorGroup::Background, brush); + + brush = pal.brush(QPalette::Active, + QColorGroup::Button); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Active, + QColorGroup::Button, brush); + + // inactive + brush = pal.brush(QPalette::Inactive, + QColorGroup::Background); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Inactive, + QColorGroup::Background, brush); + + brush = pal.brush(QPalette::Inactive, + QColorGroup::Button); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Inactive, + QColorGroup::Button, brush); + + // disabled + brush = pal.brush(QPalette::Disabled, + QColorGroup::Background); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Disabled, + QColorGroup::Background, brush); + + brush = pal.brush(QPalette::Disabled, + QColorGroup::Button); + brush.setPixmap(*pix); + pal.setBrush(QPalette::Disabled, + QColorGroup::Button, brush); + + w->setPalette(pal); + } + } + } + + break; + } + + case QEvent::Enter: + { + if (obj->inherits("QPushButton") || + obj->inherits("QComboBox") || + obj->inherits("QSlider") || + obj->inherits("QScrollbar")) { + priv->lastWidget = (QWidget *) obj; + priv->lastWidget->repaint(false); + } else if (obj->inherits("QRadioButton")) { + QWidget *w = (QWidget *) obj; + + if (! w->isTopLevel() && w->isEnabled()) { + GtkObject *gobj = priv->gtkDict.find(QRadioButton::staticMetaObject()); + + if (gobj) { + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::FlatBox; + + QPixmap *pix = gobj->draw(key, w->width(), w->height()); + + if (pix && (! pix->isNull())) { + QPalette pal = w->palette(); + QBrush brush = pal.brush(QPalette::Normal, + QColorGroup::Background); + + brush.setPixmap(*pix); + pal.setBrush(QPalette::Normal, + QColorGroup::Background, brush); + + w->setPalette(pal); + w->setBackgroundMode(QWidget::PaletteBackground); + w->setBackgroundOrigin(QWidget::WidgetOrigin); + } + } + } + } else if (obj->inherits("QCheckBox")) { + QWidget *w = (QWidget *) obj; + + if (! w->isTopLevel() && w->isEnabled()) { + GtkObject *gobj = priv->gtkDict.find(QCheckBox::staticMetaObject()); + + if (gobj) { + KLegacyImageDataKey key; + key.cachekey = 0; + key.data.function = KLegacy::FlatBox; + + QPixmap *pix = gobj->draw(key, w->width(), w->height()); + + if (pix && (! pix->isNull())) { + QPalette pal = w->palette(); + QBrush brush = pal.brush(QPalette::Normal, + QColorGroup::Background); + + brush.setPixmap(*pix); + pal.setBrush(QPalette::Normal, + QColorGroup::Background, brush); + + w->setPalette(pal); + w->setBackgroundMode(QWidget::PaletteBackground); + w->setBackgroundOrigin(QWidget::WidgetOrigin); + } + } + } + } + + break; + } + + case QEvent::Leave: + { + if (obj == priv->lastWidget) { + priv->lastWidget = 0; + ((QWidget *) obj)->repaint(false); + } else if (obj->inherits("QRadioButton") || + obj->inherits("QCheckBox")) { + QWidget *w = (QWidget *) obj; + + if (! w->isTopLevel()) { + w->setBackgroundMode(QWidget::X11ParentRelative); + w->setBackgroundOrigin(QWidget::WidgetOrigin); + w->repaint(true); + } + } + + break; + } + + case QEvent::MouseMove: + { + QMouseEvent *me = (QMouseEvent *) e; + priv->mousePos = me->pos(); + if (obj->inherits("QScrollBar") && + (! (me->state() & (LeftButton | MidButton | RightButton)))) { + priv->hovering = true; + ((QWidget *) obj)->repaint(false); + priv->hovering = false; + } + + break; + } + + default: + { + break; + } + } + + return KStyle::eventFilter(obj, e); +} diff --git a/kstyles/klegacy/klegacystyle.h b/kstyles/klegacy/klegacystyle.h new file mode 100644 index 000000000..c38e7ac80 --- /dev/null +++ b/kstyles/klegacy/klegacystyle.h @@ -0,0 +1,148 @@ +/* + + Copyright (c) 2000 KDE Project + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + */ + +#ifndef __KLegacyStyle_hh +#define __KLegacyStyle_hh + +#include <kstyle.h> + +// forward declaration +class KLegacyStylePrivate; + + +class Q_EXPORT KLegacyStyle : public KStyle { + Q_OBJECT +public: + KLegacyStyle(void); + virtual ~KLegacyStyle(void); + + virtual int defaultFrameWidth() const; + + virtual void polish(QApplication *); + virtual void polish(QWidget *); + virtual void polishPopupMenu(QPopupMenu *); + virtual void unPolish(QWidget *); + virtual void unPolish(QApplication *); + + // combo box + virtual void drawComboButton(QPainter *, int, int, int, int, const QColorGroup &, + bool = false, bool = false, bool = true, + const QBrush * = 0); + virtual QRect comboButtonRect(int, int, int, int); + virtual QRect comboButtonFocusRect(int, int, int, int); + + // menubar items + virtual void drawMenuBarItem(QPainter *, int, int, int, int, QMenuItem *, + QColorGroup &, bool, bool); + virtual void drawKMenuItem(QPainter *, int, int, int, int, const QColorGroup &, bool, + QMenuItem *, QBrush * = 0); + + // toolbar stuffs + virtual void drawKBarHandle(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, KToolBarPos type, QBrush *fill = 0); + virtual void drawKickerHandle(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, QBrush *fill = 0); + virtual void drawKickerAppletHandle(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, QBrush *fill = 0); + virtual void drawKickerTaskButton(QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, const QString &title, bool active, + QPixmap *icon = 0, QBrush *fill = 0); + + // arrows + virtual void drawArrow(QPainter *, ArrowType, bool, int, int, int, int, + const QColorGroup &, bool, const QBrush * = 0); + + // button stuffs + virtual void drawButton(QPainter *, int, int, int, int, const QColorGroup &g, + bool = false, const QBrush * = 0); + virtual void drawPushButton(QPushButton *, QPainter *); + virtual void drawBevelButton(QPainter *, int, int, int, int, + const QColorGroup &, bool = false, + const QBrush * = 0); + + // indicators (QCheckBox) + virtual void drawCheckMark(QPainter *, int, int, int, int, const QColorGroup &, + bool = false, bool = true); + virtual void drawIndicator(QPainter *, int, int, int, int, const QColorGroup &, + int, bool = false, bool = true); + virtual void drawIndicatorMask(QPainter *, int, int, int, int, int); + virtual QSize indicatorSize(void) const; + + // exclusive indicators (QRadioButton) + virtual void drawExclusiveIndicator(QPainter *, int, int, int, int, + const QColorGroup &, bool, bool = false, + bool = true); + virtual void drawExclusiveIndicatorMask(QPainter *, int, int, int, int, bool); + virtual QSize exclusiveIndicatorSize(void) const; + + // popup menus + virtual void drawPopupPanel(QPainter *, int, int, int, int, const QColorGroup &, + int = 2, const QBrush * = 0); + virtual void drawPopupMenuItem(QPainter *, bool, int, int, QMenuItem *, + const QPalette &, bool, bool, int, int, int, int); + + + // scrollbars + virtual ScrollControl scrollBarPointOver(const QScrollBar *, int, const QPoint &); + virtual void scrollBarMetrics(const QScrollBar *, int &, int &, int &, int &); + virtual void drawScrollBarControls(QPainter *, const QScrollBar *, + int, uint, uint); + + // sliders + virtual void drawSlider(QPainter *, int , int , int , int , + const QColorGroup &, Orientation, bool, bool); + virtual void drawSliderGroove(QPainter *, int, int, int, int, const QColorGroup &, + QCOORD, Orientation); + + // panel + virtual void drawPanel(QPainter *, int, int, int, int, const QColorGroup &, + bool = false, int = 1, const QBrush * = 0); + + // splitters + virtual void drawSplitter(QPainter *, int, int, int, int, + const QColorGroup &, Orientation); + + // tabs + virtual void drawTab(QPainter *, const QTabBar *, QTab *, bool); + + +protected: + bool eventFilter(QObject *, QEvent *); + + void drawMenuArrow(QPainter *, ArrowType, bool, int, int, int, int, + const QColorGroup &, bool, const QBrush * = 0); + + +private: + KLegacyStylePrivate *priv; + +#if defined(Q_DISABLE_COPY) + KLegacyStyle( const KLegacyStyle & ); + KLegacyStyle& operator=( const KLegacyStyle & ); +#endif + +}; + + +#endif // __KLegacyStyle_hh diff --git a/kstyles/klegacy/plugin.cpp b/kstyles/klegacy/plugin.cpp new file mode 100644 index 000000000..a146de2c3 --- /dev/null +++ b/kstyles/klegacy/plugin.cpp @@ -0,0 +1,29 @@ +#include "klegacystyle.h" +#include <klocale.h> + +extern "C" { + KStyle* allocate(); + int minor_version(); + int major_version(); + const char *description(); +} + +KStyle* allocate() +{ + return(new KLegacyStyle()); +} + +int minor_version() +{ + return(0); +} + +int major_version() +{ + return(1); +} + +const char *description() +{ + return(i18n("KDE LegacyStyle plugin").utf8()); +} diff --git a/kstyles/kthemestyle/Makefile.am b/kstyles/kthemestyle/Makefile.am new file mode 100644 index 000000000..0edb271b4 --- /dev/null +++ b/kstyles/kthemestyle/Makefile.am @@ -0,0 +1,29 @@ + +# This file is part of the KDE libraries +# Copyright (C) 1997 Matthias Kalle Dalheimer ([email protected]) +# (C) 1997 Stephan Kulow ([email protected]) + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. + +# This library 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 +# Library General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this library; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +AM_CPPFLAGS = -DQT_PLUGIN + +INCLUDES = -I$(top_srcdir)/kdefx $(all_includes) +noinst_HEADERS = kthemestyle.h kthemebase.h kstyledirs.h +kde_style_LTLIBRARIES = kthemestyle.la +kthemestyle_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +kthemestyle_la_LIBADD = ../../kdefx/libkdefx.la ../../kdecore/libkdecore.la +kthemestyle_la_SOURCES = kthemebase.cpp kthemestyle.cpp kstyledirs.cpp +kthemestyle_la_METASOURCES = AUTO diff --git a/kstyles/kthemestyle/kstyledirs.cpp b/kstyles/kthemestyle/kstyledirs.cpp new file mode 100644 index 000000000..b77d4d56b --- /dev/null +++ b/kstyles/kthemestyle/kstyledirs.cpp @@ -0,0 +1,48 @@ +/* + $Id$ + + Simple helper routines for style's use of KStandardDirs with QSettings, etc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + + This file is part of the KDE libraries +*/ + +#include <qfile.h> +#include <kstandarddirs.h> +#include "kstyledirs.h" + +KStyleDirs* KStyleDirs::instance = 0; + +KStyleDirs::KStyleDirs() +{ + addResourceType( "themepixmap", KStandardDirs::kde_default( "data" ) + "kstyle/pixmaps/" ); + addResourceType( "themerc", KStandardDirs::kde_default( "data" ) + "kstyle/themes/" ); +} + +KStyleDirs::~KStyleDirs() +{ +} + +void KStyleDirs::addToSearch( const char* type, QSettings& s ) const +{ + const QStringList & dirs = resourceDirs(type); + for ( int c = dirs.size()-1; c >= 0 ; c-- ) + { + s.insertSearchPath( QSettings::Unix, dirs[ c ]); + } +} + diff --git a/kstyles/kthemestyle/kstyledirs.h b/kstyles/kthemestyle/kstyledirs.h new file mode 100644 index 000000000..b23457a07 --- /dev/null +++ b/kstyles/kthemestyle/kstyledirs.h @@ -0,0 +1,82 @@ +/* + $Id$ + + This file is part of the KDE libraries + (c) 2002 Maksim Orlovich <[email protected]>, + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSTYLE_DIRS_H +#define KSTYLE_DIRS_H + + +#include <qsettings.h> +#include <qstringlist.h> +#include <kstandarddirs.h> + +/** +* @short Access to the standard KDE directories for the pixmap style +* @author Maksim Orlovich<[email protected]> is responsible for this file, + but all the interesting work is done by KStandardDirs +* @version $Id$ +* +* This class provides a this wrapper for styles around KStandardDirs, +* permitting integration with QSettings and easy loading of pixmaps +* +* It add share/apps/kstyle/themes as "themerc", +* share/apps/kstyle/pixmaps "themepixmap" +*/ +class KStyleDirs: public KStandardDirs +{ +public: + static KStyleDirs* dirs() + { + if ( !instance) + instance = new KStyleDirs; + return instance; + } + + static void release() + { + delete instance; + instance = 0; + } + + /** + Adds all of KDE directories of type type to the seach path of q. + + For example, when one does the following: + QSettings settings; + KStyleDirs dirs; + dirs.addToSearch("config",settings); + + The one can do settings.readEntry("kstyle/KDE/WidgetStyle") to access a settings in kstylerc. + */ + void addToSearch( const char* type, QSettings& q) const; //Better name? + +protected: + static KStyleDirs* instance; + /** + Creates an instance of the class, and calculates the path information. + */ + KStyleDirs(); + KStyleDirs(const KStyleDirs&); + KStyleDirs& operator= (const KStyleDirs&); + + virtual ~KStyleDirs(); +}; + +#endif diff --git a/kstyles/kthemestyle/kthemebase.cpp b/kstyles/kthemestyle/kthemebase.cpp new file mode 100644 index 000000000..bd463e28e --- /dev/null +++ b/kstyles/kthemestyle/kthemebase.cpp @@ -0,0 +1,1826 @@ +/* + $Id$ + + This file is part of the KDE libraries + Copyright (C) 1999 Daniel M. Duley <[email protected]> + + KDE3 port (C) 2001-2002 Maksim Orlovich <[email protected]> + Port version 0.9.7 + + Palette setup code is from KApplication, + Copyright (C) 1997 Matthias Kalle Dalheimer ([email protected]) + Copyright (C) 1998, 1999, 2000 KDE Team + + Includes code portions from the KDE HighColor style. + + KDE3 HighColor Style + Copyright (C) 2001 Karol Szwed <[email protected]> + (C) 2001 Fredrik H�glund <[email protected]> + + Drawing routines adapted from the KDE2 HCStyle, + Copyright (C) 2000 Daniel M. Duley <[email protected]> + (C) 2000 Dirk Mueller <[email protected]> + (C) 2001 Martijn Klingens <[email protected]> + + + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kthemebase.h" +#include <kpixmapeffect.h> +#include <qimage.h> +#include <qpainter.h> +#include <qbitmap.h> +#include <stdlib.h> + +#include <qsettings.h> +#include <qapplication.h> +#include <qscrollbar.h> + +typedef QMap<QString, QString> Prop; + +template class QIntCache<KThemePixmap> +; + +/* +Bugs: +Can't delete old slider image when calculating the rotated one for some reason. +*/ + +//Shamelessly stolen from KConfigBase +static QColor readColorEntry( QSettings* s, const char *pKey, + const QColor* pDefault ) +{ + QColor aRetColor; + int nRed = 0, nGreen = 0, nBlue = 0; + + QString aValue = s->readEntry( pKey ); + if ( !aValue.isEmpty() ) + { + if ( aValue.at( 0 ) == '#' ) + { + aRetColor.setNamedColor( aValue ); + } + else + { + bool bOK; + // find first part (red) + int nIndex = aValue.find( ',' ); + if ( nIndex == -1 ) + { + // return a sensible default -- Bernd + if ( pDefault ) + aRetColor = *pDefault; + return aRetColor; + } + + nRed = aValue.left( nIndex ).toInt( &bOK ); + + // find second part (green) + int nOldIndex = nIndex; + nIndex = aValue.find( ',', nOldIndex + 1 ); + + if ( nIndex == -1 ) + { + // return a sensible default -- Bernd + if ( pDefault ) + aRetColor = *pDefault; + return aRetColor; + } + nGreen = aValue.mid( nOldIndex + 1, + nIndex - nOldIndex - 1 ).toInt( &bOK ); + + // find third part (blue) + nBlue = aValue.right( aValue.length() - nIndex - 1 ).toInt( &bOK ); + + aRetColor.setRgb( nRed, nGreen, nBlue ); + } + } + else + { + + if ( pDefault ) + aRetColor = *pDefault; + } + + return aRetColor; +} + + +static const char * const widgetEntries[] = + { // unsunken widgets (see header) + "PushButton", "ComboBox", "HSBarSlider", "VSBarSlider", "Bevel", "ToolButton", + "ScrollButton", "HScrollDeco", "VScrollDeco", "ComboDeco", "MenuItem", "Tab", + "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", + // sunken widgets + "PushButtonDown", "ComboBoxDown", "HSBarSliderDown", "VSBarSliderDown", + "BevelDown", "ToolButtonDown", "ScrollButtonDown", "HScrollDecoDown", + "VScrollDecoDown", "ComboDecoDown", "MenuItemDown", "TabDown", "SunkenArrowUp", + "SunkenArrowDown", "SunkenArrowLeft", "SunkenArrowRight", + // everything else + "HScrollGroove", "VScrollGroove", "Slider", "SliderGroove", "CheckBoxDown", + "CheckBox", "CheckBoxTri", "RadioDown", "Radio", "HBarHandle", "VBarHandle", + "ToolBar", "Splitter", "CheckMark", "MenuBar", "DisableArrowUp", + "DisableArrowDown", "DisableArrowLeft", "DisableArrowRight", "ProgressBar", + "ProgressBackground", "MenuBarItem", "Background", "RotSlider", + "RotInactiveTab", "RotActiveTab", + }; + +#define INHERIT_ITEMS 16 + + +class KThemeBasePrivate +{ +public: + /** Color overrides flags..*/ + bool overrideForeground; + bool overrideBackground; + bool overrideSelectForeground; + bool overrideSelectBackground; + bool overrideWindowForeground; + bool overrideWindowBackground; + + /** + * Colors to override defaults with.. + */ + QColor overrideForegroundCol; + QColor overrideBackgroundCol; + QColor overrideSelectForegroundCol; + QColor overrideSelectBackgroundCol; + QColor overrideWindowForegroundCol; + QColor overrideWindowBackgroundCol; + + int contrast; + + + QMap <QString, QMap<QString, QString> > props; + + QMap<const QPixmap*, QColor> colorCache; + + /* + A heuristic routine that tries to determine the avergae color of the image + Wouldn't work for things like sliders, etc. + */ + QColor pixmapAveColor( const QPixmap* p ) + { + if ( colorCache.contains( p ) ) + return colorCache[ p ]; + + QImage to_ave = p->convertToImage(); + double h = 0, s = 0, v = 0; + int count = 0; + int dh, ds, dv; + for ( int x = 0; x < p->width(); x++ ) + { + QColor pix( to_ave.pixel( x, p->height() / 2 ) ); + pix.hsv( &dh, &ds, &dv ); + h += dh; + s += ds; + v += dv; + count++; + } + + for ( int y = 0; y < p->height(); y++ ) + { + QColor pix( to_ave.pixel( p->width() / 2, y ) ); + pix.hsv( &dh, &ds, &dv ); + h += dh; + s += ds; + v += dv; + count++; + } + colorCache[ p ] = QColor( int( h / count + 0.5 ), int( s / count + 0.5 ), int( v / count + 0.5 ), QColor::Hsv ); + return colorCache[ p ]; + } +}; + + + +// This is used to encode the keys. I used to use masks but I think this +// bitfield is nicer :) I don't know why C++ coders don't use these more.. +// (mosfet) +struct kthemeKeyData +{ +unsigned int id : + 6; +unsigned int width : + 12; +unsigned int height : + 12; +unsigned int border : + 1; +unsigned int mask : + 1; +}; + +union kthemeKey{ + kthemeKeyData data; + unsigned int cacheKey; +}; + +void KThemeBase::generateBorderPix( int i ) +{ + // separate pixmap into separate components + if ( pbPixmaps[ i ] ) + { + // evidently I have to do masks manually... + const QBitmap * srcMask = pbPixmaps[ i ] ->mask(); + QBitmap destMask( pbWidth[ i ], pbWidth[ i ] ); + QPixmap tmp( pbWidth[ i ], pbWidth[ i ] ); + + bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, 0, pbWidth[ i ], pbWidth[ i ], + Qt::CopyROP, false ); + if ( srcMask ) + { + bitBlt( &destMask, 0, 0, srcMask, 0, 0, pbWidth[ i ], pbWidth[ i ], + Qt::CopyROP, false ); + tmp.setMask( destMask ); + } + pbPixmaps[ i ] ->setBorder( KThemePixmap::TopLeft, tmp ); + + bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ], 0, + pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false ); + if ( srcMask ) + { + bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ], + 0, pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false ); + tmp.setMask( destMask ); + } + pbPixmaps[ i ] ->setBorder( KThemePixmap::TopRight, tmp ); + + bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, pbPixmaps[ i ] ->height() - pbWidth[ i ], + pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false ); + if ( srcMask ) + { + bitBlt( &destMask, 0, 0, srcMask, 0, pbPixmaps[ i ] ->height() - pbWidth[ i ], + pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false ); + tmp.setMask( destMask ); + } + pbPixmaps[ i ] ->setBorder( KThemePixmap::BottomLeft, tmp ); + + bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ], + pbPixmaps[ i ] ->height() - pbWidth[ i ], pbWidth[ i ], pbWidth[ i ], + Qt::CopyROP, false ); + if ( srcMask ) + { + bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ], + pbPixmaps[ i ] ->height() - pbWidth[ i ], pbWidth[ i ], pbWidth[ i ], + Qt::CopyROP, false ); + tmp.setMask( destMask ); + } + pbPixmaps[ i ] ->setBorder( KThemePixmap::BottomRight, tmp ); + + tmp.resize( pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ] ); + destMask.resize( pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ] ); + bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbWidth[ i ], 0, + pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false ); + if ( srcMask ) + { + bitBlt( &destMask, 0, 0, srcMask, pbWidth[ i ], 0, + pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], + Qt::CopyROP, false ); + tmp.setMask( destMask ); + } + pbPixmaps[ i ] ->setBorder( KThemePixmap::Top, tmp ); + + bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbWidth[ i ], + pbPixmaps[ i ] ->height() - pbWidth[ i ], + pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false ); + if ( srcMask ) + { + bitBlt( &destMask, 0, 0, srcMask, pbWidth[ i ], + pbPixmaps[ i ] ->height() - pbWidth[ i ], + pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false ); + tmp.setMask( destMask ); + } + pbPixmaps[ i ] ->setBorder( KThemePixmap::Bottom, tmp ); + + tmp.resize( pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2 ); + destMask.resize( pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2 ); + bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, pbWidth[ i ], pbWidth[ i ], + pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2, Qt::CopyROP, false ); + if ( srcMask ) + { + bitBlt( &destMask, 0, 0, srcMask, 0, pbWidth[ i ], pbWidth[ i ], + pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2, Qt::CopyROP, false ); + tmp.setMask( destMask ); + } + + pbPixmaps[ i ] ->setBorder( KThemePixmap::Left, tmp ); + + bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ], + pbWidth[ i ], pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2, + Qt::CopyROP, false ); + if ( srcMask ) + { + bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ], + pbWidth[ i ], pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2, + Qt::CopyROP, false ); + tmp.setMask( destMask ); + } + pbPixmaps[ i ] ->setBorder( KThemePixmap::Right, tmp ); + } + else + qWarning( "KThemeBase: Tried making border from empty pixmap\n" ); +} + + +void KThemeBase::copyWidgetConfig( int sourceID, int destID, QString *pixnames, + QString *brdnames ) +{ + scaleHints[ destID ] = scaleHints[ sourceID ]; + gradients[ destID ] = gradients[ sourceID ]; + blends[ destID ] = blends[ sourceID ]; + bContrasts[ destID ] = bContrasts[ sourceID ]; + borders[ destID ] = borders[ sourceID ]; + highlights[ destID ] = highlights[ sourceID ]; + + if ( grLowColors[ sourceID ] ) + grLowColors[ destID ] = new QColor( *grLowColors[ sourceID ] ); + else + grLowColors[ destID ] = NULL; + + if ( grHighColors[ sourceID ] ) + grHighColors[ destID ] = new QColor( *grHighColors[ sourceID ] ); + else + grHighColors[ destID ] = NULL; + + if ( colors[ sourceID ] ) + colors[ destID ] = new QColorGroup( *colors[ sourceID ] ); + else + colors[ destID ] = NULL; + + // pixmap + pixnames[ destID ] = pixnames[ sourceID ]; + duplicate[ destID ] = false; + pixmaps[ destID ] = NULL; + images[ destID ] = NULL; + if ( !pixnames[ destID ].isEmpty() ) + { + if ( scaleHints[ sourceID ] == TileScale && blends[ sourceID ] == 0.0 ) + { + pixmaps[ destID ] = pixmaps[ sourceID ]; + duplicate[ destID ] = true; + } + if ( !duplicate[ destID ] ) + { + pixmaps[ destID ] = loadPixmap( pixnames[ destID ] ); + if ( scaleHints[ destID ] == TileScale && blends[ destID ] == 0.0 ) + images[ destID ] = NULL; + else + images[ destID ] = loadImage( pixnames[ destID ] ); + } + } + + // border pixmap + pbDuplicate[ destID ] = false; + pbPixmaps[ destID ] = NULL; + pbWidth[ destID ] = pbWidth[ sourceID ]; + brdnames[ destID ] = brdnames[ sourceID ]; + if ( !brdnames[ destID ].isEmpty() ) + { + pbPixmaps[ destID ] = pbPixmaps[ sourceID ]; + pbDuplicate[ destID ] = true; + } + + if ( sourceID == ActiveTab && destID == InactiveTab ) + aTabLine = iTabLine; + else if ( sourceID == InactiveTab && destID == ActiveTab ) + iTabLine = aTabLine; +} + +void KThemeBase::readConfig( Qt::GUIStyle /*style*/ ) +{ +#define PREBLEND_ITEMS 12 + static const WidgetType preBlend[] = + { + Slider, IndicatorOn, IndicatorOff, + ExIndicatorOn, ExIndicatorOff, HScrollDeco, VScrollDeco, HScrollDecoDown, + VScrollDecoDown, ComboDeco, ComboDecoDown, CheckMark + }; + + int i; + QString tmpStr; + QString pixnames[ WIDGETS ]; // used for duplicate check + QString brdnames[ WIDGETS ]; + bool loaded[ WIDGETS ]; // used for preloading for CopyWidget + + QSettings config; + if (configDirName.isEmpty() || configDirName == ".") + { + KStyleDirs::dirs()->addToSearch( "themerc", config ); + } + else config.insertSearchPath( QSettings::Unix, configDirName ); + + applyConfigFile( config ); + + d->contrast = config.readNumEntry( configFileName + "KDE/contrast", 7 ); + + + + for ( i = 0; i < INHERIT_ITEMS; ++i ) + applyResourceGroup( &config, i ); + for ( ; i < INHERIT_ITEMS*2; ++i ) + { + if ( config.entryList( configFileName + widgetEntries[ i ] ).size() ) + applyResourceGroup( &config, i ); +#ifndef Q_WS_QWS //FIXME + + else + { + Prop& copyProp = d->props[ widgetEntries[ i ] ]; + copyProp[ "CopyWidget" ] = QString( widgetEntries[ i - INHERIT_ITEMS ] ); + } +#endif + + } + for ( ; i < WIDGETS; ++i ) + applyResourceGroup( &config, i ); + applyMiscResourceGroup( &config ); + + // initialize defaults that may not be read + for ( i = 0; i < WIDGETS; ++i ) + loaded[ i ] = false; + btnXShift = btnYShift = focus3DOffset = 0; + aTabLine = iTabLine = true; + roundedButton = roundedCombo = roundedSlider = focus3D = false; + splitterWidth = 10; + + //Handle the rotated background separately.. + d->props[ widgetEntries[ RotSliderGroove ] ] = d->props[ widgetEntries[ SliderGroove ] ]; + d->props[ widgetEntries[ RotInactiveTab ] ] = d->props[ widgetEntries[ InactiveTab ] ]; + d->props[ widgetEntries[ RotActiveTab ] ] = d->props[ widgetEntries[ ActiveTab ] ]; + + // misc items + readMiscResourceGroup(); + + + for ( i = 0; i < WIDGETS; ++i ) + readResourceGroup( i, pixnames, brdnames, loaded ); + + if ( pixmaps[ RotSliderGroove ] ) + { + QWMatrix r270; //TODO: 90 if reverse? + r270.rotate( 270 ); + KThemePixmap* bf = new KThemePixmap( pixmaps[ RotSliderGroove ], pixmaps[ RotSliderGroove ] ->xForm( r270 ) ); // + pixmaps[ RotSliderGroove ] = bf; + if ( images[ RotSliderGroove ] ) + { + delete images[ RotSliderGroove ]; + images[ RotSliderGroove ] = new QImage( bf->convertToImage() ); + } + } + + if ( pixmaps[ RotActiveTab ] ) + { + QWMatrix r180; + r180.rotate( 180 ); + KThemePixmap* bf = new KThemePixmap( pixmaps[ RotActiveTab ], pixmaps[ RotActiveTab ] ->xForm( r180 ) ); + + pixmaps[ RotActiveTab ] = bf; + if ( images[ RotActiveTab ] ) + { + delete images[ RotActiveTab ]; + images[ RotActiveTab ] = new QImage( bf->convertToImage() ); + } + } + + if ( pixmaps[ RotInactiveTab ] ) + { + QWMatrix r180; + r180.rotate( 180 ); + KThemePixmap* bf = new KThemePixmap( pixmaps[ RotInactiveTab ], pixmaps[ RotInactiveTab ] ->xForm( r180 ) ); + + pixmaps[ RotInactiveTab ] = bf; + if ( images[ RotInactiveTab ] ) + { + delete images[ RotInactiveTab ]; + images[ RotInactiveTab ] = new QImage( bf->convertToImage() ); + } + } + + // Handle preblend items + for ( i = 0; i < PREBLEND_ITEMS; ++i ) + { + if ( pixmaps[ preBlend[ i ] ] != NULL && blends[ preBlend[ i ] ] != 0.0 ) + blend( preBlend[ i ] ); + } + + d->props.clear(); +} + +KThemeBase::KThemeBase( const QString& dir, const QString & configFile ) + : KStyle( FilledFrameWorkaround ), configFileName( configFile ) +{ + d = new KThemeBasePrivate; + if ( configFileName.isEmpty() ) + configFileName = "kstylerc"; + + + configDirName = dir; + //Strip of rc from the configFileName + if ( configFileName.endsWith( "rc" ) ) + { + configFileName.truncate( configFileName.length() - 2 ); //Get rid of rc.. + } + //else SCREAM!! + + + configFileName = "/" + configFileName + "/"; + + readConfig( Qt::WindowsStyle ); + cache = new KThemeCache( cacheSize ); + + switch ( scrollBarLayout() ) + { + case SBBottomLeft: + setScrollBarType( NextStyleScrollBar ); + break; + case SBBottomRight: + setScrollBarType( PlatinumStyleScrollBar ); + break; + case SBOpposite: + break; + //Do nothing, this type already set.. + } + ; +} + +void KThemeBase::applyConfigFile( QSettings& config ) +{ + QStringList keys = config.entryList( configFileName ); + + if ( keys.contains( "foreground" ) ) + { + d->overrideForeground = true; + d->overrideForegroundCol = readColorEntry( &config, ( configFileName + "foreground" ).latin1(), 0 ); + } + else + d->overrideForeground = false; + + if ( keys.contains( "background" ) ) + { + d->overrideBackground = true; + d->overrideBackgroundCol = readColorEntry( &config, ( configFileName + "background" ).latin1(), 0 ); + } + else + d->overrideBackground = false; + + + + if ( keys.contains( "selectForeground" ) ) + { + d->overrideSelectForeground = true; + d->overrideSelectForegroundCol = readColorEntry( &config, ( configFileName + "selectForeground" ).latin1(), 0 ); + } + else + d->overrideSelectForeground = false; + + if ( keys.contains( "selectBackground" ) ) + { + d->overrideSelectBackground = true; + d->overrideSelectBackgroundCol = readColorEntry( &config, ( configFileName + "selectBackground" ).latin1(), 0 ); + } + else + d->overrideSelectBackground = false; + + if ( keys.contains( "windowBackground" ) ) + { + d->overrideWindowBackground = true; + d->overrideWindowBackgroundCol = readColorEntry( &config, ( configFileName + "windowBackground" ).latin1(), 0 ); + } + else + d->overrideWindowBackground = false; + + + if ( keys.contains( "windowForeground" ) ) + { + d->overrideWindowForeground = true; + d->overrideWindowForegroundCol = readColorEntry( &config, ( configFileName + "windowForeground" ).latin1(), 0 ); + } + else + d->overrideWindowForeground = false; + + +#ifndef Q_WS_QWS //FIXME + + for ( int input = 0; input < WIDGETS; ++input ) + { + d->props.erase( widgetEntries[ input ] ); + } + d->props.erase( "Misc" ); +#endif +} + +KThemeBase::~KThemeBase() +{ + int i; + for ( i = 0; i < WIDGETS; ++i ) + { + if ( !duplicate[ i ] ) + { + if ( images[ i ] ) + delete images[ i ]; + if ( pixmaps[ i ] ) + delete pixmaps[ i ]; + } + if ( !pbDuplicate[ i ] && pbPixmaps[ i ] ) + delete pbPixmaps[ i ]; + if ( colors[ i ] ) + delete( colors[ i ] ); + if ( grLowColors[ i ] ) + delete( grLowColors[ i ] ); + if ( grHighColors[ i ] ) + delete( grHighColors[ i ] ); + } + KStyleDirs::release(); + delete cache; + delete d; +} + +QImage* KThemeBase::loadImage( const QString &name ) +{ + QImage * image = new QImage; + QString path = KStyleDirs::dirs()->findResource( "themepixmap",name ); + image->load( path ); + if ( !image->isNull() ) + return ( image ); + qWarning( "KThemeBase: Unable to load image %s\n", name.latin1() ); + delete image; + return ( NULL ); +} + +KThemePixmap* KThemeBase::loadPixmap( const QString &name ) +{ + KThemePixmap * pixmap = new KThemePixmap( false ); + QString path = KStyleDirs::dirs()->findResource( "themepixmap", name ); + pixmap->load( path ); + if ( !pixmap->isNull() ) + return pixmap; + qWarning( "KThemeBase: Unable to load pixmap %s\n", name.latin1() ); + delete pixmap; + return ( NULL ); +} + + +KThemePixmap* KThemeBase::scale( int w, int h, WidgetType widget ) const +{ + if ( scaleHints[ widget ] == FullScale ) + { + if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w || + pixmaps[ widget ] ->height() != h ) + { + KThemePixmap * cachePix = cache->pixmap( w, h, widget ); + if ( cachePix ) + { + cachePix = new KThemePixmap( *cachePix ); + if ( pixmaps[ widget ] ) + cache->insert( pixmaps[ widget ], KThemeCache::FullScale, + widget ); + else + qWarning( "We would have inserted a null pixmap!\n" ); + pixmaps[ widget ] = cachePix; + } + else + { + cache->insert( pixmaps[ widget ], KThemeCache::FullScale, widget ); + QImage tmpImg = images[ widget ] ->smoothScale( w, h ); + pixmaps[ widget ] = new KThemePixmap; + pixmaps[ widget ] ->convertFromImage( tmpImg ); + if ( blends[ widget ] != 0.0 ) + blend( widget ); + } + } + } + else if ( scaleHints[ widget ] == HorizontalScale ) + { + if ( pixmaps[ widget ] ->width() != w ) + { + KThemePixmap * cachePix = cache->horizontalPixmap( w, widget ); + if ( cachePix ) + { + cachePix = new KThemePixmap( *cachePix ); + if ( pixmaps[ widget ] ) + cache->insert( pixmaps[ widget ], KThemeCache::HorizontalScale, widget ); + else + qWarning( "We would have inserted a null pixmap!\n" ); + pixmaps[ widget ] = cachePix; + } + else + { + cache->insert( pixmaps[ widget ], KThemeCache::HorizontalScale, widget ); + QImage tmpImg = images[ widget ] -> + smoothScale( w, images[ widget ] ->height() ); + pixmaps[ widget ] = new KThemePixmap; + pixmaps[ widget ] ->convertFromImage( tmpImg ); + if ( blends[ widget ] != 0.0 ) + blend( widget ); + } + } + } + else if ( scaleHints[ widget ] == VerticalScale ) + { + if ( pixmaps[ widget ] ->height() != h ) + { + KThemePixmap * cachePix = cache->verticalPixmap( w, widget ); + if ( cachePix ) + { + cachePix = new KThemePixmap( *cachePix ); + if ( pixmaps[ widget ] ) + cache->insert( pixmaps[ widget ], KThemeCache::VerticalScale, widget ); + else + qWarning( "We would have inserted a null pixmap!\n" ); + pixmaps[ widget ] = cachePix; + } + else + { + cache->insert( pixmaps[ widget ], KThemeCache::VerticalScale, widget ); + QImage tmpImg = + images[ widget ] ->smoothScale( images[ widget ] ->width(), h ); + pixmaps[ widget ] = new KThemePixmap; + pixmaps[ widget ] ->convertFromImage( tmpImg ); + if ( blends[ widget ] != 0.0 ) + blend( widget ); + } + } + } + // If blended tile here so the blend is scaled properly + else if ( scaleHints[ widget ] == TileScale && blends[ widget ] != 0.0 ) + { + if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w || + pixmaps[ widget ] ->height() != h ) + { + KThemePixmap * cachePix = cache->pixmap( w, h, widget ); + if ( cachePix ) + { + cachePix = new KThemePixmap( *cachePix ); + cache->insert( pixmaps[ widget ], KThemeCache::FullScale, widget ); + pixmaps[ widget ] = cachePix; + } + else + { + cache->insert( pixmaps[ widget ], KThemeCache::FullScale, widget ); + QPixmap tile; + tile.convertFromImage( *images[ widget ] ); + pixmaps[ widget ] = new KThemePixmap; + pixmaps[ widget ] ->resize( w, h ); + QPainter p( pixmaps[ widget ] ); + p.drawTiledPixmap( 0, 0, w, h, tile ); + if ( blends[ widget ] != 0.0 ) + blend( widget ); + } + } + } + return ( pixmaps[ widget ] ); +} + +KThemePixmap* KThemeBase::scaleBorder( int w, int h, WidgetType widget ) const +{ + KThemePixmap * pixmap = NULL; + if ( !pbPixmaps[ widget ] && !pbWidth[ widget ] ) + return ( NULL ); + pixmap = cache->pixmap( w, h, widget, true ); + if ( pixmap ) + { + pixmap = new KThemePixmap( *pixmap ); + } + else + { + pixmap = new KThemePixmap(); + pixmap->resize( w, h ); + QBitmap mask; + mask.resize( w, h ); + mask.fill( color0 ); + QPainter mPainter; + mPainter.begin( &mask ); + + QPixmap *tmp = borderPixmap( widget ) ->border( KThemePixmap::TopLeft ); + const QBitmap *srcMask = tmp->mask(); + int bdWidth = tmp->width(); + + bitBlt( pixmap, 0, 0, tmp, 0, 0, bdWidth, bdWidth, + Qt::CopyROP, false ); + if ( srcMask ) + bitBlt( &mask, 0, 0, srcMask, 0, 0, bdWidth, bdWidth, + Qt::CopyROP, false ); + else + mPainter.fillRect( 0, 0, bdWidth, bdWidth, color1 ); + + + tmp = borderPixmap( widget ) ->border( KThemePixmap::TopRight ); + srcMask = tmp->mask(); + bitBlt( pixmap, w - bdWidth, 0, tmp, 0, 0, bdWidth, + bdWidth, Qt::CopyROP, false ); + if ( srcMask ) + bitBlt( &mask, w - bdWidth, 0, srcMask, 0, 0, bdWidth, + bdWidth, Qt::CopyROP, false ); + else + mPainter.fillRect( w - bdWidth, 0, bdWidth, bdWidth, color1 ); + + tmp = borderPixmap( widget ) ->border( KThemePixmap::BottomLeft ); + srcMask = tmp->mask(); + bitBlt( pixmap, 0, h - bdWidth, tmp, 0, 0, bdWidth, + bdWidth, Qt::CopyROP, false ); + if ( srcMask ) + bitBlt( &mask, 0, h - bdWidth, srcMask, 0, 0, bdWidth, + bdWidth, Qt::CopyROP, false ); + else + mPainter.fillRect( 0, h - bdWidth, bdWidth, bdWidth, color1 ); + + tmp = borderPixmap( widget ) ->border( KThemePixmap::BottomRight ); + srcMask = tmp->mask(); + bitBlt( pixmap, w - bdWidth, h - bdWidth, tmp, 0, 0, + bdWidth, bdWidth, Qt::CopyROP, false ); + if ( srcMask ) + bitBlt( &mask, w - bdWidth, h - bdWidth, srcMask, 0, 0, + bdWidth, bdWidth, Qt::CopyROP, false ); + else + mPainter.fillRect( w - bdWidth, h - bdWidth, bdWidth, bdWidth, color1 ); + + QPainter p; + p.begin( pixmap ); + if ( w - bdWidth * 2 > 0 ) + { + tmp = borderPixmap( widget ) ->border( KThemePixmap::Top ); + srcMask = tmp->mask(); + p.drawTiledPixmap( bdWidth, 0, w - bdWidth * 2, bdWidth, *tmp ); + if ( srcMask ) + bitBlt( &mask, bdWidth, 0, srcMask, 0, 0, + w - bdWidth * 2, bdWidth, Qt::CopyROP, false ); + else + mPainter.fillRect( bdWidth, 0, w - bdWidth * 2, bdWidth, color1 ); + + tmp = borderPixmap( widget ) ->border( KThemePixmap::Bottom ); + srcMask = tmp->mask(); + p.drawTiledPixmap( bdWidth, h - bdWidth, w - bdWidth * 2, bdWidth, + *tmp ); + if ( srcMask ) + bitBlt( &mask, bdWidth, h - bdWidth, srcMask, 0, 0, + w - bdWidth * 2, bdWidth, Qt::CopyROP, false ); + else + mPainter.fillRect( bdWidth, h - bdWidth, w - bdWidth * 2, bdWidth, + color1 ); + } + if ( h - bdWidth * 2 > 0 ) + { + tmp = borderPixmap( widget ) ->border( KThemePixmap::Left ); + srcMask = tmp->mask(); + p.drawTiledPixmap( 0, bdWidth, bdWidth, h - bdWidth * 2, *tmp ); + if ( srcMask ) + bitBlt( &mask, 0, bdWidth, srcMask, 0, 0, + bdWidth, h - bdWidth * 2, Qt::CopyROP, false ); + else + mPainter.fillRect( 0, bdWidth, bdWidth, h - bdWidth * 2, color1 ); + + tmp = borderPixmap( widget ) ->border( KThemePixmap::Right ); + srcMask = tmp->mask(); + p.drawTiledPixmap( w - bdWidth, bdWidth, bdWidth, h - bdWidth * 2, + *tmp ); + if ( srcMask ) + bitBlt( &mask, w - bdWidth, bdWidth, srcMask, 0, 0, + bdWidth, h - bdWidth * 2, Qt::CopyROP, false ); + else + mPainter.fillRect( w - bdWidth, bdWidth, bdWidth, h - bdWidth * 2, color1 ); + } + p.end(); + mPainter.end(); + pixmap->setMask( mask ); + cache->insert( pixmap, KThemeCache::FullScale, widget, true ); + if ( !pixmap->mask() ) + qWarning( "No mask for border pixmap!\n" ); + } + return ( pixmap ); +} + + +KThemePixmap* KThemeBase::blend( WidgetType widget ) const +{ + KPixmapEffect::GradientType g; + switch ( gradients[ widget ] ) + { + case GrHorizontal: + g = KPixmapEffect::HorizontalGradient; + break; + case GrVertical: + g = KPixmapEffect::VerticalGradient; + break; + case GrPyramid: + g = KPixmapEffect::PyramidGradient; + break; + case GrRectangle: + g = KPixmapEffect::RectangleGradient; + break; + case GrElliptic: + g = KPixmapEffect::EllipticGradient; + break; + default: + g = KPixmapEffect::DiagonalGradient; + break; + } + KPixmapEffect::blend( *pixmaps[ widget ], blends[ widget ], *grLowColors[ widget ], + g, false ); + return ( pixmaps[ widget ] ); +} + +KThemePixmap* KThemeBase::gradient( int w, int h, WidgetType widget ) const +{ + if ( gradients[ widget ] == GrVertical ) + { + if ( !pixmaps[ widget ] || pixmaps[ widget ] ->height() != h ) + { + KThemePixmap * cachePix = cache->verticalPixmap( h, widget ); + if ( cachePix ) + { + cachePix = new KThemePixmap( *cachePix ); + if ( pixmaps[ widget ] ) + cache->insert( pixmaps[ widget ], KThemeCache::VerticalScale, + widget ); + pixmaps[ widget ] = cachePix; + } + else + { + if ( pixmaps[ widget ] ) + cache->insert( pixmaps[ widget ], KThemeCache::VerticalScale, + widget ); + pixmaps[ widget ] = new KThemePixmap; + pixmaps[ widget ] ->resize( w, h ); + KPixmapEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ], + *grLowColors[ widget ], + KPixmapEffect::VerticalGradient ); + } + } + } + else if ( gradients[ widget ] == GrHorizontal ) + { + if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ) + { + KThemePixmap * cachePix = cache->horizontalPixmap( w, widget ); + if ( cachePix ) + { + cachePix = new KThemePixmap( *cachePix ); + if ( pixmaps[ widget ] ) + cache->insert( pixmaps[ widget ], + KThemeCache::HorizontalScale, widget ); + pixmaps[ widget ] = cachePix; + } + else + { + if ( pixmaps[ widget ] ) + cache->insert( pixmaps[ widget ], + KThemeCache::HorizontalScale, widget ); + pixmaps[ widget ] = new KThemePixmap; + pixmaps[ widget ] ->resize( w, h ); + KPixmapEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ], + *grLowColors[ widget ], + KPixmapEffect::HorizontalGradient ); + } + } + } + else if ( gradients[ widget ] == GrReverseBevel ) + { + if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w || + pixmaps[ widget ] ->height() != h ) + { + KThemePixmap * cachePix = cache->pixmap( w, h, widget ); + if ( cachePix ) + { + cachePix = new KThemePixmap( *cachePix ); + if ( pixmaps[ widget ] ) + cache->insert( pixmaps[ widget ], KThemeCache::FullScale, + widget ); + pixmaps[ widget ] = cachePix; + } + else + { + if ( pixmaps[ widget ] ) + cache->insert( pixmaps[ widget ], KThemeCache::FullScale, + widget ); + pixmaps[ widget ] = new KThemePixmap; + pixmaps[ widget ] ->resize( w, h ); + + KPixmap s; + int offset = decoWidth( widget ); + s.resize( w - offset * 2, h - offset * 2 ); + QColor lc( *grLowColors[ widget ] ); + QColor hc( *grHighColors[ widget ] ); + if ( bevelContrast( widget ) ) + { + int bc = bevelContrast( widget ); + // want single increments, not factors like light()/dark() + lc.setRgb( lc.red() - bc, lc.green() - bc, lc.blue() - bc ); + hc.setRgb( hc.red() + bc, hc.green() + bc, hc.blue() + bc ); + } + KPixmapEffect::gradient( *pixmaps[ widget ], + lc, hc, + KPixmapEffect::DiagonalGradient ); + KPixmapEffect::gradient( s, *grHighColors[ widget ], + *grLowColors[ widget ], + KPixmapEffect::DiagonalGradient ); + bitBlt( pixmaps[ widget ], offset, offset, &s, 0, 0, w - offset * 2, + h - offset * 2, Qt::CopyROP ); + } + } + } + else + { + KPixmapEffect::GradientType g; + switch ( gradients[ widget ] ) + { + case GrPyramid: + g = KPixmapEffect::PyramidGradient; + break; + case GrRectangle: + g = KPixmapEffect::RectangleGradient; + break; + case GrElliptic: + g = KPixmapEffect::EllipticGradient; + break; + default: + g = KPixmapEffect::DiagonalGradient; + break; + } + if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w || + pixmaps[ widget ] ->height() != h ) + { + KThemePixmap * cachePix = cache->pixmap( w, h, widget ); + if ( cachePix ) + { + cachePix = new KThemePixmap( *cachePix ); + if ( pixmaps[ widget ] ) + cache->insert( pixmaps[ widget ], KThemeCache::FullScale, + widget ); + pixmaps[ widget ] = cachePix; + } + else + { + if ( pixmaps[ widget ] ) + cache->insert( pixmaps[ widget ], KThemeCache::FullScale, + widget ); + pixmaps[ widget ] = new KThemePixmap; + pixmaps[ widget ] ->resize( w, h ); + KPixmapEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ], + *grLowColors[ widget ], g ); + } + } + } + return ( pixmaps[ widget ] ); +} + +KThemePixmap* KThemeBase::scalePixmap( int w, int h, WidgetType widget ) const +{ + + if ( gradients[ widget ] && blends[ widget ] == 0.0 ) + return ( gradient( w, h, widget ) ); + + return ( scale( w, h, widget ) ); +} + +QColorGroup* KThemeBase::makeColorGroup( const QColor &fg, const QColor &bg, + Qt::GUIStyle ) +{ + if ( shading == Motif ) + { + int highlightVal, lowlightVal; + highlightVal = 100 + ( 2 * d->contrast + 4 ) * 16 / 10; + lowlightVal = 100 + ( ( 2 * d->contrast + 4 ) * 10 ); + return ( new QColorGroup( fg, bg, bg.light( highlightVal ), + bg.dark( lowlightVal ), bg.dark( 120 ), + fg, QApplication::palette().active().base() ) ); + } + else + return ( new QColorGroup( fg, bg, bg.light( 150 ), bg.dark(), + bg.dark( 120 ), fg, + QApplication::palette().active().base() ) ); +} + + +void KThemeBase::applyMiscResourceGroup( QSettings *config ) +{ +#ifndef Q_WS_QWS //FIXME + d->props.erase( "Misc" ); // clear the old property + + QString base = configFileName + "Misc/"; + + Prop& prop = d->props[ "Misc" ]; + QString tmpStr; + + tmpStr = config->readEntry( base + "SButtonPosition" ); + if ( tmpStr == "BottomLeft" ) + prop[ "SButtonPosition" ] = QString::number( ( int ) SBBottomLeft ); + else if ( tmpStr == "BottomRight" ) + prop[ "SButtonPosition" ] = QString::number( ( int ) SBBottomRight ); + else + { + if ( tmpStr != "Opposite" && !tmpStr.isEmpty() ) + qWarning( "KThemeBase: Unrecognized sb button option %s, using Opposite.\n", tmpStr.latin1() ); + ; + prop[ "SButtonPosition" ] = QString::number( ( int ) SBOpposite ); + } + tmpStr = config->readEntry( base + "ArrowType" ); + if ( tmpStr == "Small" ) + prop[ "ArrowType" ] = QString::number( ( int ) SmallArrow ); + else if ( tmpStr == "3D" ) + prop[ "ArrowType" ] = QString::number( ( int ) MotifArrow ); + else + { + if ( tmpStr != "Normal" && !tmpStr.isEmpty() ) + qWarning( "KThemeBase: Unrecognized arrow option %s, using Normal.\n", tmpStr.latin1() ); + prop[ "ArrowType" ] = QString::number( ( int ) LargeArrow ); + } + tmpStr = config->readEntry( base + "ShadeStyle" ); + if ( tmpStr == "Motif" ) + prop[ "ShadeStyle" ] = QString::number( ( int ) Motif ); + else if ( tmpStr == "Next" ) + prop[ "ShadeStyle" ] = QString::number( ( int ) Next ); + else if ( tmpStr == "KDE" ) + prop[ "ShadeStyle" ] = QString::number( ( int ) KDE ); + else + prop[ "ShadeStyle" ] = QString::number( ( int ) Windows ); + + prop[ "FrameWidth" ] = QString::number( config->readNumEntry( base + "FrameWidth", 2 ) ); + prop[ "Cache" ] = QString::number( config->readNumEntry( base + "Cache", 1024 ) ); + prop[ "ScrollBarExtent" ] = QString::number( config->readNumEntry( base + "ScrollBarExtent", 16 ) ); +#endif +} + +static int readNumEntry( Prop& prop, QString setting, int def ) +{ + bool ok; + QString s_val = prop[ setting ]; + int val = s_val.toInt( &ok ); + if ( ok ) + return val; + return def; +} + +static QColor readColorEntry( Prop& prop, QString setting, const QColor& def ) +{ + QString s_val = prop[ setting ]; + if ( !s_val.isEmpty() ) + { + QColor c( s_val ); + return c; + } + return def; +} + +void KThemeBase::readMiscResourceGroup() +{ +#ifndef Q_WS_QWS //FIXME + Prop & prop = d->props[ "Misc" ]; + + sbPlacement = ( SButton ) readNumEntry( prop, "SButtonPosition", + ( int ) SBOpposite ); + arrowStyle = ( ArrowStyle ) readNumEntry( prop, "ArrowType", + ( int ) LargeArrow ); + shading = ( ShadeStyle ) readNumEntry( prop, "ShadeStyle", ( int ) Windows ); + defaultFrame = readNumEntry( prop, "FrameWidth", 2 ); + cacheSize = readNumEntry( prop, "Cache", 1024 ); + sbExtent = readNumEntry( prop, "ScrollBarExtent", 16 ); +#endif +} + + +void KThemeBase::applyResourceGroup( QSettings *config, int i ) +{ +#ifndef Q_WS_QWS //FIXME + QString tmpStr; + int tmpVal; + + // clear the old property + d->props.erase( widgetEntries[ i ] ); + + QString base = configFileName + widgetEntries[ i ] + "/"; + + Prop& prop = d->props[ widgetEntries[ i ] ]; + + tmpStr = config->readEntry( base + "CopyWidget", "" ); + prop[ "CopyWidget" ] = tmpStr; + if ( !tmpStr.isEmpty() ) + { + return ; + } + + tmpStr = config->readEntry( base + "Scale" ); + if ( tmpStr == "Full" ) + tmpVal = ( int ) FullScale; + else if ( tmpStr == "Horizontal" ) + tmpVal = ( int ) HorizontalScale; + else if ( tmpStr == "Vertical" ) + tmpVal = ( int ) VerticalScale; + else + { + if ( tmpStr != "Tile" && !tmpStr.isEmpty() ) + qWarning( "KThemeBase: Unrecognized scale option %s, using Tile.\n", tmpStr.latin1() ); + tmpVal = ( int ) TileScale; + } + prop[ "ScaleHint" ] = QString::number( tmpVal ); + + // Gradient type + tmpStr = config->readEntry( base + "Gradient" ); + if ( tmpStr == "Diagonal" ) + tmpVal = ( int ) GrDiagonal; + else if ( tmpStr == "Horizontal" ) + tmpVal = ( int ) GrHorizontal; + else if ( tmpStr == "Vertical" ) + tmpVal = ( int ) GrVertical; + else if ( tmpStr == "Pyramid" ) + tmpVal = ( int ) GrPyramid; + else if ( tmpStr == "Rectangle" ) + tmpVal = ( int ) GrRectangle; + else if ( tmpStr == "Elliptic" ) + tmpVal = ( int ) GrElliptic; + else if ( tmpStr == "ReverseBevel" ) + tmpVal = ( int ) GrReverseBevel; + else + { + if ( tmpStr != "None" && !tmpStr.isEmpty() ) + qWarning( "KThemeBase: Unrecognized gradient option %s, using None.\n", tmpStr.latin1() ); + tmpVal = ( int ) GrNone; + } + prop[ "Gradient" ] = QString::number( tmpVal ); + + // Blend intensity + tmpStr.setNum( config->readDoubleEntry( base + "BlendIntensity", 0.0 ) ); + prop[ "Blend" ] = tmpStr; + + // Bevel contrast + prop[ "BContrast" ] = QString::number( config->readNumEntry( base + "BevelContrast", 0 ) ); + + // Border width + prop[ "Border" ] = QString::number( config->readNumEntry( base + "Border", 1 ) ); + + // Highlight width + prop[ "Highlight" ] = QString::number( config->readNumEntry( base + "Highlight", 1 ) ); + + QStringList keys = config->entryList( base ); + + // Gradient low color or blend background + if ( keys.contains( "GradientLow" ) ) + prop[ "GrLow" ] = readColorEntry( config, QString( base + "GradientLow" ).latin1(), + &QApplication::palette().active().background() ).name(); + + // Gradient high color + if ( keys.contains( "GradientHigh" ) ) + prop[ "GrHigh" ] = readColorEntry( config, QString( base + "GradientHigh" ).latin1(), + &QApplication::palette().active().foreground() ).name(); + + // Extended color attributes + if ( keys.contains( "Foreground" ) || keys.contains( "Background" ) ) + { + QColor fg, bg; + if ( keys.contains( "Background" ) ) + bg = readColorEntry( config, QString( base + "Background" ).latin1(), &bg ); + if ( keys.contains( "Foreground" ) ) + fg = readColorEntry( config, QString( base + "Foreground" ).latin1(), &fg ); + prop[ "Foreground" ] = fg.name(); + prop[ "Background" ] = bg.name(); + + } + else + colors[ i ] = NULL; + + // Pixmap + tmpStr = config->readEntry( base + "Pixmap", "" ); + if ( !tmpStr.isEmpty() ) + prop[ "Pixmap" ] = tmpStr; + // Pixmap border + tmpStr = config->readEntry( base + "PixmapBorder", "" ); + if ( !tmpStr.isEmpty() ) + { + prop[ "PixmapBorder" ] = tmpStr; + prop[ "PixmapBWidth" ] = QString::number( + config->readNumEntry( base + "PixmapBWidth", 0 ) ); + } + + // Various widget specific settings. This was more efficient when bunched + // together in the misc group, but this makes an easier to read config. + if ( i == SliderGroove ) + prop[ "SmallGroove" ] = QString::number( + config->readBoolEntry( base + "SmallGroove", false ) ); + else if ( i == ActiveTab || i == InactiveTab ) + prop[ "BottomLine" ] = QString::number( + config->readBoolEntry( base + "BottomLine", true ) ); + else if ( i == Splitter ) + prop[ "Width" ] = QString::number( config->readNumEntry( base + "Width", 10 ) ); + else if ( i == ComboBox || i == ComboBoxDown ) + { + if ( keys.contains( "Round" ) ) + prop[ "Round" ] = QString::number( config->readBoolEntry( base + "Round", false ) ); + else + prop[ "Round" ] = "5000"; // invalid, used w/multiple groups + + } + else if ( i == PushButton || i == PushButtonDown ) + { + if ( keys.contains( "XShift" ) ) + prop[ "XShift" ] = QString::number( config->readNumEntry( base + "XShift", 0 ) ); + else + prop[ "XShift" ] = "5000"; + if ( keys.contains( "YShift" ) ) + prop[ "YShift" ] = QString::number( config->readNumEntry( base + "YShift", 0 ) ); + else + prop[ "YShift" ] = "5000"; + if ( keys.contains( "3DFocusRect" ) ) + prop[ "3DFRect" ] = QString::number( config-> + readBoolEntry( base + "3DFocusRect", false ) ); + else + prop[ "3DFRect" ] = "5000"; + if ( keys.contains( "3DFocusOffset" ) ) + prop[ "3DFOffset" ] = QString::number( config-> + readBoolEntry( base + "3DFocusOffset", 0 ) ); + else + prop[ "3DFOffset" ] = "5000"; + if ( keys.contains( "Round" ) ) + prop[ "Round" ] = QString::number( config->readBoolEntry( base + "Round", false ) ); + else + prop[ "Round" ] = "5000"; + } +#endif +} + +void KThemeBase::readResourceGroup( int i, QString *pixnames, QString *brdnames, + bool *loadArray ) +{ +#ifndef Q_WS_QWS //FIXME + if ( loadArray[ i ] == true ) + { + return ; // already been preloaded. + } + + int tmpVal; + Prop prop = d->props[ widgetEntries[ i ] ]; + QString tmpStr; + + tmpStr = prop[ "CopyWidget" ]; + if ( !tmpStr.isEmpty() ) + { // Duplicate another widget's config + int sIndex; + loadArray[ i ] = true; + for ( sIndex = 0; sIndex < WIDGETS; ++sIndex ) + { + if ( tmpStr == widgetEntries[ sIndex ] ) + { + if ( !loadArray[ sIndex ] ) // hasn't been loaded yet + readResourceGroup( sIndex, pixnames, brdnames, + loadArray ); + break; + } + } + if ( loadArray[ sIndex ] ) + { + copyWidgetConfig( sIndex, i, pixnames, brdnames ); + } + else + qWarning( "KThemeBase: Unable to identify source widget for %s\n", widgetEntries[ i ] ); + return ; + } + // special inheritance for disabled arrows (these are tri-state unlike + // the rest of what we handle). + for ( tmpVal = DisArrowUp; tmpVal <= DisArrowRight; ++tmpVal ) + { + if ( tmpVal == i ) + { + tmpStr = prop[ "Pixmap" ]; + if ( tmpStr.isEmpty() ) + { + copyWidgetConfig( ArrowUp + ( tmpVal - DisArrowUp ), i, pixnames, + brdnames ); + return ; + } + } + } + + // Scale hint + scaleHints[ i ] = ( ScaleHint ) readNumEntry( prop, "ScaleHint", ( int ) TileScale ); + gradients[ i ] = ( Gradient ) readNumEntry( prop, "Gradient", ( int ) GrNone ); + + // Blend intensity + tmpStr = prop[ "Blend" ]; + if ( tmpStr.isEmpty() ) + tmpStr = QString::fromLatin1( "0.0" ); + blends[ i ] = tmpStr.toFloat(); + + // Bevel contrast + bContrasts[ i ] = readNumEntry( prop, "BContrast", 0 ); + + // Border width + borders[ i ] = readNumEntry( prop, "Border", 1 ); + + // Highlight width + highlights[ i ] = readNumEntry( prop, "Highlight", 1 ); + + // Gradient low color or blend background + if ( gradients[ i ] != GrNone || blends[ i ] != 0.0 ) + grLowColors[ i ] = + new QColor( readColorEntry( prop, "GrLow", + QApplication::palette().active(). + background() ) ); + else + grLowColors[ i ] = NULL; + + // Gradient high color + if ( gradients[ i ] != GrNone ) + grHighColors[ i ] = + new QColor( readColorEntry( prop, "GrHigh", + QApplication::palette().active(). + background() ) ); + else + grHighColors[ i ] = NULL; + + // Extended color attributes + QColor fg, bg; + fg = readColorEntry( prop, "Foreground", fg ); + bg = readColorEntry( prop, "Background", bg ); + if ( fg.isValid() || bg.isValid() ) + { + if ( !fg.isValid() ) + fg = QApplication::palette().active().foreground(); + if ( !bg.isValid() ) + bg = QApplication::palette().active().background(); + colors[ i ] = makeColorGroup( fg, bg, Qt::WindowsStyle ); + } + else + colors[ i ] = NULL; + + // Pixmap + int existing; + tmpStr = prop[ "Pixmap" ]; + pixnames[ i ] = tmpStr; + duplicate[ i ] = false; + pixmaps[ i ] = NULL; + images[ i ] = NULL; + // Scan for duplicate pixmaps(two identical pixmaps, tile scale, no blend, + // no pixmapped border) + if ( !tmpStr.isEmpty() ) + { + for ( existing = 0; existing < i; ++existing ) + { + if ( tmpStr == pixnames[ existing ] && scaleHints[ i ] == TileScale && + scaleHints[ existing ] == TileScale && blends[ existing ] == 0.0 && + blends[ i ] == 0.0 ) + { + pixmaps[ i ] = pixmaps[ existing ]; + duplicate[ i ] = true; + break; + } + } + } + // load + if ( !duplicate[ i ] && !tmpStr.isEmpty() ) + { + pixmaps[ i ] = loadPixmap( tmpStr ); + // load and save images for scaled/blended widgets for speed. + if ( scaleHints[ i ] == TileScale && blends[ i ] == 0.0 ) + images[ i ] = NULL; + else + images[ i ] = loadImage( tmpStr ); + } + + // Pixmap border + tmpStr = prop[ "PixmapBorder" ]; + brdnames[ i ] = tmpStr; + pbDuplicate[ i ] = false; + pbPixmaps[ i ] = NULL; + pbWidth[ i ] = 0; + if ( !tmpStr.isEmpty() ) + { + pbWidth[ i ] = readNumEntry( prop, "PixmapBWidth", 0 ); + if ( pbWidth[ i ] == 0 ) + { + qWarning( "KThemeBase: No border width specified for pixmapped border widget %s\n", + widgetEntries[ i ] ); + qWarning( "KThemeBase: Using default of 2.\n" ); + pbWidth[ i ] = 2; + } + // duplicate check + for ( existing = 0; existing < i; ++existing ) + { + if ( tmpStr == brdnames[ existing ] ) + { + pbPixmaps[ i ] = pbPixmaps[ existing ]; + pbDuplicate[ i ] = true; + break; + } + } + } + // load + if ( !pbDuplicate[ i ] && !tmpStr.isEmpty() ) + pbPixmaps[ i ] = loadPixmap( tmpStr ); + + if ( pbPixmaps[ i ] && !pbDuplicate[ i ] ) + generateBorderPix( i ); + + // Various widget specific settings. This was more efficient when bunched + // together in the misc group, but this makes an easier to read config. + if ( i == SliderGroove ) + roundedSlider = readNumEntry( prop, "SmallGroove", false ); + else if ( i == ActiveTab ) + aTabLine = readNumEntry( prop, "BottomLine", true ); + else if ( i == InactiveTab ) + iTabLine = readNumEntry( prop, "BottomLine", true ); + else if ( i == Splitter ) + splitterWidth = readNumEntry( prop, "Width", 10 ); + else if ( i == ComboBox || i == ComboBoxDown ) + { + tmpVal = readNumEntry( prop, "Round", 5000 ); + if ( tmpVal != 5000 ) + roundedCombo = tmpVal; + } + else if ( i == PushButton || i == PushButtonDown ) + { + tmpVal = readNumEntry( prop, "XShift", 0 ); + if ( tmpVal != 5000 ) + btnXShift = tmpVal; + tmpVal = readNumEntry( prop, "YShift", 0 ); + if ( tmpVal != 5000 ) + btnYShift = tmpVal; + tmpVal = readNumEntry( prop, "3DFRect", false ); + if ( tmpVal != 5000 ) + focus3D = tmpVal; + tmpVal = readNumEntry( prop, "3DFOffset", 0 ); + if ( tmpVal != 5000 ) + focus3DOffset = tmpVal; + tmpVal = readNumEntry( prop, "Round", false ); + if ( tmpVal != 5000 ) + roundedButton = tmpVal; + } + loadArray[ i ] = true; +#endif +} + + +QPalette KThemeBase::overridePalette( const QPalette& pal ) +{ + + //Read current settings for colors.. + QColor background = pal.active().background(); + QColor foreground = pal.active().foreground(); + QColor button = background; //CHECKME + QColor highlight = pal.active().highlight(); + QColor highlightedText = pal.active().highlightedText(); //CHECKME + QColor base = pal.active().base(); //config->readColorEntry( "windowBackground", &white ); + QColor baseText = pal.active().text(); //CHECKME + + //See whether there are any immediate overrides. + if ( d->overrideBackground ) + background = d->overrideBackgroundCol; + + if ( d->overrideForeground ) + foreground = d->overrideForegroundCol; + + if ( d->overrideSelectBackground ) + highlight = d->overrideSelectBackgroundCol; + if ( d->overrideSelectForeground ) + highlightedText = d->overrideSelectForegroundCol; + + if ( d->overrideWindowBackground ) + base = d->overrideWindowBackgroundCol; + if ( d->overrideWindowForeground ) + baseText = d->overrideWindowForegroundCol; + + //Now, try to get the button color from the pixmap + if ( uncached( Bevel ) ) + button = d->pixmapAveColor( uncached( Bevel ) ); + + QColor buttonText = foreground; + + int highlightVal, lowlightVal; + highlightVal = 100 + ( 2 * d->contrast + 4 ) * 16 / 10; + lowlightVal = 100 + ( 2 * d->contrast + 4 ) * 10; + + + if ( isPixmap( Background ) || isColor( Background ) ) + { + if ( isColor( Background ) ) + { + background = colorGroup( pal.active(), Background ) + ->background(); + } + if ( isPixmap( Background ) ) + { + background = d->pixmapAveColor( uncached( Background ) ); + } + + + QColorGroup pre( foreground, button, background.light( highlightVal ), + background.dark( lowlightVal ), background.dark( 120 ), + baseText, buttonText /*CHECKME: BrightText*/, base, background ); + + buttonText = colorGroup( pre, PushButton ) ->foreground(); + } + + QColor disfg = foreground; + int h, s, v; + disfg.hsv( &h, &s, &v ); + if ( v > 128 ) + // dark bg, light fg - need a darker disabled fg + disfg = disfg.dark( lowlightVal ); + else if ( disfg != black ) + // light bg, dark fg - need a lighter disabled fg - but only if !black + disfg = disfg.light( highlightVal ); + else + // black fg - use darkgray disabled fg + disfg = Qt::darkGray; + + + QColorGroup disabledgrp( disfg, background, //TODO:Convert this to the new ctor. + background.light( highlightVal ), + background.dark( lowlightVal ), + background.dark( 120 ), + background.dark( 120 ), base ); + + + QColorGroup colgrp( foreground, button, background.light( highlightVal ), + background.dark( lowlightVal ), background.dark( 120 ), + baseText, buttonText /*CHECKME: BrightText*/, base, background ); + + + + colgrp.setColor( QColorGroup::Highlight, highlight ); + colgrp.setColor( QColorGroup::HighlightedText, highlightedText ); + colgrp.setColor( QColorGroup::ButtonText, buttonText ); + colgrp.setColor( QColorGroup::Midlight, button.light( 110 ) ); + + + disabledgrp.setColor( QColorGroup::Base, base ); + disabledgrp.setColor( QColorGroup::Button, button ); + disabledgrp.setColor( QColorGroup::ButtonText, buttonText ); + disabledgrp.setColor( QColorGroup::Midlight, button.light( 110 ) ); + + QPalette newPal( colgrp, disabledgrp, colgrp ); + + return newPal; + +} + +KThemePixmap::KThemePixmap( bool timer ) + : KPixmap() +{ + if ( timer ) + { + t = new QTime; + t->start(); + } + else + t = NULL; + int i; + for ( i = 0; i < 8; ++i ) + b[ i ] = NULL; +} + +KThemePixmap::KThemePixmap( const KThemePixmap &p ) + : KPixmap( p ) +{ + if ( p.t ) + { + t = new QTime; + t->start(); + } + else + t = NULL; + int i; + for ( i = 0; i < 8; ++i ) + if ( p.b[ i ] ) + b[ i ] = new QPixmap( *p.b[ i ] ); + else + b[ i ] = NULL; +} + +KThemePixmap::KThemePixmap( const KThemePixmap &p, const QPixmap &p2 ) + : KPixmap( p2 ) +{ + if ( p.t ) + { + t = new QTime; + t->start(); + } + else + t = NULL; + int i; + for ( i = 0; i < 8; ++i ) + if ( p.b[ i ] ) + b[ i ] = new QPixmap( *p.b[ i ] ); + else + b[ i ] = NULL; +} + + + +KThemePixmap::~KThemePixmap() +{ + if ( t ) + delete t; + int i; + for ( i = 0; i < 8; ++i ) + if ( b[ i ] ) + delete b[ i ]; +} + +KThemeCache::KThemeCache( int maxSize, QObject *parent, const char *name ) + : QObject( parent, name ) +{ + cache.setMaxCost( maxSize * 1024 ); + cache.setAutoDelete( true ); + flushTimer.start( 300000 ); // 5 minutes + connect( &flushTimer, SIGNAL( timeout() ), SLOT( flushTimeout() ) ); +} + +void KThemeCache::flushTimeout() +{ + QIntCacheIterator<KThemePixmap> it( cache ); + while ( it.current() ) + { + if ( it.current() ->isOld() ) + cache.remove( it.currentKey() ); + else + ++it; + } +} + +KThemePixmap* KThemeCache::pixmap( int w, int h, int widgetID, bool border, + bool mask ) +{ + + kthemeKey key; + key.cacheKey = 0; // shut up, gcc + key.data.id = widgetID; + key.data.width = w; + key.data.height = h; + key.data.border = border; + key.data.mask = mask; + + KThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey ); + if ( pix ) + pix->updateAccessed(); + return ( pix ); +} + +KThemePixmap* KThemeCache::horizontalPixmap( int w, int widgetID ) +{ + kthemeKey key; + key.cacheKey = 0; // shut up, gcc + key.data.id = widgetID; + key.data.width = w; + key.data.height = 0; + key.data.border = false; + key.data.mask = false; + KThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey ); + if ( pix ) + pix->updateAccessed(); + return ( pix ); +} + +KThemePixmap* KThemeCache::verticalPixmap( int h, int widgetID ) +{ + kthemeKey key; + key.cacheKey = 0; // shut up, gcc + key.data.id = widgetID; + key.data.width = 0; + key.data.height = h; + key.data.border = false; + key.data.mask = false; + KThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey ); + if ( pix ) + pix->updateAccessed(); + return ( pix ); +} + +bool KThemeCache::insert( KThemePixmap *pixmap, ScaleHint scale, int widgetID, + bool border, bool mask ) +{ + kthemeKey key; + key.cacheKey = 0; // shut up, gcc + key.data.id = widgetID; + key.data.width = ( scale == FullScale || scale == HorizontalScale ) ? + pixmap->width() : 0; + key.data.height = ( scale == FullScale || scale == VerticalScale ) ? + pixmap->height() : 0; + key.data.border = border; + key.data.mask = mask; + + if ( cache.find( ( unsigned long ) key.cacheKey, true ) != NULL ) + { + return ( true ); // a pixmap of this scale is already in there + } + return ( cache.insert( ( unsigned long ) key.cacheKey, pixmap, + pixmap->width() * pixmap->height() * pixmap->depth() / 8 ) ); +} + + + + +#include "kthemebase.moc" diff --git a/kstyles/kthemestyle/kthemebase.h b/kstyles/kthemestyle/kthemebase.h new file mode 100644 index 000000000..8f8041464 --- /dev/null +++ b/kstyles/kthemestyle/kthemebase.h @@ -0,0 +1,853 @@ +/* + $Id$ + + This file is part of the KDE libraries + Copyright (C) 1999 Daniel M. Duley <[email protected]> + + KDE3 port (C) 2001 Maksim Orlovich <[email protected]> + + Palette setup code is from KApplication, +Copyright (C) 1997 Matthias Kalle Dalheimer ([email protected]) +Copyright (C) 1998, 1999, 2000 KDE Team + + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KTHEMEBASE_H +#define KTHEMEBASE_H + +#include <qtimer.h> +#include <qdatetime.h> +#include <kpixmap.h> +#include <qintcache.h> +#include <qstring.h> +#include <kstyle.h> +#include <qsettings.h> +#include <qpalette.h> // for QColorGroup +#include "kstyledirs.h" +#include <qmap.h> + +class QImage; + + + +/** + * This class adds simple time management to KPixmap for use in flushing + * KThemeCache. + * + * @author Daniel M. Duley <[email protected]> + */ +class KThemePixmap : public KPixmap +{ +public: + enum BorderType{Top = 0, Bottom, Left, Right, TopLeft, TopRight, BottomLeft, + BottomRight}; + + KThemePixmap( bool timer = true ); + KThemePixmap( const KThemePixmap &p ); + KThemePixmap( const KThemePixmap &p, const QPixmap& rp ); + ~KThemePixmap(); + QPixmap* border( BorderType type ); + void setBorder( BorderType type, const QPixmap &p ); + void updateAccessed(); + bool isOld(); +protected: + QTime *t; + QPixmap *b[ 8 ]; + +private: + class KThemePixmapPrivate; + KThemePixmapPrivate *d; +}; + +inline QPixmap* KThemePixmap::border( BorderType type ) +{ + return ( b[ type ] ); +} + +inline void KThemePixmap::setBorder( BorderType type, const QPixmap &p ) +{ + if ( b[ type ] ) + { + qWarning( "KThemePixmap: Overwriting existing border!" ); + delete( b[ type ] ); + } + b[ type ] = new QPixmap( p ); +} + +inline void KThemePixmap::updateAccessed() +{ + if ( t ) + t->start(); +} + +inline bool KThemePixmap::isOld() +{ + return ( t ? t->elapsed() >= 300000 : false ); +} + +/** + * A very simple pixmap cache for theme plugins. QPixmapCache is not used + * since it uses QString keys which are not needed. All the information we + * need can be encoded in a numeric key. Using QIntCache instead allows us to + * skip the string operations. + * + * This class is mostly just inline methods that do bit operations on a key + * composed of the widget ID, width and/or height, and then calls + * QIntCache::find(). + * + * One other thing to note is that full, horizontal, and vertically scaled + * pixmaps are not used interchangeably. For example, if you insert a fully + * scaled pixmap that is 32x32 then request a horizontally scaled pixmap with + * a width of 32, they will not match. This is because a pixmap that has been + * inserted into the cache has already been scaled at some point and it is + * very likely the vertical height was not originally 32. Thus the pixmap + * will be wrong when drawn, even though the horizontal width matches. + * + * @author Daniel M. Duley <[email protected]> + * + */ +class KThemeCache : public QObject +{ + Q_OBJECT +public: + /** + * The scale hints supported by the cache. Note that Tiled is not here + * since tiled pixmaps are kept only once in KThemeBase. + */ + enum ScaleHint{FullScale, HorizontalScale, VerticalScale}; + /** + * The constructor. + * + * @param maxSize The maximum size of the cache in kilobytes. + * @param parent The parent object. + * @param name The name of the object. + */ + KThemeCache( int maxSize, QObject *parent = 0, const char *name = 0 ); + /** + * Inserts a new pixmap into the cache. + * + * @param pixmap The pixmap to insert. + * @param scale The scaling type of the pixmap. + * @param widgetID The widget ID of the pixmap, usually from KThemeBase's + * WidgetType enum. + * @param border True if the pixmap has a border. + * @param mask True if the pixmap has a mask. + * + * @return True if the insert was successful, false otherwise. + */ + bool insert( KThemePixmap *pixmap, ScaleHint scale, int widgetID, + bool border = false, bool mask = false ); + /** + * Returns a fully scaled pixmap. + * + * @param w The pixmap width to search for. + * @param h The pixmap height to search for. + * @param widgetID The widget ID to search for. + * @param border True if the pixmap has a border. + * @param mask True if the pixmap has a mask. + * + * @return True if a pixmap matching the width, height, and widget ID of + * the pixmap exists, NULL otherwise. + */ + KThemePixmap* pixmap( int w, int h, int widgetID, bool border = false, + bool mask = false ); + /** + * Returns a horizontally scaled pixmap. + * + * @param w The pixmap width to search for. + * @param widgetID The widget ID to search for. + * + * @return True if a pixmap matching the width and widget ID of + * the pixmap exists, NULL otherwise. + */ + KThemePixmap* horizontalPixmap( int w, int widgetID ); + /** + * Returns a vertically scaled pixmap. + * + * @param h The pixmap height to search for. + * @param widgetID The widget ID to search for. + * + * @return True if a pixmap matching the height and widget ID of + * the pixmap exists, NULL otherwise. + */ + KThemePixmap* verticalPixmap( int h, int widgetID ); +protected slots: + void flushTimeout(); +protected: + QIntCache<KThemePixmap> cache; + QTimer flushTimer; + +private: + class KThemeCachePrivate; + KThemeCachePrivate *d; +}; + + + +class KThemeBasePrivate; +/** + * This is a base class for KDE themed styles. It implements a cache, + * configuration file parsing, pixmap scaling, gradients, and a lot + * of inline methods for accessing user specified parameters. + * + * Note that this class *does not* actually implement any themes. It just + * provides the groundwork for doing so. The only reason to use this class + * directly is if you plan to reimplement all of the widgets. Otherwise, + * refer to KThemeStyle for a fully themed style you can derive from. + * + * @author Daniel M. Duley <[email protected]> + */ +class KThemeBase: public KStyle +{ + Q_OBJECT +public: + /** + * Constructs a new KThemeBase object. + */ + KThemeBase( const QString &dirs, const QString &configFile ); + ~KThemeBase(); + /** + * Describes if a pixmap should be scaled fully, horizontally, vertically, + * or not at all and tiled. + */ + enum ScaleHint{FullScale, HorizontalScale, VerticalScale, TileScale}; + /** + * The default arrow types. + */ + enum ArrowStyle{MotifArrow, LargeArrow, SmallArrow}; + /** + * The default frame shading styles. + */ + enum ShadeStyle{Motif, Windows, Next, KDE}; + /** + * The default scrollbar button layout. BottomLeft is like what Next + * uses, BottomRight is like Platinum, and Opposite it like Windows and + * Motif. + */ + enum SButton{SBBottomLeft, SBBottomRight, SBOpposite}; + /** + * The gradient types. Horizontal is left to right, Vertical is top to + * bottom, and diagonal is upper-left to bottom-right. + */ + enum Gradient{GrNone, GrHorizontal, GrVertical, GrDiagonal, GrPyramid, + GrRectangle, GrElliptic, GrReverseBevel}; + /** + * This provides a list of widget types that KThemeBase recognizes. + */ + /* Internal note: The order here is important. Some widgets inherit + * properties. This is usually for when you have two settings for the + * same widget, ie: on(sunken), and off. The on settings will inherit + * the properties of the off one when nothing is specified in the config. + * + * In order to be able to handle this while still having everything in + * one group that is easy to loop from we have the following order: + * unsunked(off) items, sunken(on)items, and then the ones that don't + * matter. INHERIT_ITEMS define the number of widgets that have inheritence + * so if 0 == PushButtonOff then INHERIT_ITEMS should == PushButtonOn + * and so on. WIDGETS define the total number of widgets. + */ + enum WidgetType{ + // Off (unsunken widgets) + PushButton = 0, ComboBox, HScrollBarSlider, VScrollBarSlider, Bevel, + ToolButton, ScrollButton, HScrollDeco, VScrollDeco, + ComboDeco, MenuItem, InactiveTab, ArrowUp, ArrowDown, ArrowLeft, + ArrowRight, + // On (sunken widgets) + PushButtonDown, ComboBoxDown, HScrollBarSliderDown, + VScrollBarSliderDown, BevelDown, ToolButtonDown, ScrollButtonDown, + HScrollDecoDown, VScrollDecoDown, ComboDecoDown, MenuItemDown, + ActiveTab, SunkenArrowUp, SunkenArrowDown, SunkenArrowLeft, + SunkenArrowRight, + // Everything else (indicators must have separate settings) + HScrollGroove, VScrollGroove, Slider, SliderGroove, IndicatorOn, + IndicatorOff, IndicatorTri, ExIndicatorOn, ExIndicatorOff, HBarHandle, VBarHandle, + ToolBar, Splitter, CheckMark, MenuBar, DisArrowUp, DisArrowDown, + DisArrowLeft, DisArrowRight, ProgressBar, ProgressBg, MenuBarItem, + Background, RotSliderGroove, RotInactiveTab, RotActiveTab, WIDGETS}; + + /** + * The scaling type specified by the KConfig file. + * + * @param widget A Widgets enum value. + * + * @return A ScaleHint enum value. + */ + ScaleHint scaleHint( WidgetType widget ) const; + /** + * The gradient type specified by the KConfig file. + * + * @param widget A Widgets enum value. + * + * @return A Gradient enum value. + */ + Gradient gradientHint( WidgetType widget ) const; + /** + * The color group specified for a given widget. + * If a color group is set in the theme configuration + * that is used, otherwise defaultColor is returned. + * + * @param defaultGroup The colorGroup to set if one is available. + * + * @param widget The widget whose color group to retrieve. + * + */ + const QColorGroup* colorGroup( const QColorGroup &defaultGroup, + WidgetType widget ) const; + + QBrush pixmapBrush( const QColorGroup &group, QColorGroup::ColorRole role, + int w, int h, WidgetType widget ); + /** + * True if the widget has a pixmap or gradient specified. + */ + bool isPixmap( WidgetType widget ) const; + /** + * True if the widget has a color group specified. + */ + bool isColor( WidgetType widget ) const; + /** + * True if the user specified a 3D focus rectangle + */ + bool is3DFocus() const; + /** + * If the user specified a 3D focus rectangle, they may also specify an + * offset from the default rectangle to use when drawing it. This returns + * the specified offset. + */ + int focusOffset() const; + /** + * The border width of the specified widget. + */ + int borderWidth( WidgetType widget ) const; + /** + * Pixmap border width of the specified widget. + */ + int pixBorderWidth( WidgetType widget ) const; + /** + * Returns the border pixmap if enabled for the specified widget. This + * will contain the originial pixmap, plus the edges separated in + * KThemePixmap::border() if valid. If invalid it will return NULL. + */ + KThemePixmap* borderPixmap( WidgetType widget ) const; + /** + * The highlight width of the specified widget. + */ + int highlightWidth( WidgetType widget ) const; + /** + * The border plus highlight width of the widget. + */ + int decoWidth( WidgetType widget ) const; + /** + * The extent (width for vertical, height for horizontal) requested + * for the scrollbars. + */ + int getSBExtent() const; + /** + * The scrollbar button layout. + */ + SButton scrollBarLayout() const; + /** + * The arrow type. + */ + ArrowStyle arrowType() const; + /** + * The shading type. + */ + ShadeStyle shade() const; + /** + * The frame width. + */ + int frameWidth() const; + /** + * The splitter width. + */ + int splitWidth() const; + /** + * The contrast for some bevel effects such as reverse gradient. + */ + int bevelContrast( WidgetType widget ) const; + /** + * The button text X shift. + */ + int buttonXShift() const; + /** + * The button text Y shift. + */ + int buttonYShift() const; + /** + * Returns either the slider length of the slider pixmap if available, + * otherwise the length specified in the config file. + */ + int sliderButtonLength() const; + /** + * True if rounded buttons are requested. + */ + bool roundButton() const; + /** + * True if rounded comboboxes are requested. + */ + bool roundComboBox() const; + /** + * True if rounded slider grooves are requested. + */ + bool roundSlider() const; + /** + * True if a line should be drawn on the bottom of active tabs. + */ + bool activeTabLine() const; + /** + * True if a line should be drawn on the bottom of inactive tabs. + */ + bool inactiveTabLine() const; + /** + * Returns the current uncached pixmap for the given widget. This will + * usually be either the last scaled or gradient pixmap if those have + * been specified in the config file, the original pixmap if not, or NULL + * if no pixmap has been specified. + */ + KThemePixmap* uncached( WidgetType widget ) const; + /** + * Returns the pixmap for the given widget at the specified width and + * height. This will return NULL if no pixmap or gradient is specified. + * It may also return a different sized pixmap if the scaling + * is set to Tiled. When using this method, you should call it using + * the needed width and height then use QPainter::drawTiledPixmap to + * paint it. Doing this, if the pixmap is scaled it will be the proper + * size, otherwise it will be tiled. + * + * @param w Requested width. + * @param h Requested height. + * @param widget Widget type. + * @return The pixmap or NULL if one is not specified. + */ + virtual KThemePixmap *scalePixmap( int w, int h, WidgetType widget ) const; +protected: + /** + * This method reads a configuration file and sets things up so + * overrideColorGroup works. Modiying user's config files within + * a style is evil, IMHO (SadEagle). On the other hand, this will + * make it simply ignore settings. + * + * @param config The configuration file to apply. + */ + void applyConfigFile( QSettings & config ); + + /* + * Generates a new palette based on the values for which have been specified explicitly + * in the .themerc file. + */ + QPalette overridePalette( const QPalette& pal ); + + /** + * Returns a QImage for the given widget if the widget is scaled, NULL + * otherwise. QImages of the original pixmap are stored for scaled + * widgets in order to facilitate fast and accurate smooth-scaling. This + * also saves us a conversion from a pixmap to an image then back again. + */ + QImage* image( WidgetType widget ) const; + /** + * Returns the gradient high color if one is specified, NULL otherwise. + */ + QColor* gradientHigh( WidgetType widget ) const; + /** + * Returns the gradient low color if one is specified, NULL otherwise. + */ + QColor* gradientLow( WidgetType widget ) const; + /** + * Reads in all the configuration file entries supported. + * + * @param colorStyle The style for the color groups. In KDE, colors were + * calculated a little differently for Motif vs Windows styles. This + * is obsolete. + */ + void readConfig( Qt::GUIStyle colorStyle = Qt::WindowsStyle ); + void readWidgetConfig( int i, QSettings *config, QString *pixnames, + QString *brdnames, bool *loadArray ); + void copyWidgetConfig( int sourceID, int destID, QString *pixnames, + QString *brdnames ); + /** + * Makes a full color group based on the given foreground and background + * colors. This is the same code used by KDE (kapp.cpp) in previous + * versions. + */ + QColorGroup* makeColorGroup( const QColor &fg, const QColor &bg, + Qt::GUIStyle style = Qt::WindowsStyle ); + KThemePixmap* scale( int w, int h, WidgetType widget ) const; + KThemePixmap* scaleBorder( int w, int h, WidgetType type ) const; + KThemePixmap* gradient( int w, int h, WidgetType widget ) const ; + KThemePixmap* blend( WidgetType widget ) const; + void generateBorderPix( int i ); + void applyResourceGroup( QSettings *config, int i ); + void applyMiscResourceGroup( QSettings *config ); + void readResourceGroup( int i, QString *pixnames, QString *brdnames, + bool *loadArray ); + void readMiscResourceGroup(); + /** + * Attempts to load a pixmap from the default KThemeBase locations. + */ + KThemePixmap* loadPixmap( const QString &name ); + /** + * Attempts to load a image from the default KThemeBase locations. + */ + QImage* loadImage( const QString &name ); + + + /** + These are included for fuuture extension purposes.. + */ + virtual int pixelMetric ( PixelMetric metric, const QWidget * widget = 0 ) const + { + return KStyle::pixelMetric( metric, widget ); + } + + virtual void drawPrimitive ( PrimitiveElement pe, QPainter * p, const QRect & r, const QColorGroup & cg, + SFlags flags = Style_Default, + const QStyleOption& option = QStyleOption::Default ) const + { + KStyle::drawPrimitive ( pe, p, r, cg, + flags, option ); + } + + + virtual void drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how = Style_Default, + const QStyleOption& opt = QStyleOption::Default ) const + { + KStyle::drawControl( element, p, widget, + r, cg, how, opt ); + } + + virtual void drawControlMask( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& opt = QStyleOption::Default ) const + { + KStyle::drawControlMask( element, p, widget, r, opt ); + } + + + virtual void drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + SCFlags controls = SC_All, + SCFlags active = SC_None, + const QStyleOption& opt = QStyleOption::Default ) const + { + KStyle::drawComplexControl( control, p, widget, r, cg, flags, controls, active, opt ); + } + + + virtual void drawKStylePrimitive( KStylePrimitive kpe, + QPainter* p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& opt = QStyleOption::Default ) const + { + KStyle::drawKStylePrimitive( kpe, + p, widget, r, + cg, flags, opt ); + } + + + virtual int styleHint( StyleHint sh, + const QWidget *widget = 0, + const QStyleOption& opt = QStyleOption::Default, + QStyleHintReturn* returnData = 0 ) const + { + return KStyle::styleHint( sh, + widget, + opt, + returnData ); + } + + virtual QSize sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentsSize, + const QStyleOption& opt = QStyleOption::Default ) const + { + return KStyle::sizeFromContents( contents, + widget, contentsSize, opt ); + } + +private: + KThemeBasePrivate *d; + + SButton sbPlacement; + ArrowStyle arrowStyle; + ShadeStyle shading; + int defaultFrame; + int btnXShift, btnYShift; + int sliderLen; + int splitterWidth; + int focus3DOffset; + int sbExtent; + bool smallGroove; + bool roundedButton, roundedCombo, roundedSlider; + bool aTabLine, iTabLine; + bool focus3D; + KThemeCache *cache; + int cacheSize; + QString configFileName; + QString configDirName; + + /** + * The theme pixmaps. Many of these may be NULL if no pixmap is specified. + * There may also be duplicate pixmap pointers if more than one widget + * uses the same tiled pixmap. If a pixmap is tiled, it is kept here and + * this acts as a cache. Otherwise this will hold whatever the last scaled + * pixmap was. + */ + mutable KThemePixmap *pixmaps[ WIDGETS ]; + /** + * The theme images. These are for scaled images and are kept in order + * to maintain fast smoothscaling. + */ + mutable QImage *images[ WIDGETS ]; + /** + * The border widths + */ + mutable unsigned char borders[ WIDGETS ]; + /** + * The highlight widths + */ + mutable unsigned char highlights[ WIDGETS ]; + /** + * The scale hints for pixmaps and gradients. + */ + mutable ScaleHint scaleHints[ WIDGETS ]; + /** + * All the color groups. + */ + mutable QColorGroup *colors[ WIDGETS ]; + /** + * Gradient low colors (or blend background). + */ + mutable QColor *grLowColors[ WIDGETS ]; + /** + * Gradient high colors. + */ + mutable QColor *grHighColors[ WIDGETS ]; + /** + * Gradient types. + */ + mutable Gradient gradients[ WIDGETS ]; + /** + * Blend intensity factors + */ + mutable float blends[ WIDGETS ]; + /** + * Bevel contrasts + */ + mutable unsigned char bContrasts[ WIDGETS ]; + /** + * Duplicate pixmap entries (used during destruction). + */ + mutable bool duplicate[ WIDGETS ]; + /** + * Pixmapped border widths + */ + mutable int pbWidth[ WIDGETS ]; + /** + * Pixmapped borders + */ + mutable KThemePixmap *pbPixmaps[ WIDGETS ]; + /** + * Duplicate border pixmapped border entries + */ + mutable bool pbDuplicate[ WIDGETS ]; + +}; + +inline bool KThemeBase::isPixmap( WidgetType widget ) const +{ + return ( pixmaps[ widget ] != NULL || gradients[ widget ] != GrNone ); +} + +inline bool KThemeBase::isColor( WidgetType widget ) const +{ + return ( colors[ widget ] != NULL ); +} + +inline bool KThemeBase::is3DFocus() const +{ + return ( focus3D ); +} + +inline int KThemeBase::focusOffset() const +{ + return ( focus3DOffset ); +} + +inline int KThemeBase::bevelContrast( WidgetType widget ) const +{ + return ( bContrasts[ widget ] ); +} + +inline KThemeBase::ScaleHint KThemeBase::scaleHint( WidgetType widget ) const +{ + return ( ( widget < WIDGETS ) ? scaleHints[ widget ] : TileScale ); +} + +inline KThemeBase::Gradient KThemeBase::gradientHint( WidgetType widget ) const +{ + return ( ( widget < WIDGETS ) ? gradients[ widget ] : GrNone ); +} + +inline KThemePixmap* KThemeBase::uncached( WidgetType widget ) const +{ + return ( pixmaps[ widget ] ); +} + +inline QBrush KThemeBase::pixmapBrush( const QColorGroup &group, + QColorGroup::ColorRole role, + int w, int h, WidgetType widget ) +{ + if ( pixmaps[ widget ] || images[ widget ] ) + return ( QBrush( group.color( role ), *scalePixmap( w, h, widget ) ) ); + else + return ( group.color( role ) ); +} + +inline const QColorGroup* KThemeBase::colorGroup( const QColorGroup &defaultGroup, + WidgetType widget ) const +{ + return ( ( colors[ widget ] ) ? colors[ widget ] : &defaultGroup ); +} + +inline int KThemeBase::borderWidth( WidgetType widget ) const +{ + return ( pbWidth[ widget ] ? pbWidth[ widget ] : borders[ widget ] ); +} + +inline int KThemeBase::pixBorderWidth( WidgetType widget ) const +{ + return ( pbWidth[ widget ] ); +} + +inline int KThemeBase::highlightWidth( WidgetType widget ) const +{ + return ( pbWidth[ widget ] ? 0 : highlights[ widget ] ); +} + +inline int KThemeBase::decoWidth( WidgetType widget ) const +{ + return ( pbWidth[ widget ] ? pbWidth[ widget ] : borders[ widget ] + highlights[ widget ] ); +} + +inline QColor* KThemeBase::gradientHigh( WidgetType widget ) const +{ + return ( grHighColors[ widget ] ); +} + +inline QColor* KThemeBase::gradientLow( WidgetType widget ) const +{ + return ( grLowColors[ widget ] ); +} + +inline QImage* KThemeBase::image( WidgetType widget ) const +{ + return ( images[ widget ] ); +} + +inline KThemeBase::SButton KThemeBase::scrollBarLayout() const +{ + return ( sbPlacement ); +} + +inline KThemeBase::ArrowStyle KThemeBase::arrowType() const +{ + return ( arrowStyle ); +} + +inline KThemeBase::ShadeStyle KThemeBase::shade() const +{ + return ( shading ); +} + +inline int KThemeBase::frameWidth() const +{ + return ( defaultFrame ); +} + +inline int KThemeBase::buttonXShift() const +{ + return ( btnXShift ); +} + +inline int KThemeBase::splitWidth() const +{ + return ( splitterWidth ); +} + +inline int KThemeBase::buttonYShift() const +{ + return ( btnYShift ); +} + +inline int KThemeBase::sliderButtonLength() const +{ + if ( isPixmap( Slider ) ) + return ( uncached( Slider ) ->width() ); + else + return ( sliderLen ); +} + +inline bool KThemeBase::roundButton() const +{ + return ( roundedButton ); +} + +inline bool KThemeBase::roundComboBox() const +{ + return ( roundedCombo ); +} + +inline bool KThemeBase::roundSlider() const +{ + return ( roundedSlider ); +} + +inline bool KThemeBase::activeTabLine() const +{ + return ( aTabLine ); +} + +inline bool KThemeBase::inactiveTabLine() const +{ + return ( iTabLine ); +} + +inline int KThemeBase::getSBExtent() const +{ + return ( sbExtent ); +} + +inline KThemePixmap* KThemeBase::borderPixmap( WidgetType widget ) const +{ + return ( pbPixmaps[ widget ] ); +} + +#endif diff --git a/kstyles/kthemestyle/kthemestyle.cpp b/kstyles/kthemestyle/kthemestyle.cpp new file mode 100644 index 000000000..cdb419772 --- /dev/null +++ b/kstyles/kthemestyle/kthemestyle.cpp @@ -0,0 +1,2384 @@ +/* + $Id$ + + This file is part of the KDE libraries + Copyright (C) 1999 Daniel M. Duley <[email protected]> + + KDE3 port (C) 2001-2002 Maksim Orlovich <[email protected]> +Port version 0.9.7 + + Includes code portions from the dotNET style, and the KDE HighColor style. + + dotNET Style + Copyright (C) 2001, Chris Lee <[email protected]> + Carsten Pfeiffer <[email protected]> + + KDE3 HighColor Style + Copyright (C) 2001 Karol Szwed <[email protected]> + (C) 2001 Fredrik H�glund <[email protected]> + + Drawing routines adapted from the KDE2 HCStyle, + Copyright (C) 2000 Daniel M. Duley <[email protected]> + (C) 2000 Dirk Mueller <[email protected]> + (C) 2001 Martijn Klingens <[email protected]> + + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kthemestyle.h" +#include "kthemebase.h" +#include <qstyleplugin.h> +#include <qstylefactory.h> +#include <kimageeffect.h> + +#include <qbitmap.h> +#include <qcheckbox.h> +#include <qlabel.h> +#define INCLUDE_MENUITEM_DEF +#include <qmenudata.h> +#include <qpopupmenu.h> +#include <qpalette.h> +#include <qtabbar.h> +#include <qtoolbutton.h> +#include <kglobalsettings.h> +#include <kdrawutil.h> +#include <qdrawutil.h> +#include <qprogressbar.h> +#include <qdir.h> +#include <qapplication.h> +#include <qmenubar.h> +#include <qrangecontrol.h> +#include <qslider.h> +#include <qtooltip.h> +#include <qobjectlist.h> +#include <qradiobutton.h> +#include <qstatusbar.h> +#include "kstyledirs.h" + +#include <qimage.h> + +#include <limits.h> + +#ifdef __GLIBC__ +#include <dlfcn.h> +#endif + +static const QCOORD u_arrow[] = { -1, -3, 0, -3, -2, -2, 1, -2, -3, -1, 2, -1, -4, 0, 3, 0, -4, 1, 3, 1}; +static const QCOORD d_arrow[] = { -4, -2, 3, -2, -4, -1, 3, -1, -3, 0, 2, 0, -2, 1, 1, 1, -1, 2, 0, 2}; +static const QCOORD l_arrow[] = { -3, -1, -3, 0, -2, -2, -2, 1, -1, -3, -1, 2, 0, -4, 0, 3, 1, -4, 1, 3}; +static const QCOORD r_arrow[] = { -2, -4, -2, 3, -1, -4, -1, 3, 0, -3, 0, 2, 1, -2, 1, 1, 2, -1, 2, 0}; + +const QCOORD win_style_u_arrow[] = { 0, -2, 0, -2, -1, -1, 1, -1, -2, 0, 2, 0, -3, 1, 3, 1 }; +const QCOORD win_style_d_arrow[] = { -3, -2, 3, -2, -2, -1, 2, -1, -1, 0, 1, 0, 0, 1, 0, 1 }; +const QCOORD win_style_l_arrow[] = { 1, -3, 1, -3, 0, -2, 1, -2, -1, -1, 1, -1, -2, 0, 1, 0, -1, 1, 1, 1, 0, 2, 1, 2, 1, 3, 1, 3 }; +const QCOORD win_style_r_arrow[] = { -2, -3, -2, -3, -2, -2, -1, -2, -2, -1, 0, -1, -2, 0, 1, 0, -2, 1, 0, 1, -2, 2, -1, 2, -2, 3, -2, 3 }; + + +#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) + + +static const int itemFrame = 2; +static const int itemHMargin = 3; +static const int itemVMargin = 1; +static const int arrowHMargin = 6; +static const int rightBorder = 12; + + +/* +BUGS: +Sliders flash a bit -- anything else? + +TODO: +Nicer disabled buttons. +Sliders are not disabled properly +*/ + + +class KThemeStylePlugin : public QStylePlugin +{ +public: + + KThemeStylePlugin() + { +#ifdef __GLIBC__ + dlopen("kthemestyle.so",RTLD_LAZY); + //####### Keep reference count up so kdecore w. fast-malloc doesn't get unloaded + //####### (Fixes exit crashes with qt-only apps that occur on Linux) + //####### This should be rethought after 3.0, + //####### as it relies on the implementation-specific behavior + //####### of the glibc libdl (finding already loaded libraries based on the + //####### soname) +#endif + } + + ~KThemeStylePlugin() + {} + + QStringList keys() const + { + QSettings cfg; + KStyleDirs::dirs()->addToSearch( "config", cfg ); + + QStringList keys; + bool ok; + + keys = cfg.readListEntry( "/kthemestyle/themes", &ok); + if ( !ok ) + qWarning( "KThemeStyle cache seems corrupt!\n" ); //Too bad one can't i18n this :-( + + return keys; + } + + QStyle* create( const QString& key ) + { + QSettings cfg; + KStyleDirs::dirs()->addToSearch( "config", cfg ); + + QString file = cfg.readEntry( "/kthemestyle/" + key + "/file" ); + if ( !key.isEmpty() ) + { + QFileInfo fi( file ); + return new KThemeStyle( fi.dirPath(), fi.fileName() ); + } + + return 0; + } +}; + +KDE_Q_EXPORT_PLUGIN( KThemeStylePlugin ) + + +void kDrawWindowsArrow ( QPainter *p, const QStyle* style, QStyle::PrimitiveElement pe, bool down, + int x, int y, int w, int h, + const QColorGroup &cg, bool enabled ) +{ + QPointArray a; + switch ( pe ) + { + case QStyle::PE_ArrowUp: + a.setPoints( QCOORDARRLEN( win_style_u_arrow ), win_style_u_arrow ); + break; + + case QStyle::PE_ArrowDown: + a.setPoints( QCOORDARRLEN( win_style_d_arrow ), win_style_d_arrow ); + break; + + case QStyle::PE_ArrowLeft: + a.setPoints( QCOORDARRLEN( win_style_l_arrow ), win_style_l_arrow ); + break; + default: + a.setPoints( QCOORDARRLEN( win_style_r_arrow ), win_style_r_arrow ); + } + + p->save(); + if ( down ) + { + p->translate( style->pixelMetric( QStyle::PM_ButtonShiftHorizontal ), + style->pixelMetric( QStyle::PM_ButtonShiftVertical ) ); + } + + if ( enabled ) + { + a.translate( x + w / 2, y + h / 2 ); + p->setPen( cg.buttonText() ); + p->drawLineSegments( a ); + } + else + { + a.translate( x + w / 2 + 1, y + h / 2 + 1 ); + p->setPen( cg.light() ); + p->drawLineSegments( a ); + a.translate( -1, -1 ); + p->setPen( cg.mid() ); + p->drawLineSegments( a ); + } + + p->restore(); + +} + + + +QSize KThemeStyle::sizeFromContents( ContentsType contents, + const QWidget* widget, + const QSize &contentSize, + const QStyleOption& opt ) const +{ + switch ( contents ) + { + // PUSHBUTTON SIZE + // ------------------------------------------------------------------ + case CT_PushButton: + { + const QPushButton * button = ( const QPushButton* ) widget; + int w = contentSize.width(); + int h = contentSize.height(); + int bm = pixelMetric( PM_ButtonMargin, widget ); + int fw = pixelMetric( PM_DefaultFrameWidth, widget ) * 2; + + w += bm + fw + 6; // ### Add 6 to make way for bold font. + h += bm + fw; + + // Ensure we stick to standard width and heights. + if ( button->isDefault() || button->autoDefault() ) + { + if ( w < 80 && !button->text().isEmpty() ) + w = 80; + } + + if ( h < 22 ) + h = 22; + + return QSize( w, h ); + } + + // POPUPMENU ITEM SIZE + // ----------------------------------------------------------------- + case CT_PopupMenuItem: + { + if ( ! widget || opt.isDefault() ) + return contentSize; + + const QPopupMenu *popup = ( const QPopupMenu * ) widget; + bool checkable = popup->isCheckable(); + QMenuItem *mi = opt.menuItem(); + int maxpmw = opt.maxIconWidth(); + int w = contentSize.width(), h = contentSize.height(); + + if ( mi->custom() ) + { + w = mi->custom() ->sizeHint().width(); + h = mi->custom() ->sizeHint().height(); + if ( ! mi->custom() ->fullSpan() ) + h += 2 * itemVMargin + 2 * itemFrame; + } + else if ( mi->widget() ) + {} + else if ( mi->isSeparator() ) + { + w = 10; // Arbitrary + h = 2; + } + else + { + if ( mi->pixmap() ) + h = QMAX( h, mi->pixmap() ->height() + 2 * itemFrame ); + else + h = QMAX( h, popup->fontMetrics().height() + + 2 * itemVMargin + 2 * itemFrame ); + + if ( mi->iconSet() ) + h = QMAX( h, mi->iconSet() ->pixmap( + QIconSet::Small, QIconSet::Normal ).height() + + 2 * itemFrame ); + } + + if ( ! mi->text().isNull() && mi->text().find( '\t' ) >= 0 ) + w += 12; + else if ( mi->popup() ) + w += 2 * arrowHMargin; + + if ( maxpmw ) + w += maxpmw + 6; + if ( checkable && maxpmw < 20 ) + w += 20 - maxpmw; + if ( checkable || maxpmw > 0 ) + w += 12; + + w += rightBorder; + + return QSize( w, h ); + } + + default: + return KThemeBase::sizeFromContents( contents, widget, contentSize, opt ); + } +} + + +QRect KThemeStyle::subRect(SubRect sr, const QWidget* widget) const +{ + if (sr == SR_CheckBoxFocusRect) + { + const QCheckBox* cb = static_cast<const QCheckBox*>(widget); + + //Only checkbox, no label + if (cb->text().isEmpty() && (cb->pixmap() == 0) ) + { + QRect bounding = cb->rect(); + + int cw = pixelMetric(PM_IndicatorWidth, widget); + int ch = pixelMetric(PM_IndicatorHeight, widget); + + QRect checkbox(bounding.x() + 2, bounding.y() + 2 + (bounding.height() - ch)/2, cw - 4, ch - 4); + + return checkbox; + } + } + return KStyle::subRect(sr, widget); +} + +int KThemeStyle::pixelMetric ( PixelMetric metric, const QWidget * widget ) const +{ + switch ( metric ) + { + case PM_MenuBarFrameWidth: + return 1; + case PM_DefaultFrameWidth: + return ( frameWidth() ); + + case PM_ButtonMargin: + return decoWidth( PushButton ) > decoWidth( PushButtonDown ) ? + 3 + decoWidth( PushButton ) : 3 + decoWidth( PushButtonDown ); + + case PM_ScrollBarExtent: + case PM_SliderThickness: //Should this be 16 always? + return getSBExtent(); + + case PM_ButtonDefaultIndicator: + return 0; + + case PM_ButtonShiftHorizontal: + return buttonXShift(); + + case PM_ButtonShiftVertical: + return buttonYShift(); + + case PM_ExclusiveIndicatorWidth: + if ( isPixmap( ExIndicatorOn ) ) + return ( uncached( ExIndicatorOn ) ->size().width() ); + else + return KThemeBase::pixelMetric ( metric, widget ); + + case PM_ExclusiveIndicatorHeight: + if ( isPixmap( ExIndicatorOn ) ) + return ( uncached( ExIndicatorOn ) ->size().height() ); + else + return KThemeBase::pixelMetric ( metric, widget ); + + + case PM_IndicatorWidth: + if ( isPixmap( IndicatorOn ) ) + return ( uncached( IndicatorOn ) ->size().width() ); + else + return KThemeBase::pixelMetric ( metric, widget ); + + case PM_IndicatorHeight: + if ( isPixmap( IndicatorOn ) ) + return ( uncached( IndicatorOn ) ->size().height() ); + else + return KThemeBase::pixelMetric ( metric, widget ); + + case PM_SliderLength: + return ( sliderButtonLength() ); + + case PM_SplitterWidth: + return ( splitWidth() ); + + default: + return KThemeBase::pixelMetric ( metric, widget ); + } +} + + + +KThemeStyle::KThemeStyle( const QString& configDir, const QString &configFile ) + : KThemeBase( configDir, configFile ), paletteSaved( false ), polishLock( false ), menuCache( 0 ), vsliderCache( 0 ), + brushHandle( 0 ), brushHandleSet( false ), kickerMode( false ) +{ + mtfstyle = QStyleFactory::create( "Motif" ); + if ( !mtfstyle ) + mtfstyle = QStyleFactory::create( *( QStyleFactory::keys().begin() ) ); +} + +KThemeStyle::~KThemeStyle() +{ + delete vsliderCache; + delete menuCache; + +} + + +void KThemeStyle::polish( QApplication * app ) +{ + if (!qstrcmp(app->argv()[0], "kicker")) + kickerMode = true; +} + + +void KThemeStyle::polish( QPalette &p ) +{ + if ( polishLock ) + { + return ; //Palette polishing disabled ... + } + + + + if ( !paletteSaved ) + { + oldPalette = p; + paletteSaved = true; + } + + p = overridePalette( p ); + + if ( isPixmap( Background ) ) + { + QBrush bgBrush( p.color( QPalette::Normal, + QColorGroup::Background ), + *uncached( Background ) ); + brushHandle = uncached( Background )->handle(); + brushHandleSet = true; + p.setBrush( QColorGroup::Background, bgBrush ); + } + +} + +void KThemeStyle::paletteChanged() +{ + QPalette p = QApplication::palette(); + polish( p ); + QApplication::setPalette( p ); +} + + +void KThemeStyle::unPolish( QApplication *app ) +{ + app->setPalette( oldPalette, true ); +} + +bool KThemeStyle::eventFilter( QObject* object, QEvent* event ) +{ + if( object->inherits("KActiveLabel")) + { + if(event->type() == QEvent::Move || event->type() == QEvent::Resize || + event->type() == QEvent::Show) + { + QWidget *w = static_cast<QWidget*>(object); + QPoint pos(0, 0); + pos = w->mapTo(w->topLevelWidget(), pos); + QPixmap pix(uncached( Background )->size()); + QPainter p; + p.begin(&pix); + p.drawTiledPixmap(0, 0, + uncached( Background )->width(), + uncached( Background )->height() , + *uncached( Background ), + pos.x(), pos.y()); + p.end(); + QPalette pal(w->palette()); + QBrush brush( pal.color( QPalette::Normal, + QColorGroup::Background), + pix ); + pal.setBrush(QColorGroup::Base, brush); + w->setPalette(pal); + } + } + if (!qstrcmp(object->name(), "kde toolbar widget") && object->inherits("QLabel")) + { + QWidget* lb = static_cast<QWidget*>(object); + if (lb->backgroundMode() == Qt::PaletteButton) + lb->setBackgroundMode(Qt::PaletteBackground); + lb->removeEventFilter(this); + } + + return KStyle::eventFilter(object, event); +} + +void KThemeStyle::polish( QWidget *w ) +{ + if (::qt_cast<QStatusBar*>(w)) + w->setPaletteBackgroundColor(QApplication::palette().color(QPalette::Normal, QColorGroup::Background)); + + if (::qt_cast<QLabel*>(w) && !qstrcmp(w->name(), "kde toolbar widget")) + w->installEventFilter(this); + + if (w->backgroundPixmap() && !w->isTopLevel() && + (!kickerMode || + (!w->inherits("TaskBar") && !w->inherits("TaskBarContainer") && !w->inherits("TaskbarApplet") && !w->inherits("ContainerArea") && !w->inherits("AppletHandle")))) + { + //The brushHandle check verifies that the bg pixmap is actually the brush.. + if (!brushHandleSet || brushHandle == w->backgroundPixmap()->handle()) + { + w->setBackgroundOrigin( QWidget::WindowOrigin ); + } + } + + if (w->inherits("KActiveLabel")) + { + if (uncached( Background )) + w->installEventFilter(this); + } + + if ( w->inherits( "QTipLabel" ) ) + { + polishLock = true; + + QColorGroup clrGroup( Qt::black, QColor( 255, 255, 220 ), + QColor( 96, 96, 96 ), Qt::black, Qt::black, + Qt::black, QColor( 255, 255, 220 ) ); + QPalette toolTip ( clrGroup, clrGroup, clrGroup ); + + QToolTip::setPalette( toolTip ); + polishLock = false; + } + + if ( w->inherits( "KonqIconViewWidget" ) ) //Konqueror background hack/workaround + { + w->setPalette( oldPalette ); + return ; + } + + if ( ::qt_cast<QMenuBar*>(w) ) + { + w->setBackgroundMode( QWidget::NoBackground ); + } + else if ( w->inherits( "KToolBarSeparator" ) || w->inherits( "QToolBarSeparator" ) ) + { + w->setBackgroundMode( QWidget::PaletteBackground ); + } + else if ( ::qt_cast<QPopupMenu*>(w) ) + { + popupPalette = w->palette(); + if ( isColor( MenuItem ) || isColor( MenuItemDown ) ) + { + QPalette newPal( w->palette() ); + if ( isColor( MenuItem ) ) + { + newPal.setActive( *colorGroup( newPal.active(), MenuItem ) ); + newPal.setDisabled( *colorGroup( newPal.active(), MenuItem ) ); + } + if ( isColor( MenuItemDown ) ) + { + newPal.setActive( *colorGroup( newPal.active(), MenuItemDown ) ); + } + w->setPalette( newPal ); + } + + w->setBackgroundMode( QWidget::NoBackground ); + } + else if ( ::qt_cast<QCheckBox*>(w) ) + { + if ( isColor( IndicatorOff ) || isColor( IndicatorOn ) ) + { + QPalette newPal( w->palette() ); + if ( isColor( IndicatorOff ) ) + { + newPal.setActive( *colorGroup( newPal.active(), IndicatorOff ) ); + newPal.setDisabled( *colorGroup( newPal.active(), IndicatorOff ) ); + } + if ( isColor( IndicatorOn ) ) + newPal.setActive( *colorGroup( newPal.active(), IndicatorOn ) ); + w->setPalette( newPal ); + } + } + else if ( ::qt_cast<QRadioButton*>(w) ) + { + if ( isColor( ExIndicatorOff ) || isColor( ExIndicatorOn ) ) + { + QPalette newPal( w->palette() ); + if ( isColor( ExIndicatorOff ) ) + { + newPal.setActive( *colorGroup( newPal.active(), ExIndicatorOff ) ); + newPal.setDisabled( *colorGroup( newPal.active(), + ExIndicatorOff ) ); + } + if ( isColor( ExIndicatorOn ) ) + newPal.setActive( *colorGroup( newPal.active(), ExIndicatorOn ) ); + w->setPalette( newPal ); + } + } + + KStyle::polish( w ); +} + +void KThemeStyle::unPolish( QWidget* w ) +{ + if (w->backgroundPixmap() && !w->isTopLevel()) + { + //The brushHandle check verifies that the bg pixmap is actually the brush.. + if (!brushHandleSet || brushHandle ==w->backgroundPixmap()->handle()) + { + w->setBackgroundOrigin( QWidget::WidgetOrigin ); + } + } + + //Toolbar labels should nornally be PaletteButton + if ( ::qt_cast<QLabel*>(w) && !qstrcmp(w->name(), "kde toolbar widget")) + w->setBackgroundMode( QWidget::PaletteButton ); + + //The same for menu bars, popup menus + else if ( ::qt_cast<QMenuBar*>(w) || ::qt_cast<QPopupMenu*>(w) ) + w->setBackgroundMode( QWidget::PaletteButton ); + + //For toolbar internal separators, return to button, too (can't use qt_cast here since don't have access to the class) + else if ( w->inherits( "KToolBarSeparator" ) || w->inherits( "QToolBarSeparator" ) ) + w->setBackgroundMode( QWidget::PaletteButton ); + + //For scrollbars, we don't do much, since the widget queries the style on the switch + + //Drop some custom palettes. ### this really should check the serial number to be 100% correct. + if ( ::qt_cast<QPopupMenu*>(w) || ::qt_cast<QCheckBox*>(w) || ::qt_cast<QRadioButton*>(w) || ::qt_cast<QStatusBar*>(w) ) + w->unsetPalette(); + + KStyle::unPolish( w ); +} + + +void KThemeStyle::drawBaseButton( QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool sunken, bool + rounded, WidgetType type ) const +{ + int offset = borderPixmap( type ) ? 0 : decoWidth( type ) ; //##### This is wrong, but the code relies on it.. + QPen oldPen = p->pen(); + + // handle reverse bevel here since it uses decowidth differently + if ( gradientHint( type ) == GrReverseBevel ) + { + int i; + bitBlt( p->device(), x, y, scalePixmap( w, h, type ), 0, 0, w, h, + Qt::CopyROP, true ); + p->setPen( g.text() ); + for ( i = 0; i < borderWidth( type ); ++i, ++x, ++y, w -= 2, h -= 2 ) + p->drawRect( x, y, w, h ); + } + // same with KDE style borders + else if ( !borderPixmap( type ) && shade() == KDE ) + { + kDrawBeButton( p, x, y, w, h, g, sunken ); + if ( isPixmap( type ) ) + p->drawTiledPixmap( x + 4, y + 4, w - 6, h - 6, + *scalePixmap( w - 6, h - 6, + type ) ); + else + p->fillRect( x + 4, y + 4, w - 6, h - offset * 6, + g.brush( QColorGroup::Button ) ); + + } + else + { + if ( ( w - offset * 2 ) > 0 && ( h - offset * 2 ) > 0 ) + { + if ( isPixmap( type ) ) + if ( rounded ) + p->drawTiledPixmap( x, y, w, h, *scalePixmap( w, h, type ) ); + else + p->drawTiledPixmap( x + offset, y + offset, w - offset * 2, + h - offset * 2, + *scalePixmap( w - offset * 2, h - offset * 2, + type ) ); + else if ( 1 ) //##### TODO - Get this optimization working... !borderPixmap( type ) || (( w - decoWidth(type) * 2 ) > 0 && ( h - decoWidth(type) * 2 ) > 0) ) + //Sometimes border covers the whole thing - in that case, avoid drawing the base. + { + p->fillRect( x + offset, y + offset, w - offset * 2, h - offset * 2, + g.brush( QColorGroup::Button ) ); + } + } + if ( borderPixmap( type ) ) + { + bitBlt( p->device(), x, y, scaleBorder( w, h, type ), 0, 0, w, h, + Qt::CopyROP, false ); + } + else + drawShade( p, x, y, w, h, g, sunken, rounded, + highlightWidth( type ), borderWidth( type ), shade() ); + } + p->setPen( oldPen ); +} + +void KThemeStyle::drawPrimitive ( PrimitiveElement pe, QPainter * p, const QRect & r, const QColorGroup & g_base, + SFlags flags, const QStyleOption & opt ) const +{ + bool handled = false; + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + bool sunken = ( flags & Style_Sunken ); + bool enabled = ( flags & Style_Enabled ); + bool down = ( flags & Style_Down ); + bool on = flags & Style_On; + QColorGroup g = g_base; + + switch ( pe ) + { + case PE_ArrowUp: + case PE_ArrowDown: + case PE_ArrowRight: + case PE_ArrowLeft: + { + QRect r( x, y, w, h ); + if ( r.width() > 12 ) + { + r.setRect( r.x() + ( r.width() - 12 ) / 2, r.y(), 12, r.height() ); + } + if ( r.height() > 12 ) + { + r.setRect( r.x(), r.y() + ( r.height() - 12 ) / 2, r.width(), 12 ); + } + r.rect( &x, &y, &w, &h ); + // Handles pixmapped arrows. A little inefficient because you can specify + // some as pixmaps and some as default types. + WidgetType widget; + switch ( pe ) + { + case PE_ArrowUp: + widget = enabled ? down ? SunkenArrowUp : ArrowUp : DisArrowUp; + break; + case PE_ArrowDown: + widget = enabled ? down ? SunkenArrowDown : ArrowDown : DisArrowDown; + break; + case PE_ArrowLeft: + widget = enabled ? down ? SunkenArrowLeft : ArrowLeft : DisArrowLeft; + break; + case PE_ArrowRight: + default: + widget = enabled ? down ? SunkenArrowRight : ArrowRight : DisArrowRight; + break; + } + if ( isPixmap( widget ) ) + { + bitBlt( p->device(), x + ( w - uncached( widget ) ->width() ) / 2, + y + ( h - uncached( widget ) ->height() ) / 2, + uncached( widget ) ); + + return ; + } + const QColorGroup *cg = colorGroup( g, widget ); + // Standard arrow types + if ( arrowType() == MotifArrow ) + { + mtfstyle->drawPrimitive( pe, p, r, g, flags, opt ); + + handled = true; + } + else if ( arrowType() == SmallArrow ) + { + // #### FIXME: This should be like the Platinum style - uses HighColor look for now + QPointArray a; + + switch ( pe ) + { + case PE_ArrowUp: + a.setPoints( QCOORDARRLEN( u_arrow ), u_arrow ); + break; + + case PE_ArrowDown: + a.setPoints( QCOORDARRLEN( d_arrow ), d_arrow ); + break; + + case PE_ArrowLeft: + a.setPoints( QCOORDARRLEN( l_arrow ), l_arrow ); + break; + + default: + a.setPoints( QCOORDARRLEN( r_arrow ), r_arrow ); + } + + p->save(); + + if ( flags & Style_Down ) + p->translate( pixelMetric( PM_ButtonShiftHorizontal ), + pixelMetric( PM_ButtonShiftVertical ) ); + + if ( flags & Style_Enabled ) + { + a.translate( r.x() + r.width() / 2, r.y() + r.height() / 2 ); + p->setPen( cg->buttonText() ); + p->drawLineSegments( a ); + } + else + { + a.translate( r.x() + r.width() / 2 + 1, r.y() + r.height() / 2 + 1 ); + p->setPen( cg->mid() ); + p->drawLineSegments( a ); + } + p->restore(); + } + else + { + QPointArray a; + int x2 = x + w - 1, y2 = y + h - 1; + switch ( pe ) + { + case PE_ArrowUp: + a.setPoints( 4, x, y2, x2, y2, x + w / 2, y, x, y2 ); + break; + case PE_ArrowDown: + a.setPoints( 4, x, y, x2, y, x + w / 2, y2, x, y ); + break; + case PE_ArrowLeft: + a.setPoints( 4, x2, y, x2, y2, x, y + h / 2, x2, y ); + break; + default: + a.setPoints( 4, x, y, x, y2, x2, y + h / 2, x, y ); + break; + } + QBrush oldBrush = p->brush(); + QPen oldPen = p->pen(); + p->setBrush( cg->brush( QColorGroup::Shadow ) ); + p->setPen( cg->shadow() ); + p->drawPolygon( a ); + p->setBrush( oldBrush ); + p->setPen( oldPen ); + handled = true; + } + break; + + } + case PE_HeaderSection: + { + sunken = false; //Never mind this one + } + case PE_ButtonBevel: + { + WidgetType type = ( sunken || on || down ) ? BevelDown : Bevel; + drawBaseButton( p, x, y, w, h, *colorGroup( g, type ), ( sunken || on || down ), false, type ); + handled = true; + break; + } + case PE_ButtonCommand: + { + drawBaseButton( p, x, y, w, h, g, ( sunken || on || down ), roundButton(), ( sunken || on || down ) ? + PushButtonDown : PushButton ); + handled = true; + break; + } + case PE_PanelDockWindow: + { + drawBaseButton( p, x, y, w, h, *colorGroup( g, ToolBar ), false, false, + ToolBar ); + handled = true; + break; + } + case PE_CheckMark: + { + if ( isPixmap( CheckMark ) ) + { + if ( flags & Style_Enabled || flags & Style_On ) + bitBlt( p->device(), x + ( w - uncached( CheckMark ) ->width() ) / 2, + y + ( h - uncached( CheckMark ) ->height() ) / 2, + uncached( CheckMark ) ); + handled = true; + } + else //Small hack to ensure the checkmark gets painter proper color.. + { + g.setColor( QColorGroup::Text, g.buttonText() ); + } + break; + } + case PE_ExclusiveIndicator: + { + if ( isPixmap( ( flags & Style_On || flags & Style_Down ) ? ExIndicatorOn : ExIndicatorOff ) ) + { + p->drawPixmap( x, y, *uncached( ( flags & Style_On || flags & Style_Down ) ? ExIndicatorOn : + ExIndicatorOff ) ); + handled = true; + } + + break; + } + case PE_ExclusiveIndicatorMask: + { + if ( isPixmap( ( flags & Style_On || flags & Style_Down ) ? ExIndicatorOn : ExIndicatorOff ) ) + { + const QBitmap * mask = uncached( ( flags & Style_On || flags & Style_Down ) ? ExIndicatorOn : ExIndicatorOff ) ->mask(); + if ( mask ) + { + p->setPen( Qt::color1 ); + p->drawPixmap( x, y, *mask ); + } + else + p->fillRect( x, y, w, h, QBrush( color1, SolidPattern ) ); + handled = true; + } + break; + } + + case PE_IndicatorMask: + { + if ( isPixmap( ( flags & Style_On ) ? IndicatorOn : IndicatorOff ) ) + { + const QBitmap * mask = uncached( ( flags & Style_On ) ? IndicatorOn : + IndicatorOff ) ->mask(); + if ( mask ) + { + p->setPen( Qt::color1 ); + p->drawPixmap( x, y, *mask ); + } + else + p->fillRect( x, y, w, h, QBrush( color1, SolidPattern ) ); + handled = true; + } + break; + } + case PE_Indicator: + { + if ( isPixmap( ( flags & Style_On || flags & Style_Down ) ? + IndicatorOn : IndicatorOff ) ) + { + p->drawPixmap( x, y, *uncached( ( flags & Style_On || flags & Style_Down ) ? + IndicatorOn : IndicatorOff ) ); + handled = true; + } + break; + } + case PE_Splitter: + { + drawBaseButton( p, x, y, w, h, *colorGroup( g, Splitter ), false, false, + Splitter ); + handled = true; + break; + } + case PE_FocusRect: + { + if ( is3DFocus() ) + { + p->setPen( g.dark() ); + int i = focusOffset(); + p->drawLine( r.x() + i, r.y() + 1 + i, r.x() + i, r.bottom() - 1 - i ); + p->drawLine( r.x() + 1 + i, r.y() + i, r.right() - 1 - i, r.y() + i ); + p->setPen( g.light() ); + p->drawLine( r.right() - i, r.y() + 1 + i, r.right() - i, r.bottom() - 1 - i ); + p->drawLine( r.x() + 1 + i, r.bottom() - i, r.right() - 1 - i, r.bottom() - i ); + handled = true; + } + else + { + handled = true; + p->drawWinFocusRect(r); + } + break; + } + case PE_PanelMenuBar: + { + QPixmap* cache = makeMenuBarCache(w, h); + p->drawPixmap( x, y, *cache); + handled = true; + break; + } + case PE_ScrollBarAddPage: + case PE_ScrollBarSubPage: + { + WidgetType widget = ( flags & Style_Horizontal ) ? HScrollGroove : VScrollGroove; + + if ( !isPixmap( widget ) ) + { + p->fillRect( r, colorGroup( g, widget ) ->brush( QColorGroup::Background ) ); + // Do the borders and frame + drawShade( p, r.x(), r.y(), r.width(), + r.height(), *colorGroup( g, widget ), true, false, + highlightWidth( widget ), borderWidth( widget ), shade() ); + } + else + { + // If the groove is pixmapped we make a full-sized image (it gets + // cached) then bitBlt it to the appropriate rect. + p->drawTiledPixmap( r.x(), r.y(), r.width(), r.height(), + *scalePixmap( r.width(), r.height(), + widget ) ); + drawShade( p, r.x(), r.y(), r.width(), + r.height(), *colorGroup( g, widget ), true, false, + highlightWidth( widget ), borderWidth( widget ), shade() ); + } + + handled = true; + break; + } + case PE_ScrollBarAddLine: + { + bool horizontal = ( flags & Style_Horizontal ); + drawBaseButton( p, r.x(), r.y(), r.width(), r.height(), + *colorGroup( g, down ? ScrollButtonDown : ScrollButton ), + down, false, down ? ScrollButtonDown : ScrollButton ); + + drawPrimitive( ( horizontal ) ? PE_ArrowRight : PE_ArrowDown, p , + QRect( r.x() + 3, r.y() + 3, r.width() - 6, r.height() - 6 ), + *colorGroup( g, down ? ScrollButtonDown : ScrollButton ), + flags ); + + handled = true; + break; + } + case PE_ScrollBarSubLine: + { + bool horizontal = ( flags & Style_Horizontal ); + drawBaseButton( p, r.x(), r.y(), r.width(), r.height(), + *colorGroup( g, down ? ScrollButtonDown : ScrollButton ), + down, false, down ? ScrollButtonDown : ScrollButton ); + + drawPrimitive( ( horizontal ) ? PE_ArrowLeft : PE_ArrowUp, p , + QRect( r.x() + 3, r.y() + 3, r.width() - 6, r.height() - 6 ), + *colorGroup( g, down ? ScrollButtonDown : ScrollButton ), + flags ); + handled = true; + break; + } + case PE_ScrollBarSlider: + { + bool active = ( flags & Style_Active ) || ( flags & Style_Down ); //activeControl == QStyle::AddLine; + bool horizontal = ( flags & Style_Horizontal ); + int offsetH = horizontal ? 0: decoWidth(VScrollGroove) ; + int offsetV = horizontal ? decoWidth(HScrollGroove):0; + + WidgetType widget = horizontal ? + active ? HScrollBarSliderDown : HScrollBarSlider : + active ? VScrollBarSliderDown : VScrollBarSlider; + drawBaseButton( p, r.x()+offsetH, r.y()+offsetV, r.width()-2*offsetH, + r.height()-2*offsetV, *colorGroup( g, widget ), active, false, + widget ); + + int spaceW = horizontal ? r.width() - decoWidth( widget ) - 4 : + r.width(); + int spaceH = horizontal ? r.height() : + r.height() - decoWidth( widget ) - 4; + + widget = active ? horizontal ? HScrollDecoDown : VScrollDecoDown : + horizontal ? HScrollDeco : VScrollDeco; + if ( isPixmap( widget ) ) + { + if ( spaceW >= uncached( widget ) ->width() && + spaceH >= uncached( widget ) ->height() ) + { + bitBlt( p->device(), + r.x() + ( r.width() - uncached( widget ) ->width() ) / 2, + r.y() + ( r.height() - uncached( widget ) ->height() ) / 2, + uncached( widget ) ); + } + } + handled = true; + break; + + } + default: + handled = false; + } + + if ( !handled ) + KThemeBase::drawPrimitive ( pe, p, r, g, + flags, opt ); +} + + + +QPixmap* KThemeStyle::makeMenuBarCache(int w, int h) const +{ + if (menuCache) + { + if (menuCache->width() != w || menuCache->height() != h ) + { + delete menuCache; + } + else + return menuCache; + } + + const QColorGroup *g = colorGroup( QApplication::palette().active(), MenuBar); + + menuCache = new QPixmap ( w, h ); + QPainter p(menuCache); + drawBaseButton( &p, 0, 0, w, h, *g, false, false, MenuBar ); + p.end(); + return menuCache; +} + + +void KThemeStyle::drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how , + const QStyleOption& opt ) const +{ + bool handled = false; + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + + switch ( element ) + { + case CE_PushButton: + { + const QPushButton * btn = ( const QPushButton* ) widget; + bool sunken = btn->isOn() || btn->isDown(); + int diw = pixelMetric( PM_ButtonDefaultIndicator, btn ); + drawBaseButton( p, diw, diw, w - 2 * diw, h - 2 * diw, + *colorGroup( btn->colorGroup(), sunken ? PushButtonDown : + PushButton ), sunken, roundButton(), + sunken ? PushButtonDown : PushButton ); + // TODO if diw, draw fancy default button indicator + handled = true; + break; + } + case CE_PushButtonLabel: + { + const QPushButton* button = ( const QPushButton* ) widget; + bool active = button->isOn() || button->isDown(); + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + // Shift button contents if pushed. + if ( active ) + { + x += pixelMetric( PM_ButtonShiftHorizontal, widget ); + y += pixelMetric( PM_ButtonShiftVertical, widget ); + how |= Style_Sunken; + } + + // Does the button have a popup menu? + if ( button->isMenuButton() ) + { + int dx = pixelMetric( PM_MenuButtonIndicator, widget ); + drawPrimitive( PE_ArrowDown, p, QRect( x + w - dx - 2, y + 2, dx, h - 4 ), + cg, how, opt ); + w -= dx; + } + + // Draw the icon if there is one + if ( button->iconSet() && !button->iconSet() ->isNull() ) + { + QIconSet::Mode mode = QIconSet::Disabled; + QIconSet::State state = QIconSet::Off; + + if ( button->isEnabled() ) + mode = button->hasFocus() ? QIconSet::Active : QIconSet::Normal; + if ( button->isToggleButton() && button->isOn() ) + state = QIconSet::On; + + QPixmap pixmap = button->iconSet() ->pixmap( QIconSet::Small, mode, state ); + + // Center the iconset if there's no text or pixmap + if (button->text().isEmpty() && !button->pixmap()) + p->drawPixmap( x + (w - pixmap.width()) / 2, + y + (h - pixmap.height()) / 2, pixmap ); + else + p->drawPixmap( x + 4, y + (h - pixmap.height()) / 2, pixmap ); + + int pw = pixmap.width(); + x += pw + 4; + w -= pw + 4; + } + + // Make the label indicate if the button is a default button or not + if ( active || button->isDefault() && button->isEnabled() ) + { + // Draw "fake" bold text - this enables the font metrics to remain + // the same as computed in QPushButton::sizeHint(), but gives + // a reasonable bold effect. + int i; + + // Text shadow + for ( i = 0; i < 2; i++ ) + drawItem( p, QRect( x + i + 1, y + 1, w, h ), AlignCenter | ShowPrefix, + button->colorGroup(), button->isEnabled(), NULL, + button->text(), -1, + active ? &button->colorGroup().dark() : &button->colorGroup().mid() ); + + // Normal Text + for ( i = 0; i < 2; i++ ) + drawItem( p, QRect( x + i, y, w, h ), AlignCenter | ShowPrefix, + button->colorGroup(), true, i == 0 ? button->pixmap() : NULL, + button->text(), -1, + active ? &button->colorGroup().light() : &button->colorGroup().buttonText() ); + } + else + { + if ( button->isEnabled() ) + { + drawItem( p, QRect( x, y, w, h ), AlignCenter | ShowPrefix, button->colorGroup(), + true, button->pixmap(), button->text(), -1, + active ? &button->colorGroup().light() : &button->colorGroup().buttonText() ); + } + else + { + //TODO: Handle reversed + drawItem( p, QRect( x + 1, y + 1, w, h ), AlignCenter | ShowPrefix, button->colorGroup(), + true, button->pixmap(), button->text(), -1, + &button->colorGroup().light() ); + + drawItem( p, QRect( x, y, w, h ), AlignCenter | ShowPrefix, button->colorGroup(), + true, button->pixmap(), button->text(), -1, + &button->colorGroup().buttonText() ); + } + } + + // Draw a focus rect if the button has focus + if ( how & Style_HasFocus ) + drawPrimitive( PE_FocusRect, p, + QStyle::visualRect( subRect( SR_PushButtonFocusRect, widget ), widget ), + cg, how ); + handled = true; + break; + } + + case CE_MenuBarEmptyArea: + { + //Expand to cover entire region + drawPrimitive(PE_PanelMenuBar, p, + QRect(0,0,r.width()+r.x()*2, r.height()+r.y()*2), + cg, Style_Default); + handled = true; + break; + } + + case CE_TabBarTab: + { + const QTabBar* tb = ( const QTabBar* ) widget; + QTabBar::Shape tbs = tb->shape(); + bool selected = how & Style_Selected; + WidgetType widget = selected ? ActiveTab : InactiveTab; + const QColorGroup *cg = colorGroup( tb->colorGroup(), widget ); + int i; + int x2 = x + w - 1, y2 = y + h - 1; + int bWidth = borderWidth( widget ); + int hWidth = highlightWidth( widget ); + handled = true; + if ( tbs == QTabBar::RoundedAbove || tbs == QTabBar::TriangularAbove ) + { + if ( !selected ) + { + p->fillRect( x, y, x2 - x + 1, 2, + tb->palette().active().brush( QColorGroup::Background ) ); + y += 2; + } + p->setPen( cg->text() ); + i = 0; + if ( i < bWidth ) + { + p->drawLine( x, y + 1, x, y2 ); + p->drawLine( x2, y + 1, x2, y2 ); + p->drawLine( x + 1, y, x2 - 1, y ); + if ( selected ? activeTabLine() : inactiveTabLine() ) + { + p->drawLine( x, y2, x2, y2 ); + --y2; + } + ++i, ++x, ++y, --x2; + } + for ( ; i < bWidth; ++i, ++x, ++y, --x2 ) + { + p->drawLine( x, y, x, y2 ); + p->drawLine( x2, y, x2, y2 ); + p->drawLine( x, y, x2, y ); + if ( selected ? activeTabLine() : inactiveTabLine() ) + { + p->drawLine( x, y2, x2, y2 ); + --y2; + } + } + i = 0; + if ( i < hWidth && bWidth == 0 ) + { + p->setPen( cg->light() ); + p->drawLine( x, y + 1, x, y2 ); + p->drawLine( x + 1, y, x2 - 1, y ); + p->setPen( cg->dark() ); + p->drawLine( x2, y + 1, x2, y2 ); + if ( selected ? activeTabLine() : inactiveTabLine() ) + { + p->drawLine( x, y2, x2, y2 ); + --y2; + } + ++i, ++x, ++y, --x2; + } + for ( ; i < hWidth; ++i, ++x, ++y, --x2 ) + { + p->setPen( cg->light() ); + p->drawLine( x, y, x, y2 ); + p->drawLine( x, y, x2, y ); + p->setPen( cg->dark() ); + p->drawLine( x2, y + 1, x2, y2 ); + if ( selected ? activeTabLine() : inactiveTabLine() ) + { + p->drawLine( x, y2, x2, y2 ); + --y2; + } + } + if ( isPixmap( widget ) ) + p->drawTiledPixmap( x, y, x2 - x + 1, y2 - y + 1, + *scalePixmap( x2 - x + 1, y2 - y + 1, widget ) ); + else + p->fillRect( x, y, x2 - x + 1, y2 - y + 1, cg->background() ); + } + else if ( tb->shape() == QTabBar::RoundedBelow || + tb->shape() == QTabBar::TriangularBelow ) + { + if ( widget == ActiveTab ) + widget = RotActiveTab; + else + widget = RotInactiveTab; + + if ( !selected ) + { + p->fillRect( x, y2 - 2, x2 - x + 1, 2, + tb->palette().active().brush( QColorGroup::Background ) ); + y2 -= 2; + } + p->setPen( cg->text() ); + i = 0; + if ( i < bWidth ) + { + p->drawLine( x, y, x, y2 - 1 ); + p->drawLine( x2, y, x2, y2 - 1 ); + p->drawLine( x + 1, y2, x2 - 1, y2 ); + if ( selected ? activeTabLine() : inactiveTabLine() ) + { + p->drawLine( x, y, x2, y ); + ++y; + } + } + for ( ; i < bWidth; ++i, ++x, --x2, --y2 ) + { + p->drawLine( x, y, x, y2 ); + p->drawLine( x2, y, x2, y2 ); + p->drawLine( x, y2, x2, y2 ); + if ( selected ? activeTabLine() : inactiveTabLine() ) + { + p->drawLine( x, y, x2, y ); + ++y; + } + } + i = 0; + if ( i < hWidth && bWidth == 0 ) + { + p->setPen( cg->dark() ); + p->drawLine( x + 1, y2, x2 - 1, y2 ); + p->drawLine( x2, y, x2, y2 - 1 ); + p->setPen( cg->light() ); + p->drawLine( x, y, x, y2 - 1 ); + if ( selected ? activeTabLine() : inactiveTabLine() ) + { + p->drawLine( x, y, x2, y ); + ++y; + } + ++i, ++x, --x2, --y2; + } + for ( ; i < hWidth; ++i, ++x, --x2, --y2 ) + { + p->setPen( cg->dark() ); + p->drawLine( x, y2, x2, y2 ); + p->drawLine( x2, y, x2, y2 ); + p->setPen( cg->light() ); + p->drawLine( x, y, x, y2 ); + if ( selected ? activeTabLine() : inactiveTabLine() ) + { + p->drawLine( x, y, x2, y ); + ++y; + } + } + if ( isPixmap( widget ) ) + p->drawTiledPixmap( x, y, x2 - x + 1, y2 - y + 1, + *scalePixmap( x2 - x + 1, y2 - y + 1, widget ) ); + else + p->fillRect( x, y, x2 - x + 1, y2 - y + 1, cg->background() ); + } + break; + } + case CE_MenuBarItem: + { + + r.rect( &x, &y, &w, &h ); + QMenuItem *mi = opt.menuItem(); + QMenuBar *mb = ( QMenuBar* ) widget; + QRect pr = mb->rect(); + bool active = how & Style_Active; + //bool focused = how & Style_HasFocus; + const QColorGroup *g = colorGroup( cg, active ? MenuBarItem : MenuBar ); + QColor btext = g->buttonText(); + + QPixmap* cache = makeMenuBarCache(pr.width(), pr.height()); + + QPixmap buf( w, pr.height() ); + + bitBlt(&buf, 0, 0, cache, x, y, w, pr.height()); + QPainter p2( &buf ); + + if ( active ) + { + drawBaseButton( &p2, 0, 0, w, h, *g, false, false, MenuBarItem ); + } + + p2.end(); + p->drawPixmap( x, y, buf, 0, 0, w, h ); + + drawItem( p, QRect(x,y,w,h), AlignCenter | AlignVCenter | ShowPrefix | DontClip | SingleLine, + *g, mi->isEnabled(), mi->pixmap(), mi->text(), + -1, &btext ); + handled = true; + break; + } + case CE_PopupMenuItem: + { + bool separator = false; + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + const QPopupMenu *popupmenu = ( const QPopupMenu * ) widget; + QMenuItem *mi = opt.menuItem(); + if ( mi ) + { + separator = mi->isSeparator(); + } + + int tab = opt.tabWidth(); + int checkcol = opt.maxIconWidth(); + bool enabled = (mi? mi->isEnabled():true); + bool checkable = popupmenu->isCheckable(); + bool active = how & Style_Active; + bool etchtext = styleHint( SH_EtchDisabledText, 0 ); + bool reverse = QApplication::reverseLayout(); + + const QColorGroup& cg_ours = *colorGroup( cg, active ? MenuItemDown : MenuItem ); + //QColor btext = cg_ours.buttonText(); + + + if ( checkable ) + checkcol = QMAX( checkcol, 20 ); + + // Are we a menu item separator? + if ( separator ) + { + p->setPen( cg_ours.dark() ); + p->drawLine( x, y, x + w, y ); + p->setPen( cg_ours.light() ); + p->drawLine( x, y + 1, x + w, y + 1 ); + break; + } + + // Draw the menu item background + if ( active ) + drawBaseButton( p, x, y, w, h, cg_ours, true, false, MenuItemDown ); + else + { + drawShade( p, x, y, w, h, *colorGroup( cg_ours, MenuItem ), false, false, + highlightWidth( MenuItem ), borderWidth( MenuItem ), + shade() ); + int dw = decoWidth( MenuItem ); + if ( !isPixmap( MenuItem ) ) + { + p->fillRect( + x + dw, y + dw, w - dw * 2, h - dw * 2, + cg_ours.brush( QColorGroup::Background ) ); + //cg.brush( QColorGroup::Background )); + //colorGroup( cg_ours, MenuItem ) ->brush( QColorGroup::Background ) ); + } + else + { + // process inactive item pixmaps as one large item + p->drawTiledPixmap( x + dw, y + dw, w - dw * 2, h - dw * 2, *scalePixmap + ( w, p->window().height(), MenuItem ), + x, y ); + } + } + + if (!mi) + break; + + // Do we have an icon? + if ( mi->iconSet() ) + { + QIconSet::Mode mode; + QRect cr = visualRect( QRect( x, y, checkcol, h ), r ); + + // Select the correct icon from the iconset + if ( active ) + mode = enabled ? QIconSet::Active : QIconSet::Disabled; + else + mode = enabled ? QIconSet::Normal : QIconSet::Disabled; + + // Do we have an icon and are checked at the same time? + // Then draw a "pressed" background behind the icon + if ( checkable && mi->isChecked() ) //!active && -- ?? + drawBaseButton( p, cr.x(), cr.y(), cr.width(), cr.height(), *colorGroup( cg_ours, BevelDown ), true, false, BevelDown ); + + // Draw the icon + QPixmap pixmap = mi->iconSet() ->pixmap( QIconSet::Small, mode ); + int pixw = pixmap.width(); + int pixh = pixmap.height(); + QRect pmr( 0, 0, pixw, pixh ); + pmr.moveCenter( cr.center() ); + p->setPen( cg_ours.highlightedText() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + } + + // Are we checked? (This time without an icon) + else if ( checkable && mi->isChecked() ) + { + int cx = reverse ? x + w - checkcol : x; + + // We only have to draw the background if the menu item is inactive - + // if it's active the "pressed" background is already drawn + //if ( ! active ) + // qDrawShadePanel( p, cx, y, checkcol, h, cg_ours, true, 1, + // &cg_ours.brush(QColorGroup::Midlight) ); + + // Draw the checkmark + SFlags cflags = Style_Default; + cflags |= active ? Style_Enabled : Style_On; + + drawPrimitive( PE_CheckMark, p, QRect( cx + itemFrame, y + itemFrame, + checkcol - itemFrame * 2, h - itemFrame * 2 ), cg_ours, cflags ); + } + + // Time to draw the menu item label... + int xm = itemFrame + checkcol + itemHMargin; // X position margin + + int xp = reverse ? // X position + x + tab + rightBorder + itemHMargin + itemFrame - 1 : + x + xm; + + int offset = reverse ? -1 : 1; // Shadow offset for etched text + + // Label width (minus the width of the accelerator portion) + int tw = w - xm - tab - arrowHMargin - itemHMargin * 3 - itemFrame + 1; + + // Set the color for enabled and disabled text + // (used for both active and inactive menu items) + p->setPen( enabled ? cg_ours.buttonText() : cg_ours.mid() ); + + // This color will be used instead of the above if the menu item + // is active and disabled at the same time. (etched text) + QColor discol = cg_ours.mid(); + + // Does the menu item draw it's own label? + if ( mi->custom() ) + { + int m = itemVMargin; + // Save the painter state in case the custom + // paint method changes it in some way + p->save(); + + // Draw etched text if we're inactive and the menu item is disabled + if ( etchtext && !enabled && !active ) + { + p->setPen( cg_ours.light() ); + mi->custom() ->paint( p, cg_ours, active, enabled, xp + offset, y + m + 1, tw, h - 2 * m ); + p->setPen( discol ); + } + mi->custom() ->paint( p, cg_ours, active, enabled, xp, y + m, tw, h - 2 * m ); + p->restore(); + } + else + { + // The menu item doesn't draw it's own label + QString s = mi->text(); + + // Does the menu item have a text label? + if ( !s.isNull() ) + { + int t = s.find( '\t' ); + int m = itemVMargin; + int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine; + text_flags |= reverse ? AlignRight : AlignLeft; + + // Does the menu item have a tabstop? (for the accelerator text) + if ( t >= 0 ) + { + int tabx = reverse ? x + rightBorder + itemHMargin + itemFrame : + x + w - tab - rightBorder - itemHMargin - itemFrame; + + + // Draw the right part of the label (accelerator text) + if ( etchtext && !enabled && !active ) + { + // Draw etched text if we're inactive and the menu item is disabled + p->setPen( cg_ours.light() ); + p->drawText( tabx + offset, y + m + 1, tab, h - 2 * m, text_flags, s.mid( t + 1 ) ); + p->setPen( discol ); + } + p->drawText( tabx, y + m, tab, h - 2 * m, text_flags, s.mid( t + 1 ) ); + s = s.left( t ); + } + + + // Draw the left part of the label (or the whole label + // if there's no accelerator) + if ( etchtext && !enabled && !active ) + { + // Etched text again for inactive disabled menu items... + p->setPen( cg_ours.light() ); + p->drawText( xp + offset, y + m + 1, tw, h - 2 * m, text_flags, s, t ); + p->setPen( discol ); + } + + p->drawText( xp, y + m, tw, h - 2 * m, text_flags, s, t ); + + } + + // The menu item doesn't have a text label + // Check if it has a pixmap instead + else if ( mi->pixmap() ) + { + QPixmap * pixmap = mi->pixmap(); + + // Draw the pixmap + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( OpaqueMode ); + + int diffw = ( ( w - pixmap->width() ) / 2 ) + + ( ( w - pixmap->width() ) % 2 ); + p->drawPixmap( x + diffw, y + itemFrame, *pixmap ); + + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( TransparentMode ); + } + } + + // Does the menu item have a submenu? + if ( mi->popup() ) + { + PrimitiveElement arrow = reverse ? PE_ArrowLeft : PE_ArrowRight; + int dim = 10 - itemFrame; //We're not very useful to inherit off, so just hardcode.. + QRect vr = visualRect( QRect( x + w - arrowHMargin - itemFrame - dim, + y + h / 2 - dim / 2, dim, dim ), r ); + + // Draw an arrow at the far end of the menu item + if ( active ) + { + if ( enabled ) + discol = cg_ours.buttonText(); + + QColorGroup g2( discol, cg_ours.highlight(), white, white, + enabled ? white : discol, discol, white ); + + drawPrimitive( arrow, p, vr, g2, Style_Enabled | Style_Down ); + } + else + drawPrimitive( arrow, p, vr, cg_ours, + enabled ? Style_Enabled : Style_Default ); + } + handled = true; + break; + } + case CE_ProgressBarGroove: + { + QBrush bg; + const QColorGroup * cg2 = colorGroup( cg, ProgressBg ); + qDrawWinPanel( p, r, *cg2, true ); + bg.setColor( cg2->color( QColorGroup::Background ) ); + if ( isPixmap( ProgressBg ) ) + bg.setPixmap( *uncached( ProgressBg ) ); + p->fillRect( x + 2, y + 2, w - 4, h - 4, bg ); + + handled = true; + break; + } + case CE_ProgressBarContents: + { + const QProgressBar* pb = (const QProgressBar*)widget; + QRect cr = subRect(SR_ProgressBarContents, widget); + double progress = pb->progress(); + bool reverse = QApplication::reverseLayout(); + int steps = pb->totalSteps(); + + int pstep = 0; + + if (!cr.isValid()) + return; + + // Draw progress bar + if (progress > 0 || steps == 0) + { + double pg = (steps == 0) ? 0.1 : progress / steps; + int width = QMIN(cr.width(), (int)(pg * cr.width())); + if (steps == 0) + { //Busy indicator + + if (width < 1) width = 1; //A busy indicator with width 0 is kind of useless + + int remWidth = cr.width() - width; //Never disappear completely + if (remWidth <= 0) remWidth = 1; //Do something non-crashy when too small... + + pstep = int(progress) % ( 2 * remWidth ); + + if ( pstep > remWidth ) + { + //Bounce about.. We're remWidth + some delta, we want to be remWidth - delta... + // - ( (remWidth + some delta) - 2* remWidth ) = - (some deleta - remWidth) = remWidth - some delta.. + pstep = - (pstep - 2 * remWidth ); + } + } + + if ( !reverse ) + drawBaseButton( p, x + pstep, y, width, h, *colorGroup( cg, ProgressBar ), false, false, ProgressBar ); + else + { + //TODO:Optimize + QPixmap buf( width, h ); + QPainter p2( &buf ); + drawBaseButton( &p2, 0, 0, width, h, *colorGroup( cg, ProgressBar ), false, false, ProgressBar ); + p2.end(); + QPixmap mirroredPix = QPixmap( buf.convertToImage().mirror( true, false ) ); + bitBlt( p->device(), x + w - width - pstep, y, &mirroredPix ); + } + } + + handled = true; + break; + } + default: + handled = false; + }; + + if ( !handled ) + KThemeBase::drawControl( element, + p, widget, r, cg, how, opt ); +} + + +void KThemeStyle::drawControlMask( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& opt ) const +{ + bool handled = false; + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + switch ( element ) + { + case CE_PushButton: + { + //Is this correct? + drawBaseMask( p, x, y, w, h, roundButton() ); + handled = true; + break; + } + default: + handled = false; + }; + + if ( !handled ) + KThemeBase::drawControlMask( element, + p, widget, r, opt ); + +} + + +void KThemeStyle::drawKStylePrimitive( KStylePrimitive kpe, + QPainter* p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + bool handled = false; + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + switch ( kpe ) + { + case KPE_SliderGroove: + { + if ( !roundSlider() ) + { + const QSlider * slider = ( const QSlider* ) widget; + bool horizontal = slider->orientation() == Horizontal; + if ( horizontal ) + { + drawBaseButton( p, x, y, w, h, *colorGroup( cg, SliderGroove ), true, + false, SliderGroove ); + } + else + { + drawBaseButton( p, x, y, w, h, *colorGroup( cg, RotSliderGroove ), true, + false, RotSliderGroove ); + } + } + else + { + //This code is from HighColorDefault.. + const QSlider* slider = ( const QSlider* ) widget; + bool horizontal = slider->orientation() == Horizontal; + int gcenter = ( horizontal ? r.height() : r.width() ) / 2; + + QRect gr; + if ( horizontal ) + gr = QRect( r.x(), r.y() + gcenter - 3, r.width(), 7 ); + else + gr = QRect( r.x() + gcenter - 3, r.y(), 7, r.height() ); + + int x, y, w, h; + gr.rect( &x, &y, &w, &h ); + int x2 = x + w - 1; + int y2 = y + h - 1; + + // Draw the slider groove. + p->setPen( cg.dark() ); + p->drawLine( x + 2, y, x2 - 2, y ); + p->drawLine( x, y + 2, x, y2 - 2 ); + p->fillRect( x + 2, y + 2, w - 4, h - 4, + slider->isEnabled() ? cg.dark() : cg.mid() ); + p->setPen( cg.shadow() ); + p->drawRect( x + 1, y + 1, w - 2, h - 2 ); + p->setPen( cg.light() ); + p->drawPoint( x + 1, y2 - 1 ); + p->drawPoint( x2 - 1, y2 - 1 ); + p->drawLine( x2, y + 2, x2, y2 - 2 ); + p->drawLine( x + 2, y2, x2 - 2, y2 ); + } + handled = true; + break; + } + case KPE_SliderHandle: + { + if ( isPixmap( Slider ) ) + { + const QSlider * slider = ( const QSlider* ) widget; + bool horizontal = slider->orientation() == Horizontal; + if ( horizontal ) + { + bitBlt( p->device(), x, y + ( h - uncached( Slider ) ->height() ) / 2, + uncached( Slider ) ); + } + else + { + if ( !vsliderCache ) + { + QWMatrix r270; + r270.rotate( 270 ); + vsliderCache = new QPixmap( uncached( Slider ) ->xForm( r270 ) ); + if ( uncached( Slider ) ->mask() ) + vsliderCache->setMask( uncached( Slider ) ->mask() ->xForm( r270 ) ); + } + bitBlt( p->device(), x + ( w - vsliderCache->width() ) / 2, y, + vsliderCache ); + } + } + else + { + //This code again from HighColor.. + //...except sans the gradient.. + const QSlider* slider = ( const QSlider* ) widget; + bool horizontal = slider->orientation() == Horizontal; + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + int x2 = x + w - 1; + int y2 = y + h - 1; + + p->setPen( cg.mid() ); + p->drawLine( x + 1, y, x2 - 1, y ); + p->drawLine( x, y + 1, x, y2 - 1 ); + p->setPen( cg.shadow() ); + p->drawLine( x + 1, y2, x2 - 1, y2 ); + p->drawLine( x2, y + 1, x2, y2 - 1 ); + + p->setPen( cg.light() ); + p->drawLine( x + 1, y + 1, x2 - 1, y + 1 ); + p->drawLine( x + 1, y + 1, x + 1, y2 - 1 ); + p->setPen( cg.dark() ); + p->drawLine( x + 2, y2 - 1, x2 - 1, y2 - 1 ); + p->drawLine( x2 - 1, y + 2, x2 - 1, y2 - 1 ); + p->setPen( cg.midlight() ); + p->drawLine( x + 2, y + 2, x2 - 2, y + 2 ); + p->drawLine( x + 2, y + 2, x + 2, y2 - 2 ); + p->setPen( cg.mid() ); + p->drawLine( x + 3, y2 - 2, x2 - 2, y2 - 2 ); + p->drawLine( x2 - 2, y + 3, x2 - 2, y2 - 2 ); + p->fillRect( QRect( x + 3, y + 3, w - 6, h - 6 ), + cg.button() ); + + // Paint riffles + if ( horizontal ) + { + p->setPen( cg.light() ); + p->drawLine( x + 5, y + 4, x + 5, y2 - 4 ); + p->drawLine( x + 8, y + 4, x + 8, y2 - 4 ); + p->drawLine( x + 11, y + 4, x + 11, y2 - 4 ); + p->setPen( slider->isEnabled() ? cg.shadow() : cg.mid() ); + p->drawLine( x + 6, y + 4, x + 6, y2 - 4 ); + p->drawLine( x + 9, y + 4, x + 9, y2 - 4 ); + p->drawLine( x + 12, y + 4, x + 12, y2 - 4 ); + } + else + { + p->setPen( cg.light() ); + p->drawLine( x + 4, y + 5, x2 - 4, y + 5 ); + p->drawLine( x + 4, y + 8, x2 - 4, y + 8 ); + p->drawLine( x + 4, y + 11, x2 - 4, y + 11 ); + p->setPen( slider->isEnabled() ? cg.shadow() : cg.mid() ); + p->drawLine( x + 4, y + 6, x2 - 4, y + 6 ); + p->drawLine( x + 4, y + 9, x2 - 4, y + 9 ); + p->drawLine( x + 4, y + 12, x2 - 4, y + 12 ); + } + } + handled = true; + break; + } + //case KPE_DockWindowHandle: + case KPE_ToolBarHandle: + case KPE_GeneralHandle: + { + if ( w > h ) + drawBaseButton( p, x, y, w, h, *colorGroup( cg, HBarHandle ), false, false, + HBarHandle ); + else + drawBaseButton( p, x, y, w, h, *colorGroup( cg, VBarHandle ), false, false, + VBarHandle ); + + handled = true; + break; + } + default: + handled = false; + + } + + if ( !handled ) + { + KThemeBase::drawKStylePrimitive( kpe, p, widget, + r, cg, flags, opt ); + } + +} + + + + +void KThemeStyle::drawComplexControl ( ComplexControl control, QPainter * p, const QWidget * widget, + const QRect & r, const QColorGroup & g, SFlags how , + SCFlags controls, SCFlags active, + const QStyleOption & opt ) const +{ + bool handled = false; + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + bool down = how & Style_Down; + bool on = how & Style_On; + + // bool enabled = ( how & Style_Enabled ); + + switch ( control ) + { + case CC_ToolButton: + { + const QToolButton * toolbutton = ( const QToolButton * ) widget; + QRect button, menu; + button = querySubControlMetrics( control, widget, SC_ToolButton, opt ); + menu = querySubControlMetrics( control, widget, SC_ToolButtonMenu, opt ); + + + if ( controls & SC_ToolButton ) + { + WidgetType widget = ( down || on ) ? ToolButtonDown : ToolButton; + + drawBaseButton( p, button.x(), button.y(), button.width(), button.height(), *colorGroup( g, widget ), down || on, false, + widget ); + + // int m = decoWidth( widget ); + } + + if ( controls & SC_ToolButtonMenu ) + { + drawPrimitive( PE_ArrowDown, p, menu, g, how ); + /* if ( enabled ) + kDrawWindowsArrow(p, this, PE_ArrowDown, false, menu.x(), menu.y(), menu.width(), menu.height(), + g, true ); + else + kDrawWindowsArrow(p, this, PE_ArrowDown, false, menu.x(), menu.y(), menu.width(), menu.height(), + g, false );*/ + } + + if ( toolbutton->hasFocus() && !toolbutton->focusProxy() ) + { + QRect fr = toolbutton->rect(); + fr.addCoords( 3, 3, -3, -3 ); + drawPrimitive( PE_FocusRect, p, fr, g ); + } + + handled = true; + break; + } + + case CC_ComboBox: + { + if ( controls & SC_ComboBoxFrame ) + { + //TODO: Anyway of detecting when the popup is there -- would look nicer if sunken then too.. + bool sunken = ( active == SC_ComboBoxArrow ); + //No frame, edit box and button for now? + WidgetType widget = sunken ? ComboBoxDown : ComboBox; + drawBaseButton( p, x, y, w, h, *colorGroup( g, widget ), sunken, + roundComboBox(), widget ); + + controls ^= SC_ComboBoxFrame; + } + + if ( controls & SC_ComboBoxArrow ) + { + bool sunken = ( active == SC_ComboBoxArrow ); + QRect ar = QStyle::visualRect( + querySubControlMetrics( CC_ComboBox, widget, SC_ComboBoxArrow ), + widget ); + ar.rect( &x, &y, &w, &h ); + WidgetType widget = sunken ? ComboBoxDown : ComboBox; + + if ( !sunken && isPixmap( ComboDeco ) ) + bitBlt( p->device(), + x + ( w - uncached( ComboDeco ) ->width() - decoWidth( ComboBox ) / 2 ), + y + ( h - uncached( ComboDeco ) ->height() ) / 2, + uncached( ComboDeco ) ); + else if ( sunken && isPixmap( ComboDecoDown ) ) + bitBlt( p->device(), + x + ( w - uncached( ComboDecoDown ) ->width() - decoWidth( ComboBoxDown ) ) / 2, + y + ( h - uncached( ComboDecoDown ) ->height() ) / 2, + uncached( ComboDecoDown ) ); + else + { + + mtfstyle->drawPrimitive( PE_ArrowDown, p, QRect( x, y, w, h ), *colorGroup( g, widget ), sunken ? ( how | Style_Sunken ) : how, opt ); + qDrawShadeRect( p, x, y, w, h, *colorGroup( g, widget ) ); //w-14, y+7+(h-15), 10, 3, + } + controls ^= SC_ComboBoxArrow; + } + break; + } + case CC_ScrollBar: + { + const QScrollBar *sb = ( const QScrollBar* ) widget; + bool maxedOut = ( sb->minValue() == sb->maxValue() ); + bool horizontal = ( sb->orientation() == Qt::Horizontal ); + SFlags sflags = ( ( horizontal ? Style_Horizontal : Style_Default ) | + ( maxedOut ? Style_Default : Style_Enabled ) ); + + //Here, we don't do add page, subpage, etc., + QRect addline, subline, subline2, groove, slider; + subline = querySubControlMetrics( control, widget, SC_ScrollBarSubLine, opt ); + addline = querySubControlMetrics( control, widget, SC_ScrollBarAddLine, opt ); + groove = querySubControlMetrics( control, widget, SC_ScrollBarGroove, opt ); + + slider = querySubControlMetrics( control, widget, SC_ScrollBarSlider, opt ); + subline2 = addline; + + QPixmap buf( sb->width(), sb->height() ); + QPainter p2( &buf ); + + if ( groove.isValid() ) + { + p2.fillRect( groove, QColor( 255, 0, 0 ) ); + drawPrimitive( PE_ScrollBarSubPage, &p2, groove, g, + sflags | ( ( active == SC_ScrollBarSubPage ) ? + Style_Down : Style_Default ) ); + } + + + // Draw the up/left button set + if ( subline.isValid() ) + { + drawPrimitive( PE_ScrollBarSubLine, &p2, subline, g, + sflags | ( active == SC_ScrollBarSubLine ? + Style_Down : Style_Default ) ); + } + + if ( addline.isValid() ) + drawPrimitive( PE_ScrollBarAddLine, &p2, addline, g, + sflags | ( ( active == SC_ScrollBarAddLine ) ? + Style_Down : Style_Default ) ); + + if ( slider.isValid() ) + { //(controls & SC_ScrollBarSlider) && + drawPrimitive( PE_ScrollBarSlider, &p2, slider, g, + sflags | ( ( active == SC_ScrollBarSlider ) ? + Style_Down : Style_Default ) ); + // Draw focus rect + if ( sb->hasFocus() ) + { + QRect fr( slider.x() + 2, slider.y() + 2, + slider.width() - 5, slider.height() - 5 ); + drawPrimitive( PE_FocusRect, &p2, fr, g, Style_Default ); + } + p2.end(); + bitBlt( p->device(), x, y, &buf ); + handled = true; + + } + break; + } + default: + handled = false; + } + + if ( !handled ) + { + KThemeBase::drawComplexControl ( control, p, widget, + r, g, how , + controls, active, + opt ); + } + +} + + +void KThemeStyle::drawBaseMask( QPainter *p, int x, int y, int w, int h, + bool round ) const +{ + // round edge fills + static const QCOORD btm_left_fill[] = + { + 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, + 1, 2, 2, 2, 3, 2, 4, 2, 2, 3, 3, 3, 4, 3, 3, 4, 4, 4 + }; + + static const QCOORD btm_right_fill[] = + { + 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 1, 1, 1, 2, 1, 3, 1, 4, + 1, 0, 2, 1, 2, 2, 2, 3, 2, 0, 3, 1, 3, 2, 3, 0, 4, 1, 4 + }; + + static const QCOORD top_left_fill[] = + { + 3, 0, 4, 0, 2, 1, 3, 1, 4, 1, 1, 2, 2, 2, 3, 2, 4, 2, 0, 3, + 1, 3, 2, 3, 3, 3, 4, 3, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4 + }; + + static const QCOORD top_right_fill[] = + { + 0, 0, 1, 0, 0, 1, 1, 1, 2, 1, 0, 2, 1, 2, 2, 2, 3, 2, 0, + 3, 1, 3, 2, 3, 3, 3, 4, 3, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4 + }; + + QBrush fillBrush( color1, SolidPattern ); + p->setPen( color1 ); + if ( round && w > 19 && h > 19 ) + { + int x2 = x + w - 1; + int y2 = y + h - 1; + QPointArray a( QCOORDARRLEN( top_left_fill ), top_left_fill ); + a.translate( 1, 1 ); + p->drawPoints( a ); + a.setPoints( QCOORDARRLEN( btm_left_fill ), btm_left_fill ); + a.translate( 1, h - 6 ); + p->drawPoints( a ); + a.setPoints( QCOORDARRLEN( top_right_fill ), top_right_fill ); + a.translate( w - 6, 1 ); + p->drawPoints( a ); + a.setPoints( QCOORDARRLEN( btm_right_fill ), btm_right_fill ); + a.translate( w - 6, h - 6 ); + p->drawPoints( a ); + + p->fillRect( x + 6, y, w - 12, h, fillBrush ); + p->fillRect( x, y + 6, x + 6, h - 12, fillBrush ); + p->fillRect( x2 - 6, y + 6, x2, h - 12, fillBrush ); + p->drawLine( x + 6, y, x2 - 6, y ); + p->drawLine( x + 6, y2, x2 - 6, y2 ); + p->drawLine( x, y + 6, x, y2 - 6 ); + p->drawLine( x2, y + 6, x2, y2 - 6 ); + + } + else + p->fillRect( x, y, w, h, fillBrush ); +} + +int KThemeStyle::styleHint( StyleHint sh, const QWidget *w, const QStyleOption &opt, QStyleHintReturn *shr ) const +{ + switch ( sh ) + { + case SH_EtchDisabledText: + case SH_Slider_SnapToValue: + case SH_PrintDialog_RightAlignButtons: + case SH_FontDialog_SelectAssociatedText: + case SH_PopupMenu_AllowActiveAndDisabled: + case SH_MenuBar_AltKeyNavigation: + case SH_MenuBar_MouseTracking: + case SH_PopupMenu_MouseTracking: + case SH_ComboBox_ListMouseTracking: + return 1; + + case SH_GUIStyle: + return WindowsStyle; + + case SH_ScrollBar_BackgroundMode: + return NoBackground; + + default: + return KThemeBase::styleHint( sh, w, opt, shr ); + }; +} + + + +/* This is where we draw the borders and highlights. The new round button + * code is a pain in the arse. We don't want to be calculating arcs so + * use a whole lotta QPointArray's ;-) The code is made a lot more complex + * because you can have variable width border and highlights... + * I may want to cache this if round buttons are used, but am concerned + * about excessive cache misses. This is a memory/speed tradeoff that I + * have to test. + */ +void KThemeStyle::drawShade( QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool sunken, bool rounded, + int hWidth, int bWidth, ShadeStyle style ) const +{ + int i, sc, bc, x2, y2; + QPen highPen, lowPen; + + if ( style == Motif ) + { + highPen.setColor( sunken ? g.dark() : g.light() ); + lowPen.setColor( sunken ? g.light() : g.dark() ); + } + else + { + highPen.setColor( sunken ? g.shadow() : g.light() ); + lowPen.setColor( sunken ? g.light() : g.shadow() ); + } + + // Advanced round buttons + if ( rounded && w > 19 && h > 19 ) + { + x2 = x + w - 1, y2 = y + h - 1; + QPointArray bPntArray, hPntArray, lPntArray; + QPointArray bLineArray, hLineArray, lLineArray; + // borders + for ( i = 0, bc = 0; i < bWidth; ++i ) + { + bPntArray.putPoints( bc, 24, x + 4, y + 1, x + 5, y + 1, x + 3, y + 2, x + 2, y + 3, + x + 1, y + 4, x + 1, y + 5, x + 1, y2 - 5, x + 1, y2 - 4, x + 2, y2 - 3, + x2 - 5, y + 1, x2 - 4, y + 1, x2 - 3, y + 2, x2 - 5, y2 - 1, + x2 - 4, y2 - 1, x2 - 3, y2 - 2, x2 - 2, y2 - 3, x2 - 1, y2 - 5, + x2 - 1, y2 - 4, x + 3, y2 - 2, x + 4, y2 - 1, x + 5, y2 - 1, + x2 - 2, y + 3, x2 - 1, y + 4, x2 - 1, y + 5 ); + bc += 24; + // ellispe edges don't match exactly, so fill in blanks + if ( i < bWidth - 1 || hWidth != 0 ) + { + bPntArray.putPoints( bc, 20, x + 6, y + 1, x + 4, y + 2, x + 3, y + 3, + x + 2, y + 4, x + 1, y + 6, x2 - 6, y + 1, x2 - 4, y + 2, + x2 - 3, y + 3, x + 2, y2 - 4, x + 1, y2 - 6, x2 - 6, y2 - 1, + x2 - 4, y2 - 2, x2 - 3, y2 - 3, x2 - 2, y2 - 4, x2 - 1, y2 - 6, + x + 6, y2 - 1, x + 4, y2 - 2, x + 3, y2 - 3, x2 - 1, y + 6, + x2 - 2, y + 4 ); + bc += 20; + } + bLineArray.putPoints( i * 8, 8, x + 6, y, x2 - 6, y, x, y + 6, x, y2 - 6, + x + 6, y2, x2 - 6, y2, x2, y + 6, x2, y2 - 6 ); + ++x, ++y; + --x2, --y2; + } + // highlights + for ( i = 0, sc = 0; i < hWidth; ++i ) + { + hPntArray.putPoints( sc, 12, x + 4, y + 1, x + 5, y + 1, // top left + x + 3, y + 2, x + 2, y + 3, x + 1, y + 4, x + 1, y + 5, + x + 1, y2 - 5, x + 1, y2 - 4, x + 2, y2 - 3, // half corners + x2 - 5, y + 1, x2 - 4, y + 1, x2 - 3, y + 2 ); + lPntArray.putPoints( sc, 12, x2 - 5, y2 - 1, x2 - 4, y2 - 1, // btm right + x2 - 3, y2 - 2, x2 - 2, y2 - 3, x2 - 1, y2 - 5, x2 - 1, y2 - 4, + x + 3, y2 - 2, x + 4, y2 - 1, x + 5, y2 - 1, //half corners + x2 - 2, y + 3, x2 - 1, y + 4, x2 - 1, y + 5 ); + sc += 12; + if ( i < hWidth - 1 ) + { + hPntArray.putPoints( sc, 10, x + 6, y + 1, x + 4, y + 2, // top left + x + 3, y + 3, x + 2, y + 4, x + 1, y + 6, + x2 - 6, y + 1, x2 - 4, y + 2, // half corners + x2 - 3, y + 3, x + 2, y2 - 4, x + 1, y2 - 6 ); + lPntArray.putPoints( sc, 10, x2 - 6, y2 - 1, x2 - 4, y2 - 2, // btm right + x2 - 3, y2 - 3, x2 - 2, y2 - 4, x2 - 1, y2 - 6, + x + 6, y2 - 1, x + 4, y2 - 2, // half corners + x + 3, y2 - 3, x2 - 1, y + 6, x2 - 2, y + 4 ); + sc += 10; + } + hLineArray.putPoints( i * 4, 4, x + 6, y, x2 - 6, y, x, y + 6, x, y2 - 6 ); + lLineArray.putPoints( i * 4, 4, x + 6, y2, x2 - 6, y2, x2, y + 6, x2, y2 - 6 ); + ++x, ++y; + --x2, --y2; + } + p->setPen( Qt::black ); + p->drawPoints( bPntArray ); + p->drawLineSegments( bLineArray ); + p->setPen( highPen ); + p->drawPoints( hPntArray ); + p->drawLineSegments( hLineArray ); + p->setPen( lowPen ); + p->drawPoints( lPntArray ); + p->drawLineSegments( lLineArray ); + } + // Rectangular buttons + else + { + QPointArray highShade( hWidth * 4 ); + QPointArray lowShade( hWidth * 4 ); + + p->setPen( g.shadow() ); + for ( i = 0; i < bWidth && w > 2 && h > 2; ++i, ++x, ++y, w -= 2, h -= 2 ) + p->drawRect( x, y , w, h ); + + if ( !hWidth ) + return ; + + x2 = x + w - 1, y2 = y + h - 1; + for ( i = 0; i < hWidth; ++i, ++x, ++y, --x2, --y2 ) + { + highShade.putPoints( i * 4, 4, x, y, x2, y, x, y, x, y2 ); + lowShade.putPoints( i * 4, 4, x, y2, x2, y2, x2, y, x2, y2 ); + } + if ( style == Windows && hWidth > 1 ) + { + p->setPen( highPen ); + p->drawLineSegments( highShade, 0, 2 ); + p->setPen( lowPen ); + p->drawLineSegments( lowShade, 0, 2 ); + + p->setPen( ( sunken ) ? g.dark() : g.mid() ); + p->drawLineSegments( highShade, 4 ); + p->setPen( ( sunken ) ? g.mid() : g.dark() ); + p->drawLineSegments( lowShade, 4 ); + } + else + { + p->setPen( ( sunken ) ? g.dark() : g.light() ); + p->drawLineSegments( highShade ); + p->setPen( ( sunken ) ? g.light() : g.dark() ); + p->drawLineSegments( lowShade ); + } + } +} + + + + +int KThemeStyle::popupMenuItemHeight( bool /*checkable*/, QMenuItem *mi, + const QFontMetrics &fm ) +{ + int h2, h = 0; + int offset = QMAX( decoWidth( MenuItemDown ), decoWidth( MenuItem ) ) + 4; + + if ( mi->isSeparator() ) + return ( 2 ); + if ( mi->isChecked() ) + h = isPixmap( CheckMark ) ? uncached( CheckMark ) ->height() + offset : + offset + 16; + if ( mi->pixmap() ) + { + h2 = mi->pixmap() ->height() + offset; + h = h2 > h ? h2 : h; + } + if ( mi->iconSet() ) + { + h2 = mi->iconSet() -> + pixmap( QIconSet::Small, QIconSet::Normal ).height() + offset; + h = h2 > h ? h2 : h; + } + h2 = fm.height() + offset; + h = h2 > h ? h2 : h; + return ( h ); +} + +#include "kthemestyle.moc" +// kate: indent-width 4; replace-tabs off; tab-width 4; space-indent on; diff --git a/kstyles/kthemestyle/kthemestyle.h b/kstyles/kthemestyle/kthemestyle.h new file mode 100644 index 000000000..9b7d54b60 --- /dev/null +++ b/kstyles/kthemestyle/kthemestyle.h @@ -0,0 +1,230 @@ +/* +$Id$ + +This file is part of the KDE libraries +Copyright (C) 1999 Daniel M. Duley <[email protected]> + +KDE3 port (C) 2001-2002 Maksim Orlovich <[email protected]> +Port version 0.9.7 + +Includes code portions from the dotNET style, and the KDE HighColor style. + +dotNET Style + Copyright (C) 2001, Chris Lee <[email protected]> + Carsten Pfeiffer <[email protected]> + +KDE3 HighColor Style +Copyright (C) 2001 Karol Szwed <[email protected]> + (C) 2001 Fredrik H�glund <[email protected]> + +Drawing routines adapted from the KDE2 HCStyle, +Copyright (C) 2000 Daniel M. Duley <[email protected]> + (C) 2000 Dirk Mueller <[email protected]> + (C) 2001 Martijn Klingens <[email protected]> + + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef KTHEMESTYLE_H +#define KTHEMESTYLE_H + +#include <qglobal.h> + +#include "kthemebase.h" +#include <qwindowdefs.h> +#include <qobject.h> +#include <qbutton.h> +#include <qpushbutton.h> +#include <qscrollbar.h> +#include <qtabbar.h> +#include <qstring.h> +#include <qintdict.h> +#include <qmap.h> + + +/** + * KDE themed styles. + * + * It provides methods for + * drawing most widgets with user-specified borders, highlights, pixmaps, + * etc. It also handles various other settings such as scrollbar types, + * rounded buttons, and shading types. For a full list of parameters this + * class handles refer to the KDE theme configuration documentation. + * + */ + +class KThemeStyle: public KThemeBase +{ + Q_OBJECT +public: + /** + * Constructs a new KThemeStyle object. + * + * @param configDir The directory which has the KConfig file. + * @param configFile A KConfig file to use as the theme configuration. + * Defaults to ~/.kderc. + */ + KThemeStyle( const QString& configDir, const QString &configFile = QString::null ); + ~KThemeStyle(); + + virtual int pixelMetric ( PixelMetric metric, const QWidget * widget = 0 ) const; + + virtual void drawPrimitive ( PrimitiveElement pe, QPainter * p, const QRect & r, const QColorGroup & cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + virtual void drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + virtual void drawControlMask( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& = QStyleOption::Default ) const; + + + virtual void drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + SCFlags controls = SC_All, + SCFlags active = SC_None, + const QStyleOption& = QStyleOption::Default ) const; + + virtual void drawKStylePrimitive( KStylePrimitive kpe, + QPainter* p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + + virtual int styleHint( StyleHint sh, + const QWidget *widget = 0, + const QStyleOption& = QStyleOption::Default, + QStyleHintReturn* returnData = 0 ) const; + + virtual QSize sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentsSize, + const QStyleOption& = QStyleOption::Default ) const; + + virtual QRect subRect(SubRect, const QWidget *) const; + + virtual void polish( QWidget* ); + virtual void unPolish( QWidget* ); + virtual bool eventFilter( QObject* object, QEvent* event ); + /** + * By default this just sets the background brushes to the pixmapped + * background. + */ + virtual void polish( QApplication *app ); + virtual void unPolish( QApplication* ); + + /** \internal */ + // to make it possible for derived classes to overload this function + virtual void polish( QPalette& pal ); + + /** + * This is a convenience method for drawing widgets with + * borders, highlights, pixmaps, colors, etc... + * You specify the widget type and it will draw it according to the + * config file settings. + * + * @param x The x coordinate of the button's upper left hand corner. + * @param y The y coordinate of the buttons' upper left hand corner. + * @param w The button width. + * @param h The button height. + * @param p The QPainter to draw on. + * @param g The color group to use. + * @param sunken The button is drawn with a sunken style if @p true + * @param rounded @p true if the widget is rounded, @p false if rectangular. + * @param type The widget type to paint. + */ + virtual void drawBaseButton( QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool sunken = false, + bool rounded = false, WidgetType type = Bevel ) const; + /** + * Draw a mask with for widgets that may be rounded. + * + *Currently used + * by pushbuttons and comboboxes. + * + * @param p The QPainter to draw on. + * @param x The x coordinate of the widget's upper left hand corner. + * @param y The y coordinate of the widget's upper left hand corner. + * @param w The widget width. + * @param h The widget height. + * @param rounded @p true if the widget is rounded, @p false if rectangular. + */ + virtual void drawBaseMask( QPainter *p, int x, int y, int w, int h, + bool rounded ) const; + + + + /** + * Draw a shaded rectangle using the given style. + * + * @param p The painter to draw on. + * @param g The color group to use. + * @param x The x coordinate of the rectangle's upper left hand corner. + * @param y The y coordinate of the rectangle's upper left hand corner. + * @param w The rectangle width. + * @param h The rectangle height. + * @param sunken Draws a sunken style if @p true. + * @param rounded Draws a rounded shape if @p true. Requires bWidth to be + * at least 1. + * @param hWidth The highlight width. + * @param bWidth The border width. + * @param style The shading style to use. + */ + virtual void drawShade( QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool sunken, bool rounded, + int hWidth, int bWidth, ShadeStyle style ) const; + int popupMenuItemHeight( bool checkable, QMenuItem *mi, + const QFontMetrics &fm ); + +protected: + QPalette oldPalette, popupPalette, indiPalette, exIndiPalette; + bool paletteSaved; + bool polishLock; + QStyle *mtfstyle; + + QPixmap* makeMenuBarCache(int w, int h) const; + + mutable QPixmap* menuCache; + mutable QPixmap* vsliderCache; + + Qt::HANDLE brushHandle; + bool brushHandleSet; + bool kickerMode; + +protected slots: + void paletteChanged(); + + + +}; + + +#endif diff --git a/kstyles/light/Makefile.am b/kstyles/light/Makefile.am new file mode 100644 index 000000000..bbd6929b0 --- /dev/null +++ b/kstyles/light/Makefile.am @@ -0,0 +1,29 @@ + +# This file is part of the KDE libraries +# Copyright (C) 1997 Matthias Kalle Dalheimer ([email protected]) +# (C) 1997 Stephan Kulow ([email protected]) + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. + +# This library 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 +# Library General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this library; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +AM_CPPFLAGS = -DQT_PLUGIN + +INCLUDES = -I$(top_srcdir)/kdefx $(all_includes) +noinst_HEADERS = lightstyle-v2.h lightstyle-v3.h +kde_style_LTLIBRARIES = light.la +light_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +light_la_LIBADD = $(LIB_QT) ../../kdefx/libkdefx.la +light_la_SOURCES = light.cpp lightstyle-v2.cpp lightstyle-v3.cpp +light_la_METASOURCES = AUTO diff --git a/kstyles/light/light.cpp b/kstyles/light/light.cpp new file mode 100644 index 000000000..264bc5b3d --- /dev/null +++ b/kstyles/light/light.cpp @@ -0,0 +1,58 @@ +/* + Copyright (c) 2000-2001 Trolltech AS ([email protected]) + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include <qstyleplugin.h> +#include "lightstyle-v2.h" +#include "lightstyle-v3.h" + +class LightStylePlugin : public QStylePlugin +{ +public: + LightStylePlugin(); + + QStringList keys() const; + QStyle *create(const QString &); +}; + +LightStylePlugin::LightStylePlugin() + : QStylePlugin() +{ +} + +QStringList LightStylePlugin::keys() const +{ + QStringList list; + list << "Light, 2nd revision"; + list << "Light, 3rd revision"; + return list; +} + +QStyle *LightStylePlugin::create(const QString &s) +{ + if (s.lower() == "light, 2nd revision") + return new LightStyleV2; + if (s.lower() == "light, 3rd revision") + return new LightStyleV3; + return 0; +} + +KDE_Q_EXPORT_PLUGIN( LightStylePlugin ) diff --git a/kstyles/light/lightstyle-v2.cpp b/kstyles/light/lightstyle-v2.cpp new file mode 100644 index 000000000..a562c03c0 --- /dev/null +++ b/kstyles/light/lightstyle-v2.cpp @@ -0,0 +1,1627 @@ +/* + Copyright (c) 2000-2001 Trolltech AS ([email protected]) + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "lightstyle-v2.h" + +#include "qmenubar.h" +#include "qapplication.h" +#include "qpainter.h" +#include "qpalette.h" +#include "qframe.h" +#include "qpushbutton.h" +#include "qdrawutil.h" +#include "qprogressbar.h" +#include "qscrollbar.h" +#include "qtabbar.h" +#include "qguardedptr.h" +#include "qlayout.h" +#include "qlineedit.h" +#include "qimage.h" +#include "qcombobox.h" +#include "qslider.h" +#include "qstylefactory.h" + + +class LightStyleV2Private +{ +public: + LightStyleV2Private() + : ref(1) + { + basestyle = QStyleFactory::create( "Windows" ); + if ( ! basestyle ) + basestyle = QStyleFactory::create( QStyleFactory::keys().first() ); + if ( ! basestyle ) + qFatal( "LightStyle: couldn't find a basestyle!" ); + } + + ~LightStyleV2Private() + { + delete basestyle; + } + + QStyle *basestyle; + int ref; +}; + +static LightStyleV2Private *singleton = 0; + + +LightStyleV2::LightStyleV2() + : KStyle(AllowMenuTransparency) +{ + if (! singleton) + singleton = new LightStyleV2Private; + else + singleton->ref++; +} + +LightStyleV2::~LightStyleV2() +{ + if (singleton && --singleton->ref <= 0) { + delete singleton; + singleton = 0; + } +} + +void LightStyleV2::polishPopupMenu( QPopupMenu * menu ) +{ + KStyle::polishPopupMenu(menu); +} + +static void drawLightBevel(QPainter *p, const QRect &r, const QColorGroup &cg, + QStyle::SFlags flags, const QBrush *fill = 0) +{ + QRect br = r; + bool sunken = (flags & (QStyle::Style_Down | QStyle::Style_On | + QStyle::Style_Sunken)); + + p->setPen(cg.dark()); + p->drawRect(r); + + if (flags & (QStyle::Style_Down | QStyle::Style_On | + QStyle::Style_Sunken | QStyle::Style_Raised)) { + // button bevel + if (sunken) + p->setPen(cg.mid()); + else + p->setPen(cg.light()); + + p->drawLine(r.x() + 1, r.y() + 2, + r.x() + 1, r.y() + r.height() - 3); // left + p->drawLine(r.x() + 1, r.y() + 1, + r.x() + r.width() - 2, r.y() + 1); // top + + if (sunken) + p->setPen(cg.light()); + else + p->setPen(cg.mid()); + + p->drawLine(r.x() + r.width() - 2, r.y() + 2, + r.x() + r.width() - 2, r.y() + r.height() - 3); // right + p->drawLine(r.x() + 1, r.y() + r.height() - 2, + r.x() + r.width() - 2, r.y() + r.height() - 2); // bottom + + br.addCoords(2, 2, -2, -2); + } else + br.addCoords(1, 1, -1, -1); + + // fill + if (fill) p->fillRect(br, *fill); +} + +void LightStyleV2::drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption &data ) const +{ + switch (pe) { + case PE_HeaderSection: + { + flags = ((flags | Style_Sunken) ^ Style_Sunken) | Style_Raised; + //Don't show pressed too often (as in light 3) + QBrush fill(cg.background()); + if (flags & QStyle::Style_Enabled) + fill.setColor(cg.button()); + + drawLightBevel(p, r, cg, flags, &fill); + p->setPen( cg.buttonText() ); + break; + } + + case PE_ButtonCommand: + case PE_ButtonBevel: + case PE_ButtonTool: + { + const QBrush *fill; + if (flags & QStyle::Style_Enabled) { + if (flags & (QStyle::Style_Down | + QStyle::Style_On | + QStyle::Style_Sunken)) + fill = &cg.brush(QColorGroup::Midlight); + else + fill = &cg.brush(QColorGroup::Button); + } else + fill = &cg.brush(QColorGroup::Background); + drawLightBevel(p, r, cg, flags, fill); + break; + } + + case PE_ButtonDropDown: + { + QBrush thefill; + bool sunken = + (flags & (QStyle::Style_Down | QStyle::Style_On | QStyle::Style_Sunken)); + + if (flags & QStyle::Style_Enabled) { + if (sunken) + thefill = cg.brush(QColorGroup::Midlight); + else + thefill = cg.brush(QColorGroup::Button); + } else + thefill = cg.brush(QColorGroup::Background); + + p->setPen(cg.dark()); + p->drawLine(r.topLeft(), r.topRight()); + p->drawLine(r.topRight(), r.bottomRight()); + p->drawLine(r.bottomRight(), r.bottomLeft()); + + if (flags & (QStyle::Style_Down | QStyle::Style_On | + QStyle::Style_Sunken | QStyle::Style_Raised)) { + // button bevel + if (sunken) + p->setPen(cg.mid()); + else + p->setPen(cg.light()); + + p->drawLine(r.x(), r.y() + 2, + r.x(), r.y() + r.height() - 3); // left + p->drawLine(r.x(), r.y() + 1, + r.x() + r.width() - 2, r.y() + 1); // top + + if (sunken) + p->setPen(cg.light()); + else + p->setPen(cg.mid()); + + p->drawLine(r.x() + r.width() - 2, r.y() + 2, + r.x() + r.width() - 2, r.y() + r.height() - 3); // right + p->drawLine(r.x() + 1, r.y() + r.height() - 2, + r.x() + r.width() - 2, r.y() + r.height() - 2); // bottom + } + + p->fillRect(r.x() + 1, r.y() + 2, r.width() - 3, r.height() - 4, thefill); + break; + } + + case PE_ButtonDefault: + p->setPen(cg.dark()); + p->setBrush(cg.light()); + p->drawRect(r); + break; + + case PE_Indicator: + const QBrush *fill; + if (! (flags & Style_Enabled)) + fill = &cg.brush(QColorGroup::Background); + else if (flags & Style_Down) + fill = &cg.brush(QColorGroup::Mid); + else + fill = &cg.brush(QColorGroup::Base); + drawLightBevel(p, r, cg, flags | Style_Sunken, fill); + + p->setPen(cg.text()); + if (flags & Style_NoChange) { + p->drawLine(r.x() + 3, r.y() + r.height() / 2, + r.x() + r.width() - 4, r.y() + r.height() / 2); + p->drawLine(r.x() + 3, r.y() + 1 + r.height() / 2, + r.x() + r.width() - 4, r.y() + 1 + r.height() / 2); + p->drawLine(r.x() + 3, r.y() - 1 + r.height() / 2, + r.x() + r.width() - 4, r.y() - 1 + r.height() / 2); + } else if (flags & Style_On) { + p->drawLine(r.x() + 4, r.y() + 3, + r.x() + r.width() - 4, r.y() + r.height() - 5); + p->drawLine(r.x() + 3, r.y() + 3, + r.x() + r.width() - 4, r.y() + r.height() - 4); + p->drawLine(r.x() + 3, r.y() + 4, + r.x() + r.width() - 5, r.y() + r.height() - 4); + p->drawLine(r.x() + 3, r.y() + r.height() - 5, + r.x() + r.width() - 5, r.y() + 3); + p->drawLine(r.x() + 3, r.y() + r.height() - 4, + r.x() + r.width() - 4, r.y() + 3); + p->drawLine(r.x() + 4, r.y() + r.height() - 4, + r.x() + r.width() - 4, r.y() + 4); + } + + break; + + case PE_ExclusiveIndicator: + { + QRect br = r, // bevel rect + cr = r, // contents rect + ir = r; // indicator rect + br.addCoords(1, 1, -1, -1); + cr.addCoords(2, 2, -2, -2); + ir.addCoords(3, 3, -3, -3); + + p->fillRect(r, cg.brush(QColorGroup::Background)); + + p->setPen(cg.dark()); + p->drawArc(r, 0, 16*360); + p->setPen(cg.mid()); + p->drawArc(br, 45*16, 180*16); + p->setPen(cg.light()); + p->drawArc(br, 235*16, 180*16); + + p->setPen(flags & Style_Down ? cg.mid() : + (flags & Style_Enabled ? cg.base() : cg.background())); + p->setBrush(flags & Style_Down ? cg.mid() : + (flags & Style_Enabled ? cg.base() : cg.background())); + p->drawEllipse(cr); + + if (flags & Style_On) { + p->setBrush(cg.text()); + p->drawEllipse(ir); + } + + break; + } + + case PE_DockWindowHandle: + { + QString title; + bool drawTitle = false; + if ( p && p->device()->devType() == QInternal::Widget ) { + QWidget *w = (QWidget *) p->device(); + QWidget *p = w->parentWidget(); + if (p->inherits("QDockWindow") && ! p->inherits("QToolBar")) { + drawTitle = true; + title = p->caption(); + } + } + + flags |= Style_Raised; + if (flags & Style_Horizontal) { + if (drawTitle) { + QPixmap pm(r.height(), r.width()); + QPainter p2(&pm); + p2.fillRect(0, 0, pm.width(), pm.height(), + cg.brush(QColorGroup::Highlight)); + p2.setPen(cg.highlightedText()); + p2.drawText(0, 0, pm.width(), pm.height(), AlignCenter, title); + p2.end(); + + QWMatrix m; + m.rotate(270.0); + pm = pm.xForm(m); + p->drawPixmap(r.x(), r.y(), pm); + } else { + p->fillRect(r, cg.background()); + p->setPen(cg.mid().dark()); + p->drawLine(r.right() - 6, r.top() + 2, + r.right() - 6, r.bottom() - 2); + p->drawLine(r.right() - 3, r.top() + 2, + r.right() - 3, r.bottom() - 2); + p->setPen(cg.light()); + p->drawLine(r.right() - 5, r.top() + 2, + r.right() - 5, r.bottom() - 2); + p->drawLine(r.right() - 2, r.top() + 2, + r.right() - 2, r.bottom() - 2); + } + } else { + if (drawTitle) { + p->fillRect(r, cg.brush(QColorGroup::Highlight)); + p->setPen(cg.highlightedText()); + p->drawText(r, AlignCenter, title); + } else { + p->fillRect(r, cg.background()); + p->setPen(cg.mid().dark()); + p->drawLine(r.left() + 2, r.bottom() - 6, + r.right() - 2, r.bottom() - 6); + p->drawLine(r.left() + 2, r.bottom() - 3, + r.right() - 2, r.bottom() - 3); + p->setPen(cg.light()); + p->drawLine(r.left() + 2, r.bottom() - 5, + r.right() - 2, r.bottom() - 5); + p->drawLine(r.left() + 2, r.bottom() - 2, + r.right() - 2, r.bottom() - 2); + } + } + break; + } + + case PE_DockWindowSeparator: + { + if (r.width() > 20 || r.height() > 20) { + if (flags & Style_Horizontal) { + p->setPen(cg.mid().dark(120)); + p->drawLine(r.left() + 1, r.top() + 6, r.left() + 1, r.bottom() - 6); + p->setPen(cg.light()); + p->drawLine(r.left() + 2, r.top() + 6, r.left() + 2, r.bottom() - 6); + } else { + p->setPen(cg.mid().dark(120)); + p->drawLine(r.left() + 6, r.top() + 1, r.right() - 6, r.top() + 1); + p->setPen(cg.light()); + p->drawLine(r.left() + 6, r.top() + 2, r.right() - 6, r.top() + 2); + } + } else + QCommonStyle::drawPrimitive(pe, p, r, cg, flags, data); + break; + } + + case PE_Splitter: + if (flags & Style_Horizontal) + flags &= ~Style_Horizontal; + else + flags |= Style_Horizontal; + // fall through intended + + case PE_DockWindowResizeHandle: + { + p->fillRect(r, cg.background()); + if (flags & Style_Horizontal) { + p->setPen(cg.highlight().light()); + p->drawLine(r.left() + 1, r.top() + 1, r.right() - 1, r.top() + 1); + p->setPen(cg.highlight()); + p->drawLine(r.left() + 1, r.top() + 2, r.right() - 1, r.top() + 2); + p->setPen(cg.highlight().dark()); + p->drawLine(r.left() + 1, r.top() + 3, r.right() - 1, r.top() + 3); + } else { + p->setPen(cg.highlight().light()); + p->drawLine(r.left() + 1, r.top() + 1, r.left() + 1, r.bottom() - 1); + p->setPen(cg.highlight()); + p->drawLine(r.left() + 2, r.top() + 1, r.left() + 2, r.bottom() - 1); + p->setPen(cg.highlight().dark()); + p->drawLine(r.left() + 3, r.top() + 1, r.left() + 3, r.bottom() - 1); + } + break; + } + + case PE_Panel: + case PE_PanelPopup: + case PE_PanelLineEdit: + case PE_PanelTabWidget: + case PE_WindowFrame: + { + int lw = data.isDefault() ? + pixelMetric(PM_DefaultFrameWidth) : data.lineWidth(); + + if ( ! ( flags & Style_Sunken ) ) + flags |= Style_Raised; + if (lw == 2) + drawLightBevel(p, r, cg, flags); + else + QCommonStyle::drawPrimitive(pe, p, r, cg, flags, data); + break; + } + + case PE_PanelDockWindow: + { + int lw = data.isDefault() ? + pixelMetric(PM_DockWindowFrameWidth) : data.lineWidth(); + + if (lw == 2) + drawLightBevel(p, r, cg, flags | Style_Raised, + &cg.brush(QColorGroup::Button)); + else + QCommonStyle::drawPrimitive(pe, p, r, cg, flags, data); + break; + } + + case PE_PanelMenuBar: + { + int lw = data.isDefault() ? + pixelMetric(PM_MenuBarFrameWidth) : data.lineWidth(); + + if (lw == 2) + drawLightBevel(p, r, cg, flags, &cg.brush(QColorGroup::Button)); + else + QCommonStyle::drawPrimitive(pe, p, r, cg, flags, data); + break; + } + + case PE_ScrollBarSubLine: + { + QRect fr = r, ar = r; + PrimitiveElement pe; + + p->setPen(cg.dark()); + if (flags & Style_Horizontal) { + p->drawLine(r.topLeft(), r.topRight()); + fr.addCoords(0, 1, 0, 0); + ar.addCoords(0, 1, 0, 0); + pe = PE_ArrowLeft; + } else { + p->drawLine(r.topLeft(), r.bottomLeft()); + fr.addCoords(1, 0, 0, 0); + ar.addCoords(2, 0, 0, 0); + pe = PE_ArrowUp; + } + + p->fillRect(fr, cg.brush((flags & Style_Down) ? + QColorGroup::Midlight : + QColorGroup::Background)); + drawPrimitive(pe, p, ar, cg, flags); + break; + } + + case PE_ScrollBarAddLine: + { + QRect fr = r, ar = r; + PrimitiveElement pe; + + p->setPen(cg.dark()); + if (flags & Style_Horizontal) { + p->drawLine(r.topLeft(), r.topRight()); + fr.addCoords(0, 1, 0, 0); + ar.addCoords(0, 1, 0, 0); + pe = PE_ArrowRight; + } else { + p->drawLine(r.topLeft(), r.bottomLeft()); + fr.addCoords(1, 0, 0, 0); + ar.addCoords(2, 0, 0, 0); + pe = PE_ArrowDown; + } + + p->fillRect(fr, cg.brush((flags & Style_Down) ? + QColorGroup::Midlight : + QColorGroup::Background)); + drawPrimitive(pe, p, ar, cg, flags); + break; + } + + case PE_ScrollBarSubPage: + case PE_ScrollBarAddPage: + { + QRect fr = r; + + p->setPen(cg.dark()); + if (flags & Style_Horizontal) { + p->drawLine(r.topLeft(), r.topRight()); + p->setPen(cg.background()); + p->drawLine(r.left(), r.top() + 1, r.right(), r.top() + 1); + fr.addCoords(0, 2, 0, 0); + } else { + p->drawLine(r.topLeft(), r.bottomLeft()); + p->setPen(cg.background()); + p->drawLine(r.left() + 1, r.top(), r.left() + 1, r.bottom()); + fr.addCoords(2, 0, 0, 0); + } + + p->fillRect(fr, cg.brush((flags & Style_Down) ? + QColorGroup::Midlight : + QColorGroup::Mid)); + break; + } + + case PE_ScrollBarSlider: + { + QRect fr = r; + + p->setPen(cg.dark()); + if (flags & Style_Horizontal) { + p->drawLine(r.topLeft(), r.topRight()); + p->setPen(cg.background()); + p->drawLine(r.left(), r.top() + 1, r.right(), r.top() + 1); + fr.addCoords(0, 2, 0, -1); + } else { + p->drawLine(r.topLeft(), r.bottomLeft()); + p->setPen(cg.background()); + p->drawLine(r.left() + 1, r.top(), r.left() + 1, r.bottom()); + fr.addCoords(2, 0, -1, 0); + } + + drawLightBevel(p, fr, cg, ((flags | Style_Down) ^ Style_Down) | + ((flags & Style_Enabled) ? Style_Raised : Style_Default), + &cg.brush(QColorGroup::Button)); + break; + } + + case PE_FocusRect: + { + p->setBrush(NoBrush); + if (flags & Style_FocusAtBorder) + p->setPen(cg.shadow()); + else + p->setPen(cg.dark()); + p->drawRect(r); + break; + } + + case PE_ProgressBarChunk: + p->fillRect(r.x(), r.y() + 2, r.width(), r.height() - 4, cg.highlight()); + break; + + default: + if (pe == PE_HeaderArrow) { + if (flags & Style_Down) + pe = PE_ArrowDown; + else + pe = PE_ArrowUp; + } + + + if (pe >= PE_ArrowUp && pe <= PE_ArrowLeft) { + QPointArray a; + + switch ( pe ) { + case PE_ArrowUp: + a.setPoints( 7, -4,1, 2,1, -3,0, 1,0, -2,-1, 0,-1, -1,-2 ); + break; + + case PE_ArrowDown: + a.setPoints( 7, -4,-2, 2,-2, -3,-1, 1,-1, -2,0, 0,0, -1,1 ); + break; + + case PE_ArrowRight: + a.setPoints( 7, -2,-3, -2,3, -1,-2, -1,2, 0,-1, 0,1, 1,0 ); + break; + + case PE_ArrowLeft: + a.setPoints( 7, 0,-3, 0,3, -1,-2, -1,2, -2,-1, -2,1, -3,0 ); + break; + + default: + break; + } + + if (a.isNull()) + return; + + p->save(); + if ( flags & Style_Enabled ) { + a.translate( r.x() + r.width() / 2, r.y() + r.height() / 2 ); + p->setPen( cg.buttonText() ); + p->drawLineSegments( a, 0, 3 ); // draw arrow + p->drawPoint( a[6] ); + } else { + a.translate( r.x() + r.width() / 2 + 1, r.y() + r.height() / 2 + 1 ); + p->setPen( cg.light() ); + p->drawLineSegments( a, 0, 3 ); // draw arrow + p->drawPoint( a[6] ); + a.translate( -1, -1 ); + p->setPen( cg.mid() ); + p->drawLineSegments( a, 0, 3 ); // draw arrow + p->drawPoint( a[6] ); + } + p->restore(); + } else + QCommonStyle::drawPrimitive(pe, p, r, cg, flags, data); + break; + } +} + +void LightStyleV2::drawControl( ControlElement control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption &data ) const +{ + switch (control) { + case CE_TabBarTab: + { + const QTabBar* tb = static_cast<const QTabBar*>(widget); + bool below = false; + QRect tr(r); + QRect fr(r); + + tr.addCoords(0, 0, 0, -1); + fr.addCoords(2, 2, -2, -2); + + if ( tb->shape() == QTabBar::RoundedBelow || tb->shape() == QTabBar::TriangularBelow) { + tr = r; tr.addCoords(0, 1, 0, 0); + fr = r; fr.addCoords(2, 2,-2, -4); + below = true; + } + + if (! (flags & Style_Selected)) { + if (below) { + tr.addCoords(0, 0, 0, -1); + tr.addCoords(0, 0, 0, -1); + } else { + tr.addCoords(0, 1, 0, 0); + fr.addCoords(0, 1, 0, 0); + } + + p->setPen(cg.dark()); + p->drawRect(tr); + + if (tr.left() == 0) + if (below) + p->drawPoint(tr.left(), tr.top() - 1); + else + p->drawPoint(tr.left(), tr.bottom() + 1); + + p->setPen(cg.light()); + if (below) { + p->drawLine(tr.left() + 1, tr.top() + 1, + tr.left() + 1, tr.bottom() - 2); + p->drawLine(tr.left() + 1, tr.bottom() - 1, + tr.right() - 1, tr.bottom() - 1); + } else { + p->drawLine(tr.left() + 1, tr.bottom() - 1, + tr.left() + 1, tr.top() + 2); + p->drawLine(tr.left() + 1, tr.top() + 1, + tr.right() - 1, tr.top() + 1); + } + + if (below) { + if (tr.left() == 0) + p->drawLine(tr.left() + 1, tr.top() - 1, + tr.right(), tr.top() - 1); + else + { + p->setPen(cg.mid()); //To match lower border of the frame + p->drawLine(tr.left(), tr.top() - 1, + tr.right(), tr.top() - 1); + } + } else { + if (tr.left() == 0) + p->drawLine(tr.left() + 1, tr.bottom() + 1, + tr.right(), tr.bottom() + 1); + else + p->drawLine(tr.left(), tr.bottom() + 1, + tr.right(), tr.bottom() + 1); + } + + p->setPen(cg.mid()); + + if (below) { + p->drawLine(tr.right() - 1, tr.bottom() - 2, + tr.right() - 1, tr.top() + 1); + } else { + p->drawLine(tr.right() - 1, tr.top() + 2, + tr.right() - 1, tr.bottom() - 1); + } + } else { + p->setPen(cg.dark()); + if (tr.left() == 0) + if (below) + p->drawLine(tr.left(), tr.top() - 1, + tr.left(), tr.bottom() - 1); + else + p->drawLine(tr.left(), tr.bottom() + 1, + tr.left(), tr.top() + 1); + else + if (below) + p->drawLine(tr.left(), tr.bottom(), + tr.left(), tr.top() + 1); + else + p->drawLine(tr.left(), tr.bottom(), + tr.left(), tr.top() + 1); + + if (below) { + p->drawLine(tr.left(), tr.bottom(), + tr.right(), tr.bottom()); + p->drawLine(tr.right(), tr.bottom() - 1, + tr.right(), tr.top()); + + } else { + p->drawLine(tr.left(), tr.top(), + tr.right(), tr.top()); + p->drawLine(tr.right(), tr.top() + 1, + tr.right(), tr.bottom()); + } + + p->setPen(cg.light()); + if (tr.left() == 0) + if (below) + p->drawLine(tr.left() + 1, tr.top() - 2, + tr.left() + 1, tr.bottom() - 2); + else + p->drawLine(tr.left() + 1, tr.bottom() + 2, + tr.left() + 1, tr.top() + 2); + else { + if (below) { + p->drawLine(tr.left() + 1, tr.top(), + tr.left() + 1, tr.bottom() - 2); + p->drawPoint(tr.left(), tr.top() - 1); + + } else { + p->drawLine(tr.left() + 1, tr.bottom(), + tr.left() + 1, tr.top() + 2); + p->drawPoint(tr.left(), tr.bottom() + 1); + } + } + + if (below) { + p->drawLine(tr.left() + 1, tr.bottom() - 1, + tr.right() - 1, tr.bottom() - 1); + p->drawPoint(tr.right(), tr.top() - 1); + + p->setPen(cg.mid()); + p->drawLine(tr.right() - 1, tr.bottom() - 2, + tr.right() - 1, tr.top()); + } else { + p->drawLine(tr.left() + 1, tr.top() + 1, + tr.right() - 1, tr.top() + 1); + p->drawPoint(tr.right(), tr.bottom() + 1); + + p->setPen(cg.mid()); + p->drawLine(tr.right() - 1, tr.top() + 2, + tr.right() - 1, tr.bottom()); + } + } + + p->fillRect(fr, ((flags & Style_Selected) ? + cg.background() : cg.mid())); + break; + } + + case CE_PopupMenuItem: + { + if (! widget || data.isDefault()) + break; + + const QPopupMenu *popupmenu = (const QPopupMenu *) widget; + QMenuItem *mi = data.menuItem(); + int tab = data.tabWidth(); + int maxpmw = data.maxIconWidth(); + + if ( mi && mi->isSeparator() ) { + // draw separator (bg first, though) + if ( widget->erasePixmap() && !widget->erasePixmap()->isNull() ) + p->drawPixmap( r.topLeft(), *widget->erasePixmap(), r ); + else + p->fillRect(r, cg.brush(QColorGroup::Button)); + + p->setPen(cg.mid().dark(120)); + p->drawLine(r.left() + 12, r.top() + 1, + r.right() - 12, r.top() + 1); + p->setPen(cg.light()); + p->drawLine(r.left() + 12, r.top() + 2, + r.right() - 12, r.top() + 2); + break; + } + + if (flags & Style_Active) + qDrawShadePanel(p, r, cg, true, 1, + &cg.brush(QColorGroup::Midlight)); + else if ( widget->erasePixmap() && !widget->erasePixmap()->isNull() ) + p->drawPixmap( r.topLeft(), *widget->erasePixmap(), r ); + else + p->fillRect(r, cg.brush(QColorGroup::Button)); + + if ( !mi ) + break; + + maxpmw = QMAX(maxpmw, 16); + + QRect cr, ir, tr, sr; + // check column + cr.setRect(r.left(), r.top(), maxpmw, r.height()); + // submenu indicator column + sr.setCoords(r.right() - maxpmw, r.top(), r.right(), r.bottom()); + // tab/accelerator column + tr.setCoords(sr.left() - tab - 4, r.top(), sr.left(), r.bottom()); + // item column + ir.setCoords(cr.right() + 4, r.top(), tr.right() - 4, r.bottom()); + + bool reverse = QApplication::reverseLayout(); + if ( reverse ) { + cr = visualRect( cr, r ); + sr = visualRect( sr, r ); + tr = visualRect( tr, r ); + ir = visualRect( ir, r ); + } + + if (mi->isChecked() && + ! (flags & Style_Active) & + (flags & Style_Enabled)) + qDrawShadePanel(p, cr, cg, true, 1, &cg.brush(QColorGroup::Midlight)); + + if (mi->iconSet()) { + QIconSet::Mode mode = + (flags & Style_Enabled) ? QIconSet::Normal : QIconSet::Disabled; + if ((flags & Style_Active) && (flags & Style_Enabled)) + mode = QIconSet::Active; + QPixmap pixmap; + if (popupmenu->isCheckable() && mi->isChecked()) + pixmap = + mi->iconSet()->pixmap( QIconSet::Small, mode, QIconSet::On ); + else + pixmap = + mi->iconSet()->pixmap( QIconSet::Small, mode ); + QRect pmr(QPoint(0, 0), pixmap.size()); + pmr.moveCenter(cr.center()); + p->setPen(cg.text()); + p->drawPixmap(pmr.topLeft(), pixmap); + } else if (popupmenu->isCheckable() && mi->isChecked()) + drawPrimitive(PE_CheckMark, p, cr, cg, + (flags & Style_Enabled) | Style_On); + + QColor textcolor; + QColor embosscolor; + if (flags & Style_Active) { + if (! (flags & Style_Enabled)) + textcolor = cg.midlight().dark(); + else + textcolor = cg.buttonText(); + embosscolor = cg.midlight().light(); + } else if (! (flags & Style_Enabled)) { + textcolor = cg.text(); + embosscolor = cg.light(); + } else + textcolor = embosscolor = cg.buttonText(); + p->setPen(textcolor); + + if (mi->custom()) { + p->save(); + if (! (flags & Style_Enabled)) { + p->setPen(cg.light()); + mi->custom()->paint(p, cg, flags & Style_Active, + flags & Style_Enabled, + ir.x() + 1, ir.y() + 1, + ir.width() - 1, ir.height() - 1); + p->setPen(textcolor); + } + mi->custom()->paint(p, cg, flags & Style_Active, + flags & Style_Enabled, + ir.x(), ir.y(), + ir.width(), ir.height()); + p->restore(); + } + + QString text = mi->text(); + if (! text.isNull()) { + int t = text.find('\t'); + + // draw accelerator/tab-text + if (t >= 0) { + int alignFlag = AlignVCenter | ShowPrefix | DontClip | SingleLine; + alignFlag |= ( reverse ? AlignLeft : AlignRight ); + if (! (flags & Style_Enabled)) { + p->setPen(embosscolor); + tr.moveBy(1, 1); + p->drawText(tr, alignFlag, text.mid(t + 1)); + tr.moveBy(-1, -1); + p->setPen(textcolor); + } + + p->drawText(tr, alignFlag, text.mid(t + 1)); + } + + int alignFlag = AlignVCenter | ShowPrefix | DontClip | SingleLine; + alignFlag |= ( reverse ? AlignRight : AlignLeft ); + + if (! (flags & Style_Enabled)) { + p->setPen(embosscolor); + ir.moveBy(1, 1); + p->drawText(ir, alignFlag, text, t); + ir.moveBy(-1, -1); + p->setPen(textcolor); + } + + p->drawText(ir, alignFlag, text, t); + } else if (mi->pixmap()) { + QPixmap pixmap = *mi->pixmap(); + if (pixmap.depth() == 1) + p->setBackgroundMode(OpaqueMode); + p->drawPixmap(ir.x(), ir.y() + (ir.height() - pixmap.height()) / 2, pixmap); + if (pixmap.depth() == 1) + p->setBackgroundMode(TransparentMode); + } + + if (mi->popup()) + drawPrimitive( (reverse ? PE_ArrowLeft : PE_ArrowRight), p, sr, cg, flags); + break; + } + + case CE_MenuBarEmptyArea: + { + p->fillRect(r, cg.brush(QColorGroup::Button)); + break; + } + + case CE_DockWindowEmptyArea: + { + p->fillRect(r, cg.brush(QColorGroup::Button)); + break; + } + + + case CE_MenuBarItem: + { + if (flags & Style_Active) + qDrawShadePanel(p, r, cg, true, 1, &cg.brush(QColorGroup::Midlight)); + else + p->fillRect(r, cg.brush(QColorGroup::Button)); + + if (data.isDefault()) + break; + + QMenuItem *mi = data.menuItem(); + drawItem(p, r, AlignCenter | ShowPrefix | DontClip | SingleLine, cg, + flags & Style_Enabled, mi->pixmap(), mi->text(), -1, + &cg.buttonText()); + break; + } + + case CE_ProgressBarGroove: + drawLightBevel(p, r, cg, Style_Sunken, &cg.brush(QColorGroup::Background)); + break; + + default: + QCommonStyle::drawControl(control, p, widget, r, cg, flags, data); + break; + } +} + +void LightStyleV2::drawControlMask( ControlElement control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption &data ) const +{ + switch (control) { + case CE_PushButton: + p->fillRect(r, color1); + break; + + default: + QCommonStyle::drawControlMask(control, p, widget, r, data); + break; + } +} + +QRect LightStyleV2::subRect(SubRect subrect, const QWidget *widget) const +{ + QRect rect, wrect(widget->rect()); + + switch (subrect) { + case SR_PushButtonFocusRect: + { + const QPushButton *button = (const QPushButton *) widget; + int dbw1 = 0, dbw2 = 0; + if (button->isDefault() || button->autoDefault()) { + dbw1 = pixelMetric(PM_ButtonDefaultIndicator, widget); + dbw2 = dbw1 * 2; + } + + rect.setRect(wrect.x() + 3 + dbw1, + wrect.y() + 3 + dbw1, + wrect.width() - 6 - dbw2, + wrect.height() - 6 - dbw2); + break; + } + + default: + rect = QCommonStyle::subRect(subrect, widget); + } + + return rect; +} + +void LightStyleV2::drawComplexControl( ComplexControl control, + QPainter* p, + const QWidget* widget, + const QRect& r, + const QColorGroup& cg, + SFlags flags, + SCFlags controls, + SCFlags active, + const QStyleOption &data ) const +{ + switch (control) { + case CC_ComboBox: + { + const QComboBox *combobox = (const QComboBox *) widget; + QRect frame, arrow, field; + frame = + QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget, + SC_ComboBoxFrame, data), + widget); + arrow = + QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget, + SC_ComboBoxArrow, data), + widget); + field = + QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget, + SC_ComboBoxEditField, data), + widget); + + if ((controls & SC_ComboBoxFrame) && frame.isValid()) + drawLightBevel(p, frame, cg, flags | Style_Raised, + &cg.brush(QColorGroup::Button)); + + if ((controls & SC_ComboBoxArrow) && arrow.isValid()) { + if (active == SC_ComboBoxArrow) + p->fillRect(arrow, cg.brush(QColorGroup::Mid)); + arrow.addCoords(4, 2, -2, -2); + drawPrimitive(PE_ArrowDown, p, arrow, cg, flags); + } + + if ((controls & SC_ComboBoxEditField) && field.isValid()) { + p->setPen(cg.dark()); + if (combobox->editable()) { + field.addCoords(-1, -1, 1, 1); + p->drawRect(field); + } else + p->drawLine(field.right() + 1, field.top(), + field.right() + 1, field.bottom()); + + if (flags & Style_HasFocus) { + if (! combobox->editable()) { + p->fillRect( field, cg.brush( QColorGroup::Highlight ) ); + QRect fr = + QStyle::visualRect( subRect( SR_ComboBoxFocusRect, widget ), + widget ); + drawPrimitive( PE_FocusRect, p, fr, cg, + flags | Style_FocusAtBorder, + QStyleOption(cg.highlight())); + } + + p->setPen(cg.highlightedText()); + } else + p->setPen(cg.buttonText()); + } + + break; + } + + case CC_SpinWidget: + { + const QSpinWidget *spinwidget = (const QSpinWidget *) widget; + QRect frame, up, down; + + frame = querySubControlMetrics(CC_SpinWidget, widget, + SC_SpinWidgetFrame, data); + up = spinwidget->upRect(); + down = spinwidget->downRect(); + + if ((controls & SC_SpinWidgetFrame) && frame.isValid()) + drawLightBevel(p, frame, cg, flags | Style_Sunken, + &cg.brush(QColorGroup::Base)); + + if ((controls & SC_SpinWidgetUp) && up.isValid()) { + PrimitiveElement pe = PE_SpinWidgetUp; + if ( spinwidget->buttonSymbols() == QSpinWidget::PlusMinus ) + pe = PE_SpinWidgetPlus; + + p->setPen(cg.dark()); + p->drawLine(up.topLeft(), up.bottomLeft()); + + up.addCoords(1, 0, 0, 0); + p->fillRect(up, cg.brush(QColorGroup::Button)); + if (active == SC_SpinWidgetUp) + p->setPen(cg.mid()); + else + p->setPen(cg.light()); + p->drawLine(up.left(), up.top(), + up.right() - 1, up.top()); + p->drawLine(up.left(), up.top() + 1, + up.left(), up.bottom() - 1); + if (active == SC_SpinWidgetUp) + p->setPen(cg.light()); + else + p->setPen(cg.mid()); + p->drawLine(up.right(), up.top(), + up.right(), up.bottom()); + p->drawLine(up.left(), up.bottom(), + up.right() - 1, up.bottom()); + + up.addCoords(1, 0, 0, 0); + drawPrimitive(pe, p, up, cg, flags | + ((active == SC_SpinWidgetUp) ? + Style_On | Style_Sunken : Style_Raised)); + } + + if ((controls & SC_SpinWidgetDown) && down.isValid()) { + PrimitiveElement pe = PE_SpinWidgetDown; + if ( spinwidget->buttonSymbols() == QSpinWidget::PlusMinus ) + pe = PE_SpinWidgetMinus; + + p->setPen(cg.dark()); + p->drawLine(down.topLeft(), down.bottomLeft()); + + down.addCoords(1, 0, 0, 0); + p->fillRect(down, cg.brush(QColorGroup::Button)); + if (active == SC_SpinWidgetDown) + p->setPen(cg.mid()); + else + p->setPen(cg.light()); + p->drawLine(down.left(), down.top(), + down.right() - 1, down.top()); + p->drawLine(down.left(), down.top() + 1, + down.left(), down.bottom() - 1); + if (active == SC_SpinWidgetDown) + p->setPen(cg.light()); + else + p->setPen(cg.mid()); + p->drawLine(down.right(), down.top(), + down.right(), down.bottom()); + p->drawLine(down.left(), down.bottom(), + down.right() - 1, down.bottom()); + + down.addCoords(1, 0, 0, 0); + drawPrimitive(pe, p, down, cg, flags | + ((active == SC_SpinWidgetDown) ? + Style_On | Style_Sunken : Style_Raised)); + } + + break; + } + + case CC_ScrollBar: + { + const QScrollBar *scrollbar = (const QScrollBar *) widget; + QRect addline, subline, subline2, addpage, subpage, slider, first, last; + bool maxedOut = (scrollbar->minValue() == scrollbar->maxValue()); + + subline = querySubControlMetrics(control, widget, SC_ScrollBarSubLine, data); + addline = querySubControlMetrics(control, widget, SC_ScrollBarAddLine, data); + subpage = querySubControlMetrics(control, widget, SC_ScrollBarSubPage, data); + addpage = querySubControlMetrics(control, widget, SC_ScrollBarAddPage, data); + slider = querySubControlMetrics(control, widget, SC_ScrollBarSlider, data); + first = querySubControlMetrics(control, widget, SC_ScrollBarFirst, data); + last = querySubControlMetrics(control, widget, SC_ScrollBarLast, data); + + subline2 = addline; + if (scrollbar->orientation() == Qt::Horizontal) + subline2.moveBy(-addline.width(), 0); + else + subline2.moveBy(0, -addline.height()); + + if ((controls & SC_ScrollBarSubLine) && subline.isValid()) { + drawPrimitive(PE_ScrollBarSubLine, p, subline, cg, + Style_Enabled | ((active == SC_ScrollBarSubLine) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + + if (subline2.isValid()) + drawPrimitive(PE_ScrollBarSubLine, p, subline2, cg, + Style_Enabled | ((active == SC_ScrollBarSubLine) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + } + if ((controls & SC_ScrollBarAddLine) && addline.isValid()) + drawPrimitive(PE_ScrollBarAddLine, p, addline, cg, + Style_Enabled | ((active == SC_ScrollBarAddLine) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarSubPage) && subpage.isValid()) + drawPrimitive(PE_ScrollBarSubPage, p, subpage, cg, + Style_Enabled | ((active == SC_ScrollBarSubPage) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarAddPage) && addpage.isValid()) + drawPrimitive(PE_ScrollBarAddPage, p, addpage, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarAddPage) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarFirst) && first.isValid()) + drawPrimitive(PE_ScrollBarFirst, p, first, cg, + Style_Enabled | ((active == SC_ScrollBarFirst) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarLast) && last.isValid()) + drawPrimitive(PE_ScrollBarLast, p, last, cg, + Style_Enabled | ((active == SC_ScrollBarLast) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarSlider) && slider.isValid()) { + drawPrimitive(PE_ScrollBarSlider, p, slider, cg, + Style_Enabled | ((active == SC_ScrollBarSlider) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + + // ### perhaps this should not be able to accept focus if maxedOut? + if (scrollbar->hasFocus()) { + QRect fr(slider.x() + 2, slider.y() + 2, + slider.width() - 5, slider.height() - 5); + drawPrimitive(PE_FocusRect, p, fr, cg, Style_Default); + } + } + + break; + } + + case CC_Slider: + { + const QSlider *slider = (const QSlider *) widget; + QRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove, + data), + handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle, + data); + + if ((controls & SC_SliderGroove) && groove.isValid()) { + if (flags & Style_HasFocus) + drawPrimitive( PE_FocusRect, p, groove, cg ); + + if (slider->orientation() == Qt::Horizontal) { + int dh = (groove.height() - 5) / 2; + groove.addCoords(0, dh, 0, -dh); + } else { + int dw = (groove.width() - 5) / 2; + groove.addCoords(dw, 0, -dw, 0); + } + + drawLightBevel(p, groove, cg, ((flags | Style_Raised) ^ Style_Raised) | + ((flags & Style_Enabled) ? Style_Sunken : Style_Default), + &cg.brush(QColorGroup::Midlight)); + } + + if ((controls & SC_SliderHandle) && handle.isValid()) { + drawLightBevel(p, handle, cg, ((flags | Style_Down) ^ Style_Down) | + ((flags & Style_Enabled) ? Style_Raised : Style_Default), + &cg.brush(QColorGroup::Button)); + + } + + if (controls & SC_SliderTickmarks) + QCommonStyle::drawComplexControl(control, p, widget, r, cg, flags, + SC_SliderTickmarks, active, data ); + break; + } + + case CC_ListView: + // use the base style for CC_ListView + singleton->basestyle->drawComplexControl(control, p, widget, r, cg, flags, + controls, active, data); + break; + + default: + QCommonStyle::drawComplexControl(control, p, widget, r, cg, flags, + controls, active, data); + break; + } +} + +QRect LightStyleV2::querySubControlMetrics( ComplexControl control, + const QWidget *widget, + SubControl sc, + const QStyleOption &data ) const +{ + QRect ret; + + switch (control) { + case CC_ScrollBar: + { + const QScrollBar *scrollbar = (const QScrollBar *) widget; + int sliderstart = scrollbar->sliderStart(); + int sbextent = pixelMetric(PM_ScrollBarExtent, widget); + int maxlen = ((scrollbar->orientation() == Qt::Horizontal) ? + scrollbar->width() : scrollbar->height()) - (sbextent * 3); + int sliderlen; + + // calculate slider length + if (scrollbar->maxValue() != scrollbar->minValue()) { + uint range = scrollbar->maxValue() - scrollbar->minValue(); + sliderlen = (scrollbar->pageStep() * maxlen) / + (range + scrollbar->pageStep()); + + int slidermin = pixelMetric( PM_ScrollBarSliderMin, widget ); + if ( sliderlen < slidermin || range > INT_MAX / 2 ) + sliderlen = slidermin; + if ( sliderlen > maxlen ) + sliderlen = maxlen; + } else + sliderlen = maxlen; + + switch (sc) { + case SC_ScrollBarSubLine: + // top/left button + ret.setRect(0, 0, sbextent, sbextent); + break; + + case SC_ScrollBarAddLine: + // bottom/right button + if (scrollbar->orientation() == Qt::Horizontal) + ret.setRect(scrollbar->width() - sbextent, 0, sbextent, sbextent); + else + ret.setRect(0, scrollbar->height() - sbextent, sbextent, sbextent); + break; + + case SC_ScrollBarSubPage: + // between top/left button and slider + if (scrollbar->orientation() == Qt::Horizontal) + ret.setRect(sbextent, 0, sliderstart - sbextent, sbextent); + else + ret.setRect(0, sbextent, sbextent, sliderstart - sbextent); + break; + + case SC_ScrollBarAddPage: + // between bottom/right button and slider + if (scrollbar->orientation() == Qt::Horizontal) + ret.setRect(sliderstart + sliderlen, 0, + maxlen - sliderstart - sliderlen + sbextent, sbextent); + else + ret.setRect(0, sliderstart + sliderlen, + sbextent, maxlen - sliderstart - sliderlen + sbextent); + break; + + case SC_ScrollBarGroove: + if (scrollbar->orientation() == Qt::Horizontal) + ret.setRect(sbextent, 0, scrollbar->width() - sbextent * 3, + scrollbar->height()); + else + ret.setRect(0, sbextent, scrollbar->width(), + scrollbar->height() - sbextent * 3); + break; + + case SC_ScrollBarSlider: + if (scrollbar->orientation() == Qt::Horizontal) + ret.setRect(sliderstart, 0, sliderlen, sbextent); + else + ret.setRect(0, sliderstart, sbextent, sliderlen); + break; + + default: + break; + } + + break; + } + + default: + ret = QCommonStyle::querySubControlMetrics(control, widget, sc, data); + break; + } + + return ret; +} + +QStyle::SubControl LightStyleV2::querySubControl( ComplexControl control, + const QWidget *widget, + const QPoint &pos, + const QStyleOption &data ) const +{ + QStyle::SubControl ret = QCommonStyle::querySubControl(control, widget, pos, data); + + // this is an ugly hack, but i really don't care, it's the quickest way to + // enabled the third button + if (control == CC_ScrollBar && + ret == SC_None) + ret = SC_ScrollBarSubLine; + + return ret; +} + +int LightStyleV2::pixelMetric( PixelMetric metric, + const QWidget *widget ) const +{ + int ret; + + switch (metric) { + case PM_ButtonMargin: + ret = 4; + break; + + case PM_ButtonShiftHorizontal: + case PM_ButtonShiftVertical: + ret = 0; + break; + + case PM_ButtonDefaultIndicator: + case PM_DefaultFrameWidth: + ret = 2; + break; + + case PM_IndicatorWidth: + case PM_IndicatorHeight: + case PM_ExclusiveIndicatorWidth: + case PM_ExclusiveIndicatorHeight: + ret = 13; + break; + + case PM_TabBarTabOverlap: + ret = 0; + break; + + case PM_ScrollBarExtent: + case PM_ScrollBarSliderMin: + ret = 14; + break; + + case PM_MenuBarFrameWidth: + ret = 1; + break; + + case PM_ProgressBarChunkWidth: + ret = 1; + break; + + case PM_DockWindowSeparatorExtent: + ret = 4; + break; + + case PM_SplitterWidth: + ret = 6; + break; + + + case PM_SliderLength: + case PM_SliderControlThickness: + ret = singleton->basestyle->pixelMetric( metric, widget ); + break; + + case PM_MaximumDragDistance: + ret = -1; + break; + + default: + ret = QCommonStyle::pixelMetric(metric, widget); + break; + } + + return ret; +} + +QSize LightStyleV2::sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentsSize, + const QStyleOption &data ) const +{ + QSize ret; + + switch (contents) { + case CT_PushButton: + { + const QPushButton *button = (const QPushButton *) widget; + ret = QCommonStyle::sizeFromContents( contents, widget, contentsSize, data ); + int w = ret.width(), h = ret.height(); + + // only expand the button if we are displaying text... + if ( ! button->text().isEmpty() ) { + if ( button->isDefault() || button->autoDefault() ) { + // default button minimum size + if ( w < 80 ) + w = 80; + if ( h < 25 ) + h = 25; + } else { + // regular button minimum size + if ( w < 76 ) + w = 76; + if ( h < 21 ) + h = 21; + } + } + + ret = QSize( w, h ); + break; + } + + case CT_PopupMenuItem: + { + if (! widget || data.isDefault()) + break; + + QMenuItem *mi = data.menuItem(); + const QPopupMenu *popupmenu = (const QPopupMenu *) widget; + int maxpmw = data.maxIconWidth(); + int w = contentsSize.width(), h = contentsSize.height(); + + if (mi->custom()) { + w = mi->custom()->sizeHint().width(); + h = mi->custom()->sizeHint().height(); + if (! mi->custom()->fullSpan() && h < 22) + h = 22; + } else if(mi->widget()) { + } else if (mi->isSeparator()) { + w = 10; + h = 4; + } else { + // check is at least 16x16 + if (h < 16) + h = 16; + if (mi->pixmap()) + h = QMAX(h, mi->pixmap()->height()); + else if (! mi->text().isNull()) + h = QMAX(h, popupmenu->fontMetrics().height() + 2); + if (mi->iconSet() != 0) + h = QMAX(h, mi->iconSet()->pixmap(QIconSet::Small, + QIconSet::Normal).height()); + h += 2; + } + + // check | 4 pixels | item | 8 pixels | accel | 4 pixels | check + + // check is at least 16x16 + maxpmw = QMAX(maxpmw, 16); + w += (maxpmw * 2) + 8; + + if (! mi->text().isNull() && mi->text().find('\t') >= 0) + w += 8; + + ret = QSize(w, h); + break; + } + case CT_ProgressBar: + { + const QProgressBar* pb = static_cast<const QProgressBar*>(widget); + + //If we have to display the indicator, and we do it on RHS, give some more room + //for it. This tries to match the logic and the spacing in SR_ProgressBarGroove/Contents + //sizing in QCommonStyle. + if (pb->percentageVisible() && + (pb->indicatorFollowsStyle() || ! pb->centerIndicator())) + { + int addw = pb->fontMetrics().width("100%") + 6; + return QSize(contentsSize.width() + addw, contentsSize.height()); + } + else + return contentsSize; //Otherwise leave unchanged + + break; + } + + default: + ret = QCommonStyle::sizeFromContents(contents, widget, contentsSize, data); + break; + } + + return ret; +} + +int LightStyleV2::styleHint( StyleHint stylehint, + const QWidget *widget, + const QStyleOption &option, + QStyleHintReturn* returnData ) const +{ + int ret; + + switch (stylehint) { + case SH_EtchDisabledText: + case SH_Slider_SnapToValue: + case SH_PrintDialog_RightAlignButtons: + case SH_FontDialog_SelectAssociatedText: + case SH_MenuBar_AltKeyNavigation: + case SH_MenuBar_MouseTracking: + case SH_PopupMenu_MouseTracking: + case SH_ComboBox_ListMouseTracking: + case SH_ScrollBar_MiddleClickAbsolutePosition: + ret = 1; + break; + + case SH_MainWindow_SpaceBelowMenuBar: + ret = 0; + break; + + default: + ret = QCommonStyle::styleHint(stylehint, widget, option, returnData); + break; + } + + return ret; +} + +QPixmap LightStyleV2::stylePixmap( StylePixmap stylepixmap, + const QWidget *widget, + const QStyleOption &data ) const +{ + return singleton->basestyle->stylePixmap( stylepixmap, widget, data ); +} +#include "lightstyle-v2.moc" diff --git a/kstyles/light/lightstyle-v2.h b/kstyles/light/lightstyle-v2.h new file mode 100644 index 000000000..6a7befd0c --- /dev/null +++ b/kstyles/light/lightstyle-v2.h @@ -0,0 +1,85 @@ +/* + Copyright (c) 2000-2001 Trolltech AS ([email protected]) + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef LIGHTSTYLE_V2_H +#define LIGHTSTYLE_V2_H + + +#include <kstyle.h> + + +#ifdef QT_PLUGIN +# define Q_EXPORT_STYLE_LIGHT_V2 +#else +# define Q_EXPORT_STYLE_LIGHT_V2 Q_EXPORT +#endif // QT_PLUGIN + + +class Q_EXPORT_STYLE_LIGHT_V2 LightStyleV2 : public KStyle +{ + Q_OBJECT + +public: + LightStyleV2(); + virtual ~LightStyleV2(); + + void polishPopupMenu( QPopupMenu * ); + + void drawPrimitive(PrimitiveElement, QPainter *, const QRect &, const QColorGroup &, + SFlags = Style_Default, + const QStyleOption & = QStyleOption::Default ) const; + + void drawControl(ControlElement, QPainter *, const QWidget *, const QRect &, + const QColorGroup &, SFlags = Style_Default, + const QStyleOption & = QStyleOption::Default ) const; + void drawControlMask(ControlElement, QPainter *, const QWidget *, const QRect &, + const QStyleOption & = QStyleOption::Default) const; + + QRect subRect(SubRect, const QWidget *) const; + + void drawComplexControl(ComplexControl, QPainter *, const QWidget *, const QRect &, + const QColorGroup &, SFlags = Style_Default, + SCFlags = SC_All, SCFlags = SC_None, + const QStyleOption & = QStyleOption::Default ) const; + + QRect querySubControlMetrics(ComplexControl, const QWidget *, SubControl, + const QStyleOption & = QStyleOption::Default ) const; + + SubControl querySubControl(ComplexControl, const QWidget *, const QPoint &, + const QStyleOption &data = QStyleOption::Default ) const; + + int pixelMetric(PixelMetric, const QWidget * = 0 ) const; + + QSize sizeFromContents(ContentsType, const QWidget *, const QSize &, + const QStyleOption & = QStyleOption::Default ) const; + + int styleHint(StyleHint, const QWidget * = 0, + const QStyleOption & = QStyleOption::Default, + QStyleHintReturn * = 0 ) const; + + QPixmap stylePixmap( StylePixmap stylepixmap, + const QWidget* widget = 0, + const QStyleOption& = QStyleOption::Default ) const; +}; + + +#endif // LIGHTSTYLE_V2_H diff --git a/kstyles/light/lightstyle-v3.cpp b/kstyles/light/lightstyle-v3.cpp new file mode 100644 index 000000000..fc9966b63 --- /dev/null +++ b/kstyles/light/lightstyle-v3.cpp @@ -0,0 +1,1862 @@ +/* + Copyright (c) 2000-2001 Trolltech AS ([email protected]) + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "lightstyle-v3.h" + +#include "qmenubar.h" +#include "qapplication.h" +#include "qcheckbox.h" +#include "qpainter.h" +#include "qpalette.h" +#include "qframe.h" +#include "qpushbutton.h" +#include "qdrawutil.h" +#include "qprogressbar.h" +#include "qscrollbar.h" +#include "qtabbar.h" +#include "qguardedptr.h" +#include "qlayout.h" +#include "qlineedit.h" +#include "qimage.h" +#include "qcombobox.h" +#include "qslider.h" +#include "qstylefactory.h" + + +// The Light Style, 3rd revision + +LightStyleV3::LightStyleV3() + : KStyle(AllowMenuTransparency) +{ + basestyle = QStyleFactory::create( "Windows" ); + if ( ! basestyle ) + basestyle = QStyleFactory::create( QStyleFactory::keys().first() ); + if ( ! basestyle ) + qFatal( "LightStyle: couldn't find a basestyle!" ); +} + +LightStyleV3::~LightStyleV3() +{ + delete basestyle; +} + +void LightStyleV3::polishPopupMenu( QPopupMenu * menu) +{ + KStyle::polishPopupMenu(menu); + // empty to satisy pure virtual requirements +} + +/* + A LightBevel looks like this: + + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + ESSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSE + ESBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE + ESBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBSE + ESSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + + where: + E is the sunken etching ( optional, not drawn by default ) + S is the border (optional, drawn by default ) + B is the bevel (draw with the line width, minus the width of + the etching and border ) + F is the fill ( optional, not drawn by default ) +*/ +static void drawLightEtch( QPainter *p, + const QRect &rect, + const QColor &color, + bool sunken ) +{ + QPointArray pts( 4 ); + + pts.setPoint( 0, rect.left(), rect.bottom() - 1); + pts.setPoint( 1, rect.left(), rect.top() ); + pts.setPoint( 2, rect.left() + 1, rect.top() ); + pts.setPoint( 3, rect.right(), rect.top() ); + p->setPen( sunken ? color.dark( 115 ) : color.light( 115 ) ); + p->drawLineSegments( pts ); + + pts.setPoint( 0, rect.left(), rect.bottom() ); + pts.setPoint( 1, rect.right(), rect.bottom() ); + pts.setPoint( 2, rect.right(), rect.bottom() - 1 ); + pts.setPoint( 3, rect.right(), rect.top() + 1 ); + p->setPen( sunken ? color.light( 115 ) : color.dark( 115 ) ); + p->drawLineSegments( pts ); +} + +static void drawLightBevel( QPainter *p, + const QRect &rect, + const QColorGroup &cg, + QStyle::SFlags flags, + int linewidth, + bool etch = false, // light sunken bevel around border + bool border = true, // rectangle around bevel + const QBrush *fill = 0 ) // contents fill +{ + QRect br = rect; + bool bevel = ( flags & ( QStyle::Style_Down | QStyle::Style_On | + QStyle::Style_Sunken | QStyle::Style_Raised ) ); + bool sunken = (flags & (QStyle::Style_Down | QStyle::Style_On | + QStyle::Style_Sunken)); + + if ( etch && linewidth > 0 ) { + drawLightEtch( p, br, cg.background(), true ); + linewidth--; + br.addCoords( 1, 1, -1, -1 ); + } + + if ( ! br.isValid() ) + return; + if ( border && linewidth > 0 ) { + p->setPen( cg.dark() ); + p->drawRect( br ); + linewidth--; + br.addCoords( 1, 1, -1, -1 ); + } + + if ( ! br.isValid() ) + return; + if ( bevel && linewidth > 0 ) { + // draw a bevel + int x, y, w, h; + br.rect( &x, &y, &w, &h ); + + // copied form qDrawShadePanel - just changed the highlight colors... + QPointArray a( 4*linewidth ); + if ( sunken ) + p->setPen( border ? cg.mid() : cg.dark() ); + else + p->setPen( cg.light() ); + int x1, y1, x2, y2; + int i; + int n = 0; + x1 = x; + y1 = y2 = y; + x2 = x+w-2; + for ( i=0; i<linewidth; i++ ) { // top shadow + a.setPoint( n++, x1, y1++ ); + a.setPoint( n++, x2--, y2++ ); + } + x2 = x1; + y1 = y+h-2; + for ( i=0; i<linewidth; i++ ) { // left shadow + a.setPoint( n++, x1++, y1 ); + a.setPoint( n++, x2++, y2-- ); + } + p->drawLineSegments( a ); + n = 0; + if ( sunken ) + p->setPen( cg.light() ); + else + p->setPen( border ? cg.mid() : cg.dark() ); + x1 = x; + y1 = y2 = y+h-1; + x2 = x+w-1; + for ( i=0; i<linewidth; i++ ) { // bottom shadow + a.setPoint( n++, x1++, y1-- ); + a.setPoint( n++, x2, y2-- ); + } + x1 = x2; + y1 = y; + y2 = y+h-linewidth-1; + for ( i=0; i<linewidth; i++ ) { // right shadow + a.setPoint( n++, x1--, y1++ ); + a.setPoint( n++, x2--, y2 ); + } + p->drawLineSegments( a ); + + br.addCoords( linewidth, linewidth, -linewidth, -linewidth ); + } + + // fill + if ( fill ) + p->fillRect( br, *fill ); +} + +void LightStyleV3::drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption &data ) const +{ + QRect br = r; + const QBrush *fill = 0; + + switch (pe) { + case PE_HeaderSection: + // don't draw any headers sunken + flags = ((flags | Style_Sunken) ^ Style_Sunken) | Style_Raised; + + p->setPen( cg.background() ); + // hard border at the bottom/right of the header + if ( flags & Style_Horizontal ) { + p->drawLine( br.bottomLeft(), br.bottomRight() ); + br.addCoords( 0, 0, 0, -1 ); + } else { + p->drawLine( br.topRight(), br.bottomRight() ); + br.addCoords( 0, 0, -1, 0 ); + } + + // draw the header ( just an etching ) + if ( ! br.isValid() ) + break; + drawLightEtch( p, br, ( ( flags & Style_Down ) ? + cg.midlight() : cg.button() ), + ( flags & Style_Down ) ); + br.addCoords( 1, 1, -1, -1 ); + + // fill the header + if ( ! br.isValid() ) + break; + p->fillRect( br, cg.brush( ( flags & Style_Down ) ? + QColorGroup::Midlight : QColorGroup::Button ) ); + + // the taskbuttons in kicker seem to allow the style to set the pencolor + // here, which will be used to draw the text for focused window buttons... + // how utterly silly + p->setPen( cg.buttonText() ); + break; + + case PE_ButtonCommand: + { + QRect br = r; + + if (flags & QStyle::Style_Enabled) { + if (flags & (QStyle::Style_Down | + QStyle::Style_On | + QStyle::Style_Sunken)) + fill = &cg.brush(QColorGroup::Midlight); + else + fill = &cg.brush(QColorGroup::Button); + } else + fill = &cg.brush(QColorGroup::Background); + + bool etch = true; + if ( flags & Style_ButtonDefault ) { + etch = false; + br.addCoords( 1, 1, -1, -1 ); + } + drawLightBevel( p, br, cg, flags, + pixelMetric( PM_DefaultFrameWidth ) + ( etch ? 1 : 0 ), + etch, true, fill ); + break; + } + + case PE_ButtonBevel: + case PE_ButtonTool: + if (flags & QStyle::Style_Enabled) { + if (flags & (QStyle::Style_Down | + QStyle::Style_On | + QStyle::Style_Sunken)) + fill = &cg.brush(QColorGroup::Midlight); + else + fill = &cg.brush(QColorGroup::Button); + } else + fill = &cg.brush(QColorGroup::Background); + drawLightBevel( p, r, cg, flags, pixelMetric( PM_DefaultFrameWidth ), + false, true, fill ); + break; + + case PE_ButtonDropDown: + { + QBrush thefill; + bool sunken = + (flags & (QStyle::Style_Down | QStyle::Style_On | QStyle::Style_Sunken)); + + if (flags & QStyle::Style_Enabled) { + if (sunken) + thefill = cg.brush(QColorGroup::Midlight); + else + thefill = cg.brush(QColorGroup::Button); + } else + thefill = cg.brush(QColorGroup::Background); + + p->setPen( cg.dark() ); + p->drawLine(r.topLeft(), r.topRight()); + p->drawLine(r.topRight(), r.bottomRight()); + p->drawLine(r.bottomRight(), r.bottomLeft()); + + if (flags & (QStyle::Style_Down | QStyle::Style_On | + QStyle::Style_Sunken | QStyle::Style_Raised)) { + // button bevel + if (sunken) + p->setPen(cg.mid()); + else + p->setPen(cg.light()); + + p->drawLine(r.x(), r.y() + 2, + r.x(), r.y() + r.height() - 3); // left + p->drawLine(r.x(), r.y() + 1, + r.x() + r.width() - 2, r.y() + 1); // top + + if (sunken) + p->setPen(cg.light()); + else + p->setPen(cg.mid()); + + p->drawLine(r.x() + r.width() - 2, r.y() + 2, + r.x() + r.width() - 2, r.y() + r.height() - 3); // right + p->drawLine(r.x() + 1, r.y() + r.height() - 2, + r.x() + r.width() - 2, r.y() + r.height() - 2); // bottom + } + + p->fillRect(r.x() + 1, r.y() + 2, r.width() - 3, r.height() - 4, thefill); + break; + } + + case PE_ButtonDefault: + p->setPen( cg.shadow() ); + p->drawRect( r ); + break; + + case PE_Indicator: + const QBrush *fill; + if (! (flags & Style_Enabled)) + fill = &cg.brush(QColorGroup::Background); + else if (flags & Style_Down) + fill = &cg.brush(QColorGroup::Mid); + else + fill = &cg.brush(QColorGroup::Base); + drawLightBevel( p, r, cg, flags | Style_Sunken, 2, true, true, fill ); + + p->setPen(cg.text()); + if (flags & Style_NoChange) { + p->drawLine(r.x() + 3, r.y() + r.height() / 2, + r.x() + r.width() - 4, r.y() + r.height() / 2); + p->drawLine(r.x() + 3, r.y() + 1 + r.height() / 2, + r.x() + r.width() - 4, r.y() + 1 + r.height() / 2); + p->drawLine(r.x() + 3, r.y() - 1 + r.height() / 2, + r.x() + r.width() - 4, r.y() - 1 + r.height() / 2); + } else if (flags & Style_On) { + p->drawLine(r.x() + 4, r.y() + 3, + r.x() + r.width() - 4, r.y() + r.height() - 5); + p->drawLine(r.x() + 3, r.y() + 3, + r.x() + r.width() - 4, r.y() + r.height() - 4); + p->drawLine(r.x() + 3, r.y() + 4, + r.x() + r.width() - 5, r.y() + r.height() - 4); + p->drawLine(r.x() + 3, r.y() + r.height() - 5, + r.x() + r.width() - 5, r.y() + 3); + p->drawLine(r.x() + 3, r.y() + r.height() - 4, + r.x() + r.width() - 4, r.y() + 3); + p->drawLine(r.x() + 4, r.y() + r.height() - 4, + r.x() + r.width() - 4, r.y() + 4); + } + + break; + + case PE_ExclusiveIndicator: + { + QRect br = r, // bevel rect + lr = r, // outline rect + cr = r, // contents rect + ir = r; // indicator rect + lr.addCoords( 1, 1, -1, -1 ); + cr.addCoords( 2, 2, -2, -2 ); + ir.addCoords( 3, 3, -3, -3 ); + + p->fillRect( r, cg.brush( QColorGroup::Background ) ); + + p->setPen( flags & Style_Down ? cg.mid() : + ( flags & Style_Enabled ? cg.base() : cg.background() ) ); + p->setBrush( flags & Style_Down ? cg.mid() : + ( flags & Style_Enabled ? cg.base() : cg.background() ) ); + p->drawEllipse( lr ); + + p->setPen( cg.background().dark( 115 ) ); + p->drawArc( br, 45*16, 180*16 ); + p->setPen( cg.background().light( 115 ) ); + p->drawArc( br, 235*16, 180*16 ); + + p->setPen( cg.dark() ); + p->drawArc( lr, 0, 16*360 ); + + if ( flags & Style_On ) { + p->setPen( flags & Style_Down ? cg.mid() : + ( flags & Style_Enabled ? cg.base() : cg.background() ) ); + p->setBrush( cg.text() ); + p->drawEllipse( ir ); + } + + break; + } + + case PE_DockWindowHandle: + { + QString title; + bool drawTitle = false; + if ( p && p->device()->devType() == QInternal::Widget ) { + QWidget *w = (QWidget *) p->device(); + QWidget *p = w->parentWidget(); + if (p->inherits("QDockWindow") && ! p->inherits("QToolBar")) { + drawTitle = true; + title = p->caption(); + } + } + + flags |= Style_Raised; + if (flags & Style_Horizontal) { + if (drawTitle) { + QPixmap pm(r.height(), r.width()); + QPainter p2(&pm); + p2.fillRect(0, 0, pm.width(), pm.height(), + cg.brush(QColorGroup::Highlight)); + p2.setPen(cg.highlightedText()); + p2.drawText(0, 0, pm.width(), pm.height(), AlignCenter, title); + p2.end(); + + QWMatrix m; + m.rotate(270.0); + pm = pm.xForm(m); + p->drawPixmap(r.x(), r.y(), pm); + } else { + for ( int i = r.left() - 1; i < r.right(); i += 3 ) { + p->setPen( cg.midlight() ); + p->drawLine( i, r.top(), i, r.bottom() ); + p->setPen( cg.background() ); + p->drawLine( i + 1, r.top(), i + 1, r.bottom() ); + p->setPen( cg.mid() ); + p->drawLine( i + 2, r.top(), i + 2, r.bottom() ); + } + } + } else { + if (drawTitle) { + p->fillRect(r, cg.brush(QColorGroup::Highlight)); + p->setPen(cg.highlightedText()); + p->drawText(r, AlignCenter, title); + } else { + for ( int i = r.top() - 1; i < r.bottom(); i += 3 ) { + p->setPen( cg.midlight() ); + p->drawLine( r.left(), i, r.right(), i ); + p->setPen( cg.background() ); + p->drawLine( r.left(), i + 1, r.right(), i + 1); + p->setPen( cg.mid() ); + p->drawLine( r.left(), i + 2, r.right(), i + 2 ); + } + + } + } + break; + } + + case PE_DockWindowSeparator: + { + if (flags & Style_Horizontal) { + int hw = r.width() / 2; + p->setPen( cg.mid() ); + p->drawLine( hw, r.top() + 6, hw, r.bottom() - 6 ); + p->setPen( cg.light() ); + p->drawLine( hw + 1, r.top() + 6, hw + 1, r.bottom() - 6 ); + } else { + int hh = r.height() / 2; + p->setPen( cg.mid() ); + p->drawLine( r.left() + 6, hh, r.right() - 6, hh ); + p->setPen( cg.light() ); + p->drawLine( r.left() + 6, hh + 1, r.right() - 6, hh + 1 ); + } + break; + } + + case PE_Splitter: + if (flags & Style_Horizontal) + flags &= ~Style_Horizontal; + else + flags |= Style_Horizontal; + // fall through intended + + case PE_DockWindowResizeHandle: + { + QRect br = r; + + p->setPen( cg.shadow() ); + p->drawRect( br ); + + br.addCoords( 1, 1, -1, -1 ); + + if ( ! br.isValid() ) + break; + p->setPen( cg.light() ); + p->drawLine( br.left(), br.top(), br.right() - 1, br.top() ); + p->drawLine( br.left(), br.top() + 1, br.left(), br.bottom() ); + p->setPen( cg.mid() ); + p->drawLine( br.bottomLeft(), br.bottomRight() ); + p->drawLine( br.right(), br.top(), br.right(), br.bottom() - 1 ); + + br.addCoords( 1, 1, -1, -1 ); + + if ( ! br.isValid() ) + break; + p->fillRect( br, cg.brush( QColorGroup::Button ) ); + break; + } + + case PE_PanelPopup: + drawLightBevel( p, r, cg, flags, + ( data.isDefault() ? pixelMetric(PM_DefaultFrameWidth) : + data.lineWidth() ), false, true ); + break; + + case PE_Panel: + case PE_PanelLineEdit: + case PE_PanelTabWidget: + case PE_WindowFrame: + { + QRect br = r; + + int cover = 0; + int reallw = ( data.isDefault() ? + pixelMetric( PM_DefaultFrameWidth ) : data.lineWidth() ); + cover = reallw - 1; + + if ( ! ( flags & Style_Sunken ) ) + flags |= Style_Raised; + drawLightBevel( p, br, cg, flags, 1, false, false ); + br.addCoords( 1, 1, -1, -1 ); + + while ( cover-- > 0 ) { + QPointArray pts( 8 ); + pts.setPoint( 0, br.left(), br.bottom() - 1); + pts.setPoint( 1, br.left(), br.top() ); + pts.setPoint( 2, br.left() + 1, br.top() ); + pts.setPoint( 3, br.right(), br.top() ); + pts.setPoint( 4, br.left(), br.bottom() ); + pts.setPoint( 5, br.right(), br.bottom() ); + pts.setPoint( 6, br.right(), br.bottom() - 1 ); + pts.setPoint( 7, br.right(), br.top() + 1 ); + p->setPen( cg.background() ); + p->drawLineSegments( pts ); + + br.addCoords( 1, 1, -1, -1 ); + } + break; + } + + case PE_PanelDockWindow: + drawLightBevel( p, r, cg, flags, ( data.isDefault() ? + pixelMetric(PM_DefaultFrameWidth) : + data.lineWidth() ), false, false, + &cg.brush( QColorGroup::Button ) ); + break; + + case PE_PanelMenuBar: + drawLightBevel( p, r, cg, flags, ( data.isDefault() ? + pixelMetric(PM_MenuBarFrameWidth) : + data.lineWidth() ), false, false, + &cg.brush( QColorGroup::Button ) ); + break; + + case PE_ScrollBarSubLine: + { + QRect br = r; + PrimitiveElement pe; + + p->setPen( cg.background() ); + if (flags & Style_Horizontal) { + pe = PE_ArrowLeft; + p->drawLine( br.topLeft(), br.topRight() ); + br.addCoords( 0, 1, 0, 0 ); + } else { + pe = PE_ArrowUp; + p->drawLine( br.topLeft(), br.bottomLeft() ); + br.addCoords( 1, 0, 0, 0 ); + } + + if ( ! br.isValid() ) + break; + drawLightEtch( p, br, cg.button(), false ); + br.addCoords( 1, 1, -1, -1 ); + + if ( ! br.isValid() ) + break; + p->fillRect( br, cg.brush( ( flags & Style_Down ) ? + QColorGroup::Midlight : + QColorGroup::Button ) ); + br.addCoords( 2, 2, -2, -2 ); + + if ( ! br.isValid() ) + break; + drawPrimitive( pe, p, br, cg, flags ); + break; + } + + case PE_ScrollBarAddLine: + { + QRect br = r; + PrimitiveElement pe; + + p->setPen( cg.background() ); + if (flags & Style_Horizontal) { + pe = PE_ArrowRight; + p->drawLine( br.topLeft(), br.topRight() ); + br.addCoords( 0, 1, 0, 0 ); + } else { + pe = PE_ArrowDown; + p->drawLine( br.topLeft(), br.bottomLeft() ); + br.addCoords( 1, 0, 0, 0 ); + } + + if ( ! br.isValid() ) + break; + drawLightEtch( p, br, cg.button(), false ); + br.addCoords( 1, 1, -1, -1 ); + + if ( ! br.isValid() ) + break; + p->fillRect( br, cg.brush( ( flags & Style_Down ) ? + QColorGroup::Midlight : + QColorGroup::Button ) ); + br.addCoords( 2, 2, -2, -2 ); + + if ( ! br.isValid() ) + break; + drawPrimitive( pe, p, br, cg, flags ); + break; + } + + case PE_ScrollBarSubPage: + { + QRect br = r; + + p->setPen( cg.background() ); + if (flags & Style_Horizontal) { + p->drawLine( br.topLeft(), br.topRight() ); + br.addCoords( 0, 1, 0, 0 ); + } else { + p->drawLine( br.topLeft(), br.bottomLeft() ); + br.addCoords( 1, 0, 0, 0 ); + } + + if ( ! br.isValid() ) + break; + drawLightEtch( p, br, cg.button(), false ); + br.addCoords( 1, 1, -1, -1 ); + + if ( ! br.isValid() ) + break; + p->fillRect( br, cg.brush( ( flags & Style_Down ) ? + QColorGroup::Midlight : + QColorGroup::Button ) ); + break; + } + + case PE_ScrollBarAddPage: + { + QRect br = r; + + p->setPen( cg.background() ); + if (flags & Style_Horizontal) { + p->drawLine( br.topLeft(), br.topRight() ); + br.addCoords( 0, 1, 0, 0 ); + } else { + p->drawLine( br.topLeft(), br.bottomLeft() ); + br.addCoords( 1, 0, 0, 0 ); + } + + if ( ! br.isValid() ) + break; + drawLightEtch( p, br, cg.button(), false ); + br.addCoords( 1, 1, -1, -1 ); + + if ( ! br.isValid() ) + break; + p->fillRect( br, cg.brush( ( flags & Style_Down ) ? + QColorGroup::Midlight : + QColorGroup::Button ) ); + break; + } + + case PE_ScrollBarSlider: + { + QRect br = r; + + p->setPen( cg.background() ); + if (flags & Style_Horizontal) { + p->drawLine( br.topLeft(), br.topRight() ); + br.addCoords( 0, 1, 0, 0 ); + } else { + p->drawLine( br.topLeft(), br.bottomLeft() ); + br.addCoords( 1, 0, 0, 0 ); + } + + if ( ! br.isValid() ) + break; + p->setPen( cg.highlight().light() ); + p->drawLine( br.topLeft(), br.topRight() ); + p->drawLine( br.left(), br.top() + 1, br.left(), br.bottom() - 1 ); + + p->setPen( cg.highlight().dark() ); + p->drawLine( br.left(), br.bottom(), br.right() - 1, br.bottom() ); + p->drawLine( br.topRight(), br.bottomRight() ); + br.addCoords( 1, 1, -1, -1 ); + + p->fillRect( br, cg.brush( QColorGroup::Highlight ) ); + break; + } + + case PE_FocusRect: + p->setBrush( NoBrush ); + if ( flags & Style_FocusAtBorder ) + p->setPen( cg.shadow() ); + else + p->setPen( cg.dark() ); + p->drawRect( r ); + break; + + case PE_ProgressBarChunk: + p->fillRect(r.x(), r.y() + 2, r.width(), r.height() - 4, cg.highlight()); + break; + + default: + if (pe == PE_HeaderArrow) { + if (flags & Style_Down) + pe = PE_ArrowDown; + else + pe = PE_ArrowUp; + } + + if (pe >= PE_ArrowUp && pe <= PE_ArrowLeft) { + QPointArray a; + + switch ( pe ) { + case PE_ArrowUp: + a.setPoints( 7, -4,1, 2,1, -3,0, 1,0, -2,-1, 0,-1, -1,-2 ); + break; + + case PE_ArrowDown: + a.setPoints( 7, -4,-2, 2,-2, -3,-1, 1,-1, -2,0, 0,0, -1,1 ); + break; + + case PE_ArrowRight: + a.setPoints( 7, -2,-3, -2,3, -1,-2, -1,2, 0,-1, 0,1, 1,0 ); + break; + + case PE_ArrowLeft: + a.setPoints( 7, 0,-3, 0,3, -1,-2, -1,2, -2,-1, -2,1, -3,0 ); + break; + + default: + break; + } + + if (a.isNull()) + return; + + p->save(); + if ( flags & Style_Enabled ) { + a.translate( r.x() + r.width() / 2, r.y() + r.height() / 2 ); + p->setPen( cg.buttonText() ); + p->drawLineSegments( a, 0, 3 ); // draw arrow + p->drawPoint( a[6] ); + } else { + a.translate( r.x() + r.width() / 2 + 1, r.y() + r.height() / 2 + 1 ); + p->setPen( cg.light() ); + p->drawLineSegments( a, 0, 3 ); // draw arrow + p->drawPoint( a[6] ); + a.translate( -1, -1 ); + p->setPen( cg.mid() ); + p->drawLineSegments( a, 0, 3 ); // draw arrow + p->drawPoint( a[6] ); + } + p->restore(); + } else + QCommonStyle::drawPrimitive(pe, p, r, cg, flags, data); + break; + } +} + +void LightStyleV3::drawControl( ControlElement control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption &data ) const +{ + switch (control) { + case CE_TabBarTab: + { + const QTabBar *tb = (const QTabBar *) widget; + QRect br = r; + + if ( tb->shape() == QTabBar::RoundedAbove ) { + if ( ! ( flags & Style_Selected ) ) { + p->setPen( cg.background() ); + p->drawLine( br.left(), br.bottom(), + br.right(), br.bottom() ); + p->setPen( cg.light() ); + p->drawLine( br.left(), br.bottom() - 1, + br.right(), br.bottom() - 1); + br.addCoords( 0, 2, -1, -2 ); + if ( br.left() == 0 ) + p->drawPoint( br.left(), br.bottom() + 2 ); + } else { + p->setPen( cg.background() ); + p->drawLine( br.bottomLeft(), br.bottomRight() ); + if ( br.left() == 0 ) { + p->setPen( cg.light() ); + p->drawPoint( br.bottomLeft() ); + } + br.addCoords( 0, 0, 0, -1 ); + } + + p->setPen( cg.light() ); + p->drawLine( br.bottomLeft(), br.topLeft() ); + p->drawLine( br.topLeft(), br.topRight() ); + p->setPen( cg.dark() ); + p->drawLine( br.right(), br.top() + 1, br.right(), br.bottom() ); + + if ( flags & Style_Selected ) + { + p->fillRect( br.right() - 3, br.top() + 1, 3, br.height() - 1, cg.brush(QColorGroup::Highlight)); + br.addCoords( 1, 1, -4, 0 ); + } + else + br.addCoords( 1, 1, -1, 0 ); + p->fillRect( br, cg.background() ); + } else if ( tb->shape() == QTabBar::RoundedBelow ) { + if ( ! ( flags & Style_Selected ) ) { + p->setPen( cg.background() ); + p->drawLine( br.left(), br.top(), + br.right(), br.top() ); + p->setPen( cg.dark() ); + p->drawLine( br.left(), br.top() + 1, + br.right(), br.top() + 1); + br.addCoords( 0, 2, -1, -2 ); + if ( br.left() == 0 ) { + p->setPen( cg.light() ); + p->drawPoint( br.left(), br.top() - 2 ); + } + } else { + p->setPen( cg.background() ); + p->drawLine( br.topLeft(), br.topRight() ); + if ( br.left() == 0 ) { + p->setPen( cg.light() ); + p->drawPoint( br.topLeft() ); + } + br.addCoords( 0, 1, 0, 0 ); + } + + p->setPen( cg.light() ); + p->drawLine( br.topLeft(), br.bottomLeft() ); + p->setPen( cg.dark() ); + p->drawLine( br.bottomLeft(), br.bottomRight() ); + p->drawLine( br.right(), br.top(), br.right(), br.bottom() - 1 ); + br.addCoords( 1, 0, -1, -1 ); + + if ( flags & Style_Selected ) + { + p->fillRect( br.right() - 2, br.top(), 3, br.height(), cg.brush(QColorGroup::Highlight)); + br.addCoords( 1, 0, -3, -1 ); + } + else + br.addCoords( 1, 0, -1, -1 ); + + p->fillRect( br, cg.background() ); + } else + QCommonStyle::drawControl( control, p, widget, r, cg, flags, data ); + break; + } + + case CE_PopupMenuItem: + { + if (! widget || data.isDefault()) + break; + + const QPopupMenu *popupmenu = (const QPopupMenu *) widget; + QMenuItem *mi = data.menuItem(); + int tab = data.tabWidth(); + int maxpmw = data.maxIconWidth(); + + if ( mi && mi->isSeparator() ) { + if ( widget->erasePixmap() && !widget->erasePixmap()->isNull() ) + p->drawPixmap( r.topLeft(), *widget->erasePixmap(), r ); + else + p->fillRect(r, cg.brush(QColorGroup::Button)); + p->setPen( cg.mid() ); + p->drawLine(r.left() + 12, r.top() + 1, + r.right() - 12, r.top() + 1); + p->setPen( cg.light() ); + p->drawLine(r.left() + 12, r.top() + 2, + r.right() - 12, r.top() + 2); + break; + } + + if (flags & Style_Active) + qDrawShadePanel(p, r, cg, true, 1, + &cg.brush(QColorGroup::Midlight)); + else if ( widget->erasePixmap() && !widget->erasePixmap()->isNull() ) + p->drawPixmap( r.topLeft(), *widget->erasePixmap(), r ); + else + p->fillRect(r, cg.brush(QColorGroup::Button)); + + if ( !mi ) + break; + + maxpmw = QMAX(maxpmw, 16); + + QRect cr, ir, tr, sr; + // check column + cr.setRect(r.left(), r.top(), maxpmw, r.height()); + // submenu indicator column + sr.setCoords(r.right() - maxpmw, r.top(), r.right(), r.bottom()); + // tab/accelerator column + tr.setCoords(sr.left() - tab - 4, r.top(), sr.left(), r.bottom()); + // item column + ir.setCoords(cr.right() + 4, r.top(), tr.right() - 4, r.bottom()); + + bool reverse = QApplication::reverseLayout(); + if ( reverse ) { + cr = visualRect( cr, r ); + sr = visualRect( sr, r ); + tr = visualRect( tr, r ); + ir = visualRect( ir, r ); + } + + if (mi->isChecked() && + ! (flags & Style_Active) & + (flags & Style_Enabled)) + qDrawShadePanel(p, cr, cg, true, 1, &cg.brush(QColorGroup::Midlight)); + + if (mi->iconSet()) { + QIconSet::Mode mode = + (flags & Style_Enabled) ? QIconSet::Normal : QIconSet::Disabled; + if ((flags & Style_Active) && (flags & Style_Enabled)) + mode = QIconSet::Active; + QPixmap pixmap; + if (popupmenu->isCheckable() && mi->isChecked()) + pixmap = + mi->iconSet()->pixmap( QIconSet::Small, mode, QIconSet::On ); + else + pixmap = + mi->iconSet()->pixmap( QIconSet::Small, mode ); + QRect pmr(QPoint(0, 0), pixmap.size()); + pmr.moveCenter(cr.center()); + p->setPen(cg.text()); + p->drawPixmap(pmr.topLeft(), pixmap); + } else if (popupmenu->isCheckable() && mi->isChecked()) + drawPrimitive(PE_CheckMark, p, cr, cg, + (flags & Style_Enabled) | Style_On); + + QColor textcolor; + QColor embosscolor; + if (flags & Style_Active) { + if (! (flags & Style_Enabled)) + textcolor = cg.midlight().dark(); + else + textcolor = cg.buttonText(); + embosscolor = cg.midlight().light(); + } else if (! (flags & Style_Enabled)) { + textcolor = cg.text(); + embosscolor = cg.light(); + } else + textcolor = embosscolor = cg.buttonText(); + p->setPen(textcolor); + + if (mi->custom()) { + p->save(); + if (! (flags & Style_Enabled)) { + p->setPen(cg.light()); + mi->custom()->paint(p, cg, flags & Style_Active, + flags & Style_Enabled, + ir.x() + 1, ir.y() + 1, + ir.width() - 1, ir.height() - 1); + p->setPen(textcolor); + } + mi->custom()->paint(p, cg, flags & Style_Active, + flags & Style_Enabled, + ir.x(), ir.y(), + ir.width(), ir.height()); + p->restore(); + } + + QString text = mi->text(); + if (! text.isNull()) { + int t = text.find('\t'); + + // draw accelerator/tab-text + if (t >= 0) { + int alignFlag = AlignVCenter | ShowPrefix | DontClip | SingleLine; + alignFlag |= ( reverse ? AlignLeft : AlignRight ); + if (! (flags & Style_Enabled)) { + p->setPen(embosscolor); + tr.moveBy(1, 1); + p->drawText(tr, alignFlag, text.mid(t + 1)); + tr.moveBy(-1, -1); + p->setPen(textcolor); + } + + p->drawText(tr, alignFlag, text.mid(t + 1)); + } + + int alignFlag = AlignVCenter | ShowPrefix | DontClip | SingleLine; + alignFlag |= ( reverse ? AlignRight : AlignLeft ); + + if (! (flags & Style_Enabled)) { + p->setPen(embosscolor); + ir.moveBy(1, 1); + p->drawText(ir, alignFlag, text, t); + ir.moveBy(-1, -1); + p->setPen(textcolor); + } + + p->drawText(ir, alignFlag, text, t); + } else if (mi->pixmap()) { + QPixmap pixmap = *mi->pixmap(); + if (pixmap.depth() == 1) + p->setBackgroundMode(OpaqueMode); + p->drawPixmap(ir.x(), ir.y() + (ir.height() - pixmap.height()) / 2, pixmap); + if (pixmap.depth() == 1) + p->setBackgroundMode(TransparentMode); + } + + if (mi->popup()) + drawPrimitive( (QApplication::reverseLayout() ? PE_ArrowLeft : PE_ArrowRight), + p, sr, cg, flags); + break; + } + + case CE_MenuBarEmptyArea: + { + p->fillRect(r, cg.brush(QColorGroup::Button)); + break; + } + + case CE_MenuBarItem: + { + if ( flags & Style_Active ) + qDrawShadePanel(p, r, cg, true, 1, &cg.brush(QColorGroup::Midlight)); + else + p->fillRect( r, cg.brush( QColorGroup::Button ) ); + + if (data.isDefault()) + break; + + QMenuItem *mi = data.menuItem(); + drawItem(p, r, AlignCenter | ShowPrefix | DontClip | SingleLine, cg, + flags & Style_Enabled, mi->pixmap(), mi->text(), -1, + &cg.buttonText()); + break; + } + + case CE_ProgressBarGroove: + drawLightBevel( p, r, cg, Style_Sunken, pixelMetric( PM_DefaultFrameWidth ), + true, true, &cg.brush( QColorGroup::Background ) ); + break; + + default: + QCommonStyle::drawControl(control, p, widget, r, cg, flags, data); + break; + } +} + +void LightStyleV3::drawControlMask( ControlElement control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption &data ) const +{ + switch (control) { + case CE_PushButton: + p->fillRect(r, color1); + break; + + default: + QCommonStyle::drawControlMask(control, p, widget, r, data); + break; + } +} + +QRect LightStyleV3::subRect(SubRect subrect, const QWidget *widget) const +{ + QRect rect; + + switch (subrect) { + case SR_PushButtonFocusRect: + { + rect = QCommonStyle::subRect( SR_PushButtonContents, widget ); + int bm = pixelMetric( PM_ButtonMargin, widget ), hbm = bm / 2; + rect.addCoords( hbm, hbm, -hbm, -hbm ); + break; + } + + case SR_ComboBoxFocusRect: + { + rect = QCommonStyle::subRect( SR_ComboBoxFocusRect, widget ); + rect.addCoords( -1, -1, 1, 1 ); + break; + } + + case SR_CheckBoxFocusRect: + { + const QCheckBox* cb = static_cast<const QCheckBox*>(widget); + + //Only checkbox, no label + if (cb->text().isEmpty() && (cb->pixmap() == 0) ) + { + QRect bounding = cb->rect(); + QRect checkbox(bounding.x(), bounding.y() + (bounding.height() - 13)/2, + 13, 13); + + return checkbox; + } + //Fallthrough intentional + } + + + default: + rect = QCommonStyle::subRect(subrect, widget); + break; + } + + return rect; +} + +void LightStyleV3::drawComplexControl( ComplexControl control, + QPainter* p, + const QWidget* widget, + const QRect& r, + const QColorGroup& cg, + SFlags flags, + SCFlags controls, + SCFlags active, + const QStyleOption &data ) const +{ + switch (control) { + case CC_ComboBox: + { + const QComboBox *combobox = (const QComboBox *) widget; + QRect frame, arrow, field; + frame = + QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget, + SC_ComboBoxFrame, data), + widget); + arrow = + QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget, + SC_ComboBoxArrow, data), + widget); + field = + QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget, + SC_ComboBoxEditField, data), + widget); + + if ((controls & SC_ComboBoxFrame) && frame.isValid()) + drawPrimitive( PE_Panel, p, frame, cg, flags | Style_Sunken ); + + if ((controls & SC_ComboBoxArrow) && arrow.isValid()) { + drawLightEtch( p, arrow, cg.button(), ( active == SC_ComboBoxArrow ) ); + arrow.addCoords( 1, 1, -1, -1 ); + p->fillRect( arrow, cg.brush( QColorGroup::Button ) ); + arrow.addCoords(3, 1, -1, -1); + drawPrimitive(PE_ArrowDown, p, arrow, cg, flags); + } + + if ((controls & SC_ComboBoxEditField) && field.isValid()) { + if (flags & Style_HasFocus) { + if (! combobox->editable()) { + QRect fr = + QStyle::visualRect( subRect( SR_ComboBoxFocusRect, widget ), + widget ); + p->fillRect( fr, cg.brush( QColorGroup::Highlight ) ); + drawPrimitive( PE_FocusRect, p, fr, cg, + flags | Style_FocusAtBorder, + QStyleOption(cg.highlight())); + } + + p->setPen(cg.highlightedText()); + } else { + p->fillRect( field, ( ( flags & Style_Enabled ) ? + cg.brush( QColorGroup::Base ) : + cg.brush( QColorGroup::Background ) ) ); + p->setPen( cg.text() ); + } + } + + break; + } + + case CC_SpinWidget: + { + const QSpinWidget *spinwidget = (const QSpinWidget *) widget; + QRect frame, up, down; + + frame = querySubControlMetrics(CC_SpinWidget, widget, + SC_SpinWidgetFrame, data); + up = spinwidget->upRect(); + down = spinwidget->downRect(); + + if ((controls & SC_SpinWidgetFrame) && frame.isValid()) + drawPrimitive( PE_Panel, p, frame, cg, flags | Style_Sunken ); + + if ((controls & SC_SpinWidgetUp) && up.isValid()) { + PrimitiveElement pe = PE_SpinWidgetUp; + if ( spinwidget->buttonSymbols() == QSpinWidget::PlusMinus ) + pe = PE_SpinWidgetPlus; + + p->setPen( cg.background() ); + p->drawLine( up.topLeft(), up.bottomLeft() ); + + up.addCoords( 1, 0, 0, 0 ); + p->fillRect( up, cg.brush( QColorGroup::Button ) ); + drawLightEtch( p, up, cg.button(), ( active == SC_SpinWidgetUp ) ); + + up.addCoords( 1, 0, 0, 0 ); + drawPrimitive(pe, p, up, cg, flags | + ((active == SC_SpinWidgetUp) ? + Style_On | Style_Sunken : Style_Raised)); + } + + if ((controls & SC_SpinWidgetDown) && down.isValid()) { + PrimitiveElement pe = PE_SpinWidgetDown; + if ( spinwidget->buttonSymbols() == QSpinWidget::PlusMinus ) + pe = PE_SpinWidgetMinus; + + p->setPen( cg.background() ); + p->drawLine( down.topLeft(), down.bottomLeft() ); + + down.addCoords( 1, 0, 0, 0 ); + p->fillRect( down, cg.brush( QColorGroup::Button ) ); + drawLightEtch( p, down, cg.button(), ( active == SC_SpinWidgetDown ) ); + + down.addCoords( 1, 0, 0, 0 ); + drawPrimitive(pe, p, down, cg, flags | + ((active == SC_SpinWidgetDown) ? + Style_On | Style_Sunken : Style_Raised)); + } + + break; + } + + case CC_ScrollBar: + { + const QScrollBar *scrollbar = (const QScrollBar *) widget; + QRect addline, subline, subline2, addpage, subpage, slider, first, last; + bool maxedOut = (scrollbar->minValue() == scrollbar->maxValue()); + + subline = querySubControlMetrics(control, widget, SC_ScrollBarSubLine, data); + addline = querySubControlMetrics(control, widget, SC_ScrollBarAddLine, data); + subpage = querySubControlMetrics(control, widget, SC_ScrollBarSubPage, data); + addpage = querySubControlMetrics(control, widget, SC_ScrollBarAddPage, data); + slider = querySubControlMetrics(control, widget, SC_ScrollBarSlider, data); + first = querySubControlMetrics(control, widget, SC_ScrollBarFirst, data); + last = querySubControlMetrics(control, widget, SC_ScrollBarLast, data); + + subline2 = addline; + if (scrollbar->orientation() == Qt::Horizontal) + subline2.moveBy(-addline.width(), 0); + else + subline2.moveBy(0, -addline.height()); + + if ((controls & SC_ScrollBarSubLine) && subline.isValid()) { + drawPrimitive(PE_ScrollBarSubLine, p, subline, cg, + Style_Enabled | ((active == SC_ScrollBarSubLine) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + + if (subline2.isValid()) + drawPrimitive(PE_ScrollBarSubLine, p, subline2, cg, + Style_Enabled | ((active == SC_ScrollBarSubLine) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + } + if ((controls & SC_ScrollBarAddLine) && addline.isValid()) + drawPrimitive(PE_ScrollBarAddLine, p, addline, cg, + Style_Enabled | ((active == SC_ScrollBarAddLine) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarSubPage) && subpage.isValid()) + drawPrimitive(PE_ScrollBarSubPage, p, subpage, cg, + Style_Enabled | ((active == SC_ScrollBarSubPage) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarAddPage) && addpage.isValid()) + drawPrimitive(PE_ScrollBarAddPage, p, addpage, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarAddPage) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarFirst) && first.isValid()) + drawPrimitive(PE_ScrollBarFirst, p, first, cg, + Style_Enabled | ((active == SC_ScrollBarFirst) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarLast) && last.isValid()) + drawPrimitive(PE_ScrollBarLast, p, last, cg, + Style_Enabled | ((active == SC_ScrollBarLast) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarSlider) && slider.isValid()) { + drawPrimitive(PE_ScrollBarSlider, p, slider, cg, + Style_Enabled | ((active == SC_ScrollBarSlider) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + + // ### perhaps this should not be able to accept focus if maxedOut? + if (scrollbar->hasFocus()) { + QRect fr(slider.x() + 2, slider.y() + 2, + slider.width() - 5, slider.height() - 5); + drawPrimitive(PE_FocusRect, p, fr, cg, Style_Default); + } + } + + break; + } + + case CC_Slider: + { + const QSlider *slider = (const QSlider *) widget; + QRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove, + data), + handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle, + data); + + if ((controls & SC_SliderGroove) && groove.isValid()) { + QColor grooveColor = cg.midlight(); + if (!(flags & Style_Enabled)) + grooveColor = cg.background(); + + + QBrush brush(grooveColor); + drawLightBevel( p, groove, cg, + ( ( flags | Style_Raised ) ^ Style_Raised ) | + ( ( flags & Style_Enabled ) ? Style_Sunken : + Style_Default ), 2, true, true, + &brush ); + groove.addCoords( 2, 2, -2, -2 ); + drawLightEtch( p, groove, grooveColor, false ); + + if (flags & Style_HasFocus) { + groove.addCoords( -2, -2, 2, 2 ); + drawPrimitive( PE_FocusRect, p, groove, cg, flags ); + } + } + + if ((controls & SC_SliderHandle) && handle.isValid()) { + QColor sliderColor = cg.highlight(); + if (!(flags & Style_Enabled)) + sliderColor = cg.button(); + + p->setPen( sliderColor.light() ); + + p->drawLine( handle.topLeft(), handle.topRight() ); + p->drawLine( handle.left(), handle.top() + 1, + handle.left(), handle.bottom() - 1 ); + p->setPen( sliderColor.dark() ); + p->drawLine( handle.left(), handle.bottom(), + handle.right() - 1, handle.bottom() ); + p->drawLine( handle.topRight(), handle.bottomRight() ); + handle.addCoords( 1, 1, -1, -1 ); + p->fillRect( handle, sliderColor ); + p->setPen( cg.midlight() ); + + if ( slider->orientation() == Qt::Horizontal ) + p->drawLine( handle.left() + handle.width() / 2, + handle.top() + 1, + handle.left() + handle.width() / 2, + handle.bottom() - 1 ); + else + p->drawLine( handle.left() + 1, + handle.top() + handle.height() / 2, + handle.right() - 1, + handle.top() + handle.height() / 2 ); + } + + if (controls & SC_SliderTickmarks) + QCommonStyle::drawComplexControl(control, p, widget, r, cg, flags, + SC_SliderTickmarks, active, data ); + break; + } + + case CC_ListView: + // use the base style for CC_ListView + basestyle->drawComplexControl(control, p, widget, r, cg, flags, + controls, active, data); + break; + + default: + QCommonStyle::drawComplexControl(control, p, widget, r, cg, flags, + controls, active, data); + break; + } +} + +QRect LightStyleV3::querySubControlMetrics( ComplexControl control, + const QWidget *widget, + SubControl sc, + const QStyleOption &data ) const +{ + QRect ret; + + switch (control) { + case CC_ComboBox: + { + int fw = pixelMetric( PM_DefaultFrameWidth, widget ); + int sb = pixelMetric( PM_ScrollBarExtent ); // width of the arrow + + switch ( sc ) { + case SC_ComboBoxFrame: + ret = widget->rect(); + break; + case SC_ComboBoxArrow: + ret.setRect( widget->width() - fw - sb, fw, + sb, widget->height() - fw*2 ); + break; + case SC_ComboBoxEditField: + ret.setRect( fw, fw, widget->width() - fw*2 - sb - 1, + widget->height() - fw*2 ); + break; + default: + break; + } + + break; + } + + case CC_ScrollBar: + { + const QScrollBar *scrollbar = (const QScrollBar *) widget; + int sliderstart = scrollbar->sliderStart(); + int sbextent = pixelMetric(PM_ScrollBarExtent, widget); + int maxlen = ((scrollbar->orientation() == Qt::Horizontal) ? + scrollbar->width() : scrollbar->height()) - (sbextent * 3); + int sliderlen; + + // calculate slider length + if (scrollbar->maxValue() != scrollbar->minValue()) { + uint range = scrollbar->maxValue() - scrollbar->minValue(); + sliderlen = (scrollbar->pageStep() * maxlen) / + (range + scrollbar->pageStep()); + + int slidermin = pixelMetric( PM_ScrollBarSliderMin, widget ); + if ( sliderlen < slidermin || range > INT_MAX / 2 ) + sliderlen = slidermin; + if ( sliderlen > maxlen ) + sliderlen = maxlen; + } else + sliderlen = maxlen; + + switch (sc) { + case SC_ScrollBarSubLine: + // top/left button + ret.setRect(0, 0, sbextent, sbextent); + break; + + case SC_ScrollBarAddLine: + // bottom/right button + if (scrollbar->orientation() == Qt::Horizontal) + ret.setRect(scrollbar->width() - sbextent, 0, sbextent, sbextent); + else + ret.setRect(0, scrollbar->height() - sbextent, sbextent, sbextent); + break; + + case SC_ScrollBarSubPage: + // between top/left button and slider + if (scrollbar->orientation() == Qt::Horizontal) + ret.setRect(sbextent, 0, sliderstart - sbextent, sbextent); + else + ret.setRect(0, sbextent, sbextent, sliderstart - sbextent); + break; + + case SC_ScrollBarAddPage: + // between bottom/right button and slider + if (scrollbar->orientation() == Qt::Horizontal) + ret.setRect(sliderstart + sliderlen, 0, maxlen - sliderstart - + sliderlen + sbextent, sbextent); + else + ret.setRect(0, sliderstart + sliderlen, sbextent, maxlen - + sliderstart - sliderlen + sbextent); + break; + + case SC_ScrollBarGroove: + if (scrollbar->orientation() == Qt::Horizontal) + ret.setRect(sbextent, 0, maxlen, sbextent ); + else + ret.setRect(0, sbextent, sbextent, maxlen ); + break; + + case SC_ScrollBarSlider: + if (scrollbar->orientation() == Qt::Horizontal) + ret.setRect(sliderstart, 0, sliderlen, sbextent); + else + ret.setRect(0, sliderstart, sbextent, sliderlen); + break; + + default: + break; + } + + break; + } + + case CC_Slider: + { + const QSlider *slider = (const QSlider *) widget; + int tickOffset = pixelMetric( PM_SliderTickmarkOffset, widget ); + int thickness = pixelMetric( PM_SliderControlThickness, widget ); + + switch ( sc ) { + case SC_SliderGroove: + if ( slider->orientation() == Horizontal ) + ret.setRect( 0, tickOffset, slider->width(), thickness ); + else + ret.setRect( tickOffset, 0, thickness, slider->height() ); + break; + + case SC_SliderHandle: + { + int pos = slider->sliderStart(); + int len = pixelMetric( PM_SliderLength, widget ); + + if ( slider->orientation() == Horizontal ) + ret.setRect( pos + 2, tickOffset + 2, len - 4, thickness - 4 ); + else + ret.setRect( tickOffset + 2, pos + 2, thickness - 4, len - 4 ); + break; + } + + default: + ret = QCommonStyle::querySubControlMetrics(control, widget, sc, data); + break; + } + + break; + } + + default: + ret = QCommonStyle::querySubControlMetrics(control, widget, sc, data); + break; + } + + return ret; +} + +QStyle::SubControl LightStyleV3::querySubControl( ComplexControl control, + const QWidget *widget, + const QPoint &pos, + const QStyleOption &data ) const +{ + QStyle::SubControl ret = + QCommonStyle::querySubControl(control, widget, pos, data); + + // this is an ugly hack, but i really don't care, it's the quickest way to + // enabled the third button + if (control == CC_ScrollBar && + ret == SC_None) + ret = SC_ScrollBarSubLine; + + return ret; +} + +int LightStyleV3::pixelMetric( PixelMetric metric, + const QWidget *widget ) const +{ + int ret; + + switch (metric) { + case PM_ButtonMargin: + ret = 6; + break; + + case PM_ButtonShiftHorizontal: + case PM_ButtonShiftVertical: + ret = 0; + break; + + case PM_ButtonDefaultIndicator: + ret = 0; + break; + + case PM_DefaultFrameWidth: + ret = 2; + break; + + case PM_IndicatorWidth: + case PM_IndicatorHeight: + case PM_ExclusiveIndicatorWidth: + case PM_ExclusiveIndicatorHeight: + ret = 13; + break; + + case PM_TabBarTabOverlap: + case PM_TabBarBaseOverlap: + ret = 0; + break; + + case PM_ScrollBarExtent: + case PM_ScrollBarSliderMin: + ret = 15; + break; + + case PM_MenuBarFrameWidth: + ret = 1; + break; + + case PM_ProgressBarChunkWidth: + ret = 1; + break; + + case PM_DockWindowHandleExtent: + ret = 8; + break; + + case PM_DockWindowSeparatorExtent: + ret = 8; + break; + + case PM_SplitterWidth: + ret = 8; + break; + + case PM_SliderLength: + ret = 25; + break; + + case PM_SliderThickness: + ret = 11; + break; + + case PM_SliderControlThickness: + { + const QSlider * sl = (const QSlider *) widget; + int space = (sl->orientation() == Horizontal) ? sl->height() + : sl->width(); + int ticks = sl->tickmarks(); + int n = 0; + if ( ticks & QSlider::Above ) n++; + if ( ticks & QSlider::Below ) n++; + if ( !n ) { + ret = space; + break; + } + + int thick = 6; // Magic constant to get 5 + 16 + 5 + + space -= thick; + //### the two sides may be unequal in size + if ( space > 0 ) + thick += (space * 2) / (n + 2); + ret = thick; + break; + } + + case PM_MaximumDragDistance: + ret = -1; + break; + + default: + ret = QCommonStyle::pixelMetric(metric, widget); + break; + } + + return ret; +} + +QSize LightStyleV3::sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentsSize, + const QStyleOption &data ) const +{ + QSize ret; + + switch (contents) { + case CT_ComboBox: + { + int fw = pixelMetric( PM_DefaultFrameWidth, widget ) * 2; + int sb = pixelMetric( PM_ScrollBarExtent ); // width of the arrow + int w = contentsSize.width(); + int h = contentsSize.height(); + + w += fw + sb + 1; + h += fw; + + // try to keep a similar height to buttons + if ( h < 21 ) + h = 21; + + ret = QSize( w, h ); + break; + } + + case CT_PushButton: + { + const QPushButton *button = (const QPushButton *) widget; + ret = QCommonStyle::sizeFromContents( contents, widget, contentsSize, data ); + int w = ret.width(), h = ret.height(); + int dbi = pixelMetric( PM_ButtonDefaultIndicator, widget ) * 2; + int mw = 80 - dbi, mh = 25 - dbi; + + // only expand the button if we are displaying text... + if ( ! button->text().isEmpty() ) { + // button minimum size + if ( w < mw ) + w = mw; + if ( h < mh ) + h = mh; + } + + ret = QSize( w, h ); + break; + } + + case CT_PopupMenuItem: + { + if (! widget || data.isDefault()) + break; + + QMenuItem *mi = data.menuItem(); + const QPopupMenu *popupmenu = (const QPopupMenu *) widget; + int maxpmw = data.maxIconWidth(); + int w = contentsSize.width(), h = contentsSize.height(); + + if (mi->custom()) { + w = mi->custom()->sizeHint().width(); + h = mi->custom()->sizeHint().height(); + if (! mi->custom()->fullSpan() && h < 22) + h = 22; + } else if(mi->widget()) { + } else if (mi->isSeparator()) { + w = 10; + h = 4; + } else { + // check is at least 16x16 + if (h < 16) + h = 16; + if (mi->pixmap()) + h = QMAX(h, mi->pixmap()->height()); + else if (! mi->text().isNull()) + h = QMAX(h, popupmenu->fontMetrics().height() + 2); + if (mi->iconSet() != 0) + h = QMAX(h, mi->iconSet()->pixmap(QIconSet::Small, + QIconSet::Normal).height()); + h += 2; + } + + // check | 4 pixels | item | 8 pixels | accel | 4 pixels | check + + // check is at least 16x16 + maxpmw = QMAX(maxpmw, 16); + w += (maxpmw * 2) + 8; + + if (! mi->text().isNull() && mi->text().find('\t') >= 0) + w += 8; + + ret = QSize(w, h); + break; + } + + case CT_ProgressBar: + { + const QProgressBar* pb = static_cast<const QProgressBar*>(widget); + + //If we have to display the indicator, and we do it on RHS, give some more room + //for it. This tries to match the logic and the spacing in SR_ProgressBarGroove/Contents + //sizing in QCommonStyle. + if (pb->percentageVisible() && + (pb->indicatorFollowsStyle() || ! pb->centerIndicator())) + { + int addw = pb->fontMetrics().width("100%") + 6; + return QSize(contentsSize.width() + addw, contentsSize.height()); + } + else + return contentsSize; //Otherwise leave unchanged + + break; + } + + default: + ret = QCommonStyle::sizeFromContents(contents, widget, contentsSize, data); + break; + } + + return ret; +} + +int LightStyleV3::styleHint( StyleHint stylehint, + const QWidget *widget, + const QStyleOption &option, + QStyleHintReturn* returnData ) const +{ + int ret; + + switch (stylehint) { + case SH_EtchDisabledText: + case SH_Slider_SnapToValue: + case SH_PrintDialog_RightAlignButtons: + case SH_FontDialog_SelectAssociatedText: + case SH_MenuBar_AltKeyNavigation: + case SH_MenuBar_MouseTracking: + case SH_PopupMenu_MouseTracking: + case SH_ComboBox_ListMouseTracking: + case SH_ScrollBar_MiddleClickAbsolutePosition: + ret = 1; + break; + + case SH_MainWindow_SpaceBelowMenuBar: + ret = 0; + break; + + case SH_ScrollBar_BackgroundMode: + ret = NoBackground; + break; + + default: + ret = QCommonStyle::styleHint(stylehint, widget, option, returnData); + break; + } + + return ret; +} + +QPixmap LightStyleV3::stylePixmap( StylePixmap stylepixmap, + const QWidget *widget, + const QStyleOption &data ) const +{ + return basestyle->stylePixmap( stylepixmap, widget, data ); +} +#include "lightstyle-v3.moc" diff --git a/kstyles/light/lightstyle-v3.h b/kstyles/light/lightstyle-v3.h new file mode 100644 index 000000000..b46010778 --- /dev/null +++ b/kstyles/light/lightstyle-v3.h @@ -0,0 +1,89 @@ +/* + Copyright (c) 2000-2001 Trolltech AS ([email protected]) + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef LIGHTSTYLE_V3_H +#define LIGHTSTYLE_V3_H + + +#ifndef QT_H +#include <qcommonstyle.h> +#endif // QT_H + +#include "kstyle.h" + +#ifdef QT_PLUGIN +# define Q_EXPORT_STYLE_LIGHT_V3 +#else +# define Q_EXPORT_STYLE_LIGHT_V3 Q_EXPORT +#endif // QT_PLUGIN + + +class Q_EXPORT_STYLE_LIGHT_V3 LightStyleV3 : public KStyle +{ + Q_OBJECT + QStyle *basestyle; + +public: + LightStyleV3(); + virtual ~LightStyleV3(); + + void polishPopupMenu( QPopupMenu * ); + + void drawPrimitive(PrimitiveElement, QPainter *, const QRect &, const QColorGroup &, + SFlags = Style_Default, + const QStyleOption & = QStyleOption::Default ) const; + + void drawControl(ControlElement, QPainter *, const QWidget *, const QRect &, + const QColorGroup &, SFlags = Style_Default, + const QStyleOption & = QStyleOption::Default ) const; + void drawControlMask(ControlElement, QPainter *, const QWidget *, const QRect &, + const QStyleOption & = QStyleOption::Default) const; + + QRect subRect(SubRect, const QWidget *) const; + + void drawComplexControl(ComplexControl, QPainter *, const QWidget *, const QRect &, + const QColorGroup &, SFlags = Style_Default, + SCFlags = SC_All, SCFlags = SC_None, + const QStyleOption & = QStyleOption::Default ) const; + + QRect querySubControlMetrics(ComplexControl, const QWidget *, SubControl, + const QStyleOption & = QStyleOption::Default ) const; + + SubControl querySubControl(ComplexControl, const QWidget *, const QPoint &, + const QStyleOption &data = QStyleOption::Default ) const; + + int pixelMetric(PixelMetric, const QWidget * = 0 ) const; + + QSize sizeFromContents(ContentsType, const QWidget *, const QSize &, + const QStyleOption & = QStyleOption::Default ) const; + + int styleHint(StyleHint, const QWidget * = 0, + const QStyleOption & = QStyleOption::Default, + QStyleHintReturn * = 0 ) const; + + QPixmap stylePixmap( StylePixmap stylepixmap, + const QWidget* widget = 0, + const QStyleOption& = QStyleOption::Default ) const; +}; + + +#endif // LIGHTSTYLE_V3_H diff --git a/kstyles/plastik/Makefile.am b/kstyles/plastik/Makefile.am new file mode 100644 index 000000000..5b57c7681 --- /dev/null +++ b/kstyles/plastik/Makefile.am @@ -0,0 +1,22 @@ +AUTOMAKE_OPTIONS = foreign + +SUBDIRS = config + +KDE_CXXFLAGS = -DQT_PLUGIN + +INCLUDES = $(all_includes) + +stylercdir = $(kde_datadir)/kstyle/themes +stylerc_DATA = plastik.themerc + +EXTRA_DIST = $(stylerc_DATA) + +noinst_HEADERS = plastik.h misc.h + +kde_style_LTLIBRARIES = plastik.la +plastik_la_SOURCES = plastik.cpp misc.cpp +plastik_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +plastik_la_LIBADD = ../../kdefx/libkdefx.la +plastik_la_METASOURCES = AUTO + +DISTCLEANFILES = $(plastik_la_METASOURCES) diff --git a/kstyles/plastik/config/Makefile.am b/kstyles/plastik/config/Makefile.am new file mode 100644 index 000000000..a3b081ead --- /dev/null +++ b/kstyles/plastik/config/Makefile.am @@ -0,0 +1,12 @@ +INCLUDES = $(all_includes) + +noinst_HEADERS = plastikconf.h +kde_module_LTLIBRARIES = kstyle_plastik_config.la +kstyle_plastik_config_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +kstyle_plastik_config_la_LIBADD = $(LIB_KDEUI) +kstyle_plastik_config_la_SOURCES = plastikconf.cpp +kstyle_plastik_config_la_METASOURCES = AUTO + + +messages: + $(XGETTEXT) *.cpp *.h -o $(podir)/kstyle_plastik_config.pot diff --git a/kstyles/plastik/config/plastikconf.cpp b/kstyles/plastik/config/plastikconf.cpp new file mode 100644 index 000000000..b9c3ff8cf --- /dev/null +++ b/kstyles/plastik/config/plastikconf.cpp @@ -0,0 +1,223 @@ +/* +Copyright (C) 2003 Sandro Giessl <[email protected]> + +based on the Keramik configuration dialog: +Copyright (c) 2003 Maksim Orlovich <[email protected]> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include <qcheckbox.h> +#include <qlayout.h> +#include <qhbox.h> +#include <qsettings.h> +#include <qcolor.h> +#include <qgroupbox.h> +#include <kglobal.h> +#include <klocale.h> +#include <kcolorbutton.h> +#include <kdemacros.h> + +#include "plastikconf.h" + +extern "C" +{ + KDE_EXPORT QWidget* allocate_kstyle_config(QWidget* parent) + { + KGlobal::locale()->insertCatalogue("kstyle_plastik_config"); + return new PlastikStyleConfig(parent); + } +} + +PlastikStyleConfig::PlastikStyleConfig(QWidget* parent): QWidget(parent) +{ + //Should have no margins here, the dialog provides them + QVBoxLayout* layout = new QVBoxLayout(this, 0, 0); + KGlobal::locale()->insertCatalogue("kstyle_plastik_config"); + +// scrollBarLines = new QCheckBox(i18n("Scrollbar handle lines"), this); + animateProgressBar = new QCheckBox(i18n("Animate progress bars"), this); + drawToolBarSeparator = new QCheckBox(i18n("Draw toolbar separator"), this); + drawToolBarItemSeparator = new QCheckBox(i18n("Draw toolbar item separators"), this); +// drawFocusRect = new QCheckBox(i18n("Draw focus rectangles"), this); + drawTriangularExpander = new QCheckBox(i18n("Triangular tree expander"), this); + inputFocusHighlight = new QCheckBox(i18n("Highlight focused text input fields"), this); + + customFocusHighlightColor = new QCheckBox(i18n("Custom text input highlight color:"), this); + QHBox *hbox1 = new QHBox(this); + hbox1->layout()->addItem(new QSpacerItem(20, 0, QSizePolicy::Fixed, QSizePolicy::Minimum) ); + focusHighlightColor = new KColorButton(hbox1); + + customOverHighlightColor = new QCheckBox(i18n("Custom mouseover highlight color:"), this); + QHBox *hbox2 = new QHBox(this); + hbox2->layout()->addItem(new QSpacerItem(20, 0, QSizePolicy::Fixed, QSizePolicy::Minimum) ); + overHighlightColor = new KColorButton(hbox2); + + customCheckMarkColor = new QCheckBox(i18n("Custom checkmark color:"), this); + QHBox *hbox3 = new QHBox(this); + hbox3->layout()->addItem(new QSpacerItem(20, 0, QSizePolicy::Fixed, QSizePolicy::Minimum) ); + checkMarkColor = new KColorButton(hbox3); + +// layout->add(scrollBarLines); + layout->add(animateProgressBar); + layout->add(drawToolBarSeparator); + layout->add(drawToolBarItemSeparator); +// layout->add(drawFocusRect); + layout->add(drawTriangularExpander); + layout->add(inputFocusHighlight); + layout->add(customFocusHighlightColor); + layout->add(hbox1); + layout->add(customOverHighlightColor); + layout->add(hbox2); + layout->add(customCheckMarkColor); + layout->add(hbox3); + layout->addStretch(1); + + QSettings s; +// origScrollBarLines = s.readBoolEntry("/plastikstyle/Settings/scrollBarLines", false); +// scrollBarLines->setChecked(origScrollBarLines); + origAnimProgressBar = s.readBoolEntry("/plastikstyle/Settings/animateProgressBar", false); + animateProgressBar->setChecked(origAnimProgressBar); + origDrawToolBarSeparator = s.readBoolEntry("/plastikstyle/Settings/drawToolBarSeparator", false); + drawToolBarSeparator->setChecked(origDrawToolBarSeparator); + origDrawToolBarItemSeparator = s.readBoolEntry("/plastikstyle/Settings/drawToolBarItemSeparator", true); + drawToolBarItemSeparator->setChecked(origDrawToolBarItemSeparator); +// origDrawFocusRect = s.readBoolEntry("/plastikstyle/Settings/drawFocusRect", true); +// drawFocusRect->setChecked(origDrawFocusRect); + origDrawTriangularExpander = s.readBoolEntry("/plastikstyle/Settings/drawTriangularExpander", false); + drawTriangularExpander->setChecked(origDrawTriangularExpander); + origInputFocusHighlight = s.readBoolEntry("/plastikstyle/Settings/inputFocusHighlight", true); + inputFocusHighlight->setChecked(origInputFocusHighlight); + origCustomOverHighlightColor = s.readBoolEntry("/plastikstyle/Settings/customOverHighlightColor", false); + customOverHighlightColor->setChecked(origCustomOverHighlightColor); + origOverHighlightColor = s.readEntry("/plastikstyle/Settings/overHighlightColor", "black"); + overHighlightColor->setColor(origOverHighlightColor); + origCustomFocusHighlightColor = s.readBoolEntry("/plastikstyle/Settings/customFocusHighlightColor", false); + customFocusHighlightColor->setChecked(origCustomFocusHighlightColor); + origFocusHighlightColor = s.readEntry("/plastikstyle/Settings/focusHighlightColor", "black"); + focusHighlightColor->setColor(origFocusHighlightColor); + origCustomCheckMarkColor = s.readBoolEntry("/plastikstyle/Settings/customCheckMarkColor", false); + customCheckMarkColor->setChecked(origCustomCheckMarkColor); + origCheckMarkColor = s.readEntry("/plastikstyle/Settings/checkMarkColor", "black"); + checkMarkColor->setColor(origCheckMarkColor); + +// connect(scrollBarLines, SIGNAL( toggled(bool) ), SLOT( updateChanged() ) ); + connect(animateProgressBar, SIGNAL( toggled(bool) ), SLOT( updateChanged() ) ); + connect(drawToolBarSeparator, SIGNAL( toggled(bool) ), SLOT( updateChanged() ) ); + connect(drawToolBarItemSeparator, SIGNAL( toggled(bool) ), SLOT( updateChanged() ) ); +// connect(drawFocusRect, SIGNAL( toggled(bool) ), SLOT( updateChanged() ) ); + connect(drawTriangularExpander, SIGNAL( toggled(bool) ), SLOT( updateChanged() ) ); + connect(inputFocusHighlight, SIGNAL( toggled(bool) ), SLOT( updateChanged() ) ); + connect(customOverHighlightColor, SIGNAL( toggled(bool) ), SLOT( updateChanged() ) ); + connect(overHighlightColor, SIGNAL( changed(const QColor&) ), SLOT( updateChanged() ) ); + connect(customFocusHighlightColor, SIGNAL( toggled(bool) ), SLOT( updateChanged() ) ); + connect(focusHighlightColor, SIGNAL( changed(const QColor&) ), SLOT( updateChanged() ) ); + connect(customCheckMarkColor, SIGNAL( toggled(bool) ), SLOT( updateChanged() ) ); + connect(checkMarkColor, SIGNAL( changed(const QColor&) ), SLOT( updateChanged() ) ); + if ( customOverHighlightColor->isChecked() ) + overHighlightColor->setEnabled(true); + else + overHighlightColor->setEnabled(false); + if ( customFocusHighlightColor->isChecked() ) + focusHighlightColor->setEnabled(true); + else + focusHighlightColor->setEnabled(false); + if ( customCheckMarkColor->isChecked() ) + checkMarkColor->setEnabled(true); + else + checkMarkColor->setEnabled(false); +} + +PlastikStyleConfig::~PlastikStyleConfig() +{ +} + + +void PlastikStyleConfig::save() +{ + QSettings s; +// s.writeEntry("/plastikstyle/Settings/scrollBarLines", scrollBarLines->isChecked()); + s.writeEntry("/plastikstyle/Settings/animateProgressBar", animateProgressBar->isChecked()); + s.writeEntry("/plastikstyle/Settings/drawToolBarSeparator", drawToolBarSeparator->isChecked()); + s.writeEntry("/plastikstyle/Settings/drawToolBarItemSeparator", drawToolBarItemSeparator->isChecked()); +// s.writeEntry("/plastikstyle/Settings/drawFocusRect", drawFocusRect->isChecked()); + s.writeEntry("/plastikstyle/Settings/drawTriangularExpander", drawTriangularExpander->isChecked()); + s.writeEntry("/plastikstyle/Settings/inputFocusHighlight", inputFocusHighlight->isChecked()); + s.writeEntry("/plastikstyle/Settings/customOverHighlightColor", customOverHighlightColor->isChecked()); + s.writeEntry("/plastikstyle/Settings/overHighlightColor", QColor(overHighlightColor->color()).name()); + s.writeEntry("/plastikstyle/Settings/customFocusHighlightColor", customFocusHighlightColor->isChecked()); + s.writeEntry("/plastikstyle/Settings/focusHighlightColor", QColor(focusHighlightColor->color()).name()); + s.writeEntry("/plastikstyle/Settings/customCheckMarkColor", customCheckMarkColor->isChecked()); + s.writeEntry("/plastikstyle/Settings/checkMarkColor", QColor(checkMarkColor->color()).name()); +} + +void PlastikStyleConfig::defaults() +{ +// scrollBarLines->setChecked(false); + animateProgressBar->setChecked(false); + drawToolBarSeparator->setChecked(false); + drawToolBarItemSeparator->setChecked(true); +// drawFocusRect->setChecked(true); + drawTriangularExpander->setChecked(false); + inputFocusHighlight->setChecked(true); + customOverHighlightColor->setChecked(false); + overHighlightColor->setColor("black"); + customFocusHighlightColor->setChecked(false); + focusHighlightColor->setColor("black"); + customCheckMarkColor->setChecked(false); + checkMarkColor->setColor("black"); + //updateChanged would be done by setChecked already +} + +void PlastikStyleConfig::updateChanged() +{ + if ( customOverHighlightColor->isChecked() ) + overHighlightColor->setEnabled(true); + else + overHighlightColor->setEnabled(false); + if ( customFocusHighlightColor->isChecked() ) + focusHighlightColor->setEnabled(true); + else + focusHighlightColor->setEnabled(false); + if ( customCheckMarkColor->isChecked() ) + checkMarkColor->setEnabled(true); + else + checkMarkColor->setEnabled(false); + + if (/*(scrollBarLines->isChecked() == origScrollBarLines) &&*/ + (animateProgressBar->isChecked() == origAnimProgressBar) && + (drawToolBarSeparator->isChecked() == origDrawToolBarSeparator) && + (drawToolBarItemSeparator->isChecked() == origDrawToolBarItemSeparator) && +// (drawFocusRect->isChecked() == origDrawFocusRect) && + (drawTriangularExpander->isChecked() == origDrawTriangularExpander) && + (inputFocusHighlight->isChecked() == origInputFocusHighlight) && + (customOverHighlightColor->isChecked() == origCustomOverHighlightColor) && + (overHighlightColor->color() == origOverHighlightColor) && + (customFocusHighlightColor->isChecked() == origCustomFocusHighlightColor) && + (focusHighlightColor->color() == origFocusHighlightColor) && + (customCheckMarkColor->isChecked() == origCustomCheckMarkColor) && + (checkMarkColor->color() == origCheckMarkColor) + ) + emit changed(false); + else + emit changed(true); +} + +#include "plastikconf.moc" diff --git a/kstyles/plastik/config/plastikconf.h b/kstyles/plastik/config/plastikconf.h new file mode 100644 index 000000000..66106061e --- /dev/null +++ b/kstyles/plastik/config/plastikconf.h @@ -0,0 +1,85 @@ +/* +Copyright (C) 2003 Sandro Giessl <[email protected]> + +based on the Keramik configuration dialog: +Copyright (c) 2003 Maksim Orlovich <[email protected]> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#ifndef PLASTIK_CONF_H +#define PLASTIK_CONF_H + +class QCheckBox; + +class PlastikStyleConfig: public QWidget +{ + Q_OBJECT +public: + PlastikStyleConfig(QWidget* parent); + ~PlastikStyleConfig(); + + //This signal and the next two slots are the plugin + //page interface +signals: + void changed(bool); + +public slots: + void save(); + void defaults(); + + //Everything below this is internal. +protected slots: + void updateChanged(); + +protected: + //We store settings directly in widgets to + //avoid the hassle of sync'ing things +// QCheckBox* scrollBarLines; + QCheckBox* animateProgressBar; + QCheckBox* drawToolBarSeparator; + QCheckBox* drawToolBarItemSeparator; +// QCheckBox* drawFocusRect; + QCheckBox* drawTriangularExpander; + QCheckBox* inputFocusHighlight; + QCheckBox* customOverHighlightColor; + KColorButton* overHighlightColor; + QCheckBox* customFocusHighlightColor; + KColorButton* focusHighlightColor; + QCheckBox* customCheckMarkColor; + KColorButton* checkMarkColor; + + //Original settings, for accurate dirtiness tracking +// bool origScrollBarLines; + bool origAnimProgressBar; + bool origDrawToolBarSeparator; + bool origDrawToolBarItemSeparator; +// bool origDrawFocusRect; + bool origDrawTriangularExpander; + bool origInputFocusHighlight; + bool origCustomOverHighlightColor; + QColor origOverHighlightColor; + bool origCustomFocusHighlightColor; + QColor origFocusHighlightColor; + bool origCustomCheckMarkColor; + QColor origCheckMarkColor; +}; + +#endif diff --git a/kstyles/plastik/misc.cpp b/kstyles/plastik/misc.cpp new file mode 100644 index 000000000..5eddf5ad2 --- /dev/null +++ b/kstyles/plastik/misc.cpp @@ -0,0 +1,38 @@ +/* + * Copyright 2003, Sandro Giessl <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <qcolor.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/kstyles/plastik/misc.h b/kstyles/plastik/misc.h new file mode 100644 index 000000000..65bb42534 --- /dev/null +++ b/kstyles/plastik/misc.h @@ -0,0 +1,24 @@ +/* + * Copyright 2003, Sandro Giessl <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. 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 diff --git a/kstyles/plastik/plastik.cpp b/kstyles/plastik/plastik.cpp new file mode 100644 index 000000000..98e7e6d49 --- /dev/null +++ b/kstyles/plastik/plastik.cpp @@ -0,0 +1,3620 @@ +/* Plastik widget style for KDE 3 + Copyright (C) 2003 Sandro Giessl <[email protected]> + + based on the KDE style "dotNET": + + Copyright (C) 2001-2002, Chris Lee <[email protected]> + Carsten Pfeiffer <[email protected]> + Karol Szwed <[email protected]> + Drawing routines completely reimplemented from KDE3 HighColor, which was + originally based on some stuff from the KDE2 HighColor. + + based on drawing routines of the style "Keramik": + + Copyright (c) 2002 Malte Starostik <[email protected]> + (c) 2002,2003 Maksim Orlovich <[email protected]> + based on the KDE3 HighColor Style + Copyright (C) 2001-2002 Karol Szwed <[email protected]> + (C) 2001-2002 Fredrik H�glund <[email protected]> + Drawing routines adapted from the KDE2 HCStyle, + Copyright (C) 2000 Daniel M. Duley <[email protected]> + (C) 2000 Dirk Mueller <[email protected]> + (C) 2001 Martijn Klingens <[email protected]> + Progressbar code based on KStyle, + Copyright (C) 2001-2002 Karol Szwed <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include <qimage.h> +#include <qstylefactory.h> +#include <qpointarray.h> +#include <qpainter.h> +#include <qtabbar.h> +#include <qprogressbar.h> +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qcleanuphandler.h> +#include <qheader.h> +#include <qlineedit.h> +#include <qlistbox.h> +#include <qscrollbar.h> +#include <qstyleplugin.h> +#include <qpushbutton.h> +#include <qtabwidget.h> +#include <qtimer.h> +#include <qtoolbutton.h> +#include <qtoolbar.h> +#include <qmenubar.h> +#include <qpopupmenu.h> +#include <qdrawutil.h> +#include <qapplication.h> +#include <qvariant.h> +#include <qradiobutton.h> +#include <qregion.h> +#include <qslider.h> +#include <qsettings.h> +#include <kpixmap.h> + +#include "plastik.h" +#include "plastik.moc" +#include "misc.h" + +// some bitmaps for the radio button so it's easier to handle the circle stuff... +// 13x13 +static const unsigned char radiobutton_mask_bits[] = { + 0xf8, 0x03, 0xfc, 0x07, 0xfe, 0x0f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, + 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xfe, 0x0f, 0xfc, 0x07, + 0xf8, 0x03}; +static const unsigned char radiobutton_contour_bits[] = { + 0xf0, 0x01, 0x0c, 0x06, 0x02, 0x08, 0x02, 0x08, 0x01, 0x10, 0x01, 0x10, + 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x02, 0x08, 0x02, 0x08, 0x0c, 0x06, + 0xf0, 0x01}; +static const unsigned char radiobutton_aa_inside_bits[] = { + 0x00, 0x00, 0x10, 0x01, 0x04, 0x04, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x04, 0x04, 0x10, 0x01, + 0x00, 0x00}; +static const unsigned char radiobutton_aa_outside_bits[] = { + 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x02}; +static const unsigned char radiobutton_highlight1_bits[] = { + 0x00, 0x00, 0xf0, 0x01, 0x1c, 0x07, 0x04, 0x04, 0x06, 0x0c, 0x02, 0x08, + 0x02, 0x08, 0x02, 0x08, 0x06, 0x0c, 0x04, 0x04, 0x1c, 0x07, 0xf0, 0x01, + 0x00, 0x00}; +static const unsigned char radiobutton_highlight2_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x18, 0x03, 0x08, 0x02, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x08, 0x02, 0x18, 0x03, 0xe0, 0x00, 0x00, 0x00, + 0x00, 0x00}; +// check mark +const uint CHECKMARKSIZE = 9; // 9x9 +static const unsigned char checkmark_aa_bits[] = { + 0x45, 0x01, 0x28, 0x00, 0x11, 0x01, 0x82, 0x00, 0x44, 0x00, 0x82, 0x00, + 0x11, 0x01, 0x28, 0x00, 0x45, 0x01}; +static const unsigned char checkmark_dark_bits[] = { + 0x82, 0x00, 0x45, 0x01, 0xaa, 0x00, 0x54, 0x00, 0x28, 0x00, 0x74, 0x00, + 0xea, 0x00, 0xc5, 0x01, 0x82, 0x00}; +static const unsigned char checkmark_light_bits[] = { + 0x00, 0xfe, 0x82, 0xfe, 0x44, 0xfe, 0x28, 0xfe, 0x10, 0xfe, 0x08, 0xfe, + 0x04, 0xfe, 0x02, 0xfe, 0x00, 0xfe}; +static const unsigned char checkmark_tristate_bits[] = { + 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, 0x01, + 0x00, 0x00, 0xff, 0x01, 0x00, 0x00}; +// radio mark +const uint RADIOMARKSIZE = 9; // 9x9 +static const unsigned char radiomark_aa_bits[] = { + 0x00, 0x00, 0x44, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x44, 0x00, 0x00, 0x00}; +static const unsigned char radiomark_dark_bits[] = { + 0x00, 0x00, 0x38, 0x00, 0x44, 0x00, 0xf2, 0x00, 0xfa, 0x00, 0xfa, 0x00, + 0x7c, 0x00, 0x38, 0x00, 0x00, 0x00}; +static const unsigned char radiomark_light_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +// popupmenu item constants... +static const int itemHMargin = 6; +static const int itemFrame = 2; +static const int arrowHMargin = 6; +static const int rightBorder = 12; + +// -- Style Plugin Interface ------------------------- +class PlastikStylePlugin : public QStylePlugin +{ + public: + PlastikStylePlugin() {} + ~PlastikStylePlugin() {} + + QStringList keys() const { + return QStringList() << "Plastik"; + } + + QStyle* create( const QString& key ) { + if (key.lower() == "plastik") + return new PlastikStyle; + return 0; + } +}; + +KDE_Q_EXPORT_PLUGIN( PlastikStylePlugin ) +// -- end -- + +PlastikStyle::PlastikStyle() : KStyle( AllowMenuTransparency, ThreeButtonScrollBar), + kickerMode(false), + kornMode(false), + flatMode(false) +{ + hoverWidget = 0; + hoverTab = 0; + + + horizontalLine = 0; + verticalLine = 0; + + QSettings settings; + _contrast = settings.readNumEntry("/Qt/KDE/contrast", 6); + settings.beginGroup("/plastikstyle/Settings"); + _scrollBarLines = settings.readBoolEntry("/scrollBarLines", false); + _animateProgressBar = settings.readBoolEntry("/animateProgressBar", false); + _drawToolBarSeparator = settings.readBoolEntry("/drawToolBarSeparator", false); + _drawToolBarItemSeparator = settings.readBoolEntry("/drawToolBarItemSeparator", true); + _drawFocusRect = settings.readBoolEntry("/drawFocusRect", true); + _drawTriangularExpander = settings.readBoolEntry("/drawTriangularExpander", false); + _inputFocusHighlight = settings.readBoolEntry("/inputFocusHighlight", true); + _customOverHighlightColor = settings.readBoolEntry("/customOverHighlightColor", false); + _overHighlightColor.setNamedColor( settings.readEntry("/overHighlightColor", "black") ); + _customFocusHighlightColor = settings.readBoolEntry("/customFocusHighlightColor", false); + _focusHighlightColor.setNamedColor( settings.readEntry("/focusHighlightColor", "black") ); + _customCheckMarkColor = settings.readBoolEntry("/customCheckMarkColor", false); + _checkMarkColor.setNamedColor( settings.readEntry("/checkMarkColor", "black") ); + settings.endGroup(); + + // setup pixmap cache... + pixmapCache = new QIntCache<CacheEntry>(150000, 499); + pixmapCache->setAutoDelete(true); + + if ( _animateProgressBar ) + { + animationTimer = new QTimer( this ); + connect( animationTimer, SIGNAL(timeout()), this, SLOT(updateProgressPos()) ); + } +} + + +void PlastikStyle::updateProgressPos() +{ + QProgressBar* pb; + //Update the registered progressbars. + QMap<QWidget*, int>::iterator iter; + bool visible = false; + for (iter = progAnimWidgets.begin(); iter != progAnimWidgets.end(); ++iter) + { + if ( !::qt_cast<QProgressBar*>(iter.key()) ) + continue; + + pb = dynamic_cast<QProgressBar*>(iter.key()); + if ( iter.key() -> isEnabled() && + pb -> progress() != pb->totalSteps() ) + { + // update animation Offset of the current Widget + iter.data() = (iter.data() + 1) % 20; + iter.key()->update(); + } + if (iter.key()->isVisible()) + visible = true; + } + if (!visible) + animationTimer->stop(); +} + + +PlastikStyle::~PlastikStyle() +{ + delete pixmapCache; + delete horizontalLine; + delete verticalLine; +} + +void PlastikStyle::polish(QApplication* app) +{ + if (!qstrcmp(app->argv()[0], "kicker")) + kickerMode = true; + else if (!qstrcmp(app->argv()[0], "korn")) + kornMode = true; +} + +void PlastikStyle::polish(QWidget* widget) +{ + if( !strcmp(widget->name(), "__khtml") ) { // is it a khtml widget...? + khtmlWidgets[widget] = true; + connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(khtmlWidgetDestroyed(QObject*))); + } + + // use qt_cast where possible to check if the widget inheits one of the classes. might improve + // performance compared to QObject::inherits() + if ( ::qt_cast<QPushButton*>(widget) || ::qt_cast<QComboBox*>(widget) || + ::qt_cast<QSpinWidget*>(widget) || ::qt_cast<QSlider*>(widget) || + ::qt_cast<QCheckBox*>(widget) || ::qt_cast<QRadioButton*>(widget) || + ::qt_cast<QToolButton*>(widget) || widget->inherits("QSplitterHandle") ) + { +// widget->setBackgroundMode(PaletteBackground); + widget->installEventFilter(this); + } else if (::qt_cast<QLineEdit*>(widget)) { + widget->installEventFilter(this); + } else if (::qt_cast<QTabBar*>(widget)) { + widget->setMouseTracking(true); + widget->installEventFilter(this); + } else if (::qt_cast<QPopupMenu*>(widget)) { + widget->setBackgroundMode( NoBackground ); + } else if ( !qstrcmp(widget->name(), "kde toolbar widget") ) { + widget->installEventFilter(this); + } + + if( _animateProgressBar && ::qt_cast<QProgressBar*>(widget) ) + { + widget->installEventFilter(this); + progAnimWidgets[widget] = 0; + connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(progressBarDestroyed(QObject*))); + if (!animationTimer->isActive()) + animationTimer->start( 50, false ); + } + + KStyle::polish(widget); +} + +void PlastikStyle::unPolish(QWidget* widget) +{ + if( !strcmp(widget->name(), "__khtml") ) { // is it a khtml widget...? + khtmlWidgets.remove(widget); + } + + // use qt_cast to check if the widget inheits one of the classes. + if ( ::qt_cast<QPushButton*>(widget) || ::qt_cast<QComboBox*>(widget) || + ::qt_cast<QSpinWidget*>(widget) || ::qt_cast<QSlider*>(widget) || + ::qt_cast<QCheckBox*>(widget) || ::qt_cast<QRadioButton*>(widget) || + ::qt_cast<QToolButton*>(widget) || ::qt_cast<QLineEdit*>(widget) || + widget->inherits("QSplitterHandle") ) + { + widget->removeEventFilter(this); + } + else if (::qt_cast<QTabBar*>(widget)) { + widget->setMouseTracking(false); + widget->removeEventFilter(this); + } else if (::qt_cast<QPopupMenu*>(widget)) { + widget->setBackgroundMode( PaletteBackground ); + } else if ( !qstrcmp(widget->name(), "kde toolbar widget") ) { + widget->removeEventFilter(this); + } + + if ( ::qt_cast<QProgressBar*>(widget) ) + { + progAnimWidgets.remove(widget); + } + + KStyle::unPolish(widget); +} + +void PlastikStyle::khtmlWidgetDestroyed(QObject* obj) +{ + khtmlWidgets.remove(static_cast<QWidget*>(obj)); +} + +void PlastikStyle::progressBarDestroyed(QObject* obj) +{ + progAnimWidgets.remove(static_cast<QWidget*>(obj)); +} + +void PlastikStyle::renderContour(QPainter *p, + const QRect &r, + const QColor &backgroundColor, + const QColor &contour, + const uint flags) const +{ + if((r.width() <= 0)||(r.height() <= 0)) + return; + + const bool drawLeft = flags&Draw_Left; + const bool drawRight = flags&Draw_Right; + const bool drawTop = flags&Draw_Top; + const bool drawBottom = flags&Draw_Bottom; + const bool disabled = flags&Is_Disabled; + const bool alphaBlend = flags&Draw_AlphaBlend; + + QColor contourColor; + if (disabled) { + contourColor = backgroundColor.dark(150); + } else { + contourColor = contour; + } + +// sides + p->setPen( alphaBlendColors(backgroundColor, contourColor, 50) ); + if(drawLeft) + p->drawLine(r.left(), drawTop?r.top()+2:r.top(), r.left(), drawBottom?r.bottom()-2:r.bottom()); + if(drawRight) + p->drawLine(r.right(), drawTop?r.top()+2:r.top(), r.right(), drawBottom?r.bottom()-2:r.bottom()); + if(drawTop) + p->drawLine(drawLeft?r.left()+2:r.left(), r.top(), drawRight?r.right()-2:r.right(), r.top()); + if(drawBottom) + p->drawLine(drawLeft?r.left()+2:r.left(), r.bottom(), drawRight?r.right()-2:r.right(), r.bottom()); + +// edges + const int alphaAA = 110; // the alpha value for anti-aliasing... + + // first part... + p->setPen(alphaBlendColors(backgroundColor, contourColor, 50) ); + if(drawLeft && drawTop) { + switch(flags&Round_UpperLeft) { + case false: + p->drawPoint(r.left()+1, r.top()); + p->drawPoint(r.left(), r.top()+1); + break; + default: + p->drawPoint(r.left()+1, r.top()+1); + } + } + if(drawLeft && drawBottom) { + switch(flags&Round_BottomLeft) { + case false: + p->drawPoint(r.left()+1, r.bottom()); + p->drawPoint(r.left(), r.bottom()-1); + break; + default: + p->drawPoint(r.left()+1, r.bottom()-1); + } + } + if(drawRight && drawTop) { + switch(flags&Round_UpperRight) { + case false: + p->drawPoint(r.right()-1, r.top()); + p->drawPoint(r.right(), r.top()+1); + break; + default: + p->drawPoint(r.right()-1, r.top()+1); + } + } + if(drawRight && drawBottom) { + switch(flags&Round_BottomRight) { + case false: + p->drawPoint(r.right()-1, r.bottom()); + p->drawPoint(r.right(), r.bottom()-1); + break; + default: + p->drawPoint(r.right()-1, r.bottom()-1); + } + } + + // second part... fill edges in case we don't paint alpha-blended + p->setPen( backgroundColor ); + if (!alphaBlend) { + if(flags&Round_UpperLeft && drawLeft && drawTop) { + p->drawPoint( r.x(), r.y() ); + } + if(flags&Round_BottomLeft && drawLeft && drawBottom) { + p->drawPoint( r.x(), r.bottom() ); + } + if(flags&Round_UpperRight && drawRight && drawTop) { + p->drawPoint( r.right(), r.y() ); + } + if(flags&Round_BottomRight && drawRight && drawBottom) { + p->drawPoint( r.right(), r.bottom() ); + } + } + + // third part... anti-aliasing... + if(drawLeft && drawTop) { + switch(flags&Round_UpperLeft) { + case false: + renderPixel(p,QPoint(r.left(),r.top()),alphaAA,contourColor,backgroundColor,alphaBlend); + break; + default: + renderPixel(p,QPoint(r.left()+1,r.top()),alphaAA,contourColor,backgroundColor,alphaBlend); + renderPixel(p,QPoint(r.left(),r.top()+1),alphaAA,contourColor,backgroundColor,alphaBlend); + } + } + if(drawLeft && drawBottom) { + switch(flags&Round_BottomLeft) { + case false: + renderPixel(p,QPoint(r.left(),r.bottom()),alphaAA,contourColor,backgroundColor,alphaBlend); + break; + default: + renderPixel(p,QPoint(r.left()+1,r.bottom()),alphaAA,contourColor,backgroundColor,alphaBlend); + renderPixel(p,QPoint(r.left(),r.bottom()-1),alphaAA,contourColor,backgroundColor,alphaBlend); + } + } + if(drawRight && drawTop) { + switch(flags&Round_UpperRight) { + case false: + renderPixel(p,QPoint(r.right(),r.top()),alphaAA,contourColor,backgroundColor,alphaBlend); + break; + default: + renderPixel(p,QPoint(r.right()-1,r.top()),alphaAA,contourColor,backgroundColor,alphaBlend); + renderPixel(p,QPoint(r.right(),r.top()+1),alphaAA,contourColor,backgroundColor,alphaBlend); + } + } + if(drawRight && drawBottom) { + switch(flags&Round_BottomRight) { + case false: + renderPixel(p,QPoint(r.right(),r.bottom()),alphaAA,contourColor,backgroundColor,alphaBlend); + break; + default: + renderPixel(p,QPoint(r.right()-1,r.bottom()),alphaAA,contourColor,backgroundColor,alphaBlend); + renderPixel(p,QPoint(r.right(),r.bottom()-1),alphaAA,contourColor,backgroundColor,alphaBlend); + } + } + +} + +void PlastikStyle::renderMask(QPainter *p, + const QRect &r, + const QColor &color, + const uint flags) const +{ + if((r.width() <= 0)||(r.height() <= 0)) + return; + + const bool roundUpperLeft = flags&Round_UpperLeft; + const bool roundUpperRight = flags&Round_UpperRight; + const bool roundBottomLeft = flags&Round_BottomLeft; + const bool roundBottomRight = flags&Round_BottomRight; + + + p->fillRect (QRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2) , color); + + p->setPen(color); + // sides + p->drawLine(roundUpperLeft?r.x()+1:r.x(), r.y(), + roundUpperRight?r.right()-1:r.right(), r.y() ); + p->drawLine(roundBottomLeft?r.x()+1:r.x(), r.bottom(), + roundBottomRight?r.right()-1:r.right(), r.bottom() ); + p->drawLine(r.x(), roundUpperLeft?r.y()+1:r.y(), + r.x(), roundBottomLeft?r.bottom()-1:r.bottom() ); + p->drawLine(r.right(), roundUpperLeft?r.y()+1:r.y(), + r.right(), roundBottomLeft?r.bottom()-1:r.bottom() ); +} + +void PlastikStyle::renderSurface(QPainter *p, + const QRect &r, + const QColor &backgroundColor, + const QColor &buttonColor, + const QColor &highlightColor, + int intensity, + const uint flags) const +{ + if((r.width() <= 0)||(r.height() <= 0)) + return; + + const bool disabled = flags&Is_Disabled; + + const bool drawLeft = flags&Draw_Left; + const bool drawRight = flags&Draw_Right; + const bool drawTop = flags&Draw_Top; + const bool drawBottom = flags&Draw_Bottom; + const bool roundUpperLeft = flags&Round_UpperLeft; + const bool roundUpperRight = flags&Round_UpperRight; + const bool roundBottomLeft = flags&Round_BottomLeft; + const bool roundBottomRight = flags&Round_BottomRight; + const bool sunken = flags&Is_Sunken; + const bool horizontal = flags&Is_Horizontal; + bool highlight = false, + highlightLeft = false, + highlightRight = false, + highlightTop = false, + highlightBottom = false; + // only highlight if not sunken & not disabled... + if(!sunken && !disabled) { + highlight = (flags&Is_Highlight); + highlightLeft = (flags&Highlight_Left); + highlightRight = (flags&Highlight_Right); + highlightTop = (flags&Highlight_Top); + highlightBottom = (flags&Highlight_Bottom); + } + + QColor baseColor = alphaBlendColors(backgroundColor, disabled?backgroundColor:buttonColor, 10); + if (disabled) { + intensity = 2; + } else if (highlight) { + // blend this _slightly_ with the background + baseColor = alphaBlendColors(baseColor, highlightColor, 240); + } else if (sunken) { + // enforce a common sunken-style... + baseColor = baseColor.dark(110+intensity); + intensity = _contrast/2; + } +// some often needed colors... + // 1 more intensive than 2 and 3. + const QColor colorTop1 = alphaBlendColors(baseColor, + sunken?baseColor.dark(100+intensity*2):baseColor.light(100+intensity*2), 80); + const QColor colorTop2 = alphaBlendColors(baseColor, + sunken?baseColor.dark(100+intensity):baseColor.light(100+intensity), 80); + const QColor colorBottom1 = alphaBlendColors(baseColor, + sunken?baseColor.light(100+intensity*2):baseColor.dark(100+intensity*2), 80); + const QColor colorBottom2 = alphaBlendColors(baseColor, + sunken?baseColor.light(100+intensity):baseColor.dark(100+intensity), 80); + +// sides + if (drawLeft) { + if (horizontal) { + int height = r.height(); + if (roundUpperLeft || !drawTop) height--; + if (roundBottomLeft || !drawBottom) height--; + renderGradient(p, QRect(r.left(), (roundUpperLeft&&drawTop)?r.top()+1:r.top(), 1, height), + colorTop1, baseColor); + } else { + p->setPen(colorTop1 ); + p->drawLine(r.left(), (roundUpperLeft&&drawTop)?r.top()+1:r.top(), + r.left(), (roundBottomLeft&&drawBottom)?r.bottom()-1:r.bottom() ); + } + } + if (drawRight) { + if (horizontal) { + int height = r.height(); + // TODO: there's still a bogus in it: when edge4 is Thick + // and we don't whant to draw the Top, we have a unpainted area + if (roundUpperRight || !drawTop) height--; + if (roundBottomRight || !drawBottom) height--; + renderGradient(p, QRect(r.right(), (roundUpperRight&&drawTop)?r.top()+1:r.top(), 1, height), + baseColor, colorBottom1); + } else { + p->setPen(colorBottom1 ); + p->drawLine(r.right(), (roundUpperRight&&drawTop)?r.top()+1:r.top(), + r.right(), (roundBottomRight&&drawBottom)?r.bottom()-1:r.bottom() ); + } + } + if (drawTop) { + if (horizontal) { + p->setPen(colorTop1 ); + p->drawLine((roundUpperLeft&&drawLeft)?r.left()+1:r.left(), r.top(), + (roundUpperRight&&drawRight)?r.right()-1:r.right(), r.top() ); + } else { + int width = r.width(); + if (roundUpperLeft || !drawLeft) width--; + if (roundUpperRight || !drawRight) width--; + renderGradient(p, QRect((roundUpperLeft&&drawLeft)?r.left()+1:r.left(), r.top(), width, 1), + colorTop1, colorTop2); + } + } + if (drawBottom) { + if (horizontal) { + p->setPen(colorBottom1 ); + p->drawLine((roundBottomLeft&&drawLeft)?r.left()+1:r.left(), r.bottom(), + (roundBottomRight&&drawRight)?r.right()-1:r.right(), r.bottom() ); + } else { + int width = r.width(); + if (roundBottomLeft || !drawLeft) width--; + if (roundBottomRight || !drawRight) width--; + renderGradient(p, QRect((roundBottomLeft&&drawLeft)?r.left()+1:r.left(), r.bottom(), width, 1), + colorBottom2, colorBottom1); + } + } + +// button area... + int width = r.width(); + int height = r.height(); + if (drawLeft) width--; + if (drawRight) width--; + if (drawTop) height--; + if (drawBottom) height--; + renderGradient(p, QRect(drawLeft?r.left()+1:r.left(), drawTop?r.top()+1:r.top(), width, height), + colorTop2, colorBottom2, horizontal); + + +// highlighting... + if(highlightTop) { + p->setPen(alphaBlendColors(colorTop1 , highlightColor, 80) ); + p->drawLine((roundUpperLeft&&drawLeft)?r.left()+1:r.left(), r.top(), + (roundUpperRight&&drawRight)?r.right()-1:r.right(), r.top() ); + p->setPen(alphaBlendColors(colorTop2 , highlightColor, 150) ); + p->drawLine(highlightLeft?r.left()+1:r.left(), r.top()+1, + highlightRight?r.right()-1:r.right(), r.top()+1 ); + } + if(highlightBottom) { + p->setPen(alphaBlendColors(colorBottom1 , highlightColor, 80) ); + p->drawLine((roundBottomLeft&&drawLeft)?r.left()+1:r.left(), r.bottom(), + (roundBottomRight&&drawRight)?r.right()-1:r.right(), r.bottom() ); + p->setPen(alphaBlendColors(colorBottom2 , highlightColor, 150) ); + p->drawLine(highlightLeft?r.left()+1:r.left(), r.bottom()-1, + highlightRight?r.right()-1:r.right(), r.bottom()-1 ); + } + if(highlightLeft) { + p->setPen(alphaBlendColors(colorTop1 , highlightColor, 80) ); + p->drawLine(r.left(), (roundUpperLeft&&drawTop)?r.top()+1:r.top(), + r.left(), (roundBottomLeft&&drawBottom)?r.bottom()-1:r.bottom() ); + p->setPen(alphaBlendColors(colorTop2 , highlightColor, 150) ); + p->drawLine(r.left()+1, highlightTop?r.top()+1:r.top(), + r.left()+1, highlightBottom?r.bottom()-1:r.bottom() ); + } + if(highlightRight) { + p->setPen(alphaBlendColors(colorBottom1 , highlightColor, 80) ); + p->drawLine(r.right(), (roundUpperRight&&drawTop)?r.top()+1:r.top(), + r.right(), (roundBottomRight&&drawBottom)?r.bottom()-1:r.bottom() ); + p->setPen(alphaBlendColors(colorBottom2 , highlightColor, 150) ); + p->drawLine(r.right()-1, highlightTop?r.top()+1:r.top(), + r.right()-1, highlightBottom?r.bottom()-1:r.bottom() ); + } +} + +void PlastikStyle::renderPixel(QPainter *p, + const QPoint &pos, + const int alpha, + const QColor &color, + const QColor &background, + bool fullAlphaBlend) const +{ + if(fullAlphaBlend) + // full alpha blend: paint into an image with alpha buffer and convert to a pixmap ... + { + QRgb rgb = color.rgb(); + // generate a quite unique key -- use the unused width field to store the alpha value. + CacheEntry search(cAlphaDot, alpha, 0, rgb); + int key = search.key(); + + CacheEntry *cacheEntry; + if( (cacheEntry = pixmapCache->find(key)) ) { + if( search == *cacheEntry ) { // match! we can draw now... + if(cacheEntry->pixmap) + p->drawPixmap(pos, *(cacheEntry->pixmap) ); + return; + } else { //Remove old entry in case of a conflict! + pixmapCache->remove( key ); + } + } + + + QImage aImg(1,1,32); // 1x1 + aImg.setAlphaBuffer(true); + aImg.setPixel(0,0,qRgba(qRed(rgb),qGreen(rgb),qBlue(rgb),alpha)); + QPixmap *result = new QPixmap(aImg); + + p->drawPixmap(pos, *result); + + // add to the cache... + CacheEntry *toAdd = new CacheEntry(search); + toAdd->pixmap = result; + bool insertOk = pixmapCache->insert( key, toAdd, result->depth()/8); + if(!insertOk) + delete result; + } else + // don't use an alpha buffer: calculate the resulting color from the alpha value, the fg- and the bg-color. + { + QRgb rgb_a = color.rgb(); + QRgb rgb_b = background.rgb(); + int a = alpha; + if(a>255) a = 255; + if(a<0) a = 0; + int a_inv = 255 - a; + + QColor res = QColor( qRgb(qRed(rgb_b)*a_inv/255 + qRed(rgb_a)*a/255, + qGreen(rgb_b)*a_inv/255 + qGreen(rgb_a)*a/255, + qBlue(rgb_b)*a_inv/255 + qBlue(rgb_a)*a/255) ); + p->setPen(res); + p->drawPoint(pos); + } +} + +void PlastikStyle::renderButton(QPainter *p, + const QRect &r, + const QColorGroup &g, + bool sunken, + bool mouseOver, + bool horizontal, + bool enabled, + bool khtmlMode) const +{ + // small fix for the kicker buttons... + if(kickerMode) enabled = true; + + const QPen oldPen( p->pen() ); + + uint contourFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom; + if(!enabled) contourFlags|=Is_Disabled; + if(khtmlMode) contourFlags|=Draw_AlphaBlend; + + uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom; + if(horizontal) surfaceFlags|=Is_Horizontal; + if(!enabled) surfaceFlags|=Is_Disabled; + else { + if(sunken) surfaceFlags|=Is_Sunken; + else { + if(mouseOver) { + surfaceFlags|=Is_Highlight; + if(horizontal) { + surfaceFlags|=Highlight_Top; + surfaceFlags|=Highlight_Bottom; + } else { + surfaceFlags|=Highlight_Left; + surfaceFlags|=Highlight_Right; + } + } + } + } + + if (!flatMode) { + contourFlags |= Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight; + surfaceFlags |= Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight; + + renderContour(p, r, g.background(), getColor(g,ButtonContour), + contourFlags); + renderSurface(p, QRect(r.left()+1, r.top()+1, r.width()-2, r.height()-2), + g.background(), g.button(), getColor(g,MouseOverHighlight), _contrast, surfaceFlags); + } else { + renderContour(p, r, g.background(), g.button().dark(105+_contrast*3), + contourFlags); + renderSurface(p, QRect(r.left()+1, r.top()+1, r.width()-2, r.height()-2), + g.background(), g.button(), getColor(g,MouseOverHighlight), _contrast/2, surfaceFlags); + + flatMode = false; + } + + p->setPen(oldPen); +} + +void PlastikStyle::renderDot(QPainter *p, + const QPoint &point, + const QColor &baseColor, + const bool thick, + const bool sunken) const +{ + const QColor topColor = alphaBlendColors(baseColor, sunken?baseColor.dark(130):baseColor.light(150), 70); + const QColor bottomColor = alphaBlendColors(baseColor, sunken?baseColor.light(150):baseColor.dark(130), 70); + p->setPen(topColor ); + p->drawLine(point.x(), point.y(), point.x()+1, point.y()); + p->drawPoint(point.x(), point.y()+1); + p->setPen(bottomColor ); + if(thick) { + p->drawLine(point.x()+1, point.y()+2, point.x()+2, point.y()+2); + p->drawPoint(point.x()+2, point.y()+1); + } else { + p->drawPoint(point.x()+1, point.y()+1); + } +} + +void PlastikStyle::renderGradient(QPainter *painter, + const QRect &rect, + const QColor &c1, + const QColor &c2, + bool horizontal) const +{ + if((rect.width() <= 0)||(rect.height() <= 0)) + return; + + // generate a quite unique key for this surface. + CacheEntry search(cGradientTile, + horizontal ? 0 : rect.width(), + horizontal ? rect.height() : 0, + c1.rgb(), c2.rgb(), horizontal ); + int key = search.key(); + + CacheEntry *cacheEntry; + if( (cacheEntry = pixmapCache->find(key)) ) { + if( search == *cacheEntry ) { // match! we can draw now... + if(cacheEntry->pixmap) { + painter->drawTiledPixmap(rect, *(cacheEntry->pixmap) ); + } + return; + } else { + // Remove old entry in case of a conflict! + // This shouldn't happen very often, see comment in CacheEntry. + pixmapCache->remove(key); + } + } + + // there wasn't anything matching in the cache, create the pixmap now... + QPixmap *result = new QPixmap(horizontal ? 10 : rect.width(), + horizontal ? rect.height() : 10); + QPainter p(result); + + int r_w = result->rect().width(); + int r_h = result->rect().height(); + int r_x, r_y, r_x2, r_y2; + result->rect().coords(&r_x, &r_y, &r_x2, &r_y2); + + int rDiff, gDiff, bDiff; + int rc, gc, bc; + + register int x, y; + + rDiff = ( c2.red()) - (rc = c1.red()); + gDiff = ( c2.green()) - (gc = c1.green()); + bDiff = ( c2.blue()) - (bc = c1.blue()); + + register int rl = rc << 16; + register int gl = gc << 16; + register int bl = bc << 16; + + int rdelta = ((1<<16) / (horizontal ? r_h : r_w)) * rDiff; + int gdelta = ((1<<16) / (horizontal ? r_h : r_w)) * gDiff; + int bdelta = ((1<<16) / (horizontal ? r_h : r_w)) * bDiff; + + // these for-loops could be merged, but the if's in the inner loop + // would make it slow + if(horizontal) { + for ( y = 0; y < r_h; y++ ) { + rl += rdelta; + gl += gdelta; + bl += bdelta; + + p.setPen(QColor(rl>>16, gl>>16, bl>>16)); + p.drawLine(r_x, r_y+y, r_x2, r_y+y); + } + } else { + for( x = 0; x < r_w; x++) { + rl += rdelta; + gl += gdelta; + bl += bdelta; + + p.setPen(QColor(rl>>16, gl>>16, bl>>16)); + p.drawLine(r_x+x, r_y, r_x+x, r_y2); + } + } + + p.end(); + + // draw the result... + painter->drawTiledPixmap(rect, *result); + + // insert into cache using the previously created key. + CacheEntry *toAdd = new CacheEntry(search); + toAdd->pixmap = result; + bool insertOk = pixmapCache->insert( key, toAdd, result->width()*result->height()*result->depth()/8 ); + + if(!insertOk) + delete result; +} + +void PlastikStyle::renderPanel(QPainter *p, + const QRect &r, + const QColorGroup &g, + const bool pseudo3d, + const bool sunken) const +{ + int x, x2, y, y2, w, h; + r.rect(&x,&y,&w,&h); + r.coords(&x, &y, &x2, &y2); + + if (kickerMode && + p->device() && p->device()->devType() == QInternal::Widget && + QCString(static_cast<QWidget*>(p->device())->className()) == "FittsLawFrame") { + // Stolen wholesale from Keramik. I don't like it, but oh well. + if (sunken) { + const QCOORD corners[] = { x2, y, x2, y2, x, y2, x, y }; + p->setPen(g.background().dark()); + p->drawConvexPolygon(QPointArray(4, corners)); + p->setPen(g.background().light()); + p->drawPolyline(QPointArray(4, corners), 0, 3); + } else { + const QCOORD corners[] = { x, y2, x, y, x2, y, x2, y2 }; + p->setPen(g.background().dark()); + p->drawPolygon(QPointArray(4, corners)); + p->setPen(g.background().light()); + p->drawPolyline(QPointArray(4, corners), 0, 3); + } + } else { + renderContour(p, r, g.background(), getColor(g, PanelContour) ); + + if(pseudo3d) { + if (sunken) { + p->setPen(getColor(g, PanelDark) ); + } else { + p->setPen(getColor(g, PanelLight) ); + } + p->drawLine(r.left()+2, r.top()+1, r.right()-2, r.top()+1); + p->drawLine(r.left()+1, r.top()+2, r.left()+1, r.bottom()-2); + if (sunken) { + p->setPen(getColor(g, PanelLight) ); + } else { + p->setPen(getColor(g, PanelDark) ); + } + p->drawLine(r.left()+2, r.bottom()-1, r.right()-2, r.bottom()-1); + p->drawLine(r.right()-1, r.top()+2, r.right()-1, r.bottom()-2); + } + } +} + +void PlastikStyle::renderMenuBlendPixmap( KPixmap &pix, const QColorGroup &cg, + const QPopupMenu* /* popup */ ) const +{ + pix.fill( cg.background().light(105) ); +} + +void PlastikStyle::renderTab(QPainter *p, + const QRect &r, + const QColorGroup &g, + bool mouseOver, + const bool selected, + const bool bottom, + const TabPosition pos, + const bool triangular, + const bool cornerWidget) const +{ + const bool reverseLayout = QApplication::reverseLayout(); + + const bool isFirst = (pos == First) || (pos == Single); + const bool isLast = (pos == Last); + const bool isSingle = (pos == Single); + + if (selected) { + // is selected + + // the top part of the tab which is nearly the same for all positions + QRect Rc; // contour + if (!bottom) { + if (isFirst && !cornerWidget && !reverseLayout) { + Rc = QRect(r.x(), r.y(), r.width()-1, r.height()-3); + } else if (isFirst && !cornerWidget && reverseLayout) { + Rc = QRect(r.x()+1, r.y(), r.width()-1, r.height()-3); + } else { + Rc = QRect(r.x()+1, r.y(), r.width()-2, r.height()-3); + } + } else { + if (isFirst && !cornerWidget && !reverseLayout) { + Rc = QRect(r.x(), r.y()+3, r.width()-1, r.height()-3); + } else if (isFirst && !cornerWidget && reverseLayout) { + Rc = QRect(r.x()+1, r.y()+3, r.width()-1, r.height()-3); + } else { + Rc = QRect(r.x()+1, r.y()+3, r.width()-2, r.height()-3); + } + } + const QRect Rs(Rc.x()+1, bottom?Rc.y():Rc.y()+1, Rc.width()-2, Rc.height()-1); // the resulting surface + // the area where the fake border shoudl appear + const QRect Rb(r.x(), bottom?r.top():Rc.bottom()+1, r.width(), r.height()-Rc.height() ); + + uint contourFlags = Draw_Left|Draw_Right; + if(!bottom) { + contourFlags |= Draw_Top|Round_UpperLeft|Round_UpperRight; + } else { + contourFlags |= Draw_Bottom|Round_BottomLeft|Round_BottomRight; + } + renderContour(p, Rc, + g.background(), getColor(g,PanelContour), + contourFlags); + + // surface + if(!bottom) { + p->setPen(getColor(g,PanelLight) ); + p->drawLine(Rs.x()+1, Rs.y(), Rs.right()-1, Rs.y() ); + renderGradient(p, QRect(Rs.x(), Rs.y()+1, 1, Rs.height()-1), + getColor(g,PanelLight), getColor(g,PanelLight2)); + renderGradient(p, QRect(Rs.right(), Rs.y()+1, 1, Rs.height()-1), + getColor(g,PanelDark), getColor(g,PanelDark2)); + } else { + p->setPen(alphaBlendColors(g.background(), g.background().dark(160), 100) ); + p->drawLine(Rs.x()+1, Rs.bottom(), Rs.right()-1, Rs.bottom() ); + renderGradient(p, QRect(Rs.x(), Rs.y(), 1, Rs.height()-1), + getColor(g,PanelLight), getColor(g,PanelLight2)); + renderGradient(p, QRect(Rs.right(), Rs.y(), 1, Rs.height()-1), + getColor(g,PanelDark), getColor(g,PanelDark2)); + } + + // some "position specific" paintings... + // draw parts of the inactive tabs around... + if(!isSingle) { + p->setPen(alphaBlendColors(g.background(), getColor(g, ButtonContour), 50) ); + if( (!isFirst&&!reverseLayout) || (!isLast&&reverseLayout) ) { + p->drawPoint(r.left(), bottom?(triangular?r.bottom()-2:r.bottom()-3):(triangular?r.top()+2:r.top()+3) ); + renderSurface(p, QRect(r.left(), bottom?r.top()+3:(triangular?r.top()+3:r.top()+4), 1, (triangular?r.height()-6:r.height()-7) ), + g.background(), g.button(), getColor(g,MouseOverHighlight), _contrast, + Draw_Top|Draw_Bottom|Is_Horizontal); + } + if( (!isLast&&!reverseLayout) || (!isFirst&&reverseLayout) ) { + p->drawPoint(r.right(), bottom?(triangular?r.bottom()-2:r.bottom()-3):(triangular?r.top()+2:r.top()+3) ); + renderSurface(p, QRect(r.right(), bottom?r.top()+3:(triangular?r.top()+3:r.top()+4), 1, (triangular?r.height()-6:r.height()-7) ), + g.background(), g.button(), getColor(g,MouseOverHighlight), _contrast, + Draw_Top|Draw_Bottom|Is_Horizontal); + } + } + // left connection from the panel border to the tab. :) + if(isFirst && !reverseLayout && !cornerWidget) { + p->setPen(alphaBlendColors(g.background(), getColor(g,PanelContour), 50) ); + p->drawLine(Rb.x(), Rb.y(), Rb.x(), Rb.bottom() ); + p->setPen(getColor(g,PanelLight) ); + p->drawLine(Rb.x()+1, Rb.y(), Rb.x()+1, Rb.bottom() ); + } else if(isFirst && reverseLayout && !cornerWidget) { + p->setPen(alphaBlendColors(g.background(), getColor(g,PanelContour), 50) ); + p->drawLine(Rb.right(), Rb.y(), Rb.right(), Rb.bottom() ); + p->setPen(getColor(g,PanelDark) ); + p->drawLine(Rb.right()-1, Rb.y(), Rb.right()-1, Rb.bottom() ); + } + // rounded connections to the panel... + if(!bottom) { + // left + if( (!isFirst && !reverseLayout) || (reverseLayout) || (isFirst && !reverseLayout && cornerWidget) ) { + p->setPen( alphaBlendColors(g.background(), getColor(g,PanelContour), 50) ); + p->drawPoint(Rb.x(), Rb.y()); + p->setPen( alphaBlendColors(g.background(), getColor(g,PanelContour), 150) ); + p->drawPoint(Rb.x(), Rb.y()+1); + p->drawPoint(Rb.x()+1, Rb.y()); + } + // right + if( (!reverseLayout) || (!isFirst && reverseLayout) || (isFirst && reverseLayout && cornerWidget) ) { + p->setPen( alphaBlendColors(g.background(), getColor(g,PanelContour), 50) ); + p->drawPoint(Rb.right(), Rb.y()); + p->setPen( alphaBlendColors(g.background(), getColor(g,PanelContour), 150) ); + p->drawPoint(Rb.right(), Rb.y()+1); + p->drawPoint(Rb.right()-1, Rb.y()); + } + } else { + // left + if( (!isFirst && !reverseLayout) || (reverseLayout) || (isFirst && !reverseLayout && cornerWidget) ) { + p->setPen( alphaBlendColors(g.background(), getColor(g,PanelContour), 50) ); + p->drawPoint(Rb.x(), Rb.bottom()); + p->setPen( alphaBlendColors(g.background(), getColor(g,PanelContour), 150) ); + p->drawPoint(Rb.x(), Rb.bottom()-1); + p->drawPoint(Rb.x()+1, Rb.bottom()); + } + // right + if( (!reverseLayout) || (!isFirst && reverseLayout) || (isFirst && reverseLayout && cornerWidget) ) { + p->setPen( alphaBlendColors(g.background(), getColor(g,PanelContour), 50) ); + p->drawPoint(Rb.right(), Rb.bottom()); + p->setPen( alphaBlendColors(g.background(), getColor(g,PanelContour), 150) ); + p->drawPoint(Rb.right(), Rb.bottom()-1); + p->drawPoint(Rb.right()-1, Rb.bottom()); + } + } + + } else { + // inactive tabs + + // the top part of the tab which is nearly the same for all positions + QRect Rc; // contour + if (isFirst&&reverseLayout ) { + Rc = QRect(r.x()+1, (bottom?r.y()+2:(triangular?r.y()+2:r.y()+3)), r.width()-2, (triangular?r.height()-4:r.height()-5) ); + } else { + Rc = QRect(r.x()+1, (bottom?r.y()+2:(triangular?r.y()+2:r.y()+3)), r.width()-1, (triangular?r.height()-4:r.height()-5) ); + } + QRect Rs; // the resulting surface + if ( (isFirst&&!reverseLayout) || (isLast&&reverseLayout) ) { + Rs = QRect(Rc.x()+1, bottom?Rc.y():Rc.y()+1, Rc.width()-2, Rc.height()-1); + } else { + Rs = QRect(Rc.x(), bottom?Rc.y():Rc.y()+1, Rc.width()-1, Rc.height()-1); + } + // the area where the fake border shoudl appear + const QRect Rb(r.x(), bottom?r.y():Rc.bottom()+1, r.width(), 2 ); + + uint contourFlags; + if(!bottom) { + if ( (isFirst&&!reverseLayout) || (isLast&&reverseLayout) ) { + contourFlags = Draw_Left|Draw_Right|Draw_Top|Round_UpperLeft; + } else if ( (isLast&&!reverseLayout) || (isFirst&&reverseLayout) ) { + contourFlags = Draw_Right|Draw_Top|Round_UpperRight; + } else { + contourFlags = Draw_Right|Draw_Top; + } + } else { + if ( (isFirst&&!reverseLayout) || (isLast&&reverseLayout) ) { + contourFlags = Draw_Left|Draw_Right|Draw_Bottom|Round_BottomLeft; + } else if ( (isLast&&!reverseLayout) || (isFirst&&reverseLayout) ) { + contourFlags = Draw_Right|Draw_Bottom|Round_BottomRight; + } else { + contourFlags = Draw_Right|Draw_Bottom; + } + } + renderContour(p, Rc, + g.background(), getColor(g, ButtonContour), + contourFlags); + + uint surfaceFlags = Is_Horizontal; + if(mouseOver) { + surfaceFlags |= (bottom?Highlight_Bottom:Highlight_Top); + surfaceFlags |= Is_Highlight; + } + if ( (isFirst&&!reverseLayout) || (isLast&&reverseLayout) ) { + if(!bottom) + surfaceFlags |= Draw_Left|Draw_Top|Draw_Bottom|Round_UpperLeft; + else + surfaceFlags |= Draw_Left|Draw_Top|Draw_Bottom|Round_BottomLeft; + } else if ( (isLast&&!reverseLayout) || (isFirst&&reverseLayout) ) { + if(!bottom) + surfaceFlags |= Draw_Right|Draw_Top|Draw_Bottom|Round_UpperRight; + else + surfaceFlags |= Draw_Right|Draw_Top|Draw_Bottom|Round_BottomRight; + } else { + surfaceFlags |= Draw_Top|Draw_Bottom; + } + renderSurface(p, Rs, + g.background(), g.button(), getColor(g,MouseOverHighlight), _contrast, + surfaceFlags); + + // some "position specific" paintings... + // fake parts of the panel border + if(!bottom) { + p->setPen(alphaBlendColors(g.background(), getColor(g,PanelContour), 50) ); + p->drawLine(Rb.x(), Rb.y(), ((isLast&&!reverseLayout)||(isFirst&&reverseLayout&&cornerWidget))?Rb.right():Rb.right()-1, Rb.y()); + p->setPen(getColor(g,PanelLight) ); + p->drawLine(Rb.x(), Rb.y()+1, ((isLast&&!reverseLayout)||(isFirst&&reverseLayout&&cornerWidget))?Rb.right():Rb.right()-1, Rb.y()+1 ); + } else { + p->setPen(alphaBlendColors(g.background(), getColor(g,PanelContour), 50) ); + p->drawLine(Rb.x(), Rb.bottom(), ((isLast&&!reverseLayout)||(isFirst&&reverseLayout&&cornerWidget))?Rb.right():Rb.right()-1, Rb.bottom()); + p->setPen(getColor(g,PanelDark) ); + p->drawLine(Rb.x(), Rb.bottom()-1, ((isLast&&!reverseLayout)||(isFirst&&reverseLayout&&cornerWidget))?Rb.right():Rb.right()-1, Rb.bottom()-1 ); + } + // fake the panel border edge for tabs which are aligned left-most + // (i.e. only if there is no widget in the corner of the tabwidget!) + if(isFirst&&!reverseLayout&&!cornerWidget) + // normal layout + { + if (!bottom) { + p->setPen(alphaBlendColors(g.background(), getColor(g,PanelContour), 50) ); + p->drawPoint(Rb.x()+1, Rb.y()+1 ); + p->setPen(alphaBlendColors(g.background(), getColor(g,PanelContour), 150) ); + p->drawPoint(Rb.x(), Rb.y()+1 ); + p->setPen(g.background() ); + p->drawPoint(Rb.x(), Rb.y() ); + p->setPen(alphaBlendColors( alphaBlendColors(g.background(), getColor(g, ButtonContour), 50), getColor(g,PanelContour), 150) ); + p->drawPoint(Rb.x()+1, Rb.y() ); + } else { + p->setPen(alphaBlendColors(g.background(), getColor(g,PanelContour), 50) ); + p->drawPoint(Rb.x()+1, Rb.bottom()-1 ); + p->setPen(alphaBlendColors(g.background(), getColor(g,PanelContour), 150) ); + p->drawPoint(Rb.x(), Rb.bottom()-1 ); + p->setPen(g.background() ); + p->drawPoint(Rb.x(), Rb.bottom() ); + p->setPen(alphaBlendColors( alphaBlendColors(g.background(), getColor(g, ButtonContour), 50), getColor(g,PanelContour), 150) ); + p->drawPoint(Rb.x()+1, Rb.bottom() ); + } + } else if(isFirst&&reverseLayout&&!cornerWidget) + // reverse layout + { + if (!bottom) { + p->setPen(alphaBlendColors(g.background(), getColor(g,PanelContour), 50) ); + p->drawPoint(Rb.right()-1, Rb.y()+1 ); + p->setPen(alphaBlendColors(g.background(), getColor(g,PanelContour), 150) ); + p->drawPoint(Rb.right(), Rb.y()+1 ); + p->setPen(g.background() ); + p->drawPoint(Rb.right(), Rb.y() ); + p->setPen(alphaBlendColors( alphaBlendColors(g.background(), getColor(g, ButtonContour), 50), getColor(g,PanelContour), 150) ); + p->drawPoint(Rb.right()-1, Rb.y() ); + } else { + p->setPen(alphaBlendColors(g.background(), getColor(g,PanelContour), 50) ); + p->drawPoint(Rb.right()-1, Rb.bottom()-1 ); + p->setPen(alphaBlendColors(g.background(), getColor(g,PanelContour), 150) ); + p->drawPoint(Rb.right(), Rb.bottom()-1 ); + p->setPen(g.background() ); + p->drawPoint(Rb.right(), Rb.bottom() ); + p->setPen(alphaBlendColors( alphaBlendColors(g.background(), getColor(g, ButtonContour), 50), getColor(g,PanelContour), 150) ); + p->drawPoint(Rb.right()-1, Rb.bottom() ); + } + } + } +} + +void PlastikStyle::drawKStylePrimitive(KStylePrimitive kpe, + QPainter *p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt) const +{ + // some "global" vars... + const bool enabled = (flags & Style_Enabled); + +// SLIDER +// ------ + switch( kpe ) { + case KPE_SliderGroove: { + const QSlider* slider = (const QSlider*)widget; + bool horizontal = slider->orientation() == Horizontal; + + if (horizontal) { + int center = r.y()+r.height()/2; + renderContour(p, QRect(r.left(), center-2, r.width(), 4), + cg.background(), cg.background().dark(enabled?150:130), + Draw_Left|Draw_Right|Draw_Top|Draw_Bottom); + } else { + int center = r.x()+r.width()/2; + renderContour(p, QRect(center-2, r.top(), 4, r.height()), + cg.background(), cg.background().dark(enabled?150:130), + Draw_Left|Draw_Right|Draw_Top|Draw_Bottom); + } + break; + } + + case KPE_SliderHandle: { + const QSlider* slider = (const QSlider*)widget; + bool horizontal = slider->orientation() == Horizontal; + + const bool pressed = (flags&Style_Active); + const WidgetState s = enabled?(pressed?IsPressed:IsEnabled):IsDisabled; + const QColor contour = getColor(cg,DragButtonContour,s), + surface = getColor(cg,DragButtonSurface,s); + + int xcenter = (r.left()+r.right()) / 2; + int ycenter = (r.top()+r.bottom()) / 2; + + if (horizontal) { + renderContour(p, QRect(xcenter-5, ycenter-6, 11, 10), + cg.background(), contour, + Draw_Left|Draw_Right|Draw_Top|Round_UpperLeft|Round_UpperRight); + + // manual contour: vertex + p->setPen(alphaBlendColors(cg.background(), contour, 50) ); + p->drawPoint(xcenter-5+1, ycenter+4); + p->drawPoint(xcenter+5-1, ycenter+4); + p->drawPoint(xcenter-5+2, ycenter+5); + p->drawPoint(xcenter+5-2, ycenter+5); + p->drawPoint(xcenter-5+3, ycenter+6); + p->drawPoint(xcenter+5-3, ycenter+6); + p->drawPoint(xcenter-5+4, ycenter+7); + p->drawPoint(xcenter+5-4, ycenter+7); + // anti-aliasing of the contour... sort of. :) + p->setPen(alphaBlendColors(cg.background(), contour, 80) ); + p->drawPoint(xcenter, ycenter+8); + p->setPen(alphaBlendColors(cg.background(), contour, 150) ); + p->drawPoint(xcenter-5, ycenter+4); + p->drawPoint(xcenter+5, ycenter+4); + p->drawPoint(xcenter-5+1, ycenter+5); + p->drawPoint(xcenter+5-1, ycenter+5); + p->drawPoint(xcenter-5+2, ycenter+6); + p->drawPoint(xcenter+5-2, ycenter+6); + p->drawPoint(xcenter-5+3, ycenter+7); + p->drawPoint(xcenter+5-3, ycenter+7); + p->setPen(alphaBlendColors(cg.background(), contour, 190) ); + p->drawPoint(xcenter-5+4, ycenter+8); + p->drawPoint(xcenter+5-4, ycenter+8); + + + QRegion mask(xcenter-4, ycenter-5, 9, 13); + mask -= QRegion(xcenter-4, ycenter+4, 1, 4); + mask -= QRegion(xcenter-3, ycenter+5, 1, 3); + mask -= QRegion(xcenter-2, ycenter+6, 1, 2); + mask -= QRegion(xcenter-1, ycenter+7, 1, 1); + mask -= QRegion(xcenter+1, ycenter+7, 1, 1); + mask -= QRegion(xcenter+2, ycenter+6, 1, 2); + mask -= QRegion(xcenter+3, ycenter+5, 1, 3); + mask -= QRegion(xcenter+4, ycenter+4, 1, 4); + p->setClipRegion(mask); + uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Round_UpperLeft|Round_UpperRight|Is_Horizontal; + if(!enabled) + surfaceFlags |= Is_Disabled; + renderSurface(p, QRect(xcenter-4, ycenter-5, 9, 13), + cg.background(), surface, getColor(cg,MouseOverHighlight), + _contrast+3, surfaceFlags); + renderDot(p, QPoint(xcenter-3, ycenter-3), surface, false, true ); + renderDot(p, QPoint(xcenter+2, ycenter-3), surface, false, true ); + p->setClipping(false); + } else { + renderContour(p, QRect(xcenter-6, ycenter-5, 10, 11), + cg.background(), contour, + Draw_Left|Draw_Top|Draw_Bottom|Round_UpperLeft|Round_BottomLeft); + + // manual contour: vertex + p->setPen(alphaBlendColors(cg.background(), contour, 50) ); + p->drawPoint(xcenter+4, ycenter-5+1); + p->drawPoint(xcenter+4, ycenter+5-1); + p->drawPoint(xcenter+5, ycenter-5+2); + p->drawPoint(xcenter+5, ycenter+5-2); + p->drawPoint(xcenter+6, ycenter-5+3); + p->drawPoint(xcenter+6, ycenter+5-3); + p->drawPoint(xcenter+7, ycenter-5+4); + p->drawPoint(xcenter+7, ycenter+5-4); + // anti-aliasing. ...sort of :) + p->setPen(alphaBlendColors(cg.background(), contour, 80) ); + p->drawPoint(xcenter+8, ycenter); + p->setPen(alphaBlendColors(cg.background(), contour, 150) ); + p->drawPoint(xcenter+4, ycenter-5); + p->drawPoint(xcenter+4, ycenter+5); + p->drawPoint(xcenter+5, ycenter-5+1); + p->drawPoint(xcenter+5, ycenter+5-1); + p->drawPoint(xcenter+6, ycenter-5+2); + p->drawPoint(xcenter+6, ycenter+5-2); + p->drawPoint(xcenter+7, ycenter-5+3); + p->drawPoint(xcenter+7, ycenter+5-3); + p->setPen(alphaBlendColors(cg.background(), contour, 190) ); + p->drawPoint(xcenter+8, ycenter-5+4); + p->drawPoint(xcenter+8, ycenter+5-4); + + QRegion mask(xcenter-5, ycenter-4, 13, 9); + mask -= QRegion(xcenter+4, ycenter-4, 4, 1); + mask -= QRegion(xcenter+5, ycenter-3, 3, 1); + mask -= QRegion(xcenter+6, ycenter-2, 2, 1); + mask -= QRegion(xcenter+7, ycenter-1, 1, 1); + mask -= QRegion(xcenter+7, ycenter+1, 1, 1); + mask -= QRegion(xcenter+6, ycenter+2, 2, 1); + mask -= QRegion(xcenter+5, ycenter+3, 3, 1); + mask -= QRegion(xcenter+4, ycenter+4, 4, 1); + p->setClipRegion(mask); + uint surfaceFlags = Draw_Left|Draw_Top|Draw_Bottom|Round_UpperLeft|Round_BottomLeft| + Round_UpperRight|Is_Horizontal; + if(!enabled) + surfaceFlags |= Is_Disabled; + renderSurface(p, QRect(xcenter-5, ycenter-4, 13, 9), + cg.background(), surface, getColor(cg,MouseOverHighlight), + _contrast+3, surfaceFlags); + renderDot(p, QPoint(xcenter-3, ycenter-3), surface, false, true ); + renderDot(p, QPoint(xcenter-3, ycenter+2), surface, false, true ); + p->setClipping(false); + } + + break; + } + + case KPE_ListViewExpander: { + int radius = (r.width() - 4) / 2; + int centerx = r.x() + r.width()/2; + int centery = r.y() + r.height()/2; + + renderContour(p, r, cg.base(), cg.dark(), Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight ); + + p->setPen( cg.text() ); + if(!_drawTriangularExpander) + { + // plus or minus + p->drawLine( centerx - radius, centery, centerx + radius, centery ); + if ( flags & Style_On ) // Collapsed = On + p->drawLine( centerx, centery - radius, centerx, centery + radius ); + } else if(_drawTriangularExpander) { + if( flags & Style_On ) + drawPrimitive(PE_ArrowRight, p, QRect(r.x()+1,r.y()+1,r.width(),r.height()), cg,ButtonContour, flags); + if( flags & Style_Off ) + drawPrimitive(PE_ArrowDown, p, QRect(r.x()+1,r.y()+1,r.width(),r.height()), cg,ButtonContour, flags); + } + + break; + } + + // copied and slightly modified from KStyle. + case KPE_ListViewBranch: { + // Typical Windows style listview branch element (dotted line). + + // Create the dotline pixmaps if not already created + if ( !verticalLine ) + { + // make 128*1 and 1*128 bitmaps that can be used for + // drawing the right sort of lines. + verticalLine = new QBitmap( 1, 129, true ); + horizontalLine = new QBitmap( 128, 1, true ); + QPointArray a( 64 ); + QPainter p2; + p2.begin( verticalLine ); + + int i; + for( i=0; i < 64; i++ ) + a.setPoint( i, 0, i*2+1 ); + p2.setPen( color1 ); + p2.drawPoints( a ); + p2.end(); + QApplication::flushX(); + verticalLine->setMask( *verticalLine ); + + p2.begin( horizontalLine ); + for( i=0; i < 64; i++ ) + a.setPoint( i, i*2+1, 0 ); + p2.setPen( color1 ); + p2.drawPoints( a ); + p2.end(); + QApplication::flushX(); + horizontalLine->setMask( *horizontalLine ); + } + + p->setPen( cg.mid() ); + + if (flags & Style_Horizontal) + { + int point = r.x(); + int other = r.y(); + int end = r.x()+r.width(); + int thickness = r.height(); + + while( point < end ) + { + int i = 128; + if ( i+point > end ) + i = end-point; + p->drawPixmap( point, other, *horizontalLine, 0, 0, i, thickness ); + point += i; + } + + } else { + int point = r.y(); + int other = r.x(); + int end = r.y()+r.height(); + int thickness = r.width(); + int pixmapoffset = (flags & Style_NoChange) ? 0 : 1; // ### Hackish + + while( point < end ) + { + int i = 128; + if ( i+point > end ) + i = end-point; + p->drawPixmap( other, point, *verticalLine, 0, pixmapoffset, thickness, i ); + point += i; + } + } + + break; + } + + default: + KStyle::drawKStylePrimitive(kpe, p, widget, r, cg, flags, opt); + } +} + + +void PlastikStyle::drawPrimitive(PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption &opt ) const +{ + bool down = flags & Style_Down; + bool on = flags & Style_On; + bool sunken = flags & Style_Sunken; + bool horiz = flags & Style_Horizontal; + const bool enabled = flags & Style_Enabled; + const bool mouseOver = flags & Style_MouseOver; + + bool hasFocus = flags & Style_HasFocus; + + int x = r.x(); + int y = r.y(); + int w = r.width(); + int h = r.height(); + + int x2, y2; + r.coords(&x, &y, &x2, &y2); + + switch(pe) { + // BUTTONS + // ------- + case PE_FocusRect: { + if(_drawFocusRect) + p->drawWinFocusRect( r ); + break; + } + + case PE_HeaderSection: { + // the taskbar buttons seems to be painted with PE_HeaderSection but I + // want them look like normal buttons (at least for now. :) ) + if(!kickerMode) { + // detect if this is the left most header item + bool isFirst = false; + QHeader *header = dynamic_cast<QHeader*>(p->device() ); + if (header) { + isFirst = header->mapToIndex(header->sectionAt(r.x() ) ) == 0; + } + + uint contourFlags = Draw_Right|Draw_Top|Draw_Bottom; + if (isFirst) + contourFlags |= Draw_Left; + if(!enabled) contourFlags|=Is_Disabled; + renderContour(p, r, cg.background(), getColor(cg,ButtonContour), + contourFlags); + + uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Is_Horizontal; + if(!enabled) surfaceFlags|=Is_Disabled; + else { + if(on||down) surfaceFlags|=Is_Sunken; + else { + if(mouseOver) { + surfaceFlags|=Is_Highlight|Highlight_Top|Highlight_Bottom; + } + } + } + renderSurface(p, QRect(isFirst?r.left()+1:r.left(), r.top()+1, isFirst?r.width()-2:r.width()-1, r.height()-2), + cg.background(), cg.button(), getColor(cg,MouseOverHighlight), _contrast, + surfaceFlags); + + break; + } + } + case PE_ButtonBevel: + case PE_ButtonTool: + case PE_ButtonDropDown: + case PE_ButtonCommand: { + bool khtmlMode = opt.isDefault() ? false : khtmlWidgets.contains(opt.widget()); + renderButton(p, r, cg, (on||down), mouseOver, true, enabled, khtmlMode ); + break; + } + + case PE_ButtonDefault: { + uint contourFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom| + Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight; + if(!enabled) contourFlags|=Is_Disabled; + renderContour(p, r, cg.background(), cg.background().dark(120), + contourFlags); + break; + } + + case PE_SpinWidgetPlus: + case PE_SpinWidgetMinus: { + p->setPen( cg.buttonText() ); + + int l = QMIN( w-2, h-2 ); + // make the length even so that we get a nice symmetric plus... + if(l%2 != 0) + --l; + QPoint c = r.center(); + + p->drawLine( c.x()-l/2, c.y(), c.x()+l/2, c.y() ); + if ( pe == PE_SpinWidgetPlus ) { + p->drawLine( c.x(), c.y()-l/2, c.x(), c.y()+l/2 ); + } + break; + } + + case PE_ScrollBarSlider: { + const WidgetState s = enabled?(down?IsPressed:IsEnabled):IsDisabled; + const QColor surface = getColor(cg, DragButtonSurface, s); + + uint contourFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom; + if(!enabled) contourFlags|=Is_Disabled; + renderContour(p, r, cg.background(), getColor(cg, DragButtonContour, s), + contourFlags); + + uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom; + if(horiz) surfaceFlags|=Is_Horizontal; + if(!enabled) surfaceFlags|=Is_Disabled; + if(r.height() >= 4) + renderSurface(p, QRect(r.left()+1, r.top()+1, r.width()-2, r.height()-2), + cg.background(), surface, cg.background(), + _contrast+3, surfaceFlags); + + // set contour-like color for the case _scrollBarLines is set and we paint lines instead of dots. + p->setPen(alphaBlendColors(cg.background(), surface.dark(enabled?140:120), 50) ); + + const int d = 4; + int n = ((horiz?r.width():r.height())-8)/d; + if(n>5) n=5; + if(!horiz) { + for(int j = 0; j < n; j++) { + int yPos = r.center().y()-(n*d)/2+d*j+1; + if(_scrollBarLines) + p->drawLine(r.x()+1, yPos, r.right()-1, yPos); + else + { + for(int k = 3; k <= 13; k+=4) { + renderDot(p, QPoint(k, yPos), surface, false, true ); + } + } + } + } else { + for(int j = 0; j < n; j++) { + int xPos = r.center().x()-(n*d)/2+d*j+1; + if(_scrollBarLines) + p->drawLine(xPos, r.y()+1, xPos, r.bottom()-1); + else + { + for(int k = 3; k <= 13; k+=4) { + renderDot(p, QPoint(xPos, k), surface, false, true ); + } + } + } + } + + break; + } + + case PE_ScrollBarAddPage: + case PE_ScrollBarSubPage: { + // draw double buffered to avoid flicker... + QPixmap buffer; + if(flags & Style_Horizontal) { + buffer.resize(2, r.height() ); + } else { + buffer.resize(r.width(), 2 ); + } + QRect br(buffer.rect() ); + QPainter bp(&buffer); + + if (on || down) { + bp.fillRect(br, QBrush(cg.mid().dark())); + } else { + if(flags & Style_Horizontal) { + bp.setPen(cg.background().dark(106)); + bp.drawLine(br.left(), br.top(), br.right(), br.top()); + bp.setPen(cg.background().light(106)); + bp.drawLine(br.left(), br.bottom(), br.right(), br.bottom()); + bp.fillRect(br.left(), br.top()+1, br.width(), br.height()-2,cg.background()); + } else { + bp.setPen(cg.background().dark(106)); + bp.drawLine(br.left(), br.top(), br.left(), br.bottom()); + bp.setPen(cg.background().light(106)); + bp.drawLine(br.right(), br.top(), br.right(), br.bottom()); + bp.fillRect(br.left()+1, br.top(), br.width()-2, br.height(),cg.background()); + } + } + + bp.fillRect(br, QBrush(cg.background().light(), Dense4Pattern)); + + bp.end(); + + p->drawTiledPixmap(r, buffer, QPoint(0, r.top()%2) ); + break; + } + + // SCROLLBAR BUTTONS + // ----------------- + case PE_ScrollBarSubLine: { + uint contourFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom; + uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom; + if(down) surfaceFlags|=Is_Sunken; + if(!enabled) { + contourFlags|=Is_Disabled; + surfaceFlags|=Is_Disabled; + } + if(horiz) { + contourFlags |= Round_UpperLeft|Round_BottomLeft|Is_Horizontal; + surfaceFlags |= Round_UpperLeft|Round_BottomLeft|Is_Horizontal; + } else { + contourFlags |= Round_UpperLeft|Round_UpperRight; + surfaceFlags |= Round_UpperLeft|Round_UpperRight; + } + renderContour(p, r, cg.background(), getColor(cg, ButtonContour), + contourFlags); + renderSurface(p, QRect(r.left()+1, r.top()+1, r.width()-2, r.height()-2), + cg.background(), cg.button(), getColor(cg,MouseOverHighlight), _contrast+3, + surfaceFlags); + + p->setPen(cg.foreground()); + drawPrimitive((horiz ? PE_ArrowLeft : PE_ArrowUp), p, r, cg, flags); + break; + } + + case PE_ScrollBarAddLine: { + uint contourFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom; + uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom; + if(down) surfaceFlags|=Is_Sunken; + if(!enabled) { + contourFlags|=Is_Disabled; + surfaceFlags|=Is_Disabled; + } + if(horiz) { + contourFlags |= Round_UpperRight|Round_BottomRight|Is_Horizontal; + surfaceFlags |= Round_UpperRight|Round_BottomRight|Is_Horizontal; + } else { + contourFlags |= Round_BottomLeft|Round_BottomRight; + surfaceFlags |= Round_BottomLeft|Round_BottomRight; + } + renderContour(p, r, cg.background(), getColor(cg, ButtonContour), + contourFlags); + renderSurface(p, QRect(r.left()+1, r.top()+1, r.width()-2, r.height()-2), + cg.background(), cg.button(), getColor(cg,MouseOverHighlight), _contrast+3, + surfaceFlags); + + p->setPen(cg.foreground()); + drawPrimitive((horiz ? PE_ArrowRight : PE_ArrowDown), p, r, cg, flags); + break; + } + + // CHECKBOXES + // ---------- + case PE_Indicator: { + QColor contentColor = enabled?cg.base():cg.background(); + + uint contourFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom; + if(!enabled) { + contourFlags |= Is_Disabled; + } + renderContour(p, r, cg.background(), getColor(cg, ButtonContour), + contourFlags); + + // surface + uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Is_Horizontal; + if(!enabled) { + surfaceFlags |= Is_Disabled; + } else if(mouseOver) { + contentColor = alphaBlendColors(contentColor, getColor(cg,MouseOverHighlight), 240); + surfaceFlags |= Is_Highlight; + surfaceFlags |= Highlight_Left|Highlight_Right| + Highlight_Top|Highlight_Bottom; + } + renderSurface(p, QRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2), + cg.background(), contentColor, getColor(cg,MouseOverHighlight), enabled?_contrast+3:(_contrast/2), surfaceFlags); + + drawPrimitive(PE_CheckMark, p, r, cg, flags); + + break; + } + + case PE_IndicatorMask: { + p->fillRect (r, color1); + break; + } + + // RADIOBUTTONS + // ------------ + case PE_ExclusiveIndicator: { + const QColor contourColor = getColor(cg, ButtonContour, enabled); + QColor contentColor = enabled?cg.base():cg.background(); + + QBitmap bmp; + bmp = QBitmap(13, 13, radiobutton_mask_bits, true); + // first the surface... + uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Is_Horizontal; + if(!enabled) { + surfaceFlags |= Is_Disabled; + } else if (mouseOver) { + contentColor = alphaBlendColors(contentColor, getColor(cg,MouseOverHighlight), 240); + } + p->setClipRegion(bmp); + renderSurface(p, r, + cg.background(), contentColor, getColor(cg,MouseOverHighlight), enabled?_contrast+3:(_contrast/2), surfaceFlags); + p->setClipping(false); + + // ...then contour, anti-alias, mouseOver... + // contour + bmp = QBitmap(13, 13, radiobutton_contour_bits, true); + bmp.setMask(bmp); + p->setPen(alphaBlendColors(cg.background(), contourColor, 50) ); + p->drawPixmap(x, y, bmp); + // anti-alias outside + bmp = QBitmap(13, 13, radiobutton_aa_outside_bits, true); + bmp.setMask(bmp); + p->setPen(alphaBlendColors(cg.background(), contourColor, 150) ); + p->drawPixmap(x, y, bmp); + // highlighting... + if(mouseOver) { + bmp = QBitmap(13, 13, radiobutton_highlight1_bits, true); + bmp.setMask(bmp); + p->setPen(alphaBlendColors(contentColor, getColor(cg,MouseOverHighlight), 80) ); + p->drawPixmap(x, y, bmp); + bmp = QBitmap(13, 13, radiobutton_highlight2_bits, true); + bmp.setMask(bmp); + p->setPen(alphaBlendColors(contentColor, getColor(cg,MouseOverHighlight), 150) ); + p->drawPixmap(x, y, bmp); + } + // anti-alias inside, "above" the higlighting! + bmp = QBitmap(13, 13, radiobutton_aa_inside_bits, true); + bmp.setMask(bmp); + if(mouseOver) { + p->setPen(alphaBlendColors(getColor(cg,MouseOverHighlight), contourColor, 180) ); + } else { + p->setPen(alphaBlendColors(contentColor, contourColor, 180) ); + } + p->drawPixmap(x, y, bmp); + + + QColor checkmarkColor = enabled?getColor(cg,CheckMark):cg.background(); + if(flags & Style_Down) { + checkmarkColor = alphaBlendColors(contentColor, checkmarkColor, 150); + } + + // draw the radio mark + if (flags & Style_On || flags & Style_Down) { + bmp = QBitmap(CHECKMARKSIZE, CHECKMARKSIZE, radiomark_dark_bits, true); + bmp.setMask(bmp); + p->setPen(alphaBlendColors(contentColor, checkmarkColor.dark(150), 50) ); + p->drawPixmap(x+2, y+2, bmp); + bmp = QBitmap(CHECKMARKSIZE, CHECKMARKSIZE, radiomark_light_bits, true); + bmp.setMask(bmp); + p->setPen(alphaBlendColors(contentColor, checkmarkColor.dark(125), 50) ); + p->drawPixmap(x+2, y+2, bmp); + bmp = QBitmap(CHECKMARKSIZE, CHECKMARKSIZE, radiomark_aa_bits, true); + bmp.setMask(bmp); + p->setPen(alphaBlendColors(contentColor, checkmarkColor.dark(150), 150) ); + p->drawPixmap(x+2, y+2, bmp); + } + + break; + } + + case PE_ExclusiveIndicatorMask: { + p->fillRect(r, color0); + + QBitmap bmp; + bmp = QBitmap(13, 13, radiobutton_mask_bits, true); + bmp.setMask(bmp); + p->setPen(color1); + p->drawPixmap(x, y, bmp); + + break; + } + + // GENERAL PANELS + // -------------- + case PE_Splitter: { + // highlight on mouse over + QColor color = (hoverWidget == p->device())?cg.background().light(100+_contrast):cg.background(); + p->fillRect(r, color); + if (w > h) { + if (h > 4) { + int ycenter = r.height()/2; + for(int k = 2*r.width()/10; k < 8*r.width()/10; k+=5) { + renderDot(p, QPoint(k, ycenter-1), color, false, true); + } + } + } else { + if (w > 4) { + int xcenter = r.width()/2; + for(int k = 2*r.height()/10; k < 8*r.height()/10; k+=5) { + renderDot(p, QPoint(xcenter-1, k), color, false, true); + } + } + } + + break; + } + + case PE_PanelGroupBox: + case PE_GroupBoxFrame: { + if ( opt.isDefault() || opt.lineWidth() <= 0 ) + break; + renderPanel(p, r, cg, false); + + break; + } + + case PE_WindowFrame: + case PE_Panel: { + if ( opt.isDefault() || opt.lineWidth() <= 0 ) + break; + renderPanel(p, r, cg, true, sunken); + break; + } + + case PE_PanelLineEdit: { + bool isReadOnly = false; + bool isEnabled = true; + // panel is highlighted by default if it has focus, but if we have access to the + // widget itself we can try to avoid highlighting in case it's readOnly or disabled. + if (p->device() && dynamic_cast<QLineEdit*>(p->device())) + { + QLineEdit* lineEdit = dynamic_cast<QLineEdit*>(p->device()); + isReadOnly = lineEdit->isReadOnly(); + isEnabled = lineEdit->isEnabled(); + } + + uint contourFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom| + Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight; + + // HACK!! + // + // In order to draw nice edges in khtml, we need to paint alpha-blended. + // On the other hand, we can't paint alpha-blended in normal widgets. + // + // In this place there is no reliable way to detect if we are in khtml; the + // only thing we know is that khtml buffers its widgets into a pixmap. So + // when the paint device is a QPixmap, chances are high that we are in khtml. + // It's possible that this breaks other things, so let's see how it works... + if (p->device() && dynamic_cast<QPixmap*>(p->device() ) ) { + contourFlags += Draw_AlphaBlend; + } + + if ( _inputFocusHighlight && hasFocus && !isReadOnly && isEnabled) + { + renderContour(p, r, cg.background(), + getColor(cg,FocusHighlight,enabled), contourFlags ); + } + else + { + renderContour(p, r, cg.background(), + getColor(cg, ButtonContour, enabled), contourFlags ); + } + const QColor contentColor = enabled?cg.base():cg.background(); + if (_inputFocusHighlight && hasFocus && !isReadOnly && isEnabled) + { + p->setPen( getColor(cg,FocusHighlight).dark(130) ); + } + else + { + p->setPen(contentColor.dark(130) ); + } + p->drawLine(r.left()+1, r.top()+2, r.left()+1, r.bottom()-2 ); + p->drawLine(r.left()+2, r.top()+1, r.right()-2, r.top()+1 ); + if (_inputFocusHighlight && hasFocus && !isReadOnly && isEnabled) + { + p->setPen( getColor(cg,FocusHighlight).light(130) ); + } + else + { + p->setPen(contentColor.light(130) ); + } + p->drawLine(r.left()+2, r.bottom()-1, r.right()-2, r.bottom()-1 ); + p->drawLine(r.right()-1, r.top()+2, r.right()-1, r.bottom()-2 ); + break; + } + + case PE_StatusBarSection: { + renderContour(p, r, cg.background(), cg.background().dark(160), + Draw_Left|Draw_Right|Draw_Top|Draw_Bottom); + break; + } + + case PE_TabBarBase: // Still not sure what this one does + case PE_PanelTabWidget: { + renderPanel(p, r, cg, true, sunken); + break; + } + + case PE_PanelPopup: { + renderContour(p, r, cg.background(), cg.background().dark(200), + Draw_Left|Draw_Right|Draw_Top|Draw_Bottom); + break; + } + + // MENU / TOOLBAR PANEL + // -------------------- + case PE_PanelMenuBar: + case PE_PanelDockWindow: { + // fix for toolbar lag (from Mosfet Liquid) + QWidget* w = dynamic_cast<QWidget*>(p->device()); + if(w && w->backgroundMode() == PaletteButton) + w->setBackgroundMode(PaletteBackground); + p->fillRect(r, cg.brush(QColorGroup::Background)); + + if ( _drawToolBarSeparator ) { + if ( r.width() > r.height() ) { + p->setPen( getColor(cg, PanelLight) ); + p->drawLine( r.left(), r.top(), r.right(), r.top() ); + p->setPen( getColor(cg, PanelDark) ); + p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() ); + } + else { + p->setPen( getColor(cg, PanelLight) ); + p->drawLine( r.left(), r.top(), r.left(), r.bottom() ); + p->setPen( getColor(cg, PanelDark) ); + p->drawLine( r.right(), r.top(), r.right(), r.bottom() ); + } + } + + break; + } + + // TOOLBAR/DOCK WINDOW HANDLE + // -------------------------- + case PE_DockWindowResizeHandle: { + renderButton(p, r, cg); + break; + } + + case PE_DockWindowHandle: { + + int counter = 1; + + if(horiz) { + int center = r.left()+r.width()/2; + for(int j = r.top()+2; j <= r.bottom()-3; j+=3) { + if(counter%2 == 0) { + renderDot(p, QPoint(center+1, j), cg.background(), true, true); + } else { + renderDot(p, QPoint(center-2, j), cg.background(), true, true); + } + counter++; + } + } else { + int center = r.top()+r.height()/2; + for(int j = r.left()+2; j <= r.right()-3; j+=3) { + if(counter%2 == 0) { + renderDot(p, QPoint(j, center+1), cg.background(), true, true); + } else { + renderDot(p, QPoint(j, center-2), cg.background(), true, true); + } + counter++; + } + } + + break; + } + + // TOOLBAR SEPARATOR + // ----------------- + case PE_DockWindowSeparator: { + p->fillRect(r, cg.background()); + + if(_drawToolBarItemSeparator) { + if(horiz) { + int center = r.left()+r.width()/2; + p->setPen( getColor(cg, PanelDark) ); + p->drawLine( center-1, r.top()+3, center-1, r.bottom()-3 ); + p->setPen( getColor(cg, PanelLight) ); + p->drawLine( center, r.top()+3, center, r.bottom()-3 ); + } else { + int center = r.top()+r.height()/2; + p->setPen( getColor(cg, PanelDark) ); + p->drawLine( r.x()+3, center-1, r.right()-3, center-1 ); + p->setPen( getColor(cg, PanelLight) ); + p->drawLine( r.x()+3, center, r.right()-3, center ); + } + } + break; + } + + case PE_CheckMark: { + const QColor contentColor = enabled?cg.base():cg.background(); + QColor checkmarkColor = enabled?getColor(cg,CheckMark):cg.background(); + if(flags & Style_Down) { + checkmarkColor = alphaBlendColors(contentColor, checkmarkColor, 150); + } + + int x = r.center().x() - 4, y = r.center().y() - 4; + QBitmap bmp; + if( flags & Style_On ) { + bmp = QBitmap(CHECKMARKSIZE, CHECKMARKSIZE, checkmark_dark_bits, true); + bmp.setMask(bmp); + p->setPen(alphaBlendColors(contentColor, checkmarkColor.dark(150), 50) ); + p->drawPixmap(x, y, bmp); + bmp = QBitmap(CHECKMARKSIZE, CHECKMARKSIZE, checkmark_light_bits, true); + bmp.setMask(bmp); + p->setPen(alphaBlendColors(contentColor, checkmarkColor.dark(125), 50) ); + p->drawPixmap(x, y, bmp); + bmp = QBitmap(CHECKMARKSIZE, CHECKMARKSIZE, checkmark_aa_bits, true); + bmp.setMask(bmp); + p->setPen(alphaBlendColors(contentColor, checkmarkColor.dark(150), 150) ); + p->drawPixmap(x, y, bmp); + } else if ( flags & Style_Off ) { + // empty + } else { // tristate + bmp = QBitmap(CHECKMARKSIZE, CHECKMARKSIZE, checkmark_tristate_bits, true); + bmp.setMask(bmp); + p->setPen(alphaBlendColors(contentColor, checkmarkColor.dark(150), 50) ); + p->drawPixmap(x, y, bmp); + } + + break; + } + + case PE_SpinWidgetUp: + case PE_SpinWidgetDown: + case PE_HeaderArrow: + case PE_ArrowUp: + case PE_ArrowDown: + case PE_ArrowLeft: + case PE_ArrowRight: { + QPointArray a; + + switch (pe) { + case PE_SpinWidgetUp: + case PE_ArrowUp: { + a.setPoints(7, u_arrow); + break; + } + case PE_SpinWidgetDown: + case PE_ArrowDown: { + a.setPoints(7, d_arrow); + break; + } + case PE_ArrowLeft: { + a.setPoints(7, l_arrow); + break; + } + case PE_ArrowRight: { + a.setPoints(7, r_arrow); + break; + } + default: { + if (flags & Style_Up) { + a.setPoints(7, u_arrow); + } else { + a.setPoints(7, d_arrow); + } + } + } + + const QWMatrix oldMatrix( p->worldMatrix() ); + + if (flags & Style_Down) { + p->translate(pixelMetric(PM_ButtonShiftHorizontal), + pixelMetric(PM_ButtonShiftVertical)); + } + + a.translate((r.x()+r.width()/2), (r.y()+r.height()/2)); + // extra-pixel-shift, correcting some visual tics... + switch(pe) { + case PE_ArrowLeft: + case PE_ArrowRight: + a.translate(0, -1); + break; + case PE_SpinWidgetUp: + case PE_SpinWidgetDown: + a.translate(+1, 0); + break; + default: + a.translate(0, 0); + } + + if (p->pen() == QPen::NoPen) { + if (flags & Style_Enabled) { + p->setPen(cg.buttonText()); + } else { + p->setPen(cg.highlightedText()); + } + } + p->drawLineSegments(a, 0, 3); + p->drawPoint(a[6]); + + p->setWorldMatrix( oldMatrix ); + + break; + } + + default: { + return KStyle::drawPrimitive(pe, p, r, cg, flags, opt); + } + } +} + + +void PlastikStyle::drawControl(ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt) const +{ + const bool reverseLayout = QApplication::reverseLayout(); + + const bool enabled = (flags & Style_Enabled); + + switch (element) { + + // PROGRESSBAR + // ----------- + case CE_ProgressBarGroove: { + const QColor content = enabled?cg.base():cg.background(); + renderContour(p, r, cg.background(), getColor(cg, ButtonContour, enabled) ); + p->setPen(content.dark(105) ); + p->drawLine(r.left()+2, r.top()+1, r.right()-2, r.top()+1 ); + p->drawLine(r.left()+1, r.top()+2, r.left()+1, r.bottom()-2); + p->setPen(content.light(105) ); + p->drawLine(r.left()+2, r.bottom()-1, r.right()-2, r.bottom()-1 ); + p->drawLine(r.right()-1, r.top()+2, r.right()-1, r.bottom()-2); + break; + } + + case CE_ProgressBarContents: { + const QProgressBar *pb = dynamic_cast<const QProgressBar*>(widget); + int steps = pb->totalSteps(); + + const QColor bg = enabled?cg.base():cg.background(); // background + const QColor fg = enabled?cg.highlight():cg.background().dark(110); // foreground + + if( steps == 0 ) { // Busy indicator + static const int barWidth = 10; + int progress = pb->progress() % (2*(r.width()-barWidth)); + if( progress < 0) + progress = 0; + if( progress > r.width()-barWidth ) + progress = (r.width()-barWidth)-(progress-(r.width()-barWidth)); + p->fillRect( QRect( r.x(), r.y(), r.width(), r.height() ), bg ); + renderContour( p, QRect( r.x()+progress, r.y(), barWidth, r.height() ), + bg, fg.dark(160), + Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Round_UpperRight| + Round_BottomRight|Round_UpperLeft|Round_BottomLeft ); + renderSurface(p, QRect( r.x()+progress+1, r.y()+1, barWidth-2, r.height()-2 ), + bg, fg, cg.highlight(), + 2*(_contrast/3), + Draw_Right|Draw_Left|Draw_Top|Draw_Bottom| + Round_UpperRight|Round_BottomRight| + Round_UpperLeft|Round_BottomLeft|Is_Horizontal); + } else { + double percent = static_cast<double>(pb->progress()) / static_cast<double>(steps); + + int w = static_cast<int>(r.width() * percent); + // renderContour/renderSurface handle small sizes not very well, so set a minimal + // progressbar width... + if(w<4) w = 4; + int w2 = r.width()-(r.width()-w); + + QRect Rempty(reverseLayout?r.left():r.left()+w-1, r.top(), r.width()-w+1, r.height() ); + QRect Rcontour(reverseLayout?r.right()-w2+1:r.left(), r.top(), w2, r.height() ); + QRect Rsurface(Rcontour.left()+1, Rcontour.top()+1, w2-2, Rcontour.height()-2); + + p->fillRect(Rempty, bg); + + renderContour(p, Rcontour, + bg, fg.dark(160), + reverseLayout ? Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Round_UpperLeft|Round_BottomLeft + : Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Round_UpperRight|Round_BottomRight); + + QRegion mask(Rsurface); + if(reverseLayout) { + mask -= QRegion(Rsurface.left(), Rsurface.top(), 1, 1); + mask -= QRegion(Rsurface.left(), Rsurface.bottom(), 1, 1); + } else { + mask -= QRegion(Rsurface.right(), Rsurface.top(), 1, 1); + mask -= QRegion(Rsurface.right(), Rsurface.bottom(), 1, 1); + } + p->setClipRegion(mask); + int counter = 0; + QPixmap surfaceTile(21, r.height()-2); + QPainter surfacePainter(&surfaceTile); + // - 21 pixel - + // __________ + // | ` `| <- 3 + // | 1 | 2 | + // |____,____,| <- 3 + // 1 = light, 11 pixel, 1 pixel overlapping with 2 + // 2 = dark, 11 pixel, 1 pixel overlapping with 3 + // 3 = light edges + const int tileHeight = surfaceTile.height(); + // 3 + renderSurface(&surfacePainter, + QRect(20, 0, 11, tileHeight), + fg.light(105), fg, cg.highlight(), 2*(_contrast/3), + reverseLayout ? Draw_Right|Draw_Left|Draw_Top|Draw_Bottom| + Round_UpperLeft|Round_BottomLeft|Is_Horizontal + : Draw_Right|Draw_Left|Draw_Top|Draw_Bottom| + Round_UpperRight|Round_BottomRight|Is_Horizontal); + // 2 + renderSurface(&surfacePainter, + QRect(10, 0, 11, tileHeight), + fg, fg.light(105), cg.highlight(), 2*(_contrast/3), + reverseLayout ? Draw_Right|Draw_Left|Draw_Top|Draw_Bottom| + Round_UpperLeft|Round_BottomLeft|Is_Horizontal + : Draw_Right|Draw_Left|Draw_Top|Draw_Bottom| + Round_UpperRight|Round_BottomRight|Is_Horizontal); + // 1 + renderSurface(&surfacePainter, + QRect(0, 0, 11, tileHeight), + fg.light(105), fg, cg.highlight(), 2*(_contrast/3), + reverseLayout ? Draw_Right|Draw_Left|Draw_Top|Draw_Bottom| + Round_UpperLeft|Round_BottomLeft|Is_Horizontal + : Draw_Right|Draw_Left|Draw_Top|Draw_Bottom| + Round_UpperRight|Round_BottomRight|Is_Horizontal); + + surfacePainter.end(); + int staticShift = 0; + int animShift = 0; + if (!_animateProgressBar) { + staticShift = (reverseLayout ? Rsurface.left() : Rsurface.right()) % 40 - 40; + } else { + // find the animation Offset for the current Widget + QWidget* nonConstWidget = const_cast<QWidget*>(widget); + QMapConstIterator<QWidget*, int> iter = progAnimWidgets.find(nonConstWidget); + if (iter != progAnimWidgets.end()) + animShift = iter.data(); + } + while((counter*10) < (Rsurface.width()+20)) { + counter++; + if (reverseLayout) { + // from right to left, overlap 1 pixel with the previously drawn tile + p->drawPixmap(Rsurface.right()-counter*20-animShift+40+staticShift, r.top()+1, + surfaceTile); + } else { + // from left to right, overlap 1 pixel with the previously drawn tile + p->drawPixmap(Rsurface.left()+counter*20+animShift-40+staticShift, r.top()+1, + surfaceTile); + } + } + + p->setClipping(false); + } + + break; + } + + // TABS + // ---- + case CE_TabBarTab: { + const QTabBar * tb = (const QTabBar *) widget; + bool cornerWidget = false; + if( ::qt_cast<QTabWidget*>(tb->parent()) ) { + const QTabWidget *tw = (const QTabWidget*)tb->parent(); + // is there a corner widget in the (top) left edge? + QWidget *cw = tw->cornerWidget(Qt::TopLeft); + if(cw) + cornerWidget = true; + } + QTabBar::Shape tbs = tb->shape(); + bool selected = false; + if (flags & Style_Selected) selected = true; + TabPosition pos; + if (tb->count() == 1) { + pos = Single; + } else if ((tb->indexOf(opt.tab()->identifier()) == 0)) { + pos = First; + } else if (tb->indexOf(opt.tab()->identifier()) == tb->count() - 1) { + pos = Last; + } else { + pos = Middle; + } + + bool mouseOver = false; + if (opt.tab() == hoverTab) { + mouseOver = true; + flags |= Style_MouseOver; + } + + switch (tbs) { + case QTabBar::TriangularAbove: +// renderTriangularTab(p, r, cg, (flags & Style_MouseOver), selected, false, pos); + renderTab(p, r, cg, mouseOver, selected, false, pos, true, cornerWidget); + break; + case QTabBar::RoundedAbove: + renderTab(p, r, cg, mouseOver, selected, false, pos, false, cornerWidget); + break; + case QTabBar::TriangularBelow: +// renderTriangularTab(p, r, cg, (flags & Style_MouseOver), selected, true, pos); + renderTab(p, r, cg, mouseOver, selected, true, pos, true, cornerWidget); + break; + case QTabBar::RoundedBelow: + renderTab(p, r, cg, mouseOver, selected, true, pos, false, cornerWidget); + break; + default: + KStyle::drawControl(element, p, widget, r, cg, flags, opt); + } + + break; + } + + case CE_PushButton: { + QPushButton *button = (QPushButton *)widget; + + const bool isDefault = enabled && button->isDefault(); + + if (button->isFlat() ) + flatMode = true; + + if (widget == hoverWidget) + flags |= Style_MouseOver; + + QColorGroup g2 = cg; + if (isDefault) + g2.setColor(QColorGroup::Background, cg.background().dark(120) ); + drawPrimitive(PE_ButtonBevel, p, + isDefault?QRect(r.x()+1,r.y()+1,r.width()-2,r.height()-2):r, + g2, flags, QStyleOption(button) ); + + if (isDefault ) { + drawPrimitive(PE_ButtonDefault, p, r, cg, flags); + } + + break; + } + + case CE_PushButtonLabel: + { + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + const QPushButton* button = static_cast<const QPushButton *>( widget ); + bool active = button->isOn() || button->isDown(); + bool cornArrow = false; + + // Shift button contents if pushed. + if ( active ) + { + x += pixelMetric(PM_ButtonShiftHorizontal, widget); + y += pixelMetric(PM_ButtonShiftVertical, widget); + flags |= Style_Sunken; + } + + // Does the button have a popup menu? + if ( button->isMenuButton() ) + { + int dx = pixelMetric( PM_MenuButtonIndicator, widget ); + if ( button->iconSet() && !button->iconSet()->isNull() && + (dx + button->iconSet()->pixmap (QIconSet::Small, QIconSet::Normal, QIconSet::Off ).width()) >= w ) + { + cornArrow = true; //To little room. Draw the arrow in the corner, don't adjust the widget + } + else + { + p->setPen(cg.buttonText()); + drawPrimitive( PE_ArrowDown, p, visualRect( QRect(x + w - dx - 8, y + 2, dx, h - 4), r ), + cg, flags, opt ); + w -= dx; + } + } + + // Draw the icon if there is one + if ( button->iconSet() && !button->iconSet()->isNull() ) + { + QIconSet::Mode mode = QIconSet::Disabled; + QIconSet::State state = QIconSet::Off; + + if (button->isEnabled()) + mode = button->hasFocus() ? QIconSet::Active : QIconSet::Normal; + if (button->isToggleButton() && button->isOn()) + state = QIconSet::On; + + QPixmap pixmap = button->iconSet()->pixmap( QIconSet::Small, mode, state ); + + if (button->text().isEmpty() && !button->pixmap()) + p->drawPixmap( x + w/2 - pixmap.width()/2, y + h / 2 - pixmap.height() / 2, + pixmap ); + else + p->drawPixmap( x + 4, y + h / 2 - pixmap.height() / 2, pixmap ); + + if (cornArrow) //Draw over the icon + drawPrimitive( PE_ArrowDown, p, visualRect( QRect(x + w - 6, x + h - 6, 7, 7), r ), + cg, flags, opt ); + + + int pw = pixmap.width(); + x += pw + 4; + w -= pw + 4; + } + + // Make the label indicate if the button is a default button or not + drawItem( p, QRect(x, y, w, h), AlignCenter|ShowPrefix, button->colorGroup(), + button->isEnabled(), button->pixmap(), button->text(), -1, + &button->colorGroup().buttonText() ); + + + if ( flags & Style_HasFocus ) + drawPrimitive( PE_FocusRect, p, + visualRect( subRect( SR_PushButtonFocusRect, widget ), widget ), + cg, flags ); + break; + } + + // MENUBAR ITEM (sunken panel on mouse over) + // ----------------------------------------- + case CE_MenuBarItem: { + QMenuItem *mi = opt.menuItem(); + bool active = flags & Style_Active; + bool focused = flags & Style_HasFocus; + bool down = flags & Style_Down; + const int text_flags = + AlignVCenter | AlignHCenter | ShowPrefix | DontClip | SingleLine; + + p->fillRect(r, cg.background()); + + if (active && focused) { + if (down) { + drawPrimitive(PE_ButtonTool, p, r, cg, flags|Style_Down, opt); + } else { + drawPrimitive(PE_ButtonTool, p, r, cg, flags, opt); + } + } + + p->setPen(cg.foreground() ); + p->drawText(r, text_flags, mi->text()); + break; + } + + // POPUPMENU ITEM (highlighted on mouseover) + // ------------------------------------------ + case CE_PopupMenuItem: { + const QPopupMenu *popupmenu = static_cast< const QPopupMenu * >( widget ); + QMenuItem *mi = opt.menuItem(); + + if ( !mi ) + { + // Don't leave blank holes if we set NoBackground for the QPopupMenu. + // This only happens when the popupMenu spans more than one column. + if (! ( widget->erasePixmap() && !widget->erasePixmap()->isNull() ) ) + p->fillRect( r, cg.background().light( 105 ) ); + + break; + } + int tab = opt.tabWidth(); + int checkcol = opt.maxIconWidth(); + bool enabled = mi->isEnabled(); + bool checkable = popupmenu->isCheckable(); + bool active = flags & Style_Active; + bool etchtext = styleHint( SH_EtchDisabledText ); + bool reverse = QApplication::reverseLayout(); + if ( checkable ) + checkcol = QMAX( checkcol, 20 ); + + // Draw the menu item background + if (active) { + if (enabled) { + renderSurface(p, r, cg.background(), cg.highlight(), cg.highlight(), + _contrast+3, Draw_Top|Draw_Bottom|Is_Horizontal); + } + else { + if ( widget->erasePixmap() && !widget->erasePixmap()->isNull() ) + p->drawPixmap( r.topLeft(), *widget->erasePixmap(), r ); + else p->fillRect( r, cg.background().light(105) ); + if(_drawFocusRect) + p->drawWinFocusRect( r ); + } + } + // Draw the transparency pixmap + else if ( widget->erasePixmap() && !widget->erasePixmap()->isNull() ) + p->drawPixmap( r.topLeft(), *widget->erasePixmap(), r ); + // Draw a solid background + else + p->fillRect( r, cg.background().light( 105 ) ); + // Are we a menu item separator? + if ( mi->isSeparator() ) + { + p->setPen( cg.mid() ); + p->drawLine( r.x()+5, r.y() + 1, r.right()-5, r.y() + 1 ); + p->setPen( cg.light() ); + p->drawLine( r.x()+5, r.y() + 2, r.right()-5 , r.y() + 2 ); + break; + } + + QRect cr = visualRect( QRect( r.x() + 2, r.y() + 2, checkcol - 1, r.height() - 4 ), r ); + // Do we have an icon? + if ( mi->iconSet() ) + { + QIconSet::Mode mode; + + // Select the correct icon from the iconset + if (active) + mode = enabled?QIconSet::Active:QIconSet::Disabled; + else + mode = enabled?QIconSet::Normal:QIconSet::Disabled; + + // Do we have an icon and are checked at the same time? + // Then draw a "pressed" background behind the icon + if ( checkable && /*!active &&*/ mi->isChecked() ) + qDrawShadePanel( p, cr.x(), cr.y(), cr.width(), cr.height(), + cg, true, 1, &cg.brush(QColorGroup::Midlight) ); + // Draw the icon + QPixmap pixmap = mi->iconSet()->pixmap(QIconSet::Small, mode); + QRect pmr( 0, 0, pixmap.width(), pixmap.height() ); + pmr.moveCenter( cr.center() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + } + + // Are we checked? (This time without an icon) + else if ( checkable && mi->isChecked() ) + { + // We only have to draw the background if the menu item is inactive - + // if it's active the "pressed" background is already drawn + // if ( ! active ) + qDrawShadePanel( p, cr.x(), cr.y(), cr.width(), cr.height(), cg, true, 1, + &cg.brush(QColorGroup::Midlight) ); + + // Draw the checkmark + SFlags cflags = Style_On; + if (enabled) + cflags |= Style_Enabled; + drawPrimitive( PE_CheckMark, p, cr, cg, cflags ); + } + + // Time to draw the menu item label... + int xm = 2 + checkcol + 2; // X position margin + + int xp = reverse ? // X position + r.x() + tab + rightBorder + itemHMargin + itemFrame - 1 : + r.x() + xm; + + int offset = reverse ? -1 : 1; // Shadow offset for etched text + + // Label width (minus the width of the accelerator portion) + int tw = r.width() - xm - tab - arrowHMargin - itemHMargin * 3 - itemFrame + 1; + + // Set the color for enabled and disabled text + // (used for both active and inactive menu items) + p->setPen( enabled ? cg.buttonText() : cg.mid() ); + + // This color will be used instead of the above if the menu item + // is active and disabled at the same time. (etched text) + QColor discol = cg.mid(); + + // Does the menu item draw it's own label? + if ( mi->custom() ) { + int m = 2; + // Save the painter state in case the custom + // paint method changes it in some way + p->save(); + + // Draw etched text if we're inactive and the menu item is disabled + if ( etchtext && !enabled && !active ) { + p->setPen( cg.light() ); + mi->custom()->paint( p, cg, active, enabled, xp+offset, r.y()+m+1, tw, r.height()-2*m ); + p->setPen( discol ); + } + mi->custom()->paint( p, cg, active, enabled, xp, r.y()+m, tw, r.height()-2*m ); + p->restore(); + } + else { + // The menu item doesn't draw it's own label + QString s = mi->text(); + // Does the menu item have a text label? + if ( !s.isNull() ) { + int t = s.find( '\t' ); + int m = 2; + int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine; + text_flags |= reverse ? AlignRight : AlignLeft; + + //QColor draw = cg.text(); + QColor draw = (active && enabled) ? cg.highlightedText () : cg.foreground(); + p->setPen(draw); + + + // Does the menu item have a tabstop? (for the accelerator text) + if ( t >= 0 ) { + int tabx = reverse ? r.x() + rightBorder + itemHMargin + itemFrame : + r.x() + r.width() - tab - rightBorder - itemHMargin - itemFrame; + + // Draw the right part of the label (accelerator text) + if ( etchtext && !enabled ) { + // Draw etched text if we're inactive and the menu item is disabled + p->setPen( cg.light() ); + p->drawText( tabx+offset, r.y()+m+1, tab, r.height()-2*m, text_flags, s.mid( t+1 ) ); + p->setPen( discol ); + } + p->drawText( tabx, r.y()+m, tab, r.height()-2*m, text_flags, s.mid( t+1 ) ); + s = s.left( t ); + } + + // Draw the left part of the label (or the whole label + // if there's no accelerator) + if ( etchtext && !enabled ) { + // Etched text again for inactive disabled menu items... + p->setPen( cg.light() ); + p->drawText( xp+offset, r.y()+m+1, tw, r.height()-2*m, text_flags, s, t ); + p->setPen( discol ); + } + + + p->drawText( xp, r.y()+m, tw, r.height()-2*m, text_flags, s, t ); + + p->setPen(cg.text()); + + } + + // The menu item doesn't have a text label + // Check if it has a pixmap instead + else if ( mi->pixmap() ) { + QPixmap *pixmap = mi->pixmap(); + + // Draw the pixmap + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( OpaqueMode ); + + int diffw = ( ( r.width() - pixmap->width() ) / 2 ) + + ( ( r.width() - pixmap->width() ) % 2 ); + p->drawPixmap( r.x()+diffw, r.y()+1, *pixmap ); + + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( TransparentMode ); + } + } + + // Does the menu item have a submenu? + if ( mi->popup() ) { + PrimitiveElement arrow = reverse ? PE_ArrowLeft : PE_ArrowRight; + int dim = pixelMetric(PM_MenuButtonIndicator) - 1; + QRect vr = visualRect( QRect( r.x() + r.width() - 5 - 1 - dim, + r.y() + r.height() / 2 - dim / 2, dim, dim), r ); + + // Draw an arrow at the far end of the menu item + if ( active ) { + if ( enabled ) + discol = cg.buttonText(); + + QColorGroup g2( discol, cg.highlight(), white, white, + enabled ? white : discol, discol, white ); + + drawPrimitive( arrow, p, vr, g2, Style_Enabled ); + } else + drawPrimitive( arrow, p, vr, cg, + enabled ? Style_Enabled : Style_Default ); + } + break; + } + + // Menu and dockwindow empty space + // + case CE_DockWindowEmptyArea: + p->fillRect(r, cg.background()); + break; + + case CE_MenuBarEmptyArea: + p->fillRect(r, cg.background()); + +// if ( _drawToolBarSeparator ) { +// p->setPen( getColor(cg, PanelDark) ); +// p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() ); +// } + + break; + + default: + KStyle::drawControl(element, p, widget, r, cg, flags, opt); + } +} + +void PlastikStyle::drawControlMask(ControlElement element, + QPainter *p, + const QWidget *w, + const QRect &r, + const QStyleOption &opt) const +{ + switch (element) { + case CE_PushButton: { + p->fillRect (r, color0); + renderMask(p, r, color1, + Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight); + break; + } + + default: { + KStyle::drawControlMask (element, p, w, r, opt); + } + } +} + +void PlastikStyle::drawComplexControlMask(ComplexControl c, + QPainter *p, + const QWidget *w, + const QRect &r, + const QStyleOption &o) const +{ + switch (c) { + case CC_SpinWidget: + case CC_ListView: + case CC_ComboBox: { + p->fillRect (r, color0); + renderMask(p, r, color1, + Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight); + break; + } + default: { + KStyle::drawComplexControlMask (c, p, w, r, o); + } + } +} + +void PlastikStyle::drawComplexControl(ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + SCFlags controls, + SCFlags active, + const QStyleOption& opt) const +{ + const bool reverseLayout = QApplication::reverseLayout(); + + const bool enabled = (flags & Style_Enabled); + + switch(control) { + // COMBOBOX + // -------- + case CC_ComboBox: { + static const unsigned int handleWidth = 15; + + const QComboBox *cb = dynamic_cast<const QComboBox *>(widget); + // at the moment cb is only needed to check if the combo box is editable or not. + // if cb doesn't exist, just assume false and the app (gideon! ;) ) at least doesn't crash. + bool editable = false; + bool hasFocus = false; + if (cb) { + editable = cb->editable(); + hasFocus = cb->hasFocus(); + } + + const QColor buttonColor = enabled?cg.button():cg.background(); + const QColor inputColor = enabled?(editable?cg.base():cg.button()) + :cg.background(); + + uint contourFlags = 0; + if( khtmlWidgets.contains(cb) ) + contourFlags |= Draw_AlphaBlend; + + if (_inputFocusHighlight && hasFocus && editable && enabled) + { + QRect editField = querySubControlMetrics(control, widget, SC_ComboBoxEditField); + QRect editFrame = r; + QRect buttonFrame = r; + + uint editFlags = contourFlags; + uint buttonFlags = contourFlags; + + // Hightlight only the part of the contour next to the control button + if (reverseLayout) + { + // querySubControlMetrics doesn't work right for reverse Layout + int dx = r.right() - editField.right(); + editFrame.setLeft(editFrame.left() + dx); + buttonFrame.setRight(editFrame.left() - 1); + editFlags |= Draw_Right|Draw_Top|Draw_Bottom|Round_UpperRight|Round_BottomRight; + buttonFlags |= Draw_Left|Draw_Top|Draw_Bottom|Round_UpperLeft|Round_BottomLeft; + } + else + { + editFrame.setRight(editField.right()); + buttonFrame.setLeft(editField.right() + 1); + + editFlags |= Draw_Left|Draw_Top|Draw_Bottom|Round_UpperLeft|Round_BottomLeft; + buttonFlags |= Draw_Right|Draw_Top|Draw_Bottom|Round_UpperRight|Round_BottomRight; + } + renderContour(p, editFrame, cg.background(), getColor(cg,FocusHighlight,enabled), editFlags); + renderContour(p, buttonFrame, cg.background(), + getColor(cg, ButtonContour, enabled), buttonFlags); + } + else + { + contourFlags |= Draw_Left|Draw_Right|Draw_Top|Draw_Bottom| + Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight; + renderContour(p, r, cg.background(), getColor(cg, ButtonContour, enabled), contourFlags); + } + //extend the contour: between input and handler... + p->setPen(alphaBlendColors(cg.background(), getColor(cg, ButtonContour, enabled), 50) ); + if(reverseLayout) { + p->drawLine(r.left()+1+handleWidth, r.top()+1, r.left()+1+handleWidth, r.bottom()-1); + } else { + p->drawLine(r.right()-handleWidth-1, r.top()+1, r.right()-handleWidth-1, r.bottom()-1); + } + + const QRect RbuttonSurface(reverseLayout?r.left()+1:r.right()-handleWidth, r.top()+1, + handleWidth, r.height()-2); + const QRect RcontentSurface(reverseLayout?r.left()+1+handleWidth+1:r.left()+1, r.top()+1, + r.width()-handleWidth-3, r.height()-2); + + // handler + + uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Is_Horizontal; + if(reverseLayout) { + surfaceFlags |= Round_UpperLeft|Round_BottomLeft; + } else { + surfaceFlags |= Round_UpperRight|Round_BottomRight; + } + + if ((widget == hoverWidget) || (flags & Style_MouseOver)) { + surfaceFlags |= Is_Highlight; + if(editable) surfaceFlags |= Highlight_Left|Highlight_Right; + surfaceFlags |= Highlight_Top|Highlight_Bottom; + } + renderSurface(p, RbuttonSurface, + cg.background(), buttonColor, getColor(cg,MouseOverHighlight), enabled?_contrast+3:(_contrast/2), + surfaceFlags); + + if(!editable) { + surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Is_Horizontal; + if(reverseLayout) { + surfaceFlags |= Round_UpperRight|Round_BottomRight; + } else { + surfaceFlags |= Round_UpperLeft|Round_BottomLeft; + } + + if ((widget == hoverWidget) || (flags & Style_MouseOver)) { + surfaceFlags |= Is_Highlight; + surfaceFlags |= Highlight_Top|Highlight_Bottom; + } + renderSurface(p, RcontentSurface, + cg.background(), buttonColor, getColor(cg,MouseOverHighlight), enabled?_contrast+3:(_contrast/2), + surfaceFlags); + if (hasFocus) { + drawPrimitive(PE_FocusRect, p, + QRect(RcontentSurface.x() + 2, + RcontentSurface.y() + 2, + RcontentSurface.width() - 4, + RcontentSurface.height() - 4), cg); + } + } else { + // thin frame around the input area + if (_inputFocusHighlight && hasFocus && editable && enabled) + { + p->setPen( getColor(cg,FocusHighlight).dark(130) ); + } + else + { + p->setPen(inputColor.dark(130) ); + } + p->drawLine(RcontentSurface.x(), reverseLayout?RcontentSurface.y():RcontentSurface.y()+1, + RcontentSurface.x(), reverseLayout?RcontentSurface.bottom():RcontentSurface.bottom()-1); + p->drawLine(RcontentSurface.x()+1, RcontentSurface.y(), + reverseLayout?RcontentSurface.right()-1:RcontentSurface.right(), RcontentSurface.y() ); + if (_inputFocusHighlight && hasFocus && editable && enabled) + { + p->setPen( getColor(cg,FocusHighlight).light(130) ); + } + else + { + p->setPen(inputColor.light(130) ); + } + p->drawLine(reverseLayout?RcontentSurface.x():RcontentSurface.x()+1, RcontentSurface.bottom(), + reverseLayout?RcontentSurface.right()-1:RcontentSurface.right(), RcontentSurface.bottom() ); + p->drawLine(RcontentSurface.right(), RcontentSurface.top()+1, + RcontentSurface.right(), RcontentSurface.bottom()-1 ); + + // input area + p->fillRect(RcontentSurface.x()+1, RcontentSurface.y()+1, + RcontentSurface.width()-2, RcontentSurface.height()-2, inputColor ); + } + + p->setPen(cg.foreground()); + drawPrimitive(PE_SpinWidgetDown, p, RbuttonSurface, cg, Style_Default|Style_Enabled|Style_Raised); + + // QComboBox draws the text using cg.text(), we can override this + // from here + p->setPen( cg.buttonText() ); + p->setBackgroundColor( cg.button() ); + break; + } + + // TOOLBUTTON + // ---------- + case CC_ToolButton: { + const QToolButton *tb = (const QToolButton *) widget; + + QRect button, menuarea; + button = querySubControlMetrics(control, widget, SC_ToolButton, opt); + menuarea = querySubControlMetrics(control, widget, SC_ToolButtonMenu, opt); + + SFlags bflags = flags, + mflags = flags; + + if (kornMode) { + drawPrimitive(PE_ButtonTool, p, button, cg, bflags, opt); + break; + } else { + // don't want to have the buttoncolor as the background... + p->fillRect(r, cg.background()); + bflags &= ~Style_MouseOver; + } + + if (active & SC_ToolButton) + bflags |= Style_Down; + + if (active & SC_ToolButtonMenu) + mflags |= Style_Down; + + if (controls & SC_ToolButton) { + // If we're pressed, on, or raised... + if (bflags & (Style_Down | Style_On | Style_Raised) || widget==hoverWidget ) { + drawPrimitive(PE_ButtonTool, p, button, cg, bflags, opt); + } else if (tb->parentWidget() && + tb->parentWidget()->backgroundPixmap() && + !tb->parentWidget()->backgroundPixmap()->isNull()) { + QPixmap pixmap = *(tb->parentWidget()->backgroundPixmap()); + p->drawTiledPixmap( r, pixmap, tb->pos() ); + } + } + + // Draw a toolbutton menu indicator if required + if (controls & SC_ToolButtonMenu) { + if (mflags & (Style_Down | Style_On | Style_Raised)) { + drawPrimitive(PE_ButtonDropDown, p, menuarea, cg, mflags, opt); + } + drawPrimitive(PE_ArrowDown, p, menuarea, cg, mflags, opt); + } + + if (tb->hasFocus() && !tb->focusProxy()) { + QRect fr = tb->rect(); + fr.addCoords(2, 2, -2, -2); + drawPrimitive(PE_FocusRect, p, fr, cg); + } + + // Set the color for the ToolButton menu indicator + p->setPen(cg.buttonText() ); + + break; + } + + // SPINWIDGETS + // ----------- + case CC_SpinWidget: { + static const unsigned int handleWidth = 15; + + const QSpinWidget *sw = dynamic_cast<const QSpinWidget *>(widget); + SFlags sflags = flags; + PrimitiveElement pe; + + bool hasFocus = false; + if (sw) + hasFocus = sw->hasFocus(); + + const QColor buttonColor = enabled?cg.button():cg.background(); + const QColor inputColor = enabled?cg.base():cg.background(); + + // contour + const bool heightDividable = ((r.height()%2) == 0); + if (_inputFocusHighlight && hasFocus && enabled) + { + QRect editField = querySubControlMetrics(control, widget, SC_SpinWidgetEditField); + QRect editFrame = r; + QRect buttonFrame = r; + + uint editFlags = 0; + uint buttonFlags = 0; + + // Hightlight only the part of the contour next to the control buttons + if (reverseLayout) + { + // querySubControlMetrics doesn't work right for reverse Layout + int dx = r.right() - editField.right(); + editFrame.setLeft(editFrame.left() + dx); + buttonFrame.setRight(editFrame.left() - 1); + editFlags |= Draw_Right|Draw_Top|Draw_Bottom|Round_UpperRight|Round_BottomRight; + buttonFlags |= Draw_Left|Draw_Top|Draw_Bottom|Round_UpperLeft|Round_BottomLeft; + } + else + { + editFrame.setRight(editField.right()); + buttonFrame.setLeft(editField.right() + 1); + + editFlags |= Draw_Left|Draw_Top|Draw_Bottom|Round_UpperLeft|Round_BottomLeft; + buttonFlags |= Draw_Right|Draw_Top|Draw_Bottom|Round_UpperRight|Round_BottomRight; + } + renderContour(p, editFrame, cg.background(), cg.highlight(), editFlags); + renderContour(p, buttonFrame, cg.background(), + getColor(cg, ButtonContour, enabled), buttonFlags); + } + else + { + renderContour(p, querySubControlMetrics(control, widget, SC_SpinWidgetFrame), + cg.background(), getColor(cg, ButtonContour, enabled) ); + } + p->setPen(alphaBlendColors(cg.background(), getColor(cg, ButtonContour, enabled), 50) ); + p->drawLine(reverseLayout?r.left()+1+handleWidth:r.right()-handleWidth-1, r.top()+1, + reverseLayout?r.left()+1+handleWidth:r.right()-handleWidth-1, r.bottom()-1); + p->drawLine(reverseLayout?r.left()+1:r.right()-handleWidth, r.top()+1+(r.height()-2)/2, + reverseLayout?r.left()+handleWidth:r.right()-1, r.top()+1+(r.height()-2)/2); + if(heightDividable) + p->drawLine(reverseLayout?r.left()+1:r.right()-handleWidth, r.top()+1+(r.height()-2)/2-1, + reverseLayout?r.left()+handleWidth:r.right()-1, r.top()+1+(r.height()-2)/2-1); + + // surface + QRect upRect = QRect(reverseLayout?r.left()+1:r.right()-handleWidth, r.top()+1, + handleWidth, (r.height()-2)/2); + QRect downRect = QRect(reverseLayout?r.left()+1:r.right()-handleWidth, + heightDividable?r.top()+1+((r.height()-2)/2):r.top()+1+((r.height()-2)/2)+1, + handleWidth, ((r.height()-2)/2) ); + if(heightDividable) { + upRect = QRect(upRect.left(), upRect.top(), upRect.width(), upRect.height()-1 ); + downRect = QRect(downRect.left(), downRect.top()+1, downRect.width(), downRect.height()-1 ); + } + + uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Is_Horizontal; + if(reverseLayout) { + surfaceFlags |= Round_UpperLeft; + } else { + surfaceFlags |= Round_UpperRight; + } + if ((widget == hoverWidget) || (sflags & Style_MouseOver)) { + surfaceFlags |= Is_Highlight; + surfaceFlags |= Highlight_Top|Highlight_Left|Highlight_Right; + } + if (active==SC_SpinWidgetUp) surfaceFlags|=Is_Sunken; + if(!enabled) surfaceFlags|=Is_Disabled; + renderSurface(p, upRect, cg.background(), buttonColor, getColor(cg,MouseOverHighlight), + _contrast, surfaceFlags); + surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Is_Horizontal; + if(reverseLayout) { + surfaceFlags |= Round_BottomLeft; + } else { + surfaceFlags |= Round_BottomRight; + } + if ((widget == hoverWidget) || (sflags & Style_MouseOver)) { + surfaceFlags |= Is_Highlight; + surfaceFlags |= Highlight_Bottom|Highlight_Left|Highlight_Right; + } + if (active==SC_SpinWidgetDown) surfaceFlags|=Is_Sunken; + if(!enabled) surfaceFlags|=Is_Disabled; + renderSurface(p, downRect, cg.background(), buttonColor, getColor(cg,MouseOverHighlight), + _contrast, surfaceFlags); + + // icons... + sflags = Style_Default | Style_Enabled; + if (active == SC_SpinWidgetUp) { + sflags |= Style_On; + sflags |= Style_Sunken; + } else + sflags |= Style_Raised; + if (sw->buttonSymbols() == QSpinWidget::PlusMinus) + pe = PE_SpinWidgetPlus; + else + pe = PE_SpinWidgetUp; + p->setPen(cg.foreground()); + drawPrimitive(pe, p, upRect, cg, sflags); + + sflags = Style_Default | Style_Enabled; + if (active == SC_SpinWidgetDown) { + sflags |= Style_On; + sflags |= Style_Sunken; + } else + sflags |= Style_Raised; + if (sw->buttonSymbols() == QSpinWidget::PlusMinus) + pe = PE_SpinWidgetMinus; + else + pe = PE_SpinWidgetDown; + p->setPen(cg.foreground()); + drawPrimitive(pe, p, downRect, cg, sflags); + + // thin frame around the input area + const QRect Rcontent = QRect(reverseLayout?r.left()+1+handleWidth+1:r.left()+1, r.top()+1, + r.width()-1-2-handleWidth, r.height()-2); + if (_inputFocusHighlight && hasFocus && enabled) + { + p->setPen( getColor(cg,FocusHighlight).dark(130) ); + } + else + { + p->setPen(inputColor.dark(130) ); + } + p->drawLine(Rcontent.left(), reverseLayout?Rcontent.top():Rcontent.top()+1, + Rcontent.left(), reverseLayout?Rcontent.bottom():Rcontent.bottom()-1 ); + p->drawLine(Rcontent.left()+1, Rcontent.top(), + reverseLayout?Rcontent.right()-1:Rcontent.right(), Rcontent.top() ); + if (_inputFocusHighlight && hasFocus && enabled) + { + p->setPen( getColor(cg,FocusHighlight).light(130) ); + } + else + { + p->setPen(inputColor.light(130) ); + } + p->drawLine(Rcontent.left()+1, Rcontent.bottom(), Rcontent.right()-1, Rcontent.bottom() ); + p->drawLine(Rcontent.right(), Rcontent.top()+1, + Rcontent.right(), reverseLayout?Rcontent.bottom()-1:Rcontent.bottom() ); + + break; + } + + default: + KStyle::drawComplexControl(control, p, widget, + r, cg, flags, controls, + active, opt); + break; + } +} + + +QRect PlastikStyle::subRect(SubRect r, const QWidget *widget) const +{ + switch (r) { + case SR_ComboBoxFocusRect: { + return querySubControlMetrics( CC_ComboBox, widget, SC_ComboBoxEditField ); + } + + // Don't use KStyles progressbar subrect + // TODO: + case SR_ProgressBarGroove: { + return QRect(widget->rect()); + } + case SR_ProgressBarContents: + case SR_ProgressBarLabel: { + QRect rw = widget->rect(); + return QRect(rw.left()+2, rw.top()+2, rw.width()-4, rw.height()-4 ); + } + + default: { + return KStyle::subRect(r, widget); + } + } +} + +QRect PlastikStyle::querySubControlMetrics(ComplexControl control, + const QWidget *widget, + SubControl subcontrol, + const QStyleOption &opt) const +{ + if (!widget) { + return QRect(); + } + + QRect r(widget->rect()); + switch (control) { + case CC_ComboBox: { + switch (subcontrol) { + case SC_ComboBoxEditField: { + // TODO: is the handler width in pixelmetric? + return QRect(r.left()+2, r.top()+2, r.width()-4-15-1, r.height()-4); + } + default: { + return KStyle::querySubControlMetrics(control, widget, subcontrol, opt); + } + } + break; + } + case CC_SpinWidget: { + const int fw = 2; // Frame width... + + const bool heightDividable = ((r.height()%2) == 0); + + QSize bs; + if(heightDividable) { + bs.setHeight(QMAX(8, (r.height()-2)/2)); + } else { + bs.setHeight(QMAX(8, (r.height()-2-1)/2)); + } + bs.setWidth(15); + + const int buttonsLeft = /*reverseLayout?r.left()+1:*/r.right()-bs.width(); + + switch (subcontrol) { + case SC_SpinWidgetUp: { + return QRect(buttonsLeft, r.top()+1, bs.width(), bs.height() ); + } + case SC_SpinWidgetDown: { + if(heightDividable) { + return QRect(buttonsLeft, r.top()+1+bs.height(), + bs.width(), r.height()-(bs.height()+2) ); + } else { + return QRect(buttonsLeft, r.top()+1+bs.height()+1, + bs.width(), r.height()-(bs.height()+2+1) ); + } + } + case SC_SpinWidgetFrame: { + return QRect(r.left(), r.top(), r.width(), r.height() ); + } + case SC_SpinWidgetEditField: { + return QRect(r.left()+fw, r.top()+fw, + r.width()-(bs.width()+1+2*fw), r.height()-2*fw); + } + case SC_SpinWidgetButtonField: { + return QRect(buttonsLeft, r.top()+1, bs.width(), r.height()-2); + } + default: { + return KStyle::querySubControlMetrics(control, widget, subcontrol, opt); + } + } + break; + } + default: { + return KStyle::querySubControlMetrics(control, widget, subcontrol, opt); + } + } +} + +int PlastikStyle::pixelMetric(PixelMetric m, const QWidget *widget) const +{ + switch(m) { + // TABS + // ---- + case PM_TabBarTabVSpace: { + const QTabBar * tb = (const QTabBar *) widget; + if (tb->shape() == QTabBar::RoundedAbove || + tb->shape() == QTabBar::RoundedBelow) + return 12; + else + return 4; + } + + case PM_TabBarTabOverlap: { + return 1; + } + + // extra space between menubar items + case PM_MenuBarItemSpacing: { + return 6; + } + +// // extra space between toolbar items +// case PM_ToolBarItemSpacing: { +// return 4; +// } + + // SCROLL BAR + case PM_ScrollBarSliderMin: { + return 21; + } + case PM_ScrollBarExtent: { + return 16; + } + + case PM_DockWindowSeparatorExtent: + return 6; + + // SPLITTERS + // --------- + case PM_SplitterWidth: { + return 6; + } + + // PROGRESSBARS + // ------------ + case PM_ProgressBarChunkWidth: + return 10; + + // SLIDER + // ------ + case PM_SliderLength: + return 11; + + // MENU INDICATOR + // -------------- + case PM_MenuButtonIndicator: + return 8; + + // CHECKBOXES / RADIO BUTTONS + // -------------------------- + case PM_ExclusiveIndicatorWidth: // Radiobutton size + case PM_ExclusiveIndicatorHeight: // 13x13 + case PM_IndicatorWidth: // Checkbox size + case PM_IndicatorHeight: // 13x13 + return 13; + + // FRAMES + // ------ + case PM_SpinBoxFrameWidth: + return 1; + + case PM_MenuBarFrameWidth: + return 1; + + case PM_DefaultFrameWidth: { + if(widget && ::qt_cast<QPopupMenu*>(widget)) + return 1; + else + return 2; + } + + case PM_ButtonDefaultIndicator: { + return 0; + } + + case PM_ButtonMargin: { + return 2; + } + + case PM_ButtonShiftVertical: + case PM_ButtonShiftHorizontal: { + return 1; + } + + default: + return KStyle::pixelMetric(m, widget); + } +} + + +QSize PlastikStyle::sizeFromContents(ContentsType t, + const QWidget *widget, + const QSize &s, + const QStyleOption &opt) const +{ + switch (t) { + case CT_PopupMenuItem: { + if (!widget || opt.isDefault()) + return s; + + const QPopupMenu *popup = dynamic_cast<const QPopupMenu *>(widget); + QMenuItem *mi = opt.menuItem(); + int maxpmw = opt.maxIconWidth(); + int w = s.width(), h = s.height(); + bool checkable = popup->isCheckable(); + + if (mi->custom()) { + w = mi->custom()->sizeHint().width(); + h = mi->custom()->sizeHint().height(); + if (!mi->custom()->fullSpan() ) + h += 4; + } else if (mi->widget()) { + // don't change the size in this case. + } else if (mi->isSeparator()) { + w = 20; + h = 2; + } else { + if (mi->pixmap()) { + h = QMAX(h, mi->pixmap()->height() + 2); + } else { + h = QMAX(h, 16 + 2 ); + h = QMAX(h, popup->fontMetrics().height() + 4 ); + } + + if (mi->iconSet()) { + h = QMAX(h, mi->iconSet()->pixmap(QIconSet::Small, QIconSet::Normal).height() + 2); + } + } + + if (!mi->text().isNull() && (mi->text().find('\t') >= 0)) { + w += itemHMargin + itemFrame*2 + 7; + } else if (mi->popup()) { + w += 2 * arrowHMargin; + } + + if (maxpmw) { + w += maxpmw + 6; + } + if (checkable && maxpmw < 20) { + w += 20 - maxpmw; + } + if (checkable || maxpmw > 0) { + w += 12; + } + + w += rightBorder; + + return QSize(w, h); + } + + case CT_PushButton: + { + const QPushButton* btn = static_cast<const QPushButton*>(widget); + + int w = s.width() + 2 * pixelMetric(PM_ButtonMargin, widget); + int h = s.height() + 2 * pixelMetric(PM_ButtonMargin, widget); + if ( btn->text().isEmpty() && s.width() < 32 ) return QSize(w, h); + + return QSize( w+25, h+5 ); + } + + case CT_ToolButton: + { + if(widget->parent() && ::qt_cast<QToolBar*>(widget->parent()) ) + return QSize( s.width()+2*4, s.height()+2*4 ); + else + return KStyle::sizeFromContents (t, widget, s, opt); + } + + default: + return KStyle::sizeFromContents (t, widget, s, opt); + } + + return KStyle::sizeFromContents (t, widget, s, opt); +} + +int PlastikStyle::styleHint( StyleHint stylehint, + const QWidget *widget, + const QStyleOption &option, + QStyleHintReturn* returnData ) const +{ + switch (stylehint) { + case SH_PopupMenu_SubMenuPopupDelay: + return 96; // Motif-like delay... + + default: + return KStyle::styleHint(stylehint, widget, option, returnData); + } +} + +bool PlastikStyle::eventFilter(QObject *obj, QEvent *ev) +{ + if (KStyle::eventFilter(obj, ev) ) + return true; + + if (!obj->isWidgetType() ) return false; + + // focus highlight + if ( ::qt_cast<QLineEdit*>(obj) ) { + QWidget* widget = static_cast<QWidget*>(obj); + + if ( ::qt_cast<QSpinWidget*>(widget->parentWidget()) ) + { + QWidget* spinbox = widget->parentWidget(); + if ((ev->type() == QEvent::FocusIn) || (ev->type() == QEvent::FocusOut)) + { + spinbox->repaint(false); + } + return false; + } + + if ((ev->type() == QEvent::FocusIn) || (ev->type() == QEvent::FocusOut)) + { + widget->repaint(false); + } + return false; + } + + //Hover highlight... use qt_cast to check if the widget inheits one of the classes. + if ( ::qt_cast<QPushButton*>(obj) || ::qt_cast<QComboBox*>(obj) || + ::qt_cast<QSpinWidget*>(obj) || ::qt_cast<QCheckBox*>(obj) || + ::qt_cast<QRadioButton*>(obj) || ::qt_cast<QToolButton*>(obj) || obj->inherits("QSplitterHandle") ) + { + if ((ev->type() == QEvent::Enter) && static_cast<QWidget*>(obj)->isEnabled()) + { + QWidget* button = static_cast<QWidget*>(obj); + hoverWidget = button; + button->repaint(false); + } + else if ((ev->type() == QEvent::Leave) && (obj == hoverWidget) ) + { + QWidget* button = static_cast<QWidget*>(obj); + hoverWidget = 0; + button->repaint(false); + } + return false; + } + if ( ::qt_cast<QTabBar*>(obj) ) { + if ((ev->type() == QEvent::Enter) && static_cast<QWidget*>(obj)->isEnabled()) + { + QWidget* tabbar = static_cast<QWidget*>(obj); + hoverWidget = tabbar; + hoverTab = 0; + tabbar->repaint(false); + } + else if (ev->type() == QEvent::MouseMove) + { + QTabBar *tabbar = dynamic_cast<QTabBar*>(obj); + QMouseEvent *me = dynamic_cast<QMouseEvent*>(ev); + + if (tabbar && me) { + // avoid unnecessary repaints (which otherwise would occour on every + // MouseMove event causing high cpu load). + + bool repaint = true; + + QTab *tab = tabbar->selectTab(me->pos() ); + if (hoverTab == tab) + repaint = false; + hoverTab = tab; + + if (repaint) + tabbar->repaint(false); + } + } + else if (ev->type() == QEvent::Leave) + { + QWidget* tabbar = static_cast<QWidget*>(obj); + hoverWidget = 0; + hoverTab = 0; + tabbar->repaint(false); + } + return false; + } + // Track show events for progress bars + if ( _animateProgressBar && ::qt_cast<QProgressBar*>(obj) ) + { + if ((ev->type() == QEvent::Show) && !animationTimer->isActive()) + { + animationTimer->start( 50, false ); + } + } + if ( !qstrcmp(obj->name(), "kde toolbar widget") ) + { + QWidget* lb = static_cast<QWidget*>(obj); + if (lb->backgroundMode() == Qt::PaletteButton) + lb->setBackgroundMode(Qt::PaletteBackground); + lb->removeEventFilter(this); + } + + return false; +} + +QColor PlastikStyle::getColor(const QColorGroup &cg, const ColorType t, const bool enabled)const +{ + return getColor(cg, t, enabled?IsEnabled:IsDisabled); +} + +QColor PlastikStyle::getColor(const QColorGroup &cg, const ColorType t, const WidgetState s)const +{ + const bool enabled = (s != IsDisabled) && + ((s == IsEnabled) || (s == IsPressed) || (s == IsHighlighted)); + const bool pressed = (s == IsPressed); + const bool highlighted = (s == IsHighlighted); + switch(t) { + case ButtonContour: + return enabled ? cg.button().dark(130+_contrast*8) + : cg.background().dark(120+_contrast*8); + case DragButtonContour: { + if(enabled) { + if(pressed) + return cg.button().dark(130+_contrast*6); // bright + else if(highlighted) + return cg.button().dark(130+_contrast*9); // dark + else + return cg.button().dark(130+_contrast*8); // normal + } else { + return cg.background().dark(120+_contrast*8); + } + } + case DragButtonSurface: { + if(enabled) { + if(pressed) + return cg.button().dark(100-_contrast); // bright + else if(highlighted) + return cg.button().light(100+_contrast); // dark + else + return cg.button(); // normal + } else { + return cg.background(); + } + } + case PanelContour: + return cg.background().dark(160+_contrast*8); + case PanelDark: + return alphaBlendColors(cg.background(), cg.background().dark(120+_contrast*5), 110); + case PanelDark2: + return alphaBlendColors(cg.background(), cg.background().dark(110+_contrast*5), 110); + case PanelLight: + return alphaBlendColors(cg.background(), cg.background().light(120+_contrast*5), 110); + case PanelLight2: + return alphaBlendColors(cg.background(), cg.background().light(110+_contrast*5), 110); + case MouseOverHighlight: + if( _customOverHighlightColor ) + return _overHighlightColor; + else + return cg.highlight(); + case FocusHighlight: + if( _customFocusHighlightColor ) + return _focusHighlightColor; + else + return cg.highlight(); + case CheckMark: + if( _customCheckMarkColor ) + return _checkMarkColor; + else + return cg.foreground(); + default: + return cg.background(); + } +} diff --git a/kstyles/plastik/plastik.h b/kstyles/plastik/plastik.h new file mode 100644 index 000000000..32a48ec96 --- /dev/null +++ b/kstyles/plastik/plastik.h @@ -0,0 +1,362 @@ +/* Plastik widget style for KDE 3 + Copyright (C) 2003 Sandro Giessl <[email protected]> + + based on the KDE style "dotNET": + Copyright (C) 2001-2002, Chris Lee <[email protected]> + Carsten Pfeiffer <[email protected]> + Karol Szwed <[email protected]> + Drawing routines completely reimplemented from KDE3 HighColor, which was + originally based on some stuff from the KDE2 HighColor. + + based on drawing routines of the style "Keramik": + Copyright (c) 2002 Malte Starostik <[email protected]> + (c) 2002,2003 Maksim Orlovich <[email protected]> + based on the KDE3 HighColor Style + Copyright (C) 2001-2002 Karol Szwed <[email protected]> + (C) 2001-2002 Fredrik H�glund <[email protected]> + Drawing routines adapted from the KDE2 HCStyle, + Copyright (C) 2000 Daniel M. Duley <[email protected]> + (C) 2000 Dirk Mueller <[email protected]> + (C) 2001 Martijn Klingens <[email protected]> + Progressbar code based on KStyle, + Copyright (C) 2001-2002 Karol Szwed <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#ifndef __PLASTIK_H +#define __PLASTIK_H + +#include <kstyle.h> +#include <qbitmap.h> +#include <qintcache.h> + +#define u_arrow -4,1, 2,1, -3,0, 1,0, -2,-1, 0,-1, -1,-2 +#define d_arrow -4,-2, 2,-2, -3,-1, 1,-1, -2,0, 0,0, -1,1 +#define l_arrow 0,-3, 0,3,-1,-2,-1,2,-2,-1,-2,1,-3,0 +#define r_arrow -2,-3,-2,3,-1,-2, -1,2,0,-1,0,1,1,0 + +#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) + +class QSettings; +class QTab; +class QTimer; + +class PlastikStyle : public KStyle +{ + Q_OBJECT + +public: + PlastikStyle(); + virtual ~PlastikStyle(); + + void polish(QApplication* app ); + void polish(QWidget* widget ); + void unPolish(QWidget* widget ); + + void drawKStylePrimitive(KStylePrimitive kpe, + QPainter* p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawPrimitive(PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption &opt = QStyleOption::Default ) const; + + void drawControl(ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControlMask( ControlElement, QPainter *, const QWidget *, const QRect &, const QStyleOption &) const; + + void drawComplexControl(ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + SCFlags controls = SC_All, + SCFlags active = SC_None, + const QStyleOption& = QStyleOption::Default ) const; + + int pixelMetric(PixelMetric m, + const QWidget *widget = 0 ) const; + + QRect subRect(SubRect r, + const QWidget *widget ) const; + + QRect querySubControlMetrics(ComplexControl control, + const QWidget *widget, + SubControl subcontrol, + const QStyleOption &opt = QStyleOption::Default ) const; + + void drawComplexControlMask(QStyle::ComplexControl c, + QPainter *p, + const QWidget *w, + const QRect &r, + const QStyleOption &o=QStyleOption::Default) const; + + QSize sizeFromContents(QStyle::ContentsType t, + const QWidget *w, + const QSize &s, + const QStyleOption &o) const; + + int styleHint(StyleHint, const QWidget * = 0, + const QStyleOption & = QStyleOption::Default, + QStyleHintReturn * = 0 ) const; + +protected: + enum TabPosition + { + First = 0, + Middle, + Last, + Single // only one tab! + }; + + enum ColorType + { + ButtonContour, + DragButtonContour, + DragButtonSurface, + PanelContour, + PanelLight, + PanelLight2, + PanelDark, + PanelDark2, + MouseOverHighlight, + FocusHighlight, + CheckMark + }; + + enum WidgetState + { + IsEnabled, + IsPressed, // implies IsEnabled + IsHighlighted, // implies IsEnabled + IsDisabled + }; + + // the only way i see to provide all these options + // to renderContour/renderSurface... + enum SurfaceFlags { + Draw_Left = 0x00000001, + Draw_Right = 0x00000002, + Draw_Top = 0x00000004, + Draw_Bottom = 0x00000008, + Highlight_Left = 0x00000010, // surface + Highlight_Right = 0x00000020, // surface + Highlight_Top = 0x00000040, // surface + Highlight_Bottom = 0x00000080, // surface + Is_Sunken = 0x00000100, // surface + Is_Horizontal = 0x00000200, // surface + Is_Highlight = 0x00000400, // surface + Is_Default = 0x00000800, // surface + Is_Disabled = 0x00001000, + Round_UpperLeft = 0x00002000, + Round_UpperRight = 0x00004000, + Round_BottomLeft = 0x00008000, + Round_BottomRight = 0x00010000, + Draw_AlphaBlend = 0x00020000 + }; + + void renderContour(QPainter *p, + const QRect &r, + const QColor &backgroundColor, + const QColor &contourColor, + const uint flags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom| + Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight) const; + + void renderMask(QPainter *p, + const QRect &r, + const QColor &color, + const uint flags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom| + Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight) const; + + void renderSurface(QPainter *p, + const QRect &r, + const QColor &backgroundColor, + const QColor &buttonColor, + const QColor &highlightColor, + int intensity = 5, + const uint flags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom| + Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight| + Is_Horizontal) const; + + inline void renderPixel(QPainter *p, + const QPoint &pos, + const int alpha, + const QColor &color, + const QColor &background = QColor(), + bool fullAlphaBlend = true) const; + + void renderButton(QPainter *p, + const QRect &r, + const QColorGroup &g, + bool sunken = false, + bool mouseOver = false, + bool horizontal = true, + bool enabled = true, + bool khtmlMode = false) const; + + void renderPanel(QPainter *p, + const QRect &r, + const QColorGroup &g, + const bool pseudo3d = true, + const bool sunken = true) const; + + void renderDot(QPainter *p, + const QPoint &point, + const QColor &baseColor, + const bool thick = false, + const bool sunken = false) const; + + void renderGradient(QPainter *p, + const QRect &r, + const QColor &c1, + const QColor &c2, + bool horizontal = true) const; + + void renderTab(QPainter *p, + const QRect &r, + const QColorGroup &g, + bool mouseOver = false, + const bool selected = false, + const bool bottom = false, + const TabPosition pos = Middle, + const bool triangular = false, + const bool cornerWidget = false) const; + + virtual void renderMenuBlendPixmap( KPixmap& pix, const QColorGroup& cg, + const QPopupMenu* popup ) const; + + bool eventFilter(QObject *, QEvent *); + + QWidget* hoverWidget; +protected slots: + void khtmlWidgetDestroyed(QObject* w); + + //Animation slots. + void updateProgressPos(); + void progressBarDestroyed(QObject* bar); + + inline QColor getColor(const QColorGroup &cg, const ColorType t, const bool enabled = true)const; + inline QColor getColor(const QColorGroup &cg, const ColorType t, const WidgetState s)const; +private: +// Disable copy constructor and = operator + PlastikStyle( const PlastikStyle & ); + PlastikStyle& operator=( const PlastikStyle & ); + + bool kickerMode, kornMode; + mutable bool flatMode; + + int _contrast; + bool _scrollBarLines; + bool _animateProgressBar; + bool _drawToolBarSeparator; + bool _drawToolBarItemSeparator; + bool _drawFocusRect; + bool _drawTriangularExpander; + bool _inputFocusHighlight; + bool _customOverHighlightColor; + bool _customFocusHighlightColor; + bool _customCheckMarkColor; + QColor _overHighlightColor; + QColor _focusHighlightColor; + QColor _checkMarkColor; + + QTab *hoverTab; + + // track khtml widgets. + QMap<const QWidget*,bool> khtmlWidgets; + + //Animation support. + QMap<QWidget*, int> progAnimWidgets; + + // pixmap cache. + enum CacheEntryType { + cSurface, + cGradientTile, + cAlphaDot + }; + struct CacheEntry + { + CacheEntryType type; + int width; + int height; + QRgb c1Rgb; + QRgb c2Rgb; + bool horizontal; + + QPixmap* pixmap; + + CacheEntry(CacheEntryType t, int w, int h, QRgb c1, QRgb c2 = 0, + bool hor = false, QPixmap* p = 0 ): + type(t), width(w), height(h), c1Rgb(c1), c2Rgb(c2), horizontal(hor), pixmap(p) + {} + + ~CacheEntry() + { + delete pixmap; + } + + int key() + { + // create an int key from the properties which is used to refer to entries in the QIntCache. + // the result may not be 100% correct as we don't have so much space in one integer -- use + // == operator after find to make sure we got the right one. :) + return horizontal ^ (type<<1) ^ (width<<5) ^ (height<<10) ^ (c1Rgb<<19) ^ (c2Rgb<<22); + } + + bool operator == (const CacheEntry& other) + { + bool match = (type == other.type) && + (width == other.width) && + (height == other.height) && + (c1Rgb == other.c1Rgb) && + (c1Rgb == other.c1Rgb) && + (horizontal == other.horizontal); +// if(!match) { +// qDebug("operator ==: CacheEntries don't match!"); +// qDebug("width: %d\t\tother width: %d", width, other.width); +// qDebug("height: %d\t\tother height: %d", height, other.height); +// qDebug("fgRgb: %d\t\tother fgRgb: %d", fgRgb, other.fgRgb); +// qDebug("bgRgb: %d\t\tother bgRgb: %d", bgRgb, other.bgRgb); +// qDebug("surfaceFlags: %d\t\tother surfaceFlags: %d", surfaceFlags, other.surfaceFlags); +// } + return match; + } + }; + QIntCache<CacheEntry> *pixmapCache; + + // For KPE_ListViewBranch + mutable QBitmap *verticalLine; + mutable QBitmap *horizontalLine; + + // For progress bar animation + QTimer *animationTimer; +}; + +#endif // __PLASTIK_H diff --git a/kstyles/plastik/plastik.themerc b/kstyles/plastik/plastik.themerc new file mode 100644 index 000000000..c3f8ad861 --- /dev/null +++ b/kstyles/plastik/plastik.themerc @@ -0,0 +1,101 @@ +[Misc] +Name=Plastik +Name[af]=Plastiek +Name[be]=Пластыка +Name[bn]=প্লাস্টিক +Name[fa]=پلاستیک +Name[he]=פלסטיק +Name[hi]=प्लास्टिक +Name[is]=Plast +Name[ka]=პლასტიკი +Name[kk]=Пластик +Name[lt]=Plastikinis +Name[lv]=Plastika +Name[mk]=Пластик +Name[nb]=Plastikk +Name[ne]=प्लास्टिक +Name[nn]=Plastikk +Name[pa]=ਪਲਾਸਟਿਕ +Name[ru]=Пластик +Name[sr]=Пластика +Name[sr@Latn]=Plastika +Name[ta]=ப்ளாஸ்டிக் +Name[te]=ప్లాస్టిక్ +Name[tg]=Пластик +Name[th]=พลาสติคK +Name[uk]=Пластик +Name[uz@cyrillic]=Пластик +Name[zh_CN]=塑料 +ConfigPage=kstyle_plastik_config +Comment=A simple and clean style +Comment[af]=´n eenvoudige en skoon styl +Comment[be]=Просты і прыгожы стыль +Comment[bg]=Семпъл и изчистен стил +Comment[bn]=একটি সরল এবং পরিচ্ছন্ন স্টাইল +Comment[br]=Un arloadig panell eeun +Comment[bs]=Jednostavan i čist stil +Comment[ca]=Un estil simple i net +Comment[cs]=Jednoduchý a čistý styl +Comment[csb]=Prosti ë czësti sztél +Comment[cy]=Arddull syml a glan +Comment[da]=En simpel og ren stil +Comment[de]=Ein einfacher und schlichter Stil +Comment[el]=Ένα απλό και καθαρό στυλ +Comment[eo]=Simpla kaj pura etoso +Comment[es]=Un estilo sencillo y terso +Comment[et]=Lihtne ja klaar stiil +Comment[eu]=Estilo xehe eta gardena +Comment[fa]=یک سبک ساده و تمیز +Comment[fi]=Yksinkertainen ja siisti tyyli +Comment[fr]=Un style simple et propre +Comment[fy]=In ienfâldich en skjinne styl +Comment[ga]=Stíl shímplí shoiléir +Comment[gl]=Un estilo simples e limpo +Comment[he]=סגנון נקי ופשוט +Comment[hi]=एक सादा और साफ शैली +Comment[hr]=Jednostavan i pregledan stil +Comment[hu]=Áttekinthető, egyszerű alapstílus +Comment[id]=Gaya yang ringkas dan sederhana +Comment[is]=Einfaldur og hreinlegur stíll +Comment[it]=Uno stile semplice e pulito +Comment[ja]=シンプルできれいなスタイル +Comment[ka]=მარტივი და სუფთა სტილი +Comment[kk]=Қарапайым және анық стилі +Comment[km]=រចនាប័ទ្មសាមញ្ញ ហើយស្អាត +Comment[lb]=En einfachen a schlichte Stil +Comment[lt]=Paprastas ir švarus stilius +Comment[lv]=Vienkāršs un tīrs stils +Comment[mk]=Едноставен и чист стил +Comment[ms]=Gaya ringkas dan bersih +Comment[nb]=En enkel og ren stil +Comment[nds]=En eenfache un smucke Stil +Comment[ne]=सरल र सफा शैली +Comment[nl]=Een eenvoudige en schone stijl +Comment[nn]=Ein enkel og rein stil +Comment[pa]=ਇੱਕ ਸਧਾਰਨ ਤੇ ਸਾਫ਼ ਸ਼ੈਲੀ +Comment[pl]=Prosty i czysty styl +Comment[pt]=Um estilo simples e limpo +Comment[pt_BR]=Um estilo simples e limpo +Comment[ro]=Un stil simplu şi clar +Comment[ru]=Простой и изящный стиль +Comment[rw]=Imisusire yoroshye kandi ikeye +Comment[se]=Oktageardánis ja čorges stiila +Comment[sk]=Jednoduchý a čistý štýl +Comment[sl]=Preprost in čist slog +Comment[sr]=Једноставан и чист стил +Comment[sr@Latn]=Jednostavan i čist stil +Comment[sv]=En enkel och ren stil +Comment[ta]=ஒரு சுலபமானதும் தெளிவானதுமான பாணி +Comment[te]=సరళమైన మరయు శుభ్రమైన ఒక శైలి +Comment[tg]=Услуби осон ва тоза +Comment[th]=รูปแบบที่เรียบง่ายและสะอาด +Comment[tr]=Basit ve temiz stil +Comment[tt]=Ciñel yämle tışlaw +Comment[uk]=Простий та чистий стиль +Comment[uz]=Oddiy va chiroyli uslub +Comment[uz@cyrillic]=Оддий ва чиройли услуб +Comment[vi]=Kiểu dáng sạch và đơn giản. +Comment[zh_CN]=简洁清爽的样式 +Comment[zh_TW]=簡單而乾淨的風格 +[KDE] +WidgetStyle=Plastik diff --git a/kstyles/riscos/Makefile.am b/kstyles/riscos/Makefile.am new file mode 100644 index 000000000..c861fcbf9 --- /dev/null +++ b/kstyles/riscos/Makefile.am @@ -0,0 +1,40 @@ +pixmap_DATA = \ + arrowdown.png \ + arrowdown_down.png \ + arrowleft.png \ + arrowleft_down.png \ + arrowright.png \ + arrowright_down.png \ + arrowup.png \ + arrowup_down.png \ + background.png \ + check.png \ + check_checked.png \ + checkmark.png \ + combo.png \ + combo_down.png \ + hscrollback.png \ + hscrollbar.png \ + hscrollbar_down.png \ + hscrollborder.png \ + htab.png \ + menu_back.png \ + radio.png \ + radio_down.png \ + raised_border.png \ + scrollborder.png \ + slider.png \ + sunk_border.png \ + tab_up.png \ + vscrollback.png \ + vscrollbar.png \ + vscrollbar_down.png \ + vscrollborder.png \ + vtab.png + +pixmapdir = $(kde_datadir)/kstyle/pixmaps/riscos + +themerc_DATA = riscos.themerc +themercdir = $(kde_datadir)/kstyle/themes + +EXTRA_DIST = $(pixmap_DATA) $(themerc_DATA) diff --git a/kstyles/riscos/README b/kstyles/riscos/README new file mode 100644 index 000000000..2e4e6fba6 --- /dev/null +++ b/kstyles/riscos/README @@ -0,0 +1,5 @@ +This theme was made by Rich Wareham. Bug reports to Rik Hemsley <[email protected]> +who is looking after it. + +After a make install, it should appear in kcontrol's 'style' module. + diff --git a/kstyles/riscos/arrowdown.png b/kstyles/riscos/arrowdown.png Binary files differnew file mode 100644 index 000000000..3965607bd --- /dev/null +++ b/kstyles/riscos/arrowdown.png diff --git a/kstyles/riscos/arrowdown_down.png b/kstyles/riscos/arrowdown_down.png Binary files differnew file mode 100644 index 000000000..060ce51ae --- /dev/null +++ b/kstyles/riscos/arrowdown_down.png diff --git a/kstyles/riscos/arrowleft.png b/kstyles/riscos/arrowleft.png Binary files differnew file mode 100644 index 000000000..0e774c29c --- /dev/null +++ b/kstyles/riscos/arrowleft.png diff --git a/kstyles/riscos/arrowleft_down.png b/kstyles/riscos/arrowleft_down.png Binary files differnew file mode 100644 index 000000000..da2332ef5 --- /dev/null +++ b/kstyles/riscos/arrowleft_down.png diff --git a/kstyles/riscos/arrowright.png b/kstyles/riscos/arrowright.png Binary files differnew file mode 100644 index 000000000..89a619932 --- /dev/null +++ b/kstyles/riscos/arrowright.png diff --git a/kstyles/riscos/arrowright_down.png b/kstyles/riscos/arrowright_down.png Binary files differnew file mode 100644 index 000000000..dd6282ee6 --- /dev/null +++ b/kstyles/riscos/arrowright_down.png diff --git a/kstyles/riscos/arrowup.png b/kstyles/riscos/arrowup.png Binary files differnew file mode 100644 index 000000000..fce21a75d --- /dev/null +++ b/kstyles/riscos/arrowup.png diff --git a/kstyles/riscos/arrowup_down.png b/kstyles/riscos/arrowup_down.png Binary files differnew file mode 100644 index 000000000..c453a3af2 --- /dev/null +++ b/kstyles/riscos/arrowup_down.png diff --git a/kstyles/riscos/background.png b/kstyles/riscos/background.png Binary files differnew file mode 100644 index 000000000..9e41b4e54 --- /dev/null +++ b/kstyles/riscos/background.png diff --git a/kstyles/riscos/check.png b/kstyles/riscos/check.png Binary files differnew file mode 100644 index 000000000..6b259b27c --- /dev/null +++ b/kstyles/riscos/check.png diff --git a/kstyles/riscos/check_checked.png b/kstyles/riscos/check_checked.png Binary files differnew file mode 100644 index 000000000..2513565dc --- /dev/null +++ b/kstyles/riscos/check_checked.png diff --git a/kstyles/riscos/checkmark.png b/kstyles/riscos/checkmark.png Binary files differnew file mode 100644 index 000000000..331a6c827 --- /dev/null +++ b/kstyles/riscos/checkmark.png diff --git a/kstyles/riscos/combo.png b/kstyles/riscos/combo.png Binary files differnew file mode 100644 index 000000000..ead94e7a4 --- /dev/null +++ b/kstyles/riscos/combo.png diff --git a/kstyles/riscos/combo_down.png b/kstyles/riscos/combo_down.png Binary files differnew file mode 100644 index 000000000..e3e2dfab7 --- /dev/null +++ b/kstyles/riscos/combo_down.png diff --git a/kstyles/riscos/hscrollback.png b/kstyles/riscos/hscrollback.png Binary files differnew file mode 100644 index 000000000..b6ebe838a --- /dev/null +++ b/kstyles/riscos/hscrollback.png diff --git a/kstyles/riscos/hscrollbar.png b/kstyles/riscos/hscrollbar.png Binary files differnew file mode 100644 index 000000000..9f29c3e0b --- /dev/null +++ b/kstyles/riscos/hscrollbar.png diff --git a/kstyles/riscos/hscrollbar_down.png b/kstyles/riscos/hscrollbar_down.png Binary files differnew file mode 100644 index 000000000..ef0153cad --- /dev/null +++ b/kstyles/riscos/hscrollbar_down.png diff --git a/kstyles/riscos/hscrollborder.png b/kstyles/riscos/hscrollborder.png Binary files differnew file mode 100644 index 000000000..113d92200 --- /dev/null +++ b/kstyles/riscos/hscrollborder.png diff --git a/kstyles/riscos/htab.png b/kstyles/riscos/htab.png Binary files differnew file mode 100644 index 000000000..0527b4d7e --- /dev/null +++ b/kstyles/riscos/htab.png diff --git a/kstyles/riscos/menu_back.png b/kstyles/riscos/menu_back.png Binary files differnew file mode 100644 index 000000000..bbb1a0c74 --- /dev/null +++ b/kstyles/riscos/menu_back.png diff --git a/kstyles/riscos/radio.png b/kstyles/riscos/radio.png Binary files differnew file mode 100644 index 000000000..4e24602d0 --- /dev/null +++ b/kstyles/riscos/radio.png diff --git a/kstyles/riscos/radio_down.png b/kstyles/riscos/radio_down.png Binary files differnew file mode 100644 index 000000000..d416452f8 --- /dev/null +++ b/kstyles/riscos/radio_down.png diff --git a/kstyles/riscos/raised_border.png b/kstyles/riscos/raised_border.png Binary files differnew file mode 100644 index 000000000..f37c18eff --- /dev/null +++ b/kstyles/riscos/raised_border.png diff --git a/kstyles/riscos/riscos.themerc b/kstyles/riscos/riscos.themerc new file mode 100644 index 000000000..f88b8625b --- /dev/null +++ b/kstyles/riscos/riscos.themerc @@ -0,0 +1,344 @@ +# Risc OS theme by R. Wareham <[email protected]> + +[PushButton] +Background=227,227,227 +Foreground=0,0,0 +#PixmapBorder=riscos/raised_border.png +#PixmapBWidth=2 +Border=0 +Highlight=2 + +[PushButtonDown] +Background=187,187,187 +Foreground=0,0,0 +#PixmapBorder=riscos/sunk_border.png +#PixmapBWidth=2 +Border=0 +Highlight=2 + +[ToolButton] +Background=227,227,227 +Foreground=0,0,0 +#PixmapBorder=riscos/raised_border.png +#PixmapBWidth=2 +Highlight=2 +Border=0 + +[ToolButtonDown] +Background=187,187,187 +Foreground=0,0,0 +#PixmapBorder=riscos/sunk_border.png +#PixmapBWidth=2 +Border=0 +Highlight=2 + +[ToolBar] +Border=0 +Highlight=1 +Background=227,227,227 +Pixmap=riscos/background.png + +[CheckMark] +Border=0 +Highlight=0 +Pixmap=riscos/checkmark.png + +[MenuBar] +Background=227,227,227 +Border=0 +Highlight=1 +Pixmap=riscos/background.png + +[MenuBarItem] +Foreground=255,255,255 +Background=0,0,0 +Border=0 +Highlight=0 +#PixmapBorder=riscos/raised_border.png +#PixmapBWidth=2 + +[Menu] +Background=227,227,227 +Border=0 +Highlight=0 +Pixmap=riscos/background.png + +[MenuItem] +Background=227,227,227 +Border=0 +Highlight=0 +Pixmap=riscos/background.png + +[MenuItemDown] +Background=227,227,227 +Foreground=255,255,255 +Pixmap=riscos/menu_back.png +Border=0 +#Highlight=0 + +[Splitter] +Background=227,227,227 +Border=0 +Highlight=1 +#PixmapBorder=riscos/raised_border.png +#PixmapBWidth=2 + +[ProgressBar] +Border=0 +Highlight=2 +Foreground=255,255,255 +Background=187,187,187 + +[ProgressBackground] +Background=255,255,255 + +# Toolbar-Handles: +[VBarHandle] +#Pixmap=riscos/htab.png +Background=187,187,187 +Border=0 +Highlight=1 +#Scale=Vertical + +[HBarHandle] +#Pixmap=riscos/vtab.png +Background=187,187,187 +Border=0 +Highlight=1 +#Scale=Horizontal + +[VSBarSlider] +Pixmap=riscos/vscrollbar.png +PixmapBorder=riscos/vscrollborder.png +PixmapBWidth=3 + +[VSBarSliderDown] +Pixmap=riscos/vscrollbar_down.png +PixmapBorder=riscos/vscrollborder.png +PixmapBWidth=3 + +[VScrollGroove] +Pixmap=riscos/vscrollback.png +PixmapBorder=riscos/scrollborder.png +PixmapBWidth=1 + +[HSBarSlider] +Pixmap=riscos/hscrollbar.png +PixmapBorder=riscos/hscrollborder.png +PixmapBWidth=3 + +[HSBarSliderDown] +Pixmap=riscos/hscrollbar_down.png +PixmapBorder=riscos/hscrollborder.png +PixmapBWidth=3 + +[HScrollGroove] +Pixmap=riscos/hscrollback.png +PixmapBorder=riscos/scrollborder.png +PixmapBWidth=1 + +[ArrowUp] +Pixmap=riscos/arrowup.png + +[ArrowDown] +Pixmap=riscos/arrowdown.png + +[ArrowLeft] +Pixmap=riscos/arrowleft.png + +[ArrowRight] +Pixmap=riscos/arrowright.png + +[SunkenArrowUp] +Pixmap=riscos/arrowup_down.png + +[SunkenArrowDown] +Pixmap=riscos/arrowdown_down.png + +[SunkenArrowLeft] +Pixmap=riscos/arrowleft_down.png + +[SunkenArrowRight] +Pixmap=riscos/arrowright_down.png + +[Bevel] +Background=255,255,255 +Foreground=0,0,0 +Border=0 +Highlight=1 +Pixmap=riscos/background.png +#PixmapBorder=riscos/raised_border.png +#PixmapBWidth=2 + +[BevelDown] +Background=255,255,255 +Foreground=0,0,0 +Border=0 +Highlight=1 +Pixmap=riscos/background.png +#PixmapBorder=riscos/sunk_border.png +#PixmapBWidth=2 + +[ComboBox] +Background=227,227,227 +Foreground=0,0,0 +Border=0 +Highlight=1 + +[Radio] +Pixmap=riscos/radio.png +[RadioDown] +Pixmap=riscos/radio_down.png + +[CheckBox] +Pixmap=riscos/check.png +[CheckBoxDown] +Pixmap=riscos/check_checked.png + +[ComboDeco] +Pixmap=riscos/combo.png + +[Slider] +Pixmap=riscos/slider.png + +[SliderGroove] +SmallGroove=true + +[Tab] +Border=0 +Highlight=1 +Background=187,187,187 +Foreground=0,0,0 +BottomLine=true +#Pixmap=riscos/background.png + +[TabDown] +Border=0 +Highlight=1 +Background=227,227,227 +Foreground=0,0,0 +BottomLine=false +Pixmap=riscos/background.png + +[KDE] +widgetStyle=basicstyle.la +WidgetStyle=riscos + +[Misc] +ShadeStyle=Motif +ScrollBarExtent=20 +Name=RISC OS +Name[af]=Risc Os +Name[bn]=রিস্ক ও-এস +Name[cs]=Risc OS +Name[de]=RISC-OS +Name[eo]=Risc-OS +Name[eu]=RISC SE +Name[fa]=سیستم عامل RISC +Name[hi]=रिस्क ओएस(RISC OS) +Name[ko]=리스크 OS +Name[mn]=RISC-OS +Name[sl]=OS RISC +Name[sq]=Sistemi Operativ RISC +Name[te]=రిస్క్ ఓఎస్ +Name[tg]=Системаи омили RISC +Name[th]=ระบบปฏิบัติการ RISC +Name[uk]=RISC ОС +Name[uz@cyrillic]=RISC ОС +Name[zu]=IRISC OS +Comment=RISC OS-like theme +Comment[af]=Risc OS-like tema +Comment[ar]=سمة مشابهة لRISC OS +Comment[az]=RISC OS-oxşarı tərz +Comment[be]=Стыль RISC OS +Comment[bg]=Тема, подобна на RISC OS +Comment[bn]=রিস্ক ও.এস.-এর মতন থিম +Comment[br]=Giz doare ISC OS +Comment[bs]=Tema nalik na RISC OS +Comment[ca]=Tema tipus RISC OS +Comment[cs]=Motiv jako RISC OS +Comment[csb]=Téma szlachùjącô za RISC-OS +Comment[cy]=Thema sy'n debyg i RISC OS +Comment[da]=RISC OS-lignende tema +Comment[de]=Stil ähnlich RISC OS +Comment[el]=Θέμα παρόμοιο με το RISC OS +Comment[eo]=Risc OS - simila stilo +Comment[es]=Tema tipo RISC OS +Comment[et]=RISC OS-laadne teema +Comment[eu]=RISC SEen antzeko gaia +Comment[fa]=چهرۀ شبیه RISC سیستم عامل +Comment[fi]=RISC OS:n kaltainen tyyli +Comment[fr]=Thème similaire à RISC OS +Comment[fy]=RISC OS-eftich tema +Comment[ga]=Téama cosúil le RISC OS +Comment[gl]=Tema do estilo de RISC OS +Comment[he]=ערכת נושא דמויית RISC OS +Comment[hi]=रिस्क ओएस(RISC OS)-जैसा थीम +Comment[hr]=Tema nalik na RISC-OS +Comment[hu]=RISC OS-szerű téma +Comment[id]=Gaya RISC OS +Comment[is]=Stíll í anda RiscOS (Archimedes tölvur) +Comment[it]=Tema simile a RISC OS +Comment[ja]=RISC OS 風のテーマ +Comment[ka]=RISC OS-ის მსგავსი სტილი +Comment[kk]=RISC OS-секілді нақышы +Comment[km]=ស្បែក RISC OS-like +Comment[ko]=리스크 OS 같은 테마 +Comment[lb]=RISC OS-ähnlecht Thema +Comment[lt]=Panašus į RISC OS stilius +Comment[lv]=RISC OS līdzīga tēma +Comment[mk]=Тема што личи на RISC OS +Comment[mn]=RISC OS-той төсөөтэй хэлбэр +Comment[ms]=Tema ala RISC OS +Comment[mt]=Tema bħar-RISC OS +Comment[nb]=RISCO OS-lignende tema +Comment[nds]=Muster as in't RISC OS +Comment[ne]=RISC OS-जस्तै विषयवस्तु +Comment[nl]=RISC OS-achtig thema +Comment[nn]=RISC OS-aktig tema +Comment[nso]=Molaetsa wago swana le RISC OS +Comment[pa]=RISC OS-ਵਾਂਗ ਸਰੂਪ +Comment[pl]=Motyw podobny do RISC-OS +Comment[pt]=Estilo tipo RISC OS +Comment[pt_BR]=Tema parecido ao SO RISC +Comment[ro]=Tematică RISC OS +Comment[ru]=Тема, похожая на RISC OS +Comment[rw]=Insanganyamatsiko RISC OS-nka +Comment[se]=RISC OS-lágan fáddá +Comment[sk]=Téma ako RISC OS +Comment[sl]=Slog, podoben OS RISC +Comment[sq]=Temë sikurse ajo e sistemit operativ RISC +Comment[sr]=Тема налик на RISC OS +Comment[sr@Latn]=Tema nalik na RISC OS +Comment[sv]=RISC OS-liknande tema +Comment[ta]=RISC OS-போன்ற தலைப்பு +Comment[te]=రిస్క్ ఓఎస్ లాంటి ఒక వైవిద్యాంశం +Comment[tg]=Тарҳи шабияи системаи омили RISC +Comment[th]=ธีมคล้ายระบบปฏิบัติการบนชิพ RISC +Comment[tr]=RISC OS-benzeri stil +Comment[tt]=RISC OS-kebek tışlaw +Comment[uk]=Тема "а ля RISC OS" +Comment[uz]=RISC OSga oʻxshash mavzu +Comment[uz@cyrillic]=RISC ОСга ўхшаш мавзу +Comment[ven]=RISC OS-sa thero +Comment[vi]=Sắc thái kiểu RISC OS. +Comment[wa]=Tinme rishonnant al rivnance do sistinme RISC OS +Comment[xh]=RISC OS-Njengo mxholo +Comment[zh_CN]=类似 RISC OS 的主题 +Comment[zh_HK]=類似 RISC 風格的佈景 +Comment[zh_TW]=類似 RISC 的風格 +Comment[zu]=I-RISC OS-enjenge thimu +SButtonPosition=Opposite +FrameWidth=1 + +[Background] +Background=227,227,227 +Pixmap=riscos/background.png + +[General] +Background=227,227,227 +Foreground=0,0,0 +windowForeground=0,0,0 +windowBackground=255,255,255 +selectForeground=255,255,255 +selectBackground=0,0,0 diff --git a/kstyles/riscos/scrollborder.png b/kstyles/riscos/scrollborder.png Binary files differnew file mode 100644 index 000000000..21ca9e0e5 --- /dev/null +++ b/kstyles/riscos/scrollborder.png diff --git a/kstyles/riscos/slider.png b/kstyles/riscos/slider.png Binary files differnew file mode 100644 index 000000000..6eaf2641f --- /dev/null +++ b/kstyles/riscos/slider.png diff --git a/kstyles/riscos/sunk_border.png b/kstyles/riscos/sunk_border.png Binary files differnew file mode 100644 index 000000000..1710a9696 --- /dev/null +++ b/kstyles/riscos/sunk_border.png diff --git a/kstyles/riscos/tab_up.png b/kstyles/riscos/tab_up.png Binary files differnew file mode 100644 index 000000000..415896544 --- /dev/null +++ b/kstyles/riscos/tab_up.png diff --git a/kstyles/riscos/vscrollback.png b/kstyles/riscos/vscrollback.png Binary files differnew file mode 100644 index 000000000..effe211c3 --- /dev/null +++ b/kstyles/riscos/vscrollback.png diff --git a/kstyles/riscos/vscrollbar.png b/kstyles/riscos/vscrollbar.png Binary files differnew file mode 100644 index 000000000..8f869ef3a --- /dev/null +++ b/kstyles/riscos/vscrollbar.png diff --git a/kstyles/riscos/vscrollbar_down.png b/kstyles/riscos/vscrollbar_down.png Binary files differnew file mode 100644 index 000000000..31174b393 --- /dev/null +++ b/kstyles/riscos/vscrollbar_down.png diff --git a/kstyles/riscos/vscrollborder.png b/kstyles/riscos/vscrollborder.png Binary files differnew file mode 100644 index 000000000..c40c16a26 --- /dev/null +++ b/kstyles/riscos/vscrollborder.png diff --git a/kstyles/riscos/vtab.png b/kstyles/riscos/vtab.png Binary files differnew file mode 100644 index 000000000..0320818e3 --- /dev/null +++ b/kstyles/riscos/vtab.png diff --git a/kstyles/themes/Makefile.am b/kstyles/themes/Makefile.am new file mode 100644 index 000000000..da72902c7 --- /dev/null +++ b/kstyles/themes/Makefile.am @@ -0,0 +1,12 @@ + +kstylethemesdata_DATA = qtplatinum.themerc qtcde.themerc qtmotif.themerc qtwindows.themerc \ + qtsgi.themerc qtmotifplus.themerc\ + highcolor.themerc \ + default.themerc b3.themerc light-v2.themerc \ + light-v3.themerc keramik.themerc +kstylethemesdatadir = $(kde_datadir)/kstyle/themes + +EXTRA_DIST = $(kstylethemesdata_DATA) + +kde_conf_DATA = kthemestylerc + diff --git a/kstyles/themes/b3.themerc b/kstyles/themes/b3.themerc new file mode 100644 index 000000000..76cc88733 --- /dev/null +++ b/kstyles/themes/b3.themerc @@ -0,0 +1,90 @@ +[Misc] +Name=B3/KDE +Name[af]=B3/Kde +Name[bn]=বি-৩/কে.ডি.ই. +Name[fr]=B3 / KDE +Name[hi]=B3/केडीई +Name[ta]=B3/கேடிஇ +Name[te]=బ్3/కెడిఈ +Comment=B3/Modification of B2 +Comment[af]=B3/Verandering van B2 +Comment[ar]=B3/تعديل من B2 +Comment[az]=B3/B2-nin Təkmilləşdirilmiş halı +Comment[be]=Стыль B3/Modification +Comment[bg]=Тема модификация на B2, подобна на B3 +Comment[br]=Kemm B3 eus B2 +Comment[bs]=B3/Preinaka B2 +Comment[ca]=B3/Modificació de B2 +Comment[cs]=B3/modifikace B2 +Comment[csb]=B3/Mòdifikacëjô B2 +Comment[cy]=B3/Addasiad o B2 +Comment[da]=B3/Ændring af B2 +Comment[de]=B3: Eine Variante von B2 +Comment[el]=B3/Τροποποίηση του B2 +Comment[eo]=B3/Varianto bazinĝanta sur B2 +Comment[es]=B3/Modificación de B2 +Comment[et]=B3 - muudatustega B2 +Comment[eu]=B3/ B2 eraldatua +Comment[fa]=B3/اصلاح B2 +Comment[fi]=B3/Muokattu B2 +Comment[fr]=B3 / Modification de B2 +Comment[fy]=B3/modifikaasje fan B2 +Comment[ga]=B3/B2 mionathraithe +Comment[gl]=B3/Modificación de B2 +Comment[hi]=B3/ B2 का संशोधन +Comment[hr]=B3/Izmijenjeni B2 +Comment[hu]=B3/Módosított B2 +Comment[id]=B3/Modifikasi dari B2 +Comment[is]=B3, breytt útgáfa B2 +Comment[it]=B3/Modifica di B2 +Comment[ja]=B3 / B2 の改良版 +Comment[ka]=B3 - B2-ის მოდიფიკაცია +Comment[kk]=B3-өзгертілген B2 +Comment[km]=B3/ការកែប្រែរបស់ B2 +Comment[lb]=B3/Verännerung vu B2 +Comment[lt]=B3 – B2 modifikacija +Comment[lv]=B2 B3/Modifikācija +Comment[mk]=B3/Модификација на B2 +Comment[mn]=B3: B2-н нэгэн хувилбар +Comment[ms]=B3/Ubahsuaian B2 +Comment[mt]=B3/modifikazzjoni ta' B2 +Comment[nb]=B3/Endring av B2 +Comment[nds]=B3 is en ännert B2 +Comment[ne]=B2 को B3/परिमार्जन +Comment[nl]=B3/modificatie van B2 +Comment[nn]=B3 / Endring av B2 +Comment[nso]=B3/Kaonafatso ya B2 +Comment[oc]=B3/Modificacion de B2 +Comment[pa]=B3/B2 ਦਾ ਸੋਧਿਆ +Comment[pl]=B3/Modyfikacja B2 +Comment[pt]=B3/modificação do B2 +Comment[pt_BR]=B3/Modificação de B2 +Comment[ro]=B3, o modificare a B2 +Comment[ru]=B3 - вариация B2 +Comment[rw]=B3/ihindura rya B2 +Comment[se]=B3/Rievdaduvvon B2 +Comment[sk]=B3/Úprava B2 +Comment[sl]=B3/Spremenjena različica B2 +Comment[sq]=B3/Rregullimi i B2 +Comment[sr]=B3- модификација B2 +Comment[sr@Latn]=B3- modifikacija B2 +Comment[sv]=B3/Modifierad B2 +Comment[ta]=B3/B2ன் மாற்றம் +Comment[te]=B3/B2 యొక్క సవరింపు +Comment[tg]=B3/Таъғироти B2 +Comment[th]=B3/แก้ไขเพิ่มเติมจาก B2 +Comment[tr]=B3/B2'nin değiştirilmiş hali +Comment[tt]=B3/Üzgärtelgän B2 +Comment[uk]=B3/модифікація B2 +Comment[uz]=B3 - oʻzgartirilgan B2 +Comment[uz@cyrillic]=B3 - ўзгартирилган B2 +Comment[ven]=B3/U lugisela ha B2 +Comment[vi]=B2 đã sửa đổi / B3 +Comment[wa]=B3/Modifiadje do B2 +Comment[xh]=B3/Uguqulelo kancinane lwe B2 +Comment[zh_CN]=B3/修正的 B2 +Comment[zh_HK]=B3/B2 改良版 +Comment[zh_TW]=B3/B2 改良版 +Comment[zu]=B3/Ukulungisa kwe-B2 +[KDE] +WidgetStyle=B3 diff --git a/kstyles/themes/beos.themerc b/kstyles/themes/beos.themerc new file mode 100644 index 000000000..bb3e1a198 --- /dev/null +++ b/kstyles/themes/beos.themerc @@ -0,0 +1,83 @@ +[Misc] +Name=BeOS +Name[af]=Beos +Name[hi]=बीईओएस (BeOS) +Name[te]=బిఈఓఎస్ +Comment=Unthemed BeOS-like style +Comment[af]=Onbenoemde BeOS-tipe styl +Comment[ar]=مظهر مشابه لBeOS +Comment[az]=Örtüksüz BeOS bənzəri tərz +Comment[be]=Стыль BeOS +Comment[bg]=Стил без тема, подобен на BeOS +Comment[br]=Giz evel BeOS anwisket +Comment[bs]=Stil bez teme, sličan Beos-u +Comment[ca]=Estil del tipus BeOS sense temes +Comment[cs]=Styl podobný BeOS (bez motivu) +Comment[csb]=Sztél szlachùjący za BeOS-a, bez témów +Comment[cy]=Arddull di-thema sy'n debyg i BeOS +Comment[da]=BeOS-lignende stil uden tema +Comment[de]=BeOS-ähnlicher Stil (kein komplettes Design) +Comment[el]=Στυλ παρόμοιο με το BeOS +Comment[eo]=BeOS-simila stilo neetosa +Comment[es]=Estilo tipo BeOS sin tema +Comment[et]=BeOS'i-laadne teemata stiil +Comment[eu]=Gairik gabeko BeOS estiloa +Comment[fa]=سبک شبیه BeOS بدون چهره +Comment[fi]=Teemoittamaton BeOS:n kaltainen tyyli +Comment[fr]=Style sans thème similaire à BeOS +Comment[fy]=Temaleaze BeOs eftich slyl +Comment[ga]=Stíl gan téama, cosúil le BeOS +Comment[gl]=Estilo tipo Beos sen tema +Comment[he]=סגנון דומה ל־BeOS ללא ערכה +Comment[hi]=अनथीम्ड बीईओएस जैसी शैली +Comment[hr]=Stil bez teme, nalikuje na BeOS +Comment[hu]=BeOS-szerű megjelenés, téma nélkül +Comment[id]=Gaya ala BeOS tanpa tema +Comment[is]=Stíll í anda BeOS stýrikerfisins (án þema) +Comment[it]=Stile senza tema simile a BeOS +Comment[ja]=BeOS 風のスタイル (テーマなし) +Comment[ka]=BeOS-ის მსგავსი სტილი თემების გარეშე +Comment[kk]=Нақыштарсыз BeOS-секілді стиль +Comment[km]=រចនាប័ទ្ម BeOS-like ដែលគ្មានស្បែក +Comment[ko]=BeOS와 같은 꼴을 가진 테마 +Comment[lb]=BeOS-ähnlechen Stil ouni Thema +Comment[lt]=Betemis BeOS tipo stilius +Comment[lv]=Beztēmas BeOS līdzīgs stils +Comment[mk]=Beos стил (без тема) +Comment[mn]=BeOS-хэлбэрийн агшаалт +Comment[ms]=Gaya BeOS +Comment[nb]=Innebygget BeOS-liknende stil +Comment[nds]=Stil as in't BeOS (ahn Muster) +Comment[ne]=विषयवस्तु नगरिएको BeOS-जस्तै शैली +Comment[nl]=Themaloze BeOS-achtige stijl +Comment[nn]=BeOS-aktig stil utan tema +Comment[pa]=BeOS-ਵਰਗੀ ਸ਼ੈਲੀ +Comment[pl]=Styl podobny do BeOS-a, bez motywów +Comment[pt]=Estilo sem tema - tipo BeOS +Comment[pt_BR]=Estilo semelhante ao BeOS sem Temas +Comment[ro]=Stil fără tematică BeOS +Comment[ru]=Стиль без тем, похожий на BeOS +Comment[rw]=Imisusire BeOS-nka itahawe insanganyamatsiko +Comment[se]=Beos-lágan stiila fáttáhaga +Comment[sk]=Beos štýl bez témy +Comment[sl]=Netematski slog, podoben BeOS +Comment[sq]=Stili i patemë sikurse ai i BeOS +Comment[sr]=Стил без теме који личи на BeOS +Comment[sr@Latn]=Stil bez teme koji liči na BeOS +Comment[sv]=Otemad Beos-liknande stil +Comment[ta]=தலைப்பில்லா Beos-போன்ற பாணி +Comment[te]=వైవిద్యాంశం లేని బిఈఓఎస్ లాంటి ఒక శైలి +Comment[tg]=Бояд донист тарҳи BeOS ва сабук шуданашро +Comment[th]=ธีมรูปแบบคล้ายระบบปฏิบัติการ Beos +Comment[tr]=BeOS benzeri temasız stil +Comment[tt]=BeOS-kebek tışlaw +Comment[uk]=Стиль схожий на BeOS без встановленої теми +Comment[uz]=BeOS'ga oʻxshash mavzusiz uslub +Comment[uz@cyrillic]=BeOS'га ўхшаш мавзусиз услуб +Comment[vi]=Kiểu dáng như BeOS không có sắc thái. +Comment[wa]=Tinme rishonnant al rivnance do sistinme BeOS +Comment[zh_CN]=无主题的类似 Beos 的风格 +Comment[zh_HK]=類似未修改佈景的 BeOS +Comment[zh_TW]=沒有主題的 BeOS 的風格 +[KDE] +widgetStyle=beosstyle.la diff --git a/kstyles/themes/default.themerc b/kstyles/themes/default.themerc new file mode 100644 index 000000000..929fd6831 --- /dev/null +++ b/kstyles/themes/default.themerc @@ -0,0 +1,152 @@ +[Misc] +Name=KDE Classic +Name[af]=KDE Klassiek +Name[ar]=كيدي كلاسيكي +Name[az]=KDE Klassik +Name[be]=Класічны стыль KDE +Name[bn]=কে.ডি.ই. ক্লাসিক +Name[br]=KDE da gustum +Name[bs]=KDE klasični +Name[ca]=KDE clàssic +Name[cs]=Klasické KDE +Name[csb]=Klasykòwi KDE +Name[cy]=KDE Clasurol +Name[da]=KDE Klassisk +Name[de]=KDE-Classic +Name[el]=KDE κλασικό +Name[eo]=Klasika KDE +Name[es]=KDE clásico +Name[et]=KDE vaikestiil +Name[eu]=KDE Klasikoa +Name[fa]=KDE کلاسیک +Name[fi]=KDE:n klassikkotyyli +Name[fr]=KDE Classique +Name[fy]=KDE Klassyk +Name[ga]=KDE Clasaiceach +Name[gl]=Clásico de KDE +Name[he]=קלאסי של KDE +Name[hi]=केडीई क्लॉसिक +Name[hr]=KDE klasično +Name[id]=KDE Klasik +Name[is]=Klassískt KDE +Name[it]=KDE classico +Name[ja]=KDE クラシック +Name[ka]=კლასიკური KDE +Name[kk]=Классикалық KDE +Name[km]=KDE បុរាណ +Name[ko]=KDE 기본 +Name[lt]=Klasikinė KDE +Name[lv]=KDE klasisks +Name[mk]=KDE класично +Name[mn]=KDE-сонгодог +Name[ms]=KDE Klasik +Name[nb]=KDE-klassisk +Name[ne]=KDE शास्त्रीय +Name[nl]=KDE klassiek +Name[nn]=Klassisk KDE +Name[pa]=KDE ਟਕਸਾਲੀ +Name[pl]=Klasyczny KDE +Name[pt]=Clássico do KDE +Name[pt_BR]=KDE Clássico +Name[ro]=KDE clasic +Name[ru]=Классический KDE +Name[rw]=KDE Isanzwe +Name[se]=KDE standárda +Name[sk]=KDE Štandardný +Name[sq]=KDE Klasike +Name[sr]=KDE класично +Name[sr@Latn]=KDE klasično +Name[sv]=KDE klassisk +Name[ta]=கேடிஇ உயர்தரமான +Name[te]=సాంప్రదాయిక కెడిఈ +Name[tg]=KDE Классик +Name[th]=แบบคลาสสิคของ KDE +Name[tr]=Klasik KDE +Name[tt]=KDE Klassik +Name[uk]=Типовий для KDE +Name[vi]=KDE kinh điển +Name[wa]=KDE Classike +Name[zh_CN]=KDE 经典 +Name[zh_HK]=KDE 預設 +Name[zh_TW]=KDE 預設 +Comment=Classic KDE style +Comment[af]=Klassieke KDE styl +Comment[ar]=مظهر كيدي الكلاسيكي +Comment[az]=Klassik KDE tərzi +Comment[be]=Класічны стыль KDE +Comment[bg]=Класически стил на KDE +Comment[bn]=ক্লাসিক কে.ডি.ই. স্টাইল +Comment[br]=Giz KDE dre ziouer +Comment[bs]=Klasični KDE stil +Comment[ca]=Estil clàssic del KDE +Comment[cs]=Klasický styl prostředí KDE +Comment[csb]=Klasykòwi sztél KDE +Comment[cy]=Arddull clasurol KDE +Comment[da]=Klassisk KDE-stil +Comment[de]=Nostalgischer KDE-Stil +Comment[el]=Κλασικό στυλ του KDE +Comment[eo]=Origina KDE-stilo +Comment[es]=Estilo KDE clásico +Comment[et]=KDE vaikestiil +Comment[eu]=KDEren estilo klasikoa +Comment[fa]=سبک کلاسیک KDE +Comment[fi]=KDE:n klassikkotyyli +Comment[fr]=Style classique de KDE +Comment[fy]=Klassyke KDE styl +Comment[ga]=Stíl Chlasaiceach KDE +Comment[gl]=Estilo Clásico de KDE +Comment[he]=הסגנון הקלאסי של KDE +Comment[hi]=क्लॉसिक केडीई शैली +Comment[hr]=Klasični KDE stil +Comment[hu]=A KDE korábbi stílusa +Comment[id]=Gaya Klasik KDE +Comment[is]=Klassíski KDE stíllinn +Comment[it]=Stile KDE classico +Comment[ja]=クラシック KDE スタイル +Comment[ka]=KDE-ს კლასიკური სტილი +Comment[kk]=Классикалық KDE стилі +Comment[km]=រចនាប័ទ្ម KDE បុរាណ +Comment[ko]=KDE에서 기본으로 쓰는 모양새 +Comment[lb]=Klassësche KDE-Stil +Comment[lt]=Klasikinis KDE stilius +Comment[lv]=Klasisks KDE stils +Comment[mk]=Класичен KDE стил +Comment[mn]=KDE-сонгодог хэлбэр +Comment[ms]=Gaya KDE Klasik +Comment[nb]=Klassisk KDE-stil +Comment[nds]=De klass'sche KDE-Stil +Comment[ne]=शास्त्रीय KDE शैली +Comment[nl]=Klassieke KDE-stijl +Comment[nn]=Klassisk KDE-stil +Comment[pa]=ਟਕਸਾਲੀ KDE ਸ਼ੈਲੀ +Comment[pl]=Klasyczny styl KDE +Comment[pt]=Estilo clássico do KDE +Comment[pt_BR]=Estilo Clássico do KDE +Comment[ro]=Stil clasic KDE +Comment[ru]=Классический стиль KDE +Comment[rw]=Imisusire KDE isanzwe +Comment[se]=KDE standárdastiila +Comment[sk]=Štandardný štýl KDE +Comment[sl]=Klasičen slog KDE +Comment[sq]=Stili Klasik i KDE-së +Comment[sr]=Класични KDE стил +Comment[sr@Latn]=Klasični KDE stil +Comment[sv]=Klassisk KDE-stil +Comment[ta]=உயர்தர கேடிஇ பாணி +Comment[te]=సాంప్రదాయిక కెడిఈ శైలి +Comment[tg]=Сабки классикаи KDE +Comment[th]=รูปแบบดั้งเดิมของ KDE +Comment[tr]=Klasik KDE stili +Comment[tt]=KDE'neñ klassik bizäleşe +Comment[uk]=Класичний стиль KDE +Comment[uz]=Klassik KDE uslubi +Comment[uz@cyrillic]=Классик KDE услуби +Comment[vi]=Kiểu dáng KDE kinh điển. +Comment[wa]=Tinme avou l' rivnance «classike» di KDE +Comment[zh_CN]=经典的 KDE 风格 +Comment[zh_HK]=預設的 KDE 佈景 +Comment[zh_TW]=預設的 KDE 風格 +Highcolor=hcstyle.la +InactiveShading=true +[KDE] +WidgetStyle=Default diff --git a/kstyles/themes/highcolor.themerc b/kstyles/themes/highcolor.themerc new file mode 100644 index 000000000..36db5a1a8 --- /dev/null +++ b/kstyles/themes/highcolor.themerc @@ -0,0 +1,150 @@ +[Misc] +Name=HighColor Classic +Name[af]=Hoë-kontras Klassiek +Name[ar]=كلاسيكي عالي الألوان +Name[az]=Zəngin Rəngli Klassik +Name[be]=Класічны стыль HighColor +Name[bn]=হাই-কালার ক্লাসিক +Name[br]=Livioù uhel dre ziouer +Name[bs]=HighColor klasični +Name[ca]=HighColor clàssic +Name[cs]=Mnohobarevný klasický +Name[csb]=Klasykòwi z wieloma farwama +Name[cy]=Uchel-liw Clasurol +Name[da]=HighColor klassisk +Name[el]=Κλασικό - Πολλά χρώματα +Name[en_GB]=HighColour Classic +Name[eo]=Klasika multkolora +Name[es]=Alta profundidad de color clásico +Name[et]=Paljuvärviline vaikestiil +Name[eu]=Kolore askodun klasikoa +Name[fa]=رنگ بالای کلاسیک +Name[fi]=Monivärinen klassikkotyyli +Name[fr]=Style très coloré classique +Name[fy]=Klassyke Hege Kleuren +Name[gl]=Clásico de Alto Contraste +Name[he]=קלאסי ברמת צבע גבוהה +Name[hi]=हाई कलर क्लासिक +Name[hr]=Klasični stil s puno boja +Name[hu]=KDE Classic (színgazdag változat) +Name[id]=HighColor Klasik +Name[is]=Klassískur hágæða-litastíll +Name[it]=Molti colori classico +Name[ja]=ハイカラークラシック +Name[ka]=HighColor კლასიკური სტილი +Name[kk]=Классикалық HighColor +Name[km]=ពណ៌ខ្ពស់ បុរាណ +Name[ko]=기본 많은 색 +Name[lb]=VillFaarwe-Klassesch +Name[lt]=Klasikinis aukštos spalvų gebos +Name[lv]=Daudzkrāsu klasisks +Name[mk]=Високобојно класично +Name[mn]=64000 өнгөт сонгодог +Name[ms]=Klasik Warna Cerah +Name[nb]=Mangefarget klassisk +Name[ne]=उच्च रङ शास्त्रीय +Name[nl]=Klassiek Hoge Kleuren +Name[nn]=Klassisk med mange fargar +Name[pa]=ਜਿਆਦਾ ਗੂੜੇ ਰੰਗ ਟਕਸਾਲੀ +Name[pl]=Klasyczny z wieloma kolorami +Name[pt]=Clássico com Muitas Cores +Name[pt_BR]=Clássico de Alta Resolução +Name[ro]=Clasic culori multe +Name[ru]=Классический стиль HighColor +Name[rw]=IbaraRyiza Risanzwe +Name[se]=Ivdnás standárda +Name[sk]=Štandardný veľa farieb +Name[sq]=Klasike Shumë Ngjyrëshe +Name[sr]=Класични стил са пуно боја +Name[sr@Latn]=Klasični stil sa puno boja +Name[sv]=Färgrik klassisk +Name[ta]=உயர்நிற பாரம்பரியம் உயர்தரமானது +Name[te]=సాంప్రదాయిక ఎక్కువ రంగు +Name[tg]=Рангболоии классика. +Name[th]=รูปแบบคลาสสิค ความละเอียดสีสูง +Name[tr]=Klasik Yüksek Renk +Name[tt]=KüpTösle Klassik +Name[uk]=Типовий (64K кольорів) +Name[vi]=Màu cao kinh điển +Name[zh_CN]=高色彩经典 +Name[zh_HK]=預設高彩佈景 +Name[zh_TW]=預設的高彩 +Comment=Highcolor version of the classic style +Comment[af]=Hoë-kontras weergawe van die klassieke styl +Comment[ar]=نسخة عالية الألوان من المظهر الكلاسيكي +Comment[az]=Klassik tərzin zəngin rəngli buraxılışı +Comment[be]=Версія класічнага стылю з вялікай колькасцю колераў +Comment[bg]=Класически стил на KDE с високо качество на цветовете +Comment[bn]=ক্লাসিক স্টাইলের হাই-কালার সংস্করণ +Comment[br]=Stumm livioù uhel ar c'hiz da gustum +Comment[bs]=Highcolor verzija klasičnog stila +Comment[ca]=Versió Highcolor de l'estil clàssic +Comment[cs]=Mnohobarevná verze klasického stylu +Comment[csb]=Wersëjô klasykòwegò sztélu z wieloma farwama (HiColor) +Comment[cy]=Fersiwn uchel-liw o'r arddull clasurol +Comment[da]=Højfarve-version af klassisk stil +Comment[de]=64000-Farben-Version des Classic-Stils +Comment[el]=Έκδοση με πολλά χρώματα του κλασικού στυλ +Comment[en_GB]=Highcolour version of the classic style +Comment[eo]=Multkolora varianto de la klasika stilo +Comment[es]=Versión de alta profundidad de color del estilo clásico +Comment[et]=Vaikestiili paljuvärviline versioon +Comment[eu]=Estilo klasikoaren kolore askodun bertsioa +Comment[fa]=نسخۀ رنگ بالای سبک کلاسیک +Comment[fi]=Monivärinen versio klassikkotyylistä +Comment[fr]=Version très colorée du style classique +Comment[fy]=Hege kleuren ferzje fan de klassyke styl +Comment[ga]=Leagan ildathach den stíl chlasaiceach +Comment[gl]=Versión de alto contrasto do estilo clásico +Comment[he]=גירסה בצבע גבוה של הסגנון הקלאסי של KDE +Comment[hi]=क्लाशिक शैली का हाईकलर वर्जन +Comment[hr]=Verzija klasičnog stila s puno boja +Comment[hu]=A KDE korábbi stílusának színgazdag változata +Comment[id]=Versi Warna Tajam dari gaya klasik +Comment[is]=Útgáfa klassíska stílsins sem notar hágæðaliti (HighColor) +Comment[it]=Versione con molti colori dello stile classico +Comment[ja]=クラシックスタイルのハイカラーバージョン +Comment[ka]=კლასიკური სტილი ფერების მეტი რაოდენობით +Comment[kk]=Классикалық стильдің Highcolor нұсқасы +Comment[km]=កំណែពណ៌ខ្ពស់របស់រចនាប័ទ្មបុរាណ +Comment[ko]=기본 모양새를 많은 색으로 만든 것 +Comment[lb]=Versioun mat ville Faarwe vum klassesche Stil +Comment[lt]=Klasikinio stiliaus aukštos spalvų gebos versija +Comment[lv]=Daudzkrāsu versija klasiskajam stilam +Comment[mk]=Високобојна верзија на класичниот стил +Comment[mn]=64000-Өнгөт-сонгодог хэлбэрийн хувилбар +Comment[ms]=Versi warna cerah untuk gaya klasik +Comment[nb]=Mangefarget-versjon av klassisk stil +Comment[nds]=Highcolor-Verschoon vun den klass'schen Stil +Comment[ne]=शास्त्रीय शैलीको उच्च रङ संस्करण +Comment[nl]=Hoge-kleuren-versie van de klassieke stijl +Comment[nn]=Klassisk stil med mange fargar +Comment[pa]=ਜਿਆਦਾ ਗੂੜੇ ਰੰਗਾਂ ਵਾਲ ਟਕਸਾਲੀ ਸ਼ੈਲੀ +Comment[pl]=Wersja stylu klasycznego z wieloma kolorami (HiColor) +Comment[pt]=Uma versão com muitas cores do estilo clássico +Comment[pt_BR]=Estilo clássico na versão de alta resolução +Comment[ro]=Versiune cu culori multe a stilului clasic +Comment[ru]=Версия классического стиля с большим количеством цветов +Comment[rw]=Verisiyo y'ibararyiza ry'imisusire isanzwe +Comment[se]=Standárdastiilla ivdnás veršuvdna +Comment[sk]=Štandardný štýl pre veľa farieb +Comment[sl]=Raznobarvna različica klasičnega sloga +Comment[sq]=Verzion Shumë ngjyrësh i stilit klasik +Comment[sr]=Верзија класичног стила са пуно боја +Comment[sr@Latn]=Verzija klasičnog stila sa puno boja +Comment[sv]=Färgrik version av den klassiska stilen +Comment[ta]=பாரம்பரிய பாணியின் உயர்நிறப் பதிப்பு +Comment[te]=సాంప్రదాయిక శైలి యొక్క ఎక్కువ రంగు వివరణం +Comment[tg]=Нусхаи рангбаландии сабки классика +Comment[th]=รูปแบบปริยาย รุ่นความละเอียดสีสูง +Comment[tr]=Klasik stilin yüksek renk versiyonu +Comment[tt]=Klassik tışlawnıñ küptösle töre +Comment[uk]=Версія типового стилю для 64К кольорів та більше +Comment[uz]=Klassik uslubining yuqori rangli nusxasi +Comment[uz@cyrillic]=Классик услубининг юқори рангли нусхаси +Comment[vi]=Phiên bản màu cao của kiểu dáng kinh điển. +Comment[zh_CN]=经典风格的高色彩版本 +Comment[zh_HK]=預設佈景的高彩版本 +Comment[zh_TW]=預設風格的高彩版本 +[KDE] +WidgetStyle=HighColor diff --git a/kstyles/themes/keramik.themerc b/kstyles/themes/keramik.themerc new file mode 100644 index 000000000..e9599323c --- /dev/null +++ b/kstyles/themes/keramik.themerc @@ -0,0 +1,99 @@ +[Misc] +Name=Keramik +Name[be]=Кераміка +Name[bn]=কেরামিক +Name[cs]=Keramika +Name[csb]=Keramikòwi +Name[eo]=Ceramiko +Name[fa]=کرامیک +Name[fy]=Keramyk +Name[gl]=Keramic +Name[he]=קרמיק +Name[hi]=केरमिक +Name[ka]=კერამიკა +Name[kk]=Керамик +Name[ko]=K세라믹 +Name[lv]=Keramika +Name[mk]=Керамик +Name[mn]=Керамик +Name[ne]=केरामिक +Name[nn]=Keramikk +Name[pa]=ਕੀਰਾਮਿਕ +Name[ru]=Керамика +Name[se]=Keramihkka +Name[sq]=Keramikë +Name[sr]=Керамика +Name[sr@Latn]=Keramika +Name[ta]=கேராமில்க் +Name[te]=కెరామిక్ +Name[tg]=Сафолӣ +Name[th]=Kเครามิก +Name[uz]=Keramika +Name[uz@cyrillic]=Керамика +ConfigPage=kstyle_keramik_config +Comment=A style using alphablending +Comment[af]='n standaard styl wat alfa vermenging gebruik +Comment[bg]=Стил, използващ алфа сливане +Comment[bs]=Stil koji koristi alphablending +Comment[ca]=Un estil que usa barreja alfa +Comment[cs]=Styl používající alfa kanál +Comment[csb]=Sztél brëkùjący półprzezérnotã +Comment[da]=En stil der bruger alfablanding +Comment[de]=Ein Stil mit Alpha-Blending +Comment[el]=Ένα στυλ που χρησιμοποιεί alphablending +Comment[eo]=stilo kiu uzas diafanan miksadon +Comment[es]=Un estilo que utiliza mezcla alfa +Comment[et]=Alfablendingut kasutav stiil +Comment[eu]=Alfa kanala darabilen estilo lehenetsia +Comment[fa]=یک سبک با استفاده از alphablending +Comment[fi]=Alphasekoitusta käyttävä tyyli +Comment[fr]=Un style utilisant l'alpha-blending +Comment[fy]=In styl dy brûk makket fan alfaminging +Comment[ga]=Stíl a úsáideann alfachumasc +Comment[gl]=Un estilo empregando misturas alfa +Comment[he]=ערכה משתמשת במיזוג אלפא +Comment[hr]=Stil s upotrebom Alfa pretapanja +Comment[hu]=Alfakeverést használó stílus +Comment[id]=Gaya dengan alphablending +Comment[is]=Stíll sem notar alfa blöndun +Comment[it]=Stile con effetti di trasparenza +Comment[ja]=アルファブレンディングを使用したスタイル +Comment[ka]=სტილი ალფა შერევით +Comment[kk]=Альфа-арластыру стилі +Comment[km]=រចនាប័ទ្មលំនាំដើមដោយប្រើ ល្បាយអាល់ហ្វា +Comment[lb]=E Stil, deen Alphablending benotzt +Comment[lt]=Stilius, naudojantis alfa spalvų maišymą +Comment[lv]=Stils izmantojot alfasaplūšanu +Comment[mk]=Стил што користи алфа-мешање +Comment[ms]=Gaya piawai menggunakan pengadunan alfa +Comment[nb]=En stil som bruker alfablending +Comment[nds]=En Stil mit Alphablending +Comment[ne]=अल्फाब्लेन्डिङ प्रयोग गरिरहेको शैली +Comment[nl]=Een stijl die gebruik maakt van alfavermenging +Comment[nn]=Ein stil som brukar alfablanding +Comment[pa]=ਇਹ ਐਲਫਾਇੰਏਬਲਿੰਗ ਵਰਤੋਂ ਕਰਕੇ ਇੱਕ ਸ਼ੈਲੀ +Comment[pl]=Styl stosujący półprzeźroczystość +Comment[pt]=Um estilo que utiliza 'alphablending' +Comment[pt_BR]=Um estilo padrão usando Mistura Alpha +Comment[ro]=Un stil care utilizează transparenţă +Comment[ru]=Стиль с использованием альфа-смешивания +Comment[se]=Stiila mii geavaha alfaseaguhusa +Comment[sk]=Štýl používajúci alfa kanál +Comment[sl]=Slog z uporabo mešanja alfa +Comment[sr]=Стил који користи алфа-стапање +Comment[sr@Latn]=Stil koji koristi alfa-stapanje +Comment[sv]=En stil som använder alfablandning +Comment[te]=ఆల్ఫా బ్లెండింగ్ వాడు ఒక శైలి +Comment[tg]=Услуб бо истифодаи тобиши алфа +Comment[th]=รูปแบบที่ใช้เทคนิคการไล่สีอัลฟา +Comment[tr]=Alpha karışımı kullanan bir stil +Comment[uk]=Стиль з використанням альфа-змішування +Comment[uz]=Alfablendingli uslub +Comment[uz@cyrillic]=Алфаблендингли услуб +Comment[vi]=Kiểu dáng hợp nhau anfa. +Comment[zh_CN]=使用 alpha 混和的风格 +Comment[zh_HK]=一個使用漸變色的佈景 +Comment[zh_TW]=使用 alphablending 的預設風格 + +[KDE] +WidgetStyle=Keramik diff --git a/kstyles/themes/kstep.themerc b/kstyles/themes/kstep.themerc new file mode 100644 index 000000000..c96c6381f --- /dev/null +++ b/kstyles/themes/kstep.themerc @@ -0,0 +1,108 @@ +[Misc] +Name=KDE Step +Name[af]=Kde Step +Name[bn]=কে.ডি.ই. স্টেপ +Name[de]=KDE-Step +Name[eo]=KDE-Step +Name[fa]=گام KDE +Name[hi]=केडीई स्टेप +Name[is]=KDE-step +Name[ko]=KDE 스텝 +Name[lb]=KDE-Step +Name[mi]=Hikoi KDE +Name[mn]=KDE-Step +Name[ne]=KDE चरण +Name[nn]=KDE-Step +Name[nso]=Kgato ya KDE +Name[pa]=KDE ਪਗ +Name[rw]=Intambwe KDE +Name[sq]=Hapi KDE +Name[sv]=KDE step +Name[ta]=கேடிஇ முறை +Name[te]=కెడిఈ ఆడుగు +Name[tg]=Марҳилаи KDE +Name[th]=KDE สเต็ป +Name[ven]=Tshitaela tsha KDE +Name[xh]=Inyathelo le KDE +Name[zu]=Isigaba se-KDE +Comment=Unthemed Next-like style +Comment[af]=Ongetemade Next-tipe styl +Comment[ar]=مظهر مشابه لNeXT Step +Comment[be]=Стыль Next +Comment[bg]=Стил без тема, подобен на Next +Comment[br]=Giz doare NeXT anwisket +Comment[bs]=Stil bez teme, u stilu Nexta +Comment[ca]=Estil del tipus Next sense temes +Comment[cs]=Styl jako NeXT (bez motivu) +Comment[csb]=Sztél szlachùjacy za Nexta, bez témów +Comment[cy]=Arddull fel Next heb themau +Comment[da]=Next-lignende stil uden tema +Comment[de]=Reduzierter NeXt-Stil +Comment[el]=Στυλ παρόμοιο με το Next +Comment[eo]=Next-simila stilo neetosa +Comment[es]=Estilo tipo NeXT sin tema +Comment[et]=NeXT'i-laadne teemata stiil +Comment[eu]=Gairik gabeko Next estiloa +Comment[fa]=سبک مشابه بعدی بدون چهره +Comment[fi]=Teemoittamaton Next:n kaltainen tyyli +Comment[fr]=Style sans thème similaire à NeXT +Comment[fy]=Temaleaze Next-styl +Comment[ga]=Stíl gan téama, cosúil le NeXT +Comment[gl]=Estilo tipo Next sen tema +Comment[hi]=अनथीम्ड नेक्स्ट शैली क़िस्म +Comment[hr]=Stil bez teme, nalikuje na Next +Comment[hu]=Next-szerű stílus, téma nélkül +Comment[id]=Gaya ala Next tanpa tema +Comment[is]=Stíll sem minnir á Next stýrikerfið (án þema) +Comment[it]=Stile senza tema simile a Next +Comment[ja]=Next 風のスタイル (テーマなし) +Comment[ka]=Next-ის მსგავსი სტილი თემების გარეშე +Comment[kk]=Нақыштарсыз Next-секілді стиль +Comment[km]=រចនាប័ទ្ម Next-like ដែលគ្មានស្បែក +Comment[ko]=넥스트와 같은 꼴을 가진 테마 +Comment[lb]=Next-ähnleche Stil ouni Thema +Comment[lt]=Betemis Next tipo stilius +Comment[lv]=Beztēmas NEXT līdzīgs stils +Comment[mk]=NeXT стил (без тема) +Comment[mn]=NeXt-Хэлбэр агшаалт +Comment[ms]=Gaya Next +Comment[mt]=Stil bla tema simili għan-Next +Comment[nb]=Innebygget Next-lignende stil +Comment[nds]=Stil as Next (ahn Muster) +Comment[ne]=विषयवस्तु नभएको पछिल्लो-जस्तो शैली +Comment[nl]=Themaloze Next-stijl +Comment[nn]=Next-aktig stil utan tema +Comment[nso]=Mokgwa wo osenago molaetsa wago swana le Latelago +Comment[oc]=Estil dèu tipus Next sense temes +Comment[pa]=ਬੇਸਰੂਪ Next-like ਸ਼ੈਲੀ +Comment[pl]=Styl podobny do Nexta, bez motywów +Comment[pt]=Estilo tipo Next +Comment[pt_BR]=Estilo semelhante ao Next +Comment[ro]=Stil fără tematică Next +Comment[ru]=Стиль без тем, похожий на Next +Comment[rw]=Imisusire Ibikurikira-nka itahawe insanganyamatsiko +Comment[se]=Next-lágan stiila fáttáhaga +Comment[sk]=Bez témy ako Next štýl +Comment[sl]=Netematski slog, podoben Next +Comment[sq]=Stili i patemë sikurse ai i Next +Comment[sr]=Стил без теме налик на NeXT +Comment[sr@Latn]=Stil bez teme nalik na NeXT +Comment[sv]=Otemad Next-liknande stil +Comment[ta]=தலைப்பில்லா அடுத்த பாணி +Comment[te]=వైవిద్యాంశంలేని నెక్స్ట్ లాంటి శైలి +Comment[tg]=Донистани тарҳи Next сабк шудааст +Comment[th]=ธีมคล้ายระบบปฏิบัติการ Next +Comment[tr]=Next benzeri temasız stil +Comment[tt]=Next-kebek tışlaw +Comment[uk]=Стиль NeXT (без теми) +Comment[uz]=Next'ga oʻxshash mavzusiz uslub +Comment[uz@cyrillic]=Next'га ўхшаш мавзусиз услуб +Comment[ven]=Hu songo newaho thero-sa tshitaela +Comment[vi]=Kiểu dánf như NeXt không có sắc thái. +Comment[xh]=Okulandelayo Okungenamxholo-njengo hlobo +Comment[zh_CN]=无主题的类似 Next 的风格 +Comment[zh_HK]=類似未修改佈景的 NextStep +Comment[zh_TW]=沒有主題的類似 Nextstep 的風格 +Comment[zu]=Okulandelayo Okungenangqikithi-okunjengesitayela +[KDE] +widgetStyle=kstepstyle.la diff --git a/kstyles/themes/kthemestylerc b/kstyles/themes/kthemestylerc new file mode 100644 index 000000000..96fd4114f --- /dev/null +++ b/kstyles/themes/kthemestylerc @@ -0,0 +1,2 @@ +[General] +themes= diff --git a/kstyles/themes/light-v2.themerc b/kstyles/themes/light-v2.themerc new file mode 100644 index 000000000..d99048c6b --- /dev/null +++ b/kstyles/themes/light-v2.themerc @@ -0,0 +1,160 @@ +[Misc] +Name=Light Style, 2nd revision +Name[af]=Ligte Styl, 2nd hersiening +Name[ar]=نمط خفيف، التنقيح الثاني +Name[az]=Yüngül Tərz, 2-ci buraxılış +Name[be]=Лёгкі стыль 2 +Name[bn]=লাইট স্টাইল, দ্বিতীয় সংস্করণ +Name[br]=Giz sklerijenn, eil stumm +Name[bs]=Light stil, druga revizija +Name[ca]=Estil Light, 2ona revisió +Name[cs]=Light Style, druhá verze +Name[csb]=Letczi sztél, drëgô wersëjô +Name[cy]=Arddull Ysgafn, ail addasiad +Name[da]=Light Style, 2. revision +Name[de]=Leichter Stil, 2. Fassung +Name[el]=Στυλ Light, 2η διασκευή +Name[eo]=Lumstilo, 2a eldono +Name[es]=Estilo ligero, 2nda revisión +Name[et]=Light Style, 2. versioon +Name[eu]=Argi-estiloa, 2. berrikuspena +Name[fa]=سبک نور، دومین بازبینی +Name[fi]=Light Style, toinen versio +Name[fr]=Style lumière, 2ème version +Name[fy]=Light Style, 2e revyzje +Name[ga]=An Stíl Éadrom, 2ú leasú +Name[gl]=Estilo Light, 2ª revisión +Name[he]=גרסה קלילה, גרסה שנייה +Name[hi]=लाइट शैली, 2रा संशोधन +Name[hr]=Lagani stil, druga revizija +Name[hu]=Light stílus, 2. verzió +Name[id]=Light, revisi ke-2 +Name[is]=Léttur stíll, - taka 2 +Name[it]=Stile Light, seconda versione +Name[ja]=Light スタイル、第2版 +Name[ka]=Light სტილი, მე-2 რედაქცია +Name[kk]=Light стилі, 2-редақциясы +Name[km]=រចនាប័ទ្មភ្លឺ ពិនិត្យឡើងវិញលើកទី២ +Name[ko]=가벼운 꼴, 두번째 판 +Name[lb]=Liichte Stil, 2. Versioun +Name[lt]=Lengvas stilius, 2-as variantas +Name[lv]=Gaismas Stils, 2. revīzija +Name[mk]=Лесен стил, 2-ра ревизија +Name[mn]=Хөнгөн хэлбэр, 2. үзлэг +Name[mt]=Stil ħafif, 2ni reviżjoni +Name[nb]=Lett stil, 2. utgave +Name[nds]=Light-Stil, 2. Verschoon +Name[ne]=हल्का शैली, दोश्रो संशोधन +Name[nl]=Light Style, 2e herziening +Name[nn]=Lett-stil, 2. utgåve +Name[nso]=Mokgwa wo Bofefo, ponoleswa ya bobedi +Name[pa]=ਹਲਕਾ ਵਰਜਨ, 2ਜਾ ਵਰਜਨ +Name[pl]=Lekki styl, wersja druga +Name[pt]=Estilo Leve, 2a versão +Name[pt_BR]=Estilo Light, Segunda revisão +Name[ro]=Stil fin, versiunea 2 +Name[ru]=Light стиль второй редакции +Name[rw]=Imisusire Rumuri, Isubiramo rya 2 +Name[se]=Light stiila, 2. veršuvdna +Name[sk]=Štýl Light, 2. revízia +Name[sl]=Slog »Light«, 2. revizija +Name[sq]=Stili i Lehtë, Përmirësimi i Dytë +Name[sr]=Лак стил, друга ревизија +Name[sr@Latn]=Lak stil, druga revizija +Name[sv]=Lätt stil, andra revisionen +Name[ta]=சுலப பாணி, இரண்டாவது சோதனை +Name[te]=వెలుగు శైలి, ౨వ సవరణ +Name[tg]=Усули сабук, нусхаи дуввум +Name[th]=รูปแบบเบาบาง รุ่นที่ 2 +Name[tr]=Açık Stil, 2.revizyon +Name[tt]=Light Tışlaw, 2. söreme +Name[uk]=Стиль Light, випуск N2 +Name[uz]=Light uslubi, ikkinchi tahriri +Name[uz@cyrillic]=Light услуби, иккинчи таҳрири +Name[ven]=Tshitaela tshisi tshau konda, ndulamiso ya vhuvhili +Name[vi]=Kiểu dáng sáng, bản sửa đổi 2 +Name[xh]=Uhlobo Olukhanyayo, 2nd ukhumbuzo kwakhona +Name[zh_CN]=Light 风格,第二版 +Name[zh_HK]=輕靈風格,第二版 +Name[zh_TW]=輕靈風格,第二版 +Name[zu]=Ukubuyekezwa oku-2nd, Kwesitayela Esilula +Comment=Second revision of the simple and elegant 'Light' widget style. +Comment[af]=Tweede hersiening van die eenvoudige en elegante 'Light' gui-element styl. +Comment[ar]=التنقيح الثاني لنمط الكائن 'الخفيف' الأنيق والبسيط +Comment[az]=Sadə və eleqant 'Yüngül' tərzinin ikinci buraxılışı. +Comment[be]=Просты і элегантны стыль 2. +Comment[bg]=Второ издание на семплия и елегантен стил "Light" +Comment[bs]=Druga revizija jednostavnog i elegantnog 'Light' stila ukrasa. +Comment[ca]=Segona revisió de l'elegant estil d'estris 'Light'. +Comment[cs]=Druhá revize jednoduchého a elegantního stylu prvků uživatelského prostředí 'Light'. +Comment[csb]=Drëgô wersëjô prostegò ë szëkòwnégò letczégò sztélu (Light). +Comment[cy]=Ail addasiad o'r arddull celfigyn syml a gwych 'Light' +Comment[da]=Anden revision af den simple og elegante 'Light'-kontrolstil. +Comment[de]=Zweite Version des einfachen und eleganten "Leichten Stils" +Comment[el]=Δεύτερη διασκευή του απλού και κομψού στυλ 'Light'. +Comment[eo]=Dua eldono de la simpla kaj eleganta fenestrostilo 'Lumo'. +Comment[es]=Segunda revisión del elegante estilo de widgets 'Ligero'. +Comment[et]=Lihtsa ja elegantse 'Light' stiili teine versioon +Comment[eu]='Argi' trepetaren estilo sinple eta dotorearen 2. berrikuspena. +Comment[fa]=دومین بازبینی سبک عنصر ساده و زیبای نور +Comment[fi]=Toinen versio yksinkertaisesta ja elegantista Light-tyylistä +Comment[fr]=Deuxième version du style graphique « Lumière », simple et élégant. +Comment[fy]=Twadde revyzje fan de ienfâldige en elegante widgetstyl 'Light' +Comment[ga]=An dara leasú de stíl shimplí fhíneálta giuirléidí 'Light'. +Comment[gl]=Segunda revisión do simple e elegante estilo de widgets 'Light'. +Comment[he]=גרסה שנייה של הערכה הפשוטה האלגנטית וה"קלילה". +Comment[hi]=सादा और सुरूचिकर 'लाइट' विजेट शैली का दूसरा संशोधन. +Comment[hr]=Druga revizija jednostavnog i elegantnog 'laganog' widget stila. +Comment[hu]=A nemesen egyszerű 'Light' elemstílus második változata. +Comment[id]=Revisi kedua dari gaya widget sederhana dan elegan 'Light'. +Comment[is]=Önnur útgáfa af einföldum og snotrum stíl +Comment[it]=Seconda versione dello stile semplice ed elegante "Light". +Comment[ja]=シンプルでエレガントな 'Light' ウィジェットスタイル第 2 版。 +Comment[ka]=მარტივი და ელეგანტური Light მართვის ელემენტის სტილის მე–2 რედაქცია. +Comment[kk]='Light' деген қарапайым және әсем стилінің 2-редакциясы. +Comment[km]=ការកែប្រែលើកទី ២ របស់រចនាប័ទ្មវត្ថុមើលឃើញសាមញ្ញ និងប្រណិត "ភ្លឺ" ។ +Comment[ko]=뽐 내지 않고 멋진 '가벼운' 위젯 꼴, 두번째 판. +Comment[lb]=Zweet Versioun vum einfachen and eleganten 'liichte' Widget-Stil +Comment[lt]=Paprasto ir elegantiško „lengvo“ valdiklio stiliaus antras variantas. +Comment[lv]= Vienkāršā un elegantā 'Gaismas' vidžeta stila otrā revīzija. +Comment[mk]=Втора ревизија на едноставниот и елегантен „Лесен“ стил. +Comment[mn]=Энгийн ухаалаг "Хөнгөн хэлбэрүүд"-н хоёрдугаар хувилбар +Comment[ms]=Revisi kedua untuk gaya wijet 'Light' yang ringkas dan elegan. +Comment[mt]=It-tieni reviżjoni tal-istil sempliċi u eleganti "Light" +Comment[nb]=Andre utgave av den enkle og elegante elementstilen «Lett». +Comment[nds]=Tweet Verschoon vun den eenfachen un smucken "Light"-Stil. +Comment[ne]=सरल र सुन्दर 'हल्का' विजेट शैलीको दोश्रो संशोधन । +Comment[nl]=Tweede herziening van de eenvoudige en elegante widgetstijl 'Light' +Comment[nn]=Andre utgåva av den enkle og elegante stilen «Lett». +Comment[nso]=Ponoleswa ya bobedi ya mokgwa wa widget wo bonolo wo botsana ebile wo 'Bofefo'. +Comment[pa]=ਸਧਾਰਨ 'Light' ਵਿਦਗਿਟ ਸ਼ੈਲੀ ਦਾ ਦੂਜਾ ਵਰਜਨ +Comment[pl]=Druga wersja prostego i eleganckiego stylu Lekkiego (Light). +Comment[pt]=Segunda versão do estilo gráfico simples e elegante 'Leve'. +Comment[pt_BR]=Segunda revisão do simples e elegante estilo widget 'Light'. +Comment[ro]=A doua revizie a stilului 'Fin' simplu şi elegant +Comment[ru]=Вторая редакция простого и красивого стиля Light. +Comment[rw]=Isubiramo rya kabiri ry'imisusire y'uburyo 'Rumuri' ryoroshye kandi ryiza. +Comment[se]=Oktageardánis ja fárddalaš 'Light'-stiilla nubbi veršuvdna. +Comment[sk]=Druhá revízia jednoduchého a elegantného štýlu prvkov 'Light'. +Comment[sl]=Druga revizija preprostega in elegantnega sloga gradnikov »Light«. +Comment[sr]=Друга ревизија једноставног и елегантног „лаког“ стила. +Comment[sr@Latn]=Druga revizija jednostavnog i elegantnog „lakog“ stila. +Comment[sv]=Andra revisionen av den simpla och eleganta komponentstilen "Lätt". +Comment[ta]=சுலபமான 'இலேசான' சாளர பாணியின் இரண்டாவது சோதனை +Comment[te]=సరళమైన మరయు సొగసైన 'వెలుగు' విడ్జెట్ శైలి యొక్క రెండవ సవరణ +Comment[tg]=Интишори дуввуми сабки тикаи содда ва зебои 'Нур'. +Comment[th]=รุ่นแก้ไขรุ่นที่สองของรูปแบบ 'บางเบา' ที่เรียบง่ายและภูมิฐาน +Comment[tr]=Hafif Stil'in ikinci revizyonu +Comment[tt]=Ciñel yämle "Light" tışlawınıñ 2. söreme. +Comment[uk]=Друга версія простого та елегантного стилю віджетів "Light". +Comment[uz]=Oddiy va chiroyli Light uslubining ikkinchi tahriri +Comment[uz@cyrillic]=Оддий ва чиройли Light услубининг иккинчи таҳрири +Comment[ven]=Ndulamiso ya vhuvhili isa kondi na tshitaela tshileluwaho +Comment[vi]=Bản sửa đổi thứ hai của kiểu dáng ô điều khiển Sáng đơn giản và thanh lịch. +Comment[xh]=Ukhumbuzo kwakhona lwesibini lokulula nokubukekayo kwe hlobo lwe widget 'Ekhaphu-khaphu. +Comment[zh_CN]=简约雅致的“Light”风格,第二版。 +Comment[zh_HK]=簡單高雅的「輕靈」介面工具風格的第二版。 +Comment[zh_TW]=簡單高雅的“輕靈”界面工具風格的第二版。 +Comment[zu]=Ukubuyekezwa kwesibili kwesitayela se-widget 'Esilula' kanye nesiphucuzekile. +[KDE] +WidgetStyle=Light, 2nd revision diff --git a/kstyles/themes/light-v3.themerc b/kstyles/themes/light-v3.themerc new file mode 100644 index 000000000..cc0b5b25c --- /dev/null +++ b/kstyles/themes/light-v3.themerc @@ -0,0 +1,161 @@ +[Misc] +Name=Light Style, 3rd revision +Name[af]=Ligte Styl, 3de hersiening +Name[ar]=نمط خفيف، التنقيح الثالث +Name[az]=Yüngül Tərz, 3-cü buraxılış +Name[be]=Лёгкі стыль 3 +Name[bn]=লাইট স্টাইল, তৃতীয় সংস্করণ +Name[br]=Giz sklerijenn, trede stumm +Name[bs]=Light stil, treća revizija +Name[ca]=Estil Light, 3era revisió +Name[cs]=Light Style, třetí verze +Name[csb]=Letczi sztél, trzecô wersëjô +Name[cy]=Arddull Ysgafn, 3ydd addasiad +Name[da]=Light Style, 3. revision +Name[de]=Leichter Stil, 3. Fassung +Name[el]=Στυλ Light, 3η διασκευή +Name[eo]=Lumo-stilo, 3a eldono +Name[es]=Estilo Ligero, 3era revisión +Name[et]=Light Style, 3. versioon +Name[eu]=Argi-estiloa, 3. berrikuspena +Name[fa]=سبک نور، سومین بازبینی +Name[fi]=Light-tyyli, kolmas versio +Name[fr]=Style lumière, 3ème version +Name[fy]=Light Style, 3e revyzje +Name[ga]=An Stíl Éadrom, 3ú leasú +Name[gl]=Estilo Light, 3ª revisión +Name[he]=גרסה קלילה, גרסה שלישית. +Name[hi]=लाइट शैली, 3रा संशोधन +Name[hr]=Lagani stil, treća revizija +Name[hu]=Light stílus, 3. verzió +Name[id]=Light, revisi ke-2 +Name[is]=Léttur stíll, - taka 3 +Name[it]=Stile Light, terza versione +Name[ja]=Light スタイル、第3版 +Name[ka]=Light სტილი, მე–3 რედაქცია +Name[kk]=Light стилі, 3-редакциясы +Name[km]=រចនាប័ទ្មភ្លឺ ពិនិត្យឡើងវិញលើកទី៣ +Name[ko]=가벼운 꼴, 세번째 판 +Name[lb]=Liichte Stil, 3. Versioun +Name[lt]=Lengvas stilius, 3-ias variantas +Name[lv]=Gaismas Stils, 3. revīzija +Name[mk]=Лесен стил, 3-та ревизија +Name[mn]=Хөнгөн хэлбэр, 3. үзлэг +Name[mt]=Stil ħafif, 3et reviżjoni +Name[nb]=Lett stil, 3.utgave +Name[nds]=Light-Stil, 3. Verschoon +Name[ne]=हल्का शैली, तेस्रो संशोधन +Name[nl]=Light Style, 3e herziening +Name[nn]=Lett-stil, 3. utgåve +Name[nso]=Mokgwa wo Bofefo, ponoleswa ya boraro +Name[pa]=ਹਲਕੀ ਸ਼ੈਲੀ, 3ਜਾ ਵਰਜਨ +Name[pl]=Lekki styl, wersja trzecia +Name[pt]=Estilo Leve, 3a versão +Name[pt_BR]=Estilo Light, Terceira revisão +Name[ro]=Stil fin, versiunea 3 +Name[ru]=Light стиль, третья редакция +Name[rw]=Imisusire Rumuri, Isubiramo rya 3 +Name[se]=Light stiila, 3. veršuvdna +Name[sk]=Štýl Light, 3. revízia +Name[sl]=Slog »Light«, 3. revizija +Name[sq]=Stili i Lehtë, Përmirësimi i Tretë +Name[sr]=Лак стил, трећа ревизија +Name[sr@Latn]=Lak stil, treća revizija +Name[sv]=Lätt stil, tredje revisionen +Name[ta]=சுலப பாணி, மூன்றாவது சோதனை +Name[te]=వెలుగు శైలి, ౩వ సవరణ +Name[tg]=Сабки нур, нусхаи саввум +Name[th]=รูปแบบเบาบาง รุ่นที่ 3 +Name[tr]=Hafif Stil +Name[tt]=Light Tışlaw, 3. söreme +Name[uk]=Стиль Light, випуск N3 +Name[uz]=Light uslubi, uchinchi tahriri +Name[uz@cyrillic]=Light услуби, учинчи таҳрири +Name[ven]=Tshitaela tshisa kondi, ndovhololo ya vhuraru +Name[vi]=Kiểu dáng sáng, bản sửa đổi 3 +Name[xh]=Uhlobo Olukhanyayo, 3rd ukhumbuzo kwakhona +Name[zh_CN]=Light 风格,第三版 +Name[zh_HK]=輕靈風格,第三版 +Name[zh_TW]=輕靈風格,第三版 +Name[zu]=Isitayela Esilula, ukubuyekezwa kwesithathu +Comment=Third revision of the simple and elegant 'Light' widget style. +Comment[af]=Derde hersiening van die eenvoudige en elegante 'Light' gui-element styl. +Comment[ar]=التنقيح الثالث لنمط الكائن 'الخفيف' الأنيق والبسيط +Comment[az]=Sadə və eleqant 'Yüngül' tərzinin üçüncü buraxılışı. +Comment[be]=Просты і элегантны стыль 3. +Comment[bg]=Трето издание на семплия и елегантен стил "Light" +Comment[bs]=Treća revizija jednostavnog i elegantnog 'Light' stila ukrasa. +Comment[ca]=Tercera revisió de l'elegant estil d'estris 'Light'. +Comment[cs]=Třetí revize jednoduchého a elegantního stylu prvků uživatelského prostředí 'Light'. +Comment[csb]=Trzecô wersëjô prostegò ë szëkòwnégò letczégò sztélu (Light). +Comment[cy]=Trydydd addasiad o'r arddull celfigyn syml a gwych 'Light' +Comment[da]=Tredje revision af den simple og elegante 'Light'-kontrolstil. +Comment[de]=Dritte Version des einfachen und eleganten "Leichten Stils" +Comment[el]=Τρίτη διασκευή του απλού και κομψού στυλ 'Light'. +Comment[eo]=Tria eldono de la simpla kaj eleganta fenstrostilo 'Lumo'. +Comment[es]=Tercera revisión del elegante estilo de widgets 'Ligero'. +Comment[et]=Lihtsa ja elegantse 'Light' stiili kolmas versioon +Comment[eu]='Argi' trepetaren estilo sinple eta dotorearen 3. berrikuspena. +Comment[fa]=سومین بازبینی سبک عنصر ساده و زیبای نور +Comment[fi]=Kolmas versio yksinkertaisesta ja elegantista Light-tyylistä +Comment[fr]=Troisième version du style graphique « Lumière », simple et élégant. +Comment[fy]=Tredde revyzje fan de ienfâldige en elegante widgetstyl 'Light' +Comment[ga]=An tríú leasú de stíl shimplí fhíneálta giuirléidí 'Light'. +Comment[gl]=Terceira revisión do estilo elegante e simple de widgets 'Light'. +Comment[he]=גרסה שלישית של הערכה הפשוטה האלגנטית וה"קלילה". +Comment[hi]=सादा और सुरूचिकर 'लाइट' विजेट शैली का तीसरा संशोधन. +Comment[hr]=Treća revizija jednostavnog i elegantnog 'laganog' widget stila. +Comment[hu]=A nemesen egyszerű 'Light' elemstílus harmadik változata. +Comment[id]=Revisi ketiga dari gaya widget sederhana dan elegan 'Light'. +Comment[is]=Þriðja útgáfa af einföldum og snotrum stíl +Comment[it]=Terza versione dello stile semplice ed elegante "Light". +Comment[ja]=シンプルでエレガントな 'Light' ウィジェットスタイル第 3 版。 +Comment[ka]=მარტივი და ელეგანტური Light მართვის ელემენტის სტილის მე–3 რედაქცია. +Comment[kk]='Light' деген қарапайым және әсем стилінің 3-редакциясы. +Comment[km]=ការកែប្រែលើកទី ៣ របស់រចនាប័ទ្មវត្ថុមើលឃើញសាមញ្ញ និងប្រណិត "ភ្លឺ" ។ +Comment[ko]=뽐 내지 않고 멋진 '가벼운' 위젯 꼴, 세번째 판. +Comment[lb]=Drëtt Versioun vum einfachen and eleganten 'liichte' Widget-Stil +Comment[lt]=Paprasto ir elegantiško „lengvo“ valdiklio stiliaus trečias variantas. +Comment[lv]= Vienkāršā un elegantā 'Gaismas' vidžeta stila trešā revīzija. +Comment[mk]=Трета ревизија на едноставниот и елегантен „Лесен“ стил. +Comment[mn]=Энгийн ухаалаг "Хөнгөн хэлбэрүүд"-н гуравдугаар хувилбар +Comment[ms]=Revisi ketiga untuk gaya wijet 'Light' yang ringkas dan elegan. +Comment[mt]=It-tielet reviżjoni tal-istil sempliċi u eleganti "Light" +Comment[nb]=Tredje utgave av den enkle og elegante elementstilen «Lett». +Comment[nds]=Drütt Verschoon vun den eenfachen un smucken "Light"-Stil. +Comment[ne]=सरल र सुन्दर 'हल्का' विजेट शैलीको तेश्रो संशोधन । +Comment[nl]=Derde herziening van de eenvoudige en elegante widgetstijl 'Light' +Comment[nn]=Tredje utgåva av den enkle og elegante stilen «Lett». +Comment[nso]=Ponoleswa ya boraro ya mokgwa wa widget wo bonolo wo mmotsana ebile wo 'Bofefo'. +Comment[pa]=ਸਧਾਰਨ 'Light' ਵਿਦਗਿਟ ਸ਼ੈਲੀ ਦਾ ਤੀਜਾ ਵਰਜਨ +Comment[pl]=Trzecia wersja prostego i eleganckiego stylu Lekkiego (Light). +Comment[pt]=Terceira versão do estilo gráfico simples e elegante 'Leve'. +Comment[pt_BR]=Terceira revisão do simples e elegante estilo widget 'Light'. +Comment[ro]=A treia revizie a stilului 'Fin' simplu şi elegant +Comment[ru]=Третья редакция простого и красивого стиля Light. +Comment[rw]=Isubiramo rya gatatu ry'imisusire y'uburyo 'Rumuri' ryoroshye kandi ryiza. +Comment[se]=Oktageardánis ja fárddalaš 'Light'-stiilla goalmmát veršuvdna. +Comment[sk]=Tretia revízia jednoduchého a elegantného štýlu prvkov 'Light'. +Comment[sl]=Tretja revizija preprostega in elegantnega sloga gradnikov »Light«. +Comment[sq]=Përmirësimi i tretë i Stilit [Lehtë] i cili është i thjeshtë edhe elegant. +Comment[sr]=Трећа ревизија једноставног и елегантног „лаког“ стила. +Comment[sr@Latn]=Treća revizija jednostavnog i elegantnog „lakog“ stila. +Comment[sv]=Tredje revisionen av den simpla och eleganta komponentstilen "Lätt". +Comment[ta]=சுலபமான 'இலேசான' சாளர பாணியின் மூன்றாவது சோதனை +Comment[te]=సరళమైన మరయు సొగసైన 'వెలుగు' విడ్జెట్ శైలి యొక్క మూడొవ సవరణ +Comment[tg]=Интишори саввум сабки кушоди 'Light' содда ва зебо аст. +Comment[th]=รุ่นแก้ไขรุ่นที่สามของรูปแบบ 'บางเบา' ที่เรียบง่ายและภูมิฐาน +Comment[tr]=Hafif Stil'in üçüncü revizyonu +Comment[tt]=Ciñel yämle "Light" tışlawınıñ 3. söreme. +Comment[uk]=Третя версія простого та елегантного стилю віджетів "Light". +Comment[uz]=Oddiy va chiroyli Light uslubining uchinchi tahriri +Comment[uz@cyrillic]=Оддий ва чиройли Light услубининг учинчи таҳрири +Comment[ven]=Ndovhololo ya vhuraru isa kondi na tshitaela tshisa kondi. +Comment[vi]=Bản sửa đổi thứ ba của kiểu dáng ô điều khiển Sáng đơn giản và thanh lịch. +Comment[xh]=Ukhumbuzo kwakhona lwesithathu lokulula kunye nokubukekayo kohlobo lwe widget 'Ekhaphu-khaphu'. +Comment[zh_CN]=简约雅致的“Light”风格,第三版。 +Comment[zh_HK]=簡單高雅的「輕靈」介面工具風格的第三版。 +Comment[zh_TW]=簡單高雅的“輕靈”界面工具風格的第三版。 +Comment[zu]=Ukubuyekezwa kwesithathu kwesitayela se-widget 'Esilula' kanye nokuphucuzekile. +[KDE] +WidgetStyle=Light, 3rd revision diff --git a/kstyles/themes/mega.themerc b/kstyles/themes/mega.themerc new file mode 100644 index 000000000..a0cf79e19 --- /dev/null +++ b/kstyles/themes/mega.themerc @@ -0,0 +1,76 @@ +[Misc] +Name=MegaGradient highcolor style +Name[af]=Megagradiënt hoë-kleur styl +Name[az]=MegaGradient yüksək rəng tərzi +Name[be]=Градыентавы стыль HighColor +Name[ca]=Estil MegaGradient d'alta profunditat +Name[cs]=Highcolor styl MegaGradient +Name[csb]=Wielofarwny sztél MegaGradient +Name[cy]=Arddull GraddliwMega uchel-liw +Name[da]=MegaGradient højfarvestil +Name[de]=MegaGradient (64000-Farben-Stil) +Name[el]=MegaGradient στυλ πολλών χρωμάτων +Name[en_GB]=MegaGradient highcolour style +Name[eo]=Multkolorega stilo kun kolortransiroj +Name[es]=Estilo MegaDegradado de alta profundidad +Name[et]=MegaGradient paljuvärviline stiil +Name[eu]=MegaGradient kolore askodun estiloa +Name[fa]=سبک رنگ بالای مگاگرادینت +Name[fi]=MegaGradient-monivärityyli +Name[fr]=Style MégaGradient très coloré +Name[fy]=MegaGradiënt hege-kleurenstyl +Name[gl]=Estilo de alto contraste MegaGradient +Name[hi]=मेगाग्रंडिएंट हाईकलर शैली +Name[hr]=MegaGradient stil s puno boja +Name[hu]=Megagradiens (színgazdag) +Name[id]=Gaya highcolor MegaGradient +Name[is]=MegaGradient fjöllitastíll +Name[it]=Mega sfumature con molti colori +Name[ja]=MegaGradient ハイカラースタイル +Name[ka]=highcolor გრადიენტული სტილი +Name[kk]=МегаГрадиент түстерге бай стилі +Name[km]=រចនាប័ទ្មពណ៌ខ្ពស់ MegaGradient +Name[lb]=MegaGradient-Stil (vill Faarwen) +Name[lt]=MegaGradient aukštos spalvų gebos stilius +Name[lv]=MegaGradient daudzkrāsu stils +Name[mk]=MegaGradient високобоен стил +Name[mn]=МигаГрадиент (64000-Өнгө-Хэлбэр) +Name[ms]=Gaya MegaGradient warna cerah +Name[mt]=Stil MegaGradient +Name[nb]=MegaGradient mangefargestil +Name[nds]=MegaGradient-Stil (Highcolor) +Name[ne]=मेगाग्रेडियन्ट उच्चरङ शैली +Name[nl]=MegaGradiënt hogekleurenstijl +Name[nn]=MegaGradient-stil med mange fargar +Name[nso]=Mokgwa wa kholoro ya godimo ya MegaGradient +Name[pa]=MegaGradient ਗੂੜਾ ਸ਼ੈਲੀ +Name[pl]=Styl wielokolorowy MegaGradient +Name[pt]=Estilo MegaGradient com muitas cores +Name[pt_BR]=Estilo Mega-Gradiente +Name[ro]=Stil cu culori multe MegaGradient +Name[ru]=Градиентный стиль highcolor +Name[se]=MegaGradient ivdnás stiila +Name[sk]=MegaGradient štýl veľa farieb +Name[sl]=Raznobarvni slog MegaGradient +Name[sq]=Stili Shumëngjyrësh i MegaShkrirjes +Name[sr]=Мегаградијент стил са пуно боја +Name[sr@Latn]=Megagradijent stil sa puno boja +Name[sv]=Megagradient färgrik stil +Name[ta]=மிகப்பெரிய வண்ணக்களஞ்சிய உயர் வண்ண பாணி +Name[te]=మెగాగ్రెడియంట్ ఎక్కువ రంగు శైలి +Name[tg]=Сабки рангбаландии MegaGradient +Name[th]=รูปแบบไล่สี ความละเอียดสีสูง +Name[tr]=Yüksek renkli stil +Name[tt]=Küptösle MegaGradient tışlawı +Name[uk]=Багатокольоровий стиль "Мега-градієнт" +Name[uz]=MegaGradient highcolor uslubi +Name[uz@cyrillic]=MegaGradient highcolor услуби +Name[ven]=Tshitaela tsha muvhala wa ntha wa MegaGradient +Name[vi]=Kiểu dáng màu cao Siêu Dốc +Name[xh]=Uhlobo lombala ophezulu we MegaGradient +Name[zh_CN]=MegaGradient 高色彩风格 +Name[zh_HK]=MegaGradient 高彩風格 +Name[zh_TW]=MegaGradient 高彩風格 +Name[zu]=Isitayela sombala ophezulu se-MegaGradient +[KDE] +widgetStyle=mega.la diff --git a/kstyles/themes/qtcde.themerc b/kstyles/themes/qtcde.themerc new file mode 100644 index 000000000..5f71e6a1e --- /dev/null +++ b/kstyles/themes/qtcde.themerc @@ -0,0 +1,88 @@ +[Misc] +Name=CDE +Name[bn]=সি-ডি-ই +Name[hi]=सीडीई +Name[te]=సిడిఈ +Name[th]=ซีดีอี +Comment=Built-in unthemed CDE style +Comment[af]=Ingeboude ongetemade Cde styl +Comment[ar]=مظهر مضمن مشابه لCDE +Comment[az]=Yerləşmiş, örtüsüz CDE tərzi +Comment[be]=Убудаваны стыль CDE +Comment[bg]=Вграден в библиотеката Qt стил без тема CDE +Comment[br]=Giz CDE enframmet anwisket +Comment[bs]=Ugrađeni CDE stil bez teme +Comment[ca]=Estil incorporat CDE sense temes +Comment[cs]=Zabudovaný CDE styl (bez motivu) +Comment[csb]=Wbùdowóny sztél CDE, bez témów +Comment[cy]=Ardull mewnadeiladedig di-thema CDE +Comment[da]=Indbygget CDE-stil uden tema +Comment[de]=Eingebauter, reduzierter CDE-Stil +Comment[el]=Ενσωματωμένο στυλ παρόμοιο με το CDE +Comment[eo]=Originala CDE-stilo neetosa +Comment[es]=Estilo incorporado CDE sin tema +Comment[et]=Qt CDE-laadne teemata stiil +Comment[eu]=Gairik gabeko CDE estiloa +Comment[fa]=سبک CDE بدون چهرۀ توکار +Comment[fi]=Sisäänrakennettu teemoittamaton CDE-tyyli +Comment[fr]=Style CDE d'origine sans thème +Comment[fy]=Ynboude, temaleaze CDE-styl +Comment[ga]=Stíl insuite gan téama, cosúil le CDE +Comment[gl]=Estilo incorporado CDE sen tema +Comment[he]=ערכה פנימית תואמת CDE +Comment[hi]=अंतर्निर्मित अनथीम्ड सीडीई शैली +Comment[hr]=Ugrađeni CDE stil, bez teme +Comment[hu]=Beépített CDE-stílus +Comment[id]=Gaya ala CDE built-in tanpa tema +Comment[is]=Innbyggður stíll sem minnir á CDE notendaskilin (án þema) +Comment[it]=Stile CDE interno senza tema +Comment[ja]=ビルトイン CDE スタイル (テーマなし) +Comment[ka]=ჩადგმული CDE სტილი თემის გარეშე +Comment[kk]=Qt құрамындағы нақыштарсыз CDE-секілді стиль +Comment[km]=រចនាប័ទ្ម CDE ដែលគ្មានស្បែកជាប់ +Comment[ko]=CDE와 같은 꼴을 가진 붙박이 테마 +Comment[lb]=Agebauten CDE-Stil ouni Thema +Comment[lt]=Įtaisytas betemis CDE stilius +Comment[lv]=Iebūvēts beztēmas CDE stils +Comment[mk]=Вграден CDE стил (без тема) +Comment[mn]=Агшаалттай суулгасан CDE-хэлбэр +Comment[ms]=Gaya CDE bina dalam +Comment[mt]=Stil bla tema CDE +Comment[nb]=Innebygget CDE-stil uten tema +Comment[nds]=Inbuut CDE-Stil (ahn Muster) +Comment[ne]=विषयवस्तु नभएको CDE शैलीमा निर्माण +Comment[nl]=Ingebouwde, themaloze CDE-stijl +Comment[nn]=Innebygd CDE-stil utan tema +Comment[nso]=Mokgwa wa CDE wa kagelogare wo osenago molaetsa +Comment[oc]=Estil incorporat CDE sense temes +Comment[pa]=ਵਿੱਚੇ ਸ਼ਾਮਿਲ CDE ਸ਼ੈਲੀ +Comment[pl]=Wbudowany styl CDE, bez motywów +Comment[pt]=Estilo embutido CDE +Comment[pt_BR]=Estilo predefinido CDE +Comment[ro]=Stil fără tematică CDE +Comment[ru]=Встроенный в Qt стиль без тем, похожий на CDE +Comment[rw]=Imisusire CDE itahawe insanganyamatsiko nkoranwa +Comment[se]=Sisahuksejuvvon CDE-stiila fáttáhaga +Comment[sk]=Zabudovaný netémový CDE štýl +Comment[sl]=Vgrajeni običajni slog CDE +Comment[sr]=Уграђени, без теме, CDE стил +Comment[sr@Latn]=Ugrađeni, bez teme, CDE stil +Comment[sv]=Inbyggd otemad CDE-stil +Comment[ta]=உள்ளமைந்த மேம்படுத்திய CDE பாணி +Comment[te]=అంతర్గత వైవిద్యాంశంలేని సిడిఈ శైలి +Comment[tg]=Донистани тарҳи аз нав сохтани CDE сабк аст +Comment[th]=รูปแบบตัวจัดการหน้าต่าง CDE ที่มีมาให้ +Comment[tr]=Yerleşik, temasız CDE stili +Comment[tt]=CDE kebek köylänmäslek eçke tışlaw +Comment[uk]=Вбудований стиль CDE без теми +Comment[uz]=Ichki mavzusiz CDE uslubi +Comment[uz@cyrillic]=Ички мавзусиз CDE услуби +Comment[ven]=Tshitaela tsha CDE tsho fhatelwaho ngomu +Comment[vi]=Kiểu dáng CDE có sẵn không có sắc thái. +Comment[xh]=Uhlobo olungenamxholo olakhelwe-ngaphakathi lwe CDE +Comment[zh_CN]=内建的无主题 CDE 风格 +Comment[zh_HK]=內置類似沒有修改風格的 CDE 佈景 +Comment[zh_TW]=內建的無主題 CDE 風格 +Comment[zu]=Isitayela Sokwakheka-ngaphakathi okungenagqikithi +[KDE] +WidgetStyle=CDE diff --git a/kstyles/themes/qtmotif.themerc b/kstyles/themes/qtmotif.themerc new file mode 100644 index 000000000..dfdc9b0dc --- /dev/null +++ b/kstyles/themes/qtmotif.themerc @@ -0,0 +1,94 @@ +[Misc] +Name=Motif +Name[af]=Motief +Name[bn]=মোটিফ +Name[fa]=موتیف +Name[hi]=यूटी मोटिफ़ +Name[ko]=모티프 +Name[ne]=मोटिफ +Name[pa]=ਮੋਟੀਫ +Name[ta]=மோடிஃப் +Name[te]=మోటిఫ్ +Name[th]=โมทิฟ +Comment=Built-in unthemed Motif style +Comment[af]=Ingeboude ongetemade motief styl +Comment[ar]=مظهر مضمن مشابه لMotif +Comment[az]=Yerləşmiş, örtüsüz Motif tərzi +Comment[be]=Убудаваны стыль Motif +Comment[bg]=Вграден в библиотеката Qt стил без тема Motif +Comment[br]=Giz Motif enframmet anwisket +Comment[bs]=Ugrađeni Motif stil bez teme +Comment[ca]=Estil encastat del Motif sense temes +Comment[cs]=Zabudovaný styl Motif (bez motivu) +Comment[csb]=Wbùdowóny sztél Motif, bez témów +Comment[cy]=Arddull Motif mewnadeiladedig heb thema +Comment[da]=Indbygget Motif-stil uden tema +Comment[de]=Eingebauter, reduzierter Motif-Stil +Comment[el]=Ενσωματωμένο στυλ παρόμοιο με το Motif +Comment[eo]=Originala Motif-stilo neetosa +Comment[es]=Estilo incorporado Motif sin tema +Comment[et]=Qt Motif'i-laadne teemata stiil +Comment[eu]=Gairik gabeko Motif estiloa +Comment[fa]=سبک موتیف بدون چهرۀ توکار +Comment[fi]=Sisäänrakennettu teemoittamaton Motif-tyyli +Comment[fr]=Style Motif d'origine sans thème +Comment[fy]=Ynboude, temaleaze Motif-styl +Comment[ga]=Stíl insuite gan téama, cosúil le Motif +Comment[gl]=Estilo incorporado Motif sen tema +Comment[he]=ערכת נושא פנימית תואמת Motif +Comment[hi]=अंतर्निर्मित अनथीम्ड मोटिफ शैली +Comment[hr]=Ugrađeni Motif stil, bez teme +Comment[hu]=Beépített Motif-stílus +Comment[id]=Gaya ala Motif built-in tanpa tema +Comment[is]=Innbyggður stíll sem minnir á Motif unhverfið (án þema) +Comment[it]=Stile Motif interno senza tema +Comment[ja]=ビルトイン Motif スタイル (テーマなし) +Comment[ka]=ჩადგმული Motif სტილი თემის გარეშე +Comment[kk]=Qt құрамындағы нақыштарсыз Motif-секілді стиль +Comment[km]=រចនាប័ទ្ម Motif ដែលគ្មានស្បែកជាប់ +Comment[ko]=모티프와 같은 꼴을 가진 붙박이 테마 +Comment[lb]=Agebaute Motif-Stil ouni Thema +Comment[lt]=Įtaisytas betemis Motif stilius +Comment[lv]=Iebūvēts beztēmas Motif stils +Comment[mk]=Вграден Motif стил (без тема) +Comment[mn]=Motif-Хэлбэр +Comment[ms]=Gaya Motif bina dalam +Comment[mt]=Stil bla tema Motif +Comment[nb]=Innebygget Motif-stil uten tema +Comment[nds]=Inbuut Motif-Stil (ahn Muster) +Comment[ne]=विषयवस्तु नभएको मोटिफ शैलीमा निर्माण +Comment[nl]=Ingebouwde, themaloze Motifstijl +Comment[nn]=Innebygd Motif-stil utan tema +Comment[nso]=Mokgwa wa Motif wa kagelogare wo osenago molaetsa +Comment[oc]=Estil incorporat Motif sense temes +Comment[pa]=ਵਿੱਚੇ ਸ਼ਾਮਿਲ ਮੋਟੀਂਫ ਸ਼ੈਲੀ +Comment[pl]=Wbudowany styl Motif, bez motywów +Comment[pt]=Estilo embutido Motif +Comment[pt_BR]=Estilo Motif predefinido +Comment[ro]=Stil fără tematică Motif +Comment[ru]=Встроенный в Qt стиль без тем, похожий на Motif +Comment[rw]=Imisusire y'Umutako itahawe insanganyamatsiko nkoranwa +Comment[se]=Sisahuksejuvvon Motif-stiila fáttáhaga +Comment[sk]=Zabudovaný netémový CDE štýl +Comment[sl]=Vgrajen običajni slog Motif +Comment[sr]=Уграђени, без теме, Motif стил +Comment[sr@Latn]=Ugrađeni, bez teme, Motif stil +Comment[sv]=Inbyggd otemad Motif-stil +Comment[ta]=உள்ளமைந்த மேம்படுத்திய மோடிஃப் பாணி +Comment[te]=అంతర్గత వైవిద్యాంశంలేని మోటిఫ్ శైలి +Comment[tg]= Сохташудани Сабки Motif бебарнома аст +Comment[th]=รูปแบบโมทิฟ ที่มีมาให้ +Comment[tr]=Yerleşik, temasız Motif stili +Comment[tt]=Motif kebek köylänmäslek eçke tışlaw +Comment[uk]=Вбудований стиль Motif без теми +Comment[uz]=Ichki mavzusiz Motif uslubi +Comment[uz@cyrillic]=Ички мавзусиз Motif услуби +Comment[ven]=Tshitaela tsha mothifi tsho fhatelwaho ngomu +Comment[vi]=Kiểu dáng Motif có sẵn không có sắc thái. +Comment[xh]=Uhlobo lwe Motir olungenamxholo olakhelwe-ngaphakathi +Comment[zh_CN]=内建的无主题 Motif 风格 +Comment[zh_HK]=內置類似沒有修改風格的 Motif 佈景 +Comment[zh_TW]=內建的無主題 Motif 風格 +Comment[zu]=Ukwakekha-ngaphakathi okungenagqikithi sesitayela se-Motif +[KDE] +WidgetStyle=Motif diff --git a/kstyles/themes/qtmotifplus.themerc b/kstyles/themes/qtmotifplus.themerc new file mode 100644 index 000000000..d12e5dc51 --- /dev/null +++ b/kstyles/themes/qtmotifplus.themerc @@ -0,0 +1,104 @@ +[Misc] +Name=Motif Plus +Name[af]=Motief Plus +Name[bn]=মোটিফ প্লাস +Name[br]=Motif Mui +Name[cy]=Motif Plws +Name[fa]=موتیف ممتاز +Name[hi]=मोटिफ़ प्लस +Name[is]=Motif plús +Name[it]=Motif plus +Name[ja]=Motif プラス +Name[ko]=모티프 플러스 +Name[ne]=मोटिफ प्लस +Name[nn]=Motif pluss +Name[pa]=ਮੋਟੀਫ ਨਵਾਂ +Name[rw]=Impamvu Nyongera +Name[ta]=மோடிஃப் ப்ளஸ் +Name[te]=మోటిఫ్ ప్లస్ +Name[th]=โมทีฟพลัส +Name[vi]=Motif Cộng +Comment=Built-in enhanced Motif style +Comment[af]=Ingeboude verbeterde Motief styl +Comment[ar]=مظهر مضمن محسّن مشابه لMotif +Comment[az]=Yerləşmiş, örtüsüz Motif tərzi +Comment[be]=Убудаваны палепшаны стыль Motif +Comment[bg]=Допълнително разширен, вграден в библиотеката Qt стил без тема Motif +Comment[br]=Giz Motif enframmet gwellaet +Comment[bs]=Ugrađeni napredni Motif stil +Comment[ca]=Estil encastat del Motif millorat +Comment[cs]=Zabudovaný vylepšený styl Motif +Comment[csb]=Wbùdowóny, pòszerzony sztél Motif +Comment[cy]=Arddull Motif mewnadeiladedig uwch +Comment[da]=Indbygget udvidet Motif-stil +Comment[de]=Eingebauter, erweiterter Motif-Stil +Comment[el]=Ενσωματωμένο στυλ παρόμοιο με το Motif με βελτιώσεις +Comment[eo]=Enkonstruita etendita Motif-stilo +Comment[es]=Estilo incorporado Motif mejorado +Comment[et]=Qt täiustatud Motif'i-laadne stiil +Comment[eu]=Gairik gabeko Motif estilo hobetua +Comment[fa]=سبک موتیف افزودۀ توکار +Comment[fi]=Sisäänrakennettu paranneltu Motif-tyyli +Comment[fr]=Style Motif amélioré d'origine +Comment[fy]=Ynboude, ferbettere Motif-styl +Comment[ga]=Stíl insuite méadaithe, cosúil le Motif +Comment[gl]=Estilo incorporado Motif mellorado sen tema +Comment[he]=ערכת נושא פנימית תואמת Motif משופרת +Comment[hi]=अंतर्निर्मित एनहेंस्ड मोटिफ शैली +Comment[hr]=Ugrađeni unaprijeđeni Motif stil, bez teme +Comment[hu]=Beépített továbbfejlesztett Motif-stílus +Comment[id]=Gaya modifikasi Motif tanpa tema +Comment[is]=Innbyggður stíll, endurbætt Motif unhverfi +Comment[it]=Stile Motif interno avanzato +Comment[ja]=ビルトイン Motif スタイル 改良版 +Comment[ka]=ჩადგმული გაუმჯობესებული Motif სტილი +Comment[kk]=Qt құрамындағы жетілдірген Motif-секілді стиль +Comment[km]=រចនាប័ទ្ម Motif ជាប់ +Comment[ko]=더 나은 모티프와 같은 꼴을 가진 붙박이 테마 +Comment[lb]=Agebauten, erweiderte Motif-Stil +Comment[lt]=Įtaisytas išplėstas Motif stilius +Comment[lv]=Iebūvēts uzlabots Motif stils +Comment[mk]=Вграден напреден Motif стил +Comment[mn]=Агшаалттай суулгасан Motif-хэлбэр +Comment[ms]=Gaya Motif bina dalam lanjut +Comment[mt]=Stil Motif estiż +Comment[nb]=Innebygget utvidet Motif-stil +Comment[nds]=Inbuut verwiedert Motif-Stil +Comment[ne]=विस्तारित मोटिफ शैलीमा निर्माण +Comment[nl]=Ingebouwde verbeterde Motifstijl +Comment[nn]=Innebygd forbetra Motif-stil +Comment[nso]=Mokgwa wa kagelogare wo o hlohloleditswego wa Motif +Comment[oc]=Estil incorporat Motif amelhorat +Comment[pa]=ਨਵੀਂ ਮੋਟੀਫ ਸ਼ੈਲੀ +Comment[pl]=Wbudowany, rozszerzony styl Motif +Comment[pt]=Estilo embutido melhorado de Motif +Comment[pt_BR]=Estilo Motif interno melhorado +Comment[ro]=Stil Motif îmbunătăţit +Comment[ru]=Встроенный в Qt улучшенный стиль Motif +Comment[rw]=Imisusire y'Umutako ivuguruwe nkoranwa +Comment[se]=Sisahuksejuvvon buorádallon Motif-stiila +Comment[sk]=Zabudovaný vylepšený štýl Motif +Comment[sl]=Vgrajen izboljšani slog Motif +Comment[sr]=Уграђени, унапређени, Motif стил +Comment[sr@Latn]=Ugrađeni, unapređeni, Motif stil +Comment[sv]=Inbyggd utökad Motif-stil +Comment[ta]=உள்ளமைந்த மேம்படுத்திய மோடிஃப் பாணி +Comment[te]=అంతర్గత అభివ్రుద్దిపరిచిన మోటిఫ్ శైలి +Comment[tg]=Сохташудани Сабки Motif тез аст +Comment[th]=รูปแบบโมทีฟที่ปรับปรุงขึ้นมา +Comment[tr]=Yerleşik, temasız Motif stili +Comment[tt]=Motif kebek köylänmäslek yaxşırtılğan eçke tışlaw +Comment[uk]=Вбудований покращений стиль Motif +Comment[uz]=Kengaytirilgan ichki Motif uslubi +Comment[uz@cyrillic]=Кенгайтирилган ички Motif услуби +Comment[ven]=Tshitaela tsho fhatelwaho nga ngomu +Comment[vi]=Name=Kiểu dáng Motif có sẵn tăng cường. +Comment[xh]=Uhlobo lwe Motif olunyusiweyo olwakhelwe-ngaphakathi +Comment[zh_CN]=内建的增强的 Motif 风格 +Comment[zh_HK]=內置的增強的 Motif 風格 +Comment[zh_TW]=內建的增強的 Motif 風格 +Comment[zu]=Isitayela se-Mofit esenziwe ngcono +[KDE] +WidgetStyle=MotifPlus +[Desktop Entry] +Hidden=true diff --git a/kstyles/themes/qtplatinum.themerc b/kstyles/themes/qtplatinum.themerc new file mode 100644 index 000000000..08227bc4c --- /dev/null +++ b/kstyles/themes/qtplatinum.themerc @@ -0,0 +1,109 @@ +[Misc] +Name=Platinum +Name[be]=Платына +Name[bn]=প্ল্যাটিনাম +Name[csb]=Platina +Name[cy]=Platinwm +Name[eo]=Plateno +Name[fa]=پلاتین +Name[hi]=प्लेटिनम +Name[is]=Platínum +Name[it]=Platino +Name[ko]=플래티넘 +Name[lt]=Platina +Name[lv]=Platīns +Name[mn]=Платиниум +Name[nds]=Platin +Name[ne]=प्लाटिनम +Name[pa]=ਪਲੈਟੀਨਮ +Name[pl]=Platyna +Name[sv]=Platina +Name[ta]=பிளாட்டினம் +Name[te]=ప్లాటినం +Name[th]=แพลตตินัม +Name[tr]=Platin +Name[vi]=Bạch kim +Name[wa]=Platene +Name[zh_CN]=白金 +Comment=Built-in unthemed Platinum style +Comment[af]=Ingeboude ongetemade Platinum styl +Comment[ar]=مظهر مضمن Platinum +Comment[az]=Yerləşmiş, örtüsüz Platin tərzi +Comment[be]=Убудаваны стыль Платына +Comment[bg]=Вграден в библиотеката Qt стил без тема Platinum +Comment[br]=Giz Platinum enframmet anwisket +Comment[bs]=Ugrađeni Platinum stil bez teme +Comment[ca]=Estil encastat del Platinium sense temes +Comment[cs]=Zabudovaný styl Platinum (bez motivu) +Comment[csb]=Wbùdowóny sztél Platina, bez témów +Comment[cy]=Arddull Platinwm mewnadeiladedig heb thema +Comment[da]=Indbygget platin-stil uden tema +Comment[de]=Eingebauter, reduzierter Platin-Stil +Comment[el]=Ενσωματωμένο στυλ Platinum +Comment[eo]=Originala Platena stilo neetosa +Comment[es]=Estilo incorporado Platinum sin tema +Comment[et]=Qt Platinum teemata stiil +Comment[eu]=Gairik gabeko Platinum estiloa +Comment[fa]=سبک پلاتین بدون چهرۀ توکار +Comment[fi]=Sisäänrakennettu teemoittamaton Platinium-tyyli +Comment[fr]=Style Platinum d'origine sans thème +Comment[fy]=Ynboude, temaleaze Platinum-styl +Comment[ga]=Platinum - Stíl insuite gan téama +Comment[gl]=Estilo incorporado Platinum sen tema +Comment[he]=ערכת נושא פנימית תואמת Platinum +Comment[hi]=अंतर्निर्मित अनथीम्ड प्लेटिनम शैली +Comment[hr]=Ugrađeni Platinum stil, bez teme +Comment[hu]=Beépített Platinum stílus +Comment[id]=Gaya ala Platinum built-in tanpa tema +Comment[is]=Innbyggði Platínum stíllinn (án þema) +Comment[it]=Stile Platino interno senza tema +Comment[ja]=ビルトイン Platinum スタイル (テーマなし) +Comment[ka]=ჩადგმული Platinum სტილი თემის გარეშე +Comment[kk]=Qt құрамындағы нақыштарсыз Platinum стилі +Comment[km]=រចនាប័ទ្ម Platinum ដែលគ្មានស្បែកជាប់ +Comment[ko]=플래티넘과 같은 꼴을 가진 붙박이 테마 +Comment[lb]=Agebaute Platinum-Stil ouni Thema +Comment[lt]=Įtaisytas betemis Platinos stilius +Comment[lv]=Iebūvēts beztēmas Platīna stils +Comment[mk]=Вграден платинум стил (без тема) +Comment[mn]=Агшаалттай суулгасан Platin--хэлбэр +Comment[ms]=Gaya Platinum bina dalam +Comment[mt]=Stil Platinum bla tema +Comment[nb]=Innebygget Platinum-stil +Comment[nds]=Inbuut Platin-Stil (ahn Muster) +Comment[ne]=विषय वस्तु नभएको प्लाटिनम शैलीमा निर्माण +Comment[nl]=Ingebouwde themaloze Platinum-stijl +Comment[nn]=Innebygd Platinum-stil utan tema +Comment[nso]=Mokgwa wa Platinum wa kagelogare wo osenago molaetsa +Comment[oc]=Estil incorporat Plati sense temes +Comment[pa]=ਵਿੱਚੇ ਸ਼ਾਮਿਲ ਪਲਾਟੀਨਮ ਸ਼ੈਲੀ +Comment[pl]=Wbudowany styl Platyna, bez motywów +Comment[pt]=Estilo embutido Platinum +Comment[pt_BR]=Estilo Platinum predefinido +Comment[ro]=Stil fără tematică Platinum +Comment[ru]=Встроенный в Qt стиль без тем Platinum +Comment[rw]=Imiterere ya Pulatine itahawe insanganyamatsiko nkorana +Comment[se]=Sisahuksejuvvon Platinum-stiila fáttáhaga +Comment[sk]=Zabudovaný platinový štýl bez témy +Comment[sl]=Netematski vgrajeni platinasti slog +Comment[sr]=Уграђени, без теме, Platinum стил +Comment[sr@Latn]=Ugrađeni, bez teme, Platinum stil +Comment[sv]=Inbyggd otemad platinumstil +Comment[ta]=உள்ளமைந்த தலைப்பில்லா பிளாட்டினம் பாணி +Comment[te]=అంతర్గత వైవిద్యాంశంలేని ప్లాటినమ్ శైలి +Comment[tg]=Сохташудани Сабки Platinum Motif бебарнома аст +Comment[th]=รูปแบบแพลตตินัม +Comment[tr]=Yerleşik, temasız Platin stili +Comment[tt]=Platinum kebek köylänmäslek eçke tışlaw +Comment[uk]=Вбудований стиль Platinum без теми +Comment[uz]=Ichki mavzusiz Platinum uslubi +Comment[uz@cyrillic]=Ички мавзусиз Platinum услуби +Comment[ven]=Tshitale tsha pulathinamu tsho fhatelwaho nga ngomu +Comment[vi]=Kiểu dáng Bạch Kim có sẵn không có sắc thái. +Comment[xh]=Uhloboa lwe Platinum olungenamxholo olwakhelwe-ngaphakathi +Comment[zh_CN]=内建的无主题白金风格 +Comment[zh_HK]=內置的無主題 Platinum 風格 +Comment[zh_TW]=內建的無主題 Platinum 風格 +Comment[zu]=Yakhelwe-kuhlobo lwesingenabizogama isitayelaPlatinum +[KDE] +WidgetStyle=Platinum diff --git a/kstyles/themes/qtsgi.themerc b/kstyles/themes/qtsgi.themerc new file mode 100644 index 000000000..85cf8b7b0 --- /dev/null +++ b/kstyles/themes/qtsgi.themerc @@ -0,0 +1,90 @@ +[Misc] +Name=SGI +Name[bn]=এস-জি-আই +Name[hi]=एसजीआई +Name[nl]=SIG +Name[te]=ఏస్ జిఐ +Name[th]=เอสจีไอ +Comment=Built-in SGI style +Comment[af]=Ingeboude Sgi styl +Comment[ar]=مظهر مضمن مشابه لSGI +Comment[az]=SGI tərzi +Comment[be]=Убудаваны стыль SGI +Comment[bg]=Вграден в библиотеката Qt стил без тема SGI +Comment[br]=Giz SGI enframmet +Comment[bs]=Ugrađeni SGI stil +Comment[ca]=Estil encastat del SGI +Comment[cs]=Zabudovaný SGI styl +Comment[csb]=Wbùdowóny sztél SGI +Comment[cy]=Thema SGI mewnadeiladedig +Comment[da]=Indbygget SGI-stil +Comment[de]=Eingebauter SGI-Stil +Comment[el]=Ενσωματωμένο στυλ παρόμοιο με το SGI +Comment[eo]=Enkonstruita SGI-stilo +Comment[es]=Estilo incorporado SGI +Comment[et]=Qt SGI stiil +Comment[eu]=SGI estiloa +Comment[fa]=سبک SGI توکار +Comment[fi]=Sisäänrakennettu SGI-tyyli +Comment[fr]=Style SGI d'origine +Comment[fy]=Ynboude SGI-styl +Comment[ga]=Stíl insuite SGI +Comment[gl]=Estilo incorporado SGI +Comment[he]=ערכת נושא פנימית תואמת SGI +Comment[hi]=अंतर्निर्मित एसजीआई शैली +Comment[hr]=Ugrađeni SGI stil +Comment[hu]=Beépített SGI stílus +Comment[id]=Gaya ala SGI built-in +Comment[is]=Innbyggður stíll sem minnir á SGI notendaskilin +Comment[it]=Stile SGI interno +Comment[ja]=ビルトイン SGI スタイル +Comment[ka]=ჩადგმული SGI სტილი +Comment[kk]=Qt құрамындағы SGI стилі +Comment[km]=រចនាប័ទ្ម Built-in SGI +Comment[ko]=SGI와 같은 꼴을 가진 붙박이 테마 +Comment[lb]=Agebauten SGI-Stil +Comment[lt]=Įtaisytas SGI stilius +Comment[lv]=Iebūvēts SGI stils +Comment[mk]=Вграден SGI стил +Comment[mn]=Суулгасан SGI-Хэлбэр +Comment[ms]=Gaya SGI bina dalam +Comment[mt]=Stil SGI +Comment[nb]=Innebygget SGI-stil +Comment[nds]=Inbuut SGI-Stil +Comment[ne]=SGI शैलीमा निर्माण +Comment[nl]=Ingebouwde SGI-stijl +Comment[nn]=Innebygd SGI-stil +Comment[nso]=Mokgwa wa Kagelo gare wa SGI +Comment[oc]=Estil incorporat SGI +Comment[pa]=ਵਿੱਚੇ ਸ਼ਾਮਿਲ SGI ਸ਼ੈਲੀ +Comment[pl]=Wbudowany styl SGI +Comment[pt]=Estilo embutido de SGI +Comment[pt_BR]=Estilo predefinido SGI +Comment[ro]=Stil SGI +Comment[ru]=Встроенный в Qt стиль, похожий на SGI +Comment[rw]=Imisusire SGI nkoranwa +Comment[se]=Sisahuksejuvvon SGI-stiila +Comment[sk]=Zabudovaný SGI štýl +Comment[sl]=Vgrajeni slog SGI +Comment[sq]=Stili SGI i ambalazhuar +Comment[sr]=Уграђени SGI стил +Comment[sr@Latn]=Ugrađeni SGI stil +Comment[sv]=Inbyggd SGI-stil +Comment[ta]=உள்ளமைந்த SGI பாணி +Comment[te]=అంతర్గత ఎస్ జిఐ శైలి +Comment[tg]=Аз нав сохтани SGI сабк +Comment[th]=รูปแบบ SGI +Comment[tr]=SGI stili +Comment[tt]=SGI kebek eçke tışlaw +Comment[uk]=Вбудований стиль SGI +Comment[uz]=Ichki SGI uslubi +Comment[uz@cyrillic]=Ички SGI услуби +Comment[ven]=Tshitaela tsha SGI tsho fhatelwaho nga ngomu +Comment[vi]=Kiểu dáng SGI có sẵn. +Comment[xh]=Uhlobo lwe SGI olwakhelwe-ngaphakathi +Comment[zh_CN]=内建的 SGI 风格 +Comment[zh_HK]=內置的 SGI 風格 +Comment[zh_TW]=內建的 SGI 風格 +Comment[zu]=Yakhelwe-kwisitayela se SGI +[KDE] +WidgetStyle=SGI diff --git a/kstyles/themes/qtwindows.themerc b/kstyles/themes/qtwindows.themerc new file mode 100644 index 000000000..68ee69815 --- /dev/null +++ b/kstyles/themes/qtwindows.themerc @@ -0,0 +1,96 @@ +[Misc] +Name=MS Windows 9x +Name[bn]=এম-এস উইন্ডোস ৯x +Name[eo]=Vindozo 9x +Name[gl]=MS Windows 8x +Name[hi]=एमएस विंडोज़ 9x +Name[ko]=MS 윈도우즈 9x +Name[lt]=MSWindows 9x +Name[ne]=MS विन्डोज 9x +Name[se]=Windows +Name[te]=ఎమ్ ఎస్ విండొస్ 9x +Name[th]=เอ็มเอสวินโดว์ส 9x +Name[vi]=MS™ Windows 9x +Name[zh_TW]=MSWindows 9x +Comment=Built-in unthemed Windows 9x style +Comment[af]=Ingeboude ongetemade Vensters 9x styl +Comment[ar]=مظهر مضمن مشابه لويندوز +Comment[az]=Yerləşmiş, örtüsüz Windows 98 tərzi +Comment[be]=Убудаваны стыль Windows 9x +Comment[bg]=Вграден в библиотеката Qt стил без тема, приличащ на Windows 98 +Comment[br]=Giz Windows enframmet anwisket +Comment[bs]=Ugrađeni Windows 9x stil bez teme +Comment[ca]=Estil encastat del Windows 9x sense temes +Comment[cs]=Zabudovaný Windows 9x styl (bez motivu) +Comment[csb]=Wbùdowóny sztél szlachùjący za Windows 9x, bez témów +Comment[cy]=Arddull Windows 9x mewnadeiladedig heb thema +Comment[da]=Indbygget Windows 9x-stil uden tema +Comment[de]=Eingebauter, reduzierter Windows-9x-Stil +Comment[el]=Ενσωματωμένο στυλ παρόμοιο με το Windows 9x +Comment[eo]=Senetosa Vindozo-9x-stilo +Comment[es]=Estilo incorporado Windows 9x sin tema +Comment[et]=Qt Windows9x-laadne teemata stiil +Comment[eu]=Gairik gabeko Windows 9x estiloa +Comment[fa]=سبک ویندوز 9x بدون چهره توکار +Comment[fi]=Sisäänrakennettu teemoittamaton Windows 9x-tyyli +Comment[fr]=Style Windows 9x d'origine sans thème +Comment[fy]=Ynboude, temaleaze Windows 9x-styl +Comment[ga]=Stíl insuite gan téama, cosúil le Windows 9x +Comment[gl]=Estilo incorporado Windows 9x sen tema +Comment[he]=ערכת נושא פנימית תואמת Windows 9x +Comment[hi]=अंतर्निर्मित विंडोज़ 9x शैली +Comment[hr]=Ugrađeni Windows 9x stil, bez teme +Comment[hu]=Beépített Windows 9x-stílus +Comment[id]=Gaya ala Windows 9x built-in tanpa tema +Comment[is]=Innbyggður stíll sem minnir á Windows 9x (án þema) +Comment[it]=Stile Windows 9x interno senza tema +Comment[ja]=ビルトイン Windows 9x スタイル (テーマなし) +Comment[ka]=ჩადგმული Windows 9x სტილი თემის გარეშე +Comment[kk]=Qt құрамындағы нақыштарсыз Windows 9x стилі +Comment[km]=រចនាប័ទ្ម Windows 9x ដែលគ្មានស្បែក +Comment[ko]=윈도우즈 9X와 비슷한 꼴을 가진 붙박이 테마 +Comment[lb]=Agebaute Windows 9x-Stil ouni Thema +Comment[lt]=Įtaisytas betemis Windows 9x stilius +Comment[lv]=Iebūvēts beztēmas Windows 9x stils +Comment[mk]=Вграден Windows 9x стил (без тема) +Comment[mn]=Агшаалттай суулгасан Windows-9x-Хэлбэр +Comment[ms]=Gaya Windows 9x bina dalam +Comment[mt]=Stil bla tema Windows 9x +Comment[nb]=Innebygget Windows 9x-stil +Comment[nds]=Inbuut Windows 9x-Stil (ahn Muster) +Comment[ne]=विषयवस्तु नभएको विन्डोज 9x शैलीमा निर्माण +Comment[nl]=Ingebouwde, themaloze MS-Windows-9x-stijl +Comment[nn]=Innebygd Windows 9x-stil utan tema +Comment[nso]=Mokgwa wa Windows 9x wo o agetswego kagare wo osenago molaetsa +Comment[oc]=Estil incorporat Windows 9x sense temes +Comment[pa]=ਵਿੰਡੋ 9x ਵਰਗੀ ਸ਼ੈਲੀ +Comment[pl]=Wbudowany styl podobny do Windows 9x, bez motywów +Comment[pt]=Estilo embutido Windows 9x +Comment[pt_BR]=Estilo Windows 9x predefinido +Comment[ro]=Stil fără tematică Windows 9x +Comment[ru]=Встроенный в Qt стиль без тем, похожий на Windows 9x +Comment[rw]=Imisusire Windows 9x nkoranwa idahawe insanganyamatsiko +Comment[se]=Sisahuksejuvvon Windows 9x-stiila fáttáhaga +Comment[sk]=Zabudovaný štýl Windows 9x bez témy +Comment[sl]=Vgrajeni običajni slog Windows 9x +Comment[sr]=Уграђени, без теме, стил Windows-а 9x +Comment[sr@Latn]=Ugrađeni, bez teme, stil Windows-a 9x +Comment[sv]=Inbyggd otemad Windows 9x-stil +Comment[ta]=உள்ளமைந்த தலைப்பில்லா சாளரங்கள் 9x பாணி +Comment[te]=అంతర్గత వైద్యాంశంలేని విండొస్ 9x లాంటి శైలి +Comment[tg]= Намуди Windows 9x бемавзӯи сохта шуда +Comment[th]=รูปแบบคล้ายวินโดว์ส 9x +Comment[tr]=Yerleşik, temasız Windows 98 stili +Comment[tt]=Windows9x kebek köylänmäslek eçke tışlaw +Comment[uk]=Вбудований стиль Windows 9x без теми +Comment[uz]=Ichki mavzusiz Windows 9x uslubi +Comment[uz@cyrillic]=Ички мавзусиз Windows 9x услуби +Comment[ven]=Tshitaela tsha 9x tsha windo i songo bulwaho tsho fhatelwaho nga ngomu +Comment[vi]=Kiểu dáng Windows 9x có sẵn không có sắc thái. +Comment[xh]=Uhlobo lwe Windows 9x olungenamxholo olwakhelwe-ngaphakathi +Comment[zh_CN]=内建的无主题 Windows 9x 风格 +Comment[zh_HK]=內置的無主題 Windows 9x 風格 +Comment[zh_TW]=內建的無主題 Windows 9x 風格 +Comment[zu]=Yakhelwe-kuhlobo kwisitayela samawindi 9x +[KDE] +WidgetStyle=Windows diff --git a/kstyles/utils/Makefile.am b/kstyles/utils/Makefile.am new file mode 100644 index 000000000..e949d7ef2 --- /dev/null +++ b/kstyles/utils/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS= installtheme + diff --git a/kstyles/utils/installtheme/Makefile.am b/kstyles/utils/installtheme/Makefile.am new file mode 100644 index 000000000..ff222bad0 --- /dev/null +++ b/kstyles/utils/installtheme/Makefile.am @@ -0,0 +1,18 @@ + +# set the include path for X, qt and KDE +INCLUDES= $(all_includes) + +####### This part is very settheme specific +# you can add here more. This one gets installed +bin_PROGRAMS = kinstalltheme + +# Which sources should be compiled for settheme. +kinstalltheme_SOURCES = main.cpp + +# the library search path. +kinstalltheme_LDFLAGS = $(all_libraries) $(KDE_RPATH) + +# the libraries to link against. Be aware of the order. First the libraries, +# that depend on the following ones. +kinstalltheme_LDADD = $(LIB_KDEUI) + diff --git a/kstyles/utils/installtheme/main.cpp b/kstyles/utils/installtheme/main.cpp new file mode 100644 index 000000000..0569c74ef --- /dev/null +++ b/kstyles/utils/installtheme/main.cpp @@ -0,0 +1,90 @@ +/* + Copyright (c) 2002 Maksim Orlovich <[email protected]> + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include <qfileinfo.h> +#include <qmap.h> +#include <qstringlist.h> +#include <qsettings.h> + +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <kglobal.h> +#include <klocale.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> + +static const char desc[] = I18N_NOOP("KDE Tool to build a cache list of all pixmap themes installed"); +static const char ver[] = "0.9.1"; + +int main(int argc, char **argv) +{ + KCmdLineArgs::init(argc, argv, "kinstalltheme", I18N_NOOP("KInstalltheme"), desc, ver); + KApplication qapp(false, false); //We don't allow styles.. Kind of ironic, isn't it? + + KGlobal::dirs()->addResourceType("themercs", KGlobal::dirs()->kde_default("data")+QString("kstyle/themes")); + QStringList themercs = KGlobal::dirs()->findAllResources("themercs","*.themerc"); + + QMap <QString, QString> themes; //Name->file mapping.. + + for (QStringList::iterator i = themercs.begin(); i!=themercs.end(); ++i) + { + QString file=*i; + KSimpleConfig config(file, true); + QString name = QFileInfo(file).baseName(); //This is nice and static... + //So we don't have to worry about our key changing when the language does. + + config.setGroup( "KDE" ); + + if (config.readEntry( "widgetStyle" ) == "basicstyle.la") + { + //OK, emit a style entry... + if (!themes.contains(name)) //Only add first occurrence, i.e. user local one. + themes[name] = file; + } + } + + KSimpleConfig cache( KGlobal::dirs()->saveLocation("config")+"kthemestylerc"); + +#if 0 +//Doesn't seem to work with present Qt.. + QStringList existing = cache.subkeyList("/kthemestyle"); + for (QStringList::iterator i = existing.begin(); i != existing.end(); i++) + { + cout<<"Have:"<<(*i).latin1()<<"\n"; + cache.removeEntry("/ktmthestyle"+(*i)); + } +#endif + + QStringList themeNames; //A list of names, each occurring once - the keys of the themes map.. + + for (QMap<QString, QString>::Iterator i = themes.begin(); i!=themes.end(); ++i) + { + cache.setGroup(i.key().lower()); + cache.writePathEntry("file",QFileInfo(i.data()).fileName()); + themeNames.push_back(i.key()); + } + + cache.setGroup("General"); + cache.writeEntry("themes", themeNames.join("^e")+"^e"); + + return 0; +} diff --git a/kstyles/web/Makefile.am b/kstyles/web/Makefile.am new file mode 100644 index 000000000..daa26a19d --- /dev/null +++ b/kstyles/web/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = $(all_includes) +lib_LTLIBRARIES = webstyle.la +webstyle_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +webstyle_la_LIBADD = $(LIB_KDEUI) +webstyle_la_SOURCES = webstyle.cpp plugin.cpp +noinst_HEADERS = webstyle.h + +kstylewebdata_DATA = web.themerc +kstylewebdatadir = $(kde_datadir)/kstyle/themes +EXTRA_DIST = $(kstylewebdata_DATA) diff --git a/kstyles/web/README b/kstyles/web/README new file mode 100644 index 000000000..42e198d00 --- /dev/null +++ b/kstyles/web/README @@ -0,0 +1,7 @@ +Widget style which mimicks the 'flat' appearance favored by many +web sites. If you set the scrollbar and (exclusive) indicator sizes +to something small (say 8 pixels) then this makes a nice style for +embedded apps. + +Maintainer: Rik Hemsley (rikkus) <[email protected]> + diff --git a/kstyles/web/plugin.cpp b/kstyles/web/plugin.cpp new file mode 100644 index 000000000..c22bb08fa --- /dev/null +++ b/kstyles/web/plugin.cpp @@ -0,0 +1,11 @@ +#include <klocale.h> +#include "webstyle.h" + +extern "C" +{ + KStyle * allocate() { return new WebStyle; } + int minor_version() { return 0; } + int major_version() { return 1; } + const char * description() { return(i18n("Web style plugin").utf8()); } +} + diff --git a/kstyles/web/web.themerc b/kstyles/web/web.themerc new file mode 100644 index 000000000..041d54da0 --- /dev/null +++ b/kstyles/web/web.themerc @@ -0,0 +1,163 @@ +[Misc] +Name=Web style +Name[af]=Web styl +Name[ar]=مظهر الويب +Name[az]=Veb tərzi +Name[be]=Стыль Сеціва +Name[bn]=ওয়েব স্টাইল +Name[br]=Giz gwiad +Name[bs]=Web stil +Name[ca]=Estil Web +Name[cs]=Webový styl +Name[csb]=Sztél Internetu +Name[cy]=Arddull Gwe +Name[da]=Netsidestil +Name[de]=Webstil +Name[el]=Στυλ Web +Name[eo]=TTT-stilo +Name[es]=Estilo Web +Name[et]=Veebistiil +Name[eu]=Web estiloa +Name[fa]=سبک وب +Name[fi]=Web-tyyli +Name[fr]=Style web +Name[fy]=Webstyl +Name[ga]=Stíl Ghréasáin +Name[gl]=Estilo Web +Name[he]=סגנון רשת +Name[hi]=वेब शैली +Name[hr]=Web stil +Name[hu]=Webes stílus +Name[id]=Gaya Web +Name[is]=Vefstíll +Name[it]=Web +Name[ja]=ウェブスタイル +Name[ka]=Web სტილი +Name[kk]=Веб стилі +Name[km]=រចនាប័ទ្មរបស់គេហទំព័រ +Name[ko]=웹 꼴 +Name[lb]=Web-Stil +Name[lt]=Žiniatinklio stilius +Name[lv]=Tīmekļa stils +Name[mk]=Web стил +Name[mn]=Вэб хэлбэр +Name[ms]=Gaya Web +Name[mt]=Stil web +Name[nb]=Vevstil +Name[nds]=Web-Stil +Name[ne]=वेब शैली +Name[nl]=Webstijl +Name[nn]=Vevstil +Name[nso]=Mokgwa wa web +Name[pa]=ਵੈਬ ਸ਼ੈਲੀ +Name[pl]=Styl Internetu +Name[pt]=Estilo Web +Name[pt_BR]=Estilos Web +Name[ro]=Stil web +Name[ru]=Стиль Web +Name[rw]=Imisusire y'urubuga +Name[se]=Fierpmádat-stiila +Name[sk]=Web štýl +Name[sl]=Spletni slog +Name[sq]=Stili Web +Name[sr]=Веб стил +Name[sr@Latn]=Veb stil +Name[sv]=Webbstil +Name[ta]=வலைப் பாணி +Name[te]=వెబ్ శైలి +Name[tg]=Сабки Вэб +Name[th]=รูปแบบเว็บ +Name[tr]=Web stili +Name[tt]=Web-tışlaw +Name[uk]=Стиль "Тенета" +Name[uz]=Veb uslubi +Name[uz@cyrillic]=Веб услуби +Name[ven]=Tshitaela tsha webu +Name[vi]=Kiểu dáng Mạng +Name[xh]=Uhlobo lwe Web +Name[zh_CN]=网络风格 +Name[zh_HK]=網站風格 +Name[zh_TW]=網站風格 +Name[zu]=Uhlobo lwe-web +Comment=Web widget style +Comment[af]=Web gui-element styl +Comment[ar]=مظهر ويدجات الويب +Comment[az]=Veb pəncərəcik tərzi +Comment[be]=Стыль Сеціва +Comment[bg]=Стил, приличащ на уеб графични обекти +Comment[bn]=ওয়েব উইজেট স্টাইল +Comment[br]=Giz widget gwiad +Comment[bs]=Stil ukrasa na webu +Comment[ca]=Estil d'objectes web +Comment[cs]=Styl prvků webu +Comment[csb]=Internetowi sztél elementów intefejsu +Comment[cy]=Arddull celfigyn Gwe +Comment[da]=Netsidekontrolstil +Comment[de]=Web-ähnlicher Stil für Bedienelemente +Comment[el]=Στυλ Web +Comment[eo]=TTT-speca stilo +Comment[es]=Estilo objeto visual Web +Comment[et]=Veebi elementide sarnane stiil +Comment[eu]=Web trepetaren estiloa +Comment[fa]=سبک عنصر وب +Comment[fi]=Web-tyyli +Comment[fr]=Style web +Comment[fy]=Web-widgetstyl +Comment[gl]=Estilo de widgets Web +Comment[he]=ערכנת נושא המושפעת מהרשת +Comment[hi]=वेब विज़ेट शैली +Comment[hr]=Web widget stil +Comment[hu]=Webes elemstílus +Comment[id]=Gaya widget Web +Comment[is]=Vefeiningastíll +Comment[it]=Stile Web +Comment[ja]=ウェブウィジェットスタイル +Comment[ka]=Web widget სტილი +Comment[kk]=Веб элементтер стилі +Comment[km]=រចនាប័ទ្មរបស់វត្ថុមើលឃើញនៃគេហទំព័រ +Comment[ko]=웹 위젯 꼴 +Comment[lb]=Web-Widget-Stil +Comment[lt]=Žiniatinklio valdiklių stilius +Comment[lv]=Tīmekļa vidžeta stils +Comment[mk]=Стил со елементи како за на веб +Comment[mn]=Вэбтэй төстэй хэлбэр +Comment[ms]=Gaya wijet Web +Comment[mt]=Stil tal-widgets tal-web +Comment[nb]=Elementstilen «vev» +Comment[nds]=Web-Stil för Bedeenelementen +Comment[ne]=वेब विजेट शैली +Comment[nl]=Web widgetstijl +Comment[nn]=Elementstilen «vev» +Comment[nso]=Mokgwa wa widget wa web +Comment[pa]=ਵੈੱਬ ਸਹਾਇਕ ਸ਼ੈਲੀ +Comment[pl]=Internetowy styl elementów intefejsu +Comment[pt]=Estilo gráfico Web +Comment[pt_BR]=Estilo Widget Web +Comment[ro]=Stil de componente Web +Comment[ru]=Стиль web widget +Comment[rw]=Imisusire y'uburyo bw'urubuga +Comment[se]=Fierpmádatáđa-stiila +Comment[sk]=Štýl prvku Web +Comment[sl]=Slog spletnega gradnika +Comment[sq]=Stili Web i emëruar +Comment[sr]=Веб стил контрола +Comment[sr@Latn]=Veb stil kontrola +Comment[sv]=Webbskärmdelsstil +Comment[ta]=வலை சாளரப் பாணி +Comment[te]=వెబ్ విడ్జెట్ శైలి +Comment[tg]=Сабки тақои Вэб +Comment[th]=รูปแบบเว็บ +Comment[tr]=Web aleti benzeri stil +Comment[tt]=Web widget tışlawı +Comment[uk]=Стиль "Віджети Тенет" +Comment[uz]=Veb uslubi +Comment[uz@cyrillic]=Веб услуби +Comment[ven]=Tshitaela tsha webe ya Widget +Comment[vi]=Kiểu dáng ô điều khiển Mạng +Comment[xh]=Uhlobo lwe widget ye Web +Comment[zh_CN]=网络部件风格 +Comment[zh_HK]=Web 元件風格 +Comment[zh_TW]=Web 元件風格 +Comment[zu]=Uhlobo lwe-widget ye-web +[KDE] +widgetStyle=webstyle.la diff --git a/kstyles/web/webstyle.cpp b/kstyles/web/webstyle.cpp new file mode 100644 index 000000000..ec5f606d0 --- /dev/null +++ b/kstyles/web/webstyle.cpp @@ -0,0 +1,1690 @@ +/* + * Copyright (C) 2001 Rik Hemsley (rikkus) <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDE_MENUITEM_DEF +#define INCLUDE_MENUITEM_DEF +#endif + +#include <qmenudata.h> +#include <qpalette.h> +#include <qbitmap.h> +#include <qtabbar.h> +#include <qpointarray.h> +#include <qscrollbar.h> +#include <qframe.h> +#include <qpushbutton.h> +#include <qdrawutil.h> +#include <qpainter.h> + +#include <kapplication.h> +#include <kdrawutil.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kdebug.h> + +#include "webstyle.h" + +static const int _indicatorSize = 13; +static QButton * _highlightedButton = 0; +static const int _scrollBarExtent = 14; + +static QFrame * _currentFrame = 0; +static int _savedFrameLineWidth; +static int _savedFrameMidLineWidth; +static ulong _savedFrameStyle; + +static QColor contrastingForeground(const QColor & fg, const QColor & bg) +{ + int h, s, vbg, vfg; + + bg.hsv(&h, &s, &vbg); + fg.hsv(&h, &s, &vfg); + + int diff(vbg - vfg); + + if ((diff > -72) && (diff < 72)) + { + return (vbg < 128) ? Qt::white : Qt::black; + } + else + { + return fg; + } +} + +// Gotta keep it separated. + + static void +scrollBarControlsMetrics +( + const QScrollBar * sb, + int sliderStart, + int /* sliderMin */, + int sliderMax, + int sliderLength, + int buttonDim, + QRect & rSub, + QRect & rAdd, + QRect & rSubPage, + QRect & rAddPage, + QRect & rSlider + ) +{ + bool horizontal = sb->orientation() == QScrollBar::Horizontal; + + int len = horizontal ? sb->width() : sb->height(); + + int extent = horizontal ? sb->height() : sb->width(); + + QColorGroup g = sb->colorGroup(); + + if (sliderStart > sliderMax) + sliderStart = sliderMax; + + int sliderEnd = sliderStart + sliderLength; + + int addX, addY; + int subX, subY; + int subPageX, subPageY, subPageW, subPageH; + int addPageX, addPageY, addPageW, addPageH; + int sliderX, sliderY, sliderW, sliderH; + + if (horizontal) + { + subY = 0; + addY = 0; + subX = 0; + addX = buttonDim; + + subPageX = buttonDim * 2; + subPageY = 0; + subPageW = sliderStart - 1; + subPageH = extent; + + addPageX = sliderEnd; + addPageY = 0; + addPageW = len - sliderEnd; + addPageH = extent; + + sliderX = sliderStart; + sliderY = 0; + sliderW = sliderLength; + sliderH = extent; + } + else + { + subX = 0; + addX = 0; + subY = len - buttonDim * 2; + addY = len - buttonDim; + + subPageX = 0; + subPageY = 0; + subPageW = extent; + subPageH = sliderStart; + + addPageX = 0; + addPageY = sliderEnd; + addPageW = extent; + addPageH = subY - sliderEnd; + + sliderX = 0; + sliderY = sliderStart; + sliderW = extent; + sliderH = sliderLength; + } + + rSub .setRect( subX, subY, buttonDim, buttonDim); + rAdd .setRect( addX, addY, buttonDim, buttonDim); + rSubPage .setRect(subPageX, subPageY, subPageW, subPageH); + rAddPage .setRect(addPageX, addPageY, addPageW, addPageH); + rSlider .setRect( sliderX, sliderY, sliderW, sliderH); +} + +// Rounded rects my way. + + static void +drawFunkyRect +( + QPainter * p, + int x, + int y, + int w, + int h, + bool small +) +{ + p->translate(x, y); + + if (small) + { + p->drawLine( 2, 0, w - 3, 0 ); + p->drawLine( w - 1, 2, w - 1, h - 3 ); + p->drawLine( w - 3, h - 1, 2, h - 1 ); + p->drawLine( 0, h - 3, 0, 2 ); + + // Use an array of points so that there's only one round-trip with the + // X server. + + QCOORD pointList[] = + { + 1, 1, + w - 2, 1, + w - 2, h - 2, + 1, h - 2 + }; + + p->drawPoints(QPointArray(4, pointList)); + } + else + { + p->drawLine( 3, 0, w - 4, 0 ); + p->drawLine( w - 1, 3, w - 1, h - 4 ); + p->drawLine( w - 4, h - 1, 3, h - 1 ); + p->drawLine( 0, h - 4, 0, 3 ); + + QCOORD pointList[] = + { + 1, 2, + 2, 1, + w - 3, 1, + w - 2, 2, + w - 2, h - 3, + w - 3, h - 2, + 2, h - 2, + 1, h - 3 + }; + + p->drawPoints(QPointArray(8, pointList)); + } + + p->translate(-x, -y); +} + +WebStyle::WebStyle() + : KStyle() +{ + setButtonDefaultIndicatorWidth(6); + setScrollBarExtent(_scrollBarExtent, _scrollBarExtent); +} + +WebStyle::~WebStyle() +{ + // Empty. +} + + void +WebStyle::polish(QApplication *) +{ + // Empty. +} + + void +WebStyle::polish(QPalette &) +{ + // Empty. +} + + void +WebStyle::unPolish(QApplication *) +{ + // Empty. +} + + void +WebStyle::polish(QWidget * w) +{ + if (w->inherits("QPushButton")) + w->installEventFilter(this); + + else if (w->inherits("QGroupBox") || w->inherits("QFrame")) + { + QFrame * f(static_cast<QFrame *>(w)); + + if (f->frameStyle() != QFrame::NoFrame) + { + _currentFrame = f; + + _savedFrameLineWidth = f->lineWidth(); + _savedFrameMidLineWidth = f->midLineWidth(); + _savedFrameStyle = f->frameStyle(); + + if (f->frameShape() == QFrame::HLine || f->frameShape() == QFrame::VLine) + { + f->setMidLineWidth(1); + f->setFrameStyle(f->frameShape() | QFrame::Plain); + } + else + { + f->setLineWidth(1); + f->setFrameStyle(QFrame::Box | QFrame::Plain); + } + } + } +} + + void +WebStyle::unPolish(QWidget * w) +{ + if (w->inherits("QPushButton")) + w->removeEventFilter(this); + + else if (w == _currentFrame) + { + QFrame * f(static_cast<QFrame *>(w)); + + f->setLineWidth(_savedFrameLineWidth); + f->setMidLineWidth(_savedFrameMidLineWidth); + f->setFrameStyle(_savedFrameStyle); + } +} + + bool +WebStyle::eventFilter(QObject * o, QEvent * e) +{ + QPushButton * pb(static_cast<QPushButton *>(o)); + + if (e->type() == QEvent::Enter) + { + _highlightedButton = pb; + pb->repaint(false); + } + else if (e->type() == QEvent::Leave) + { + _highlightedButton = 0; + pb->repaint(false); + } + + return false; +} + + void +WebStyle::drawButton +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + bool sunken, + const QBrush * fill +) +{ + p->save(); + + if (sunken) + p->setPen(contrastingForeground(g.light(), g.button())); + else + p->setPen(contrastingForeground(g.mid(), g.button())); + + p->setBrush(0 == fill ? NoBrush : *fill); + + drawFunkyRect(p, x, y, w, h, true); + + p->restore(); +} + + QRect +WebStyle::buttonRect(int x, int y, int w, int h) +{ + return QRect(x + 2, y + 2, w - 4, h - 4); +} + + void +WebStyle::drawBevelButton +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + bool sunken, + const QBrush * fill +) +{ + drawButton(p, x, y, w, h, g, sunken, fill); +} + + void +WebStyle::drawPushButton(QPushButton * b, QPainter * p) +{ + // Note: painter is already translated for us. + + bool sunken(b->isDown() || b->isOn()); + bool hl(_highlightedButton == b); + + QColor bg(b->colorGroup().button()); + + p->save(); + p->fillRect(b->rect(), b->colorGroup().brush(QColorGroup::Background)); + + if (b->isDefault()) + { + QColor c(hl ? b->colorGroup().highlight() : b->colorGroup().mid()); + + p->setPen(contrastingForeground(c, bg)); + + drawFunkyRect(p, 0, 0, b->width(), b->height(), false); + } + + p->fillRect + ( + 4, + 4, + b->width() - 8, + b->height() - 8, + b->colorGroup().brush(QColorGroup::Button) + ); + + if (b->isEnabled()) + { + if (sunken) + { + p->setPen(contrastingForeground(b->colorGroup().light(), bg)); + } + else + { + if (hl) + p->setPen(contrastingForeground(b->colorGroup().highlight(), bg)); + else + p->setPen(contrastingForeground(b->colorGroup().mid(), bg)); + } + } + else + { + p->setPen(b->colorGroup().button()); + } + + drawFunkyRect(p, 3, 3, b->width() - 6, b->height() - 6, true); + + p->restore(); +} + + void +WebStyle::drawPushButtonLabel(QPushButton * b, QPainter * p) +{ + // This is complicated stuff and we don't really want to mess with it. + + KStyle::drawPushButtonLabel(b, p); +} + + void +WebStyle::drawScrollBarControls +( + QPainter * p, + const QScrollBar * sb, + int sliderStart, + uint controls, + uint activeControl +) +{ + p->save(); + + int sliderMin, sliderMax, sliderLength, buttonDim; + + scrollBarMetrics(sb, sliderMin, sliderMax, sliderLength, buttonDim); + + QRect rSub, rAdd, rSubPage, rAddPage, rSlider; + + scrollBarControlsMetrics + ( + sb, + sliderStart, + sliderMin, + sliderMax, + sliderLength, + buttonDim, + rSub, + rAdd, + rSubPage, + rAddPage, + rSlider + ); + + QColorGroup g(sb->colorGroup()); + + if (controls & AddLine && rAdd.isValid()) + { + bool active(activeControl & AddLine); + + QColor c(active ? g.highlight() : g.dark()); + + p->setPen(c); + p->setBrush(g.button()); + p->drawRect(rAdd); + + Qt::ArrowType t = + sb->orientation() == Horizontal ? Qt::RightArrow : Qt::DownArrow; + + // Is it me or is KStyle::drawArrow broken ? + + drawArrow + ( + p, + t, + true, // FIXME - down ? + rAdd.x(), + rAdd.y(), + rAdd.width(), + rAdd.height(), + g, + true // FIXME - enabled ? + ); + } + + if (controls & SubLine && rSub.isValid()) + { + bool active(activeControl & SubLine); + + QColor c(active ? g.highlight() : g.dark()); + + p->setPen(c); + p->setBrush(g.button()); + p->drawRect(rSub); + + Qt::ArrowType t = + sb->orientation() == Horizontal ? Qt::LeftArrow : Qt::UpArrow; + + drawArrow + ( + p, + t, + true, // FIXME - down ? + rSub.x(), + rSub.y(), + rSub.width(), + rSub.height(), + g, + true // FIXME - enabled ? + ); + } + + if (controls & SubPage && rSubPage.isValid()) + { + p->setPen(g.mid()); + p->setBrush(g.base()); + p->drawRect(rSubPage); + } + + if (controls & AddPage && rAddPage.isValid()) + { + p->setPen(g.mid()); + p->setBrush(g.base()); + p->drawRect(rAddPage); + } + + if (controls & Slider && rSlider.isValid()) + { + p->setPen(activeControl & Slider ? g.highlight() : g.dark()); + + p->setBrush(g.button()); + p->drawRect(rSlider); + + p->setBrush(g.light()); + p->setPen(g.dark()); + + if (sliderLength > _scrollBarExtent * 2) + { + int ellipseSize = + Horizontal == sb->orientation() + ? + rSlider.height() - 4 + : + rSlider.width() - 4 + ; + + QPoint center(rSlider.center()); + + if (Horizontal == sb->orientation()) + { + p->drawEllipse + ( + center.x() - ellipseSize / 2, rSlider.y() + 2, + ellipseSize, ellipseSize + ); + } + else + { + p->drawEllipse + ( + rSlider.x() + 2, center.y() - ellipseSize / 2, + ellipseSize, ellipseSize + ); + } + } + } + + p->restore(); +} + + QStyle::ScrollControl +WebStyle::scrollBarPointOver +( + const QScrollBar * sb, + int sliderStart, + const QPoint & point +) +{ + if (!sb->rect().contains(point)) + return NoScroll; + + int sliderMin, sliderMax, sliderLength, buttonDim; + + scrollBarMetrics(sb, sliderMin, sliderMax, sliderLength, buttonDim); + + if (sb->orientation() == QScrollBar::Horizontal) + { + int x = point.x(); + + if (x <= buttonDim) + return SubLine; + + else if (x <= buttonDim * 2) + return AddLine; + + else if (x < sliderStart) + return SubPage; + + else if (x < sliderStart+sliderLength) + return Slider; + + return AddPage; + } + else + { + int y = point.y(); + + if (y < sliderStart) + return SubPage; + + else if (y < sliderStart + sliderLength) + return Slider; + + else if (y < sliderMax + sliderLength) + return AddPage; + + else if (y < sliderMax + sliderLength + buttonDim) + return SubLine; + + return AddLine; + } +} + + void +WebStyle::scrollBarMetrics +( + const QScrollBar * sb, + int & sliderMin, + int & sliderMax, + int & sliderLength, + int & buttonDim +) +{ + int maxlen; + + bool horizontal = sb->orientation() == QScrollBar::Horizontal; + + int len = (horizontal) ? sb->width() : sb->height(); + + int extent = (horizontal) ? sb->height() : sb->width(); + + if (len > (extent - 1) * 2) + buttonDim = extent; + else + buttonDim = len / 2 - 1; + + if (horizontal) + sliderMin = buttonDim * 2; + else + sliderMin = 1; + + maxlen = len - buttonDim * 2 - 1; + + sliderLength = + (sb->pageStep() * maxlen) / + (sb->maxValue() - sb->minValue() + sb->pageStep()); + + if (sliderLength < _scrollBarExtent) + sliderLength = _scrollBarExtent; + + if (sliderLength > maxlen) + sliderLength = maxlen; + + sliderMax = sliderMin + maxlen - sliderLength; +} + + QSize +WebStyle::indicatorSize() const +{ + return QSize(_indicatorSize, _indicatorSize); +} + + void +WebStyle::drawIndicator +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + int state, + bool down, + bool enabled +) +{ + p->save(); + + p->fillRect(x, y, w, h, g.background()); + + if (enabled) + { + p->setPen(down ? g.highlight() : contrastingForeground(g.dark(), g.background())); + } + else + { + g.mid(); + } + + p->drawRect(x, y, w, h); + + if (state != QButton::Off) + { + p->fillRect(x + 2, y + 2, w - 4, h - 4, enabled ? g.highlight() : g.mid()); + + if (state == QButton::NoChange) + { + p->fillRect(x + 4, y + 4, w - 8, h - 8, g.background()); + } + } + + p->restore(); +} + + QSize +WebStyle::exclusiveIndicatorSize() const +{ + return QSize(_indicatorSize, _indicatorSize); +} + + void +WebStyle::drawExclusiveIndicator +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + bool on, + bool down, + bool enabled +) +{ + p->save(); + + p->fillRect(x, y, w, h, g.background()); + + if (enabled) + { + p->setPen(down ? g.highlight() : contrastingForeground(g.dark(), g.background())); + } + else + { + p->setPen(g.mid()); + } + + p->setBrush(g.brush(QColorGroup::Background)); + + // Avoid misshapen ellipses. Qt or X bug ? Who knows... + + if (0 == w % 2) + --w; + + if (0 == h % 2) + --h; + + p->drawEllipse(x, y, w, h); + + if (on) + { + p->setPen(enabled ? g.highlight() : g.mid()); + p->setBrush(enabled ? g.highlight() : g.mid()); + p->drawEllipse(x + 3, y + 3, w - 6, h - 6); + } + + p->restore(); +} + + void +WebStyle::drawIndicatorMask +( + QPainter * p, + int x, + int y, + int w, + int h, + int /* state */ +) +{ + p->fillRect(x, y, w, h, Qt::color1); +} + + void +WebStyle::drawExclusiveIndicatorMask +( + QPainter * p, + int x, + int y, + int w, + int h, + bool /* on */ +) +{ + if (0 == w % 2) + --w; + + if (0 == h % 2) + --h; + + p->setPen(Qt::color1); + p->setBrush(Qt::color1); + p->drawEllipse(x, y, w, h); +} + + void +WebStyle::drawComboButton +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + bool sunken, + bool editable, + bool enabled, + const QBrush * fill +) +{ + p->save(); + + p->setPen(NoPen); + p->setBrush(0 == fill ? g.brush(QColorGroup::Background) : *fill); + p->drawRect(x, y, w, h); + + if (enabled) + { + if (sunken) + p->setPen(contrastingForeground(g.highlight(), g.background())); + else + p->setPen(contrastingForeground(g.mid(), g.background())); + } + else + { + p->setPen(contrastingForeground(g.mid(), g.background())); + } + + drawFunkyRect(p, x, y, w, h, true); + + p->drawPoint(w - 10, h - 6); + p->drawPoint(w - 9, h - 6); + p->drawPoint(w - 8, h - 6); + p->drawPoint(w - 7, h - 6); + p->drawPoint(w - 6, h - 6); + + p->drawPoint(w - 9, h - 7); + p->drawPoint(w - 8, h - 7); + p->drawPoint(w - 7, h - 7); + p->drawPoint(w - 6, h - 7); + + p->drawPoint(w - 8, h - 8); + p->drawPoint(w - 7, h - 8); + p->drawPoint(w - 6, h - 8); + + p->drawPoint(w - 7, h - 9); + p->drawPoint(w - 6, h - 9); + + p->drawPoint(w - 6, h - 10); + + if (editable) + p->fillRect(comboButtonFocusRect(x, y, w, h), Qt::red); + + p->restore(); +} + + QRect +WebStyle::comboButtonRect(int x, int y, int w, int h) +{ + return QRect(x + 2, y + 2, w - 20, h - 4); +} + + QRect +WebStyle::comboButtonFocusRect(int x, int y, int w, int h) +{ + return QRect(x + 2, y + 2, w - 20, h - 4); +} + + int +WebStyle::sliderLength() const +{ + return 13; +} + + void +WebStyle::drawSliderGroove +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + QCOORD /* c */, + Orientation o +) +{ + p->save(); + + p->setPen(QPen(g.dark(), 0, Qt::DotLine)); + + if( o == Qt::Horizontal ) + p->drawLine(x, y + h / 2, w, y + h / 2); + else + if( o == Qt::Vertical ) + p->drawLine(x + w / 2, y, x + w / 2, h); + + p->restore(); +} + + void +WebStyle::drawArrow +( + QPainter * p, + Qt::ArrowType type, + bool down, + int x, + int y, + int w, + int h, + const QColorGroup & g, + bool enabled, + const QBrush * fill +) +{ + KStyle::drawArrow(p, type, down, x, y, w, h, g, enabled, fill); +} + + void +WebStyle::drawSlider +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + Orientation o, + bool /* tickAbove */, + bool /* tickBelow */ +) +{ + p->save(); + + p->fillRect(x + 1, y + 1, w - 2, h - 2, g.background()); + p->setPen(g.dark()); + p->setBrush(g.light()); + + int sl = sliderLength(); + + if( o == Qt::Horizontal ) + p->drawEllipse(x, y + h / 2 - sl / 2, sl, sl); + else + if( o == Qt::Vertical ) + p->drawEllipse(x + w / 2 - sl / 2, y, sl, sl); + + p->restore(); +} + + void +WebStyle::drawKToolBar +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + KToolBarPos /* pos */, + QBrush * /* fill */ +) +{ + p->save(); + p->setPen(g.background()); + p->setBrush(g.background()); + p->drawRect(x, y, w, h); + p->restore(); +} + + void +WebStyle::drawKBarHandle +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + KToolBarPos /* pos */, + QBrush * /* fill */ +) +{ + p->save(); + p->setPen(g.mid()); + p->setBrush(g.background()); + p->drawRect(x + 1, y + 1, w - 2, h - 2); + p->restore(); +} + + void +WebStyle::drawKMenuBar +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + bool /* macMode */, + QBrush * /* fill */ +) +{ + p->save(); + p->setPen(g.mid()); + p->setBrush(g.background()); + p->drawRect(x, y, w, h); + p->restore(); +} + + void +WebStyle::drawKToolBarButton +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + bool sunken, + bool raised, + bool enabled, + bool popup, + KToolButtonType type, + const QString & btext, + const QPixmap * pixmap, + QFont * font, + QWidget * button +) +{ + bool toggleAndOn = false; + + if (button->inherits("QButton")) + { + QButton * b = static_cast<QButton *>(button); + toggleAndOn = b->isToggleButton() && b->isOn(); + } + + p->save(); + + QColor borderColour; + QColor textColour; + QColor fillColour; + + if (!enabled) + { + borderColour = g.background(); + fillColour = g.background(); + textColour = g.text(); + } + else + { + if (toggleAndOn) + { + borderColour = g.dark(); + fillColour = g.button(); + textColour = g.buttonText(); + } + else if (sunken) + { + borderColour = g.light(); + fillColour = g.button(); + textColour = g.buttonText(); + } + else if (raised) + { + borderColour = g.highlight(); + fillColour = g.background(); + textColour = g.text(); + } + else + { + borderColour = g.background(); + fillColour = g.background(); + textColour = g.text(); + } + } + + p->setPen(borderColour); + p->setBrush(fillColour); + + p->drawRect(x, y, w, h); + + p->setPen(g.background()); + + p->drawPoint(x, y); + p->drawPoint(x + w, y); + p->drawPoint(x, y + h); + p->drawPoint(x + w, y + h); + + switch (type) + { + case Icon: + + if (0 != pixmap) + p->drawPixmap + ( + x + (w - pixmap->width()) / 2, + y + (h - pixmap->height()) / 2, + *pixmap + ); + break; + + case Text: + + if (!btext.isNull()) + { + if (0 != font) + p->setFont(*font); + + p->setPen(textColour); + + p->drawText + ( + x, + y, + w, + h, + AlignCenter, + btext + ); + } + + break; + + case IconTextRight: + + if (0 != pixmap) + p->drawPixmap + ( + x + 2, + y + (h - pixmap->height()) / 2, + *pixmap + ); + + if (!btext.isNull()) + { + if (0 != font) + p->setFont(*font); + + p->setPen(textColour); + + if (0 != pixmap) + { + int textLeft = pixmap->width() + 4; + + p->drawText + ( + x + textLeft, + y, + w - textLeft, + h, + AlignVCenter | AlignLeft, + btext + ); + } + else + { + p->drawText + ( + x, + y, + w, + h, + AlignVCenter | AlignLeft, + btext + ); + } + } + break; + + case IconTextBottom: + + if (0 != pixmap) + p->drawPixmap + ( + x + (w - pixmap->width()) / 2, + y + 2, + *pixmap + ); + + if (!btext.isNull()) + { + if (0 != font) + p->setFont(*font); + + p->setPen(textColour); + + if (0 != pixmap) + { + int textTop = y + pixmap->height() + 4; + + p->drawText + ( + x + 2, + textTop, + w - 4, + h - x - textTop, + AlignCenter, + btext + ); + } + else + { + p->drawText + ( + x, + y, + w, + h, + AlignCenter, + btext + ); + } + } + break; + + default: + break; + } + + if (popup) + { + p->setPen(g.dark()); + for (int px = 0; px < 5; ++px) + for (int py = 0; py < 5 - px; ++py) + p->drawPoint(w - 6 - px, h - 6 - py); + } + + p->restore(); +} + + void +WebStyle::drawKMenuItem +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + bool active, + QMenuItem * mi, + QBrush * /* fill */ +) +{ + p->save(); + + QColor bg(active ? g.highlight() : g.background()); + + p->fillRect(x, y, w, h, bg); + + QColor textColour = + active ? + contrastingForeground(g.highlightedText(), bg) : + contrastingForeground(g.text(), bg); + + QApplication::style().drawItem + ( + p, + x, + y, + w, + h, + AlignCenter | ShowPrefix | DontClip | SingleLine, + g, + mi->isEnabled(), + mi->pixmap(), + mi->text(), + -1, + &textColour + ); + + p->restore(); +} + + void +WebStyle::drawPopupMenuItem +( + QPainter * p, + bool checkable, + int maxpmw, + int tab, + QMenuItem * mi, + const QPalette & pal, + bool act, + bool enabled, + int x, + int y, + int w, + int h +) +{ + // TODO + KStyle::drawPopupMenuItem(p, checkable, maxpmw, tab, mi, pal, act, enabled, x, y, w, h); +} + + void +WebStyle::drawKProgressBlock +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + QBrush * fill +) +{ + p->save(); + + p->setBrush(0 == fill ? NoBrush : *fill); + + p->fillRect(x, y, w, h, g.highlight()); + + p->restore(); +} + + void +WebStyle::drawFocusRect +( + QPainter * p, + const QRect & r, + const QColorGroup & g, + const QColor * pen, + bool atBorder +) +{ + p->save(); + + if (0 != pen) + p->setPen(0 == pen ? g.foreground() : *pen); + p->setBrush(NoBrush); + + if (atBorder) + { + p->drawRect(QRect(r.x() + 1, r.y() + 1, r.width() - 2, r.height() - 2)); + } + else + { + p->drawRect(r); + } + + p->restore(); +} + + void +WebStyle::drawPanel +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + bool /* sunken */, + int /* lineWidth */, + const QBrush * fill +) +{ + p->save(); + + p->setPen(g.dark()); + + p->setBrush(0 == fill ? NoBrush : *fill); + + p->drawRect(x, y, w, h); + + p->restore(); +} + + void +WebStyle::drawPopupPanel +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + int /* lineWidth */, + const QBrush * fill +) +{ + p->save(); + + p->setPen(g.dark()); + + p->setBrush(0 == fill ? NoBrush : *fill); + + p->drawRect(x, y, w, h); + + p->restore(); +} + + void +WebStyle::drawSeparator +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + bool /* sunken */, + int /* lineWidth */, + int /* midLineWidth */ +) +{ + p->save(); + + p->setPen(g.dark()); + + if (w > h) + { + p->drawLine(x, y + h / 2, x + w, y + h / 2); + } + else + { + p->drawLine(x + w / 2, y, x + w / 2, y + h); + } + + p->restore(); +} + + void +WebStyle::drawTab +( + QPainter * p, + const QTabBar * tabBar, + QTab * tab, + bool selected +) +{ + QRect r(tab->rect()); + + QColorGroup g(tabBar->colorGroup()); + + p->save(); + + p->setPen(selected ? g.dark() : g.mid()); + p->fillRect(r, g.brush(QColorGroup::Background)); + + switch (tabBar->shape()) + { + case QTabBar::RoundedAbove: + case QTabBar::TriangularAbove: + p->drawLine(r.left(), r.top(), r.left(), r.bottom()); + p->drawLine(r.left(), r.top(), r.right(), r.top()); + p->drawLine(r.right(), r.top(), r.right(), r.bottom()); + if (!selected) + { + p->setPen(g.dark()); + p->drawLine(r.left(), r.bottom(), r.right(), r.bottom()); + } + break; + case QTabBar::RoundedBelow: + case QTabBar::TriangularBelow: + if (!selected) + { + p->setPen(g.dark()); + p->drawLine(r.left(), r.top(), r.right(), r.top()); + } + p->drawLine(r.left(), r.top(), r.left(), r.bottom()); + p->drawLine(r.left(), r.bottom(), r.right(), r.bottom()); + p->drawLine(r.right(), r.top(), r.right(), r.bottom()); + break; + } + + p->restore(); +} + + void +WebStyle::drawTabMask +( + QPainter * p, + const QTabBar *, + QTab * tab, + bool +) +{ + p->fillRect(tab->rect(), Qt::color1); +} + + void +WebStyle::drawKickerHandle +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + QBrush * fill +) +{ + p->save(); + + p->setPen(g.mid()); + + p->setBrush(0 == fill ? NoBrush : *fill); + + p->drawRect(x, y, w, h); + + p->restore(); +} + + void +WebStyle::drawKickerAppletHandle +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + QBrush * fill +) +{ + p->save(); + + p->setPen(g.mid()); + + p->setBrush(0 == fill ? NoBrush : *fill); + + p->drawRect(x, y, w, h); + + p->restore(); +} + + void +WebStyle::drawKickerTaskButton +( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + const QString & text, + bool active, + QPixmap * icon, + QBrush * /* fill */ +) +{ + p->save(); + + QColor bg; + + if (active) + { + p->setPen(g.light()); + bg = g.highlight(); + } + else + { + p->setPen(g.mid()); + bg = g.button(); + } + + p->setBrush(bg); + + p->drawRect(x, y, w, h); + + if (text.isEmpty() && 0 == icon) + { + p->restore(); + return; + } + + const int pxWidth = 20; + + int textPos = pxWidth; + + QRect br(buttonRect(x, y, w, h)); + + if ((0 != icon) && !icon->isNull()) + { + int dx = (pxWidth - icon->width()) / 2; + int dy = (h - icon->height()) / 2; + + p->drawPixmap(br.x() + dx, dy, *icon); + } + + QString s(text); + + static QString modStr = + QString::fromUtf8("[") + i18n("modified") + QString::fromUtf8("]"); + + int modStrPos = s.find(modStr); + + if (-1 != modStrPos) + { + // +1 because we include a space after the closing brace. + s.remove(modStrPos, modStr.length() + 1); + + QPixmap modPixmap = SmallIcon("modified"); + + int dx = (pxWidth - modPixmap.width()) / 2; + int dy = (h - modPixmap.height()) / 2; + + p->drawPixmap(br.x() + textPos + dx, dy, modPixmap); + + textPos += pxWidth; + } + + if (!s.isEmpty()) + { + if (p->fontMetrics().width(s) > br.width() - textPos) + { + int maxLen = br.width() - textPos - p->fontMetrics().width("..."); + + while ((!s.isEmpty()) && (p->fontMetrics().width(s) > maxLen)) + s.truncate(s.length() - 1); + + s.append("..."); + } + + if (active) + { + p->setPen(contrastingForeground(g.buttonText(), bg)); + } + else + { + p->setPen(contrastingForeground(g.text(), bg)); + } + + p->setPen(Qt::white); + + p->drawText + ( + br.x() + textPos, + -1, + w - textPos, + h, + AlignLeft | AlignVCenter, + s + ); + } + + p->restore(); + p->setPen(Qt::white); +} + + int +WebStyle::popupMenuItemHeight(bool, QMenuItem * i, const QFontMetrics & fm) +{ + if (i->isSeparator()) + return 1; + + int h = 0; + + if (0 != i->pixmap()) + { + h = i->pixmap()->height(); + } + + if (0 != i->iconSet()) + { + h = QMAX + ( + i->iconSet()->pixmap(QIconSet::Small, QIconSet::Normal).height(), + h + ); + } + + h = QMAX(fm.height() + 4, h); + + h = QMAX(18, h); + + return h; + +} + diff --git a/kstyles/web/webstyle.h b/kstyles/web/webstyle.h new file mode 100644 index 000000000..b0a6a7a87 --- /dev/null +++ b/kstyles/web/webstyle.h @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2001 Rik Hemsley (rikkus) <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WEB_STYLE_H +#define WEB_STYLE_H + +#include <kstyle.h> +#include <qpalette.h> + +class QPainter; +class QScrollBar; +class QPushButton; +class QWidget; + +class WebStyle : public KStyle +{ + public: + + WebStyle(); + + ~WebStyle(); + + void polish(QApplication *); + + void unPolish(QWidget *); + + void polish(QWidget *); + + void polish(QPalette &); + + void unPolish(QApplication *); + + void drawButton + ( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + bool sunken = false, + const QBrush * fill = 0 + ); + + QRect buttonRect(int x, int y, int w, int h); + + void drawBevelButton + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + bool sunken = false, + const QBrush * fill = 0 + ); + + void drawPushButton(QPushButton *, QPainter *); + + virtual void drawPushButtonLabel(QPushButton *, QPainter *); + + void drawScrollBarControls + ( + QPainter *, + const QScrollBar *, + int sliderStart, + uint controls, + uint activeControl + ); + + QStyle::ScrollControl scrollBarPointOver + ( + const QScrollBar *, + int sliderStart, + const QPoint & + ); + + void scrollBarMetrics + ( + const QScrollBar *, + int & sliderMin, + int & sliderMax, + int & sliderLength, + int & buttonDim + ); + + QSize indicatorSize() const; + + void drawIndicator + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + int state, + bool down = false, + bool enabled = true + ); + + QSize exclusiveIndicatorSize() const; + + void drawExclusiveIndicator + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + bool on, + bool down = false, + bool enabled = true + ); + + void drawIndicatorMask + ( + QPainter *, + int x, + int y, + int w, + int h, + int state + ); + + void drawExclusiveIndicatorMask + ( + QPainter *, + int x, + int y, + int w, + int h, + bool on + ); + + void drawComboButton + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + bool sunken = false, + bool editable = false, + bool enabled = true, + const QBrush * fill = 0 + ); + + QRect comboButtonRect(int x, int y, int w, int h); + + QRect comboButtonFocusRect(int x, int y, int w, int h); + + int sliderLength() const; + + void drawSliderGroove + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + QCOORD, + Orientation + ); + + void drawArrow + ( + QPainter *, + Qt::ArrowType, + bool down, + int x, + int y, + int w, + int h, + const QColorGroup &, + bool enabled = true, + const QBrush * fill = 0 + ); + + void drawSlider + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + Orientation, + bool tickAbove, + bool tickBelow + ); + + void drawKToolBar + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + KToolBarPos, + QBrush * fill = 0 + ); + + void drawKBarHandle + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + KToolBarPos, + QBrush * fill = 0 + ); + + void drawKMenuBar + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + bool macMode, + QBrush * fill = 0 + ); + + void drawKToolBarButton + ( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + bool sunken = false, + bool raised = true, + bool enabled = true, + bool popup = false, + KToolButtonType = Icon, + const QString & btext = QString::null, + const QPixmap * = 0, + QFont * = 0, + QWidget * button = 0 + ); + + void drawKMenuItem + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + bool active, + QMenuItem *, + QBrush * fill = 0 + ); + + void drawPopupMenuItem + ( + QPainter *, + bool checkable, + int maxpmw, + int tab, + QMenuItem *, + const QPalette &, + bool act, + bool enabled, + int x, + int y, + int w, + int h + ); + + void drawKProgressBlock + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + QBrush * fill + ); + + void drawFocusRect + ( + QPainter *, + const QRect &, + const QColorGroup &, + const QColor * pen, + bool atBorder + ); + + void drawPanel + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + bool sunken, + int lineWidth = 1, + const QBrush * = 0 + ); + + void drawPopupPanel + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + int lineWidth = 2, + const QBrush * = 0 + ); + + void drawSeparator + ( + QPainter *, + int x, + int y, + int w, + int h, + const QColorGroup &, + bool sunken = true, + int lineWidth = 1, + int midLineWidth = 0 + ); + + void drawTab + ( + QPainter * p, + const QTabBar * tabBar, + QTab * tab, + bool selected + ); + + void drawTabMask + ( + QPainter * p, + const QTabBar *, + QTab * tab, + bool + ); + + void drawKickerHandle + ( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + QBrush * + ); + + void drawKickerAppletHandle + ( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + QBrush * + ); + + void drawKickerTaskButton + ( + QPainter * p, + int x, + int y, + int w, + int h, + const QColorGroup & g, + const QString & title, + bool active, + QPixmap * icon, + QBrush * + ); + + int popupMenuItemHeight(bool, QMenuItem *, const QFontMetrics &); + + GUIStyle guiStyle() const { return Qt::MotifStyle; } + + bool eventFilter(QObject *, QEvent *); +}; + +#endif |