From 75c674e6bbf2713533a611fb010ab661ba1ab134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Br=C3=BCbach=2C=20Lukas?= Date: Sat, 29 Nov 2025 23:37:13 +0100 Subject: [PATCH] More doxys. --- .../widgets/general/display/color_bar.h | 92 +++++++++++++++++- ...chidekt_api_response_deck_display_widget.h | 95 ++++++++++++++++--- ...t_api_response_deck_entry_display_widget.h | 88 ++++++++++++++--- ...pi_response_deck_listings_display_widget.h | 65 ++++++++++++- 4 files changed, 312 insertions(+), 28 deletions(-) diff --git a/cockatrice/src/interface/widgets/general/display/color_bar.h b/cockatrice/src/interface/widgets/general/display/color_bar.h index 252a8ddc1..f61ab6942 100644 --- a/cockatrice/src/interface/widgets/general/display/color_bar.h +++ b/cockatrice/src/interface/widgets/general/display/color_bar.h @@ -6,36 +6,122 @@ #include #include +/** + * @class ColorBar + * @brief A widget for visualizing proportional color distributions as a horizontal bar. + * + * This widget renders a horizontal bar divided into colored segments whose widths reflect + * the relative values associated with each color key in a `QMap`. The class + * is designed as a small, lightweight, and self-contained visualization component suitable + * for representing distributions such as color counts, mana statistics, categorical frequencies, and similar data sets. + * + * Key features: + * - Filled segments for better visual clarity. + * - Deterministic alphabetical ordering of color keys. + * - Optional minimum percentage threshold for filtering out insignificant segments. + * - Mouse-hover tooltips showing each segment’s key, count, and percentage of total. + * + * Default color mappings exist for `"R"`, `"G"`, `"U"`, `"W"`, and `"B"`, using named + * colors, but any string recognized by `QColor` may be used. If an unknown name is provided, + * the segment will fall back to gray. + * + * This component is display-only and does not interpret or mutate domain-level data. + */ class ColorBar : public QWidget { Q_OBJECT public: + /** + * @brief Constructs a ColorBar widget. + * + * @param colors Map of color identifiers to integer counts. + * @param parent Optional parent widget. + */ explicit ColorBar(const QMap &colors, QWidget *parent = nullptr); + /** + * @brief Updates the color distribution map. + * @param colors New color → count mapping. + * + * Triggers an immediate repaint. + */ void setColors(const QMap &colors); + + /** + * @brief Sets a minimum percentage threshold below which segments are not drawn. + * + * @param treshold Percentage from 0 to 100. + * + * Internally converted into a ratio (0.05 = 5%). + */ void setMinPercentThreshold(double treshold) { - minRatioThreshold = treshold / 100.0; // store as ratio + minRatioThreshold = treshold / 100.0; } + + /** + * @brief Returns the recommended minimum size. + */ QSize minimumSizeHint() const override; protected: + /** + * @brief Paints the color distribution bar. + * + * Draws: + * - A rounded border + * - Filled segments for each color + * - Only segments above the minimum ratio threshold + */ void paintEvent(QPaintEvent *event) override; + #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + /** + * @brief Handles mouse hover entering (Qt6 version). + */ void enterEvent(QEnterEvent *event) override; #else + /** + * @brief Handles mouse hover entering (Qt5 version). + */ void enterEvent(QEvent *event) override; #endif + + /** + * @brief Handles mouse hover leaving. + */ void leaveEvent(QEvent *event) override; + + /** + * @brief Handles mouse movement to update contextual tooltips. + */ void mouseMoveEvent(QMouseEvent *event) override; private: + /// Map of color keys to counts used for rendering. QMap colors; - bool isHovered = false; - double minRatioThreshold = 0.0; // 0.05 means 5% + /// True if the mouse is currently inside the widget. + bool isHovered = false; + + /// Minimum ratio a segment must exceed to be drawn. + double minRatioThreshold = 0.0; + + /** + * @brief Converts a color name into a display QColor. + * + * Recognized special keys: `"R", "G", "U", "W", "B"`. + * Other strings are treated as QColor names or fall back to gray. + */ QColor colorFromName(const QString &name) const; + + /** + * @brief Returns tooltip text for a given x-coordinate in the bar. + * + * @param x Horizontal coordinate relative to widget. + * @return Tooltip text or empty string if no segment applies. + */ QString tooltipForPosition(int x) const; }; diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.h index 5aaa32433..3d624d293 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.h @@ -14,42 +14,111 @@ #include #include +/** + * @class ArchidektApiResponseDeckDisplayWidget + * @brief Displays a full deck fetched from an Archidekt API response. + * + * This widget visualizes all cards in a deck retrieved from the Archidekt API. + * It supports: + * - Interactive display options via a VisualDeckDisplayOptionsWidget. + * - Scrollable display of deck zones/cards with DeckCardZoneDisplayWidget. + * - Integration with a CardSizeWidget slider for card scaling. + * - Opening the deck in a deck editor. + * + * The widget internally constructs a DeckListModel from the Archidekt API response, + * then builds zone widgets for each group of cards according to the active group + * criteria. It also responds dynamically to model resets or sorting/grouping changes. + * + * ### Signals + * - `requestNavigation(QString url)` — triggered when navigation to a deck URL is requested. + * - `openInDeckEditor(DeckLoader *loader)` — emitted when the user chooses to open the deck + * in the deck editor. + * + * ### Features + * - Automatically generates DeckCardZoneDisplayWidget instances for each card group. + * - Provides a scrollable layout for decks of arbitrary size. + * - Updates layouts dynamically when resized or when display/group/sort criteria change. + */ class ArchidektApiResponseDeckDisplayWidget : public QWidget { Q_OBJECT signals: + /** + * @brief Emitted when navigation to a deck URL is requested. + * @param url URL of the deck on Archidekt. + */ void requestNavigation(QString url); + + /** + * @brief Emitted when the deck should be opened in the deck editor. + * @param loader Initialized DeckLoader containing the deck data. + */ void openInDeckEditor(DeckLoader *loader); public: + /** + * @brief Constructs a display widget for an Archidekt deck. + * @param parent Parent widget. + * @param response API deck data container. + * @param cardSizeSlider Slider controlling card scaling. + */ explicit ArchidektApiResponseDeckDisplayWidget(QWidget *parent, ArchidektApiResponseDeck response, CardSizeWidget *cardSizeSlider); + + /** + * @brief Updates all UI text for retranslation/localization. + * + * Called when the application language changes. + */ void retranslateUi(); + + /** + * @brief Opens the deck in the deck editor via DeckLoader. + */ void actOpenInDeckEditor(); + + /** + * @brief Clears all dynamically generated card zone display widgets. + */ void clearAllDisplayWidgets(); + + /** + * @brief Handles model reset by clearing and reconstructing display widgets. + */ void decklistModelReset(); + + /** + * @brief Builds DeckCardZoneDisplayWidget instances from the current DeckListModel. + */ void constructZoneWidgetsFromDeckListModel(); private slots: + /** + * @brief Slot triggered when the active group criteria change. + * @param activeGroupCriteria Name of the new grouping criteria. + */ void onGroupCriteriaChange(const QString &activeGroupCriteria); private: - ArchidektApiResponseDeck response; - CardSizeWidget *cardSizeSlider; - QVBoxLayout *layout; - QPushButton *openInEditorButton; - VisualDeckDisplayOptionsWidget *displayOptionsWidget; - QScrollArea *scrollArea; - QWidget *zoneContainer; - QVBoxLayout *zoneContainerLayout; - QWidget *container; - QHash indexToWidgetMap; - QVBoxLayout *containerLayout; - DeckListModel *model; - + ArchidektApiResponseDeck response; ///< API deck data container + CardSizeWidget *cardSizeSlider; ///< Slider for adjusting card sizes + QVBoxLayout *layout; ///< Main vertical layout + QPushButton *openInEditorButton; ///< Button to open deck in editor + VisualDeckDisplayOptionsWidget *displayOptionsWidget; ///< Controls grouping/sorting/display + QScrollArea *scrollArea; ///< Scrollable area for deck zones + QWidget *zoneContainer; ///< Container for deck zones + QVBoxLayout *zoneContainerLayout; ///< Layout for deck zones + QWidget *container; ///< Outer container for scroll area + QHash indexToWidgetMap; ///< Maps model indices to widgets + QVBoxLayout *containerLayout; ///< Layout for container + DeckListModel *model; ///< Deck list model protected slots: + /** + * @brief Updates layout and display on resize. + * @param event Resize event. + */ void resizeEvent(QResizeEvent *event) override; }; diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_entry_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_entry_display_widget.h index 5d36ebe8b..876deec09 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_entry_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_entry_display_widget.h @@ -12,44 +12,110 @@ #include class BackgroundPlateWidget; + +/** + * @class ArchidektApiResponseDeckEntryDisplayWidget + * @brief Displays a single Archidekt deck listing as a preview card with metadata. + * + * This widget renders a deck entry received from an Archidekt API response. It includes: + * - A scaled deck preview image loaded asynchronously via QNetworkAccessManager. + * - Elided deck name in the top-left corner. + * - Deck size, EDH bracket, and view count labels. + * - A color distribution bar summarizing deck colors. + * - Metadata labels including owner, creation date, and last update date. + * + * The widget dynamically scales the preview image and labels according to a linked + * CardSizeWidget slider. Hovering over the widget highlights the background plate, + * and clicking emits a `requestNavigation` signal pointing to the deck URL. + * + * ### Features + * - Asynchronous image loading with fallback to a default placeholder image. + * - Maintains a fixed aspect ratio for the preview image (150:267). + * - Updates text elision dynamically when resized or scaled. + * - Integrates with FlowWidget containers for scrollable deck galleries. + * - Supports Qt5 and Qt6 enterEvent signatures for hover behavior. + * + * ### Signals + * - `requestNavigation(QString url)` — emitted when the widget is clicked to request + * navigation to the deck's Archidekt page. + * + * ### Slots + * - `actRequestNavigationToDeck()` — programmatically triggers navigation. + * - `setScaleFactor(int scale)` — adjusts preview image scaling. + */ class ArchidektApiResponseDeckEntryDisplayWidget : public QWidget { Q_OBJECT signals: + /** + * @brief Emitted when the user requests navigation to this deck. + * @param url Full URL to the Archidekt deck page. + */ void requestNavigation(QString url); public: + /** + * @brief Constructs a deck entry display widget. + * @param parent Parent widget. + * @param response API container holding deck listing data. + * @param imageNetworkManager Shared network manager for fetching preview images. + */ explicit ArchidektApiResponseDeckEntryDisplayWidget(QWidget *parent, ArchidektApiResponseDeckListingContainer response, QNetworkAccessManager *imageNetworkManager); + + /** + * @brief Handles finished network replies for preview images. + * @param reply QNetworkReply containing image data. + * + * Validates that the reply corresponds to this widget and updates the preview image. + */ void onPreviewImageLoadFinished(QNetworkReply *reply); + + /** + * @brief Updates the scaled preview image and adjusts layout accordingly. + */ void updateScaledPreview(); + + /** + * @brief Ensures layout responds correctly on resize events. + * @param event Resize event. + */ void resizeEvent(QResizeEvent *event) override; public slots: + /** + * @brief Emits `requestNavigation` for the deck's URL. + */ void actRequestNavigationToDeck(); + + /** + * @brief Sets a scaling factor (percentage) for the preview image. + * @param scale Scale percentage (100 = normal size). + */ void setScaleFactor(int scale); protected: void mousePressEvent(QMouseEvent *event) override; + #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - void enterEvent(QEnterEvent *event) override; // Qt6 signature + void enterEvent(QEnterEvent *event) override; ///< Qt6 hover enter #else - void enterEvent(QEvent *event) override; // Qt5 signature + void enterEvent(QEvent *event) override; ///< Qt5 hover enter #endif void leaveEvent(QEvent *event) override; private: - QVBoxLayout *layout; - ArchidektApiResponseDeckListingContainer response; - QUrl imageUrl; - QNetworkAccessManager *imageNetworkManager; - ArchidektDeckPreviewImageDisplayWidget *previewWidget; - QLabel *picture; - QPixmap originalPixmap; - int scaleFactor = 100; - BackgroundPlateWidget *backgroundPlateWidget; + QVBoxLayout *layout; ///< Main vertical layout + ArchidektApiResponseDeckListingContainer response; ///< Deck data + QUrl imageUrl; ///< URL of the deck's preview image + QNetworkAccessManager *imageNetworkManager; ///< Shared network manager + ArchidektDeckPreviewImageDisplayWidget *previewWidget; ///< Widget showing the deck preview + QLabel *picture; ///< QLabel displaying the scaled pixmap + QPixmap originalPixmap; ///< Original image for scaling (avoids degradation) + int scaleFactor = 100; ///< Current scaling percentage + BackgroundPlateWidget *backgroundPlateWidget; ///< Plate for metadata labels }; #endif // COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_ENTRY_DISPLAY_WIDGET_H diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_listings_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_listings_display_widget.h index cdd445ed4..f00941239 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_listings_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_listings_display_widget.h @@ -11,24 +11,87 @@ #include #include +/** + * @class ArchidektApiResponseDeckListingsDisplayWidget + * @brief Displays a scrollable horizontal list of Archidekt deck listings with dynamic card sizing. + * + * This widget serves as a container for multiple + * ArchidektApiResponseDeckEntryDisplayWidget instances, each representing one deck listing + * returned from an Archidekt API call. + * + * ### Responsibilities + * - Creates a **FlowWidget** that arranges deck entries horizontally with wrapping. + * - Creates a shared **QNetworkAccessManager** for entry widgets to fetch card thumbnails. + * - Connects a **CardSizeWidget** slider to all deck entries to dynamically rescale their preview cards. + * - Propagates deck-navigation requests (`requestNavigation`) from children to the parent. + * + * ### Layout + * The widget uses a single `QHBoxLayout` containing the `FlowWidget`. + * The FlowWidget automatically manages child flow and scrollbar behavior (horizontal = off, + * vertical = auto), providing an efficient scrollable gallery of deck entries. + * + * ### API Integration + * The constructor consumes an `ArchidektDeckListingApiResponse`, iterates through its + * `results`, and instantiates a child entry widget for each deck. + * + * ### Signals + * - `requestNavigation(QString url)` — emitted whenever a child entry widget requests + * navigation to a deck or related Archidekt page. + * + * ### Performance Notes + * - All entry widgets share a single QNetworkAccessManager instance to reuse connections + * and avoid redundant session creation. + * - `resizeEvent()` forces layout invalidation to ensure the flow layout responds properly + * to container resizing. + */ class ArchidektApiResponseDeckListingsDisplayWidget : public QWidget { Q_OBJECT signals: + /** + * @brief Emitted when a child deck entry requests that the UI navigate to a particular URL. + * @param url The destination URL (typically an Archidekt deck page). + */ void requestNavigation(QString url); public: + /** + * @brief Constructs a widget that displays multiple deck listing previews. + * + * @param parent Parent widget. + * @param response The Archidekt API response containing deck listings. + * @param cardSizeSlider A slider widget used to dynamically resize card previews. + * + * Each deck in `response.results` becomes its own + * ArchidektApiResponseDeckEntryDisplayWidget, added to the FlowWidget. + */ explicit ArchidektApiResponseDeckListingsDisplayWidget(QWidget *parent, ArchidektDeckListingApiResponse response, CardSizeWidget *cardSizeSlider); + + /** + * @brief Ensures FlowWidget layout properly recomputes on resize. + * + * Forces the layout to invalidate and activate itself so that the + * FlowWidget recalculates wrapping and child placement. + * + * @param event Resize event. + */ void resizeEvent(QResizeEvent *event) override; private: + /// Slider controlling the scale of card thumbnails in all deck entry widgets. CardSizeWidget *cardSizeSlider; + + /// Main horizontal layout containing the FlowWidget. QHBoxLayout *layout; + + /// Container providing scrollable multi-row flow layout of deck entries. FlowWidget *flowWidget; + + /// Shared network manager used to download card images for all child entry widgets. QNetworkAccessManager *imageNetworkManager; }; -#endif // COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_LISTINGS_DISPLAY_WIDGET_H +#endif // COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_LISTINGS_DISPLAY_WIDGET_H \ No newline at end of file