diff --git a/ChannelListWidget.cpp b/ChannelListWidget.cpp index 00fbe4a50109361201ba154fc1366f1912d526a4..c468f63b5a339f931149762c2d42d22753076687 100644 --- a/ChannelListWidget.cpp +++ b/ChannelListWidget.cpp @@ -51,25 +51,76 @@ void ChannelTree::mouseMoveEvent(QMouseEvent * event) } +/////////////////////////////////////////////////////////////////////////////////////// + +Background::Background(ChannelListWidget * widget, QWidget *parent) + : QLabel(parent) +{ + m_parent = widget; + + QFile styleSheet("plugins\\qtTsOverlay\\background.styl"); + styleSheet.open(QIODevice::ReadOnly); + setStyleSheet(styleSheet.readAll()); + styleSheet.close(); +} + +Background::~Background() +{ + +} + +void Background::mousePressEvent(QMouseEvent * event) +{ + if (event->button() == Qt::LeftButton) + doMove = true; + else if (event->button() == Qt::RightButton) + m_parent->hide(); + + QLabel::mousePressEvent(event); +} + +void Background::mouseReleaseEvent(QMouseEvent * event) +{ + doMove = false; + + QLabel::mouseReleaseEvent(event); +} + +void Background::mouseMoveEvent(QMouseEvent * event) +{ + if (doMove) + m_parent->move(event->globalPos()); + + QLabel::mouseMoveEvent(event); +} + + /////////////////////////////////////////////////////////////////////////////////////// ChannelListWidget::ChannelListWidget(QWidget *parent) : QWidget(parent) { + m_state = full; + setAttribute(Qt::WA_TranslucentBackground); setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::SplashScreen); move(320, 200); - m_background = new QLabel(this); - QFile styleSheet("plugins\\qtTsOverlay\\background.styl"); - styleSheet.open(QIODevice::ReadOnly); - m_background->setStyleSheet(styleSheet.readAll()); - styleSheet.close(); + m_background = new Background(this, this); QVBoxLayout* layout = new QVBoxLayout(this); layout->setMargin(0); layout->setSpacing(0); + m_button = new QPushButton(this); + m_button->setText("-"); + connect(m_button, &QPushButton::pressed, this, &ChannelListWidget::buttonPressed); + QFile style("plugins\\qtTsOverlay\\button.styl"); + style.open(QIODevice::ReadOnly); + m_button->setStyleSheet(style.readAll()); + style.close(); + layout->addWidget(m_button, 0, Qt::AlignTop | Qt::AlignRight); + m_child = new ChannelTree(this); layout->addWidget(m_child); @@ -84,6 +135,7 @@ ChannelListWidget::~ChannelListWidget() delete m_child; delete m_grip; delete m_background; + delete m_button; } QTreeWidget * ChannelListWidget::getTree() @@ -91,6 +143,22 @@ QTreeWidget * ChannelListWidget::getTree() return (QTreeWidget*)m_child; } +void ChannelListWidget::buttonPressed() +{ + if (m_state == full) + { + m_state = minimum; + m_button->setText("O"); + } + else + { + m_state = full; + m_button->setText("-"); + } + + emit treeStateChanged(m_state); +} + void ChannelListWidget::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); diff --git a/ChannelListWidget.h b/ChannelListWidget.h index dc1cda2e1f27ddb0e08fdf7b6057cf333830f093..74b8541d6ba92edf7ec444f5ebd18e1995c6a153 100644 --- a/ChannelListWidget.h +++ b/ChannelListWidget.h @@ -4,6 +4,12 @@ #include #include #include +#include + +enum TreeState { + full, + minimum +}; class ChannelListWidget; @@ -25,7 +31,25 @@ private: QPoint m_oldPosition; QWidget *m_parent; +}; + +class Background : public QLabel +{ + Q_OBJECT + public: + explicit Background(ChannelListWidget * widget, QWidget *parent = NULL); + ~Background(); + +protected: + virtual void mousePressEvent(QMouseEvent * event) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent * event) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent * event) Q_DECL_OVERRIDE; + +private: + bool doMove = false; + QPoint m_oldPosition; + QWidget *m_parent; }; @@ -38,9 +62,14 @@ public: ~ChannelListWidget(); private: + TreeState m_state; ChannelTree *m_child; QSizeGrip *m_grip; - QLabel *m_background; + Background *m_background; + QPushButton* m_button; + +private slots: + void buttonPressed(); protected: virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; @@ -48,4 +77,7 @@ protected: public: QTreeWidget* getTree(); + +signals: + void treeStateChanged(TreeState state); }; diff --git a/Release/x64/qtTsOverlay_x64.dll b/Release/x64/qtTsOverlay_x64.dll index b08d7981aa2936c05c241234720c500d595ff066..ce839c20acd6c5f7fb6523d3dc4920cec54bb7aa 100644 Binary files a/Release/x64/qtTsOverlay_x64.dll and b/Release/x64/qtTsOverlay_x64.dll differ diff --git a/Release/x64/qtTsOverlay_x64.exp b/Release/x64/qtTsOverlay_x64.exp index 501e4e3b21890854433396ce06ff2156c7f04c45..0c5c38b3f304e07c5782ccd898bea262c7dfa8d8 100644 Binary files a/Release/x64/qtTsOverlay_x64.exp and b/Release/x64/qtTsOverlay_x64.exp differ diff --git a/Release/x64/qtTsOverlay_x64.lib b/Release/x64/qtTsOverlay_x64.lib index 5b4571d58c378ef2d7649b13b977fb38af3127c3..9bb0edc0a89839e4e8a001f2f1284fcbd4bf009c 100644 Binary files a/Release/x64/qtTsOverlay_x64.lib and b/Release/x64/qtTsOverlay_x64.lib differ diff --git a/Resources/button.styl b/Resources/button.styl new file mode 100644 index 0000000000000000000000000000000000000000..c4324b6514ecf3ce0c984fe45ed2233f840c8409 --- /dev/null +++ b/Resources/button.styl @@ -0,0 +1,25 @@ +QPushButton { + width:10px; + height:10px; + font-size:10px; + background-color:rgba(50,50,50,0); + color:rgb(255,255,255); + border-style:solid; + border-radius:5px; + border-width:1px; + border-color:rgb(100,100,100); + padding:2px; + margin:2px; +} + +QPushButton:hover { + width:10px; + height:10px; + background-color:rgba(255,255,255,100); + color:rgb(0,0,0); + border-style:solid; + border-radius:5px; + border-width:1px; + border-color:rgb(100,100,100); + padding:2px; +} \ No newline at end of file diff --git a/overlaycontroller.cpp b/overlaycontroller.cpp index a1373bee56bff92c98173cdac6f0eb27eca53302..46427c5e375aad329df3957b1bf87dbff0ab5502 100644 --- a/overlaycontroller.cpp +++ b/overlaycontroller.cpp @@ -20,10 +20,13 @@ enum nodeType { Q_DECLARE_METATYPE(nodeType); -OverlayController::OverlayController(const struct TS3Functions funcs, quint64 serverConnectionHandlerID) : QObject(), ts3(funcs) +OverlayController::OverlayController(const struct TS3Functions funcs, quint64 serverConnectionHandlerID) : QObject(), m_ts3(funcs) { QDesktopWidget desktop; + m_muted = false; + m_treeState = full; + m_channelIcon.addFile("plugins\\qtTsOverlay\\channel.png"); m_clientIcon.addFile("plugins\\qtTsOverlay\\client.png"); @@ -46,8 +49,10 @@ OverlayController::OverlayController(const struct TS3Functions funcs, quint64 se m_tree = new ChannelListWidget; connect(m_tree->getTree(), &QTreeWidget::itemDoubleClicked, this, &OverlayController::treeItemClicked); + connect(m_tree, &ChannelListWidget::treeStateChanged, this, &OverlayController::changeTreeState); updateChannelList(); + updateClientList(); } OverlayController::~OverlayController() @@ -90,18 +95,25 @@ void OverlayController::treeItemClicked(QTreeWidgetItem * item, int column) if (type == channel) { anyID clientID; - ts3.getClientID(m_SCHID, &clientID); + m_ts3.getClientID(m_SCHID, &clientID); quint64 id = item->data(1, Qt::UserRole).value(); - ts3.requestClientMove(m_SCHID, clientID, id, "", NULL); + m_ts3.requestClientMove(m_SCHID, clientID, id, "", NULL); } else if (type == client) { anyID id = item->data(1, Qt::UserRole).value(); - ts3.requestClientPoke(m_SCHID, id, "", NULL); + m_ts3.requestClientPoke(m_SCHID, id, "", NULL); } } +void OverlayController::changeTreeState(TreeState state) +{ + m_treeState = state; + updateChannelList(); + updateClientList(); +} + void OverlayController::addChatLine(QString message) { // generate new chatline @@ -147,6 +159,9 @@ void OverlayController::addChatLine(QString message) void OverlayController::addSpeaker(QString name) { + if (m_muted) + return; + int labelWidth = 0; QWidget* w = new QWidget; QLabel* newSpeaker = new QLabel(w); @@ -224,7 +239,7 @@ void OverlayController::updateChannelList() { // get list of all channelIDs uint64* channelIDList; - if (ts3.getChannelList(m_SCHID, &channelIDList) != ERROR_ok) + if (m_ts3.getChannelList(m_SCHID, &channelIDList) != ERROR_ok) return; // remove old stuff @@ -240,8 +255,8 @@ void OverlayController::updateChannelList() ChannelInfo tmp; tmp.id = channelIDList[i]; tmp.name = channelID2Name(m_SCHID, channelIDList[i]); - ts3.getChannelVariableAsInt(m_SCHID, tmp.id, CHANNEL_ORDER, &tmp.order); - ts3.getParentChannelOfChannel(m_SCHID, channelIDList[i], &tmp.parent); + m_ts3.getChannelVariableAsInt(m_SCHID, tmp.id, CHANNEL_ORDER, &tmp.order); + m_ts3.getParentChannelOfChannel(m_SCHID, channelIDList[i], &tmp.parent); tmp.entry = new QTreeWidgetItem; tmp.entry->setData(0, Qt::DisplayRole, tmp.name); tmp.entry->setData(1, Qt::UserRole, tmp.id); @@ -261,54 +276,80 @@ void OverlayController::updateChannelList() i++; } - // for every channel - for (auto &parent : m_channelList) + if (m_treeState == full) { - // collect all childs - QVector childs; - for (auto &child : m_channelList) - if (child.parent == parent.id) - childs.push_back(child); - - // add childs in correct order - int prevID(0); - while (!childs.isEmpty()) + + // for every channel + for (auto &parent : m_channelList) + { + // collect all childs + QVector childs; + for (auto &child : m_channelList) + if (child.parent == parent.id) + childs.push_back(child); + + // add childs in correct order + int prevID(0); + while (!childs.isEmpty()) + { + int i; + for (i = 0; i < childs.size(); i++) + if (childs[i].order == prevID) + break; + + prevID = childs[i].id; + parent.entry->addChild(childs.takeAt(i).entry); + } + } + + // get all toplvl channels + QVector topLvlList; + for (auto &it : m_channelList) + if (it.parent == 0) + topLvlList.push_back(it); + + // add toplvl to tree in correct order + int prevID = 0; + while (!topLvlList.isEmpty()) { int i; - for (i = 0; i < childs.size(); i++) - if (childs[i].order == prevID) + for (i = 0; i < topLvlList.size(); i++) + if (topLvlList[i].order == prevID) break; - prevID = childs[i].id; - parent.entry->addChild(childs.takeAt(i).entry); + prevID = topLvlList[i].id; + m_tree->getTree()->addTopLevelItem(topLvlList.takeAt(i).entry); } } + else if (m_treeState == minimum) + { + //TODO: different order + uint64 channel = getCurrentChannel(m_SCHID); + QTreeWidgetItem* item = NULL; - // get all toplvl channels - QVector topLvlList; - for (auto &it : m_channelList) - if (it.parent == 0) - topLvlList.push_back(it); + for (auto &it : m_channelList) + if (it.id == channel) + item = it.entry; - // add toplvl to tree in correct order - int prevID = 0; - while (!topLvlList.isEmpty()) - { - int i; - for (i = 0; i < topLvlList.size(); i++) - if (topLvlList[i].order == prevID) - break; + if (item == NULL) + { + debugPrint("i was here"); + m_ts3.freeMemory(channelIDList); + return; + } + m_tree->getTree()->addTopLevelItem(item); - prevID = topLvlList[i].id; - m_tree->getTree()->addTopLevelItem(topLvlList.takeAt(i).entry); } - updateClientList(); m_tree->getTree()->expandAll(); + m_ts3.freeMemory(channelIDList); } void OverlayController::updateClientList() { + if (m_treeState == minimum) + updateChannelList(); + //TODO: remove all clients while (!m_clientList.isEmpty()) delete m_clientList.takeFirst(); @@ -317,7 +358,7 @@ void OverlayController::updateClientList() for (auto& it : m_channelList) { anyID* clientIDList; - if (ts3.getChannelClientList(m_SCHID, it.id, &clientIDList) != ERROR_ok) + if (m_ts3.getChannelClientList(m_SCHID, it.id, &clientIDList) != ERROR_ok) continue; int i(0); @@ -333,6 +374,7 @@ void OverlayController::updateClientList() it.entry->addChild(tmp); i++; } + m_ts3.freeMemory(clientIDList); } } @@ -342,3 +384,15 @@ void OverlayController::displayChannelList() m_tree->adjustSize(); m_tree->show(); } + +void OverlayController::mute(bool value) +{ + m_muted = value; + + if (m_muted) + { + m_speakerOffset = 0; + while (!m_speakers.isEmpty()) + delete m_speakers.takeFirst(); + } +} diff --git a/overlaycontroller.h b/overlaycontroller.h index a51dabac7f663bdd78380f3326edab4bd4eb5248..51abefbbe367d948cfec6b163acffd1c8ff58fc6 100644 --- a/overlaycontroller.h +++ b/overlaycontroller.h @@ -26,6 +26,7 @@ struct ChannelInfo { int order; }; + class QTTSOVERLAY_EXPORT OverlayController : public QObject { Q_OBJECT @@ -35,8 +36,10 @@ public: ~OverlayController(); private: - const struct TS3Functions ts3; + const struct TS3Functions m_ts3; quint64 m_SCHID; + bool m_muted; + TreeState m_treeState; int m_screenWidth; int m_screenHeight; int m_speakerOffset; @@ -57,6 +60,7 @@ private: private slots: void treeItemClicked(QTreeWidgetItem * item, int column); + void changeTreeState(TreeState state); public: void addChatLine(QString message); @@ -67,4 +71,5 @@ public: void updateChannelList(); void updateClientList(); void displayChannelList(); + void mute(bool value); }; diff --git a/plugin.cpp b/plugin.cpp index 9abc7ad8ee5c6788e797935346e8dc2f762be9be..96a8026570aa6e9d4d72d3acccd6a66c234b678c 100644 --- a/plugin.cpp +++ b/plugin.cpp @@ -131,6 +131,16 @@ OverlayController* getController(uint64 serverConnectionHandlerID = 0) return tmp.value(); } +void setActiveServer(uint64 serverConnectionHanderlID) +{ + // mute all server + for (auto& it : g_serverList) + it->mute(true); + + // unmute the current server + getController(serverConnectionHanderlID)->mute(false); +} + /* Helper function to create a hotkey */ static struct PluginHotkey* createHotkey(const char* keyword, const char* description) { struct PluginHotkey* hotkey = (struct PluginHotkey*)malloc(sizeof(struct PluginHotkey)); @@ -173,7 +183,7 @@ const char* ts3plugin_name() { /* Plugin version */ const char* ts3plugin_version() { - return "0.2"; + return "1.0"; } /* Plugin API version. Must be the same as the clients API major version, else the plugin fails to load. */ @@ -359,6 +369,7 @@ void ts3plugin_onConnectStatusChangeEvent(uint64 serverConnectionHandlerID, int else if (newStatus == STATUS_CONNECTION_ESTABLISHED) { getController(serverConnectionHandlerID)->updateChannelList(); + getController(serverConnectionHandlerID)->updateClientList(); getController(serverConnectionHandlerID)->displayChannelList(); } } @@ -368,14 +379,17 @@ void ts3plugin_onNewChannelEvent(uint64 serverConnectionHandlerID, uint64 channe void ts3plugin_onNewChannelCreatedEvent(uint64 serverConnectionHandlerID, uint64 channelID, uint64 channelParentID, anyID invokerID, const char* invokerName, const char* invokerUniqueIdentifier) { getController(serverConnectionHandlerID)->updateChannelList(); + getController(serverConnectionHandlerID)->updateClientList(); } void ts3plugin_onDelChannelEvent(uint64 serverConnectionHandlerID, uint64 channelID, anyID invokerID, const char* invokerName, const char* invokerUniqueIdentifier) { getController(serverConnectionHandlerID)->updateChannelList(); + getController(serverConnectionHandlerID)->updateClientList(); } void ts3plugin_onChannelMoveEvent(uint64 serverConnectionHandlerID, uint64 channelID, uint64 newChannelParentID, anyID invokerID, const char* invokerName, const char* invokerUniqueIdentifier) { getController(serverConnectionHandlerID)->updateChannelList(); + getController(serverConnectionHandlerID)->updateClientList(); } void ts3plugin_onUpdateChannelEvent(uint64 serverConnectionHandlerID, uint64 channelID) { @@ -383,6 +397,7 @@ void ts3plugin_onUpdateChannelEvent(uint64 serverConnectionHandlerID, uint64 cha void ts3plugin_onUpdateChannelEditedEvent(uint64 serverConnectionHandlerID, uint64 channelID, anyID invokerID, const char* invokerName, const char* invokerUniqueIdentifier) { getController(serverConnectionHandlerID)->updateChannelList(); + getController(serverConnectionHandlerID)->updateClientList(); } void ts3plugin_onUpdateClientEvent(uint64 serverConnectionHandlerID, anyID clientID, anyID invokerID, const char* invokerName, const char* invokerUniqueIdentifier) { @@ -605,6 +620,16 @@ int ts3plugin_onClientPokeEvent(uint64 serverConnectionHandlerID, anyID fromClie } void ts3plugin_onClientSelfVariableUpdateEvent(uint64 serverConnectionHandlerID, int flag, const char* oldValue, const char* newValue) { + + if (flag == CLIENT_INPUT_HARDWARE) + { + // from mute to speak + if (atoi(oldValue) == 0 && atoi(newValue) == 1) + setActiveServer(serverConnectionHandlerID); + // this should not happen + else + getController(serverConnectionHandlerID)->debugPrint("This should not happen"); + } } void ts3plugin_onFileListEvent(uint64 serverConnectionHandlerID, uint64 channelID, const char* path, const char* name, uint64 size, uint64 datetime, int type, uint64 incompletesize, const char* returnCode) {