1 //-----------------------------------------------------------------------------
3 // kscience - screen saver for KDE
5 // Copyright (c) Rene Beutler 1998
12 #include <sys/types.h>
18 #include <q3listbox.h>
19 #include <qcheckbox.h>
23 #include <QVBoxLayout>
24 #include <QHBoxLayout>
25 #include <QPaintEvent>
27 #include <kapplication.h>
29 #include <kmessagebox.h>
32 #include <kstandarddirs.h>
33 #include <krandomsequence.h>
36 #include "science.moc"
38 #if defined Q_WS_X11 && !defined K_WS_QTONLY
40 #include <X11/Xutil.h>
43 #define SCI_DEFAULT_MODE 0
44 #define SCI_DEFAULT_MOVEX 6
45 #define SCI_DEFAULT_MOVEY 8
46 #define SCI_DEFAULT_SIZE 15
47 #define SCI_DEFAULT_INTENSITY 4
48 #define SCI_DEFAULT_SPEED 70
49 #define SCI_DEFAULT_INVERSE false
50 #define SCI_DEFAULT_GRAVITY false
51 #define SCI_DEFAULT_HIDE false
52 #define SCI_MAX_SPEED 100
53 #define SCI_MAX_MOVE 20
58 // libkscreensaver interface
59 class KScienceSaverInterface
: public KScreenSaverInterface
64 virtual KAboutData
* aboutData() {
65 return new KAboutData( "kscience.kss", I18N_NOOP( "Science Screen Saver" ), "2.2.0", I18N_NOOP( "Science Screen Saver" ) );
69 virtual KScreenSaver
* create( WId id
)
71 return new KScienceSaver( id
);
74 virtual QDialog
* setup()
76 return new KScienceSetup();
80 int main( int argc
, char *argv
[] )
82 KScienceSaverInterface kss
;
83 return kScreenSaverMain( argc
, argv
, kss
);
89 } modeInfo
[MAX_MODES
];
91 enum { MODE_WHIRL
=0, MODE_CURVATURE
, MODE_SPHERE
, MODE_WAVE
, MODE_EXPONENTIAL
, MODE_CONTRACTION
};
95 modeInfo
[MODE_WHIRL
].name
= i18n( "Whirl" );
96 modeInfo
[MODE_WHIRL
].inverseEnable
= true;
98 modeInfo
[MODE_SPHERE
].name
= i18n( "Sphere" );
99 modeInfo
[MODE_SPHERE
].inverseEnable
= true;
101 modeInfo
[MODE_EXPONENTIAL
].name
= i18n( "Exponential" );
102 modeInfo
[MODE_EXPONENTIAL
].inverseEnable
= false;
104 modeInfo
[MODE_CONTRACTION
].name
= i18n( "Contraction" );
105 modeInfo
[MODE_CONTRACTION
].inverseEnable
= false;
107 modeInfo
[MODE_WAVE
].name
= i18n( "Wave" );
108 modeInfo
[MODE_WAVE
].inverseEnable
= false;
110 modeInfo
[MODE_CURVATURE
].name
= i18n( "Curvature" );
111 modeInfo
[MODE_CURVATURE
].inverseEnable
= true;
114 //-----------------------------------------------------------------------------
118 KPreviewWidget::KPreviewWidget( QWidget
*parent
) :
119 QWidget ( parent
) { }
121 void KPreviewWidget::paintEvent( QPaintEvent
*event
)
124 saver
->do_refresh( event
->rect() );
127 void KPreviewWidget::notifySaver( KScienceSaver
*s
)
132 //-----------------------------------------------------------------------------
144 KScienceSaver::KScienceSaver( WId id
, bool s
, bool gP
)
147 d
= new KScienceData
;
148 d
->gc
= XCreateGC(QX11Info::display(), id
, 0, 0);
163 do_refresh( QRect ( 0, 0, width(), height() ) );
166 connect( &timer
, SIGNAL( timeout() ), SLOT( slotTimeout() ) );
167 timer
.start( SCI_MAX_SPEED
- speed
[mode
] );
170 KScienceSaver::~KScienceSaver()
175 XDestroyImage( d
->xRootWin
);
176 XFreeGC(QX11Info::display(), d
->gc
);
180 void KScienceSaver::myAssert( bool term
, const char *eMsg
)
183 fprintf(stderr
, "Error in KScreensaver - mode Science: %s\n", eMsg
);
189 void KScienceSaver::initialize()
193 signed int ws
= (signed int) (width() - diam
);
194 signed int hs
= (signed int) (height() - diam
);
196 x
= (ws
> 0) ? (rnd
.getDouble() * ws
) : 0.0;
197 y
= (hs
> 0) ? (rnd
.getDouble() * hs
) : 0.0;
203 case 1 : applyLens
= &KScienceSaver::applyLens8bpp
; break;
204 case 2 : applyLens
= &KScienceSaver::applyLens16bpp
; break;
205 case 3 : applyLens
= &KScienceSaver::applyLens24bpp
; break;
206 case 4 : applyLens
= &KScienceSaver::applyLens32bpp
; break;
207 default: myAssert( false, "unsupported colordepth "\
208 "(only 8, 16, 24, 32 bpp supported)" );
212 void KScienceSaver::initWhirlLens()
214 double dx
, dy
, r
, phi
, intens
;
218 intens
= double( intensity
[mode
] + 1) / 5.0;
222 for(int y
= side
-1; y
>= 0; y
--)
225 off
= d
->offset
[y
] = (T32bit
*) malloc(sizeof(T32bit
) * side
);
226 myAssert( off
!= 0, "too few memory" );
227 for(int x
= side
-1; x
>= 0; x
--)
230 r
= sqrt( dx
*dx
+ dy
*dy
);
235 phi
= (dy
> 0.0) ? M_PI_2
:-(M_PI_2
);
237 phi
= atan2( dy
, dx
);
238 phi
+= intens
* ( radius
- r
) / ( r
+7.0 );
239 xo
= (T32bit
) ( origin
+ r
*cos( phi
) - x
);
240 yo
= (T32bit
) ( origin
+ r
*sin( phi
) - y
);
241 off
[x
] = xo
*bpp
+ yo
*imgnext
;
245 off
[x
] = (border
-y
)*imgnext
+ (border
-x
)*bpp
;
252 void KScienceSaver::initSphereLens()
254 double dx
, dy
, r
, xr
, yr
, phi
, intens
;
258 intens
= 1.0 - double( intensity
[mode
] ) / 20.0;
263 for(int y
= side
-1; y
>= 0; y
--)
266 off
= d
->offset
[y
] = (T32bit
*) malloc(sizeof(T32bit
) * side
);
267 myAssert( off
!= 0, "too few memory" );
268 for(int x
= side
-1; x
>= 0; x
--)
271 r
= sqrt( dx
*dx
+ dy
*dy
);
275 xr
= (double) radius
*cos(asin(dy
/radius
));
276 yr
= (double) radius
*cos(asin(dx
/radius
));
277 phi
= (xr
!= 0.0) ? asin(dx
/xr
) : 0.0;
278 xo
= (T32bit
) (origin
+ intens
*2.0*phi
*xr
/ M_PI
- x
);
279 phi
= (yr
!= 0.0) ? asin(dy
/yr
) : 0.0;
280 yo
= (T32bit
) (origin
+ intens
*2.0*phi
*yr
/ M_PI
- y
);
281 off
[x
] = xo
*bpp
+ yo
*imgnext
;
285 off
[x
] = (border
-y
)*imgnext
+ (border
-x
)*bpp
;
292 void KScienceSaver::initExponentialLens()
294 double dx
, dy
, r
, rnew
, f
, intens
;
298 if( mode
== MODE_EXPONENTIAL
)
299 intens
= - (0.1 + 0.8 * double( intensity
[mode
] + 2) / 10.0);
301 intens
= 0.9 - 0.8 * double( intensity
[mode
] ) / 10.0;
303 for(int y
= side
-1; y
>= 0; y
--)
306 off
= d
->offset
[y
] = (T32bit
*) malloc(sizeof(T32bit
) * side
);
307 myAssert( off
!= 0, "too few memory" );
308 for(int x
= side
-1; x
>= 0; x
--)
311 r
= sqrt( dx
*dx
+ dy
*dy
);
319 rnew
= radius
*(pow(r
, intens
) / pow(radius
, intens
));
320 f
= double ((int)rnew
% radius
) / r
;
322 xo
= (T32bit
) ( origin
+ f
*dx
- x
);
323 yo
= (T32bit
) ( origin
+ f
*dy
- y
);
324 off
[x
] = xo
*bpp
+ yo
*imgnext
;
328 off
[x
] = (border
-y
)*imgnext
+ (border
-x
)*bpp
;
335 void KScienceSaver::initCurvatureLens()
337 double dx
, dy
, r
, f
, intens
;
341 intens
= (double) radius
*intensity
[mode
] / 20.0;
342 if( inverse
[mode
] ) intens
= -intens
;
344 for(int y
= side
-1; y
>= 0; y
--)
347 off
= d
->offset
[y
] = (T32bit
*) malloc(sizeof(T32bit
) * side
);
348 myAssert( off
!= 0, "too few memory" );
349 for(int x
= side
-1; x
>= 0; x
--)
352 r
= sqrt( dx
*dx
+ dy
*dy
);
359 f
= (r
- intens
* sin(M_PI
* r
/(double)radius
)) / r
;
360 xo
= (T32bit
) ( origin
+ f
*dx
- x
);
361 yo
= (T32bit
) ( origin
+ f
*dy
- y
);
362 off
[x
] = xo
*bpp
+ yo
*imgnext
;
366 off
[x
] = (border
-y
)*imgnext
+ (border
-x
)*bpp
;
373 void KScienceSaver::initWaveLens()
375 double dx
, dy
, r
, rnew
, f
, intens
, k
;
379 intens
= (double) intensity
[mode
] + 1.0;
380 k
= (intensity
[mode
] % 2) ? -12.0 : 12.0;
382 for(int y
= side
-1; y
>= 0; y
--)
385 off
= d
->offset
[y
] = (T32bit
*) malloc(sizeof(T32bit
) * side
);
386 myAssert( off
!= 0, "too few memory" );
387 for(int x
= side
-1; x
>= 0; x
--)
390 r
= sqrt( dx
*dx
+ dy
*dy
);
398 rnew
= r
- k
* sin( M_PI
* intens
* r
/(double)radius
);
399 f
= double ((int)rnew
% radius
) / r
;
401 xo
= (T32bit
) ( origin
+ f
*dx
- x
);
402 yo
= (T32bit
) ( origin
+ f
*dy
- y
);
403 off
[x
] = xo
*bpp
+ yo
*imgnext
;
407 off
[x
] = (border
-y
)*imgnext
+ (border
-x
)*bpp
;
414 void KScienceSaver::initLens()
416 int min
= (width() < height()) ? width() : height();
417 border
= 1 + SCI_MAX_MOVE
;
419 radius
= (size
[mode
] * min
) / 100;
420 if( radius
<<1 == min
) radius
--;
422 myAssert( diam
< min
, "assertion violated: diam < min" );
423 origin
= radius
+ border
;
426 d
->buffer
= XSubImage( d
->xRootWin
, 0, 0, side
, side
);
427 myAssert( d
->buffer
!= 0, "can't allocate pixmap" );
429 d
->offset
= (T32bit
**) malloc( sizeof(T32bit
*) * side
);
430 myAssert( d
->offset
!= 0, "too few memory" );
433 case MODE_WHIRL
: initWhirlLens(); break;
434 case MODE_SPHERE
: initSphereLens(); break;
435 case MODE_EXPONENTIAL
:
436 case MODE_CONTRACTION
: initExponentialLens(); break;
437 case MODE_CURVATURE
: initCurvatureLens(); break;
438 case MODE_WAVE
: initWaveLens(); break;
439 default: myAssert( false, "internal error (wrong mode in initLens() )" );
443 void KScienceSaver::releaseLens()
445 if( d
->offset
!= 0 ) {
446 for(int i
=0; i
<side
; i
++)
447 if( d
->offset
[i
] != 0 ) free( d
->offset
[i
] );
451 if( d
->buffer
!= 0 ) {
452 XDestroyImage( d
->buffer
);
457 void KScienceSaver::setMode( int m
)
464 vx
= copysign( moveX
[mode
], vx
);
465 vy
= copysign( moveY
[mode
], vy
);
468 if( hideBG
[old
] ^ hideBG
[m
] )
469 do_refresh( QRect( 0, 0, width(), height() ) );
473 do_refresh( QRect( (int) x
+diam
, (int) y
, dm
-diam
, diam
) );
474 do_refresh( QRect( (int) x
, (int) y
+diam
, dm
, dm
-diam
) );
477 timer
.start( SCI_MAX_SPEED
- speed
[mode
] );
480 void KScienceSaver::setMoveX( int s
)
485 vx
= copysign( moveX
[mode
], vx
);
487 timer
.start( SCI_MAX_SPEED
- speed
[mode
] );
490 void KScienceSaver::setMoveY( int s
)
495 vy
= copysign( moveY
[mode
], vy
);
497 timer
.start( SCI_MAX_SPEED
- speed
[mode
] );
500 void KScienceSaver::setMove( bool s
)
505 void KScienceSaver::setSize( int s
)
515 do_refresh( QRect( (int) x
+diam
, (int) y
, dm
-diam
, diam
) );
516 do_refresh( QRect( (int) x
, (int) y
+diam
, dm
, dm
-diam
) );
519 timer
.start( SCI_MAX_SPEED
- speed
[mode
] );
522 void KScienceSaver::setSpeed( int s
)
526 timer
.changeInterval( SCI_MAX_SPEED
- speed
[mode
] );
529 void KScienceSaver::setIntensity( int i
)
537 timer
.start( SCI_MAX_SPEED
- speed
[mode
]);
540 void KScienceSaver::setInverse( bool b
)
548 timer
.start( SCI_MAX_SPEED
- speed
[mode
]);
551 void KScienceSaver::setGravity( bool b
)
557 vy
= copysign( moveY
[mode
], vy
);
560 timer
.start( SCI_MAX_SPEED
- speed
[mode
]);
563 void KScienceSaver::setHideBG( bool b
)
570 do_refresh( QRect( 0, 0, width(), height() ) );
572 timer
.start( SCI_MAX_SPEED
- speed
[mode
]);
575 void KScienceSaver::readSettings()
577 KConfig
*config
= KGlobal::config();
580 config
->setGroup( "Settings" );
581 mode
= config
->readNumEntry( "ModeNr", SCI_DEFAULT_MODE
);
583 for(int i
=0; i
< MAX_MODES
; i
++)
586 config
->setGroup( "Mode" + sMode
);
587 moveX
[i
] = config
->readNumEntry( "MoveX", SCI_DEFAULT_MOVEX
);
588 moveY
[i
] = config
->readNumEntry( "MoveY", SCI_DEFAULT_MOVEY
);
589 size
[i
] = config
->readNumEntry( "Size", SCI_DEFAULT_SIZE
);
590 speed
[i
] = config
->readNumEntry( "Speed", SCI_DEFAULT_SPEED
);
591 intensity
[i
] = config
->readNumEntry( "Intensity", SCI_DEFAULT_INTENSITY
);
592 inverse
[i
] = config
->readBoolEntry( "Inverse", SCI_DEFAULT_INVERSE
);
593 gravity
[i
] = config
->readBoolEntry( "Gravity", SCI_DEFAULT_GRAVITY
);
594 hideBG
[i
] = config
->readBoolEntry( "HideBG", SCI_DEFAULT_HIDE
);
597 vx
= copysign( moveX
[mode
], vx
);
598 vy
= copysign( moveY
[mode
], vy
);
601 void KScienceSaver::do_refresh( const QRect
& rect
)
609 XSetWindowBackground( QX11Info::display(), winId(), QColor(Qt::black
).pixel() );
610 XClearArea( QX11Info::display(), winId(), rect
.left(), rect
.top(),
611 rect
.width(), rect
.height(), false );
615 myAssert( d
->xRootWin
!= 0, "root window not grabbed" );
616 XPutImage( QX11Info::display(), winId(), d
->gc
, d
->xRootWin
,
617 rect
.left(), rect
.top(),
618 rect
.left(), rect
.top(),
619 rect
.width(), rect
.height() );
623 void KScienceSaver::slotTimeout()
626 if( !QWidget::find(winId())->isActiveWindow() )
632 do_refresh( QRect ( 0, 0, width(), height() ) );
635 signed int oldx
= xcoord
, oldy
= ycoord
;
637 if( gravity
[mode
] ) {
638 double h
= double(y
+1.0) / double(height()-diam
);
639 if( h
> 1.0 ) h
= 1.0;
640 vy
= sqrt( h
) * ( (vy
> 0.0) ? moveY
[mode
] : -moveY
[mode
] );
642 myAssert( abs((int)rint(vy
)) <= border
, "assertion violated: vy <= border" );
654 if( int(x
) + diam
>= width()) {
656 myAssert( width()-diam
> 0, "assertion violated: width-diam > 0" );
657 x
= (double) (width() - diam
- 1);
663 if( int(y
) + diam
>= height() ) {
665 myAssert( height() - diam
> 0, "assertion violated: height-diam > 0" );
666 y
= (double) (height() - diam
- 1);
671 signed int dx
= (signed int) xcoord
- oldx
;
672 signed int dy
= (signed int) ycoord
- oldy
;
673 signed int xs
, ys
, xd
, yd
, w
, h
;
705 if( xd
+ w
>= width() ) w
= width() - xd
- 1;
706 if( yd
+ h
>= height() ) h
= height() - yd
- 1;
708 //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);
709 myAssert( dx
<= border
&& dy
<=border
, "assertion violated: dx or dy <= border");
710 myAssert( xcoord
>= 0 && ycoord
>= 0, "assertion violated: xcoord, ycoord >= 0 ");
711 myAssert( xd
+w
< width(), "assertion violated: xd+w < width" );
712 myAssert( yd
+h
< height(), "assertion violated: yd+h < height" );
715 blackPixel( xcoord
, ycoord
);
716 (this->*applyLens
)(xs
, ys
, xd
, yd
, w
, h
);
717 XPutImage( QX11Info::display(), winId(), d
->gc
, d
->buffer
, 0, 0, xd
, yd
, w
, h
);
719 blackPixelUndo( xcoord
, ycoord
);
722 void KScienceSaver::grabRootWindow()
724 Display
*dsp
= QX11Info::display();
725 Window rootwin
= RootWindow( dsp
, QX11Info::appScreen() );
727 // grab contents of root window
729 XDestroyImage( d
->xRootWin
);
731 d
->xRootWin
= XGetImage( dsp
, rootwin
, 0, 0, width(),
732 height(), AllPlanes
, ZPixmap
);
733 myAssert( d
->xRootWin
, "unable to grab root window\n" );
735 imgnext
= d
->xRootWin
->bytes_per_line
;
736 bpp
= ( d
->xRootWin
->bits_per_pixel
) >> 3;
739 void KScienceSaver::grabPreviewWidget()
741 myAssert( QWidget::find(winId())->isActiveWindow(), "can't grab preview widget: dialog not active()" );
744 XDestroyImage( d
->xRootWin
);
746 Display
*dsp
= QX11Info::display();
747 d
->xRootWin
= XGetImage( dsp
, winId(), 0, 0, width(), height(), AllPlanes
, ZPixmap
);
748 myAssert( d
->xRootWin
, "unable to grab preview window\n" );
750 imgnext
= d
->xRootWin
->bytes_per_line
;
751 bpp
= ( d
->xRootWin
->bits_per_pixel
) >> 3;
754 void KScienceSaver::blackPixel( int x
, int y
)
756 unsigned char black
= (char) BlackPixel( QX11Info::display(), QX11Info::appScreen() );
757 unsigned int adr
= x
*bpp
+ y
*imgnext
;
759 for(int i
=0; i
<bpp
; i
++) {
760 blackRestore
[i
] = d
->xRootWin
->data
[adr
];
761 d
->xRootWin
->data
[adr
++] = black
;
765 void KScienceSaver::blackPixelUndo( int x
, int y
)
767 unsigned int adr
= x
*bpp
+ y
*imgnext
;
768 for(int i
=0; i
<bpp
; i
++)
769 d
->xRootWin
->data
[adr
++] = blackRestore
[i
];
774 void KScienceSaver::applyLens8bpp(int xs
, int ys
, int xd
, int yd
, int w
, int h
)
777 char *img1
, *img2
, *data
;
778 signed int ix
, iy
, datanext
= d
->buffer
->bytes_per_line
- w
;
780 img1
= d
->xRootWin
->data
+ xd
+ yd
*imgnext
;
781 data
= d
->buffer
->data
;
782 for(iy
= ys
; iy
< ys
+h
; iy
++)
784 off
= d
->offset
[iy
] + xs
;
786 for(ix
= w
; ix
> 0; ix
--)
787 *data
++ = img2
++[*off
++];
794 void KScienceSaver::applyLens16bpp(int xs
, int ys
, int xd
, int yd
, int w
, int h
)
797 char *img1
, *img2
, *data
;
798 int ix
, iy
, datanext
= d
->buffer
->bytes_per_line
- (w
<< 1);
800 img1
= d
->xRootWin
->data
+ (xd
<< 1) + yd
*imgnext
;
801 data
= d
->buffer
->data
;
802 for(iy
= ys
; iy
< ys
+h
; iy
++)
804 off
= d
->offset
[iy
] + xs
;
806 for(ix
= w
; ix
> 0; ix
--) {
807 *data
++ = img2
++[*off
];
808 *data
++ = img2
++[*off
++];
815 void KScienceSaver::applyLens24bpp(int xs
, int ys
, int xd
, int yd
, int w
, int h
)
818 char *img1
, *img2
, *data
;
819 signed int ix
, iy
, datanext
= d
->buffer
->bytes_per_line
- 3*w
;
821 img1
= d
->xRootWin
->data
+ 3*xd
+ yd
*imgnext
;
822 data
= d
->buffer
->data
;
823 for(iy
= ys
; iy
< ys
+h
; iy
++)
825 off
= d
->offset
[iy
] + xs
;
827 for(ix
= w
; ix
> 0; ix
--) {
828 *data
++ = img2
++[*off
];
829 *data
++ = img2
++[*off
];
830 *data
++ = img2
++[*off
++];
837 void KScienceSaver::applyLens32bpp(int xs
, int ys
, int xd
, int yd
, int w
, int h
)
840 char *img1
, *img2
, *data
;
841 signed int ix
, iy
, datanext
= d
->buffer
->bytes_per_line
- (w
<< 2);
843 img1
= d
->xRootWin
->data
+ (xd
<< 2) + yd
*imgnext
;
844 data
= d
->buffer
->data
;
845 for(iy
= ys
; iy
< ys
+h
; iy
++)
847 off
= d
->offset
[iy
] + xs
;
849 for(ix
= w
; ix
> 0; ix
--) {
850 *data
++ = img2
++[*off
];
851 *data
++ = img2
++[*off
];
852 *data
++ = img2
++[*off
];
853 *data
++ = img2
++[*off
++];
861 //-----------------------------------------------------------------------------
863 KScienceSetup::KScienceSetup( QWidget
*parent
, const char *name
)
867 setCaption(i18n( "Setup Science Screen Saver" ));
869 setButtons(Ok
|Cancel
|Help
);
870 setDefaultButton(Ok
);
871 showButtonSeparator(true);
875 QWidget
*main
= new QWidget(this);
878 QHBoxLayout
*lt
= new QHBoxLayout( main
, 0, spacingHint());
879 QVBoxLayout
*ltm
= new QVBoxLayout
;
880 lt
->addLayout( ltm
);
881 QVBoxLayout
*ltc
= new QVBoxLayout
;
882 lt
->addLayout( ltc
);
885 QLabel
*label
= new QLabel( i18n("Mode:"), main
);
886 ltm
->addWidget( label
);
888 Q3ListBox
*c
= new Q3ListBox( main
);
889 for(int i
= 0; i
<MAX_MODES
; i
++)
890 c
->insertItem( modeInfo
[i
].name
);
891 c
->setCurrentItem( mode
);
892 c
->setFixedHeight( 5 * c
->fontMetrics().height() );
893 connect( c
, SIGNAL( highlighted( int ) ), SLOT( slotMode( int ) ) );
897 QCheckBox
*cbox
= checkInverse
= new QCheckBox( i18n("Inverse"), main
);
898 cbox
->setEnabled( modeInfo
[mode
].inverseEnable
);
899 cbox
->setChecked( inverse
[mode
] );
900 connect( cbox
, SIGNAL( clicked() ), SLOT( slotInverse() ) );
901 ltm
->addWidget( cbox
);
904 cbox
= checkGravity
= new QCheckBox( i18n("Gravity"), main
);
905 cbox
->setChecked( gravity
[mode
] );
906 connect( cbox
, SIGNAL( clicked() ), SLOT( slotGravity() ) );
907 ltm
->addWidget( cbox
);
910 cbox
= checkHideBG
= new QCheckBox( i18n("Hide background"), main
);
911 cbox
->setChecked( hideBG
[mode
] );
912 connect( cbox
, SIGNAL( clicked() ), SLOT( slotHideBG() ) );
913 ltm
->addWidget( cbox
);
917 label
= new QLabel( i18n("Size:"), main
);
918 ltc
->addWidget( label
);
920 slideSize
= new QSlider(9, 50, 5, size
[mode
], Qt::Horizontal
,
922 slideSize
->setMinimumSize( 90, 20 );
923 slideSize
->setTickPosition(QSlider::TicksBelow
);
924 slideSize
->setTickInterval(5);
925 connect( slideSize
, SIGNAL( sliderMoved( int ) ),
926 SLOT( slotSize( int ) ) );
927 connect( slideSize
, SIGNAL( sliderPressed() ),
928 SLOT( slotSliderPressed() ) );
929 connect( slideSize
, SIGNAL( sliderReleased() ),
930 SLOT( slotSliderReleased() ) );
932 ltc
->addWidget( slideSize
);
935 label
= new QLabel( i18n("Intensity:"), main
);
936 ltc
->addWidget( label
);
938 slideIntensity
= new QSlider(0, 10, 1, intensity
[mode
],
939 Qt::Horizontal
, main
);
940 slideIntensity
->setMinimumSize( 90, 20 );
941 slideIntensity
->setTickPosition(QSlider::TicksBelow
);
942 slideIntensity
->setTickInterval(1);
943 connect( slideIntensity
, SIGNAL( sliderMoved( int ) ),
944 SLOT( slotIntensity( int )) );
945 connect( slideIntensity
, SIGNAL( sliderPressed() ),
946 SLOT( slotSliderPressed() ) );
947 connect( slideIntensity
, SIGNAL( sliderReleased() ),
948 SLOT( slotSliderReleased() ) );
949 ltc
->addWidget( slideIntensity
);
952 label
= new QLabel( i18n("Speed:"), main
);
953 ltc
->addWidget( label
);
955 slideSpeed
= new QSlider(0, SCI_MAX_SPEED
, 10, speed
[mode
],
956 Qt::Horizontal
, main
);
957 slideSpeed
->setMinimumSize( 90, 20 );
958 slideSpeed
->setTickPosition(QSlider::TicksBelow
);
959 slideSpeed
->setTickInterval(10);
960 connect( slideSpeed
, SIGNAL( sliderMoved( int ) ),
961 SLOT( slotSpeed( int ) ) );
962 ltc
->addWidget( slideSpeed
);
965 label
= new QLabel( i18n("Motion:"), main
);
966 ltc
->addWidget( label
);
968 QHBoxLayout
*ltcm
= new QHBoxLayout
;
969 ltc
->addLayout( ltcm
);
971 slideMoveX
= new QSlider(0, SCI_MAX_MOVE
, 5, moveX
[mode
],
972 Qt::Horizontal
, main
);
973 slideMoveX
->setMinimumSize( 40, 20 );
974 slideMoveX
->setTickPosition(QSlider::TicksBelow
);
975 slideMoveX
->setTickInterval(5);
976 connect( slideMoveX
, SIGNAL( sliderMoved( int ) ),
977 SLOT( slotMoveX( int ) ) );
978 ltcm
->addWidget( slideMoveX
);
980 slideMoveY
= new QSlider(0, SCI_MAX_MOVE
, 5, moveY
[mode
],
981 Qt::Horizontal
, main
);
982 slideMoveY
->setMinimumSize( 40, 20 );
983 slideMoveY
->setTickPosition(QSlider::TicksBelow
);
984 slideMoveY
->setTickInterval(5);
985 connect( slideMoveY
, SIGNAL( sliderMoved( int ) ),
986 SLOT( slotMoveY( int ) ) );
987 ltcm
->addWidget( slideMoveY
);
992 preview
= new KPreviewWidget( main
);
993 preview
->setFixedSize( 220, 170 );
994 QPixmap
p( KStandardDirs::locate("data", "kscreensaver/pics/kscience.png") );
996 preview
->setBackgroundColor( Qt::black
);
998 preview
->setBackgroundPixmap( p
);
999 preview
->show(); // otherwise saver does not get correct size
1000 lt
->addWidget( preview
);
1002 // let the preview window display before creating the saver
1003 kapp
->processEvents();
1005 saver
= new KScienceSaver( preview
->winId(), true, !p
.isNull() );
1006 preview
->notifySaver( saver
);
1007 connect(this,SIGNAL(okClicked()),SLOT(slotOk()));
1010 KScienceSetup::~KScienceSetup()
1012 delete saver
; // be sure to delete this first
1015 void KScienceSetup::updateSettings()
1018 slideMoveX
->setValue( moveX
[mode
] );
1019 slideMoveY
->setValue( moveY
[mode
] );
1020 slideSize
->setValue( size
[mode
] );
1021 slideSpeed
->setValue( speed
[mode
] );
1022 slideIntensity
->setValue( intensity
[mode
] );
1023 checkInverse
->setEnabled( modeInfo
[mode
].inverseEnable
);
1024 checkInverse
->setChecked( inverse
[mode
] );
1025 checkGravity
->setChecked( gravity
[mode
] );
1026 checkHideBG
->setChecked( hideBG
[mode
] );
1029 // read settings from config file
1030 void KScienceSetup::readSettings()
1032 KConfig
*config
= KGlobal::config();
1035 config
->setGroup( "Settings" );
1036 mode
= config
->readNumEntry( "ModeNr", SCI_DEFAULT_MODE
);
1038 for(int i
=0; i
< MAX_MODES
; i
++)
1041 config
->setGroup( "Mode" + sMode
);
1042 moveX
[i
] = config
->readNumEntry( "MoveX", SCI_DEFAULT_MOVEX
);
1043 moveY
[i
] = config
->readNumEntry( "MoveY", SCI_DEFAULT_MOVEY
);
1044 size
[i
] = config
->readNumEntry( "Size", SCI_DEFAULT_SIZE
);
1045 speed
[i
] = config
->readNumEntry( "Speed", SCI_DEFAULT_SPEED
);
1046 intensity
[i
] = config
->readNumEntry( "Intensity", SCI_DEFAULT_INTENSITY
);
1047 inverse
[i
] = config
->readBoolEntry( "Inverse", SCI_DEFAULT_INVERSE
);
1048 gravity
[i
] = config
->readBoolEntry( "Gravity", SCI_DEFAULT_GRAVITY
);
1049 hideBG
[i
] = config
->readBoolEntry( "HideBG", SCI_DEFAULT_HIDE
);
1053 void KScienceSetup::slotMode( int m
)
1058 saver
->setMode( mode
);
1063 void KScienceSetup::slotInverse( )
1065 inverse
[mode
] = checkInverse
->isChecked();
1068 saver
->setInverse( inverse
[mode
] );
1071 void KScienceSetup::slotGravity( )
1073 gravity
[mode
] = checkGravity
->isChecked();
1076 saver
->setGravity( gravity
[mode
] );
1079 void KScienceSetup::slotHideBG( )
1081 hideBG
[mode
] = checkHideBG
->isChecked();
1084 saver
->setHideBG( hideBG
[mode
] );
1087 void KScienceSetup::slotMoveX( int x
)
1092 saver
->setMoveX( x
);
1095 void KScienceSetup::slotMoveY( int y
)
1100 saver
->setMoveY( y
);
1103 void KScienceSetup::slotSize( int s
)
1108 saver
->setSize( s
);
1111 void KScienceSetup::slotSpeed( int s
)
1116 saver
->setSpeed( s
);
1119 void KScienceSetup::slotIntensity( int i
)
1121 intensity
[mode
] = i
;
1124 saver
->setIntensity( i
);
1127 void KScienceSetup::slotSliderPressed()
1130 saver
->setMove( false );
1133 void KScienceSetup::slotSliderReleased()
1136 saver
->setMove( true );
1139 // Ok pressed - save settings and exit
1140 void KScienceSetup::slotOk()
1142 KConfig
*config
= KGlobal::config();
1143 QString sSize
, sSpeed
, sIntensity
, sMode
;
1145 config
->setGroup( "Settings" );
1146 config
->writeEntry( "ModeNr", mode
);
1148 for(int i
=0; i
<MAX_MODES
; i
++)
1151 config
->setGroup( "Mode" + sMode
);
1152 config
->writeEntry( "MoveX", moveX
[i
] );
1153 config
->writeEntry( "MoveY", moveY
[i
] );
1154 config
->writeEntry( "Size", size
[i
] );
1155 config
->writeEntry( "Speed", speed
[i
] );
1156 config
->writeEntry( "Intensity", intensity
[i
] );
1157 config
->writeEntry( "Inverse", inverse
[i
] );
1158 config
->writeEntry( "Gravity", gravity
[i
] );
1159 config
->writeEntry( "HideBG", hideBG
[i
] );
1167 void KScienceSetup::slotHelp()
1169 QString about
= i18n("Science Version 0.26.5\n\nWritten by Rene Beutler (1998)\nrbeutler@g26.ethz.ch");
1170 KMessageBox::about(this,