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.
tdeartwork/kscreensaver/kdesavers/science.cpp

1152 lines
27 KiB

//-----------------------------------------------------------------------------
//
// kscience - screen saver for KDE
//
// Copyright (c) Rene Beutler 1998
//
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <time.h>
#include <tqpainter.h>
#include <tqpixmap.h>
#include <tqlabel.h>
#include <tqlistbox.h>
#include <tqcheckbox.h>
#include <tqslider.h>
#include <tqlayout.h>
#include <kapplication.h>
#include <kglobal.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <kconfig.h>
#include <kstandarddirs.h>
#include <krandomsequence.h>
#include "science.h"
#include "science.moc"
#if defined Q_WS_X11 && !defined K_WS_TQTONLY
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif
#define SCI_DEFAULT_MODE 0
#define SCI_DEFAULT_MOVEX 6
#define SCI_DEFAULT_MOVEY 8
#define SCI_DEFAULT_SIZE 15
#define SCI_DEFAULT_INTENSITY 4
#define SCI_DEFAULT_SPEED 70
#define SCI_DEFAULT_INVERSE false
#define SCI_DEFAULT_GRAVITY false
#define SCI_DEFAULT_HIDE false
#define SCI_MAX_SPEED 100
#define SCI_MAX_MOVE 20
#undef Below
// libkscreensaver interface
extern "C"
{
KDE_EXPORT const char *kss_applicationName = "kscience.kss";
KDE_EXPORT const char *kss_description = I18N_NOOP( "Science Screen Saver" );
KDE_EXPORT const char *kss_version = "2.2.0";
KDE_EXPORT KScreenSaver *kss_create( WId id )
{
return new KScienceSaver( id );
}
KDE_EXPORT TQDialog *kss_setup()
{
return new KScienceSetup();
}
}
static struct {
TQString name;
bool inverseEnable;
} modeInfo[MAX_MODES];
enum { MODE_WHIRL=0, MODE_CURVATURE, MODE_SPHERE, MODE_WAVE, MODE_EXPONENTIAL, MODE_CONTRACTION };
void initModeInfo()
{
modeInfo[MODE_WHIRL].name = i18n( "Whirl" );
modeInfo[MODE_WHIRL].inverseEnable = true;
modeInfo[MODE_SPHERE].name = i18n( "Sphere" );
modeInfo[MODE_SPHERE].inverseEnable = true;
modeInfo[MODE_EXPONENTIAL].name = i18n( "Exponential" );
modeInfo[MODE_EXPONENTIAL].inverseEnable = false;
modeInfo[MODE_CONTRACTION].name = i18n( "Contraction" );
modeInfo[MODE_CONTRACTION].inverseEnable = false;
modeInfo[MODE_WAVE].name = i18n( "Wave" );
modeInfo[MODE_WAVE].inverseEnable = false;
modeInfo[MODE_CURVATURE].name = i18n( "Curvature" );
modeInfo[MODE_CURVATURE].inverseEnable = true;
}
//-----------------------------------------------------------------------------
// KPreviewWidget
//
KPreviewWidget::KPreviewWidget( TQWidget *parent ) :
TQWidget ( parent ) { }
void KPreviewWidget::paintEvent( TQPaintEvent *event )
{
if( saver != 0 )
saver->do_refresh( event->rect() );
}
void KPreviewWidget::notifySaver( KScienceSaver *s )
{
saver = s;
}
//-----------------------------------------------------------------------------
// Screen Saver
//
struct KScienceData
{
T32bit **offset;
XImage *buffer;
XImage *xRootWin;
GC gc;
};
KScienceSaver::KScienceSaver( WId id, bool s, bool gP )
: KScreenSaver( id )
{
d = new KScienceData;
d->gc = XCreateGC(tqt_xdisplay(), id, 0, 0);
d->xRootWin = 0;
d->buffer = 0;
moveOn = true;
grabPixmap = gP;
setup = s;
vx = vy = 0.0;
readSettings();
if( !grabPixmap )
{
grabRootWindow();
initialize();
do_refresh( TQRect ( 0, 0, width(), height() ) );
}
connect( &timer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotTimeout() ) );
timer.start( SCI_MAX_SPEED - speed[mode] );
}
KScienceSaver::~KScienceSaver()
{
timer.stop();
releaseLens();
if ( d->xRootWin )
XDestroyImage( d->xRootWin );
XFreeGC(tqt_xdisplay(), d->gc );
delete d;
}
void KScienceSaver::myAssert( bool term, const char *eMsg )
{
if( !term ) {
fprintf(stderr, "Error in KScreensaver - mode Science: %s\n", eMsg);
releaseLens();
exit(-1);
}
}
void KScienceSaver::initialize()
{
KRandomSequence rnd;
initLens();
signed int ws = (signed int) (width() - diam);
signed int hs = (signed int) (height() - diam);
x = (ws > 0) ? (rnd.getDouble() * ws ) : 0.0;
y = (hs > 0) ? (rnd.getDouble() * hs ) : 0.0;
xcoord = (int) x;
ycoord = (int) y;
switch( bpp ) {
case 1 : applyLens = &KScienceSaver::applyLens8bpp; break;
case 2 : applyLens = &KScienceSaver::applyLens16bpp; break;
case 3 : applyLens = &KScienceSaver::applyLens24bpp; break;
case 4 : applyLens = &KScienceSaver::applyLens32bpp; break;
default: myAssert( false, "unsupported colordepth "\
"(only 8, 16, 24, 32 bpp supported)" );
}
}
void KScienceSaver::initWhirlLens()
{
double dx, dy, r, phi, intens;
T32bit *off;
T32bit xo, yo;
intens = double( intensity[mode] + 1) / 5.0;
if( inverse[mode] )
intens = -intens;
for(int y = side-1; y >= 0; y--)
{
dy = y - origin;
off = d->offset[y] = (T32bit *) malloc(sizeof(T32bit) * side);
myAssert( off != 0, "too few memory" );
for(int x = side-1; x >= 0; x--)
{
dx = x - origin;
r = sqrt( dx*dx + dy*dy );
if( r < radius )
{
if ( dx == 0.0 )
phi = (dy > 0.0) ? M_PI_2 :-(M_PI_2);
else
phi = atan2( dy, dx );
phi += intens * ( radius - r ) / ( r+7.0 );
xo = (T32bit) ( origin + r*cos( phi ) - x );
yo = (T32bit) ( origin + r*sin( phi ) - y );
off[x] = xo*bpp + yo*imgnext;
}
else
if( hideBG[mode] )
off[x] = (border-y)*imgnext + (border-x)*bpp;
else
off[x] = 0;
}
}
}
void KScienceSaver::initSphereLens()
{
double dx, dy, r, xr, yr, phi, intens;
T32bit *off;
T32bit xo, yo;
intens = 1.0 - double( intensity[mode] ) / 20.0;
if( inverse[mode] )
intens = -intens;
for(int y = side-1; y >= 0; y--)
{
dy = y - origin;
off = d->offset[y] = (T32bit *) malloc(sizeof(T32bit) * side);
myAssert( off != 0, "too few memory" );
for(int x = side-1; x >= 0; x--)
{
dx = x - origin;
r = sqrt( dx*dx + dy*dy );
if( r < radius )
{
xr = (double) radius*cos(asin(dy/radius));
yr = (double) radius*cos(asin(dx/radius));
phi = (xr != 0.0) ? asin(dx/xr) : 0.0;
xo = (T32bit) (origin + intens*2.0*phi*xr / M_PI - x);
phi = (yr != 0.0) ? asin(dy/yr) : 0.0;
yo = (T32bit) (origin + intens*2.0*phi*yr / M_PI - y);
off[x] = xo*bpp + yo*imgnext;
}
else
if( hideBG[mode] )
off[x] = (border-y)*imgnext + (border-x)*bpp;
else
off[x] = 0;
}
}
}
void KScienceSaver::initExponentialLens()
{
double dx, dy, r, rnew, f, intens;
T32bit *off;
T32bit xo, yo;
if( mode == MODE_EXPONENTIAL )
intens = - (0.1 + 0.8 * double( intensity[mode] + 2) / 10.0);
else
intens = 0.9 - 0.8 * double( intensity[mode] ) / 10.0;
for(int y = side-1; y >= 0; y--)
{
dy = y - origin;
off = d->offset[y] = (T32bit *) malloc(sizeof(T32bit) * side);
myAssert( off != 0, "too few memory" );
for(int x = side-1; x >= 0; x--)
{
dx = x - origin;
r = sqrt( dx*dx + dy*dy );
if( r < radius )
{
if( r == 0.0 )
f = 0.0;
else
{
rnew = radius*(pow(r, intens) / pow(radius, intens));
f = double ((int)rnew % radius) / r;
}
xo = (T32bit) ( origin + f*dx - x );
yo = (T32bit) ( origin + f*dy - y );
off[x] = xo*bpp + yo*imgnext;
}
else
if( hideBG[mode] )
off[x] = (border-y)*imgnext + (border-x)*bpp;
else
off[x] = 0;
}
}
}
void KScienceSaver::initCurvatureLens()
{
double dx, dy, r, f, intens;
T32bit *off;
T32bit xo, yo;
intens = (double) radius*intensity[mode] / 20.0;
if( inverse[mode] ) intens = -intens;
for(int y = side-1; y >= 0; y--)
{
dy = y - origin;
off = d->offset[y] = (T32bit *) malloc(sizeof(T32bit) * side);
myAssert( off != 0, "too few memory" );
for(int x = side-1; x >= 0; x--)
{
dx = x - origin;
r = sqrt( dx*dx + dy*dy );
if( r < radius )
{
if( r == 0.0 )
f = 0.0;
else
f = (r - intens * sin(M_PI * r/(double)radius)) / r;
xo = (T32bit) ( origin + f*dx - x );
yo = (T32bit) ( origin + f*dy - y );
off[x] = xo*bpp + yo*imgnext;
}
else
if( hideBG[mode] )
off[x] = (border-y)*imgnext + (border-x)*bpp;
else
off[x] = 0;
}
}
}
void KScienceSaver::initWaveLens()
{
double dx, dy, r, rnew, f, intens, k;
T32bit *off;
T32bit xo, yo;
intens = (double) intensity[mode] + 1.0;
k = (intensity[mode] % 2) ? -12.0 : 12.0;
for(int y = side-1; y >= 0; y--)
{
dy = y - origin;
off = d->offset[y] = (T32bit *) malloc(sizeof(T32bit) * side);
myAssert( off != 0, "too few memory" );
for(int x = side-1; x >= 0; x--)
{
dx = x - origin;
r = sqrt( dx*dx + dy*dy );
if( r < radius )
{
if( r == 0.0 )
f = 0.0;
else
{
rnew = r - k * sin( M_PI * intens * r/(double)radius);
f = double ((int)rnew % radius) / r;
}
xo = (T32bit) ( origin + f*dx - x );
yo = (T32bit) ( origin + f*dy - y );
off[x] = xo*bpp + yo*imgnext;
}
else
if( hideBG[mode] )
off[x] = (border-y)*imgnext + (border-x)*bpp;
else
off[x] = 0;
}
}
}
void KScienceSaver::initLens()
{
int min = (width() < height()) ? width() : height();
border = 1 + SCI_MAX_MOVE;
radius = (size[mode] * min) / 100;
if( radius<<1 == min ) radius--;
diam = radius << 1;
myAssert( diam < min, "assertion violated: diam < min" );
origin = radius + border;
side = origin << 1;
d->buffer = XSubImage( d->xRootWin, 0, 0, side, side );
myAssert( d->buffer != 0, "can't allocate pixmap" );
d->offset = (T32bit **) malloc( sizeof(T32bit *) * side );
myAssert( d->offset != 0, "too few memory" );
switch( mode ) {
case MODE_WHIRL: initWhirlLens(); break;
case MODE_SPHERE: initSphereLens(); break;
case MODE_EXPONENTIAL:
case MODE_CONTRACTION: initExponentialLens(); break;
case MODE_CURVATURE: initCurvatureLens(); break;
case MODE_WAVE: initWaveLens(); break;
default: myAssert( false, "internal error (wrong mode in initLens() )" );
}
}
void KScienceSaver::releaseLens()
{
if( d->offset != 0 ) {
for(int i=0; i<side; i++)
if( d->offset[i] != 0 ) free( d->offset[i] );
free( d->offset );
d->offset = 0;
}
if( d->buffer != 0 ) {
XDestroyImage( d->buffer );
d->buffer = 0;
}
}
void KScienceSaver::setMode( int m )
{
timer.stop();
releaseLens();
int old = mode;
mode = m;
vx = copysign( moveX[mode], vx );
vy = copysign( moveY[mode], vy );
int dm = diam;
initLens();
if( hideBG[old] ^ hideBG[m] )
do_refresh( TQRect( 0, 0, width(), height() ) );
else
if( diam < dm )
{
do_refresh( TQRect( (int) x+diam, (int) y, dm-diam, diam ) );
do_refresh( TQRect( (int) x, (int) y+diam, dm, dm-diam ) );
}
timer.start( SCI_MAX_SPEED - speed[mode] );
}
void KScienceSaver::setMoveX( int s )
{
timer.stop();
moveX[mode] = s;
vx = copysign( moveX[mode], vx );
timer.start( SCI_MAX_SPEED - speed[mode] );
}
void KScienceSaver::setMoveY( int s )
{
timer.stop();
moveY[mode] = s;
vy = copysign( moveY[mode], vy );
timer.start( SCI_MAX_SPEED - speed[mode] );
}
void KScienceSaver::setMove( bool s )
{
moveOn = s;
}
void KScienceSaver::setSize( int s )
{
timer.stop();
releaseLens();
int dm = diam;
size[mode] = s;
initLens();
if( diam < dm )
{
do_refresh( TQRect( (int) x+diam, (int) y, dm-diam, diam ) );
do_refresh( TQRect( (int) x, (int) y+diam, dm, dm-diam ) );
}
timer.start( SCI_MAX_SPEED - speed[mode] );
}
void KScienceSaver::setSpeed( int s )
{
speed[mode] = s;
timer.changeInterval( SCI_MAX_SPEED - speed[mode] );
}
void KScienceSaver::setIntensity( int i )
{
timer.stop();
releaseLens();
intensity[mode] = i;
initLens();
timer.start( SCI_MAX_SPEED - speed[mode]);
}
void KScienceSaver::setInverse( bool b )
{
timer.stop();
releaseLens();
inverse[mode] = b;
initLens();
timer.start( SCI_MAX_SPEED - speed[mode]);
}
void KScienceSaver::setGravity( bool b )
{
timer.stop();
releaseLens();
gravity[mode] = b;
vy = copysign( moveY[mode], vy );
initLens();
timer.start( SCI_MAX_SPEED - speed[mode]);
}
void KScienceSaver::setHideBG( bool b )
{
timer.stop();
releaseLens();
hideBG[mode] = b;
initLens();
do_refresh( TQRect( 0, 0, width(), height() ) );
timer.start( SCI_MAX_SPEED - speed[mode]);
}
void KScienceSaver::readSettings()
{
KConfig *config = KGlobal::config();
TQString sMode;
config->setGroup( "Settings" );
mode = config->readNumEntry( "ModeNr", SCI_DEFAULT_MODE );
for(int i=0; i < MAX_MODES; i++)
{
sMode.setNum( i );
config->setGroup( "Mode" + sMode );
moveX[i] = config->readNumEntry( "MoveX", SCI_DEFAULT_MOVEX);
moveY[i] = config->readNumEntry( "MoveY", SCI_DEFAULT_MOVEY);
size[i] = config->readNumEntry( "Size", SCI_DEFAULT_SIZE);
speed[i] = config->readNumEntry( "Speed", SCI_DEFAULT_SPEED);
intensity[i] = config->readNumEntry( "Intensity", SCI_DEFAULT_INTENSITY);
inverse[i] = config->readBoolEntry( "Inverse", SCI_DEFAULT_INVERSE);
gravity[i] = config->readBoolEntry( "Gravity", SCI_DEFAULT_GRAVITY);
hideBG[i] = config->readBoolEntry( "HideBG", SCI_DEFAULT_HIDE);
}
vx = copysign( moveX[mode], vx );
vy = copysign( moveY[mode], vy );
}
void KScienceSaver::do_refresh( const TQRect & rect )
{
if( grabPixmap )
return;
rect.normalize();
if( hideBG[mode] )
{
XSetWindowBackground( tqt_xdisplay(), winId(), black.pixel() );
XClearArea( tqt_xdisplay(), winId(), rect.left(), rect.top(),
rect.width(), rect.height(), false );
}
else
{
myAssert( d->xRootWin != 0, "root window not grabbed" );
XPutImage( tqt_xdisplay(), winId(), d->gc, d->xRootWin,
rect.left(), rect.top(),
rect.left(), rect.top(),
rect.width(), rect.height() );
}
}
void KScienceSaver::slotTimeout()
{
if( grabPixmap ) {
if( !TQWidget::find(winId())->isActiveWindow() )
return;
grabPreviewWidget();
grabPixmap = false;
initialize();
if( hideBG[mode] )
do_refresh( TQRect ( 0, 0, width(), height() ) );
}
signed int oldx = xcoord, oldy = ycoord;
if( gravity[mode] ) {
double h = double(y+1.0) / double(height()-diam);
if( h > 1.0 ) h = 1.0;
vy = sqrt( h ) * ( (vy > 0.0) ? moveY[mode] : -moveY[mode] );
}
myAssert( abs((int)rint(vy)) <= border, "assertion violated: vy <= border" );
if( moveOn )
{
x += vx;
y += vy;
}
if( x <= 0.0 ) {
vx = -vx;
x = 0.0;
}
if( int(x) + diam >= width()) {
vx = -vx;
myAssert( width()-diam > 0, "assertion violated: width-diam > 0" );
x = (double) (width() - diam - 1);
}
if( y <= 0.0 ) {
vy = -vy;
y = 0.0;
}
if( int(y) + diam >= height() ) {
vy = -vy;
myAssert( height() - diam > 0, "assertion violated: height-diam > 0" );
y = (double) (height() - diam - 1);
}
xcoord = (int) x ;
ycoord = (int) y ;
signed int dx = (signed int) xcoord - oldx;
signed int dy = (signed int) ycoord - oldy;
signed int xs, ys, xd, yd, w, h;
if( dx > 0 ) {
w = diam+dx;
xd = oldx;
xs = border-dx;
if( dy > 0 ) {
h = diam+dy;
yd = oldy;
ys = border-dy;
}
else {
h = diam-dy;
yd = ycoord;
ys = border;
}
}
else {
w = diam-dx;
xd = xcoord;
xs = border;
if( dy > 0 ) {
h = diam+dy;
yd = oldy;
ys = border-dy;
} else {
h = diam-dy;
yd = ycoord;
ys = border;
}
}
if( xd + w >= width() ) w = width() - xd - 1;
if( yd + h >= height() ) h = height() - yd - 1;
//printf("%d: (dx: %3d, dy: %3d), diam: %3d, (xc: %3d, yc: %3d), (xs: %3d, ys: %3d), (xd: %3d, yd: %3d), (w: %3d, h: %3d)\n", mode, dx, dy, diam, xcoord, ycoord, xs, ys, xd, yd, w, h);
myAssert( dx <= border && dy <=border, "assertion violated: dx or dy <= border");
myAssert( xcoord >= 0 && ycoord >= 0, "assertion violated: xcoord, ycoord >= 0 ");
myAssert( xd+w < width(), "assertion violated: xd+w < width" );
myAssert( yd+h < height(), "assertion violated: yd+h < height" );
if( hideBG[mode] )
blackPixel( xcoord, ycoord );
(this->*applyLens)(xs, ys, xd, yd, w, h);
XPutImage( tqt_xdisplay(), winId(), d->gc, d->buffer, 0, 0, xd, yd, w, h );
if( hideBG[mode] )
blackPixelUndo( xcoord, ycoord );
}
void KScienceSaver::grabRootWindow()
{
Display *dsp = tqt_xdisplay();
Window rootwin = RootWindow( dsp, tqt_xscreen() );
// grab contents of root window
if( d->xRootWin )
XDestroyImage( d->xRootWin );
d->xRootWin = XGetImage( dsp, rootwin, 0, 0, width(),
height(), AllPlanes, ZPixmap);
myAssert( d->xRootWin, "unable to grab root window\n" );
imgnext = d->xRootWin->bytes_per_line;
bpp = ( d->xRootWin->bits_per_pixel ) >> 3;
}
void KScienceSaver::grabPreviewWidget()
{
myAssert( TQWidget::find(winId())->isActiveWindow(), "can't grab preview widget: dialog not active()" );
if( d->xRootWin )
XDestroyImage( d->xRootWin );
Display *dsp = tqt_xdisplay();
d->xRootWin = XGetImage( dsp, winId(), 0, 0, width(), height(), AllPlanes, ZPixmap);
myAssert( d->xRootWin, "unable to grab preview window\n" );
imgnext = d->xRootWin->bytes_per_line;
bpp = ( d->xRootWin->bits_per_pixel ) >> 3;
}
void KScienceSaver::blackPixel( int x, int y )
{
unsigned char black = (char) BlackPixel( tqt_xdisplay(), tqt_xscreen() );
unsigned int adr = x*bpp + y*imgnext;
for(int i=0; i<bpp; i++) {
blackRestore[i] = d->xRootWin->data[adr];
d->xRootWin->data[adr++] = black;
}
}
void KScienceSaver::blackPixelUndo( int x, int y )
{
unsigned int adr = x*bpp + y*imgnext;
for(int i=0; i<bpp; i++)
d->xRootWin->data[adr++] = blackRestore[i];
}
// hm....
void KScienceSaver::applyLens8bpp(int xs, int ys, int xd, int yd, int w, int h)
{
T32bit *off;
char *img1, *img2, *data;
signed int ix, iy, datanext = d->buffer->bytes_per_line - w;
img1 = d->xRootWin->data + xd + yd*imgnext;
data = d->buffer->data;
for(iy = ys; iy < ys+h; iy++)
{
off = d->offset[iy] + xs;
img2 = img1;
for(ix = w; ix > 0; ix--)
*data++ = img2++[*off++];
img1 += imgnext;
data += datanext;
}
}
void KScienceSaver::applyLens16bpp(int xs, int ys, int xd, int yd, int w, int h)
{
T32bit *off;
char *img1, *img2, *data;
int ix, iy, datanext = d->buffer->bytes_per_line - (w << 1);
img1 = d->xRootWin->data + (xd << 1) + yd*imgnext;
data = d->buffer->data;
for(iy = ys; iy < ys+h; iy++)
{
off = d->offset[iy] + xs;
img2 = img1;
for(ix = w; ix > 0; ix--) {
*data++ = img2++[*off];
*data++ = img2++[*off++];
}
img1 += imgnext;
data += datanext;
}
}
void KScienceSaver::applyLens24bpp(int xs, int ys, int xd, int yd, int w, int h)
{
T32bit *off;
char *img1, *img2, *data;
signed int ix, iy, datanext = d->buffer->bytes_per_line - 3*w;
img1 = d->xRootWin->data + 3*xd + yd*imgnext;
data = d->buffer->data;
for(iy = ys; iy < ys+h; iy++)
{
off = d->offset[iy] + xs;
img2 = img1;
for(ix = w; ix > 0; ix--) {
*data++ = img2++[*off];
*data++ = img2++[*off];
*data++ = img2++[*off++];
}
img1 += imgnext;
data += datanext;
}
}
void KScienceSaver::applyLens32bpp(int xs, int ys, int xd, int yd, int w, int h)
{
T32bit *off;
char *img1, *img2, *data;
signed int ix, iy, datanext = d->buffer->bytes_per_line - (w << 2);
img1 = d->xRootWin->data + (xd << 2) + yd*imgnext;
data = d->buffer->data;
for(iy = ys; iy < ys+h; iy++)
{
off = d->offset[iy] + xs;
img2 = img1;
for(ix = w; ix > 0; ix--) {
*data++ = img2++[*off];
*data++ = img2++[*off];
*data++ = img2++[*off];
*data++ = img2++[*off++];
}
img1 += imgnext;
data += datanext;
}
}
//-----------------------------------------------------------------------------
KScienceSetup::KScienceSetup( TQWidget *parent, const char *name )
: KDialogBase( parent, name, true, i18n( "Setup Science Screen Saver" ),
Ok|Cancel|Help, Ok, true ), saver( 0 )
{
readSettings();
initModeInfo();
TQWidget *main = makeMainWidget();
TQHBoxLayout *lt = new TQHBoxLayout( main, 0, spacingHint());
TQVBoxLayout *ltm = new TQVBoxLayout;
lt->addLayout( ltm );
TQVBoxLayout *ltc = new TQVBoxLayout;
lt->addLayout( ltc );
// mode
TQLabel *label = new TQLabel( i18n("Mode:"), main );
ltm->addWidget( label );
TQListBox *c = new TQListBox( main );
for(int i = 0; i<MAX_MODES; i++)
c->insertItem( modeInfo[i].name );
c->setCurrentItem( mode );
c->setFixedHeight( 5 * c->fontMetrics().height() );
connect( c, TQT_SIGNAL( highlighted( int ) ), TQT_SLOT( slotMode( int ) ) );
ltm->addWidget( c );
// inverse
TQCheckBox *cbox = checkInverse = new TQCheckBox( i18n("Inverse"), main );
cbox->setEnabled( modeInfo[mode].inverseEnable );
cbox->setChecked( inverse[mode] );
connect( cbox, TQT_SIGNAL( clicked() ), TQT_SLOT( slotInverse() ) );
ltm->addWidget( cbox );
// gravity
cbox = checkGravity = new TQCheckBox( i18n("Gravity"), main );
cbox->setChecked( gravity[mode] );
connect( cbox, TQT_SIGNAL( clicked() ), TQT_SLOT( slotGravity() ) );
ltm->addWidget( cbox );
// hide background
cbox = checkHideBG = new TQCheckBox( i18n("Hide background"), main );
cbox->setChecked( hideBG[mode] );
connect( cbox, TQT_SIGNAL( clicked() ), TQT_SLOT( slotHideBG() ) );
ltm->addWidget( cbox );
ltm->addStretch();
// size
label = new TQLabel( i18n("Size:"), main );
ltc->addWidget( label );
slideSize = new TQSlider(9, 50, 5, size[mode], Qt::Horizontal,
main );
slideSize->setMinimumSize( 90, 20 );
slideSize->setTickmarks(TQSlider::Below);
slideSize->setTickInterval(5);
connect( slideSize, TQT_SIGNAL( sliderMoved( int ) ),
TQT_SLOT( slotSize( int ) ) );
connect( slideSize, TQT_SIGNAL( sliderPressed() ),
TQT_SLOT( slotSliderPressed() ) );
connect( slideSize, TQT_SIGNAL( sliderReleased() ),
TQT_SLOT( slotSliderReleased() ) );
ltc->addWidget( slideSize );
// intensity
label = new TQLabel( i18n("Intensity:"), main );
ltc->addWidget( label );
slideIntensity = new TQSlider(0, 10, 1, intensity[mode],
Qt::Horizontal, main );
slideIntensity->setMinimumSize( 90, 20 );
slideIntensity->setTickmarks(TQSlider::Below);
slideIntensity->setTickInterval(1);
connect( slideIntensity, TQT_SIGNAL( sliderMoved( int ) ),
TQT_SLOT( slotIntensity( int )) );
connect( slideIntensity, TQT_SIGNAL( sliderPressed() ),
TQT_SLOT( slotSliderPressed() ) );
connect( slideIntensity, TQT_SIGNAL( sliderReleased() ),
TQT_SLOT( slotSliderReleased() ) );
ltc->addWidget( slideIntensity );
// speed
label = new TQLabel( i18n("Speed:"), main );
ltc->addWidget( label );
slideSpeed = new TQSlider(0, SCI_MAX_SPEED, 10, speed[mode],
Qt::Horizontal, main );
slideSpeed->setMinimumSize( 90, 20 );
slideSpeed->setTickmarks(TQSlider::Below);
slideSpeed->setTickInterval(10);
connect( slideSpeed, TQT_SIGNAL( sliderMoved( int ) ),
TQT_SLOT( slotSpeed( int ) ) );
ltc->addWidget( slideSpeed );
// motion
label = new TQLabel( i18n("Motion:"), main );
ltc->addWidget( label );
TQHBoxLayout *ltcm = new TQHBoxLayout;
ltc->addLayout( ltcm );
slideMoveX = new TQSlider(0, SCI_MAX_MOVE, 5, moveX[mode],
Qt::Horizontal, main );
slideMoveX->setMinimumSize( 40, 20 );
slideMoveX->setTickmarks(TQSlider::Below);
slideMoveX->setTickInterval(5);
connect( slideMoveX, TQT_SIGNAL( sliderMoved( int ) ),
TQT_SLOT( slotMoveX( int ) ) );
ltcm->addWidget( slideMoveX );
slideMoveY = new TQSlider(0, SCI_MAX_MOVE, 5, moveY[mode],
Qt::Horizontal, main );
slideMoveY->setMinimumSize( 40, 20 );
slideMoveY->setTickmarks(TQSlider::Below);
slideMoveY->setTickInterval(5);
connect( slideMoveY, TQT_SIGNAL( sliderMoved( int ) ),
TQT_SLOT( slotMoveY( int ) ) );
ltcm->addWidget( slideMoveY );
ltc->addStretch();
// preview
preview = new KPreviewWidget( main );
preview->setFixedSize( 220, 170 );
TQPixmap p( locate("data", "kscreensaver/pics/kscience.png") );
if( p.isNull() )
preview->setBackgroundColor( black );
else
preview->setBackgroundPixmap( p );
preview->show(); // otherwise saver does not get correct size
lt->addWidget( preview );
// let the preview window display before creating the saver
kapp->processEvents();
saver = new KScienceSaver( preview->winId(), true, !p.isNull() );
preview->notifySaver( saver );
}
KScienceSetup::~KScienceSetup()
{
delete saver; // be sure to delete this first
}
void KScienceSetup::updateSettings()
{
// update dialog
slideMoveX ->setValue( moveX[mode] );
slideMoveY ->setValue( moveY[mode] );
slideSize ->setValue( size[mode] );
slideSpeed ->setValue( speed[mode] );
slideIntensity->setValue( intensity[mode] );
checkInverse ->setEnabled( modeInfo[mode].inverseEnable );
checkInverse ->setChecked( inverse[mode] );
checkGravity ->setChecked( gravity[mode] );
checkHideBG ->setChecked( hideBG[mode] );
}
// read settings from config file
void KScienceSetup::readSettings()
{
KConfig *config = KGlobal::config();
TQString sMode;
config->setGroup( "Settings" );
mode = config->readNumEntry( "ModeNr", SCI_DEFAULT_MODE );
for(int i=0; i < MAX_MODES; i++)
{
sMode.setNum( i );
config->setGroup( "Mode" + sMode );
moveX[i] = config->readNumEntry( "MoveX", SCI_DEFAULT_MOVEX);
moveY[i] = config->readNumEntry( "MoveY", SCI_DEFAULT_MOVEY);
size[i] = config->readNumEntry( "Size", SCI_DEFAULT_SIZE);
speed[i] = config->readNumEntry( "Speed", SCI_DEFAULT_SPEED);
intensity[i] = config->readNumEntry( "Intensity", SCI_DEFAULT_INTENSITY);
inverse[i] = config->readBoolEntry( "Inverse", SCI_DEFAULT_INVERSE);
gravity[i] = config->readBoolEntry( "Gravity", SCI_DEFAULT_GRAVITY);
hideBG[i] = config->readBoolEntry( "HideBG", SCI_DEFAULT_HIDE);
}
}
void KScienceSetup::slotMode( int m )
{
mode = m;
if( saver )
saver->setMode( mode );
updateSettings();
}
void KScienceSetup::slotInverse( )
{
inverse[mode] = checkInverse->isChecked();
if( saver )
saver->setInverse( inverse[mode] );
}
void KScienceSetup::slotGravity( )
{
gravity[mode] = checkGravity->isChecked();
if( saver )
saver->setGravity( gravity[mode] );
}
void KScienceSetup::slotHideBG( )
{
hideBG[mode] = checkHideBG->isChecked();
if( saver )
saver->setHideBG( hideBG[mode] );
}
void KScienceSetup::slotMoveX( int x )
{
moveX[mode] = x;
if( saver )
saver->setMoveX( x );
}
void KScienceSetup::slotMoveY( int y )
{
moveY[mode] = y;
if( saver )
saver->setMoveY( y );
}
void KScienceSetup::slotSize( int s )
{
size[mode] = s;
if( saver )
saver->setSize( s );
}
void KScienceSetup::slotSpeed( int s )
{
speed[mode] = s;
if( saver )
saver->setSpeed( s );
}
void KScienceSetup::slotIntensity( int i )
{
intensity[mode] = i;
if( saver )
saver->setIntensity( i );
}
void KScienceSetup::slotSliderPressed()
{
if( saver )
saver->setMove( false );
}
void KScienceSetup::slotSliderReleased()
{
if( saver )
saver->setMove( true );
}
// Ok pressed - save settings and exit
void KScienceSetup::slotOk()
{
KConfig *config = KGlobal::config();
TQString sSize, sSpeed, sIntensity, sMode;
config->setGroup( "Settings" );
config->writeEntry( "ModeNr", mode );
for(int i=0; i<MAX_MODES; i++)
{
sMode.setNum( i );
config->setGroup( "Mode" + sMode );
config->writeEntry( "MoveX", moveX[i] );
config->writeEntry( "MoveY", moveY[i] );
config->writeEntry( "Size", size[i] );
config->writeEntry( "Speed", speed[i] );
config->writeEntry( "Intensity", intensity[i] );
config->writeEntry( "Inverse", inverse[i] );
config->writeEntry( "Gravity", gravity[i] );
config->writeEntry( "HideBG", hideBG[i] );
}
config->sync();
accept();
}
void KScienceSetup::slotHelp()
{
TQString about = i18n("Science Version 0.26.5\n\nWritten by Rene Beutler (1998)\nrbeutler@g26.ethz.ch");
KMessageBox::about(this,
about);
}