Changed handling of buttons
Use PixmapButton in most cases insteas of Button or ToggleButton Moved positions and sizes of the buttons to Skin and let it return QIcons instead of Pixmaps
This commit is contained in:
parent
08cbc98487
commit
d3e140ad0e
12 changed files with 344 additions and 214 deletions
229
src/Skin.cpp
229
src/Skin.cpp
|
@ -13,6 +13,8 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Skin.h"
|
||||
|
||||
#include <QDir>
|
||||
|
@ -29,27 +31,90 @@ Skin *Skin::getInstance (void)
|
|||
return singleton;
|
||||
}
|
||||
|
||||
Skin::Skin ()
|
||||
{
|
||||
setSizes ();
|
||||
setPositions ();
|
||||
}
|
||||
|
||||
void
|
||||
Skin::setSizes ()
|
||||
{
|
||||
m_sizes.clear ();
|
||||
m_sizes << QSize ( 9, 9) // BUTTON_MW_MENU
|
||||
<< QSize ( 9, 9) // BUTTON_MW_MINIMIZE
|
||||
<< QSize ( 9, 9) // BUTTON_MW_CLOSE
|
||||
<< QSize ( 9, 9) // BUTTON_MW_SHADE
|
||||
<< QSize (23, 18) // BUTTON_MW_PREV
|
||||
<< QSize (23, 18) // BUTTON_MW_PLAY
|
||||
<< QSize (23, 18) // BUTTON_MW_PAUSE
|
||||
<< QSize (23, 18) // BUTTON_MW_STOP
|
||||
<< QSize (22, 18) // BUTTON_MW_NEXT
|
||||
<< QSize (22, 16) // BUTTON_MW_EJECT
|
||||
<< QSize (23, 12) // BUTTON_MW_EQ
|
||||
<< QSize (23, 12) // BUTTON_MW_PLS
|
||||
<< QSize (46, 15) // BUTTON_MW_SHUFFLE
|
||||
<< QSize (28, 15) // BUTTON_MW_REPEAT
|
||||
<< QSize ( 9, 9) // BUTTON_MW_SHADED_SHADE
|
||||
<< QSize (25, 12) // BUTTON_EQ_ACTIVE
|
||||
<< QSize (33, 12) // BUTTON_EQ_AUTO
|
||||
<< QSize (44, 12) // BUTTON_EQ_PRESET
|
||||
;
|
||||
}
|
||||
|
||||
void
|
||||
Skin::setPositions ()
|
||||
{
|
||||
m_positions.clear ();
|
||||
m_positions << QPoint ( 6, 3) // BUTTON_MW_MENU
|
||||
<< QPoint (244, 3) // BUTTON_MW_MINIMIZE
|
||||
<< QPoint (264, 3) // BUTTON_MW_CLOSE
|
||||
<< QPoint (254, 3) // BUTTON_MW_SHADE
|
||||
<< QPoint ( 16, 88) // BUTTON_MW_PREV
|
||||
<< QPoint ( 39, 88) // BUTTON_MW_PLAY
|
||||
<< QPoint ( 62, 88) // BUTTON_MW_PAUSE
|
||||
<< QPoint ( 85, 88) // BUTTON_MW_STOP
|
||||
<< QPoint (108, 88) // BUTTON_MW_NEXT
|
||||
<< QPoint (136, 89) // BUTTON_MW_EJECT
|
||||
<< QPoint (219, 58) // BUTTON_MW_EQ
|
||||
<< QPoint (242, 58) // BUTTON_MW_PLS
|
||||
<< QPoint (164, 89) // BUTTON_MW_SHUFFLE
|
||||
<< QPoint (210, 89) // BUTTON_MW_REPEAT
|
||||
<< QPoint (254, 3) // BUTTON_MW_SHADED_SHADE
|
||||
<< QPoint ( 14, 18) // BUTTON_EQ_ACTIVE
|
||||
<< QPoint ( 39, 18) // BUTTON_EQ_AUTO
|
||||
<< QPoint (217, 18) // BUTTON_EQ_PRESET
|
||||
;
|
||||
}
|
||||
|
||||
void
|
||||
Skin::BuildEqualizer (void)
|
||||
{
|
||||
QPixmap *img = getPixmap ("eqmain");
|
||||
if (img) {
|
||||
m_items[EQ_WIN_BG] = img->copy (0, 0, 275, 116);
|
||||
m_items[EQ_WIN_OFF_0] = img->copy (10, 119, 25, 12);
|
||||
m_items[EQ_WIN_OFF_1] = img->copy (128, 119, 25, 12);
|
||||
m_items[EQ_WIN_ON_1] = img->copy (187, 119, 25, 12);
|
||||
m_items[EQ_WIN_ON_0] = img->copy (69, 119, 25, 12);
|
||||
|
||||
m_items[EQ_WIN_AUTO_OFF_0] = img->copy (35, 119, 33, 12);
|
||||
m_items[EQ_WIN_AUTO_OFF_1] = img->copy (153, 119, 33, 12);
|
||||
m_items[EQ_WIN_AUTO_ON_1] = img->copy (212, 119, 33, 12);
|
||||
m_items[EQ_WIN_AUTO_ON_0] = img->copy (94, 119, 33, 12);
|
||||
|
||||
m_items[EQ_WIN_PRESET_0] = img->copy (224, 164, 44, 12);
|
||||
m_items[EQ_WIN_PRESET_1] = img->copy (224, 176, 44, 12);
|
||||
|
||||
m_items[EQ_WIN_GRAPH_BG] = img->copy (0, 294, 113, 19);
|
||||
|
||||
QIcon icon;
|
||||
icon.addPixmap (img->copy ( 10, 119, 25, 12), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (128, 119, 25, 12), QIcon::Active, QIcon::Off);
|
||||
icon.addPixmap (img->copy ( 69, 119, 25, 12), QIcon::Normal, QIcon::On);
|
||||
icon.addPixmap (img->copy (187, 119, 25, 12), QIcon::Active, QIcon::On);
|
||||
m_icons[BUTTON_EQ_ACTIVE] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy ( 35, 119, 33, 12), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (153, 119, 33, 12), QIcon::Active, QIcon::Off);
|
||||
icon.addPixmap (img->copy ( 94, 119, 33, 12), QIcon::Normal, QIcon::On);
|
||||
icon.addPixmap (img->copy (212, 119, 33, 12), QIcon::Active, QIcon::On);
|
||||
m_icons[BUTTON_EQ_AUTO] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy (224, 164, 44, 12), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (224, 176, 44, 12), QIcon::Active, QIcon::Off);
|
||||
m_icons[BUTTON_EQ_PRESET] = icon;
|
||||
|
||||
for (int i = 0; i < 14; i++) {
|
||||
m_items[EQ_WIN_BAR_POS_0+i] = img->copy (13+15*i, 164, 14, 63);
|
||||
}
|
||||
|
@ -333,24 +398,36 @@ Skin::BuildButtons (void)
|
|||
QPixmap *img = getPixmap("cbuttons");
|
||||
if(img)
|
||||
{
|
||||
m_items[BTN_PREV_0] = img->copy(0, 0, 23, 18);
|
||||
m_items[BTN_PREV_1] = img->copy(0, 18, 23, 18);
|
||||
|
||||
m_items[BTN_PLAY_0] = img->copy(23, 0, 23, 18);
|
||||
m_items[BTN_PLAY_1] = img->copy(23, 18, 23, 18);
|
||||
|
||||
m_items[BTN_PAUSE_0] = img->copy(46, 0, 23, 18);
|
||||
m_items[BTN_PAUSE_1] = img->copy(46, 18, 23, 18);
|
||||
|
||||
m_items[BTN_STOP_0] = img->copy(69, 0, 23, 18);
|
||||
m_items[BTN_STOP_1] = img->copy(69, 18, 23, 18);
|
||||
|
||||
m_items[BTN_NEXT_0] = img->copy(92, 0, 22, 18);
|
||||
m_items[BTN_NEXT_1] = img->copy(92, 18, 22, 18);
|
||||
|
||||
m_items[BTN_EJECT_0] = img->copy(114, 0, 22, 16);
|
||||
m_items[BTN_EJECT_1] = img->copy(114, 16, 22, 16);
|
||||
|
||||
QIcon icon;
|
||||
icon.addPixmap (img->copy (0, 0, 23, 18), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (0, 18, 23, 18), QIcon::Active, QIcon::Off);
|
||||
m_icons[BUTTON_MW_PREV] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy (23, 0, 23, 18), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (23, 18, 23, 18), QIcon::Active, QIcon::Off);
|
||||
m_icons[BUTTON_MW_PLAY] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy (46, 0, 23, 18), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (46, 18, 23, 18), QIcon::Active, QIcon::Off);
|
||||
m_icons[BUTTON_MW_PAUSE] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy (69, 0, 23, 18), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (69, 18, 23, 18), QIcon::Active, QIcon::Off);
|
||||
m_icons[BUTTON_MW_STOP] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy (92, 0, 22, 18), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (92, 18, 22, 18), QIcon::Active, QIcon::Off);
|
||||
m_icons[BUTTON_MW_NEXT] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy (114, 0, 22, 16), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (114, 16, 22, 16), QIcon::Active, QIcon::Off);
|
||||
m_icons[BUTTON_MW_EJECT] = icon;
|
||||
|
||||
delete img;
|
||||
}
|
||||
else
|
||||
|
@ -365,30 +442,34 @@ Skin::BuildToggleButtons (void)
|
|||
|
||||
if(img)
|
||||
{
|
||||
m_items[REPEAT_ON_0] = img->copy(0, 30, 28, 15);
|
||||
m_items[REPEAT_ON_1] = img->copy(0, 45, 28, 15);
|
||||
|
||||
m_items[REPEAT_OFF_0] = img->copy(0, 0, 28, 15);
|
||||
m_items[REPEAT_OFF_1] = img->copy(0, 15, 28, 15);
|
||||
|
||||
m_items[SHUFFLE_ON_0] = img->copy(28, 30, 46, 15);
|
||||
m_items[SHUFFLE_ON_1] = img->copy(28, 45, 46, 15);
|
||||
|
||||
m_items[SHUFFLE_OFF_0] = img->copy(28, 0, 46, 15);
|
||||
m_items[SHUFFLE_OFF_1] = img->copy(28, 15, 46, 15);
|
||||
|
||||
m_items[EQ_ON_0] = img->copy( 0, 73, 23, 12);
|
||||
m_items[EQ_ON_1] = img->copy(46, 73, 23, 12);
|
||||
|
||||
m_items[EQ_OFF_0] = img->copy( 0, 61, 23, 12);
|
||||
m_items[EQ_OFF_1] = img->copy(46, 61, 23, 12);
|
||||
|
||||
m_items[PLS_ON_0] = img->copy(23, 73, 23, 12);
|
||||
m_items[PLS_ON_1] = img->copy(69, 73, 23, 12);
|
||||
|
||||
m_items[PLS_OFF_0] = img->copy(23, 61, 23, 12);
|
||||
m_items[PLS_OFF_1] = img->copy(69, 61, 23, 12);
|
||||
|
||||
QIcon icon;
|
||||
icon.addPixmap (img->copy ( 0, 61, 23, 12), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (46, 61, 23, 12), QIcon::Active, QIcon::Off);
|
||||
icon.addPixmap (img->copy ( 0, 73, 23, 12), QIcon::Normal, QIcon::On);
|
||||
icon.addPixmap (img->copy (46, 73, 23, 12), QIcon::Active, QIcon::On);
|
||||
m_icons[BUTTON_MW_EQ] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy (23, 61, 23, 12), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (69, 61, 23, 12), QIcon::Active, QIcon::Off);
|
||||
icon.addPixmap (img->copy (23, 73, 23, 12), QIcon::Normal, QIcon::On);
|
||||
icon.addPixmap (img->copy (69, 73, 23, 12), QIcon::Active, QIcon::On);
|
||||
m_icons[BUTTON_MW_PLS] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy (28, 0, 46, 15), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (28, 15, 46, 15), QIcon::Active, QIcon::Off);
|
||||
icon.addPixmap (img->copy (28, 30, 46, 15), QIcon::Normal, QIcon::On);
|
||||
icon.addPixmap (img->copy (28, 45, 46, 15), QIcon::Active, QIcon::On);
|
||||
m_icons[BUTTON_MW_SHUFFLE] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy (0, 0, 28, 15), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (0, 15, 28, 15), QIcon::Active, QIcon::Off);
|
||||
icon.addPixmap (img->copy (0, 30, 28, 15), QIcon::Normal, QIcon::On);
|
||||
icon.addPixmap (img->copy (0, 45, 28, 15), QIcon::Active, QIcon::On);
|
||||
m_icons[BUTTON_MW_REPEAT] = icon;
|
||||
|
||||
delete img;
|
||||
}
|
||||
else
|
||||
|
@ -403,21 +484,31 @@ Skin::BuildTitleBar (void)
|
|||
|
||||
if(img)
|
||||
{
|
||||
m_items[MENUBUTTON_0] = img->copy(0, 0, 9, 9);
|
||||
m_items[MENUBUTTON_1] = img->copy(0, 9, 9, 9);
|
||||
|
||||
m_items[MINIMIZE_0] = img->copy(9, 0, 9, 9);
|
||||
m_items[MINIMIZE_1] = img->copy(9, 9, 9, 9);
|
||||
|
||||
m_items[CLOSE_0] = img->copy(18, 0, 9, 9);
|
||||
m_items[CLOSE_1] = img->copy(18, 9, 9 ,9);
|
||||
|
||||
m_items[SHADE_1_0] = img->copy(0, 18, 9, 9);
|
||||
m_items[SHADE_1_1] = img->copy(9, 18, 9, 9);
|
||||
|
||||
m_items[SHADE_2_0] = img->copy(0, 27, 9, 9);
|
||||
m_items[SHADE_2_1] = img->copy(9, 27, 9, 9);
|
||||
|
||||
QIcon icon;
|
||||
icon.addPixmap (img->copy (0, 0, 9, 9), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (0, 9, 9, 9), QIcon::Active, QIcon::Off);
|
||||
m_icons[BUTTON_MW_MENU] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy (9, 0, 9, 9), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (9, 9, 9, 9), QIcon::Active, QIcon::Off);
|
||||
m_icons[BUTTON_MW_MINIMIZE] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy (18, 0, 9, 9), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (18, 9, 9, 9), QIcon::Active, QIcon::Off);
|
||||
m_icons[BUTTON_MW_CLOSE] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy (0, 18, 9, 9), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (9, 18, 9, 9), QIcon::Active, QIcon::Off);
|
||||
m_icons[BUTTON_MW_SHADE] = icon;
|
||||
|
||||
icon = QIcon ();
|
||||
icon.addPixmap (img->copy (0, 27, 9, 9), QIcon::Normal, QIcon::Off);
|
||||
icon.addPixmap (img->copy (9, 27, 9, 9), QIcon::Active, QIcon::Off);
|
||||
m_icons[BUTTON_MW_SHADED_SHADE] = icon;
|
||||
|
||||
m_items[TITLEBAR_0] = img->copy(27, 0, 275, 14);
|
||||
m_items[TITLEBAR_1] = img->copy(27, 15, 275, 14);
|
||||
|
||||
|
|
103
src/Skin.h
103
src/Skin.h
|
@ -16,14 +16,19 @@
|
|||
#ifndef __SKIN_H__
|
||||
#define __SKIN_H__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QWidget>
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
|
||||
#include <QSize>
|
||||
#include <QPoint>
|
||||
#include <QIcon>
|
||||
#include <QPixmap>
|
||||
|
||||
class QDir;
|
||||
|
||||
//class Skin : public QWidget
|
||||
typedef QList<QPixmap> QPixmapList;
|
||||
|
||||
class Skin : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -33,6 +38,10 @@ class Skin : public QObject
|
|||
void setSkin (const QString& name);
|
||||
static QPixmap getPixmap (const QString&, QDir);
|
||||
|
||||
const QSize getSize (uint item) const { return m_sizes[item]; };
|
||||
const QPoint getPos (uint item) const { return m_positions[item]; };
|
||||
const QIcon getIcon (uint item) const { return m_icons.value(item); };
|
||||
|
||||
const QPixmap getItem (uint part) const { return m_items[part]; }
|
||||
const QPixmap getPls (uint part) const { return m_playlist[part]; }
|
||||
const QPixmap getLetter (uint c) const { return m_letterMap[c]; }
|
||||
|
@ -40,6 +49,31 @@ class Skin : public QObject
|
|||
uint getNumberSize () { return m_numbers.size(); }
|
||||
const QByteArray getPLeditValue (QByteArray c) const { return m_pledit_txt[c]; }
|
||||
|
||||
enum Buttons {
|
||||
/* Mainwindow buttons */
|
||||
BUTTON_MW_MENU,
|
||||
BUTTON_MW_MINIMIZE,
|
||||
BUTTON_MW_CLOSE,
|
||||
BUTTON_MW_SHADE,
|
||||
BUTTON_MW_PREV,
|
||||
BUTTON_MW_PLAY,
|
||||
BUTTON_MW_PAUSE,
|
||||
BUTTON_MW_STOP,
|
||||
BUTTON_MW_NEXT,
|
||||
BUTTON_MW_EJECT,
|
||||
BUTTON_MW_EQ,
|
||||
BUTTON_MW_PLS,
|
||||
BUTTON_MW_SHUFFLE,
|
||||
BUTTON_MW_REPEAT,
|
||||
/* Mainwindow buttons shaded*/
|
||||
BUTTON_MW_SHADED_SHADE,
|
||||
/* Equalizer buttons */
|
||||
BUTTON_EQ_ACTIVE,
|
||||
BUTTON_EQ_AUTO,
|
||||
BUTTON_EQ_PRESET
|
||||
/* Playlist buttons */
|
||||
};
|
||||
|
||||
enum Part {
|
||||
NONE,
|
||||
MAIN_WINDOW,
|
||||
|
@ -49,16 +83,6 @@ class Skin : public QObject
|
|||
MONO_1,
|
||||
STEREO_0,
|
||||
STEREO_1,
|
||||
MENUBUTTON_0,
|
||||
MENUBUTTON_1,
|
||||
MINIMIZE_0,
|
||||
MINIMIZE_1,
|
||||
CLOSE_0,
|
||||
CLOSE_1,
|
||||
SHADE_1_0,
|
||||
SHADE_1_1,
|
||||
SHADE_2_0,
|
||||
SHADE_2_1,
|
||||
TITLEBAR_0,
|
||||
TITLEBAR_1,
|
||||
STATUSBAR_0,
|
||||
|
@ -66,34 +90,6 @@ class Skin : public QObject
|
|||
SEEKBAR,
|
||||
SEEKBAR_POS_0,
|
||||
SEEKBAR_POS_1,
|
||||
REPEAT_ON_0,
|
||||
REPEAT_ON_1,
|
||||
REPEAT_OFF_0,
|
||||
REPEAT_OFF_1,
|
||||
SHUFFLE_ON_0,
|
||||
SHUFFLE_ON_1,
|
||||
SHUFFLE_OFF_0,
|
||||
SHUFFLE_OFF_1,
|
||||
EQ_ON_0,
|
||||
EQ_ON_1,
|
||||
EQ_OFF_0,
|
||||
EQ_OFF_1,
|
||||
PLS_ON_0,
|
||||
PLS_ON_1,
|
||||
PLS_OFF_0,
|
||||
PLS_OFF_1,
|
||||
BTN_PREV_0,
|
||||
BTN_PREV_1,
|
||||
BTN_PLAY_0,
|
||||
BTN_PLAY_1,
|
||||
BTN_PAUSE_0,
|
||||
BTN_PAUSE_1,
|
||||
BTN_STOP_0,
|
||||
BTN_STOP_1,
|
||||
BTN_NEXT_0,
|
||||
BTN_NEXT_1,
|
||||
BTN_EJECT_0,
|
||||
BTN_EJECT_1,
|
||||
TEXTBG,
|
||||
PIC_PLAY,
|
||||
PIC_PAUSE,
|
||||
|
@ -139,16 +135,6 @@ class Skin : public QObject
|
|||
CLUTTER_D,
|
||||
CLUTTER_V,
|
||||
EQ_WIN_BG,
|
||||
EQ_WIN_ON_0,
|
||||
EQ_WIN_ON_1,
|
||||
EQ_WIN_OFF_0,
|
||||
EQ_WIN_OFF_1,
|
||||
EQ_WIN_AUTO_ON_0,
|
||||
EQ_WIN_AUTO_ON_1,
|
||||
EQ_WIN_AUTO_OFF_0,
|
||||
EQ_WIN_AUTO_OFF_1,
|
||||
EQ_WIN_PRESET_0,
|
||||
EQ_WIN_PRESET_1,
|
||||
EQ_WIN_GRAPH_BG,
|
||||
EQ_WIN_BAR_POS_0,
|
||||
EQ_WIN_BAR_POS_1,
|
||||
|
@ -305,9 +291,12 @@ class Skin : public QObject
|
|||
PLS_LST_OPN_1
|
||||
};
|
||||
private:
|
||||
Skin() {};
|
||||
Skin();
|
||||
static Skin *singleton;
|
||||
|
||||
void setSizes ();
|
||||
void setPositions ();
|
||||
|
||||
QPixmap *getPixmap (const QString& file);
|
||||
void BuildLetterMap (void);
|
||||
void BuildButtons (void);
|
||||
|
@ -324,6 +313,12 @@ class Skin : public QObject
|
|||
QString m_skinname;
|
||||
QString m_path;
|
||||
|
||||
QList<QPoint> m_positions;
|
||||
QList<QSize> m_sizes;
|
||||
|
||||
QMap<uint, QIcon> m_icons;
|
||||
|
||||
|
||||
QMap<uint, QPixmap> m_items;
|
||||
QMap<uint, QPixmap> m_letterMap;
|
||||
QMap<uint, QPixmap> m_volume_bar;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "SkinChooser.h"
|
||||
// #include "MedialibWindow.h"
|
||||
#include "settingsdialog.h"
|
||||
#include "Button.h"
|
||||
#include "pixmapbutton.h"
|
||||
#include "BrowseDialog.h"
|
||||
#include "Skin.h"
|
||||
|
||||
|
@ -31,25 +31,35 @@ TitleBar::TitleBar (QWidget *parent, bool shaded) : PixWidget (parent)
|
|||
{
|
||||
MainWindow *mw = dynamic_cast<MainWindow*>(window ());
|
||||
m_shaded = shaded;
|
||||
|
||||
setMinimumSize (275, 14);
|
||||
setMaximumSize (275, 14);
|
||||
Skin *skin = Skin::getInstance ();
|
||||
|
||||
m_menubtn = new Button (this, Skin::MENUBUTTON_0, Skin::MENUBUTTON_1);
|
||||
setFixedSize (275, 14);
|
||||
|
||||
m_menubtn = new PixmapButton (this);
|
||||
m_menubtn->resize (skin->getSize (Skin::BUTTON_MW_MENU));
|
||||
m_menubtn->move (skin->getPos (Skin::BUTTON_MW_MENU));
|
||||
connect (m_menubtn, SIGNAL (clicked ()), this, SLOT (showMenu ()));
|
||||
m_menubtn->move(6, 3);
|
||||
|
||||
m_minimize = new Button (this, Skin::MINIMIZE_0, Skin::MINIMIZE_1);
|
||||
m_minimize = new PixmapButton (this);
|
||||
m_minimize->resize (skin->getSize (Skin::BUTTON_MW_MINIMIZE));
|
||||
m_minimize->move (skin->getPos (Skin::BUTTON_MW_MINIMIZE));
|
||||
connect (m_minimize, SIGNAL (clicked ()), mw, SLOT (showMinimized ()));
|
||||
m_minimize->move(244, 3);
|
||||
|
||||
m_shadebtn = new Button (this, Skin::SHADE_1_0, Skin::SHADE_1_1);
|
||||
if (shaded) {
|
||||
m_shadebtn = new PixmapButton (this);
|
||||
m_shadebtn->resize (skin->getSize (Skin::BUTTON_MW_SHADED_SHADE));
|
||||
m_shadebtn->move (skin->getPos (Skin::BUTTON_MW_SHADED_SHADE));
|
||||
} else {
|
||||
m_shadebtn = new PixmapButton (this);
|
||||
m_shadebtn->resize (skin->getSize (Skin::BUTTON_MW_SHADE));
|
||||
m_shadebtn->move (skin->getPos (Skin::BUTTON_MW_SHADE));
|
||||
}
|
||||
connect (m_shadebtn, SIGNAL (clicked()), mw, SLOT (switchDisplay ()));
|
||||
m_shadebtn->move(254, 3);
|
||||
|
||||
m_closebtn = new Button (this, Skin::CLOSE_0, Skin::CLOSE_1);
|
||||
m_closebtn = new PixmapButton (this);
|
||||
m_closebtn->resize (skin->getSize (Skin::BUTTON_MW_CLOSE));
|
||||
m_closebtn->move (skin->getPos (Skin::BUTTON_MW_CLOSE));
|
||||
connect (m_closebtn, SIGNAL (clicked()), qApp, SLOT (quit ()));
|
||||
m_closebtn->move(264, 3);
|
||||
|
||||
}
|
||||
|
||||
|
@ -139,6 +149,15 @@ TitleBar::setPixmaps (Skin *skin)
|
|||
m_pixmap = m_pixmap_inactive;
|
||||
}
|
||||
|
||||
m_menubtn->setIcon (skin->getIcon (Skin::BUTTON_MW_MENU));
|
||||
m_minimize->setIcon (skin->getIcon (Skin::BUTTON_MW_MINIMIZE));
|
||||
if (m_shaded) {
|
||||
m_shadebtn->setIcon (skin->getIcon (Skin::BUTTON_MW_SHADED_SHADE));
|
||||
} else {
|
||||
m_shadebtn->setIcon (skin->getIcon (Skin::BUTTON_MW_SHADE));
|
||||
}
|
||||
m_closebtn->setIcon (skin->getIcon (Skin::BUTTON_MW_CLOSE));
|
||||
|
||||
update ();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class TitleBar;
|
|||
|
||||
#include "PixWidget.h"
|
||||
|
||||
class Button;
|
||||
class PixmapButton;
|
||||
class Skin;
|
||||
|
||||
class TitleBar : public PixWidget
|
||||
|
@ -46,10 +46,10 @@ class TitleBar : public PixWidget
|
|||
QPixmap m_pixmap_active;
|
||||
QPixmap m_pixmap_inactive;
|
||||
|
||||
Button *m_shadebtn;
|
||||
Button *m_menubtn;
|
||||
Button *m_closebtn;
|
||||
Button *m_minimize;
|
||||
PixmapButton *m_shadebtn;
|
||||
PixmapButton *m_menubtn;
|
||||
PixmapButton *m_closebtn;
|
||||
PixmapButton *m_minimize;
|
||||
|
||||
bool m_shaded;
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "equalizerwidget.h"
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "Button.h"
|
||||
#include "pixmapbutton.h"
|
||||
#include "Skin.h"
|
||||
#include "VolumeSlider.h"
|
||||
|
||||
|
@ -58,24 +58,27 @@ EqualizerWidget::EqualizerWidget (QWidget *parent) : QWidget (parent)
|
|||
connect (skin, SIGNAL(skinChanged(Skin *)),
|
||||
this, SLOT(setPixmaps(Skin *)));
|
||||
|
||||
m_enable = new ToggleButton(this, Skin::EQ_WIN_ON_0, Skin::EQ_WIN_ON_1,
|
||||
Skin::EQ_WIN_OFF_0, Skin::EQ_WIN_OFF_1);
|
||||
m_enable->move(14, 18);
|
||||
m_enable = new PixmapButton (this);
|
||||
m_enable->setCheckable (true);
|
||||
m_enable->resize (skin->getSize (Skin::BUTTON_EQ_ACTIVE));
|
||||
m_enable->move (skin->getPos (Skin::BUTTON_EQ_ACTIVE));
|
||||
// must use signal clicked here, as this button also becomes unchecked if
|
||||
// use_legacy is deactivated
|
||||
connect(m_enable, SIGNAL (clicked (bool)),
|
||||
this, SLOT (setEqualizerEnabled (bool)));
|
||||
|
||||
|
||||
m_auto = new ToggleButton(this, Skin::EQ_WIN_AUTO_ON_0, Skin::EQ_WIN_AUTO_ON_1,
|
||||
Skin::EQ_WIN_AUTO_OFF_0, Skin::EQ_WIN_AUTO_OFF_1);
|
||||
m_auto->move(39, 18);
|
||||
m_auto = new PixmapButton (this);
|
||||
m_auto->setCheckable (true);
|
||||
m_auto->resize (skin->getSize (Skin::BUTTON_EQ_AUTO));
|
||||
m_auto->move (skin->getPos (Skin::BUTTON_EQ_AUTO));
|
||||
m_auto->setEnabled(false); // FIXME: needs to be implemented
|
||||
|
||||
connect(m_auto, SIGNAL(clicked()), parent, SLOT(setEnabled()));
|
||||
|
||||
m_preset = new Button(this, Skin::EQ_WIN_PRESET_0, Skin::EQ_WIN_PRESET_1);
|
||||
m_preset->move(217, 18);
|
||||
m_preset = new PixmapButton (this);
|
||||
m_preset->resize (skin->getSize (Skin::BUTTON_EQ_PRESET));
|
||||
m_preset->move (skin->getPos (Skin::BUTTON_EQ_PRESET));
|
||||
m_preset->setEnabled(false); // FIXME: needs to be implemented
|
||||
|
||||
connect(m_preset, SIGNAL(clicked()), parent, SLOT(setEnabled()));
|
||||
|
@ -138,6 +141,10 @@ EqualizerWidget::setPixmaps (Skin *skin)
|
|||
setMinimumSize (m_pixmap.size ());
|
||||
setMaximumSize (m_pixmap.size ());
|
||||
|
||||
m_enable->setIcon (skin->getIcon (Skin::BUTTON_EQ_ACTIVE));
|
||||
m_auto->setIcon (skin->getIcon (Skin::BUTTON_EQ_AUTO));
|
||||
m_preset->setIcon (skin->getIcon (Skin::BUTTON_EQ_PRESET));
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
|
@ -178,7 +185,7 @@ EqualizerWidget::serverConfigChanged (QString key, QString value)
|
|||
}
|
||||
}
|
||||
if (key == "equalizer.preamp") {
|
||||
// FIXME: value can be of type floas
|
||||
// FIXME: value can be of type float
|
||||
m_preamp->setValue (value.toInt ());
|
||||
}
|
||||
if (key.startsWith ("equalizer.legacy")) {
|
||||
|
|
|
@ -25,8 +25,7 @@ class QPaintEvent;
|
|||
#include "VolumeSlider.h"
|
||||
class XConfig;
|
||||
class Skin;
|
||||
class Button;
|
||||
class ToggleButton;
|
||||
class PixmapButton;
|
||||
|
||||
//#include <iostream>
|
||||
|
||||
|
@ -69,9 +68,9 @@ class EqualizerWidget : public QWidget
|
|||
XConfig *m_xconfig;
|
||||
QPixmap m_pixmap;
|
||||
QPixmap m_graph;
|
||||
ToggleButton *m_enable;
|
||||
ToggleButton *m_auto;
|
||||
Button *m_preset;
|
||||
PixmapButton *m_enable;
|
||||
PixmapButton *m_auto;
|
||||
PixmapButton *m_preset;
|
||||
Slider *m_preamp;
|
||||
EqualizerSlider *m_bands[10];
|
||||
};
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
#include "maindisplay.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include "pixmapbutton.h"
|
||||
#include "TitleBar.h"
|
||||
#include "Button.h"
|
||||
#include "TextBar.h"
|
||||
#include "NumberDisplay.h"
|
||||
#include "TimeDisplay.h"
|
||||
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include <QFileDialog>
|
||||
#include <QSettings>
|
||||
#include <QDebug>
|
||||
|
||||
MainDisplay::MainDisplay (QWidget *parent) : SkinDisplay(parent)
|
||||
{
|
||||
|
@ -129,6 +130,18 @@ MainDisplay::setPixmaps (Skin *skin)
|
|||
setPalette(palette);
|
||||
|
||||
setFixedSize(QSize(275, 116));
|
||||
|
||||
/* update buttons*/
|
||||
m_prev->setIcon (skin->getIcon (Skin::BUTTON_MW_PREV));
|
||||
m_play->setIcon (skin->getIcon (Skin::BUTTON_MW_PLAY));
|
||||
m_pause->setIcon (skin->getIcon (Skin::BUTTON_MW_PAUSE));
|
||||
m_stop->setIcon (skin->getIcon (Skin::BUTTON_MW_STOP));
|
||||
m_next->setIcon (skin->getIcon (Skin::BUTTON_MW_NEXT));
|
||||
m_eject->setIcon (skin->getIcon (Skin::BUTTON_MW_EJECT));
|
||||
m_eq->setIcon (skin->getIcon (Skin::BUTTON_MW_EQ));
|
||||
m_pls->setIcon (skin->getIcon (Skin::BUTTON_MW_PLS));
|
||||
m_shuffle->setIcon (skin->getIcon (Skin::BUTTON_MW_SHUFFLE));
|
||||
m_repeat->setIcon (skin->getIcon (Skin::BUTTON_MW_REPEAT));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -211,36 +224,40 @@ void
|
|||
MainDisplay::SetupToggleButtons (void)
|
||||
{
|
||||
QSettings s;
|
||||
Skin *skin = Skin::getInstance ();
|
||||
|
||||
|
||||
m_eq = new ToggleButton (this, Skin::EQ_ON_0, Skin::EQ_ON_1,
|
||||
Skin::EQ_OFF_0, Skin::EQ_OFF_1);
|
||||
m_eq->move(219, 58);
|
||||
m_eq = new PixmapButton (this);
|
||||
m_eq->setCheckable (true);
|
||||
m_eq->resize (skin->getSize (Skin::BUTTON_MW_EQ));
|
||||
m_eq->move (skin->getPos (Skin::BUTTON_MW_EQ));
|
||||
m_eq->setChecked (m_mw->getEQ ()->isVisible ());
|
||||
connect (m_eq, SIGNAL (toggled (bool)),
|
||||
m_mw->getEQ (), SLOT (setVisible (bool)));
|
||||
connect (m_mw->getEQ (), SIGNAL (visibilityChanged (bool)),
|
||||
m_eq, SLOT (setChecked (bool)));
|
||||
|
||||
|
||||
m_pls = new ToggleButton (this, Skin::PLS_ON_0, Skin::PLS_ON_1,
|
||||
Skin::PLS_OFF_0, Skin::PLS_OFF_1);
|
||||
m_pls->move(242, 58);
|
||||
m_pls = new PixmapButton (this);
|
||||
m_pls->setCheckable (true);
|
||||
m_pls->resize (skin->getSize (Skin::BUTTON_MW_PLS));
|
||||
m_pls->move (skin->getPos (Skin::BUTTON_MW_PLS));
|
||||
m_pls->setChecked (m_mw->getPL ()->isVisible ());
|
||||
connect (m_pls, SIGNAL (toggled (bool)),
|
||||
m_mw->getPL (), SLOT (setVisible (bool)));
|
||||
connect (m_mw->getPL (), SIGNAL (visibilityChanged (bool)),
|
||||
m_pls, SLOT (setChecked (bool)));
|
||||
|
||||
// FIXME: Shuffle not yet implemented
|
||||
// Shuffled play should be done serverside through a service client
|
||||
m_shuffle = new PixmapButton (this);
|
||||
m_shuffle->setCheckable (true);
|
||||
m_shuffle->resize (skin->getSize (Skin::BUTTON_MW_SHUFFLE));
|
||||
m_shuffle->move (skin->getPos (Skin::BUTTON_MW_SHUFFLE));
|
||||
m_shuffle->setEnabled(false);
|
||||
|
||||
m_shuffle = new ToggleButton (this, Skin::SHUFFLE_ON_0, Skin::SHUFFLE_ON_1,
|
||||
Skin::SHUFFLE_OFF_0, Skin::SHUFFLE_OFF_1);
|
||||
m_shuffle->move(164, 89);
|
||||
m_shuffle->setEnabled(false); // FIXME: Disabled button for now, not yet implemented
|
||||
|
||||
m_repeat = new ToggleButton (this, Skin::REPEAT_ON_0, Skin::REPEAT_ON_1,
|
||||
Skin::REPEAT_OFF_0, Skin::REPEAT_OFF_1);
|
||||
m_repeat->move(210, 89);
|
||||
m_repeat = new PixmapButton (this);
|
||||
m_repeat->setCheckable (true);
|
||||
m_repeat->resize (skin->getSize (Skin::BUTTON_MW_REPEAT));
|
||||
m_repeat->move (skin->getPos (Skin::BUTTON_MW_REPEAT));
|
||||
connect (m_repeat, SIGNAL (clicked (bool)),
|
||||
this, SLOT (setRepeatAllEnabled (bool)));
|
||||
}
|
||||
|
@ -256,35 +273,41 @@ void
|
|||
MainDisplay::SetupPushButtons (void)
|
||||
{
|
||||
XMMSHandler &client = XMMSHandler::getInstance ();
|
||||
Skin *skin = Skin::getInstance ();
|
||||
|
||||
/* Normal buttons */
|
||||
m_prev = new Button (this, Skin::BTN_PREV_0, Skin::BTN_PREV_1);
|
||||
m_prev->move(16, 88);
|
||||
m_prev = new PixmapButton (this);
|
||||
m_prev->resize (skin->getSize (Skin::BUTTON_MW_PREV));
|
||||
m_prev->move (skin->getPos (Skin::BUTTON_MW_PREV));
|
||||
connect (m_prev, SIGNAL(clicked()), client.xplayback (), SLOT(prev ()));
|
||||
|
||||
m_play = new Button (this, Skin::BTN_PLAY_0, Skin::BTN_PLAY_1);
|
||||
m_play->move(39, 88);
|
||||
m_play = new PixmapButton (this);
|
||||
m_play->resize (skin->getSize (Skin::BUTTON_MW_PLAY));
|
||||
m_play->move (skin->getPos (Skin::BUTTON_MW_PLAY));
|
||||
connect (m_play, SIGNAL(clicked()), client.xplayback (), SLOT(play ()));
|
||||
|
||||
m_pause = new Button (this, Skin::BTN_PAUSE_0, Skin::BTN_PAUSE_1);
|
||||
m_pause->move(62, 88);
|
||||
m_pause = new PixmapButton (this);
|
||||
m_pause->resize (skin->getSize (Skin::BUTTON_MW_PAUSE));
|
||||
m_pause->move (skin->getPos (Skin::BUTTON_MW_PAUSE));
|
||||
connect (m_pause, SIGNAL(clicked()), client.xplayback (), SLOT(pause ()));
|
||||
|
||||
m_stop = new Button (this, Skin::BTN_STOP_0, Skin::BTN_STOP_1);
|
||||
m_stop->move(85, 88);
|
||||
m_stop = new PixmapButton (this);
|
||||
m_stop->resize (skin->getSize (Skin::BUTTON_MW_STOP));
|
||||
m_stop->move (skin->getPos (Skin::BUTTON_MW_STOP));
|
||||
connect (m_stop, SIGNAL(clicked()), client.xplayback (), SLOT(stop ()));
|
||||
|
||||
m_next = new Button (this, Skin::BTN_NEXT_0, Skin::BTN_NEXT_1);
|
||||
m_next->move(108, 88);
|
||||
m_next = new PixmapButton (this);
|
||||
m_next->resize (skin->getSize (Skin::BUTTON_MW_NEXT));
|
||||
m_next->move (skin->getPos (Skin::BUTTON_MW_NEXT));
|
||||
connect (m_next, SIGNAL(clicked()), client.xplayback (), SLOT(next ()));
|
||||
|
||||
m_eject = new Button (this, Skin::BTN_EJECT_0, Skin::BTN_EJECT_1);
|
||||
m_eject->move(136, 89);
|
||||
m_eject = new PixmapButton (this);
|
||||
m_eject->resize (skin->getSize (Skin::BUTTON_MW_EJECT));
|
||||
m_eject->move (skin->getPos (Skin::BUTTON_MW_EJECT));
|
||||
connect (m_eject, SIGNAL(clicked()), this, SLOT(fileOpen()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Methods for interaction with the server configuration
|
||||
*/
|
||||
|
|
|
@ -32,8 +32,7 @@ class MainDisplay;
|
|||
|
||||
#include "Display.h"
|
||||
|
||||
class Button;
|
||||
class ToggleButton;
|
||||
class PixmapButton;
|
||||
class TextScroller;
|
||||
class TimeDisplay;
|
||||
class SmallNumberDisplay;
|
||||
|
@ -83,17 +82,17 @@ class MainDisplay : public SkinDisplay
|
|||
void SetupPushButtons (void);
|
||||
void SetupToggleButtons (void);
|
||||
|
||||
Button *m_prev;
|
||||
Button *m_play;
|
||||
Button *m_pause;
|
||||
Button *m_stop;
|
||||
Button *m_next;
|
||||
Button *m_eject;
|
||||
PixmapButton *m_prev;
|
||||
PixmapButton *m_play;
|
||||
PixmapButton *m_pause;
|
||||
PixmapButton *m_stop;
|
||||
PixmapButton *m_next;
|
||||
PixmapButton *m_eject;
|
||||
|
||||
ToggleButton *m_pls;
|
||||
ToggleButton *m_eq;
|
||||
ToggleButton *m_shuffle;
|
||||
ToggleButton *m_repeat;
|
||||
PixmapButton *m_pls;
|
||||
PixmapButton *m_eq;
|
||||
PixmapButton *m_shuffle;
|
||||
PixmapButton *m_repeat;
|
||||
|
||||
MainWindow *m_mw;
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "maindisplay.h"
|
||||
#include "shadeddisplay.h"
|
||||
#include "equalizerwindow.h"
|
||||
#include "Button.h"
|
||||
#include "Skin.h"
|
||||
|
||||
#include <QSettings>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "shadeddisplay.h"
|
||||
#include "TitleBar.h"
|
||||
#include "Button.h"
|
||||
#include "pixmapbutton.h"
|
||||
|
||||
#include "SmallNumberDisplay.h"
|
||||
#include "TextBar.h"
|
||||
|
@ -46,32 +46,32 @@ ShadedDisplay::ShadedDisplay (QWidget *parent) : SkinDisplay (parent)
|
|||
m_title = new TextScroller (this, 39, 7, "shaded");
|
||||
m_title->move (79, 4);
|
||||
|
||||
m_prev = new Button (this);
|
||||
m_prev = new PixmapButton (this);
|
||||
m_prev->move(169, 4);
|
||||
m_prev->resize (8, 7);
|
||||
connect (m_prev, SIGNAL(clicked()), client.xplayback (), SLOT(prev ()));
|
||||
|
||||
m_play = new Button (this);
|
||||
m_play = new PixmapButton (this);
|
||||
m_play->move(177, 4);
|
||||
m_play->resize (10, 7);
|
||||
connect (m_play, SIGNAL(clicked()), client.xplayback (), SLOT(play ()));
|
||||
|
||||
m_pause = new Button (this);
|
||||
m_pause = new PixmapButton (this);
|
||||
m_pause->move(187, 4);
|
||||
m_pause->resize (10, 7);
|
||||
connect (m_pause, SIGNAL(clicked()), client.xplayback (), SLOT(pause ()));
|
||||
|
||||
m_stop = new Button (this);
|
||||
m_stop = new PixmapButton (this);
|
||||
m_stop->move(197, 4);
|
||||
m_stop->resize (9, 7);
|
||||
connect (m_stop, SIGNAL(clicked()), client.xplayback (), SLOT(stop ()));
|
||||
|
||||
m_next = new Button (this);
|
||||
m_next = new PixmapButton (this);
|
||||
m_next->move(206, 4);
|
||||
m_next->resize (8, 7);
|
||||
connect (m_next, SIGNAL(clicked()), client.xplayback (), SLOT(next ()));
|
||||
|
||||
m_eject = new Button (this);
|
||||
m_eject = new PixmapButton (this);
|
||||
m_eject->move(216, 4);
|
||||
m_eject->resize (9, 7);
|
||||
connect (m_eject, SIGNAL(clicked()), this, SLOT(fileOpen()));
|
||||
|
|
|
@ -22,7 +22,7 @@ class ShadedDisplay;
|
|||
#include "Display.h"
|
||||
|
||||
class MainWindow;
|
||||
class Button;
|
||||
class PixmapButton;
|
||||
class SmallNumberDisplay;
|
||||
class TextScroller;
|
||||
|
||||
|
@ -38,12 +38,12 @@ class ShadedDisplay : public SkinDisplay
|
|||
TextScroller *m_title;
|
||||
|
||||
private:
|
||||
Button *m_prev;
|
||||
Button *m_play;
|
||||
Button *m_pause;
|
||||
Button *m_stop;
|
||||
Button *m_next;
|
||||
Button *m_eject;
|
||||
PixmapButton *m_prev;
|
||||
PixmapButton *m_play;
|
||||
PixmapButton *m_pause;
|
||||
PixmapButton *m_stop;
|
||||
PixmapButton *m_next;
|
||||
PixmapButton *m_eject;
|
||||
|
||||
public slots:
|
||||
void setStatus (Xmms::Playback::Status status);
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
class PlaylistWidget;
|
||||
class PlaylistScroller;
|
||||
|
||||
#include "Button.h"
|
||||
|
||||
class Skin;
|
||||
class PlaylistView;
|
||||
class PlaylistMenu;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue