summaryrefslogtreecommitdiffstats
path: root/noatun/modules/kaiman/style.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'noatun/modules/kaiman/style.cpp')
-rw-r--r--noatun/modules/kaiman/style.cpp1504
1 files changed, 1504 insertions, 0 deletions
diff --git a/noatun/modules/kaiman/style.cpp b/noatun/modules/kaiman/style.cpp
new file mode 100644
index 00000000..d42ed45f
--- /dev/null
+++ b/noatun/modules/kaiman/style.cpp
@@ -0,0 +1,1504 @@
+/*
+ Copyright (c) 2000 Stefan Schimanski ([email protected])
+ 1999-2000 Christian Esken ([email protected])
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#include <kapplication.h>
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qpainter.h>
+#include <qdropsite.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kurldrag.h>
+#include <qtimer.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "style.h"
+#include "userinterface.h"
+#include <noatun/app.h>
+#include <noatun/stdaction.h>
+
+const bool KaimanStyleSlider::optionVertical = 1;
+const bool KaimanStyleSlider::optionReversed = 2;
+const bool KaimanStyleText::optionExtended = 1;
+
+KaimanStyleElement::KaimanStyleElement(QWidget *parent, const char *name)
+ : QWidget(parent, name)
+{
+ // Initialize everything to default values
+ filename = "";
+ element = "";
+ upperLeft.setX(0);
+ upperLeft.setY(0);
+ dimension.setWidth(0);
+ dimension.setHeight(0);
+ optionPrelight = optionStatuslight = false;
+ options[0] = options[1] = options[2] = false;
+ _currentPixmap = 0;
+ digits = -1;
+ pixmapLines = 1;
+ pixmapColumns = 1;
+
+ setAcceptDrops(true);
+ pixmaps.setAutoDelete(true);
+
+ setBackgroundMode( NoBackground );
+}
+
+
+KaimanStyleElement::~KaimanStyleElement()
+{
+}
+
+
+void KaimanStyleElement::loadPixmaps(QString &val_s_filename)
+{
+ QPixmap pixmap;
+
+ bool i_b_ret = pixmap.load(val_s_filename);
+ pixmapNum = pixmapLines*pixmapColumns;
+
+ pixmaps.resize(pixmapNum);
+
+ if ( i_b_ret ) {
+ if(pixmapNum) {
+ int firstWidth, firstHeight, width, height, sourcex = 0, sourcey = 0;
+
+ // first bitmap may be with different size
+ if ( dimension.width()!=0 )
+ {
+ firstWidth = dimension.width();
+ if ( pixmapColumns>1 )
+ width = (pixmap.width()-firstWidth) / (pixmapColumns-1);
+ else
+ width = 0;
+ } else
+ firstWidth = width = pixmap.width() / pixmapColumns;
+
+ if ( dimension.height()!=0 )
+ {
+ firstHeight = dimension.height();
+ if ( pixmapLines>1 )
+ height = (pixmap.height()-firstHeight) / (pixmapLines-1);
+ else
+ height = 0;
+ } else
+ firstHeight = height = pixmap.height() / pixmapLines;
+
+ // create single pixmaps
+ int i=0;
+ sourcey = 0;
+ for( int y=0; y<pixmapLines; y++ )
+ {
+ int h = (y==0) ? firstHeight : height;
+ sourcex = 0;
+
+ for( int x=0; x<pixmapColumns; x++ )
+ {
+ int w = (x==0) ? firstWidth : width;
+
+ QPixmap *part = new QPixmap(w,h,pixmap.depth());
+ part->fill(Qt::black);
+ bitBlt(part,0,0,&pixmap,sourcex,sourcey,w,h);
+ pixmaps.insert(i,part);
+
+ if(pixmap.mask())
+ {
+ QBitmap maskpart(w,h);
+ bitBlt(&maskpart,0,0,pixmap.mask(),sourcex,sourcey,w,h);
+ part->setMask(maskpart);
+ }
+
+ i++;
+ sourcex += w;
+ }
+
+ sourcey += h;
+ }
+ }
+ } else {
+ kdDebug() << "Cannot load pixmap " << val_s_filename << endl;
+
+ for ( int i=0; i<pixmapNum; i++ )
+ {
+ QPixmap *pm = new QPixmap(10, 10);
+ pm->fill(Qt::black);
+ pixmaps.insert( i, pm );
+ }
+ }
+
+ if ( dimension.width()==0 ) dimension.setWidth( pixmaps[0]->width() );
+ if ( dimension.height()==0 ) dimension.setHeight( pixmaps[0]->height() );
+ setGeometry( QRect(upperLeft, dimension) );
+}
+
+void KaimanStyleElement::setPixmap( int num )
+{
+ if ( num!=_currentPixmap )
+ {
+ if ( num>pixmapNum-1 ) num = pixmapNum-1;
+ if ( num<0 ) num = 0;
+
+ _currentPixmap = num;
+ repaint( FALSE );
+ }
+}
+
+void KaimanStyleElement::paintEvent ( QPaintEvent */*qpe*/ )
+{
+ QPixmap *pm = pixmaps[_currentPixmap];
+ if ( pm )
+ bitBlt(this, 0, 0, pm );
+ else
+ kdDebug() << "Invalid pixmap" << endl;
+
+/* QPainter p( this );
+ p.setBrush( NoBrush );
+ p.setPen( QColor(255,255,255) );
+ p.drawRect( 0, 0, width(), height() );
+ p.drawText( 2, 16, name() ); */
+}
+
+void KaimanStyleElement::dragEnterEvent( QDragEnterEvent *event )
+{
+ event->accept( KURLDrag::canDecode(event) );
+}
+
+void KaimanStyleElement::dropEvent( QDropEvent *event )
+{
+ ((Kaiman*)(parentWidget()->parentWidget()))->doDropEvent(event);
+}
+
+/***************************************************************************/
+
+
+KaimanStyleButton::KaimanStyleButton(QWidget *parent, const char *name)
+ : KaimanStyleMasked(parent, name)
+{
+ i_b_lit = i_b_prelit = i_b_down = false;
+ i_i_currentState = NormalUp;
+
+ I_pmIndex.resize( StateListEND );
+
+ for (int i=0; i<StateListEND; i++) {
+ // Set pixmap index of all states to 0 (the default pixmap)
+ I_pmIndex.insert( i, new int(0));
+ }
+}
+
+KaimanStyleButton::~KaimanStyleButton()
+{
+}
+
+void KaimanStyleButton::mousePressEvent(QMouseEvent *qme)
+{
+ // We deactivate prelight, because the user presses the button.
+ // So it is now down, but there is no PrelitDown icon (BTW: would
+ // make no real sense anyhow).
+ setPrelight(false);
+ setDown(true);
+ grabMouse();
+
+ KaimanStyleMasked::mousePressEvent( qme );
+}
+
+void KaimanStyleButton::mouseReleaseEvent(QMouseEvent *qme)
+{
+ releaseMouse ();
+
+ if (down())
+ {
+ setDown(false);
+ emit clicked();
+ }
+
+ KaimanStyleMasked::mouseReleaseEvent( qme );
+}
+
+
+/* paint prelight */
+void KaimanStyleButton::enterEvent ( QEvent * e )
+{
+ if ( !down() )
+ setPrelight(true);
+
+ KaimanStyleMasked::enterEvent( e );
+}
+
+/* unpaint prelight */
+void KaimanStyleButton::leaveEvent ( QEvent * e )
+{
+ if (!down())
+ setPrelight(false);
+
+ KaimanStyleMasked::leaveEvent( e );
+}
+
+bool KaimanStyleButton::lit()
+{
+ return i_b_lit;
+}
+
+void KaimanStyleButton::setLit(bool val_b_lit)
+{
+ i_b_lit = val_b_lit;
+ updateButtonState();
+}
+
+bool KaimanStyleButton::prelit()
+{
+ return i_b_prelit;
+}
+
+void KaimanStyleButton::setPrelight(bool val_b_prelit)
+{
+ i_b_prelit = val_b_prelit;
+ updateButtonState();
+}
+
+bool KaimanStyleButton::down()
+{
+ return i_b_down;
+}
+
+void KaimanStyleButton::setDown(bool val_b_down)
+{
+ i_b_down = val_b_down;
+ updateButtonState();
+}
+
+void KaimanStyleButton::updateButtonState() {
+
+ if ( i_b_prelit ) {
+ if ( i_b_lit ) {
+ // Prelit and Lit
+ i_i_currentState = PrelightLitUp;
+ }
+ else {
+ // Prelit and not Lit
+ i_i_currentState = PrelightUp;
+ }
+ }
+
+ else if ( i_b_lit ) {
+ if ( i_b_down ) {
+ // Lit and Down
+ i_i_currentState = LitDown;
+ } else {
+ // Lit and not Down
+ i_i_currentState = LitUp;
+ }
+ }
+ else {
+ if ( i_b_down ) {
+ // Normal and Down
+ i_i_currentState = NormalDown;
+ }
+ else {
+ // Normal and not Down
+ i_i_currentState = NormalUp;
+ }
+ }
+
+ setPixmap( *I_pmIndex[i_i_currentState] );
+ repaint();
+}
+
+
+/***********************************************************************/
+
+KaimanStyleSlider::KaimanStyleSlider(int min, int max, QWidget *parent, const char *name)
+ : KaimanStyleMasked( parent, name )
+{
+ _min = min;
+ _max = max;
+ _down = false;
+ _lit = false;
+
+ setValue( _min );
+}
+
+
+KaimanStyleSlider::~KaimanStyleSlider()
+{
+}
+
+
+void KaimanStyleSlider::setValue( int value )
+{
+ if (value>_max) value=_max;
+ if (value<_min) value=_min;
+ _value = value;
+ repaint();
+}
+
+
+void KaimanStyleSlider::setValue( int value, int min, int max )
+{
+ if ( value!=_value || min!=_min || max!=_max ) {
+ _min = min;
+ _max = max;
+ setValue( value );
+ repaint();
+ }
+}
+
+int KaimanStyleSlider::pos2value( int x, int y )
+{
+ int p;
+ int v;
+ if ( options[optionVertical] ) {
+ p = y;
+ v = p*(_max-_min)/height();
+ } else {
+ p = x;
+ v = p*(_max-_min)/width();
+ }
+
+ if ( options[optionReversed] ) v = (_max-_min) - v;
+ return _min + v;
+}
+
+
+void KaimanStyleSlider::mouseMoveEvent(QMouseEvent *qme)
+{
+ KaimanStyleMasked::mouseMoveEvent( qme );
+
+ if ( _down )
+ {
+ setValue( pos2value(qme->x(), qme->y()) );
+ emit newValue( value() );
+ }
+}
+
+void KaimanStyleSlider::mousePressEvent(QMouseEvent *qme)
+{
+ if ( !_down )
+ {
+ grabMouse();
+ _down = true;
+
+ setValue( pos2value(qme->x(), qme->y()) );
+ emit newValueDrag( value() );
+ emit newValue( value() );
+ }
+
+ KaimanStyleMasked::mousePressEvent( qme );
+}
+
+
+void KaimanStyleSlider::mouseReleaseEvent(QMouseEvent *qme)
+{
+ if ( _down )
+ {
+ _down = false;
+ releaseMouse();
+ repaint();
+
+ setValue( pos2value(qme->x(), qme->y()) );
+ emit newValue( value() );
+ emit newValueDrop( value() );
+ }
+
+ KaimanStyleMasked::mouseReleaseEvent( qme );
+}
+
+
+void KaimanStyleSlider::paintEvent(QPaintEvent */*qpe*/)
+{
+ // draw background
+ bitBlt( this, 0, 0, pixmaps[0] );
+
+ // draw optional handle
+ QPixmap *handle;
+ if ( _down )
+ handle = pixmaps[2];
+ else
+ {
+ if ( _lit && optionPrelight )
+ handle = pixmaps[3];
+ else
+ handle = pixmaps[1];
+ }
+
+ if ( handle && handle->width() )
+ {
+ int x = 0;
+ int y = 0;
+
+ if ( _max-_min ) {
+ int v = _value-_min;
+ if ( options[optionReversed] ) v = (_max-_min) - v;
+
+ if ( options[optionVertical] )
+ y = ( height()-handle->height() ) * v / (_max-_min);
+ else
+ x = ( width()-handle->width() ) * v / (_max-_min);
+ }
+
+ bitBlt( this, x, y, handle );
+ }
+}
+
+void KaimanStyleSlider::enterEvent ( QEvent * e )
+{
+ if ( !_lit && optionPrelight )
+ {
+ _lit = true;
+ repaint();
+ }
+
+ KaimanStyleMasked::enterEvent( e );
+}
+
+void KaimanStyleSlider::leaveEvent ( QEvent * e )
+{
+ if ( _lit )
+ {
+ _lit = false;
+ repaint();
+ }
+
+ KaimanStyleMasked::leaveEvent( e );
+}
+
+
+/***********************************************************************/
+
+
+KaimanStyleBackground::KaimanStyleBackground(QWidget *parent, const char *name)
+ : KaimanStyleMasked( parent, name )
+{
+ i_b_move = false;
+}
+
+KaimanStyleBackground::~KaimanStyleBackground()
+{
+}
+
+void KaimanStyleBackground::mouseReleaseEvent(QMouseEvent *qme)
+{
+ i_b_move = false;
+ KaimanStyleMasked::mouseReleaseEvent( qme );
+}
+
+void KaimanStyleBackground::mouseMoveEvent(QMouseEvent *qme)
+{
+ QPoint diff = qme->globalPos() - i_point_lastPos;
+ if ( abs(diff.x()) > 10 || abs(diff.y()) > 10) {
+ // Moving starts only, when passing a drag border
+ i_b_move = true;
+ }
+
+ if ( i_b_move ) {
+ QWidget *p = parentWidget()->parentWidget();
+ if ( !p ) p = parentWidget();
+
+ p->move( qme->globalPos() - i_point_dragStart );
+ }
+
+ KaimanStyleMasked::mouseMoveEvent( qme );
+}
+
+void KaimanStyleBackground::mousePressEvent(QMouseEvent *qme)
+{
+ // On the background we move the shaped toplevel around
+ if (!i_b_move) {
+ i_point_dragStart = qme->pos();
+ i_point_lastPos = qme->globalPos();
+ }
+
+ KaimanStyleMasked::mousePressEvent( qme );
+}
+
+/***********************************************************************/
+
+KaimanStyleValue::KaimanStyleValue(int min, int max, QWidget *parent, const char *name)
+ : KaimanStyleMasked( parent, name )
+{
+ _min = min;
+ _max = max;
+ _value = _min;
+
+ setPixmap( 0 );
+}
+
+KaimanStyleValue::~KaimanStyleValue()
+{
+}
+
+void KaimanStyleValue::setValue( int value )
+{
+ if (value>_max) value=_max;
+ if (value<_min) value=_min;
+ _value = value;
+
+ int len = _max-_min;
+ if ( len )
+ setPixmap( (_value-_min)*pixmapNum/len );
+ else
+ setPixmap( 0 );
+}
+
+void KaimanStyleValue::setValue( int value, int min, int max )
+{
+ _min = min;
+ _max = max;
+
+ setValue( value );
+}
+
+
+/***********************************************************************/
+
+KaimanStyleNumber::KaimanStyleNumber(QWidget *parent, const char *name)
+ : KaimanStyleElement( parent, name )
+{
+ //kdDebug(66666) << k_funcinfo << "name = '" << name << "'" << endl;
+ _value = 0;
+ if (QCString(name) == "In_Rate_Number")
+ digits = 3;
+ else
+ digits = 2;
+}
+
+KaimanStyleNumber::~KaimanStyleNumber()
+{
+}
+
+
+void KaimanStyleNumber::loadPixmaps(QString &val_s_filename)
+{
+ KaimanStyleElement::loadPixmaps( val_s_filename );
+ resize( digits*pixmaps[0]->width(),pixmaps[0]->height() );
+}
+
+
+void KaimanStyleNumber::setValue( int value )
+{
+ if ( _value!=value )
+ {
+ _value = value;
+ repaint();
+ }
+}
+
+void KaimanStyleNumber::paintEvent(QPaintEvent */*qpe*/)
+{
+ // check for overflow
+ int v = _value;
+ for ( int i=digits; i>0 && v>0; i-- )
+ v /= 10;
+
+ if ( v!=0 )
+ v = 999999999; // overflow
+ else
+ v = _value;
+
+ // draw number
+ int x = width();
+ do {
+ x -= pixmaps[0]->width();
+ bitBlt(this, x, 0, pixmaps[v%10] );
+
+ v /= 10;
+ } while ( v>0 );
+
+ // draw right free space
+ while ( x>0 )
+ {
+ x -= pixmaps[0]->width();
+ bitBlt(this, x, 0, pixmaps[0] );
+ }
+/*
+ QPainter p( this );
+ p.setBrush( NoBrush );
+ p.setPen( QColor(255,255,255) );
+ p.drawRect( 0, 0, width(), height() );
+ p.drawText( 2, 16, name() );*/
+}
+
+/***********************************************************************/
+
+KaimanStyleText::KaimanStyleText(QWidget *parent, const char *name)
+ : KaimanStyleElement( parent, name )
+{
+ _pos = 0;
+ _timer = new QTimer( this );
+ _delay = 500;
+ connect( _timer, SIGNAL(timeout()), this, SLOT(timeout()) );
+}
+
+KaimanStyleText::~KaimanStyleText()
+{
+}
+
+
+void KaimanStyleText::loadPixmaps(QString &val_s_filename)
+{
+ KaimanStyleElement::loadPixmaps( val_s_filename );
+ resize( digits*pixmaps[0]->width(), pixmaps[0]->height() );
+}
+
+
+void KaimanStyleText::setValue( QString value )
+{
+ if ( value!=_value ) {
+ _pos = 0;
+ _direction = 1;
+ _value = value;
+ repaint();
+ }
+}
+
+
+void KaimanStyleText::startAnimation( int delay )
+{
+ _pos = 0;
+ _direction = 1;
+ _delay = delay;
+ _timer->start( _delay, TRUE );
+}
+
+
+void KaimanStyleText::stopAnimation()
+{
+ _pos = 0;
+ _timer->stop();
+}
+
+
+void KaimanStyleText::timeout()
+{
+ // reflect
+ if ( _pos+_direction<0 || (int)_value.length()-(_pos+_direction)<digits ) {
+ _direction = -_direction;
+ _timer->start( _delay*5, TRUE );
+ } else {
+ // check new position
+ if ( _pos+_direction>=0 && (int)_value.length()-(_pos+_direction)>=digits ) {
+ _pos += _direction;
+ repaint();
+ }
+
+ _timer->start( _delay, TRUE );
+ }
+
+
+}
+
+
+void KaimanStyleText::paintEvent(QPaintEvent */*qpe*/)
+{
+ // draw number
+ int p;
+ for (p=0; p<digits && p<(int)_value.length()-_pos; p++ )
+ {
+ int pmNum = _value[p+_pos].latin1() - ' ' ;
+ if ( pmNum>=96 ) pmNum = '?' - ' ';
+ if ( pmNum<0 ) pmNum = '?' - ' ';
+
+ QPixmap *pm = pixmaps[pmNum];
+ if ( pm ) bitBlt(this, p*pixmaps[0]->width(), 0, pm );
+ }
+
+ QPixmap *pm = pixmaps[0];
+ for ( ; p<digits; p++ )
+ bitBlt(this, p*pixmaps[0]->width(), 0, pm );
+
+/* QPainter pnt( this );
+ pnt.setBrush( NoBrush );
+ pnt.setPen( QColor(255,255,255) );
+ pnt.drawRect( 0, 0, width(), height() );
+ pnt.drawText( 2, 16, name() );*/
+}
+
+/***********************************************************************/
+
+KaimanStyleAnimation::KaimanStyleAnimation(int delay, QWidget *parent, const char *name)
+ : KaimanStyleMasked( parent, name )
+{
+ _delay = delay;
+ _frame = 0;
+ _timer = new QTimer( this );
+ connect( _timer, SIGNAL(timeout()), this, SLOT(timeout()) );
+}
+
+KaimanStyleAnimation::~KaimanStyleAnimation()
+{
+}
+
+void KaimanStyleAnimation::start()
+{
+ _timer->start( _delay, FALSE );
+}
+
+void KaimanStyleAnimation::pause()
+{
+ _timer->stop();
+}
+
+void KaimanStyleAnimation::stop()
+{
+ _timer->stop();
+ _frame = 0;
+ setPixmap( _frame );
+}
+
+void KaimanStyleAnimation::timeout()
+{
+ _frame++;
+ if ( _frame>=pixmapNum ) _frame = 1;
+ setPixmap( _frame );
+}
+
+/***********************************************************************/
+
+KaimanStyleState::KaimanStyleState(QWidget *parent, const char *name)
+ : KaimanStyleMasked( parent, name )
+{
+ _value = 0;
+}
+
+KaimanStyleState::~KaimanStyleState()
+{
+}
+
+void KaimanStyleState::setValue( int value )
+{
+ _value = value;
+ setPixmap( _value );
+}
+
+void KaimanStyleState::mousePressEvent(QMouseEvent *qme)
+{
+ emit clicked();
+ KaimanStyleMasked::mouseReleaseEvent( qme );
+}
+
+/***********************************************************************/
+
+
+KaimanStyle::KaimanStyle( QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+ i_qw_parent = parent;
+ i_eventSemaphore = false;
+}
+
+
+KaimanStyle::~KaimanStyle()
+{
+}
+
+
+int KaimanStyle::parseStyleFile(QString &l_s_tmpName)
+{
+ int l_i_ret = false;
+
+ QStringList l_s_tokens;
+
+ QFile l_fd(l_s_tmpName);
+ if ( l_fd.open(IO_ReadOnly) ) {
+ // file opened successfully
+ QTextStream l_ts_line( &l_fd );
+ QString l_s_textLine, l_s_token;
+ while ( !l_ts_line.eof() ) {
+ // Clear list of tokens (we are going to fill them now)
+ l_s_tokens.clear();
+
+ // Read a line
+ l_s_textLine = l_ts_line.readLine();
+ l_s_textLine = l_s_textLine.simplifyWhiteSpace();
+
+ if ( l_s_textLine.left(1) != "#" ) {
+ // OK, this is not a comment line
+ if ( l_s_textLine.isNull())
+ l_s_textLine = "";
+ while ( !l_s_textLine.isEmpty() ) {
+ l_s_token = getToken(l_s_textLine, ' ');
+ if ( ! l_s_token.isEmpty() ) {
+ // OK. There is a useful token. It is not NULL
+ if ( l_s_token.right(1) == ":" )
+ l_s_tokens.append(l_s_token.left(l_s_token.length() -1 ));
+ else
+ l_s_tokens.append(l_s_token);
+ } // -<- if it is a not-empty token
+ } // -<- while there are tokens available
+
+ interpretTokens(l_s_tokens);
+
+ } // -<- if is not comment line
+ } // -<- While not EOF on file
+
+ l_i_ret = 0;
+ } // -<- if file could be opened
+
+ else {
+ l_i_ret = KaimanStyle::FileNotFound;
+ }
+ return l_i_ret;
+}
+
+
+
+/*
+ This function gets a list of tokens and inserts a new
+ KaimanStyleElement in I_styleElem. */
+void KaimanStyle::interpretTokens(QStringList& ref_s_tokens)
+{
+ if ( ref_s_tokens.count() < 1 ) {
+ // A list with less than 1 item is useless to us
+ return;
+ }
+
+ QString l_s_tokenTypes;
+ const QString &l_s_elem = ref_s_tokens.first();
+ bool l_vertPixmaps = false;
+ int l_i_pmIndex[KaimanStyleButton::StateListEND];
+ for (int i=0; i<KaimanStyleButton::StateListEND; i++) l_i_pmIndex[i]=0;
+
+ enum { UnknownElement, BackgroundElement, MaskElement, ButtonElement, SliderElement,
+ ValueElement, AnimationElement, StateElement, DigitElement, NumberElement,
+ TextElement } l_elementType = UnknownElement;
+
+ // Now determine the meaning of the following tokens
+ // l_s_tokenTypes stores the meaning (e.g. x-Position, filename, ...)
+ if ( l_s_elem == "Background" ) {
+ l_s_tokenTypes = "f";
+ l_elementType = BackgroundElement;
+ }
+ // ---
+ else if ( l_s_elem == "Mask" ) {
+ l_s_tokenTypes = "f";
+ l_elementType = MaskElement;
+ } else if ( l_s_elem=="Digit_Small" || l_s_elem=="Digit_Small_Default" ) {
+ i_smallFont = ref_s_tokens[1];
+ return;
+ } else if ( l_s_elem=="Digit_Large" || l_s_elem=="Digit_Large_Default" ) {
+ i_largeFont = ref_s_tokens[1];
+ return;
+ }
+ // ---
+ else if ( l_s_elem == "Title" ||
+ l_s_elem == "Album" ||
+ l_s_elem == "Artist" ||
+ l_s_elem == "Genre" ) {
+ // You can have an OPTIONAL argument, so lets see if it is there.
+ if (ref_s_tokens.count() == 6 )
+ l_s_tokenTypes = "fd1xy";
+ else
+ l_s_tokenTypes = "fdxy";
+ l_elementType = TextElement;
+ }
+ // ---
+ else if ( l_s_elem == "Play_Button" ||
+ l_s_elem == "Pause_Button" ||
+ l_s_elem == "Stop_Button" ||
+ l_s_elem == "Shuffle_Button" ||
+ l_s_elem == "Repeat_Button" ) {
+ l_s_tokenTypes = "fPSxy";
+ l_i_pmIndex[KaimanStyleButton::NormalUp] = 0;
+ l_i_pmIndex[KaimanStyleButton::NormalDown] = 1;
+ l_i_pmIndex[KaimanStyleButton::LitUp] = 2;
+ l_i_pmIndex[KaimanStyleButton::LitDown] = 3;
+ l_i_pmIndex[KaimanStyleButton::PrelightUp] = 4;
+ l_i_pmIndex[KaimanStyleButton::PrelightLitUp] = 5;
+ l_elementType = ButtonElement;
+ }
+ // ---
+ else if ( l_s_elem == "Next_Button" ||
+ l_s_elem == "Prev_Button" ||
+ l_s_elem == "FF" ||
+ l_s_elem == "RW" ||
+ l_s_elem == "Playlist_Button" ||
+ l_s_elem == "Config_Button" ||
+ l_s_elem == "Iconify_Button" ||
+ l_s_elem == "Mixer_Button" ||
+ l_s_elem == "Exit_Button" ||
+ l_s_elem == "Alt_Skin_Button" ||
+ l_s_elem == "Volume_Up_Button" ||
+ l_s_elem == "Volume_Down_Button" ||
+ l_s_elem == "Balance_Left_Button" ||
+ l_s_elem == "Balance_Right_Button" ) {
+ l_i_pmIndex[KaimanStyleButton::NormalUp] = 0;
+ l_i_pmIndex[KaimanStyleButton::NormalDown] = 1;
+ l_i_pmIndex[KaimanStyleButton::PrelightUp] = 2;
+ l_s_tokenTypes = "fPxy";
+ l_elementType = ButtonElement;
+ }
+ // ---
+ else if ( l_s_elem == "Stereo_Item" ||
+ l_s_elem == "Shuffle_Item" ||
+ l_s_elem == "Repeat_Item" ||
+ l_s_elem == "Mpegversion_Item" ||
+ l_s_elem == "Mpeglayer_Item" ||
+ l_s_elem == "Mpegmode_Item" ||
+ l_s_elem == "Status_Item" ) {
+ l_s_tokenTypes = "Vfxy";
+ l_elementType = StateElement;
+ }
+ // ---
+ else if ( l_s_elem == "Hour_Number" ||
+ l_s_elem == "Minute_Number" ||
+ l_s_elem == "Second_Number" ||
+ l_s_elem == "Song_Number" ||
+ l_s_elem == "Total_Number" ||
+ l_s_elem == "In_Rate_Number" ||
+ l_s_elem == "In_Hz_Number" ||
+ l_s_elem == "Out_Bits" ||
+ l_s_elem == "Out_Hz" ||
+ l_s_elem == "Song_Minute" ||
+ l_s_elem == "Song_Second" ||
+ l_s_elem == "Frame" ||
+ l_s_elem == "Frame_Total" ||
+ l_s_elem == "CPU_Number" ||
+ l_s_elem == "Hour_Total" ||
+ l_s_elem == "Minute_Total" ||
+ l_s_elem == "Second_Total_Number" ) {
+ // You can have an OPTIONAL argument, so lets see if it is there.
+ if (ref_s_tokens.count() == 6 )
+ l_s_tokenTypes = "fd1xy";
+ else if (ref_s_tokens.count() == 5 )
+ l_s_tokenTypes = "fdxy";
+ else
+ l_s_tokenTypes = "fxy";
+
+ l_elementType = NumberElement;
+ }
+ // ---
+ else if ( l_s_elem == "Position_Item" ||
+ l_s_elem == "Volume_Item" ||
+ l_s_elem == "Balance_Item" ) {
+ l_s_tokenTypes = "Vflxy";
+ l_elementType = ValueElement;
+ }
+ // ---
+ else if ( l_s_elem == "Load_Item" ) {
+ l_s_tokenTypes = "Vflxy";
+ l_elementType = AnimationElement;
+ }
+ // ---
+ else if ( l_s_elem == "Position_Slider" ||
+ l_s_elem == "Volume_Slider" ||
+ l_s_elem == "Balance_Slider" ) {
+
+ if ( ref_s_tokens.count()==10 )
+ l_s_tokenTypes = "VfP12wxyh";
+ else
+ l_s_tokenTypes = "VfP12sxy";
+ l_elementType = SliderElement;
+ }
+ else {
+ kdDebug() << l_s_elem << " not handled yet." << endl;
+ l_s_tokenTypes = "f";
+ }
+
+ /* The above lines decode the meanings of the tokens. The rules for
+ this are the SKIN-SPECS. So the decoder implements a syntactic
+ analyser (parser).
+
+ I now do know the type of each tokens, whether it represents a
+ filename, the prelight parameter, the x position or what else. This
+ information resides in l_s_tokenTypes, and will help in creating
+ the kaiman style elements.
+
+ I will now do two things:
+ 1) Create a new KaimanStyle*, that is inserted into I_styleElem.
+ 2) Fill the KaimanStyleElement structure, by interpreting the tokens.
+ */
+ QStringList::Iterator li_s_tokens = ref_s_tokens.begin();
+ ++ li_s_tokens; // Skip the name of the element
+
+ // 1) Create a new KaimanStyleElement, that is inserted into I_styleElem.
+ KaimanStyleElement *l_kse_elem = 0;
+ KaimanStyleButton *but = 0;
+
+ switch ( l_elementType )
+ {
+ case BackgroundElement:
+ l_kse_elem = new KaimanStyleBackground(this, l_s_elem.latin1());
+ l_kse_elem->show();
+ break;
+
+ case MaskElement:
+ l_kse_elem = new KaimanStyleElement(this, l_s_elem.latin1());
+ l_kse_elem->hide();
+ break;
+
+ case ButtonElement:
+ l_kse_elem = new KaimanStyleButton(this, l_s_elem.latin1());
+ but = static_cast<KaimanStyleButton*>(l_kse_elem);
+ l_kse_elem->show();
+ break;
+
+ case SliderElement:
+ l_kse_elem = new KaimanStyleSlider(0, 100, this, l_s_elem.latin1());
+ i_sliders.append(l_kse_elem);
+ l_kse_elem->show();
+ break;
+
+ case ValueElement:
+ l_kse_elem = new KaimanStyleValue(0, 100, this, l_s_elem.latin1());
+ break;
+
+ case AnimationElement:
+ l_kse_elem = new KaimanStyleAnimation(30, this, l_s_elem.latin1());
+ break;
+
+ case StateElement:
+ l_kse_elem = new KaimanStyleState(this, l_s_elem.latin1());
+ break;
+
+ case NumberElement:
+ l_kse_elem = new KaimanStyleNumber(this, l_s_elem.latin1());
+ break;
+
+ case TextElement:
+ l_kse_elem = new KaimanStyleText(this, l_s_elem.latin1());
+ break;
+
+ default:
+ break;
+ }
+
+ if ( !l_kse_elem )
+ {
+ kdDebug() << "Ignoring style element " << l_s_elem << endl;
+ return;
+ }
+
+ // insert element into element list
+ uint l_i_size = I_styleElem.size();
+ I_styleElem.resize(l_i_size + 1);
+ I_styleElem.insert(l_i_size, l_kse_elem);
+ l_kse_elem->installEventFilter( this );
+
+ // initialize element parameters
+ l_kse_elem->element = l_s_elem;
+
+ if ( l_s_tokenTypes.left(1) == "V" ) {
+ // Vertical flag
+ l_vertPixmaps = true;
+ l_s_tokenTypes = l_s_tokenTypes.mid(1);
+ }
+
+ // initialize button parameters
+ if ( but )
+ {
+ for (int i=0; i<KaimanStyleButton::StateListEND; i++)
+ but->I_pmIndex.insert(i, new int(l_i_pmIndex[i]) );
+ }
+
+ // 2) Fill the KaimanStyleElement structure, by interpreting the tokens.
+ while ( l_s_tokenTypes.length() != 0 ) {
+ /* The skindata format allows omitting arguments if the parser
+ can reconstruct without problems what you mean. This is taken
+ into account when writing the l_s_tokenTypes sting.
+
+ Unfortunately, several skins do ship with a broken skindata file.
+ Most common problem is that width and height is also given.
+
+ Even worse examples leave out specified parametes and add others.
+ For instance, the pause line is specified as "fPSxy". But in k9
+
+
+ the line looks like
+
+ Pause_Button: pause.jpg FALSE 91 148 116 173
+
+ So the actual parameters are fPxywh. The parser has to be pretty
+ smart now. It should "see" that S (status light) is not present,
+ since that should be either TRUE or FALSE, and distribute the
+ others accordingly. */
+
+ bool skipOne;
+
+ do {
+ skipOne = false;
+
+ // Take the first item from the l_s_tokenTypes;
+ char l_c_type = (l_s_tokenTypes[0]).latin1();
+ l_s_tokenTypes = l_s_tokenTypes.mid(1);
+ QString l_s_token = *li_s_tokens;
+ switch(l_c_type) {
+ case 'f':
+ // filename
+ l_kse_elem->filename = l_s_token;
+ break;
+ case 'P':
+ // Prelight
+ if ( l_s_token.upper() == "TRUE" )
+ l_kse_elem->optionPrelight = true;
+ else
+ {
+ l_kse_elem->optionPrelight = false;
+
+ // was that token really there?
+ skipOne = ( l_s_token.upper() != "FALSE" );
+ }
+ break;
+ case 'S':
+ // Statuslight
+ if ( l_s_token.upper() == "TRUE" )
+ l_kse_elem->optionStatuslight = true;
+ else
+ {
+ l_kse_elem->optionStatuslight = false;
+
+ // was that token really there?
+ skipOne = ( l_s_token.upper() != "FALSE" );
+ }
+ break;
+ case '1':
+ // parameter 1
+ if ( l_s_token.upper() == "TRUE" )
+ l_kse_elem->options[0] = true;
+ else
+ {
+ l_kse_elem->options[0] = false;
+
+ // was that token really there?
+ skipOne = ( l_s_token.upper() != "FALSE" );
+ }
+ break;
+ case '2':
+ // parameter 2
+ if ( l_s_token.upper() == "TRUE" )
+ l_kse_elem->options[1] = true;
+ else
+ {
+ l_kse_elem->options[1] = false;
+
+ // was that token really there?
+ skipOne = ( l_s_token.upper() != "FALSE" );
+ }
+ break;
+ case '3':
+ // parameter 3
+ if ( l_s_token.upper() == "TRUE" )
+ l_kse_elem->options[2] = true;
+ else
+ {
+ l_kse_elem->options[2] = false;
+
+ // was that token really there?
+ skipOne = ( l_s_token.upper() != "FALSE" );
+ }
+ break;
+ case 'l':
+ // length
+ if ( l_vertPixmaps )
+ l_kse_elem->pixmapLines = l_s_token.toInt();
+ else
+ l_kse_elem->pixmapColumns = l_s_token.toInt();
+ break;
+ case 'x':
+ // x Position
+ l_kse_elem->upperLeft.setX(l_s_token.toInt());
+ break;
+ case 'y':
+ // y Position
+ l_kse_elem->upperLeft.setY(l_s_token.toInt());
+ break;
+ case 's':
+ // dimension
+ if ( l_kse_elem->options[KaimanStyleSlider::optionVertical] )
+ l_kse_elem->dimension.setHeight(l_s_token.toInt());
+ else
+ l_kse_elem->dimension.setWidth(l_s_token.toInt());
+ break;
+ case 'w':
+ // width
+ l_kse_elem->dimension.setWidth(l_s_token.toInt());
+ break;
+ case 'h':
+ // height
+ l_kse_elem->dimension.setHeight(l_s_token.toInt());
+ break;
+ case 'd':
+ // number of digits
+ l_kse_elem->digits = l_s_token.toInt();
+ break;
+
+ default:
+ kdDebug() << "Element type '" << l_c_type << "' unknown" << endl;
+ }
+
+ if(skipOne) {
+ kdDebug() << "Skipped one element '" << l_c_type << "'" << endl;
+ }
+ } while(skipOne && l_s_tokenTypes.length() != 0);
+
+ // Next token.
+ ++li_s_tokens;
+ if (li_s_tokens == ref_s_tokens.end() ) {
+ // End of token list
+ break;
+ }
+ }
+
+ /* Do some post-processing */
+
+ if( l_elementType==ButtonElement ) {
+ // <Normal button>
+ if(but->optionPrelight) {
+ // --- Has Prelight ---
+ if(but->optionStatuslight)
+ but->pixmapColumns = 6;
+ else {
+ but->pixmapColumns = 3;
+ but->I_pmIndex.insert( KaimanStyleButton::LitUp,
+ new int( *(but->I_pmIndex[KaimanStyleButton::NormalUp])));
+ but->I_pmIndex.insert( KaimanStyleButton::LitDown,
+ new int( *(but->I_pmIndex[KaimanStyleButton::NormalDown])));
+ }
+ } else {
+ // --- Has No Prelight ---
+ but->I_pmIndex.insert( KaimanStyleButton::PrelightUp,
+ new int( *(but->I_pmIndex[KaimanStyleButton::NormalUp])));
+ but->I_pmIndex.insert( KaimanStyleButton::PrelightLitUp,
+ new int( *(but->I_pmIndex[KaimanStyleButton::LitUp])));
+ if(l_kse_elem->optionStatuslight)
+ but->pixmapColumns = 4;
+ else {
+ but->pixmapColumns = 2;
+ but->I_pmIndex.insert( KaimanStyleButton::LitUp,
+ new int( *(but->I_pmIndex[KaimanStyleButton::NormalUp])));
+ but->I_pmIndex.insert( KaimanStyleButton::LitDown,
+ new int( *(but->I_pmIndex[KaimanStyleButton::NormalDown])));
+ but->I_pmIndex.insert( KaimanStyleButton::PrelightLitUp,
+ new int( *(but->I_pmIndex[KaimanStyleButton::NormalUp])));
+ }
+ }
+ } else if( l_elementType==NumberElement ) {
+ // number items
+ l_kse_elem->pixmapColumns = 11;
+ if ( l_kse_elem->filename=="Small" ) l_kse_elem->filename = i_smallFont;
+ else if ( l_kse_elem->filename=="Large" ) l_kse_elem->filename = i_largeFont;
+ } else if( l_elementType==SliderElement ) {
+ // slider items
+ if ( l_kse_elem->options[KaimanStyleSlider::optionVertical] )
+ l_kse_elem->pixmapLines = l_kse_elem->optionPrelight ? 4 : 3;
+ else
+ l_kse_elem->pixmapColumns = l_kse_elem->optionPrelight ? 4 : 3;
+ } else if( l_elementType==TextElement ) {
+ // text items
+ l_kse_elem->pixmapColumns = 32;
+ l_kse_elem->pixmapLines = l_kse_elem->options[KaimanStyleText::optionExtended] ? 6 : 3;
+ } else {
+ // <Not standard element>
+ if(l_s_elem == "Stereo_Item")
+ l_kse_elem->pixmapLines = 3;
+ else if(l_s_elem == "Shuffle_Item")
+ l_kse_elem->pixmapLines = 2;
+ else if(l_s_elem == "Repeat_Item")
+ l_kse_elem->pixmapLines = 2;
+ else if(l_s_elem == "Mpegversion_Item")
+ l_kse_elem->pixmapLines = 3;
+ else if(l_s_elem == "Mpegversion_Item")
+ l_kse_elem->pixmapLines = 4;
+ else if(l_s_elem == "Mpegmode_Item")
+ l_kse_elem->pixmapLines = 5;
+ else if(l_s_elem == "Status_Item")
+ l_kse_elem->pixmapLines = 3;
+ } // </Not normal button>
+}
+
+
+QString KaimanStyle::getToken(QString &val_s_string, char val_c_separator)
+{
+ int l_i_pos;
+ QString l_s_token;
+
+ // Find the first occurrence of the separator
+ l_i_pos = val_s_string.find(val_c_separator, 0, false);
+ if ( l_i_pos == -1 ) {
+ // No sparator! Then the whole string is the token
+ l_s_token = val_s_string;
+ val_s_string = "";
+ }
+ else {
+ // Separator found: Split the string at the separator position
+ l_s_token = val_s_string.left(l_i_pos);
+ val_s_string.remove(0,l_i_pos);
+ }
+ val_s_string = val_s_string.simplifyWhiteSpace();
+
+ // Return the first token
+ return l_s_token;
+}
+
+
+
+bool KaimanStyle::loadStyle(const QString &styleName, const QString &descFile)
+{
+ bool l_b_ret = true;
+ int l_i_ret = 0;
+ QString l_s_tmpName;
+
+ i_skinName = styleName;
+ this->i_s_styleName = styleName;
+ i_s_styleBase = QString("skins/kaiman/") + i_s_styleName + QString("/");
+
+ l_s_tmpName = locate("appdata", i_s_styleBase + descFile );
+ if ( l_s_tmpName.isNull() ) {
+ l_b_ret = false;
+ }
+
+ if ( l_b_ret) {
+ // Skin description found. Now parse StyleFile.
+ l_i_ret = parseStyleFile(l_s_tmpName);
+ if (l_i_ret == 0) {
+ // If parsiing OK, load the referenced pixmaps
+ l_b_ret = loadPixmaps();
+
+ kdDebug(66666) << "Found " << I_styleElem.count() << " elements." << endl;
+ }
+ else {
+ if ( l_i_ret == KaimanStyle::FileNotFound ) {
+ // File not found
+ KMessageBox::error( 0, i18n("Cannot load style. Style not installed.") );
+ }
+ else {
+ // Parsing not OK: Notify user
+ KMessageBox::error( 0, i18n("Cannot load style. Unsupported or faulty style description.") );
+ }
+ }
+ }
+
+ return l_b_ret;
+}
+
+bool KaimanStyle::eventFilter( QObject *o, QEvent *e )
+{
+ /* HACK! HACK! HACK! */
+ if ( !i_eventSemaphore )
+ if ( e->type()==QEvent::MouseMove || e->type()==QEvent::MouseButtonPress ||
+ e->type()==QEvent::MouseButtonRelease )
+ {
+ QMouseEvent *m = (QMouseEvent*)e;
+
+ // handle noatun context menu
+ if (m->button()==RightButton) {
+ NoatunStdAction::ContextMenu::showContextMenu();
+ return true;
+ }
+
+ QPoint mousePos( m->x()+static_cast<QWidget *>(o)->x(),
+ m->y()+static_cast<QWidget *>(o)->y() );
+ QWidget *slider = 0;
+
+ /* find slider that is under the mouse position */
+ for ( QWidget *s = i_sliders.first(); s!=0; s=i_sliders.next() )
+ {
+ QRect sliderRect( s->pos(), s->size() );
+ if ( sliderRect.contains(mousePos) ) slider = s;
+ }
+
+ /* the slider the mouse events instead of the visible widget */
+ if ( slider )
+ {
+ QMouseEvent newMouseEvent( m->type(), mousePos-slider->pos(),
+ m->globalPos(), m->button(), m->state() );
+
+ i_eventSemaphore = true;
+ bool ret = QApplication::sendEvent( slider, &newMouseEvent );
+ i_eventSemaphore = false;
+ return ret;
+ }
+ }
+
+ return QWidget::eventFilter( o, e ); // standard event processing
+}
+
+bool KaimanStyle::loadPixmaps()
+{
+ QString l_s_tmpName;
+ QPixmap *l_pixmap_Background = 0, *l_pixmap_Mask = 0;
+ KaimanStyleElement *l_kse_elem;
+
+ for ( uint l_i_elem = 0; l_i_elem<I_styleElem.count(); l_i_elem++) {
+ l_kse_elem = I_styleElem[l_i_elem];
+
+ l_s_tmpName = locate("appdata", i_s_styleBase + l_kse_elem->filename );
+ l_kse_elem->loadPixmaps(l_s_tmpName);
+ }
+
+ l_kse_elem = this->find("Background");
+ if ( l_kse_elem != 0 ) {
+ l_pixmap_Background = l_kse_elem->pixmaps[0];
+ }
+ l_kse_elem = this->find("Mask");
+ if ( l_kse_elem != 0 ) {
+ l_pixmap_Mask = l_kse_elem->pixmaps[0];
+ }
+
+ if ( (l_pixmap_Background != 0) && (l_pixmap_Mask != 0) ) {
+
+ // OK, background and mask are defined. So now I can calculate the shape
+ int l_i_width_Mask = l_pixmap_Mask->width();
+ int l_i_height_Mask = l_pixmap_Mask->height();
+
+ QImage l_image_MaskOrig = l_pixmap_Mask->convertToImage();
+
+ QImage l_image_Mask(l_i_width_Mask,l_i_height_Mask, 1, 2, QImage::LittleEndian);
+ l_image_Mask.setColor( 0, 0x00ffffff );
+ l_image_Mask.setColor( 1, 0 );
+ l_image_Mask.fill( 0xff );
+
+ uchar *l_c_pixel;
+ uint l_qcol_white = qRgb(255,255,255);
+
+ for (int l_i_x=0; l_i_x<l_i_width_Mask; l_i_x++) {
+ for (int l_i_y=0; l_i_y < l_i_height_Mask; l_i_y++) {
+ if ( ((*((QRgb*) l_image_MaskOrig.scanLine(l_i_y)+l_i_x) & 0x00ffffff)) != (l_qcol_white & 0x00ffffff) ) {
+ l_c_pixel = (uchar *)l_image_Mask.scanLine(l_i_y);
+ *(l_c_pixel + (l_i_x>>3) ) &= ~(1 << (l_i_x & 7));
+ }
+ }
+ }
+
+ i_bitmap_Mask.convertFromImage(l_image_Mask);
+ // l_pixmap_Background.setMask(i_bitmap_Mask);
+ }
+
+ return true;
+}
+
+
+QBitmap* KaimanStyle::Mask()
+{
+ return &i_bitmap_Mask;
+}
+
+KaimanStyleElement* KaimanStyle::find(const char *val_s_elemName)
+{
+ for (uint i=0; i< I_styleElem.count(); i++) {
+ if ( I_styleElem[i]->element == QString(val_s_elemName)) {
+ return I_styleElem[i];
+ }
+ }
+ return 0;
+}
+#include "style.moc"