From 0ea8375a2fa4937d13fcd44d4af4923d87d52f5a Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Sun, 17 Apr 2011 17:23:44 +0200 Subject: [PATCH] close buttons for tabs --- cockatrice/src/tab.h | 1 + cockatrice/src/tab_game.cpp | 10 +++- cockatrice/src/tab_game.h | 1 + cockatrice/src/tab_message.cpp | 5 ++ cockatrice/src/tab_message.h | 1 + cockatrice/src/tab_room.cpp | 5 ++ cockatrice/src/tab_room.h | 1 + cockatrice/src/tab_supervisor.cpp | 85 ++++++++++++++++++++++++++++--- cockatrice/src/tab_supervisor.h | 17 ++++++- 9 files changed, 116 insertions(+), 10 deletions(-) diff --git a/cockatrice/src/tab.h b/cockatrice/src/tab.h index ac83ec59..31fdcbab 100644 --- a/cockatrice/src/tab.h +++ b/cockatrice/src/tab.h @@ -23,6 +23,7 @@ public: void setContentsChanged(bool _contentsChanged) { contentsChanged = _contentsChanged; } virtual QString getTabText() const = 0; virtual void retranslateUi() = 0; + virtual void closeRequest() { } }; #endif diff --git a/cockatrice/src/tab_game.cpp b/cockatrice/src/tab_game.cpp index a90281ad..49f724db 100644 --- a/cockatrice/src/tab_game.cpp +++ b/cockatrice/src/tab_game.cpp @@ -310,6 +310,11 @@ void TabGame::retranslateUi() scene->retranslateUi(); } +void TabGame::closeRequest() +{ + actLeaveGame(); +} + void TabGame::actConcede() { if (QMessageBox::question(this, tr("Concede"), tr("Are you sure you want to concede this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) @@ -320,8 +325,9 @@ void TabGame::actConcede() void TabGame::actLeaveGame() { - if (QMessageBox::question(this, tr("Leave game"), tr("Are you sure you want to leave this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) - return; + if (!spectator) + if (QMessageBox::question(this, tr("Leave game"), tr("Are you sure you want to leave this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) + return; sendGameCommand(new Command_LeaveGame); deleteLater(); diff --git a/cockatrice/src/tab_game.h b/cockatrice/src/tab_game.h index 4bf30af7..5982b42b 100644 --- a/cockatrice/src/tab_game.h +++ b/cockatrice/src/tab_game.h @@ -161,6 +161,7 @@ public: TabGame(TabSupervisor *_tabSupervisor, QList &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming); ~TabGame(); void retranslateUi(); + void closeRequest(); const QMap &getPlayers() const { return players; } CardItem *getCard(int playerId, const QString &zoneName, int cardId) const; int getGameId() const { return gameId; } diff --git a/cockatrice/src/tab_message.cpp b/cockatrice/src/tab_message.cpp index 4581ad14..03fb401f 100644 --- a/cockatrice/src/tab_message.cpp +++ b/cockatrice/src/tab_message.cpp @@ -40,6 +40,11 @@ void TabMessage::retranslateUi() aLeave->setText(tr("&Leave")); } +void TabMessage::closeRequest() +{ + actLeave(); +} + void TabMessage::sendMessage() { if (sayEdit->text().isEmpty() || !userOnline) diff --git a/cockatrice/src/tab_message.h b/cockatrice/src/tab_message.h index 17856aa5..b8543704 100644 --- a/cockatrice/src/tab_message.h +++ b/cockatrice/src/tab_message.h @@ -30,6 +30,7 @@ public: TabMessage(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, const QString &_userName); ~TabMessage(); void retranslateUi(); + void closeRequest(); QString getUserName() const { return userName; } QString getTabText() const { return tr("Talking to %1").arg(userName); } diff --git a/cockatrice/src/tab_room.cpp b/cockatrice/src/tab_room.cpp index efdc0e8a..5c440941 100644 --- a/cockatrice/src/tab_room.cpp +++ b/cockatrice/src/tab_room.cpp @@ -193,6 +193,11 @@ void TabRoom::retranslateUi() aLeaveRoom->setText(tr("&Leave room")); } +void TabRoom::closeRequest() +{ + actLeaveRoom(); +} + QString TabRoom::sanitizeHtml(QString dirty) const { return dirty diff --git a/cockatrice/src/tab_room.h b/cockatrice/src/tab_room.h index 1b013306..9c19542f 100644 --- a/cockatrice/src/tab_room.h +++ b/cockatrice/src/tab_room.h @@ -84,6 +84,7 @@ public: TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, ServerInfo_Room *info); ~TabRoom(); void retranslateUi(); + void closeRequest(); void processRoomEvent(RoomEvent *event); int getRoomId() const { return roomId; } const QMap &getGameTypes() const { return gameTypes; } diff --git a/cockatrice/src/tab_supervisor.cpp b/cockatrice/src/tab_supervisor.cpp index 2d09bb12..be7751a0 100644 --- a/cockatrice/src/tab_supervisor.cpp +++ b/cockatrice/src/tab_supervisor.cpp @@ -11,8 +11,60 @@ #include "protocol_items.h" #include "pixmapgenerator.h" #include +#include -TabSupervisor:: TabSupervisor(QWidget *parent) +CloseButton::CloseButton(QWidget *parent) + : QAbstractButton(parent) +{ + setFocusPolicy(Qt::NoFocus); + setCursor(Qt::ArrowCursor); + resize(sizeHint()); +} + +QSize CloseButton::sizeHint() const +{ + ensurePolished(); + int width = style()->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, this); + int height = style()->pixelMetric(QStyle::PM_TabCloseIndicatorHeight, 0, this); + return QSize(width, height); +} + +void CloseButton::enterEvent(QEvent *event) +{ + update(); + QAbstractButton::enterEvent(event); +} + +void CloseButton::leaveEvent(QEvent *event) +{ + update(); + QAbstractButton::leaveEvent(event); +} + +void CloseButton::paintEvent(QPaintEvent * /*event*/) +{ + QPainter p(this); + QStyleOption opt; + opt.init(this); + opt.state |= QStyle::State_AutoRaise; + if (isEnabled() && underMouse() && !isChecked() && !isDown()) + opt.state |= QStyle::State_Raised; + if (isChecked()) + opt.state |= QStyle::State_On; + if (isDown()) + opt.state |= QStyle::State_Sunken; + + if (const QTabBar *tb = qobject_cast(parent())) { + int index = tb->currentIndex(); + QTabBar::ButtonPosition position = (QTabBar::ButtonPosition) style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, tb); + if (tb->tabButton(index, position) == this) + opt.state |= QStyle::State_Selected; + } + + style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &p, this); +} + +TabSupervisor::TabSupervisor(QWidget *parent) : QTabWidget(parent), client(0), tabServer(0), tabDeckStorage(0), tabAdmin(0) { tabChangedIcon = new QIcon(":/resources/icon_tab_changed.svg"); @@ -47,10 +99,10 @@ void TabSupervisor::retranslateUi() } } -void TabSupervisor::myAddTab(Tab *tab) +int TabSupervisor::myAddTab(Tab *tab) { connect(tab, SIGNAL(userEvent()), this, SLOT(tabUserEvent())); - addTab(tab, tab->getTabText()); + return addTab(tab, tab->getTabText()); } void TabSupervisor::start(AbstractClient *_client, ServerInfo_User *userInfo) @@ -152,12 +204,28 @@ void TabSupervisor::updatePingTime(int value, int max) setTabIcon(0, QIcon(PingPixmapGenerator::generatePixmap(15, value, max))); } +void TabSupervisor::closeButtonPressed() +{ + Tab *tab = static_cast(static_cast(sender())->property("tab").value()); + tab->closeRequest(); +} + +void TabSupervisor::addCloseButtonToTab(Tab *tab, int tabIndex) +{ + QTabBar::ButtonPosition closeSide = (QTabBar::ButtonPosition) tabBar()->style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, tabBar()); + CloseButton *closeButton = new CloseButton; + connect(closeButton, SIGNAL(clicked()), this, SLOT(closeButtonPressed())); + closeButton->setProperty("tab", qVariantFromValue((QObject *) tab)); + tabBar()->setTabButton(tabIndex, closeSide, closeButton); +} + void TabSupervisor::gameJoined(Event_GameJoined *event) { TabGame *tab = new TabGame(this, QList() << client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *))); connect(tab, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool))); - myAddTab(tab); + int tabIndex = myAddTab(tab); + addCloseButtonToTab(tab, tabIndex); gameTabs.insert(event->getGameId(), tab); setCurrentWidget(tab); } @@ -166,7 +234,8 @@ void TabSupervisor::localGameJoined(Event_GameJoined *event) { TabGame *tab = new TabGame(this, localClients, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *))); - myAddTab(tab); + int tabIndex = myAddTab(tab); + addCloseButtonToTab(tab, tabIndex); gameTabs.insert(event->getGameId(), tab); setCurrentWidget(tab); @@ -192,7 +261,8 @@ void TabSupervisor::addRoomTab(ServerInfo_Room *info, bool setCurrent) TabRoom *tab = new TabRoom(this, client, userName, info); connect(tab, SIGNAL(roomClosing(TabRoom *)), this, SLOT(roomLeft(TabRoom *))); connect(tab, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool))); - myAddTab(tab); + int tabIndex = myAddTab(tab); + addCloseButtonToTab(tab, tabIndex); roomTabs.insert(info->getRoomId(), tab); if (setCurrent) setCurrentWidget(tab); @@ -213,7 +283,8 @@ TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus TabMessage *tab = new TabMessage(this, client, userName, receiverName); connect(tab, SIGNAL(talkClosing(TabMessage *)), this, SLOT(talkLeft(TabMessage *))); - myAddTab(tab); + int tabIndex = myAddTab(tab); + addCloseButtonToTab(tab, tabIndex); messageTabs.insert(receiverName, tab); if (focus) setCurrentWidget(tab); diff --git a/cockatrice/src/tab_supervisor.h b/cockatrice/src/tab_supervisor.h index 087d9327..439ac1f8 100644 --- a/cockatrice/src/tab_supervisor.h +++ b/cockatrice/src/tab_supervisor.h @@ -3,6 +3,7 @@ #include #include +#include class QMenu; class AbstractClient; @@ -21,6 +22,18 @@ class Event_Message; class ServerInfo_Room; class ServerInfo_User; +class CloseButton : public QAbstractButton { + Q_OBJECT +public: + CloseButton(QWidget *parent = 0); + QSize sizeHint() const; + inline QSize minimumSizeHint() const { return sizeHint(); } +protected: + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void paintEvent(QPaintEvent *event); +}; + class TabSupervisor : public QTabWidget { Q_OBJECT private: @@ -36,7 +49,8 @@ private: QMap roomTabs; QMap gameTabs; QMap messageTabs; - void myAddTab(Tab *tab); + int myAddTab(Tab *tab); + void addCloseButtonToTab(Tab *tab, int tabIndex); public: TabSupervisor(QWidget *parent = 0); ~TabSupervisor(); @@ -52,6 +66,7 @@ signals: void setMenu(QMenu *menu); void localGameEnded(); private slots: + void closeButtonPressed(); void updateCurrent(int index); void updatePingTime(int value, int max); void gameJoined(Event_GameJoined *event);