/*
*
* KStyle
* Copyright ( C ) 2001 - 2002 Karol Szwed < gallium @ kde . org >
*
* TQWindowsStyle CC_ListView and style images were kindly donated by TrollTech ,
* Copyright ( C ) 1998 - 2000 TrollTech AS .
*
* 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 .
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "kstyle.h"
# include <tqapplication.h>
# include <tqbitmap.h>
# include <tqmetaobject.h>
# include <tqcleanuphandler.h>
# include <tqmap.h>
# include <tqimage.h>
# include <tqlistview.h>
# include <tqmenubar.h>
# include <tqpainter.h>
# include <tqpixmap.h>
# include <tqpopupmenu.h>
# include <tqprogressbar.h>
# include <tqscrollbar.h>
# include <tqsettings.h>
# include <tqslider.h>
# include <tqstylefactory.h>
# include <tqtabbar.h>
# include <tqtoolbar.h>
# include <tqframe.h>
# include <kpixmap.h>
# include <kpixmapeffect.h>
# include <kimageeffect.h>
# ifdef Q_WS_X11
# include <X11 / Xlib.h>
# ifdef HAVE_XRENDER
# include <X11 / extensions / Xrender.h> // schroder
extern bool qt_use_xrender ;
# endif
# else
# undef HAVE_XRENDER
# endif
# ifdef HAVE_XCOMPOSITE
# include <X11/extensions/Xrender.h>
# include <X11/extensions/Xcomposite.h>
# include <dlfcn.h>
# endif
# include <limits.h>
namespace
{
// INTERNAL
enum TransparencyEngine {
Disabled = 0 ,
SoftwareTint ,
SoftwareBlend ,
XRender
} ;
// Drop Shadow
struct ShadowElements {
TQWidget * w1 ;
TQWidget * w2 ;
} ;
typedef TQMap < const TQWidget * , ShadowElements > ShadowMap ;
static ShadowMap * _shadowMap = 0 ;
TQSingleCleanupHandler < ShadowMap > cleanupShadowMap ;
ShadowMap & shadowMap ( ) {
if ( ! _shadowMap ) {
_shadowMap = new ShadowMap ;
cleanupShadowMap . set ( & _shadowMap ) ;
}
return * _shadowMap ;
}
// DO NOT ASK ME HOW I MADE THESE TABLES!
// (I probably won't remember anyway ;)
const double top_right_corner [ 16 ] =
{ 0.949 , 0.965 , 0.980 , 0.992 ,
0.851 , 0.890 , 0.945 , 0.980 ,
0.706 , 0.780 , 0.890 , 0.960 ,
0.608 , 0.706 , 0.851 , 0.949 } ;
const double bottom_right_corner [ 16 ] =
{ 0.608 , 0.706 , 0.851 , 0.949 ,
0.706 , 0.780 , 0.890 , 0.960 ,
0.851 , 0.890 , 0.945 , 0.980 ,
0.949 , 0.965 , 0.980 , 0.992 } ;
const double bottom_left_corner [ 16 ] =
{ 0.949 , 0.851 , 0.706 , 0.608 ,
0.965 , 0.890 , 0.780 , 0.706 ,
0.980 , 0.945 , 0.890 , 0.851 ,
0.992 , 0.980 , 0.960 , 0.949 } ;
const double shadow_strip [ 4 ] =
{ 0.565 , 0.675 , 0.835 , 0.945 } ;
static bool useDropShadow ( TQWidget * w )
{
return w & & w - > metaObject ( ) & &
w - > metaObject ( ) - > findProperty ( " KStyleMenuDropShadow " ) ! = - 1 ;
}
}
namespace
{
class TransparencyHandler : public TQObject
{
public :
TransparencyHandler ( KStyle * style , TransparencyEngine tEngine ,
float menuOpacity , bool useDropShadow ) ;
~ TransparencyHandler ( ) ;
bool eventFilter ( TQObject * object , TQEvent * event ) ;
protected :
void blendToColor ( const TQColor & col ) ;
void blendToPixmap ( const TQColorGroup & cg , const TQWidget * p ) ;
# ifdef HAVE_XRENDER
void XRenderBlendToPixmap ( const TQWidget * p ) ;
# endif
bool haveX11RGBASupport ( ) ;
TQImage handleRealAlpha ( TQImage ) ;
void createShadowWindows ( const TQWidget * p ) ;
void removeShadowWindows ( const TQWidget * p ) ;
void rightShadow ( TQImage & dst ) ;
void bottomShadow ( TQImage & dst ) ;
private :
bool dropShadow ;
float opacity ;
TQPixmap pix ;
KStyle * kstyle ;
TransparencyEngine te ;
} ;
} // namespace
struct KStylePrivate
{
bool highcolor : 1 ;
bool useFilledFrameWorkaround : 1 ;
bool etchDisabledText : 1 ;
bool scrollablePopupmenus : 1 ;
bool menuAltKeyNavigation : 1 ;
bool menuDropShadow : 1 ;
bool sloppySubMenus : 1 ;
bool semiTransparentRubberband : 1 ;
int popupMenuDelay ;
float menuOpacity ;
TransparencyEngine transparencyEngine ;
KStyle : : KStyleScrollBarType scrollbarType ;
TransparencyHandler * menuHandler ;
KStyle : : KStyleFlags flags ;
//For KPE_ListViewBranch
TQBitmap * verticalLine ;
TQBitmap * horizontalLine ;
} ;
// -----------------------------------------------------------------------------
KStyle : : KStyle ( KStyleFlags flags , KStyleScrollBarType sbtype )
: TQCommonStyle ( ) , d ( new KStylePrivate )
{
d - > flags = flags ;
bool useMenuTransparency = ( flags & AllowMenuTransparency ) ;
d - > useFilledFrameWorkaround = ( flags & FilledFrameWorkaround ) ;
d - > scrollbarType = sbtype ;
d - > highcolor = TQPixmap : : defaultDepth ( ) > 8 ;
// Read style settings
TQSettings settings ;
d - > popupMenuDelay = settings . readNumEntry ( " /KStyle/Settings/PopupMenuDelay " , 256 ) ;
d - > sloppySubMenus = settings . readBoolEntry ( " /KStyle/Settings/SloppySubMenus " , false ) ;
d - > etchDisabledText = settings . readBoolEntry ( " /KStyle/Settings/EtchDisabledText " , true ) ;
d - > menuAltKeyNavigation = settings . readBoolEntry ( " /KStyle/Settings/MenuAltKeyNavigation " , true ) ;
d - > scrollablePopupmenus = settings . readBoolEntry ( " /KStyle/Settings/ScrollablePopupMenus " , false ) ;
d - > menuDropShadow = settings . readBoolEntry ( " /KStyle/Settings/MenuDropShadow " , false ) ;
d - > semiTransparentRubberband = settings . readBoolEntry ( " /KStyle/Settings/SemiTransparentRubberband " , false ) ;
d - > menuHandler = NULL ;
if ( useMenuTransparency ) {
TQString effectEngine = settings . readEntry ( " /KStyle/Settings/MenuTransparencyEngine " , " Disabled " ) ;
# ifdef HAVE_XRENDER
if ( effectEngine = = " XRender " )
d - > transparencyEngine = XRender ;
# else
if ( effectEngine = = " XRender " )
d - > transparencyEngine = SoftwareBlend ;
# endif
else if ( effectEngine = = " SoftwareBlend " )
d - > transparencyEngine = SoftwareBlend ;
else if ( effectEngine = = " SoftwareTint " )
d - > transparencyEngine = SoftwareTint ;
else
d - > transparencyEngine = Disabled ;
if ( d - > transparencyEngine ! = Disabled ) {
// Create an instance of the menu transparency handler
d - > menuOpacity = settings . readDoubleEntry ( " /KStyle/Settings/MenuOpacity " , 0.90 ) ;
d - > menuHandler = new TransparencyHandler ( this , d - > transparencyEngine ,
d - > menuOpacity , d - > menuDropShadow ) ;
}
}
d - > verticalLine = 0 ;
d - > horizontalLine = 0 ;
// Create a transparency handler if only drop shadows are enabled.
if ( ! d - > menuHandler & & d - > menuDropShadow )
d - > menuHandler = new TransparencyHandler ( this , Disabled , 1.0 , d - > menuDropShadow ) ;
}
KStyle : : ~ KStyle ( )
{
delete d - > verticalLine ;
delete d - > horizontalLine ;
delete d - > menuHandler ;
d - > menuHandler = NULL ;
delete d ;
}
TQString KStyle : : defaultStyle ( )
{
if ( TQPixmap : : defaultDepth ( ) > 8 )
return TQString ( " plastik " ) ;
else
return TQString ( " light, 3rd revision " ) ;
}
void KStyle : : polish ( TQWidget * widget )
{
if ( d - > useFilledFrameWorkaround )
{
if ( TQFrame * frame = : : tqqt_cast < TQFrame * > ( widget ) ) {
TQFrame : : Shape shape = frame - > frameShape ( ) ;
if ( shape = = TQFrame : : ToolBarPanel | | shape = = TQFrame : : MenuBarPanel )
widget - > installEventFilter ( this ) ;
}
}
if ( widget - > isTopLevel ( ) )
{
if ( ! d - > menuHandler & & useDropShadow ( widget ) )
d - > menuHandler = new TransparencyHandler ( this , Disabled , 1.0 , false ) ;
if ( d - > menuHandler & & useDropShadow ( widget ) )
widget - > installEventFilter ( d - > menuHandler ) ;
}
}
void KStyle : : unPolish ( TQWidget * widget )
{
if ( d - > useFilledFrameWorkaround )
{
if ( TQFrame * frame = : : tqqt_cast < TQFrame * > ( widget ) ) {
TQFrame : : Shape shape = frame - > frameShape ( ) ;
if ( shape = = TQFrame : : ToolBarPanel | | shape = = TQFrame : : MenuBarPanel )
widget - > removeEventFilter ( this ) ;
}
}
if ( widget - > isTopLevel ( ) & & d - > menuHandler & & useDropShadow ( widget ) )
widget - > removeEventFilter ( d - > menuHandler ) ;
}
// Style changes (should) always re-polish popups.
void KStyle : : polishPopupMenu ( TQPopupMenu * p )
{
if ( ! p - > testWState ( WState_Polished ) )
p - > setCheckable ( true ) ;
// Install transparency handler if the effect is enabled.
if ( d - > menuHandler & &
( strcmp ( p - > name ( ) , " tear off menu " ) ! = 0 ) )
p - > installEventFilter ( d - > menuHandler ) ;
}
// -----------------------------------------------------------------------------
// KStyle extensions
// -----------------------------------------------------------------------------
void KStyle : : setScrollBarType ( KStyleScrollBarType sbtype )
{
d - > scrollbarType = sbtype ;
}
KStyle : : KStyleFlags KStyle : : styleFlags ( ) const
{
return d - > flags ;
}
void KStyle : : renderMenuBlendPixmap ( KPixmap & pix , const TQColorGroup & cg ,
const TQPopupMenu * /* popup */ ) const
{
pix . fill ( cg . button ( ) ) ; // Just tint as the default behavior
}
void KStyle : : drawKStylePrimitive ( KStylePrimitive kpe ,
TQPainter * p ,
const TQWidget * widget ,
const TQRect & r ,
const TQColorGroup & cg ,
SFlags flags ,
const TQStyleOption & /* opt */ ) const
{
switch ( kpe )
{
// Dock / Toolbar / General handles.
// ---------------------------------
case KPE_DockWindowHandle : {
// Draws a nice DockWindow handle including the dock title.
TQWidget * wid = const_cast < TQWidget * > ( widget ) ;
bool horizontal = flags & Style_Horizontal ;
int x , y , w , h , x2 , y2 ;
r . rect ( & x , & y , & w , & h ) ;
if ( ( w < = 2 ) | | ( h < = 2 ) ) {
p - > fillRect ( r , cg . highlight ( ) ) ;
return ;
}
x2 = x + w - 1 ;
y2 = y + h - 1 ;
TQFont fnt ;
fnt = TQApplication : : font ( wid ) ;
fnt . setPointSize ( fnt . pointSize ( ) - 2 ) ;
// Draw the item on an off-screen pixmap
// to preserve Xft antialiasing for
// vertically oriented handles.
TQPixmap pix ;
if ( horizontal )
pix . resize ( h - 2 , w - 2 ) ;
else
pix . resize ( w - 2 , h - 2 ) ;
TQString title = wid - > parentWidget ( ) - > caption ( ) ;
TQPainter p2 ;
p2 . begin ( & pix ) ;
p2 . fillRect ( pix . rect ( ) , cg . brush ( TQColorGroup : : Highlight ) ) ;
p2 . setPen ( cg . highlightedText ( ) ) ;
p2 . setFont ( fnt ) ;
p2 . drawText ( pix . rect ( ) , AlignCenter , title ) ;
p2 . end ( ) ;
// Draw a sunken bevel
p - > setPen ( cg . dark ( ) ) ;
p - > drawLine ( x , y , x2 , y ) ;
p - > drawLine ( x , y , x , y2 ) ;
p - > setPen ( cg . light ( ) ) ;
p - > drawLine ( x + 1 , y2 , x2 , y2 ) ;
p - > drawLine ( x2 , y + 1 , x2 , y2 ) ;
if ( horizontal ) {
TQWMatrix m ;
m . rotate ( - 90.0 ) ;
TQPixmap vpix = pix . xForm ( m ) ;
bitBlt ( wid , r . x ( ) + 1 , r . y ( ) + 1 , & vpix ) ;
} else
bitBlt ( wid , r . x ( ) + 1 , r . y ( ) + 1 , & pix ) ;
break ;
}
/*
* KPE_ListViewExpander and KPE_ListViewBranch are based on code from
* QWindowStyle ' s CC_ListView , kindly donated by TrollTech .
* CC_ListView code is Copyright ( C ) 1998 - 2000 TrollTech AS .
*/
case KPE_ListViewExpander : {
// Typical Windows style expand/collapse element.
int radius = ( r . width ( ) - 4 ) / 2 ;
int centerx = r . x ( ) + r . width ( ) / 2 ;
int centery = r . y ( ) + r . height ( ) / 2 ;
// Outer box
p - > setPen ( cg . mid ( ) ) ;
p - > drawRect ( r ) ;
// plus or minus
p - > setPen ( cg . text ( ) ) ;
p - > drawLine ( centerx - radius , centery , centerx + radius , centery ) ;
if ( flags & Style_On ) // Collapsed = On
p - > drawLine ( centerx , centery - radius , centerx , centery + radius ) ;
break ;
}
case KPE_ListViewBranch : {
// Typical Windows style listview branch element (dotted line).
// Create the dotline pixmaps if not already created
if ( ! d - > verticalLine )
{
// make 128*1 and 1*128 bitmaps that can be used for
// drawing the right sort of lines.
d - > verticalLine = new TQBitmap ( 1 , 129 , true ) ;
d - > horizontalLine = new TQBitmap ( 128 , 1 , true ) ;
TQPointArray a ( 64 ) ;
TQPainter p2 ;
p2 . begin ( d - > verticalLine ) ;
int i ;
for ( i = 0 ; i < 64 ; i + + )
a . setPoint ( i , 0 , i * 2 + 1 ) ;
p2 . setPen ( color1 ) ;
p2 . drawPoints ( a ) ;
p2 . end ( ) ;
TQApplication : : flushX ( ) ;
d - > verticalLine - > setMask ( * d - > verticalLine ) ;
p2 . begin ( d - > horizontalLine ) ;
for ( i = 0 ; i < 64 ; i + + )
a . setPoint ( i , i * 2 + 1 , 0 ) ;
p2 . setPen ( color1 ) ;
p2 . drawPoints ( a ) ;
p2 . end ( ) ;
TQApplication : : flushX ( ) ;
d - > horizontalLine - > setMask ( * d - > horizontalLine ) ;
}
p - > setPen ( cg . text ( ) ) ; // cg.dark() is bad for dark color schemes.
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 , * d - > 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 , * d - > verticalLine , 0 , pixmapoffset , thickness , i ) ;
point + = i ;
}
}
break ;
}
// Reimplement the other primitives in your styles.
// The current implementation just paints something visibly different.
case KPE_ToolBarHandle :
case KPE_GeneralHandle :
case KPE_SliderHandle :
p - > fillRect ( r , cg . light ( ) ) ;
break ;
case KPE_SliderGroove :
p - > fillRect ( r , cg . dark ( ) ) ;
break ;
default :
p - > fillRect ( r , Qt : : yellow ) ; // Something really bad happened - highlight.
break ;
}
}
int KStyle : : kPixelMetric ( KStylePixelMetric kpm , const TQWidget * /* widget */ ) const
{
int value ;
switch ( kpm )
{
case KPM_ListViewBranchThickness :
value = 1 ;
break ;
case KPM_MenuItemSeparatorHeight :
case KPM_MenuItemHMargin :
case KPM_MenuItemVMargin :
case KPM_MenuItemHFrame :
case KPM_MenuItemVFrame :
case KPM_MenuItemCheckMarkHMargin :
case KPM_MenuItemArrowHMargin :
case KPM_MenuItemTabSpacing :
default :
value = 0 ;
}
return value ;
}
// -----------------------------------------------------------------------------
// #ifdef USE_QT4 // kdebindings / smoke needs this function declaration available at all times. Furthermore I don't think it would hurt to have the declaration available at all times...so leave these commented out for now
//void KStyle::tqdrawPrimitive( TQ_ControlElement pe,
// TQPainter* p,
// const TQRect &r,
// const TQColorGroup &cg,
// SFlags flags,
// const TQStyleOption& opt ) const
//{
// // FIXME:
// // What should "widget" be in actuality? How should I get it? From where?
// // Almost certainly it should not be null!
// TQWidget *widget = 0;
// drawControl(pe, p, widget, r, cg, flags, opt);
//}
// #endif // USE_QT4
// -----------------------------------------------------------------------------
void KStyle : : tqdrawPrimitive ( TQ_PrimitiveElement pe ,
TQPainter * p ,
const TQRect & r ,
const TQColorGroup & cg ,
SFlags flags ,
const TQStyleOption & opt ) const
{
// TOOLBAR/DOCK WINDOW HANDLE
// ------------------------------------------------------------------------
if ( pe = = PE_DockWindowHandle )
{
// Wild workarounds are here. Beware.
TQWidget * widget , * parent ;
if ( p & & p - > device ( ) - > devType ( ) = = TQInternal : : Widget ) {
widget = static_cast < TQWidget * > ( p - > device ( ) ) ;
parent = widget - > parentWidget ( ) ;
} else
return ; // Don't paint on non-widgets
// Check if we are a normal toolbar or a hidden dockwidget.
if ( parent & &
( parent - > inherits ( TQTOOLBAR_OBJECT_NAME_STRING ) | | // Normal toolbar
( parent - > inherits ( TQMAINWINDOW_OBJECT_NAME_STRING ) ) ) ) // Collapsed dock
// Draw a toolbar handle
drawKStylePrimitive ( KPE_ToolBarHandle , p , widget , r , cg , flags , opt ) ;
else if ( widget - > inherits ( TQDOCKWINDOWHANDLE_OBJECT_NAME_STRING ) )
// Draw a dock window handle
drawKStylePrimitive ( KPE_DockWindowHandle , p , widget , r , cg , flags , opt ) ;
else
// General handle, probably a kicker applet handle.
drawKStylePrimitive ( KPE_GeneralHandle , p , widget , r , cg , flags , opt ) ;
# if QT_VERSION >= 0x030300
# ifdef HAVE_XRENDER
} else if ( d - > semiTransparentRubberband & & pe = = TQStyle : : PE_RubberBand ) {
TQRect rect = r . normalize ( ) ;
TQPoint point ;
point = p - > xForm ( point ) ;
static XRenderColor clr = { 0 , 0 , 0 , 0 } ;
static unsigned long fillColor = 0 ;
if ( fillColor ! = cg . highlight ( ) . rgb ( ) ) {
fillColor = cg . highlight ( ) . rgb ( ) ;
unsigned long color = fillColor < < 8 | 0x40 ;
int red = ( color > > 24 ) & 0xff ;
int green = ( color > > 16 ) & 0xff ;
int blue = ( color > > 8 ) & 0xff ;
int alpha = ( color > > 0 ) & 0xff ;
red = red * alpha / 255 ;
green = green * alpha / 255 ;
blue = blue * alpha / 255 ;
clr . red = ( red < < 8 ) + red ;
clr . green = ( green < < 8 ) + green ;
clr . blue = ( blue < < 8 ) + blue ;
clr . alpha = ( alpha < < 8 ) + alpha ;
}
XRenderFillRectangle (
p - > device ( ) - > x11Display ( ) ,
PictOpOver ,
p - > device ( ) - > x11RenderHandle ( ) ,
& clr ,
rect . x ( ) + point . x ( ) ,
rect . y ( ) + point . y ( ) ,
rect . width ( ) ,
rect . height ( ) ) ;
p - > save ( ) ;
p - > setRasterOp ( TQt : : CopyROP ) ;
p - > setPen ( TQPen ( cg . highlight ( ) . dark ( 160 ) , 1 ) ) ;
p - > setBrush ( NoBrush ) ;
p - > drawRect (
rect . x ( ) + point . x ( ) ,
rect . y ( ) + point . y ( ) ,
rect . width ( ) ,
rect . height ( ) ) ;
p - > restore ( ) ;
# endif
# endif
} else
TQCommonStyle : : tqdrawPrimitive ( pe , p , r , cg , flags , opt ) ;
}
void KStyle : : drawControl ( TQ_ControlElement element ,
TQPainter * p ,
const TQWidget * widget ,
const TQRect & r ,
const TQColorGroup & cg ,
SFlags flags ,
const TQStyleOption & opt ) const
{
switch ( element )
{
// TABS
// ------------------------------------------------------------------------
case CE_TabBarTab : {
const TQTabBar * tb = ( const TQTabBar * ) widget ;
TQTabBar : : Shape tbs = tb - > shape ( ) ;
bool selected = flags & Style_Selected ;
int x = r . x ( ) , y = r . y ( ) , bottom = r . bottom ( ) , right = r . right ( ) ;
switch ( tbs ) {
case TQTabBar : : RoundedAbove : {
if ( ! selected )
p - > translate ( 0 , 1 ) ;
p - > setPen ( selected ? cg . light ( ) : cg . shadow ( ) ) ;
p - > drawLine ( x , y + 4 , x , bottom ) ;
p - > drawLine ( x , y + 4 , x + 4 , y ) ;
p - > drawLine ( x + 4 , y , right - 1 , y ) ;
if ( selected )
p - > setPen ( cg . shadow ( ) ) ;
p - > drawLine ( right , y + 1 , right , bottom ) ;
p - > setPen ( cg . midlight ( ) ) ;
p - > drawLine ( x + 1 , y + 4 , x + 1 , bottom ) ;
p - > drawLine ( x + 1 , y + 4 , x + 4 , y + 1 ) ;
p - > drawLine ( x + 5 , y + 1 , right - 2 , y + 1 ) ;
if ( selected ) {
p - > setPen ( cg . mid ( ) ) ;
p - > drawLine ( right - 1 , y + 1 , right - 1 , bottom ) ;
} else {
p - > setPen ( cg . mid ( ) ) ;
p - > drawPoint ( right - 1 , y + 1 ) ;
p - > drawLine ( x + 4 , y + 2 , right - 1 , y + 2 ) ;
p - > drawLine ( x + 3 , y + 3 , right - 1 , y + 3 ) ;
p - > fillRect ( x + 2 , y + 4 , r . width ( ) - 3 , r . height ( ) - 6 , cg . mid ( ) ) ;
p - > setPen ( cg . light ( ) ) ;
p - > drawLine ( x , bottom - 1 , right , bottom - 1 ) ;
p - > translate ( 0 , - 1 ) ;
}
break ;
}
case TQTabBar : : RoundedBelow : {
if ( ! selected )
p - > translate ( 0 , - 1 ) ;
p - > setPen ( selected ? cg . light ( ) : cg . shadow ( ) ) ;
p - > drawLine ( x , bottom - 4 , x , y ) ;
if ( selected )
p - > setPen ( cg . mid ( ) ) ;
p - > drawLine ( x , bottom - 4 , x + 4 , bottom ) ;
if ( selected )
p - > setPen ( cg . shadow ( ) ) ;
p - > drawLine ( x + 4 , bottom , right - 1 , bottom ) ;
p - > drawLine ( right , bottom - 1 , right , y ) ;
p - > setPen ( cg . midlight ( ) ) ;
p - > drawLine ( x + 1 , bottom - 4 , x + 1 , y ) ;
p - > drawLine ( x + 1 , bottom - 4 , x + 4 , bottom - 1 ) ;
p - > drawLine ( x + 5 , bottom - 1 , right - 2 , bottom - 1 ) ;
if ( selected ) {
p - > setPen ( cg . mid ( ) ) ;
p - > drawLine ( right - 1 , y , right - 1 , bottom - 1 ) ;
} else {
p - > setPen ( cg . mid ( ) ) ;
p - > drawPoint ( right - 1 , bottom - 1 ) ;
p - > drawLine ( x + 4 , bottom - 2 , right - 1 , bottom - 2 ) ;
p - > drawLine ( x + 3 , bottom - 3 , right - 1 , bottom - 3 ) ;
p - > fillRect ( x + 2 , y + 2 , r . width ( ) - 3 , r . height ( ) - 6 , cg . mid ( ) ) ;
p - > translate ( 0 , 1 ) ;
p - > setPen ( cg . dark ( ) ) ;
p - > drawLine ( x , y , right , y ) ;
}
break ;
}
case TQTabBar : : TriangularAbove : {
if ( ! selected )
p - > translate ( 0 , 1 ) ;
p - > setPen ( selected ? cg . light ( ) : cg . shadow ( ) ) ;
p - > drawLine ( x , bottom , x , y + 6 ) ;
p - > drawLine ( x , y + 6 , x + 6 , y ) ;
p - > drawLine ( x + 6 , y , right - 6 , y ) ;
if ( selected )
p - > setPen ( cg . mid ( ) ) ;
p - > drawLine ( right - 5 , y + 1 , right - 1 , y + 5 ) ;
p - > setPen ( cg . shadow ( ) ) ;
p - > drawLine ( right , y + 6 , right , bottom ) ;
p - > setPen ( cg . midlight ( ) ) ;
p - > drawLine ( x + 1 , bottom , x + 1 , y + 6 ) ;
p - > drawLine ( x + 1 , y + 6 , x + 6 , y + 1 ) ;
p - > drawLine ( x + 6 , y + 1 , right - 6 , y + 1 ) ;
p - > drawLine ( right - 5 , y + 2 , right - 2 , y + 5 ) ;
p - > setPen ( cg . mid ( ) ) ;
p - > drawLine ( right - 1 , y + 6 , right - 1 , bottom ) ;
TQPointArray a ( 6 ) ;
a . setPoint ( 0 , x + 2 , bottom ) ;
a . setPoint ( 1 , x + 2 , y + 7 ) ;
a . setPoint ( 2 , x + 7 , y + 2 ) ;
a . setPoint ( 3 , right - 7 , y + 2 ) ;
a . setPoint ( 4 , right - 2 , y + 7 ) ;
a . setPoint ( 5 , right - 2 , bottom ) ;
p - > setPen ( selected ? cg . background ( ) : cg . mid ( ) ) ;
p - > setBrush ( selected ? cg . background ( ) : cg . mid ( ) ) ;
p - > drawPolygon ( a ) ;
p - > setBrush ( NoBrush ) ;
if ( ! selected ) {
p - > translate ( 0 , - 1 ) ;
p - > setPen ( cg . light ( ) ) ;
p - > drawLine ( x , bottom , right , bottom ) ;
}
break ;
}
default : { // TQTabBar::TriangularBelow
if ( ! selected )
p - > translate ( 0 , - 1 ) ;
p - > setPen ( selected ? cg . light ( ) : cg . shadow ( ) ) ;
p - > drawLine ( x , y , x , bottom - 6 ) ;
if ( selected )
p - > setPen ( cg . mid ( ) ) ;
p - > drawLine ( x , bottom - 6 , x + 6 , bottom ) ;
if ( selected )
p - > setPen ( cg . shadow ( ) ) ;
p - > drawLine ( x + 6 , bottom , right - 6 , bottom ) ;
p - > drawLine ( right - 5 , bottom - 1 , right - 1 , bottom - 5 ) ;
if ( ! selected )
p - > setPen ( cg . shadow ( ) ) ;
p - > drawLine ( right , bottom - 6 , right , y ) ;
p - > setPen ( cg . midlight ( ) ) ;
p - > drawLine ( x + 1 , y , x + 1 , bottom - 6 ) ;
p - > drawLine ( x + 1 , bottom - 6 , x + 6 , bottom - 1 ) ;
p - > drawLine ( x + 6 , bottom - 1 , right - 6 , bottom - 1 ) ;
p - > drawLine ( right - 5 , bottom - 2 , right - 2 , bottom - 5 ) ;
p - > setPen ( cg . mid ( ) ) ;
p - > drawLine ( right - 1 , bottom - 6 , right - 1 , y ) ;
TQPointArray a ( 6 ) ;
a . setPoint ( 0 , x + 2 , y ) ;
a . setPoint ( 1 , x + 2 , bottom - 7 ) ;
a . setPoint ( 2 , x + 7 , bottom - 2 ) ;
a . setPoint ( 3 , right - 7 , bottom - 2 ) ;
a . setPoint ( 4 , right - 2 , bottom - 7 ) ;
a . setPoint ( 5 , right - 2 , y ) ;
p - > setPen ( selected ? cg . background ( ) : cg . mid ( ) ) ;
p - > setBrush ( selected ? cg . background ( ) : cg . mid ( ) ) ;
p - > drawPolygon ( a ) ;
p - > setBrush ( NoBrush ) ;
if ( ! selected ) {
p - > translate ( 0 , 1 ) ;
p - > setPen ( cg . dark ( ) ) ;
p - > drawLine ( x , y , right , y ) ;
}
break ;
}
} ;
break ;
}
// Popup menu scroller
// ------------------------------------------------------------------------
case CE_PopupMenuScroller : {
p - > fillRect ( r , cg . background ( ) ) ;
tqdrawPrimitive ( PE_ButtonTool , p , r , cg , Style_Enabled ) ;
tqdrawPrimitive ( ( flags & Style_Up ) ? PE_ArrowUp : PE_ArrowDown , p , r , cg , Style_Enabled ) ;
break ;
}
// PROGRESSBAR
// ------------------------------------------------------------------------
case CE_ProgressBarGroove : {
TQRect fr = subRect ( SR_ProgressBarGroove , widget ) ;
tqdrawPrimitive ( PE_Panel , p , fr , cg , Style_Sunken , TQStyleOption : : SO_Default ) ;
break ;
}
case CE_ProgressBarContents : {
// ### Take into account totalSteps() for busy indicator
const TQProgressBar * pb = ( const TQProgressBar * ) widget ;
TQRect cr = subRect ( SR_ProgressBarContents , widget ) ;
double progress = pb - > progress ( ) ;
bool reverse = TQApplication : : 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 ) { //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 ) ;
}
if ( reverse )
p - > fillRect ( cr . x ( ) + cr . width ( ) - width - pstep , cr . y ( ) , width , cr . height ( ) ,
cg . brush ( TQColorGroup : : Highlight ) ) ;
else
p - > fillRect ( cr . x ( ) + pstep , cr . y ( ) , width , cr . height ( ) ,
cg . brush ( TQColorGroup : : Highlight ) ) ;
return ;
}
// Do fancy gradient for highcolor displays
if ( d - > highcolor ) {
TQColor c ( cg . highlight ( ) ) ;
KPixmap pix ;
pix . resize ( cr . width ( ) , cr . height ( ) ) ;
KPixmapEffect : : gradient ( pix , reverse ? c . light ( 150 ) : c . dark ( 150 ) ,
reverse ? c . dark ( 150 ) : c . light ( 150 ) ,
KPixmapEffect : : HorizontalGradient ) ;
if ( reverse )
p - > drawPixmap ( cr . x ( ) + ( cr . width ( ) - width ) , cr . y ( ) , pix ,
cr . width ( ) - width , 0 , width , cr . height ( ) ) ;
else
p - > drawPixmap ( cr . x ( ) , cr . y ( ) , pix , 0 , 0 , width , cr . height ( ) ) ;
} else
if ( reverse )
p - > fillRect ( cr . x ( ) + ( cr . width ( ) - width ) , cr . y ( ) , width , cr . height ( ) ,
cg . brush ( TQColorGroup : : Highlight ) ) ;
else
p - > fillRect ( cr . x ( ) , cr . y ( ) , width , cr . height ( ) ,
cg . brush ( TQColorGroup : : Highlight ) ) ;
}
break ;
}
case CE_ProgressBarLabel : {
const TQProgressBar * pb = ( const TQProgressBar * ) widget ;
TQRect cr = subRect ( SR_ProgressBarContents , widget ) ;
double progress = pb - > progress ( ) ;
bool reverse = TQApplication : : reverseLayout ( ) ;
int steps = pb - > totalSteps ( ) ;
if ( ! cr . isValid ( ) )
return ;
TQFont font = p - > font ( ) ;
font . setBold ( true ) ;
p - > setFont ( font ) ;
// Draw label
if ( progress > 0 | | steps = = 0 ) {
double pg = ( steps = = 0 ) ? 1.0 : progress / steps ;
int width = QMIN ( cr . width ( ) , ( int ) ( pg * cr . width ( ) ) ) ;
TQRect crect ;
if ( reverse )
crect . setRect ( cr . x ( ) + ( cr . width ( ) - width ) , cr . y ( ) , cr . width ( ) , cr . height ( ) ) ;
else
crect . setRect ( cr . x ( ) + width , cr . y ( ) , cr . width ( ) , cr . height ( ) ) ;
p - > save ( ) ;
p - > setPen ( pb - > isEnabled ( ) ? ( reverse ? cg . text ( ) : cg . highlightedText ( ) ) : cg . text ( ) ) ;
p - > drawText ( r , AlignCenter , pb - > progressString ( ) ) ;
p - > setClipRect ( crect ) ;
p - > setPen ( reverse ? cg . highlightedText ( ) : cg . text ( ) ) ;
p - > drawText ( r , AlignCenter , pb - > progressString ( ) ) ;
p - > restore ( ) ;
} else {
p - > setPen ( cg . text ( ) ) ;
p - > drawText ( r , AlignCenter , pb - > progressString ( ) ) ;
}
break ;
}
default :
TQCommonStyle : : drawControl ( element , p , widget , r , cg , flags , opt ) ;
}
}
TQRect KStyle : : subRect ( SubRect r , const TQWidget * widget ) const
{
switch ( r )
{
// KDE2 look smooth progress bar
// ------------------------------------------------------------------------
case SR_ProgressBarGroove :
return widget - > rect ( ) ;
case SR_ProgressBarContents :
case SR_ProgressBarLabel : {
// ### take into account indicatorFollowsStyle()
TQRect rt = widget - > rect ( ) ;
return TQRect ( rt . x ( ) + 2 , rt . y ( ) + 2 , rt . width ( ) - 4 , rt . height ( ) - 4 ) ;
}
default :
return TQCommonStyle : : subRect ( r , widget ) ;
}
}
int KStyle : : pixelMetric ( PixelMetric m , const TQWidget * widget ) const
{
switch ( m )
{
// BUTTONS
// ------------------------------------------------------------------------
case PM_ButtonShiftHorizontal : // Offset by 1
case PM_ButtonShiftVertical : // ### Make configurable
return 1 ;
case PM_DockWindowHandleExtent :
{
TQWidget * parent = 0 ;
// Check that we are not a normal toolbar or a hidden dockwidget,
// in which case we need to adjust the height for font size
if ( widget & & ( parent = widget - > parentWidget ( ) )
& & ! parent - > inherits ( TQTOOLBAR_OBJECT_NAME_STRING )
& & ! parent - > inherits ( TQMAINWINDOW_OBJECT_NAME_STRING )
& & widget - > inherits ( TQDOCKWINDOWHANDLE_OBJECT_NAME_STRING ) )
return widget - > fontMetrics ( ) . lineSpacing ( ) ;
else
return TQCommonStyle : : pixelMetric ( m , widget ) ;
}
// TABS
// ------------------------------------------------------------------------
case PM_TabBarTabHSpace :
return 24 ;
case PM_TabBarTabVSpace : {
const TQTabBar * tb = ( const TQTabBar * ) widget ;
if ( tb - > shape ( ) = = TQTabBar : : RoundedAbove | |
tb - > shape ( ) = = TQTabBar : : RoundedBelow )
return 10 ;
else
return 4 ;
}
case PM_TabBarTabOverlap : {
const TQTabBar * tb = ( const TQTabBar * ) widget ;
TQTabBar : : Shape tbs = tb - > shape ( ) ;
if ( ( tbs = = TQTabBar : : RoundedAbove ) | |
( tbs = = TQTabBar : : RoundedBelow ) )
return 0 ;
else
return 2 ;
}
// SLIDER
// ------------------------------------------------------------------------
case PM_SliderLength :
return 18 ;
case PM_SliderThickness :
return 24 ;
// Determines how much space to leave for the actual non-tickmark
// portion of the slider.
case PM_SliderControlThickness : {
const TQSlider * slider = ( const TQSlider * ) widget ;
TQSlider : : TickSetting ts = slider - > tickmarks ( ) ;
int thickness = ( slider - > orientation ( ) = = Qt : : Horizontal ) ?
slider - > height ( ) : slider - > width ( ) ;
switch ( ts ) {
case TQSlider : : NoMarks : // Use total area.
break ;
case TQSlider : : Both :
thickness = ( thickness / 2 ) + 3 ; // Use approx. 1/2 of area.
break ;
default : // Use approx. 2/3 of area
thickness = ( ( thickness * 2 ) / 3 ) + 3 ;
break ;
} ;
return thickness ;
}
// SPLITTER
// ------------------------------------------------------------------------
case PM_SplitterWidth :
if ( widget & & widget - > inherits ( " QDockWindowResizeHandle " ) )
return 8 ; // ### why do we need 2pix extra?
else
return 6 ;
// FRAMES
// ------------------------------------------------------------------------
case PM_MenuBarFrameWidth :
return 1 ;
case PM_DockWindowFrameWidth :
return 1 ;
// GENERAL
// ------------------------------------------------------------------------
case PM_MaximumDragDistance :
return - 1 ;
case PM_MenuBarItemSpacing :
return 5 ;
case PM_ToolBarItemSpacing :
return 0 ;
case PM_PopupMenuScrollerHeight :
return pixelMetric ( PM_ScrollBarExtent , 0 ) ;
default :
return TQCommonStyle : : pixelMetric ( m , widget ) ;
}
}
//Helper to find the next sibling that's not hidden
static TQListViewItem * nextVisibleSibling ( TQListViewItem * item )
{
TQListViewItem * sibling = item ;
do
{
sibling = sibling - > nextSibling ( ) ;
}
while ( sibling & & ! sibling - > isVisible ( ) ) ;
return sibling ;
}
void KStyle : : drawComplexControl ( TQ_ComplexControl control ,
TQPainter * p ,
const TQWidget * widget ,
const TQRect & r ,
const TQColorGroup & cg ,
SFlags flags ,
SCFlags controls ,
SCFlags active ,
const TQStyleOption & opt ) const
{
switch ( control )
{
// 3 BUTTON SCROLLBAR
// ------------------------------------------------------------------------
case CC_ScrollBar : {
// Many thanks to Brad Hughes for contributing this code.
bool useThreeButtonScrollBar = ( d - > scrollbarType & ThreeButtonScrollBar ) ;
const TQScrollBar * sb = ( const TQScrollBar * ) 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 ) ) ;
TQRect addline , subline , subline2 , addpage , subpage , slider , first , last ;
subline = querySubControlMetrics ( control , widget , SC_ScrollBarSubLine , opt ) ;
addline = querySubControlMetrics ( control , widget , SC_ScrollBarAddLine , opt ) ;
subpage = querySubControlMetrics ( control , widget , SC_ScrollBarSubPage , opt ) ;
addpage = querySubControlMetrics ( control , widget , SC_ScrollBarAddPage , opt ) ;
slider = querySubControlMetrics ( control , widget , SC_ScrollBarSlider , opt ) ;
first = querySubControlMetrics ( control , widget , SC_ScrollBarFirst , opt ) ;
last = querySubControlMetrics ( control , widget , SC_ScrollBarLast , opt ) ;
subline2 = addline ;
if ( useThreeButtonScrollBar )
if ( horizontal )
subline2 . moveBy ( - addline . width ( ) , 0 ) ;
else
subline2 . moveBy ( 0 , - addline . height ( ) ) ;
// Draw the up/left button set
if ( ( controls & SC_ScrollBarSubLine ) & & subline . isValid ( ) ) {
tqdrawPrimitive ( PE_ScrollBarSubLine , p , subline , cg ,
sflags | ( active = = SC_ScrollBarSubLine ?
Style_Down : Style_Default ) ) ;
if ( useThreeButtonScrollBar & & subline2 . isValid ( ) )
tqdrawPrimitive ( PE_ScrollBarSubLine , p , subline2 , cg ,
sflags | ( active = = SC_ScrollBarSubLine ?
Style_Down : Style_Default ) ) ;
}
if ( ( controls & SC_ScrollBarAddLine ) & & addline . isValid ( ) )
tqdrawPrimitive ( PE_ScrollBarAddLine , p , addline , cg ,
sflags | ( ( active = = SC_ScrollBarAddLine ) ?
Style_Down : Style_Default ) ) ;
if ( ( controls & SC_ScrollBarSubPage ) & & subpage . isValid ( ) )
tqdrawPrimitive ( PE_ScrollBarSubPage , p , subpage , cg ,
sflags | ( ( active = = SC_ScrollBarSubPage ) ?
Style_Down : Style_Default ) ) ;
if ( ( controls & SC_ScrollBarAddPage ) & & addpage . isValid ( ) )
tqdrawPrimitive ( PE_ScrollBarAddPage , p , addpage , cg ,
sflags | ( ( active = = SC_ScrollBarAddPage ) ?
Style_Down : Style_Default ) ) ;
if ( ( controls & SC_ScrollBarFirst ) & & first . isValid ( ) )
tqdrawPrimitive ( PE_ScrollBarFirst , p , first , cg ,
sflags | ( ( active = = SC_ScrollBarFirst ) ?
Style_Down : Style_Default ) ) ;
if ( ( controls & SC_ScrollBarLast ) & & last . isValid ( ) )
tqdrawPrimitive ( PE_ScrollBarLast , p , last , cg ,
sflags | ( ( active = = SC_ScrollBarLast ) ?
Style_Down : Style_Default ) ) ;
if ( ( controls & SC_ScrollBarSlider ) & & slider . isValid ( ) ) {
tqdrawPrimitive ( PE_ScrollBarSlider , p , slider , cg ,
sflags | ( ( active = = SC_ScrollBarSlider ) ?
Style_Down : Style_Default ) ) ;
// Draw focus rect
if ( sb - > hasFocus ( ) ) {
TQRect fr ( slider . x ( ) + 2 , slider . y ( ) + 2 ,
slider . width ( ) - 5 , slider . height ( ) - 5 ) ;
tqdrawPrimitive ( PE_FocusRect , p , fr , cg , Style_Default ) ;
}
}
break ;
}
// SLIDER
// -------------------------------------------------------------------
case CC_Slider : {
const TQSlider * slider = ( const TQSlider * ) widget ;
TQRect groove = querySubControlMetrics ( CC_Slider , widget , SC_SliderGroove , opt ) ;
TQRect handle = querySubControlMetrics ( CC_Slider , widget , SC_SliderHandle , opt ) ;
// Double-buffer slider for no flicker
TQPixmap pix ( widget - > size ( ) ) ;
TQPainter p2 ;
p2 . begin ( & pix ) ;
if ( slider - > parentWidget ( ) & &
slider - > parentWidget ( ) - > backgroundPixmap ( ) & &
! slider - > parentWidget ( ) - > backgroundPixmap ( ) - > isNull ( ) ) {
TQPixmap pixmap = * ( slider - > parentWidget ( ) - > backgroundPixmap ( ) ) ;
p2 . drawTiledPixmap ( r , pixmap , slider - > pos ( ) ) ;
} else
pix . fill ( cg . background ( ) ) ;
// Draw slider groove
if ( ( controls & SC_SliderGroove ) & & groove . isValid ( ) ) {
drawKStylePrimitive ( KPE_SliderGroove , & p2 , widget , groove , cg , flags , opt ) ;
// Draw the focus rect around the groove
if ( slider - > hasFocus ( ) )
tqdrawPrimitive ( PE_FocusRect , & p2 , groove , cg ) ;
}
// Draw the tickmarks
if ( controls & SC_SliderTickmarks )
TQCommonStyle : : drawComplexControl ( control , & p2 , widget ,
r , cg , flags , SC_SliderTickmarks , active , opt ) ;
// Draw the slider handle
if ( ( controls & SC_SliderHandle ) & & handle . isValid ( ) ) {
if ( active = = SC_SliderHandle )
flags | = Style_Active ;
drawKStylePrimitive ( KPE_SliderHandle , & p2 , widget , handle , cg , flags , opt ) ;
}
p2 . end ( ) ;
bitBlt ( ( TQWidget * ) widget , r . x ( ) , r . y ( ) , & pix ) ;
break ;
}
// LISTVIEW
// -------------------------------------------------------------------
case CC_ListView : {
/*
* Many thanks to TrollTech AS for donating CC_ListView from TQWindowsStyle .
* CC_ListView code is Copyright ( C ) 1998 - 2000 TrollTech AS .
*/
// Paint the icon and text.
if ( controls & SC_ListView )
TQCommonStyle : : 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 ;
TQListViewItem * item = opt . listViewItem ( ) ;
TQListViewItem * child = item - > firstChild ( ) ;
int y = r . y ( ) ;
int c ; // dotline vertice count
int dotoffset = 0 ;
TQPointArray dotlines ;
if ( active = = SC_All & & controls = = SC_ListViewExpand ) {
// We only need to draw a vertical line
c = 2 ;
dotlines . resize ( 2 ) ;
dotlines [ 0 ] = TQPoint ( r . right ( ) , r . top ( ) ) ;
dotlines [ 1 ] = TQPoint ( 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
TQListView * v = item - > listView ( ) ;
int lh = QMAX ( p - > fontMetrics ( ) . height ( ) + 2 * v - > itemMargin ( ) ,
TQApplication : : globalStrut ( ) . height ( ) ) ;
if ( lh % 2 > 0 )
lh + + ;
// Draw all the expand/close boxes...
TQRect boxrect ;
TQStyle : : StyleFlags boxflags ;
while ( child & & y < r . height ( ) )
{
linebot = y + lh / 2 ;
if ( ( child - > isExpandable ( ) | | child - > childCount ( ) ) & &
( child - > height ( ) > 0 ) )
{
// The primitive requires a rect.
boxrect = TQRect ( bx - 4 , linebot - 4 , 9 , 9 ) ;
boxflags = child - > isOpen ( ) ? TQStyle : : Style_Off : TQStyle : : 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 + + ] = TQPoint ( bx , linetop ) ;
dotlines [ c + + ] = TQPoint ( bx , linebot - 5 ) ;
dotlines [ c + + ] = TQPoint ( bx + 5 , linebot ) ;
dotlines [ c + + ] = TQPoint ( r . width ( ) , linebot ) ;
linetop = linebot + 5 ;
} else {
// just dotlinery
dotlines [ c + + ] = TQPoint ( bx + 1 , linebot ) ;
dotlines [ c + + ] = TQPoint ( 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 + + ] = TQPoint ( bx , linetop ) ;
dotlines [ c + + ] = TQPoint ( bx , linebot ) ;
}
}
// Draw all the branches...
static int thickness = kPixelMetric ( KPM_ListViewBranchThickness ) ;
int line ; // index into dotlines
TQRect branchrect ;
TQStyle : : 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 = TQRect ( point , other - ( thickness / 2 ) , end - point , thickness ) ;
branchflags = TQStyle : : 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 = TQRect ( other - ( thickness / 2 ) , point , thickness , end - point ) ;
if ( ! pixmapoffset ) // ### Hackish - used to hint the offset
branchflags = TQStyle : : Style_NoChange ;
else
branchflags = TQStyle : : Style_Default ;
// KStyle extension: Draw the vertical branch
drawKStylePrimitive ( KPE_ListViewBranch , p , NULL , branchrect , cg , branchflags , opt ) ;
}
}
}
break ;
}
default :
TQCommonStyle : : drawComplexControl ( control , p , widget , r , cg ,
flags , controls , active , opt ) ;
break ;
}
}
TQStyle : : SubControl KStyle : : querySubControl ( TQ_ComplexControl control ,
const TQWidget * widget ,
const TQPoint & pos ,
const TQStyleOption & opt ) const
{
TQStyle : : SubControl ret = TQCommonStyle : : querySubControl ( control , widget , pos , opt ) ;
if ( d - > scrollbarType = = ThreeButtonScrollBar ) {
// Enable third button
if ( control = = CC_ScrollBar & & ret = = SC_None )
ret = SC_ScrollBarSubLine ;
}
return ret ;
}
TQRect KStyle : : querySubControlMetrics ( TQ_ComplexControl control ,
const TQWidget * widget ,
SubControl sc ,
const TQStyleOption & opt ) const
{
TQRect ret ;
if ( control = = CC_ScrollBar )
{
bool threeButtonScrollBar = d - > scrollbarType & ThreeButtonScrollBar ;
bool platinumScrollBar = d - > scrollbarType & PlatinumStyleScrollBar ;
bool nextScrollBar = d - > scrollbarType & NextStyleScrollBar ;
const TQScrollBar * sb = ( const TQScrollBar * ) widget ;
bool horizontal = sb - > orientation ( ) = = Qt : : Horizontal ;
int sliderstart = sb - > sliderStart ( ) ;
int sbextent = pixelMetric ( PM_ScrollBarExtent , widget ) ;
int maxlen = ( horizontal ? sb - > width ( ) : sb - > height ( ) )
- ( sbextent * ( threeButtonScrollBar ? 3 : 2 ) ) ;
int sliderlen ;
// calculate slider length
if ( sb - > maxValue ( ) ! = sb - > minValue ( ) )
{
uint range = sb - > maxValue ( ) - sb - > minValue ( ) ;
sliderlen = ( sb - > pageStep ( ) * maxlen ) / ( range + sb - > pageStep ( ) ) ;
int slidermin = pixelMetric ( PM_ScrollBarSliderMin , widget ) ;
if ( sliderlen < slidermin | | range > INT_MAX / 2 )
sliderlen = slidermin ;
if ( sliderlen > maxlen )
sliderlen = maxlen ;
} else
sliderlen = maxlen ;
// Subcontrols
switch ( sc )
{
case SC_ScrollBarSubLine : {
// top/left button
if ( platinumScrollBar ) {
if ( horizontal )
ret . setRect ( sb - > width ( ) - 2 * sbextent , 0 , sbextent , sbextent ) ;
else
ret . setRect ( 0 , sb - > height ( ) - 2 * sbextent , sbextent , sbextent ) ;
} else
ret . setRect ( 0 , 0 , sbextent , sbextent ) ;
break ;
}
case SC_ScrollBarAddLine : {
// bottom/right button
if ( nextScrollBar ) {
if ( horizontal )
ret . setRect ( sbextent , 0 , sbextent , sbextent ) ;
else
ret . setRect ( 0 , sbextent , sbextent , sbextent ) ;
} else {
if ( horizontal )
ret . setRect ( sb - > width ( ) - sbextent , 0 , sbextent , sbextent ) ;
else
ret . setRect ( 0 , sb - > height ( ) - sbextent , sbextent , sbextent ) ;
}
break ;
}
case SC_ScrollBarSubPage : {
// between top/left button and slider
if ( platinumScrollBar ) {
if ( horizontal )
ret . setRect ( 0 , 0 , sliderstart , sbextent ) ;
else
ret . setRect ( 0 , 0 , sbextent , sliderstart ) ;
} else if ( nextScrollBar ) {
if ( horizontal )
ret . setRect ( sbextent * 2 , 0 , sliderstart - 2 * sbextent , sbextent ) ;
else
ret . setRect ( 0 , sbextent * 2 , sbextent , sliderstart - 2 * sbextent ) ;
} else {
if ( 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
int fudge ;
if ( platinumScrollBar )
fudge = 0 ;
else if ( nextScrollBar )
fudge = 2 * sbextent ;
else
fudge = sbextent ;
if ( horizontal )
ret . setRect ( sliderstart + sliderlen , 0 ,
maxlen - sliderstart - sliderlen + fudge , sbextent ) ;
else
ret . setRect ( 0 , sliderstart + sliderlen , sbextent ,
maxlen - sliderstart - sliderlen + fudge ) ;
break ;
}
case SC_ScrollBarGroove : {
int multi = threeButtonScrollBar ? 3 : 2 ;
int fudge ;
if ( platinumScrollBar )
fudge = 0 ;
else if ( nextScrollBar )
fudge = 2 * sbextent ;
else
fudge = sbextent ;
if ( horizontal )
ret . setRect ( fudge , 0 , sb - > width ( ) - sbextent * multi , sb - > height ( ) ) ;
else
ret . setRect ( 0 , fudge , sb - > width ( ) , sb - > height ( ) - sbextent * multi ) ;
break ;
}
case SC_ScrollBarSlider : {
if ( horizontal )
ret . setRect ( sliderstart , 0 , sliderlen , sbextent ) ;
else
ret . setRect ( 0 , sliderstart , sbextent , sliderlen ) ;
break ;
}
default :
ret = TQCommonStyle : : querySubControlMetrics ( control , widget , sc , opt ) ;
break ;
}
} else
ret = TQCommonStyle : : querySubControlMetrics ( control , widget , sc , opt ) ;
return ret ;
}
static const char * const kstyle_close_xpm [ ] = {
" 12 12 2 1 " ,
" # c #000000 " ,
" . c None " ,
" ............ " ,
" ............ " ,
" ..##....##.. " ,
" ...##..##... " ,
" ....####.... " ,
" .....##..... " ,
" ....####.... " ,
" ...##..##... " ,
" ..##....##.. " ,
" ............ " ,
" ............ " ,
" ............ " } ;
static const char * const kstyle_maximize_xpm [ ] = {
" 12 12 2 1 " ,
" # c #000000 " ,
" . c None " ,
" ............ " ,
" ............ " ,
" .##########. " ,
" .##########. " ,
" .#........#. " ,
" .#........#. " ,
" .#........#. " ,
" .#........#. " ,
" .#........#. " ,
" .#........#. " ,
" .##########. " ,
" ............ " } ;
static const char * const kstyle_minimize_xpm [ ] = {
" 12 12 2 1 " ,
" # c #000000 " ,
" . c None " ,
" ............ " ,
" ............ " ,
" ............ " ,
" ............ " ,
" ............ " ,
" ............ " ,
" ............ " ,
" ...######... " ,
" ...######... " ,
" ............ " ,
" ............ " ,
" ............ " } ;
static const char * const kstyle_normalizeup_xpm [ ] = {
" 12 12 2 1 " ,
" # c #000000 " ,
" . c None " ,
" ............ " ,
" ...#######.. " ,
" ...#######.. " ,
" ...#.....#.. " ,
" .#######.#.. " ,
" .#######.#.. " ,
" .#.....#.#.. " ,
" .#.....###.. " ,
" .#.....#.... " ,
" .#.....#.... " ,
" .#######.... " ,
" ............ " } ;
static const char * const kstyle_shade_xpm [ ] = {
" 12 12 2 1 " ,
" # c #000000 " ,
" . c None " ,
" ............ " ,
" ............ " ,
" ............ " ,
" ............ " ,
" ............ " ,
" .....#...... " ,
" ....###..... " ,
" ...#####.... " ,
" ..#######... " ,
" ............ " ,
" ............ " ,
" ............ " } ;
static const char * const kstyle_unshade_xpm [ ] = {
" 12 12 2 1 " ,
" # c #000000 " ,
" . c None " ,
" ............ " ,
" ............ " ,
" ............ " ,
" ............ " ,
" ..#######... " ,
" ...#####.... " ,
" ....###..... " ,
" .....#...... " ,
" ............ " ,
" ............ " ,
" ............ " ,
" ............ " } ;
static const char * const dock_window_close_xpm [ ] = {
" 8 8 2 1 " ,
" # c #000000 " ,
" . c None " ,
" ##....## " ,
" .##..##. " ,
" ..####.. " ,
" ...##... " ,
" ..####.. " ,
" .##..##. " ,
" ##....## " ,
" ........ " } ;
// Message box icons, from page 210 of the Windows style guide.
// Hand-drawn to resemble Microsoft's icons, but in the Mac/Netscape
// palette. The "question mark" icon, which Microsoft recommends not
// using but a lot of people still use, is left out.
/* XPM */
static const char * const information_xpm [ ] = {
" 32 32 5 1 " ,
" . c None " ,
" c c #000000 " ,
" * c #999999 " ,
" a c #ffffff " ,
" b c #0000ff " ,
" ...........********............. " ,
" ........***aaaaaaaa***.......... " ,
" ......**aaaaaaaaaaaaaa**........ " ,
" .....*aaaaaaaaaaaaaaaaaa*....... " ,
" ....*aaaaaaaabbbbaaaaaaaac...... " ,
" ...*aaaaaaaabbbbbbaaaaaaaac..... " ,
" ..*aaaaaaaaabbbbbbaaaaaaaaac.... " ,
" .*aaaaaaaaaaabbbbaaaaaaaaaaac... " ,
" .*aaaaaaaaaaaaaaaaaaaaaaaaaac*.. " ,
" *aaaaaaaaaaaaaaaaaaaaaaaaaaaac*. " ,
" *aaaaaaaaaabbbbbbbaaaaaaaaaaac*. " ,
" *aaaaaaaaaaaabbbbbaaaaaaaaaaac** " ,
" *aaaaaaaaaaaabbbbbaaaaaaaaaaac** " ,
" *aaaaaaaaaaaabbbbbaaaaaaaaaaac** " ,
" *aaaaaaaaaaaabbbbbaaaaaaaaaaac** " ,
" *aaaaaaaaaaaabbbbbaaaaaaaaaaac** " ,
" .*aaaaaaaaaaabbbbbaaaaaaaaaac*** " ,
" .*aaaaaaaaaaabbbbbaaaaaaaaaac*** " ,
" ..*aaaaaaaaaabbbbbaaaaaaaaac***. " ,
" ...caaaaaaabbbbbbbbbaaaaaac****. " ,
" ....caaaaaaaaaaaaaaaaaaaac****.. " ,
" .....caaaaaaaaaaaaaaaaaac****... " ,
" ......ccaaaaaaaaaaaaaacc****.... " ,
" .......*cccaaaaaaaaccc*****..... " ,
" ........***cccaaaac*******...... " ,
" ..........****caaac*****........ " ,
" .............*caaac**........... " ,
" ...............caac**........... " ,
" ................cac**........... " ,
" .................cc**........... " ,
" ..................***........... " ,
" ...................**........... " } ;
/* XPM */
static const char * const warning_xpm [ ] = {
" 32 32 4 1 " ,
" . c None " ,
" a c #ffff00 " ,
" * c #000000 " ,
" b c #999999 " ,
" .............***................ " ,
" ............*aaa*............... " ,
" ...........*aaaaa*b............. " ,
" ...........*aaaaa*bb............ " ,
" ..........*aaaaaaa*bb........... " ,
" ..........*aaaaaaa*bb........... " ,
" .........*aaaaaaaaa*bb.......... " ,
" .........*aaaaaaaaa*bb.......... " ,
" ........*aaaaaaaaaaa*bb......... " ,
" ........*aaaa***aaaa*bb......... " ,
" .......*aaaa*****aaaa*bb........ " ,
" .......*aaaa*****aaaa*bb........ " ,
" ......*aaaaa*****aaaaa*bb....... " ,
" ......*aaaaa*****aaaaa*bb....... " ,
" .....*aaaaaa*****aaaaaa*bb...... " ,
" .....*aaaaaa*****aaaaaa*bb...... " ,
" ....*aaaaaaaa***aaaaaaaa*bb..... " ,
" ....*aaaaaaaa***aaaaaaaa*bb..... " ,
" ...*aaaaaaaaa***aaaaaaaaa*bb.... " ,
" ...*aaaaaaaaaa*aaaaaaaaaa*bb.... " ,
" ..*aaaaaaaaaaa*aaaaaaaaaaa*bb... " ,
" ..*aaaaaaaaaaaaaaaaaaaaaaa*bb... " ,
" .*aaaaaaaaaaaa**aaaaaaaaaaa*bb.. " ,
" .*aaaaaaaaaaa****aaaaaaaaaa*bb.. " ,
" *aaaaaaaaaaaa****aaaaaaaaaaa*bb. " ,
" *aaaaaaaaaaaaa**aaaaaaaaaaaa*bb. " ,
" *aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb " ,
" *aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb " ,
" .*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb " ,
" ..*************************bbbbb " ,
" ....bbbbbbbbbbbbbbbbbbbbbbbbbbb. " ,
" .....bbbbbbbbbbbbbbbbbbbbbbbbb.. " } ;
/* XPM */
static const char * const critical_xpm [ ] = {
" 32 32 4 1 " ,
" . c None " ,
" a c #999999 " ,
" * c #ff0000 " ,
" b c #ffffff " ,
" ...........********............. " ,
" .........************........... " ,
" .......****************......... " ,
" ......******************........ " ,
" .....********************a...... " ,
" ....**********************a..... " ,
" ...************************a.... " ,
" ..*******b**********b*******a... " ,
" ..******bbb********bbb******a... " ,
" .******bbbbb******bbbbb******a.. " ,
" .*******bbbbb****bbbbb*******a.. " ,
" *********bbbbb**bbbbb*********a. " ,
" **********bbbbbbbbbb**********a. " ,
" ***********bbbbbbbb***********aa " ,
" ************bbbbbb************aa " ,
" ************bbbbbb************aa " ,
" ***********bbbbbbbb***********aa " ,
" **********bbbbbbbbbb**********aa " ,
" *********bbbbb**bbbbb*********aa " ,
" .*******bbbbb****bbbbb*******aa. " ,
" .******bbbbb******bbbbb******aa. " ,
" ..******bbb********bbb******aaa. " ,
" ..*******b**********b*******aa.. " ,
" ...************************aaa.. " ,
" ....**********************aaa... " ,
" ....a********************aaa.... " ,
" .....a******************aaa..... " ,
" ......a****************aaa...... " ,
" .......aa************aaaa....... " ,
" .........aa********aaaaa........ " ,
" ...........aaaaaaaaaaa.......... " ,
" .............aaaaaaa............ " } ;
TQPixmap KStyle : : stylePixmap ( StylePixmap stylepixmap ,
const TQWidget * widget ,
const TQStyleOption & opt ) const
{
switch ( stylepixmap ) {
case SP_TitleBarShadeButton :
return TQPixmap ( const_cast < const char * * > ( kstyle_shade_xpm ) ) ;
case SP_TitleBarUnshadeButton :
return TQPixmap ( const_cast < const char * * > ( kstyle_unshade_xpm ) ) ;
case SP_TitleBarNormalButton :
return TQPixmap ( const_cast < const char * * > ( kstyle_normalizeup_xpm ) ) ;
case SP_TitleBarMinButton :
return TQPixmap ( const_cast < const char * * > ( kstyle_minimize_xpm ) ) ;
case SP_TitleBarMaxButton :
return TQPixmap ( const_cast < const char * * > ( kstyle_maximize_xpm ) ) ;
case SP_TitleBarCloseButton :
return TQPixmap ( const_cast < const char * * > ( kstyle_close_xpm ) ) ;
case SP_DockWindowCloseButton :
return TQPixmap ( const_cast < const char * * > ( dock_window_close_xpm ) ) ;
case SP_MessageBoxInformation :
return TQPixmap ( const_cast < const char * * > ( information_xpm ) ) ;
case SP_MessageBoxWarning :
return TQPixmap ( const_cast < const char * * > ( warning_xpm ) ) ;
case SP_MessageBoxCritical :
return TQPixmap ( const_cast < const char * * > ( critical_xpm ) ) ;
default :
break ;
}
return TQCommonStyle : : stylePixmap ( stylepixmap , widget , opt ) ;
}
int KStyle : : styleHint ( TQ_StyleHint sh , const TQWidget * w ,
const TQStyleOption & opt , TQStyleHintReturn * shr ) const
{
switch ( sh )
{
case SH_EtchDisabledText :
return d - > etchDisabledText ? 1 : 0 ;
case SH_PopupMenu_Scrollable :
return d - > scrollablePopupmenus ? 1 : 0 ;
case SH_MenuBar_AltKeyNavigation :
return d - > menuAltKeyNavigation ? 1 : 0 ;
case SH_PopupMenu_SubMenuPopupDelay :
if ( styleHint ( SH_PopupMenu_SloppySubMenus , w ) )
return QMIN ( 100 , d - > popupMenuDelay ) ;
else
return d - > popupMenuDelay ;
case SH_PopupMenu_SloppySubMenus :
return d - > sloppySubMenus ;
case SH_ItemView_ChangeHighlightOnFocus :
case SH_Slider_SloppyKeyEvents :
case SH_MainWindow_SpaceBelowMenuBar :
case SH_PopupMenu_AllowActiveAndDisabled :
return 0 ;
case SH_Slider_SnapToValue :
case SH_PrintDialog_RightAlignButtons :
case SH_FontDialog_SelectAssociatedText :
case SH_MenuBar_MouseTracking :
case SH_PopupMenu_MouseTracking :
case SH_ComboBox_ListMouseTracking :
case SH_ScrollBar_MiddleClickAbsolutePosition :
return 1 ;
case SH_LineEdit_PasswordCharacter :
{
if ( w ) {
const TQFontMetrics & fm = w - > fontMetrics ( ) ;
if ( fm . inFont ( TQChar ( 0x25CF ) ) ) {
return 0x25CF ;
} else if ( fm . inFont ( TQChar ( 0x2022 ) ) ) {
return 0x2022 ;
}
}
return ' * ' ;
}
default :
return TQCommonStyle : : styleHint ( sh , w , opt , shr ) ;
}
}
bool KStyle : : eventFilter ( TQObject * object , TQEvent * event )
{
if ( d - > useFilledFrameWorkaround )
{
// Make the QMenuBar/TQToolBar paintEvent() cover a larger area to
// ensure that the filled frame contents are properly painted.
// We essentially modify the paintEvent's rect to include the
// panel border, which also paints the widget's interior.
// This is nasty, but I see no other way to properly repaint
// filled frames in all QMenuBars and QToolBars.
// -- Karol.
TQFrame * frame = 0 ;
if ( event - > type ( ) = = TQEvent : : Paint
& & ( frame = : : tqqt_cast < TQFrame * > ( object ) ) )
{
if ( frame - > frameShape ( ) ! = TQFrame : : ToolBarPanel & & frame - > frameShape ( ) ! = TQFrame : : MenuBarPanel )
return false ;
bool horizontal = true ;
TQPaintEvent * pe = ( TQPaintEvent * ) event ;
TQToolBar * toolbar = : : tqqt_cast < TQToolBar * > ( frame ) ;
TQRect r = pe - > rect ( ) ;
if ( toolbar & & toolbar - > orientation ( ) = = Qt : : Vertical )
horizontal = false ;
if ( horizontal ) {
if ( r . height ( ) = = frame - > height ( ) )
return false ; // Let TQFrame handle the painting now.
// Else, send a new paint event with an updated paint rect.
TQPaintEvent dummyPE ( TQRect ( r . x ( ) , 0 , r . width ( ) , frame - > height ( ) ) ) ;
TQApplication : : sendEvent ( frame , & dummyPE ) ;
}
else { // Vertical
if ( r . width ( ) = = frame - > width ( ) )
return false ;
TQPaintEvent dummyPE ( TQRect ( 0 , r . y ( ) , frame - > width ( ) , r . height ( ) ) ) ;
TQApplication : : sendEvent ( frame , & dummyPE ) ;
}
// Discard this event as we sent a new paintEvent.
return true ;
}
}
return false ;
}
// -----------------------------------------------------------------------------
// I N T E R N A L - KStyle menu transparency handler
// -----------------------------------------------------------------------------
TransparencyHandler : : TransparencyHandler ( KStyle * style ,
TransparencyEngine tEngine , float menuOpacity , bool useDropShadow )
: TQObject ( )
{
te = tEngine ;
kstyle = style ;
opacity = menuOpacity ;
dropShadow = useDropShadow ;
pix . setOptimization ( TQPixmap : : BestOptim ) ;
}
TransparencyHandler : : ~ TransparencyHandler ( )
{
}
bool TransparencyHandler : : haveX11RGBASupport ( )
{
// Simple way to determine if we have ARGB support
if ( TQPaintDevice : : x11AppDepth ( ) = = 32 ) {
return true ;
}
else {
return false ;
}
}
# define REAL_ALPHA_STRENGTH 255.0
// This is meant to be ugly but fast.
void TransparencyHandler : : rightShadow ( TQImage & dst )
{
bool have_composite = haveX11RGBASupport ( ) ;
if ( dst . depth ( ) ! = 32 )
dst = dst . convertDepth ( 32 ) ;
// blend top-right corner.
int pixels = dst . width ( ) * dst . height ( ) ;
# ifdef WORDS_BIGENDIAN
register unsigned char * data = dst . bits ( ) + 1 ; // Skip alpha
# else
register unsigned char * data = dst . bits ( ) ; // Skip alpha
# endif
for ( register int i = 0 ; i < 16 ; i + + ) {
if ( have_composite ) {
data + + ;
data + + ;
data + + ;
* data = ( unsigned char ) ( REAL_ALPHA_STRENGTH * ( 1.0 - top_right_corner [ i ] ) ) ; data + + ;
}
else {
* data = ( unsigned char ) ( ( * data ) * top_right_corner [ i ] ) ; data + + ;
* data = ( unsigned char ) ( ( * data ) * top_right_corner [ i ] ) ; data + + ;
* data = ( unsigned char ) ( ( * data ) * top_right_corner [ i ] ) ; data + + ;
data + + ; // skip alpha
}
}
pixels - = 32 ; // tint right strip without rounded edges.
register int c = 0 ;
for ( register int i = 0 ; i < pixels ; i + + ) {
if ( have_composite ) {
data + + ;
data + + ;
data + + ; ;
* data = ( unsigned char ) ( REAL_ALPHA_STRENGTH * ( 1.0 - shadow_strip [ c ] ) ) ; data + + ;
}
else {
* data = ( unsigned char ) ( ( * data ) * shadow_strip [ c ] ) ; data + + ;
* data = ( unsigned char ) ( ( * data ) * shadow_strip [ c ] ) ; data + + ;
* data = ( unsigned char ) ( ( * data ) * shadow_strip [ c ] ) ; data + + ;
data + + ; // skip alpha
}
+ + c ;
c % = 4 ;
}
// tint bottom edge
for ( register int i = 0 ; i < 16 ; i + + ) {
if ( have_composite ) {
data + + ;
data + + ;
data + + ;
* data = ( unsigned char ) ( REAL_ALPHA_STRENGTH * ( 1.0 - bottom_right_corner [ i ] ) ) ; data + + ;
}
else {
* data = ( unsigned char ) ( ( * data ) * bottom_right_corner [ i ] ) ; data + + ;
* data = ( unsigned char ) ( ( * data ) * bottom_right_corner [ i ] ) ; data + + ;
* data = ( unsigned char ) ( ( * data ) * bottom_right_corner [ i ] ) ; data + + ;
data + + ; // skip alpha
}
}
}
void TransparencyHandler : : bottomShadow ( TQImage & dst )
{
bool have_composite = haveX11RGBASupport ( ) ;
if ( dst . depth ( ) ! = 32 )
dst = dst . convertDepth ( 32 ) ;
int line = 0 ;
int width = dst . width ( ) - 4 ;
double strip_data = shadow_strip [ 0 ] ;
double * corner = const_cast < double * > ( bottom_left_corner ) ;
# ifdef WORDS_BIGENDIAN
register unsigned char * data = dst . bits ( ) + 1 ; // Skip alpha
# else
register unsigned char * data = dst . bits ( ) ; // Skip alpha
# endif
for ( int y = 0 ; y < 4 ; y + + )
{
// Bottom-left Corner
for ( register int x = 0 ; x < 4 ; x + + ) {
if ( have_composite ) {
data + + ;
data + + ;
data + + ;
* data = ( unsigned char ) ( REAL_ALPHA_STRENGTH * ( 1.0 - ( * corner ) ) ) ; data + + ;
}
else {
* data = ( unsigned char ) ( ( * data ) * ( * corner ) ) ; data + + ;
* data = ( unsigned char ) ( ( * data ) * ( * corner ) ) ; data + + ;
* data = ( unsigned char ) ( ( * data ) * ( * corner ) ) ; data + + ;
data + + ; // skip alpha
}
corner + + ;
}
// Scanline
for ( register int x = 0 ; x < width ; x + + ) {
if ( have_composite ) {
data + + ;
data + + ;
data + + ;
* data = ( unsigned char ) ( REAL_ALPHA_STRENGTH * ( 1.0 - strip_data ) ) ; data + + ;
}
else {
* data = ( unsigned char ) ( ( * data ) * strip_data ) ; data + + ;
* data = ( unsigned char ) ( ( * data ) * strip_data ) ; data + + ;
* data = ( unsigned char ) ( ( * data ) * strip_data ) ; data + + ;
data + + ; // skip alpha
}
}
strip_data = shadow_strip [ + + line ] ;
}
}
TQImage TransparencyHandler : : handleRealAlpha ( TQImage img ) {
TQImage clearImage = img . convertDepth ( 32 ) ;
clearImage . setAlphaBuffer ( true ) ;
int w = clearImage . width ( ) ;
int h = clearImage . height ( ) ;
for ( int y = 0 ; y < h ; + + y ) {
TQRgb * ls = ( TQRgb * ) clearImage . scanLine ( y ) ;
for ( int x = 0 ; x < w ; + + x ) {
TQRgb l = ls [ x ] ;
ls [ x ] = tqRgba ( 0 , 0 , 0 , 0 ) ;
}
}
return clearImage ;
}
// Create a shadow of thickness 4.
void TransparencyHandler : : createShadowWindows ( const TQWidget * p )
{
# ifdef Q_WS_X11
int x2 = p - > x ( ) + p - > width ( ) ;
int y2 = p - > y ( ) + p - > height ( ) ;
TQRect shadow1 ( x2 , p - > y ( ) + 4 , 4 , p - > height ( ) ) ;
TQRect shadow2 ( p - > x ( ) + 4 , y2 , p - > width ( ) - 4 , 4 ) ;
bool have_composite = haveX11RGBASupport ( ) ;
// Create a fake drop-down shadow effect via blended Xwindows
ShadowElements se ;
se . w1 = new TQWidget ( 0 , 0 , ( WFlags ) ( WStyle_Customize | WType_Popup | WX11BypassWM ) ) ;
se . w2 = new TQWidget ( 0 , 0 , ( WFlags ) ( WStyle_Customize | WType_Popup | WX11BypassWM ) ) ;
se . w1 - > setGeometry ( shadow1 ) ;
se . w2 - > setGeometry ( shadow2 ) ;
XSelectInput ( qt_xdisplay ( ) , se . w1 - > winId ( ) , StructureNotifyMask ) ;
XSelectInput ( qt_xdisplay ( ) , se . w2 - > winId ( ) , StructureNotifyMask ) ;
// Insert a new ShadowMap entry
shadowMap ( ) [ p ] = se ;
// Some hocus-pocus here to create the drop-shadow.
TQPixmap pix_shadow1 ;
TQPixmap pix_shadow2 ;
if ( have_composite ) {
pix_shadow1 = TQPixmap ( shadow1 . width ( ) , shadow1 . height ( ) ) ;
pix_shadow2 = TQPixmap ( shadow2 . width ( ) , shadow2 . height ( ) ) ;
}
else {
pix_shadow1 = TQPixmap : : grabWindow ( qt_xrootwin ( ) ,
shadow1 . x ( ) , shadow1 . y ( ) , shadow1 . width ( ) , shadow1 . height ( ) ) ;
pix_shadow2 = TQPixmap : : grabWindow ( qt_xrootwin ( ) ,
shadow2 . x ( ) , shadow2 . y ( ) , shadow2 . width ( ) , shadow2 . height ( ) ) ;
}
TQImage img ;
img = pix_shadow1 . convertToImage ( ) ;
if ( have_composite ) img = handleRealAlpha ( img ) ;
rightShadow ( img ) ;
pix_shadow1 . convertFromImage ( img ) ;
img = pix_shadow2 . convertToImage ( ) ;
if ( have_composite ) img = handleRealAlpha ( img ) ;
bottomShadow ( img ) ;
pix_shadow2 . convertFromImage ( img ) ;
// Set the background pixmaps
se . w1 - > setErasePixmap ( pix_shadow1 ) ;
se . w2 - > setErasePixmap ( pix_shadow2 ) ;
// Show the 'shadow' just before showing the popup menu window
// Don't use TQWidget::show() so we don't confuse QEffects, thus causing broken focus.
XMapWindow ( qt_xdisplay ( ) , se . w1 - > winId ( ) ) ;
XMapWindow ( qt_xdisplay ( ) , se . w2 - > winId ( ) ) ;
# else
Q_UNUSED ( p )
# endif
}
void TransparencyHandler : : removeShadowWindows ( const TQWidget * p )
{
# ifdef Q_WS_X11
ShadowMap : : iterator it = shadowMap ( ) . find ( p ) ;
if ( it ! = shadowMap ( ) . end ( ) )
{
ShadowElements se = it . data ( ) ;
XUnmapWindow ( qt_xdisplay ( ) , se . w1 - > winId ( ) ) ; // hide
XUnmapWindow ( qt_xdisplay ( ) , se . w2 - > winId ( ) ) ;
XFlush ( qt_xdisplay ( ) ) ; // try to hide faster
delete se . w1 ;
delete se . w2 ;
shadowMap ( ) . erase ( it ) ;
}
# else
Q_UNUSED ( p )
# endif
}
bool TransparencyHandler : : eventFilter ( TQObject * object , TQEvent * event )
{
# if !defined Q_WS_MAC && !defined Q_WS_WIN
// Transparency idea was borrowed from KDE2's "MegaGradient" Style,
// Copyright (C) 2000 Daniel M. Duley <mosfet@kde.org>
// Added 'fake' menu shadows <04-Jul-2002> -- Karol
TQWidget * p = ( TQWidget * ) object ;
TQEvent : : Type et = event - > type ( ) ;
if ( et = = TQEvent : : Show )
{
// Handle translucency
if ( te ! = Disabled )
{
pix = TQPixmap : : grabWindow ( qt_xrootwin ( ) ,
p - > x ( ) , p - > y ( ) , p - > width ( ) , p - > height ( ) ) ;
switch ( te ) {
# ifdef HAVE_XRENDER
case XRender :
if ( qt_use_xrender ) {
XRenderBlendToPixmap ( p ) ;
break ;
}
// Fall through intended
# else
case XRender :
# endif
case SoftwareBlend :
blendToPixmap ( p - > colorGroup ( ) , p ) ;
break ;
case SoftwareTint :
default :
blendToColor ( p - > colorGroup ( ) . button ( ) ) ;
} ;
p - > setErasePixmap ( pix ) ;
}
// Handle drop shadow
// * FIXME : !shadowMap().contains(p) is a workaround for leftover
// * shadows after duplicate show events.
// * TODO : determine real cause for duplicate events
// * till 20021005
if ( ( dropShadow | | useDropShadow ( p ) )
& & p - > width ( ) > 16 & & p - > height ( ) > 16 & & ! shadowMap ( ) . contains ( p ) )
createShadowWindows ( p ) ;
}
else if ( et = = TQEvent : : Resize & & p - > isShown ( ) & & p - > isTopLevel ( ) )
{
// Handle drop shadow
if ( dropShadow | | useDropShadow ( p ) )
{
removeShadowWindows ( p ) ;
createShadowWindows ( p ) ;
}
}
else if ( et = = TQEvent : : Hide )
{
// Handle drop shadow
if ( dropShadow | | useDropShadow ( p ) )
removeShadowWindows ( p ) ;
// Handle translucency
if ( te ! = Disabled )
p - > setErasePixmap ( TQPixmap ( ) ) ;
}
# endif
return false ;
}
// Blends a TQImage to a predefined color, with a given opacity.
void TransparencyHandler : : blendToColor ( const TQColor & col )
{
if ( opacity < 0.0 | | opacity > 1.0 )
return ;
TQImage img = pix . convertToImage ( ) ;
KImageEffect : : blend ( col , img , opacity ) ;
pix . convertFromImage ( img ) ;
}
void TransparencyHandler : : blendToPixmap ( const TQColorGroup & cg , const TQWidget * p )
{
if ( opacity < 0.0 | | opacity > 1.0 )
return ;
KPixmap blendPix ;
blendPix . resize ( pix . width ( ) , pix . height ( ) ) ;
if ( blendPix . width ( ) ! = pix . width ( ) | |
blendPix . height ( ) ! = pix . height ( ) )
return ;
// Allow styles to define the blend pixmap - allows for some interesting effects.
if ( : : tqqt_cast < TQPopupMenu * > ( p ) )
kstyle - > renderMenuBlendPixmap ( blendPix , cg , : : tqqt_cast < TQPopupMenu * > ( p ) ) ;
else
blendPix . fill ( cg . button ( ) ) ; // Just tint as the default behavior
TQImage blendImg = blendPix . convertToImage ( ) ;
TQImage backImg = pix . convertToImage ( ) ;
KImageEffect : : blend ( blendImg , backImg , opacity ) ;
pix . convertFromImage ( backImg ) ;
}
# ifdef HAVE_XRENDER
// Here we go, use XRender in all its glory.
// NOTE: This is actually a bit slower than the above routines
// on non-accelerated displays. -- Karol.
void TransparencyHandler : : XRenderBlendToPixmap ( const TQWidget * p )
{
KPixmap renderPix ;
renderPix . resize ( pix . width ( ) , pix . height ( ) ) ;
// Allow styles to define the blend pixmap - allows for some interesting effects.
if ( : : tqqt_cast < TQPopupMenu * > ( p ) )
kstyle - > renderMenuBlendPixmap ( renderPix , p - > colorGroup ( ) ,
: : tqqt_cast < TQPopupMenu * > ( p ) ) ;
else
renderPix . fill ( p - > colorGroup ( ) . button ( ) ) ; // Just tint as the default behavior
Display * dpy = qt_xdisplay ( ) ;
Pixmap alphaPixmap ;
Picture alphaPicture ;
XRenderPictFormat Rpf ;
XRenderPictureAttributes Rpa ;
XRenderColor clr ;
clr . alpha = ( ( unsigned short ) ( 255 * opacity ) < < 8 ) ;
Rpf . type = PictTypeDirect ;
Rpf . depth = 8 ;
Rpf . direct . alphaMask = 0xff ;
Rpa . repeat = True ; // Tile
XRenderPictFormat * xformat = XRenderFindFormat ( dpy ,
PictFormatType | PictFormatDepth | PictFormatAlphaMask , & Rpf , 0 ) ;
alphaPixmap = XCreatePixmap ( dpy , p - > handle ( ) , 1 , 1 , 8 ) ;
alphaPicture = XRenderCreatePicture ( dpy , alphaPixmap , xformat , CPRepeat , & Rpa ) ;
XRenderFillRectangle ( dpy , PictOpSrc , alphaPicture , & clr , 0 , 0 , 1 , 1 ) ;
XRenderComposite ( dpy , PictOpOver ,
renderPix . x11RenderHandle ( ) , alphaPicture , pix . x11RenderHandle ( ) , // src, mask, dst
0 , 0 , // srcx, srcy
0 , 0 , // maskx, masky
0 , 0 , // dstx, dsty
pix . width ( ) , pix . height ( ) ) ;
XRenderFreePicture ( dpy , alphaPicture ) ;
XFreePixmap ( dpy , alphaPixmap ) ;
}
# endif
void KStyle : : virtual_hook ( int , void * )
{ /*BASE::virtual_hook( id, data );*/ }
// HACK for gtk-qt-engine
KDE_EXPORT extern " C "
void kde_kstyle_set_scrollbar_type_windows ( void * style )
{
( ( KStyle * ) style ) - > setScrollBarType ( KStyle : : WindowsStyleScrollBar ) ;
}
// vim: set noet ts=4 sw=4:
// kate: indent-width 4; replace-tabs off; tab-width 4; space-indent off;
# include "kstyle.moc"