Basic scrollArea work, win32 sound controlpanel shortcut

This commit is contained in:
Hane 2024-03-26 19:00:34 +01:00
commit a373c706ac
12 changed files with 159 additions and 13 deletions

View file

@ -1,5 +1,6 @@
<!DOCTYPE RCC><RCC version="1.0"> <!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/"> <qresource prefix="/">
<file>assets/notificationAreaIcon.png</file> <file>assets/notificationAreaIcon.png</file>
<file>assets/style.qss</file>
</qresource> </qresource>
</RCC> </RCC>

6
assets/style.qss Normal file
View file

@ -0,0 +1,6 @@
QMainWindow { background: rgba(100,100,100,100); }
QCheckBox:hover, QCheckBox:checked { color: white }

View file

@ -1,3 +1,4 @@
taskkill /F /IM "qtest.exe"
qmake -o build\Makefile .\qtest.pro qmake -o build\Makefile .\qtest.pro
copy /Y /B .\assets\SoundVolumeView.exe .\build\debug copy /Y /B .\assets\SoundVolumeView.exe .\build\debug
copy /Y /B .\assets\SoundVolumeView.exe .\build\release copy /Y /B .\assets\SoundVolumeView.exe .\build\release

View file

@ -689,6 +689,32 @@ Overseer::Overseer() { //: epsc(deviceEnumerator, playbackDevices){
if(FAILED(deviceEnumerator->RegisterEndpointNotificationCallback(((IMMNotificationClient*)&epsc)))) { log_debugcpp("when no enchufas......"); } if(FAILED(deviceEnumerator->RegisterEndpointNotificationCallback(((IMMNotificationClient*)&epsc)))) { log_debugcpp("when no enchufas......"); }
} }
void Overseer::openControlPanel() {
STARTUPINFOEXW startupConfig;
PROCESS_INFORMATION processInfo;
SecureZeroMemory(&startupConfig, sizeof(STARTUPINFOEXW));
SecureZeroMemory(&startupConfig.StartupInfo, sizeof(STARTUPINFOW));
startupConfig.StartupInfo.cb = sizeof(STARTUPINFOEXW);
SecureZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION));
std::wstring command = L"rundll32 shell32, Control_RunDLL mmsys.cpl";
if(CreateProcessW(
NULL,
(wchar_t*)command.c_str(),
NULL,
NULL,
false,
CREATE_UNICODE_ENVIRONMENT,
NULL,
NULL,
(LPSTARTUPINFOW)&startupConfig,
&processInfo
) == true) {
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
}
NGuid Overseer::getGuid() { NGuid Overseer::getGuid() {
return guid; return guid;
} }

View file

@ -106,6 +106,7 @@ class Overseer {
//TODO singleton? //TODO singleton?
public: public:
Overseer(); Overseer();
void openControlPanel();
std::vector<Endpoint*> getPlaybackEndpoints(); std::vector<Endpoint*> getPlaybackEndpoints();
std::vector<Endpoint*> getCaptureEndpoints(); std::vector<Endpoint*> getCaptureEndpoints();

View file

@ -6,6 +6,7 @@
//done by qt by def #define UNICODE //done by qt by def #define UNICODE
#include <Windows.h> #include <Windows.h>
#include <shellapi.h>
#include <processthreadsapi.h> #include <processthreadsapi.h>
#include <mmdeviceapi.h> #include <mmdeviceapi.h>
#include <combaseapi.h> #include <combaseapi.h>

View file

@ -201,6 +201,10 @@ OverseerHandler::OverseerHandler() {
this->os = new Overseer(); this->os = new Overseer();
} }
void OverseerHandler::openControlPanel() {
this->os->openControlPanel();
}
std::vector<Endpoint*> OverseerHandler::getPlaybackEndpoints() { std::vector<Endpoint*> OverseerHandler::getPlaybackEndpoints() {
return this->os->getPlaybackEndpoints(); return this->os->getPlaybackEndpoints();
} }

View file

@ -97,6 +97,8 @@ class OverseerHandler {
public: public:
OverseerHandler(); OverseerHandler();
void openControlPanel();
void setChangeFrontDefaultsFunction(std::function<void(Roles, std::wstring)> changeFrontDefaults); void setChangeFrontDefaultsFunction(std::function<void(Roles, std::wstring)> changeFrontDefaults);
void changeFrontDefaultsCallback(Roles role, std::wstring endpointId); void changeFrontDefaultsCallback(Roles role, std::wstring endpointId);

View file

@ -22,6 +22,10 @@
#define STRING_SYSTEM_SOUNDS "System Sounds" #define STRING_SYSTEM_SOUNDS "System Sounds"
#define LSTRING_SYSTEM_SOUNDS L"System Sounds" #define LSTRING_SYSTEM_SOUNDS L"System Sounds"
#define STRING_CP "Open Control Panel"
#define STRING_ABOUT "About"
#define STRING_STARTUP "Run at startup"
//INIT BACK //INIT BACK
enum AudioChannel { enum AudioChannel {

View file

@ -6,7 +6,7 @@ CustomWidgetEvent<T>::CustomWidgetEvent(QEvent::Type type, T payload) : QEvent(t
} }
void ExtendedCheckBox::customEvent(QEvent* ev) { void ExtendedCheckBox::customEvent(QEvent* ev) {
QEvent::Type tipo = ev->type(); //QEvent::Type tipo = ev->type();
if (ev->type() == (QEvent::Type)CustomQEvent::EndpointDefaultChange) { if (ev->type() == (QEvent::Type)CustomQEvent::EndpointDefaultChange) {
//todo: still prone to bugs; whack-a-mole to come //todo: still prone to bugs; whack-a-mole to come
ev->setAccepted(true); ev->setAccepted(true);
@ -56,6 +56,8 @@ SessionWidget::SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent)
layout->addWidget(muteButton, 0, 1, Qt::AlignLeft | Qt::AlignBottom); layout->addWidget(muteButton, 0, 1, Qt::AlignLeft | Qt::AlignBottom);
layout->addWidget(mainSlider, 0, 2, 1, 2); layout->addWidget(mainSlider, 0, 2, 1, 2);
layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
//TODO:0 = mute and muted, change volume = unmuted are client side tricks = 2 callbacks, one for volume, one for mute state. Implement as an user selectable option? //TODO:0 = mute and muted, change volume = unmuted are client side tricks = 2 callbacks, one for volume, one for mute state. Implement as an user selectable option?
connect<void(QSlider::*)(int), void(SessionWidget::*)(int)>(mainSlider, &QSlider::valueChanged, this,&SessionWidget::updateMainVolume); connect<void(QSlider::*)(int), void(SessionWidget::*)(int)>(mainSlider, &QSlider::valueChanged, this,&SessionWidget::updateMainVolume);
connect<void(QCheckBox::*)(int), void(SessionWidget::*)(int)>(muteButton, &QCheckBox::stateChanged, this, (&SessionWidget::updateMute)); connect<void(QCheckBox::*)(int), void(SessionWidget::*)(int)>(muteButton, &QCheckBox::stateChanged, this, (&SessionWidget::updateMute));
@ -108,6 +110,7 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
//todo: sussy //todo: sussy
this->eph->setState(EndpointState::ENDPOINT_ACTIVE, idx); this->eph->setState(EndpointState::ENDPOINT_ACTIVE, idx);
//setAttribute(Qt::WA_TranslucentBackground);
layout = new QGridLayout(this); layout = new QGridLayout(this);
//this->setLayout(layout); //this->setLayout(layout);
log_debugcpp("epw main layout parent: " + std::to_string((intptr_t)(layout->parent()))); log_debugcpp("epw main layout parent: " + std::to_string((intptr_t)(layout->parent())));
@ -149,9 +152,11 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
//tip: would need to be new widget with layout in it //tip: would need to be new widget with layout in it
//mainMuteLayout = new QGridLayout(); //mainMuteLayout = new QGridLayout();
layout->addWidget(mainLabel, row, 0, Qt::AlignLeft | Qt::AlignBottom); layout->addWidget(mainLabel, row, 0, Qt::AlignLeft | Qt::AlignVCenter);
layout->addWidget(muteButton, row, 1, Qt::AlignLeft | Qt::AlignBottom); layout->addWidget(muteButton, row, 1, Qt::AlignLeft | Qt::AlignVCenter);
layout->addWidget(mainSlider, row, 2, 1, 2); layout->addWidget(mainSlider, row, 2, 1, 2, Qt::AlignLeft | Qt::AlignVCenter);
layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
int debug2 = this->minimumWidth();
row++; row++;
//TODO:0 = mute and muted, change volume = unmuted are client side tricks = 2 callbacks, one for volume, one for mute state. Implement as an user selectable option? //TODO:0 = mute and muted, change volume = unmuted are client side tricks = 2 callbacks, one for volume, one for mute state. Implement as an user selectable option?
@ -263,7 +268,7 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
/* First SessionWidget batch */ /* First SessionWidget batch */
for (size_t i = 0; i < eph->getSessionCount(); i++) { for (size_t i = 0; i < eph->getSessionCount(); i++) {
SessionWidget* sessionWidget = new SessionWidget(i, eph->getSessionHandlers().at(i), this); SessionWidget* sessionWidget = new SessionWidget(i, eph->getSessionHandlers().at(i), this);
layout->addWidget(sessionWidget, row, 4); layout->addWidget(sessionWidget, row, 1, 1, 4);
row++; row++;
sessionWidgets.push_back(sessionWidget); sessionWidgets.push_back(sessionWidget);
eph->getSessionHandlers().at(i)->setFrontIndex(i); eph->getSessionHandlers().at(i)->setFrontIndex(i);
@ -290,7 +295,7 @@ void EndpointWidget::addSessionWidget(CustomWidgetEvent<SessionHandler*>* ev){
uint64_t index = this->sessionWidgets.size(); uint64_t index = this->sessionWidgets.size();
SessionWidget* sw = new SessionWidget(index, ev->payload, this); SessionWidget* sw = new SessionWidget(index, ev->payload, this);
ev->payload->setFrontIndex(index); ev->payload->setFrontIndex(index);
this->layout->addWidget(sw, row, 4); this->layout->addWidget(sw, row, 1, 1, 4);
row++; row++;
sessionWidgets.push_back(sw); sessionWidgets.push_back(sw);
return; return;
@ -326,7 +331,7 @@ EndpointWidget::~EndpointWidget() {
} }
void MainWindow::customEvent(QEvent* ev) { void MainWindow::customEvent(QEvent* ev) {
if (ev->type() == CustomQEvent::EndpointWidgetObsolete) { if (ev->type() == (QEvent::Type)CustomQEvent::EndpointWidgetObsolete) {
ev->setAccepted(true); ev->setAccepted(true);
this->removeEndpointWidget((CustomWidgetEvent<uint64_t>*)ev); this->removeEndpointWidget((CustomWidgetEvent<uint64_t>*)ev);
} else if (ev->type() == (QEvent::Type)CustomQEvent::EndpointWidgetCreated) { } else if (ev->type() == (QEvent::Type)CustomQEvent::EndpointWidgetCreated) {
@ -448,6 +453,23 @@ std::map<Roles, ExtendedCheckBox*> EndpointWidget::getDefaultRolesWidgets() {
return defaultRolesCheckBoxes; return defaultRolesCheckBoxes;
} }
HeaderWidget::HeaderWidget(QWidget *parent) : QWidget(parent) {
layout = new QGridLayout(this);
QString text = "&" STRING_ABOUT;
about = new QPushButton(text, this);
#ifdef WIN32
text = "&" STRING_CP;
openCP = new QPushButton(text, this);
connect(openCP, &QPushButton::clicked, [this](){ osh->openControlPanel(); });
text = "&" STRING_STARTUP;
startup = new QPushButton(text, this);
layout->addWidget(openCP , 0, 0);
layout->addWidget(startup, 0, 1);
#endif
layout->addWidget(about , 0, 2);
this->setLayout(layout);
}
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
// setWindowState(Qt::WindowFullScreen); // setWindowState(Qt::WindowFullScreen);
@ -459,7 +481,13 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
QEvent::registerEventType(CustomQEvent::EndpointWidgetObsolete); QEvent::registerEventType(CustomQEvent::EndpointWidgetObsolete);
QEvent::registerEventType(CustomQEvent::EndpointWidgetCreated); QEvent::registerEventType(CustomQEvent::EndpointWidgetCreated);
QEvent::registerEventType(CustomQEvent::EndpointDefaultChange); QEvent::registerEventType(CustomQEvent::EndpointDefaultChange);
QEvent::registerEventType(CustomQEvent::SessionWidgetObsolete);
QEvent::registerEventType(CustomQEvent::SessionWidgetCreated);
//setWindowFlags(Qt::FramelessWindowHint);
//setParent(0); // Create TopLevel-Widget
//setAttribute(Qt::WA_NoSystemBackground, true);
//setAttribute(Qt::WA_TranslucentBackground, true);
ewsUpdateTimer = new QTimer(this); ewsUpdateTimer = new QTimer(this);
widget = new QWidget(); widget = new QWidget();
layout = new QGridLayout(); layout = new QGridLayout();
@ -470,13 +498,34 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
ewsUpdateTimer->setSingleShot(true); ewsUpdateTimer->setSingleShot(true);
ewsUpdateTimer->setInterval(ewsUpdateTimerFrequency); ewsUpdateTimer->setInterval(ewsUpdateTimerFrequency);
connect(ewsUpdateTimer, &QTimer::timeout, this, &MainWindow::reorderEndpointWidgetCollection); connect(ewsUpdateTimer, &QTimer::timeout, this, &MainWindow::reorderEndpointWidgetCollection);
//widget->setMinimumSize(QSize(300,300));
widget->setLayout(layout); widget->setLayout(layout);
setCentralWidget(widget); /*
* Scroll bar code
*/
scrollArea = new QScrollArea(this);
scrollArea->setWidget(widget);
scrollArea->setWidgetResizable(true);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scrollArea->setMinimumWidth(500);
setCentralWidget(scrollArea);
/*
* Menu bar code
*/
QMenuBar* menuBar = (this->menuBar)();
hw = new HeaderWidget(this);
menuBar->setCornerWidget(hw,Qt::TopLeftCorner);
menuBar->show();
this->setMenuBar(menuBar);
//setCentralWidget(widget);
//layout->addWidget(pintas, 0, 0); //layout->addWidget(pintas, 0, 0);
setWindowTitle(STRING_TITLE); setWindowTitle(STRING_TITLE);
reloadEndpointWidgets(); reloadEndpointWidgets();
scrollArea->setMinimumWidth(ews.at(0)->minimumWidth());
int debug = scrollArea->minimumWidth();
/* /*
* Tray Icon code * Tray Icon code
*/ */

View file

@ -18,6 +18,12 @@
#include <QPushButton> #include <QPushButton>
#include <QCheckBox> #include <QCheckBox>
#include <QTimer> #include <QTimer>
#include <QScrollArea>
#include <QSize>
#include <QMenuBar>
#include <QMenu>
//#include <QScrollBar>
/* /*
* #else * #else
* class QSlider; * class QSlider;
@ -142,6 +148,7 @@ private slots:
private: private:
int row; int row;
const int sessionCol = 2;
QCheckBox *muteButton = nullptr; QCheckBox *muteButton = nullptr;
QLabel *mainLabel = nullptr, *leftChannelLabel = nullptr, *rightChannelLabel = nullptr; QLabel *mainLabel = nullptr, *leftChannelLabel = nullptr, *rightChannelLabel = nullptr;
QSlider *mainSlider = nullptr; QSlider *mainSlider = nullptr;
@ -164,6 +171,38 @@ private:
}; };
class HeaderWidget : public QWidget {
Q_OBJECT
public:
HeaderWidget(QWidget *parent = nullptr);
//~HeaderWidget();
//void updateMainVolume(float newValue);
//void updateVolume(uint32_t channel, float newValue);
//void updateMute(bool muted);
//void populateEndpointWidget(EndpointHandler *eph);
//void setEndpointHandlers(std::vector<EndpointHandler*> *ephs);
//public slots:
//protected:
//void customEvent(QEvent* ev) override;
//private slots:
//void addSessionWidget(CustomWidgetEvent<SessionHandler*>* ev);
//void removeSessionWidget(CustomWidgetEvent<SessionHandler*>* ev);
private:
QGridLayout *layout;
QPushButton *about;
#ifdef WIN32
QPushButton *openCP;
QPushButton *startup;
#endif
};
class MainWindow : public QMainWindow { class MainWindow : public QMainWindow {
Q_OBJECT Q_OBJECT
@ -196,6 +235,10 @@ private:
QAction *trayIconMenuQuit; QAction *trayIconMenuQuit;
QTimer *ewsUpdateTimer; QTimer *ewsUpdateTimer;
static constexpr uint64_t ewsUpdateTimerFrequency = 500; static constexpr uint64_t ewsUpdateTimerFrequency = 500;
QScrollArea *scrollArea;
HeaderWidget* hw;
//QMenuBar *menuBar;
//public slots: //public slots:
// void setEndpointHandlers(std::vector<EndpointHandler*> *ephs); // void setEndpointHandlers(std::vector<EndpointHandler*> *ephs);

View file

@ -10,6 +10,7 @@
#include <QLocalSocket> #include <QLocalSocket>
#include <QLocalServer> #include <QLocalServer>
#include <QString> #include <QString>
#include <QFile>
//#include "contclasses.h" //#include "contclasses.h"
#include "qtclasses.h" #include "qtclasses.h"
#include "global.h" #include "global.h"
@ -55,9 +56,16 @@ int main (int argc, char* argv[]) {
//INIT FRONT //INIT FRONT
QScopedPointer<QApplication> app(createApplication(argc, argv)); QScopedPointer<QApplication> app(createApplication(argc, argv));
MainWindow window = MainWindow(); MainWindow window = MainWindow();
//window.setEndpointHandlers(ephs);
QApplication::setQuitOnLastWindowClosed(false); QApplication::setQuitOnLastWindowClosed(false);
app->setStyle("windowsvista"); /*
* QFile styleFile(":/assets/style.qss");
* styleFile.open(QFile::ReadOnly);
* QString styleSheet { QLatin1String(styleFile.readAll()) };
*/
//app->setStyleSheet(styleSheet);
//window.setMinimumSize(100, 100);
window.show(); window.show();
return app->exec(); return app->exec();
} }