diff --git a/build/depends.py b/build/depends.py
index 747bb99059ab..751757956287 100644
--- a/build/depends.py
+++ b/build/depends.py
@@ -765,6 +765,7 @@ def sources(self, build):
"widget/wwidget.cpp",
"widget/wwidgetgroup.cpp",
"widget/wwidgetstack.cpp",
+ "widget/wlibrarystack.cpp",
"widget/wsizeawarestack.cpp",
"widget/wlabel.cpp",
"widget/wtracktext.cpp",
diff --git a/res/skins/Experiment/button_1state.xml b/res/skins/Experiment/button_1state.xml
new file mode 100644
index 000000000000..ff50f993ff14
--- /dev/null
+++ b/res/skins/Experiment/button_1state.xml
@@ -0,0 +1,16 @@
+
+
+
+ 1
+ 40,20
+ 100,20
+ me,me
+
+ 0
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/skins/Experiment/pressed.svg b/res/skins/Experiment/pressed.svg
new file mode 100644
index 000000000000..3a2369801071
--- /dev/null
+++ b/res/skins/Experiment/pressed.svg
@@ -0,0 +1,63 @@
+
+
+
+
diff --git a/res/skins/Experiment/skin.xml b/res/skins/Experiment/skin.xml
new file mode 100644
index 000000000000..c22682808d12
--- /dev/null
+++ b/res/skins/Experiment/skin.xml
@@ -0,0 +1,160 @@
+
+
+
+ Experiment
+ jmigual
+ 0.0
+ An experiment
+ en
+ Creative Commons Attribution, Share-Alike 3.0 Unported
+
+
+ Mixxx
+
+ 1280,700
+ me,me
+ vertical
+
+
+
+
+
+ horizontal
+ 40,20
+ me,me
+ 2,8
+
+
+
+ vertical
+
+
+ horizontal
+ min,min
+
+
+
+ Previous
+ [Experiment],left_previous
+
+
+
+ Next
+ [Experiment],left_next
+
+
+
+ Config
+ [Experiment],left_config
+
+
+
+
+
+ [Experiment],left_previous
+ [Experiment],left_next
+ [Experiment],left_config
+
+
+
+
+
+
+
+
+
+
+ vertical
+
+
+
+ horizontal
+
+
+
+ Previous
+ [Experiment],right_previous
+
+
+
+ Next
+ [Experiment],right_next
+
+
+
+ Config
+ [Experiment],right_config
+
+
+
+
+
+ [Experiment],right_previous
+ [Experiment],right_next
+ [Experiment],right_config
+
+
+
+
+
+
+
+
+
+
+
+
+ vertical
+
+
+
+ horizontal
+
+
+
+ Previous
+ [Experiment],right_previous2
+
+
+
+ Next
+ [Experiment],right_next2
+
+
+
+ Config
+ [Experiment],right_config2
+
+
+
+
+
+ [Experiment],right_previous2
+ [Experiment],right_next2
+ [Experiment],right_config2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/skins/Experiment/style.qss b/res/skins/Experiment/style.qss
new file mode 100644
index 000000000000..34144215dad6
--- /dev/null
+++ b/res/skins/Experiment/style.qss
@@ -0,0 +1,199 @@
+/* library table */
+QTableView {
+ color: #d2d2d2;
+ background-color: #1F1F1F;
+ alternate-background-color: #1A1A1A;
+ selection-background-color: #006596;
+ selection-color: #D6D6D6;
+ border: 1px solid #1A1A1A;
+ gridline-color: red;
+}
+
+/* checkbox in library "Played" column */
+QTableView::indicator {
+ width: 12px;
+ height: 12px;
+}
+
+QSplitter:handle {
+ background-color: #622121
+}
+
+/* checkbox in library "Played" column */
+QTableView::indicator {
+ width: 12px;
+ height: 12px;
+}
+
+QTableView::indicator:checked {
+ background: url(skin:/image/style_checkbox_checked.png);
+}
+
+QTableView::indicator:unchecked {
+ background: url(skin:/image/style_checkbox_unchecked.png);
+}
+
+
+/* library header row */
+QHeaderView {
+ color: #d2d2d2;
+ background: #1A1A1A;
+ border-bottom: 1px solid #141414;
+}
+
+QHeaderView::section {
+ height: 18px;
+ font-size: 13px/15px;
+ font-weight: normal;
+ padding: 2px;
+ background: #1A1A1A;
+ border-top: none;
+ border-bottom: 1px solid #141414;
+ border-left: 1px solid #141414;
+ border-right: none;
+}
+
+QHeaderView::section:selected {
+ font-size: 13px/15px;
+ font-weight: bold;
+ padding: 2px;
+ background: #1A1A1A;
+ border-top: none;
+ border-bottom: 1px solid #141414;
+ border-left: 1px solid #141414;
+ border-right: none;
+}
+
+/* Spacing between treeview and preview deck/search bar */
+QTreeView {
+ margin: 4px 0px 0px 0px;
+}
+
+/* sidebar, as well as root items for playlists, crates, and history */
+QTextBrowser, QTreeView {
+ color: #d2d2d2;
+ background-color: #1F1F1F;
+ selection-background-color: #006596;
+ selection-color: #D6D6D6;
+ border: 1px solid #1A1A1A;
+ gridline-color: red;
+ /* Suppresses that selected sidebar item's branch indicator shows wrong color
+ when out of focus, see lp:880588 */
+ show-decoration-selected: 1;
+}
+/* triangle for closed/opened branches in treeview */
+QTreeView::branch:has-children:!has-siblings:closed,
+QTreeView::branch:closed:has-children:has-siblings {
+ border-image: none; image: url(skin:/image/style_branch_closed.png);
+}
+
+QTreeView::branch:open:has-children:!has-siblings,
+QTreeView::branch:open:has-children:has-siblings {
+ border-image: none; image: url(skin:/image/style_branch_open.png);
+}
+
+
+/*******************************************************************************
+ ** Buttons *******************************************************************
+ *******************************************************************************/
+
+WPushButton {
+ color: #D2D2D2;
+ background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,
+ stop: 0 #4B4B4B,
+ stop: 1 #4B4B4B);
+ border: 1px solid #4B4B4B;
+ border-radius: 2px;
+ outline: none;
+}
+
+WPushButton:hover {
+ color: #D2D2D2;
+ background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,
+ stop: 0 #5F5F5F,
+ stop: 1 #5F5F5F);
+ border: 0px solid #5F5F5F;
+}
+
+/*"Pressed" state*/
+WPushButton[value="1"] {
+ /*color: #FDFDFD;*/
+ color: #FDFDFD;
+ background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,
+ stop: 0 #006596,
+ stop: 1 #006596);
+ border: 0px solid #006596;
+}
+
+WPushButton[value="1"]:hover {
+ color: #FDFDFD;
+ background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,
+ stop: 0 #0080bE,
+ stop: 1 #0080BE);
+ border: 0px solid #0080BE;
+}
+
+/*"Enabled" state, e.g. for recording status
+ 0 -- disconnected / off
+ 1 -- connecting / enabling
+ 2 -- connected / enabled
+*/
+WPushButton[value="2"] {
+ color: #FDFDFD;
+ background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,
+ stop: 0 #006596,
+ stop: 1 #006596);
+ border: 0px solid #006596;
+}
+
+WPushButton[value="2"]:hover {
+ color: #FDFDFD;
+ background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,
+ stop: 0 #0080BE,
+ stop: 1 #0080BE);
+ border: 0px solid #0080BE;
+}
+
+WLabel {
+ color: #D2D2D2;
+}
+
+
+/* transition time in Auto DJ tab */
+WLibrary QSpinBox {
+ min-height: 20px;
+ max-height: 20px;
+ min-width: 40px;
+ max-width: 40px;
+}
+
+WLibrary QSpinBox:editable {
+ background: transparent;
+ color:#d2d2d2;
+}
+
+/* Extra declaration for QRadionButton otherwise it shows up with wrong colors in Linux with Gnome */
+WLibrary QLabel, WLibrary QRadioButton {
+ /* same as QTreeview */
+ color: #d2d2d2;
+ margin: 9px 10px 6px 0px;
+}
+
+WLibrary QRadioButton::indicator {
+ margin: 0px 5px 0px 2px;
+ width: 18px;
+ height: 18px;
+}
+
+/* Additional space for the first QRadionButton in the row */
+WLibrary QRadioButton#radioButtonRecentlyAdded {
+ margin: 9px 10px 6px 14px;
+}
+
+WLibrary QRadioButton::indicator:checked {
+ background: url(skin:/icon/ic_radio_button_on_18px.svg);
+}
+
+WLibrary QRadioButton::indicator:unchecked {
+ background: url(skin:/icon/ic_radio_button_off_18px.svg);
+}
diff --git a/res/skins/Experiment/unpressed.svg b/res/skins/Experiment/unpressed.svg
new file mode 100644
index 000000000000..b53b6774cea1
--- /dev/null
+++ b/res/skins/Experiment/unpressed.svg
@@ -0,0 +1,63 @@
+
+
+
+
diff --git a/src/mixxx.cpp b/src/mixxx.cpp
index a7b6c50bd192..4e6503ad4e7b 100644
--- a/src/mixxx.cpp
+++ b/src/mixxx.cpp
@@ -106,7 +106,8 @@ MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args)
m_toolTipsCfg(mixxx::TooltipsPreference::TOOLTIPS_ON),
m_runtime_timer("MixxxMainWindow::runtime"),
m_cmdLineArgs(args),
- m_pTouchShift(nullptr) {
+ m_pTouchShift(nullptr),
+ m_wLibraryViewManager(nullptr) {
m_runtime_timer.start();
Time::start();
@@ -323,6 +324,8 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) {
// Connect signals to the menubar. Should be done before we go fullscreen
// and emit newSkinLoaded.
connectMenuBar();
+
+ m_wLibraryViewManager = new WLibraryViewManager;
// Before creating the first skin we need to create a QGLWidget so that all
// the QGLWidget's we create can use it as a shared QGLContext.
@@ -341,7 +344,8 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) {
m_pControllerManager,
m_pLibrary,
m_pVCManager,
- m_pEffectsManager))) {
+ m_pEffectsManager,
+ m_wLibraryViewManager))) {
reportCriticalErrorAndQuit(
"default skin cannot be loaded see mixxx trace for more information.");
@@ -1066,7 +1070,8 @@ void MixxxMainWindow::rebootMixxxView() {
m_pControllerManager,
m_pLibrary,
m_pVCManager,
- m_pEffectsManager))) {
+ m_pEffectsManager,
+ m_wLibraryViewManager))) {
QMessageBox::critical(this,
tr("Error in skin file"),
diff --git a/src/mixxx.h b/src/mixxx.h
index a1793d56b541..a09403d850dc 100644
--- a/src/mixxx.h
+++ b/src/mixxx.h
@@ -46,6 +46,7 @@ class SkinLoader;
class SoundManager;
class VinylControlManager;
class WMainMenuBar;
+class WLibraryViewManager;
// This Class is the base class for Mixxx. It sets up the main
// window and providing a menubar.
@@ -170,6 +171,9 @@ class MixxxMainWindow : public QMainWindow {
const CmdlineArgs& m_cmdLineArgs;
ControlPushButton* m_pTouchShift;
+
+ // Manager for the Widget elements of the library
+ WLibraryViewManager* m_wLibraryViewManager;
static const int kMicrophoneCount;
static const int kAuxiliaryCount;
diff --git a/src/skin/legacyskinparser.cpp b/src/skin/legacyskinparser.cpp
index 9fabb0cc05e0..c9e01dfecbfc 100644
--- a/src/skin/legacyskinparser.cpp
+++ b/src/skin/legacyskinparser.cpp
@@ -65,6 +65,7 @@
#include "widget/wsearchlineedit.h"
#include "widget/wlibrary.h"
#include "widget/wlibrarysidebar.h"
+#include "widget/wlibrarystack.h"
#include "widget/wskincolor.h"
#include "widget/wpixmapstore.h"
#include "widget/wwidgetstack.h"
@@ -142,6 +143,7 @@ LegacySkinParser::LegacySkinParser()
m_pLibrary(NULL),
m_pVCManager(NULL),
m_pEffectsManager(NULL),
+ m_wLibraryViewManager(NULL),
m_pParent(NULL),
m_pContext(NULL) {
}
@@ -152,7 +154,8 @@ LegacySkinParser::LegacySkinParser(UserSettingsPointer pConfig,
ControllerManager* pControllerManager,
Library* pLibrary,
VinylControlManager* pVCMan,
- EffectsManager* pEffectsManager)
+ EffectsManager* pEffectsManager,
+ WLibraryViewManager* wLibraryViewManager)
: m_pConfig(pConfig),
m_pKeyboard(pKeyboard),
m_pPlayerManager(pPlayerManager),
@@ -160,6 +163,7 @@ LegacySkinParser::LegacySkinParser(UserSettingsPointer pConfig,
m_pLibrary(pLibrary),
m_pVCManager(pVCMan),
m_pEffectsManager(pEffectsManager),
+ m_wLibraryViewManager(wLibraryViewManager),
m_pParent(NULL),
m_pContext(NULL) {
}
@@ -567,6 +571,8 @@ QList LegacySkinParser::parseNode(const QDomElement& node) {
parseSingletonDefinition(node);
} else if (nodeName == "SingletonContainer") {
result = wrapWidget(parseStandardWidget(node));
+ } else if (nodeName == "LibraryStack") {
+ result = wrapWidget(parseLibraryStack(node));
} else {
SKIN_WARNING(node, *m_pContext) << "Invalid node name in skin:"
<< nodeName;
@@ -1558,6 +1564,126 @@ const char* LegacySkinParser::safeChannelString(const QString& channelStr) {
return safe;
}
+QWidget* LegacySkinParser::parseLibraryStack(const QDomElement& node) {
+ bool createdConfig = false;
+ ControlObject* pConfigControl = controlFromConfigNode(
+ node.toElement(), "ConfigControl", &createdConfig);
+
+ bool createdNext = false;
+ ControlObject* pNextControl = controlFromConfigNode(
+ node.toElement(), "NextControl", &createdNext);
+
+ bool createdPrev = false;
+ ControlObject* pPrevControl = controlFromConfigNode(
+ node.toElement(), "PrevControl", &createdPrev);
+
+ bool createdCurrentPage = false;
+ ControlObject* pCurrentPageControl = NULL;
+ QString currentpage_co = node.attribute("currentpage");
+ if (currentpage_co.length() > 0) {
+ ConfigKey configKey = ConfigKey::parseCommaSeparated(currentpage_co);
+ bool persist = m_pContext->selectAttributeBool(node, "persist", false);
+ pCurrentPageControl = controlFromConfigKey(configKey, persist,
+ &createdCurrentPage);
+ }
+
+
+ WLibraryStack* pStack = new WLibraryStack(m_pParent,
+ m_pLibrary,
+ m_pControllerManager->getControllerLearningEventFilter(),
+ m_pKeyboard,
+ pNextControl,
+ pPrevControl,
+ pCurrentPageControl,
+ pConfigControl);
+ pStack->setObjectName("WidgetStack");
+ pStack->setContentsMargins(0, 0, 0, 0);
+ commonWidgetSetup(node, pStack);
+
+ if (createdConfig && pConfigControl) {
+ pConfigControl->setParent(pStack);
+ }
+
+ if (createdNext && pNextControl) {
+ pNextControl->setParent(pStack);
+ }
+
+ if (createdPrev && pPrevControl) {
+ pPrevControl->setParent(pStack);
+ }
+
+ if (pCurrentPageControl != nullptr && createdCurrentPage) {
+ pCurrentPageControl->setParent(pStack);
+ }
+
+ QWidget* pOldParent = m_pParent;
+ m_pParent = pStack;
+
+ QDomNode childrenNode = m_pContext->selectNode(node, "Children");
+ if (!childrenNode.isNull()) {
+ // Descend chilren
+ QDomNodeList children = childrenNode.childNodes();
+
+ for (int i = 0; i < children.count(); ++i) {
+ QDomNode node = children.at(i);
+
+ if (!node.isElement()) {
+ continue;
+ }
+ QDomElement element = node.toElement();
+
+ QList child_widgets = parseNode(element);
+
+ if (child_widgets.empty()) {
+ SKIN_WARNING(node, *m_pContext)
+ << "WidgetStack child produced no widget.";
+ continue;
+ }
+
+ if (child_widgets.size() > 1) {
+ SKIN_WARNING(node, *m_pContext)
+ << "WidgetStack child produced multiple widgets."
+ << "All but the first are ignored.";
+ }
+ QWidget* pChild = child_widgets[0];
+
+ if (pChild == NULL) {
+ continue;
+ }
+
+ ControlObject* pControl = NULL;
+ QString trigger_configkey = element.attribute("trigger");
+ if (trigger_configkey.length() > 0) {
+ ConfigKey configKey = ConfigKey::parseCommaSeparated(trigger_configkey);
+ bool created;
+ pControl = controlFromConfigKey(configKey, false, &created);
+ if (pControl != nullptr && created) {
+ // If we created the control, parent it to the child widget so
+ // it doesn't leak.
+ pControl->setParent(pChild);
+ }
+ }
+ int on_hide_select = -1;
+ QString on_hide_attr = element.attribute("on_hide_select");
+ if (on_hide_attr.length() > 0) {
+ bool ok = false;
+ on_hide_select = on_hide_attr.toInt(&ok);
+ if (!ok) {
+ on_hide_select = -1;
+ }
+ }
+
+ pStack->addWidgetWithControl(pChild, pControl, on_hide_select);
+ }
+ }
+
+ // Init the widget last now that all the children have been created,
+ // so if the current page was saved we can switch to the correct page.
+ pStack->Init();
+ m_pParent = pOldParent;
+ return pStack;
+}
+
QWidget* LegacySkinParser::parseEffectChainName(const QDomElement& node) {
WEffectChain* pEffectChain = new WEffectChain(m_pParent, m_pEffectsManager);
setupLabelWidget(node, pEffectChain);
diff --git a/src/skin/legacyskinparser.h b/src/skin/legacyskinparser.h
index bd7d4b2eaa51..e4326f5766d2 100644
--- a/src/skin/legacyskinparser.h
+++ b/src/skin/legacyskinparser.h
@@ -12,6 +12,7 @@
#include "vinylcontrol/vinylcontrolmanager.h"
#include "skin/tooltips.h"
#include "proto/skin.pb.h"
+#include "widget/wlibraryviewmanager.h"
class WBaseWidget;
class Library;
@@ -23,6 +24,7 @@ class SkinContext;
class WLabel;
class ControlObject;
class LaunchImage;
+class WLibraryViewManager;
class LegacySkinParser : public QObject, public SkinParser {
Q_OBJECT
@@ -32,7 +34,8 @@ class LegacySkinParser : public QObject, public SkinParser {
KeyboardEventFilter* pKeyboard, PlayerManager* pPlayerManager,
ControllerManager* pControllerManager,
Library* pLibrary, VinylControlManager* pVCMan,
- EffectsManager* pEffectsManager);
+ EffectsManager* pEffectsManager,
+ WLibraryViewManager *wLibraryViewManager);
virtual ~LegacySkinParser();
virtual bool canParse(const QString& skinPath);
@@ -78,6 +81,7 @@ class LegacySkinParser : public QObject, public SkinParser {
QWidget* parseEffectParameterName(const QDomElement& node);
QWidget* parseEffectButtonParameterName(const QDomElement& node);
QWidget* parseEffectPushButton(const QDomElement& node);
+ QWidget* parseLibraryStack(const QDomElement& node);
// Legacy pre-1.12.0 skin support.
QWidget* parseBackground(const QDomElement& node, QWidget* pOuterWidget, QWidget* pInnerWidget);
@@ -133,6 +137,7 @@ class LegacySkinParser : public QObject, public SkinParser {
Library* m_pLibrary;
VinylControlManager* m_pVCManager;
EffectsManager* m_pEffectsManager;
+ WLibraryViewManager* m_wLibraryViewManager;
QWidget* m_pParent;
SkinContext* m_pContext;
Tooltips m_tooltips;
diff --git a/src/skin/skinloader.cpp b/src/skin/skinloader.cpp
index 2cc4bb3bf1de..a3cb1e0fb165 100644
--- a/src/skin/skinloader.cpp
+++ b/src/skin/skinloader.cpp
@@ -115,7 +115,8 @@ QWidget* SkinLoader::loadDefaultSkin(QWidget* pParent,
ControllerManager* pControllerManager,
Library* pLibrary,
VinylControlManager* pVCMan,
- EffectsManager* pEffectsManager) {
+ EffectsManager* pEffectsManager,
+ WLibraryViewManager* wLibraryViewManager) {
ScopedTimer timer("SkinLoader::loadDefaultSkin");
QString skinPath = getSkinPath();
@@ -126,7 +127,7 @@ QWidget* SkinLoader::loadDefaultSkin(QWidget* pParent,
LegacySkinParser legacy(m_pConfig, pKeyboard, pPlayerManager,
pControllerManager, pLibrary, pVCMan,
- pEffectsManager);
+ pEffectsManager, wLibraryViewManager);
return legacy.parseSkin(skinPath, pParent);
}
diff --git a/src/skin/skinloader.h b/src/skin/skinloader.h
index ac76b0c99785..e69b585459a2 100644
--- a/src/skin/skinloader.h
+++ b/src/skin/skinloader.h
@@ -14,6 +14,7 @@ class Library;
class VinylControlManager;
class EffectsManager;
class LaunchImage;
+class WLibraryViewManager;
class SkinLoader {
public:
@@ -26,7 +27,8 @@ class SkinLoader {
ControllerManager* pControllerManager,
Library* pLibrary,
VinylControlManager* pVCMan,
- EffectsManager* pEffectsManager);
+ EffectsManager* pEffectsManager,
+ WLibraryViewManager* wLibraryViewManager);
LaunchImage* loadLaunchImage(QWidget* pParent);
diff --git a/src/widget/wlibraryfeature.cpp b/src/widget/wlibraryfeature.cpp
new file mode 100644
index 000000000000..a8f6c1b094cf
--- /dev/null
+++ b/src/widget/wlibraryfeature.cpp
@@ -0,0 +1,6 @@
+#include "wlibraryfeature.h"
+
+WLibraryFeature::WLibraryFeature() {
+
+}
+
diff --git a/src/widget/wlibraryfeature.h b/src/widget/wlibraryfeature.h
new file mode 100644
index 000000000000..915856233b7f
--- /dev/null
+++ b/src/widget/wlibraryfeature.h
@@ -0,0 +1,11 @@
+#ifndef WLIBRARYFEATURE_H
+#define WLIBRARYFEATURE_H
+
+
+class WLibraryFeature
+{
+public:
+ WLibraryFeature();
+};
+
+#endif // WLIBRARYFEATURE_H
diff --git a/src/widget/wlibrarystack.cpp b/src/widget/wlibrarystack.cpp
new file mode 100644
index 000000000000..f8ffc35bb99a
--- /dev/null
+++ b/src/widget/wlibrarystack.cpp
@@ -0,0 +1,83 @@
+#include
+#include "wlibrary.h"
+#include "wlibrarysidebar.h"
+#include "wlibrarystack.h"
+
+
+WLibraryStack::WLibraryStack(QWidget* pParent,
+ Library* pLibrary,
+ ControllerLearningEventFilter* pControllerLearningEventFilter,
+ KeyboardEventFilter* pKeyboardEventFilter,
+ ControlObject* pNextControl,
+ ControlObject* pPrevControl,
+ ControlObject* pCurrentPageControl,
+ ControlObject* pConfigControl)
+ : WWidgetStack(pParent,
+ pNextControl,
+ pPrevControl,
+ pCurrentPageControl),
+ m_configControl(
+ pConfigControl ?
+ pConfigControl->getKey() : ConfigKey(), this),
+ m_pActions(ConfigActions::NUM_ACTIONS),
+ m_pLibrary(pLibrary),
+ m_pControllerLearningEventFilter(pControllerLearningEventFilter),
+ m_pKeyboard(pKeyboardEventFilter) {
+
+ m_configControl.connectValueChanged(SLOT(onConfigControlChanged(double)));
+
+
+ m_pMenu = new QMenu(this);
+ m_pMenuAdd = new QMenu(m_pMenu);
+ m_pMenuAdd->setTitle(tr("Add Feature"));
+
+ m_pActions[ConfigActions::LIBRARY] = m_pMenuAdd->addAction(tr("Library"));
+ m_pActions[ConfigActions::LIBRARY_SIDEBAR] =
+ m_pMenuAdd->addAction(tr("Library Sidebar"));
+
+ m_pMenu->addMenu(m_pMenuAdd);
+ m_pActions[ConfigActions::REMOVE] = m_pMenu->addAction(tr("Remove current element"));
+}
+
+void WLibraryStack::onConfigControlChanged(double v) {
+ if (v > 0.0) {
+ QAction* ret = m_pMenu->exec(QCursor::pos());
+
+ int index = m_pActions.indexOf(ret);
+ int cIndex = currentIndex();
+
+ switch (index) {
+ case ConfigActions::REMOVE:
+ removeWidget(currentWidget());
+ break;
+
+ case ConfigActions::LIBRARY:
+ {
+ WLibrary* pLibraryWidget = new WLibrary(this);
+ pLibraryWidget->installEventFilter(m_pKeyboard);
+ pLibraryWidget->installEventFilter(m_pControllerLearningEventFilter);
+
+ connect(m_pLibrary, SIGNAL(search(QString)),
+ pLibraryWidget, SLOT(search(QString)));
+
+ m_pLibrary->bindWidget(pLibraryWidget, m_pKeyboard);
+ cIndex = insertWidget(cIndex, pLibraryWidget);
+ m_pLibrary->onSkinLoadFinished();
+ break;
+ }
+ case ConfigActions::LIBRARY_SIDEBAR:
+ {
+ WLibrarySidebar* pLibrarySidebar = new WLibrarySidebar(this);
+ pLibrarySidebar->installEventFilter(m_pKeyboard);
+ pLibrarySidebar->installEventFilter(m_pControllerLearningEventFilter);
+
+ m_pLibrary->bindSidebarWidget(pLibrarySidebar);
+ cIndex = insertWidget(cIndex, pLibrarySidebar);
+ break;
+ }
+ default:
+ qWarning() << "Index" << index << "not found for" << ret;
+ }
+ setCurrentIndex(cIndex);
+ }
+}
diff --git a/src/widget/wlibrarystack.h b/src/widget/wlibrarystack.h
new file mode 100644
index 000000000000..a871d1816a0b
--- /dev/null
+++ b/src/widget/wlibrarystack.h
@@ -0,0 +1,53 @@
+#ifndef WLIBRARYSTACK_H
+#define WLIBRARYSTACK_H
+
+#include
+
+#include "library/library.h"
+#include "controllers/keyboard/keyboardeventfilter.h"
+#include "controllers/controllerlearningeventfilter.h"
+#include "wwidgetstack.h"
+
+class WLibraryStack : public WWidgetStack
+{
+ Q_OBJECT
+
+ enum ConfigActions {
+ REMOVE,
+ LIBRARY,
+ LIBRARY_SIDEBAR,
+
+ // This should be always the last value
+ NUM_ACTIONS
+ };
+
+ public:
+ WLibraryStack(QWidget* pParent,
+ Library* pLibrary,
+ ControllerLearningEventFilter* pControllerLearningEventFilter,
+ KeyboardEventFilter* pKeyboardEventFilter,
+ ControlObject* pNextControl,
+ ControlObject* pPrevControl,
+ ControlObject* pCurrentPageControl,
+ ControlObject* pConfigControl);
+
+ private slots:
+
+ void onConfigControlChanged(double v);
+
+ private:
+
+ ControlProxy m_configControl;
+
+ QMenu* m_pMenu;
+ QMenu* m_pMenuAdd;
+
+ QVector m_pActions;
+
+ // Necessary to add the Library and LibrarySidebar
+ Library* m_pLibrary;
+ ControllerLearningEventFilter* m_pControllerLearningEventFilter;
+ KeyboardEventFilter* m_pKeyboard;
+};
+
+#endif // WLIBRARYSTACK_H
diff --git a/src/widget/wlibraryviewmanager.cpp b/src/widget/wlibraryviewmanager.cpp
new file mode 100644
index 000000000000..eed7bea75de8
--- /dev/null
+++ b/src/widget/wlibraryviewmanager.cpp
@@ -0,0 +1 @@
+#include "wlibraryviewmanager.h"
diff --git a/src/widget/wlibraryviewmanager.h b/src/widget/wlibraryviewmanager.h
new file mode 100644
index 000000000000..38369456b4bc
--- /dev/null
+++ b/src/widget/wlibraryviewmanager.h
@@ -0,0 +1,21 @@
+#ifndef WLIBRARYVIEWMANAGER_H
+#define WLIBRARYVIEWMANAGER_H
+
+#include "wlibrarystack.h"
+
+class WLibraryViewManager
+{
+ public:
+
+ inline void addWLibraryStack(WLibraryStack* stack) {
+ if (!m_stacks.contains(stack)) {
+ m_stacks.append(stack);
+ }
+ }
+
+ private:
+
+ QList m_stacks;
+};
+
+#endif // WLIBRARYVIEWMANAGER_H
diff --git a/src/widget/wwidgetstack.cpp b/src/widget/wwidgetstack.cpp
index 75378795e7d7..5151bb4997e4 100644
--- a/src/widget/wwidgetstack.cpp
+++ b/src/widget/wwidgetstack.cpp
@@ -110,7 +110,7 @@ void WWidgetStack::onNextControlChanged(double v) {
if (!isVisible()) {
return;
}
- if (v > 0.0) {
+ if (v > 0.0 && count() > 0) {
setCurrentIndex((currentIndex() + 1) % count());
}
}
@@ -121,7 +121,7 @@ void WWidgetStack::onPrevControlChanged(double v) {
}
if (v > 0.0) {
int newIndex = currentIndex() - 1;
- while (newIndex < 0) {
+ while (newIndex < 0 && count() > 0) {
newIndex += count();
}
setCurrentIndex(newIndex);