Compare commits

..

No commits in common. "master" and "publictest" have entirely different histories.

13 changed files with 53 additions and 215 deletions

View file

@ -4,7 +4,5 @@
<file>assets/notificationAreaIcon.png</file> <file>assets/notificationAreaIcon.png</file>
<file>assets/style.qss</file> <file>assets/style.qss</file>
<file>assets/logo.ico</file> <file>assets/logo.ico</file>
<file>assets/mute.svg</file>
<file>assets/unmute.svg</file>
</qresource> </qresource>
</RCC> </RCC>

View file

@ -1,7 +1,7 @@
taskkill /F /IM "MixerQ.exe" taskkill /F /IM "MixerQ.exe"
taskkill /F /IM "MixerQd.exe" taskkill /F /IM "MixerQd.exe"
qmake -o build\Makefile .\qtest.pro qmake -o build\Makefile .\qtest.pro
REM mingw32-make.exe -C .\build -f Makefile.Release mingw32-make.exe -C .\build -f Makefile.Release
mingw32-make.exe -C .\build -f Makefile.Debug mingw32-make.exe -C .\build -f Makefile.Debug
REM makensis /DBUILDTYPE=release install\installer.nsi makensis /DBUILDTYPE=release install\installer.nsi
REM makensis /DBUILDTYPE=debug install\installer.nsi makensis /DBUILDTYPE=debug install\installer.nsi

View file

@ -18,7 +18,7 @@ LIBS += -lWinmm -lodbc32 -lodbccp32 -luuid -loleaut32 -lole32 -lshell32 -ladvapi
DEFINES += QT_LOGGING_TO_CONSOLE=1 WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0602 DEFINES += QT_LOGGING_TO_CONSOLE=1 WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0602
DEFINES_DEBUG += DEBUG DEFINES_DEBUG += DEBUG
QT += widgets network svg QT += widgets network
INCLUDEPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\back\reimpl" "$$PWD\src\cont" INCLUDEPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\back\reimpl" "$$PWD\src\cont"
VPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\back\reimpl" "$$PWD\src\cont" VPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\back\reimpl" "$$PWD\src\cont"

View file

@ -234,7 +234,6 @@ HRESULT EndpointSituationCallback::OnDeviceRemoved(LPCWSTR pwstrDeviceId) {
HRESULT EndpointSituationCallback::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) { HRESULT EndpointSituationCallback::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) {
std::wstring endpointId = std::wstring(pwstrDeviceId); std::wstring endpointId = std::wstring(pwstrDeviceId);
log_wdebugcpp(L"Endpoint state change for " + endpointId);
EndpointState newState; EndpointState newState;
switch (dwNewState) { switch (dwNewState) {
case DEVICE_STATE_ACTIVE: case DEVICE_STATE_ACTIVE:
@ -250,7 +249,7 @@ HRESULT EndpointSituationCallback::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, D
newState = EndpointState::ENDPOINT_UNPLUGGED; newState = EndpointState::ENDPOINT_UNPLUGGED;
break; break;
} }
isEpStateChanging.exchange(true); isEpStateChanging = true;
std::thread newEndpointThread(&OverseerHandler::reviseEndpointShowing, osh, std::thread newEndpointThread(&OverseerHandler::reviseEndpointShowing, osh,
endpointId, newState); endpointId, newState);
newEndpointThread.detach(); newEndpointThread.detach();
@ -259,7 +258,7 @@ HRESULT EndpointSituationCallback::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, D
} }
HRESULT EndpointSituationCallback::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key) { HRESULT EndpointSituationCallback::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key) {
isEpStateChanging.exchange(true); isEpStateChanging = true;
std::thread propertyThread(&Overseer::updateEndpointInfo, os, std::wstring(pwstrDeviceId)); std::thread propertyThread(&Overseer::updateEndpointInfo, os, std::wstring(pwstrDeviceId));
propertyThread.detach(); propertyThread.detach();
while(isEpStateChanging); while(isEpStateChanging);
@ -267,8 +266,7 @@ HRESULT EndpointSituationCallback::OnPropertyValueChanged(LPCWSTR pwstrDeviceId,
} }
void EndpointSituationCallback::reportFinishedStateChange() { void EndpointSituationCallback::reportFinishedStateChange() {
this->isEpStateChanging.exchange(false); this->isEpStateChanging = false;
return;
} }
Endpoint::Endpoint(IMMDevice* ep, IPolicyConfig7* policyConfig, uint64_t idx) { Endpoint::Endpoint(IMMDevice* ep, IPolicyConfig7* policyConfig, uint64_t idx) {
@ -327,29 +325,23 @@ void Endpoint::activateEndpointSessions() {
return; return;
} }
if (!sessionManager) { if (FAILED(endpoint->Activate(__uuidof(IAudioSessionManager2),
if (FAILED(endpoint->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void**) &sessionManager))) {
CLSCTX_ALL, NULL, (void**) &sessionManager))) { log_debugcpp("Couldn't open session manager2, huh");
log_debugcpp("Couldn't open session manager2, huh"); return;
return;
}
} }
IAudioSessionEnumerator* sessionEnumerator = nullptr; IAudioSessionEnumerator* sessionEnumerator = nullptr;
if (FAILED(sessionManager->GetSessionEnumerator(&sessionEnumerator))) { log_wdebugcpp(L"sesEnumeratorBros..."); exit(-5); return; } if (FAILED(sessionManager->GetSessionEnumerator(&sessionEnumerator))) { log_wdebugcpp(L"sesEnumeratorBros..."); return; }
endpointSessions.resize(1, nullptr); endpointSessions.resize(1, nullptr);
int sessionCount; int sessionCount;
sessionEnumerator->GetCount(&sessionCount); sessionEnumerator->GetCount(&sessionCount);
for (int i = 0; i < sessionCount; i++) { for (int i = 0; i < sessionCount; i++) {
IAudioSessionControl* sessionControlTmp; IAudioSessionControl* sessionControlTmp;
if (FAILED(sessionEnumerator->GetSession(i, (IAudioSessionControl**)&sessionControlTmp))) { sessionEnumerator->GetSession(i, (IAudioSessionControl**)&sessionControlTmp);
exit(-6);
}
IAudioSessionControl2* sessionControl; IAudioSessionControl2* sessionControl;
if(FAILED(sessionControlTmp->QueryInterface(__uuidof(IAudioSessionControl2), (void**)&sessionControl))){ sessionControlTmp->QueryInterface(__uuidof(IAudioSessionControl2), (void**)&sessionControl);
exit(-7); sessionControl->AddRef();
}
sessionControlTmp->Release(); sessionControlTmp->Release();
Session* session = new Session(this, sessionControl, (size_t)i); Session* session = new Session(this, sessionControl, (size_t)i);
if (sessionControl->IsSystemSoundsSession() == S_OK) endpointSessions[0] = session; if (sessionControl->IsSystemSoundsSession() == S_OK) endpointSessions[0] = session;
@ -358,13 +350,6 @@ void Endpoint::activateEndpointSessions() {
sessionEnumerator->Release(); sessionEnumerator->Release();
} }
/*
* void Endpoint::deleteSessionManager() {
* sessionManager->Release();
* sessionManager = nullptr;
* }
*/
void Endpoint::addSession(Session* session) { void Endpoint::addSession(Session* session) {
session->setIndex(this->getSessionCount()); session->setIndex(this->getSessionCount());
endpointSessions.push_back(session); endpointSessions.push_back(session);
@ -372,15 +357,9 @@ void Endpoint::addSession(Session* session) {
void Endpoint::activateEndpointVolume() { void Endpoint::activateEndpointVolume() {
//If this EP is created after init, COM won't be initialized on the executing thread. //If this EP is created after init, COM won't be initialized on the executing thread.
HRESULT result = CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE); HRESULT result = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (this->endpointVolume == nullptr) { if (this->endpointVolume == nullptr) {
if(FAILED(endpoint->Activate( endpoint->Activate(IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (void**)&this->endpointVolume);
IID_IAudioEndpointVolume,
CLSCTX_ALL,
NULL,
(void**)&this->endpointVolume))) {
log_debugcpp("No volume, huh");
}
//todo: check header //todo: check header
if(FAILED(endpoint->Activate(__uuidof(IAudioMeterInformation), if(FAILED(endpoint->Activate(__uuidof(IAudioMeterInformation),
@ -615,8 +594,8 @@ void Overseer::createEndpoints(Flows flow) {
/* /*
* Counting them * Counting them
*/ */
if(FAILED(deviceCollection->GetCount(&numEndpoints))) { log_debugcpp("si");}; if(FAILED(deviceCollection->GetCount(&numEndpoints))) { log_debugcpp("si");};
if(numEndpoints == 0) { log_debugcpp("si"); }; if(numEndpoints == 0) { log_debugcpp("si"); };
/* /*
* Retrieving actual endpoints and storing them on their own collection * Retrieving actual endpoints and storing them on their own collection

View file

@ -82,7 +82,6 @@ class Endpoint {
void unregisterNewSessionNotification(EndpointNewSessionCallback* ensc); void unregisterNewSessionNotification(EndpointNewSessionCallback* ensc);
void deleteSessions(); void deleteSessions();
void activateEndpointSessions(); void activateEndpointSessions();
//void deleteSessionManager();
std::mutex endpointSessionsMutex; std::mutex endpointSessionsMutex;
~Endpoint(); ~Endpoint();
@ -92,13 +91,12 @@ class Endpoint {
std::vector<Session*> endpointSessions; std::vector<Session*> endpointSessions;
uint32_t channelCount = 0; uint32_t channelCount = 0;
IMMDevice *endpoint; IMMDevice *endpoint;
IAudioEndpointVolume *endpointVolume = nullptr; IAudioClient *audioClient;
IPropertyStore *properties;
IAudioMeterInformation *endpointPeakMeter = nullptr;
//IAudioClient *audioClient;
int64_t defTime, minTime; int64_t defTime, minTime;
IAudioSessionManager2 *sessionManager = nullptr; IAudioSessionManager2 *sessionManager = nullptr;
Flows flow; Flows flow;
IAudioEndpointVolume *endpointVolume = nullptr;
IPropertyStore *properties;
std::wstring friendlyName; std::wstring friendlyName;
std::wstring descriptionName; std::wstring descriptionName;
std::wstring deviceName; std::wstring deviceName;
@ -107,6 +105,7 @@ class Endpoint {
Roles endpointRoles = (Roles)0; Roles endpointRoles = (Roles)0;
uint64_t idx; uint64_t idx;
//Not implemented in llvm-mingw. Sad! todo: mingw patch //Not implemented in llvm-mingw. Sad! todo: mingw patch
IAudioMeterInformation *endpointPeakMeter = nullptr;
IPolicyConfig7* policyConfig; IPolicyConfig7* policyConfig;
}; };
@ -126,7 +125,7 @@ class EndpointVolumeCallback : public IAudioEndpointVolumeCallback {
private: private:
ULONG ref = 1; ULONG ref = 1;
Endpoint* ep; Endpoint* ep;
std::atomic<bool> wait = false; bool wait = false;
}; };
class EndpointSituationCallback : public IMMNotificationClient { class EndpointSituationCallback : public IMMNotificationClient {
@ -144,7 +143,7 @@ class EndpointSituationCallback : public IMMNotificationClient {
private: private:
ULONG ref = 1; ULONG ref = 1;
Overseer* os; Overseer* os;
std::atomic<bool> isEpStateChanging = false; bool isEpStateChanging = false;
}; };
class Overseer { class Overseer {
@ -205,7 +204,7 @@ class EndpointNewSessionCallback : public IAudioSessionNotification {
void createSessionThread(SessionThreadParams params); void createSessionThread(SessionThreadParams params);
private: private:
std::atomic<bool> wait = false; bool wait = false;
ULONG ref = 1; ULONG ref = 1;
EndpointHandler *eph; EndpointHandler *eph;

View file

@ -39,7 +39,6 @@ HRESULT SessionStateCallback::QueryInterface(REFIID riid, VOID **ppvInterface) {
HRESULT SessionStateCallback::OnDisplayNameChanged(LPCWSTR NewDisplayName, LPCGUID EventContext) { HRESULT SessionStateCallback::OnDisplayNameChanged(LPCWSTR NewDisplayName, LPCGUID EventContext) {
//TODO: Preguntar //TODO: Preguntar
while(sh->getVolumeInfo()->isNameChanged == true); while(sh->getVolumeInfo()->isNameChanged == true);
sh->setName(std::wstring(NewDisplayName)); sh->setName(std::wstring(NewDisplayName));
sh->getVolumeInfo()->isNameChanged = true; sh->getVolumeInfo()->isNameChanged = true;
return S_OK; return S_OK;
@ -239,15 +238,13 @@ bool Session::fetchNameViaFD(std::wstring exePath, DWORD pid, std::wstring *sess
void* fileVersionInfo = malloc(fileVersionInfoSize); void* fileVersionInfo = malloc(fileVersionInfoSize);
if(!GetFileVersionInfoExW(FILE_VER_GET_LOCALISED | FILE_VER_GET_NEUTRAL, if(!GetFileVersionInfoExW(FILE_VER_GET_LOCALISED | FILE_VER_GET_NEUTRAL,
exePath.c_str(),0,fileVersionInfoSize, fileVersionInfo)) { exePath.c_str(),0,fileVersionInfoSize, fileVersionInfo))
return false; return false;
}
UINT translationArrayLen = 0; UINT translationArrayLen = 0;
if (!VerQueryValueW(fileVersionInfo, L"\\VarFileInfo\\Translation", (LPVOID*)&translationArray, &translationArrayLen)) { if (!VerQueryValueW(fileVersionInfo, L"\\VarFileInfo\\Translation", (LPVOID*)&translationArray, &translationArrayLen))
free(fileVersionInfo);
return false; return false;
}
//File descriptor parsing //File descriptor parsing
//TODO: https://learn.microsoft.com/en-us/windows/win32/api/winnls/nf-winnls-getuserpreferreduilanguages //TODO: https://learn.microsoft.com/en-us/windows/win32/api/winnls/nf-winnls-getuserpreferreduilanguages
/* It is possible to retrieve user languages and try to use one of those before falling back to whatever /* It is possible to retrieve user languages and try to use one of those before falling back to whatever
@ -260,6 +257,7 @@ bool Session::fetchNameViaFD(std::wstring exePath, DWORD pid, std::wstring *sess
int8_t syslangIdx = -1; int8_t syslangIdx = -1;
wchar_t metadataStringKey[256]; wchar_t metadataStringKey[256];
wchar_t* metadataString = NULL; wchar_t* metadataString = NULL;
//std::wstring name;
for (UINT i = 0; i < availableLangs; i++) { for (UINT i = 0; i < availableLangs; i++) {
LANGID defaultUILanguage = GetUserDefaultUILanguage(); LANGID defaultUILanguage = GetUserDefaultUILanguage();
if (defaultUILanguage != translationArray[i].wLanguage) if (defaultUILanguage != translationArray[i].wLanguage)
@ -342,6 +340,8 @@ bool Session::fetchNameViaMSIX(std::wstring exePath, DWORD pid, std::wstring *se
if (sessionName->length() > 0) if (sessionName->length() > 0)
return true; return true;
else return false; else return false;
} }
@ -419,7 +419,4 @@ Session::~Session() {
meterInformation->Release(); meterInformation->Release();
sessionControl->Release(); sessionControl->Release();
sessionVolume->Release(); sessionVolume->Release();
meterInformation = nullptr;
sessionControl = nullptr;
sessionVolume = nullptr;
} }

View file

@ -28,6 +28,7 @@ EndpointHandler::EndpointHandler(uint64_t idx, Flows flow) {
this->flow = flow; this->flow = flow;
this->ep = (flow == Flows::FLOW_PLAYBACK ? osh->getPlaybackEndpoints().at(idx) : osh->getCaptureEndpoints().at(idx)); this->ep = (flow == Flows::FLOW_PLAYBACK ? osh->getPlaybackEndpoints().at(idx) : osh->getCaptureEndpoints().at(idx));
epc = new EndpointVolumeCallback(ep);
this->callbackInfo.caller = osh->getGuid(); this->callbackInfo.caller = osh->getGuid();
//epName = ep->getName(); //epName = ep->getName();
this->setBackEndpointVolumeCallbackInfoContent(this->getState()); this->setBackEndpointVolumeCallbackInfoContent(this->getState());
@ -114,10 +115,7 @@ void EndpointHandler::setBackEndpointVolumeCallbackInfoContent(uint8_t state) {
callbackInfo.muted = this->getMute(); callbackInfo.muted = this->getMute();
callbackInfo.mainVolume = this->getVolume(AudioChannel::CHANNEL_MAIN); callbackInfo.mainVolume = this->getVolume(AudioChannel::CHANNEL_MAIN);
callbackInfo.channels = this->getChannelCount(); callbackInfo.channels = this->getChannelCount();
if (!epc) { ep->setVolumeCallback(epc);
epc = new EndpointVolumeCallback(ep);
ep->setVolumeCallback(epc);
}
callbackInfo.channelVolumes.resize(this->callbackInfo.channels); callbackInfo.channelVolumes.resize(this->callbackInfo.channels);
for(uint32_t i = 0; i < this->getChannelCount(); i++){ for(uint32_t i = 0; i < this->getChannelCount(); i++){
callbackInfo.channelVolumes.at(i) = this->getVolume(i); callbackInfo.channelVolumes.at(i) = this->getVolume(i);
@ -183,13 +181,13 @@ Endpoint* EndpointHandler::getEndpoint() {
void EndpointHandler::addSessionSendFront(Session* session) { void EndpointHandler::addSessionSendFront(Session* session) {
if(!ep->endpointSessionsMutex.try_lock()) return; if(!ep->endpointSessionsMutex.try_lock()) return;
sessionHandlersMutex.lock();
this->ep->addSession(session); this->ep->addSession(session);
SessionHandler* sessionHandler = new SessionHandler(this, session, (getSessionCount() - 1)); SessionHandler* sessionHandler = new SessionHandler(this, session, (getSessionCount() - 1));
sessionHandlers.push_back(sessionHandler);
ep->endpointSessionsMutex.unlock(); ep->endpointSessionsMutex.unlock();
sessionHandlersMutex.lock();
sessionHandlers.push_back(sessionHandler);
sessionHandlersMutex.unlock(); sessionHandlersMutex.unlock();
this->addSessionWidget(sessionHandler); this->addSessionWidget(sessionHandler);
} }
@ -205,13 +203,11 @@ void EndpointHandler::removeSessionFromFront(SessionHandler* sh) {
void EndpointHandler::deleteSessions() { void EndpointHandler::deleteSessions() {
ep->unregisterNewSessionNotification(ensc); ep->unregisterNewSessionNotification(ensc);
ensc->Release(); ensc->Release();
ensc = nullptr;
for (auto sh : sessionHandlers) { for (auto sh : sessionHandlers) {
delete sh; delete sh;
} }
sessionHandlers.resize(0); sessionHandlers.resize(0);
ep->deleteSessions(); ep->deleteSessions();
//ep->deleteSessionManager();
} }
void EndpointHandler::createSessionHandlers() { void EndpointHandler::createSessionHandlers() {
@ -222,9 +218,6 @@ void EndpointHandler::createSessionHandlers() {
sessionHandlers.push_back(sessionHandler); sessionHandlers.push_back(sessionHandler);
} }
} }
}
void EndpointHandler::createSessionHandlersCallback() {
ensc = new EndpointNewSessionCallback(this); ensc = new EndpointNewSessionCallback(this);
ep->registerNewSessionNotification(ensc); ep->registerNewSessionNotification(ensc);
} }
@ -239,12 +232,6 @@ void EndpointHandler::unlockSessionCollections() {
this->ep->endpointSessionsMutex.unlock(); this->ep->endpointSessionsMutex.unlock();
} }
void EndpointHandler::removeVolumeCallback() {
ep->removeVolumeCallback(epc);
epc->Release();
epc = nullptr;
}
EndpointHandler::~EndpointHandler() { EndpointHandler::~EndpointHandler() {
ep->removeVolumeCallback(epc); ep->removeVolumeCallback(epc);
ep->unregisterNewSessionNotification(ensc); ep->unregisterNewSessionNotification(ensc);
@ -424,13 +411,10 @@ void OverseerHandler::reviseEndpointShowing(std::wstring endpointId, EndpointSta
if (flow == Flows::FLOW_CAPTURE) goto end; if (flow == Flows::FLOW_CAPTURE) goto end;
if (eph && EndpointState::ENDPOINT_ACTIVE & state) { if (eph && EndpointState::ENDPOINT_ACTIVE & state) {
eph->setState(EndpointState::ENDPOINT_ACTIVE);
this->addEndpointWidget(eph); this->addEndpointWidget(eph);
} else if (eph && eph->getFrontVisibilityState() == EndpointState::ENDPOINT_ACTIVE) { } else if (eph && eph->getFrontVisibilityState() == EndpointState::ENDPOINT_ACTIVE) {
eph->removeVolumeCallback();
this->removeEndpointWidget(eph->getFrontVisibilityIndex()); this->removeEndpointWidget(eph->getFrontVisibilityIndex());
} }
end: end:
handlersPlaybackMutex.unlock(); handlersPlaybackMutex.unlock();
handlersCaptureMutex.unlock(); handlersCaptureMutex.unlock();

View file

@ -76,11 +76,9 @@ public:
void removeSessionFromFront(SessionHandler* sh); void removeSessionFromFront(SessionHandler* sh);
void deleteSessions(); void deleteSessions();
void createSessionHandlers(); void createSessionHandlers();
void createSessionHandlersCallback();
std::mutex sessionHandlersMutex; std::mutex sessionHandlersMutex;
void lockSessionCollections(); void lockSessionCollections();
void unlockSessionCollections(); void unlockSessionCollections();
void removeVolumeCallback();
~EndpointHandler(); ~EndpointHandler();
private: private:

View file

@ -9,10 +9,10 @@ class SessionStateCallback;
struct SessionVolumeInfo { struct SessionVolumeInfo {
//SessionVolumeInfo(bool muted, float mainVolume); //SessionVolumeInfo(bool muted, float mainVolume);
bool muted; bool muted;
float mainVolume; float mainVolume;
NGuid caller; NGuid caller;
std::atomic<bool> isNameChanged = false; bool isNameChanged = false;
//size_t channels; //size_t channels;
//std::vector<float> channelVolumes; //std::vector<float> channelVolumes;
}; };

View file

@ -207,36 +207,6 @@ void ExtendedCheckBox::customEvent(QEvent* ev) {
QCheckBox::customEvent(ev); QCheckBox::customEvent(ev);
} }
void ExtendedCheckBox::paintEvent(QPaintEvent *event) {
QStylePainter p(this);
QStyleOptionButton opt;
initStyleOption(&opt);
opt.icon = this->icons;
p.drawControl((QStyle::ControlElement)CustomControlElement::CE_ExtendedCheckBox, opt);
//QStyle* style = QApplication::style();
//style->drawComplexControl((QStyle::ComplexControl)CC_MeterSlider, &sliderComplex2, &painter, this);
}
void ExtendedCheckBox::addIcon(char* const path, QIcon::State state) {
QString str(path);
QSvgRenderer rr(str);
QPixmap pixmap(64, 64);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
rr.render(&painter);
painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
uint8_t a, r, g, b;
if (StylingHelper::argbToDiscreteValues(osh->getAccentColor(), &r, &g, &b, &a)) {
QColor color(r, g, b, a);
painter.fillRect(pixmap.rect(), color);
}
painter.end();
icons.addPixmap(pixmap, QIcon::Normal, state);
//this->setIcon(icons);
//icons.addFile(":/Icons/images/second.svg",QSize(32,32),QIcon::Normal,QIcon::Off);
}
QRect MainWindow::setSizePosition(QScreen* screen, int width, int height) { QRect MainWindow::setSizePosition(QScreen* screen, int width, int height) {
//setGeometry ignores decoration size, theres others for that //setGeometry ignores decoration size, theres others for that
QRect trayIconPos = this->trayIcon->geometry(); QRect trayIconPos = this->trayIcon->geometry();
@ -306,7 +276,7 @@ void MainWindow::compose(bool isVisible) {
* Setting correct widget widths and heights * Setting correct widget widths and heights
*/ */
log_to_file("[Compose]\n"); log_to_file("[Compose]\n");
screen = StylingHelper::getCurrentScreen(); screen = this->getCurrentScreen();
log_debugcpp("Screen: " + screen->model().toStdString() + " " + screen->name().toStdString()); log_debugcpp("Screen: " + screen->model().toStdString() + " " + screen->name().toStdString());
QRect screenRes = screen->geometry(); QRect screenRes = screen->geometry();
@ -366,7 +336,7 @@ void MainWindow::compose(bool isVisible) {
} }
QScreen* MainWindow::getCurrentScreen() { QScreen* MainWindow::getCurrentScreen() {
//note: Using cursor pos as screen detector. Flawed. //todo: Using cursor pos as screen detector. Flawed.
QPoint cursorPos = QCursor::pos(); QPoint cursorPos = QCursor::pos();
log_debugcpp("Cursor pos: " + std::to_string(cursorPos.ry()) + " " + std::to_string(cursorPos.rx())); log_debugcpp("Cursor pos: " + std::to_string(cursorPos.ry()) + " " + std::to_string(cursorPos.rx()));
@ -393,9 +363,7 @@ SessionWidget::SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent)
widgetLayout->getContentsMargins(&left, &top, &right, &bottom); widgetLayout->getContentsMargins(&left, &top, &right, &bottom);
widgetLayout->setContentsMargins(0, top, 0, bottom); widgetLayout->setContentsMargins(0, top, 0, bottom);
muteButton = new ExtendedCheckBox(this); muteButton = new QCheckBox(this);
muteButton->addIcon(":/assets/mute.svg", QIcon::On);
muteButton->addIcon(":/assets/unmute.svg", QIcon::Off);
mainLabel = new QLabel(QString::fromStdWString(sh->getName()), this); mainLabel = new QLabel(QString::fromStdWString(sh->getName()), this);
mainLabel->setToolTip(QString::fromStdWString(sh->getName())); mainLabel->setToolTip(QString::fromStdWString(sh->getName()));
mainSlider = new MeterSlider(Qt::Horizontal, this); mainSlider = new MeterSlider(Qt::Horizontal, this);
@ -443,7 +411,6 @@ SessionWidget::SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent)
if (sh->getVolumeInfo()->isNameChanged) { if (sh->getVolumeInfo()->isNameChanged) {
mainLabel->setText(QString::fromStdWString(sh->getName())); mainLabel->setText(QString::fromStdWString(sh->getName()));
mainLabel->setToolTip(QString::fromStdWString(sh->getName())); mainLabel->setToolTip(QString::fromStdWString(sh->getName()));
sh->getVolumeInfo()->isNameChanged = false;
} }
const float roundingFactor = 0.005; const float roundingFactor = 0.005;
mainSlider->blockSignals(true); mainSlider->blockSignals(true);
@ -571,7 +538,7 @@ EndpointWidget::EndpointWidget(EndpointHandler* eph, QWidget *parent, uint64_t i
eph->createSessionHandlers(); eph->createSessionHandlers();
//todo: sussy //todo: sussy
this->eph->setFrontVisibilityInfo(EndpointState::ENDPOINT_ACTIVE, idx); this->eph->setState(EndpointState::ENDPOINT_ACTIVE, idx);
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
widgetLayout = new QGridLayout(this); widgetLayout = new QGridLayout(this);
//this->setContentsMargins(0, 0, 0, 0); //this->setContentsMargins(0, 0, 0, 0);
@ -731,9 +698,9 @@ EndpointWidget::EndpointWidget(EndpointHandler* eph, QWidget *parent, uint64_t i
}); });
log_debugcpp("ENDPOINT_WIDGETED"); log_debugcpp("ENDPOINT_WIDGETED");
eph->createSessionHandlersCallback();
} }
void EndpointWidget::addSessionWidget(CustomWidgetEvent<SessionHandler*>* ev){ void EndpointWidget::addSessionWidget(CustomWidgetEvent<SessionHandler*>* ev){
this->setUpdatesEnabled(false); this->setUpdatesEnabled(false);
uint64_t index = this->sessionWidgets.size(); uint64_t index = this->sessionWidgets.size();
@ -812,7 +779,7 @@ void MainWindow::customEvent(QEvent* ev) {
} }
//__attribute__((optimize("O0", "unroll-loops"))) //__attribute__((optimize("O0", "unroll-loops")))
void MainWindow::removeEndpointWidget(CustomWidgetEvent<uint64_t>* ev) { void MainWindow::removeEndpointWidget(CustomWidgetEvent<uint64_t>* ev){
uint64_t i = ev->payload; uint64_t i = ev->payload;
this->ews.at(i)->setParent(nullptr); this->ews.at(i)->setParent(nullptr);
this->widgetLayout->removeWidget(ews.at(i)); this->widgetLayout->removeWidget(ews.at(i));
@ -825,7 +792,7 @@ void MainWindow::removeEndpointWidget(CustomWidgetEvent<uint64_t>* ev) {
return; return;
} }
void MainWindow::addEndpointWidget(CustomWidgetEvent<EndpointHandler*>* ev) { void MainWindow::addEndpointWidget(CustomWidgetEvent<EndpointHandler*>* ev){
EndpointWidget* epw = new EndpointWidget(ev->payload, containerWidget, this->ews.size()); EndpointWidget* epw = new EndpointWidget(ev->payload, containerWidget, this->ews.size());
//epw->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); //epw->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
epw->setParent(this); epw->setParent(this);
@ -957,9 +924,9 @@ EndpointHandler* EndpointWidget::getEndpointHandler(){
* } * }
*/ */
void EndpointWidget::setIndex(uint64_t idx) { void EndpointWidget::setIndex(uint64_t idx){
this->idx = idx; this->idx = idx;
this->eph->setFrontVisibilityInfo(EndpointState::ENDPOINT_ACTIVE, this->idx); this->eph->setState(EndpointState::ENDPOINT_ACTIVE, this->idx);
} }
uint64_t EndpointWidget::getIndex(){ uint64_t EndpointWidget::getIndex(){

View file

@ -40,17 +40,12 @@ public:
class ExtendedCheckBox : public QCheckBox { class ExtendedCheckBox : public QCheckBox {
Q_OBJECT Q_OBJECT
private:
QIcon icons;
protected: protected:
void customEvent(QEvent* ev) override; void customEvent(QEvent* ev) override;
void paintEvent(QPaintEvent* event) override;
public: public:
//c++11: this inherits all parent's constructors unconditionally //c++11: this inherits all parent's constructors unconditionally
using QCheckBox::QCheckBox; using QCheckBox::QCheckBox;
void addIcon(char* const path, QIcon::State state);
//alternative being calling parent ctor directly after declaring child ctor: //alternative being calling parent ctor directly after declaring child ctor:
//B(int x) : A(x) { } //B(int x) : A(x) { }
}; };
@ -73,7 +68,7 @@ private:
MeterSlider *mainSlider = nullptr; MeterSlider *mainSlider = nullptr;
uint64_t idx; uint64_t idx;
QHBoxLayout *widgetLayout = nullptr; QHBoxLayout *widgetLayout = nullptr;
ExtendedCheckBox *muteButton = nullptr; QCheckBox *muteButton = nullptr;
SessionHandler* sh; SessionHandler* sh;
QTimer* volumePoller = nullptr; QTimer* volumePoller = nullptr;
QSpacerItem* widthSpacer; QSpacerItem* widthSpacer;

View file

@ -44,7 +44,6 @@
#include <QFontDatabase> #include <QFontDatabase>
#include <QAbstractNativeEventFilter> #include <QAbstractNativeEventFilter>
#include <QAbstractEventDispatcher> #include <QAbstractEventDispatcher>
#include <QSvgRenderer>
//#include <QScrollbarStyleAnimation> //#include <QScrollbarStyleAnimation>
//#include <QScrollBar> //#include <QScrollBar>
/* /*
@ -64,10 +63,6 @@ enum CustomComplexControl {
CC_MeterSlider = 0xf0000001 CC_MeterSlider = 0xf0000001
}; };
enum CustomControlElement {
CE_ExtendedCheckBox = 0xf0000001
};
namespace StylingHelper { namespace StylingHelper {
static inline void setBackgroundColor(bool lightMode) { static inline void setBackgroundColor(bool lightMode) {
@ -223,32 +218,5 @@ namespace StylingHelper {
return pal.color(QPalette::Base); return pal.color(QPalette::Base);
} }
static inline QPixmap svg2Pixmap(const QString& svgContent,
const QSize& size,
QPainter::CompositionMode mode = QPainter::CompositionMode_SourceOver)
{
QSvgRenderer rr(svgContent);
QImage image(size.width(), size.height(), QImage::Format_ARGB32);
QPainter painter(&image);
painter.setCompositionMode(mode);
image.fill(Qt::transparent);
rr.render(&painter);
return QPixmap::fromImage(image);
}
static inline QScreen* getCurrentScreen() {
//note: Using cursor pos as screen detector. Flawed.
QPoint cursorPos = QCursor::pos();
for (QScreen *screen : QGuiApplication::screens()) {
QRect screenRect = screen->geometry();
if (screenRect.contains(cursorPos)) {
return screen;
}
}
return QGuiApplication::primaryScreen();
}
} }

View file

@ -20,10 +20,8 @@ public:
return baseStyle()->styleHint(hint, option, widget, returnData); return baseStyle()->styleHint(hint, option, widget, returnData);
} }
QRect subControlRect(ComplexControl control, QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option,
const QStyleOptionComplex *option, SubControl subControl, const QWidget *widget) const {
SubControl subControl,
const QWidget *widget) const {
QRect rect = QCommonStyle::subControlRect(CC_Slider, option, subControl, widget); QRect rect = QCommonStyle::subControlRect(CC_Slider, option, subControl, widget);
switch (control) { switch (control) {
@ -188,51 +186,6 @@ public:
} }
void drawControl(ControlElement element, const QStyleOption *opt,
QPainter *p, const QWidget *widget) const
{
switch(element) {
case CE_ExtendedCheckBox:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
QStyleOptionButton subopt = *btn;
subopt.rect = subElementRect(SE_CheckBoxIndicator, btn, widget);
//proxy()->drawPrimitive(PE_IndicatorCheckBox, &subopt, p, widget);
subopt.rect = subElementRect(SE_CheckBoxContents, btn, widget);
//proxy()->drawControl(CE_CheckBoxLabel, &subopt, p, widget);
int alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter);
if (!proxy()->styleHint(SH_UnderlineShortcut, btn, widget))
alignment |= Qt::TextHideMnemonic;
QPixmap pix;
QRect textRect = btn->rect;
if (!btn->icon.isNull()) {
pix = btn->icon.pixmap(btn->iconSize, StylingHelper::getCurrentScreen()->devicePixelRatio(),
QIcon::Mode::Normal, btn->state & State_On ? QIcon::On : QIcon::Off);
proxy()->drawItemPixmap(p, btn->rect, alignment, pix);
if (btn->direction == Qt::RightToLeft)
textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
else
textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
}
if (!btn->text.isEmpty()){
proxy()->drawItemText(p, textRect, alignment | Qt::TextShowMnemonic,
btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText);
}
//
if (btn->state & State_HasFocus) {
QStyleOptionFocusRect fropt;
fropt.QStyleOption::operator=(*btn);
fropt.rect = subElementRect(SE_CheckBoxFocusRect, btn, widget);
proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
}
}
default:
baseStyle()->drawControl(element, opt, p, widget);
break;
}
}
void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option,
QPainter *painter, const QWidget *widget) const { QPainter *painter, const QWidget *widget) const {
QColor outline; QColor outline;