mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-11 04:23:29 -08:00
Replace the macOS pull-down with a sibling settings button
QMacStyle has no split-button rendering: a menu-bearing QToolButton is drawn as a second square bezel. Keep the primary Host game button as the one-click quick host on every platform, and show a plain Game settings button as the secondary action on macOS instead; other styles keep the split arrow. Rename the secondary action from "Review settings first..." to "Game settings..." so the label says what it opens, and update the shortcuts page label to match.
This commit is contained in:
parent
b089a51be4
commit
e506fb4ad4
3 changed files with 64 additions and 52 deletions
|
|
@ -316,7 +316,7 @@ private:
|
||||||
{"GameSelector/aQuickHostGame", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Host Game"),
|
{"GameSelector/aQuickHostGame", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Host Game"),
|
||||||
parseSequenceString("Ctrl+N"),
|
parseSequenceString("Ctrl+N"),
|
||||||
ShortcutGroup::Game_Lobby)},
|
ShortcutGroup::Game_Lobby)},
|
||||||
{"GameSelector/aReviewGame", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Review Game Settings"),
|
{"GameSelector/aReviewGame", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Game Settings"),
|
||||||
parseSequenceString("Ctrl+Shift+N"),
|
parseSequenceString("Ctrl+Shift+N"),
|
||||||
ShortcutGroup::Game_Lobby)},
|
ShortcutGroup::Game_Lobby)},
|
||||||
{"Player/aCCMagenta", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter (F)"),
|
{"Player/aCCMagenta", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter (F)"),
|
||||||
|
|
|
||||||
|
|
@ -184,20 +184,22 @@ GameSelector::GameSelector(AbstractClient *_client,
|
||||||
|
|
||||||
// A plain QPushButton, so the quick host sits in the same control family as the
|
// A plain QPushButton, so the quick host sits in the same control family as the
|
||||||
// join buttons. A QPushButton does not take its text, tooltip or enabled state from
|
// join buttons. A QPushButton does not take its text, tooltip or enabled state from
|
||||||
// an action, so those are mirrored by hand below and in setHostCommandPending().
|
// an action, so those are mirrored by hand below and in updateHostControlsEnabled().
|
||||||
hostGameButton = new QPushButton(this);
|
hostGameButton = new QPushButton(this);
|
||||||
hostGameButton->setObjectName("hostGameButton");
|
hostGameButton->setObjectName("hostGameButton");
|
||||||
|
connect(hostGameButton, &QPushButton::clicked, hostGameAction, &QAction::trigger);
|
||||||
|
|
||||||
hostGameMenu = new QMenu(this);
|
hostGameMenu = new QMenu(this);
|
||||||
hostGameMenu->setObjectName("hostGameMenu");
|
hostGameMenu->setObjectName("hostGameMenu");
|
||||||
hostGameMenu->addAction(hostGameAction);
|
hostGameMenu->addAction(hostGameAction);
|
||||||
reviewGameAction = hostGameMenu->addAction(QString());
|
gameSettingsAction = hostGameMenu->addAction(QString());
|
||||||
reviewGameAction->setObjectName("reviewGameAction");
|
gameSettingsAction->setObjectName("gameSettingsAction");
|
||||||
reviewGameAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
gameSettingsAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
||||||
connect(reviewGameAction, &QAction::triggered, this, &GameSelector::actCreate);
|
connect(gameSettingsAction, &QAction::triggered, this, &GameSelector::actCreate);
|
||||||
|
|
||||||
// The secondary control: a flat arrow next to the primary button. It is hidden when
|
// The secondary control: a flat arrow next to the primary button on styles that
|
||||||
// the active style draws a native pull-down instead (see applyHostGameStyle()).
|
// support a split control. The native macOS style does not, so there it is a plain
|
||||||
|
// sibling button instead (see applyHostGameStyle()).
|
||||||
hostGameMenuButton = new QToolButton(this);
|
hostGameMenuButton = new QToolButton(this);
|
||||||
hostGameMenuButton->setObjectName("hostGameMenuButton");
|
hostGameMenuButton->setObjectName("hostGameMenuButton");
|
||||||
hostGameMenuButton->setArrowType(Qt::DownArrow);
|
hostGameMenuButton->setArrowType(Qt::DownArrow);
|
||||||
|
|
@ -205,6 +207,10 @@ GameSelector::GameSelector(AbstractClient *_client,
|
||||||
hostGameMenuButton->setPopupMode(QToolButton::InstantPopup);
|
hostGameMenuButton->setPopupMode(QToolButton::InstantPopup);
|
||||||
hostGameMenuButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
hostGameMenuButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
||||||
|
|
||||||
|
hostGameSettingsButton = new QPushButton(this);
|
||||||
|
hostGameSettingsButton->setObjectName("hostGameSettingsButton");
|
||||||
|
connect(hostGameSettingsButton, &QPushButton::clicked, gameSettingsAction, &QAction::trigger);
|
||||||
|
|
||||||
hostGameButtonWidget = new QWidget(this);
|
hostGameButtonWidget = new QWidget(this);
|
||||||
auto *hostGameButtonLayout = new QHBoxLayout(hostGameButtonWidget);
|
auto *hostGameButtonLayout = new QHBoxLayout(hostGameButtonWidget);
|
||||||
hostGameButtonLayout->setContentsMargins(0, 0, 0, 0);
|
hostGameButtonLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
@ -216,13 +222,13 @@ GameSelector::GameSelector(AbstractClient *_client,
|
||||||
|
|
||||||
// The shortcuts belong to the whole room tab, not just the game list, so they also
|
// The shortcuts belong to the whole room tab, not just the game list, so they also
|
||||||
// fire while the chat or the user list has focus. A QToolButton menu is mouse-only,
|
// fire while the chat or the user list has focus. A QToolButton menu is mouse-only,
|
||||||
// so the review action needs its own shortcut for keyboard parity.
|
// so the settings action needs its own shortcut for keyboard parity.
|
||||||
if (auto *roomTab = qobject_cast<TabRoom *>(parentWidget())) {
|
if (auto *roomTab = qobject_cast<TabRoom *>(parentWidget())) {
|
||||||
roomTab->addAction(hostGameAction);
|
roomTab->addAction(hostGameAction);
|
||||||
roomTab->addAction(reviewGameAction);
|
roomTab->addAction(gameSettingsAction);
|
||||||
} else {
|
} else {
|
||||||
addAction(hostGameAction);
|
addAction(hostGameAction);
|
||||||
addAction(reviewGameAction);
|
addAction(gameSettingsAction);
|
||||||
}
|
}
|
||||||
refreshShortcuts();
|
refreshShortcuts();
|
||||||
}
|
}
|
||||||
|
|
@ -239,6 +245,7 @@ GameSelector::GameSelector(AbstractClient *_client,
|
||||||
buttonLayout->addStretch();
|
buttonLayout->addStretch();
|
||||||
if (room) {
|
if (room) {
|
||||||
buttonLayout->addWidget(hostGameButtonWidget);
|
buttonLayout->addWidget(hostGameButtonWidget);
|
||||||
|
buttonLayout->addWidget(hostGameSettingsButton);
|
||||||
}
|
}
|
||||||
buttonLayout->addWidget(joinButton);
|
buttonLayout->addWidget(joinButton);
|
||||||
if (tabSupervisor->getUserInfo()->user_level() & ServerInfo_User::IsJudge) {
|
if (tabSupervisor->getUserInfo()->user_level() & ServerInfo_User::IsJudge) {
|
||||||
|
|
@ -428,31 +435,25 @@ void GameSelector::clearHostError()
|
||||||
|
|
||||||
void GameSelector::applyHostGameStyle()
|
void GameSelector::applyHostGameStyle()
|
||||||
{
|
{
|
||||||
if (hostGameButton == nullptr || hostGameMenu == nullptr) {
|
if (hostGameButton == nullptr || hostGameMenu == nullptr || hostGameMenuButton == nullptr ||
|
||||||
|
hostGameSettingsButton == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The appearance settings can switch the application style while the room is open, so
|
// The primary button always quick-hosts. The native macOS style has no split-button
|
||||||
// the primary click is wired from scratch instead of once: disconnect first, otherwise
|
// rendering (a QToolButton menu becomes a second square bezel), so the secondary
|
||||||
// a second pass would quick-host twice.
|
// action is a plain sibling button there; every other style gets the split arrow.
|
||||||
disconnect(hostGameButton, &QPushButton::clicked, hostGameAction, &QAction::trigger);
|
|
||||||
|
|
||||||
if (usesMacStyle()) {
|
if (usesMacStyle()) {
|
||||||
// A native pull-down: one bezel with the menu indicator inside it. The separate
|
|
||||||
// arrow is hidden because QMacStyle would draw it as a second square bezel.
|
|
||||||
hostGameButton->setMenu(hostGameMenu);
|
|
||||||
hostGameMenuButton->setMenu(nullptr);
|
hostGameMenuButton->setMenu(nullptr);
|
||||||
hostGameMenuButton->setVisible(false);
|
hostGameMenuButton->setVisible(false);
|
||||||
|
hostGameSettingsButton->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
// The split button: the primary half quick-hosts, the flat arrow opens the menu.
|
|
||||||
hostGameButton->setMenu(nullptr);
|
|
||||||
connect(hostGameButton, &QPushButton::clicked, hostGameAction, &QAction::trigger);
|
|
||||||
hostGameMenuButton->setMenu(hostGameMenu);
|
hostGameMenuButton->setMenu(hostGameMenu);
|
||||||
hostGameMenuButton->setVisible(true);
|
hostGameMenuButton->setVisible(true);
|
||||||
|
hostGameSettingsButton->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The tooltip depends on the control type: on macOS a click opens the menu, elsewhere it
|
// The appearance settings can switch the style while the room is open.
|
||||||
// quick-hosts, and the appearance settings can switch between the two while the room is open.
|
|
||||||
updateHostGameToolTip();
|
updateHostGameToolTip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -484,8 +485,11 @@ void GameSelector::updateHostControlsEnabled()
|
||||||
if (hostGameMenuButton) {
|
if (hostGameMenuButton) {
|
||||||
hostGameMenuButton->setEnabled(hostControlsEnabled);
|
hostGameMenuButton->setEnabled(hostControlsEnabled);
|
||||||
}
|
}
|
||||||
if (reviewGameAction) {
|
if (hostGameSettingsButton) {
|
||||||
reviewGameAction->setEnabled(hostControlsEnabled);
|
hostGameSettingsButton->setEnabled(hostControlsEnabled);
|
||||||
|
}
|
||||||
|
if (gameSettingsAction) {
|
||||||
|
gameSettingsAction->setEnabled(hostControlsEnabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -744,8 +748,13 @@ void GameSelector::retranslateUi()
|
||||||
}
|
}
|
||||||
updateHostGameToolTip();
|
updateHostGameToolTip();
|
||||||
}
|
}
|
||||||
if (reviewGameAction) {
|
if (gameSettingsAction) {
|
||||||
reviewGameAction->setText(tr("Review settings first…"));
|
gameSettingsAction->setText(tr("Game settings…"));
|
||||||
|
if (hostGameSettingsButton) {
|
||||||
|
// A QPushButton does not draw text from an action; on macOS this button is the
|
||||||
|
// secondary action, so it carries the same label.
|
||||||
|
hostGameSettingsButton->setText(tr("Game settings…"));
|
||||||
|
}
|
||||||
if (hostGameMenuButton) {
|
if (hostGameMenuButton) {
|
||||||
// The split arrow has no text of its own; name it for the menu it opens.
|
// The split arrow has no text of its own; name it for the menu it opens.
|
||||||
hostGameMenuButton->setToolTip(tr("More host options"));
|
hostGameMenuButton->setToolTip(tr("More host options"));
|
||||||
|
|
@ -766,8 +775,8 @@ void GameSelector::refreshShortcuts()
|
||||||
hostGameAction->setShortcuts(SettingsCache::instance().shortcuts().getShortcut("GameSelector/aQuickHostGame"));
|
hostGameAction->setShortcuts(SettingsCache::instance().shortcuts().getShortcut("GameSelector/aQuickHostGame"));
|
||||||
updateHostGameToolTip();
|
updateHostGameToolTip();
|
||||||
}
|
}
|
||||||
if (reviewGameAction) {
|
if (gameSettingsAction) {
|
||||||
reviewGameAction->setShortcuts(SettingsCache::instance().shortcuts().getShortcut("GameSelector/aReviewGame"));
|
gameSettingsAction->setShortcuts(SettingsCache::instance().shortcuts().getShortcut("GameSelector/aReviewGame"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -783,9 +792,10 @@ void GameSelector::updateHostGameToolTip()
|
||||||
hostGameAction->setToolTip(quickHostTooltip);
|
hostGameAction->setToolTip(quickHostTooltip);
|
||||||
}
|
}
|
||||||
if (hostGameButton) {
|
if (hostGameButton) {
|
||||||
// Under the native macOS style the button is a pull-down, so a click opens the menu
|
hostGameButton->setToolTip(quickHostTooltip);
|
||||||
// instead of quick-hosting and the tooltip names the menu rather than the quick host.
|
}
|
||||||
hostGameButton->setToolTip(usesMacStyle() ? tr("Open the host menu") : quickHostTooltip);
|
if (hostGameSettingsButton) {
|
||||||
|
hostGameSettingsButton->setToolTip(tr("Open the game settings before hosting"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -162,19 +162,20 @@ private:
|
||||||
|
|
||||||
GameSelectorQuickFilterToolBar *quickFilterToolBar;
|
GameSelectorQuickFilterToolBar *quickFilterToolBar;
|
||||||
|
|
||||||
QPushButton *filterButton; /**< Button to open the filter dialog. */
|
QPushButton *filterButton; /**< Button to open the filter dialog. */
|
||||||
QPushButton *clearFilterButton; /**< Button to clear active filters. */
|
QPushButton *clearFilterButton; /**< Button to clear active filters. */
|
||||||
QPushButton *hostGameButton = nullptr; /**< Host button, in the same family as the join buttons. */
|
QPushButton *hostGameButton = nullptr; /**< Host button, in the same family as the join buttons. */
|
||||||
QToolButton *hostGameMenuButton = nullptr; /**< Split arrow that opens the host menu (non-macOS styles only). */
|
QPushButton *hostGameSettingsButton = nullptr; /**< Opens the host form; a sibling button on macOS. */
|
||||||
QWidget *hostGameButtonWidget = nullptr; /**< Container that keeps the split button and its arrow together. */
|
QToolButton *hostGameMenuButton = nullptr; /**< Split arrow that opens the host menu (non-macOS styles only). */
|
||||||
QMenu *hostGameMenu = nullptr; /**< Menu behind the arrow, or behind the pull-down button on macOS. */
|
QWidget *hostGameButtonWidget = nullptr; /**< Container that keeps the split button and its arrow together. */
|
||||||
QAction *hostGameAction = nullptr; /**< Quick-host action, carrying the keyboard shortcut. */
|
QMenu *hostGameMenu = nullptr; /**< Menu behind the split arrow (non-macOS styles only). */
|
||||||
QAction *reviewGameAction = nullptr; /**< Menu action that opens the full create dialog. */
|
QAction *hostGameAction = nullptr; /**< Quick-host action, carrying the keyboard shortcut. */
|
||||||
QLabel *hostErrorLabel; /**< Inline failure message for a quick-host request. */
|
QAction *gameSettingsAction = nullptr; /**< Opens the host form with the current settings. */
|
||||||
QPushButton *joinButton; /**< Button to join the selected game. */
|
QLabel *hostErrorLabel; /**< Inline failure message for a quick-host request. */
|
||||||
QPushButton *joinAsJudgeButton; /**< Button to join the selected game as a judge. */
|
QPushButton *joinButton; /**< Button to join the selected game. */
|
||||||
QPushButton *spectateButton; /**< Button to spectate the selected game. */
|
QPushButton *joinAsJudgeButton; /**< Button to join the selected game as a judge. */
|
||||||
QPushButton *joinAsJudgeSpectatorButton; /**< Button to join the selected game as a spectating judge. */
|
QPushButton *spectateButton; /**< Button to spectate the selected game. */
|
||||||
|
QPushButton *joinAsJudgeSpectatorButton; /**< Button to join the selected game as a spectating judge. */
|
||||||
|
|
||||||
const bool showFilters; /**< Determines whether filter buttons are displayed. */
|
const bool showFilters; /**< Determines whether filter buttons are displayed. */
|
||||||
GameTypeMap gameTypeMap; /**< Mapping of game types for the current room. */
|
GameTypeMap gameTypeMap; /**< Mapping of game types for the current room. */
|
||||||
|
|
@ -192,15 +193,16 @@ private:
|
||||||
/**
|
/**
|
||||||
* @brief Rebuilds the host control for the active style.
|
* @brief Rebuilds the host control for the active style.
|
||||||
*
|
*
|
||||||
* The native macOS style draws a single pull-down button; every other style gets the
|
* The primary button always quick-hosts. Every other style gets the split button,
|
||||||
* split button, whose primary half quick-hosts and whose arrow opens the menu.
|
* whose arrow opens the menu; the native macOS style has no split control, so it
|
||||||
|
* gets a plain sibling button for the secondary action instead.
|
||||||
*/
|
*/
|
||||||
void applyHostGameStyle();
|
void applyHostGameStyle();
|
||||||
/** @brief Enables or disables the quick-host and review controls while a command is in flight. */
|
/** @brief Marks a quick-host command as in flight or finished, then updates the host controls. */
|
||||||
void setHostCommandPending(bool pending);
|
void setHostCommandPending(bool pending);
|
||||||
/** @brief Applies the in-flight state of both host and join commands to the quick-host and review controls. */
|
/** @brief Applies the in-flight state of both host and join commands to the host controls. */
|
||||||
void updateHostControlsEnabled();
|
void updateHostControlsEnabled();
|
||||||
/** @brief Keeps the quick-host button tooltip in sync with the current shortcut. */
|
/** @brief Keeps the host control tooltips in sync with the current shortcut and style. */
|
||||||
void updateHostGameToolTip();
|
void updateHostGameToolTip();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue