mirror of
https://github.com/sebastiandine/Card-Collection-Manager-3.git
synced 2026-09-04 09:13:27 +00:00
patch: Feature/ygo set selection (#16)
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
// declared in the corresponding base headers (BaseCardListPanel.hpp,
|
||||
// BaseSelectedCardPanel.hpp) and defined exactly once here, so that template
|
||||
// instantiations (Magic, Pokemon, ...) all use the same event type tag.
|
||||
// EVT_CARD_ACTIVATED is declared alongside EVT_CARD_SELECTED in
|
||||
// BaseCardListPanel.hpp.
|
||||
|
||||
#include "ccm/ui/BaseCardListPanel.hpp"
|
||||
#include "ccm/ui/BaseSelectedCardPanel.hpp"
|
||||
@@ -9,6 +11,7 @@
|
||||
namespace ccm::ui {
|
||||
|
||||
wxDEFINE_EVENT(EVT_CARD_SELECTED, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_CARD_ACTIVATED, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_PREVIEW_STATUS, wxCommandEvent);
|
||||
|
||||
} // namespace ccm::ui
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#include "ccm/ui/MagicGameView.hpp"
|
||||
|
||||
#include "ccm/ui/CardEditModalGuard.hpp"
|
||||
#include "ccm/ui/MagicCardEditDialog.hpp"
|
||||
#include "ccm/ui/MagicCardListPanel.hpp"
|
||||
#include "ccm/ui/MagicSelectedCardPanel.hpp"
|
||||
#include "ccm/ui/Theme.hpp"
|
||||
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
@@ -54,6 +56,10 @@ wxPanel* MagicGameView::listPanel(wxWindow* parent) {
|
||||
selectedPanel_->setCard(listPanel_->selected());
|
||||
}
|
||||
});
|
||||
listPanel_->Bind(EVT_CARD_ACTIVATED, [this](wxCommandEvent&) {
|
||||
wxWindow* owner = wxGetTopLevelParent(listPanel_);
|
||||
onEditCard(owner != nullptr ? owner : static_cast<wxWindow*>(listPanel_));
|
||||
});
|
||||
}
|
||||
return listPanel_;
|
||||
}
|
||||
@@ -88,6 +94,11 @@ const std::vector<Set>& MagicGameView::setsForDialog() {
|
||||
}
|
||||
|
||||
void MagicGameView::onAddCard(wxWindow* parentWindow) {
|
||||
if (cardEditModalIsActive()) {
|
||||
showThemedMessageDialog(parentWindow, wxString::FromUTF8(kCardEditModalBlockedUtf8),
|
||||
wxString::FromUTF8("Add card"), wxOK | wxICON_INFORMATION);
|
||||
return;
|
||||
}
|
||||
MagicCard fresh;
|
||||
fresh.amount = 1;
|
||||
fresh.language = Language::English;
|
||||
@@ -96,6 +107,7 @@ void MagicGameView::onAddCard(wxWindow* parentWindow) {
|
||||
MagicCardEditDialog dlg(parentWindow, images_, sets_, EditMode::Create, fresh,
|
||||
&setsForDialog());
|
||||
themeModalDialog(&dlg, config_.current().theme);
|
||||
CardEditModalGuard modalGuard;
|
||||
if (dlg.ShowModal() != wxID_OK) return;
|
||||
|
||||
auto added = collection_.add(Game::Magic, dlg.card());
|
||||
@@ -132,9 +144,15 @@ void MagicGameView::onEditCard(wxWindow* parentWindow) {
|
||||
showThemedMessageDialog(parentWindow, "Select a card first.", "Edit", wxOK | wxICON_INFORMATION);
|
||||
return;
|
||||
}
|
||||
if (cardEditModalIsActive()) {
|
||||
showThemedMessageDialog(parentWindow, wxString::FromUTF8(kCardEditModalBlockedUtf8),
|
||||
wxString::FromUTF8("Edit"), wxOK | wxICON_INFORMATION);
|
||||
return;
|
||||
}
|
||||
MagicCardEditDialog dlg(parentWindow, images_, sets_, EditMode::Edit, *sel,
|
||||
&setsForDialog());
|
||||
themeModalDialog(&dlg, config_.current().theme);
|
||||
CardEditModalGuard modalGuard;
|
||||
if (dlg.ShowModal() != wxID_OK) return;
|
||||
auto updated = collection_.update(Game::Magic, dlg.card());
|
||||
if (!updated) {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#include "ccm/ui/PokemonGameView.hpp"
|
||||
|
||||
#include "ccm/ui/CardEditModalGuard.hpp"
|
||||
#include "ccm/ui/PokemonCardEditDialog.hpp"
|
||||
#include "ccm/ui/PokemonCardListPanel.hpp"
|
||||
#include "ccm/ui/PokemonSelectedCardPanel.hpp"
|
||||
#include "ccm/ui/Theme.hpp"
|
||||
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
@@ -51,6 +53,10 @@ wxPanel* PokemonGameView::listPanel(wxWindow* parent) {
|
||||
selectedPanel_->setCard(listPanel_->selected());
|
||||
}
|
||||
});
|
||||
listPanel_->Bind(EVT_CARD_ACTIVATED, [this](wxCommandEvent&) {
|
||||
wxWindow* owner = wxGetTopLevelParent(listPanel_);
|
||||
onEditCard(owner != nullptr ? owner : static_cast<wxWindow*>(listPanel_));
|
||||
});
|
||||
}
|
||||
return listPanel_;
|
||||
}
|
||||
@@ -85,6 +91,11 @@ const std::vector<Set>& PokemonGameView::setsForDialog() {
|
||||
}
|
||||
|
||||
void PokemonGameView::onAddCard(wxWindow* parentWindow) {
|
||||
if (cardEditModalIsActive()) {
|
||||
showThemedMessageDialog(parentWindow, wxString::FromUTF8(kCardEditModalBlockedUtf8),
|
||||
wxString::FromUTF8("Add card"), wxOK | wxICON_INFORMATION);
|
||||
return;
|
||||
}
|
||||
PokemonCard fresh;
|
||||
fresh.amount = 1;
|
||||
fresh.language = Language::English;
|
||||
@@ -93,6 +104,7 @@ void PokemonGameView::onAddCard(wxWindow* parentWindow) {
|
||||
PokemonCardEditDialog dlg(parentWindow, images_, sets_, cardPreview_, EditMode::Create, fresh,
|
||||
&setsForDialog());
|
||||
themeModalDialog(&dlg, config_.current().theme);
|
||||
CardEditModalGuard modalGuard;
|
||||
if (dlg.ShowModal() != wxID_OK) return;
|
||||
|
||||
auto added = collection_.add(Game::Pokemon, dlg.card());
|
||||
@@ -129,9 +141,15 @@ void PokemonGameView::onEditCard(wxWindow* parentWindow) {
|
||||
showThemedMessageDialog(parentWindow, "Select a card first.", "Edit", wxOK | wxICON_INFORMATION);
|
||||
return;
|
||||
}
|
||||
if (cardEditModalIsActive()) {
|
||||
showThemedMessageDialog(parentWindow, wxString::FromUTF8(kCardEditModalBlockedUtf8),
|
||||
wxString::FromUTF8("Edit"), wxOK | wxICON_INFORMATION);
|
||||
return;
|
||||
}
|
||||
PokemonCardEditDialog dlg(parentWindow, images_, sets_, cardPreview_, EditMode::Edit, *sel,
|
||||
&setsForDialog());
|
||||
themeModalDialog(&dlg, config_.current().theme);
|
||||
CardEditModalGuard modalGuard;
|
||||
if (dlg.ShowModal() != wxID_OK) return;
|
||||
auto updated = collection_.update(Game::Pokemon, dlg.card());
|
||||
if (!updated) {
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
#include "ccm/ui/SwitchCtrl.hpp"
|
||||
#include "ccm/domain/Enums.hpp"
|
||||
#include "ccm/ui/Theme.hpp"
|
||||
|
||||
#include <wx/dcbuffer.h>
|
||||
#include <wx/dcclient.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace ccm::ui {
|
||||
|
||||
wxDEFINE_EVENT(EVT_CCM_SWITCH, wxCommandEvent);
|
||||
|
||||
namespace {
|
||||
|
||||
wxColour liftRgb(const wxColour& c, int delta) {
|
||||
auto lift = [delta](unsigned char ch) -> unsigned char {
|
||||
const int v = static_cast<int>(ch) + delta;
|
||||
return static_cast<unsigned char>(v > 255 ? 255 : (v < 0 ? 0 : v));
|
||||
};
|
||||
return wxColour(lift(c.Red()), lift(c.Green()), lift(c.Blue()));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
SwitchCtrl::SwitchCtrl(wxWindow* parent, wxWindowID id, bool initialOn)
|
||||
: wxWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE, wxString()),
|
||||
on_(initialOn) {
|
||||
SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||
SetCursor(wxCURSOR_HAND);
|
||||
const wxSize sz = FromDIP(wxSize(40, 20));
|
||||
SetMinSize(sz);
|
||||
SetMaxSize(sz);
|
||||
SetInitialSize(sz);
|
||||
|
||||
Bind(wxEVT_PAINT, &SwitchCtrl::onPaint, this);
|
||||
Bind(wxEVT_LEFT_DOWN, &SwitchCtrl::onLeftDown, this);
|
||||
Bind(wxEVT_ENTER_WINDOW, &SwitchCtrl::onEnter, this);
|
||||
Bind(wxEVT_LEAVE_WINDOW, &SwitchCtrl::onLeave, this);
|
||||
Bind(wxEVT_ERASE_BACKGROUND, [](wxEraseEvent&) {});
|
||||
}
|
||||
|
||||
void SwitchCtrl::SetValue(bool on, bool notify) {
|
||||
if (on_ == on) return;
|
||||
on_ = on;
|
||||
Refresh();
|
||||
if (notify) {
|
||||
wxCommandEvent e(EVT_CCM_SWITCH, GetId());
|
||||
e.SetEventObject(this);
|
||||
e.SetInt(on_ ? 1 : 0);
|
||||
ProcessEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
bool SwitchCtrl::Enable(bool enable) {
|
||||
const bool ok = wxWindow::Enable(enable);
|
||||
SetCursor(enable ? wxCURSOR_HAND : wxCURSOR_ARROW);
|
||||
Refresh();
|
||||
return ok;
|
||||
}
|
||||
|
||||
void SwitchCtrl::onEnter(wxMouseEvent& ev) {
|
||||
hovered_ = true;
|
||||
Refresh();
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
void SwitchCtrl::onLeave(wxMouseEvent& ev) {
|
||||
hovered_ = false;
|
||||
Refresh();
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
void SwitchCtrl::onLeftDown(wxMouseEvent& ev) {
|
||||
if (!IsEnabled()) {
|
||||
ev.Skip();
|
||||
return;
|
||||
}
|
||||
on_ = !on_;
|
||||
Refresh();
|
||||
wxCommandEvent e(EVT_CCM_SWITCH, GetId());
|
||||
e.SetEventObject(this);
|
||||
e.SetInt(on_ ? 1 : 0);
|
||||
ProcessEvent(e);
|
||||
ev.Skip(false);
|
||||
}
|
||||
|
||||
void SwitchCtrl::onPaint(wxPaintEvent&) {
|
||||
wxAutoBufferedPaintDC dc(this);
|
||||
const wxRect rect = GetClientRect();
|
||||
if (rect.width <= 0 || rect.height <= 0) return;
|
||||
|
||||
const Theme theme = inferThemeFromWindow(this);
|
||||
const ThemePalette p = paletteForTheme(theme);
|
||||
const bool dark = theme == Theme::Dark;
|
||||
|
||||
wxColour trackOff = p.inputBg;
|
||||
wxColour trackOn = p.buttonBg;
|
||||
wxColour thumb = dark ? wxColour(240, 240, 240) : wxColour(252, 252, 252);
|
||||
wxColour border = dark ? wxColour(72, 72, 72) : wxColour(158, 158, 158);
|
||||
|
||||
wxColour track = on_ ? trackOn : trackOff;
|
||||
if (hovered_ && IsEnabled()) {
|
||||
track = liftRgb(track, dark ? 14 : 10);
|
||||
}
|
||||
if (!IsEnabled()) {
|
||||
track = liftRgb(track, dark ? -22 : -25);
|
||||
thumb = liftRgb(thumb, dark ? -55 : -35);
|
||||
border = liftRgb(border, dark ? -15 : 10);
|
||||
}
|
||||
|
||||
// Fill the full client rect first so rounded-track corners do not show
|
||||
// undrawn pixels (often black) against the parent panel.
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.SetBrush(wxBrush(p.panelBg));
|
||||
dc.DrawRectangle(rect);
|
||||
|
||||
dc.SetPen(wxPen(border));
|
||||
dc.SetBrush(wxBrush(track));
|
||||
const int radius = rect.height / 2;
|
||||
dc.DrawRoundedRectangle(rect, radius);
|
||||
|
||||
const int pad = FromDIP(2);
|
||||
const int thumbD = std::max(4, rect.height - 2 * pad);
|
||||
const int travel = std::max(0, rect.width - 2 * pad - thumbD);
|
||||
const int thumbX = pad + (on_ ? travel : 0);
|
||||
const int thumbY = rect.y + (rect.height - thumbD) / 2;
|
||||
|
||||
wxColour thumbBorder = liftRgb(border, dark ? 18 : -12);
|
||||
dc.SetPen(wxPen(thumbBorder));
|
||||
dc.SetBrush(wxBrush(thumb));
|
||||
dc.DrawEllipse(thumbX, thumbY, thumbD, thumbD);
|
||||
}
|
||||
|
||||
} // namespace ccm::ui
|
||||
+33
-5
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <wx/button.h>
|
||||
#include <wx/bmpbuttn.h>
|
||||
#include <wx/tglbtn.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/dcbuffer.h>
|
||||
#include <wx/frame.h>
|
||||
@@ -444,8 +445,11 @@ void applyThemeToWindowTree(wxWindow* root, const ThemePalette& palette, Theme t
|
||||
#endif
|
||||
}
|
||||
|
||||
// `wxToggleButton` is not a `wxButton` on MSW; without this branch it keeps
|
||||
// native visual styles (e.g. light hover flashes) under dark palette dialogs.
|
||||
if (dynamic_cast<wxButton*>(root) != nullptr ||
|
||||
dynamic_cast<wxBitmapButton*>(root) != nullptr) {
|
||||
dynamic_cast<wxBitmapButton*>(root) != nullptr ||
|
||||
dynamic_cast<wxToggleButton*>(root) != nullptr) {
|
||||
const bool darkLike = isDarkLikeTheme(theme);
|
||||
root->SetThemeEnabled(!darkLike);
|
||||
root->SetBackgroundColour(palette.buttonBg);
|
||||
@@ -485,7 +489,11 @@ void applyThemeToWindowTree(wxWindow* root, const ThemePalette& palette, Theme t
|
||||
return;
|
||||
}
|
||||
it->second.hovered = false;
|
||||
const wxColour bg = it->second.focused ? it->second.hoverBg : it->second.normalBg;
|
||||
const bool toggleOn =
|
||||
dynamic_cast<wxToggleButton*>(root) != nullptr &&
|
||||
static_cast<wxToggleButton*>(root)->GetValue();
|
||||
const wxColour bg =
|
||||
(it->second.focused || toggleOn) ? it->second.hoverBg : it->second.normalBg;
|
||||
root->SetBackgroundColour(bg);
|
||||
root->SetForegroundColour(it->second.text);
|
||||
root->Refresh();
|
||||
@@ -513,7 +521,11 @@ void applyThemeToWindowTree(wxWindow* root, const ThemePalette& palette, Theme t
|
||||
const wxPoint localPos = root->ScreenToClient(mousePos);
|
||||
const bool inside = root->GetClientRect().Contains(localPos);
|
||||
it->second.hovered = inside;
|
||||
const wxColour bg = (inside || it->second.focused) ? it->second.hoverBg : it->second.normalBg;
|
||||
const bool toggleOn =
|
||||
dynamic_cast<wxToggleButton*>(root) != nullptr &&
|
||||
static_cast<wxToggleButton*>(root)->GetValue();
|
||||
const wxColour bg =
|
||||
(inside || it->second.focused || toggleOn) ? it->second.hoverBg : it->second.normalBg;
|
||||
root->SetBackgroundColour(bg);
|
||||
root->SetForegroundColour(it->second.text);
|
||||
root->Refresh();
|
||||
@@ -539,12 +551,25 @@ void applyThemeToWindowTree(wxWindow* root, const ThemePalette& palette, Theme t
|
||||
}
|
||||
it->second.focused = false;
|
||||
it->second.pressed = false;
|
||||
const wxColour bg = it->second.hovered ? it->second.hoverBg : it->second.normalBg;
|
||||
const bool toggleOn =
|
||||
dynamic_cast<wxToggleButton*>(root) != nullptr &&
|
||||
static_cast<wxToggleButton*>(root)->GetValue();
|
||||
const wxColour bg =
|
||||
(it->second.hovered || toggleOn) ? it->second.hoverBg : it->second.normalBg;
|
||||
root->SetBackgroundColour(bg);
|
||||
root->SetForegroundColour(it->second.text);
|
||||
root->Refresh();
|
||||
event.Skip();
|
||||
});
|
||||
if (auto* toggle = dynamic_cast<wxToggleButton*>(root)) {
|
||||
toggle->Bind(wxEVT_TOGGLEBUTTON, [root](wxCommandEvent& event) {
|
||||
auto it = gButtonVisualStates.find(root);
|
||||
if (it != gButtonVisualStates.end() && it->second.darkLike) {
|
||||
root->Refresh();
|
||||
}
|
||||
event.Skip();
|
||||
});
|
||||
}
|
||||
root->SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||
root->Bind(wxEVT_ERASE_BACKGROUND, [](wxEraseEvent&) {});
|
||||
root->Bind(wxEVT_PAINT, [root](wxPaintEvent& event) {
|
||||
@@ -555,10 +580,13 @@ void applyThemeToWindowTree(wxWindow* root, const ThemePalette& palette, Theme t
|
||||
}
|
||||
wxAutoBufferedPaintDC dc(root);
|
||||
const wxRect rect = root->GetClientRect();
|
||||
const bool toggleOn =
|
||||
dynamic_cast<wxToggleButton*>(root) != nullptr &&
|
||||
static_cast<wxToggleButton*>(root)->GetValue();
|
||||
wxColour bg = it->second.normalBg;
|
||||
if (it->second.pressed) {
|
||||
bg = it->second.pressedBg;
|
||||
} else if (it->second.hovered || it->second.focused) {
|
||||
} else if (it->second.hovered || it->second.focused || toggleOn) {
|
||||
bg = it->second.hoverBg;
|
||||
}
|
||||
const wxColour fg = it->second.text;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "ccm/ui/YuGiOhCardEditDialog.hpp"
|
||||
#include "ccm/ui/SwitchCtrl.hpp"
|
||||
#include "ccm/domain/Enums.hpp"
|
||||
#include "ccm/util/YuGiOhPrintingSlot.hpp"
|
||||
#include "ccm/util/YuGiOhSetLookup.hpp"
|
||||
#include <wx/app.h>
|
||||
#include <wx/panel.h>
|
||||
#include <algorithm>
|
||||
@@ -57,6 +59,33 @@ void YuGiOhCardEditDialog::buildFlagsRow(wxBoxSizer* flagsBox) {
|
||||
flagsBox->Add(alteredCheck_, 0, wxRIGHT, 12);
|
||||
}
|
||||
|
||||
void YuGiOhCardEditDialog::customizeSetPickerRow(wxBoxSizer& row, wxComboBox* combo) {
|
||||
wxWindow* const host = combo->GetParent();
|
||||
setCodeRowPanel_ = new wxPanel(host, wxID_ANY);
|
||||
auto* inner = new wxBoxSizer(wxHORIZONTAL);
|
||||
setCodeText_ = new wxTextCtrl(setCodeRowPanel_, wxID_ANY);
|
||||
setCodeAutoBtn_ = new wxButton(setCodeRowPanel_, wxID_ANY, "Auto detect");
|
||||
inner->Add(setCodeText_, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, 6);
|
||||
inner->Add(setCodeAutoBtn_, 0, wxALIGN_CENTER_VERTICAL);
|
||||
setCodeRowPanel_->SetSizer(inner);
|
||||
setCodeRowPanel_->Show(false);
|
||||
|
||||
setModeHint_ = new wxStaticText(host, wxID_ANY, wxString());
|
||||
setPickerSwitch_ = new SwitchCtrl(host, wxID_ANY, false);
|
||||
setPickerSwitch_->Bind(EVT_CCM_SWITCH, &YuGiOhCardEditDialog::onSetRowSwitch, this);
|
||||
setCodeAutoBtn_->Bind(wxEVT_BUTTON, &YuGiOhCardEditDialog::onSetCodeAutoDetect, this);
|
||||
|
||||
row.Add(combo, 1, wxEXPAND);
|
||||
row.Add(setCodeRowPanel_, 1, wxEXPAND);
|
||||
row.Add(setModeHint_, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5);
|
||||
row.Add(setPickerSwitch_, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
if (availableSets().empty()) {
|
||||
setPickerSwitch_->Enable(false);
|
||||
}
|
||||
syncSetModeHint();
|
||||
}
|
||||
|
||||
void YuGiOhCardEditDialog::appendExtraRows(wxFlexGridSizer* grid) {
|
||||
auto* setNoPanel = new wxPanel(this, wxID_ANY);
|
||||
setNoCtrl_ = new wxTextCtrl(setNoPanel, wxID_ANY);
|
||||
@@ -340,10 +369,78 @@ void YuGiOhCardEditDialog::onSetNoTextChanged(wxCommandEvent&) {
|
||||
}
|
||||
|
||||
void YuGiOhCardEditDialog::onSetSelectionChanged(wxCommandEvent& ev) {
|
||||
handleSetSelectionChanged();
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
void YuGiOhCardEditDialog::onSetSelectionApplied() {
|
||||
handleSetSelectionChanged();
|
||||
}
|
||||
|
||||
void YuGiOhCardEditDialog::handleSetSelectionChanged() {
|
||||
clearCachedPrintVariants();
|
||||
refreshSetNoFullPreview();
|
||||
scheduleDeferredVariantPrefetch();
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
void YuGiOhCardEditDialog::syncSetModeHint() {
|
||||
if (!setModeHint_ || !setPickerSwitch_) return;
|
||||
// Switch on = set-code entry; hint tells user how to return to the name list.
|
||||
setModeHint_->SetLabel(setPickerSwitch_->GetValue() ? wxString::FromUTF8("Set name")
|
||||
: wxString::FromUTF8("Set code"));
|
||||
}
|
||||
|
||||
void YuGiOhCardEditDialog::onSetRowSwitch(wxCommandEvent&) {
|
||||
if (!setPickerSwitch_ || !setComboControl() || !setCodeRowPanel_) return;
|
||||
syncSetModeHint();
|
||||
const bool codeMode = setPickerSwitch_->GetValue();
|
||||
setComboControl()->Show(!codeMode);
|
||||
setCodeRowPanel_->Show(codeMode);
|
||||
wxWindow* host = setComboControl()->GetParent();
|
||||
if (host) {
|
||||
host->Layout();
|
||||
}
|
||||
Layout();
|
||||
}
|
||||
|
||||
void YuGiOhCardEditDialog::onSetCodeAutoDetect(wxCommandEvent&) {
|
||||
if (!setCodeText_ || !setPickerSwitch_) return;
|
||||
const auto& sets = availableSets();
|
||||
if (sets.empty()) {
|
||||
showThemedMessageDialog(this,
|
||||
"No sets are cached. Use Sets > Update Yu-Gi-Oh! first.",
|
||||
"Set code", wxOK | wxICON_INFORMATION);
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string raw = setCodeText_->GetValue().ToStdString(wxConvUTF8);
|
||||
const auto r = lookupYuGiOhSetByShorthand(raw, sets);
|
||||
using Kind = YuGiOhSetShorthandLookup::Kind;
|
||||
if (r.kind == Kind::NotFound) {
|
||||
showThemedMessageDialog(
|
||||
this,
|
||||
"No set matches that code. Check the code spelling or use Sets > Update Yu-Gi-Oh! to refresh the list.",
|
||||
"Set code", wxOK | wxICON_INFORMATION);
|
||||
return;
|
||||
}
|
||||
if (r.kind == Kind::Ambiguous) {
|
||||
showThemedMessageDialog(this,
|
||||
"Multiple cached sets match that code. Refresh the set list or pick the set from the list.",
|
||||
"Set code", wxOK | wxICON_INFORMATION);
|
||||
return;
|
||||
}
|
||||
|
||||
applySetSelectionByIndex(r.index);
|
||||
|
||||
setPickerSwitch_->SetValue(false, false);
|
||||
syncSetModeHint();
|
||||
setComboControl()->Show(true);
|
||||
setCodeRowPanel_->Show(false);
|
||||
wxWindow* host = setComboControl()->GetParent();
|
||||
if (host) {
|
||||
host->Layout();
|
||||
}
|
||||
Layout();
|
||||
}
|
||||
|
||||
std::string YuGiOhCardEditDialog::extractSetNoNumeric(std::string_view fullSetNo) const {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#include "ccm/ui/YuGiOhGameView.hpp"
|
||||
|
||||
#include "ccm/ui/CardEditModalGuard.hpp"
|
||||
#include "ccm/ui/YuGiOhCardEditDialog.hpp"
|
||||
#include "ccm/ui/YuGiOhCardListPanel.hpp"
|
||||
#include "ccm/ui/YuGiOhSelectedCardPanel.hpp"
|
||||
#include "ccm/ui/Theme.hpp"
|
||||
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
#include <optional>
|
||||
#include <algorithm>
|
||||
@@ -56,6 +58,10 @@ wxPanel* YuGiOhGameView::listPanel(wxWindow* parent) {
|
||||
selectedPanel_->setCard(listPanel_->selected());
|
||||
}
|
||||
});
|
||||
listPanel_->Bind(EVT_CARD_ACTIVATED, [this](wxCommandEvent&) {
|
||||
wxWindow* owner = wxGetTopLevelParent(listPanel_);
|
||||
onEditCard(owner != nullptr ? owner : static_cast<wxWindow*>(listPanel_));
|
||||
});
|
||||
}
|
||||
return listPanel_;
|
||||
}
|
||||
@@ -94,6 +100,11 @@ const std::vector<Set>& YuGiOhGameView::setsForDialog() {
|
||||
}
|
||||
|
||||
void YuGiOhGameView::onAddCard(wxWindow* parentWindow) {
|
||||
if (cardEditModalIsActive()) {
|
||||
showThemedMessageDialog(parentWindow, wxString::FromUTF8(kCardEditModalBlockedUtf8),
|
||||
wxString::FromUTF8("Add card"), wxOK | wxICON_INFORMATION);
|
||||
return;
|
||||
}
|
||||
YuGiOhCard fresh;
|
||||
fresh.amount = 1;
|
||||
fresh.language = Language::English;
|
||||
@@ -102,6 +113,7 @@ void YuGiOhGameView::onAddCard(wxWindow* parentWindow) {
|
||||
YuGiOhCardEditDialog dlg(parentWindow, images_, sets_, cardPreview_, EditMode::Create, fresh,
|
||||
&setsForDialog());
|
||||
themeModalDialog(&dlg, config_.current().theme);
|
||||
CardEditModalGuard modalGuard;
|
||||
if (dlg.ShowModal() != wxID_OK) return;
|
||||
|
||||
auto added = collection_.add(Game::YuGiOh, dlg.card());
|
||||
@@ -141,9 +153,15 @@ void YuGiOhGameView::onEditCard(wxWindow* parentWindow) {
|
||||
showThemedMessageDialog(parentWindow, "Select a card first.", "Edit", wxOK | wxICON_INFORMATION);
|
||||
return;
|
||||
}
|
||||
if (cardEditModalIsActive()) {
|
||||
showThemedMessageDialog(parentWindow, wxString::FromUTF8(kCardEditModalBlockedUtf8),
|
||||
wxString::FromUTF8("Edit"), wxOK | wxICON_INFORMATION);
|
||||
return;
|
||||
}
|
||||
YuGiOhCardEditDialog dlg(parentWindow, images_, sets_, cardPreview_, EditMode::Edit, *sel,
|
||||
&setsForDialog());
|
||||
themeModalDialog(&dlg, config_.current().theme);
|
||||
CardEditModalGuard modalGuard;
|
||||
if (dlg.ShowModal() != wxID_OK) return;
|
||||
auto updated = collection_.update(Game::YuGiOh, dlg.card());
|
||||
if (!updated) {
|
||||
|
||||
Reference in New Issue
Block a user