start of set completion tracking

This commit is contained in:
sdine
2026-07-22 20:03:54 +02:00
parent c9e6bc2b6b
commit 8a89e79e43
29 changed files with 1337 additions and 78 deletions
+26 -1
View File
@@ -5,18 +5,27 @@
#include "ccm/services/CardPreviewService.hpp"
#include "ccm/services/CollectionService.hpp"
#include "ccm/services/ConfigService.hpp"
#include "ccm/services/DigiBattle99SetCatalogService.hpp"
#include "ccm/services/ImageService.hpp"
#include "ccm/services/SetService.hpp"
#include "ccm/ui/IGameView.hpp"
#include <array>
#include <string>
#include <string_view>
#include <vector>
class wxBitmapButton;
class wxBoxSizer;
class wxNotebook;
class wxSplitterWindow;
class wxTextCtrl;
namespace ccm::ui {
class DigiBattle99CardListPanel;
class DigiBattle99SelectedCardPanel;
class DigiBattle99SetCompletionPanel;
class DigiBattle99GameView final : public IGameView {
public:
@@ -25,13 +34,19 @@ public:
SetService& sets,
ImageService& images,
CardPreviewService& cardPreview,
IGameModule& module);
IGameModule& module,
DigiBattle99SetCatalogService& catalogStore);
[[nodiscard]] Game gameId() const noexcept override { return Game::DigiBattle99; }
[[nodiscard]] std::string displayName() const override { return "Digimon (Digi-Battle)"; }
wxPanel* listPanel(wxWindow* parent) override;
wxPanel* selectedPanel(wxWindow* parent) override;
wxPanel* contentPanel(wxWindow* parent) override;
[[nodiscard]] wxPanel* contentPanelIfCreated() const noexcept override {
return contentPanel_;
}
[[nodiscard]] bool hostsOwnLayout() const noexcept override { return true; }
void refreshCollection() override;
void onAddCard(wxWindow* parentWindow) override;
@@ -47,6 +62,9 @@ public:
private:
void ensureSetsLoaded();
const std::vector<Set>& setsForDialog();
void ensureSingleCardsMounted(wxWindow* splitterParent);
void buildSingleCardsToolbar(wxWindow* parent, wxBoxSizer* pageSizer);
void refreshToolbarIcons(const ThemePalette& palette);
ConfigService& config_;
CollectionService<DigiBattle99Card>& collection_;
@@ -54,9 +72,16 @@ private:
ImageService& images_;
CardPreviewService& cardPreview_;
IGameModule& module_;
DigiBattle99SetCatalogService& catalogStore_;
wxPanel* contentPanel_{nullptr};
wxNotebook* notebook_{nullptr};
wxSplitterWindow* singleSplitter_{nullptr};
DigiBattle99CardListPanel* listPanel_{nullptr};
DigiBattle99SelectedCardPanel* selectedPanel_{nullptr};
DigiBattle99SetCompletionPanel* setCompletionPanel_{nullptr};
std::array<wxBitmapButton*, 3> toolbarButtons_{{nullptr, nullptr, nullptr}};
wxTextCtrl* filterInput_{nullptr};
std::vector<Set> setsCache_;
bool attemptedInitialSetLoad_{false};
};
@@ -0,0 +1,59 @@
#pragma once
// DigiBattle99SetCompletionPanel: Set Completion tab — pack tiles with
// progress bars for sets the user owns ≥1 card of, plus an in-tab checklist
// drill-down (unowned rows greyed). Catalog is offline (set-catalog.json).
#include "ccm/domain/DigiBattle99Card.hpp"
#include "ccm/domain/DigiBattle99SetCatalog.hpp"
#include "ccm/services/DigiBattle99SetCatalogService.hpp"
#include "ccm/ui/Theme.hpp"
#include <wx/panel.h>
#include <string>
#include <vector>
class wxBoxSizer;
class wxListCtrl;
class wxScrolledWindow;
class wxSimplebook;
class wxStaticText;
namespace ccm::ui {
class DigiBattle99SetCompletionPanel : public wxPanel {
public:
DigiBattle99SetCompletionPanel(wxWindow* parent, DigiBattle99SetCatalogService& catalogStore);
void setCollection(std::vector<DigiBattle99Card> cards);
void reloadFromStore();
void applyTheme(const ThemePalette& palette);
private:
void showGridPage();
void showChecklistPage(const std::string& setId, const std::string& setName);
void rebuildGrid();
void rebuildChecklist(const std::string& setId);
void setEmptyMessage(const wxString& message);
void clearGridTiles();
DigiBattle99SetCatalogService& catalogStore_;
DigiBattle99SetCatalog catalog_;
bool catalogLoaded_{false};
std::vector<DigiBattle99Card> collection_;
ThemePalette palette_{};
wxSimplebook* book_{nullptr};
wxPanel* gridPage_{nullptr};
wxScrolledWindow* scroll_{nullptr};
wxBoxSizer* gridSizer_{nullptr};
wxStaticText* emptyLabel_{nullptr};
wxPanel* detailPage_{nullptr};
wxStaticText* detailTitle_{nullptr};
wxListCtrl* checklist_{nullptr};
std::string detailSetId_;
};
} // namespace ccm::ui
+18
View File
@@ -35,6 +35,24 @@ public:
virtual wxPanel* listPanel(wxWindow* parent) = 0;
virtual wxPanel* selectedPanel(wxWindow* parent) = 0;
// When non-null, MainFrame mounts this as the sole content under the
// toolbar instead of the shared selected|list splitter. Digimon uses this
// for its Single Cards / Set Completion notebook. Default: no custom host.
virtual wxPanel* contentPanel(wxWindow* parent) {
(void)parent;
return nullptr;
}
// Non-constructing accessor so MainFrame can hide a previously mounted
// content panel without forcing lazy creation for inactive games.
[[nodiscard]] virtual wxPanel* contentPanelIfCreated() const noexcept {
return nullptr;
}
// Games that own their layout via contentPanel must not have their
// list/selected panels parented onto MainFrame's shared splitter.
[[nodiscard]] virtual bool hostsOwnLayout() const noexcept { return false; }
// Reload the active collection from disk and refresh the panels. The
// selected card is preserved when possible.
virtual void refreshCollection() = 0;
+2
View File
@@ -59,6 +59,8 @@ private:
Game activeGame_{Game::Magic};
wxSplitterWindow* splitter_{nullptr};
wxPanel* contentHost_{nullptr};
wxPanel* toolbarPanel_{nullptr};
wxTextCtrl* filterInput_{nullptr};
wxPanel* menuStrip_{nullptr};
wxStaticText* statusText_{nullptr};