diff options
Diffstat (limited to 'noatun/modules/winskin')
83 files changed, 5815 insertions, 0 deletions
diff --git a/noatun/modules/winskin/Makefile.am b/noatun/modules/winskin/Makefile.am new file mode 100644 index 00000000..5c0423e6 --- /dev/null +++ b/noatun/modules/winskin/Makefile.am @@ -0,0 +1,51 @@ +SUBDIRS = vis skins mimetypes + +noatun_modules_winskin_DATA = winskin.plugin +noatun_modules_winskindir = $(kde_datadir)/noatun + +INCLUDES = -I$(top_srcdir)/noatun/library \ + -I$(top_builddir)/noatun/library \ + -I$(kde_includes)/arts \ + $(all_includes) + +kde_module_LTLIBRARIES = noatun_winskin.la + +noatun_winskin_la_SOURCES = fileInfo.cpp \ + guiSpectrumAnalyser.cpp \ + plugin.cpp \ + waBalanceSlider.cpp \ + waButton.cpp \ + waClutterbar.cpp \ + waColor.cpp \ + waDigit.cpp \ + waInfo.cpp \ + waIndicator.cpp \ + waJumpSlider.cpp \ + waLabel.cpp \ + waMain.cpp \ + waRegion.cpp \ + waSkin.cpp \ + waSkinModel.cpp \ + waSlider.cpp \ + waStatus.cpp \ + waTitleBar.cpp \ + waVolumeSlider.cpp \ + waWidget.cpp \ + winSkinConfig.cpp \ + winSkinVis.cpp \ + waSkinManager.cpp \ + waSkinManager.skel + +noatun_winskin_la_LDFLAGS = $(all_libraries) \ + -module -avoid-version -no-undefined + +noatun_winskin_la_LIBADD = $(top_builddir)/noatun/library/libnoatun.la \ + $(top_builddir)/noatun/modules/winskin/vis/libwinskinvis.la + +noatun_winskin_la_METASOURCES = AUTO + + + +waSkin.lo: ../../library/noatunarts/noatunarts.h vis/winskinvis.h +winSkinVis.lo: ../../library/noatunarts/noatunarts.h vis/winskinvis.h +guiSpectrumAnalyser.lo: ../../library/noatunarts/noatunarts.h vis/winskinvis.h diff --git a/noatun/modules/winskin/fileInfo.cpp b/noatun/modules/winskin/fileInfo.cpp new file mode 100644 index 00000000..69f93215 --- /dev/null +++ b/noatun/modules/winskin/fileInfo.cpp @@ -0,0 +1,50 @@ +#include <noatun/app.h> +#include <noatun/playlist.h> + +#include <qstring.h> +#include <kfilemetainfo.h> + +#include "fileInfo.h" + +fileInfo::fileInfo(const PlaylistItem &item) +{ + QString prop; + + prop = item.property("bitrate"); + if (prop.isNull()) + _bps = 0; + else + _bps = prop.toInt(); + + prop = item.property("samplerate"); + if (prop.isNull()) + _KHz = 44100; + else + _KHz = prop.toInt(); + + prop = item.property("channels"); + if (prop.isNull()) + _channelCount = 2; + else + _channelCount = prop.toInt(); +} + +fileInfo::~fileInfo() +{ +} + +unsigned int fileInfo::bps() +{ + return _bps; +} + +unsigned int fileInfo::KHz() +{ + return _KHz; +} + +unsigned int fileInfo::channelCount() +{ + return _channelCount; +} + diff --git a/noatun/modules/winskin/fileInfo.h b/noatun/modules/winskin/fileInfo.h new file mode 100644 index 00000000..203af087 --- /dev/null +++ b/noatun/modules/winskin/fileInfo.h @@ -0,0 +1,21 @@ +#ifndef _FILEINFO_H +#define _FILEINFO_H + +#include <noatun/playlist.h> + +class fileInfo { + public: + fileInfo(const PlaylistItem &); + ~fileInfo(); + + unsigned int bps(); + unsigned int KHz(); + unsigned int channelCount(); + + private: + int _KHz; + int _bps; + int _channelCount; +}; + +#endif diff --git a/noatun/modules/winskin/guiSpectrumAnalyser.cpp b/noatun/modules/winskin/guiSpectrumAnalyser.cpp new file mode 100644 index 00000000..d015e5da --- /dev/null +++ b/noatun/modules/winskin/guiSpectrumAnalyser.cpp @@ -0,0 +1,224 @@ +/* + winamp visualisation plugin. + Copyright (C) 2001 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include <klocale.h> +#include <qcolor.h> +#include <qpopupmenu.h> +#include <qpainter.h> +#include <kconfig.h> + +#include "waColor.h" +#include "waSkinModel.h" + +#include "guiSpectrumAnalyser.h" +#include "vis/winskinvis.h" + +#define __BANDS 75 + +GuiSpectrumAnalyser::GuiSpectrumAnalyser() + : WaWidget(_WA_MAPPING_ANALYSER) +{ + connect(WaSkinModel::instance(), SIGNAL(skinChanged()), this, SLOT(pixmapChange())); + + contextMenu = new QPopupMenu(this); + visualizationMenu = new QPopupMenu(); + analyserMenu = new QPopupMenu(); + + contextMenu->insertItem(i18n("Visualization Mode"), visualizationMenu); + contextMenu->insertItem(i18n("Analyzer Mode"), analyserMenu); + + visualizationMenu->insertItem(i18n("Analyzer"), (int)MODE_ANALYSER); + visualizationMenu->insertItem(i18n("Disabled"), (int)MODE_DISABLED); + visualizationMenu->setCheckable(true); + connect(visualizationMenu, SIGNAL(activated(int)), this, SLOT(setVisualizationMode(int))); + + analyserMenu->insertItem(i18n("Normal"), (int)MODE_NORMAL); + analyserMenu->insertItem(i18n("Fire"), (int)MODE_FIRE); + analyserMenu->insertItem(i18n("Vertical Lines"), (int)MODE_VERTICAL_LINES); + analyserMenu->setCheckable(true); + connect(analyserMenu, SIGNAL(activated(int)), this, SLOT(setAnalyserMode(int))); + + analyserCache = NULL; + winSkinVis = NULL; + + KConfig *config = KGlobal::config(); + config->setGroup("Winskin"); + + setVisualizationMode(config->readNumEntry("visualizationMode", MODE_ANALYSER)); + setAnalyserMode(config->readNumEntry("analyserMode", MODE_NORMAL)); +} + + +GuiSpectrumAnalyser::~GuiSpectrumAnalyser() +{ + KConfig *config = KGlobal::config(); + config->setGroup("Winskin"); + + config->writeEntry("visualizationMode", visualization_mode); + config->writeEntry("analyserMode", analyser_mode); + + delete analyserCache; +} + +void GuiSpectrumAnalyser::mousePressEvent ( QMouseEvent *e ) +{ + if (e->button() == LeftButton) { + if (visualization_mode == MODE_DISABLED) + setVisualizationMode(MODE_ANALYSER); + else + setVisualizationMode(MODE_DISABLED); + } + else if (e->button() == RightButton) { + contextMenu->popup(mapToGlobal(QPoint(e->x(), e->y()))); + } +} + +void GuiSpectrumAnalyser::setAnalyserMode(int mode) +{ + analyser_mode = mode; + + analyserMenu->setItemChecked(MODE_NORMAL, (mode == MODE_NORMAL)); + analyserMenu->setItemChecked(MODE_FIRE, (mode == MODE_FIRE)); + analyserMenu->setItemChecked(MODE_VERTICAL_LINES, (mode == MODE_VERTICAL_LINES)); + + delete analyserCache; + analyserCache = NULL; +} + +void GuiSpectrumAnalyser::pauseVisualization() +{ + hide(); +} + +void GuiSpectrumAnalyser::resumeVisualization() +{ + show(); +} + +void GuiSpectrumAnalyser::updatePeaks() +{ + if ((visualization_mode == MODE_DISABLED) || (!isVisible())) + return; + + float* currentPeaks = winSkinVis->currentPeaks(); + + if (!analyserCache) + freshenAnalyserCache(); + + for (int x = 0;x < __BANDS;x++) { + int amp = int(currentPeaks[x]); + + if (amp < 0) + amp = 0; + else if (amp > 16) + amp = 16; + + bitBlt(this, x, 0, analyserCache, (amp * 2) + (x % 2), 0, 1, 16); + } +} + +void GuiSpectrumAnalyser::setVisualizationMode(int mode) +{ + visualization_mode = mode; + + visualizationMenu->setItemChecked(MODE_ANALYSER, (mode == MODE_ANALYSER)); + visualizationMenu->setItemChecked(MODE_DISABLED, (mode == MODE_DISABLED)); + + if (mode == MODE_ANALYSER) + { + if (!winSkinVis) + { + winSkinVis=new WinSkinVis(this,"WinSkinVis"); + connect(winSkinVis,SIGNAL(doRepaint()),this,SLOT(updatePeaks())); + } + } + else + { + delete winSkinVis; + winSkinVis = NULL; + } + + update(); +} + + +void GuiSpectrumAnalyser::freshenAnalyserCache() +{ + // We need a color scheme + if (!colorScheme) + return; + + // The analyser cache is a 34x16 pixmap containing all the bits needed + // to quickly draw the spectrum analyser + analyserCache = new QPixmap(34, 16); + QPainter p(analyserCache); + + for (unsigned int x = 0;x < 17;x++) { + if (x != 16) { + p.setPen(QPen(colorScheme->skinColors[INDEX_BACKGROUND_COLOR])); + p.drawLine(x * 2, 0, x * 2, 16 - x - 1); + } + + for (unsigned int y = 0; y < (16 - x);y++) { + if (y % 2) + p.setPen(QPen(colorScheme->skinColors[INDEX_GRID_COLOR])); + else + p.setPen(QPen(colorScheme->skinColors[INDEX_BACKGROUND_COLOR])); + + p.drawPoint((x * 2) + 1, y); + } + + if (!x) + continue; + + switch (analyser_mode) { + case MODE_FIRE: + for (unsigned int y = (16 - x); y < 16; y++) { + p.setPen(QPen(colorScheme->skinColors[INDEX_SPEC_BASE + (y - (16 - x))])); + p.drawPoint((x * 2), y); + p.drawPoint((x * 2) + 1, y); + } + break; + case MODE_VERTICAL_LINES: + p.setPen(QPen(colorScheme->skinColors[INDEX_SPEC_BASE + (16 - x)])); + p.drawLine((x * 2), (15 - x), (x * 2), 15); + p.drawLine((x * 2) + 1, (15 - x), (x * 2) + 1, 15); + break; + case MODE_NORMAL: + // Fall through + default: + for (unsigned int y = (16 - x); y < 16; y++) { + p.setPen(QPen(colorScheme->skinColors[INDEX_SPEC_BASE + y])); + p.drawPoint((x * 2), y); + p.drawPoint((x * 2) + 1, y); + } + break; + } + } +} + +void GuiSpectrumAnalyser::paintEvent (QPaintEvent *) +{ + if (visualization_mode == MODE_DISABLED) + paintBackground(); +} + +void GuiSpectrumAnalyser::pixmapChange() +{ + delete analyserCache; + analyserCache = NULL; +} + + +#include "guiSpectrumAnalyser.moc" + diff --git a/noatun/modules/winskin/guiSpectrumAnalyser.h b/noatun/modules/winskin/guiSpectrumAnalyser.h new file mode 100644 index 00000000..ecef8d37 --- /dev/null +++ b/noatun/modules/winskin/guiSpectrumAnalyser.h @@ -0,0 +1,66 @@ +/* + a GUI for a spectrum analyser + Copyright (C) 1998 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef _GUISPECTRUMANALYSER_H +#define _GUISPECTRUMANALYSER_H + +#include <math.h> + +#include "winSkinVis.h" +#include "waWidget.h" +#include "waColor.h" + + +#define MAX_MODE 1 + +enum visualizationMode {MODE_DISABLED = 0, MODE_ANALYSER = 1}; +enum analyserMode {MODE_NORMAL = 0, MODE_FIRE = 1, MODE_VERTICAL_LINES = 2}; + +class GuiSpectrumAnalyser : public WaWidget { + Q_OBJECT + + public: + GuiSpectrumAnalyser(); + ~GuiSpectrumAnalyser(); + + void mousePressEvent(QMouseEvent * mouseEvent); + + public slots: + void pauseVisualization(); + void resumeVisualization(); + + private slots: + void pixmapChange(); + void updatePeaks(); + + void setVisualizationMode(int); + void setAnalyserMode(int); + + private: + void paintEvent(QPaintEvent *); + + QPopupMenu *contextMenu; + QPopupMenu *visualizationMenu; + QPopupMenu *analyserMenu; + + void freshenAnalyserCache(); + + int visualization_mode; + int analyser_mode; + + QPixmap *analyserCache; + WinSkinVis *winSkinVis; +}; +#endif + diff --git a/noatun/modules/winskin/mimetypes/Makefile.am b/noatun/modules/winskin/mimetypes/Makefile.am new file mode 100644 index 00000000..c28d0e8e --- /dev/null +++ b/noatun/modules/winskin/mimetypes/Makefile.am @@ -0,0 +1,2 @@ + +SUBDIRS = interface diff --git a/noatun/modules/winskin/mimetypes/interface/Makefile.am b/noatun/modules/winskin/mimetypes/interface/Makefile.am new file mode 100644 index 00000000..9ca52284 --- /dev/null +++ b/noatun/modules/winskin/mimetypes/interface/Makefile.am @@ -0,0 +1,6 @@ +noatun_modules_winskin_mimetypes_interface_DATA = x-winamp-skin.desktop + +noatun_modules_winskin_mimetypes_interfacedir = $(kde_mimedir)/interface + +EXTRA_DIST = $(noatun_modules_winskin_mimetypes_interface_DATA) + diff --git a/noatun/modules/winskin/mimetypes/interface/x-winamp-skin.desktop b/noatun/modules/winskin/mimetypes/interface/x-winamp-skin.desktop new file mode 100644 index 00000000..34686e98 --- /dev/null +++ b/noatun/modules/winskin/mimetypes/interface/x-winamp-skin.desktop @@ -0,0 +1,58 @@ +[Desktop Entry] +Type=MimeType +MimeType=interface/x-winamp-skin +Icon=colorscm +Patterns=*.wsz;*.WSZ +Comment=Compressed Winamp Skin +Comment[bg]=Компресирана тема за Winamp +Comment[bn]=কম্প্রেস করা উইন-অ্যাম্প স্কিন +Comment[br]=Kroc'hen Winamp gwasket +Comment[bs]=Komprimirani Winamp skin +Comment[ca]=Aparença Winamp comprimida +Comment[cs]=Komprimovaný Winamp skin +Comment[cy]=Croen Winamp cywasgedig +Comment[da]=Komprimeret Winamp-forside +Comment[de]=Komprimierte Winamp-Oberfläche +Comment[el]=Συμπιεσμένο θέμα Winamp +Comment[eo]=Kunpremita Winamp-etoso +Comment[es]=Piel comprimida de Winamp +Comment[et]=Winampi pakitud kest (skin) +Comment[eu]=Winamp azal konprimitua +Comment[fa]=Winamp Skin فشرده +Comment[fi]=Pakattu Winamp-nahka +Comment[fr]=Revêtement Winamp compacté +Comment[gl]=Pel de Winamp Comprimida +Comment[he]=Winamp דחוס של Skin +Comment[hi]=संपीडित विनएम्प स्किन +Comment[hu]=Tömörített Winamp-kinézet +Comment[is]=Þjappað Winamp-skin +Comment[it]=Skin di Winamp compressa +Comment[ja]=圧縮された Winamp のスキン +Comment[kk]=Сығылған Winamp тысы +Comment[km]=ស្បែក Winamp បានបង្ហាប់ +Comment[ko]=압축된 Winamp 스킨 +Comment[lt]=Suglaudintas Winamp pavidalas +Comment[mk]=Компресирана маска Winamp +Comment[nb]=Komprimert Winamp-ham +Comment[nds]=Komprimeert Winamp-Böversiet +Comment[ne]=सङ्कुचित विन्याप स्किन +Comment[nl]=Gecomprimeerde Winamp-skin +Comment[nn]=Komprimert Winamp-drakt +Comment[pl]=Skompresowana skóra Winampa +Comment[pt]=Aspecto Comprimido do Winamp +Comment[pt_BR]=Skin do Winamp comprimido +Comment[ro]=Interfaţă Winamp comprimată +Comment[ru]=Сжатая тема Winamp +Comment[sk]=Komprimované rozhranie pre Winamp +Comment[sl]=Stisnjena preobleka za Winamp +Comment[sr]=Компресован Winamp-ов скин +Comment[sr@Latn]=Kompresovan Winamp-ov skin +Comment[sv]=Komprimerat Winamp-skal +Comment[ta]=அழுத்தப்பட்ட வின் ஆம்ப் அலங்கார அமைப்பு +Comment[tg]=Намуди Фишурдашудаи Winamp +Comment[th]=หน้ากากวินแอมป์บีบอัด Compress +Comment[tr]=Sıkıştırılmış Winamp Teması +Comment[uk]=Стиснутий жупан Winamp +Comment[zh_CN]=压缩的 Winamp 皮肤 +Comment[zh_HK]=已壓縮的 Winamp skin +Comment[zh_TW]=壓縮的 Winamp 面板 diff --git a/noatun/modules/winskin/plugin.cpp b/noatun/modules/winskin/plugin.cpp new file mode 100644 index 00000000..8890c515 --- /dev/null +++ b/noatun/modules/winskin/plugin.cpp @@ -0,0 +1,13 @@ +#include <kglobal.h> +#include <klocale.h> + +#include "winSkinConfig.h" +#include "waSkin.h" + +extern "C" { + KDE_EXPORT Plugin *create_plugin() { + WaSkin *new_skin = new WaSkin(); + new WinSkinConfig(new_skin, new_skin->skinManager()); + return new_skin; + } +} diff --git a/noatun/modules/winskin/skinMap.h b/noatun/modules/winskin/skinMap.h new file mode 100644 index 00000000..f67f1557 --- /dev/null +++ b/noatun/modules/winskin/skinMap.h @@ -0,0 +1,38 @@ +/* + generic type for describing skins. + Copyright (C) 1999 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef _SKINMAP_H +#define _SKINMAP_H + +#include <qpixmap.h> + +typedef struct { + int x; + int y; + int width; + int height; +} SkinMap; + +typedef struct { + int fileId; + int x; + int y; + int width; + int height; +} SkinDesc; + + + +#endif diff --git a/noatun/modules/winskin/skins/Makefile.am b/noatun/modules/winskin/skins/Makefile.am new file mode 100644 index 00000000..8f8e17ab --- /dev/null +++ b/noatun/modules/winskin/skins/Makefile.am @@ -0,0 +1,11 @@ +# widgetlib - Makefile.am + +SUBDIRS = winamp + + + + + + + + diff --git a/noatun/modules/winskin/skins/winamp/BALANCE.BMP b/noatun/modules/winskin/skins/winamp/BALANCE.BMP Binary files differnew file mode 100644 index 00000000..3ce036e9 --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/BALANCE.BMP diff --git a/noatun/modules/winskin/skins/winamp/CBUTTONS.BMP b/noatun/modules/winskin/skins/winamp/CBUTTONS.BMP Binary files differnew file mode 100644 index 00000000..8b335e55 --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/CBUTTONS.BMP diff --git a/noatun/modules/winskin/skins/winamp/FONT.BMP b/noatun/modules/winskin/skins/winamp/FONT.BMP Binary files differnew file mode 100644 index 00000000..57caa947 --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/FONT.BMP diff --git a/noatun/modules/winskin/skins/winamp/MAIN.BMP b/noatun/modules/winskin/skins/winamp/MAIN.BMP Binary files differnew file mode 100644 index 00000000..5e8a2cec --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/MAIN.BMP diff --git a/noatun/modules/winskin/skins/winamp/MONOSTER.BMP b/noatun/modules/winskin/skins/winamp/MONOSTER.BMP Binary files differnew file mode 100644 index 00000000..35fee70c --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/MONOSTER.BMP diff --git a/noatun/modules/winskin/skins/winamp/Makefile.am b/noatun/modules/winskin/skins/winamp/Makefile.am new file mode 100644 index 00000000..169e1bc5 --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/Makefile.am @@ -0,0 +1,8 @@ + +EXTRA_DIST = BALANCE.BMP CBUTTONS.BMP FONT.BMP MAIN.BMP \ + MONOSTER.BMP NUMS_EX.BMP PLAYPAUS.BMP \ + POSBAR.BMP SHUFREP.BMP SPEC.BMP \ + TEXT.BMP TITLEBAR.BMP VISCOLOR.TXT VOLUME.BMP + +skin_DATA = $(EXTRA_DIST) +skindir = $(kde_datadir)/noatun/skins/winamp/Winamp diff --git a/noatun/modules/winskin/skins/winamp/NUMS_EX.BMP b/noatun/modules/winskin/skins/winamp/NUMS_EX.BMP Binary files differnew file mode 100644 index 00000000..72c3215d --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/NUMS_EX.BMP diff --git a/noatun/modules/winskin/skins/winamp/PLAYPAUS.BMP b/noatun/modules/winskin/skins/winamp/PLAYPAUS.BMP Binary files differnew file mode 100644 index 00000000..90319a0e --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/PLAYPAUS.BMP diff --git a/noatun/modules/winskin/skins/winamp/POSBAR.BMP b/noatun/modules/winskin/skins/winamp/POSBAR.BMP Binary files differnew file mode 100644 index 00000000..be6636ca --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/POSBAR.BMP diff --git a/noatun/modules/winskin/skins/winamp/SHUFREP.BMP b/noatun/modules/winskin/skins/winamp/SHUFREP.BMP Binary files differnew file mode 100644 index 00000000..12f5e406 --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/SHUFREP.BMP diff --git a/noatun/modules/winskin/skins/winamp/SPEC.BMP b/noatun/modules/winskin/skins/winamp/SPEC.BMP Binary files differnew file mode 100644 index 00000000..38df7813 --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/SPEC.BMP diff --git a/noatun/modules/winskin/skins/winamp/TEXT.BMP b/noatun/modules/winskin/skins/winamp/TEXT.BMP Binary files differnew file mode 100644 index 00000000..5b0b3a77 --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/TEXT.BMP diff --git a/noatun/modules/winskin/skins/winamp/TITLEBAR.BMP b/noatun/modules/winskin/skins/winamp/TITLEBAR.BMP Binary files differnew file mode 100644 index 00000000..b3109235 --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/TITLEBAR.BMP diff --git a/noatun/modules/winskin/skins/winamp/VISCOLOR.TXT b/noatun/modules/winskin/skins/winamp/VISCOLOR.TXT new file mode 100644 index 00000000..5871ad89 --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/VISCOLOR.TXT @@ -0,0 +1,24 @@ +0,0,0, // color 0 = black
+24,33,41, // color 1 = grey for dots
+239,49,16, // color 2 = top of spec
+206,41,16, // 3
+214,90,0, // 4
+214,102,0, // 5
+214,115,0, // 6
+198,123,8, // 7
+222,165,24, // 8
+214,181,33, // 9
+189,222,41, // 10
+148,222,33, // 11
+41,206,16, // 12
+50,190,16, // 13
+57,181,16, // 14
+49,156,8, // 15
+41,148,0, // 16
+24,132,8, // 17 = bottom of spec
+255,255,255, // 18 = osc 1
+214,214,222, // 19 = osc 2 (slightly dimmer)
+181,189,189, // 20 = osc 3
+160,170,175, // 21 = osc 4
+148,156,165, // 22 = osc 4
+150, 150, 150, // 23 = analyzer peak dots
diff --git a/noatun/modules/winskin/skins/winamp/VOLUME.BMP b/noatun/modules/winskin/skins/winamp/VOLUME.BMP Binary files differnew file mode 100644 index 00000000..deb7e924 --- /dev/null +++ b/noatun/modules/winskin/skins/winamp/VOLUME.BMP diff --git a/noatun/modules/winskin/vis/Makefile.am b/noatun/modules/winskin/vis/Makefile.am new file mode 100644 index 00000000..6935d860 --- /dev/null +++ b/noatun/modules/winskin/vis/Makefile.am @@ -0,0 +1,39 @@ +INCLUDES= -I$(kde_includes)/arts $(all_includes) +KDE_OPTIONS = nofinal + +DISTCLEANFILES = winskinvis.h winskinvis.cc + +winskinvis.mcopclass: winskinvis.h +winskinvis.mcoptype: winskinvis.h +winskinvis.cc winskinvis.h : $(srcdir)/winskinvis.idl + $(MCOPIDL) -t -I$(kde_includes)/arts $(srcdir)/winskinvis.idl + +lib_LTLIBRARIES = libwinskinvis.la +libwinskinvis_la_SOURCES= winskinvis.cc \ + winSkinFFT_impl.cpp realFFT.cpp \ + realFFTFilter.cpp visQueue.cpp + + +libwinskinvis_la_LDFLAGS= $(all_libraries) -avoid-version \ + -no-undefined + +libwinskinvis_la_LIBADD = -lkmedia2_idl -lsoundserver_idl -lartsflow +libwinskinvis_la_COMPILE_FIRST = winskinvis.cc +libwinskinvis_la_METASOURCES = AUTO + + + +mcoptypedir = $(libdir)/mcop +mcoptype_DATA = winskinvis.mcoptype winskinvis.mcopclass + +mcopclassdir = $(libdir)/mcop/Noatun +mcopclass_DATA = WinSkinFFT.mcopclass + +noatuninclude_HEADERS = winskinvis.h + +noatunincludedir = $(includedir)/noatun + + +winSkinFFT_impl.lo: winskinvis.h +winskinvis.lo: winskinvis.h + diff --git a/noatun/modules/winskin/vis/WinSkinFFT.mcopclass b/noatun/modules/winskin/vis/WinSkinFFT.mcopclass new file mode 100644 index 00000000..90d21e61 --- /dev/null +++ b/noatun/modules/winskin/vis/WinSkinFFT.mcopclass @@ -0,0 +1,5 @@ +Interface=Noatun::WinSkinFFT,Arts::StereoEffect,Arts::Object +Language=C++ +Library=libwinskinvis.la + + diff --git a/noatun/modules/winskin/vis/realFFT.cpp b/noatun/modules/winskin/vis/realFFT.cpp new file mode 100644 index 00000000..330280ea --- /dev/null +++ b/noatun/modules/winskin/vis/realFFT.cpp @@ -0,0 +1,156 @@ +/* + a FFT class + Copyright (C) 1998 Martin Vogt;Philip VanBaren + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "realFFT.h" + +/* + * Initialize the Sine table and Twiddle pointers (bit-reversed pointers) + * for the FFT routine. + */ +RealFFT::RealFFT(int fftlen) { + int i; + int temp; + int mask; + + /* + * FFT size is only half the number of data points + * The full FFT output can be reconstructed from this FFT's output. + * (This optimization can be made since the data is real.) + */ + Points = fftlen; + + if((SinTable=(short *)malloc(Points*sizeof(short)))==NULL) + { + puts("Error allocating memory for Sine table."); + exit(1); + } + if((BitReversed=(int *)malloc(Points/2*sizeof(int)))==NULL) + { + puts("Error allocating memory for BitReversed."); + exit(1); + } + + for(i=0;i<Points/2;i++) + { + temp=0; + for(mask=Points/4;mask>0;mask >>= 1) + temp=(temp >> 1) + (i&mask ? Points/2 : 0); + + BitReversed[i]=temp; + } + + for(i=0;i<Points/2;i++) + { + register double s,c; + s=floor(-32768.0*sin(2*M_PI*i/(Points))+0.5); + c=floor(-32768.0*cos(2*M_PI*i/(Points))+0.5); + if(s>32767.5) s=32767; + if(c>32767.5) c=32767; + SinTable[BitReversed[i] ]=(short)s; + SinTable[BitReversed[i]+1]=(short)c; + } + +} + +/* + * Free up the memory allotted for Sin table and Twiddle Pointers + */ +RealFFT::~RealFFT() { + free(BitReversed); + free(SinTable); + Points=0; +} + + +/* + * Actual FFT routine. Must call InitializeFFT(fftlen) first! + * This routine has another parameter list than the other fft's + * But because we want a fast fft on pcm data this routine + * is better than the other two. + * The other two can be useful for inverse FFT. + * The format is an array of floats. (only real parts the img + * part does not exists) + */ +void RealFFT::fft(short* buffer) { + int ButterfliesPerGroup=Points/4; + + endptr1=buffer+Points; + + /* + * Butterfly: + * Ain-----Aout + * \ / + * / \ + * Bin-----Bout + */ + + while(ButterfliesPerGroup>0) + { + A=buffer; + B=buffer+ButterfliesPerGroup*2; + sptr=SinTable; + + while(A<endptr1) + { + register short sin=*sptr; + register short cos=*(sptr+1); + endptr2=B; + while(A<endptr2) + { + long v1=((long)*B*cos + (long)*(B+1)*sin) >> 15; + long v2=((long)*B*sin - (long)*(B+1)*cos) >> 15; + *B=(*A+v1)>>1; + *(A++)=*(B++)-v1; + *B=(*A-v2)>>1; + *(A++)=*(B++)+v2; + } + A=B; + B+=ButterfliesPerGroup*2; + sptr+=2; + } + ButterfliesPerGroup >>= 1; + } + /* + * Massage output to get the output for a real input sequence. + */ + br1=BitReversed+1; + br2=BitReversed+Points/2-1; + + while(br1<=br2) + { + register long temp1,temp2; + short sin=SinTable[*br1]; + short cos=SinTable[*br1+1]; + A=buffer+*br1; + B=buffer+*br2; + HRplus = (HRminus = *A - *B ) + (*B << 1); + HIplus = (HIminus = *(A+1) - *(B+1)) + (*(B+1) << 1); + temp1 = ((long)sin*HRminus - (long)cos*HIplus) >> 15; + temp2 = ((long)cos*HRminus + (long)sin*HIplus) >> 15; + *B = (*A = (HRplus + temp1) >> 1) - temp1; + *(B+1) = (*(A+1) = (HIminus + temp2) >> 1) - HIminus; + + br1++; + br2--; + } + /* + * Handle DC bin separately + */ + buffer[0]+=buffer[1]; + buffer[1]=0; +} + + +int* RealFFT::getBitReversed() { + return BitReversed; +} diff --git a/noatun/modules/winskin/vis/realFFT.h b/noatun/modules/winskin/vis/realFFT.h new file mode 100644 index 00000000..39c6dbfd --- /dev/null +++ b/noatun/modules/winskin/vis/realFFT.h @@ -0,0 +1,69 @@ +/* + a FFT class + Copyright (C) 1998 Martin Vogt;Philip VanBaren + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __REALFFT_H +#define __REALFFT_H + +#include <math.h> +#include <stdlib.h> +#include <stdio.h> + +/** + <pre> + * Program: REALFFTF.C + * Author: Philip VanBaren + * Date: 2 September 1993 + * + * Description: These routines perform an FFT on real data. + * On a 486/33 compiled using Borland C++ 3.1 with full + * speed optimization and a small memory model, a 1024 point + * FFT takes about 16ms. + * This code is for floating point data. + * + * Note: Output is BIT-REVERSED! so you must use the BitReversed to + * get legible output, (i.e. Real_i = buffer[ BitReversed[i] ] + * Imag_i = buffer[ BitReversed[i]+1 ] ) + * Input is in normal order. + </pre> + */ + + + +class RealFFT { + + int* BitReversed; + short* SinTable; + int Points; + + public: + RealFFT(int fftlen); + ~RealFFT(); + + void fft(short* buffer); + int* getBitReversed(); + + private: + + short *A,*B; + short *sptr; + short *endptr1,*endptr2; + int *br1,*br2; + long HRplus,HRminus,HIplus,HIminus; + + +}; + + +#endif diff --git a/noatun/modules/winskin/vis/realFFTFilter.cpp b/noatun/modules/winskin/vis/realFFTFilter.cpp new file mode 100644 index 00000000..13343bce --- /dev/null +++ b/noatun/modules/winskin/vis/realFFTFilter.cpp @@ -0,0 +1,88 @@ +/* + a FFT filter + Copyright (C) 1998 Martin Vogt;Philip VanBaren, 2 September 1993 + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "realFFTFilter.h" + +RealFFTFilter::RealFFTFilter(int fftPoints) { + this->fftPoints = fftPoints; + data=new short[fftPoints*4]; + realFFT= new RealFFT(fftPoints*2); +} + + +RealFFTFilter::~RealFFTFilter() { + delete data; + delete realFFT; +} + + +int RealFFTFilter::getPoints() { + return fftPoints; +} + + +short* RealFFTFilter::getPointPtr() { + return data; +} + + +/* + the array is expected to be a PCM stream (real data) +*/ +int RealFFTFilter::fft16(float* left,float* right,int len) { + int i; + + len=len/4; + + + int mixTmp; + + // take care for no array overflows: + int n=min(len,fftPoints); + + // copy things into fftArray. + + for (i = 0 ; i < n; i++) { + mixTmp=(int) (16384.0*(left[i]+right[i])); + + if (mixTmp < SHRT_MIN) { + data[i]= SHRT_MIN; + } else { + if (mixTmp > SHRT_MAX) { + data[i] = SHRT_MAX; + } else { + data[i]=(short)mixTmp; + } + } + } + + realFFT->fft(data); + return true; +} + + + +int* RealFFTFilter::getBitReversed() { + return realFFT->getBitReversed(); +} + + + +int RealFFTFilter::min(int x1,int x2) { + if (x1 < x2) { + return x1; + } + return x2; +} + + diff --git a/noatun/modules/winskin/vis/realFFTFilter.h b/noatun/modules/winskin/vis/realFFTFilter.h new file mode 100644 index 00000000..255e5191 --- /dev/null +++ b/noatun/modules/winskin/vis/realFFTFilter.h @@ -0,0 +1,49 @@ +/* + a FFT filter + Copyright (C) 1998 Martin Vogt;Philip VanBaren, 2 September 1993 + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __REALFFTFILTER_H +#define __REALFFTFILTER_H + + + +#include "realFFT.h" +#include <limits.h> + + + +class RealFFTFilter { + + int fftPoints; + RealFFT* realFFT; + + short* data; + + + public: + RealFFTFilter(int points); + ~RealFFTFilter(); + int fft16(float* left,float* right,int len); + + int* getBitReversed(); + int getPoints(); + short* getPointPtr(); + + private: + int min(int x1,int x2); + +}; + + +#endif diff --git a/noatun/modules/winskin/vis/visQueue.cpp b/noatun/modules/winskin/vis/visQueue.cpp new file mode 100644 index 00000000..370930d2 --- /dev/null +++ b/noatun/modules/winskin/vis/visQueue.cpp @@ -0,0 +1,43 @@ +/* + queue fft samples + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "visQueue.h" + + +VISQueue::VISQueue(int elements) { + this->elements=elements; + + visArrayQueue = new std::vector<float>*[elements]; + for(int i=0;i<elements;i++) + { + visArrayQueue[i]=new std::vector<float>; + } + +} + +VISQueue::~VISQueue() { + for(int i=0;i<elements;i++) { + delete visArrayQueue[i]; + } + delete [] visArrayQueue; +} + +std::vector<float>* VISQueue::getElement(int i) +{ + if ( (i < 0) || (i>elements) ) { + return visArrayQueue[0]; + } + return visArrayQueue[i]; +} + + diff --git a/noatun/modules/winskin/vis/visQueue.h b/noatun/modules/winskin/vis/visQueue.h new file mode 100644 index 00000000..2f737fd1 --- /dev/null +++ b/noatun/modules/winskin/vis/visQueue.h @@ -0,0 +1,32 @@ +/* + queue fft samples + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#ifndef __VISQUEUE_H +#define __VISQUEUE_H + + +#include <vector> + +class VISQueue { + + int elements; + std::vector<float> **visArrayQueue; + + public: + VISQueue(int elements); + ~VISQueue(); + + std::vector<float>* getElement(int i); + +}; +#endif diff --git a/noatun/modules/winskin/vis/winSkinFFT_impl.cpp b/noatun/modules/winskin/vis/winSkinFFT_impl.cpp new file mode 100644 index 00000000..5396ac3c --- /dev/null +++ b/noatun/modules/winskin/vis/winSkinFFT_impl.cpp @@ -0,0 +1,148 @@ +/* + implementation for winskin fft + Copyright (C) 2000 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#include "winSkinFFT_impl.h" +#include <audiosubsys.h> +#include <cstring> + +#define __BANDS 75 + +namespace Noatun { + +WinSkinFFT_impl::WinSkinFFT_impl() { + fftBands_short=256; + realFFTFilter= new RealFFTFilter(fftBands_short); + fftArray=new int[fftBands_short]; + bands=0; + + fragCnt=(int)(AudioSubSystem::the()->fragmentCount()); + visQueue=new VISQueue(fragCnt); + writePos=0; + +} + +WinSkinFFT_impl::~WinSkinFFT_impl(){ + delete realFFTFilter; + delete fftArray; + delete visQueue; +} + +void WinSkinFFT_impl::streamInit() { +} + + +void WinSkinFFT_impl::streamStart() { +} + + +void WinSkinFFT_impl::calculateBlock(unsigned long samples) { + + + unsigned long i; + + // monitoring only tasks can't be done with that StereoEffect + // interface nicely - copy input to output until there is + // something better + // (when?) + int n=sizeof(float)*samples; + memcpy(outleft,inleft,n); + memcpy(outright,inright,n); + + + if (realFFTFilter->fft16(inleft,inright,samples) == false) { + return; + } + + + + // + // The following modifications have nothing to do + // with an fft, they only make the output look nice. + // (mostly scaling) + + short* fftPtr; + int* bitReversed; + + fftPtr=realFFTFilter->getPointPtr(); + bitReversed=realFFTFilter->getBitReversed(); + + int pos=0; + int step=realFFTFilter->getPoints()/__BANDS; + + + int re; + int im; + int tmp; + + float max=0.0; + float avg=0.0; + + + + for (i=0;i<__BANDS;i++) { + re=(int)fftPtr[bitReversed[pos]]; + im=(int)fftPtr[bitReversed[pos]+1]; + + tmp=re*re+im*im; + // Here I check a new idea. We remove all low values + // and all values over xyz to xyz. + fftArray[pos]=(int)(::sqrt(::sqrt(tmp))); + + if (fftArray[pos]<=15) { + max+=fftArray[pos]; + } else { + max+=15+fftArray[pos]/2; + } + pos=pos+step; + } + avg=0.65*max/(float)__BANDS; + + pos=0; + vector<float>* visAnalyserArray=visQueue->getElement(writePos); + visAnalyserArray->clear(); + visAnalyserArray->reserve(__BANDS); + for (i=0;i<__BANDS;i++) { + float val=(float)(fftArray[pos]-avg); + visAnalyserArray->push_back(val); + pos=pos+step; + } + writePos++; + if (writePos >= fragCnt) writePos=0; + +} + + +void WinSkinFFT_impl::bandResolution(float res) { + bands=(int)res; +} + +float WinSkinFFT_impl::bandResolution() { + return (float)bands; +} + + +vector<float>* WinSkinFFT_impl::scope() { + int delay=writePos+1; + if (delay >= fragCnt) delay=0; + + + vector<float>* visAnalyserArray=visQueue->getElement(delay); + + return new vector<float>(*visAnalyserArray); +} + + +REGISTER_IMPLEMENTATION(WinSkinFFT_impl); + +} diff --git a/noatun/modules/winskin/vis/winSkinFFT_impl.h b/noatun/modules/winskin/vis/winSkinFFT_impl.h new file mode 100644 index 00000000..c1a77e45 --- /dev/null +++ b/noatun/modules/winskin/vis/winSkinFFT_impl.h @@ -0,0 +1,62 @@ +/* + implementation for winskin fft + Copyright (C) 2000 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#ifndef __WINSKINFFT_IMPL_H +#define __WINSKINFFT_IMPL_H + +#include <artsflow.h> +#include <stdsynthmodule.h> +#include "winskinvis.h" +#include "realFFTFilter.h" +#include "visQueue.h" + + +using namespace std; +using namespace Arts; + +namespace Noatun { + +class WinSkinFFT_impl : public WinSkinFFT_skel, public StdSynthModule { + + public: + + WinSkinFFT_impl(); + ~WinSkinFFT_impl(); + + void streamInit(); + void streamStart(); + + // in: audio stream inleft, inright; + // out: audio stream outleft, outright; + void calculateBlock(unsigned long samples); + + void bandResolution(float res); + float bandResolution(); + vector<float> *scope(); + + private: + RealFFTFilter* realFFTFilter; + int fftBands_short; + int* fftArray; + VISQueue* visQueue; + int bands; + + int fragCnt; + int writePos; + int readPos; +}; + + +} + +#endif diff --git a/noatun/modules/winskin/vis/winskinvis.idl b/noatun/modules/winskin/vis/winskinvis.idl new file mode 100644 index 00000000..9b6564f4 --- /dev/null +++ b/noatun/modules/winskin/vis/winskinvis.idl @@ -0,0 +1,12 @@ +#include <artsflow.idl> + +module Noatun +{ + +interface WinSkinFFT : Arts::StereoEffect +{ + attribute float bandResolution; + sequence<float> scope(); +}; + +};
\ No newline at end of file diff --git a/noatun/modules/winskin/waBalanceSlider.cpp b/noatun/modules/winskin/waBalanceSlider.cpp new file mode 100644 index 00000000..1ac1b562 --- /dev/null +++ b/noatun/modules/winskin/waBalanceSlider.cpp @@ -0,0 +1,56 @@ +/* + balanceslider for winamp skins + Copyright (C) 1998 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include <waBalanceSlider.h> + + +WaBalanceSlider::WaBalanceSlider() : WaWidget(_WA_MAPPING_BALANCE_BAR) +{ +} + + +WaBalanceSlider::~WaBalanceSlider() +{ +} + + +void WaBalanceSlider::buildGui() +{ + ws = new WaSlider(_WA_MAPPING_BALANCE_BAR, + _WA_MAPPING_BALANCE_SLIDER, true); + + ws->setRange(-100, 100); + + + ws->setPixmapSliderButtonUp(_WA_SKIN_BALANCE_SLIDER_NORM); + ws->setPixmapSliderButtonDown(_WA_SKIN_BALANCE_SLIDER_PRES); + ws->setPixmapSliderBar(_WA_SKIN_BALANCE_BAR); + + ws->setValue(0); + + connect(ws, SIGNAL(valueChanged(int)), this, + SIGNAL(balanceSetValue(int))); + connect(ws, SIGNAL(sliderPressed()), SIGNAL(sliderPressed())); + connect(ws, SIGNAL(sliderReleased()), SIGNAL(sliderReleased())); +} + + +void WaBalanceSlider::setBalanceValue(int val) +{ + int currVal = ws->value(); + if (currVal != val) { + ws->setValue(val); + } +} + +#include "waBalanceSlider.moc" diff --git a/noatun/modules/winskin/waBalanceSlider.h b/noatun/modules/winskin/waBalanceSlider.h new file mode 100644 index 00000000..d120bcc7 --- /dev/null +++ b/noatun/modules/winskin/waBalanceSlider.h @@ -0,0 +1,42 @@ +/* + balanceslider for winamp skins + Copyright (C) 1999 Martin Vogt + Copyright (C) 2001 Ryan Cumming + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef __WABALANCESLIDER_H +#define __WABALANCESLIDER_H + +#include <waSlider.h> +#include "waWidget.h" + +class WaBalanceSlider : public WaWidget { + Q_OBJECT + + public: + WaBalanceSlider(); + ~WaBalanceSlider(); + void buildGui(); + + void setBalanceValue(int val); + + private: + WaSlider *ws; + + signals: + void balanceSetValue(int val); + void sliderPressed(); + void sliderReleased(); +}; + + +#endif diff --git a/noatun/modules/winskin/waButton.cpp b/noatun/modules/winskin/waButton.cpp new file mode 100644 index 00000000..cac0275a --- /dev/null +++ b/noatun/modules/winskin/waButton.cpp @@ -0,0 +1,101 @@ +/* + standard Button fo winamp Skin + Copyright (C) 1999 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + +#include <qbitmap.h> + +#include "waButton.h" + +WaButton::WaButton(int mapId) : WaWidget(mapId) +{ + _togglable = false; + _toggled = false; + pressed = false; +} + + +WaButton::~WaButton() { +} + +void WaButton::setPixmapUp(int pixId) { + nUpId=pixId; +} + + +void WaButton::setPixmapDown(int pixId) { + nDownId=pixId; +} + + +void WaButton::setPixmapUpSelected(int pixId) { + nUpIdSelected=pixId; +} + + +void WaButton::setPixmapDownSelected(int pixId) { + nDownIdSelected=pixId; +} + +void WaButton::paintEvent(QPaintEvent *) { + paintPixmap(getPixmapId()); +} + + +void WaButton::mousePressEvent(QMouseEvent* e) { + if (e->button() != LeftButton) { + // We can't deal with it, but maybe the widget can do something clever + WaWidget::mousePressEvent(e); + } + else { + pressed = true; + update(); + } +} + +void WaButton::mouseReleaseEvent(QMouseEvent* e) { + if (!pressed) { + // We're not pressed, so just pass along the mouse event, it's not ours + WaWidget::mouseReleaseEvent(e); + } + else { + pressed = false; + + if (this->rect().contains(e->pos())){ + if (_togglable) { + _toggled = !_toggled; + emit(toggleEvent(_toggled)); + } + + emit(clicked()); + } + } + + update(); +} + +int WaButton::getPixmapId() { + if (_toggled == true) { + if (pressed) + return nDownIdSelected; + else + return nUpIdSelected; + } + else { + if (pressed) + return nDownId; + else + return nUpId; + } + + return -1; +} + +#include "waButton.moc" diff --git a/noatun/modules/winskin/waButton.h b/noatun/modules/winskin/waButton.h new file mode 100644 index 00000000..50947216 --- /dev/null +++ b/noatun/modules/winskin/waButton.h @@ -0,0 +1,62 @@ +/* + standard Button for winamp Skin + Copyright (C) 1999 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __WABUTTON_H +#define __WABUTTON_H + +#include <qpainter.h> +#include "waWidget.h" + +class WaButton : public WaWidget { + Q_OBJECT + public: + WaButton(int mapId); + ~WaButton(); + + void setPixmapDown(int pixId); + void setPixmapUp(int pixId); + void setPixmapUpSelected(int pixId); + void setPixmapDownSelected(int pixId); + + void setToggled(bool toggled_flag) { _toggled = toggled_flag; update(); } + bool toggled() const { return _toggled; } + + void setTogglable(bool togglable_flag) { _togglable = togglable_flag; update(); } + bool togglable() const { return _togglable; } + + int getPixmapId(); + void paintEvent(QPaintEvent*); + + private: + void mousePressEvent (QMouseEvent* e); + void mouseReleaseEvent (QMouseEvent* e); + + int nUpId; + int nDownId; + int nDownIdSelected; + int nUpIdSelected; + + QPoint currentLocation; + + bool _toggled; + bool _togglable; + + bool pressed; + + signals: + void toggleEvent(bool val); + void clicked(); +}; +#endif diff --git a/noatun/modules/winskin/waClutterbar.cpp b/noatun/modules/winskin/waClutterbar.cpp new file mode 100644 index 00000000..6ceb7d04 --- /dev/null +++ b/noatun/modules/winskin/waClutterbar.cpp @@ -0,0 +1,11 @@ +#include "waClutterbar.h" +#include "waClutterbar.moc" +WaClutterbar::WaClutterbar() : WaWidget(_WA_MAPPING_CLUTTERBAR) { +} + +WaClutterbar::~WaClutterbar() { +} + +void WaClutterbar::paintEvent(QPaintEvent *) { + paintPixmap(_WA_SKIN_CLUTTERBAR_DISABLED); +} diff --git a/noatun/modules/winskin/waClutterbar.h b/noatun/modules/winskin/waClutterbar.h new file mode 100644 index 00000000..69339c37 --- /dev/null +++ b/noatun/modules/winskin/waClutterbar.h @@ -0,0 +1,18 @@ +#ifndef __WACLUTTERBAR_H +#define __WACLUTTERBAR_H + +#include <qpainter.h> +#include "waWidget.h" + +class WaClutterbar : public WaWidget { + Q_OBJECT + + public: + WaClutterbar(); + ~WaClutterbar(); + + public slots: + void paintEvent(QPaintEvent *); +}; + +#endif diff --git a/noatun/modules/winskin/waColor.cpp b/noatun/modules/winskin/waColor.cpp new file mode 100644 index 00000000..e06b38bc --- /dev/null +++ b/noatun/modules/winskin/waColor.cpp @@ -0,0 +1,73 @@ +#include <fstream> +#include <qfile.h> + +#include "waColor.h" + +WaColor *colorScheme = NULL; + +WaColor::WaColor(QString filename) { + int r, g, b; + char comma; + + skinColors[0].setRgb(0, 0, 0); + skinColors[1].setRgb(24, 33, 41); + skinColors[2].setRgb(239, 49, 16); + skinColors[3].setRgb(206, 41, 16); + skinColors[4].setRgb(214, 90, 0); + skinColors[5].setRgb(214, 102, 0); + skinColors[6].setRgb(214, 115, 0); + skinColors[7].setRgb(198, 123, 8); + skinColors[8].setRgb(222, 165, 24); + skinColors[9].setRgb(214, 181, 33); + skinColors[10].setRgb(189, 222, 41); + skinColors[11].setRgb(148, 222, 33); + skinColors[12].setRgb(41, 206, 16); + skinColors[13].setRgb(50, 190, 16); + skinColors[14].setRgb(57, 181, 16); + skinColors[15].setRgb(49, 156, 8); + skinColors[16].setRgb(41, 148, 0); + skinColors[17].setRgb(24, 132, 8); + skinColors[18].setRgb(255, 255, 255); + skinColors[19].setRgb(214, 214, 222); + skinColors[20].setRgb(181, 189, 189); + skinColors[21].setRgb(160, 170, 175); + skinColors[22].setRgb(148, 156, 165); + skinColors[23].setRgb(150, 150, 150); + + if (filename.isEmpty()) { + return; + } + + std::ifstream viscolor(QFile::encodeName(filename)); + + if (!viscolor) + return; + + for (int index = 0;index < 24;index++) { + viscolor >> r; + viscolor >> std::ws; + viscolor >> comma; + viscolor >> std::ws; + viscolor >> g; + viscolor >> std::ws; + viscolor >> comma; + viscolor >> std::ws; + viscolor >> b; + + while(1) { + char c; + + if (!viscolor.get(c)) + return; + + if (c == '\n') + break; + } + + skinColors[index].setRgb(r, g, b); + } + +} + +WaColor::~WaColor() { +} diff --git a/noatun/modules/winskin/waColor.h b/noatun/modules/winskin/waColor.h new file mode 100644 index 00000000..a0e18484 --- /dev/null +++ b/noatun/modules/winskin/waColor.h @@ -0,0 +1,26 @@ + + +#ifndef WACOLOR_H +#define WACOLOR_H + +#include <qcolor.h> +#include <qstring.h> + +#define INDEX_BACKGROUND_COLOR 0 +#define INDEX_GRID_COLOR 1 +#define INDEX_SPEC_BASE 2 +#define INDEX_OSC_BASE 18 +#define INDEX_PEAKS 23 + +class WaColor { +public: + WaColor(QString filename); + ~WaColor(); + + QColor skinColors[24]; +}; + +extern WaColor *colorScheme; + +#endif + diff --git a/noatun/modules/winskin/waDigit.cpp b/noatun/modules/winskin/waDigit.cpp new file mode 100644 index 00000000..b775d7cf --- /dev/null +++ b/noatun/modules/winskin/waDigit.cpp @@ -0,0 +1,89 @@ +/* + The digit for the time + Copyright (C) 1999 Martin Vogt + Copyright (C) 2002 Ryan Cumming + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "waDigit.h" +#include "waSkinModel.h" + +#include <kconfig.h> +#include <kglobal.h> + +WaDigit::WaDigit() : WaWidget(_WA_MAPPING_DIGITS) +{ + KConfig *config = KGlobal::config(); + config->setGroup("Winskin"); + + reverse_time = config->readNumEntry("timeReversed", false); +} + + +WaDigit::~WaDigit() +{ + KConfig *config = KGlobal::config(); + config->setGroup("Winskin"); + config->writeEntry("timeReversed", reverse_time); +} + +void WaDigit::paintEvent(QPaintEvent *) +{ + paintBackground(); + + const char *time = timeString.latin1(); + int len = strlen(time); + if (len == 0) + return; + + // Declare all these variables after we check for zero-length + WaSkinModel *waSkinModel = WaSkinModel::instance(); + + int x = waSkinModel->getMapGeometry(mapping).x(); + int y = waSkinModel->getMapGeometry(mapping).y(); + + QRect mapRect; + + // We expect strings either in the form "xx:yy", or "-xx:yy" + // If the string length is 6, we have it in the form of "-xx:yy" + // Remove the -, move the string forward one character, and + // continue parsing + mapRect = waSkinModel->getMapGeometry(_WA_MAPPING_MINUS); + if (len == 6) { + waSkinModel->getDigit('-', this, mapRect.x() - x, mapRect.y() - y); + time++; + } + else { + waSkinModel->getDigit(' ', this, mapRect.x() - x, mapRect.y() - y); + } + + mapRect = waSkinModel->getMapGeometry(_WA_MAPPING_DIGIT_1); + waSkinModel->getDigit(time[0], this, mapRect.x() - x, mapRect.y() - y); + + mapRect = waSkinModel->getMapGeometry(_WA_MAPPING_DIGIT_2); + waSkinModel->getDigit(time[1], this, mapRect.x() - x, mapRect.y() - y); + + mapRect = waSkinModel->getMapGeometry(_WA_MAPPING_DIGIT_3); + waSkinModel->getDigit(time[3], this, mapRect.x() - x, mapRect.y() - y); + + mapRect = waSkinModel->getMapGeometry(_WA_MAPPING_DIGIT_4); + waSkinModel->getDigit(time[4], this, mapRect.x() - x, mapRect.y() - y); +} + +void WaDigit::mousePressEvent(QMouseEvent* e) { + if (e->button() == LeftButton) { + reverse_time = !reverse_time; + emit digitsClicked(); + } + else + WaWidget::mousePressEvent(e); +} + +#include "waDigit.moc" diff --git a/noatun/modules/winskin/waDigit.h b/noatun/modules/winskin/waDigit.h new file mode 100644 index 00000000..cefbfeb3 --- /dev/null +++ b/noatun/modules/winskin/waDigit.h @@ -0,0 +1,48 @@ +/* + The digit for the time + Copyright (C) 1999 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __WADIGIT_H +#define __WADIGIT_H + +#include <qpainter.h> + +#include "waWidget.h" + +class WaDigit : public WaWidget { + Q_OBJECT + + public: + WaDigit(); + ~WaDigit(); + + void setTime(QString time) { timeString = time; update(); } + QString time() const { return timeString; } + + bool timeReversed() const { return reverse_time; } + + public slots: + void paintEvent(QPaintEvent * paintEvent); + + private: + void mousePressEvent(QMouseEvent* e); + bool reverse_time; + + WaSkinModel *waSkinModel; + QString timeString; + + signals: + void digitsClicked(); +}; +#endif diff --git a/noatun/modules/winskin/waIndicator.cpp b/noatun/modules/winskin/waIndicator.cpp new file mode 100644 index 00000000..9c5efa84 --- /dev/null +++ b/noatun/modules/winskin/waIndicator.cpp @@ -0,0 +1,34 @@ +/* + State indicator for Winamp Skin + Copyright (C) 2002 Ryan Cumming + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include <waIndicator.h> + +WaIndicator::WaIndicator(int widget_mapping, int enabled_mapping, int disabled_mapping) + : WaWidget(widget_mapping) +{ + _state = false; + _enabled_mapping = enabled_mapping; + _disabled_mapping = disabled_mapping; +} + +WaIndicator::~WaIndicator() +{ +} + +void WaIndicator::paintEvent(QPaintEvent *) +{ + paintPixmap( _state ? _enabled_mapping : _disabled_mapping ); +} + + +#include "waIndicator.moc" diff --git a/noatun/modules/winskin/waIndicator.h b/noatun/modules/winskin/waIndicator.h new file mode 100644 index 00000000..f367fe84 --- /dev/null +++ b/noatun/modules/winskin/waIndicator.h @@ -0,0 +1,41 @@ +/* + Standard state indicator for Winamp skin + Copyright (C) 2002 Ryan Cumming + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __WAINDICATOR_H +#define __WAINDICATOR_H + +#include <qpainter.h> + +#include "waWidget.h" + +class WaIndicator : public WaWidget { + Q_OBJECT + + public: + WaIndicator(int widget_mapping, int enabled_mapping, int disabled_mapping); + ~WaIndicator(); + + void setState(bool state) { _state = state; update(); } + bool state() const { return _state; } + + public slots: + void paintEvent(QPaintEvent *); + + private: + int _enabled_mapping; + int _disabled_mapping; + bool _state; +}; +#endif diff --git a/noatun/modules/winskin/waInfo.cpp b/noatun/modules/winskin/waInfo.cpp new file mode 100644 index 00000000..c735a8e4 --- /dev/null +++ b/noatun/modules/winskin/waInfo.cpp @@ -0,0 +1,173 @@ +/* + Scrolling song title for winamp Skin + Copyright (C) 1999 Martin Vogt + Copyright (C) 2001 Ryan Cumming + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include <qpainter.h> +#include <qpixmap.h> + +#include <stdlib.h> + +#include <kconfig.h> +#include <kglobal.h> + +#include "waInfo.h" +#include "waSkinModel.h" + +WaInfo::WaInfo() : WaWidget(_WA_MAPPING_INFO) +{ + connect(WaSkinModel::instance(), SIGNAL(skinChanged()), + this, SLOT(pixmapChange())); + + completePixmap = new QPixmap(); + + QSize size = sizeHint(); + completePixmap->resize(size.width(), size.height()); + + xGrabbedPos = -1; + + timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(timeEvent())); +} + +WaInfo::~WaInfo() +{ + delete completePixmap; +} + + +void WaInfo::timeEvent() +{ + if ((xGrabbedPos == -1) && (xScrollDirection)) { + xScrollPos += xScrollDirection; + + if (abs(xScrollPos) > completePixmap->width()) { + xScrollPos = 0; + } + + if (isVisible()) + repaint(false); + } +} + + +void WaInfo::scrollerSetup() +{ + xScrollPos = 0; + xScrollDirection = 0; + timer->stop(); + QSize size = sizeHint(); + if (completePixmap->width() > size.width()) { + xScrollDirection = 1; + + KConfig *config=KGlobal::config(); + config->setGroup("Winskin"); + int s = config->readNumEntry("ScrollDelay", 15); + if (s!=0) + timer->start(50-s); + } +} + +void WaInfo::paintEvent(QPaintEvent *) +{ + QSize size = sizeHint(); + + if (completePixmap->width() <= size.width()) { + bitBlt(this, 0, 0, completePixmap); + return; + } + + // pixmap widther than window: + int xDrawWidth; + int xRestWidth; + + xDrawWidth = completePixmap->width() - xScrollPos; + if (xDrawWidth > size.width()) { + xDrawWidth = size.width(); + } + + + bitBlt(this, 0, 0, completePixmap, xScrollPos, 0, xDrawWidth); + + if (xDrawWidth < size.width()) { + xRestWidth = size.width() - xDrawWidth; + bitBlt(this, xDrawWidth, 0, completePixmap, 0, 0, xRestWidth); + } +} + + +void WaInfo::setText(QString song) +{ + if (_text != song) { + _text = song; + pixmapChange(); + } +} + +QString WaInfo::text() const +{ + return _text; +} + + +void WaInfo::pixmapChange() +{ + int i; + const char *infoString = _text.latin1(); + + int x = 0; + int n=infoString ? strlen(infoString) : 0; + + QSize size = sizeHint(); + + completePixmap->resize(QMAX(n * _WA_TEXT_WIDTH, size.width()), _WA_TEXT_HEIGHT); + + for (i = 0; i < n; i++) { + WaSkinModel::instance()->getText(infoString[i], completePixmap, x, 0); + x += _WA_TEXT_WIDTH; + } + + // if the size is now smaller than the with of this widget, we + // fill the pixmap with spaces + if (x < size.width()) { + while (x < size.width()) { + WaSkinModel::instance()->getText(' ', completePixmap, x, 0); + x += _WA_TEXT_WIDTH; + } + } + + scrollerSetup(); + update(); +} + +void WaInfo::mousePressEvent (QMouseEvent *e) { + if (e->button() == LeftButton) + xGrabbedPos = (e->x() + xScrollPos) % completePixmap->width(); +} + +void WaInfo::mouseMoveEvent (QMouseEvent * e) { + xScrollPos = -e->x() + xGrabbedPos; + + if (xScrollPos < 0) + xScrollPos = completePixmap->width() - (-xScrollPos % completePixmap->width()); + else + xScrollPos %= completePixmap->width(); + + update(); +} + +void WaInfo::mouseReleaseEvent (QMouseEvent *) { + xGrabbedPos = -1; +} + + +#include "waInfo.moc" diff --git a/noatun/modules/winskin/waInfo.h b/noatun/modules/winskin/waInfo.h new file mode 100644 index 00000000..513ff3cc --- /dev/null +++ b/noatun/modules/winskin/waInfo.h @@ -0,0 +1,53 @@ +/* + standard Button for winamp Skin + Copyright (C) 1999 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __WAINFO_H +#define __WAINFO_H + +#include <qpainter.h> +#include <qtimer.h> + +#include "waWidget.h" + +class WaInfo : public WaWidget { + Q_OBJECT + + public: + WaInfo(); + ~WaInfo(); + + void setText(QString song); + QString text() const; + void scrollerSetup(); + + protected: + void paintEvent(QPaintEvent * paintEvent); + + void mousePressEvent (QMouseEvent * e); + void mouseMoveEvent (QMouseEvent * e); + void mouseReleaseEvent (QMouseEvent * e); + + QPixmap *completePixmap; + QString _text; + QTimer *timer; + int xScrollPos; + int xScrollDirection; + int xGrabbedPos; + + protected slots: + void pixmapChange(); + void timeEvent(); +}; +#endif diff --git a/noatun/modules/winskin/waJumpSlider.cpp b/noatun/modules/winskin/waJumpSlider.cpp new file mode 100644 index 00000000..51633300 --- /dev/null +++ b/noatun/modules/winskin/waJumpSlider.cpp @@ -0,0 +1,78 @@ +/* + jumpslider for winamp skins + Copyright (C) 1998 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "waJumpSlider.h" + +WaJumpSlider::WaJumpSlider() : WaWidget(_WA_MAPPING_POS_BAR) +{ +} + +WaJumpSlider::~WaJumpSlider() +{ +} + +void WaJumpSlider::buildGui() +{ + ws = new WaSlider(_WA_MAPPING_POS_BAR, _WA_MAPPING_POS_BAR_SLIDER); + ws->setPixmapSliderButtonUp(_WA_SKIN_POS_BAR_SLIDER_NORM); + ws->setPixmapSliderButtonDown(_WA_SKIN_POS_BAR_SLIDER_PRES); + ws->setPixmapSliderBar(_WA_SKIN_POS_BAR); + ws->setRange(0, 100); + ws->setValue(0); + + connect(ws, SIGNAL(sliderPressed()), this, SIGNAL(sliderPressed())); + connect(ws, SIGNAL(sliderReleased()), this, SLOT(releasedSlider())); + connect(ws, SIGNAL(valueChanged(int)), this, SIGNAL(valueChanged(int))); +} + +void WaJumpSlider::setJumpRange(int val) +{ + if (val == -1) + ws->hideButton(); + else { + ws->showButton(); + ws->setRange(0, val); + } +} + +int WaJumpSlider::jumpValue() { + return ws->value(); +} + +void WaJumpSlider::setJumpValue(int val) +{ + int currVal = ws->value(); + + if (currVal != val) { + ws->setValue(val); + } +} + +void WaJumpSlider::releasedSlider() { + emit(jump(ws->value())); + emit(sliderReleased()); +} + +void WaJumpSlider::showEvent (QShowEvent *) { + ws->show(); +} + +void WaJumpSlider::hideEvent (QHideEvent *) { + ws->hide(); +} + +void WaJumpSlider::cancelDrag() { + ws->cancelDrag(); +} + +#include "waJumpSlider.moc" diff --git a/noatun/modules/winskin/waJumpSlider.h b/noatun/modules/winskin/waJumpSlider.h new file mode 100644 index 00000000..12c07808 --- /dev/null +++ b/noatun/modules/winskin/waJumpSlider.h @@ -0,0 +1,52 @@ +/* + jumpslider for winamp skins + Copyright (C) 1998 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef __WAJUMPSLIDER_H +#define __WAJUMPSLIDER_H + +#include "waSlider.h" +#include "waWidget.h" + +class WaJumpSlider : public WaWidget { + Q_OBJECT + + public: + WaJumpSlider(); + ~WaJumpSlider(); + void buildGui(); + + void setJumpRange(int val); + + void setJumpValue(int val); + int jumpValue(); + + void cancelDrag(); + + protected: + WaSlider *ws; + void showEvent (QShowEvent *); + void hideEvent (QHideEvent *); + + private slots: + void releasedSlider(); + + signals: + void jump(int seconds); + void sliderPressed(); + void sliderReleased(); + void valueChanged(int); +}; + + +#endif diff --git a/noatun/modules/winskin/waLabel.cpp b/noatun/modules/winskin/waLabel.cpp new file mode 100644 index 00000000..8f3ddb60 --- /dev/null +++ b/noatun/modules/winskin/waLabel.cpp @@ -0,0 +1,65 @@ +/* + Standard label for Winskin + Copyright (C) 1999 Martin Vogt + Copyright (C) 2001 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + +#include <qpainter.h> +#include <qpixmap.h> + +#include "waLabel.h" +#include "waSkinModel.h" + +WaLabel::WaLabel(int mapping) : WaWidget(mapping) +{ + connect(WaSkinModel::instance(), SIGNAL(skinChanged()), + this, SLOT(pixmapChange())); + + completePixmap = new QPixmap(); + + QSize size = sizeHint(); + + completePixmap->resize(size.width(), size.height()); +} + +WaLabel::~WaLabel() +{ + delete completePixmap; +} + +void WaLabel::paintEvent(QPaintEvent *) +{ + bitBlt(this, 0, 0, completePixmap); +} + +void WaLabel::setText(const QString &new_text) +{ + int width = WaSkinModel::instance()->getMapGeometry(mapping).width(); + + // Fit the text to the widget + // This should always be three characters, but we generate its value anyway + _text = new_text.rightJustify(width / _WA_TEXT_WIDTH, ' '); + + pixmapChange(); + + update(); +} + +void WaLabel::pixmapChange() +{ + const char *label_text = _text.latin1(); + int n = label_text ? strlen(label_text) : 0; + + for (int i = 0; i < n; i++) + WaSkinModel::instance()->getText(label_text[i], completePixmap, + i * _WA_TEXT_WIDTH, 0); +} + +#include "waLabel.moc" diff --git a/noatun/modules/winskin/waLabel.h b/noatun/modules/winskin/waLabel.h new file mode 100644 index 00000000..f1470902 --- /dev/null +++ b/noatun/modules/winskin/waLabel.h @@ -0,0 +1,39 @@ +/* + standard Button for winamp Skin + Copyright (C) 1999 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + +#ifndef __WABPS_H +#define __WABPS_H + +#include <qpainter.h> +#include "waWidget.h" + +class WaLabel : public WaWidget { + Q_OBJECT + + public: + WaLabel(int mapping); + ~WaLabel(); + + void setText(const QString &text); + QString text() const { return _text; } + + private: + void paintEvent(QPaintEvent *); + + QPixmap *completePixmap; + QString _text; + + + private slots: + void pixmapChange(); +}; +#endif diff --git a/noatun/modules/winskin/waMain.cpp b/noatun/modules/winskin/waMain.cpp new file mode 100644 index 00000000..a5bb7fdc --- /dev/null +++ b/noatun/modules/winskin/waMain.cpp @@ -0,0 +1,13 @@ +#include "waMain.h" + +WaMain::WaMain() : WaWidget(_WA_MAPPING_MAIN) { +} + +WaMain::~WaMain() { +} + +void WaMain::paintEvent(QPaintEvent *) { + paintPixmap(_WA_SKIN_MAIN); +} + +#include "waMain.moc" diff --git a/noatun/modules/winskin/waMain.h b/noatun/modules/winskin/waMain.h new file mode 100644 index 00000000..06bcfe5d --- /dev/null +++ b/noatun/modules/winskin/waMain.h @@ -0,0 +1,16 @@ +#ifndef __WAMAIN_H +#define __WAMAIN_H + +#include "waWidget.h" + +class WaMain : WaWidget { + Q_OBJECT +public: + WaMain(); + ~WaMain(); + +protected: + void paintEvent(QPaintEvent *); +}; + +#endif diff --git a/noatun/modules/winskin/waRegion.cpp b/noatun/modules/winskin/waRegion.cpp new file mode 100644 index 00000000..ab4d2e57 --- /dev/null +++ b/noatun/modules/winskin/waRegion.cpp @@ -0,0 +1,126 @@ +/* + Winamp Skin + Copyright (C) 2002 Ryan Cumming + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + +#include <ksimpleconfig.h> +#include <qbitmap.h> +#include <qpainter.h> +#include <qregexp.h> + +#include "waSkinModel.h" +#include "waSkins.h" +#include "waRegion.h" + +WaRegion *windowRegion = NULL; + +// Hack around case-insensitivity in Winamp INI files by searching for common capitializations +// Needs to be replaced with an all-custom loader after 3.0 +const char *pointListNames[] = {"PointList", "pointlist", "Pointlist", "pointList", "POINTLIST", 0}; +const char *numPointsNames[] = {"NumPoints", "numpoints", "Numpoints", "numPoints", "NUMPOINTS", 0}; + +WaRegion::WaRegion(QString filename) { + // Load the region file, which happens to be in KConfig format + KSimpleConfig regionFile(filename, true); + + // Clear our variables by default + window_mask = 0; + shade_mask = 0; + + // Make the new bitmaps, default window size + window_mask = new QBitmap(WaSkinModel::instance()->getMapGeometry(_WA_MAPPING_MAIN).size(), true); + shade_mask = new QBitmap(WaSkinModel::instance()->getMapGeometry(_WA_MAPPING_TITLE).size(), true); + + // Load the normal window mask data + regionFile.setGroup("Normal"); + + QValueList<int> num_points; + for (int x = 0;numPointsNames[x];x++) { + if (regionFile.hasKey(numPointsNames[x])) + num_points = parseList(regionFile.readEntry(numPointsNames[x])); + } + + QValueList<int> point_list; + for (int x = 0;pointListNames[x];x++) { + if (regionFile.hasKey(pointListNames[x])) + point_list = parseList(regionFile.readEntry(pointListNames[x])); + } + + // Now build the mask + buildPixmap(num_points, point_list, window_mask); + + // Load the windowshade mask data + regionFile.setGroup("WindowShade"); + + num_points = parseList(regionFile.readEntry("NumPoints")); + point_list = parseList(regionFile.readEntry("PointList")); + + // Now build the mask + buildPixmap(num_points, point_list, shade_mask); +} + +WaRegion::~WaRegion() { + delete window_mask; + delete shade_mask; +} + +void WaRegion::buildPixmap(const QValueList<int> &num_points_list, const QValueList<int> &points_list, QBitmap *dest) { + if (!num_points_list.count()) { + dest->fill(Qt::color1); + return; + } + + QValueList<int>::const_iterator points = points_list.begin(); + + QPainter p(dest); + + // Coordinates in REGION.TXT can go one pixel beyond the window size + QBitmap bm(dest->width()+1,dest->height()+1,true); + QPainter bmp(&bm); + + bmp.setBrush(Qt::color1); + bmp.setPen(Qt::NoPen); // The polygon border itself should not be part of the visible window + + // Go over each "region" in the file + for (QValueList<int>::const_iterator num_points = num_points_list.begin();num_points != num_points_list.end();num_points++) { + // Make a new point array + QPointArray point_array(*num_points); + + // Populate it + for (int i = 0;i < *num_points;i++) { + int x = (*points++); + int y = (*points++); + + point_array.setPoint(i, x, y); + } + + // Now draw it as a filled polygon on the mask + bmp.drawPolygon(point_array); + } + + p.drawPixmap(0,0,bm,0,0,dest->width(),dest->height()); +} + + +// The winamp list format is absolutely insane, it will accept either +// commas or whitespace as the delimiter. This function deals with +// that. +QValueList<int> WaRegion::parseList(const QString &list) const { + QValueList<int> temp_list; + + if (list.isEmpty()) + return temp_list; + + QStringList open=QStringList::split(QRegExp("[,\\s]+"), list); + for (QStringList::Iterator i=open.begin(); i != open.end(); ++i) + temp_list.append((*i).toInt()); + + return temp_list; +} diff --git a/noatun/modules/winskin/waRegion.h b/noatun/modules/winskin/waRegion.h new file mode 100644 index 00000000..853909c1 --- /dev/null +++ b/noatun/modules/winskin/waRegion.h @@ -0,0 +1,26 @@ +#ifndef WAREGION_H +#define WAREGION_H + +#include <qcolor.h> +#include <qstring.h> + +class WaRegion { +public: + WaRegion(QString filename); + ~WaRegion(); + + const QBitmap *mainWindowMask() const { return window_mask; } + const QBitmap *mainWindowShadeMask() const { return shade_mask; } + +private: + QValueList<int> parseList(const QString &list) const; + void buildPixmap(const QValueList<int> &num_points, const QValueList<int> &point_list, QBitmap *dest); + + QBitmap *window_mask; + QBitmap *shade_mask; +}; + +extern WaRegion *windowRegion; + +#endif + diff --git a/noatun/modules/winskin/waShadeMapping.h b/noatun/modules/winskin/waShadeMapping.h new file mode 100644 index 00000000..d28d4ca8 --- /dev/null +++ b/noatun/modules/winskin/waShadeMapping.h @@ -0,0 +1,148 @@ +/* + mapping from file and id to pixmap, and global player map + Copyright (C) 1999 Martin Vogt + Copyright (C) 2002 Ryan Cumming + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef __WASHADEMAPPING_H +#define __WASHADEMAPPING_H + + +/** + This file is not a header file in the normal sense. + It define _directly_ variables, which are used in the + WaSkinLoader class. + Its a bit black voodoo magic. +*/ + +/** + The Skin file format was downloaded from the web. + http://www.algonet.et.se/~daniel7 + + Author: unknown +*/ + +#include "skinMap.h" +#include "waSkins.h" + +static const SkinMap shadeMapToGui[] = { + {0, 0, 275, 14}, // _WA_MAPPING_MAIN + {168, 3, 9, 9}, // _WA_MAPPING_CBUTTONS_PREV + {177, 3, 9, 9}, // _WA_MAPPING_CBUTTONS_PLAY + {186, 3, 9, 9}, // _WA_MAPPING_CBUTTONS_PAUSE + {195, 3, 9, 9}, // _WA_MAPPING_CBUTTONS_STOP + {204, 3, 9, 9}, // _WA_MAPPING_CBUTTONS_NEXT + {215, 3, 9, 9}, // _WA_MAPPING_CBUTTONS_EJECT + {239, 41, 29, 12}, // _WA_MAPPING_MONOSTER_STEREO + {212, 41, 27, 12}, // _WA_MAPPING_MONOSTER_MONO + {210, 89, 28, 15}, // _WA_MAPPING_REPEAT + {164, 89, 46, 15}, // _WA_MAPPING_SHUFFLE + {242, 58, 23, 12}, // _WA_MAPPING_PLAYLIST + {219, 58, 23, 12}, // _WA_MAPPING_EQ + {107, 57, 68, 13}, // _WA_MAPPING_VOLUME_BAR + {0, 0, 13, 11}, // _WA_MAPPING_VOLUME_SLIDER + {177, 57, 38, 13}, // _WA_MAPPING_BALANCE_BAR + {0, 0, 13, 11}, // _WA_MAPPING_BALANCE_SLIDER + {24, 28, 11, 9}, // _WA_MAPPING_PLAYPAUS + {16, 72, 248, 10}, // _WA_MAPPING_POS_BAR + {0, 0, 29, 10}, // _WA_MAPPING_POS_BAR_SLIDER + {130, 4, 27, 6}, // _WA_MAPPING_DIGITS + {130, 4, 5, 6}, // _WA_MAPPING_MINUS + {135, 4, 5, 6}, // _WA_MAPPING_DIGIT_1 + {140, 4, 5, 6}, // _WA_MAPPING_DIGIT_2 + {147, 4, 5, 6}, // _WA_MAPPING_DIGIT_3 + {152, 4, 5, 6}, // _WA_MAPPING_DIGIT_4 + {24, 43, 75, 16}, // _WA_MAPPING_ANALYSER + {111, 43, 15, 6}, // _WA_MAPPING_BPS + {156, 43, 10, 6}, // _WA_MAPPING_FREQ + {112, 27, 152, 6}, // _WA_MAPPING_INFO + {0, 0, 274, 14}, // _WA_MAPPING_TITLE + {6, 3, 9, 9}, // _WA_MAPPING_TITLE_MENU + {244, 3, 9, 9}, // _WA_MAPPING_TITLE_MIN + {254, 3, 9, 9}, // _WA_MAPPING_TITLE_SHADE + {264, 3, 9, 9}, // _WA_MAPPING_TITLE_CLOSE + {10, 22, 8, 43} // _WA_MAPPING_CLUTTERBAR +}; + + +static const SkinDesc shadeMapFromFile[] = { + {_WA_FILE_TITLEBAR, 27, 29, 275, 14}, // _WA_SKIN_MAIN + {_WA_FILE_TITLEBAR, 195, 32, 9, 9}, // _WA_SKIN_CBUTTONS_PREV_NORM + {_WA_FILE_TITLEBAR, 195, 32, 9, 9}, // _WA_SKIN_CBUTTONS_PREV_PRES + {_WA_FILE_TITLEBAR, 204, 32, 9, 9}, //_WA_SKIN_CBUTTONS_PLAY_NORM, + {_WA_FILE_TITLEBAR, 204, 32, 9, 9}, // _WA_SKIN_CBUTTONS_PLAY_PRES + {_WA_FILE_TITLEBAR, 213, 32, 9, 9}, // _WA_SKIN_CBUTTONS_PAUSE_NORM + {_WA_FILE_TITLEBAR, 213, 32, 9, 9}, // _WA_SKIN_CBUTTONS_PAUSE_PRES + {_WA_FILE_TITLEBAR, 222, 32, 9, 9}, // _WA_SKIN_CBUTTONS_STOP_NORM + {_WA_FILE_TITLEBAR, 222, 32, 9, 9}, // _WA_SKIN_CBUTTONS_STOP_PRES + {_WA_FILE_TITLEBAR, 231, 32, 9, 9}, // _WA_SKIN_CBUTTONS_NEXT_NORM + {_WA_FILE_TITLEBAR, 231, 32, 9, 9}, // _WA_SKIN_CBUTTONS_NEXT_PRES + {_WA_FILE_TITLEBAR, 242, 32, 9, 9}, // _WA_SKIN_CBUTTONS_EJECT_NORM + {_WA_FILE_TITLEBAR, 242, 32, 9, 9}, // _WA_SKIN_CBUTTONS_EJECT_PRESS + {_WA_FILE_MONOSTER, 0, 0, 29, 12}, // _WA_SKIN_MONOSTER_STEREO_TRUE + {_WA_FILE_MONOSTER, 0, 12, 29, 12}, // _WA_SKIN_MONOSTER_STEREO_FALSE + {_WA_FILE_MONOSTER, 29, 0, 27, 12}, // _WA_SKIN_MONOSTER_MONO_TRUE + {_WA_FILE_MONOSTER, 29, 12, 27, 12}, // _WA_SKIN_MONOSTER_MONO_FALSE + {_WA_FILE_TEXT, 0, 6, 50, 6}, // _WA_SKIN_NUMBERS + {_WA_FILE_TEXT, 75, 6, 5, 6}, // _WA_SKIN_NUMBERS_MINUS + {_WA_FILE_TEXT, 50, 12, 5, 6}, // _WA_SKIN_NUMBERS_BLANK + {_WA_FILE_SHUFREP, 0, 0, 28, 15}, // _WA_SKIN_SHUFREP_REPEAT_NOT_SET_NORM + {_WA_FILE_SHUFREP, 0, 15, 28, 15}, // _WA_SKIN_SHUFREP_REPEAT_NOT_SET_PRES + {_WA_FILE_SHUFREP, 0, 30, 28, 15}, // _WA_SKIN_SHUFREP_REPEAT_SET_NORM + {_WA_FILE_SHUFREP, 0, 45, 28, 15}, // _WA_SKIN_SHUFREP_REPEAT_SET_PRES + {_WA_FILE_SHUFREP, 28, 0, 47, 15}, // _WA_SKIN_SHUFREP_SHUFFLE_NOT_SET_NORM + {_WA_FILE_SHUFREP, 28, 15, 47, 15}, // _WA_SKIN_SHUFREP_SHUFFLE_NOT_SET_PRES + {_WA_FILE_SHUFREP, 28, 30, 47, 15}, // _WA_SKIN_SHUFREP_SHUFFLE_SET_NORM + {_WA_FILE_SHUFREP, 28, 45, 47, 15}, // _WA_SKIN_SHUFREP_SHUFFLE_SET_PRES + {_WA_FILE_SHUFREP, 23, 61, 23, 12}, // _WA_SKIN_SHUFREP_PLAYLIST_NOT_SET_NORM + {_WA_FILE_SHUFREP, 69, 61, 23, 12}, // _WA_SKIN_SHUFREP_PLAYLIST_NOT_SET_PRES + {_WA_FILE_SHUFREP, 23, 73, 23, 12}, // _WA_SKIN_SHUFREP_PLAYLIST_SET_NORM + {_WA_FILE_SHUFREP, 73, 23, 12}, // _WA_SKIN_SHUFREP_PLAYLIST_SET_PRES + {_WA_FILE_SHUFREP, 0, 61, 23, 12}, // _WA_SKIN_SHUFREP_EQ_NOT_SET_NORM + {_WA_FILE_SHUFREP, 46, 61, 23, 12}, // _WA_SKIN_SHUFREP_EQ_NOT_SET_PRES + {_WA_FILE_SHUFREP, 0, 73, 23, 12}, // _WA_SKIN_SHUFREP_EQ_SET_NORM + {_WA_FILE_SHUFREP, 46, 73, 23, 12}, // _WA_SKIN_SHUFREP_EQ_SET_PRES + {_WA_FILE_TEXT, 0, 0, 155, 18}, // _WA_SKIN_TEXT + {_WA_FILE_VOLUME, 0, 0, 68, 421}, // _WA_SKIN_VOLUME_BAR_ALL_BARS + {_WA_FILE_VOLUME, 0, 0, 68, 13}, // _WA_SKIN_VOLUME_BAR + {_WA_FILE_VOLUME, 0, 422, 14, 11}, // _WA_SKIN_VOLUME_SLIDER_NORM + {_WA_FILE_VOLUME, 15, 422, 14, 11}, // _WA_SKIN_VOLUME_SLIDER_PRES + {_WA_FILE_BALANCE, 9, 0, 38, 421}, // _WA_SKIN_BALANCE_BAR_ALL_BARS + {_WA_FILE_BALANCE, 9, 0, 38, 13}, // _WA_SKIN_BALANCE_BAR + {_WA_FILE_BALANCE, 0, 422, 14, 11}, // _WA_SKIN_BALANCE_SLIDER_NORM + {_WA_FILE_BALANCE, 15, 422, 14, 11}, // _WA_SKIN_BALANCE_SLIDER_PRES + {_WA_FILE_POSBAR, 0, 0, 248, 10}, // _WA_SKIN_POS_BAR + {_WA_FILE_POSBAR, 278, 0, 29, 10}, // _WA_SKIN_POS_BAR_SLIDER_NORM + {_WA_FILE_POSBAR, 248, 0, 29, 10}, // _WA_SKIN_POS_BAR_SLIDER_PRES + {_WA_FILE_PLAYPAUS, 1, 0, 8, 9}, // _WA_SKIN_PLAYPAUS_PLAY + {_WA_FILE_PLAYPAUS, 9, 0, 9, 9}, // _WA_SKIN_PLAYPAUS_PAUSE + {_WA_FILE_PLAYPAUS, 18, 0, 9, 9}, // _WA_SKIN_PLAYPAUS_STOP + {_WA_FILE_PLAYPAUS, 27, 0, 2, 9}, // _WA_SKIN_PLAYPAUS_FILLER + {_WA_FILE_PLAYPAUS, 36, 0, 3, 9}, // _WA_SKIN_PLAYPAUS_WORK_INDICATOR + {_WA_FILE_TITLEBAR, 27, 29, 275, 14}, // _WA_SKIN_TITLE_ACTIVE + {_WA_FILE_TITLEBAR, 27, 42, 275, 14}, // _WA_SKIN_TITLE_INACTIVE + {_WA_FILE_TITLEBAR, 0, 9, 9, 9}, // _WA_SKIN_TITLE_MENU_PRES + {_WA_FILE_TITLEBAR, 33, 32, 9, 9}, // _WA_SKIN_TITLE_MENU_NORM + {_WA_FILE_TITLEBAR, 33, 45, 9, 9}, // _WA_SKIN_TITLE_MENU_INACTIVE + {_WA_FILE_TITLEBAR, 9, 9, 9, 9}, // _WA_SKIN_TITLE_MIN_PRES + {_WA_FILE_TITLEBAR, 271, 32, 9, 9}, // _WA_SKIN_TITLE_MIN_NORM + {_WA_FILE_TITLEBAR, 271, 45, 9, 9}, // _WA_SKIN_TITLE_MIN_INACTIVE + {_WA_FILE_TITLEBAR, 9, 27, 9, 9}, // _WA_SKIN_TITLE_SHADE_PRES + {_WA_FILE_TITLEBAR, 281, 32, 9, 9}, // _WA_SKIN_TITLE_SHADE_NORM + {_WA_FILE_TITLEBAR, 281, 45, 9, 9}, // _WA_SKIN_TITLE_SHADE_INACTIVE + {_WA_FILE_TITLEBAR, 18, 9, 9, 9}, // _WA_SKIN_TITLE_CLOSE_PRES + {_WA_FILE_TITLEBAR, 291, 32, 9, 9}, // _WA_SKIN_TITLE_CLOSE_NORM + {_WA_FILE_TITLEBAR, 291, 45, 9, 9}, // _WA_SKIN_TITLE_CLOSE_INACTIVE + {_WA_FILE_TITLEBAR, 304, 0, 8, 43} // _WA_SKIN_CLUTTERBAR_DISABLED +}; + +#endif diff --git a/noatun/modules/winskin/waSkin.cpp b/noatun/modules/winskin/waSkin.cpp new file mode 100644 index 00000000..7d95047d --- /dev/null +++ b/noatun/modules/winskin/waSkin.cpp @@ -0,0 +1,800 @@ +/* + Winamp Skin + Copyright (C) 1999 Martin Vogt + Copyright (C) 2001-2002 Ryan Cumming + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + +#include <kconfig.h> +#include <qstringlist.h> +#include <kglobal.h> +#include <klocale.h> +#include <kiconloader.h> +#include <khelpmenu.h> +#include <kpopupmenu.h> +#include <kurldrag.h> +#include <kstdaction.h> +#include <kaction.h> +#include <qdragobject.h> +#include <kstandarddirs.h> +#include <kwin.h> +#include <time.h> + +#include <noatun/playlist.h> +#include <noatun/app.h> +#include <noatun/stdaction.h> + +#include "waSkin.h" + +#include "waRegion.h" + +#include "waMain.h" +#include "waClutterbar.h" +#include "waDigit.h" +#include "waInfo.h" +#include "waButton.h" +#include "waLabel.h" +#include "waIndicator.h" +#include "waTitleBar.h" + +#include "waJumpSlider.h" +#include "waBalanceSlider.h" +#include "waVolumeSlider.h" + +#include "waStatus.h" + +#include "waSkinManager.h" +#include "waSkinModel.h" + +#include "guiSpectrumAnalyser.h" +#include "fileInfo.h" + +WaSkin *_waskin_instance = NULL; + +WaSkin::WaSkin() : QWidget(0, "NoatunWinampSkin"), UserInterface() +{ + mJumpPressed = false; + mVolumePressed = false; + mBalancePressed = false; + + _waskin_instance = this; + + // Our really low-level render-y sort of stuff + waSkinModel = new WaSkinModel(); + // Skin management stuff + waSkinManager = new WaSkinManager(); + + createHighLevelElements(); + createButtons(); + setMinimumSize(sizeHint()); + setMaximumSize(sizeHint()); + + KWin::setType(this->winId(), NET::Override); + setBackgroundMode(NoBackground); + + setAcceptDrops(true); + + title_shaded = false; + + // These slots make Young Hickory love us + connect( napp, SIGNAL(hideYourself()), this, SLOT(hide()) ); + connect( napp, SIGNAL(showYourself()), this, SLOT(show()) ); + + connect(napp->player(), SIGNAL(playlistShown()), this, + SLOT(playlistShown())); + connect(napp->player(), SIGNAL(playlistHidden()), this, + SLOT(playlistHidden())); + connect(napp->player(), SIGNAL(loopTypeChange(int)), this, + SLOT(loopChange(int))); + connect(napp->player(), SIGNAL(newSong()), this, SLOT(newSong())); + + connect(napp->player(), SIGNAL(timeout()), this, SLOT(timetick())); + KConfig *config=KGlobal::config(); + + config->setGroup("Winskin"); + QString skin = config->readEntry("CurrentSkin", WaSkin::defaultSkin()); + + loadSkin(skin); + + setCaption(i18n("Noatun")); + setIcon(SmallIcon("noatun")); + + + QObject::connect(waTitleBar, SIGNAL(shaded()), this, SLOT(shadeEvent())); + // connect to players signals - so we can update our display if someone else + // changes settings... + + connect(napp->player(), SIGNAL(stopped()), this, SLOT(slotStopped())); + connect(napp->player(), SIGNAL(playing()), this, SLOT(slotPlaying())); + connect(napp->player(), SIGNAL(paused()), this, SLOT(slotPaused())); + + napp->player()->handleButtons(); + + playlist->setToggled(napp->playlist()->listVisible()); + + shuffle->setToggled(false); + repeat->setToggled(false); + waBalanceSlider->setBalanceValue(0); + waVolumeSlider->setVolumeValue(napp->player()->volume()); + + newSong(); + + // HACK: We won't get focus events otherwise + setFocusPolicy(QWidget::ClickFocus); + + show(); +} + + +WaSkin::~WaSkin() +{ + delete waSkinManager; + waSkinManager = 0L; +} + +void WaSkin::loadSkin(QString newSkinDir) +{ + waSkinManager->loadSkin(newSkinDir); + + setMinimumSize(sizeHint()); + + if (title_shaded) { + // waSkinModel::load() resets our skin model :( + waSkinModel->setSkinModel(WA_MODEL_WINDOWSHADE); + setMask(*windowRegion->mainWindowShadeMask()); + } + else { + setMask(*windowRegion->mainWindowMask()); + } +} + +QSize WaSkin::sizeHint() const +{ + QRect temp_rect; + + temp_rect = waSkinModel->getGeometry(_WA_SKIN_MAIN); + + return temp_rect.size(); +} + + +void WaSkin::createButtons() +{ + prev = new WaButton(_WA_MAPPING_CBUTTONS_PREV); + play = new WaButton(_WA_MAPPING_CBUTTONS_PLAY); + pause = new WaButton(_WA_MAPPING_CBUTTONS_PAUSE); + stop = new WaButton(_WA_MAPPING_CBUTTONS_STOP); + next = new WaButton(_WA_MAPPING_CBUTTONS_NEXT); + eject = new WaButton(_WA_MAPPING_CBUTTONS_EJECT); + shuffle = new WaButton(_WA_MAPPING_SHUFFLE); + repeat = new WaButton(_WA_MAPPING_REPEAT); + playlist = new WaButton(_WA_MAPPING_PLAYLIST); + eq = new WaButton(_WA_MAPPING_EQ); + + menu = new WaButton(_WA_MAPPING_TITLE_MENU); + menu->setPixmapUp(_WA_SKIN_TITLE_MENU_NORM); + menu->setPixmapDown(_WA_SKIN_TITLE_MENU_PRES); + connect(menu, SIGNAL(clicked()), this, SLOT(menuEvent())); + + minimize = new WaButton(_WA_MAPPING_TITLE_MIN); + minimize->setPixmapUp(_WA_SKIN_TITLE_MIN_NORM); + minimize->setPixmapDown(_WA_SKIN_TITLE_MIN_PRES); + connect(minimize, SIGNAL(clicked()), this, SLOT(minimizeEvent())); + + titleshade = new WaButton(_WA_MAPPING_TITLE_SHADE); + titleshade->setPixmapUp(_WA_SKIN_TITLE_SHADE_NORM); + titleshade->setPixmapDown(_WA_SKIN_TITLE_SHADE_PRES); + connect(titleshade, SIGNAL(clicked()), this, SLOT(shadeEvent())); + + close = new WaButton(_WA_MAPPING_TITLE_CLOSE); + close->setPixmapUp(_WA_SKIN_TITLE_CLOSE_NORM); + close->setPixmapDown(_WA_SKIN_TITLE_CLOSE_PRES); + connect(close, SIGNAL(clicked()), this, SLOT(doClose())); + + shuffle->setTogglable(true); + shuffle->show(); + + repeat->setTogglable(true); + playlist->setTogglable(true); + + connect(shuffle, SIGNAL(toggleEvent(bool)), + this, SLOT(shuffleClickedEvent(bool))); + + connect(repeat, SIGNAL(toggleEvent(bool)), + this, SLOT(repeatClickedEvent(bool))); + + connect(playlist, SIGNAL(toggleEvent(bool)), + this, SLOT(playlistClickedEvent(bool))); + + connect(eq, SIGNAL(clicked()), + this, SLOT(eqClickedEvent())); + + prev->setPixmapUp(_WA_SKIN_CBUTTONS_PREV_NORM); + prev->setPixmapDown(_WA_SKIN_CBUTTONS_PREV_PRES); + connect(prev, SIGNAL(clicked()), napp->player(), SLOT(back())); + + play->setPixmapUp(_WA_SKIN_CBUTTONS_PLAY_NORM); + play->setPixmapDown(_WA_SKIN_CBUTTONS_PLAY_PRES); + connect(play, SIGNAL(clicked()), this, SLOT(playCurrentEvent())); + + pause->setPixmapUp(_WA_SKIN_CBUTTONS_PAUSE_NORM); + pause->setPixmapDown(_WA_SKIN_CBUTTONS_PAUSE_PRES); + connect(pause, SIGNAL(clicked()), this, SLOT(playPauseEvent())); + + + stop->setPixmapUp(_WA_SKIN_CBUTTONS_STOP_NORM); + stop->setPixmapDown(_WA_SKIN_CBUTTONS_STOP_PRES); + connect(stop, SIGNAL(clicked()), napp->player(), SLOT(stop())); + + + next->setPixmapUp(_WA_SKIN_CBUTTONS_NEXT_NORM); + next->setPixmapDown(_WA_SKIN_CBUTTONS_NEXT_PRES); + connect(next, SIGNAL(clicked()), napp->player(), SLOT(forward())); + + + eject->setPixmapUp(_WA_SKIN_CBUTTONS_EJECT_NORM); + eject->setPixmapDown(_WA_SKIN_CBUTTONS_EJECT_PRESS); + connect(eject, SIGNAL(clicked()), napp, SLOT(fileOpen())); + + shuffle->setPixmapUp(_WA_SKIN_SHUFREP_SHUFFLE_NOT_SET_NORM); + shuffle->setPixmapDown(_WA_SKIN_SHUFREP_SHUFFLE_NOT_SET_PRES); + shuffle->setPixmapUpSelected(_WA_SKIN_SHUFREP_SHUFFLE_SET_NORM); + shuffle->setPixmapDownSelected(_WA_SKIN_SHUFREP_SHUFFLE_SET_PRES); + shuffle->setToggled(true); + + repeat->setPixmapUp(_WA_SKIN_SHUFREP_REPEAT_NOT_SET_NORM); + repeat->setPixmapDown(_WA_SKIN_SHUFREP_REPEAT_NOT_SET_PRES); + repeat->setPixmapUpSelected(_WA_SKIN_SHUFREP_REPEAT_SET_NORM); + repeat->setPixmapDownSelected(_WA_SKIN_SHUFREP_REPEAT_SET_PRES); + + + eq->setPixmapUp(_WA_SKIN_SHUFREP_EQ_NOT_SET_NORM); + eq->setPixmapDown(_WA_SKIN_SHUFREP_EQ_NOT_SET_PRES); + + playlist->setPixmapUp(_WA_SKIN_SHUFREP_PLAYLIST_NOT_SET_NORM); + playlist->setPixmapDown( _WA_SKIN_SHUFREP_PLAYLIST_NOT_SET_PRES); + + playlist->setPixmapUpSelected(_WA_SKIN_SHUFREP_PLAYLIST_SET_NORM); + playlist->setPixmapDownSelected(_WA_SKIN_SHUFREP_PLAYLIST_SET_PRES); + + waClutterbar = new WaClutterbar(); +} + +void WaSkin::createHighLevelElements() +{ + // Two most top-level elements + main = new WaMain(); + waTitleBar = new WaTitleBar(); + + guiSpectrumAnalyser = new GuiSpectrumAnalyser(); + + waJumpSlider = new WaJumpSlider(); + waJumpSlider->buildGui(); + + waVolumeSlider = new WaVolumeSlider(); + waVolumeSlider->buildGui(); + + connect(waVolumeSlider, SIGNAL(volumeSetValue(int)), + this, SLOT(volumeSetValue(int))); + connect(waVolumeSlider, SIGNAL(sliderPressed()), + this, SLOT(volumeSliderPressed())); + connect(waVolumeSlider, SIGNAL(sliderReleased()), + this, SLOT(volumeSliderReleased())); + + waBalanceSlider = new WaBalanceSlider(); + waBalanceSlider->buildGui(); + + connect(waBalanceSlider, SIGNAL(balanceSetValue(int)), + this, SLOT(balanceSetValue(int))); + connect(waBalanceSlider, SIGNAL(sliderPressed()), + this, SLOT(balanceSliderPressed())); + connect(waBalanceSlider, SIGNAL(sliderReleased()), + this, SLOT(balanceSliderReleased())); + + waDigit = new WaDigit(); + connect(waDigit, SIGNAL(digitsClicked()), this, SLOT(digitsClicked())); + + waBPS = new WaLabel(_WA_MAPPING_BPS); + waFreq = new WaLabel(_WA_MAPPING_FREQ); + + waInfo = new WaInfo(); + + waStatus = new WaStatus(); + + waStereo = new WaIndicator(_WA_MAPPING_MONOSTER_STEREO, _WA_SKIN_MONOSTER_STEREO_TRUE, _WA_SKIN_MONOSTER_STEREO_FALSE); + waMono = new WaIndicator(_WA_MAPPING_MONOSTER_MONO, _WA_SKIN_MONOSTER_MONO_TRUE, _WA_SKIN_MONOSTER_MONO_FALSE); + + connect(waJumpSlider, SIGNAL(jump(int)), this, SLOT(jump(int))); + connect(waJumpSlider, SIGNAL(sliderPressed()), + this, SLOT(jumpSliderPressed())); + connect(waJumpSlider, SIGNAL(sliderReleased()), + this, SLOT(jumpSliderReleased())); + connect(waJumpSlider, SIGNAL(valueChanged(int)), + this, SLOT(jumpValueChanged(int))); +} + + +void WaSkin::setChannels(int val) +{ + if (val <= 0) { + waStereo->setState(false); + waMono->setState(false); + } else if (val == 1) { + waStereo->setState(false); + waMono->setState(true); + } else { + waStereo->setState(true); + waMono->setState(false); + } +} + +void WaSkin::shade() { + waSkinModel->setSkinModel(WA_MODEL_WINDOWSHADE); + + setMinimumSize(sizeHint()); + setMask(*windowRegion->mainWindowShadeMask()); + + title_shaded = true; +} + +void WaSkin::unshade() { + waSkinModel->setSkinModel(WA_MODEL_NORMAL); + + setMinimumSize(sizeHint()); + setMask(*windowRegion->mainWindowMask()); + + title_shaded = false; +} + +void WaSkin::focusOutEvent( QFocusEvent * ) { + menu->setPixmapUp(_WA_SKIN_TITLE_MENU_INACTIVE); + menu->update(); + + minimize->setPixmapUp(_WA_SKIN_TITLE_MIN_INACTIVE); + minimize->update(); + + titleshade->setPixmapUp(_WA_SKIN_TITLE_SHADE_INACTIVE); + titleshade->update(); + + close->setPixmapUp(_WA_SKIN_TITLE_CLOSE_INACTIVE); + close->update(); + + waTitleBar->setState(false); +} + +void WaSkin::focusInEvent( QFocusEvent * ) { + menu->setPixmapUp(_WA_SKIN_TITLE_MENU_NORM); + menu->update(); + + minimize->setPixmapUp(_WA_SKIN_TITLE_MIN_NORM); + minimize->update(); + + titleshade->setPixmapUp(_WA_SKIN_TITLE_SHADE_NORM); + titleshade->update(); + + close->setPixmapUp(_WA_SKIN_TITLE_CLOSE_NORM); + close->update(); + + waTitleBar->setState(true); +} + +void WaSkin::wheelEvent(QWheelEvent *e) { + // Get the current volume + int newVolume = napp->player()->volume(); + + // Wheel events return needlessly large "deltas", normalize it a bit + newVolume += e->delta() / 24; + napp->player()->setVolume(newVolume); +} + +void WaSkin::repeatClickedEvent(bool) +{ + updateLoopStyle(); +} + +void WaSkin::shuffleClickedEvent(bool) +{ + updateLoopStyle(); +} + +void WaSkin::updateLoopStyle() { + if (shuffle->toggled()) { + napp->player()->loop(Player::Random); + } + else { + int loopVal = repeat->toggled() ? Player::Playlist : Player::None; + napp->player()->loop(loopVal); + } +} + +void WaSkin::playlistClickedEvent(bool) +{ + napp->playlist()->toggleList(); +} + +void WaSkin::eqClickedEvent() +{ + napp->equalizerView(); +} + +void WaSkin::jump(int val) +{ + if (napp->player()->isStopped()) { + waJumpSlider->setJumpValue(0); + } else { + napp->player()->skipTo((int) (val * 1000)); + } +} + +void WaSkin::jumpSliderPressed() +{ + mJumpPressed = true; + jumpValueChanged(waJumpSlider->jumpValue()); +} + + +void WaSkin::jumpSliderReleased() +{ + mJumpPressed = false; + waInfo->setText(getTitleString()); +} + +void WaSkin::jumpValueChanged(int val) +{ + if (mJumpPressed && !napp->player()->isStopped()) { + QString timeStr = i18n("Seek to: %1/%2 (%3%)"). + arg(getTimeString(val * 1000)). + arg(getTimeString(napp->player()->getLength())). + arg((val * 1000 * 100) / napp->player()->getLength()); + waInfo->setText(timeStr); + } +} + +QString WaSkin::getTitleString() { + int length; + QString title = ""; + + if (!napp->playlist()->current()) { + title = "Noatun "; + title += QString::number(NOATUN_MAJOR) + "."; + title += QString::number(NOATUN_MINOR) + "."; + title += QString::number(NOATUN_PATCHLEVEL); + } + else { + length = napp->playlist()->current().length(); + + title = napp->playlist()->current().title(); + + if (length >= 0) + title += " (" + getTimeString(length) + ")"; + + if (title.length() > 30) { + // It's scrolling; provide the nice, friendly seperator. + title += " *** "; + } + } + + return title; +} + +QString WaSkin::getTimeString(int milliseconds, bool truncate) { + int seconds = abs(milliseconds / 1000); + QString ret = ""; + + // Do we need to convert to hours:minutes instead of minutes:seconds? + if (truncate && (abs(seconds) >= (100 * 60))) + seconds /= 60; + + // Print the optional minus sign, hours/minutes, a colon, and then minutes/seconds. + ret.sprintf("%s%.2d:%.2d", ((milliseconds < 0) ? "-" : ""), seconds / 60, seconds % 60); + + return ret; +} + +void WaSkin::menuEvent() { + NoatunStdAction::ContextMenu::showContextMenu(mapToGlobal(QPoint(0, 14))); +} + +void WaSkin::minimizeEvent() { + showMinimized(); +} + +void WaSkin::shadeEvent() +{ + if (!title_shaded) + shade(); + else + unshade(); +} + +void WaSkin::doUnload() { + unload(); +} + +void WaSkin::doClose() { + QTimer::singleShot(0, this, SLOT(doUnload())); +} + +void WaSkin::dragEnterEvent(QDragEnterEvent * event) +{ + // accept uri drops only + event->accept(KURLDrag::canDecode(event)); +} + +void WaSkin::dropEvent(QDropEvent * event) +{ + KURL::List uri; + if (KURLDrag::decode(event, uri)) + { + for (KURL::List::Iterator i = uri.begin(); i != uri.end(); ++i) + napp->player()->openFile(*i, false); + } +} + +void WaSkin::balanceSliderPressed() +{ + mBalancePressed = true; + balanceSetValue(0); +} + +void WaSkin::balanceSliderReleased() +{ + + mBalancePressed = false; + waBalanceSlider->setBalanceValue(0); + + waInfo->setText(getTitleString()); +} + +void WaSkin::balanceSetValue(int val) +{ + if (val == 0) { + waInfo->setText(i18n("Balance: Center")); + } + else if (val < 0) { + waInfo->setText(i18n("Balance: %1% Left").arg(-val)); + } else { + waInfo->setText(i18n("Balance: %1% Right").arg(val)); + } +} + +void WaSkin::playCurrentEvent() +{ + if (napp->player()->isPaused()) + napp->player()->playpause(); + else + napp->player()->playCurrent(); +} + +void WaSkin::playPauseEvent() +{ + if (!napp->player()->isStopped()) + napp->player()->playpause(); +} + + +void WaSkin::loopChange(int loopType) +{ + shuffle->setToggled(loopType == Player::Random); + + if (loopType != Player::Random) + repeat->setToggled(loopType != Player::None); +} + +void WaSkin::playlistShown() +{ + playlist->setToggled(true); +} + +void WaSkin::playlistHidden() +{ + playlist->setToggled(false); +} + +void WaSkin::newSong() +{ + if (napp->player()->getLength() == -1) + waJumpSlider->hide(); + else + waJumpSlider->show(); + + mJumpPressed = false; + waJumpSlider->cancelDrag(); + + timetick(); +} + +void WaSkin::timetick() +{ + int mLength; + + if (!mVolumePressed && !mBalancePressed && !mJumpPressed) + waInfo->setText(getTitleString()); + + if (!napp->player()->current()) + return; + + mLength = (int) napp->player()->getLength() / 1000; + if (mLength < 0) + mLength = 0; + + waJumpSlider->setJumpRange(mLength); + + digitsClicked(); + + int time = 0; + if (napp->player()->current()) + time = (int) napp->player()->getTime() / 1000; + + if (!mJumpPressed) + waJumpSlider->setJumpValue(time); + + waVolumeSlider->setVolumeValue(napp->player()->volume()); +} + +void WaSkin::digitsClicked() { + if (!waDigit->timeReversed() || (napp->player()->getLength() == -1)) { + // Setting truncate=true means we want setTime to return + // no more than 6 digits (-xx:yy) + + if (napp->player()->getTime() != -1) + waDigit->setTime(getTimeString(napp->player()->getTime(), true)); + else + waDigit->setTime(getTimeString(0, true)); + } + else { + int rem_time = napp->player()->getTime() - napp->player()->getLength(); + + // Setting truncate=true means we want setTime to return + // no more than 6 digits (-xx:yy) + waDigit->setTime(getTimeString(rem_time, true)); + } +} + +void WaSkin::volumeSliderPressed() +{ + mVolumePressed = true; + volumeSetValue(napp->player()->volume()); +} + +void WaSkin::volumeSliderReleased() +{ + mVolumePressed = false; + waInfo->setText(getTitleString()); +} + +void WaSkin::volumeSetValue(int val) +{ + if (mVolumePressed) + waInfo->setText(i18n("Volume: %1%").arg(val)); + + napp->player()->setVolume(val); +} + +void WaSkin::slotPlaying() +{ + waStatus->setStatus(STATUS_PLAYING); + + if (!napp->playlist()->current()) { + return; + } + + fileInfo info(napp->playlist()->current()); + + if (!info.bps()) + waBPS->setText(""); + else + waBPS->setText(QString::number(info.bps())); + + if (!info.KHz()) + waFreq->setText(""); + else + waFreq->setText(QString::number(info.KHz() / 1000)); + + setChannels(info.channelCount()); + guiSpectrumAnalyser->resumeVisualization(); + + if (napp->player()->getLength() == -1) + waJumpSlider->hide(); + else + waJumpSlider->show(); + + timetick(); +} + +void WaSkin::slotStopped() +{ + waStatus->setStatus(STATUS_STOPPED); + + waDigit->setTime(""); + + waBPS->setText(""); + waFreq->setText(""); + setChannels(0); + + waJumpSlider->setJumpValue(0); + // -1 == disable jump bar + waJumpSlider->setJumpRange(-1); + + + mJumpPressed = false; + waJumpSlider->cancelDrag(); + + waJumpSlider->hide(); + + guiSpectrumAnalyser->pauseVisualization(); +} + +void WaSkin::slotPaused() +{ + waStatus->setStatus(STATUS_PAUSED); +} + +void WaSkin::keyPressEvent(QKeyEvent *e) { + switch(e->key()) { + case Key_Up: + napp->player()->setVolume(napp->player()->volume() + 5); + break; + case Key_Down: + napp->player()->setVolume(napp->player()->volume() - 5); + break; + case Key_Left: + if (napp->player()->current()) + napp->player()->skipTo(napp->player()->getTime() - 5000); + + break; + case Key_Right: + if (napp->player()->current()) + napp->player()->skipTo(napp->player()->getTime() + 5000); + + break; + + case Key_Z: + napp->player()->back(); + break; + + case Key_X: + if (napp->player()->isPaused()) + napp->player()->playpause(); + else + napp->player()->playCurrent(); + + break; + + case Key_C: + if (!napp->player()->isStopped()) + napp->player()->playpause(); + + break; + + case Key_V: + napp->player()->stop(); + break; + + case Key_B: + napp->player()->forward(); + break; + + case Key_R: + repeat->setToggled(!repeat->toggled()); + updateLoopStyle(); + break; + + case Key_S: + shuffle->setToggled(!shuffle->toggled()); + updateLoopStyle(); + break; + } +} + +QString WaSkin::defaultSkin() { + return "Winamp"; +} + +#include "waSkin.moc" diff --git a/noatun/modules/winskin/waSkin.h b/noatun/modules/winskin/waSkin.h new file mode 100644 index 00000000..7a2db9e1 --- /dev/null +++ b/noatun/modules/winskin/waSkin.h @@ -0,0 +1,177 @@ +/* + Winamp Skin + Copyright (C) 1999 Martin Vogt + Copyright (C) 2001 Ryan Cumming + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef __WASKIN_H +#define __WASKIN_H + +#include <noatun/plugin.h> +#include <noatun/app.h> +#include <noatun/player.h> +#include <qwidget.h> + +// Use forward declarations so we compile in a finite time +class WaSkinModel; +class WaSkinManager; + +class WaButton; +class WaDigit; +class WaLabel; +class WaInfo; +class WaMain; +class WaIndicator; +class WaTitleBar; +class WaClutterbar; +class WaStatus; + +class WaJumpSlider; +class WaVolumeSlider; +class WaBalanceSlider; + +class GuiSpectrumAnalyser; + +class WaSkin; +extern WaSkin *_waskin_instance; + +class WaSkin : public QWidget, public UserInterface { + Q_OBJECT + NOATUNPLUGIND + WaSkinModel *waSkinModel; + WaSkinManager *waSkinManager; + + public: + WaSkin(); + ~WaSkin(); + + int getSkinId(); + + void loadSkin(QString skinDir); + void setChannels(int val); + + QSize sizeHint() const; + + static QString defaultSkin(); + static WaSkin *instance() { return _waskin_instance; } + + public slots: + void repeatClickedEvent(bool); + void shuffleClickedEvent(bool); + void playlistClickedEvent(bool); + void eqClickedEvent(); + + // seek bar + void jump(int second); + void jumpSliderPressed(); + void jumpSliderReleased(); + void jumpValueChanged(int); + + void menuEvent(); + void minimizeEvent(); + void shadeEvent(); + void doUnload(); + void doClose(); + + // balance + void balanceSliderPressed(); + void balanceSetValue(int val); + void balanceSliderReleased(); + + // volume + void volumeSliderPressed(); + void volumeSetValue(int val); + void volumeSliderReleased(); + + void playCurrentEvent(); + void playPauseEvent(); + + void loopChange(int loopType); + void playlistShown(); + void playlistHidden(); + void newSong(); + + void timetick(); + void digitsClicked(); + + void slotPlaying(); + void slotStopped(); + void slotPaused(); + + WaSkinModel *skinModel() { return waSkinModel; } + WaSkinManager *skinManager() { return waSkinManager; } + WaInfo *skinInfo() { return waInfo; } + + protected: + void updateLoopStyle(); + + void createButtons(); + void createHighLevelElements(); + + void keyPressEvent(QKeyEvent *); + + void shade(); + void unshade(); + + QString getTitleString(); + QString getTimeString(int milliseconds, bool truncate = false); + + void focusOutEvent ( QFocusEvent * ); + void focusInEvent ( QFocusEvent * ); + + void dragEnterEvent(QDragEnterEvent * event); + void dropEvent(QDropEvent * event); + + void wheelEvent(QWheelEvent *e); + + WaButton *prev; + WaButton *play; + WaButton *pause; + WaButton *stop; + WaButton *next; + WaButton *eject; + WaButton *shuffle; + WaButton *repeat; + WaButton *playlist; + WaButton *eq; + + WaButton *menu; + WaButton *minimize; + WaButton *titleshade; + WaButton *close; + + WaJumpSlider *waJumpSlider; + WaVolumeSlider *waVolumeSlider; + WaBalanceSlider *waBalanceSlider; + WaDigit *waDigit; + + WaLabel *waBPS; + WaLabel *waFreq; + + WaInfo *waInfo; + WaStatus *waStatus; + WaIndicator *waStereo; + WaIndicator *waMono; + + WaMain *main; + WaTitleBar *waTitleBar; + WaClutterbar *waClutterbar; + + GuiSpectrumAnalyser *guiSpectrumAnalyser; + + bool title_shaded; + + bool mJumpPressed; + bool mBalancePressed; + bool mVolumePressed; +}; +#endif diff --git a/noatun/modules/winskin/waSkinManager.cpp b/noatun/modules/winskin/waSkinManager.cpp new file mode 100644 index 00000000..5cde117b --- /dev/null +++ b/noatun/modules/winskin/waSkinManager.cpp @@ -0,0 +1,127 @@ +#include <kglobal.h> +#include <qfileinfo.h> +#include <qregexp.h> +#include <kstandarddirs.h> +#include <qdir.h> +#include <kdebug.h> +#include <kmimetype.h> +#include <kio/job.h> +#include <kurl.h> +#include <kio/netaccess.h> +#include <kzip.h> + +#include "waSkinManager.h" +#include "waSkinModel.h" + +WaSkinManager::WaSkinManager() : DCOPObject("WaSkinManager") { +} + +WaSkinManager::~WaSkinManager() { +} + +QStringList WaSkinManager::availableSkins() { + QStringList skinDirs = KGlobal::dirs()->findDirs("data", "noatun/skins/winamp"); + QStringList skin_list; + + // This loop adds them all to our skin list + for(unsigned int x = 0;x < skinDirs.count();x++) { + QDir skinQDir(skinDirs[x]); + + // We only want directories, although there shouldn't be anything else + skinQDir.setFilter( QDir::Dirs ); + // I guess name is as good as any + skinQDir.setSorting( QDir::Name ); + + for (unsigned int y = 0;y < skinQDir.count();y++) { + QStringList skins = skinQDir.entryList(QDir::Dirs, QDir::Name); + + // We really don't care for '.' and '..' + if (skinQDir[y][0] != (char)'.') { + // Add ourselves to the list, using our directory name + skin_list += skinQDir[y]; + } + } + } + + return skin_list; +} + +QString WaSkinManager::currentSkin() { + return mCurrentSkin; +} + +QString WaSkinManager::defaultSkin() { + return "Winamp"; +} + +bool WaSkinManager::loadSkin(QString skinName) { + QStringList skins = KGlobal::dirs()->findDirs("data", "noatun/skins/winamp/" + skinName); + + if (!skins.count()) + mCurrentSkin = defaultSkin(); + else + mCurrentSkin = skinName; + + return _waskinmodel_instance->load(skins[0]); +} + +bool WaSkinManager::installSkin(QString _url) { + QString location = KGlobal::dirs()->saveLocation("data", "noatun/skins/winamp"); + KURL url(_url); + QString mimetype = KMimeType::findByURL(_url)->name(); + + if (mimetype == "inode/directory") + { + KIO::Job *job = KIO::copy(url, location, !url.isLocalFile()); + connect(job, SIGNAL(result(KIO::Job *)), this, SIGNAL(updateSkinList())); + return true; + } + else if ((mimetype == "interface/x-winamp-skin") || (mimetype == "application/x-zip")) + { + if (!url.isLocalFile()) + return false; + + QString base_path; + base_path = location + "/" + QFileInfo(url.path()).baseName().replace(QRegExp("_"), " "); + KIO::Job *job = KIO::copy("zip:" + url.path(), base_path); + connect(job, SIGNAL(result(KIO::Job *)), this, SIGNAL(updateSkinList())); + + return true; + } + + return false; +} + +bool WaSkinManager::removeSkin(QString skinName) { + if (!skinRemovable(skinName)) + return false; + + QStringList skins = KGlobal::dirs()->findDirs("data", "noatun/skins/winamp/" + skinName); + + KIO::Job *job = KIO::del(KURL(skins[0]), false, false); + connect(job, SIGNAL(result(KIO::Job *)), this, SIGNAL(updateSkinList())); + + return true; +} + +bool WaSkinManager::skinRemovable(QString skinName) { + QStringList skins = KGlobal::dirs()->findDirs("data", "noatun/skins/winamp/" + skinName); + + if (!skins.count()) + return false; + + QFileInfo info(skins[0]); + return info.isWritable(); +} + +QStringList WaSkinManager::skinMimeTypes() { + QStringList temp; + + temp.append("interface/x-winamp-skin"); + temp.append("application/x-zip"); + temp.append("inode/directory"); + + return temp; +} + +#include "waSkinManager.moc" diff --git a/noatun/modules/winskin/waSkinManager.h b/noatun/modules/winskin/waSkinManager.h new file mode 100644 index 00000000..17b21daf --- /dev/null +++ b/noatun/modules/winskin/waSkinManager.h @@ -0,0 +1,39 @@ +#ifndef _WASKINMANAGER_H +#define _WASKINMANAGER_H + +#include <dcopobject.h> +#include <qobject.h> +#include <qstringlist.h> +#include <qstring.h> +#include <qmap.h> + +class WaSkinManager : public QObject, public DCOPObject { +Q_OBJECT +K_DCOP + +public: + WaSkinManager(); + ~WaSkinManager(); + +k_dcop: + QStringList availableSkins(); + QString currentSkin(); + bool loadSkin(QString skinName); + + QString defaultSkin(); + + bool installSkin(QString url); + + bool skinRemovable(QString skinName); + bool removeSkin(QString skinName); + + QStringList skinMimeTypes(); + +signals: + void updateSkinList(); + +private: + QString mCurrentSkin; +}; + +#endif diff --git a/noatun/modules/winskin/waSkinMapping.h b/noatun/modules/winskin/waSkinMapping.h new file mode 100644 index 00000000..a3dfc9c5 --- /dev/null +++ b/noatun/modules/winskin/waSkinMapping.h @@ -0,0 +1,148 @@ +/* + mapping from file and id to pixmap, and global player map + Copyright (C) 1999 Martin Vogt + Copyright (C) 2002 Ryan Cumming + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef __WASKINMAPPING_H +#define __WASKINMAPPING_H + + +/** + This file is not a header file in the normal sense. + It define _directly_ variables, which are used in the + WaSkinLoader class. + Its a bit black voodoo magic. +*/ + +/** + The Skin file format was downloaded from the web. + http://www.algonet.et.se/~daniel7 + + Author: unknown +*/ + +#include "skinMap.h" +#include "waSkins.h" + +static const SkinMap normalMapToGui[] = { + {0, 0, 275, 116}, // _WA_MAPPING_MAIN + {16, 88, 23, 18}, // _WA_MAPPING_CBUTTONS_PREV + {16 + 1 * 23, 88, 23, 18}, // _WA_MAPPING_CBUTTONS_PLAY + {16 + 2 * 23, 88, 23, 18}, // _WA_MAPPING_CBUTTONS_PAUSE + {16 + 3 * 23, 88, 23, 18}, // _WA_MAPPING_CBUTTONS_STOP + {16 + 4 * 23, 88, 22, 18}, // _WA_MAPPING_CBUTTONS_NEXT + {136, 89, 22, 16}, // _WA_MAPPING_CBUTTONS_EJECT + {239, 41, 29, 12}, // _WA_MAPPING_MONOSTER_STEREO + {212, 41, 27, 12}, // _WA_MAPPING_MONOSTER_MONO + {210, 89, 28, 15}, // _WA_MAPPING_REPEAT + {164, 89, 46, 15}, // _WA_MAPPING_SHUFFLE + {242, 58, 23, 12}, // _WA_MAPPING_PLAYLIST + {219, 58, 23, 12}, // _WA_MAPPING_EQ + {107, 57, 68, 13}, // _WA_MAPPING_VOLUME_BAR + {0, 0, 14, 11}, // _WA_MAPPING_VOLUME_SLIDER + {177, 57, 38, 13}, // _WA_MAPPING_BALANCE_BAR + {0, 0, 14, 11}, // _WA_MAPPING_BALANCE_SLIDER + {24, 28, 11, 9}, // _WA_MAPPING_PLAYPAUS + {16, 72, 248, 10}, // _WA_MAPPING_POS_BAR + {0, 0, 29, 10}, // _WA_MAPPING_POS_BAR_SLIDER + {40, 26, 63, 13}, // _WA_MAPPING_DIGITS + {40, 32, 5, 1}, // _WA_MAPPING_MINUS + {48, 26, 9, 13}, // _WA_MAPPING_DIGIT_1 + {60, 26, 9, 13}, // _WA_MAPPING_DIGIT_2 + {78, 26, 9, 13}, // _WA_MAPPING_DIGIT_3 + {90, 26, 9, 13}, // _WA_MAPPING_DIGIT_4 + {24, 43, 75, 16}, // _WA_MAPPING_ANALYSER + {111, 43, 15, 6}, // _WA_MAPPING_BPS + {156, 43, 10, 6}, // _WA_MAPPING_FREQ + {112, 27, 152, 6}, // _WA_MAPPING_INFO + {0, 0, 274, 14}, // _WA_MAPPING_TITLE + {6, 3, 9, 9}, // _WA_MAPPING_TITLE_MENU + {244, 3, 9, 9}, // _WA_MAPPING_TITLE_MIN + {254, 3, 9, 9}, // _WA_MAPPING_TITLE_SHADE + {264, 3, 9, 9}, // _WA_MAPPING_TITLE_CLOSE + {10, 22, 8, 43} // _WA_MAPPING_CLUTTERBAR +}; + + +static const SkinDesc normalMapFromFile[] = { + {_WA_FILE_MAIN, 0, 0, 275, 116}, // _WA_SKIN_MAIN + {_WA_FILE_CBUTTONS, 0, 0, 23, 18}, // _WA_SKIN_CBUTTONS_PREV_NORM + {_WA_FILE_CBUTTONS, 0, 18, 23, 18}, // _WA_SKIN_CBUTTONS_PREV_PRES + {_WA_FILE_CBUTTONS, 23, 0, 23, 18}, //_WA_SKIN_CBUTTONS_PLAY_NORM, + {_WA_FILE_CBUTTONS, 23, 18, 23, 18}, // _WA_SKIN_CBUTTONS_PLAY_PRES + {_WA_FILE_CBUTTONS, 46, 0, 23, 18}, // _WA_SKIN_CBUTTONS_PAUSE_NORM + {_WA_FILE_CBUTTONS, 46, 18, 23, 18}, // _WA_SKIN_CBUTTONS_PAUSE_PRES + {_WA_FILE_CBUTTONS, 69, 0, 23, 18}, // _WA_SKIN_CBUTTONS_STOP_NORM + {_WA_FILE_CBUTTONS, 69, 18, 23, 18}, // _WA_SKIN_CBUTTONS_STOP_PRES + {_WA_FILE_CBUTTONS, 92, 0, 22, 18}, // _WA_SKIN_CBUTTONS_NEXT_NORM + {_WA_FILE_CBUTTONS, 92, 18, 22, 18}, // _WA_SKIN_CBUTTONS_NEXT_PRES + {_WA_FILE_CBUTTONS, 114, 0, 22, 16}, // _WA_SKIN_CBUTTONS_EJECT_NORM + {_WA_FILE_CBUTTONS, 114, 16, 22, 16}, // _WA_SKIN_CBUTTONS_EJECT_PRESS + {_WA_FILE_MONOSTER, 0, 0, 29, 12}, // _WA_SKIN_MONOSTER_STEREO_TRUE + {_WA_FILE_MONOSTER, 0, 12, 29, 12}, // _WA_SKIN_MONOSTER_STEREO_FALSE + {_WA_FILE_MONOSTER, 29, 0, 27, 12}, // _WA_SKIN_MONOSTER_MONO_TRUE + {_WA_FILE_MONOSTER, 29, 12, 27, 12}, // _WA_SKIN_MONOSTER_MONO_FALSE + {_WA_FILE_NUMBERS, 0, 0, 99, 13}, // _WA_SKIN_NUMBERS + {_WA_FILE_NUMBERS, 20, 6, 5, 1}, // _WA_SKIN_NUMBERS_MINUS + {_WA_FILE_NUMBERS, 90, 6, 5, 1}, // _WA_SKIN_NUMBERS_BLANK + {_WA_FILE_SHUFREP, 0, 0, 28, 15}, // _WA_SKIN_SHUFREP_REPEAT_NOT_SET_NORM + {_WA_FILE_SHUFREP, 0, 15, 28, 15}, // _WA_SKIN_SHUFREP_REPEAT_NOT_SET_PRES + {_WA_FILE_SHUFREP, 0, 30, 28, 15}, // _WA_SKIN_SHUFREP_REPEAT_SET_NORM + {_WA_FILE_SHUFREP, 0, 45, 28, 15}, // _WA_SKIN_SHUFREP_REPEAT_SET_PRES + {_WA_FILE_SHUFREP, 28, 0, 47, 15}, // _WA_SKIN_SHUFREP_SHUFFLE_NOT_SET_NORM + {_WA_FILE_SHUFREP, 28, 15, 47, 15}, // _WA_SKIN_SHUFREP_SHUFFLE_NOT_SET_PRES + {_WA_FILE_SHUFREP, 28, 30, 47, 15}, // _WA_SKIN_SHUFREP_SHUFFLE_SET_NORM + {_WA_FILE_SHUFREP, 28, 45, 47, 15}, // _WA_SKIN_SHUFREP_SHUFFLE_SET_PRES + {_WA_FILE_SHUFREP, 23, 61, 23, 12}, // _WA_SKIN_SHUFREP_PLAYLIST_NOT_SET_NORM + {_WA_FILE_SHUFREP, 69, 61, 23, 12}, // _WA_SKIN_SHUFREP_PLAYLIST_NOT_SET_PRES + {_WA_FILE_SHUFREP, 23, 73, 23, 12}, // _WA_SKIN_SHUFREP_PLAYLIST_SET_NORM + {_WA_FILE_SHUFREP, 73, 23, 12}, // _WA_SKIN_SHUFREP_PLAYLIST_SET_PRES + {_WA_FILE_SHUFREP, 0, 61, 23, 12}, // _WA_SKIN_SHUFREP_EQ_NOT_SET_NORM + {_WA_FILE_SHUFREP, 46, 61, 23, 12}, // _WA_SKIN_SHUFREP_EQ_NOT_SET_PRES + {_WA_FILE_SHUFREP, 0, 73, 23, 12}, // _WA_SKIN_SHUFREP_EQ_SET_NORM + {_WA_FILE_SHUFREP, 46, 73, 23, 12}, // _WA_SKIN_SHUFREP_EQ_SET_PRES + {_WA_FILE_TEXT, 0, 0, 155, 18}, // _WA_SKIN_TEXT + {_WA_FILE_VOLUME, 0, 0, 68, 421}, // _WA_SKIN_VOLUME_BAR_ALL_BARS + {_WA_FILE_VOLUME, 0, 0, 68, 13}, // _WA_SKIN_VOLUME_BAR + {_WA_FILE_VOLUME, 0, 422, 14, 11}, // _WA_SKIN_VOLUME_SLIDER_NORM + {_WA_FILE_VOLUME, 15, 422, 14, 11}, // _WA_SKIN_VOLUME_SLIDER_PRES + {_WA_FILE_BALANCE, 9, 0, 38, 421}, // _WA_SKIN_BALANCE_BAR_ALL_BARS + {_WA_FILE_BALANCE, 9, 0, 38, 13}, // _WA_SKIN_BALANCE_BAR + {_WA_FILE_BALANCE, 0, 422, 14, 11}, // _WA_SKIN_BALANCE_SLIDER_NORM + {_WA_FILE_BALANCE, 15, 422, 14, 11}, // _WA_SKIN_BALANCE_SLIDER_PRES + {_WA_FILE_POSBAR, 0, 0, 248, 10}, // _WA_SKIN_POS_BAR + {_WA_FILE_POSBAR, 278, 0, 29, 10}, // _WA_SKIN_POS_BAR_SLIDER_NORM + {_WA_FILE_POSBAR, 248, 0, 29, 10}, // _WA_SKIN_POS_BAR_SLIDER_PRES + {_WA_FILE_PLAYPAUS, 1, 0, 8, 9}, // _WA_SKIN_PLAYPAUS_PLAY + {_WA_FILE_PLAYPAUS, 9, 0, 9, 9}, // _WA_SKIN_PLAYPAUS_PAUSE + {_WA_FILE_PLAYPAUS, 18, 0, 9, 9}, // _WA_SKIN_PLAYPAUS_STOP + {_WA_FILE_PLAYPAUS, 27, 0, 2, 9}, // _WA_SKIN_PLAYPAUS_FILLER + {_WA_FILE_PLAYPAUS, 36, 0, 3, 9}, // _WA_SKIN_PLAYPAUS_WORK_INDICATOR + {_WA_FILE_TITLEBAR, 27, 0, 275, 14}, // _WA_SKIN_TITLE_ACTIVE + {_WA_FILE_TITLEBAR, 27, 15, 275, 14}, // _WA_SKIN_TITLE_INACTIVE + {_WA_FILE_TITLEBAR, 0, 9, 9, 9}, // _WA_SKIN_TITLE_MENU_PRES + {_WA_FILE_TITLEBAR, 0, 0, 9, 9}, // _WA_SKIN_TITLE_MENU_NORM + {_WA_FILE_TITLEBAR, 33, 18, 9, 9}, // _WA_SKIN_TITLE_MENU_INACTIVE + {_WA_FILE_TITLEBAR, 9, 9, 9, 9}, // _WA_SKIN_TITLE_MIN_PRES + {_WA_FILE_TITLEBAR, 9, 0, 9, 9}, // _WA_SKIN_TITLE_MIN_NORM + {_WA_FILE_TITLEBAR, 271, 18, 9, 9}, // _WA_SKIN_TITLE_MIN_INACTIVE + {_WA_FILE_TITLEBAR, 9, 18, 9, 9}, // _WA_SKIN_TITLE_SHADE_PRES + {_WA_FILE_TITLEBAR, 0, 18, 9, 9}, // _WA_SKIN_TITLE_SHADE_NORM + {_WA_FILE_TITLEBAR, 281, 18, 9, 9}, // _WA_SKIN_TITLE_SHADE_INACTIVE + {_WA_FILE_TITLEBAR, 18, 9, 9, 9}, // _WA_SKIN_TITLE_CLOSE_PRES + {_WA_FILE_TITLEBAR, 18, 0, 9, 9}, // _WA_SKIN_TITLE_CLOSE_NORM + {_WA_FILE_TITLEBAR, 291, 18, 9, 9}, // _WA_SKIN_TITLE_CLOSE_INACTIVE + {_WA_FILE_TITLEBAR, 312, 0, 8, 43} // _WA_SKIN_CLUTTERBAR_DISABLED +}; + +#endif diff --git a/noatun/modules/winskin/waSkinModel.cpp b/noatun/modules/winskin/waSkinModel.cpp new file mode 100644 index 00000000..ff53b4e6 --- /dev/null +++ b/noatun/modules/winskin/waSkinModel.cpp @@ -0,0 +1,458 @@ +/* + operations with skinset. + Copyright (C) 1999 Martin Vogt + Copyright (C) 2001 Ryan Cumming + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include <config.h> +#include <qdir.h> +#include <qstringlist.h> +#include <qbitmap.h> +#include <kdebug.h> +#include <kstandarddirs.h> + +#include "waSkinMapping.h" +#include "waShadeMapping.h" + +#include "waSkinModel.h" +#include "waColor.h" +#include "waRegion.h" +#include "waSkin.h" + +WaSkinModel *_waskinmodel_instance = NULL; + +// Our current skin map +// Can switch between normal and windowshade maps +const SkinMap *mapToGui; +const SkinDesc *mapFromFile; +int digit_width; +int digit_height; + + +struct WaPixmapEntry { + const char *filename; + QPixmap *pixmap; +}; + +WaPixmapEntry waPixmapEntries[11] = { + {"main.bmp", NULL}, + {"cbuttons.bmp", NULL}, + {"monoster.bmp", NULL}, + {"numbers.bmp", NULL}, + {"shufrep.bmp", NULL}, + {"text.bmp", NULL}, + {"volume.bmp", NULL}, + {"balance.bmp", NULL}, + {"posbar.bmp", NULL}, + {"playpaus.bmp", NULL}, + {"titlebar.bmp", NULL} + }; + +WaSkinModel::WaSkinModel() +{ + for (int x = 0;x < 11;x++) + waPixmapEntries[x].pixmap = new QPixmap; + + resetSkinModel(); + _waskinmodel_instance = this; +} + +WaSkinModel::~WaSkinModel() +{ + for (int x = 0;x < 11;x++) + delete waPixmapEntries[x].pixmap; + + delete windowRegion; + delete colorScheme; +} + +bool WaSkinModel::load(QString skinDir) +{ + bool success = true; + + QDir dir(skinDir); + + if (findFile(dir, "main.bmp").isEmpty()) { + // Ack, our skin dir doesn't exist, fall back to the default + dir = QDir(KGlobal::dirs()->findDirs("data", "noatun/skins/winamp/" + WaSkin::defaultSkin())[0]); + success = false; + } + + for (int x = 0;x < 11;x++) { + getPixmap(dir, waPixmapEntries[x].filename, + waPixmapEntries[x].pixmap); + } + + resetSkinModel(); + + loadColors(dir); + loadRegion(dir); + + emit(skinChanged()); + + return success; +} + +// Does a case-insenstive file search (like DOS/Windows) +// Filename -must- be lowercase, which is an nice optimization, since +// this is a private API, and all our filenames are internally lowercase +// anyway +QString WaSkinModel::findFile(const QDir &dir, const QString &filename) { + QFileInfo fileInfo; + QString ret = ""; + + QStringList strList = dir.entryList(); + + for (QStringList::iterator file = strList.begin(); file != strList.end(); file++) { + QFileInfo fileInfo(*file); + + if (fileInfo.isDir()) + continue; + + if (fileInfo.filePath().lower() == filename) + return dir.absPath() + "/" + QString(fileInfo.filePath()); + } + + return ""; +} + +void WaSkinModel::loadColors(const QDir &dir) { + QString colorFile = findFile(dir, "viscolor.txt"); + + if (colorScheme) { + delete colorScheme; + } + + colorScheme = new WaColor(colorFile); +} + +void WaSkinModel::loadRegion(const QDir &dir) { + QString regionFile = findFile(dir, "region.txt"); + + if (windowRegion) { + delete windowRegion; + windowRegion = 0; + } + + windowRegion = new WaRegion(regionFile); +} + +int WaSkinModel::getPixmap(const QDir &dir, QString fname, + QPixmap *target) +{ + QFileInfo fileInfo; + QStringList strList = dir.entryList(); + QString abspath; + + abspath = findFile(dir, fname); + + if (!abspath.isEmpty()) { + target->load(abspath); + return true; + } + + // now the filename mapping 1.8x -> 2.0 + if (fname == "volume.bmp") + return WaSkinModel::getPixmap(dir, QString("volbar.bmp"), target); + + if (fname == "numbers.bmp") + return WaSkinModel::getPixmap(dir, QString("nums_ex.bmp"), target); + + // Even 2.x themes can omit BALANCE, in which case we use VOLUME + if (fname == "balance.bmp") + return WaSkinModel::getPixmap(dir, QString("volume.bmp"), target); + + return false; +} + + +QRect WaSkinModel::getGeometry(int id) { + if ( (id < 0) || (id >= _WA_SKIN_ENTRIES) ) { + kdDebug() << "Array index out of range. WaSkinModel::getGeometry"<<endl; + exit(-1); + } + return QRect(mapFromFile[id].x, mapFromFile[id].y, + mapFromFile[id].width, mapFromFile[id].height); +} + +QRect WaSkinModel::getMapGeometry(int id) { + if ( (id < 0) || (id >= _WA_MAPPING_ENTRIES) ) { + kdDebug() << "Array index out of range. WaSkinModel::getMapGeometry"<<endl; + exit(-1); + } + return QRect(mapToGui[id].x, mapToGui[id].y, + mapToGui[id].width, mapToGui[id].height); +} + +void WaSkinModel::bltTo(int id, QPaintDevice *dest, int x, int y) { + bitBlt(dest, x, y, waPixmapEntries[mapFromFile[id].fileId].pixmap, + mapFromFile[id].x, mapFromFile[id].y, + mapFromFile[id].width, mapFromFile[id].height); +} + +void WaSkinModel::bltTo(int id, QPaintDevice *dest, int x, int y, int argument) { + if (id == _WA_SKIN_VOLUME_BAR) { + QPixmap *pix = waPixmapEntries[_WA_FILE_VOLUME].pixmap; + + int nBar = int((float)argument * 27.0 / 100.0); + bitBlt(dest, x, y, pix, 0, 15 * nBar, 68, 13); + + return; + } + + if (id == _WA_SKIN_BALANCE_BAR) { + QPixmap *pix = waPixmapEntries[_WA_FILE_BALANCE].pixmap; + + argument = abs(argument); + + int nBar = int((float)argument * 27.0 / 100.0); + bitBlt(dest, x, y, pix, 9, 15 * nBar, 38, 13); + + return; + } + + bltTo(id, dest, x, y); +} + +void WaSkinModel::getDigit(char number, QPaintDevice *dest, int x, int y) { + if (number=='-') { + bltTo(_WA_SKIN_NUMBERS_MINUS, dest, x, y); + return; + } + + // empty number ? + if (number == ' ') { + bltTo(_WA_SKIN_NUMBERS_BLANK, dest, x, y); + return; + } + + // number + QPixmap *pix = waPixmapEntries[mapFromFile[_WA_SKIN_NUMBERS].fileId].pixmap; + + // ordinary number: + int index = number - '0'; + if ((index < 0) || (index > 9)) + return; + + bitBlt(dest, x, y, pix , (index * digit_width) + mapFromFile[_WA_SKIN_NUMBERS].x, mapFromFile[_WA_SKIN_NUMBERS].y, digit_width, digit_height); + + return; +} + +void WaSkinModel::getText(char text, QPaintDevice * dest, int x, int y) { + QPixmap *pix = waPixmapEntries[_WA_FILE_TEXT].pixmap; + + text = deaccent(text); + + if (('A' <= text) && (text <= 'Z')) { + bitBlt(dest, x, y,pix,(text-'A')*5,0,5,6); + return; + } + if (('a' <= text) && (text <= 'z')) { + bitBlt(dest, x, y,pix,(text-'a')*5,0,5,6); + return; + } + if (('0' <= text) && (text <= '9')) { + bitBlt(dest, x, y,pix,(text-'0')*5,6,5,6); + return; + } + if ('"' == text) { + bitBlt(dest, x, y,pix,27*5,0,5,6); + return; + } + if ('@' == text) { + bitBlt(dest, x, y,pix,28*5,0,5,6); + return; + } + + + if ('.' == text) { + bitBlt(dest, x, y,pix,11*5,6,5,6); + return; + } + if (':' == text) { + bitBlt(dest, x, y,pix,12*5,6,5,6); + return; + } + if (('(' == text) || ('<' == text) || ('{' == text)) { + bitBlt(dest, x, y,pix,13*5,6,5,6); + return; + } + if ((')' == text) || ('>' == text) || ('}' == text)) { + bitBlt(dest, x, y,pix,14*5,6,5,6); + return; + } + if ('-' == text) { + bitBlt(dest, x, y,pix,15*5,6,5,6); + return; + } + if (('`' == text) || ('\'' == text)) { + bitBlt(dest, x, y,pix,16*5,6,5,6); + return; + } + if ('!' == text) { + bitBlt(dest, x, y,pix,17*5,6,5,6); + return; + } + if ('_' == text) { + bitBlt(dest, x, y,pix,18*5,6,5,6); + return; + } + if ('+' == text) { + bitBlt(dest, x, y,pix,19*5,6,5,6); + return; + } + if ('\\' == text) { + bitBlt(dest, x, y,pix,20*5,6,5,6); + return; + } + if ('/' == text) { + bitBlt(dest, x, y,pix,21*5,6,5,6); + return; + } + if ('[' == text) { + bitBlt(dest, x, y,pix,22*5,6,5,6); + return; + } + if (']' == text) { + bitBlt(dest, x, y,pix,23*5,6,5,6); + return; + } + if ('^' == text) { + bitBlt(dest, x, y,pix,24*5,6,5,6); + return; + } + if ('&' == text) { + bitBlt(dest, x, y,pix,25*5,6,5,6); + return; + } + if ('%' == text) { + bitBlt(dest, x, y,pix,26*5,6,5,6); + return; + } + if (',' == text) { + bitBlt(dest, x, y,pix,27*5,6,5,6); + return; + } + if ('=' == text) { + bitBlt(dest, x, y,pix,28*5,6,5,6); + return; + } + if ('$' == text) { + bitBlt(dest, x, y,pix,29*5,6,5,6); + return; + } + if ('#' == text) { + bitBlt(dest, x, y,pix,30*5,6,5,6); + return; + } + if (('' == text) || ('' == text)) { + bitBlt(dest, x, y,pix,0*5,12,5,6); + return; + } + if (('' == text) || ('' == text)) { + bitBlt(dest, x, y,pix,1*5,12,5,6); + return; + } + if (('' == text) || ('' == text)) { + bitBlt(dest, x, y,pix,2*5,12,5,6); + return; + } + if ('?' == text) { + bitBlt(dest, x, y,pix,3*5,12,5,6); + return; + } + if ('*' == text) { + bitBlt(dest, x, y,pix,4*5,12,5,6); + return; + } + // default back is space char + bitBlt(dest, x, y,pix,(10*5),12,5,6); +} + +void WaSkinModel::paintBackgroundTo(int mapping, QPaintDevice *dest, int x, int y) +{ + QPixmap *pix = waPixmapEntries[mapFromFile[_WA_SKIN_MAIN].fileId].pixmap; + QRect main_rect = getGeometry(_WA_SKIN_MAIN); + QRect dest_rect = getMapGeometry(mapping); + + int source_x = main_rect.x() + dest_rect.x() + x; + int source_y = main_rect.y() + dest_rect.y() + y; + + int width = dest_rect.width() - x; + int height = dest_rect.height() - y; + + bitBlt(dest, x, y, pix, source_x, source_y, width, height); +} + +void WaSkinModel::setSkinModel(skin_models new_model) { + if (new_model == WA_MODEL_NORMAL) { + mapToGui = normalMapToGui; + mapFromFile = normalMapFromFile; + digit_width = 9; + digit_height = 13; + } + else if (new_model == WA_MODEL_WINDOWSHADE) { + mapToGui = shadeMapToGui; + mapFromFile = shadeMapFromFile; + digit_width = 5; + digit_height = 6; + } + + emit(skinChanged()); +} + +void WaSkinModel::resetSkinModel() { + mapToGui = normalMapToGui; + mapFromFile = normalMapFromFile; + digit_width = 9; + digit_height = 13; +} + + +QChar WaSkinModel::deaccent(QChar input) { + if (QString("").contains(input)) + return 'A'; + + if (QString("").contains(input)) + return 'E'; + + if (QString("").contains(input)) + return 'I'; + + if (QString("").contains(input)) + return 'O'; + + if (QString("").contains(input)) + return 'U'; + + if (input == '') + return 'Y'; + + if (QString("").contains(input)) + return 'a'; + + if (QString("").contains(input)) + return 'e'; + + if (QString("").contains(input)) + return 'i'; + + if (QString("").contains(input)) + return 'o'; + + if (QString("").contains(input)) + return 'u'; + + return input; +} + +#include "waSkinModel.moc" diff --git a/noatun/modules/winskin/waSkinModel.h b/noatun/modules/winskin/waSkinModel.h new file mode 100644 index 00000000..9447f8ae --- /dev/null +++ b/noatun/modules/winskin/waSkinModel.h @@ -0,0 +1,64 @@ +/* + Model for winamp skins + Copyright (C) 1999 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + +#ifndef __WASKINMODEL_H +#define __WASKINMODEL_H + +#include <qstring.h> +#include <qobject.h> +#include <qdir.h> + +#include "waSkins.h" + +enum skin_models { WA_MODEL_NORMAL, WA_MODEL_WINDOWSHADE }; + +class QChar; +class WaSkinModel; +extern WaSkinModel *_waskinmodel_instance; + +class WaSkinModel : public QObject { + Q_OBJECT + + public: + WaSkinModel(); + ~WaSkinModel(); + + void getDigit(char number, QPaintDevice *dest, int x, int y); + void getText(char text, QPaintDevice *dest, int x, int y); + + void bltTo(int id, QPaintDevice *dest, int x, int y); + void bltTo(int id, QPaintDevice *dest, int x, int y, int argument); + + void paintBackgroundTo(int mapping, QPaintDevice *dest, int x, int y); + + QRect getGeometry(int id); + QRect getMapGeometry(int id); + + bool load(QString skinDir); + + void setSkinModel(skin_models new_model); + static WaSkinModel *instance() { return _waskinmodel_instance; } + + private: + void resetSkinModel(); + + QString findFile(const QDir &dir, const QString &filename); + QChar deaccent(QChar input); + + int getPixmap(const QDir &dir, QString fname, QPixmap * target); + void loadColors(const QDir &dir); + void loadRegion(const QDir &dir); + + signals: + void skinChanged(); +}; +#endif diff --git a/noatun/modules/winskin/waSkins.h b/noatun/modules/winskin/waSkins.h new file mode 100644 index 00000000..f8d5f623 --- /dev/null +++ b/noatun/modules/winskin/waSkins.h @@ -0,0 +1,161 @@ +/* + names for the different skins in winamp + Copyright (C) 1999 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#ifndef _WASKINS_H +#define _WASKINS_H + + + +/** + The Skin file format was downloaded from the web. + http://www.algonet.et.se/~daniel7 + + Author: unknown +*/ + + +#define _WA_SKIN_MAIN 0 +#define _WA_SKIN_CBUTTONS_PREV_NORM 1 +#define _WA_SKIN_CBUTTONS_PREV_PRES 2 +#define _WA_SKIN_CBUTTONS_PLAY_NORM 3 +#define _WA_SKIN_CBUTTONS_PLAY_PRES 4 +#define _WA_SKIN_CBUTTONS_PAUSE_NORM 5 +#define _WA_SKIN_CBUTTONS_PAUSE_PRES 6 +#define _WA_SKIN_CBUTTONS_STOP_NORM 7 +#define _WA_SKIN_CBUTTONS_STOP_PRES 8 +#define _WA_SKIN_CBUTTONS_NEXT_NORM 9 +#define _WA_SKIN_CBUTTONS_NEXT_PRES 10 +#define _WA_SKIN_CBUTTONS_EJECT_NORM 11 +#define _WA_SKIN_CBUTTONS_EJECT_PRESS 12 +#define _WA_SKIN_MONOSTER_STEREO_TRUE 13 +#define _WA_SKIN_MONOSTER_STEREO_FALSE 14 +#define _WA_SKIN_MONOSTER_MONO_TRUE 15 +#define _WA_SKIN_MONOSTER_MONO_FALSE 16 + +#define _WA_SKIN_NUMBERS 17 +#define _WA_SKIN_NUMBERS_MINUS 18 +#define _WA_SKIN_NUMBERS_BLANK 19 + +#define _WA_SKIN_SHUFREP_REPEAT_NOT_SET_NORM 20 +#define _WA_SKIN_SHUFREP_REPEAT_NOT_SET_PRES 21 +#define _WA_SKIN_SHUFREP_REPEAT_SET_NORM 22 +#define _WA_SKIN_SHUFREP_REPEAT_SET_PRES 23 +#define _WA_SKIN_SHUFREP_SHUFFLE_NOT_SET_NORM 24 +#define _WA_SKIN_SHUFREP_SHUFFLE_NOT_SET_PRES 25 +#define _WA_SKIN_SHUFREP_SHUFFLE_SET_NORM 26 +#define _WA_SKIN_SHUFREP_SHUFFLE_SET_PRES 27 +#define _WA_SKIN_SHUFREP_PLAYLIST_NOT_SET_NORM 28 +#define _WA_SKIN_SHUFREP_PLAYLIST_NOT_SET_PRES 29 +#define _WA_SKIN_SHUFREP_PLAYLIST_SET_NORM 30 +#define _WA_SKIN_SHUFREP_PLAYLIST_SET_PRES 31 +#define _WA_SKIN_SHUFREP_EQ_NOT_SET_NORM 32 +#define _WA_SKIN_SHUFREP_EQ_NOT_SET_PRES 33 +#define _WA_SKIN_SHUFREP_EQ_SET_NORM 34 +#define _WA_SKIN_SHUFREP_EQ_SET_PRES 35 + +#define _WA_SKIN_TEXT 36 + +#define _WA_SKIN_VOLUME_BAR_ALL_BARS 37 +#define _WA_SKIN_VOLUME_BAR 38 +#define _WA_SKIN_VOLUME_SLIDER_NORM 39 +#define _WA_SKIN_VOLUME_SLIDER_PRES 40 + +#define _WA_SKIN_BALANCE_BAR_ALL_BARS 41 +#define _WA_SKIN_BALANCE_BAR 42 +#define _WA_SKIN_BALANCE_SLIDER_NORM 43 +#define _WA_SKIN_BALANCE_SLIDER_PRES 44 + +#define _WA_SKIN_POS_BAR 45 +#define _WA_SKIN_POS_BAR_SLIDER_NORM 46 +#define _WA_SKIN_POS_BAR_SLIDER_PRES 47 + +#define _WA_SKIN_PLAYPAUS_PLAY 48 +#define _WA_SKIN_PLAYPAUS_PAUSE 49 +#define _WA_SKIN_PLAYPAUS_STOP 50 +#define _WA_SKIN_PLAYPAUS_FILLER 51 +#define _WA_SKIN_PLAYPAUS_WORK_INDICATOR 52 + +#define _WA_SKIN_TITLE_ACTIVE 53 +#define _WA_SKIN_TITLE_INACTIVE 54 + +#define _WA_SKIN_TITLE_MENU_PRES 55 +#define _WA_SKIN_TITLE_MENU_NORM 56 +#define _WA_SKIN_TITLE_MENU_INACTIVE 57 +#define _WA_SKIN_TITLE_MIN_PRES 58 +#define _WA_SKIN_TITLE_MIN_NORM 59 +#define _WA_SKIN_TITLE_MIN_INACTIVE 60 +#define _WA_SKIN_TITLE_SHADE_PRES 61 +#define _WA_SKIN_TITLE_SHADE_NORM 62 +#define _WA_SKIN_TITLE_SHADE_INACTIVE 63 +#define _WA_SKIN_TITLE_CLOSE_PRES 64 +#define _WA_SKIN_TITLE_CLOSE_NORM 65 +#define _WA_SKIN_TITLE_CLOSE_INACTIVE 66 + +#define _WA_SKIN_CLUTTERBAR_DISABLED 67 + +#define _WA_MAPPING_MAIN 0 +#define _WA_MAPPING_CBUTTONS_PREV 1 +#define _WA_MAPPING_CBUTTONS_PLAY 2 +#define _WA_MAPPING_CBUTTONS_PAUSE 3 +#define _WA_MAPPING_CBUTTONS_STOP 4 +#define _WA_MAPPING_CBUTTONS_NEXT 5 +#define _WA_MAPPING_CBUTTONS_EJECT 6 +#define _WA_MAPPING_MONOSTER_STEREO 7 +#define _WA_MAPPING_MONOSTER_MONO 8 +#define _WA_MAPPING_REPEAT 9 +#define _WA_MAPPING_SHUFFLE 10 +#define _WA_MAPPING_PLAYLIST 11 +#define _WA_MAPPING_EQ 12 +#define _WA_MAPPING_VOLUME_BAR 13 +#define _WA_MAPPING_VOLUME_SLIDER 14 +#define _WA_MAPPING_BALANCE_BAR 15 +#define _WA_MAPPING_BALANCE_SLIDER 16 +#define _WA_MAPPING_PLAYPAUS 17 +#define _WA_MAPPING_POS_BAR 18 +#define _WA_MAPPING_POS_BAR_SLIDER 19 +#define _WA_MAPPING_DIGITS 20 +#define _WA_MAPPING_MINUS 21 +#define _WA_MAPPING_DIGIT_1 22 +#define _WA_MAPPING_DIGIT_2 23 +#define _WA_MAPPING_DIGIT_3 24 +#define _WA_MAPPING_DIGIT_4 25 +#define _WA_MAPPING_ANALYSER 26 +#define _WA_MAPPING_BPS 27 +#define _WA_MAPPING_FREQ 28 +#define _WA_MAPPING_INFO 29 +#define _WA_MAPPING_TITLE 30 +#define _WA_MAPPING_TITLE_MENU 31 +#define _WA_MAPPING_TITLE_MIN 32 +#define _WA_MAPPING_TITLE_SHADE 33 +#define _WA_MAPPING_TITLE_CLOSE 34 +#define _WA_MAPPING_CLUTTERBAR 35 + +#define _WA_FILE_MAIN 0 +#define _WA_FILE_CBUTTONS 1 +#define _WA_FILE_MONOSTER 2 +#define _WA_FILE_NUMBERS 3 +#define _WA_FILE_SHUFREP 4 +#define _WA_FILE_TEXT 5 +#define _WA_FILE_VOLUME 6 +#define _WA_FILE_BALANCE 7 +#define _WA_FILE_POSBAR 8 +#define _WA_FILE_PLAYPAUS 9 +#define _WA_FILE_TITLEBAR 10 + +#define _WA_MAPPING_ENTRIES 36 +#define _WA_SKIN_ENTRIES 68 + +#define _WA_TEXT_WIDTH 5 +#define _WA_TEXT_HEIGHT 6 + +#endif diff --git a/noatun/modules/winskin/waSlider.cpp b/noatun/modules/winskin/waSlider.cpp new file mode 100644 index 00000000..4fff1b0d --- /dev/null +++ b/noatun/modules/winskin/waSlider.cpp @@ -0,0 +1,209 @@ +/* + Standard slider for Winskin + Copyright (C) 1999 Martin Vogt + Copyright (C) 2002 Ryan Cumming + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + +#include <stdlib.h> + +#include "waSlider.h" +#include "waSkinModel.h" + +WaSlider::WaSlider(int sliderBarMapId, int sliderId, bool is_volume) : WaWidget(sliderBarMapId) +{ + this->sliderBarMapId = sliderBarMapId; + + lDragging = false; + + currentValue = 0; + setRange(0, 100); + + slider_y = is_volume ? 1 : 0; + slider_x = 0; + + slider_width = WaSkinModel::instance()->getMapGeometry(sliderId).width(); + + slider_visible = true; +} + + +WaSlider::~WaSlider() +{ +} + +void WaSlider::setPixmapSliderBar(int pixId) +{ + this->sliderBarId = pixId; + update(); +} + +void WaSlider::paintEvent(QPaintEvent *) +{ + // POSBAR.BMP does not have full height in all Winamp skins + // Paint background before painting slider to be on the safe side + if(sliderBarId == _WA_SKIN_POS_BAR) + paintPixmap(-1); + + paintPixmap(sliderBarId, value()); + + if (slider_visible) + paintPixmap(lDragging ? up_pixmap : down_pixmap, slider_x, slider_y); +} + + +void WaSlider::mouseMoveEvent(QMouseEvent * e) +{ + if (lDragging == false) { + WaWidget::mouseMoveEvent(e); + return; + } + + int newX = e->x() - pressPoint.x(); + + if (newX < 0) + newX = 0; + + QSize size = sizeHint(); + + int maxX = size.width() - slider_width; + + if(mapping == _WA_MAPPING_VOLUME_BAR) + maxX -= 3; + + if (newX > maxX) + newX = maxX; + + int value = pixel2Value(newX); + + setValue(value); +} + + +void WaSlider::updateSliderPos(int value) +{ + if (value > maxValue) { + value = maxValue; + } + if (value < minValue) { + value = minValue; + } + + int pixelPos = value2Pixel(value); + slider_x = (pixelPos); + + update(); +} + +void WaSlider::mousePressEvent(QMouseEvent *e) { + if (e->button() != LeftButton && e->button() != MidButton) { + WaWidget::mousePressEvent(e); + return; + } + + int maxX = slider_x - slider_width; + + if(mapping == _WA_MAPPING_VOLUME_BAR) + maxX -= 3; + + if ((e->x() < slider_x) || (e->x() > (maxX))) { + int newX = e->x(); + newX -= (slider_width / 2); + setValue(pixel2Value(newX)); + } + + + pressPoint.setX(e->x() - slider_x); + lDragging = true; + + update(); + + emit(sliderPressed()); +} + +void WaSlider::mouseReleaseEvent(QMouseEvent *e) +{ + if (!lDragging) { + WaWidget::mouseReleaseEvent(e); + return; + } + + lDragging = false; + update(); + + emit(sliderReleased()); +} + + +int WaSlider::pixel2Value(int xpos) +{ + QSize size = sizeHint(); + int min = abs(minValue); + int max = abs(maxValue); + + int valuerange = min + max; + int pixelrange = size.width() - slider_width; + + if(mapping == _WA_MAPPING_VOLUME_BAR) + pixelrange -= 3; + + return ((xpos * valuerange) / pixelrange) + minValue; +} + +int WaSlider::value2Pixel(int value) +{ + QSize size = sizeHint(); + float min = (float) minValue; + float max = (float) maxValue; + float fmin = min; + float fmax = max; + if (min < 0) { + fmin = -1 * fmin; + } + if (max < 0) { + fmax = -1 * fmax; + } + float valuerange = fmin + fmax; + float verhaeltnis = fmin / valuerange; + float pixelrange = (float) (size.width() - slider_width); + + if(mapping == _WA_MAPPING_VOLUME_BAR) + pixelrange -= 3; + + float zeropoint = verhaeltnis * pixelrange; + float anstieg = pixelrange / valuerange; + + float pixel = (float) value * anstieg + zeropoint; + return (int) (pixel+0.5); // add 0.5 to round upwards if larger than x.5 +} + +void WaSlider::setRange(int min, int max) { + minValue = min; + maxValue = max; + + if (currentValue < min) + currentValue = min; + + if (currentValue > max) + currentValue = max; +} + +void WaSlider::setValue(int value) { + currentValue = value; + + updateSliderPos(currentValue); + emit(valueChanged(value)); +} + +void WaSlider::cancelDrag() { + lDragging = false; + update(); +} + +#include "waSlider.moc" diff --git a/noatun/modules/winskin/waSlider.h b/noatun/modules/winskin/waSlider.h new file mode 100644 index 00000000..0003afd2 --- /dev/null +++ b/noatun/modules/winskin/waSlider.h @@ -0,0 +1,82 @@ +/* + standard Slider for winamp Skin + Copyright (C) 1999 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __WASLIDER_H +#define __WASLIDER_H + +#include <qpainter.h> + +#include "waWidget.h" +#include "waButton.h" + +class WaSlider : public WaWidget { + Q_OBJECT + + public: + WaSlider(int sliderBarMapId, int sliderId, bool is_volume = false); + ~WaSlider(); + + void setRange(int min, int max); + + void setValue(int value); + int value() const { return currentValue; } + + void hideButton() { slider_visible = false; } + void showButton() { slider_visible = true; } + + void cancelDrag(); + + public slots: + void setPixmapSliderButtonDown(int pixId) { down_pixmap = pixId; } + void setPixmapSliderButtonUp(int pixId) { up_pixmap = pixId; } + void setPixmapSliderBar(int pixId); + + private: + void paintEvent(QPaintEvent *); + int pixel2Value(int xpos); + int value2Pixel(int value); + + int slider_x; + int slider_y; + int slider_width; + bool slider_visible; + + int up_pixmap; + int down_pixmap; + + int sliderBarId; + int sliderBarMapId; + + bool lDragging; + QPoint pressPoint; + + int currentValue; + + int minValue; + int maxValue; + + void mousePressEvent(QMouseEvent *e); + void mouseMoveEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + + private slots: + void updateSliderPos(int value); + + signals: + void sliderPressed(); + void sliderReleased(); + void valueChanged(int); +}; +#endif diff --git a/noatun/modules/winskin/waStatus.cpp b/noatun/modules/winskin/waStatus.cpp new file mode 100644 index 00000000..e028b7f0 --- /dev/null +++ b/noatun/modules/winskin/waStatus.cpp @@ -0,0 +1,42 @@ +/* + standard Button for winamp Skin + Copyright (C) 1999 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "waStatus.h" +#include "waSkinModel.h" + +WaStatus::WaStatus() : WaWidget(_WA_MAPPING_PLAYPAUS) +{ + _status = STATUS_STOPPED; +} + +WaStatus::~WaStatus() +{ +} + +void WaStatus::paintEvent(QPaintEvent *) +{ + if (_status == STATUS_PLAYING) { + paintPixmap(_WA_SKIN_PLAYPAUS_WORK_INDICATOR); + paintPixmap(_WA_SKIN_PLAYPAUS_PLAY, 3, 0); + } + else if (_status == STATUS_STOPPED) { + paintPixmap(_WA_SKIN_PLAYPAUS_FILLER); + paintPixmap(_WA_SKIN_PLAYPAUS_STOP, 2 ,0); + } + else if (_status == STATUS_PAUSED) { + paintPixmap(_WA_SKIN_PLAYPAUS_FILLER); + paintPixmap(_WA_SKIN_PLAYPAUS_PAUSE, 2, 0); + } +} + +#include "waStatus.moc" diff --git a/noatun/modules/winskin/waStatus.h b/noatun/modules/winskin/waStatus.h new file mode 100644 index 00000000..a3fe1bc8 --- /dev/null +++ b/noatun/modules/winskin/waStatus.h @@ -0,0 +1,40 @@ +/* + standard Button for winamp Skin + Copyright (C) 1999 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __WASTATUS_H +#define __WASTATUS_H + +#include <qpainter.h> + +#include "waWidget.h" + +enum status_enum {STATUS_PLAYING, STATUS_STOPPED, STATUS_PAUSED}; + +class WaStatus : public WaWidget { + Q_OBJECT + + public: + WaStatus(); + ~WaStatus(); + + void setStatus(status_enum status) { _status = status; update(); } + status_enum status() const { return _status; } + + private: + void paintEvent(QPaintEvent * paintEvent); + + status_enum _status; +}; +#endif diff --git a/noatun/modules/winskin/waTitleBar.cpp b/noatun/modules/winskin/waTitleBar.cpp new file mode 100644 index 00000000..82b603f5 --- /dev/null +++ b/noatun/modules/winskin/waTitleBar.cpp @@ -0,0 +1,79 @@ +/* + Titlebar for winamp Skin + Copyright (C) 1999 Martin Vogt + Copyright (C) 2001 Ryan Cumming + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include <qwidget.h> +#include <qpixmap.h> + +#include "waTitleBar.h" +#include "waSkinModel.h" + +#include <stdlib.h> + +#include <iostream> + +WaTitleBar::WaTitleBar() : WaIndicator(_WA_MAPPING_TITLE, _WA_SKIN_TITLE_ACTIVE, _WA_SKIN_TITLE_INACTIVE) +{ + moving = false; + setState(parentWidget()->isActiveWindow()); +} + +WaTitleBar::~WaTitleBar() +{ +} + +void WaTitleBar::mousePressEvent(QMouseEvent * e) +{ + if (e->button() != RightButton) { + if (!moving) { + moving = true; + mDragStart = e->pos(); + mLastPos = e->globalPos(); + } + + setState(true); + update(); + return; + } + else + WaWidget::mousePressEvent(e); +} + +void WaTitleBar::mouseDoubleClickEvent(QMouseEvent *) { + emit(shaded()); +} + +void WaTitleBar::mouseReleaseEvent(QMouseEvent * e) +{ + if (e->button() != RightButton) { + moving = false; + update(); + return; + } + else + WaWidget::mouseReleaseEvent(e); +} + +void WaTitleBar::mouseMoveEvent(QMouseEvent * e) +{ + QPoint diff = e->globalPos() - mLastPos; + if (abs(diff.x()) > 10 || abs(diff.y()) > 10) { + // Moving starts only, when passing a drag border + moving = true; + } + + if (moving) + parentWidget()->move(e->globalPos() - mDragStart); +} + +#include <waTitleBar.moc> diff --git a/noatun/modules/winskin/waTitleBar.h b/noatun/modules/winskin/waTitleBar.h new file mode 100644 index 00000000..4e001394 --- /dev/null +++ b/noatun/modules/winskin/waTitleBar.h @@ -0,0 +1,51 @@ +/* + standard Button for winamp Skin + Copyright (C) 1999 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __WATITLEBAR_H +#define __WATITLEBAR_H + +#include <qpainter.h> + +#include "waIndicator.h" + + +/** + A titlebar is similar to a button only that we move + the whole widget, when pressed +*/ + + +class WaTitleBar : public WaIndicator { + Q_OBJECT + + public: + WaTitleBar(); + ~WaTitleBar(); + + private: + void mouseDoubleClickEvent (QMouseEvent * e); + void mousePressEvent(QMouseEvent * e); + void mouseReleaseEvent(QMouseEvent * e); + void mouseMoveEvent(QMouseEvent * e); + + bool moving; + QPoint mLastPos; + QPoint mDragStart; + + signals: + void shaded(); + +}; +#endif diff --git a/noatun/modules/winskin/waVolumeSlider.cpp b/noatun/modules/winskin/waVolumeSlider.cpp new file mode 100644 index 00000000..d0a934d7 --- /dev/null +++ b/noatun/modules/winskin/waVolumeSlider.cpp @@ -0,0 +1,51 @@ +/* + jumpslider for winamp skins + Copyright (C) 1998 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include <waVolumeSlider.h> + + +WaVolumeSlider::WaVolumeSlider() : WaWidget(_WA_MAPPING_VOLUME_BAR) +{ + +} + + +WaVolumeSlider::~WaVolumeSlider() +{ +} + + +void WaVolumeSlider::buildGui() +{ + ws = new WaSlider(_WA_MAPPING_VOLUME_BAR, _WA_MAPPING_VOLUME_SLIDER, true); + + ws->setPixmapSliderButtonUp(_WA_SKIN_VOLUME_SLIDER_NORM); + ws->setPixmapSliderButtonDown(_WA_SKIN_VOLUME_SLIDER_PRES); + ws->setPixmapSliderBar(_WA_SKIN_VOLUME_BAR); + + connect(ws, SIGNAL(valueChanged(int)), this, + SIGNAL(volumeSetValue(int))); + connect(ws, SIGNAL(sliderPressed()), SIGNAL(sliderPressed())); + connect(ws, SIGNAL(sliderReleased()), SIGNAL(sliderReleased())); +} + +void WaVolumeSlider::setVolumeValue(int val) +{ + int currVal = ws->value(); + if (currVal != val) { + ws->setValue(val); + } +} + + +#include "waVolumeSlider.moc" diff --git a/noatun/modules/winskin/waVolumeSlider.h b/noatun/modules/winskin/waVolumeSlider.h new file mode 100644 index 00000000..29030c65 --- /dev/null +++ b/noatun/modules/winskin/waVolumeSlider.h @@ -0,0 +1,41 @@ +/* + jumpslider for winamp skins + Copyright (C) 1998 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef __WAVOLUMESLIDER_H +#define __WAVOLUMESLIDER_H + +#include "waSlider.h" +#include "waWidget.h" + +class WaVolumeSlider:public WaWidget { + Q_OBJECT + + public: + WaVolumeSlider(); + ~WaVolumeSlider(); + void buildGui(); + + void setVolumeValue(int val); + + private: + WaSlider *ws; + + signals: + void volumeSetValue(int val); + void sliderPressed(); + void sliderReleased(); +}; + + +#endif diff --git a/noatun/modules/winskin/waWidget.cpp b/noatun/modules/winskin/waWidget.cpp new file mode 100644 index 00000000..ffe2d3b4 --- /dev/null +++ b/noatun/modules/winskin/waWidget.cpp @@ -0,0 +1,58 @@ +#include "waWidget.h" +#include "waSkinModel.h" +#include "noatun/stdaction.h" +#include "waSkin.h" + +WaWidget::WaWidget(int _mapping) : QWidget(WaSkin::instance()) { + mapping = _mapping; + setBackgroundMode(NoBackground); + connect (WaSkinModel::instance(), SIGNAL(skinChanged()), this, SLOT(skinChanged())); +} + +WaWidget::~WaWidget() { +} + +void WaWidget::paintPixmap(int pixmap_mapping) { + if (pixmap_mapping != -1) + WaSkinModel::instance()->bltTo(pixmap_mapping, this, 0, 0); + else + WaSkinModel::instance()->paintBackgroundTo(mapping, this, 0, 0); +} + +void WaWidget::paintPixmap(int pixmap_mapping, int x, int y) { + if (pixmap_mapping != -1) + WaSkinModel::instance()->bltTo(pixmap_mapping, this, x, y); + else + WaSkinModel::instance()->paintBackgroundTo(mapping, this, x, y); +} + +void WaWidget::paintPixmap(int pixmap_mapping, int argument) { + if (pixmap_mapping != -1) + WaSkinModel::instance()->bltTo(pixmap_mapping, this, 0, 0, argument); + else + WaSkinModel::instance()->paintBackgroundTo(mapping, this, 0, 0); + +} + +void WaWidget::paintPixmap(int pixmap_mapping, int argument, int x, int y) { + if (pixmap_mapping != -1) + WaSkinModel::instance()->bltTo(pixmap_mapping, this, x, y, argument); + else + WaSkinModel::instance()->paintBackgroundTo(mapping, this, x, y); +} + +QSize WaWidget::sizeHint() { + return WaSkinModel::instance()->getMapGeometry(mapping).size(); +} + +void WaWidget::mousePressEvent(QMouseEvent *e) { + if (e->button() == RightButton) + NoatunStdAction::ContextMenu::showContextMenu(); +} + +void WaWidget::skinChanged() { + setGeometry(WaSkinModel::instance()->getMapGeometry(mapping)); + update(); +} + +#include <waWidget.moc> diff --git a/noatun/modules/winskin/waWidget.h b/noatun/modules/winskin/waWidget.h new file mode 100644 index 00000000..f2a41c82 --- /dev/null +++ b/noatun/modules/winskin/waWidget.h @@ -0,0 +1,31 @@ +#ifndef _WAWIDGET_H +#define _WAWIDGET_H + +#include <qwidget.h> +#include "waSkinModel.h" + +class WaWidget : public QWidget { + Q_OBJECT +public: + WaWidget(int mapping); + virtual ~WaWidget(); + + QSize sizeHint(); + + void paintPixmap(int wa_mapping); + void paintPixmap(int wa_mapping, int number); + + void paintPixmap(int wa_mapping, int x, int y); + void paintPixmap(int wa_mapping, int number, int x, int y); + + void paintBackground() { WaSkinModel::instance()->paintBackgroundTo(mapping, this, 0, 0); } + +protected: + void mousePressEvent(QMouseEvent *); + int mapping; + +private slots: + void skinChanged(); +}; + +#endif diff --git a/noatun/modules/winskin/winSkinConfig.cpp b/noatun/modules/winskin/winSkinConfig.cpp new file mode 100644 index 00000000..649fd1fe --- /dev/null +++ b/noatun/modules/winskin/winSkinConfig.cpp @@ -0,0 +1,174 @@ +#include <noatun/pref.h> + +#include <klocale.h> +#include <qpushbutton.h> +#include <qlayout.h> +#include <qlabel.h> +#include <qpixmap.h> +#include <kglobal.h> +#include <kconfig.h> +#include <qslider.h> +#include <qframe.h> +#include <qstringlist.h> +#include <kfile.h> +#include <kfiledialog.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <kurlrequester.h> +#include <kurlrequesterdlg.h> +#include <qdir.h> + +#include "waSkin.h" +#include "waInfo.h" +#include "waSkinManager.h" +#include "winSkinConfig.h" + +WinSkinConfig::WinSkinConfig(QWidget * parent, WaSkinManager *waSkinManager) : + CModule(i18n("Winskin"), + i18n("Skin Selection for the Winskin Plugin"), + "style", + parent) +{ + // Make a token horizontal layout box + vbox = new QVBoxLayout(this); + vbox->setSpacing( 6 ); + vbox->setMargin( 0 ); + + // Add a simple list of skins, populated in WinSkinConfig::reopen() + skin_list = new QListBox(this, "skin_list"); + vbox->addWidget(skin_list); + + QHBoxLayout* hbox = new QHBoxLayout( 0, 6, 6 ); + + QPushButton* buttonInstall = new QPushButton( i18n("&Install New Skin..."), this ); + hbox->addWidget(buttonInstall); + + buttonRemove = new QPushButton( i18n("&Remove Skin"), this ); + buttonRemove->setEnabled(false); + hbox->addWidget(buttonRemove); + vbox->addLayout(hbox); + + connect( skin_list, SIGNAL(highlighted(const QString &)), this, SLOT(selected())); + connect( buttonInstall, SIGNAL(clicked()), this, SLOT(install())); + connect( buttonRemove, SIGNAL(clicked()), this, SLOT(remove())); + connect(waSkinManager, SIGNAL(updateSkinList()), this, SLOT(reopen())); + + mWaSkinManager = waSkinManager; + + QGroupBox *settingsBox = new QGroupBox( 1, Vertical, i18n("Settings"), this ); + vbox->addWidget(settingsBox); + + QHBox *box = new QHBox(settingsBox); + QLabel *label = new QLabel(i18n("T&itle scrolling speed:"), box); + new QLabel(i18n("None"), box); + + scrollSpeed = new QSlider(box); + label->setBuddy(scrollSpeed); + scrollSpeed->setMinimumSize( QSize( 80, 0 ) ); + scrollSpeed->setMinValue( 0 ); + scrollSpeed->setMaxValue( 50 ); + scrollSpeed->setPageStep( 1 ); + scrollSpeed->setOrientation( QSlider::Horizontal ); + scrollSpeed->setTickmarks( QSlider::NoMarks ); + + label = new QLabel(i18n("Fast"), box); + + reopen(); +} + +void WinSkinConfig::save() +{ + KConfig *config=KGlobal::config(); + config->setGroup("Winskin"); + config->writeEntry("CurrentSkin", skin_list->currentText()); + config->writeEntry("ScrollDelay", scrollSpeed->value()); + config->sync(); + + if (skin_list->currentText() != orig_skin) { + _waskin_instance->loadSkin(skin_list->currentText()); + orig_skin = skin_list->currentText(); + } + else + { + _waskin_instance->skinInfo()->scrollerSetup(); + } +} + +void WinSkinConfig::reopen() { + // Wipe out the old list + skin_list->clear(); + + // Get a list of skins + QStringList skins = mWaSkinManager->availableSkins(); + + // This loop adds them all to our skin list + for(unsigned int x = 0;x < skins.count();x++) { + // Add ourselves to the list + skin_list->insertItem(skins[x]); + } + + // Figure out our current skin + QString orig_skin = mWaSkinManager->currentSkin(); + + // Where is that skin in our big-list-o-skins? + QListBoxItem *item = skin_list->findItem(orig_skin); + + if (item) { + // Aha, found it... make it the currently selected skin + skin_list->setCurrentItem( item ); + } + else { + // Er, it's not there... select the current item + // Maybe this should emit a warning? Oh well, it's not harmful + skin_list->setCurrentItem( 0 ); + } + + KConfig *config=KGlobal::config(); + config->setGroup("Winskin"); + scrollSpeed->setValue(config->readNumEntry("ScrollDelay", 15)); +} + +void WinSkinConfig::selected() +{ + buttonRemove->setEnabled(mWaSkinManager->skinRemovable( skin_list->currentText() )); +} + +void WinSkinConfig::install() +{ + QString url; + + // Ask the user for directory containing a skin + KURLRequesterDlg* udlg = new KURLRequesterDlg( QString::null, this, "udlg", true ); + udlg->urlRequester()->setFilter(mWaSkinManager->skinMimeTypes().join(" ")); + udlg->urlRequester()->setMode( KFile::File | KFile::Directory | KFile::ExistingOnly ); + + if( udlg->exec() == QDialog::Accepted ) { + url = udlg->urlRequester()->url(); + mWaSkinManager->installSkin( url ); + } +} + +void WinSkinConfig::remove() +{ + // Is there any item selected ?? + if( skin_list->currentText().isEmpty() ) + return; + + // We can't remove every skin + if( !mWaSkinManager->skinRemovable( skin_list->currentText() ) ) { + KMessageBox::information( this, i18n("You cannot remove this skin.") ); + // Reload skin list, perhaps the skin is already removed! + return; + } + + // Ask the user first + if( KMessageBox::warningContinueCancel( this, + i18n("<qt>Are you sure you want to remove the <b>%1</b> skin?</qt>").arg( skin_list->currentText() ), QString::null, KStdGuiItem::del() ) + == KMessageBox::Continue ) { + + mWaSkinManager->removeSkin( skin_list->currentText() ); + reopen(); + } +} + +#include <winSkinConfig.moc> diff --git a/noatun/modules/winskin/winSkinConfig.h b/noatun/modules/winskin/winSkinConfig.h new file mode 100644 index 00000000..22dca884 --- /dev/null +++ b/noatun/modules/winskin/winSkinConfig.h @@ -0,0 +1,35 @@ +#ifndef __WINSKINCONFIG_H +#define __WINSKINCONFIG_H + +#include <noatun/pref.h> +#include <qwidget.h> + +class QVBoxLayout; +class WaSkinManager; +class QSlider; + +class WinSkinConfig:public CModule { + Q_OBJECT + public: + WinSkinConfig(QWidget * parent, WaSkinManager *waManager); + + void save(); + + public slots: + void reopen(); + + private slots: + void selected(); + void install(); + void remove(); + + private: + WaSkinManager *mWaSkinManager; + QListBox *skin_list; + QString orig_skin; + QVBoxLayout *vbox; + QPushButton *buttonRemove; + QSlider *scrollSpeed; +}; + +#endif diff --git a/noatun/modules/winskin/winSkinVis.cpp b/noatun/modules/winskin/winSkinVis.cpp new file mode 100644 index 00000000..f9937981 --- /dev/null +++ b/noatun/modules/winskin/winSkinVis.cpp @@ -0,0 +1,107 @@ +/* + noatun visualisation interface for winskin + Copyright (C) 2001 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#include "winSkinVis.h" + +#define __BANDS 75 +#define __SPAHEIGHT 15 + +WinSkinVis::WinSkinVis(QObject *parent, const char *name): + QObject(parent,name),Visualization(50) { + + m_currentPeaks=new float[__BANDS]; + + for(unsigned int i=0;i<__BANDS;i++) + m_currentPeaks[i]=0.0; + + // If we can create our server-side object, visualize away + if (initServerObject()) + { + start(); + } +} + + +WinSkinVis::~WinSkinVis() +{ + if (m_winSkinFFT != NULL) { + if (connected()) + { + visualizationStack().remove(m_id); + m_winSkinFFT->stop(); + delete m_winSkinFFT; + } + } + + delete[] m_currentPeaks; +} + + +bool WinSkinVis::initServerObject() +{ + // Create FFT on server + m_winSkinFFT = new Noatun::WinSkinFFT(); + *m_winSkinFFT = Arts::DynamicCast(server()->createObject("Noatun::WinSkinFFT")); + + if ( (*m_winSkinFFT).isNull() ) { + delete m_winSkinFFT; + m_winSkinFFT=NULL; + } + else + { + m_winSkinFFT->bandResolution(__BANDS); + m_winSkinFFT->start(); + m_id=visualizationStack().insertBottom(*m_winSkinFFT, "WinSkin FFT"); + } + + return (m_winSkinFFT != NULL); +} + +void WinSkinVis::timeout() +{ + std::vector<float> *data(m_winSkinFFT->scope()); + + float *f=&data->front(); + if (data->size()) + scopeEvent(f, data->size()); + + delete data; +} + +float* WinSkinVis::currentPeaks() +{ + return m_currentPeaks; +} + +void WinSkinVis::scopeEvent(float* bandPtr, unsigned int bands) +{ + for (unsigned int i = 0;i < bands;i++) { + float value=bandPtr[i]; + // if the peak is less we prefer the higher one + if (m_currentPeaks[i] < value) + m_currentPeaks[i] = value; + else + m_currentPeaks[i] = m_currentPeaks[i]-1.3; + + if (m_currentPeaks[i] < 0.0) + m_currentPeaks[i] = 0.0; + + if (m_currentPeaks[i] > __SPAHEIGHT) + m_currentPeaks[i]=__SPAHEIGHT; + } + emit(doRepaint()); +} + + +#include "winSkinVis.moc" diff --git a/noatun/modules/winskin/winSkinVis.h b/noatun/modules/winskin/winSkinVis.h new file mode 100644 index 00000000..7d139d0c --- /dev/null +++ b/noatun/modules/winskin/winSkinVis.h @@ -0,0 +1,54 @@ +/* + noatun visualisation interface for winskin + Copyright (C) 2001 Martin Vogt + + 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. + + For more information look at the file COPYRIGHT in this package + + */ + + +#ifndef __WINSKINVIS_H +#define __WINSKINVIS_H + +#include <qobject.h> + +// These are needed for the Visualisation class +#include <soundserver.h> +#include "noatunarts/noatunarts.h" +#include "noatun/plugin.h" + +#include "vis/winskinvis.h" + +class WinSkinVis : public QObject, public Visualization { + Q_OBJECT + + public: + WinSkinVis(QObject* parent,const char* name); + ~WinSkinVis(); + + /** + * reimplemented from class Visualization, you + * should never need to reimplement this yourself + **/ + void timeout(); + float* currentPeaks(); + + signals: + void doRepaint(); + + private: + bool initServerObject(); + void scopeEvent(float* spectrum, unsigned int size); + + Noatun::WinSkinFFT* m_winSkinFFT; + long m_id; + float* m_currentPeaks; + + +}; + +#endif diff --git a/noatun/modules/winskin/winskin.plugin b/noatun/modules/winskin/winskin.plugin new file mode 100644 index 00000000..0f8b1074 --- /dev/null +++ b/noatun/modules/winskin/winskin.plugin @@ -0,0 +1,122 @@ +Filename=noatun_winskin.la +Author=Ryan Cumming, Martin Vogt +Site=http://mpeglib.sf.net +Email=bodnar42@phalynx.dhs.org +Type=userinterface +License=LGPL +Name=WinAmp Interface +Name[af]=Winamp Koppelvlak +Name[ar]=واجهة WinAmp +Name[az]=WinAMP Ara üzü +Name[bn]=উইন-অ্যাম্প ইন্টারফেস +Name[br]=Talbenn evit WinAmp +Name[ca]=Interfície WinAmp +Name[cs]=Rozhraní WinAmpu +Name[cy]=Rhyngwyneb Winamp +Name[da]=Winamp-grænseflade +Name[de]=Winamp-Oberfläche +Name[el]=Περιβάλλον WinAmp +Name[eo]=WinAmp-interfaco +Name[es]=Interfaz de Winamp +Name[et]=WinAmp liides +Name[eu]=WinAmp interfazea +Name[fa]=واسط WinAmp +Name[fi]=WinAmp-käyttöliittymä +Name[fr]=Interface Winamp +Name[ga]=Comhéadan WinAmp +Name[gl]=Interface de WinAmp +Name[he]=ממשק WinAmp +Name[hi]= विनएम्प इंटरफेस +Name[hr]=WinAmp sučelje +Name[hu]=Winamp-felület +Name[id]=Interface winamp +Name[is]=WinAmp andlit +Name[it]=Interfaccia WinAmp +Name[ja]=WinAmp インターフェース +Name[kk]=WinAmp интерфейсі +Name[km]=ចំណុចប្រទាក់ WinAmp +Name[ko]=WinAmp 인터페이스 +Name[lt]=WinAmp sąsaja +Name[lv]=WinAmp Starpseja +Name[mk]=Интерфејс WinAmp +Name[ms]=Antaramuka WinAmp +Name[mt]=Interfaċċja WinAmp +Name[nb]=WinAmp-grensesnitt +Name[nds]=Winamp-Böversiet +Name[ne]=WinAmp इन्टरफेस +Name[nl]=WinAmp-interface +Name[nn]=WinAmp-grensesnitt +Name[pa]=WinAmp ਇੰਟਰਫੇਸ +Name[pl]=Motyw WinAmpa +Name[pt]=Interface do WinAmp +Name[pt_BR]=Interface WinAmp +Name[ro]=Interfaţă WinAmp +Name[ru]=Интерфейс WinAmp +Name[sk]=Rozhranie WinAmp +Name[sl]=Vmesnik WinAmp +Name[sr]=WinAmp интерфејс +Name[sr@Latn]=WinAmp interfejs +Name[sv]=Winamp-gränssnitt +Name[ta]=வின் ஆம்ப் முகப்பு +Name[tg]=Интерфейси WinAmp +Name[th]=ส่วนติดต่อแบบ WinAmp +Name[tr]=WinAmp Arayüzü +Name[uk]=Інтерфейс WinAmp +Name[ven]=Interface ya WinAmp +Name[wa]=Eterface po WinAmp +Name[xh]=Ujongano lwe WinAmp +Name[zh_CN]=WinAmp 界面 +Name[zh_HK]=WinAmp 界面 +Name[zh_TW]=WinAmp 界面 +Name[zu]=Uxhumano olubhekeneyo lwe WinAmp +Comment=A Winamp skin loader +Comment[bg]=Зареждане на теми за Winamp +Comment[bn]=একটি উইন-অ্যাম্প স্কিন লোডার +Comment[br]=Ur c'harger a groc'hen Winamp +Comment[bs]=Učitavanje Winamp skinova +Comment[ca]=Carregador d'aparences de Winamp +Comment[cs]=Zavaděč motivů WinAmpu +Comment[cy]=Llwythydd Crwyn Winamp +Comment[da]=En Winamp-forsideindlæser +Comment[de]=Import von Winamp-Designs +Comment[el]=Φόρτωση θεμάτων Winamp +Comment[eo]=WinAmp-etosŝargilo +Comment[es]=Un cargador de pieles de Winamp +Comment[et]=Winampi rüüde laadija +Comment[eu]=Winamp azal kargatzailea +Comment[fa]=یک بارکنندۀ Winamp skin +Comment[fi]=Winamp-nahkojen lataaja +Comment[fr]=Un chargeur de revêtement Winamp +Comment[gl]=Un cargador de peles de Winamp +Comment[he]=טוען Skins של Winamp +Comment[hu]=Betöltőprogram Winamp-kinézetekhez +Comment[is]=Les skinn fyrir WinAmp +Comment[it]=Caricatore di skin di Winamp +Comment[ja]=Winamp のスキンローダ +Comment[kk]=Winamp тысының жүктегіші +Comment[km]=កម្មវិធីផ្ទុកស្បែក Winamp +Comment[ko]=Winamp 스킨 로더 +Comment[lt]=Winamp pavidalų įkėliklis +Comment[mk]=Вчитувач на маски за Winamp +Comment[nb]=Laster WinAmp-drakt +Comment[nds]=En Winamp-Böversietlader +Comment[ne]=विन्याप स्किन लोडर +Comment[nl]=Een Winamp-skinlader +Comment[nn]=Lastar WinAmp-skal +Comment[pl]=Ładowarka skór Winampa +Comment[pt]=Um leitor de aspectos do WinAmp +Comment[pt_BR]=Um carregador de aparências (skins) do Winamp +Comment[ro]=Un încărcător de tematici WinAmp +Comment[ru]=Загрузчик тем Winamp +Comment[sk]=Načítavač tém WinAmp +Comment[sl]=Nalagalnik preoblek Winamp +Comment[sr]=Учитавач Winamp-ових кошуљица +Comment[sr@Latn]=Učitavač Winamp-ovih košuljica +Comment[sv]=Skalladdare för Winamp +Comment[ta]=வின் ஆம்ப் அலங்கார அமைப்பு ஏற்றி +Comment[th]=ตัวโหลดหน้ากากแบบวินแอมป์ +Comment[tr]=Winamp arayüz yükleyici +Comment[uk]=Завантажувач жупанів Winamp +Comment[zh_CN]=Winamp 外观载入器 +Comment[zh_HK]=Winamp Skin 載入器 +Comment[zh_TW]=Winamp 面板載入器 |