summaryrefslogtreecommitdiff
path: root/noncore/multimedia/opieplayer2/videowidget.cpp
Unidiff
Diffstat (limited to 'noncore/multimedia/opieplayer2/videowidget.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/opieplayer2/videowidget.cpp473
1 files changed, 473 insertions, 0 deletions
diff --git a/noncore/multimedia/opieplayer2/videowidget.cpp b/noncore/multimedia/opieplayer2/videowidget.cpp
new file mode 100644
index 0000000..5625c0e
--- a/dev/null
+++ b/noncore/multimedia/opieplayer2/videowidget.cpp
@@ -0,0 +1,473 @@
1
2#include <qpe/resource.h>
3#include <qpe/mediaplayerplugininterface.h>
4#include <qpe/config.h>
5
6#include <qwidget.h>
7#include <qpainter.h>
8#include <qpixmap.h>
9#include <qslider.h>
10#include <qdrawutil.h>
11#include "videowidget.h"
12#include "mediaplayerstate.h"
13
14
15#ifdef Q_WS_QWS
16# define USE_DIRECT_PAINTER
17# include <qdirectpainter_qws.h>
18# include <qgfxraster_qws.h>
19#endif
20
21
22extern MediaPlayerState *mediaPlayerState;
23
24
25static const int xo = 2; // movable x offset
26static const int yo = 0; // movable y offset
27
28
29struct MediaButton {
30 int xPos, yPos;
31 bool isToggle, isHeld, isDown;
32 int controlType;
33};
34
35
36// Layout information for the videoButtons (and if it is a toggle button or not)
37MediaButton videoButtons[] = {
38 { 5+0*32+xo, 200+yo, FALSE, FALSE, FALSE, 4 }, // previous
39 { 5+1*32+xo, 200+yo, FALSE, FALSE, FALSE, 1 }, // stop
40 { 5+2*32+xo, 200+yo, TRUE, FALSE, FALSE, 0 }, // play
41 { 5+3*32+xo, 200+yo, TRUE, FALSE, FALSE, 2 }, // pause
42 { 5+4*32+xo, 200+yo, FALSE, FALSE, FALSE, 3 }, // next
43 { 5+5*32+xo, 200+yo, FALSE, FALSE, FALSE, 8 }, // playlist
44 { 5+6*32+xo, 200+yo, TRUE, FALSE, FALSE, 9 } // fullscreen
45};
46
47
48static const int numButtons = (sizeof(videoButtons)/sizeof(MediaButton));
49
50
51VideoWidget::VideoWidget(QWidget* parent, const char* name, WFlags f) :
52 QWidget( parent, name, f ), scaledWidth( 0 ), scaledHeight( 0 ) {
53 setCaption( tr("OpiePlayer - Video") );
54 Config cfg("OpiePlayer");
55 cfg.setGroup("VideoWidget");
56
57 QString backgroundPix, Button0aPix, Button0bPix, controlsPix;
58 backgroundPix=cfg.readEntry( "backgroundPix", "opieplayer/metalFinish");
59 Button0aPix=cfg.readEntry( "Button0aPix", "opieplayer/mediaButton0a");
60 Button0bPix=cfg.readEntry( "Button0bPix","opieplayer/mediaButton0b");
61 controlsPix=cfg.readEntry( "controlsPix","opieplayer/mediaControls0" );
62
63 setBackgroundPixmap( Resource::loadPixmap( backgroundPix) );
64 pixmaps[0] = new QPixmap( Resource::loadPixmap( Button0aPix ) );
65 pixmaps[1] = new QPixmap( Resource::loadPixmap( Button0bPix ) );
66 pixmaps[2] = new QPixmap( Resource::loadPixmap( controlsPix) );
67 currentFrame = new QImage( 220 + 2, 160, (QPixmap::defaultDepth() == 16) ? 16 : 32 );
68
69 slider = new QSlider( Qt::Horizontal, this );
70 slider->setMinValue( 0 );
71 slider->setMaxValue( 1 );
72 slider->setBackgroundPixmap( Resource::loadPixmap( backgroundPix ) );
73 slider->setFocusPolicy( QWidget::NoFocus );
74 slider->setGeometry( QRect( 7, 250, 220, 20 ) );
75
76 connect( slider, SIGNAL( sliderPressed() ), this, SLOT( sliderPressed() ) );
77 connect( slider, SIGNAL( sliderReleased() ), this, SLOT( sliderReleased() ) );
78
79 connect( mediaPlayerState, SIGNAL( lengthChanged(long) ), this, SLOT( setLength(long) ) );
80 connect( mediaPlayerState, SIGNAL( positionChanged(long) ),this, SLOT( setPosition(long) ) );
81 connect( mediaPlayerState, SIGNAL( positionUpdated(long) ),this, SLOT( setPosition(long) ) );
82 connect( mediaPlayerState, SIGNAL( viewChanged(char) ), this, SLOT( setView(char) ) );
83 connect( mediaPlayerState, SIGNAL( pausedToggled(bool) ), this, SLOT( setPaused(bool) ) );
84 connect( mediaPlayerState, SIGNAL( playingToggled(bool) ), this, SLOT( setPlaying(bool) ) );
85
86 // Intialise state
87 setLength( mediaPlayerState->length() );
88 setPosition( mediaPlayerState->position() );
89 setFullscreen( mediaPlayerState->fullscreen() );
90 setPaused( mediaPlayerState->paused() );
91 setPlaying( mediaPlayerState->playing() );
92}
93
94
95VideoWidget::~VideoWidget() {
96 for ( int i = 0; i < 3; i++ ) {
97 delete pixmaps[i];
98 }
99 delete currentFrame;
100}
101
102
103static bool videoSliderBeingMoved = FALSE;
104
105
106void VideoWidget::sliderPressed() {
107 videoSliderBeingMoved = TRUE;
108}
109
110
111void VideoWidget::sliderReleased() {
112 videoSliderBeingMoved = FALSE;
113 if ( slider->width() == 0 ) {
114 return;
115 }
116 long val = long((double)slider->value() * mediaPlayerState->length() / slider->width());
117 mediaPlayerState->setPosition( val );
118}
119
120
121void VideoWidget::setPosition( long i ) {
122 updateSlider( i, mediaPlayerState->length() );
123}
124
125
126void VideoWidget::setLength( long max ) {
127 updateSlider( mediaPlayerState->position(), max );
128}
129
130
131void VideoWidget::setView( char view ) {
132 if ( view == 'v' ) {
133 makeVisible();
134 } else {
135 // Effectively blank the view next time we show it so it looks nicer
136 scaledWidth = 0;
137 scaledHeight = 0;
138 hide();
139 }
140}
141
142
143void VideoWidget::updateSlider( long i, long max ) {
144 // Will flicker too much if we don't do this
145 if ( max == 0 ) {
146 return;
147 }
148 int width = slider->width();
149 int val = int((double)i * width / max);
150 if ( !mediaPlayerState->fullscreen() && !videoSliderBeingMoved ) {
151 if ( slider->value() != val ) {
152 slider->setValue( val );
153 }
154 if ( slider->maxValue() != width ) {
155 slider->setMaxValue( width );
156 }
157 }
158}
159
160
161void VideoWidget::setToggleButton( int i, bool down ) {
162 if ( down != videoButtons[i].isDown ) {
163 toggleButton( i );
164 }
165}
166
167
168void VideoWidget::toggleButton( int i ) {
169 videoButtons[i].isDown = !videoButtons[i].isDown;
170 QPainter p(this);
171 paintButton ( &p, i );
172}
173
174
175void VideoWidget::paintButton( QPainter *p, int i ) {
176 int x = videoButtons[i].xPos;
177 int y = videoButtons[i].yPos;
178 int offset = 10 + videoButtons[i].isDown;
179 p->drawPixmap( x, y, *pixmaps[videoButtons[i].isDown] );
180 p->drawPixmap( x + 1 + offset, y + offset, *pixmaps[2], 9 * videoButtons[i].controlType, 0, 9, 9 );
181}
182
183
184void VideoWidget::mouseMoveEvent( QMouseEvent *event ) {
185 for ( int i = 0; i < numButtons; i++ ) {
186 int x = videoButtons[i].xPos;
187 int y = videoButtons[i].yPos;
188 if ( event->state() == QMouseEvent::LeftButton ) {
189 // The test to see if the mouse click is inside the circular button or not
190 // (compared with the radius squared to avoid a square-root of our distance)
191 int radius = 16;
192 QPoint center = QPoint( x + radius, y + radius );
193 QPoint dXY = center - event->pos();
194 int dist = dXY.x() * dXY.x() + dXY.y() * dXY.y();
195 bool isOnButton = dist <= (radius * radius);
196 if ( isOnButton != videoButtons[i].isHeld ) {
197 videoButtons[i].isHeld = isOnButton;
198 toggleButton(i);
199 }
200 } else {
201 if ( videoButtons[i].isHeld ) {
202 videoButtons[i].isHeld = FALSE;
203 if ( !videoButtons[i].isToggle )
204 setToggleButton( i, FALSE );
205 }
206 }
207 switch (i) {
208 case VideoPlay: mediaPlayerState->setPlaying(videoButtons[i].isDown); return;
209 case VideoStop: mediaPlayerState->setPlaying(FALSE); return;
210 case VideoPause: mediaPlayerState->setPaused(videoButtons[i].isDown); return;
211 case VideoNext: mediaPlayerState->setNext(); return;
212 case VideoPrevious: mediaPlayerState->setPrev(); return;
213 case VideoPlayList: mediaPlayerState->setList(); return;
214 case VideoFullscreen: mediaPlayerState->setFullscreen( TRUE ); makeVisible(); return;
215 }
216
217 }
218}
219
220
221void VideoWidget::mousePressEvent( QMouseEvent *event ) {
222 mouseMoveEvent( event );
223}
224
225
226void VideoWidget::mouseReleaseEvent( QMouseEvent *event ) {
227 if ( mediaPlayerState->fullscreen() ) {
228 mediaPlayerState->setFullscreen( FALSE );
229 makeVisible();
230
231 mouseMoveEvent( event );
232 }
233}
234
235
236void VideoWidget::makeVisible() {
237 if ( mediaPlayerState->fullscreen() ) {
238 setBackgroundMode( QWidget::NoBackground );
239 showFullScreen();
240 resize( qApp->desktop()->size() );
241 slider->hide();
242 } else {
243 setBackgroundPixmap( Resource::loadPixmap( "opieplayer/metalFinish" ) );
244 showNormal();
245 showMaximized();
246 slider->show();
247 }
248}
249
250
251void VideoWidget::paintEvent( QPaintEvent * ) {
252 QPainter p( this );
253
254 if ( mediaPlayerState->fullscreen() ) {
255 // Clear the background
256 p.setBrush( QBrush( Qt::black ) );
257 p.drawRect( rect() );
258
259 // Draw the current frame
260 //p.drawImage( ); // If using directpainter we won't have a copy except whats on the screen
261 } else {
262 // draw border
263 qDrawShadePanel( &p, 4, 15, 230, 170, colorGroup(), TRUE, 5, NULL );
264
265 // Clear the movie screen first
266 p.setBrush( QBrush( Qt::black ) );
267 p.drawRect( 9, 20, 220, 160 );
268
269 // draw current frame (centrally positioned from scaling to maintain aspect ratio)
270 p.drawImage( 9 + (220 - scaledWidth) / 2, 20 + (160 - scaledHeight) / 2, *currentFrame, 0, 0, scaledWidth, scaledHeight );
271
272 // draw the buttons
273 for ( int i = 0; i < numButtons; i++ ) {
274 paintButton( &p, i );
275 }
276
277 // draw the slider
278 slider->repaint( TRUE );
279 }
280}
281
282
283void VideoWidget::closeEvent( QCloseEvent* ) {
284 mediaPlayerState->setList();
285}
286
287
288bool VideoWidget::playVideo() {
289 bool result = FALSE;
290
291 int stream = 0;
292
293 int sw = 240; //mediaPlayerState->curDecoder()->videoWidth( stream );
294 int sh = 320; //mediaPlayerState->curDecoder()->videoHeight( stream );
295 int dd = QPixmap::defaultDepth();
296 int w = height();
297 int h = width();
298
299 ColorFormat format = (dd == 16) ? RGB565 : BGRA8888;
300
301 if ( mediaPlayerState->fullscreen() ) {
302#ifdef USE_DIRECT_PAINTER
303 QDirectPainter p(this);
304
305 if ( ( qt_screen->transformOrientation() == 3 ) &&
306 ( ( dd == 16 ) || ( dd == 32 ) ) && ( p.numRects() == 1 ) ) {
307
308 w = 320;
309 h = 240;
310
311 if ( mediaPlayerState->scaled() ) {
312 // maintain aspect ratio
313 if ( w * sh > sw * h )
314 w = sw * h / sh;
315 else
316 h = sh * w / sw;
317 } else {
318 w = sw;
319 h = sh;
320 }
321
322 w--; // we can't allow libmpeg to overwrite.
323 QPoint roff = qt_screen->mapToDevice( p.offset(), QSize( qt_screen->width(), qt_screen->height() ) );
324
325 int ox = roff.x() - height() + 2 + (height() - w) / 2;
326 int oy = roff.y() + (width() - h) / 2;
327 int sx = 0, sy = 0;
328
329 uchar* fp = p.frameBuffer() + p.lineStep() * oy;
330 fp += dd * ox / 8;
331 uchar **jt = new uchar*[h];
332 for ( int i = h; i; i-- ) {
333 jt[h - i] = fp;
334 fp += p.lineStep();
335 }
336
337 result = 42; //mediaPlayerState->curDecoder()->videoReadScaledFrame( jt, sx, sy, sw, sh, w, h, format, 0) == 0;
338
339 delete [] jt;
340 } else {
341#endif
342 QPainter p(this);
343
344 w = 320;
345 h = 240;
346
347 if ( mediaPlayerState->scaled() ) {
348 // maintain aspect ratio
349 if ( w * sh > sw * h ) {
350 w = sw * h / sh;
351 } else {
352 h = sh * w / sw;
353 }
354 } else {
355 w = sw;
356 h = sh;
357 }
358
359 int bytes = ( dd == 16 ) ? 2 : 4;
360 QImage tempFrame( w, h, bytes << 3 );
361 result = 42; // mediaPlayerState->curDecoder()->videoReadScaledFrame( tempFrame.jumpTable(),
362 // 0, 0, sw, sh, w, h, format, 0) == 0;
363 if ( result && mediaPlayerState->fullscreen() ) {
364
365 int rw = h, rh = w;
366 QImage rotatedFrame( rw, rh, bytes << 3 );
367
368 ushort* in = (ushort*)tempFrame.bits();
369 ushort* out = (ushort*)rotatedFrame.bits();
370 int spl = rotatedFrame.bytesPerLine() / bytes;
371 for (int x=0; x<h; x++) {
372 if ( bytes == 2 ) {
373 ushort* lout = out++ + (w - 1)*spl;
374 for (int y=0; y<w; y++) {
375 *lout=*in++;
376 lout-=spl;
377 }
378 } else {
379 ulong* lout = ((ulong *)out)++ + (w - 1)*spl;
380 for (int y=0; y<w; y++) {
381 *lout=*((ulong*)in)++;
382 lout-=spl;
383 }
384 }
385 }
386
387 p.drawImage( (240 - rw) / 2, (320 - rh) / 2, rotatedFrame, 0, 0, rw, rh );
388 }
389#ifdef USE_DIRECT_PAINTER
390 }
391#endif
392 } else {
393
394 w = 220;
395 h = 160;
396
397 // maintain aspect ratio
398 if ( w * sh > sw * h ) {
399 w = sw * h / sh;
400 } else {
401 h = sh * w / sw;
402 }
403
404 result = 42 ; //mediaPlayerState->curDecoder()->videoReadScaledFrame( currentFrame->jumpTable(), 0, 0, sw, sh, w, h, format, 0) == 0;
405
406 QPainter p( this );
407
408 // Image changed size, therefore need to blank the possibly unpainted regions first
409 if ( scaledWidth != w || scaledHeight != h ) {
410 p.setBrush( QBrush( Qt::black ) );
411 p.drawRect( 9, 20, 220, 160 );
412 }
413
414 scaledWidth = w;
415 scaledHeight = h;
416
417 if ( result ) {
418 p.drawImage( 9 + (220 - scaledWidth) / 2, 20 + (160 - scaledHeight) / 2, *currentFrame, 0, 0, scaledWidth, scaledHeight );
419 }
420 }
421 return result;
422}
423
424
425
426void VideoWidget::keyReleaseEvent( QKeyEvent *e)
427{
428 switch ( e->key() ) {
429////////////////////////////// Zaurus keys
430 case Key_Home:
431 break;
432 case Key_F9: //activity
433 break;
434 case Key_F10: //contacts
435// hide();
436 break;
437 case Key_F11: //menu
438 break;
439 case Key_F12: //home
440 break;
441 case Key_F13: //mail
442 break;
443 case Key_Space: {
444 if(mediaPlayerState->playing()) {
445 mediaPlayerState->setPlaying(FALSE);
446 } else {
447 mediaPlayerState->setPlaying(TRUE);
448 }
449 }
450 break;
451 case Key_Down:
452// toggleButton(6);
453// emit lessClicked();
454// emit lessReleased();
455// toggleButton(6);
456 break;
457 case Key_Up:
458// toggleButton(5);
459// emit moreClicked();
460// emit moreReleased();
461// toggleButton(5);
462 break;
463 case Key_Right:
464 mediaPlayerState->setNext();
465 break;
466 case Key_Left:
467 mediaPlayerState->setPrev();
468 break;
469 case Key_Escape:
470 break;
471
472 };
473}