From d2173491484b24fb6e8502960067e3db62e29d15 Mon Sep 17 00:00:00 2001 From: twanvl Date: Sun, 16 Jan 2011 13:34:50 +0000 Subject: [PATCH] Added filter box for keywords git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1615 0fc631ac-6414-0410-93d0-97cfa31319b6 --- data/en.mse-locale/locale | 3 +- src/data/card.cpp | 38 - src/data/keyword.cpp | 8 + src/data/keyword.hpp | 3 + src/gui/control/filter_ctrl.cpp | 160 +++ src/gui/control/filter_ctrl.hpp | 61 ++ src/gui/control/filtered_card_list.cpp | 15 - src/gui/control/filtered_card_list.hpp | 24 +- src/gui/control/keyword_list.cpp | 13 +- src/gui/control/keyword_list.hpp | 7 + src/gui/set/cards_panel.cpp | 181 +--- src/gui/set/keywords_panel.cpp | 13 + src/gui/set/keywords_panel.hpp | 3 + src/gui/set/stats_panel.cpp | 2 +- src/mse.vc71.vcproj | 9 + src/resource/common/expected_locale_keys | 1245 +++++++++++----------- src/util/window_id.hpp | 3 +- 17 files changed, 908 insertions(+), 880 deletions(-) create mode 100644 src/gui/control/filter_ctrl.cpp create mode 100644 src/gui/control/filter_ctrl.hpp diff --git a/data/en.mse-locale/locale b/data/en.mse-locale/locale index 94590c78..a4ade44a 100644 --- a/data/en.mse-locale/locale +++ b/data/en.mse-locale/locale @@ -413,9 +413,10 @@ tooltip: label: # Cards tab card notes: Card notes: - search cards: Search for cards + search cards: Search for cards... # Keywords tab + search keywords: Search for keywords... keyword: Keyword match: Matches mode: Mode diff --git a/src/data/card.cpp b/src/data/card.cpp index d3eb3e4a..e63c1f54 100644 --- a/src/data/card.cpp +++ b/src/data/card.cpp @@ -55,41 +55,6 @@ String Card::identification() const { } } -/// Does the given object match the quick search query? -template -bool match_quicksearch_query(String const& query, T const& object) { - bool need_match = true; - // iterate over the components of the query - for (size_t i = 0 ; i < query.size() ; ) { - if (query.GetChar(i) == _(' ')) { - // skip spaces - i++; - } else if (query.GetChar(i) == _('-')) { - // negate the next query, i.e. match only if it is not on the card - need_match = !need_match; - i++; - } else { - size_t end, next; - if (query.GetChar(i) == _('"')) { - // quoted string, match exactly - i++; - end =query.find_first_of(_('"'),i); - next = min(end,query.size()) + 1; - } else { - // single word - next = end = query.find_first_of(_(' '),i); - } - bool match = object.contains(query.substr(i,end-i)); - if (match != need_match) { - return false; - } - need_match = true; // next word is no longer negated - i = next; - } - } - return true; -} - bool Card::contains(String const& query) const { FOR_EACH_CONST(v, data) { if (find_i(v->toString(),query) != String::npos) return true; @@ -97,9 +62,6 @@ bool Card::contains(String const& query) const { if (find_i(notes,query) != String::npos) return true; return false; } -bool Card::contains_words(String const& query) const { - return match_quicksearch_query(query,*this); -} IndexMap& Card::extraDataFor(const StyleSheet& stylesheet) { return extra_data.get(stylesheet.name(), stylesheet.extra_card_fields); diff --git a/src/data/keyword.cpp b/src/data/keyword.cpp index db676b7a..01ba1b04 100644 --- a/src/data/keyword.cpp +++ b/src/data/keyword.cpp @@ -80,6 +80,14 @@ void read_compat(Reader& tag, Keyword* k) { } } +bool Keyword::contains(String const& query) const { + if (find_i(keyword,query) != String::npos) return true; + if (find_i(rules,query) != String::npos) return true; + if (find_i(match,query) != String::npos) return true; + if (find_i(reminder.get(),query) != String::npos) return true; + return false; +} + IMPLEMENT_REFLECTION(Keyword) { REFLECT(keyword); read_compat(tag, this); diff --git a/src/data/keyword.hpp b/src/data/keyword.hpp index 0652bb62..d5156202 100644 --- a/src/data/keyword.hpp +++ b/src/data/keyword.hpp @@ -116,6 +116,9 @@ class Keyword : public IntrusivePtrVirtualBase { */ void prepare(const vector& param_types, bool force = false); + /// Does the keyword contain the given query word? + bool contains(String const& word) const; + DECLARE_REFLECTION(); }; diff --git a/src/gui/control/filter_ctrl.cpp b/src/gui/control/filter_ctrl.cpp new file mode 100644 index 00000000..f83f516f --- /dev/null +++ b/src/gui/control/filter_ctrl.cpp @@ -0,0 +1,160 @@ +//+----------------------------------------------------------------------------+ +//| Description: Magic Set Editor - Program to make Magic (tm) cards | +//| Copyright: (C) 2001 - 2010 Twan van Laarhoven and Sean Hunt | +//| License: GNU General Public License 2 or later (see file COPYING) | +//+----------------------------------------------------------------------------+ + +// ----------------------------------------------------------------------------- : Includes + +#include +#include +#include // for HoverButton +#include + +// ----------------------------------------------------------------------------- : DropDownMRUList + +/// A drop down list of recent choices, for autocomplete +class DropDownMRUList : public DropDownList { + public: + DropDownMRUList(Window* parent, vector const& choices) + : DropDownList(parent) + , choices(choices) + {} + + vector choices; + + protected: + virtual size_t selection() const { return NO_SELECTION; } + virtual size_t itemCount() const { return choices.size(); } + virtual String itemText(size_t item) const { return choices.at(item); } + virtual void select(size_t item); +}; + +// ----------------------------------------------------------------------------- : FilterControl + +/// Text control that forwards focus events to the parent +class TextCtrlWithFocus : public wxTextCtrl { + public: + DECLARE_EVENT_TABLE(); + void forwardFocusEvent(wxFocusEvent&); + void forwardKeyEvent(wxKeyEvent&); +}; + +FilterCtrl::FilterCtrl(wxWindow* parent, int id, String const& placeholder) + : wxControl(parent, id, wxDefaultPosition, wxSize(160,41), wxSTATIC_BORDER) + , changing(false) + , placeholder(placeholder) +{ + wxColour bg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + SetBackgroundColour(bg); + SetCursor(wxCURSOR_IBEAM); + filter_ctrl = new TextCtrlWithFocus(); + filter_ctrl->Create(this, wxID_ANY, _(""), wxDefaultPosition, wxSize(130,-1), wxNO_BORDER); + clear_button = new HoverButton(this, wxID_ANY, _("btn_clear_filter"), bg, false); + clear_button->SetCursor(*wxSTANDARD_CURSOR); + onSize(); + update(); +} + +void FilterCtrl::setFilter(const String& new_value, bool event) { + if (this->value == new_value) return; + // update ui + this->value = new_value; + update(); + // send event + if (event) { + wxCommandEvent ev(wxEVT_COMMAND_TEXT_UPDATED, GetId()); + GetParent()->HandleWindowEvent(ev); + } +} + +void FilterCtrl::update() { + changing = true; + if (!value.empty() || hasFocus()) { + filter_ctrl->SetValue(value); + wxColour fg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + filter_ctrl->SetDefaultStyle(wxTextAttr(fg)); + filter_ctrl->SetForegroundColour(fg); + wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + filter_ctrl->SetFont(font); + } else { + filter_ctrl->SetValue(placeholder); + wxColour fg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + wxColour bg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + filter_ctrl->SetDefaultStyle(wxTextAttr(lerp(fg,bg,0.5))); + filter_ctrl->SetForegroundColour(lerp(fg,bg,0.5)); + wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + font.SetStyle(wxFONTSTYLE_ITALIC); + filter_ctrl->SetFont(font); + } + clear_button->Show(!value.empty()); + changing = false; +} + +void FilterCtrl::onChangeEvent(wxCommandEvent&) { + if (!changing) { + setFilter(filter_ctrl->GetValue(),true); + } +} +void FilterCtrl::onChar(wxKeyEvent& ev) { + if (ev.GetKeyCode() == WXK_ESCAPE) { + // escape clears the filter box + clearFilter(true); + } else { + ev.Skip(); + } +} + +void FilterCtrl::onClear(wxCommandEvent&) { + clearFilter(true); +} + +void FilterCtrl::onSizeEvent(wxSizeEvent&) { + onSize(); +} +void FilterCtrl::onSize() { + wxSize s = GetClientSize(); + wxSize fs = filter_ctrl->GetBestSize(); + wxSize cs = clear_button->GetBestSize(); + int margin = 2; + filter_ctrl ->SetSize(margin, max(margin,(s.y-fs.y)/2), s.x - cs.x - 3*margin, fs.y); + clear_button->SetSize(s.x - cs.x - margin, (s.y-cs.y)/2, cs.x, cs.y); +} + +void FilterCtrl::onSetFocus(wxFocusEvent&) { + filter_ctrl->SetFocus(); + update(); +} +void FilterCtrl::onKillFocus(wxFocusEvent&) { + update(); +} + +bool FilterCtrl::hasFocus() { + wxWindow* focus = wxWindow::FindFocus(); + return focus == this || focus == filter_ctrl || focus == clear_button; +} + +BEGIN_EVENT_TABLE(FilterCtrl, wxControl) + EVT_BUTTON (wxID_ANY, FilterCtrl::onClear) + EVT_TEXT (wxID_ANY, FilterCtrl::onChangeEvent) + EVT_SIZE (FilterCtrl::onSizeEvent) + EVT_SET_FOCUS (FilterCtrl::onSetFocus) + EVT_KILL_FOCUS(FilterCtrl::onKillFocus) + EVT_CHAR (FilterCtrl::onChar) +END_EVENT_TABLE() + +// ----------------------------------------------------------------------------- : TextCtrlWithFocus + +void TextCtrlWithFocus::forwardFocusEvent(wxFocusEvent& ev) { + GetParent()->HandleWindowEvent(ev); +} +void TextCtrlWithFocus::forwardKeyEvent(wxKeyEvent& ev) { + GetParent()->HandleWindowEvent(ev); +} + +BEGIN_EVENT_TABLE(TextCtrlWithFocus, wxTextCtrl) + EVT_SET_FOCUS (TextCtrlWithFocus::forwardFocusEvent) + EVT_KILL_FOCUS(TextCtrlWithFocus::forwardFocusEvent) + EVT_CHAR (TextCtrlWithFocus::forwardKeyEvent) +END_EVENT_TABLE() + diff --git a/src/gui/control/filter_ctrl.hpp b/src/gui/control/filter_ctrl.hpp new file mode 100644 index 00000000..d0bcb0ed --- /dev/null +++ b/src/gui/control/filter_ctrl.hpp @@ -0,0 +1,61 @@ +//+----------------------------------------------------------------------------+ +//| Description: Magic Set Editor - Program to make Magic (tm) cards | +//| Copyright: (C) 2001 - 2010 Twan van Laarhoven and Sean Hunt | +//| License: GNU General Public License 2 or later (see file COPYING) | +//+----------------------------------------------------------------------------+ + +#ifndef HEADER_GUI_CONTROL_FILTER_CTRL +#define HEADER_GUI_CONTROL_FILTER_CTRL + +// ----------------------------------------------------------------------------- : Includes + +#include +#include + +class HoverButton; +class TextCtrlWithFocus; + +// ----------------------------------------------------------------------------- : FilterCtrl + +/// A search/filter textbox +class FilterCtrl : public wxControl { + public: + FilterCtrl(wxWindow* parent, int id, String const& placeholder); + + /// Set the filter text + void setFilter(const String& filter, bool send_event = false); + void clearFilter(bool send_event = false) { setFilter(String(),send_event); } + bool hasFilter() const { return !value.empty(); } + String const& getFilterString() const { return value; } + + template + intrusive_ptr > getFilter() const { + if (hasFilter()) { + return intrusive(new QuickFilter(getFilterString())); + } else { + return intrusive_ptr >(); + } + } + + private: + DECLARE_EVENT_TABLE(); + bool changing; + String value; + String placeholder; + TextCtrlWithFocus* filter_ctrl; + HoverButton* clear_button; + + void update(); + bool hasFocus(); + // wxWidgets appears to have developed an overload allergy + void onChangeEvent(wxCommandEvent&); + void onClear(wxCommandEvent&); + void onSizeEvent(wxSizeEvent&); + void onChar(wxKeyEvent&); + void onSize(); + void onSetFocus(wxFocusEvent&); + void onKillFocus(wxFocusEvent&); +}; + +// ----------------------------------------------------------------------------- : EOF +#endif diff --git a/src/gui/control/filtered_card_list.cpp b/src/gui/control/filtered_card_list.cpp index 8006c557..fe9404dc 100644 --- a/src/gui/control/filtered_card_list.cpp +++ b/src/gui/control/filtered_card_list.cpp @@ -33,18 +33,3 @@ void FilteredCardList::getItems(vector& out) const { filter->getItems(set->cards,out); } } - -// ----------------------------------------------------------------------------- : CardListFilter - -void CardListFilter::getItems(const vector& cards, vector& out) const { - FOR_EACH_CONST(c, cards) { - if (keep(c)) { - out.push_back(c); - } - } -} - -bool QueryCardListFilter::keep(const CardP& card) const { - return card->contains_words(query); -} - diff --git a/src/gui/control/filtered_card_list.hpp b/src/gui/control/filtered_card_list.hpp index 2a4a9472..5140880d 100644 --- a/src/gui/control/filtered_card_list.hpp +++ b/src/gui/control/filtered_card_list.hpp @@ -11,29 +11,9 @@ #include #include +#include -DECLARE_POINTER_TYPE(CardListFilter); - -// ----------------------------------------------------------------------------- : CardListFilter - -/// A filter function to determine which items are shown in a card list -class CardListFilter : public IntrusivePtrVirtualBase { - public: - virtual ~CardListFilter() {} - /// Should a card be shown in the list? - virtual bool keep(const CardP& card) const { return false; } - /// Select cards from a card list - virtual void getItems(const vector& cards, vector& out) const; -}; - -/// A filter function that searches for cards containing a string -class QueryCardListFilter : public CardListFilter { - public: - QueryCardListFilter(String const& query) : query(query) {} - virtual bool keep(const CardP& card) const; - private: - String query; -}; +typedef intrusive_ptr > CardListFilterP; // ----------------------------------------------------------------------------- : FilteredCardList diff --git a/src/gui/control/keyword_list.cpp b/src/gui/control/keyword_list.cpp index 55968d66..fc809d11 100644 --- a/src/gui/control/keyword_list.cpp +++ b/src/gui/control/keyword_list.cpp @@ -56,6 +56,11 @@ void KeywordList::onChangeSet() { refreshList(); } +void KeywordList::setFilter(const KeywordListFilterP& filter) { + this->filter = filter; + refreshList(); +} + void KeywordList::onAction(const Action& action, bool undone) { TYPE_CASE(action, AddKeywordAction) { if (action.action.adding != undone) { @@ -151,11 +156,15 @@ String match_string(const Keyword& a) { void KeywordList::getItems(vector& out) const { FOR_EACH(k, set->keywords) { k->fixed = false; - out.push_back(k); + if (!filter || filter->keep(*k)) { + out.push_back(k); + } } FOR_EACH(k, set->game->keywords) { k->fixed = true; - out.push_back(k); + if (!filter || filter->keep(*k)) { + out.push_back(k); + } } } void KeywordList::sendEvent() { diff --git a/src/gui/control/keyword_list.hpp b/src/gui/control/keyword_list.hpp index c693f803..d041c884 100644 --- a/src/gui/control/keyword_list.hpp +++ b/src/gui/control/keyword_list.hpp @@ -12,8 +12,11 @@ #include #include #include +#include #include +typedef intrusive_ptr > KeywordListFilterP; + // ----------------------------------------------------------------------------- : Events DECLARE_EVENT_TYPE(EVENT_KEYWORD_SELECT, ) @@ -51,6 +54,9 @@ class KeywordList : public ItemList, public SetView { inline KeywordP getKeyword() const { return static_pointer_cast(selected_item); } inline void setKeyword(const KeywordP& kw) { selectItem(kw, true, false); } + /// Change the filter to use, can be null + void setFilter(const KeywordListFilterP& filter); + // --------------------------------------------------- : Clipboard bool canDelete() const; @@ -87,6 +93,7 @@ class KeywordList : public ItemList, public SetView { void storeColumns(); mutable wxListItemAttr item_attr; // for OnGetItemAttr + KeywordListFilterP filter; ///< Which keywords to show? /// How often is a keyword used in the set? int usage(const Keyword&) const; diff --git a/src/gui/set/cards_panel.cpp b/src/gui/set/cards_panel.cpp index a3527772..53357c80 100644 --- a/src/gui/set/cards_panel.cpp +++ b/src/gui/set/cards_panel.cpp @@ -11,10 +11,10 @@ #include #include #include +#include #include // for HoverButton #include #include -#include #include #include #include @@ -35,177 +35,6 @@ DECLARE_TYPEOF_COLLECTION(AddCardsScriptP); #define HAVE_TOOLBAR_DROPDOWN_MENU 1 #endif -// ----------------------------------------------------------------------------- : DropDownMRUList - -/// A drop down list of recent choices, for autocomplete -class DropDownMRUList : public DropDownList { - public: - DropDownMRUList(Window* parent, vector const& choices) - : DropDownList(parent) - , choices(choices) - {} - - vector choices; - - protected: - virtual size_t selection() const { return NO_SELECTION; } - virtual size_t itemCount() const { return choices.size(); } - virtual String itemText(size_t item) const { return choices.at(item); } - virtual void select(size_t item); -}; - -// ----------------------------------------------------------------------------- : FilterControl - -/// Text control that forwards focus events to the parent -class TextCtrlWithFocus : public wxTextCtrl { - public: - DECLARE_EVENT_TABLE(); - void forwardFocusEvent(wxFocusEvent&); - void forwardKeyEvent(wxKeyEvent&); -}; - -/// A search/filter textbox -class FilterCtrl : public wxControl { - public: - FilterCtrl(wxWindow* parent, int id); - /// Set the filter text - void setFilter(const String& filter, bool event = false); - void clearFilter(bool event = false) { setFilter(String(),event); } - bool hasFilter() const { return !value.empty(); } - String const& getFilter() const { return value; } - - //bool AcceptsFocus() const { return false; } - private: - DECLARE_EVENT_TABLE(); - bool changing; - wxString value; - TextCtrlWithFocus* filter_ctrl; - HoverButton* clear_button; - - void update(); - bool hasFocus(); - // wxWidgets appears to have developed an overload allergy - void onChange(); - void onChangeEvent(wxCommandEvent&); - void onClear(wxCommandEvent&); - void onSizeEvent(wxSizeEvent&); - void onChar(wxKeyEvent&); - void onSize(); - public: - void onSetFocus(wxFocusEvent&); - void onKillFocus(wxFocusEvent&); -}; - -FilterCtrl::FilterCtrl(wxWindow* parent, int id) - : wxControl(parent, id, wxDefaultPosition, wxSize(160,41), wxSTATIC_BORDER) - , changing(false) -{ - wxColour bg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); - SetBackgroundColour(bg); - SetCursor(wxCURSOR_IBEAM); - filter_ctrl = new TextCtrlWithFocus(); - filter_ctrl->Create(this, wxID_ANY, _(""), wxDefaultPosition, wxSize(130,-1), wxNO_BORDER); - clear_button = new HoverButton(this, wxID_ANY, _("btn_clear_filter"), bg, false); - clear_button->SetCursor(*wxSTANDARD_CURSOR); - onSize(); - update(); -} - -void FilterCtrl::setFilter(const String& new_value, bool event) { - if (this->value == new_value) return; - // update ui - this->value = new_value; - update(); - // send event - if (event) { - wxCommandEvent ev(wxEVT_COMMAND_TEXT_UPDATED, GetId()); - GetParent()->HandleWindowEvent(ev); - } -} - -void FilterCtrl::update() { - changing = true; - if (!value.empty() || hasFocus()) { - filter_ctrl->SetValue(value); - wxColour fg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); - filter_ctrl->SetDefaultStyle(wxTextAttr(fg)); - filter_ctrl->SetForegroundColour(fg); - } else { - filter_ctrl->SetValue(_LABEL_("search cards")); - wxColour fg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); - wxColour bg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); - filter_ctrl->SetDefaultStyle(wxTextAttr(lerp(fg,bg,0.5))); - filter_ctrl->SetForegroundColour(lerp(fg,bg,0.5)); - } - clear_button->Show(!value.empty()); - changing = false; -} - -void FilterCtrl::onChangeEvent(wxCommandEvent&) { - if (!changing) { - setFilter(filter_ctrl->GetValue(),true); - } -} -void FilterCtrl::onChar(wxKeyEvent& ev) { - if (ev.GetKeyCode() == WXK_ESCAPE) { - // escape clears the filter box - clearFilter(true); - } else { - ev.Skip(); - } -} - -void FilterCtrl::onClear(wxCommandEvent&) { - clearFilter(true); -} - -void FilterCtrl::onSizeEvent(wxSizeEvent&) { - onSize(); -} -void FilterCtrl::onSize() { - wxSize s = GetClientSize(); - wxSize fs = filter_ctrl->GetBestSize(); - wxSize cs = clear_button->GetBestSize(); - int margin = 2; - filter_ctrl ->SetSize(margin, max(margin,(s.y-fs.y)/2), s.x - cs.x - 3*margin, fs.y); - clear_button->SetSize(s.x - cs.x - margin, (s.y-cs.y)/2, cs.x, cs.y); -} - -void FilterCtrl::onSetFocus(wxFocusEvent&) { - filter_ctrl->SetFocus(); - update(); -} -void FilterCtrl::onKillFocus(wxFocusEvent&) { - update(); -} - -bool FilterCtrl::hasFocus() { - wxWindow* focus = wxWindow::FindFocus(); - return focus == this || focus == filter_ctrl || focus == clear_button; -} - -BEGIN_EVENT_TABLE(FilterCtrl, wxControl) - EVT_BUTTON (wxID_ANY, FilterCtrl::onClear) - EVT_TEXT (wxID_ANY, FilterCtrl::onChangeEvent) - EVT_SIZE (FilterCtrl::onSizeEvent) - EVT_SET_FOCUS (FilterCtrl::onSetFocus) - EVT_KILL_FOCUS(FilterCtrl::onKillFocus) - EVT_CHAR (FilterCtrl::onChar) -END_EVENT_TABLE() - -void TextCtrlWithFocus::forwardFocusEvent(wxFocusEvent& ev) { - GetParent()->HandleWindowEvent(ev); -} -void TextCtrlWithFocus::forwardKeyEvent(wxKeyEvent& ev) { - GetParent()->HandleWindowEvent(ev); -} - -BEGIN_EVENT_TABLE(TextCtrlWithFocus, wxTextCtrl) - EVT_SET_FOCUS (TextCtrlWithFocus::forwardFocusEvent) - EVT_KILL_FOCUS(TextCtrlWithFocus::forwardFocusEvent) - EVT_CHAR (TextCtrlWithFocus::forwardKeyEvent) -END_EVENT_TABLE() - // ----------------------------------------------------------------------------- : CardsPanel CardsPanel::CardsPanel(Window* parent, int id) @@ -387,7 +216,7 @@ void CardsPanel::initUI(wxToolBar* tb, wxMenuBar* mb) { #endif // Filter/search textbox tb->AddSeparator(); - if (!filter) filter = new FilterCtrl(tb, ID_CARD_FILTER); + if (!filter) filter = new FilterCtrl(tb, ID_CARD_FILTER, _LABEL_("search cards")); tb->AddControl(filter); tb->Realize(); // Menus @@ -518,11 +347,7 @@ void CardsPanel::onCommand(int id) { } case ID_CARD_FILTER: { // card filter has changed, update the card list - if (filter->hasFilter()) { - card_list->setFilter(intrusive(new QueryCardListFilter(filter->getFilter()))); - } else { - card_list->setFilter(CardListFilterP()); - } + card_list->setFilter(filter->getFilter()); break; } default: { diff --git a/src/gui/set/keywords_panel.cpp b/src/gui/set/keywords_panel.cpp index 9e31e8ee..68da4005 100644 --- a/src/gui/set/keywords_panel.cpp +++ b/src/gui/set/keywords_panel.cpp @@ -49,6 +49,7 @@ void KeywordsPanel::initControls() { ref_param = new wxButton(panel, ID_KEYWORD_REF_PARAM, _BUTTON_("refer parameter")); rules = new TextCtrl(panel, ID_RULES, true); errors = new wxStaticText(panel, wxID_ANY, _("")); + filter = nullptr; errors->SetForegroundColour(*wxRED); // warning about fixed keywords fixedL = new wxStaticText(panel, wxID_ANY, _("")); @@ -132,6 +133,10 @@ void KeywordsPanel::initUI(wxToolBar* tb, wxMenuBar* mb) { // Toolbar tb->AddTool(ID_KEYWORD_ADD, _(""), load_resource_tool_image(_("keyword_add")), wxNullBitmap, wxITEM_NORMAL,_TOOLTIP_("add keyword"), _HELP_("add keyword")); tb->AddTool(ID_KEYWORD_REMOVE, _(""), load_resource_tool_image(_("keyword_del")), wxNullBitmap, wxITEM_NORMAL,_TOOLTIP_("remove keyword"),_HELP_("remove keyword")); + // Filter/search textbox + tb->AddSeparator(); + if (!filter) filter = new FilterCtrl(tb, ID_KEYWORD_FILTER, _LABEL_("search keywords")); + tb->AddControl(filter); tb->Realize(); // Menus mb->Insert(2, menuKeyword, _MENU_("keywords")); @@ -141,6 +146,9 @@ void KeywordsPanel::destroyUI(wxToolBar* tb, wxMenuBar* mb) { // Toolbar tb->DeleteTool(ID_KEYWORD_ADD); tb->DeleteTool(ID_KEYWORD_REMOVE); + tb->DeleteTool(filter->GetId()); filter = nullptr; + // HACK: hardcoded size of rest of toolbar + tb->DeleteToolByPos(12); // delete separator // Menus mb->Remove(2); @@ -203,6 +211,11 @@ void KeywordsPanel::onCommand(int id) { ref_param->PopupMenu(&ref_menu, 0, ref_param->GetSize().y); break; } + case ID_KEYWORD_FILTER: { + // keyword filter has changed, update the list + list->setFilter(filter->getFilter()); + break; + } default: if (id >= ID_PARAM_TYPE_MIN && id < ID_PARAM_TYPE_MAX) { // add parameter diff --git a/src/gui/set/keywords_panel.hpp b/src/gui/set/keywords_panel.hpp index 4305130e..4bf39072 100644 --- a/src/gui/set/keywords_panel.hpp +++ b/src/gui/set/keywords_panel.hpp @@ -11,12 +11,14 @@ #include #include +#include class wxSplitterWindow; class KeywordList; class TextCtrl; class IconMenu; struct KeywordSelectEvent; +class FilterCtrl; // ----------------------------------------------------------------------------- : KeywordsPanel @@ -69,6 +71,7 @@ class KeywordsPanel : public SetWindowPanel { wxChoice* mode; wxButton* add_param; wxButton* ref_param; + FilterCtrl* filter; // --------------------------------------------------- : Events void onKeywordSelect(KeywordSelectEvent& ev); diff --git a/src/gui/set/stats_panel.cpp b/src/gui/set/stats_panel.cpp index e115a037..3b093fbb 100644 --- a/src/gui/set/stats_panel.cpp +++ b/src/gui/set/stats_panel.cpp @@ -530,7 +530,7 @@ void StatsPanel::onGraphSelect(wxCommandEvent&) { // ----------------------------------------------------------------------------- : Filtering card list -class StatsFilter : public CardListFilter { +class StatsFilter : public Filter { public: StatsFilter(GraphData& data, const vector match) { data.indices(match, indices); diff --git a/src/mse.vc71.vcproj b/src/mse.vc71.vcproj index d63b3806..93bfbf71 100644 --- a/src/mse.vc71.vcproj +++ b/src/mse.vc71.vcproj @@ -622,6 +622,12 @@ + + + + @@ -1884,6 +1890,9 @@ + +