mirror of
https://github.com/sebastiandine/Card-Collection-Manager-3.git
synced 2026-08-28 17:01:02 +00:00
patch: Feature/ygo set selection (#16)
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include <wx/filedlg.h>
|
||||
#include <wx/listbox.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/stattext.h>
|
||||
@@ -146,6 +147,28 @@ protected:
|
||||
return &available[static_cast<std::size_t>(sel)];
|
||||
}
|
||||
|
||||
[[nodiscard]] const std::vector<Set>& availableSets() const noexcept {
|
||||
return preloadedSets_ != nullptr ? *preloadedSets_ : sets_;
|
||||
}
|
||||
|
||||
// Default: combo only. Yu-Gi-Oh! overrides to add set-code entry + toggle.
|
||||
virtual void customizeSetPickerRow(wxBoxSizer& row, wxComboBox* combo) {
|
||||
row.Add(combo, 1, wxEXPAND);
|
||||
}
|
||||
|
||||
// After programmatically changing the set combo + `card_.set` (see
|
||||
// `applySetSelectionByIndex`). Default no-op; Yu-Gi-Oh! clears print-variant cache.
|
||||
virtual void onSetSelectionApplied() {}
|
||||
|
||||
void applySetSelectionByIndex(std::size_t index) {
|
||||
const auto& available = availableSets();
|
||||
if (!setCombo_ || !setCombo_->IsEnabled()) return;
|
||||
if (index >= available.size()) return;
|
||||
setCombo_->SetSelection(static_cast<int>(index));
|
||||
card_.set = available[index];
|
||||
onSetSelectionApplied();
|
||||
}
|
||||
|
||||
private:
|
||||
void readSets() {
|
||||
auto loaded = setService_.getSets(game_);
|
||||
@@ -158,10 +181,6 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] const std::vector<Set>& availableSets() const noexcept {
|
||||
return preloadedSets_ != nullptr ? *preloadedSets_ : sets_;
|
||||
}
|
||||
|
||||
void buildLayout() {
|
||||
auto* root = new wxBoxSizer(wxVERTICAL);
|
||||
auto* grid = new wxFlexGridSizer(2, 6, 8);
|
||||
@@ -174,9 +193,16 @@ private:
|
||||
});
|
||||
appendRow(grid, "Name", nameCtrl_);
|
||||
|
||||
setCombo_ = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0,
|
||||
// `setCombo_` must be parented to `setHost` so every control in the Set row
|
||||
// shares the same `wxPanel`; otherwise the combo stays a direct child of the
|
||||
// dialog while the sizer lives on `setHost`, which corrupts layout on MSW.
|
||||
auto* setHost = new wxPanel(this, wxID_ANY);
|
||||
auto* setRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
setHost->SetSizer(setRow);
|
||||
setCombo_ = new wxComboBox(setHost, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0,
|
||||
nullptr, wxCB_READONLY);
|
||||
appendRow(grid, "Set", setCombo_);
|
||||
customizeSetPickerRow(*setRow, setCombo_);
|
||||
appendRow(grid, "Set", setHost);
|
||||
|
||||
// Subclass extra rows go between Set and Amount (Pokemon adds Set #).
|
||||
appendExtraRows(grid);
|
||||
@@ -237,8 +263,13 @@ private:
|
||||
|
||||
CallAfter([this]() {
|
||||
if (nameCtrl_) {
|
||||
nameCtrl_->SetInsertionPoint(0);
|
||||
nameCtrl_->ShowPosition(0);
|
||||
nameCtrl_->SetFocus();
|
||||
if (mode_ == EditMode::Edit && !nameCtrl_->IsEmpty()) {
|
||||
nameCtrl_->SetInsertionPointEnd();
|
||||
} else {
|
||||
nameCtrl_->SetInsertionPoint(0);
|
||||
nameCtrl_->ShowPosition(0);
|
||||
}
|
||||
}
|
||||
if (noteCtrl_) {
|
||||
noteCtrl_->SetInsertionPoint(0);
|
||||
|
||||
@@ -70,6 +70,10 @@ namespace ccm::ui {
|
||||
// not duplicated per template instantiation.
|
||||
wxDECLARE_EVENT(EVT_CARD_SELECTED, wxCommandEvent);
|
||||
|
||||
// Raised on `wxEVT_LIST_ITEM_ACTIVATED` (double-click / Enter on a row).
|
||||
// `IGameView` implementations bind this to open Edit for `selected()`.
|
||||
wxDECLARE_EVENT(EVT_CARD_ACTIVATED, wxCommandEvent);
|
||||
|
||||
template <typename TCard, typename TSortColumn>
|
||||
class BaseCardListPanel : public wxPanel {
|
||||
public:
|
||||
@@ -238,6 +242,7 @@ protected:
|
||||
|
||||
list_->Bind(wxEVT_LIST_ITEM_SELECTED, &BaseCardListPanel::onSelectionChanged, this);
|
||||
list_->Bind(wxEVT_LIST_ITEM_DESELECTED, &BaseCardListPanel::onSelectionChanged, this);
|
||||
list_->Bind(wxEVT_LIST_ITEM_ACTIVATED, &BaseCardListPanel::onListItemActivated, this);
|
||||
}
|
||||
|
||||
// Forwarded helpers ------------------------------------------------------
|
||||
@@ -642,6 +647,14 @@ private:
|
||||
notifySelectionChanged();
|
||||
}
|
||||
|
||||
void onListItemActivated(wxListEvent& event) {
|
||||
(void)event;
|
||||
if (inRebuild_) return;
|
||||
wxCommandEvent ev(EVT_CARD_ACTIVATED, GetId());
|
||||
ev.SetEventObject(this);
|
||||
ProcessWindowEvent(ev);
|
||||
}
|
||||
|
||||
// ----- members ----------------------------------------------------------
|
||||
|
||||
static constexpr int kFlagIconSize = 14;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
// Tracks when a modal Add/Edit card dialog is on screen so a second one
|
||||
// cannot be stacked (toolbar + list activation, or rare re-entrant cases).
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace ccm::ui {
|
||||
|
||||
// User-visible hint when Add/Edit is requested while a card dialog is already modal.
|
||||
inline constexpr const char* kCardEditModalBlockedUtf8 =
|
||||
"Close the open card dialog (save or cancel) before opening another card.";
|
||||
|
||||
[[nodiscard]] inline std::atomic<int>& cardEditModalDepthRef() noexcept {
|
||||
static std::atomic<int> depth{0};
|
||||
return depth;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool cardEditModalIsActive() noexcept {
|
||||
return cardEditModalDepthRef().load(std::memory_order_relaxed) > 0;
|
||||
}
|
||||
|
||||
struct CardEditModalGuard {
|
||||
CardEditModalGuard() {
|
||||
cardEditModalDepthRef().fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
~CardEditModalGuard() {
|
||||
cardEditModalDepthRef().fetch_sub(1, std::memory_order_relaxed);
|
||||
}
|
||||
CardEditModalGuard(const CardEditModalGuard&) = delete;
|
||||
CardEditModalGuard& operator=(const CardEditModalGuard&) = delete;
|
||||
};
|
||||
|
||||
} // namespace ccm::ui
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <wx/event.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
namespace ccm::ui {
|
||||
|
||||
wxDECLARE_EVENT(EVT_CCM_SWITCH, wxCommandEvent);
|
||||
|
||||
// Small on/off switch (pill track + thumb) for modal dialogs. Fires `EVT_CCM_SWITCH`
|
||||
// when the user toggles; bind with the control pointer as the event source.
|
||||
class SwitchCtrl final : public wxWindow {
|
||||
public:
|
||||
explicit SwitchCtrl(wxWindow* parent, wxWindowID id = wxID_ANY, bool initialOn = false);
|
||||
|
||||
[[nodiscard]] bool GetValue() const noexcept { return on_; }
|
||||
void SetValue(bool on, bool notify = false);
|
||||
|
||||
bool Enable(bool enable = true) override;
|
||||
|
||||
private:
|
||||
void onPaint(wxPaintEvent&);
|
||||
void onLeftDown(wxMouseEvent&);
|
||||
void onEnter(wxMouseEvent&);
|
||||
void onLeave(wxMouseEvent&);
|
||||
|
||||
bool on_{false};
|
||||
bool hovered_{false};
|
||||
};
|
||||
|
||||
} // namespace ccm::ui
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "ccm/ports/ICardPreviewSource.hpp"
|
||||
#include "ccm/services/CardPreviewService.hpp"
|
||||
#include "ccm/ui/BaseCardEditDialog.hpp"
|
||||
#include "ccm/ui/SwitchCtrl.hpp"
|
||||
#include <wx/button.h>
|
||||
#include <wx/stattext.h>
|
||||
|
||||
@@ -21,11 +22,13 @@ public:
|
||||
|
||||
protected:
|
||||
void buildFlagsRow(wxBoxSizer* flagsBox) override;
|
||||
void customizeSetPickerRow(wxBoxSizer& row, wxComboBox* combo) override;
|
||||
void appendExtraRows(wxFlexGridSizer* grid) override;
|
||||
void readExtraFromCard() override;
|
||||
void writeExtraToCard() override;
|
||||
[[nodiscard]] std::string updateMenuName() const override { return "Update Yu-Gi-Oh!"; }
|
||||
void onCardLookupContextChanged() override;
|
||||
void onSetSelectionApplied() override;
|
||||
|
||||
private:
|
||||
void onAutoDetectSetNo(wxCommandEvent&);
|
||||
@@ -34,6 +37,10 @@ private:
|
||||
void onNextRarity(wxCommandEvent&);
|
||||
void onSetNoTextChanged(wxCommandEvent&);
|
||||
void onSetSelectionChanged(wxCommandEvent&);
|
||||
void handleSetSelectionChanged();
|
||||
void onSetRowSwitch(wxCommandEvent&);
|
||||
void onSetCodeAutoDetect(wxCommandEvent&);
|
||||
void syncSetModeHint();
|
||||
void autoDetectFromApi(bool fillSetNo, bool fillRarity);
|
||||
void refreshSetNoFullPreview();
|
||||
void clearCachedPrintVariants();
|
||||
@@ -63,6 +70,12 @@ private:
|
||||
wxCheckBox* signedCheck_{nullptr};
|
||||
wxCheckBox* alteredCheck_{nullptr};
|
||||
|
||||
wxPanel* setCodeRowPanel_{nullptr};
|
||||
wxTextCtrl* setCodeText_{nullptr};
|
||||
wxButton* setCodeAutoBtn_{nullptr};
|
||||
wxStaticText* setModeHint_{nullptr};
|
||||
SwitchCtrl* setPickerSwitch_{nullptr};
|
||||
|
||||
std::vector<AutoDetectedPrint> cachedVariants_;
|
||||
std::vector<std::string> uniqueSetCodes_;
|
||||
std::vector<std::string> raritiesForCurrentSetCode_;
|
||||
|
||||
Reference in New Issue
Block a user