diff --git a/src/back/backlasses.cpp b/src/back/backlasses.cpp index c1607cc..8960c49 100644 --- a/src/back/backlasses.cpp +++ b/src/back/backlasses.cpp @@ -47,7 +47,7 @@ HRESULT EndpointNewSessionCallback::OnSessionCreated(IAudioSessionControl *NewSe sessionControl->AddRef(); //sessionControl->QueryInterface(__uuidof(ISimpleAudioVolume), (void**)&sessionVolume); Session* newSession = new Session(this->eph->getEndpoint(), sessionControl); - eph->addSession(newSession); + eph->addSessionSendFront(newSession); } if (result == S_OK) @@ -602,7 +602,6 @@ void Overseer::reloadEndpoints(Flows flow) { if(deviceCollection->Item(i, &temp) != 0) { log_debugcpp("si"); }; Endpoint *endpoint = new Endpoint(temp, i); - //endpoint->setIndex(i); if (flow == Flows::FLOW_PLAYBACK) this->playbackDevices.push_back(endpoint); else diff --git a/src/back/backsessionclasses.cpp b/src/back/backsessionclasses.cpp index 7f3b101..ced7fb1 100644 --- a/src/back/backsessionclasses.cpp +++ b/src/back/backsessionclasses.cpp @@ -71,57 +71,26 @@ HRESULT SessionStateCallback::OnGroupingParamChanged(LPCGUID NewGroupingParam, L } HRESULT SessionStateCallback::OnStateChanged(AudioSessionState NewState) { - /* enum _AudioSessionState { - * AudioSessionStateInactive, - * AudioSessionStateActive, - * AudioSessionStateExpired - * } AudioSessionState; */ - /* - * char *pszState = "?????"; - * - * switch (NewState) - * { - * case AudioSessionStateActive: - * pszState = "active"; - * break; - * case AudioSessionStateInactive: - * pszState = "inactive"; - * break; - * } - * printf("New session state = %s\n", pszState); - */ + SessionState newState;// = sh->getState(); + switch (NewState) { + case AudioSessionStateActive: + newState = SessionState::ACTIVE; + break; + case AudioSessionStateInactive: + newState = SessionState::INACTIVE; + break; + case AudioSessionStateExpired: + newState = SessionState::EXPIRED; + break; + } + + sh->reviseSessionShowing(newState); return S_OK; } HRESULT SessionStateCallback::OnSessionDisconnected(AudioSessionDisconnectReason DisconnectReason) { - /* - * char *pszReason = "?????"; - * - * switch (DisconnectReason) - * { - * case DisconnectReasonDeviceRemoval: - * pszReason = "device removed"; - * break; - * case DisconnectReasonServerShutdown: - * pszReason = "server shut down"; - * break; - * case DisconnectReasonFormatChanged: - * pszReason = "format changed"; - * break; - * case DisconnectReasonSessionLogoff: - * pszReason = "user logged off"; - * break; - * case DisconnectReasonSessionDisconnected: - * pszReason = "session disconnected"; - * break; - * case DisconnectReasonExclusiveModeOverride: - * pszReason = "exclusive-mode override"; - * break; - * } - * printf("Audio session disconnected (reason: %s)\n", - * pszReason); - */ - + sh->setState(SessionState::DISCONNECTED); + sh->reviseSessionShowing(SessionState::DISCONNECTED); return S_OK; } diff --git a/src/cont/contclasses.cpp b/src/cont/contclasses.cpp index 1982bf8..38c30b1 100644 --- a/src/cont/contclasses.cpp +++ b/src/cont/contclasses.cpp @@ -153,6 +153,10 @@ void EndpointHandler::setAddSessionWidgetFunction(std::functionaddSessionWidget = addSessionWidget; } +void EndpointHandler::setRemoveSessionWidgetFunction(std::function removeSessionWidget) { + this->removeSessionWidget = removeSessionWidget; +} + /* sessions */ size_t EndpointHandler::getSessionCount() { return ep->getSessionCount(); @@ -170,7 +174,7 @@ Endpoint* EndpointHandler::getEndpoint() { return this->ep; } -void EndpointHandler::addSession(Session* session) { +void EndpointHandler::addSessionSendFront(Session* session) { ep->addSession(session); SessionHandler* sessionHandler = new SessionHandler(this, session, (getSessionCount() - 1)); @@ -178,6 +182,14 @@ void EndpointHandler::addSession(Session* session) { this->addSessionWidget(sessionHandler); } +void EndpointHandler::sendSessionToFront(SessionHandler* sh) { + this->addSessionWidget(sh); +} + +void EndpointHandler::removeSessionFromFront(SessionHandler* sh) { + this->removeSessionWidget(sh); +} + EndpointHandler::~EndpointHandler() { ep->removeVolumeCallback(epc); ep->unregisterNewSessionNotification(ensc); diff --git a/src/cont/contclasses.h b/src/cont/contclasses.h index df4d755..25fcaea 100644 --- a/src/cont/contclasses.h +++ b/src/cont/contclasses.h @@ -66,8 +66,11 @@ public: Endpoint* getEndpoint(); /*Session*/ - void addSession(Session* session); + void addSessionSendFront(Session* session); void setAddSessionWidgetFunction(std::function addSessionWidget); + void setRemoveSessionWidgetFunction(std::function removeSessionWidget); + void sendSessionToFront(SessionHandler* sh); + void removeSessionFromFront(SessionHandler* sh); ~EndpointHandler(); private: @@ -86,6 +89,7 @@ private: EndpointNewSessionCallback* ensc; std::vector sessionHandlers; std::function addSessionWidget; + std::function removeSessionWidget; //QSlider *slidy; }; diff --git a/src/cont/contsessionclasses.cpp b/src/cont/contsessionclasses.cpp index e3f69d0..155c0e1 100644 --- a/src/cont/contsessionclasses.cpp +++ b/src/cont/contsessionclasses.cpp @@ -36,6 +36,44 @@ bool SessionHandler::getMute(){ return session->getMute(); } +void SessionHandler::setFrontIndex(uint64_t frontIdx) { + this->frontIdx = frontIdx; +} + +uint64_t SessionHandler::getFrontIndex() { + return frontIdx; +} + SessionVolumeInfo* SessionHandler::getVolumeInfo() { return &svi; } + +SessionState SessionHandler::getState() { + return session->getState(); +} + +void SessionHandler::setState(SessionState state) { + session->setState(state); +} + +void SessionHandler::reviseSessionShowing(SessionState state) { + SessionState currentState = this->getState(); + switch (currentState) { + case SessionState::ACTIVE: + case SessionState::INACTIVE: + if (state == SessionState::EXPIRED) { + eph->removeSessionFromFront(this); + } + break; + case SessionState::EXPIRED: + if (state == SessionState::ACTIVE || INACTIVE) { + eph->sendSessionToFront(this); + } + break; + case SessionState::DISCONNECTED: + if (frontIdx != INT_MAX) + eph->removeSessionFromFront(this); + break; + } +} + diff --git a/src/cont/contsessionclasses.h b/src/cont/contsessionclasses.h index e637e47..51f620f 100644 --- a/src/cont/contsessionclasses.h +++ b/src/cont/contsessionclasses.h @@ -24,7 +24,12 @@ class SessionHandler { float getVolume(int channel); void setMute(NGuid guid, bool muted); bool getMute(); + void setFrontIndex(uint64_t frontIdx); + SessionState getState(); + void setState(SessionState state); + uint64_t getFrontIndex(); std::wstring getName(); + void reviseSessionShowing(SessionState state); SessionVolumeInfo* getVolumeInfo(); private: @@ -33,5 +38,5 @@ class SessionHandler { Session* session; SessionStateCallback* ssc; size_t idx; - + uint64_t frontIdx = INT_MAX; }; diff --git a/src/global.h b/src/global.h index ced95ca..292ec06 100644 --- a/src/global.h +++ b/src/global.h @@ -39,10 +39,11 @@ enum EndpointState { }; enum SessionState { - ACTIVE = (1 << 0), - INACTIVE = (1 << 1), - EXPIRED = (1 << 2), - ALL = 0x07 + ACTIVE = (1 << 0), + INACTIVE = (1 << 1), + EXPIRED = (1 << 2), + DISCONNECTED = (1 << 3), + ALL = 0x0F }; enum Flows { diff --git a/src/qt/qtclasses.cpp b/src/qt/qtclasses.cpp index 96cbcc3..a9da261 100644 --- a/src/qt/qtclasses.cpp +++ b/src/qt/qtclasses.cpp @@ -95,6 +95,11 @@ void SessionWidget::updateMainVolume(int newValue){ this->sh->setVolume(osh->getGuid(), AudioChannel::CHANNEL_MAIN, newValue); } +SessionWidget::~SessionWidget() { + volumePoller->stop(); + delete volumePoller; +} + EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *parent) : QWidget(parent){ //todo: based on qgridlayout, name+mute should be its own widget, same with channels row = 0; @@ -261,12 +266,17 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare layout->addWidget(sessionWidget, row, 4); row++; sessionWidgets.push_back(sessionWidget); + eph->getSessionHandlers().at(i)->setFrontIndex(i); } - /* New SessionWidget callback */ + /* Add/Remove SessionWidget callback */ eph->setAddSessionWidgetFunction([this](SessionHandler* sessionHandler) { QCoreApplication::instance()->postEvent(this, new CustomWidgetEvent((QEvent::Type)CustomQEvent::SessionWidgetCreated, sessionHandler)); }); + + eph->setRemoveSessionWidgetFunction([this](SessionHandler* sessionHandler) { + QCoreApplication::instance()->postEvent(this, new CustomWidgetEvent((QEvent::Type)CustomQEvent::SessionWidgetObsolete, sessionHandler)); + }); //todo parent? layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 1, 0); @@ -277,23 +287,34 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare } void EndpointWidget::addSessionWidget(CustomWidgetEvent* ev){ - SessionWidget* sw = new SessionWidget(this->sessionWidgets.size(), ev->payload, this); + uint64_t index = this->sessionWidgets.size(); + SessionWidget* sw = new SessionWidget(index, ev->payload, this); + ev->payload->setFrontIndex(index); this->layout->addWidget(sw, row, 4); row++; sessionWidgets.push_back(sw); return; } +void EndpointWidget::removeSessionWidget(CustomWidgetEvent* ev){ + uint64_t i = ev->payload->getFrontIndex(); + this->sessionWidgets.at(i)->setParent(nullptr); + this->layout->removeWidget(sessionWidgets.at(i)); + delete sessionWidgets.at(i); + sessionWidgets.at(i) = nullptr; + ev->payload->setFrontIndex(INT_MAX); + //this->sessionWidgetsUpdateTimer->start(); + return; +} + void EndpointWidget::customEvent(QEvent* ev) { if (ev->type() == (QEvent::Type)CustomQEvent::SessionWidgetCreated) { ev->setAccepted(true); this->addSessionWidget((CustomWidgetEvent*) ev); - return; } else if (ev->type() == (QEvent::Type)CustomQEvent::SessionWidgetObsolete) { ev->setAccepted(true); - //this->addEndpointWidget((CustomWidgetEvent*)ev); + this->removeSessionWidget((CustomWidgetEvent*) ev); } - // Make sure the rest of events are handled QWidget::customEvent(ev); } @@ -308,12 +329,10 @@ void MainWindow::customEvent(QEvent* ev) { if (ev->type() == CustomQEvent::EndpointWidgetObsolete) { ev->setAccepted(true); this->removeEndpointWidget((CustomWidgetEvent*)ev); - return; } else if (ev->type() == (QEvent::Type)CustomQEvent::EndpointWidgetCreated) { ev->setAccepted(true); this->addEndpointWidget((CustomWidgetEvent*)ev); } - // Make sure the rest of events are handled QMainWindow::customEvent(ev); } @@ -326,15 +345,6 @@ void MainWindow::removeEndpointWidget(CustomWidgetEvent* ev){ delete ews.at(i); ews.at(i) = nullptr; this->ewsUpdateTimer->start(); - - /* - * while ((i + 1) < ews.size()) { - * ews.at(i) = ews.at(i + 1); - * ews.at(i)->setIndex(i); - * i++; - * } - * ews.pop_back(); - */ return; } @@ -346,6 +356,7 @@ void MainWindow::addEndpointWidget(CustomWidgetEvent* ev){ } void MainWindow::reorderEndpointWidgetCollection() { + /* Flatten */ size_t firstNullPosition = 0; size_t ewsSize = ews.size(); bool breakSorting = false; diff --git a/src/qt/qtclasses.h b/src/qt/qtclasses.h index c130fdd..b9c4fa8 100644 --- a/src/qt/qtclasses.h +++ b/src/qt/qtclasses.h @@ -92,7 +92,8 @@ Q_OBJECT public: SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent /* = nullptr */); - + ~SessionWidget(); + public slots: void updateMainVolume(int newValue); void updateMute(int checked); @@ -137,6 +138,7 @@ protected: private slots: void addSessionWidget(CustomWidgetEvent* ev); + void removeSessionWidget(CustomWidgetEvent* ev); private: int row;