diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | core/qmpmidiplay.cpp | 6 | ||||
-rw-r--r-- | qmidiplayer-desktop/main.cpp | 2 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpchannelswindow.cpp | 13 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpchannelswindow.hpp | 3 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpmainwindow.cpp | 7 | ||||
-rw-r--r-- | simple-visualization/qmpkeyboardwindow.cpp | 36 | ||||
-rw-r--r-- | simple-visualization/qmpkeyboardwindow.hpp | 36 | ||||
-rw-r--r-- | simple-visualization/qmppianowidget.cpp | 62 | ||||
-rw-r--r-- | simple-visualization/qmppianowidget.hpp | 25 | ||||
-rw-r--r-- | simple-visualization/simple-visualization.pro | 39 | ||||
-rw-r--r-- | simple-visualization/simplevisualization.cpp | 29 | ||||
-rw-r--r-- | simple-visualization/simplevisualization.hpp | 32 |
14 files changed, 295 insertions, 5 deletions
@@ -1,3 +1,6 @@ # User configuration *.pro.user build/ + +# KDE-generated rubbish +.directory @@ -1,3 +1,10 @@ +2019-04-22 0.8.7 indev +New development cycle! +Partially reintroduce High DPI handling. +Pressing enter when a preset is focused now opens the preset selection dialog. +Close all functionality windows before shutting down. +And the most important one of them all: new simple visualization! + 2019-03-18 0.8.6 alpha Fixed initial preset selection in XG mode. diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp index 84561ae..29f636f 100644 --- a/core/qmpmidiplay.cpp +++ b/core/qmpmidiplay.cpp @@ -332,11 +332,11 @@ void CMidiPlayer::playerInit() chstatus[9][0]=127; for(int i=0;i<16;++i) { - chstatus[i][7]=100;chstatus[i][11]=127; + chstatus[i][7]=100;chstatus[i][8]=64;chstatus[i][11]=127; chstatus[i][10]=chstatus[i][71]=chstatus[i][72]= chstatus[i][73]=chstatus[i][74]=chstatus[i][75]= chstatus[i][76]=chstatus[i][77]=chstatus[i][78]=64; - for(int cc=0;cc<127;++cc) + for(int cc=0;cc<124;++cc)//Temporary fix before introduction of per-device initialization profile mididev[mappedoutput[i]].dev->basicMessage(0xB0|i,cc,chstatus[i][cc]); } } @@ -486,7 +486,7 @@ void CMidiPlayer::setChannelOutput(int ch,int outid) int origoutput=mappedoutput[ch]; SMidiDev& dnew=mididev[outid]; dnew.dev->onMapped(ch,++dnew.refcnt); - for(int i=0;i<128;++i) + for(int i=0;i<124;++i) if(i!=6&&i!=38&&i!=100&&i!=101)//avoid sending RPN/NRPN dnew.dev->basicMessage(0xB0|ch,i,chstatus[ch][i]); dnew.dev->basicMessage(0xC0|ch,chstatus[ch][128],0); diff --git a/qmidiplayer-desktop/main.cpp b/qmidiplayer-desktop/main.cpp index a2375ca..f62429c 100644 --- a/qmidiplayer-desktop/main.cpp +++ b/qmidiplayer-desktop/main.cpp @@ -24,6 +24,8 @@ int main(int argc,char **argv) { QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + if(!qgetenv("QT_SCALE_FACTOR").length()&&!qgetenv("QT_SCREEN_SCALE_FACTORS").length()) + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication a(argc,argv); QTranslator qtTranslator; qtTranslator.load("qt_"+QLocale::system().name(), diff --git a/qmidiplayer-desktop/qmpchannelswindow.cpp b/qmidiplayer-desktop/qmpchannelswindow.cpp index 6b1b8b4..3b54069 100644 --- a/qmidiplayer-desktop/qmpchannelswindow.cpp +++ b/qmidiplayer-desktop/qmpchannelswindow.cpp @@ -71,6 +71,7 @@ qmpChannelsWindow::qmpChannelsWindow(QWidget *parent) : ui->twChannels->setColumnWidth(3,192); ui->twChannels->setColumnWidth(4,208); ui->twChannels->setColumnWidth(5,32); + ui->twChannels->installEventFilter(this); qmpMainWindow::getInstance()->registerFunctionality( chnlf=new qmpChannelFunc(this), std::string("Channel"), @@ -224,6 +225,18 @@ void qmpChannelsWindow::changeMidiMapping(int chid,int idx) qmpMainWindow::getInstance()->getPlayer()->setChannelOutput(chid,idx); } +bool qmpChannelsWindow::eventFilter(QObject *o,QEvent *e) +{ + if(e->type()==QEvent::KeyPress&&ui->twChannels->currentColumn()==4) + { + QKeyEvent *ke=static_cast<QKeyEvent*>(e); + if(ke->key()!=Qt::Key_Enter&&ke->key()!=Qt::Key_Return)return false; + showPresetWindow(ui->twChannels->currentRow(),4); + return true; + } + return false; +} + qmpChannelFunc::qmpChannelFunc(qmpChannelsWindow *par) {p=par;} void qmpChannelFunc::show() diff --git a/qmidiplayer-desktop/qmpchannelswindow.hpp b/qmidiplayer-desktop/qmpchannelswindow.hpp index 9ff0cd0..cb7b791 100644 --- a/qmidiplayer-desktop/qmpchannelswindow.hpp +++ b/qmidiplayer-desktop/qmpchannelswindow.hpp @@ -90,6 +90,9 @@ class qmpChannelsWindow:public QWidget void on_pbUnmute_clicked(); void on_pbUnsolo_clicked(); + protected: + bool eventFilter(QObject *o,QEvent *e); + private: Ui::qmpChannelsWindow *ui; qmpPresetSelector *pselectw; diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp index 335a3c5..baebe4f 100644 --- a/qmidiplayer-desktop/qmpmainwindow.cpp +++ b/qmidiplayer-desktop/qmpmainwindow.cpp @@ -177,8 +177,11 @@ 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); + { + i->second.i()->close(); + i->second.setAssignedControl((QReflectiveAction*)NULL), + i->second.setAssignedControl((QReflectivePushButton*)NULL); + } efxw->close();chnlw->close(); plistw->close();infow->close(); settingsw->close(); diff --git a/simple-visualization/qmpkeyboardwindow.cpp b/simple-visualization/qmpkeyboardwindow.cpp new file mode 100644 index 0000000..a42a2e0 --- /dev/null +++ b/simple-visualization/qmpkeyboardwindow.cpp @@ -0,0 +1,36 @@ +#include <QVBoxLayout> +#include <QCloseEvent> +#include "qmpkeyboardwindow.hpp" + +qmpKeyboardWindow::qmpKeyboardWindow(qmpPluginAPI *_api,QWidget *parent): + QWidget(parent,Qt::Dialog),api(_api) +{ + setLayout(new QVBoxLayout()); + for(int ch=0;ch<16;++ch) + layout()->addWidget(pw[ch]=new qmpPianoWidget(this)); + hide(); + api->registerEventHandlerIntf(ec=new EventCallback(),this); + connect(ec,&EventCallback::keystateupdated,this,&qmpKeyboardWindow::onkeystatesupdate); +} +qmpKeyboardWindow::~qmpKeyboardWindow() +{ +} +void qmpKeyboardWindow::closeEvent(QCloseEvent *event) +{ + api->setFuncState("Keyboard",false); + event->accept(); +} +void qmpKeyboardWindow::onkeystatesupdate(int ch,int key,bool state) +{pw[ch]->setKeyState(key,state);} +void qmpKeyboardWindow::resetAll() +{for(int ch=0;ch<16;++ch)pw[ch]->reset();} + +void EventCallback::callBack(void* callerdata,void* userdata) +{ + qmpKeyboardWindow *w=(qmpKeyboardWindow*)userdata; + SEventCallBackData *cbd=(SEventCallBackData*)callerdata; + if((cbd->type&0xF0)==0x80) + emit keystateupdated(cbd->type&0xF,cbd->p1,false); + if((cbd->type&0xF0)==0x90) + emit keystateupdated(cbd->type&0xF,cbd->p1,cbd->p2>0); +} diff --git a/simple-visualization/qmpkeyboardwindow.hpp b/simple-visualization/qmpkeyboardwindow.hpp new file mode 100644 index 0000000..a99e62e --- /dev/null +++ b/simple-visualization/qmpkeyboardwindow.hpp @@ -0,0 +1,36 @@ +#ifndef QMPKEYBOARDWINDOW_HPP +#define QMPKEYBOARDWINDOW_HPP + +#include "../include/qmpcorepublic.hpp" +#include "qmppianowidget.hpp" + +#include <QWidget> + +class EventCallback:public QObject,public ICallBack +{ + Q_OBJECT + public: + void callBack(void* callerdata,void* userdata); + signals: + void keystateupdated(int ch,int key,bool state); +}; + +class qmpKeyboardWindow:public QWidget +{ + Q_OBJECT + friend class EventCallback; + private: + qmpPianoWidget *pw[16]; + qmpPluginAPI *api; + EventCallback *ec; + public: + qmpKeyboardWindow(qmpPluginAPI *_api,QWidget *parent); + ~qmpKeyboardWindow(); + void resetAll(); + protected: + void closeEvent(QCloseEvent *event); + public slots: + void onkeystatesupdate(int ch,int key,bool state); +}; + +#endif diff --git a/simple-visualization/qmppianowidget.cpp b/simple-visualization/qmppianowidget.cpp new file mode 100644 index 0000000..febd90f --- /dev/null +++ b/simple-visualization/qmppianowidget.cpp @@ -0,0 +1,62 @@ +#include <cstring> +#include <QPainter> +#include "qmppianowidget.hpp" + +qmpPianoWidget::qmpPianoWidget(QWidget *parent) : QWidget(parent) +{ + memset(keystates,0,sizeof(keystates)); +} +void qmpPianoWidget::setKeyState(int key,bool state) +{ + keystates[key]=state; + update(); +} +void qmpPianoWidget::reset() +{ + memset(keystates,0,sizeof(keystates)); + update(); +} +QSize qmpPianoWidget::minimumSizeHint()const +{ + return QSize(320,22); +} + +void qmpPianoWidget::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + for(int i=0;i<128;++i) + { + QRectF r=getKeyRect(i); + paintKey(r,QColor(keystates[i]?0xff66cc:0x66ccff)); + } +} + +QRectF qmpPianoWidget::getKeyRect(int key) +{ + int octave=key/12;key%=12; + bool is_black=(key<5&&(key&1))||(key>5&&((key&1)^1)); + double key_width=width()/75.; + QRectF ret(0,0,key_width,height()/2.); + if(!is_black) + { + ret.moveTop(height()/2.); + int shift=(key+(key>=5))>>1; + ret.moveLeft((octave*7+shift)*key_width); + } + else + ret.moveLeft((octave*7+(key+(key>=5))/2.)*key_width); + return ret; +} +void qmpPianoWidget::paintKey(QRectF keyrect,QColor keycolor) +{ + QColor bordercolor(keycolor); + if(keycolor.valueF()>0.5) + bordercolor=bordercolor.darker(150); + else + bordercolor=bordercolor.lighter(150); + QPainter *p=new QPainter(this); + p->setPen(bordercolor); + p->setBrush(QBrush(keycolor)); + p->drawRect(keyrect.adjusted(1,1,-1,-1)); + delete p; +} diff --git a/simple-visualization/qmppianowidget.hpp b/simple-visualization/qmppianowidget.hpp new file mode 100644 index 0000000..22af6ce --- /dev/null +++ b/simple-visualization/qmppianowidget.hpp @@ -0,0 +1,25 @@ +#ifndef QMPPIANOWIDGET_HPP +#define QMPPIANOWIDGET_HPP + +#include <QWidget> +#include <bitset> + +class qmpPianoWidget : public QWidget +{ + Q_OBJECT + public: + explicit qmpPianoWidget(QWidget *parent = nullptr); + void setKeyState(int key,bool state); + void reset(); + QSize minimumSizeHint()const override; + + protected: + void paintEvent(QPaintEvent *event)override; + + private: + bool keystates[128]; + QRectF getKeyRect(int key); + void paintKey(QRectF keyrect,QColor keycolor); +}; + +#endif // QMPPIANOWIDGET_HPP diff --git a/simple-visualization/simple-visualization.pro b/simple-visualization/simple-visualization.pro new file mode 100644 index 0000000..7a22769 --- /dev/null +++ b/simple-visualization/simple-visualization.pro @@ -0,0 +1,39 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2019-04-08T17:50:57 +# +#------------------------------------------------- + +QT += widgets +QT += gui + +TARGET = simple-visualization +TEMPLATE = lib + +DEFINES += SIMPLEVISUALIZATION_LIBRARY + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + simplevisualization.cpp \ + qmppianowidget.cpp \ + qmpkeyboardwindow.cpp + +HEADERS += \ + simplevisualization.hpp \ + qmppianowidget.hpp \ + qmpkeyboardwindow.hpp + +unix { + target.path = /usr/lib + INSTALLS += target +} diff --git a/simple-visualization/simplevisualization.cpp b/simple-visualization/simplevisualization.cpp new file mode 100644 index 0000000..0a1de02 --- /dev/null +++ b/simple-visualization/simplevisualization.cpp @@ -0,0 +1,29 @@ +#include "simplevisualization.hpp" +#include "qmpkeyboardwindow.hpp" + +qmpSimpleVisualization::qmpSimpleVisualization(qmpPluginAPI *_api){api=_api;} +void qmpSimpleVisualization::show(){p->show();} +void qmpSimpleVisualization::close(){p->close();} +void qmpSimpleVisualization::init() +{ + api->registerFunctionality(this,"Keyboard","Keyboard",api->isDarkTheme()?":/img/visualization_i.svg":":/img/visualization.svg",0,true); + p=new qmpKeyboardWindow(api,NULL); + uihs=api->registerUIHook("main.stop",qmpSimpleVisualization::cbstop,(void*)this); +} +void qmpSimpleVisualization::deinit() +{ + if(!api)return;close(); + api->unregisterFunctionality("Keyboard"); + api->unregisterUIHook("main.stop",uihs); + delete p; +} +const char* qmpSimpleVisualization::pluginGetName() +{return "QMidiPlayer Simple Visualization Plugin";} +const char* qmpSimpleVisualization::pluginGetVersion() +{return "0.8.6";} + +void qmpSimpleVisualization::cbstop(void*,void* usrd) +{ + qmpSimpleVisualization *v=(qmpSimpleVisualization*)usrd; + v->p->resetAll(); +} diff --git a/simple-visualization/simplevisualization.hpp b/simple-visualization/simplevisualization.hpp new file mode 100644 index 0000000..b3edeee --- /dev/null +++ b/simple-visualization/simplevisualization.hpp @@ -0,0 +1,32 @@ +#ifndef SIMPLEVISUALIZATION_HPP +#define SIMPLEVISUALIZATION_HPP + +#include "../include/qmpcorepublic.hpp" + +class qmpKeyboardWindow; +class qmpSimpleVisualization:public qmpPluginIntf,public qmpFuncBaseIntf +{ + private: + qmpPluginAPI* api; + qmpKeyboardWindow *p; + int uihs; + public: + qmpSimpleVisualization(qmpPluginAPI* _api); + void show(); + void close(); + void init(); + void deinit(); + const char* pluginGetName(); + const char* pluginGetVersion(); + + static void cbstop(void* cbd,void* usrd); +}; + +extern "C"{ + EXPORTSYM qmpPluginIntf* qmpPluginGetInterface(qmpPluginAPI* api) + {return new qmpSimpleVisualization(api);} + EXPORTSYM const char* qmpPluginGetAPIRev() + {return QMP_PLUGIN_API_REV;} +} + +#endif // SIMPLEVISUALIZATION_HPP |