aboutsummaryrefslogtreecommitdiff
path: root/qmidiplayer-desktop
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2017-10-18 11:40:51 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2017-10-18 11:40:51 +0800
commitd985112164bd2bfeca0c895abb523d45f0e065bb (patch)
tree3a44ae92001c2a8cac89eb46fe74248249d6e0ea /qmidiplayer-desktop
parent48dd5f9fb11f0a2e69291271d9140ebcec640117 (diff)
downloadQMidiPlayer-d985112164bd2bfeca0c895abb523d45f0e065bb.tar.xz
API changes and crash fixes.
Details in the changelog.
Diffstat (limited to 'qmidiplayer-desktop')
-rw-r--r--qmidiplayer-desktop/main.cpp2
-rw-r--r--qmidiplayer-desktop/qmpchannelswindow.hpp2
-rw-r--r--qmidiplayer-desktop/qmpmainwindow.cpp84
-rw-r--r--qmidiplayer-desktop/qmpmainwindow.hpp34
-rw-r--r--qmidiplayer-desktop/qmpplugin.cpp18
-rw-r--r--qmidiplayer-desktop/qmpsettingswindow.cpp6
6 files changed, 99 insertions, 47 deletions
diff --git a/qmidiplayer-desktop/main.cpp b/qmidiplayer-desktop/main.cpp
index 2ac275e..c7167d0 100644
--- a/qmidiplayer-desktop/main.cpp
+++ b/qmidiplayer-desktop/main.cpp
@@ -23,6 +23,8 @@
int main(int argc,char **argv)
{
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication a(argc,argv);
QTranslator qtTranslator;
qtTranslator.load("qt_"+QLocale::system().name(),
diff --git a/qmidiplayer-desktop/qmpchannelswindow.hpp b/qmidiplayer-desktop/qmpchannelswindow.hpp
index c7630fe..008598c 100644
--- a/qmidiplayer-desktop/qmpchannelswindow.hpp
+++ b/qmidiplayer-desktop/qmpchannelswindow.hpp
@@ -59,7 +59,7 @@ class QDCComboBox:public QComboBox
void indexChangedSlot(int idx){emit(onChange(id,idx));}
};
-class qmpCWNoteOnCB:public QObject,public IMidiCallBack
+class qmpCWNoteOnCB:public QObject,public ICallBack
{
Q_OBJECT
public:
diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp
index b6e1267..dbec402 100644
--- a/qmidiplayer-desktop/qmpmainwindow.cpp
+++ b/qmidiplayer-desktop/qmpmainwindow.cpp
@@ -1,5 +1,6 @@
#include <cstdio>
#include <cmath>
+#include <functional>
#include <QUrl>
#include <QFileInfo>
#include <QMimeData>
@@ -22,19 +23,6 @@ char* wcsto8bit(const wchar_t* s)
WideCharToMultiByte(CP_OEMCP,WC_NO_BEST_FIT_CHARS,s,-1,c,size,0,0);
return c;
}
-#define LOAD_FILE \
- {\
- 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);\
- }
-#else
-#define LOAD_FILE \
- {\
- 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
#define UPDATE_INTERVAL 66
@@ -240,7 +228,7 @@ void qmpMainWindow::updateWidgets()
if(!plistw->getRepeat())
{
timer->stop();stopped=true;playing=false;
- for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->stop();
+ invokeCallback("main.stop",NULL);
setFuncEnabled("Render",stopped);setFuncEnabled("ReloadSynth",stopped);
chnlw->resetAcitivity();
player->playerDeinit();playerTh->join();
@@ -288,7 +276,7 @@ void qmpMainWindow::switchTrack(QString s)
setFuncEnabled("Render",stopped);setFuncEnabled("ReloadSynth",stopped);
ui->pbPlayPause->setIcon(QIcon(getThemedIcon(":/img/pause.svg")));
timer->stop();player->playerDeinit();
- for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->stop();
+ invokeCallback("main.stop",NULL);
if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;}
player->playerPanic(true);
ui->hsTimer->setValue(0);
@@ -296,12 +284,12 @@ void qmpMainWindow::switchTrack(QString s)
QString fns=s;setWindowTitle(QUrl::fromLocalFile(fns).fileName().left(QUrl::fromLocalFile(fns).fileName().lastIndexOf('.'))+" - QMidiPlayer");
ui->lbFileName->setText(QUrl::fromLocalFile(fns).fileName().left(QUrl::fromLocalFile(fns).fileName().lastIndexOf('.')));
onfnChanged();
- LOAD_FILE;
+ if(!loadFile(fns))return;
char ts[100];
sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
ui->lbFinTime->setText(ts);
player->playerInit();
- for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->start();
+ invokeCallback("main.start",NULL);
player->fluid()->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
playerTh=new std::thread(&CMidiPlayer::playerThread,player);
@@ -379,6 +367,23 @@ void qmpMainWindow::loadSoundFont(IFluidSettings *fs)
#endif
}
}
+int qmpMainWindow::loadFile(QString fns)
+{
+#ifdef _WIN32
+ char* c=wcsto8bit(fns.toStdWString().c_str());
+#else
+ std::string s=fns.toStdString();
+ const char* c=s.c_str();
+#endif
+ int ret=1;
+ invokeCallback("main.reset",NULL);
+ if(!player->playerLoadFile(c))
+ {QMessageBox::critical(this,tr("Error"),tr("%1 is not a valid midi file.").arg(fns));ret=0;}
+#ifdef _WIN32
+ free(c);
+#endif
+ return ret;
+}
void qmpMainWindow::on_pbPlayPause_clicked()
{
@@ -394,12 +399,12 @@ void qmpMainWindow::on_pbPlayPause_clicked()
}setWindowTitle(QUrl::fromLocalFile(fns).fileName().left(QUrl::fromLocalFile(fns).fileName().lastIndexOf('.'))+" - QMidiPlayer");
ui->lbFileName->setText(QUrl::fromLocalFile(fns).fileName().left(QUrl::fromLocalFile(fns).fileName().lastIndexOf('.')));
onfnChanged();
- LOAD_FILE;
+ if(!loadFile(fns))return;
char ts[100];
sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
ui->lbFinTime->setText(ts);
player->playerInit();
- for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->start();
+ invokeCallback("main.start",NULL);
player->fluid()->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
playerTh=new std::thread(&CMidiPlayer::playerThread,player);
@@ -423,7 +428,7 @@ void qmpMainWindow::on_pbPlayPause_clicked()
player->setResumed();
}
player->setTCpaused(!playing);
- for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->pause();
+ invokeCallback("main.pause",NULL);
}
ui->pbPlayPause->setIcon(QIcon(getThemedIcon(playing?":/img/pause.svg":":/img/play.svg")));
}
@@ -490,7 +495,7 @@ void qmpMainWindow::on_pbStop_clicked()
if(!stopped)
{
timer->stop();stopped=true;playing=false;
- for(auto i=mfunc.begin();i!=mfunc.end();++i)if(i->second.isVisualization())((qmpVisualizationIntf*)(i->second.i()))->stop();
+ invokeCallback("main.stop",NULL);
player->playerDeinit();
setFuncEnabled("Render",stopped);setFuncEnabled("ReloadSynth",stopped);
player->playerPanic(true);chnlw->resetAcitivity();
@@ -543,19 +548,32 @@ void qmpMainWindow::onfnChanged()
ui->lbFileName->setFont(f);
}
-void qmpMainWindow::registerVisualizationIntf(qmpVisualizationIntf* intf,std::string name,std::string desc,const char* icon,int iconlen)
+int qmpMainWindow::registerUIHook(std::string e,ICallBack *callback,void* userdat)
+{
+ std::map<int,std::pair<qmpCallBack,void*>>& m=muicb[e];
+ int id=0;
+ if(m.size())id=m.rbegin()->first+1;
+ m[id]=std::make_pair(qmpCallBack(callback),userdat);
+ return id;
+}
+int qmpMainWindow::registerUIHook(std::string e,callback_t callback,void *userdat)
{
- registerFunctionality(intf,name,desc,icon,iconlen,true,true);
+ std::map<int,std::pair<qmpCallBack,void*>>& m=muicb[e];
+ int id=0;
+ if(m.size())id=m.rbegin()->first+1;
+ m[id]=std::make_pair(qmpCallBack(callback),userdat);
+ return id;
}
-void qmpMainWindow::unregisterVisualizationIntf(std::string name)
+void qmpMainWindow::unregisterUIHook(std::string e,int hook)
{
- unregisterFunctionality(name);
+ std::map<int,std::pair<qmpCallBack,void*>>& m=muicb[e];
+ m.erase(hook);
}
-void qmpMainWindow::registerFunctionality(qmpFuncBaseIntf *i,std::string name,std::string desc,const char *icon,int iconlen,bool checkable,bool isv)
+void qmpMainWindow::registerFunctionality(qmpFuncBaseIntf *i,std::string name,std::string desc,const char *icon,int iconlen,bool checkable)
{
if(mfunc.find(name)!=mfunc.end())return;
- mfunc[name]=qmpFuncPrivate(i,desc,icon,iconlen,checkable,isv);
+ mfunc[name]=qmpFuncPrivate(i,desc,icon,iconlen,checkable);
}
void qmpMainWindow::unregisterFunctionality(std::string name)
@@ -676,6 +694,14 @@ void qmpMainWindow::setupWidget()
ui->buttonwidget->layout()->setAlignment(Qt::AlignLeft);
}
+void qmpMainWindow::invokeCallback(std::string cat,void* callerdat)
+{
+ std::map<int,std::pair<qmpCallBack,void*>> *mp;
+ mp=&muicb[cat];
+ for(auto&i:*mp)
+ i.second.first(callerdat,i.second.second);
+}
+
void qmpMainWindow::on_pbSettings_clicked()
{
if(ui->pbSettings->isChecked())settingsw->show();else settingsw->close();
@@ -699,8 +725,8 @@ void qmpMainWindow::on_pushButton_clicked()
helpw->show();
}
-qmpFuncPrivate::qmpFuncPrivate(qmpFuncBaseIntf *i,std::string _desc,const char *icon,int iconlen,bool checkable,bool _isv):
- _i(i),des(_desc),_checkable(checkable),visual(_isv)
+qmpFuncPrivate::qmpFuncPrivate(qmpFuncBaseIntf *i,std::string _desc,const char *icon,int iconlen,bool checkable):
+ _i(i),des(_desc),_checkable(checkable)
{
if(icon)
{
diff --git a/qmidiplayer-desktop/qmpmainwindow.hpp b/qmidiplayer-desktop/qmpmainwindow.hpp
index c713ca3..a70083a 100644
--- a/qmidiplayer-desktop/qmpmainwindow.hpp
+++ b/qmidiplayer-desktop/qmpmainwindow.hpp
@@ -18,6 +18,7 @@
#include <chrono>
#include <future>
#include <map>
+#include <unordered_map>
#include "../core/qmpmidiplay.hpp"
#include "qmpplugin.hpp"
#include "qmpplistwindow.hpp"
@@ -95,19 +96,18 @@ class qmpFuncPrivate
qmpFuncBaseIntf* _i;
QIcon _icon;
std::string des;
- bool _checkable,checked,visual;
+ bool _checkable,checked;
QReflectiveAction* asgna;
QReflectivePushButton* asgnb;
public:
qmpFuncPrivate(){}
- qmpFuncPrivate(qmpFuncBaseIntf* i,std::string _desc,const char* icon,int iconlen,bool checkable,bool _isv);
+ qmpFuncPrivate(qmpFuncBaseIntf* i,std::string _desc,const char* icon,int iconlen,bool checkable);
~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);}
@@ -118,6 +118,24 @@ class qmpRenderFunc;
class qmpPanicFunc;
class qmpReloadSynthFunc;
+class qmpCallBack
+{
+ private:
+ int t;
+ ICallBack* cbc;
+ callback_t cbf;
+ public:
+ qmpCallBack(){t=-1;cbc=NULL;cbf=NULL;}
+ qmpCallBack(ICallBack* _cb){t=0;cbc=_cb;cbf=NULL;}
+ qmpCallBack(callback_t _cb){t=1;cbf=_cb;cbc=NULL;}
+ void operator ()(void* cbd,void* usrd)
+ {
+ if(t<0)return;
+ if(t)cbf(cbd,usrd);
+ else cbc->callBack(cbd,usrd);
+ }
+};
+
class qmpMainWindow:public QMainWindow
{
Q_OBJECT
@@ -140,16 +158,18 @@ class qmpMainWindow:public QMainWindow
uint32_t getPlaybackPercentage();
void playerSeek(uint32_t percentage);
int pharseArgs();
- 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 registerFunctionality(qmpFuncBaseIntf* i,std::string name,std::string desc,const char* icon,int iconlen,bool checkable);
void unregisterFunctionality(std::string name);
+ int registerUIHook(std::string e,ICallBack* callback,void* userdat);
+ int registerUIHook(std::string e,callback_t callback,void* userdat);
+ void unregisterUIHook(std::string e,int hook);
void setFuncState(std::string name,bool state);
void setFuncEnabled(std::string name,bool enable);
bool isDarkTheme();
void startRender();
void reloadSynth();
void setupWidget();
+ void invokeCallback(std::string cat,void *callerdat);
std::vector<std::string>& getWidgets(int w);
std::map<std::string,qmpFuncPrivate>& getFunc();
@@ -191,6 +211,7 @@ class qmpMainWindow:public QMainWindow
QPointer<qmpSettingsWindow> settingsw;
QPointer<qmpHelpWindow> helpw;
std::map<std::string,qmpFuncPrivate> mfunc;
+ std::unordered_map<std::string,std::map<int,std::pair<qmpCallBack,void*>>> muicb;
qmpRenderFunc* renderf;
qmpPanicFunc* panicf;
qmpReloadSynthFunc* reloadsynf;
@@ -199,6 +220,7 @@ class qmpMainWindow:public QMainWindow
void onfnChanged();
void playerSetup(IFluidSettings *fs);
void loadSoundFont(IFluidSettings *fs);
+ int loadFile(QString fns);
private:
static qmpMainWindow* ref;
diff --git a/qmidiplayer-desktop/qmpplugin.cpp b/qmidiplayer-desktop/qmpplugin.cpp
index 6eca257..4c0ee7c 100644
--- a/qmidiplayer-desktop/qmpplugin.cpp
+++ b/qmidiplayer-desktop/qmpplugin.cpp
@@ -193,27 +193,29 @@ void qmpPluginAPI::registerMidiOutDevice(qmpMidiOutDevice *dev, std::string name
{qmw->getPlayer()->registerMidiOutDevice(dev,name);}
void qmpPluginAPI::unregisterMidiOutDevice(std::string name)
{qmw->getPlayer()->unregisterMidiOutDevice(name);}
-int qmpPluginAPI::registerEventHandlerIntf(IMidiCallBack *cb,void *userdata)
+int qmpPluginAPI::registerEventHandlerIntf(ICallBack *cb,void *userdata)
{return qmw->getPlayer()->setEventHandlerCB(cb,userdata);}
void qmpPluginAPI::unregisterEventHandlerIntf(int intfhandle)
{qmw->getPlayer()->unsetEventHandlerCB(intfhandle);}
-int qmpPluginAPI::registerEventReaderIntf(IMidiCallBack *cb,void *userdata)
+int qmpPluginAPI::registerEventReaderIntf(ICallBack *cb,void *userdata)
{return qmw->getPlayer()->setEventReaderCB(cb,userdata);}
void qmpPluginAPI::unregisterEventReaderIntf(int intfhandle)
{qmw->getPlayer()->unsetEventReaderCB(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::registerUIHook(std::string e,ICallBack* cb,void* userdat)
+{return qmw->registerUIHook(e,cb,userdat);}
+int qmpPluginAPI::registerUIHook(std::string e,callback_t cb,void* userdat)
+{return qmw->registerUIHook(e,cb,userdat);}
+void qmpPluginAPI::unregisterUIHook(std::string e,int hook)
+{qmw->unregisterUIHook(e,hook);}
void qmpPluginAPI::registerFunctionality(qmpFuncBaseIntf *i,std::string name,std::string desc,const char *icon,int iconlen,bool checkable)
{qmw->registerFunctionality(i,name,desc,icon,iconlen,checkable);}
void qmpPluginAPI::unregisterFunctionality(std::string name)
{qmw->unregisterFunctionality(name);}
-int qmpPluginAPI::registerFileReadFinishedHandlerIntf(IMidiCallBack* cb,void* userdata)
+int qmpPluginAPI::registerFileReadFinishedHandlerIntf(ICallBack* cb,void* userdata)
{return qmw->getPlayer()->setFileReadFinishedCB(cb,userdata);}
void qmpPluginAPI::unregisterFileReadFinishedHandlerIntf(int intfhandle)
{qmw->getPlayer()->unsetFileReadFinishedCB(intfhandle);}
-void qmpPluginAPI::registerFileReader(IMidiFileReader* reader,std::string name)
+void qmpPluginAPI::registerFileReader(qmpFileReader* reader,std::string name)
{qmw->getPlayer()->registerReader(reader,name);}
void qmpPluginAPI::unregisterFileReader(std::string name)
{qmw->getPlayer()->unregisterReader(name);}
diff --git a/qmidiplayer-desktop/qmpsettingswindow.cpp b/qmidiplayer-desktop/qmpsettingswindow.cpp
index ba460dd..0f5b66a 100644
--- a/qmidiplayer-desktop/qmpsettingswindow.cpp
+++ b/qmidiplayer-desktop/qmpsettingswindow.cpp
@@ -383,9 +383,9 @@ void qmpSettingsWindow::verifySF()
if(((QCheckBox*)ui->twSoundfont->cellWidget(i,0))->isChecked())++sf;
if(settings->value("Midi/DefaultOutput","Internal FluidSynth").toString()=="Internal FluidSynth"&&!sf)
{
- // blmark: show dialog at the current screen which user using now.
- int curMonitor = QApplication::desktop()->screenNumber(this);
- if(QMessageBox::question(QDesktopWidget().screen(curMonitor),//this,
+ // blmark: show dialog at the current screen which user using now.
+ int curMonitor = QApplication::desktop()->screenNumber(this);
+ if(QMessageBox::question(QDesktopWidget().screen(curMonitor),//this,
tr("No soundfont loaded"),
tr("Internal fluidsynth was chosen as the default output but it has no soundfont set. "
"Would you like to setup soundfonts now? After that you may have to reload the internal synth."))==QMessageBox::Yes)