You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdebase/ksplashml/themeengine/standard/wndicon.cpp

311 lines
7.6 KiB

/***************************************************************************
* Copyright Brian Ledbetter 2001-2003 <brian@shadowcom.net> *
* Copyright Ravikiran Rajagopal 2003 *
* ravi@ee.eng.ohio-state.edu *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License (version 2) as *
* published by the Free Software Foundation. (The original KSplash/ML *
* codebase (upto version 0.95.3) is BSD-licensed.) *
* *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <kapplication.h>
#include <kcursor.h>
#include <kdebug.h>
#include <kdebug.h>
#include <kglobalsettings.h>
#include <kwin.h>
#include <qdesktopwidget.h>
#include <qhbox.h>
#include <qlabel.h>
#include <qpixmap.h>
#include <qpoint.h>
#include <qtimer.h>
#include <qwidget.h>
#include "wndicon.h"
#include "wndicon.moc"
WndIcon::WndIcon(
unsigned int icon_num,
unsigned int icon_std_width,
unsigned int status_height,
int xineramaScreen,
const KPixmap& pix,
const QString& text,
Position icon_position,
bool statusAtTop,
bool iconsJumping )
:QHBox( 0, "wndSplash", WStyle_Customize|WX11BypassWM ),
mStatusText(text), mIconPos(icon_position), mXineramaScreen( xineramaScreen ), mPosX(0), mPosY(0), mGroundX(0), mGroundY(0),
mVelocity(8.0), mInitialVelocity(8.0), mGravity(0.8),
mIconNum(icon_num), mStatusHeight(status_height), mIconSize(icon_std_width), mStatusAtTop(statusAtTop),
mStopJump(false), mIconJumping(iconsJumping)
{
setFrameStyle( QFrame::NoFrame );
QLabel *w = new QLabel( this );
w->setFixedSize( pix.width(), pix.height() );
w->setPixmap( pix );
if(pix.mask())
{
setMask(*pix.mask());
w->setMask(*pix.mask());
}
resize( pix.width(), pix.height() );
// Set initial position of icon, and ground.
QPoint p = determinePosition();
mGroundX = mPosX = p.x();
mGroundY = mPosY = p.y();
move( p + kapp->desktop()->screenGeometry( mXineramaScreen ).topLeft() );
if( mIconJumping )
{
QTimer *t = new QTimer( this );
connect(t, SIGNAL(timeout()), SLOT(slotJump()));
t->start( 50, false );
}
}
void WndIcon::show()
{
emit setStatusText( mStatusText );
QHBox::show();
}
// Emit our EXTRA signal without becoming visible.
void WndIcon::noshow()
{
emit setStatusText( mStatusText );
}
/*
* WndIcon::determinePosition(): Based on the information we've
* stored within us, determine where we should be placed on the
* screen. This is placed in its own function due to the massive
* complexity required by the variables involved.
*/
QPoint WndIcon::determinePosition()
{
int DW, DH, SBH, wid, X, Y, x, y, nSlot, topshift, bottomshift;
bottomshift = topshift = 0;
const QRect srect = kapp->desktop()->screenGeometry( mXineramaScreen );
// KGlobalSettings::splashScreenDesktopGeometry(); cannot be used here.
DW = srect.width();
DH = srect.height();
SBH = mStatusHeight;
wid = mIconSize;
x = mIconNum;
y = 1;
if(mStatusAtTop)
topshift = mStatusHeight;
else
bottomshift = mStatusHeight;
// Different starting positions require different positioning
// rules. The horizontal rules and the vertical rules can be
// grouped together, as they are innately similar.
switch( mIconPos )
{
// HORIZONTAL: Top Left -> Top Right
case( WndIcon::HTopLeft ):
nSlot = ( DW / wid );
while( x > nSlot )
{
x = QMAX(0,x-nSlot);
y++;
}
X = (3) + ((x - 1) * wid);
Y = topshift + 3 + ( (y-1) * wid );
break;
// HORIZONTAL: Bottom Left -> Bottom Right
case( WndIcon::HBottomLeft ):
nSlot = ( DW / wid );
while( x > nSlot )
{
x = QMAX(0,x-nSlot);
y++;
}
X = (3) + ((x - 1) * wid);
Y = (DH-3) - (y * wid) - bottomshift;
break;
// HORIZONTAL: Top Right -> Top Left
case( WndIcon::HTopRight ):
nSlot = ( DW / wid );
while( x > nSlot )
{
x = QMAX(0,x-nSlot);
y++;
}
X = (DW - 3) - (( x ) * wid );
Y = topshift + (3) + ( (y-1) * wid );
break;
// HORIZONTAL: Bottom Right -> Bottom Left
case( WndIcon::HBottomRight ):
nSlot = ( DW / wid );
while( x > nSlot )
{
x = QMAX(0,x-nSlot);
y++;
}
X = (DW - 3) - (( x ) * wid );
Y = (DH-3) - (y * wid) - bottomshift;
break;
// VERTICAL: Top Left -> Bottom Left
case( WndIcon::VTopLeft ):
nSlot = ( DH / wid );
while( x > nSlot )
{
x = QMAX(0,x-nSlot);
y++;
}
X = (3) + (( y - 1 ) * wid );
Y = topshift + (3) + ((x-1) * wid);
break;
// VERTICAL: Top Right -> Bottom Right
case( WndIcon::VTopRight ):
nSlot = ( DH / wid );
while( x > nSlot )
{
x = QMAX(0,x-nSlot);
y++;
}
X = (DW - 3) - (( y ) * wid );
Y = topshift + (3) + ((x-1) * wid);
break;
// VERTICAL: Bottom Left -> Top Left
case( WndIcon::VBottomLeft ):
nSlot = ( DH / wid );
while( x > nSlot )
{
x = QMAX(0,x-nSlot);
y++;
}
X = (3) + (( y - 1 ) * wid );
Y = (DH-3) - (x * wid) - bottomshift;
break;
// VERTICAL: Bottom Right -> Top Right
case( WndIcon::VBottomRight ):
nSlot = ( DH / wid );
while( x > nSlot )
{
x = QMAX(0,x-nSlot);
y++;
}
X = (DW - 3) - (( y ) * wid );
Y = (DH-3) - (x * wid) - bottomshift;
break;
// Unknown Condition. Reconfigure variable and
// retry. Recursively, of course! ;)
default:
mIconPos = HBottomLeft;
return(determinePosition());
break;
}
return( QPoint( X, Y ) );
}
// Make the icons jump in a macosx-like way (Thanks, Jone!:)
void WndIcon::slotJump()
{
// Based on our position, bounce around.
switch( mIconPos )
{
// LEFT
case( WndIcon::VTopLeft ):
case( WndIcon::VBottomLeft ):
mVelocity -= mGravity;
if( mStopJump )
{
if( mPosX <= mGroundX )
{
mPosX = mGroundX;
mVelocity = mGravity = 0.0;
}
}
else
if( mPosX <= mGroundX )
mVelocity = mInitialVelocity;
mPosX = (int)((float)mPosX + mVelocity);
break;
// RIGHT
case( WndIcon::VTopRight ):
case( WndIcon::VBottomRight ):
mVelocity -= mGravity;
if( mStopJump )
{
if( mPosX >= mGroundX )
{
mPosX = mGroundX;
mVelocity = mGravity = 0.0;
}
}
else
if( mPosX >= mGroundX )
mVelocity = mInitialVelocity;
mPosX = (int)((float)mPosX - mVelocity);
break;
// TOP
case( WndIcon::HTopLeft ):
case( WndIcon::HTopRight ):
mVelocity -= mGravity;
if( mStopJump )
{
if( mPosY <= mGroundY )
{
mPosY = mGroundY;
mVelocity = mGravity = 0.0;
}
}
else
if( mPosY <= mGroundY )
mVelocity = mInitialVelocity;
mPosY = (int)((float)mPosY + mVelocity );
break;
// BOTTOM
case( WndIcon::HBottomLeft ):
case( WndIcon::HBottomRight ): default:
mVelocity -= mGravity;
if( mStopJump )
{
if( mPosY >= mGroundY )
{
mPosY = mGroundY;
mVelocity = mGravity = 0.0;
}
}
else
if( mPosY >= mGroundY )
mVelocity = mInitialVelocity;
mPosY = (int)((float)mPosY - mVelocity );
break;
}
move( QPoint( mPosX, mPosY ) + kapp->desktop()->screenGeometry( mXineramaScreen ).topLeft() );
}
void WndIcon::slotStopJumping()
{
mStopJump = true;
}