//+----------------------------------------------------------------------------+ //| Description: Magic Set Editor - Program to make Magic (tm) cards | //| Copyright: (C) 2001 - 2017 Twan van Laarhoven and Sean Hunt | //| License: GNU General Public License 2 or later (see file COPYING) | //+----------------------------------------------------------------------------+ // ----------------------------------------------------------------------------- : Includes #include #include #include #include #include #include #include #include #include #include DECLARE_TYPEOF_COLLECTION(AutoReplaceP); // ----------------------------------------------------------------------------- : AutoReplaceList DECLARE_EVENT_TYPE(EVENT_ITEM_SELECT, ) DEFINE_EVENT_TYPE(EVENT_ITEM_SELECT); class AutoReplaceList : public ItemList { public: AutoReplaceList(Window* parent, int id, const Game& game); /// The items vector items; /// Settings we are edditing const Game& game; GameSettings& gs; /// The current item inline AutoReplaceP getSelected() const { return static_pointer_cast(selected_item); } /// Add an item void addItem(const AutoReplaceP& item); /// Remove the selected item void removeSelected(); /// Reset the list to the default void reset(); using ItemList::refreshList; protected: /// Get all items virtual void getItems(vector& out) const; /// Return the AutoReplace at the given position in the sorted list inline AutoReplaceP getAR(long pos) const { return static_pointer_cast(getItem(pos)); } /// Send an 'item selected' event for the currently selected item (selected_item) virtual void sendEvent(); /// Compare items virtual bool compareItems(void* a, void* b) const; virtual bool mustSort() const { return true; } /// Get the text of an item in a specific column /** Overrides a function from wxListCtrl */ virtual String OnGetItemText (long pos, long col) const; /// Get the image of an item, by default no image is used /** Overrides a function from wxListCtrl */ virtual int OnGetItemImage(long pos) const; /// Get the color for an item virtual wxListItemAttr* OnGetItemAttr(long pos) const; mutable wxListItemAttr item_attr; // for OnGetItemAttr }; AutoReplaceList::AutoReplaceList(Window* parent, int id, const Game& game) : ItemList(parent, id) , game(game) , gs(settings.gameSettingsFor(game)) { // clone items FOR_EACH_CONST(ar, gs.auto_replaces) { items.push_back(ar->clone()); } // Add columns InsertColumn(0, _(""), wxLIST_FORMAT_LEFT, 0); // dummy, prevent the image from taking up space InsertColumn(1, _LABEL_("auto match"), wxLIST_FORMAT_LEFT, 100); InsertColumn(2, _LABEL_("auto replace"), wxLIST_FORMAT_LEFT, 200); // grey for disabled items item_attr.SetTextColour(lerp(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT),0.5)); // init list refreshList(); sortBy(1,true); } void AutoReplaceList::addItem(const AutoReplaceP& item) { items.push_back(item); refreshList(); selectItem(item, true, true); } void AutoReplaceList::removeSelected() { for (size_t i = 0 ; i < items.size() ; ++i) { if (items[i] == selected_item) { items.erase(items.begin() + i); // select next refreshList(); selectItem(items.empty() ? VoidP() : static_pointer_cast(items[min(i, items.size())]), true, true); return; } } } void AutoReplaceList::reset() { // reset to list from game items.clear(); FOR_EACH_CONST(ar, game.auto_replaces) { items.push_back(ar->clone()); } refreshList(); } void AutoReplaceList::getItems(vector& out) const { FOR_EACH_CONST(i, items) out.push_back(i); } void AutoReplaceList::sendEvent() { wxCommandEvent ev(EVENT_ITEM_SELECT, GetId()); ProcessEvent(ev); } bool AutoReplaceList::compareItems(void* ap, void* bp) const { AutoReplace& a = *static_cast(ap); AutoReplace& b = *static_cast(bp); switch (sort_by_column) { case 2: return a.replace < b.replace; default: return a.match < b.match; } } String AutoReplaceList::OnGetItemText (long pos, long col) const { AutoReplaceP ar = getAR(pos); if (col == 0) return ar->match; if (col == 1) return ar->match; if (col == 2) return ar->replace; throw InternalError(_("too many columns")); } int AutoReplaceList::OnGetItemImage(long pos) const { return -1; } wxListItemAttr* AutoReplaceList::OnGetItemAttr(long pos) const { // grey disabled keywords return getAR(pos)->enabled ? nullptr : &item_attr; } // ----------------------------------------------------------------------------- : AutoReplaceWindow AutoReplaceWindow::AutoReplaceWindow(Window* parent, const Game& game) : wxDialog(parent, wxID_ANY, _TITLE_("auto replaces")) , in_event(false) { // Create controls list = new AutoReplaceList(this, wxID_ANY, game); match = new wxTextCtrl(this, ID_ITEM_VALUE); replace = new wxTextCtrl(this, ID_ITEM_VALUE); enabled = new wxCheckBox(this, ID_ITEM_VALUE, _BUTTON_("enabled")); whole_word = new wxCheckBox(this, ID_ITEM_VALUE, _BUTTON_("whole word")); use_auto_replace = new wxCheckBox(this, ID_USE_AUTO_REPLACE, _BUTTON_("use auto replace")); add = new wxButton(this, ID_ADD_ITEM, _BUTTON_("add item")); remove = new wxButton(this, ID_REMOVE_ITEM, _BUTTON_("remove item")); wxButton* defaults = new wxButton(this, ID_DEFAULTS, _BUTTON_("defaults")); matchL = new wxStaticText(this, wxID_ANY, _LABEL_("auto match")); replaceL = new wxStaticText(this, wxID_ANY, _LABEL_("auto replace")); // Create sizer wxSizer* s = new wxBoxSizer(wxVERTICAL); // enabled? s->Add(use_auto_replace, 0, wxALL & ~wxBOTTOM, 8); // list s->Add(list, 1, wxEXPAND | (wxALL & ~wxBOTTOM), 8); s->AddSpacer(4); wxSizer* s2 = new wxBoxSizer(wxHORIZONTAL); s2->Add(add, 0, wxRIGHT, 4); s2->Add(remove); s->Add(s2, 0, wxALIGN_RIGHT | (wxALL & ~wxTOP & ~wxBOTTOM), 8); // values wxFlexGridSizer* s3 = new wxFlexGridSizer(2); s3->AddGrowableCol(1); s3->Add(matchL, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 4); s3->Add(match, 1, wxEXPAND | wxBOTTOM, 2); s3->Add(replaceL, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 4); s3->Add(replace, 1, wxEXPAND | wxBOTTOM, 2); s->Add(s3, 0, wxEXPAND | (wxALL & ~wxBOTTOM), 8); s->AddSpacer(2); s->Add(whole_word, 0, wxALL & ~wxBOTTOM & ~wxTOP, 8); s->AddSpacer(4); s->Add(enabled, 0, wxALL & ~wxTOP & ~wxBOTTOM, 8); // buttons wxSizer* s4 = new wxBoxSizer(wxHORIZONTAL); s4->Add(defaults, 0, wxALL & ~wxRIGHT, 8); s4->Add(CreateButtonSizer(wxOK | wxCANCEL), 1, wxALL, 8); s->Add(s4, 0, wxEXPAND); s->SetSizeHints(this); SetSizer(s); // Set default size SetSize(350, 450); // initialize values use_auto_replace->SetValue(list->gs.use_auto_replace); enable(); refreshItem(); } void AutoReplaceWindow::onItemSelect(wxCommandEvent&) { refreshItem(); } void AutoReplaceWindow::onItemChange(wxCommandEvent&) { updateItem(); } void AutoReplaceWindow::onEnable(wxCommandEvent&) { enable(); } void AutoReplaceWindow::onOk(wxCommandEvent&) { store(); Hide(); } void AutoReplaceWindow::onRemove(wxCommandEvent&) { list->removeSelected(); } void AutoReplaceWindow::onAdd(wxCommandEvent&) { list->addItem(intrusive(new AutoReplace())); } void AutoReplaceWindow::onDefault(wxCommandEvent&) { use_auto_replace->SetValue(true); list->reset(); enable(); } void AutoReplaceWindow::enable() { bool enable = use_auto_replace->GetValue(); list ->Enable(enable); matchL ->Enable(enable); replaceL ->Enable(enable); match ->Enable(enable); replace ->Enable(enable); enabled ->Enable(enable); whole_word->Enable(enable); add ->Enable(enable); remove ->Enable(enable); } void AutoReplaceWindow::refreshItem() { if (in_event) return; if (!use_auto_replace->GetValue()) return; in_event = true; AutoReplaceP ar = list->getSelected(); match ->Enable(ar && ar->custom); replace ->Enable((bool)ar); matchL ->Enable(ar && ar->custom); replaceL ->Enable((bool)ar); enabled ->Enable((bool)ar); whole_word->Enable((bool)ar); remove ->Enable(ar && ar->custom); if (ar) { match ->SetValue(ar->match); replace ->SetValue(ar->replace); enabled ->SetValue(ar->enabled); whole_word->SetValue(ar->whole_word); } else { match ->SetValue(wxEmptyString); replace ->SetValue(wxEmptyString); enabled ->SetValue(false); whole_word->SetValue(false); } in_event = false; } void AutoReplaceWindow::updateItem() { if (in_event) return; in_event = true; AutoReplaceP ar = list->getSelected(); if (!ar) return; ar->match = match->GetValue(); ar->replace = replace->GetValue(); ar->enabled = enabled->GetValue(); ar->whole_word = whole_word->GetValue(); list->refreshList(true); in_event = false; } void AutoReplaceWindow::store() { list->gs.use_auto_replace = use_auto_replace->GetValue(); swap(list->items, list->gs.auto_replaces); } BEGIN_EVENT_TABLE(AutoReplaceWindow, wxDialog) EVT_COMMAND (wxID_ANY, EVENT_ITEM_SELECT, AutoReplaceWindow::onItemSelect) EVT_TEXT (ID_ITEM_VALUE, AutoReplaceWindow::onItemChange) EVT_CHECKBOX (ID_ITEM_VALUE, AutoReplaceWindow::onItemChange) EVT_CHECKBOX (ID_USE_AUTO_REPLACE, AutoReplaceWindow::onEnable) EVT_BUTTON (wxID_OK, AutoReplaceWindow::onOk) EVT_BUTTON (ID_ADD_ITEM, AutoReplaceWindow::onAdd) EVT_BUTTON (ID_REMOVE_ITEM, AutoReplaceWindow::onRemove) EVT_BUTTON (ID_DEFAULTS, AutoReplaceWindow::onDefault) END_EVENT_TABLE()