From d779d32c8c32e0e0c22662046498620b11fa46de Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Sun, 12 Feb 2017 00:29:01 +0800 Subject: New functionality API. Port built-in features to the new API. Start the revamp of the main Window. Credit of the new design goes to @BLumia. --- ChangeLog | 6 + include/qmpcorepublic.hpp | 17 +- qmidiplayer-desktop/qmidiplayer-desktop.pro | 9 +- qmidiplayer-desktop/qmpchannelswindow.cpp | 29 +- qmidiplayer-desktop/qmpchannelswindow.hpp | 15 +- qmidiplayer-desktop/qmpcustomizewindow.cpp | 103 +++++ qmidiplayer-desktop/qmpcustomizewindow.hpp | 33 ++ qmidiplayer-desktop/qmpcustomizewindow.ui | 107 ++++++ qmidiplayer-desktop/qmpefxwindow.cpp | 29 +- qmidiplayer-desktop/qmpefxwindow.hpp | 17 +- qmidiplayer-desktop/qmpinfowindow.cpp | 24 ++ qmidiplayer-desktop/qmpinfowindow.hpp | 15 + qmidiplayer-desktop/qmpmainwindow.cpp | 250 ++++++------ qmidiplayer-desktop/qmpmainwindow.hpp | 128 ++++++- qmidiplayer-desktop/qmpmainwindow.ui | 564 +++++++++++----------------- qmidiplayer-desktop/qmpplistwindow.cpp | 32 +- qmidiplayer-desktop/qmpplistwindow.hpp | 15 +- qmidiplayer-desktop/qmpplugin.cpp | 9 +- qmidiplayer-desktop/qmpsettingswindow.cpp | 12 + qmidiplayer-desktop/qmpsettingswindow.hpp | 6 + qmidiplayer-desktop/qmpsettingswindow.ui | 38 +- visualization/qmpvisualization.cpp | 4 +- visualization/qmpvisualization.hpp | 2 +- 23 files changed, 955 insertions(+), 509 deletions(-) create mode 100644 qmidiplayer-desktop/qmpcustomizewindow.cpp create mode 100644 qmidiplayer-desktop/qmpcustomizewindow.hpp create mode 100644 qmidiplayer-desktop/qmpcustomizewindow.ui diff --git a/ChangeLog b/ChangeLog index f4c6f0d..6688519 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2017-02-12 0.8.5 indev +New functionality API. Port built-in features to the +new API. +Start the revamp of the main Window. Credit of the +new design goes to @BLumia. + 2017-02-10 0.8.5 indev Road to standardize: use two parameters for pitchbend. Documentation. diff --git a/include/qmpcorepublic.hpp b/include/qmpcorepublic.hpp index 18b2f6a..67259e0 100644 --- a/include/qmpcorepublic.hpp +++ b/include/qmpcorepublic.hpp @@ -8,7 +8,7 @@ #else #define EXPORTSYM __attribute__ ((visibility ("default"))) #endif -#define QMP_PLUGIN_API_REV "1+indev2" +#define QMP_PLUGIN_API_REV "1+indev3" //MIDI Event structure struct SEvent { @@ -70,9 +70,17 @@ class qmpPluginIntf virtual const char* pluginGetName(){return "";} virtual const char* pluginGetVersion(){return "";} }; +class qmpFuncBaseIntf +{ + public: + qmpFuncBaseIntf(){} + virtual void show()=0; + virtual void close()=0; + virtual ~qmpFuncBaseIntf(){} +}; //Visualization plugin pinterface. If your plugin implements a visualization, //you should implement this pinterface. -class qmpVisualizationIntf +class qmpVisualizationIntf:public qmpFuncBaseIntf { public: qmpVisualizationIntf(){} @@ -112,6 +120,7 @@ class qmpPluginAPI virtual std::string getTitle(); virtual std::wstring getWTitle(); virtual std::string getChannelPresetString(int ch); + virtual bool isDarkTheme(); //WARNING!!: This function should be called from event reader callbacks only and //it is somehow dangerous -- other plugins might be unaware of the removal of the @@ -124,8 +133,8 @@ class qmpPluginAPI //This function should be called from a file reader when it has read a new event virtual void callEventReaderCB(SEventCallBackData d); - virtual int registerVisualizationIntf(qmpVisualizationIntf* intf); - virtual void unregisterVisualizationIntf(int intfhandle); + virtual void registerVisualizationIntf(qmpVisualizationIntf* intf,std::string name,std::string desc,const char* icon,int iconlen); + virtual void unregisterVisualizationIntf(std::string name); virtual int registerEventReaderIntf(IMidiCallBack* cb,void* userdata); virtual void unregisterEventReaderIntf(int intfhandle); virtual int registerEventHandlerIntf(IMidiCallBack* cb,void* userdata); diff --git a/qmidiplayer-desktop/qmidiplayer-desktop.pro b/qmidiplayer-desktop/qmidiplayer-desktop.pro index 4a04d6b..427a2ff 100644 --- a/qmidiplayer-desktop/qmidiplayer-desktop.pro +++ b/qmidiplayer-desktop/qmidiplayer-desktop.pro @@ -27,7 +27,8 @@ SOURCES += main.cpp\ qmphelpwindow.cpp \ qdialskulpturestyle.cpp \ ../core/qmpmidimapperrtmidi.cpp \ - qmpplugin.cpp + qmpplugin.cpp \ + qmpcustomizewindow.cpp HEADERS += qmpmainwindow.hpp \ ../core/qmpmidiplay.hpp \ @@ -42,7 +43,8 @@ HEADERS += qmpmainwindow.hpp \ qdialskulpturestyle.hpp \ ../core/qmpmidimappers.hpp \ ../include/qmpcorepublic.hpp \ - qmpplugin.hpp + qmpplugin.hpp \ + qmpcustomizewindow.hpp FORMS += qmpmainwindow.ui \ qmpplistwindow.ui \ @@ -52,7 +54,8 @@ FORMS += qmpmainwindow.ui \ qmpefxwindow.ui \ qmpinfowindow.ui \ qmpsettingswindow.ui \ - qmphelpwindow.ui + qmphelpwindow.ui \ + qmpcustomizewindow.ui TRANSLATIONS += translations/qmp_zh_CN.ts DEFINES += BUILD_MACHINE=$${QMAKE_HOST.name} diff --git a/qmidiplayer-desktop/qmpchannelswindow.cpp b/qmidiplayer-desktop/qmpchannelswindow.cpp index ed522a0..fc7c686 100644 --- a/qmidiplayer-desktop/qmpchannelswindow.cpp +++ b/qmidiplayer-desktop/qmpchannelswindow.cpp @@ -15,7 +15,6 @@ qmpChannelsWindow::qmpChannelsWindow(QWidget *parent) : setMaximumWidth(w);setMaximumHeight(h);setMinimumWidth(w);setMinimumHeight(h); pselectw=new qmpPresetSelector(this); ceditw=new qmpChannelEditor(this); - connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed())); mapper=qmpMainWindow::getInstance()->getPlayer()->getMidiMapper(); cha=new QPixmap(":/img/ledon.png");chi=new QPixmap(":/img/ledoff.png"); cb=new qmpCWNoteOnCB();fused=callbacksc=cbcnt=0; @@ -73,6 +72,18 @@ qmpChannelsWindow::qmpChannelsWindow(QWidget *parent) : ui->twChannels->setColumnWidth(3,192*(logicalDpiX()/96.)); ui->twChannels->setColumnWidth(4,208*(logicalDpiX()/96.)); ui->twChannels->setColumnWidth(5,32*(logicalDpiX()/96.)); + qmpMainWindow::getInstance()->registerFunctionality( + chnlf=new qmpChannelFunc(this), + std::string("Channel"), + tr("Channel").toStdString(), + getThemedIconc(":/img/channel.png"), + 0, + true + ); + if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlW",QByteArray()).toByteArray().length()) + restoreGeometry(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlW",QRect(-999,-999,-999,-999)).toByteArray()); + if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlWShown",0).toInt()) + {show();qmpMainWindow::getInstance()->setFuncState("Channel",true);} } void qmpChannelsWindow::showEvent(QShowEvent *event) @@ -81,6 +92,8 @@ void qmpChannelsWindow::showEvent(QShowEvent *event) { qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlWShown",1); } + if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlW",QByteArray()).toByteArray().length()) + restoreGeometry(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlW",QRect(-999,-999,-999,-999)).toByteArray()); event->accept(); } @@ -91,7 +104,7 @@ void qmpChannelsWindow::closeEvent(QCloseEvent *event) { qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlWShown",0); } - emit dialogClosing(); + qmpMainWindow::getInstance()->setFuncState("Channel",false); event->accept(); } @@ -99,8 +112,9 @@ void qmpChannelsWindow::moveEvent(QMoveEvent *event) { if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) { - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlW",event->pos()); + qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlW",saveGeometry()); } + event->accept(); } void qmpChannelsWindow::resetAcitivity() @@ -174,6 +188,8 @@ void qmpChannelsWindow::channelMSChanged() qmpChannelsWindow::~qmpChannelsWindow() { + qmpMainWindow::getInstance()->unregisterFunctionality("Channel"); + delete chnlf; delete chi;delete cha; delete cb;delete ui; } @@ -212,3 +228,10 @@ void qmpChannelsWindow::changeMidiMapping(int chid,int idx) { qmpMainWindow::getInstance()->getPlayer()->setChannelOutput(chid,idx); } + +qmpChannelFunc::qmpChannelFunc(qmpChannelsWindow *par) +{p=par;} +void qmpChannelFunc::show() +{p->show();} +void qmpChannelFunc::close() +{p->close();} diff --git a/qmidiplayer-desktop/qmpchannelswindow.hpp b/qmidiplayer-desktop/qmpchannelswindow.hpp index 0fa1e06..4502b21 100644 --- a/qmidiplayer-desktop/qmpchannelswindow.hpp +++ b/qmidiplayer-desktop/qmpchannelswindow.hpp @@ -69,6 +69,18 @@ class qmpCWNoteOnCB:public QObject,public IMidiCallBack void onNoteOn(); }; +class qmpChannelsWindow; + +class qmpChannelFunc:public qmpFuncBaseIntf +{ + private: + qmpChannelsWindow *p; + public: + qmpChannelFunc(qmpChannelsWindow *par); + void show(); + void close(); +}; + class qmpChannelsWindow:public QDialog { Q_OBJECT @@ -80,8 +92,6 @@ class qmpChannelsWindow:public QDialog void closeEvent(QCloseEvent *event); void moveEvent(QMoveEvent *event); void resetAcitivity(); - signals: - void dialogClosing(); public slots: void channelWindowsUpdate(); void updateChannelActivity(); @@ -99,6 +109,7 @@ class qmpChannelsWindow:public QDialog qmpMidiMapperRtMidi *mapper; QPixmap *cha,*chi; qmpCWNoteOnCB *cb; + qmpChannelFunc *chnlf; //callback fuse... (avoid black midi blocking the main thread) int callbacksc,cbcnt,fused; }; diff --git a/qmidiplayer-desktop/qmpcustomizewindow.cpp b/qmidiplayer-desktop/qmpcustomizewindow.cpp new file mode 100644 index 0000000..5ac9bd0 --- /dev/null +++ b/qmidiplayer-desktop/qmpcustomizewindow.cpp @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include +#include +#include "qmpmainwindow.hpp" +#include "qmpcustomizewindow.hpp" +#include "ui_qmpcustomizewindow.h" + +qmpCustomizeWindow::qmpCustomizeWindow(QWidget *parent) : + QDialog(parent), + ui(new Ui::qmpCustomizeWindow) +{ + ui->setupUi(this); + int w=size().width(),h=size().height();w=w*(logicalDpiX()/96.);h=h*(logicalDpiY()/96.); + setMinimumWidth(w);setMinimumHeight(h); + QSettings *s=qmpMainWindow::getInstance()->getSettingsWindow()->getSettingsIntf(); + QList defa={"FileInfo","Render","Panic","ReloadSynth"}; + QList defb={"Channel","Playlist","Effects","Visualization"}; + QList a=s->value("Behavior/Actions",QVariant(defa)).toList(); + QList b=s->value("Behavior/Toolbar",QVariant(defb)).toList(); + std::vector& v=qmpMainWindow::getInstance()->getWidgets(1); + v.clear(); + for(int i=0;i& vv=qmpMainWindow::getInstance()->getWidgets(0); + vv.clear(); + for(int i=0;ilwAvail->clear(); + ui->lwEnabled->clear(); + ow=w; + std::vector& v=qmpMainWindow::getInstance()->getWidgets(w); + std::map& m=qmpMainWindow::getInstance()->getFunc(); + std::set s; + for(auto i=v.begin();i!=v.end();++i) + { + s.insert(*i); + QListWidgetItem* it=new QListWidgetItem( + m[*i].icon(), + QString(m[*i].desc().c_str()) + ); + it->setToolTip(i->c_str()); + ui->lwEnabled->addItem(it); + } + for(auto i=m.begin();i!=m.end();++i) + { + if(s.find(i->first)==s.end()) + { + QListWidgetItem* it=new QListWidgetItem( + i->second.icon(), + QString(i->second.desc().c_str()) + ); + it->setToolTip(i->first.c_str()); + ui->lwAvail->addItem(it); + } + } +} + +void qmpCustomizeWindow::on_tbAdd_clicked() +{ + if(!ui->lwAvail->currentItem())return; + ui->lwEnabled->addItem(ui->lwAvail->takeItem(ui->lwAvail->currentRow())); + ui->lwAvail->removeItemWidget(ui->lwAvail->currentItem()); +} + +void qmpCustomizeWindow::on_tbRemove_clicked() +{ + if(!ui->lwEnabled->currentItem())return; + ui->lwAvail->addItem(ui->lwEnabled->takeItem(ui->lwEnabled->currentRow())); +} + +void qmpCustomizeWindow::on_buttonBox_accepted() +{ + std::vector& v=qmpMainWindow::getInstance()->getWidgets(ow); + v.clear(); + QList ql; + for(int i=0;ilwEnabled->count();++i) + { + v.push_back(ui->lwEnabled->item(i)->toolTip().toStdString()); + ql.push_back(QVariant(ui->lwEnabled->item(i)->toolTip())); + } + QSettings *s=qmpMainWindow::getInstance()->getSettingsWindow()->getSettingsIntf(); + s->setValue(ow?"Behavior/Actions":"Behavior/Toolbar",ql); + qmpMainWindow::getInstance()->setupWidget(); + close(); +} + +void qmpCustomizeWindow::on_buttonBox_rejected() +{ + close(); +} diff --git a/qmidiplayer-desktop/qmpcustomizewindow.hpp b/qmidiplayer-desktop/qmpcustomizewindow.hpp new file mode 100644 index 0000000..0d0f529 --- /dev/null +++ b/qmidiplayer-desktop/qmpcustomizewindow.hpp @@ -0,0 +1,33 @@ +#ifndef QMPCUSTOMIZEWINDOW_HPP +#define QMPCUSTOMIZEWINDOW_HPP + +#include + +namespace Ui { +class qmpCustomizeWindow; +} + +class qmpCustomizeWindow : public QDialog +{ + Q_OBJECT + + public: + explicit qmpCustomizeWindow(QWidget *parent = 0); + ~qmpCustomizeWindow(); + void launch(int w); + + private slots: + void on_tbAdd_clicked(); + + void on_tbRemove_clicked(); + + void on_buttonBox_accepted(); + + void on_buttonBox_rejected(); + + private: + Ui::qmpCustomizeWindow *ui; + int ow; +}; + +#endif // QMPCUSTOMIZEWINDOW_HPP diff --git a/qmidiplayer-desktop/qmpcustomizewindow.ui b/qmidiplayer-desktop/qmpcustomizewindow.ui new file mode 100644 index 0000000..94b6531 --- /dev/null +++ b/qmidiplayer-desktop/qmpcustomizewindow.ui @@ -0,0 +1,107 @@ + + + qmpCustomizeWindow + + + + 0 + 0 + 578 + 315 + + + + Customize widgets + + + + + + + + QAbstractItemView::InternalMove + + + + + + + + + > + + + + + + + < + + + + + + + + + QAbstractItemView::InternalMove + + + + + + + + + Items can be sorted by drag and drop. + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + qmpCustomizeWindow + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + qmpCustomizeWindow + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/qmidiplayer-desktop/qmpefxwindow.cpp b/qmidiplayer-desktop/qmpefxwindow.cpp index 25e9bf4..04a7e8d 100644 --- a/qmidiplayer-desktop/qmpefxwindow.cpp +++ b/qmidiplayer-desktop/qmpefxwindow.cpp @@ -14,7 +14,6 @@ qmpEfxWindow::qmpEfxWindow(QWidget *parent) : dials.at(i)->setStyle(styl); int w=size().width(),h=size().height();w=w*(logicalDpiX()/96.);h=h*(logicalDpiY()/96.); setMaximumWidth(w);setMaximumHeight(h);setMinimumWidth(w);setMinimumHeight(h); - connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed())); //stub. read these from settings after the setting module is implemented QSettings *settings=qmpSettingsWindow::getSettingsIntf(); ui->cbEnabledC->setChecked(settings->value("Effects/ChorusEnabled",1).toInt()); @@ -29,10 +28,24 @@ qmpEfxWindow::qmpEfxWindow(QWidget *parent) : cr=settings->value("Effects/ChorusRate",FLUID_CHORUS_DEFAULT_SPEED).toDouble(); cd=settings->value("Effects/ChorusDepth",FLUID_CHORUS_DEFAULT_DEPTH).toDouble(); ct=settings->value("Effects/ChorusType",FLUID_CHORUS_DEFAULT_TYPE).toInt(); + qmpMainWindow::getInstance()->registerFunctionality( + efxf=new qmpEfxFunc(this), + std::string("Effects"), + tr("Effects").toStdString(), + getThemedIconc(":/img/effects.png"), + 0, + true + ); + if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxW",QByteArray()).toByteArray().length()) + restoreGeometry(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxW",QRect(-999,-999,-999,-999)).toByteArray()); + if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxWShown",0).toInt()) + {show();qmpMainWindow::getInstance()->setFuncState("Effects",true);} } qmpEfxWindow::~qmpEfxWindow() { + qmpMainWindow::getInstance()->unregisterFunctionality("Effects"); + delete efxf; delete styl; delete ui; } @@ -44,7 +57,7 @@ void qmpEfxWindow::closeEvent(QCloseEvent *event) { qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxWShown",0); } - emit dialogClosing(); + qmpMainWindow::getInstance()->setFuncState("Effects",false); event->accept(); } @@ -69,6 +82,8 @@ void qmpEfxWindow::showEvent(QShowEvent *event) if(ct==FLUID_CHORUS_MOD_SINE)ui->rbSine->setChecked(true),ui->rbTriangle->setChecked(false); if(ct==FLUID_CHORUS_MOD_TRIANGLE)ui->rbSine->setChecked(false),ui->rbTriangle->setChecked(true); initialized=true; + if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxW",QByteArray()).toByteArray().length()) + restoreGeometry(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxW",QRect(-999,-999,-999,-999)).toByteArray()); if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) { qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxWShown",1); @@ -80,8 +95,9 @@ void qmpEfxWindow::moveEvent(QMoveEvent *event) { if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) { - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxW",event->pos()); + qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxW",saveGeometry()); } + event->accept(); } void qmpEfxWindow::sendEfxChange() @@ -198,3 +214,10 @@ void qmpEfxWindow::on_rbSine_toggled() void qmpEfxWindow::on_rbTriangle_toggled() {sendEfxChange();} + +qmpEfxFunc::qmpEfxFunc(qmpEfxWindow *par) +{p=par;} +void qmpEfxFunc::show() +{p->show();} +void qmpEfxFunc::close() +{p->close();} diff --git a/qmidiplayer-desktop/qmpefxwindow.hpp b/qmidiplayer-desktop/qmpefxwindow.hpp index 2a080f0..1adadd0 100644 --- a/qmidiplayer-desktop/qmpefxwindow.hpp +++ b/qmidiplayer-desktop/qmpefxwindow.hpp @@ -7,11 +7,24 @@ #include #include "qdialskulpturestyle.hpp" +#include "../include/qmpcorepublic.hpp" namespace Ui { class qmpEfxWindow; } +class qmpEfxWindow; + +class qmpEfxFunc:public qmpFuncBaseIntf +{ + private: + qmpEfxWindow *p; + public: + qmpEfxFunc(qmpEfxWindow *par); + void show(); + void close(); +}; + class qmpEfxWindow : public QDialog { Q_OBJECT @@ -24,9 +37,6 @@ class qmpEfxWindow : public QDialog void moveEvent(QMoveEvent *event); void sendEfxChange(); - signals: - void dialogClosing(); - private slots: void on_dRoom_valueChanged(); void on_dDamp_valueChanged(); @@ -57,6 +67,7 @@ class qmpEfxWindow : public QDialog int cfb,ct,initialized; double cl,cr,cd; QCommonStyle* styl; + qmpEfxFunc *efxf; }; #endif // QMPEFXWINDOW_HPP diff --git a/qmidiplayer-desktop/qmpinfowindow.cpp b/qmidiplayer-desktop/qmpinfowindow.cpp index fda94f8..03084c1 100644 --- a/qmidiplayer-desktop/qmpinfowindow.cpp +++ b/qmidiplayer-desktop/qmpinfowindow.cpp @@ -15,13 +15,30 @@ qmpInfoWindow::qmpInfoWindow(QWidget *parent) : ui->setupUi(this); int w=size().width(),h=size().height();w=w*(logicalDpiX()/96.);h=h*(logicalDpiY()/96.); setMinimumWidth(w);setMinimumHeight(h); + qmpMainWindow::getInstance()->registerFunctionality( + infof=new qmpInfoFunc(this), + std::string("FileInfo"), + tr("File Information").toStdString(), + NULL, + 0, + true + ); } qmpInfoWindow::~qmpInfoWindow() { + qmpMainWindow::getInstance()->unregisterFunctionality("FileInfo"); + delete infof; delete ui; } +void qmpInfoWindow::closeEvent(QCloseEvent *e) +{ + setVisible(false); + qmpMainWindow::getInstance()->setFuncState("FileInfo",false); + e->accept(); +} + void qmpInfoWindow::updateInfo() { char str[256]; @@ -57,3 +74,10 @@ void qmpInfoWindow::updateInfo() strncpy(str,standards+player->getFileStandard()*3,3);str[3]='\0'; ui->lbFileStandard->setText(QString("File standard: ")+str); } + +qmpInfoFunc::qmpInfoFunc(qmpInfoWindow *par) +{p=par;} +void qmpInfoFunc::show() +{p->show();} +void qmpInfoFunc::close() +{p->close();} diff --git a/qmidiplayer-desktop/qmpinfowindow.hpp b/qmidiplayer-desktop/qmpinfowindow.hpp index a76b46b..87ac2c0 100644 --- a/qmidiplayer-desktop/qmpinfowindow.hpp +++ b/qmidiplayer-desktop/qmpinfowindow.hpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include "../include/qmpcorepublic.hpp" namespace Ui { class qmpInfoWindow; @@ -25,6 +27,17 @@ class QClickableLabel : public QLabel } }; +class qmpInfoWindow; +class qmpInfoFunc:public qmpFuncBaseIntf +{ + private: + qmpInfoWindow *p; + public: + qmpInfoFunc(qmpInfoWindow *par); + void show(); + void close(); +}; + class qmpInfoWindow : public QDialog { Q_OBJECT @@ -32,11 +45,13 @@ class qmpInfoWindow : public QDialog public: explicit qmpInfoWindow(QWidget *parent = 0); ~qmpInfoWindow(); + void closeEvent(QCloseEvent *e); public slots: void updateInfo(); private: Ui::qmpInfoWindow *ui; + qmpInfoFunc *infof; }; #endif // QMPINFOWINDOW_HPP diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp index 491c39d..cbec3f5 100644 --- a/qmidiplayer-desktop/qmpmainwindow.cpp +++ b/qmidiplayer-desktop/qmpmainwindow.cpp @@ -13,6 +13,7 @@ #include "ui_qmpmainwindow.h" #include "../core/qmpmidiplay.hpp" #define setButtonHeight(x,h) {x->setMaximumHeight(h*(logicalDpiY()/96.));x->setMinimumHeight(h*(logicalDpiY()/96.));} +#define setButtonWidth(x,h) {x->setMaximumWidth(h*(logicalDpiY()/96.));x->setMinimumWidth(h*(logicalDpiY()/96.));} #ifdef _WIN32 #include char* wcsto8bit(const wchar_t* s) @@ -30,7 +31,7 @@ char* wcsto8bit(const wchar_t* s) } #define LOAD_FILE \ {\ - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->reset();\ + for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->reset();\ char* c=wcsto8bit(fns.toStdWString().c_str());\ if(!player->playerLoadFile(c)){free(c);QMessageBox::critical(this,tr("Error"),tr("%1 is not a valid midi file.").arg(fns));return;}\ free(c);\ @@ -40,7 +41,7 @@ char* wcsto8bit(const wchar_t* s) player->pushSoundFont(settingsw->getSFWidget()->item(i,1)->text().toStdString().c_str()) #define LOAD_FILE \ {\ - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->reset();\ + for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->reset();\ if(!player->playerLoadFile(fns.toStdString().c_str())){QMessageBox::critical(this,tr("Error"),tr("%1 is not a valid midi file.").arg(fns));return;}\ } #endif @@ -57,11 +58,11 @@ qmpMainWindow::qmpMainWindow(QWidget *parent) : ui->lbFileName->setText("");ref=this;ui->verticalLayout->setAlignment(ui->pushButton,Qt::AlignRight); int w=size().width(),h=size().height();w=w*(logicalDpiX()/96.);h=h*(logicalDpiY()/96.); setMaximumWidth(w);setMaximumHeight(h);setMinimumWidth(w);setMinimumHeight(h); - setButtonHeight(ui->pbNext,34);setButtonHeight(ui->pbPlayPause,34); - setButtonHeight(ui->pbPrev,34);setButtonHeight(ui->pbSettings,34);setButtonHeight(ui->pbStop,34); - setButtonHeight(ui->pbChannels,36);setButtonHeight(ui->pbPList,36); - setButtonHeight(ui->pbEfx,36);setButtonHeight(ui->pbVisualization,36); - playing=false;stopped=true;dragging=false;memset(VIs,0,sizeof(VIs)); + setButtonHeight(ui->pbNext,36);setButtonHeight(ui->pbPlayPause,36); + setButtonHeight(ui->pbPrev,36);setButtonHeight(ui->pbSettings,36);setButtonHeight(ui->pbStop,36); + //setButtonHeight(ui->pbChannels,36);setButtonHeight(ui->pbPList,36); + //setButtonHeight(ui->pbEfx,36);setButtonHeight(ui->pbVisualization,36); + playing=false;stopped=true;dragging=false; settingsw=new qmpSettingsWindow(this);pmgr=new qmpPluginManager(); plistw=new qmpPlistWindow(this);player=NULL;timer=NULL; singleFS=qmpSettingsWindow::getSettingsIntf()->value("Behavior/SingleInstance",0).toInt(); @@ -89,14 +90,12 @@ void qmpMainWindow::init() infow=new qmpInfoWindow(this); helpw=new qmpHelpWindow(this); timer=new QTimer(this); - fnA1=new QAction(tr("File Information"),ui->lbFileName); - fnA2=new QAction(tr("Render to Wave"),ui->lbFileName); - fnA3=new QAction(tr("Panic"),ui->lbFileName); - fnA4=new QAction(tr("Restart fluidsynth"),ui->lbFileName); - ui->lbFileName->addAction(fnA1); - ui->lbFileName->addAction(fnA2); - ui->lbFileName->addAction(fnA3); - ui->lbFileName->addAction(fnA4); + renderf=new qmpRenderFunc(this); + panicf=new qmpPanicFunc(this); + reloadsynf=new qmpReloadSynthFunc(this); + registerFunctionality(renderf,"Render",tr("Render to wave").toStdString(),NULL,0,false); + registerFunctionality(panicf,"Panic",tr("Panic").toStdString(),NULL,0,false); + registerFunctionality(reloadsynf,"ReloadSynth",tr("Restart fluidsynth").toStdString(),NULL,0,false); pmgr->scanPlugins();settingsw->updatePluginList(pmgr);pmgr->initPlugins(); if(singleFS){player->fluidPreInitialize();playerSetup();player->fluidInitialize(); for(int i=settingsw->getSFWidget()->rowCount()-1;i>=0;--i){if(!((QCheckBox*)settingsw->getSFWidget()->cellWidget(i,0))->isChecked())continue; @@ -111,17 +110,7 @@ void qmpMainWindow::init() Qt::LeftToRight,Qt::AlignCenter,size(), qApp->desktop()->availableGeometry())); }show(); - if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListWShown",0).toInt()) - {ui->pbPList->setChecked(true);on_pbPList_clicked();} - if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlWShown",0).toInt()) - {ui->pbChannels->setChecked(true);on_pbChannels_clicked();} - if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxWShown",0).toInt()) - {ui->pbEfx->setChecked(true);on_pbEfx_clicked();} ui->vsMasterVol->setValue(qmpSettingsWindow::getSettingsIntf()->value("Audio/Gain",50).toInt()); - connect(fnA1,SIGNAL(triggered()),this,SLOT(onfnA1())); - connect(fnA2,SIGNAL(triggered()),this,SLOT(onfnA2())); - connect(fnA3,SIGNAL(triggered()),this,SLOT(onfnA3())); - connect(fnA4,SIGNAL(triggered()),this,SLOT(onfnA4())); connect(timer,SIGNAL(timeout()),this,SLOT(updateWidgets())); connect(timer,SIGNAL(timeout()),chnlw,SLOT(channelWindowsUpdate())); connect(timer,SIGNAL(timeout()),infow,SLOT(updateInfo())); @@ -129,12 +118,13 @@ void qmpMainWindow::init() ui->pbPrev->setIcon(QIcon(getThemedIcon(":/img/prev.png"))); ui->pbPlayPause->setIcon(QIcon(getThemedIcon(":/img/play.png"))); ui->pbStop->setIcon(QIcon(getThemedIcon(":/img/stop.png"))); - ui->pbChannels->setIcon(QIcon(getThemedIcon(":/img/channel.png"))); - ui->pbEfx->setIcon(QIcon(getThemedIcon(":/img/effects.png"))); - ui->pbPList->setIcon(QIcon(getThemedIcon(":/img/list.png"))); - ui->pbVisualization->setIcon(QIcon(getThemedIcon(":/img/visualization.png"))); + //ui->pbChannels->setIcon(QIcon(getThemedIcon(":/img/channel.png"))); + //ui->pbEfx->setIcon(QIcon(getThemedIcon(":/img/effects.png"))); + //ui->pbPList->setIcon(QIcon(getThemedIcon(":/img/list.png"))); + //ui->pbVisualization->setIcon(QIcon(getThemedIcon(":/img/visualization.png"))); ui->pbSettings->setIcon(QIcon(getThemedIcon(":/img/settings.png"))); if(havemidi)on_pbPlayPause_clicked(); + setupWidget(); } int qmpMainWindow::pharseArgs() @@ -209,6 +199,9 @@ int qmpMainWindow::pharseArgs() void qmpMainWindow::closeEvent(QCloseEvent *event) { on_pbStop_clicked();fin=true; + for(auto i=mfunc.begin();i!=mfunc.end();++i) + i->second.setAssignedControl((QReflectiveAction*)NULL), + i->second.setAssignedControl((QReflectivePushButton*)NULL); efxw->close();chnlw->close(); plistw->close();infow->close(); settingsw->close(); @@ -221,6 +214,7 @@ void qmpMainWindow::moveEvent(QMoveEvent *event) { qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/MainW",event->pos()); } + event->accept(); } void qmpMainWindow::dropEvent(QDropEvent *event) { @@ -239,16 +233,15 @@ void qmpMainWindow::dragEnterEvent(QDragEnterEvent *event) void qmpMainWindow::updateWidgets() { - fnA2->setEnabled(stopped); - fnA4->setEnabled(stopped); + setFuncEnabled("Render",stopped);setFuncEnabled("ReloadSynth",stopped); if(player->isFinished()&&playerTh) { if(!plistw->getRepeat()) { timer->stop();stopped=true;playing=false; - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->stop(); - fnA2->setEnabled(stopped); - fnA4->setEnabled(stopped);chnlw->resetAcitivity(); + for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->stop(); + setFuncEnabled("Render",stopped);setFuncEnabled("ReloadSynth",stopped); + chnlw->resetAcitivity(); player->playerDeinit();playerTh->join(); delete playerTh;playerTh=NULL; if(singleFS)player->playerPanic(true); @@ -302,7 +295,7 @@ void qmpMainWindow::switchTrack(QString s) timer->stop();player->playerDeinit();playerTh->join(); delete playerTh;playerTh=NULL; ui->hsTimer->setValue(0); - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->stop(); + for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->stop(); if(singleFS)player->playerPanic(true); chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked(); QString fns=s;setWindowTitle(QUrl::fromLocalFile(fns).fileName().left(QUrl::fromLocalFile(fns).fileName().lastIndexOf('.'))+" - QMidiPlayer"); @@ -316,7 +309,7 @@ void qmpMainWindow::switchTrack(QString s) for(int i=settingsw->getSFWidget()->rowCount()-1;i>=0;--i){if(!((QCheckBox*)settingsw->getSFWidget()->cellWidget(i,0))->isChecked())continue; LOAD_SOUNDFONT; }} - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->start(); + for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->start(); player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange(); player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt()); playerTh=new std::thread(&CMidiPlayer::playerThread,player); @@ -405,7 +398,7 @@ void qmpMainWindow::on_pbPlayPause_clicked() LOAD_SOUNDFONT; } } - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->start(); + for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->start(); player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange(); player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt()); playerTh=new std::thread(&CMidiPlayer::playerThread,player); @@ -429,7 +422,7 @@ void qmpMainWindow::on_pbPlayPause_clicked() player->setResumed(); } player->setTCpaused(!playing); - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->pause(); + for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->pause(); } ui->pbPlayPause->setIcon(QIcon(getThemedIcon(playing?":/img/pause.png":":/img/play.png"))); } @@ -496,8 +489,9 @@ void qmpMainWindow::on_pbStop_clicked() if(!stopped) { timer->stop();stopped=true;playing=false; - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->stop(); - player->playerDeinit();fnA2->setEnabled(stopped);fnA4->setEnabled(stopped); + for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->stop(); + player->playerDeinit(); + setFuncEnabled("Render",stopped);setFuncEnabled("ReloadSynth",stopped); if(singleFS)player->playerPanic(true);chnlw->resetAcitivity(); if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;} chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked(); @@ -510,38 +504,9 @@ void qmpMainWindow::on_pbStop_clicked() void qmpMainWindow::dialogClosed() { - if(!plistw->isVisible())ui->pbPList->setChecked(false); - if(!chnlw->isVisible())ui->pbChannels->setChecked(false); - if(!efxw->isVisible())ui->pbEfx->setChecked(false); if(!settingsw->isVisible())ui->pbSettings->setChecked(false); } -void qmpMainWindow::on_pbPList_clicked() -{ - if(ui->pbPList->isChecked()) - { - QRect g=plistw->geometry(); - g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListW",QPoint(-999,-999)).toPoint()); - if(g.topLeft()==QPoint(-999,-999)) - g.setTopLeft(window()->mapToGlobal(window()->rect().center())-plistw->rect().center()); - plistw->setGeometry(g); - plistw->show(); - }else plistw->close(); -} - -void qmpMainWindow::on_pbChannels_clicked() -{ - if(ui->pbChannels->isChecked()) - { - QRect g=chnlw->geometry(); - g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlW",QPoint(-999,-999)).toPoint()); - if(g.topLeft()==QPoint(-999,-999)) - g.setTopLeft(window()->mapToGlobal(window()->rect().center())-chnlw->rect().center()); - chnlw->setGeometry(g); - chnlw->show(); - }else chnlw->close(); -} - void qmpMainWindow::on_pbPrev_clicked() { switchTrack(plistw->getPrevItem()); @@ -557,7 +522,7 @@ void qmpMainWindow::selectionChanged() stopped=false;playing=true; ui->pbPlayPause->setIcon(QIcon(getThemedIcon(":/img/pause.png"))); timer->stop();player->playerDeinit(); - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->stop(); + for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->stop(); if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;} if(singleFS)player->playerPanic(true); ui->hsTimer->setValue(0); @@ -574,7 +539,7 @@ void qmpMainWindow::selectionChanged() for(int i=settingsw->getSFWidget()->rowCount()-1;i>=0;--i){if(!((QCheckBox*)settingsw->getSFWidget()->cellWidget(i,0))->isChecked())continue; LOAD_SOUNDFONT; }} - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->start(); + for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->start(); player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange(); player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt()); playerTh=new std::thread(&CMidiPlayer::playerThread,player); @@ -585,20 +550,6 @@ void qmpMainWindow::selectionChanged() timer->start(UPDATE_INTERVAL); } -void qmpMainWindow::on_pbEfx_clicked() -{ - if(ui->pbEfx->isChecked()) - { - QRect g=efxw->geometry(); - g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxW",QPoint(-999,-999)).toPoint()); - if(g.topLeft()==QPoint(-999,-999)) - g.setTopLeft(window()->mapToGlobal(window()->rect().center())-efxw->rect().center()); - efxw->setGeometry(g); - efxw->show(); - } - else efxw->close(); -} - void qmpMainWindow::on_lbFileName_customContextMenuRequested(const QPoint &pos) { QMenu menu(ui->lbFileName); @@ -619,20 +570,36 @@ void qmpMainWindow::onfnChanged() ui->lbFileName->setFont(f); } -int qmpMainWindow::registerVisualizationIntf(qmpVisualizationIntf* intf) +void qmpMainWindow::registerVisualizationIntf(qmpVisualizationIntf* intf,std::string name,std::string desc,const char* icon,int iconlen) { - for(int i=0;i<16;++i) - { - if(VIs[i]==intf)return i; - if(VIs[i]==NULL){VIs[i]=intf;return i;} - } - return -1; + registerFunctionality(intf,name,desc,icon,iconlen,true,true); +} +void qmpMainWindow::unregisterVisualizationIntf(std::string name) +{ + unregisterFunctionality(name); +} + +void qmpMainWindow::registerFunctionality(qmpFuncBaseIntf *i,std::string name,std::string desc,const char *icon,int iconlen,bool checkable,bool isv) +{ + if(mfunc.find(name)!=mfunc.end())return; + mfunc[name]=qmpFuncPrivate(i,desc,icon,iconlen,checkable,isv); } -void qmpMainWindow::unregisterVisualizationIntf(int handle) + +void qmpMainWindow::unregisterFunctionality(std::string name) { - VIs[handle]=NULL; + mfunc.erase(name); + for(auto i=enabled_actions.begin();i!=enabled_actions.end();++i) + if(*i==name){enabled_actions.erase(i);break;} + for(auto i=enabled_buttons.begin();i!=enabled_buttons.end();++i) + if(*i==name){enabled_buttons.erase(i);break;} + setupWidget(); } +void qmpMainWindow::setFuncState(std::string name,bool state) +{mfunc[name].setChecked(state);} +void qmpMainWindow::setFuncEnabled(std::string name,bool enable) +{mfunc[name].setEnabled(enable);} + bool qmpMainWindow::isDarkTheme() { if(!qmpSettingsWindow::getSettingsIntf()->value("Behavior/IconTheme",0).toInt()) @@ -642,12 +609,7 @@ bool qmpMainWindow::isDarkTheme() else return 2-qmpSettingsWindow::getSettingsIntf()->value("Behavior/IconTheme",0).toInt(); } -void qmpMainWindow::onfnA1() -{ - infow->show(); -} - -void qmpMainWindow::onfnA2() +void qmpMainWindow::startRender() { if(singleFS)player->fluidDeinitialize(); #ifdef _WIN32 @@ -668,12 +630,7 @@ void qmpMainWindow::onfnA2() renderTh=new std::thread(&CMidiPlayer::rendererThread,player); } -void qmpMainWindow::onfnA3() -{ - player->playerPanic(); -} - -void qmpMainWindow::onfnA4() +void qmpMainWindow::reloadSynth() { player->fluidDeinitialize();player->fluidPreInitialize();playerSetup();player->fluidInitialize(); for(int i=settingsw->getSFWidget()->rowCount()-1;i>=0;--i){if(!((QCheckBox*)settingsw->getSFWidget()->cellWidget(i,0))->isChecked())continue; @@ -681,28 +638,85 @@ void qmpMainWindow::onfnA4() } } +std::vector& qmpMainWindow::getWidgets(int w) +{return w?enabled_actions:enabled_buttons;} +std::map& qmpMainWindow::getFunc() +{return mfunc;} + +void qmpMainWindow::setupWidget() +{ + QListw=ui->buttonwidget->findChildren("",Qt::FindDirectChildrenOnly); + for(unsigned i=0;ia=ui->lbFileName->actions(); + for(unsigned i=0;ilbFileName->removeAction(a[i]); + delete a[i]; + } + for(unsigned i=0;ibuttonwidget->layout()->addWidget(pb); + mfunc[enabled_buttons[i]].setAssignedControl(pb); + connect(pb,SIGNAL(onClick(std::string)),this,SLOT(funcReflector(std::string))); + } + for(unsigned i=0;ilbFileName->addAction(a); + mfunc[enabled_actions[i]].setAssignedControl(a); + connect(a,SIGNAL(onClick(std::string)),this,SLOT(funcReflector(std::string))); + } + ui->buttonwidget->layout()->setAlignment(Qt::AlignLeft); +} + void qmpMainWindow::on_pbSettings_clicked() { if(ui->pbSettings->isChecked())settingsw->show();else settingsw->close(); } +void qmpMainWindow::funcReflector(std::string reflt) +{ + if(mfunc[reflt].isCheckable()) + { + mfunc[reflt].setChecked(!mfunc[reflt].isChecked()); + if(mfunc[reflt].isChecked()) + mfunc[reflt].i()->show(); + else + mfunc[reflt].i()->close(); + } + else mfunc[reflt].i()->show(); +} + void qmpMainWindow::on_pushButton_clicked() { helpw->show(); } -void qmpMainWindow::on_pbVisualization_clicked() +qmpFuncPrivate::qmpFuncPrivate(qmpFuncBaseIntf *i,std::string _desc,const char *icon,int iconlen,bool checkable,bool _isv): + _i(i),des(_desc),_checkable(checkable),visual(_isv) { - if(ui->pbVisualization->isChecked()) + if(icon) { - bool havevis=false; - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->show(),havevis=true; - if(!havevis) - { - QMessageBox::information(this,tr("No visualization plugin enabled"),tr("No visualization plugin enabled. Please enable at least one in plugin settings.")); - ui->pbVisualization->setChecked(false); - } - } - else - {for(int i=0;i<16;++i)if(VIs[i])VIs[i]->close();} + QImage img; + if(icon[0]==':'&&icon[1]=='/'||icon[0]=='q'&&icon[1]=='r'&&icon[2]=='c') + img=QImage(QString(icon)); + else + img.loadFromData((uchar*)icon,iconlen); + QPixmap pixm;pixm.convertFromImage(img); + _icon=QIcon(pixm); + }else _icon=QIcon(); + checked=false; + asgna=NULL;asgnb=NULL; } diff --git a/qmidiplayer-desktop/qmpmainwindow.hpp b/qmidiplayer-desktop/qmpmainwindow.hpp index 0b835e7..395b833 100644 --- a/qmidiplayer-desktop/qmpmainwindow.hpp +++ b/qmidiplayer-desktop/qmpmainwindow.hpp @@ -10,11 +10,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include "../core/qmpmidiplay.hpp" #include "qmpplugin.hpp" #include "qmpplistwindow.hpp" @@ -25,6 +27,7 @@ #include "qmphelpwindow.hpp" #define getThemedIcon(x) (qmpMainWindow::getInstance()->isDarkTheme()?QString(x).insert(QString(x).lastIndexOf('.'),"_i"):QString(x)) +#define getThemedIconc(x) ((qmpMainWindow::getInstance()->isDarkTheme()?QString(x).insert(QString(x).lastIndexOf('.'),"_i"):QString(x)).toStdString().c_str()) namespace Ui { class qmpMainWindow; @@ -48,6 +51,72 @@ class QClickableSlider:public QSlider } }; +class QReflectiveAction:public QAction +{ + Q_OBJECT + private: + std::string reflt; + signals: + void onClick(std::string s); + private slots: + void triggerslot(){ + emit(onClick(reflt)); + } + public: + explicit QReflectiveAction(const QIcon& icon,const QString& text,const std::string& ref): + QAction(icon,text),reflt(ref){ + connect(this,SIGNAL(triggered(bool)),this,SLOT(triggerslot())); + } +}; + +class QReflectivePushButton:public QPushButton +{ + Q_OBJECT + private: + std::string reflt; + signals: + void onClick(std::string s); + private slots: + void clickslot(){ + emit(onClick(reflt)); + } + public: + explicit QReflectivePushButton(const QIcon& icon,const QString& text,const std::string& ref): + QPushButton(icon,""),reflt(ref){ + connect(this,SIGNAL(clicked(bool)),this,SLOT(clickslot())); + setToolTip(text); + } +}; + +class qmpFuncPrivate +{ + private: + qmpFuncBaseIntf* _i; + QIcon _icon; + std::string des; + bool _checkable,checked,visual; + QReflectiveAction* asgna; + QReflectivePushButton* asgnb; + public: + qmpFuncPrivate(){} + qmpFuncPrivate(qmpFuncBaseIntf* i,std::string _desc,const char* icon,int iconlen,bool checkable,bool _isv); + ~qmpFuncPrivate(){asgna=NULL;asgnb=NULL;} + qmpFuncBaseIntf* i(){return _i;} + void setAssignedControl(QReflectiveAction* a){asgna=a;if(!a)return;asgna->setCheckable(_checkable);asgna->setChecked(checked);} + void setAssignedControl(QReflectivePushButton* a){asgnb=a;if(!a)return;asgnb->setCheckable(_checkable);asgnb->setChecked(checked);} + const QIcon& icon(){return _icon;} + const std::string& desc(){return des;} + bool isVisualization(){return visual;} + bool isCheckable(){return _checkable;} + bool isChecked(){return checked;} + void setEnabled(bool e){if(asgna)asgna->setEnabled(e);if(asgnb)asgnb->setEnabled(e);} + void setChecked(bool _c){checked=_c;if(asgna)asgna->setChecked(checked);if(asgnb)asgnb->setChecked(checked);} +}; + +class qmpRenderFunc; +class qmpPanicFunc; +class qmpReloadSynthFunc; + class qmpMainWindow:public QMainWindow { Q_OBJECT @@ -71,9 +140,18 @@ class qmpMainWindow:public QMainWindow uint32_t getPlaybackPercentage(); void playerSeek(uint32_t percentage); int pharseArgs(); - int registerVisualizationIntf(qmpVisualizationIntf* intf); - void unregisterVisualizationIntf(int handle); + void registerVisualizationIntf(qmpVisualizationIntf* intf,std::string name,std::string desc,const char* icon,int iconlen); + void unregisterVisualizationIntf(std::string name); + void registerFunctionality(qmpFuncBaseIntf* i,std::string name,std::string desc,const char* icon,int iconlen,bool checkable,bool isv=false); + void unregisterFunctionality(std::string name); + void setFuncState(std::string name,bool state); + void setFuncEnabled(std::string name,bool enable); bool isDarkTheme(); + void startRender(); + void reloadSynth(); + void setupWidget(); + std::vector& getWidgets(int w); + std::map& getFunc(); private slots: void on_pbPlayPause_clicked(); @@ -82,22 +160,13 @@ class qmpMainWindow:public QMainWindow void on_hsTimer_sliderReleased(); void on_vsMasterVol_valueChanged(); void on_pbStop_clicked(); - void on_pbPList_clicked(); void on_pbPrev_clicked(); void on_pbNext_clicked(); - void on_pbChannels_clicked(); - void on_pbEfx_clicked(); void on_lbFileName_customContextMenuRequested(const QPoint &pos); void on_pbSettings_clicked(); - void onfnA1(); - void onfnA2(); - void onfnA3(); - void onfnA4(); - + void funcReflector(std::string reflt); void on_pushButton_clicked(); - void on_pbVisualization_clicked(); - public slots: void dialogClosed(); void selectionChanged(); @@ -118,9 +187,12 @@ class qmpMainWindow:public QMainWindow QPointer infow; QPointer settingsw; QPointer helpw; - qmpVisualizationIntf* VIs[16]; + std::map mfunc; + qmpRenderFunc* renderf; + qmpPanicFunc* panicf; + qmpReloadSynthFunc* reloadsynf; + std::vector enabled_buttons,enabled_actions; - QAction *fnA1,*fnA2,*fnA3,*fnA4; void onfnChanged(); void playerSetup(); @@ -129,4 +201,32 @@ class qmpMainWindow:public QMainWindow public: static qmpMainWindow* getInstance(){return ref;} }; +class qmpRenderFunc:public qmpFuncBaseIntf +{ + private: + qmpMainWindow *p; + public: + qmpRenderFunc(qmpMainWindow *par){p=par;} + void show(){p->startRender();} + void close(){} +}; +class qmpPanicFunc:public qmpFuncBaseIntf +{ + private: + qmpMainWindow *p; + public: + qmpPanicFunc(qmpMainWindow *par){p=par;} + void show(){p->getPlayer()->playerPanic();} + void close(){} +}; +class qmpReloadSynthFunc:public qmpFuncBaseIntf +{ + private: + qmpMainWindow *p; + public: + qmpReloadSynthFunc(qmpMainWindow *par){p=par;} + void show(){p->reloadSynth();} + void close(){} +}; + #endif // QMPMAINWINDOW_H diff --git a/qmidiplayer-desktop/qmpmainwindow.ui b/qmidiplayer-desktop/qmpmainwindow.ui index 10ead67..8f41b4b 100644 --- a/qmidiplayer-desktop/qmpmainwindow.ui +++ b/qmidiplayer-desktop/qmpmainwindow.ui @@ -176,360 +176,230 @@ - + + + 0 + - - - 0 + + + + 0 + 0 + - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 34 - - - - - - - - :/img/play.png:/img/play.png - - - - 32 - 32 - - - - - - - - - 0 - 0 - - - - - 0 - 34 - - - - - 16777215 - 34 - - - - - - - - :/img/stop.png:/img/stop.png - - - - 32 - 32 - - - - - - - - - 0 - 0 - - - - - 0 - 34 - - - - - 16777215 - 34 - - - - - - - - :/img/prev.png:/img/prev.png - - - - 32 - 32 - - - - - - - - - 0 - 0 - - - - - 0 - 34 - - - - - 16777215 - 34 - - - - - - - - :/img/next.png:/img/next.png - - - - 32 - 32 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 32 - 32 - - - - - - - - - 0 - 0 - - - - - 0 - 34 - - - - - 16777215 - 34 - - - - - - - - :/img/settings.png:/img/settings.png - - - - 32 - 32 - - - - true - - - - + + + 0 + 36 + + + + + 16777215 + 36 + + + + + + + + :/img/play.png:/img/play.png + + + + 32 + 32 + + + - - - - - - 0 - 0 - - - - - 16777215 - 36 - - - - text-align:left - - - Channels - - - - :/img/channel.png:/img/channel.png - - - - 32 - 32 - - - - true - - - - - - - - 0 - 0 - - - - - 16777215 - 36 - - - - text-align:left - - - Playlist - - - - :/img/list.png:/img/list.png - - - - 32 - 32 - - - - true - - - false - - - false - - - - - - - - 0 - 0 - - - - - 16777215 - 36 - - - - text-align:left - - - Effects - - - - :/img/effects.png:/img/effects.png - - - - 32 - 32 - - - - true - - - - - - - - 0 - 0 - - - - - 16777215 - 36 - - - - text-align:left - - - Visualization - - - - :/img/visualization.png:/img/visualization.png - - - - 32 - 32 - - - - true - - - - + + + + 0 + 0 + + + + + 0 + 36 + + + + + 16777215 + 36 + + + + + + + + :/img/stop.png:/img/stop.png + + + + 32 + 32 + + + + + + + + + 0 + 0 + + + + + 0 + 36 + + + + + 16777215 + 36 + + + + + + + + :/img/prev.png:/img/prev.png + + + + 32 + 32 + + + + + + + + + 0 + 0 + + + + + 0 + 36 + + + + + 16777215 + 36 + + + + + + + + :/img/next.png:/img/next.png + + + + 32 + 32 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 32 + 32 + + + + + + + + + 0 + 0 + + + + + 0 + 36 + + + + + 16777215 + 36 + + + + + + + + :/img/settings.png:/img/settings.png + + + + 32 + 32 + + + + true + + + + + + + 0 + 32 + + + + + 0 + + + 6 + + + 0 + + + 6 + + + + diff --git a/qmidiplayer-desktop/qmpplistwindow.cpp b/qmidiplayer-desktop/qmpplistwindow.cpp index 799f99a..b6b133e 100644 --- a/qmidiplayer-desktop/qmpplistwindow.cpp +++ b/qmidiplayer-desktop/qmpplistwindow.cpp @@ -22,7 +22,6 @@ qmpPlistWindow::qmpPlistWindow(QWidget *parent) : setButtonHeight(ui->pbClear,36);setButtonHeight(ui->pbLoad,36); setButtonHeight(ui->pbRemove,36);setButtonHeight(ui->pbRepeat,36); setButtonHeight(ui->pbSave,36);setButtonHeight(ui->pbShuffle,36); - connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed())); connect(this,SIGNAL(selectionChanging()),parent,SLOT(selectionChanged())); repeat=0;shuffle=0; if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/RestorePlaylist","").toInt()) @@ -69,10 +68,24 @@ qmpPlistWindow::qmpPlistWindow(QWidget *parent) : ui->pbAddFolder->setIcon(QIcon(getThemedIcon(":/img/addfolder.png"))); ui->pbSave->setIcon(QIcon(getThemedIcon(":/img/save.png"))); ui->pbLoad->setIcon(QIcon(getThemedIcon(":/img/load.png"))); + qmpMainWindow::getInstance()->registerFunctionality( + plistf=new qmpPlistFunc(this), + std::string("Playlist"), + tr("Playlist").toStdString(), + getThemedIconc(":/img/list.png"), + 0, + true + ); + if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListW",QByteArray()).toByteArray().length()) + restoreGeometry(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListW",QRect(-999,-999,-999,-999)).toByteArray()); + if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListWShown",0).toInt()) + {show();qmpMainWindow::getInstance()->setFuncState("Playlist",true);} } qmpPlistWindow::~qmpPlistWindow() { + qmpMainWindow::getInstance()->unregisterFunctionality("Playlist"); + delete plistf; delete ui; } @@ -82,6 +95,8 @@ void qmpPlistWindow::showEvent(QShowEvent *event) { qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListWShown",1); } + if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListW",QByteArray()).toByteArray().length()) + restoreGeometry(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListW",QRect(-999,-999,-999,-999)).toByteArray()); event->accept(); } @@ -104,7 +119,7 @@ void qmpPlistWindow::closeEvent(QCloseEvent *event) plist->sync(); delete plist; } - emit dialogClosing(); + qmpMainWindow::getInstance()->setFuncState("Playlist",false); event->accept(); } @@ -112,8 +127,9 @@ void qmpPlistWindow::moveEvent(QMoveEvent *event) { if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) { - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListW",event->pos()); + qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListW",saveGeometry()); } + event->accept(); } void qmpPlistWindow::dropEvent(QDropEvent *event) @@ -327,3 +343,13 @@ void qmpPlistWindow::on_pbLoad_clicked() } delete plist; } +qmpPlistFunc::qmpPlistFunc(qmpPlistWindow *par) +{p=par;} +void qmpPlistFunc::show() +{ + p->show(); +} +void qmpPlistFunc::close() +{ + p->close(); +} diff --git a/qmidiplayer-desktop/qmpplistwindow.hpp b/qmidiplayer-desktop/qmpplistwindow.hpp index b1deab4..9e78a8a 100644 --- a/qmidiplayer-desktop/qmpplistwindow.hpp +++ b/qmidiplayer-desktop/qmpplistwindow.hpp @@ -8,11 +8,24 @@ #include #include #include +#include "../include/qmpcorepublic.hpp" namespace Ui { class qmpPlistWindow; } +class qmpPlistWindow; + +class qmpPlistFunc:public qmpFuncBaseIntf +{ + private: + qmpPlistWindow* p; + public: + qmpPlistFunc(qmpPlistWindow *par); + void show(); + void close(); +}; + class qmpPlistWindow : public QDialog { Q_OBJECT @@ -35,7 +48,6 @@ class qmpPlistWindow : public QDialog void insertItem(QString i); void insertItems(QStringList il); signals: - void dialogClosing(); void selectionChanging(); public slots: @@ -51,6 +63,7 @@ class qmpPlistWindow : public QDialog void on_pbLoad_clicked(); private: + qmpPlistFunc* plistf; Ui::qmpPlistWindow *ui; int shuffle,repeat;//rep 0=off 1=one 2=all }; diff --git a/qmidiplayer-desktop/qmpplugin.cpp b/qmidiplayer-desktop/qmpplugin.cpp index 5b4dd11..7ff305c 100644 --- a/qmidiplayer-desktop/qmpplugin.cpp +++ b/qmidiplayer-desktop/qmpplugin.cpp @@ -174,6 +174,7 @@ std::string qmpPluginAPI::getChannelPresetString(int ch) } return std::string(ret); } +bool qmpPluginAPI::isDarkTheme(){return qmw?qmw->isDarkTheme():false;} void qmpPluginAPI::discardCurrentEvent(){if(qmw&&qmw->getPlayer())qmw->getPlayer()->discardCurrentEvent();} void qmpPluginAPI::commitEventChange(SEventCallBackData d){if(qmw&&qmw->getPlayer())qmw->getPlayer()->commitEventChange(d);} @@ -187,10 +188,10 @@ int qmpPluginAPI::registerEventReaderIntf(IMidiCallBack *cb,void *userdata) {return qmw->getPlayer()->setEventReaderCB(cb,userdata);} void qmpPluginAPI::unregisterEventReaderIntf(int intfhandle) {qmw->getPlayer()->unsetEventReaderCB(intfhandle);} -int qmpPluginAPI::registerVisualizationIntf(qmpVisualizationIntf* intf) -{return qmw->registerVisualizationIntf(intf);} -void qmpPluginAPI::unregisterVisualizationIntf(int intfhandle) -{qmw->unregisterVisualizationIntf(intfhandle);} +void qmpPluginAPI::registerVisualizationIntf(qmpVisualizationIntf* intf,std::string name,std::string desc,const char* icon,int iconlen) +{qmw->registerVisualizationIntf(intf,name,desc,icon,iconlen);} +void qmpPluginAPI::unregisterVisualizationIntf(std::string name) +{qmw->unregisterVisualizationIntf(name);} int qmpPluginAPI::registerFileReadFinishedHandlerIntf(IMidiCallBack* cb,void* userdata) {return qmw->getPlayer()->setFileReadFinishedCB(cb,userdata);} void qmpPluginAPI::unregisterFileReadFinishedHandlerIntf(int intfhandle) diff --git a/qmidiplayer-desktop/qmpsettingswindow.cpp b/qmidiplayer-desktop/qmpsettingswindow.cpp index 72d1cb5..abd8213 100644 --- a/qmidiplayer-desktop/qmpsettingswindow.cpp +++ b/qmidiplayer-desktop/qmpsettingswindow.cpp @@ -28,10 +28,12 @@ qmpSettingsWindow::qmpSettingsWindow(QWidget *parent) : ui->pbRemove->setIcon(QIcon(getThemedIcon(":/img/remove.png"))); ui->pbDown->setIcon(QIcon(getThemedIcon(":/img/down.png"))); ui->pbUp->setIcon(QIcon(getThemedIcon(":/img/up.png"))); + cw=new qmpCustomizeWindow(this); } qmpSettingsWindow::~qmpSettingsWindow() { + delete cw; delete settings;settings=NULL; delete ui; } @@ -654,3 +656,13 @@ void qmpSettingsWindow::setOptionEnumInt(std::string key,int val) if(customOptions[key].widget) ((QComboBox*)customOptions[key].widget)->setCurrentIndex(val); } + +void qmpSettingsWindow::on_pbCustomizeTb_clicked() +{ + cw->launch(0); +} + +void qmpSettingsWindow::on_pbCustomizeAct_clicked() +{ + cw->launch(1); +} diff --git a/qmidiplayer-desktop/qmpsettingswindow.hpp b/qmidiplayer-desktop/qmpsettingswindow.hpp index 15c720a..16faa0f 100644 --- a/qmidiplayer-desktop/qmpsettingswindow.hpp +++ b/qmidiplayer-desktop/qmpsettingswindow.hpp @@ -12,6 +12,7 @@ #include #include #include "qmpplugin.hpp" +#include "qmpcustomizewindow.hpp" namespace Ui { class qmpSettingsWindow; @@ -105,12 +106,17 @@ class qmpSettingsWindow:public QDialog void on_cbAutoBS_stateChanged(); + void on_pbCustomizeTb_clicked(); + + void on_pbCustomizeAct_clicked(); + private: Ui::qmpSettingsWindow *ui; void settingsUpdate(); std::map customOptions; std::map customOptPages; void updateCustomOptions(); + qmpCustomizeWindow *cw; static QSettings *settings; static QComboBox* outwidget; public: diff --git a/qmidiplayer-desktop/qmpsettingswindow.ui b/qmidiplayer-desktop/qmpsettingswindow.ui index aa96869..6497d1c 100644 --- a/qmidiplayer-desktop/qmpsettingswindow.ui +++ b/qmidiplayer-desktop/qmpsettingswindow.ui @@ -23,7 +23,7 @@ - 0 + 3 @@ -638,6 +638,42 @@ + + + + + + Customize toolbar + + + + + + + Customize + + + + + + + + + + + Customize actions + + + + + + + Customize + + + + + diff --git a/visualization/qmpvisualization.cpp b/visualization/qmpvisualization.cpp index 8bc0ecb..9a8f675 100644 --- a/visualization/qmpvisualization.cpp +++ b/visualization/qmpvisualization.cpp @@ -754,7 +754,7 @@ void qmpVisualization::init() rendererTh=NULL;playing=false; memset(spectra,0,sizeof(spectra)); memset(spectrar,0,sizeof(spectrar)); - hvif=api->registerVisualizationIntf(vi); + api->registerVisualizationIntf(vi,"Visualization","Visualization",api->isDarkTheme()?":/img/visualization_i.png":":/img/visualization.png",0); herif=api->registerEventReaderIntf(cb,NULL); hehif=api->registerEventHandlerIntf(hcb,NULL); hfrf=api->registerFileReadFinishedHandlerIntf(frcb,NULL); @@ -828,7 +828,7 @@ void qmpVisualization::deinit() { if(!api)return;close();tspool.clear(); for(unsigned i=0;iunregisterVisualizationIntf(hvif); + api->unregisterVisualizationIntf("Visualization"); api->unregisterEventReaderIntf(herif); api->unregisterEventHandlerIntf(hehif); api->unregisterFileReadFinishedHandlerIntf(hfrf); diff --git a/visualization/qmpvisualization.hpp b/visualization/qmpvisualization.hpp index 28e9b52..6518376 100644 --- a/visualization/qmpvisualization.hpp +++ b/visualization/qmpvisualization.hpp @@ -70,7 +70,7 @@ class qmpVisualization:public qmpPluginIntf uint32_t ctc,ctk,fintk,elb; double etps; bool shouldclose,playing; - int hvif,herif,hehif,hfrf; + int herif,hehif,hfrf; std::vector>tspool; int traveld[16][128];bool notestatus[16][128],lastnotestatus[16][128]; int spectra[16][128],spectrar[16][128]; -- cgit v1.2.3