aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--ChangeLog7
-rw-r--r--core/qmpmidiplay.cpp6
-rw-r--r--qmidiplayer-desktop/main.cpp2
-rw-r--r--qmidiplayer-desktop/qmpchannelswindow.cpp13
-rw-r--r--qmidiplayer-desktop/qmpchannelswindow.hpp3
-rw-r--r--qmidiplayer-desktop/qmpmainwindow.cpp7
-rw-r--r--simple-visualization/qmpkeyboardwindow.cpp36
-rw-r--r--simple-visualization/qmpkeyboardwindow.hpp36
-rw-r--r--simple-visualization/qmppianowidget.cpp62
-rw-r--r--simple-visualization/qmppianowidget.hpp25
-rw-r--r--simple-visualization/simple-visualization.pro39
-rw-r--r--simple-visualization/simplevisualization.cpp29
-rw-r--r--simple-visualization/simplevisualization.hpp32
14 files changed, 295 insertions, 5 deletions
diff --git a/.gitignore b/.gitignore
index a0f2e60..a46a9f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
# User configuration
*.pro.user
build/
+
+# KDE-generated rubbish
+.directory
diff --git a/ChangeLog b/ChangeLog
index d7490c8..892f273 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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