mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 09:05:10 -07:00
Merge branch 'master' into tooomm-qt5
This commit is contained in:
commit
4fba3c31f2
275 changed files with 66660 additions and 44237 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -6,6 +6,7 @@ mysql.cnf
|
|||
.DS_Store
|
||||
.idea/
|
||||
*.aps
|
||||
*.cache
|
||||
cmake-build*
|
||||
preferences
|
||||
compile_commands.json
|
||||
|
|
|
|||
8
Doxyfile
8
Doxyfile
|
|
@ -349,7 +349,7 @@ OPTIMIZE_OUTPUT_SLICE = NO
|
|||
#
|
||||
# Note see also the list of default file extension mappings.
|
||||
|
||||
EXTENSION_MAPPING =
|
||||
EXTENSION_MAPPING = proto=C++
|
||||
|
||||
# If the MARKDOWN_SUPPORT tag is enabled then Doxygen pre-processes all comments
|
||||
# according to the Markdown format, which allows for more readable
|
||||
|
|
@ -1086,7 +1086,8 @@ FILE_PATTERNS = *.cc \
|
|||
*.h++ \
|
||||
*.markdown \
|
||||
*.md \
|
||||
*.dox
|
||||
*.dox \
|
||||
*.proto
|
||||
|
||||
# The RECURSIVE tag can be used to specify whether or not subdirectories should
|
||||
# be searched for input files as well.
|
||||
|
|
@ -1103,6 +1104,7 @@ RECURSIVE = YES
|
|||
|
||||
EXCLUDE = build/ \
|
||||
cmake/ \
|
||||
cmake-build-debug/ \
|
||||
doc/doxygen/theme/docs/ \
|
||||
doc/doxygen/theme/include/ \
|
||||
vcpkg/
|
||||
|
|
@ -1195,7 +1197,7 @@ INPUT_FILTER =
|
|||
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||
# properly processed by Doxygen.
|
||||
|
||||
FILTER_PATTERNS =
|
||||
FILTER_PATTERNS = "*.proto=python doc/doxygen/filters/proto2cpp.py"
|
||||
|
||||
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
|
||||
# INPUT_FILTER) will also be used to filter the input files that are used for
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ set(cockatrice_SOURCES
|
|||
src/game_graphics/player/menu/rfg_menu.cpp
|
||||
src/game_graphics/player/menu/say_menu.cpp
|
||||
src/game_graphics/player/menu/sideboard_menu.cpp
|
||||
src/game_graphics/player/menu/tally_menu.cpp
|
||||
src/game_graphics/player/menu/utility_menu.cpp
|
||||
src/game_graphics/tally/subtype_tally.cpp
|
||||
src/game_graphics/tally/tally.cpp
|
||||
|
|
@ -228,8 +229,9 @@ set(cockatrice_SOURCES
|
|||
src/interface/widgets/printing_selector/set_name_and_collectors_number_display_widget.cpp
|
||||
src/interface/widgets/quick_settings/settings_button_widget.cpp
|
||||
src/interface/widgets/quick_settings/settings_popup_widget.cpp
|
||||
src/interface/widgets/replay/replay_manager.cpp
|
||||
src/interface/widgets/replay/replay_quick_settings_widget.cpp
|
||||
src/interface/widgets/replay/replay_timeline_widget.cpp
|
||||
src/interface/widgets/replay/replay_widget.cpp
|
||||
src/interface/widgets/server/chat_view/chat_view.cpp
|
||||
src/interface/widgets/server/game_filter_configs.cpp
|
||||
src/interface/widgets/server/game_selector.cpp
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <QThread>
|
||||
#include <libcockatrice/network/client/remote/remote_client.h>
|
||||
#include <libcockatrice/protocol/pb/response.pb.h>
|
||||
#include <libcockatrice/settings/servers_settings.h>
|
||||
|
||||
ConnectionController::ConnectionController(QWidget *dialogParent, QObject *parent)
|
||||
: QObject(parent), dialogParent(dialogParent)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
#include <QtConcurrent>
|
||||
#include <libcockatrice/card/database/card_database.h>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/settings/paths_settings.h>
|
||||
#include <libcockatrice/settings/personal_settings.h>
|
||||
#include <version_string.h>
|
||||
|
||||
#define SPOILERS_STATUS_URL "https://raw.githubusercontent.com/Cockatrice/Magic-Spoiler/files/SpoilerSeasonEnabled"
|
||||
|
|
@ -21,7 +23,7 @@
|
|||
|
||||
SpoilerBackgroundUpdater::SpoilerBackgroundUpdater(QObject *apParent) : QObject(apParent), cardUpdateProcess(nullptr)
|
||||
{
|
||||
isSpoilerDownloadEnabled = SettingsCache::instance().getDownloadSpoilersStatus();
|
||||
isSpoilerDownloadEnabled = SettingsCache::instance().personal().getDownloadSpoilersStatus();
|
||||
if (isSpoilerDownloadEnabled) {
|
||||
// Start the process of checking if we're in spoiler season
|
||||
// File exists means we're in spoiler season
|
||||
|
|
@ -75,7 +77,7 @@ void SpoilerBackgroundUpdater::actDownloadFinishedSpoilersFile()
|
|||
|
||||
bool SpoilerBackgroundUpdater::deleteSpoilerFile()
|
||||
{
|
||||
QString fileName = SettingsCache::instance().getSpoilerCardDatabasePath();
|
||||
QString fileName = SettingsCache::instance().paths().getSpoilerCardDatabasePath();
|
||||
QFileInfo fi(fileName);
|
||||
QDir fileDir(fi.path());
|
||||
QFile file(fileName);
|
||||
|
|
@ -126,7 +128,7 @@ void SpoilerBackgroundUpdater::actCheckIfSpoilerSeasonEnabled()
|
|||
|
||||
bool SpoilerBackgroundUpdater::saveDownloadedFile(QByteArray data)
|
||||
{
|
||||
QString fileName = SettingsCache::instance().getSpoilerCardDatabasePath();
|
||||
QString fileName = SettingsCache::instance().paths().getSpoilerCardDatabasePath();
|
||||
QFileInfo fi(fileName);
|
||||
QDir fileDir(fi.path());
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -2,9 +2,11 @@
|
|||
|
||||
#include "settings/cache_settings.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QAudioOutput>
|
||||
#include <QDir>
|
||||
#include <QMediaPlayer>
|
||||
#include <libcockatrice/settings/sound_settings.h>
|
||||
|
||||
#define DEFAULT_THEME_NAME "Default"
|
||||
#define TEST_SOUND_FILENAME "player_join"
|
||||
|
|
@ -12,8 +14,10 @@
|
|||
SoundEngine::SoundEngine(QObject *parent) : QObject(parent), audioOutput(nullptr), player(nullptr)
|
||||
{
|
||||
ensureThemeDirectoryExists();
|
||||
connect(&SettingsCache::instance(), &SettingsCache::soundThemeChanged, this, &SoundEngine::themeChangedSlot);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::soundEnabledChanged, this, &SoundEngine::soundEnabledChanged);
|
||||
connect(&SettingsCache::instance().sound(), &SoundSettings::soundThemeChanged, this,
|
||||
&SoundEngine::themeChangedSlot);
|
||||
connect(&SettingsCache::instance().sound(), &SoundSettings::soundEnabledChanged, this,
|
||||
&SoundEngine::soundEnabledChanged);
|
||||
|
||||
soundEnabledChanged();
|
||||
themeChangedSlot();
|
||||
|
|
@ -33,7 +37,7 @@ SoundEngine::~SoundEngine()
|
|||
|
||||
void SoundEngine::soundEnabledChanged()
|
||||
{
|
||||
if (SettingsCache::instance().getSoundEnabled()) {
|
||||
if (SettingsCache::instance().sound().getSoundEnabled()) {
|
||||
qCInfo(SoundEngineLog) << "SoundEngine: enabling sound with" << audioData.size() << "sounds";
|
||||
if (!player) {
|
||||
player = new QMediaPlayer;
|
||||
|
|
@ -65,7 +69,7 @@ void SoundEngine::playSound(const QString &fileName)
|
|||
}
|
||||
|
||||
player->stop();
|
||||
int volumeSliderValue = SettingsCache::instance().getMasterVolume();
|
||||
int volumeSliderValue = SettingsCache::instance().sound().getMasterVolume();
|
||||
player->audioOutput()->setVolume(qreal(volumeSliderValue) / 100);
|
||||
player->setSource(QUrl::fromLocalFile(audioData[fileName]));
|
||||
player->play();
|
||||
|
|
@ -78,10 +82,10 @@ void SoundEngine::testSound()
|
|||
|
||||
void SoundEngine::ensureThemeDirectoryExists()
|
||||
{
|
||||
if (SettingsCache::instance().getSoundThemeName().isEmpty() ||
|
||||
!getAvailableThemes().contains(SettingsCache::instance().getSoundThemeName())) {
|
||||
if (SettingsCache::instance().sound().getSoundThemeName().isEmpty() ||
|
||||
!getAvailableThemes().contains(SettingsCache::instance().sound().getSoundThemeName())) {
|
||||
qCInfo(SoundEngineLog) << "Sounds theme name not set, setting default value";
|
||||
SettingsCache::instance().setSoundThemeName(DEFAULT_THEME_NAME);
|
||||
SettingsCache::instance().sound().setSoundThemeName(DEFAULT_THEME_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +126,7 @@ QStringMap &SoundEngine::getAvailableThemes()
|
|||
|
||||
void SoundEngine::themeChangedSlot()
|
||||
{
|
||||
QString themeName = SettingsCache::instance().getSoundThemeName();
|
||||
QString themeName = SettingsCache::instance().sound().getSoundThemeName();
|
||||
qCInfo(SoundEngineLog) << "Sound theme changed:" << themeName;
|
||||
|
||||
QDir dir = getAvailableThemes().value(themeName);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef SETTINGS_CARD_DATABASE_PATH_PROVIDER_H
|
||||
#define SETTINGS_CARD_DATABASE_PATH_PROVIDER_H
|
||||
|
||||
#include "../../client/settings/cache_settings.h"
|
||||
|
||||
#include <libcockatrice/interfaces/interface_card_database_path_provider.h>
|
||||
#include <libcockatrice/settings/paths_settings.h>
|
||||
|
||||
class SettingsCardDatabasePathProvider : public ICardDatabasePathProvider
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SettingsCardDatabasePathProvider(QObject *parent = nullptr) : ICardDatabasePathProvider(parent)
|
||||
{
|
||||
connect(&SettingsCache::instance().paths(), &PathsSettings::cardDatabasePathChanged, this,
|
||||
&ICardDatabasePathProvider::cardDatabasePathChanged);
|
||||
}
|
||||
|
||||
[[nodiscard]] QString getCardDatabasePath() const override
|
||||
{
|
||||
return SettingsCache::instance().paths().getCardDatabasePath();
|
||||
}
|
||||
|
||||
[[nodiscard]] QString getCustomCardDatabasePath() const override
|
||||
{
|
||||
return SettingsCache::instance().paths().getCustomCardDatabasePath();
|
||||
}
|
||||
|
||||
[[nodiscard]] QString getTokenDatabasePath() const override
|
||||
{
|
||||
return SettingsCache::instance().paths().getTokenDatabasePath();
|
||||
}
|
||||
|
||||
[[nodiscard]] virtual QString getSpoilerCardDatabasePath() const override
|
||||
{
|
||||
return SettingsCache::instance().paths().getSpoilerCardDatabasePath();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SETTINGS_CARD_DATABASE_PATH_PROVIDER_H
|
||||
|
|
@ -3,6 +3,8 @@
|
|||
#include "../../client/settings/cache_settings.h"
|
||||
|
||||
#include <libcockatrice/interfaces/interface_card_preference_provider.h>
|
||||
#include <libcockatrice/settings/card_override_settings.h>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
|
||||
class SettingsCardPreferenceProvider : public ICardPreferenceProvider
|
||||
{
|
||||
|
|
@ -14,7 +16,7 @@ public:
|
|||
|
||||
[[nodiscard]] bool getIncludeRebalancedCards() const override
|
||||
{
|
||||
return SettingsCache::instance().getIncludeRebalancedCards();
|
||||
return SettingsCache::instance().cardsDisplay().getIncludeRebalancedCards();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,16 @@
|
|||
/**
|
||||
* @file game_event_handler.h
|
||||
* @ingroup GameLogic
|
||||
* @brief Game-level command sender and event dispatcher.
|
||||
*
|
||||
* GameEventHandler sends commands initiated by the local client to the server
|
||||
* and processes incoming game-wide events. It bridges the networking layer
|
||||
* (protobuf events received via AbstractClient) with the game model and UI
|
||||
* (GameState, PlayerManager, logging, widgets).
|
||||
*
|
||||
* Player-scoped events are forwarded to PlayerEventHandler instances, while
|
||||
* spectator and global game events are handled directly here.
|
||||
*/
|
||||
//! \todo Document this file.
|
||||
|
||||
#ifndef COCKATRICE_GAME_EVENT_HANDLER_H
|
||||
#define COCKATRICE_GAME_EVENT_HANDLER_H
|
||||
|
|
@ -15,92 +23,310 @@
|
|||
#include <libcockatrice/protocol/pb/serverinfo_player.pb.h>
|
||||
|
||||
class AbstractClient;
|
||||
class Response;
|
||||
class AbstractGame;
|
||||
class CommandContainer;
|
||||
class GameCommand;
|
||||
class GameEventContainer;
|
||||
class GameEventContext;
|
||||
class GameCommand;
|
||||
class GameState;
|
||||
class MessageLogWidget;
|
||||
class CommandContainer;
|
||||
class Event_GameJoined;
|
||||
class PendingCommand;
|
||||
class PlayerLogic;
|
||||
class Response;
|
||||
|
||||
class Event_GameStateChanged;
|
||||
class Event_PlayerPropertiesChanged;
|
||||
class Event_Join;
|
||||
class Event_Leave;
|
||||
class Event_GameHostChanged;
|
||||
class Event_GameClosed;
|
||||
class Event_GameStart;
|
||||
class Event_SetActivePlayer;
|
||||
class Event_SetActivePhase;
|
||||
class Event_Ping;
|
||||
class Event_GameSay;
|
||||
class Event_Kicked;
|
||||
class Event_ReverseTurn;
|
||||
class AbstractGame;
|
||||
class PendingCommand;
|
||||
class PlayerLogic;
|
||||
class Event_Ping;
|
||||
|
||||
inline Q_LOGGING_CATEGORY(GameEventHandlerLog, "game_event_handler");
|
||||
|
||||
/**
|
||||
* @class GameEventHandler
|
||||
* @brief Central dispatcher for game-wide commands and events.
|
||||
*
|
||||
* This class owns no game state itself. Instead, it:
|
||||
* - Sends commands to the server on behalf of local players
|
||||
* - Receives and dispatches server-side game events
|
||||
* - Updates the game model indirectly via Player, GameState, and PlayerManager
|
||||
* - Emits high-level signals for UI updates and logging
|
||||
*/
|
||||
class GameEventHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
/** Pointer to the owning game instance. */
|
||||
AbstractGame *game;
|
||||
|
||||
public:
|
||||
/** @name Construction
|
||||
* Lifecycle and ownership.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Construct a GameEventHandler.
|
||||
*
|
||||
* The handler is owned by the AbstractGame instance and uses it to
|
||||
* access the game state, players, and network clients.
|
||||
*
|
||||
* @param _game Owning game instance (also used as QObject parent).
|
||||
*/
|
||||
explicit GameEventHandler(AbstractGame *_game);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Outgoing game commands
|
||||
* Commands initiated locally and sent to the server.
|
||||
*
|
||||
* These methods construct and send protobuf commands corresponding
|
||||
* to user actions in the UI.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Request advancing the game to the next turn. */
|
||||
void handleNextTurn();
|
||||
|
||||
/** @brief Request reversing the current turn order. */
|
||||
void handleReverseTurn();
|
||||
|
||||
/** @brief Concede the game for the currently active local player. */
|
||||
void handleActiveLocalPlayerConceded();
|
||||
|
||||
/** @brief Undo a previous concede for the active local player. */
|
||||
void handleActiveLocalPlayerUnconceded();
|
||||
|
||||
/**
|
||||
* @brief Set the active phase of the game.
|
||||
*
|
||||
* Typically triggered by the active player selecting a new phase.
|
||||
*
|
||||
* @param phase Phase identifier.
|
||||
*/
|
||||
void handleActivePhaseChanged(int phase);
|
||||
|
||||
/** @brief Leave the current game session. */
|
||||
void handleGameLeft();
|
||||
|
||||
/**
|
||||
* @brief Send a chat message to all players and spectators.
|
||||
*
|
||||
* @param chatMessage Message text.
|
||||
*/
|
||||
void handleChatMessageSent(const QString &chatMessage);
|
||||
|
||||
/**
|
||||
* @brief Delete an existing arrow.
|
||||
*
|
||||
* @param arrowId Unique identifier of the arrow to delete.
|
||||
*/
|
||||
void handleArrowDeletion(int creatorId, int arrowId);
|
||||
void handleArrowDeletionFinished(const Response &response, int creatorId, int arrowId);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Incoming event processing
|
||||
* Entry points for server-sent events.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Process a container of game events received from the server.
|
||||
*
|
||||
* This is the main dispatch function for incoming game events.
|
||||
* Events are routed to spectator handlers, game-level handlers,
|
||||
* or forwarded to PlayerEventHandler instances as appropriate.
|
||||
*
|
||||
* @param cont Game event container from the server.
|
||||
* @param client Client that received the container.
|
||||
* @param options Processing flags (e.g. silent, replay).
|
||||
*/
|
||||
void
|
||||
processGameEventContainer(const GameEventContainer &cont, AbstractClient *client, EventProcessingOptions options);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Command preparation helpers
|
||||
* Internal helpers for building command containers.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Wrap a single protobuf command in a PendingCommand.
|
||||
*
|
||||
* @param cmd Protobuf command message.
|
||||
* @return Newly allocated PendingCommand (caller takes ownership).
|
||||
*/
|
||||
PendingCommand *prepareGameCommand(const ::google::protobuf::Message &cmd);
|
||||
|
||||
/**
|
||||
* @brief Wrap multiple protobuf commands in a single PendingCommand.
|
||||
*
|
||||
* Ownership of the messages in cmdList is transferred to the handler.
|
||||
*
|
||||
* @param cmdList List of protobuf command messages.
|
||||
* @return Newly allocated PendingCommand.
|
||||
*/
|
||||
PendingCommand *prepareGameCommand(const QList<const ::google::protobuf::Message *> &cmdList);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Spectator event handlers
|
||||
* Events originating from spectators.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Handle a spectator chat message.
|
||||
*/
|
||||
void eventSpectatorSay(const Event_GameSay &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
/**
|
||||
* @brief Handle a spectator leaving the game.
|
||||
*/
|
||||
void eventSpectatorLeave(const Event_Leave &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Game state event handlers
|
||||
* Events that affect global game state.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Handle a full game state update from the server.
|
||||
*
|
||||
* Used during game startup, reconnection, and resynchronization.
|
||||
*/
|
||||
void eventGameStateChanged(const Event_GameStateChanged &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
/**
|
||||
* @brief Update card attachment relationships for all players.
|
||||
*
|
||||
* Called after a game state update to ensure attachments are resolved
|
||||
* consistently across all zones.
|
||||
*/
|
||||
void processCardAttachmentsForPlayers(const Event_GameStateChanged &event);
|
||||
|
||||
/** @brief Handle a change in game host. */
|
||||
void eventGameHostChanged(const Event_GameHostChanged &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
/** @brief Handle the game being closed by the server. */
|
||||
void eventGameClosed(const Event_GameClosed &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
/** @brief Handle a change of the active player. */
|
||||
void eventSetActivePlayer(const Event_SetActivePlayer &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
/** @brief Handle a change of the active phase. */
|
||||
void eventSetActivePhase(const Event_SetActivePhase &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
/** @brief Handle a turn reversal event. */
|
||||
void eventReverseTurn(const Event_ReverseTurn &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
/** @brief Handle ping / latency updates. */
|
||||
void eventPing(const Event_Ping &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Player lifecycle and property handlers
|
||||
* Events related to players joining, leaving, or changing state.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Handle updates to a player's properties.
|
||||
*
|
||||
* Includes readiness, concede state, deck selection, sideboard lock,
|
||||
* and connection state changes.
|
||||
*/
|
||||
void eventPlayerPropertiesChanged(const Event_PlayerPropertiesChanged &event,
|
||||
int eventPlayerId,
|
||||
const GameEventContext &context);
|
||||
|
||||
/** @brief Handle a player or spectator joining the game. */
|
||||
void eventJoin(const Event_Join &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
/** @brief Handle a player leaving the game. */
|
||||
void eventLeave(const Event_Leave &event, int eventPlayerId, const GameEventContext &context);
|
||||
QString getLeaveReason(Event_Leave::LeaveReason reason);
|
||||
|
||||
/** @brief Handle the local player being kicked from the game. */
|
||||
void eventKicked(const Event_Kicked &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventGameHostChanged(const Event_GameHostChanged &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventGameClosed(const Event_GameClosed &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
void eventSetActivePlayer(const Event_SetActivePlayer &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventSetActivePhase(const Event_SetActivePhase &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventPing(const Event_Ping &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventReverseTurn(const Event_ReverseTurn &event, int eventPlayerId, const GameEventContext & /*context*/);
|
||||
/**
|
||||
* @brief Convert a leave reason enum to a human-readable string.
|
||||
*/
|
||||
QString getLeaveReason(Event_Leave::LeaveReason reason);
|
||||
|
||||
void commandFinished(const Response &response);
|
||||
/** @} */
|
||||
|
||||
void
|
||||
processGameEventContainer(const GameEventContainer &cont, AbstractClient *client, EventProcessingOptions options);
|
||||
PendingCommand *prepareGameCommand(const ::google::protobuf::Message &cmd);
|
||||
PendingCommand *prepareGameCommand(const QList<const ::google::protobuf::Message *> &cmdList);
|
||||
public slots:
|
||||
/** @name Command dispatch slots
|
||||
* Low-level command transmission.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Send a prepared PendingCommand.
|
||||
*
|
||||
* @param pend Pending command to send.
|
||||
* @param playerId Player whose client should send the command.
|
||||
*/
|
||||
void sendGameCommand(PendingCommand *pend, int playerId = -1);
|
||||
|
||||
/**
|
||||
* @brief Send a single protobuf command.
|
||||
*
|
||||
* @param command Protobuf command message.
|
||||
* @param playerId Player whose client should send the command.
|
||||
*/
|
||||
void sendGameCommand(const ::google::protobuf::Message &command, int playerId = -1);
|
||||
|
||||
/**
|
||||
* @brief Called when a PendingCommand finishes execution.
|
||||
*
|
||||
* Used to detect server-side errors such as chat flood protection.
|
||||
*/
|
||||
void commandFinished(const Response &response);
|
||||
|
||||
/** @} */
|
||||
|
||||
signals:
|
||||
/** @name Core state signals
|
||||
* @{
|
||||
*/
|
||||
|
||||
void emitUserEvent();
|
||||
void containerProcessingStarted(GameEventContext context);
|
||||
void containerProcessingDone();
|
||||
void gameFlooded();
|
||||
void setContextJudgeName(QString judgeName);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Player and spectator signals
|
||||
* @{
|
||||
*/
|
||||
|
||||
void addPlayerToAutoCompleteList(QString playerName);
|
||||
void localPlayerDeckSelected(PlayerLogic *localPlayer, int playerId, ServerInfo_Player playerInfo);
|
||||
void remotePlayerDeckSelected(QString deckList, int playerId, QString playerName);
|
||||
void remotePlayersDecksSelected(QVector<QPair<int, QPair<QString, QString>>> opponentDecks);
|
||||
void localPlayerSideboardLocked(int playerId, bool sideboardLocked);
|
||||
void localPlayerReadyStateChanged(int playerId, bool ready);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Game flow signals
|
||||
* @{
|
||||
*/
|
||||
|
||||
void gameStopped();
|
||||
void gameClosed();
|
||||
void playerPropertiesChanged(const ServerInfo_PlayerProperties &prop, int playerId);
|
||||
|
|
@ -109,11 +335,15 @@ signals:
|
|||
void playerKicked();
|
||||
void spectatorJoined(const ServerInfo_PlayerProperties &spectatorInfo);
|
||||
void spectatorLeft(int leavingSpectatorId);
|
||||
void gameFlooded();
|
||||
void containerProcessingStarted(GameEventContext context);
|
||||
void setContextJudgeName(QString judgeName);
|
||||
void containerProcessingDone();
|
||||
void arrowDeleted(int creatorId, int arrowId);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Logging signals
|
||||
* Signals consumed by MessageLogWidget.
|
||||
* @{
|
||||
*/
|
||||
|
||||
void logSpectatorSay(ServerInfo_User userInfo, QString message);
|
||||
void logSpectatorLeave(QString name, QString reason);
|
||||
void logGameStart();
|
||||
|
|
@ -132,6 +362,8 @@ signals:
|
|||
void logActivePhaseChanged(int activePhase);
|
||||
void logConcede(int playerId);
|
||||
void logUnconcede(int playerId);
|
||||
|
||||
/** @} */
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_GAME_EVENT_HANDLER_H
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include <libcockatrice/protocol/pb/command_shuffle.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_undo_draw.pb.h>
|
||||
#include <libcockatrice/protocol/pb/context_move_card.pb.h>
|
||||
#include <libcockatrice/settings/card_override_settings.h>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
#include <libcockatrice/utility/clamped_arithmetic.h>
|
||||
#include <libcockatrice/utility/counter_limits.h>
|
||||
#include <libcockatrice/utility/expression.h>
|
||||
|
|
@ -67,7 +69,7 @@ void PlayerActions::playCard(CardItem *card, bool faceDown)
|
|||
const CardInfo &info = exactCard.getInfo();
|
||||
|
||||
int tableRow = info.getUiAttributes().tableRow;
|
||||
bool playToStack = SettingsCache::instance().getPlayToStack();
|
||||
bool playToStack = SettingsCache::instance().interface().getPlayToStack();
|
||||
QString currentZone = card->getZone()->getName();
|
||||
if (!faceDown && currentZone == ZoneNames::STACK && tableRow == 3) {
|
||||
cmd.set_target_zone(ZoneNames::GRAVE);
|
||||
|
|
@ -310,7 +312,7 @@ void PlayerActions::actDrawCard()
|
|||
|
||||
void PlayerActions::actRequestMulliganDialog()
|
||||
{
|
||||
int startSize = SettingsCache::instance().getStartingHandSize();
|
||||
int startSize = SettingsCache::instance().interface().getStartingHandSize();
|
||||
int handSize = player->getHandZone()->getCards().size();
|
||||
int deckSize = player->getDeckZone()->getCards().size() + handSize;
|
||||
|
||||
|
|
@ -326,7 +328,7 @@ void PlayerActions::actMulligan(int number)
|
|||
}
|
||||
|
||||
doMulligan(number);
|
||||
SettingsCache::instance().setStartingHandSize(number);
|
||||
SettingsCache::instance().interface().setStartingHandSize(number);
|
||||
}
|
||||
|
||||
void PlayerActions::actMulliganSameSize()
|
||||
|
|
@ -933,7 +935,7 @@ void PlayerActions::setLastTokenInfo(CardInfoPtr cardInfo)
|
|||
lastTokenInfo = {.name = cardInfo->getName(),
|
||||
.color = cardInfo->getColors().isEmpty() ? QString() : cardInfo->getColors().left(1).toLower(),
|
||||
.pt = cardInfo->getPowTough(),
|
||||
.annotation = SettingsCache::instance().getAnnotateTokens() ? cardInfo->getText() : "",
|
||||
.annotation = SettingsCache::instance().interface().getAnnotateTokens() ? cardInfo->getText() : "",
|
||||
.destroy = true,
|
||||
.providerId =
|
||||
SettingsCache::instance().cardOverrides().getCardPreferenceOverride(cardInfo->getName())};
|
||||
|
|
@ -1169,7 +1171,7 @@ void PlayerActions::createCard(const CardItem *sourceCard,
|
|||
}
|
||||
|
||||
cmd.set_pt(cardInfo->getPowTough().toStdString());
|
||||
if (SettingsCache::instance().getAnnotateTokens()) {
|
||||
if (SettingsCache::instance().interface().getAnnotateTokens()) {
|
||||
cmd.set_annotation(cardInfo->getText().toStdString());
|
||||
} else {
|
||||
cmd.set_annotation("");
|
||||
|
|
|
|||
|
|
@ -1,11 +1,24 @@
|
|||
/**
|
||||
* @file player_event_handler.h
|
||||
* @ingroup GameLogicPlayers
|
||||
* @brief Player-scoped game event handler.
|
||||
*
|
||||
* PlayerEventHandler applies game events that affect a single Player’s
|
||||
* board state, zones, cards, counters, arrows, and related UI/log output.
|
||||
*
|
||||
* It is invoked by GameEventHandler after basic routing and validation.
|
||||
* Each instance is bound 1:1 to a Player and must never mutate state
|
||||
* belonging to other players except where explicitly required by events
|
||||
* (e.g. moving cards between players, attaching cards, arrows).
|
||||
*
|
||||
* This class is intentionally stateful and tightly coupled to Player,
|
||||
* PlayerActions, and the board/zones implementation. It performs both
|
||||
* model mutation and UI-side bookkeeping (zone views, arrows, menus).
|
||||
*/
|
||||
//! \todo Document this file.
|
||||
|
||||
#ifndef COCKATRICE_PLAYER_EVENT_HANDLER_H
|
||||
#define COCKATRICE_PLAYER_EVENT_HANDLER_H
|
||||
|
||||
#include "event_processing_options.h"
|
||||
|
||||
#include <QObject>
|
||||
|
|
@ -16,6 +29,7 @@
|
|||
class CardItem;
|
||||
class CardZoneLogic;
|
||||
class PlayerLogic;
|
||||
|
||||
class Event_AttachCard;
|
||||
class Event_ChangeZoneProperties;
|
||||
class Event_CreateArrow;
|
||||
|
|
@ -37,11 +51,176 @@ class Event_SetCounter;
|
|||
class Event_Shuffle;
|
||||
class Event_GameLogNotice;
|
||||
|
||||
/**
|
||||
* @class PlayerEventHandler
|
||||
* @brief Applies player-specific game events and emits corresponding log signals.
|
||||
*
|
||||
* Design notes:
|
||||
* - All event handlers assume events are authoritative and already validated
|
||||
* by the server.
|
||||
* - Most handlers mutate both logical state (CardItem, CardZoneLogic, counters)
|
||||
* and visual/UI state (views, arrows, menus).
|
||||
* - Logging signals are emitted *after* or *during* state mutation, depending
|
||||
* on whether later mutations would invalidate log data.
|
||||
*/
|
||||
class PlayerEventHandler : public QObject
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a PlayerEventHandler bound to a Player.
|
||||
* @param player Owning player instance.
|
||||
*/
|
||||
explicit PlayerEventHandler(PlayerLogic *player);
|
||||
|
||||
/** @name Event dispatch
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Dispatch a generic GameEvent to the appropriate handler.
|
||||
*
|
||||
* This is the single entry point used by GameEventHandler. It extracts
|
||||
* the correct protobuf extension and forwards the event to a typed
|
||||
* handler method.
|
||||
*
|
||||
* @param type Game event type enum.
|
||||
* @param event Generic protobuf container.
|
||||
* @param context Additional context (undo, judge, etc.).
|
||||
* @param options Processing options (UI suppression, reveal behavior).
|
||||
*/
|
||||
void processGameEvent(GameEvent::GameEventType type,
|
||||
const GameEvent &event,
|
||||
const GameEventContext &context,
|
||||
EventProcessingOptions options);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Chat and randomization events
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// Handle in-game chat messages from this player.
|
||||
void eventGameSay(const Event_GameSay &event);
|
||||
|
||||
/// Handle zone shuffle events (typically libraries).
|
||||
void eventShuffle(const Event_Shuffle &event);
|
||||
|
||||
/// Handle die roll events.
|
||||
void eventRollDie(const Event_RollDie &event);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Arrow and targeting events
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// Create a visual arrow between cards or players.
|
||||
void eventCreateArrow(const Event_CreateArrow &event);
|
||||
|
||||
/// Delete an existing arrow.
|
||||
void eventDeleteArrow(const Event_DeleteArrow &event);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Token and card creation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// Create a token card in a target zone.
|
||||
void eventCreateToken(const Event_CreateToken &event);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Card attribute and counter updates
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set a card attribute (tapped, PT, annotation, etc.).
|
||||
*
|
||||
* May apply to a single card or all cards in a zone if no card ID
|
||||
* is provided by the event.
|
||||
*/
|
||||
void
|
||||
eventSetCardAttr(const Event_SetCardAttr &event, const GameEventContext &context, EventProcessingOptions options);
|
||||
|
||||
/// Update a counter attached to a card.
|
||||
void eventSetCardCounter(const Event_SetCardCounter &event);
|
||||
|
||||
/// Create a player-level counter.
|
||||
void eventCreateCounter(const Event_CreateCounter &event);
|
||||
|
||||
/// Set a player-level counter value.
|
||||
void eventSetCounter(const Event_SetCounter &event);
|
||||
|
||||
/// Delete a player-level counter.
|
||||
void eventDelCounter(const Event_DelCounter &event);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Zone-level operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// Log a zone dump (e.g. reveal graveyard/library contents).
|
||||
void eventDumpZone(const Event_DumpZone &event);
|
||||
|
||||
/**
|
||||
* @brief Move a card between zones and/or players.
|
||||
*
|
||||
* This is one of the most complex handlers:
|
||||
* - Removes the card from the start zone
|
||||
* - Updates card identity and ownership if needed
|
||||
* - Handles attachments and arrows
|
||||
* - Emits appropriate move or undo-draw logs
|
||||
* - Inserts the card into the target zone
|
||||
*/
|
||||
void eventMoveCard(const Event_MoveCard &event, const GameEventContext &context);
|
||||
|
||||
/// Flip a card face up or face down.
|
||||
void eventFlipCard(const Event_FlipCard &event);
|
||||
|
||||
/// Destroy a card and clean up attachments.
|
||||
void eventDestroyCard(const Event_DestroyCard &event);
|
||||
|
||||
/// Attach or detach a card to/from another card.
|
||||
void eventAttachCard(const Event_AttachCard &event);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Draw and reveal operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// Draw one or more cards from the deck.
|
||||
void eventDrawCards(const Event_DrawCards &event);
|
||||
|
||||
/**
|
||||
* @brief Reveal cards from a zone.
|
||||
*
|
||||
* Handles peeking, in-place top-card reveals, full reveal windows,
|
||||
* and write-access granting.
|
||||
*/
|
||||
void eventRevealCards(const Event_RevealCards &event, EventProcessingOptions options);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Zone configuration
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// Update zone visibility and reveal behavior.
|
||||
void eventChangeZoneProperties(const Event_ChangeZoneProperties &event);
|
||||
|
||||
/** @} */
|
||||
|
||||
void eventGameLogNotice(const Event_GameLogNotice &event);
|
||||
signals:
|
||||
/** @name Logging signals
|
||||
* @{
|
||||
*/
|
||||
void logSay(PlayerLogic *player, QString message);
|
||||
void logShuffle(PlayerLogic *player, CardZoneLogic *zone, int start, int end);
|
||||
void logRollDie(PlayerLogic *player, int sides, const QList<uint> &rolls);
|
||||
|
|
@ -82,40 +261,13 @@ signals:
|
|||
bool isLentToAnotherPlayer = false);
|
||||
void logAlwaysRevealTopCard(PlayerLogic *player, CardZoneLogic *zone, bool reveal);
|
||||
void logAlwaysLookAtTopCard(PlayerLogic *player, CardZoneLogic *zone, bool reveal);
|
||||
/** @} */
|
||||
|
||||
void cardZoneChanged(CardItem *card, bool sameZone);
|
||||
void requestCardMenuUpdate(const CardItem *card);
|
||||
|
||||
public:
|
||||
PlayerEventHandler(PlayerLogic *player);
|
||||
|
||||
void processGameEvent(GameEvent::GameEventType type,
|
||||
const GameEvent &event,
|
||||
const GameEventContext &context,
|
||||
EventProcessingOptions options);
|
||||
|
||||
void eventGameSay(const Event_GameSay &event);
|
||||
void eventShuffle(const Event_Shuffle &event);
|
||||
void eventRollDie(const Event_RollDie &event);
|
||||
void eventCreateArrow(const Event_CreateArrow &event);
|
||||
void eventDeleteArrow(const Event_DeleteArrow &event);
|
||||
void eventCreateToken(const Event_CreateToken &event);
|
||||
void
|
||||
eventSetCardAttr(const Event_SetCardAttr &event, const GameEventContext &context, EventProcessingOptions options);
|
||||
void eventSetCardCounter(const Event_SetCardCounter &event);
|
||||
void eventCreateCounter(const Event_CreateCounter &event);
|
||||
void eventSetCounter(const Event_SetCounter &event);
|
||||
void eventDelCounter(const Event_DelCounter &event);
|
||||
void eventDumpZone(const Event_DumpZone &event);
|
||||
void eventMoveCard(const Event_MoveCard &event, const GameEventContext &context);
|
||||
void eventFlipCard(const Event_FlipCard &event);
|
||||
void eventDestroyCard(const Event_DestroyCard &event);
|
||||
void eventAttachCard(const Event_AttachCard &event);
|
||||
void eventDrawCards(const Event_DrawCards &event);
|
||||
void eventRevealCards(const Event_RevealCards &event, EventProcessingOptions options);
|
||||
void eventChangeZoneProperties(const Event_ChangeZoneProperties &event);
|
||||
void eventGameLogNotice(const Event_GameLogNotice &event);
|
||||
|
||||
private:
|
||||
/** Owning player instance. */
|
||||
PlayerLogic *player;
|
||||
|
||||
void setCardAttrHelper(const GameEventContext &context,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "../../client/settings/cache_settings.h"
|
||||
#include "../../game_graphics/board/card_item.h"
|
||||
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
/**
|
||||
* @param _player the player that the cards are revealed to.
|
||||
* @param _origZone the zone the cards were revealed from.
|
||||
|
|
@ -57,7 +58,7 @@ bool ZoneViewZoneLogic::prepareAddCard(int x)
|
|||
|
||||
// autoclose check is done both here and in removeCard
|
||||
|
||||
if (cards.isEmpty() && !doInsert && SettingsCache::instance().getCloseEmptyCardView()) {
|
||||
if (cards.isEmpty() && !doInsert && SettingsCache::instance().interface().getCloseEmptyCardView()) {
|
||||
emit closeView();
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +145,7 @@ void ZoneViewZoneLogic::removeCard(int position, bool toNewZone)
|
|||
// card gets dragged within the view.
|
||||
// Another autoclose check is done in prepareAddCard so that the view autocloses if the last card was moved to an
|
||||
// unrevealed portion of the same zone.
|
||||
if (cards.isEmpty() && SettingsCache::instance().getCloseEmptyCardView() && toNewZone) {
|
||||
if (cards.isEmpty() && SettingsCache::instance().interface().getCloseEmptyCardView() && toNewZone) {
|
||||
emit closeView();
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <QDebug>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
|
||||
const QColor GHOST_MASK = QColor(255, 255, 255, 50);
|
||||
|
||||
|
|
@ -34,12 +35,13 @@ AbstractCardDragItem::AbstractCardDragItem(AbstractCardItem *_item,
|
|||
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::roundCardCornersChanged, this, [this](bool _roundCardCorners) {
|
||||
Q_UNUSED(_roundCardCorners);
|
||||
connect(&SettingsCache::instance().cardsDisplay(), &CardsDisplaySettings::roundCardCornersChanged, this,
|
||||
[this](bool _roundCardCorners) {
|
||||
Q_UNUSED(_roundCardCorners);
|
||||
|
||||
prepareGeometryChange();
|
||||
update();
|
||||
});
|
||||
prepareGeometryChange();
|
||||
update();
|
||||
});
|
||||
|
||||
connect(item, &QObject::destroyed, this, &AbstractCardDragItem::deleteLater);
|
||||
}
|
||||
|
|
@ -47,7 +49,8 @@ AbstractCardDragItem::AbstractCardDragItem(AbstractCardItem *_item,
|
|||
QPainterPath AbstractCardDragItem::shape() const
|
||||
{
|
||||
QPainterPath shape;
|
||||
qreal cardCornerRadius = SettingsCache::instance().getRoundCardCorners() ? 0.05 * CardDimensions::WIDTH_F : 0.0;
|
||||
qreal cardCornerRadius =
|
||||
SettingsCache::instance().cardsDisplay().getRoundCardCorners() ? 0.05 * CardDimensions::WIDTH_F : 0.0;
|
||||
shape.addRoundedRect(boundingRect(), cardCornerRadius, cardCornerRadius);
|
||||
return shape;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
#include <algorithm>
|
||||
#include <libcockatrice/card/database/card_database.h>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
#include <libcockatrice/settings/debug_settings.h>
|
||||
#include <libcockatrice/settings/personal_settings.h>
|
||||
|
||||
AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, const CardRef &cardRef, PlayerLogic *_owner, int _id)
|
||||
: ArrowTarget(_owner, parent), id(_id), cardRef(cardRef), tapped(false), facedown(false), tapAngle(0),
|
||||
|
|
@ -21,15 +24,17 @@ AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, const CardRef &cardRef
|
|||
setFlag(ItemIsSelectable);
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::displayCardNamesChanged, this, [this] { update(); });
|
||||
connect(&SettingsCache::instance().cardsDisplay(), &CardsDisplaySettings::displayCardNamesChanged, this,
|
||||
[this] { update(); });
|
||||
refreshCardInfo();
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::roundCardCornersChanged, this, [this](bool _roundCardCorners) {
|
||||
Q_UNUSED(_roundCardCorners);
|
||||
connect(&SettingsCache::instance().cardsDisplay(), &CardsDisplaySettings::roundCardCornersChanged, this,
|
||||
[this](bool _roundCardCorners) {
|
||||
Q_UNUSED(_roundCardCorners);
|
||||
|
||||
prepareGeometryChange();
|
||||
update();
|
||||
});
|
||||
prepareGeometryChange();
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
AbstractCardItem::~AbstractCardItem()
|
||||
|
|
@ -45,7 +50,8 @@ QRectF AbstractCardItem::boundingRect() const
|
|||
QPainterPath AbstractCardItem::shape() const
|
||||
{
|
||||
QPainterPath shape;
|
||||
qreal cardCornerRadius = SettingsCache::instance().getRoundCardCorners() ? 0.05 * CardDimensions::WIDTH_F : 0.0;
|
||||
qreal cardCornerRadius =
|
||||
SettingsCache::instance().cardsDisplay().getRoundCardCorners() ? 0.05 * CardDimensions::WIDTH_F : 0.0;
|
||||
shape.addRoundedRect(boundingRect(), cardCornerRadius, cardCornerRadius);
|
||||
return shape;
|
||||
}
|
||||
|
|
@ -101,7 +107,7 @@ QSizeF AbstractCardItem::getTranslatedSize(QPainter *painter) const
|
|||
|
||||
void AbstractCardItem::transformPainter(QPainter *painter, const QSizeF &translatedSize, int angle)
|
||||
{
|
||||
const int MAX_FONT_SIZE = SettingsCache::instance().getMaxFontSize();
|
||||
const int MAX_FONT_SIZE = SettingsCache::instance().personal().getMaxFontSize();
|
||||
const int fontSize = std::max(9, MAX_FONT_SIZE);
|
||||
|
||||
QRectF totalBoundingRect = painter->combinedTransform().mapRect(boundingRect());
|
||||
|
|
@ -151,7 +157,7 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS
|
|||
painter->drawPath(shape());
|
||||
}
|
||||
|
||||
if (translatedPixmap.isNull() || SettingsCache::instance().getDisplayCardNames() || facedown) {
|
||||
if (translatedPixmap.isNull() || SettingsCache::instance().cardsDisplay().getDisplayCardNames() || facedown) {
|
||||
painter->save();
|
||||
transformPainter(painter, translatedSize, angle);
|
||||
painter->setPen(Qt::white);
|
||||
|
|
@ -234,7 +240,7 @@ void AbstractCardItem::setHovered(bool _hovered)
|
|||
|
||||
isHovered = _hovered;
|
||||
setZValue(_hovered ? ZValues::HOVERED_CARD : realZValue);
|
||||
setScale(_hovered && SettingsCache::instance().getScaleCards() ? 1.1 : 1);
|
||||
setScale(_hovered && SettingsCache::instance().cardsDisplay().getScaleCards() ? 1.1 : 1);
|
||||
setTransformOriginPoint(_hovered ? CardDimensions::WIDTH_HALF_F : 0, _hovered ? CardDimensions::HEIGHT_HALF_F : 0);
|
||||
update();
|
||||
}
|
||||
|
|
@ -287,7 +293,7 @@ void AbstractCardItem::setTapped(bool _tapped, bool canAnimate)
|
|||
}
|
||||
|
||||
tapped = _tapped;
|
||||
if (SettingsCache::instance().getTapAnimation() && canAnimate) {
|
||||
if (SettingsCache::instance().cardsDisplay().getTapAnimation() && canAnimate) {
|
||||
static_cast<GameScene *>(scene())->registerAnimationItem(this);
|
||||
} else {
|
||||
tapAngle = tapped ? 90 : 0;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "abstract_counter.h"
|
||||
|
||||
#include "../../client/settings/cache_settings.h"
|
||||
#include "../../client/settings/shortcuts_settings.h"
|
||||
#include "../../game/player/player_actions.h"
|
||||
#include "../../game/player/player_logic.h"
|
||||
#include "../../game_graphics/board/translate_counter_name.h"
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <libcockatrice/protocol/pb/command_attach_card.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_create_arrow.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_delete_arrow.pb.h>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
#include <libcockatrice/utility/color.h>
|
||||
#include <libcockatrice/utility/zone_names.h>
|
||||
|
||||
|
|
@ -261,7 +262,7 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||
if (startZone->getName() == ZoneNames::HAND) {
|
||||
startCard->playCard(false);
|
||||
CardInfoPtr ci = startCard->getCard().getCardPtr();
|
||||
bool playToStack = SettingsCache::instance().getPlayToStack();
|
||||
bool playToStack = SettingsCache::instance().interface().getPlayToStack();
|
||||
if (ci && ((!playToStack && ci->getUiAttributes().tableRow == 3) ||
|
||||
(playToStack && ci->getUiAttributes().tableRow != 0 &&
|
||||
startCard->getZone()->getName() != ZoneNames::STACK))) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "card_item.h"
|
||||
|
||||
#include "../../client/settings/cache_settings.h"
|
||||
#include "../../client/settings/card_counter_settings.h"
|
||||
#include "../../game/phase.h"
|
||||
#include "../../game/player/player_actions.h"
|
||||
#include "../../game/player/player_logic.h"
|
||||
|
|
@ -19,6 +20,7 @@
|
|||
#include <QPainter>
|
||||
#include <libcockatrice/card/card_info.h>
|
||||
#include <libcockatrice/protocol/pb/serverinfo_card.pb.h>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
|
||||
CardItem::CardItem(PlayerLogic *_owner,
|
||||
QGraphicsItem *parent,
|
||||
|
|
@ -279,7 +281,7 @@ void CardItem::drawArrow(const QColor &arrowColor)
|
|||
auto *game = owner->getGame();
|
||||
PlayerLogic *arrowOwner = game->getPlayerManager()->getActiveLocalPlayer(game->getGameState()->getActivePlayer());
|
||||
int phase = 0; // 0 means to not set the phase
|
||||
if (SettingsCache::instance().getDoNotDeleteArrowsInSubPhases()) {
|
||||
if (SettingsCache::instance().interface().getDoNotDeleteArrowsInSubPhases()) {
|
||||
int currentPhase = game->getGameState()->getCurrentPhase();
|
||||
phase = Phases::getLastSubphase(currentPhase) + 1;
|
||||
}
|
||||
|
|
@ -398,7 +400,7 @@ void CardItem::playCard(bool faceDown)
|
|||
if (tz) {
|
||||
emit tz->toggleTapped();
|
||||
} else {
|
||||
if (SettingsCache::instance().getClickPlaysAllSelected()) {
|
||||
if (SettingsCache::instance().interface().getClickPlaysAllSelected()) {
|
||||
if (faceDown) {
|
||||
emit playSelectedFaceDown(this);
|
||||
} else {
|
||||
|
|
@ -462,7 +464,7 @@ static bool isUnwritableRevealZone(CardZoneLogic *zone)
|
|||
void CardItem::handleClickedToPlay(bool shiftHeld)
|
||||
{
|
||||
if (isUnwritableRevealZone(state->getZone())) {
|
||||
if (SettingsCache::instance().getClickPlaysAllSelected()) {
|
||||
if (SettingsCache::instance().interface().getClickPlaysAllSelected()) {
|
||||
emit hideSelected(this);
|
||||
} else {
|
||||
state->getZone()->removeCard(this);
|
||||
|
|
@ -479,7 +481,7 @@ void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||
return;
|
||||
}
|
||||
if ((event->modifiers() != Qt::AltModifier) && (event->button() == Qt::LeftButton) &&
|
||||
(!SettingsCache::instance().getDoubleClickToPlay())) {
|
||||
(!SettingsCache::instance().interface().getDoubleClickToPlay())) {
|
||||
handleClickedToPlay(event->modifiers().testFlag(Qt::ShiftModifier));
|
||||
}
|
||||
if (owner != nullptr) {
|
||||
|
|
@ -491,7 +493,7 @@ void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||
void CardItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if ((event->modifiers() != Qt::AltModifier) && (event->buttons() == Qt::LeftButton) &&
|
||||
(SettingsCache::instance().getDoubleClickToPlay())) {
|
||||
(SettingsCache::instance().interface().getDoubleClickToPlay())) {
|
||||
handleClickedToPlay(event->modifiers().testFlag(Qt::ShiftModifier));
|
||||
}
|
||||
event->accept();
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <libcockatrice/card/card_info.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/deck_list/tree/deck_list_card_node.h>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
|
||||
DeckViewCardDragItem::DeckViewCardDragItem(DeckViewCard *_item,
|
||||
const QPointF &_hotSpot,
|
||||
|
|
@ -77,11 +78,12 @@ DeckViewCard::DeckViewCard(QGraphicsItem *parent, const CardRef &cardRef, const
|
|||
{
|
||||
setAcceptHoverEvents(true);
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::roundCardCornersChanged, this, [this](bool _roundCardCorners) {
|
||||
Q_UNUSED(_roundCardCorners);
|
||||
connect(&SettingsCache::instance().cardsDisplay(), &CardsDisplaySettings::roundCardCornersChanged, this,
|
||||
[this](bool _roundCardCorners) {
|
||||
Q_UNUSED(_roundCardCorners);
|
||||
|
||||
update();
|
||||
});
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
DeckViewCard::~DeckViewCard()
|
||||
|
|
@ -99,7 +101,8 @@ void DeckViewCard::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
|||
pen.setJoinStyle(Qt::MiterJoin);
|
||||
pen.setColor(originZone == DECK_ZONE_MAIN ? Qt::green : Qt::red);
|
||||
painter->setPen(pen);
|
||||
qreal cardRadius = SettingsCache::instance().getRoundCardCorners() ? 0.05 * (CardDimensions::WIDTH_F - 3) : 0.0;
|
||||
qreal cardRadius =
|
||||
SettingsCache::instance().cardsDisplay().getRoundCardCorners() ? 0.05 * (CardDimensions::WIDTH_F - 3) : 0.0;
|
||||
painter->drawRoundedRect(QRectF(1.5, 1.5, CardDimensions::WIDTH_F - 3, CardDimensions::HEIGHT_F - 3), cardRadius,
|
||||
cardRadius);
|
||||
painter->restore();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "deck_view_container.h"
|
||||
|
||||
#include "../../client/settings/cache_settings.h"
|
||||
#include "../../client/settings/shortcuts_settings.h"
|
||||
#include "../../interface/card_picture_loader/card_picture_loader.h"
|
||||
#include "../../interface/deck_loader/deck_loader.h"
|
||||
#include "../../interface/widgets/dialogs/dlg_load_deck.h"
|
||||
|
|
@ -19,6 +20,7 @@
|
|||
#include <libcockatrice/protocol/pb/command_set_sideboard_plan.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_deck_download.pb.h>
|
||||
#include <libcockatrice/protocol/pending_command.h>
|
||||
#include <libcockatrice/settings/visual_deck_storage_settings.h>
|
||||
#include <libcockatrice/utility/string_limits.h>
|
||||
|
||||
ToggleButton::ToggleButton(QWidget *parent) : QPushButton(parent), state(false)
|
||||
|
|
@ -95,8 +97,8 @@ DeckViewContainer::DeckViewContainer(int _playerId, TabGame *parent)
|
|||
&DeckViewContainer::refreshShortcuts);
|
||||
refreshShortcuts();
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::visualDeckStorageInGameChanged, this,
|
||||
&DeckViewContainer::setVisualDeckStorageExists);
|
||||
connect(&SettingsCache::instance().visualDeckStorage(), &VisualDeckStorageSettings::visualDeckStorageInGameChanged,
|
||||
this, &DeckViewContainer::setVisualDeckStorageExists);
|
||||
|
||||
switchToDeckSelectView();
|
||||
}
|
||||
|
|
@ -138,7 +140,7 @@ static void setVisibility(QPushButton *button, bool visible)
|
|||
|
||||
void DeckViewContainer::switchToDeckSelectView()
|
||||
{
|
||||
if (SettingsCache::instance().getVisualDeckStorageInGame()) {
|
||||
if (SettingsCache::instance().visualDeckStorage().getVisualDeckStorageInGame()) {
|
||||
deckView->setHidden(true);
|
||||
|
||||
tryCreateVisualDeckStorageWidget();
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@
|
|||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/models/database/card_database_model.h>
|
||||
#include <libcockatrice/models/database/token/token_display_model.h>
|
||||
#include <libcockatrice/settings/card_override_settings.h>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
#include <libcockatrice/settings/layouts_settings.h>
|
||||
#include <libcockatrice/utility/string_limits.h>
|
||||
|
||||
DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *parent)
|
||||
|
|
@ -186,7 +189,7 @@ void DlgCreateToken::tokenSelectionChanged(const QModelIndex ¤t, const QMo
|
|||
const QChar cardColor = cardInfo->getColorChar();
|
||||
colorEdit->setCurrentIndex(colorEdit->findData(cardColor, Qt::UserRole, Qt::MatchFixedString));
|
||||
ptEdit->setText(cardInfo->getPowTough());
|
||||
if (SettingsCache::instance().getAnnotateTokens()) {
|
||||
if (SettingsCache::instance().interface().getAnnotateTokens()) {
|
||||
annotationEdit->setText(cardInfo->getText());
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include <QGraphicsView>
|
||||
#include <QSet>
|
||||
#include <QtMath>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
#include <libcockatrice/utility/zone_names.h>
|
||||
#include <numeric>
|
||||
|
||||
|
|
@ -36,7 +37,7 @@ GameScene::GameScene(PhasesToolbar *_phasesToolbar, QObject *parent)
|
|||
{
|
||||
animationTimer = new QBasicTimer;
|
||||
addItem(phasesToolbar);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::minPlayersForMultiColumnLayoutChanged, this,
|
||||
connect(&SettingsCache::instance().interface(), &InterfaceSettings::minPlayersForMultiColumnLayoutChanged, this,
|
||||
&GameScene::rearrange);
|
||||
|
||||
rearrange();
|
||||
|
|
@ -46,6 +47,17 @@ GameScene::~GameScene()
|
|||
{
|
||||
delete animationTimer;
|
||||
|
||||
// Delete all ArrowItems before QGraphicsScene's base destructor runs.
|
||||
// QGraphicsScene::~QGraphicsScene() destroys items in arbitrary order.
|
||||
// If a PlayerTarget is destroyed before an ArrowItem pointing to it,
|
||||
// ArrowItem::onTargetDestroyed fires and emits on the partially-destroyed
|
||||
// GameScene, causing a segfault.
|
||||
for (auto *item : items()) {
|
||||
if (auto *arrow = qgraphicsitem_cast<ArrowItem *>(item)) {
|
||||
delete arrow;
|
||||
}
|
||||
}
|
||||
|
||||
// DO NOT call clearViews() here
|
||||
// clearViews calls close() on the zoneViews, which sends signals; sending signals in destructors leads to segfaults
|
||||
// deleteLater() deletes the zoneView without allowing it to send signals
|
||||
|
|
@ -324,7 +336,7 @@ QList<PlayerLogic *> GameScene::rotatePlayers(const QList<PlayerLogic *> &active
|
|||
|
||||
int GameScene::determineColumnCount(int playerCount)
|
||||
{
|
||||
return playerCount < SettingsCache::instance().getMinPlayersForMultiColumnLayout() ? 1 : 2;
|
||||
return playerCount < SettingsCache::instance().interface().getMinPlayersForMultiColumnLayout() ? 1 : 2;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -529,7 +541,9 @@ void GameScene::clearArrowsForPlayer(int playerId)
|
|||
void GameScene::clearArrowsForPlayerLocally(int playerId)
|
||||
{
|
||||
for (int arrowId : arrowRegistry.idsForPlayer(playerId)) {
|
||||
arrowRegistry.take(playerId, arrowId)->delArrow();
|
||||
if (auto *arrow = arrowRegistry.take(playerId, arrowId)) {
|
||||
arrow->delArrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "game_view.h"
|
||||
|
||||
#include "../client/settings/cache_settings.h"
|
||||
#include "../client/settings/shortcuts_settings.h"
|
||||
#include "game_scene.h"
|
||||
|
||||
#include <QAction>
|
||||
|
|
@ -9,6 +10,7 @@
|
|||
#include <QLayout>
|
||||
#include <QResizeEvent>
|
||||
#include <QRubberBand>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
#include <libcockatrice/utility/qt_utils.h>
|
||||
|
||||
// QRubberBand calls raise() in showEvent() and changeEvent() to stay on top of siblings.
|
||||
|
|
@ -45,9 +47,12 @@ GameView::GameView(GameScene *scene, QWidget *parent) : QGraphicsView(scene, par
|
|||
connect(scene, &GameScene::sigResizeRubberBand, this, &GameView::resizeRubberBand);
|
||||
connect(scene, &GameScene::sigStopRubberBand, this, &GameView::stopRubberBand);
|
||||
connect(scene, &QGraphicsScene::selectionChanged, this, [this]() { updateTotalSelectionCount(); });
|
||||
connect(&SettingsCache::instance().interface(), &InterfaceSettings::tallyTypeChanged, this,
|
||||
[this] { updateTotalSelectionCount(); });
|
||||
|
||||
setFocusDisabled(SettingsCache::instance().getKeepGameChatFocus());
|
||||
connect(&SettingsCache::instance(), &SettingsCache::keepGameChatFocusChanged, this, &GameView::setFocusDisabled);
|
||||
setFocusDisabled(SettingsCache::instance().interface().getKeepGameChatFocus());
|
||||
connect(&SettingsCache::instance().interface(), &InterfaceSettings::keepGameChatFocusChanged, this,
|
||||
&GameView::setFocusDisabled);
|
||||
|
||||
aCloseMostRecentZoneView = new QAction(this);
|
||||
|
||||
|
|
@ -125,7 +130,7 @@ void GameView::resizeRubberBand(const QPointF &cursorPoint, int selectedCount)
|
|||
QRect rect = QRect(mapFromScene(selectionOrigin), cursor).normalized();
|
||||
rubberBand->setGeometry(rect);
|
||||
|
||||
if (!SettingsCache::instance().getShowDragSelectionCount()) {
|
||||
if (!SettingsCache::instance().interface().getShowDragSelectionCount()) {
|
||||
dragCountLabel->hide();
|
||||
return;
|
||||
}
|
||||
|
|
@ -234,7 +239,7 @@ void GameView::updateTotalSelectionCount(const QSize &viewSize)
|
|||
|
||||
int count = scene()->selectedItems().count();
|
||||
|
||||
if (!SettingsCache::instance().getShowTotalSelectionCount() || count <= 1) {
|
||||
if (!SettingsCache::instance().interface().getShowTotalSelectionCount() || count <= 1) {
|
||||
totalCountLabel->hide();
|
||||
} else {
|
||||
totalCountLabel->setText(QString::number(count));
|
||||
|
|
@ -246,8 +251,7 @@ void GameView::updateTotalSelectionCount(const QSize &viewSize)
|
|||
totalCountLabel->show();
|
||||
}
|
||||
|
||||
TallyType tallyType =
|
||||
SettingsCache::instance().getShowSubtypeSelectionTally() ? TallyType::Subtypes : TallyType::None;
|
||||
TallyType tallyType = Tally::intToType(SettingsCache::instance().interface().getTallyType());
|
||||
|
||||
GameScene *gameScene = static_cast<GameScene *>(scene());
|
||||
QList<TallyRow> entries = Tally::compute(gameScene->selectedCards(), tallyType);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "card_menu.h"
|
||||
|
||||
#include "../../../client/settings/card_counter_settings.h"
|
||||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "../../../interface/widgets/tabs/tab_game.h"
|
||||
#include "../../board/card_item.h"
|
||||
#include "../../game/player/player_actions.h"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "grave_menu.h"
|
||||
|
||||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "../../game/abstract_game.h"
|
||||
#include "../../game/player/player_actions.h"
|
||||
#include "../../game/player/player_logic.h"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "move_menu.h"
|
||||
|
||||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "../../game/player/player_actions.h"
|
||||
#include "../../game/player/player_logic.h"
|
||||
#include "../card_menu_action_type.h"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "player_menu.h"
|
||||
|
||||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "../../../game_graphics/zones/hand_zone.h"
|
||||
#include "../../../game_graphics/zones/pile_zone.h"
|
||||
#include "../../../game_graphics/zones/table_zone.h"
|
||||
|
|
@ -44,6 +45,8 @@ PlayerMenu::PlayerMenu(PlayerGraphicsItem *_player) : QObject(_player), player(_
|
|||
utilityMenu = nullptr;
|
||||
}
|
||||
|
||||
tallyMenu = addManagedMenu<TallyMenu>();
|
||||
|
||||
if (player->getLogic()->getPlayerInfo()->getLocal()) {
|
||||
sayMenu = addManagedMenu<SayMenu>(player);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -15,11 +15,13 @@
|
|||
#include "rfg_menu.h"
|
||||
#include "say_menu.h"
|
||||
#include "sideboard_menu.h"
|
||||
#include "tally_menu.h"
|
||||
#include "utility_menu.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QMenu>
|
||||
#include <QObject>
|
||||
#include <libcockatrice/utility/card_ref.h>
|
||||
|
||||
class CardItem;
|
||||
class CardMenu;
|
||||
|
|
@ -87,6 +89,7 @@ private:
|
|||
GraveyardMenu *graveMenu;
|
||||
RfgMenu *rfgMenu;
|
||||
UtilityMenu *utilityMenu;
|
||||
TallyMenu *tallyMenu;
|
||||
SayMenu *sayMenu;
|
||||
CustomZoneMenu *customZonesMenu;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "pt_menu.h"
|
||||
|
||||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "../../game/player/player_actions.h"
|
||||
#include "../../game/player/player_logic.h"
|
||||
#include "../player_graphics_item.h"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "../../game/player/player_logic.h"
|
||||
#include "../player_graphics_item.h"
|
||||
|
||||
#include <libcockatrice/settings/message_settings.h>
|
||||
SayMenu::SayMenu(PlayerGraphicsItem *_player) : player(_player)
|
||||
{
|
||||
connect(&SettingsCache::instance().messages(), &MessageSettings::messageMacrosChanged, this, &SayMenu::initSayMenu);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "sideboard_menu.h"
|
||||
|
||||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "../../game/player/player_actions.h"
|
||||
#include "../../game/player/player_logic.h"
|
||||
#include "../player_graphics_item.h"
|
||||
|
|
|
|||
54
cockatrice/src/game_graphics/player/menu/tally_menu.cpp
Normal file
54
cockatrice/src/game_graphics/player/menu/tally_menu.cpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#include "tally_menu.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
|
||||
#include <QActionGroup>
|
||||
|
||||
TallyMenu::TallyMenu()
|
||||
{
|
||||
actionGroup = new QActionGroup(this);
|
||||
actionGroup->setExclusive(true);
|
||||
|
||||
aTallyNone = createTallyAction(TallyType::None);
|
||||
aTallySubtypes = createTallyAction(TallyType::Subtypes);
|
||||
|
||||
addAction(aTallyNone);
|
||||
addSeparator();
|
||||
addAction(aTallySubtypes);
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
QAction *TallyMenu::createTallyAction(TallyType tallyType)
|
||||
{
|
||||
TallyType currentType = Tally::intToType(SettingsCache::instance().interface().getTallyType());
|
||||
|
||||
QAction *action = new QAction(this);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(tallyType == currentType);
|
||||
|
||||
connect(action, &QAction::triggered, &SettingsCache::instance().interface(),
|
||||
[tallyType] { SettingsCache::instance().interface().setTallyType(static_cast<int>(tallyType)); });
|
||||
|
||||
actionGroup->addAction(action);
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
void TallyMenu::setShortcutsActive()
|
||||
{
|
||||
// no-op because we haven't decided if we're adding shortcuts for tally types
|
||||
}
|
||||
|
||||
void TallyMenu::setShortcutsInactive()
|
||||
{
|
||||
// no-op because we haven't decided if we're adding shortcuts for tally types
|
||||
}
|
||||
|
||||
void TallyMenu::retranslateUi()
|
||||
{
|
||||
setTitle(tr("Tally"));
|
||||
|
||||
aTallyNone->setText(tr("None"));
|
||||
aTallySubtypes->setText(tr("Subtypes"));
|
||||
}
|
||||
30
cockatrice/src/game_graphics/player/menu/tally_menu.h
Normal file
30
cockatrice/src/game_graphics/player/menu/tally_menu.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef COCKATRICE_TALLY_MENU_H
|
||||
#define COCKATRICE_TALLY_MENU_H
|
||||
|
||||
#include "../../../interface/widgets/menus/tearoff_menu.h"
|
||||
#include "../../tally/tally.h"
|
||||
#include "abstract_player_component.h"
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
class TallyMenu : public TearOffMenu, public AbstractPlayerComponent
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TallyMenu();
|
||||
|
||||
void setShortcutsActive() override;
|
||||
void setShortcutsInactive() override;
|
||||
void retranslateUi() override;
|
||||
|
||||
private:
|
||||
QActionGroup *actionGroup = nullptr;
|
||||
|
||||
QAction *aTallyNone = nullptr;
|
||||
QAction *aTallySubtypes = nullptr;
|
||||
|
||||
QAction *createTallyAction(TallyType tallyType);
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_TALLY_MENU_H
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#include "utility_menu.h"
|
||||
|
||||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "../../../interface/deck_loader/deck_loader.h"
|
||||
#include "../../game/player/player_actions.h"
|
||||
#include "../../game/player/player_logic.h"
|
||||
|
|
|
|||
|
|
@ -13,12 +13,13 @@
|
|||
#include "player_dialogs.h"
|
||||
|
||||
#include <QGraphicsView>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
|
||||
PlayerGraphicsItem::PlayerGraphicsItem(PlayerLogic *_player) : player(_player)
|
||||
{
|
||||
connect(&SettingsCache::instance(), &SettingsCache::horizontalHandChanged, this,
|
||||
connect(&SettingsCache::instance().interface(), &InterfaceSettings::horizontalHandChanged, this,
|
||||
&PlayerGraphicsItem::rearrangeZones);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::handJustificationChanged, this,
|
||||
connect(&SettingsCache::instance().interface(), &InterfaceSettings::handJustificationChanged, this,
|
||||
&PlayerGraphicsItem::rearrangeZones);
|
||||
connect(player, &PlayerLogic::rearrangeCounters, this, &PlayerGraphicsItem::rearrangeCounters);
|
||||
connect(player, &PlayerLogic::activeChanged, this, &PlayerGraphicsItem::onPlayerActiveChanged);
|
||||
|
|
@ -148,7 +149,7 @@ qreal PlayerGraphicsItem::getMinimumWidth() const
|
|||
{
|
||||
qreal result = tableZoneGraphicsItem->getMinimumWidth() + CardDimensions::HEIGHT_F + 15 + counterAreaWidth +
|
||||
stackZoneGraphicsItem->boundingRect().width();
|
||||
if (!SettingsCache::instance().getHorizontalHand()) {
|
||||
if (!SettingsCache::instance().interface().getHorizontalHand()) {
|
||||
result += handZoneGraphicsItem->boundingRect().width();
|
||||
}
|
||||
return result;
|
||||
|
|
@ -165,7 +166,7 @@ void PlayerGraphicsItem::processSceneSizeChange(int newPlayerWidth)
|
|||
// Extend table (and hand, if horizontal) to accommodate the new player width.
|
||||
qreal tableWidth = newPlayerWidth - CardDimensions::HEIGHT_F - 15 - counterAreaWidth -
|
||||
stackZoneGraphicsItem->boundingRect().width();
|
||||
if (!SettingsCache::instance().getHorizontalHand()) {
|
||||
if (!SettingsCache::instance().interface().getHorizontalHand()) {
|
||||
tableWidth -= handZoneGraphicsItem->boundingRect().width();
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +234,7 @@ void PlayerGraphicsItem::rearrangeCounters()
|
|||
void PlayerGraphicsItem::rearrangeZones()
|
||||
{
|
||||
auto base = QPointF(CardDimensions::HEIGHT_F + counterAreaWidth + 15, 0);
|
||||
if (SettingsCache::instance().getHorizontalHand()) {
|
||||
if (SettingsCache::instance().interface().getHorizontalHand()) {
|
||||
if (mirrored) {
|
||||
if (player->getHandZone()->contentsKnown()) {
|
||||
handVisible = true;
|
||||
|
|
@ -284,7 +285,7 @@ void PlayerGraphicsItem::updateBoundingRect()
|
|||
{
|
||||
prepareGeometryChange();
|
||||
qreal width = CardDimensions::HEIGHT_F + 15 + counterAreaWidth + stackZoneGraphicsItem->boundingRect().width();
|
||||
if (SettingsCache::instance().getHorizontalHand()) {
|
||||
if (SettingsCache::instance().interface().getHorizontalHand()) {
|
||||
qreal handHeight = handVisible ? handZoneGraphicsItem->boundingRect().height() : 0;
|
||||
bRect = QRectF(0, 0, width + tableZoneGraphicsItem->boundingRect().width(),
|
||||
tableZoneGraphicsItem->boundingRect().height() + handHeight);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,15 @@
|
|||
|
||||
#include "subtype_tally.h"
|
||||
|
||||
TallyType Tally::intToType(int value)
|
||||
{
|
||||
if (value < static_cast<int>(TallyType::None) || value > static_cast<int>(TallyType::MaxValue)) {
|
||||
return TallyType::None;
|
||||
}
|
||||
|
||||
return static_cast<TallyType>(value);
|
||||
}
|
||||
|
||||
QList<TallyRow> Tally::compute(const QList<CardItem *> &cards, const TallyType type)
|
||||
{
|
||||
switch (type) {
|
||||
|
|
|
|||
|
|
@ -20,11 +20,20 @@ enum class TallyType
|
|||
{
|
||||
None,
|
||||
Subtypes,
|
||||
MaxValue = Subtypes // sentinel value
|
||||
};
|
||||
|
||||
namespace Tally
|
||||
{
|
||||
|
||||
/**
|
||||
* Safely converts an int into the corresponding TallyType.
|
||||
*
|
||||
* @param value The int value
|
||||
* @return The TallyType. Returns TallyType::None if the value is not within range
|
||||
*/
|
||||
TallyType intToType(int value);
|
||||
|
||||
/**
|
||||
* @brief Analyzes the selected cards according to the tally type and builds the resulting tally rows.
|
||||
* This forwards the cards to the code for that tally type.
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <QPainter>
|
||||
#include <libcockatrice/protocol/pb/command_move_card.pb.h>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
|
||||
HandZone::HandZone(HandZoneLogic *_logic, int _zoneHeight, QGraphicsItem *parent)
|
||||
: SelectZone(_logic, parent), zoneHeight(_zoneHeight)
|
||||
|
|
@ -33,7 +34,7 @@ void HandZone::handleDropEvent(const QList<CardDragItem *> &dragItems,
|
|||
|
||||
QPoint point = dropPoint + scenePos().toPoint();
|
||||
int x = -1;
|
||||
if (SettingsCache::instance().getHorizontalHand()) {
|
||||
if (SettingsCache::instance().interface().getHorizontalHand()) {
|
||||
for (x = 0; x < getLogic()->getCards().size(); x++) {
|
||||
if (point.x() < static_cast<CardItem *>(getLogic()->getCards().at(x))->scenePos().x()) {
|
||||
break;
|
||||
|
|
@ -60,7 +61,7 @@ void HandZone::handleDropEvent(const QList<CardDragItem *> &dragItems,
|
|||
|
||||
QRectF HandZone::boundingRect() const
|
||||
{
|
||||
if (SettingsCache::instance().getHorizontalHand()) {
|
||||
if (SettingsCache::instance().interface().getHorizontalHand()) {
|
||||
return QRectF(0, 0, width, CardDimensions::HEIGHT_F + 10);
|
||||
} else {
|
||||
return QRectF(0, 0, CardDimensions::WIDTH_F * 1.5, zoneHeight);
|
||||
|
|
@ -77,8 +78,8 @@ void HandZone::reorganizeCards()
|
|||
{
|
||||
if (!getLogic()->getCards().isEmpty()) {
|
||||
const int cardCount = getLogic()->getCards().size();
|
||||
if (SettingsCache::instance().getHorizontalHand()) {
|
||||
bool leftJustified = SettingsCache::instance().getLeftJustified();
|
||||
if (SettingsCache::instance().interface().getHorizontalHand()) {
|
||||
bool leftJustified = SettingsCache::instance().interface().getLeftJustified();
|
||||
qreal cardWidth = getLogic()->getCards().at(0)->boundingRect().width();
|
||||
const int xPadding = leftJustified ? cardWidth * 1.4 : 5;
|
||||
qreal totalWidth =
|
||||
|
|
@ -126,7 +127,7 @@ void HandZone::sortHand(const QList<CardList::SortOption> &options)
|
|||
|
||||
void HandZone::setWidth(qreal _width)
|
||||
{
|
||||
if (SettingsCache::instance().getHorizontalHand()) {
|
||||
if (SettingsCache::instance().interface().getHorizontalHand()) {
|
||||
prepareGeometryChange();
|
||||
width = _width;
|
||||
reorganizeCards();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "pile_zone.h"
|
||||
|
||||
#include "../../client/settings/cache_settings.h"
|
||||
#include "../../game/player/player_actions.h"
|
||||
#include "../../game/player/player_logic.h"
|
||||
#include "../../game/zones/pile_zone_logic.h"
|
||||
|
|
@ -11,6 +12,7 @@
|
|||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <libcockatrice/protocol/pb/command_move_card.pb.h>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
|
||||
PileZone::PileZone(PileZoneLogic *_logic, QGraphicsItem *parent) : CardZone(_logic, parent)
|
||||
{
|
||||
|
|
@ -23,12 +25,13 @@ PileZone::PileZone(PileZoneLogic *_logic, QGraphicsItem *parent) : CardZone(_log
|
|||
.rotate(90)
|
||||
.translate(-CardDimensions::WIDTH_HALF_F, -CardDimensions::HEIGHT_HALF_F));
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::roundCardCornersChanged, this, [this](bool _roundCardCorners) {
|
||||
Q_UNUSED(_roundCardCorners);
|
||||
connect(&SettingsCache::instance().cardsDisplay(), &CardsDisplaySettings::roundCardCornersChanged, this,
|
||||
[this](bool _roundCardCorners) {
|
||||
Q_UNUSED(_roundCardCorners);
|
||||
|
||||
prepareGeometryChange();
|
||||
update();
|
||||
});
|
||||
prepareGeometryChange();
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
QRectF PileZone::boundingRect() const
|
||||
|
|
@ -39,7 +42,8 @@ QRectF PileZone::boundingRect() const
|
|||
QPainterPath PileZone::shape() const
|
||||
{
|
||||
QPainterPath shape;
|
||||
qreal cardCornerRadius = SettingsCache::instance().getRoundCardCorners() ? 0.05 * CardDimensions::WIDTH_F : 0.0;
|
||||
qreal cardCornerRadius =
|
||||
SettingsCache::instance().cardsDisplay().getRoundCardCorners() ? 0.05 * CardDimensions::WIDTH_F : 0.0;
|
||||
shape.addRoundedRect(boundingRect(), cardCornerRadius, cardCornerRadius);
|
||||
return shape;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@
|
|||
#include <QGraphicsRectItem>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QtMath>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
|
||||
static qreal stackingOffset(qreal cardHeight)
|
||||
{
|
||||
const qreal overlapPercent = SettingsCache::instance().getStackCardOverlapPercent();
|
||||
const qreal overlapPercent = SettingsCache::instance().cardsDisplay().getStackCardOverlapPercent();
|
||||
return cardHeight * (100.0 - overlapPercent) / 100.0;
|
||||
}
|
||||
|
||||
|
|
@ -21,40 +22,32 @@ SelectZone::ZoneLayout SelectZone::computeZoneLayout(const StackLayoutParams &pa
|
|||
}
|
||||
qreal effectiveOffset = params.desiredOffset;
|
||||
if (params.cardCount > 1) {
|
||||
qreal fitOffset;
|
||||
if (params.totalHeight < params.cardHeight && params.minOffset > 0.0) {
|
||||
// Zone is shorter than a card (e.g. minimized). Compress offsets so
|
||||
// every card has at least minOffset pixels of its top visible.
|
||||
fitOffset = (params.totalHeight - params.minOffset) / (params.cardCount - 1);
|
||||
effectiveOffset = qMax(0.0, qMin(params.desiredOffset, fitOffset));
|
||||
qreal reservedForBottomCard;
|
||||
if (params.allowBottomOverflow) {
|
||||
// Allow the bottom card to partially overflow in tight zones, scaling the
|
||||
// overflow allowance by sqrt(cardCount-1) so offsets decrease smoothly
|
||||
// as cards are added rather than dropping by 1/(n-1) each time.
|
||||
// The 0.75 ratio was tuned experimentally to balance card visibility vs. overflow.
|
||||
constexpr qreal bottomCardZoneRatio = 0.75;
|
||||
const qreal adjustedRatio = bottomCardZoneRatio / qSqrt(static_cast<qreal>(params.cardCount - 1));
|
||||
reservedForBottomCard = qMin(params.cardHeight, params.totalHeight * adjustedRatio);
|
||||
} else {
|
||||
qreal reservedForBottomCard;
|
||||
if (params.allowBottomOverflow) {
|
||||
// Allow the bottom card to partially overflow in tight zones, scaling the
|
||||
// overflow allowance by sqrt(cardCount-1) so offsets decrease smoothly
|
||||
// as cards are added rather than dropping by 1/(n-1) each time.
|
||||
// The 0.75 ratio was tuned experimentally to balance card visibility vs. overflow.
|
||||
constexpr qreal bottomCardZoneRatio = 0.75;
|
||||
const qreal adjustedRatio = bottomCardZoneRatio / qSqrt(static_cast<qreal>(params.cardCount - 1));
|
||||
reservedForBottomCard = qMin(params.cardHeight, params.totalHeight * adjustedRatio);
|
||||
} else {
|
||||
// No overflow: reserve full card height for the bottom card
|
||||
reservedForBottomCard = params.cardHeight;
|
||||
}
|
||||
fitOffset = (params.totalHeight - reservedForBottomCard) / (params.cardCount - 1);
|
||||
// No overflow: reserve full card height for the bottom card
|
||||
reservedForBottomCard = params.cardHeight;
|
||||
}
|
||||
qreal fitOffset = (params.totalHeight - reservedForBottomCard) / (params.cardCount - 1);
|
||||
|
||||
if (!params.allowBottomOverflow) {
|
||||
// Constrain offset so all card tops remain within zone bounds.
|
||||
// With start=0, last card top at (cardCount-1) * effectiveOffset must be < totalHeight.
|
||||
qreal maxOffsetForTops = params.totalHeight / (params.cardCount - 1);
|
||||
fitOffset = qMin(fitOffset, maxOffsetForTops);
|
||||
}
|
||||
if (!params.allowBottomOverflow) {
|
||||
// Constrain offset so all card tops remain within zone bounds.
|
||||
// With start=0, last card top at (cardCount-1) * effectiveOffset must be < totalHeight.
|
||||
qreal maxOffsetForTops = params.totalHeight / (params.cardCount - 1);
|
||||
fitOffset = qMin(fitOffset, maxOffsetForTops);
|
||||
}
|
||||
|
||||
// Apply minOffset only if it fits; otherwise compress further to keep all card tops visible.
|
||||
effectiveOffset = qMin(params.desiredOffset, fitOffset);
|
||||
if (fitOffset >= params.minOffset) {
|
||||
effectiveOffset = qMax(params.minOffset, effectiveOffset);
|
||||
}
|
||||
// Apply minOffset only if it fits; otherwise compress further to keep all card tops visible.
|
||||
effectiveOffset = qMin(params.desiredOffset, fitOffset);
|
||||
if (fitOffset >= params.minOffset) {
|
||||
effectiveOffset = qMax(params.minOffset, effectiveOffset);
|
||||
}
|
||||
}
|
||||
qreal stackHeight = (params.cardCount - 1) * effectiveOffset + params.cardHeight;
|
||||
|
|
|
|||
|
|
@ -43,12 +43,18 @@ void StackZone::handleDropEvent(const QList<CardDragItem *> &dragItems,
|
|||
return;
|
||||
}
|
||||
|
||||
int index = calcDropIndexFromY(dropPoint.y(), MIN_CARD_VISIBLE);
|
||||
|
||||
// Same-zone no-op: don't move a card onto itself
|
||||
const auto &cards = getLogic()->getCards();
|
||||
if (!cards.isEmpty() && startZone == getLogic() && cards.at(index)->getId() == dragItems.at(0)->getId()) {
|
||||
return;
|
||||
int index;
|
||||
if (startZone == getLogic()) {
|
||||
// Reordering within the zone: use drop position
|
||||
index = calcDropIndexFromY(dropPoint.y(), MIN_CARD_VISIBLE);
|
||||
// Same-zone no-op: don't move a card onto itself
|
||||
if (!cards.isEmpty() && cards.at(index)->getId() == dragItems.at(0)->getId()) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Coming from another zone: append at end (top of stack, rendered on top)
|
||||
index = static_cast<int>(cards.size());
|
||||
}
|
||||
|
||||
Command_MoveCard cmd;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <libcockatrice/card/card_info.h>
|
||||
#include <libcockatrice/protocol/pb/command_move_card.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_set_card_attr.pb.h>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
#include <libcockatrice/utility/zone_names.h>
|
||||
|
||||
const QColor TableZone::BACKGROUND_COLOR = QColor(100, 100, 100);
|
||||
|
|
@ -28,7 +29,7 @@ TableZone::TableZone(TableZoneLogic *_logic, bool _mirrored, QGraphicsItem *pare
|
|||
connect(_logic, &TableZoneLogic::contentSizeChanged, this, &TableZone::resizeToContents);
|
||||
connect(_logic, &TableZoneLogic::toggleTapped, this, &TableZone::toggleTapped);
|
||||
connect(themeManager, &ThemeManager::themeChanged, this, &TableZone::updateBg);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::invertVerticalCoordinateChanged, this,
|
||||
connect(&SettingsCache::instance().interface(), &InterfaceSettings::invertVerticalCoordinateChanged, this,
|
||||
&TableZone::reorganizeCards);
|
||||
|
||||
updateBg();
|
||||
|
|
@ -59,8 +60,8 @@ void TableZone::setMirrored(bool isMirrored)
|
|||
|
||||
bool TableZone::isInverted() const
|
||||
{
|
||||
return ((mirrored && !SettingsCache::instance().getInvertVerticalCoordinate()) ||
|
||||
(!mirrored && SettingsCache::instance().getInvertVerticalCoordinate()));
|
||||
return ((mirrored && !SettingsCache::instance().interface().getInvertVerticalCoordinate()) ||
|
||||
(!mirrored && SettingsCache::instance().interface().getInvertVerticalCoordinate()));
|
||||
}
|
||||
|
||||
void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <QStyle>
|
||||
#include <QStyleOption>
|
||||
#include <libcockatrice/protocol/pb/command_shuffle.pb.h>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
|
@ -65,7 +66,7 @@ ZoneViewWidget::ZoneViewWidget(PlayerLogic *_player,
|
|||
|
||||
connect(help, &QAction::triggered, this, [this] { createSearchSyntaxHelpWindow(&searchEdit); });
|
||||
|
||||
if (SettingsCache::instance().getFocusCardViewSearchBar()) {
|
||||
if (SettingsCache::instance().interface().getFocusCardViewSearchBar()) {
|
||||
this->setActive(true);
|
||||
searchEdit.setFocus();
|
||||
}
|
||||
|
|
@ -76,8 +77,8 @@ ZoneViewWidget::ZoneViewWidget(PlayerLogic *_player,
|
|||
vbox->addItem(searchEditProxy);
|
||||
|
||||
// hide search bar if chat autofocus setting is enabled, since typing into it will no longer work anyway
|
||||
searchEditProxy->setVisible(!SettingsCache::instance().getKeepGameChatFocus());
|
||||
connect(&SettingsCache::instance(), &SettingsCache::keepGameChatFocusChanged, searchEditProxy,
|
||||
searchEditProxy->setVisible(!SettingsCache::instance().interface().getKeepGameChatFocus());
|
||||
connect(&SettingsCache::instance().interface(), &InterfaceSettings::keepGameChatFocusChanged, searchEditProxy,
|
||||
[searchEditProxy](bool keepFocus) { searchEditProxy->setVisible(!keepFocus); });
|
||||
|
||||
// top row
|
||||
|
|
@ -158,9 +159,9 @@ ZoneViewWidget::ZoneViewWidget(PlayerLogic *_player,
|
|||
connect(&sortBySelector, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||
&ZoneViewWidget::processSortBy);
|
||||
connect(&pileViewCheckBox, &QCheckBox::QT_STATE_CHANGED, this, &ZoneViewWidget::processSetPileView);
|
||||
groupBySelector.setCurrentIndex(SettingsCache::instance().getZoneViewGroupByIndex());
|
||||
sortBySelector.setCurrentIndex(SettingsCache::instance().getZoneViewSortByIndex());
|
||||
pileViewCheckBox.setChecked(SettingsCache::instance().getZoneViewPileView());
|
||||
groupBySelector.setCurrentIndex(SettingsCache::instance().interface().getZoneViewGroupByIndex());
|
||||
sortBySelector.setCurrentIndex(SettingsCache::instance().interface().getZoneViewSortByIndex());
|
||||
pileViewCheckBox.setChecked(SettingsCache::instance().interface().getZoneViewPileView());
|
||||
|
||||
if (CardList::NoSort == static_cast<CardList::SortOption>(groupBySelector.currentData().toInt())) {
|
||||
pileViewCheckBox.setEnabled(false);
|
||||
|
|
@ -190,7 +191,7 @@ ZoneViewWidget::ZoneViewWidget(PlayerLogic *_player,
|
|||
void ZoneViewWidget::processGroupBy(int index)
|
||||
{
|
||||
auto option = static_cast<CardList::SortOption>(groupBySelector.itemData(index).toInt());
|
||||
SettingsCache::instance().setZoneViewGroupByIndex(index);
|
||||
SettingsCache::instance().interface().setZoneViewGroupByIndex(index);
|
||||
zone->setGroupBy(option);
|
||||
|
||||
// disable pile view checkbox if we're not grouping by anything
|
||||
|
|
@ -214,13 +215,13 @@ void ZoneViewWidget::processSortBy(int index)
|
|||
return;
|
||||
}
|
||||
|
||||
SettingsCache::instance().setZoneViewSortByIndex(index);
|
||||
SettingsCache::instance().interface().setZoneViewSortByIndex(index);
|
||||
zone->setSortBy(option);
|
||||
}
|
||||
|
||||
void ZoneViewWidget::processSetPileView(QT_STATE_CHANGED_T value)
|
||||
{
|
||||
SettingsCache::instance().setZoneViewPileView(value);
|
||||
SettingsCache::instance().interface().setZoneViewPileView(value);
|
||||
zone->setPileView(value);
|
||||
}
|
||||
|
||||
|
|
@ -477,7 +478,7 @@ static qreal rowsToHeight(int rows)
|
|||
**/
|
||||
static qreal calcMaxInitialHeight()
|
||||
{
|
||||
return rowsToHeight(SettingsCache::instance().getCardViewInitialRowsMax());
|
||||
return rowsToHeight(SettingsCache::instance().interface().getCardViewInitialRowsMax());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -559,7 +560,7 @@ void ZoneViewWidget::initStyleOption(QStyleOption *option) const
|
|||
void ZoneViewWidget::expandWindow()
|
||||
{
|
||||
qreal maxInitialHeight = calcMaxInitialHeight();
|
||||
qreal maxExpandedHeight = rowsToHeight(SettingsCache::instance().getCardViewExpandedRowsMax());
|
||||
qreal maxExpandedHeight = rowsToHeight(SettingsCache::instance().interface().getCardViewExpandedRowsMax());
|
||||
qreal height = rect().height() - extraHeight - 10;
|
||||
qreal maxHeight = maximumHeight() - extraHeight - 10;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#include "card_picture_loader.h"
|
||||
|
||||
#include "../../client/settings/cache_settings.h"
|
||||
#include "card_picture_loader_cache_method.h"
|
||||
#include "card_picture_loader_local_schemes.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QBuffer>
|
||||
|
|
@ -16,6 +18,9 @@
|
|||
#include <QStatusBar>
|
||||
#include <QThread>
|
||||
#include <algorithm>
|
||||
#include <libcockatrice/settings/cache_storage_settings.h>
|
||||
#include <libcockatrice/settings/paths_settings.h>
|
||||
#include <libcockatrice/settings/personal_settings.h>
|
||||
#include <utility>
|
||||
|
||||
// never cache more than 300 cards at once for a single deck
|
||||
|
|
@ -24,8 +29,9 @@
|
|||
CardPictureLoader::CardPictureLoader() : QObject(nullptr)
|
||||
{
|
||||
worker = new CardPictureLoaderWorker;
|
||||
connect(&SettingsCache::instance(), &SettingsCache::picsPathChanged, this, &CardPictureLoader::picsPathChanged);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::picDownloadChanged, this,
|
||||
connect(&SettingsCache::instance().paths(), &PathsSettings::picsPathChanged, this,
|
||||
&CardPictureLoader::picsPathChanged);
|
||||
connect(&SettingsCache::instance().personal(), &PersonalSettings::picDownloadChanged, this,
|
||||
&CardPictureLoader::picDownloadChanged);
|
||||
|
||||
qRegisterMetaType<ExactCard>();
|
||||
|
|
@ -169,7 +175,8 @@ void CardPictureLoader::imageLoaded(const ExactCard &card, const QImage &image)
|
|||
|
||||
QPixmapCache::insert(card.getPixmapCacheKey(), finalPixmap);
|
||||
|
||||
if (SettingsCache::instance().getCardPictureLoaderCacheMethod() ==
|
||||
if (static_cast<CardPictureLoaderCacheMethod::CacheMethod>(
|
||||
SettingsCache::instance().cacheStorage().getCardPictureLoaderCacheMethod()) ==
|
||||
CardPictureLoaderCacheMethod::CacheMethod::FILESYSTEM_CACHE) {
|
||||
saveCardImageToLocalStorage(card, finalPixmap);
|
||||
}
|
||||
|
|
@ -189,9 +196,9 @@ void CardPictureLoader::saveCardImageToLocalStorage(const ExactCard &card, const
|
|||
return;
|
||||
}
|
||||
|
||||
const QString picsRoot = SettingsCache::instance().getPicsPath();
|
||||
CardPictureLoaderLocalSchemes::NamingScheme scheme =
|
||||
SettingsCache::instance().getLocalCardImageStorageNamingScheme();
|
||||
const QString picsRoot = SettingsCache::instance().paths().getPicsPath();
|
||||
CardPictureLoaderLocalSchemes::NamingScheme scheme = static_cast<CardPictureLoaderLocalSchemes::NamingScheme>(
|
||||
SettingsCache::instance().cacheStorage().getLocalCardImageStorageNamingScheme());
|
||||
|
||||
QString pattern;
|
||||
|
||||
|
|
@ -306,7 +313,7 @@ void CardPictureLoader::picsPathChanged()
|
|||
|
||||
bool CardPictureLoader::hasCustomArt()
|
||||
{
|
||||
auto picsPath = SettingsCache::instance().getPicsPath();
|
||||
auto picsPath = SettingsCache::instance().paths().getPicsPath();
|
||||
QDirIterator it(picsPath, QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
|
||||
// Check if there is at least one non-directory file in the pics path, other
|
||||
|
|
|
|||
|
|
@ -7,15 +7,16 @@
|
|||
#include <QDirIterator>
|
||||
#include <QMovie>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/settings/paths_settings.h>
|
||||
|
||||
static constexpr int REFRESH_INTERVAL_MS = 10 * 1000;
|
||||
|
||||
CardPictureLoaderLocal::CardPictureLoaderLocal(QObject *parent)
|
||||
: QObject(parent), picsPath(SettingsCache::instance().getPicsPath()),
|
||||
customPicsPath(SettingsCache::instance().getCustomPicsPath())
|
||||
: QObject(parent), picsPath(SettingsCache::instance().paths().getPicsPath()),
|
||||
customPicsPath(SettingsCache::instance().paths().getCustomPicsPath())
|
||||
{
|
||||
// Hook up signals to settings
|
||||
connect(&SettingsCache::instance(), &SettingsCache::picsPathChanged, this,
|
||||
connect(&SettingsCache::instance().paths(), &PathsSettings::picsPathChanged, this,
|
||||
&CardPictureLoaderLocal::picsPathChanged);
|
||||
|
||||
refreshIndex();
|
||||
|
|
@ -127,6 +128,6 @@ QImage CardPictureLoaderLocal::tryLoadCardImageFromDisk(const QString &setName,
|
|||
|
||||
void CardPictureLoaderLocal::picsPathChanged()
|
||||
{
|
||||
picsPath = SettingsCache::instance().getPicsPath();
|
||||
customPicsPath = SettingsCache::instance().getCustomPicsPath();
|
||||
picsPath = SettingsCache::instance().paths().getPicsPath();
|
||||
customPicsPath = SettingsCache::instance().paths().getCustomPicsPath();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "card_picture_loader_worker.h"
|
||||
|
||||
#include "../../client/settings/cache_settings.h"
|
||||
#include "card_picture_loader_cache_method.h"
|
||||
#include "card_picture_loader_local.h"
|
||||
#include "card_picture_loader_worker_work.h"
|
||||
|
||||
|
|
@ -9,13 +10,17 @@
|
|||
#include <QNetworkDiskCache>
|
||||
#include <QNetworkReply>
|
||||
#include <QThread>
|
||||
#include <libcockatrice/settings/cache_storage_settings.h>
|
||||
#include <libcockatrice/settings/paths_settings.h>
|
||||
#include <libcockatrice/settings/personal_settings.h>
|
||||
#include <utility>
|
||||
#include <version_string.h>
|
||||
|
||||
static constexpr int MAX_REQUESTS_PER_SEC = 10;
|
||||
|
||||
CardPictureLoaderWorker::CardPictureLoaderWorker()
|
||||
: QObject(nullptr), picDownload(SettingsCache::instance().getPicDownload()), requestQuota(MAX_REQUESTS_PER_SEC)
|
||||
: QObject(nullptr), picDownload(SettingsCache::instance().personal().getPicDownload()),
|
||||
requestQuota(MAX_REQUESTS_PER_SEC)
|
||||
{
|
||||
networkManager = new QNetworkAccessManager(this);
|
||||
// We need a timeout to ensure requests don't hang indefinitely in case of
|
||||
|
|
@ -25,13 +30,14 @@ CardPictureLoaderWorker::CardPictureLoaderWorker()
|
|||
cache = new QNetworkDiskCache(this);
|
||||
cache->setCacheDirectory(SettingsCache::instance().getNetworkCachePath());
|
||||
cache->setMaximumCacheSize(1024L * 1024L *
|
||||
static_cast<qint64>(SettingsCache::instance().getNetworkCacheSizeInMB()));
|
||||
static_cast<qint64>(SettingsCache::instance().cacheStorage().getNetworkCacheSizeInMB()));
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::networkCacheSizeChanged, cache, [this](int newSizeInMB) {
|
||||
if (cache) {
|
||||
cache->setMaximumCacheSize(1024L * 1024L * static_cast<qint64>(newSizeInMB));
|
||||
}
|
||||
});
|
||||
connect(&SettingsCache::instance().cacheStorage(), &CacheStorageSettings::networkCacheSizeChanged, cache,
|
||||
[this](int newSizeInMB) {
|
||||
if (cache) {
|
||||
cache->setMaximumCacheSize(1024L * 1024L * static_cast<qint64>(newSizeInMB));
|
||||
}
|
||||
});
|
||||
|
||||
networkManager->setCache(cache);
|
||||
|
||||
|
|
@ -39,7 +45,7 @@ CardPictureLoaderWorker::CardPictureLoaderWorker()
|
|||
// We can't use NoLessSafeRedirectPolicy because it is not applied with AlwaysCache
|
||||
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
|
||||
|
||||
cacheFilePath = SettingsCache::instance().getRedirectCachePath() + REDIRECT_CACHE_FILENAME;
|
||||
cacheFilePath = SettingsCache::instance().paths().getRedirectCachePath() + REDIRECT_CACHE_FILENAME;
|
||||
loadRedirectCache();
|
||||
cleanStaleEntries();
|
||||
|
||||
|
|
@ -72,7 +78,8 @@ void CardPictureLoaderWorker::queueRequest(const QUrl &url, CardPictureLoaderWor
|
|||
queueRequest(cachedRedirect, worker);
|
||||
return;
|
||||
}
|
||||
if (SettingsCache::instance().getCardPictureLoaderCacheMethod() ==
|
||||
if (static_cast<CardPictureLoaderCacheMethod::CacheMethod>(
|
||||
SettingsCache::instance().cacheStorage().getCardPictureLoaderCacheMethod()) ==
|
||||
CardPictureLoaderCacheMethod::CacheMethod::NETWORK_CACHE &&
|
||||
cache->metaData(url).isValid()) {
|
||||
// If we hit a cached url, we get to make the request for free, since it won't contribute towards the
|
||||
|
|
@ -98,8 +105,10 @@ QNetworkReply *CardPictureLoaderWorker::makeRequest(const QUrl &url, CardPicture
|
|||
req.setHeader(QNetworkRequest::UserAgentHeader, QString("Cockatrice %1").arg(VERSION_STRING));
|
||||
req.setRawHeader("Accept", "image/avif,image/webp,image/apng,image/,/*;q=0.8");
|
||||
|
||||
bool useNetworkCache = !picDownload && SettingsCache::instance().getCardPictureLoaderCacheMethod() ==
|
||||
CardPictureLoaderCacheMethod::CacheMethod::NETWORK_CACHE;
|
||||
bool useNetworkCache =
|
||||
!picDownload && static_cast<CardPictureLoaderCacheMethod::CacheMethod>(
|
||||
SettingsCache::instance().cacheStorage().getCardPictureLoaderCacheMethod()) ==
|
||||
CardPictureLoaderCacheMethod::CacheMethod::NETWORK_CACHE;
|
||||
|
||||
req.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
|
||||
useNetworkCache ? QNetworkRequest::AlwaysCache : QNetworkRequest::AlwaysNetwork);
|
||||
|
|
@ -229,7 +238,7 @@ void CardPictureLoaderWorker::cleanStaleEntries()
|
|||
|
||||
auto it = redirectCache.begin();
|
||||
while (it != redirectCache.end()) {
|
||||
if (it.value().second.addDays(SettingsCache::instance().getRedirectCacheTtl()) < now) {
|
||||
if (it.value().second.addDays(SettingsCache::instance().cacheStorage().getRedirectCacheTtl()) < now) {
|
||||
it = redirectCache.erase(it); // Remove stale entry
|
||||
} else {
|
||||
++it;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <QNetworkReply>
|
||||
#include <QThread>
|
||||
#include <QThreadPool>
|
||||
#include <libcockatrice/settings/personal_settings.h>
|
||||
|
||||
// Card back returned by gatherer when card is not found
|
||||
static const QStringList MD5_BLACKLIST = {
|
||||
|
|
@ -19,7 +20,7 @@ static const QStringList MD5_BLACKLIST = {
|
|||
|
||||
CardPictureLoaderWorkerWork::CardPictureLoaderWorkerWork(const CardPictureLoaderWorker *worker, const ExactCard &toLoad)
|
||||
: QObject(nullptr), cardToDownload(CardPictureToLoad(toLoad)),
|
||||
picDownload(SettingsCache::instance().getPicDownload())
|
||||
picDownload(SettingsCache::instance().personal().getPicDownload())
|
||||
{
|
||||
// Hook up signals to the orchestrator
|
||||
connect(this, &CardPictureLoaderWorkerWork::requestImageDownload, worker, &CardPictureLoaderWorker::queueRequest);
|
||||
|
|
@ -31,7 +32,7 @@ CardPictureLoaderWorkerWork::CardPictureLoaderWorkerWork(const CardPictureLoader
|
|||
&CardPictureLoaderWorker::imageRequestSucceeded);
|
||||
|
||||
// Hook up signals to settings
|
||||
connect(&SettingsCache::instance(), SIGNAL(picDownloadChanged()), this, SLOT(picDownloadChanged()));
|
||||
connect(&SettingsCache::instance().personal(), SIGNAL(picDownloadChanged()), this, SLOT(picDownloadChanged()));
|
||||
|
||||
startNextPicDownload();
|
||||
}
|
||||
|
|
@ -210,5 +211,5 @@ void CardPictureLoaderWorkerWork::concludeImageLoad(const QImage &image)
|
|||
|
||||
void CardPictureLoaderWorkerWork::picDownloadChanged()
|
||||
{
|
||||
picDownload = SettingsCache::instance().getPicDownload();
|
||||
picDownload = SettingsCache::instance().personal().getPicDownload();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#include <algorithm>
|
||||
#include <libcockatrice/card/set/card_set_comparator.h>
|
||||
#include <libcockatrice/interfaces/noop_card_set_priority_controller.h>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
#include <libcockatrice/settings/download_settings.h>
|
||||
|
||||
CardPictureToLoad::CardPictureToLoad(const ExactCard &_card)
|
||||
: card(_card), urlTemplates(SettingsCache::instance().downloads().getAllURLs())
|
||||
|
|
@ -34,7 +36,7 @@ QList<CardSetPtr> CardPictureToLoad::extractSetsSorted(const ExactCard &card)
|
|||
std::sort(sortedSets.begin(), sortedSets.end(), SetPriorityComparator());
|
||||
|
||||
// If the user hasn't disabled arts other than their personal preference...
|
||||
if (!SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference()) {
|
||||
if (!SettingsCache::instance().cardsDisplay().getOverrideAllCardArtWithPersonalPreference()) {
|
||||
// If the pixmapCacheKey corresponds to a specific set, we have to try to load it first.
|
||||
qsizetype setIndex = sortedSets.indexOf(card.getPrinting().getSet());
|
||||
if (setIndex > 0) { // we don't need to move the set if it's already first
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "palette_editor_dialog.h"
|
||||
|
||||
#include "../../client/settings/cache_settings.h"
|
||||
#include "../theme_manager.h"
|
||||
#include "palette_generator.h"
|
||||
#include "palette_grid_widget.h"
|
||||
|
|
@ -8,13 +9,33 @@
|
|||
#include <QApplication>
|
||||
#include <QComboBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QFrame>
|
||||
#include <QGuiApplication>
|
||||
#include <QLabel>
|
||||
#include <QLoggingCategory>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QStyleHints>
|
||||
#include <QTimer>
|
||||
#include <libcockatrice/settings/paths_settings.h>
|
||||
|
||||
// Probe whether a directory is truly writable by trying to create and remove a
|
||||
// temporary file. QFileInfo::isWritable() on a directory is unreliable (notably
|
||||
// on Windows where UAC VirtualStore can make a system dir appear writable).
|
||||
static bool isDirReallyWritable(const QString &dirPath)
|
||||
{
|
||||
const QString probe = QDir(dirPath).absoluteFilePath(".cockatrice_write_test");
|
||||
QFile f(probe);
|
||||
if (!f.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
f.close();
|
||||
f.remove();
|
||||
return true;
|
||||
}
|
||||
|
||||
PaletteEditorDialog::PaletteEditorDialog(const QString &_themeDirPath, const QString &_themeName, QWidget *parent)
|
||||
: QDialog(parent), themeDirPath(_themeDirPath), themeName(_themeName)
|
||||
|
|
@ -22,6 +43,18 @@ PaletteEditorDialog::PaletteEditorDialog(const QString &_themeDirPath, const QSt
|
|||
setMinimumSize(740, 220);
|
||||
setupUi();
|
||||
|
||||
// Resolve a writable directory for saving. Built-in (Default / Fusion) and
|
||||
// other read-only theme directories must be customised in the user-writable
|
||||
// themes directory; otherwise the write would fail or be lost on upgrade.
|
||||
if (!themeDirPath.isEmpty() && isDirReallyWritable(themeDirPath)) {
|
||||
saveDir = themeDirPath;
|
||||
} else {
|
||||
saveDir = QDir(SettingsCache::instance().paths().getThemesPath()).absoluteFilePath(themeName);
|
||||
if (!QDir().mkpath(saveDir)) {
|
||||
qWarning() << "Failed to create palette save directory:" << saveDir;
|
||||
}
|
||||
}
|
||||
|
||||
// Load both scheme configs upfront so switching is instant
|
||||
loadSchemes();
|
||||
|
||||
|
|
@ -31,7 +64,9 @@ PaletteEditorDialog::PaletteEditorDialog(const QString &_themeDirPath, const QSt
|
|||
schemeComboBox->setCurrentText(loadedScheme);
|
||||
schemeComboBox->blockSignals(false);
|
||||
|
||||
paletteGrid->blockSignals(true);
|
||||
paletteGrid->loadPalette(workingConfig[loadedScheme]);
|
||||
paletteGrid->blockSignals(false);
|
||||
seedAccentFromScheme(loadedScheme);
|
||||
|
||||
retranslateUi();
|
||||
|
|
@ -124,8 +159,7 @@ void PaletteEditorDialog::setupUi()
|
|||
|
||||
buttonBox = new QDialogButtonBox;
|
||||
resetBtn = buttonBox->addButton(tr("Reset"), QDialogButtonBox::ResetRole);
|
||||
applyBtn = buttonBox->addButton(tr("Apply"), QDialogButtonBox::ApplyRole);
|
||||
saveBtn = buttonBox->addButton(tr("Save && Apply"), QDialogButtonBox::AcceptRole);
|
||||
saveBtn = buttonBox->addButton(tr("Save"), QDialogButtonBox::AcceptRole);
|
||||
closeBtn = buttonBox->addButton(QDialogButtonBox::Close);
|
||||
|
||||
footerLayout->addWidget(revertButton);
|
||||
|
|
@ -135,10 +169,14 @@ void PaletteEditorDialog::setupUi()
|
|||
|
||||
// Connections
|
||||
connect(schemeComboBox, &QComboBox::currentTextChanged, this, &PaletteEditorDialog::onSchemeChanged);
|
||||
connect(quickSetupPanel, &QuickSetupPanel::generateRequested, this, &PaletteEditorDialog::onGenerateFromAccent);
|
||||
autoApplyTimer = new QTimer(this);
|
||||
autoApplyTimer->setSingleShot(true);
|
||||
autoApplyTimer->setInterval(150);
|
||||
connect(autoApplyTimer, &QTimer::timeout, this, &PaletteEditorDialog::onApply);
|
||||
connect(quickSetupPanel, &QuickSetupPanel::valueChanged, this, &PaletteEditorDialog::onGenerateFromAccent);
|
||||
connect(paletteGrid, &PaletteGridWidget::paletteChanged, this, [this] { autoApplyTimer->start(); });
|
||||
connect(revertButton, &QPushButton::clicked, this, &PaletteEditorDialog::onRevertToDefault);
|
||||
connect(resetBtn, &QPushButton::clicked, this, &PaletteEditorDialog::onReset);
|
||||
connect(applyBtn, &QPushButton::clicked, this, &PaletteEditorDialog::onApply);
|
||||
connect(saveBtn, &QPushButton::clicked, this, &PaletteEditorDialog::onSave);
|
||||
connect(closeBtn, &QPushButton::clicked, this, &QDialog::reject);
|
||||
|
||||
|
|
@ -162,15 +200,8 @@ void PaletteEditorDialog::retranslateUi()
|
|||
setWindowTitle(tr("Palette Editor — %1").arg(themeName));
|
||||
titleLabel->setText(tr("<b>Palette Editor</b> · %1").arg(themeName));
|
||||
|
||||
// Revert button only makes sense when the theme ships default palette files
|
||||
const bool hasDefault = PaletteConfig::fromDefault(themeDirPath, "Light").hasPalette() ||
|
||||
PaletteConfig::fromDefault(themeDirPath, "Dark").hasPalette();
|
||||
revertButton->setEnabled(hasDefault);
|
||||
if (!hasDefault) {
|
||||
revertButton->setToolTip(tr("This theme ships no default palette files"));
|
||||
} else {
|
||||
revertButton->setToolTip(tr("Replace current colours with the theme author's defaults"));
|
||||
}
|
||||
revertButton->setToolTip(
|
||||
tr("Delete this scheme's custom palette and revert to the theme default (or the application palette)"));
|
||||
|
||||
schemeComboBox->setToolTip(tr("Switch between the light and dark palette files"));
|
||||
editingLabel->setText(tr("Editing:"));
|
||||
|
|
@ -179,15 +210,13 @@ void PaletteEditorDialog::retranslateUi()
|
|||
revertButton->setText(tr("↺ Revert to theme default"));
|
||||
|
||||
resetBtn->setText(tr("Reset"));
|
||||
applyBtn->setText(tr("Apply"));
|
||||
saveBtn->setText(tr("Save && Apply"));
|
||||
saveBtn->setText(tr("Save"));
|
||||
resetBtn->setToolTip(tr("Discard unsaved edits and restore the last saved palette"));
|
||||
applyBtn->setToolTip(tr("Preview this palette without saving to disk"));
|
||||
saveBtn->setToolTip(tr("Write palette-%1.toml and reload the theme").arg(loadedScheme.toLower()));
|
||||
|
||||
if (themeDirPath.isEmpty()) {
|
||||
if (saveDir.isEmpty() || !isDirReallyWritable(saveDir)) {
|
||||
saveBtn->setEnabled(false);
|
||||
saveBtn->setToolTip(tr("Cannot save: this theme has no directory on disk"));
|
||||
saveBtn->setToolTip(tr("Cannot save: this theme has no writable directory"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -198,7 +227,7 @@ void PaletteEditorDialog::loadSchemes()
|
|||
PaletteConfig cfg = PaletteConfig::fromScheme(themeDirPath, scheme);
|
||||
|
||||
if (!cfg.hasPalette()) {
|
||||
cfg = PaletteConfig::fromDefault(themeDirPath, scheme);
|
||||
cfg = ThemeManager::loadDefaultPaletteConfig(themeDirPath, themeName, scheme);
|
||||
}
|
||||
|
||||
if (!cfg.hasPalette()) {
|
||||
|
|
@ -235,7 +264,6 @@ void PaletteEditorDialog::onSchemeChanged(const QString &scheme)
|
|||
loadedScheme = scheme;
|
||||
paletteGrid->loadPalette(workingConfig.value(scheme));
|
||||
seedAccentFromScheme(scheme);
|
||||
onApply();
|
||||
}
|
||||
|
||||
void PaletteEditorDialog::onGenerateFromAccent(const QColor &accent, int intensity)
|
||||
|
|
@ -256,20 +284,34 @@ void PaletteEditorDialog::onSave()
|
|||
return;
|
||||
}
|
||||
|
||||
PaletteConfig cfg = paletteGrid->currentPaletteConfig();
|
||||
// Snapshot the currently displayed scheme so unsaved edits are not lost.
|
||||
workingConfig[loadedScheme] = paletteGrid->currentPaletteConfig();
|
||||
|
||||
if (!ThemeManager::savePaletteConfig(themeDirPath, loadedScheme, cfg)) {
|
||||
QMessageBox::warning(this, tr("Save failed"),
|
||||
tr("Could not write %1 to:\n%2").arg(PaletteConfig::fileName(loadedScheme), themeDirPath));
|
||||
return;
|
||||
// Persist every scheme that changed, not just the one on screen. Each scheme
|
||||
// has its own file, so edits to the non-active scheme would otherwise be
|
||||
// silently discarded when the dialog closes.
|
||||
for (auto it = workingConfig.begin(); it != workingConfig.end(); ++it) {
|
||||
const QString &scheme = it.key();
|
||||
if (it.value().colors == savedConfig.value(scheme).colors) {
|
||||
continue; // unchanged — leave the on-disk file alone
|
||||
}
|
||||
|
||||
if (!ThemeManager::savePaletteConfig(saveDir, scheme, it.value())) {
|
||||
QMessageBox::warning(this, tr("Save failed"),
|
||||
tr("Could not write %1 to:\n%2").arg(PaletteConfig::fileName(scheme), saveDir));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ThemeConfig globalCfg = ThemeConfig::fromThemeDir(themeDirPath);
|
||||
globalCfg.colorScheme = loadedScheme;
|
||||
globalCfg.save(themeDirPath);
|
||||
// Keep the saved snapshot in sync so Reset behaves correctly afterwards.
|
||||
for (auto it = workingConfig.begin(); it != workingConfig.end(); ++it) {
|
||||
savedConfig[it.key()] = it.value();
|
||||
}
|
||||
|
||||
ThemeConfig globalCfg = ThemeConfig::fromThemeDir(saveDir);
|
||||
globalCfg.colorScheme = loadedScheme;
|
||||
globalCfg.save(saveDir);
|
||||
|
||||
savedConfig[loadedScheme] = cfg;
|
||||
workingConfig[loadedScheme] = cfg;
|
||||
themeManager->reloadCurrentTheme();
|
||||
accept();
|
||||
}
|
||||
|
|
@ -278,18 +320,40 @@ void PaletteEditorDialog::onReset()
|
|||
{
|
||||
workingConfig[loadedScheme] = savedConfig[loadedScheme];
|
||||
paletteGrid->loadPalette(savedConfig[loadedScheme]);
|
||||
seedAccentFromScheme(loadedScheme);
|
||||
}
|
||||
|
||||
void PaletteEditorDialog::onRevertToDefault()
|
||||
{
|
||||
PaletteConfig def = PaletteConfig::fromDefault(themeDirPath, loadedScheme);
|
||||
// Delete this scheme's custom palette file so the theme falls back to its
|
||||
// default (or, when it ships none, the application palette).
|
||||
// Note: shipped defaults use palette-default-<scheme>.toml so this only
|
||||
// removes user-written custom palette files; the theme author's defaults
|
||||
// are left untouched.
|
||||
QFile::remove(QDir(saveDir).absoluteFilePath(PaletteConfig::fileName(loadedScheme)));
|
||||
|
||||
// Reload the live theme so the revert takes effect immediately.
|
||||
themeManager->reloadCurrentTheme();
|
||||
|
||||
// Reflect the resolved palette (theme default, else current app palette) in
|
||||
// the editor so it no longer shows the deleted custom colours.
|
||||
PaletteConfig def = ThemeManager::loadDefaultPaletteConfig(themeDirPath, themeName, loadedScheme);
|
||||
if (!def.hasPalette()) {
|
||||
QMessageBox::information(this, tr("No default found"),
|
||||
tr("No default palette file found for the \"%1\" scheme.").arg(loadedScheme));
|
||||
return;
|
||||
const QPalette appPal = qApp->palette();
|
||||
for (auto group : {QPalette::Active, QPalette::Disabled, QPalette::Inactive}) {
|
||||
for (int i = 0; i < QPalette::NColorRoles; ++i) {
|
||||
auto role = static_cast<QPalette::ColorRole>(i);
|
||||
if (role != QPalette::NoRole) {
|
||||
def.colors[group][role] = appPal.color(group, role);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
savedConfig[loadedScheme] = def;
|
||||
workingConfig[loadedScheme] = def;
|
||||
paletteGrid->loadPalette(def);
|
||||
seedAccentFromScheme(loadedScheme);
|
||||
}
|
||||
|
||||
void PaletteEditorDialog::changeEvent(QEvent *e)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
#include <QFrame>
|
||||
#include <QMap>
|
||||
|
||||
class QTimer;
|
||||
|
||||
class QLabel;
|
||||
class QComboBox;
|
||||
class QDialogButtonBox;
|
||||
|
|
@ -48,7 +50,6 @@ private:
|
|||
QComboBox *schemeComboBox = nullptr;
|
||||
QDialogButtonBox *buttonBox = nullptr;
|
||||
QPushButton *resetBtn = nullptr;
|
||||
QPushButton *applyBtn = nullptr;
|
||||
QPushButton *saveBtn = nullptr;
|
||||
QPushButton *closeBtn = nullptr;
|
||||
QPushButton *revertButton = nullptr;
|
||||
|
|
@ -57,10 +58,15 @@ private:
|
|||
QString themeDirPath;
|
||||
QString themeName;
|
||||
QString loadedScheme;
|
||||
// Directory writes are directed to; may differ from themeDirPath when the
|
||||
// latter is read-only (e.g. a built-in / system theme directory).
|
||||
QString saveDir;
|
||||
|
||||
QMap<QString, PaletteConfig> workingConfig;
|
||||
QMap<QString, PaletteConfig> savedConfig;
|
||||
|
||||
QTimer *autoApplyTimer = nullptr;
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *e) override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ void PaletteGridWidget::buildGrid(QWidget *host)
|
|||
for (int col = 0; col < 3; ++col) {
|
||||
auto group = ALL_GROUPS[col];
|
||||
auto *btn = new ColorButton(host);
|
||||
connect(btn, &ColorButton::colorChanged, this, [this] { emit paletteChanged(); });
|
||||
colorButtons[group][role] = btn;
|
||||
grid->addWidget(btn, row + 1, col + 1, Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ public:
|
|||
void loadPalette(const PaletteConfig &cfg);
|
||||
PaletteConfig currentPaletteConfig() const;
|
||||
|
||||
signals:
|
||||
void paletteChanged();
|
||||
|
||||
private:
|
||||
void buildGrid(QWidget *host);
|
||||
void changeEvent(QEvent *e);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
#include <QApplication>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QSlider>
|
||||
|
||||
QuickSetupPanel::QuickSetupPanel(QWidget *parent) : QWidget(parent)
|
||||
|
|
@ -41,8 +40,6 @@ QuickSetupPanel::QuickSetupPanel(QWidget *parent) : QWidget(parent)
|
|||
intensityPercentageLabel->setFixedWidth(34);
|
||||
intensityPercentageLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
|
||||
generateButton = new QPushButton(this);
|
||||
|
||||
layout->addWidget(heading);
|
||||
layout->addSpacing(6);
|
||||
layout->addWidget(accentLabel);
|
||||
|
|
@ -54,12 +51,13 @@ QuickSetupPanel::QuickSetupPanel(QWidget *parent) : QWidget(parent)
|
|||
layout->addWidget(labelHigh);
|
||||
layout->addWidget(intensityPercentageLabel);
|
||||
layout->addStretch();
|
||||
layout->addWidget(generateButton);
|
||||
|
||||
connect(intensitySlider, &QSlider::valueChanged, this,
|
||||
[this](int v) { intensityPercentageLabel->setText(tr("%1%").arg(v)); });
|
||||
connect(generateButton, &QPushButton::clicked, this,
|
||||
[this] { emit generateRequested(accentButton->getColor(), intensitySlider->value()); });
|
||||
connect(intensitySlider, &QSlider::valueChanged, this, [this](int v) {
|
||||
intensityPercentageLabel->setText(tr("%1%").arg(v));
|
||||
emit valueChanged(accentButton->getColor(), v);
|
||||
});
|
||||
connect(accentButton, &ColorButton::colorChanged, this,
|
||||
[this](const QColor &c) { emit valueChanged(c, intensitySlider->value()); });
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
|
|
@ -77,10 +75,6 @@ void QuickSetupPanel::retranslateUi()
|
|||
"30–70 Accented — buttons, tooltips, and borders join in\n"
|
||||
"70–100 Full colour — backgrounds, everything"));
|
||||
intensityPercentageLabel->setText(tr("70%"));
|
||||
|
||||
generateButton->setText(tr("Generate ↓"));
|
||||
generateButton->setToolTip(tr("Derive all palette roles from the accent colour above.\n"
|
||||
"Fine-tune individual colours in the grid afterwards."));
|
||||
}
|
||||
|
||||
QColor QuickSetupPanel::accentColor() const
|
||||
|
|
@ -95,5 +89,7 @@ int QuickSetupPanel::intensity() const
|
|||
|
||||
void QuickSetupPanel::setAccentColor(const QColor &c)
|
||||
{
|
||||
accentButton->blockSignals(true);
|
||||
accentButton->setColor(c);
|
||||
}
|
||||
accentButton->blockSignals(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include <QWidget>
|
||||
|
||||
class QPushButton;
|
||||
class QHBoxLayout;
|
||||
class QLabel;
|
||||
class QSlider;
|
||||
|
|
@ -16,12 +15,11 @@ class QSlider;
|
|||
*
|
||||
* The panel contains:
|
||||
* - an accent color picker,
|
||||
* - an intensity slider,
|
||||
* - and a generate button.
|
||||
* - an intensity slider.
|
||||
*
|
||||
* When the user clicks the generate button, the panel emits
|
||||
* generateRequested() with the currently selected accent color
|
||||
* and intensity value.
|
||||
* Whenever either value changes the panel emits valueChanged() with
|
||||
* the current accent colour and intensity, which the parent dialog
|
||||
* uses to auto-apply the generated palette.
|
||||
*
|
||||
* Typically used together with PaletteGenerator::fromAccent()
|
||||
* to quickly generate color schemes from a chosen accent color.
|
||||
|
|
@ -71,12 +69,12 @@ public:
|
|||
|
||||
signals:
|
||||
/**
|
||||
* @brief Emitted when the user requests palette generation.
|
||||
* @brief Emitted whenever the accent colour or intensity changes.
|
||||
*
|
||||
* @param accent The selected accent color.
|
||||
* @param intensity The selected intensity value.
|
||||
* The parent dialog consumes this to auto-apply the generated palette
|
||||
* without requiring an explicit Generate click.
|
||||
*/
|
||||
void generateRequested(QColor accent, int intensity);
|
||||
void valueChanged(QColor accent, int intensity);
|
||||
|
||||
private:
|
||||
QHBoxLayout *layout;
|
||||
|
|
@ -88,7 +86,6 @@ private:
|
|||
QLabel *labelHigh;
|
||||
QSlider *intensitySlider;
|
||||
QLabel *intensityPercentageLabel;
|
||||
QPushButton *generateButton;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_QUICK_SETUP_PANEL_H
|
||||
#endif // COCKATRICE_QUICK_SETUP_PANEL_H
|
||||
|
|
|
|||
|
|
@ -245,14 +245,11 @@ PaletteConfig PaletteConfig::fromDefault(const QString &themeDirPath, const QStr
|
|||
|
||||
bool wantDark = colorScheme.compare("Dark", Qt::CaseInsensitive) == 0;
|
||||
|
||||
PaletteConfig cfg =
|
||||
fromFile(dir.absoluteFilePath(wantDark ? "palette-default-dark.toml" : "palette-default-light.toml"));
|
||||
|
||||
if (!cfg.hasPalette()) {
|
||||
cfg = fromFile(dir.absoluteFilePath(wantDark ? "palette-default-light.toml" : "palette-default-dark.toml"));
|
||||
}
|
||||
|
||||
return cfg;
|
||||
// Only the default file matching the requested scheme is used. Falling back
|
||||
// to the opposite scheme's default would silently apply dark colours to a
|
||||
// "Light" scheme (or vice versa). Callers already fall back to the OS /
|
||||
// application palette when no default palette is available.
|
||||
return fromFile(dir.absoluteFilePath(wantDark ? "palette-default-dark.toml" : "palette-default-light.toml"));
|
||||
}
|
||||
|
||||
QPalette PaletteConfig::apply(QPalette base) const
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <QStyleHints>
|
||||
#include <QWidget>
|
||||
#include <Qt>
|
||||
#include <libcockatrice/settings/paths_settings.h>
|
||||
|
||||
#define NONE_THEME_NAME "Default"
|
||||
#define FUSION_THEME_NAME "Fusion"
|
||||
|
|
@ -96,9 +97,14 @@ ThemeManager::ThemeManager(QObject *parent) : QObject(parent)
|
|||
if (defaultStyleName == "windows11") {
|
||||
defaultStyleName = "windowsvista";
|
||||
}
|
||||
// Capture the untouched application palette before any theme is applied.
|
||||
defaultPalette = qApp->palette();
|
||||
ensureThemeDirectoryExists();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
|
||||
connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, &ThemeManager::themeChangedSlot);
|
||||
connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, [this] {
|
||||
defaultPalette = qApp->palette();
|
||||
themeChangedSlot();
|
||||
});
|
||||
#endif
|
||||
connect(&SettingsCache::instance(), &SettingsCache::themeChanged, this, &ThemeManager::themeChangedSlot);
|
||||
themeChangedSlot();
|
||||
|
|
@ -137,13 +143,27 @@ bool ThemeManager::isBuiltInTheme()
|
|||
return themeName == NONE_THEME_NAME || themeName == FUSION_THEME_NAME;
|
||||
}
|
||||
|
||||
// System (read-only) themes location, relative to the application binary.
|
||||
static QString systemThemesBasePath()
|
||||
{
|
||||
QString base = qApp->applicationDirPath();
|
||||
#ifdef Q_OS_MAC
|
||||
base += "/../Resources/themes";
|
||||
#elif defined(Q_OS_WIN)
|
||||
base += "/themes";
|
||||
#else // linux
|
||||
base += "/../share/cockatrice/themes";
|
||||
#endif
|
||||
return base;
|
||||
}
|
||||
|
||||
QStringMap &ThemeManager::getAvailableThemes()
|
||||
{
|
||||
QDir dir;
|
||||
availableThemes.clear();
|
||||
|
||||
// load themes from user profile dir
|
||||
dir.setPath(SettingsCache::instance().getThemesPath());
|
||||
dir.setPath(SettingsCache::instance().paths().getThemesPath());
|
||||
|
||||
// add default value
|
||||
availableThemes.insert(NONE_THEME_NAME, dir.absoluteFilePath("Default"));
|
||||
|
|
@ -157,15 +177,7 @@ QStringMap &ThemeManager::getAvailableThemes()
|
|||
}
|
||||
|
||||
// load themes from cockatrice system dir
|
||||
dir.setPath(qApp->applicationDirPath() +
|
||||
#ifdef Q_OS_MAC
|
||||
"/../Resources/themes"
|
||||
#elif defined(Q_OS_WIN)
|
||||
"/themes"
|
||||
#else // linux
|
||||
"/../share/cockatrice/themes"
|
||||
#endif
|
||||
);
|
||||
dir.setPath(systemThemesBasePath());
|
||||
|
||||
for (QString themeName : dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name)) {
|
||||
if (!availableThemes.contains(themeName)) {
|
||||
|
|
@ -242,6 +254,20 @@ bool ThemeManager::savePaletteConfig(const QString &themeDirPath, const QString
|
|||
return true;
|
||||
}
|
||||
|
||||
PaletteConfig ThemeManager::loadDefaultPaletteConfig(const QString &themeDirPath,
|
||||
const QString &themeName,
|
||||
const QString &colorScheme)
|
||||
{
|
||||
PaletteConfig cfg = PaletteConfig::fromDefault(themeDirPath, colorScheme);
|
||||
if (!cfg.hasPalette()) {
|
||||
// The shipped default may live in the system theme directory rather
|
||||
// than the resolved (user) theme directory, so built-in themes still
|
||||
// get their curated defaults.
|
||||
cfg = PaletteConfig::fromDefault(QDir(systemThemesBasePath()).absoluteFilePath(themeName), colorScheme);
|
||||
}
|
||||
return cfg;
|
||||
}
|
||||
|
||||
void ThemeManager::setColorScheme(const QString &scheme)
|
||||
{
|
||||
const QString dirPath = getAvailableThemes().value(SettingsCache::instance().getThemeName());
|
||||
|
|
@ -253,6 +279,17 @@ void ThemeManager::setColorScheme(const QString &scheme)
|
|||
reloadCurrentTheme();
|
||||
}
|
||||
|
||||
void ThemeManager::setStyleName(const QString &styleName)
|
||||
{
|
||||
const QString dirPath = getAvailableThemes().value(SettingsCache::instance().getThemeName());
|
||||
ThemeConfig cfg = ThemeConfig::fromThemeDir(dirPath);
|
||||
|
||||
cfg.styleName = styleName;
|
||||
|
||||
cfg.save(dirPath);
|
||||
reloadCurrentTheme();
|
||||
}
|
||||
|
||||
void ThemeManager::reloadCurrentTheme()
|
||||
{
|
||||
themeChangedSlot();
|
||||
|
|
@ -298,7 +335,11 @@ void ThemeManager::applyStyleAndPalette(const QString &themeName,
|
|||
}
|
||||
#endif
|
||||
} else {
|
||||
base = qApp->palette();
|
||||
// Use the pristine startup palette rather than qApp->palette(): the
|
||||
// latter may already carry a previously-applied custom (e.g. dark)
|
||||
// palette, which would otherwise persist when switching to a scheme
|
||||
// that supplies no palette of its own.
|
||||
base = defaultPalette;
|
||||
}
|
||||
|
||||
// Overlay custom palette colours
|
||||
|
|
@ -353,7 +394,7 @@ void ThemeManager::themeChangedSlot()
|
|||
// ── Load palette: custom first, then theme default ────────────────────
|
||||
PaletteConfig palette = PaletteConfig::fromScheme(dirPath, activeScheme);
|
||||
if (!palette.hasPalette()) {
|
||||
palette = PaletteConfig::fromDefault(dirPath, activeScheme);
|
||||
palette = ThemeManager::loadDefaultPaletteConfig(dirPath, themeName, activeScheme);
|
||||
}
|
||||
|
||||
applyStyleAndPalette(themeName, themeCfg, palette, activeScheme);
|
||||
|
|
@ -362,6 +403,16 @@ void ThemeManager::themeChangedSlot()
|
|||
if (!dirPath.isEmpty()) {
|
||||
resources << dir.absolutePath();
|
||||
}
|
||||
|
||||
// When the resolved dir is a user copy (e.g. user/<theme>), also
|
||||
// include the system theme dir as a fallback so shipped assets like
|
||||
// zones/*.png and style.css still resolve for themes that ship only
|
||||
// those files (e.g. Leather, Plasma, Fabric, VelvetMarble).
|
||||
const QString sysPath = QDir(systemThemesBasePath()).absoluteFilePath(themeName);
|
||||
if (sysPath != dirPath && QDir(sysPath).exists()) {
|
||||
resources << sysPath;
|
||||
}
|
||||
|
||||
resources << DEFAULT_RESOURCE_PATHS;
|
||||
|
||||
QDir::setSearchPaths("theme", resources);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@ public:
|
|||
|
||||
private:
|
||||
QString defaultStyleName;
|
||||
// Pristine application palette captured at startup, before any custom theme
|
||||
// palette is applied. Used as the base when a theme supplies no palette, so
|
||||
// switching away from a custom palette restores the original colours.
|
||||
QPalette defaultPalette;
|
||||
QString currentThemePath;
|
||||
std::array<QBrush, Role::MaxRole + 1> brushes;
|
||||
QStringMap availableThemes;
|
||||
|
|
@ -76,7 +80,12 @@ public:
|
|||
// Load/save per-scheme palette colors
|
||||
static PaletteConfig loadPaletteConfig(const QString &themeDirPath, const QString &colorScheme);
|
||||
static bool savePaletteConfig(const QString &themeDirPath, const QString &colorScheme, const PaletteConfig &cfg);
|
||||
// Load the theme's shipped default palette, falling back to the system
|
||||
// theme directory when it is absent from the resolved (user) directory.
|
||||
static PaletteConfig
|
||||
loadDefaultPaletteConfig(const QString &themeDirPath, const QString &themeName, const QString &colorScheme);
|
||||
void setColorScheme(const QString &scheme);
|
||||
void setStyleName(const QString &styleName);
|
||||
|
||||
void reloadCurrentTheme();
|
||||
void previewPalette(const PaletteConfig &cfg, const QString &scheme);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <QRegularExpression>
|
||||
#include <QResizeEvent>
|
||||
#include <QSize>
|
||||
#include <libcockatrice/settings/visual_deck_storage_settings.h>
|
||||
#include <libcockatrice/utility/qt_utils.h>
|
||||
|
||||
ColorIdentityWidget::ColorIdentityWidget(QWidget *parent, const QString &_colorIdentity)
|
||||
|
|
@ -21,7 +22,8 @@ ColorIdentityWidget::ColorIdentityWidget(QWidget *parent, const QString &_colorI
|
|||
|
||||
populateManaSymbolWidgets();
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::visualDeckStorageDrawUnusedColorIdentitiesChanged, this,
|
||||
connect(&SettingsCache::instance().visualDeckStorage(),
|
||||
&VisualDeckStorageSettings::visualDeckStorageDrawUnusedColorIdentitiesChanged, this,
|
||||
&ColorIdentityWidget::toggleUnusedVisibility);
|
||||
}
|
||||
|
||||
|
|
@ -40,7 +42,7 @@ void ColorIdentityWidget::populateManaSymbolWidgets()
|
|||
QtUtils::clearLayoutRec(layout);
|
||||
|
||||
// populate mana symbols
|
||||
if (SettingsCache::instance().getVisualDeckStorageDrawUnusedColorIdentities()) {
|
||||
if (SettingsCache::instance().visualDeckStorage().getVisualDeckStorageDrawUnusedColorIdentities()) {
|
||||
for (const QString symbol : fullColorIdentity) {
|
||||
auto *manaSymbol = new ManaSymbolWidget(this, symbol, symbols.contains(symbol));
|
||||
layout->addWidget(manaSymbol);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "../../../../client/settings/cache_settings.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <libcockatrice/settings/visual_deck_storage_settings.h>
|
||||
|
||||
ManaSymbolWidget::ManaSymbolWidget(QWidget *parent, QString _symbol, bool _isActive, bool _mayBeToggled)
|
||||
: QLabel(parent), symbol(_symbol), isActive(_isActive), mayBeToggled(_mayBeToggled)
|
||||
|
|
@ -16,7 +17,8 @@ ManaSymbolWidget::ManaSymbolWidget(QWidget *parent, QString _symbol, bool _isAct
|
|||
setGraphicsEffect(opacityEffect);
|
||||
updateOpacity();
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::visualDeckStorageUnusedColorIdentitiesOpacityChanged, this,
|
||||
connect(&SettingsCache::instance().visualDeckStorage(),
|
||||
&VisualDeckStorageSettings::visualDeckStorageUnusedColorIdentitiesOpacityChanged, this,
|
||||
&ManaSymbolWidget::updateOpacity);
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +44,11 @@ void ManaSymbolWidget::updateOpacity()
|
|||
opacity = isActive ? 1.0 : 0.5;
|
||||
} else {
|
||||
// It's just for display, they can do whatever they want.
|
||||
opacity = isActive ? 1.0 : SettingsCache::instance().getVisualDeckStorageUnusedColorIdentitiesOpacity() / 100.0;
|
||||
opacity =
|
||||
isActive
|
||||
? 1.0
|
||||
: SettingsCache::instance().visualDeckStorage().getVisualDeckStorageUnusedColorIdentitiesOpacity() /
|
||||
100.0;
|
||||
}
|
||||
opacityEffect->setOpacity(opacity);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/card/relation/card_relation.h>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
|
||||
CardInfoFrameWidget::CardInfoFrameWidget(QWidget *parent)
|
||||
: QTabWidget(parent), viewTransformationButton(nullptr), cardTextOnly(false)
|
||||
|
|
@ -60,7 +61,7 @@ CardInfoFrameWidget::CardInfoFrameWidget(QWidget *parent)
|
|||
tab3Layout->addWidget(splitter);
|
||||
tab3->setLayout(tab3Layout);
|
||||
|
||||
setViewMode(SettingsCache::instance().getCardInfoViewMode());
|
||||
setViewMode(SettingsCache::instance().cardsDisplay().getCardInfoViewMode());
|
||||
}
|
||||
|
||||
void CardInfoFrameWidget::retranslateUi()
|
||||
|
|
@ -127,7 +128,7 @@ void CardInfoFrameWidget::setViewMode(int mode)
|
|||
|
||||
refreshLayout();
|
||||
|
||||
SettingsCache::instance().setCardInfoViewMode(mode);
|
||||
SettingsCache::instance().cardsDisplay().setCardInfoViewMode(mode);
|
||||
}
|
||||
|
||||
static bool hasTransformation(const CardInfo &info)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <QPainterPath>
|
||||
#include <QStylePainter>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
|
||||
/**
|
||||
* @brief Constructs a CardPictureEnlargedWidget.
|
||||
|
|
@ -17,11 +18,12 @@ CardInfoPictureEnlargedWidget::CardInfoPictureEnlargedWidget(QWidget *parent) :
|
|||
setWindowFlags(Qt::ToolTip); // Keeps this widget on top of everything
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::roundCardCornersChanged, this, [this](bool _roundCardCorners) {
|
||||
Q_UNUSED(_roundCardCorners);
|
||||
connect(&SettingsCache::instance().cardsDisplay(), &CardsDisplaySettings::roundCardCornersChanged, this,
|
||||
[this](bool _roundCardCorners) {
|
||||
Q_UNUSED(_roundCardCorners);
|
||||
|
||||
update();
|
||||
});
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -99,7 +101,8 @@ void CardInfoPictureEnlargedWidget::paintEvent(QPaintEvent *event)
|
|||
QPoint topLeft{(width() - scaledLogicalSize.width()) / 2, (height() - scaledLogicalSize.height()) / 2};
|
||||
|
||||
// Rounded corner radius based on logical width
|
||||
qreal radius = SettingsCache::instance().getRoundCardCorners() ? 0.05 * scaledLogicalSize.width() : 0.0;
|
||||
qreal radius =
|
||||
SettingsCache::instance().cardsDisplay().getRoundCardCorners() ? 0.05 * scaledLogicalSize.width() : 0.0;
|
||||
|
||||
QStylePainter painter(this);
|
||||
// Fill the background with transparent color to ensure rounded corners are rendered properly
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <QWidget>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/card/relation/card_relation.h>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
#include <utility>
|
||||
|
||||
static constexpr qreal MTG_CARD_ASPECT_RATIO = 1.396;
|
||||
|
|
@ -66,11 +67,12 @@ CardInfoPictureWidget::CardInfoPictureWidget(QWidget *parent, const bool _hoverT
|
|||
animation->setStartValue(originalPos);
|
||||
animation->setEndValue(originalPos - QPoint(0, ANIMATION_OFFSET));
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::roundCardCornersChanged, this, [this](bool _roundCardCorners) {
|
||||
Q_UNUSED(_roundCardCorners);
|
||||
connect(&SettingsCache::instance().cardsDisplay(), &CardsDisplaySettings::roundCardCornersChanged, this,
|
||||
[this](bool _roundCardCorners) {
|
||||
Q_UNUSED(_roundCardCorners);
|
||||
|
||||
update();
|
||||
});
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -190,7 +192,7 @@ void CardInfoPictureWidget::paintEvent(QPaintEvent *event)
|
|||
}
|
||||
|
||||
QPixmap transformedPixmap = resizedPixmap; // Default pixmap
|
||||
if (SettingsCache::instance().getAutoRotateSidewaysLayoutCards()) {
|
||||
if (SettingsCache::instance().cardsDisplay().getAutoRotateSidewaysLayoutCards()) {
|
||||
if (exactCard.getInfo().getUiAttributes().landscapeOrientation) {
|
||||
// Rotate pixmap 90 degrees to the left
|
||||
QTransform transform;
|
||||
|
|
@ -220,7 +222,9 @@ void CardInfoPictureWidget::paintEvent(QPaintEvent *event)
|
|||
|
||||
// Compute rounded corner radius
|
||||
// Ensure consistent rounding
|
||||
qreal radius = SettingsCache::instance().getRoundCardCorners() ? 0.05 * static_cast<qreal>(targetRect.width()) : 0.;
|
||||
qreal radius = SettingsCache::instance().cardsDisplay().getRoundCardCorners()
|
||||
? 0.05 * static_cast<qreal>(targetRect.width())
|
||||
: 0.;
|
||||
|
||||
// Draw the pixmap with rounded corners
|
||||
QStylePainter painter(this);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <QMouseEvent>
|
||||
#include <QPainterPath>
|
||||
#include <QStylePainter>
|
||||
#include <libcockatrice/settings/visual_deck_storage_settings.h>
|
||||
|
||||
/**
|
||||
* @brief Constructs a CardPictureWithTextOverlay widget.
|
||||
|
|
@ -38,7 +39,8 @@ DeckPreviewCardPictureWidget::DeckPreviewCardPictureWidget(QWidget *parent,
|
|||
singleClickTimer = new QTimer(this);
|
||||
singleClickTimer->setSingleShot(true);
|
||||
connect(singleClickTimer, &QTimer::timeout, this, [this]() { emit imageClicked(lastMouseEvent, this); });
|
||||
connect(&SettingsCache::instance(), &SettingsCache::visualDeckStorageSelectionAnimationChanged, this,
|
||||
connect(&SettingsCache::instance().visualDeckStorage(),
|
||||
&VisualDeckStorageSettings::visualDeckStorageSelectionAnimationChanged, this,
|
||||
&CardInfoPictureWidget::setRaiseOnEnterEnabled);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/card/relation/card_relation.h>
|
||||
#include <libcockatrice/deck_list/tree/inner_deck_list_node.h>
|
||||
#include <libcockatrice/settings/layouts_settings.h>
|
||||
|
||||
static bool canBeCommander(const CardInfo &cardInfo)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "deck_editor_deck_dock_widget.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "deck_list_style_proxy.h"
|
||||
#include "deck_state_manager.h"
|
||||
|
||||
|
|
@ -11,6 +12,8 @@
|
|||
#include <QSplitter>
|
||||
#include <QTextEdit>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
#include <libcockatrice/utility/macros.h>
|
||||
#include <libcockatrice/utility/string_limits.h>
|
||||
|
||||
static int findRestoreIndex(const CardRef &wanted, const QComboBox *combo)
|
||||
|
|
@ -108,18 +111,20 @@ void DeckEditorDeckDockWidget::createDeckDock()
|
|||
|
||||
showBannerCardCheckBox = new QCheckBox();
|
||||
showBannerCardCheckBox->setObjectName("showBannerCardCheckBox");
|
||||
showBannerCardCheckBox->setChecked(SettingsCache::instance().getDeckEditorBannerCardComboBoxVisible());
|
||||
connect(showBannerCardCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(),
|
||||
&SettingsCache::setDeckEditorBannerCardComboBoxVisible);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::deckEditorBannerCardComboBoxVisibleChanged, this,
|
||||
showBannerCardCheckBox->setChecked(
|
||||
SettingsCache::instance().cardsDisplay().getDeckEditorBannerCardComboBoxVisible());
|
||||
connect(showBannerCardCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance().cardsDisplay(),
|
||||
&CardsDisplaySettings::setDeckEditorBannerCardComboBoxVisible);
|
||||
connect(&SettingsCache::instance().cardsDisplay(),
|
||||
&CardsDisplaySettings::deckEditorBannerCardComboBoxVisibleChanged, this,
|
||||
&DeckEditorDeckDockWidget::updateShowBannerCardComboBox);
|
||||
|
||||
showTagsWidgetCheckBox = new QCheckBox();
|
||||
showTagsWidgetCheckBox->setObjectName("showTagsWidgetCheckBox");
|
||||
showTagsWidgetCheckBox->setChecked(SettingsCache::instance().getDeckEditorTagsWidgetVisible());
|
||||
connect(showTagsWidgetCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(),
|
||||
&SettingsCache::setDeckEditorTagsWidgetVisible);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::deckEditorTagsWidgetVisibleChanged, this,
|
||||
showTagsWidgetCheckBox->setChecked(SettingsCache::instance().cardsDisplay().getDeckEditorTagsWidgetVisible());
|
||||
connect(showTagsWidgetCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance().cardsDisplay(),
|
||||
&CardsDisplaySettings::setDeckEditorTagsWidgetVisible);
|
||||
connect(&SettingsCache::instance().cardsDisplay(), &CardsDisplaySettings::deckEditorTagsWidgetVisibleChanged, this,
|
||||
&DeckEditorDeckDockWidget::updateShowTagsWidget);
|
||||
|
||||
quickSettingsWidget->addSettingsWidget(showBannerCardCheckBox);
|
||||
|
|
@ -151,7 +156,7 @@ void DeckEditorDeckDockWidget::createDeckDock()
|
|||
bannerCardLabel = new QLabel();
|
||||
bannerCardLabel->setObjectName("bannerCardLabel");
|
||||
bannerCardLabel->setText(tr("Banner Card"));
|
||||
bannerCardLabel->setHidden(!SettingsCache::instance().getDeckEditorBannerCardComboBoxVisible());
|
||||
bannerCardLabel->setHidden(!SettingsCache::instance().cardsDisplay().getDeckEditorBannerCardComboBoxVisible());
|
||||
bannerCardComboBox = new QComboBox(this);
|
||||
connect(getModel(), &DeckListModel::cardNodesChanged, this, [this]() {
|
||||
// Delay the update to avoid race conditions
|
||||
|
|
@ -162,10 +167,10 @@ void DeckEditorDeckDockWidget::createDeckDock()
|
|||
|
||||
connect(bannerCardComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DeckEditorDeckDockWidget::writeBannerCard);
|
||||
bannerCardComboBox->setHidden(!SettingsCache::instance().getDeckEditorBannerCardComboBoxVisible());
|
||||
bannerCardComboBox->setHidden(!SettingsCache::instance().cardsDisplay().getDeckEditorBannerCardComboBoxVisible());
|
||||
|
||||
deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, {});
|
||||
deckTagsDisplayWidget->setHidden(!SettingsCache::instance().getDeckEditorTagsWidgetVisible());
|
||||
deckTagsDisplayWidget->setHidden(!SettingsCache::instance().cardsDisplay().getDeckEditorTagsWidgetVisible());
|
||||
connect(deckTagsDisplayWidget, &DeckPreviewDeckTagsDisplayWidget::tagsChanged, deckStateManager,
|
||||
&DeckStateManager::setTags);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "deck_editor_filter_dock_widget.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "../../../filters/filter_builder.h"
|
||||
#include "../../../filters/filter_tree_model.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "printing_disabled_info_widget.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
|
||||
DeckEditorPrintingSelectorDockWidget::DeckEditorPrintingSelectorDockWidget(AbstractTabDeckEditor *parent)
|
||||
: QDockWidget(parent), deckEditor(parent)
|
||||
|
|
@ -18,8 +19,9 @@ DeckEditorPrintingSelectorDockWidget::DeckEditorPrintingSelectorDockWidget(Abstr
|
|||
createPrintingSelectorDock();
|
||||
printingDisabledInfoWidget = new PrintingDisabledInfoWidget(this);
|
||||
|
||||
setVisibleWidget(SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference());
|
||||
connect(&SettingsCache::instance(), &SettingsCache::overrideAllCardArtWithPersonalPreferenceChanged, this,
|
||||
setVisibleWidget(SettingsCache::instance().cardsDisplay().getOverrideAllCardArtWithPersonalPreference());
|
||||
connect(&SettingsCache::instance().cardsDisplay(),
|
||||
&CardsDisplaySettings::overrideAllCardArtWithPersonalPreferenceChanged, this,
|
||||
&DeckEditorPrintingSelectorDockWidget::setVisibleWidget);
|
||||
|
||||
retranslateUi();
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <libcockatrice/settings/servers_settings.h>
|
||||
#include <libcockatrice/utility/string_limits.h>
|
||||
|
||||
DlgConnect::DlgConnect(QWidget *parent) : QDialog(parent)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <QSpinBox>
|
||||
#include <libcockatrice/protocol/pb/serverinfo_game.pb.h>
|
||||
#include <libcockatrice/protocol/pending_command.h>
|
||||
#include <libcockatrice/settings/game_settings.h>
|
||||
#include <libcockatrice/utility/string_limits.h>
|
||||
|
||||
void DlgCreateGame::sharedCtor()
|
||||
|
|
@ -49,7 +50,7 @@ void DlgCreateGame::sharedCtor()
|
|||
auto *gameTypeRadioButton = new QRadioButton(gameTypeIterator.value(), this);
|
||||
gameTypeLayout->addWidget(gameTypeRadioButton);
|
||||
gameTypeCheckBoxes.insert(gameTypeIterator.key(), gameTypeRadioButton);
|
||||
bool isChecked = SettingsCache::instance().getGameTypes().contains(gameTypeIterator.value() + ", ");
|
||||
bool isChecked = SettingsCache::instance().game().getGameTypes().contains(gameTypeIterator.value() + ", ");
|
||||
gameTypeCheckBoxes[gameTypeIterator.key()]->setChecked(isChecked);
|
||||
}
|
||||
auto *gameTypeGroupBox = new QGroupBox(tr("Game type"));
|
||||
|
|
@ -154,23 +155,23 @@ DlgCreateGame::DlgCreateGame(TabRoom *_room, const QMap<int, QString> &_gameType
|
|||
{
|
||||
sharedCtor();
|
||||
|
||||
rememberGameSettings->setChecked(SettingsCache::instance().getRememberGameSettings());
|
||||
descriptionEdit->setText(SettingsCache::instance().getGameDescription());
|
||||
maxPlayersEdit->setValue(SettingsCache::instance().getMaxPlayers());
|
||||
rememberGameSettings->setChecked(SettingsCache::instance().game().getRememberGameSettings());
|
||||
descriptionEdit->setText(SettingsCache::instance().game().getGameDescription());
|
||||
maxPlayersEdit->setValue(SettingsCache::instance().game().getMaxPlayers());
|
||||
if (room && room->getUserInfo()->user_level() & ServerInfo_User::IsRegistered) {
|
||||
onlyBuddiesCheckBox->setChecked(SettingsCache::instance().getOnlyBuddies());
|
||||
onlyRegisteredCheckBox->setChecked(SettingsCache::instance().getOnlyRegistered());
|
||||
onlyBuddiesCheckBox->setChecked(SettingsCache::instance().game().getOnlyBuddies());
|
||||
onlyRegisteredCheckBox->setChecked(SettingsCache::instance().game().getOnlyRegistered());
|
||||
} else {
|
||||
onlyBuddiesCheckBox->setEnabled(false);
|
||||
onlyRegisteredCheckBox->setEnabled(false);
|
||||
}
|
||||
spectatorsAllowedCheckBox->setChecked(SettingsCache::instance().getSpectatorsAllowed());
|
||||
spectatorsNeedPasswordCheckBox->setChecked(SettingsCache::instance().getSpectatorsNeedPassword());
|
||||
spectatorsCanTalkCheckBox->setChecked(SettingsCache::instance().getSpectatorsCanTalk());
|
||||
spectatorsSeeEverythingCheckBox->setChecked(SettingsCache::instance().getSpectatorsCanSeeEverything());
|
||||
createGameAsSpectatorCheckBox->setChecked(SettingsCache::instance().getCreateGameAsSpectator());
|
||||
startingLifeTotalEdit->setValue(SettingsCache::instance().getDefaultStartingLifeTotal());
|
||||
shareDecklistsOnLoadCheckBox->setChecked(SettingsCache::instance().getShareDecklistsOnLoad());
|
||||
spectatorsAllowedCheckBox->setChecked(SettingsCache::instance().game().getSpectatorsAllowed());
|
||||
spectatorsNeedPasswordCheckBox->setChecked(SettingsCache::instance().game().getSpectatorsNeedPassword());
|
||||
spectatorsCanTalkCheckBox->setChecked(SettingsCache::instance().game().getSpectatorsCanTalk());
|
||||
spectatorsSeeEverythingCheckBox->setChecked(SettingsCache::instance().game().getSpectatorsCanSeeEverything());
|
||||
createGameAsSpectatorCheckBox->setChecked(SettingsCache::instance().game().getCreateGameAsSpectator());
|
||||
startingLifeTotalEdit->setValue(SettingsCache::instance().game().getDefaultStartingLifeTotal());
|
||||
shareDecklistsOnLoadCheckBox->setChecked(SettingsCache::instance().game().getShareDecklistsOnLoad());
|
||||
|
||||
if (!rememberGameSettings->isChecked()) {
|
||||
actReset();
|
||||
|
|
@ -291,20 +292,20 @@ void DlgCreateGame::actOK()
|
|||
}
|
||||
}
|
||||
|
||||
SettingsCache::instance().setRememberGameSettings(rememberGameSettings->isChecked());
|
||||
SettingsCache::instance().game().setRememberGameSettings(rememberGameSettings->isChecked());
|
||||
if (rememberGameSettings->isChecked()) {
|
||||
SettingsCache::instance().setGameDescription(descriptionEdit->text());
|
||||
SettingsCache::instance().setMaxPlayers(maxPlayersEdit->value());
|
||||
SettingsCache::instance().setOnlyBuddies(onlyBuddiesCheckBox->isChecked());
|
||||
SettingsCache::instance().setOnlyRegistered(onlyRegisteredCheckBox->isChecked());
|
||||
SettingsCache::instance().setSpectatorsAllowed(spectatorsAllowedCheckBox->isChecked());
|
||||
SettingsCache::instance().setSpectatorsNeedPassword(spectatorsNeedPasswordCheckBox->isChecked());
|
||||
SettingsCache::instance().setSpectatorsCanTalk(spectatorsCanTalkCheckBox->isChecked());
|
||||
SettingsCache::instance().setSpectatorsCanSeeEverything(spectatorsSeeEverythingCheckBox->isChecked());
|
||||
SettingsCache::instance().setCreateGameAsSpectator(createGameAsSpectatorCheckBox->isChecked());
|
||||
SettingsCache::instance().setDefaultStartingLifeTotal(startingLifeTotalEdit->value());
|
||||
SettingsCache::instance().setShareDecklistsOnLoad(shareDecklistsOnLoadCheckBox->isChecked());
|
||||
SettingsCache::instance().setGameTypes(_gameTypes);
|
||||
SettingsCache::instance().game().setGameDescription(descriptionEdit->text());
|
||||
SettingsCache::instance().game().setMaxPlayers(maxPlayersEdit->value());
|
||||
SettingsCache::instance().game().setOnlyBuddies(onlyBuddiesCheckBox->isChecked());
|
||||
SettingsCache::instance().game().setOnlyRegistered(onlyRegisteredCheckBox->isChecked());
|
||||
SettingsCache::instance().game().setSpectatorsAllowed(spectatorsAllowedCheckBox->isChecked());
|
||||
SettingsCache::instance().game().setSpectatorsNeedPassword(spectatorsNeedPasswordCheckBox->isChecked());
|
||||
SettingsCache::instance().game().setSpectatorsCanTalk(spectatorsCanTalkCheckBox->isChecked());
|
||||
SettingsCache::instance().game().setSpectatorsCanSeeEverything(spectatorsSeeEverythingCheckBox->isChecked());
|
||||
SettingsCache::instance().game().setCreateGameAsSpectator(createGameAsSpectatorCheckBox->isChecked());
|
||||
SettingsCache::instance().game().setDefaultStartingLifeTotal(startingLifeTotalEdit->value());
|
||||
SettingsCache::instance().game().setShareDecklistsOnLoad(shareDecklistsOnLoadCheckBox->isChecked());
|
||||
SettingsCache::instance().game().setGameTypes(_gameTypes);
|
||||
}
|
||||
PendingCommand *pend = room->prepareRoomCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &DlgCreateGame::checkResponse);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/settings/visual_deck_storage_settings.h>
|
||||
|
||||
DlgDefaultTagsEditor::DlgDefaultTagsEditor(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
|
|
@ -54,7 +55,7 @@ void DlgDefaultTagsEditor::retranslateUi()
|
|||
void DlgDefaultTagsEditor::loadStringList()
|
||||
{
|
||||
listWidget->clear();
|
||||
QStringList tags = SettingsCache::instance().getVisualDeckStorageDefaultTagsList();
|
||||
QStringList tags = SettingsCache::instance().visualDeckStorage().getVisualDeckStorageDefaultTagsList();
|
||||
for (const QString &tag : tags) {
|
||||
auto *item = new QListWidgetItem(); // Create item but don't insert yet
|
||||
|
||||
|
|
@ -147,6 +148,6 @@ void DlgDefaultTagsEditor::confirmChanges()
|
|||
updatedList.append(lineEdit->text());
|
||||
}
|
||||
}
|
||||
SettingsCache::instance().setVisualDeckStorageDefaultTagsList(updatedList);
|
||||
SettingsCache::instance().visualDeckStorage().setVisualDeckStorageDefaultTagsList(updatedList);
|
||||
accept(); // Close dialog and confirm changes
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <libcockatrice/settings/servers_settings.h>
|
||||
#include <libcockatrice/utility/string_limits.h>
|
||||
|
||||
DlgEditPassword::DlgEditPassword(QWidget *parent) : QDialog(parent)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <libcockatrice/settings/servers_settings.h>
|
||||
#include <libcockatrice/utility/string_limits.h>
|
||||
|
||||
DlgForgotPasswordChallenge::DlgForgotPasswordChallenge(QWidget *parent) : QDialog(parent)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <libcockatrice/settings/servers_settings.h>
|
||||
#include <libcockatrice/utility/string_limits.h>
|
||||
|
||||
DlgForgotPasswordRequest::DlgForgotPasswordRequest(QWidget *parent) : QDialog(parent)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <libcockatrice/settings/servers_settings.h>
|
||||
#include <libcockatrice/utility/string_limits.h>
|
||||
|
||||
DlgForgotPasswordReset::DlgForgotPasswordReset(QWidget *parent) : QDialog(parent)
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@
|
|||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
|
||||
#include <libcockatrice/settings/paths_settings.h>
|
||||
#include <libcockatrice/settings/recents_settings.h>
|
||||
DlgLoadDeck::DlgLoadDeck(QWidget *parent) : QFileDialog(parent, tr("Load Deck"))
|
||||
{
|
||||
QString startingDir = SettingsCache::instance().recents().getLatestDeckDirPath();
|
||||
if (startingDir.isEmpty()) {
|
||||
startingDir = SettingsCache::instance().getDeckPath();
|
||||
startingDir = SettingsCache::instance().paths().getDeckPath();
|
||||
}
|
||||
|
||||
setDirectory(startingDir);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "dlg_load_deck_from_clipboard.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "../../deck_loader/card_node_function.h"
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "dlg_settings.h"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <QLabel>
|
||||
#include <QSpinBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/settings/game_settings.h>
|
||||
|
||||
DlgLocalGameOptions::DlgLocalGameOptions(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
|
|
@ -53,10 +54,10 @@ DlgLocalGameOptions::DlgLocalGameOptions(QWidget *parent) : QDialog(parent)
|
|||
mainLayout->addWidget(buttonBox);
|
||||
setLayout(mainLayout);
|
||||
|
||||
rememberSettingsCheckBox->setChecked(SettingsCache::instance().getLocalGameRememberSettings());
|
||||
rememberSettingsCheckBox->setChecked(SettingsCache::instance().game().getLocalGameRememberSettings());
|
||||
if (rememberSettingsCheckBox->isChecked()) {
|
||||
numberPlayersEdit->setValue(SettingsCache::instance().getLocalGameMaxPlayers());
|
||||
startingLifeTotalEdit->setValue(SettingsCache::instance().getLocalGameStartingLifeTotal());
|
||||
numberPlayersEdit->setValue(SettingsCache::instance().game().getLocalGameMaxPlayers());
|
||||
startingLifeTotalEdit->setValue(SettingsCache::instance().game().getLocalGameStartingLifeTotal());
|
||||
}
|
||||
|
||||
setWindowTitle(tr("Local game options"));
|
||||
|
|
@ -67,10 +68,10 @@ DlgLocalGameOptions::DlgLocalGameOptions(QWidget *parent) : QDialog(parent)
|
|||
|
||||
void DlgLocalGameOptions::actOK()
|
||||
{
|
||||
SettingsCache::instance().setLocalGameRememberSettings(rememberSettingsCheckBox->isChecked());
|
||||
SettingsCache::instance().game().setLocalGameRememberSettings(rememberSettingsCheckBox->isChecked());
|
||||
if (rememberSettingsCheckBox->isChecked()) {
|
||||
SettingsCache::instance().setLocalGameMaxPlayers(numberPlayersEdit->value());
|
||||
SettingsCache::instance().setLocalGameStartingLifeTotal(startingLifeTotalEdit->value());
|
||||
SettingsCache::instance().game().setLocalGameMaxPlayers(numberPlayersEdit->value());
|
||||
SettingsCache::instance().game().setLocalGameStartingLifeTotal(startingLifeTotalEdit->value());
|
||||
}
|
||||
|
||||
accept();
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@
|
|||
#include <algorithm>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/models/database/card_set/card_sets_model.h>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
#include <libcockatrice/settings/download_settings.h>
|
||||
#include <libcockatrice/settings/layouts_settings.h>
|
||||
|
||||
WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||
{
|
||||
|
|
@ -153,7 +156,7 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
|||
sortWarning->setLayout(sortWarningLayout);
|
||||
sortWarning->setVisible(false);
|
||||
|
||||
includeRebalancedCards = SettingsCache::instance().getIncludeRebalancedCards();
|
||||
includeRebalancedCards = SettingsCache::instance().cardsDisplay().getIncludeRebalancedCards();
|
||||
QCheckBox *includeRebalancedCardsCheckBox =
|
||||
new QCheckBox(tr("Include cards rebalanced for Alchemy [requires restart]"));
|
||||
includeRebalancedCardsCheckBox->setChecked(includeRebalancedCards);
|
||||
|
|
@ -253,7 +256,7 @@ void WndSets::includeRebalancedCardsChanged(bool _includeRebalancedCards)
|
|||
void WndSets::actSave()
|
||||
{
|
||||
model->save(CardDatabaseManager::getInstance());
|
||||
SettingsCache::instance().setIncludeRebalancedCards(includeRebalancedCards);
|
||||
SettingsCache::instance().cardsDisplay().setIncludeRebalancedCards(includeRebalancedCards);
|
||||
CardPictureLoader::clearPixmapCache();
|
||||
const auto reloadOk1 = QtConcurrent::run([] {
|
||||
CardDatabaseManager::getInstance()->reloadCardDatabasesAndNotify();
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <libcockatrice/settings/servers_settings.h>
|
||||
#include <libcockatrice/utility/string_limits.h>
|
||||
|
||||
DlgRegister::DlgRegister(QWidget *parent) : QDialog(parent)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
#include <QScrollBar>
|
||||
#include <QStackedWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/settings/paths_settings.h>
|
||||
#include <libcockatrice/settings/personal_settings.h>
|
||||
|
||||
static QScrollArea *makeScrollable(QWidget *widget)
|
||||
{
|
||||
|
|
@ -43,7 +45,7 @@ DlgSettings::DlgSettings(QWidget *parent) : QDialog(parent)
|
|||
auto rec = QGuiApplication::primaryScreen()->availableGeometry();
|
||||
this->setMinimumSize(qMin(700, rec.width()), qMin(700, rec.height()));
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::langChanged, this, &DlgSettings::updateLanguage);
|
||||
connect(&SettingsCache::instance().personal(), &PersonalSettings::langChanged, this, &DlgSettings::updateLanguage);
|
||||
|
||||
contentsWidget = new QListWidget;
|
||||
contentsWidget->setViewMode(QListView::IconMode);
|
||||
|
|
@ -79,7 +81,7 @@ DlgSettings::DlgSettings(QWidget *parent) : QDialog(parent)
|
|||
mainLayout->addWidget(buttonBox);
|
||||
setLayout(mainLayout);
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::langChanged, this, &DlgSettings::retranslateUi);
|
||||
connect(&SettingsCache::instance().personal(), &PersonalSettings::langChanged, this, &DlgSettings::retranslateUi);
|
||||
retranslateUi();
|
||||
|
||||
adjustSize();
|
||||
|
|
@ -205,7 +207,8 @@ void DlgSettings::closeEvent(QCloseEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
if (!QDir(SettingsCache::instance().getDeckPath()).exists() || SettingsCache::instance().getDeckPath().isEmpty()) {
|
||||
if (!QDir(SettingsCache::instance().paths().getDeckPath()).exists() ||
|
||||
SettingsCache::instance().paths().getDeckPath().isEmpty()) {
|
||||
//! \todo Prompt to create the deck directory.
|
||||
if (QMessageBox::critical(
|
||||
this, tr("Error"),
|
||||
|
|
@ -216,7 +219,8 @@ void DlgSettings::closeEvent(QCloseEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
if (!QDir(SettingsCache::instance().getPicsPath()).exists() || SettingsCache::instance().getPicsPath().isEmpty()) {
|
||||
if (!QDir(SettingsCache::instance().paths().getPicsPath()).exists() ||
|
||||
SettingsCache::instance().paths().getPicsPath().isEmpty()) {
|
||||
//! \todo Prompt to create the pictures directory.
|
||||
if (QMessageBox::critical(this, tr("Error"),
|
||||
tr("The path to your card pictures directory is invalid. Would you like to go back "
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "../../../client/settings/cache_settings.h"
|
||||
|
||||
#include <QDate>
|
||||
#include <libcockatrice/settings/updates_settings.h>
|
||||
|
||||
DlgStartupCardCheck::DlgStartupCardCheck(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
|
|
@ -10,7 +11,7 @@ DlgStartupCardCheck::DlgStartupCardCheck(QWidget *parent) : QDialog(parent)
|
|||
|
||||
layout = new QVBoxLayout(this);
|
||||
|
||||
QDate lastCheckDate = SettingsCache::instance().getLastCardUpdateCheck();
|
||||
QDate lastCheckDate = SettingsCache::instance().updates().getLastCardUpdateCheck();
|
||||
int daysAgo = lastCheckDate.daysTo(QDate::currentDate());
|
||||
|
||||
instructionLabel = new QLabel(
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <libcockatrice/settings/personal_settings.h>
|
||||
|
||||
#define MIN_TIP_IMAGE_HEIGHT 200
|
||||
#define MIN_TIP_IMAGE_WIDTH 200
|
||||
|
|
@ -41,7 +42,7 @@ DlgTipOfTheDay::DlgTipOfTheDay(QWidget *parent) : QDialog(parent)
|
|||
tipNumber = new QLabel();
|
||||
tipNumber->setAlignment(Qt::AlignCenter);
|
||||
|
||||
QList<int> seenTips = SettingsCache::instance().getSeenTips();
|
||||
QList<int> seenTips = SettingsCache::instance().personal().getSeenTips();
|
||||
newTipsAvailable = false;
|
||||
currentTip = 0;
|
||||
for (int i = 0; i < tipDatabase->rowCount(); i++) {
|
||||
|
|
@ -73,9 +74,9 @@ DlgTipOfTheDay::DlgTipOfTheDay(QWidget *parent) : QDialog(parent)
|
|||
connect(previousButton, &QPushButton::clicked, this, &DlgTipOfTheDay::previousClicked);
|
||||
|
||||
showTipsOnStartupCheck = new QCheckBox("Show tips on startup");
|
||||
showTipsOnStartupCheck->setChecked(SettingsCache::instance().getShowTipsOnStartup());
|
||||
connect(showTipsOnStartupCheck, &QCheckBox::clicked, &SettingsCache::instance(),
|
||||
&SettingsCache::setShowTipsOnStartup);
|
||||
showTipsOnStartupCheck->setChecked(SettingsCache::instance().personal().getShowTipsOnStartup());
|
||||
connect(showTipsOnStartupCheck, &QCheckBox::clicked, &SettingsCache::instance().personal(),
|
||||
&PersonalSettings::setShowTipsOnStartup);
|
||||
buttonBar = new QHBoxLayout();
|
||||
buttonBar->addWidget(showTipsOnStartupCheck);
|
||||
buttonBar->addWidget(tipNumber);
|
||||
|
|
@ -130,10 +131,10 @@ void DlgTipOfTheDay::updateTip(int tipId)
|
|||
}
|
||||
|
||||
// Store tip id as seen
|
||||
QList<int> seenTips = SettingsCache::instance().getSeenTips();
|
||||
QList<int> seenTips = SettingsCache::instance().personal().getSeenTips();
|
||||
if (!seenTips.contains(tipId)) {
|
||||
seenTips.append(tipId);
|
||||
SettingsCache::instance().setSeenTips(seenTips);
|
||||
SettingsCache::instance().personal().setSeenTips(seenTips);
|
||||
}
|
||||
|
||||
TipOfTheDay tip = tipDatabase->getTip(tipId);
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@
|
|||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../logger.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpression>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/settings/servers_settings.h>
|
||||
|
||||
DlgViewLog::DlgViewLog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "../../card_picture_loader/card_picture_loader.h"
|
||||
#include "../../client/settings/cache_settings.h"
|
||||
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
bool OverridePrintingWarning::execMessageBox(QWidget *parent, bool enable)
|
||||
{
|
||||
QString message;
|
||||
|
|
@ -27,7 +28,7 @@ bool OverridePrintingWarning::execMessageBox(QWidget *parent, bool enable)
|
|||
QMessageBox::question(parent, QObject::tr("Confirm Change"), message, QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (result == QMessageBox::Yes) {
|
||||
SettingsCache::instance().setOverrideAllCardArtWithPersonalPreference(static_cast<Qt::CheckState>(enable));
|
||||
SettingsCache::instance().cardsDisplay().setOverrideAllCardArtWithPersonalPreference(enable);
|
||||
// Caches are now invalid.
|
||||
CardPictureLoader::clearPixmapCache();
|
||||
CardPictureLoader::clearNetworkCache();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/network/client/remote/remote_client.h>
|
||||
#include <libcockatrice/settings/paths_settings.h>
|
||||
#include <libcockatrice/settings/personal_settings.h>
|
||||
|
||||
HomeWidget::HomeWidget(QWidget *parent, TabSupervisor *_tabSupervisor)
|
||||
: QWidget(parent), tabSupervisor(_tabSupervisor), background("theme:backgrounds/home"), overlay("theme:cockatrice")
|
||||
|
|
@ -41,12 +43,13 @@ HomeWidget::HomeWidget(QWidget *parent, TabSupervisor *_tabSupervisor)
|
|||
updateConnectButton(tabSupervisor->getClient()->getStatus());
|
||||
|
||||
connect(tabSupervisor->getClient(), &RemoteClient::statusChanged, this, &HomeWidget::updateConnectButton);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::homeTabBackgroundSourceChanged, this,
|
||||
connect(&SettingsCache::instance().personal(), &PersonalSettings::homeTabBackgroundSourceChanged, this,
|
||||
&HomeWidget::initializeBackgroundFromSource);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::homeTabBackgroundShuffleFrequencyChanged, this,
|
||||
connect(&SettingsCache::instance().personal(), &PersonalSettings::homeTabBackgroundShuffleFrequencyChanged, this,
|
||||
&HomeWidget::onBackgroundShuffleFrequencyChanged);
|
||||
// Lambda is cleaner to read than overloading this
|
||||
connect(&SettingsCache::instance(), &SettingsCache::homeTabDisplayCardNameChanged, this, [this] { repaint(); });
|
||||
connect(&SettingsCache::instance().personal(), &PersonalSettings::homeTabDisplayCardNameChanged, this,
|
||||
[this] { repaint(); });
|
||||
connect(&SettingsCache::instance(), &SettingsCache::themeChanged, this,
|
||||
&HomeWidget::initializeBackgroundFromSource);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::themeChanged, this,
|
||||
|
|
@ -61,7 +64,8 @@ void HomeWidget::initializeBackgroundFromSource()
|
|||
return;
|
||||
}
|
||||
|
||||
auto backgroundSourceType = BackgroundSources::fromId(SettingsCache::instance().getHomeTabBackgroundSource());
|
||||
auto backgroundSourceType =
|
||||
BackgroundSources::fromId(SettingsCache::instance().personal().getHomeTabBackgroundSource());
|
||||
|
||||
switch (backgroundSourceType) {
|
||||
case BackgroundSources::Theme:
|
||||
|
|
@ -88,7 +92,7 @@ void HomeWidget::initializeBackgroundFromSource()
|
|||
void HomeWidget::loadBackgroundSourceDeck()
|
||||
{
|
||||
std::optional<LoadedDeck> deckOpt = DeckLoader::loadFromFile(
|
||||
SettingsCache::instance().getDeckPath() + "background.cod", DeckFileFormat::Cockatrice, false);
|
||||
SettingsCache::instance().paths().getDeckPath() + "background.cod", DeckFileFormat::Cockatrice, false);
|
||||
backgroundSourceDeck = deckOpt.has_value() ? deckOpt.value().deckList : DeckList();
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +112,8 @@ void HomeWidget::setRandomCard(ExactCard &newCard)
|
|||
|
||||
void HomeWidget::updateRandomCard()
|
||||
{
|
||||
auto backgroundSourceType = BackgroundSources::fromId(SettingsCache::instance().getHomeTabBackgroundSource());
|
||||
auto backgroundSourceType =
|
||||
BackgroundSources::fromId(SettingsCache::instance().personal().getHomeTabBackgroundSource());
|
||||
|
||||
ExactCard newCard;
|
||||
|
||||
|
|
@ -151,8 +156,8 @@ void HomeWidget::updateRandomCard()
|
|||
void HomeWidget::onBackgroundShuffleFrequencyChanged()
|
||||
{
|
||||
cardChangeTimer->stop();
|
||||
if (SettingsCache::instance().getHomeTabBackgroundShuffleFrequency() > 0) {
|
||||
cardChangeTimer->start(SettingsCache::instance().getHomeTabBackgroundShuffleFrequency() * 1000);
|
||||
if (SettingsCache::instance().personal().getHomeTabBackgroundShuffleFrequency() > 0) {
|
||||
cardChangeTimer->start(SettingsCache::instance().personal().getHomeTabBackgroundShuffleFrequency() * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -260,8 +265,8 @@ void HomeWidget::updateConnectButton(const ClientStatus status)
|
|||
|
||||
QPair<QColor, QColor> HomeWidget::extractDominantColors(const QPixmap &pixmap)
|
||||
{
|
||||
if (themeManager->isBuiltInTheme() &&
|
||||
SettingsCache::instance().getHomeTabBackgroundSource() == BackgroundSources::toId(BackgroundSources::Theme)) {
|
||||
if (themeManager->isBuiltInTheme() && SettingsCache::instance().personal().getHomeTabBackgroundSource() ==
|
||||
BackgroundSources::toId(BackgroundSources::Theme)) {
|
||||
return QPair<QColor, QColor>(QColor::fromRgb(20, 140, 60), QColor::fromRgb(120, 200, 80));
|
||||
}
|
||||
|
||||
|
|
@ -347,7 +352,7 @@ void HomeWidget::paintEvent(QPaintEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
if (!cardName.isEmpty() && SettingsCache::instance().getHomeTabDisplayCardName()) {
|
||||
if (!cardName.isEmpty() && SettingsCache::instance().personal().getHomeTabDisplayCardName()) {
|
||||
QFont font = painter.font();
|
||||
font.setPointSize(14);
|
||||
font.setBold(true);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "../tabs/abstract_tab_deck_editor.h"
|
||||
|
||||
#include <libcockatrice/settings/recents_settings.h>
|
||||
DeckEditorMenu::DeckEditorMenu(AbstractTabDeckEditor *parent) : QMenu(parent), deckEditor(parent)
|
||||
{
|
||||
aNewDeck = new QAction(QString(), this);
|
||||
|
|
|
|||
|
|
@ -9,22 +9,23 @@
|
|||
#include "../../../client/settings/cache_settings.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
|
||||
class TearOffMenu : public QMenu
|
||||
{
|
||||
public:
|
||||
explicit TearOffMenu(const QString &title, QWidget *parent = nullptr) : QMenu(title, parent)
|
||||
{
|
||||
connect(&SettingsCache::instance(), &SettingsCache::useTearOffMenusChanged, this,
|
||||
connect(&SettingsCache::instance().interface(), &InterfaceSettings::useTearOffMenusChanged, this,
|
||||
[this](const bool state) { setTearOffEnabled(state); });
|
||||
setTearOffEnabled(SettingsCache::instance().getUseTearOffMenus());
|
||||
setTearOffEnabled(SettingsCache::instance().interface().getUseTearOffMenus());
|
||||
}
|
||||
|
||||
explicit TearOffMenu(QWidget *parent = nullptr) : QMenu(parent)
|
||||
{
|
||||
connect(&SettingsCache::instance(), &SettingsCache::useTearOffMenusChanged, this,
|
||||
connect(&SettingsCache::instance().interface(), &InterfaceSettings::useTearOffMenusChanged, this,
|
||||
[this](const bool state) { setTearOffEnabled(state); });
|
||||
setTearOffEnabled(SettingsCache::instance().getUseTearOffMenus());
|
||||
setTearOffEnabled(SettingsCache::instance().interface().getUseTearOffMenus());
|
||||
}
|
||||
|
||||
TearOffMenu *addTearOffMenu(const QString &title)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include <QBoxLayout>
|
||||
#include <QScrollBar>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
#include <libcockatrice/utility/macros.h>
|
||||
|
||||
/**
|
||||
* @brief Constructs a PrintingSelector widget to display and manage card printings.
|
||||
|
|
@ -45,16 +47,17 @@ PrintingSelector::PrintingSelector(QWidget *parent, AbstractTabDeckEditor *_deck
|
|||
|
||||
// Create the checkbox for navigation buttons visibility
|
||||
navigationCheckBox = new QCheckBox(this);
|
||||
navigationCheckBox->setChecked(SettingsCache::instance().getPrintingSelectorNavigationButtonsVisible());
|
||||
navigationCheckBox->setChecked(
|
||||
SettingsCache::instance().cardsDisplay().getPrintingSelectorNavigationButtonsVisible());
|
||||
connect(navigationCheckBox, &QCheckBox::QT_STATE_CHANGED, this,
|
||||
&PrintingSelector::toggleVisibilityNavigationButtons);
|
||||
connect(navigationCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(),
|
||||
&SettingsCache::setPrintingSelectorNavigationButtonsVisible);
|
||||
connect(navigationCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance().cardsDisplay(),
|
||||
&CardsDisplaySettings::setPrintingSelectorNavigationButtonsVisible);
|
||||
|
||||
cardSizeWidget =
|
||||
new CardSizeWidget(displayOptionsWidget, flowWidget, SettingsCache::instance().getPrintingSelectorCardSize());
|
||||
connect(cardSizeWidget, &CardSizeWidget::cardSizeSettingUpdated, &SettingsCache::instance(),
|
||||
&SettingsCache::setPrintingSelectorCardSize);
|
||||
cardSizeWidget = new CardSizeWidget(displayOptionsWidget, flowWidget,
|
||||
SettingsCache::instance().cardsDisplay().getPrintingSelectorCardSize());
|
||||
connect(cardSizeWidget, &CardSizeWidget::cardSizeSettingUpdated, &SettingsCache::instance().cardsDisplay(),
|
||||
&CardsDisplaySettings::setPrintingSelectorCardSize);
|
||||
|
||||
displayOptionsWidget->addSettingsWidget(sortToolBar);
|
||||
displayOptionsWidget->addSettingsWidget(navigationCheckBox);
|
||||
|
|
@ -81,7 +84,8 @@ PrintingSelector::PrintingSelector(QWidget *parent, AbstractTabDeckEditor *_deck
|
|||
flowWidget->setVisible(false);
|
||||
|
||||
cardSelectionBar = new PrintingSelectorCardSelectionWidget(this, deckStateManager);
|
||||
cardSelectionBar->setVisible(SettingsCache::instance().getPrintingSelectorNavigationButtonsVisible());
|
||||
cardSelectionBar->setVisible(
|
||||
SettingsCache::instance().cardsDisplay().getPrintingSelectorNavigationButtonsVisible());
|
||||
layout->addWidget(cardSelectionBar);
|
||||
|
||||
// Connect deck model data change signal to update display
|
||||
|
|
@ -98,7 +102,7 @@ void PrintingSelector::retranslateUi()
|
|||
|
||||
void PrintingSelector::printingsInDeckChanged()
|
||||
{
|
||||
if (SettingsCache::instance().getBumpSetsWithCardsInDeckToTop()) {
|
||||
if (SettingsCache::instance().cardsDisplay().getBumpSetsWithCardsInDeckToTop()) {
|
||||
// Delay the update to avoid race conditions
|
||||
QTimer::singleShot(100, this, &PrintingSelector::updateDisplay);
|
||||
}
|
||||
|
|
@ -211,7 +215,7 @@ void PrintingSelector::getAllSetsForCurrentCard()
|
|||
sortToolBar->filterSets(sortedPrintings, searchBar->getSearchText().trimmed().toLower());
|
||||
QList<PrintingInfo> printingsToUse;
|
||||
|
||||
if (SettingsCache::instance().getBumpSetsWithCardsInDeckToTop()) {
|
||||
if (SettingsCache::instance().cardsDisplay().getBumpSetsWithCardsInDeckToTop()) {
|
||||
printingsToUse =
|
||||
sortToolBar->prependPrintingsInDeck(filteredPrintings, selectedCard, deckStateManager->getModel());
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <QtMath>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/card/relation/card_relation.h>
|
||||
#include <libcockatrice/settings/card_override_settings.h>
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
#include "../../../client/settings/cache_settings.h"
|
||||
|
||||
#include <libcockatrice/card/set/card_set_comparator.h>
|
||||
#include <libcockatrice/settings/card_database_settings.h>
|
||||
#include <libcockatrice/settings/card_override_settings.h>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
|
||||
const QString PrintingSelectorCardSortingWidget::SORT_OPTIONS_ALPHABETICAL = tr("Alphabetical");
|
||||
const QString PrintingSelectorCardSortingWidget::SORT_OPTIONS_PREFERENCE = tr("Preference");
|
||||
|
|
@ -26,7 +29,7 @@ PrintingSelectorCardSortingWidget::PrintingSelectorCardSortingWidget(PrintingSel
|
|||
sortOptionsSelector = new QComboBox(this);
|
||||
sortOptionsSelector->setFocusPolicy(Qt::StrongFocus);
|
||||
sortOptionsSelector->addItems(SORT_OPTIONS);
|
||||
sortOptionsSelector->setCurrentIndex(SettingsCache::instance().getPrintingSelectorSortOrder());
|
||||
sortOptionsSelector->setCurrentIndex(SettingsCache::instance().cardsDisplay().getPrintingSelectorSortOrder());
|
||||
connect(sortOptionsSelector, &QComboBox::currentTextChanged, this,
|
||||
&PrintingSelectorCardSortingWidget::updateSortSetting);
|
||||
connect(sortOptionsSelector, &QComboBox::currentTextChanged, parent, &PrintingSelector::updateDisplay);
|
||||
|
|
@ -62,7 +65,7 @@ void PrintingSelectorCardSortingWidget::updateSortOrder()
|
|||
*/
|
||||
void PrintingSelectorCardSortingWidget::updateSortSetting()
|
||||
{
|
||||
SettingsCache::instance().setPrintingSelectorSortOrder(sortOptionsSelector->currentIndex());
|
||||
SettingsCache::instance().cardsDisplay().setPrintingSelectorSortOrder(sortOptionsSelector->currentIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -90,7 +93,7 @@ QList<PrintingInfo> PrintingSelectorCardSortingWidget::sortSets(const SetToPrint
|
|||
}
|
||||
|
||||
if (sortedSets.empty()) {
|
||||
sortedSets << CardSet::newInstance(SettingsCache::instance().cardDatabase(), "", "", "", QDate());
|
||||
sortedSets << CardSet::newInstance(&SettingsCache::instance().cardDatabase(), "", "", "", QDate());
|
||||
}
|
||||
|
||||
if (sortOptionsSelector->currentText() == SORT_OPTIONS_PREFERENCE) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,13 @@ SettingsButtonWidget::SettingsButtonWidget(QWidget *parent)
|
|||
setLayout(layout);
|
||||
}
|
||||
|
||||
SettingsButtonWidget::~SettingsButtonWidget()
|
||||
{
|
||||
// We don't parent the popup because it might lead to better behavior on certain window managers.
|
||||
// So we have to manually delete it
|
||||
popup->deleteLater();
|
||||
}
|
||||
|
||||
void SettingsButtonWidget::addSettingsWidget(QWidget *toAdd) const
|
||||
{
|
||||
popup->addSettingsWidget(toAdd);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ class SettingsButtonWidget : public QWidget
|
|||
|
||||
public:
|
||||
explicit SettingsButtonWidget(QWidget *parent = nullptr);
|
||||
|
||||
~SettingsButtonWidget() override;
|
||||
|
||||
void addSettingsWidget(QWidget *toAdd) const;
|
||||
void removeSettingsWidget(QWidget *toRemove) const;
|
||||
void setButtonIcon(QPixmap iconMap);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
#include "replay_quick_settings_widget.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
#include <libcockatrice/settings/personal_settings.h>
|
||||
|
||||
ReplayQuickSettingsWidget::ReplayQuickSettingsWidget(QWidget *parent) : SettingsButtonWidget(parent)
|
||||
{
|
||||
// fast forward speed
|
||||
fastForwardSpeedBox.setMinimum(1);
|
||||
fastForwardSpeedBox.setMaximum(99.9);
|
||||
fastForwardSpeedBox.setDecimals(1);
|
||||
fastForwardSpeedBox.setValue(SettingsCache::instance().interface().getFastForwardSpeed());
|
||||
connect(&fastForwardSpeedBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this,
|
||||
&ReplayQuickSettingsWidget::actUpdateFastForwardSpeed);
|
||||
|
||||
// putting it all together
|
||||
auto *widget = new QWidget;
|
||||
auto *grid = new QGridLayout(widget);
|
||||
grid->setContentsMargins(0, 0, 0, 0);
|
||||
grid->addWidget(&fastForwardSpeedLabel, 0, 0, 1, 1);
|
||||
grid->addWidget(&fastForwardSpeedBox, 0, 1, 1, 1);
|
||||
|
||||
this->addSettingsWidget(widget);
|
||||
|
||||
connect(&SettingsCache::instance().personal(), &PersonalSettings::langChanged, this,
|
||||
&ReplayQuickSettingsWidget::retranslateUi);
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void ReplayQuickSettingsWidget::retranslateUi()
|
||||
{
|
||||
fastForwardSpeedLabel.setText(tr("Fast forward speed:"));
|
||||
fastForwardSpeedBox.setSuffix("x");
|
||||
}
|
||||
|
||||
void ReplayQuickSettingsWidget::actUpdateFastForwardSpeed(qreal value)
|
||||
{
|
||||
SettingsCache::instance().interface().setFastForwardSpeed(value);
|
||||
emit fastForwardSpeedChanged(value);
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef COCKATRICE_REPLAY_QUICK_SETTINGS_WIDGET_H
|
||||
#define COCKATRICE_REPLAY_QUICK_SETTINGS_WIDGET_H
|
||||
|
||||
#include "../../interface/widgets/quick_settings/settings_button_widget.h"
|
||||
|
||||
#include <QDoubleSpinBox>
|
||||
|
||||
class ReplayQuickSettingsWidget : public SettingsButtonWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ReplayQuickSettingsWidget(QWidget *parent);
|
||||
|
||||
void retranslateUi();
|
||||
|
||||
signals:
|
||||
void fastForwardSpeedChanged(qreal speed);
|
||||
|
||||
private:
|
||||
QLabel fastForwardSpeedLabel;
|
||||
QDoubleSpinBox fastForwardSpeedBox;
|
||||
|
||||
private slots:
|
||||
void actUpdateFastForwardSpeed(qreal value);
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_REPLAY_QUICK_SETTINGS_WIDGET_H
|
||||
|
|
@ -5,12 +5,14 @@
|
|||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QTimer>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
|
||||
ReplayTimelineWidget::ReplayTimelineWidget(QWidget *parent)
|
||||
: QWidget(parent), maxBinValue(1), maxTime(1), timeScaleFactor(1.0), currentVisualTime(0), currentProcessedTime(0),
|
||||
currentEvent(0)
|
||||
{
|
||||
replayTimer = new QTimer(this);
|
||||
replayTimer->setInterval(TIMER_INTERVAL_MS);
|
||||
connect(replayTimer, &QTimer::timeout, this, &ReplayTimelineWidget::replayTimerTimeout);
|
||||
|
||||
rewindBufferingTimer = new QTimer(this);
|
||||
|
|
@ -112,7 +114,7 @@ void ReplayTimelineWidget::handleBackwardsSkip(bool doRewindBuffering)
|
|||
// The rewind only happens once the timer runs out.
|
||||
// If another backwards skip happens, the timer will just get reset instead of rewinding.
|
||||
rewindBufferingTimer->stop();
|
||||
rewindBufferingTimer->start(SettingsCache::instance().getRewindBufferingMs());
|
||||
rewindBufferingTimer->start(SettingsCache::instance().interface().getRewindBufferingMs());
|
||||
} else {
|
||||
// otherwise, process the rewind immediately
|
||||
processRewind();
|
||||
|
|
@ -182,12 +184,13 @@ void ReplayTimelineWidget::processNewEvents(PlaybackMode playbackMode)
|
|||
void ReplayTimelineWidget::setTimeScaleFactor(qreal _timeScaleFactor)
|
||||
{
|
||||
timeScaleFactor = _timeScaleFactor;
|
||||
replayTimer->setInterval(static_cast<int>(TIMER_INTERVAL_MS / timeScaleFactor));
|
||||
int interval = std::max(1, qRound(TIMER_INTERVAL_MS / timeScaleFactor));
|
||||
replayTimer->setInterval(interval);
|
||||
}
|
||||
|
||||
void ReplayTimelineWidget::startReplay()
|
||||
{
|
||||
replayTimer->start(static_cast<int>(TIMER_INTERVAL_MS / timeScaleFactor));
|
||||
replayTimer->start();
|
||||
}
|
||||
|
||||
void ReplayTimelineWidget::stopReplay()
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ private slots:
|
|||
public:
|
||||
static constexpr int SMALL_SKIP_MS = 1000;
|
||||
static constexpr int BIG_SKIP_MS = 10000;
|
||||
static constexpr qreal FAST_FORWARD_SCALE_FACTOR = 10.0;
|
||||
|
||||
explicit ReplayTimelineWidget(QWidget *parent = nullptr);
|
||||
void setTimeline(const QList<int> &_replayTimeline);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
#include "replay_manager.h"
|
||||
#include "replay_widget.h"
|
||||
|
||||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "../interface/widgets/tabs/tab_game.h"
|
||||
#include "replay_quick_settings_widget.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QToolButton>
|
||||
|
||||
ReplayManager::ReplayManager(TabGame *parent, GameReplay *_replay)
|
||||
ReplayWidget::ReplayWidget(TabGame *parent, GameReplay *_replay)
|
||||
: QWidget(parent), game(parent), replay(_replay), replayPlayButton(nullptr), replayFastForwardButton(nullptr),
|
||||
aReplaySkipForward(nullptr), aReplaySkipBackward(nullptr), aReplaySkipForwardBig(nullptr),
|
||||
aReplaySkipBackwardBig(nullptr)
|
||||
|
|
@ -39,9 +41,9 @@ ReplayManager::ReplayManager(TabGame *parent, GameReplay *_replay)
|
|||
// timeline widget
|
||||
timelineWidget = new ReplayTimelineWidget;
|
||||
timelineWidget->setTimeline(replayTimeline);
|
||||
connect(timelineWidget, &ReplayTimelineWidget::processNextEvent, this, &ReplayManager::replayNextEvent);
|
||||
connect(timelineWidget, &ReplayTimelineWidget::replayFinished, this, &ReplayManager::replayFinished);
|
||||
connect(timelineWidget, &ReplayTimelineWidget::rewound, this, &ReplayManager::replayRewind);
|
||||
connect(timelineWidget, &ReplayTimelineWidget::processNextEvent, this, &ReplayWidget::replayNextEvent);
|
||||
connect(timelineWidget, &ReplayTimelineWidget::replayFinished, this, &ReplayWidget::replayFinished);
|
||||
connect(timelineWidget, &ReplayTimelineWidget::rewound, this, &ReplayWidget::replayRewind);
|
||||
|
||||
// timeline skip shortcuts
|
||||
aReplaySkipForward = new QAction(timelineWidget);
|
||||
|
|
@ -72,41 +74,47 @@ ReplayManager::ReplayManager(TabGame *parent, GameReplay *_replay)
|
|||
playButtonIcon.addPixmap(QPixmap("theme:replay/pause"), QIcon::Normal, QIcon::On);
|
||||
replayPlayButton->setIcon(playButtonIcon);
|
||||
replayPlayButton->setCheckable(true);
|
||||
connect(replayPlayButton, &QToolButton::toggled, this, &ReplayManager::replayPlayButtonToggled);
|
||||
connect(replayPlayButton, &QToolButton::toggled, this, &ReplayWidget::replayPlayButtonToggled);
|
||||
|
||||
replayFastForwardButton = new QToolButton;
|
||||
replayFastForwardButton->setIconSize(QSize(32, 32));
|
||||
replayFastForwardButton->setIcon(QPixmap("theme:replay/fastforward"));
|
||||
replayFastForwardButton->setCheckable(true);
|
||||
connect(replayFastForwardButton, &QToolButton::toggled, this, &ReplayManager::replayFastForwardButtonToggled);
|
||||
connect(replayFastForwardButton, &QToolButton::toggled, this, &ReplayWidget::updateTimeScaleFactor);
|
||||
|
||||
settingsWidget = new ReplayQuickSettingsWidget(this);
|
||||
settingsWidget->setFixedSize(QSize(32, 32));
|
||||
connect(settingsWidget, &ReplayQuickSettingsWidget::fastForwardSpeedChanged, this,
|
||||
[this] { updateTimeScaleFactor(replayFastForwardButton->isChecked()); });
|
||||
|
||||
// putting everything together
|
||||
auto replayControlLayout = new QHBoxLayout;
|
||||
replayControlLayout->addWidget(timelineWidget, 10);
|
||||
replayControlLayout->addWidget(replayPlayButton);
|
||||
replayControlLayout->addWidget(replayFastForwardButton);
|
||||
replayControlLayout->addWidget(settingsWidget);
|
||||
|
||||
setObjectName("replayControlWidget");
|
||||
setLayout(replayControlLayout);
|
||||
|
||||
connect(this, &ReplayManager::requestChatAndPhaseReset, game, &TabGame::resetChatAndPhase);
|
||||
connect(this, &ReplayWidget::requestChatAndPhaseReset, game, &TabGame::resetChatAndPhase);
|
||||
|
||||
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||
&ReplayManager::refreshShortcuts);
|
||||
&ReplayWidget::refreshShortcuts);
|
||||
refreshShortcuts();
|
||||
}
|
||||
|
||||
void ReplayManager::replayNextEvent(EventProcessingOptions options)
|
||||
void ReplayWidget::replayNextEvent(EventProcessingOptions options)
|
||||
{
|
||||
emit eventReplayed(replay->event_list(timelineWidget->getCurrentEvent()), options);
|
||||
}
|
||||
|
||||
void ReplayManager::replayFinished()
|
||||
void ReplayWidget::replayFinished()
|
||||
{
|
||||
replayPlayButton->setChecked(false);
|
||||
}
|
||||
|
||||
void ReplayManager::replayPlayButtonToggled(bool checked)
|
||||
void ReplayWidget::replayPlayButtonToggled(bool checked)
|
||||
{
|
||||
if (checked) { // start replay
|
||||
timelineWidget->startReplay();
|
||||
|
|
@ -115,20 +123,21 @@ void ReplayManager::replayPlayButtonToggled(bool checked)
|
|||
}
|
||||
}
|
||||
|
||||
void ReplayManager::replayFastForwardButtonToggled(bool checked)
|
||||
void ReplayWidget::updateTimeScaleFactor(bool isFastForward)
|
||||
{
|
||||
timelineWidget->setTimeScaleFactor(checked ? ReplayTimelineWidget::FAST_FORWARD_SCALE_FACTOR : 1.0);
|
||||
qreal factor = isFastForward ? SettingsCache::instance().interface().getFastForwardSpeed() : 1.0;
|
||||
timelineWidget->setTimeScaleFactor(factor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles everything that needs to be reset when doing a replay rewind.
|
||||
*/
|
||||
void ReplayManager::replayRewind()
|
||||
void ReplayWidget::replayRewind()
|
||||
{
|
||||
emit requestChatAndPhaseReset();
|
||||
}
|
||||
|
||||
void ReplayManager::refreshShortcuts()
|
||||
void ReplayWidget::refreshShortcuts()
|
||||
{
|
||||
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||
if (aReplaySkipForward) {
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
/**
|
||||
* @file replay_manager.h
|
||||
* @file replay_widget.h
|
||||
* @ingroup Core
|
||||
* @ingroup Replay
|
||||
*/
|
||||
//! \todo Document this file.
|
||||
|
||||
#ifndef REPLAY_MANAGER_H
|
||||
#define REPLAY_MANAGER_H
|
||||
#ifndef REPLAY_WIDGET_H
|
||||
#define REPLAY_WIDGET_H
|
||||
|
||||
#include "replay_timeline_widget.h"
|
||||
|
||||
|
|
@ -14,14 +14,19 @@
|
|||
#include <QWidget>
|
||||
#include <libcockatrice/protocol/pb/game_replay.pb.h>
|
||||
|
||||
class ReplayQuickSettingsWidget;
|
||||
class TabGame;
|
||||
|
||||
class ReplayManager : public QWidget
|
||||
/**
|
||||
* @brief The top-level that is put in the replay dock widget.
|
||||
* Contains the replay timeline as well as the buttons.
|
||||
*/
|
||||
class ReplayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ReplayManager(TabGame *parent, GameReplay *replay);
|
||||
ReplayWidget(TabGame *parent, GameReplay *replay);
|
||||
TabGame *game;
|
||||
GameReplay *replay;
|
||||
|
||||
|
|
@ -35,15 +40,16 @@ private:
|
|||
QList<int> replayTimeline;
|
||||
ReplayTimelineWidget *timelineWidget;
|
||||
QToolButton *replayPlayButton, *replayFastForwardButton;
|
||||
ReplayQuickSettingsWidget *settingsWidget;
|
||||
QAction *aReplaySkipForward, *aReplaySkipBackward, *aReplaySkipForwardBig, *aReplaySkipBackwardBig;
|
||||
|
||||
private slots:
|
||||
void replayNextEvent(EventProcessingOptions options);
|
||||
void replayFinished();
|
||||
void replayPlayButtonToggled(bool checked);
|
||||
void replayFastForwardButtonToggled(bool checked);
|
||||
void updateTimeScaleFactor(bool checked);
|
||||
void replayRewind();
|
||||
void refreshShortcuts();
|
||||
};
|
||||
|
||||
#endif // REPLAY_MANAGER_H
|
||||
#endif // REPLAY_WIDGET_H
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
#include <QMouseEvent>
|
||||
#include <QScrollBar>
|
||||
#include <libcockatrice/network/server/remote/user_level.h>
|
||||
#include <libcockatrice/settings/chat_settings.h>
|
||||
|
||||
const QColor DEFAULT_MENTION_COLOR = QColor(194, 31, 47);
|
||||
|
||||
|
|
@ -292,8 +293,8 @@ void ChatView::appendMessage(QString message,
|
|||
}
|
||||
cursor.setCharFormat(defaultFormat);
|
||||
|
||||
bool mentionEnabled = SettingsCache::instance().getChatMention();
|
||||
highlightedWords = SettingsCache::instance().getHighlightWords().split(' ', Qt::SkipEmptyParts);
|
||||
bool mentionEnabled = SettingsCache::instance().chat().getChatMention();
|
||||
highlightedWords = SettingsCache::instance().chat().getHighlightWords().split(' ', Qt::SkipEmptyParts);
|
||||
|
||||
// parse the message
|
||||
while (message.size()) {
|
||||
|
|
@ -395,8 +396,9 @@ void ChatView::checkMention(QTextCursor &cursor, QString &message, const QString
|
|||
// You have received a valid mention!!
|
||||
soundEngine->playSound("chat_mention");
|
||||
mentionFormat.setBackground(QBrush(getCustomMentionColor()));
|
||||
mentionFormat.setForeground(SettingsCache::instance().getChatMentionForeground() ? QBrush(Qt::white)
|
||||
: QBrush(Qt::black));
|
||||
mentionFormat.setForeground(SettingsCache::instance().chat().getChatMentionForeground()
|
||||
? QBrush(Qt::white)
|
||||
: QBrush(Qt::black));
|
||||
cursor.insertText(mention, mentionFormat);
|
||||
message = message.mid(mention.size());
|
||||
showSystemPopup(userName);
|
||||
|
|
@ -417,8 +419,8 @@ void ChatView::checkMention(QTextCursor &cursor, QString &message, const QString
|
|||
// Moderator Sending Global Message
|
||||
soundEngine->playSound("all_mention");
|
||||
mentionFormat.setBackground(QBrush(getCustomMentionColor()));
|
||||
mentionFormat.setForeground(SettingsCache::instance().getChatMentionForeground() ? QBrush(Qt::white)
|
||||
: QBrush(Qt::black));
|
||||
mentionFormat.setForeground(
|
||||
SettingsCache::instance().chat().getChatMentionForeground() ? QBrush(Qt::white) : QBrush(Qt::black));
|
||||
cursor.insertText("@" + fullMentionUpToSpaceOrEnd, mentionFormat);
|
||||
message = message.mid(fullMentionUpToSpaceOrEnd.size() + 1);
|
||||
showSystemPopup(userName);
|
||||
|
|
@ -465,8 +467,8 @@ void ChatView::checkWord(QTextCursor &cursor, QString &message)
|
|||
if (fullWordUpToSpaceOrEnd.compare(word, Qt::CaseInsensitive) == 0) {
|
||||
// You have received a valid mention of custom word!!
|
||||
highlightFormat.setBackground(QBrush(getCustomHighlightColor()));
|
||||
highlightFormat.setForeground(SettingsCache::instance().getChatHighlightForeground() ? QBrush(Qt::white)
|
||||
: QBrush(Qt::black));
|
||||
highlightFormat.setForeground(
|
||||
SettingsCache::instance().chat().getChatHighlightForeground() ? QBrush(Qt::white) : QBrush(Qt::black));
|
||||
cursor.insertText(fullWordUpToSpaceOrEnd, highlightFormat);
|
||||
cursor.insertText(rest, defaultFormat);
|
||||
QApplication::alert(this);
|
||||
|
|
@ -522,20 +524,20 @@ void ChatView::actMessageClicked()
|
|||
void ChatView::showSystemPopup(const QString &userName)
|
||||
{
|
||||
QApplication::alert(this);
|
||||
if (SettingsCache::instance().getShowMentionPopup()) {
|
||||
if (SettingsCache::instance().chat().getShowMentionPopup()) {
|
||||
emit showMentionPopup(userName);
|
||||
}
|
||||
}
|
||||
|
||||
QColor ChatView::getCustomMentionColor()
|
||||
{
|
||||
QColor customColor = QColor::fromString("#" + SettingsCache::instance().getChatMentionColor());
|
||||
QColor customColor = QColor::fromString("#" + SettingsCache::instance().chat().getChatMentionColor());
|
||||
return customColor.isValid() ? customColor : DEFAULT_MENTION_COLOR;
|
||||
}
|
||||
|
||||
QColor ChatView::getCustomHighlightColor()
|
||||
{
|
||||
QColor customColor = QColor::fromString("#" + SettingsCache::instance().getChatMentionColor());
|
||||
QColor customColor = QColor::fromString("#" + SettingsCache::instance().chat().getChatMentionColor());
|
||||
return customColor.isValid() ? customColor : DEFAULT_MENTION_COLOR;
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue