More doxys.

This commit is contained in:
Brübach, Lukas 2025-11-29 23:37:13 +01:00
parent 61c7d2a05f
commit 75c674e6bb
4 changed files with 312 additions and 28 deletions

View file

@ -6,36 +6,122 @@
#include <QString>
#include <QWidget>
/**
* @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<QString, int>`. 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 segments 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<QString, int> &colors, QWidget *parent = nullptr);
/**
* @brief Updates the color distribution map.
* @param colors New color count mapping.
*
* Triggers an immediate repaint.
*/
void setColors(const QMap<QString, int> &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<QString, int> 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;
};

View file

@ -14,42 +14,111 @@
#include <QVBoxLayout>
#include <QWidget>
/**
* @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<QPersistentModelIndex, QWidget *> 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<QPersistentModelIndex, QWidget *> 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;
};

View file

@ -12,44 +12,110 @@
#include <QWidget>
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

View file

@ -11,24 +11,87 @@
#include <QVBoxLayout>
#include <QWidget>
/**
* @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