From e83c00c05a3447e51209b958ad355bedec9d69cd Mon Sep 17 00:00:00 2001 From: twanvl Date: Thu, 8 Feb 2007 22:15:11 +0000 Subject: [PATCH] Changed scroll size of PackageList; Added 'collapse' option for card notes; Made variant of DECLARE_TYPEOF for maps (two template arguments). git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@202 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/data/action/symbol.cpp | 6 +- src/data/card.cpp | 3 +- src/data/field/choice.cpp | 3 +- src/data/game.cpp | 2 + src/data/game.hpp | 1 + src/data/keyword.cpp | 106 ++++++++++++++++++++ src/data/keyword.hpp | 17 +++- src/data/set.cpp | 3 +- src/gui/about_window.cpp | 24 +++-- src/gui/about_window.hpp | 15 ++- src/gui/control/card_list.cpp | 6 +- src/gui/control/gallery_list.cpp | 65 ++++++------ src/gui/control/gallery_list.hpp | 9 +- src/gui/control/graph.cpp | 3 +- src/gui/control/native_look_editor.cpp | 3 +- src/gui/control/package_list.cpp | 5 +- src/gui/set/cards_panel.cpp | 29 +++++- src/gui/set/cards_panel.hpp | 2 + src/gui/set/keywords_panel.cpp | 13 +++ src/gui/set/keywords_panel.hpp | 4 + src/gui/set/stats_panel.cpp | 2 +- src/gui/set/window.cpp | 7 +- src/render/card/viewer.cpp | 3 +- src/resource/common/btn_collapse_down.png | Bin 0 -> 139 bytes src/resource/common/btn_collapse_focus.png | Bin 0 -> 137 bytes src/resource/common/btn_collapse_hover.png | Bin 0 -> 137 bytes src/resource/common/btn_collapse_normal.png | Bin 0 -> 104 bytes src/resource/common/btn_expand_down.png | Bin 0 -> 133 bytes src/resource/common/btn_expand_focus.png | Bin 0 -> 132 bytes src/resource/common/btn_expand_hover.png | Bin 0 -> 132 bytes src/resource/common/btn_expand_normal.png | Bin 0 -> 104 bytes src/resource/msw/mse.rc | 8 ++ src/script/script_manager.cpp | 6 +- src/util/for_each.hpp | 20 +++- src/util/window_id.hpp | 8 ++ 35 files changed, 292 insertions(+), 81 deletions(-) create mode 100644 src/resource/common/btn_collapse_down.png create mode 100644 src/resource/common/btn_collapse_focus.png create mode 100644 src/resource/common/btn_collapse_hover.png create mode 100644 src/resource/common/btn_collapse_normal.png create mode 100644 src/resource/common/btn_expand_down.png create mode 100644 src/resource/common/btn_expand_focus.png create mode 100644 src/resource/common/btn_expand_hover.png create mode 100644 src/resource/common/btn_expand_normal.png diff --git a/src/data/action/symbol.cpp b/src/data/action/symbol.cpp index 0df5fe92..c125b017 100644 --- a/src/data/action/symbol.cpp +++ b/src/data/action/symbol.cpp @@ -9,10 +9,8 @@ #include #include -typedef pair pair_part_combine_t; -typedef pair pair_part_size_t; -DECLARE_TYPEOF_COLLECTION(pair_part_combine_t); -DECLARE_TYPEOF_COLLECTION(pair_part_size_t); +DECLARE_TYPEOF_COLLECTION2(pair); +DECLARE_TYPEOF_COLLECTION2(pair); DECLARE_TYPEOF_COLLECTION(SymbolPartP); DECLARE_TYPEOF_COLLECTION(ControlPointP); diff --git a/src/data/card.cpp b/src/data/card.cpp index 170d4d63..cf565060 100644 --- a/src/data/card.cpp +++ b/src/data/card.cpp @@ -13,8 +13,7 @@ #include DECLARE_TYPEOF_COLLECTION(FieldP); -typedef IndexMap IndexMap_FieldP_ValueP; -DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_ValueP); +DECLARE_TYPEOF_NO_REV2(IndexMap); // ----------------------------------------------------------------------------- : Card diff --git a/src/data/field/choice.cpp b/src/data/field/choice.cpp index 61c184ef..3de83051 100644 --- a/src/data/field/choice.cpp +++ b/src/data/field/choice.cpp @@ -10,8 +10,7 @@ #include DECLARE_TYPEOF_COLLECTION(ChoiceField::ChoiceP); -typedef map map_String_ScriptableImage; -DECLARE_TYPEOF(map_String_ScriptableImage); +DECLARE_TYPEOF2(map); // ----------------------------------------------------------------------------- : ChoiceField diff --git a/src/data/game.cpp b/src/data/game.cpp index 8571acd7..7e92d3ff 100644 --- a/src/data/game.cpp +++ b/src/data/game.cpp @@ -22,6 +22,7 @@ IMPLEMENT_DYNAMIC_ARG(Game*, game_for_reading, nullptr); Game::Game() : dependencies_initialized(false) + , has_keywords(false) {} GameP Game::byName(const String& name) { @@ -42,6 +43,7 @@ IMPLEMENT_REFLECTION(Game) { REFLECT(card_fields); REFLECT(statistics_dimensions); REFLECT(statistics_categories); + REFLECT(has_keywords); REFLECT(keyword_parameter_types); REFLECT(keyword_modes); REFLECT(keywords); diff --git a/src/data/game.hpp b/src/data/game.hpp index 7a4c7c4d..d24af7e1 100644 --- a/src/data/game.hpp +++ b/src/data/game.hpp @@ -39,6 +39,7 @@ class Game : public Packaged { vector statistics_dimensions; ///< (Additional) statistics dimensions vector statistics_categories; ///< (Additional) statistics categories + bool has_keywords; ///< Does this game use keywords? vector keyword_parameter_types;///< Types of keyword parameters vector keyword_modes; ///< Modes of keywords vector keywords; ///< Keywords for use in text diff --git a/src/data/keyword.cpp b/src/data/keyword.cpp index d67f8ba8..5aafb6fb 100644 --- a/src/data/keyword.cpp +++ b/src/data/keyword.cpp @@ -7,6 +7,10 @@ // ----------------------------------------------------------------------------- : Includes #include +#include + +class KeywordTrie; +DECLARE_TYPEOF2(map); // ----------------------------------------------------------------------------- : Reflection @@ -57,4 +61,106 @@ IMPLEMENT_REFLECTION(Keyword) { REFLECT(mode); } + + +// ----------------------------------------------------------------------------- : KeywordTrie + +/// A node in a trie to match keywords +class KeywordTrie { + public: + KeywordTrie(); + ~KeywordTrie(); + + map children; ///< children after a given character (owned) + KeywordTrie* on_any_star; ///< children on /.*/ (owned) + Keyword* finished; ///< keywords that end in this node + + /// Insert nodes representing the given string + /** return the node where the evaluation will be after matching the string */ + KeywordTrie* insert(const String& match); + + /// Insert nodes representing the regex /.*/ + /** return the node where the evaluation will be after matching that regex */ + KeywordTrie* insertAnyStar(); +}; + + +KeywordTrie::KeywordTrie() + : on_any_star(nullptr) + , finished(nullptr) +{} + +KeywordTrie::~KeywordTrie() { + FOR_EACH(c, children) { + delete c.second; + } + delete on_any_star; +} + +KeywordTrie* KeywordTrie::insert(const String& match) { + KeywordTrie* cur = this; + FOR_EACH_CONST(c, match) { + KeywordTrie*& child = cur->children[c]; + if (!child) child = new KeywordTrie; + cur = child; + } + return cur; +} + +KeywordTrie* KeywordTrie::insertAnyStar() { + if (!on_any_star) on_any_star = new KeywordTrie; + return on_any_star; +} + +// ----------------------------------------------------------------------------- : KeywordMatcher + +/// State of the matching algorithm +class KeywordMatcher { + public: + KeywordMatcher(const String& s); + private: + String str; + size_t pos; +}; + +// ----------------------------------------------------------------------------- : KeywordDatabase + +/// A database of keywords to allow for fast matching +/** NOTE: keywords may not be altered after they are added to the database, + * The database should be rebuild. + */ +class KeywordDatabase { + public: + /// Add a keyword to be matched + void addKeyword(const Keyword&); + + /// Find the first matching keyword, return its position + size_t firstMatch(const String& input, Keyword* keyword); + + private: + KeywordTrie root; +}; + +void KeywordDatabase::addKeyword(const Keyword& kw) { + // TODO +} + // ----------------------------------------------------------------------------- : Using keywords + +KeywordDatabaseP new_keyword_database() { + return new_shared(); +} +void add_keyword(KeywordDatabase& db, const Keyword& kw) { + db.addKeyword(kw); +} + + +String expand_keywords(const KeywordDatabase& db, const String& text) { + // 1. Remove all old reminder texts + String s = remove_tag_contents(text, _("")); + // 2. Process keywords + + // TODO + + return s; +} diff --git a/src/data/keyword.hpp b/src/data/keyword.hpp index 62abb20f..946f4bfe 100644 --- a/src/data/keyword.hpp +++ b/src/data/keyword.hpp @@ -27,6 +27,7 @@ class KeywordParam { String match; ///< Uncompiled regex wxRegEx matchRe; ///< Regular expression to match OptionalScript script; ///< Transformation of the value for showing in the reminder text + String example; ///< Example for preview dialog DECLARE_REFLECTION(); }; @@ -68,10 +69,24 @@ class Keyword { DECLARE_REFLECTION(); }; + // ----------------------------------------------------------------------------- : Using keywords +/// A class that allows for fast matching of keywords +class KeywordDatabase; +DECLARE_POINTER_TYPE(KeywordDatabase); + +/// Create a new keyword database +KeywordDatabaseP new_keyword_database(); + +/// Add a keyword to a KeywordDatabase +/** NOTE: keywords may not be altered after they are added to the database, + * The database should be rebuild. + */ +void add_keyword(KeywordDatabase& db, const Keyword& kw); + /// Expand/update all keywords in the given string -String expand_keywords(const String& text); +String expand_keywords(const KeywordDatabase& db, const String& text); // ----------------------------------------------------------------------------- : EOF #endif diff --git a/src/data/set.cpp b/src/data/set.cpp index ddfb1c08..00ce0b81 100644 --- a/src/data/set.cpp +++ b/src/data/set.cpp @@ -19,8 +19,7 @@ #include DECLARE_TYPEOF_COLLECTION(CardP); -typedef IndexMap IndexMap_FieldP_ValueP; -DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_ValueP); +DECLARE_TYPEOF_NO_REV2(IndexMap); // ----------------------------------------------------------------------------- : Set diff --git a/src/gui/about_window.cpp b/src/gui/about_window.cpp index 390b61d4..912829c8 100644 --- a/src/gui/about_window.cpp +++ b/src/gui/about_window.cpp @@ -64,18 +64,26 @@ END_EVENT_TABLE () // ----------------------------------------------------------------------------- : Button with image and hover effect -HoverButton::HoverButton(Window* parent, int id, const String& name) - : wxControl(parent, id, wxDefaultPosition, wxDefaultSize, wxNO_BORDER) - , bg_normal(load_resource_image(name + _("_normal"))) - , bg_hover (load_resource_image(name + _("_hover"))) - , bg_focus (load_resource_image(name + _("_focus"))) - , bg_down (load_resource_image(name + _("_down"))) +HoverButton::HoverButton(Window* parent, int id, const String& name, const Color& background) + : wxControl(parent, id, wxDefaultPosition, wxDefaultSize, wxNO_BORDER ) , hover(false), focus(false), mouse_down(false), key_down(false) , last_drawn(nullptr) + , background(background) { + loadBitmaps(name); SetSize(DoGetBestSize()); } +void HoverButton::loadBitmaps(const String& name) { + if (bitmaps == name) return; + bitmaps = name; + bg_normal = Bitmap(load_resource_image(name + _("_normal"))); + bg_hover = Bitmap(load_resource_image(name + _("_hover"))); + bg_focus = Bitmap(load_resource_image(name + _("_focus"))); + bg_down = Bitmap(load_resource_image(name + _("_down"))); + Refresh(false); +} + void HoverButton::onMouseEnter(wxMouseEvent&) { hover = true; refreshIfNeeded(); @@ -151,10 +159,10 @@ void HoverButton::draw(DC& dc) { // clear background (for transparent button images) wxSize ws = GetClientSize(); dc.SetPen(*wxTRANSPARENT_PEN); - dc.SetBrush(Color(240,247,255)); + dc.SetBrush(background != wxNullColour ? background : wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); dc.DrawRectangle(0, 0, ws.GetWidth(), ws.GetHeight()); // draw button - dc.DrawBitmap(*toDraw(), 0, 0); + dc.DrawBitmap(*toDraw(), 0, 0, true); last_drawn = toDraw(); } int HoverButton::drawDelta() const { diff --git a/src/gui/about_window.hpp b/src/gui/about_window.hpp index 1e789887..919856de 100644 --- a/src/gui/about_window.hpp +++ b/src/gui/about_window.hpp @@ -30,16 +30,25 @@ class AboutWindow : public wxDialog { // ----------------------------------------------------------------------------- : Button with image and hover effect -// A button that changes images on mouseenter/leave +/// A button that changes images on mouseenter/leave class HoverButton : public wxControl { public: - HoverButton(Window* parent, int id, const String& name); + /// Create a HoverButton, name is the resource name of the images to use + /** name+"_normal", name+"_hover", name+"_focus", name+"_down" + * are the resource names of the images used. + */ + HoverButton(Window* parent, int id, const String& name, const Color& background = Color(240,247,255)); + + /// Load different bitmaps for this button + void loadBitmaps(const String& name); private: DECLARE_EVENT_TABLE(); - Bitmap bg_normal, bg_hover, bg_focus, bg_down; /// Bitmaps for the states of the button + String bitmaps; ///< Name of the loaded bitmaps + Bitmap bg_normal, bg_hover, bg_focus, bg_down; ///< Bitmaps for the states of the button bool hover, focus, mouse_down, key_down; + Color background; void onMouseEnter(wxMouseEvent&); void onMouseLeave(wxMouseEvent&); diff --git a/src/gui/control/card_list.cpp b/src/gui/control/card_list.cpp index cbfabf42..b7f247eb 100644 --- a/src/gui/control/card_list.cpp +++ b/src/gui/control/card_list.cpp @@ -26,10 +26,8 @@ DECLARE_TYPEOF_COLLECTION(CardP); DECLARE_TYPEOF_COLLECTION(FieldP); DECLARE_POINTER_TYPE(ChoiceValue); -typedef map map_int_FieldP; -DECLARE_TYPEOF(map_int_FieldP); -typedef IndexMap IndexMap_FieldP_StyleP; -DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_StyleP); +DECLARE_TYPEOF2(map); +DECLARE_TYPEOF_NO_REV2(IndexMap); // ----------------------------------------------------------------------------- : Events diff --git a/src/gui/control/gallery_list.cpp b/src/gui/control/gallery_list.cpp index 58bea3e4..d9002c64 100644 --- a/src/gui/control/gallery_list.cpp +++ b/src/gui/control/gallery_list.cpp @@ -17,37 +17,40 @@ DEFINE_EVENT_TYPE(EVENT_GALLERY_ACTIVATE); // ----------------------------------------------------------------------------- : GalleryList -const int MARGIN = 1; // margin between items -const int BORDER = 1; // margin between items +const int MARGIN = 1; // margin between items (excluding border) +const int BORDER = 1; // border aroung items +const int SPACING = MARGIN + 2*BORDER; // distance between items GalleryList::GalleryList(Window* parent, int id, int direction) : wxScrolledWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | (direction == wxHORIZONTAL ? wxHSCROLL : wxVSCROLL) ) , selection(NO_SELECTION) , direction(direction) + , scroll_increment(10) {} void GalleryList::update() { - const int w = (int)item_size.width + MARGIN + 2*BORDER; - const int h = (int)item_size.height + MARGIN + 2*BORDER; + const int w = item_size.x + SPACING; + const int h = item_size.y + SPACING; // resize and scroll if (direction == wxHORIZONTAL) { SetVirtualSize(w * (int)itemCount() + MARGIN, h + MARGIN); - SetScrollRate(w, 0); + SetScrollRate(scroll_increment, 0); } else { // wxVERTICAL - SetVirtualSize(w, h * (int)itemCount() + MARGIN + MARGIN); - SetScrollRate(0, h); + SetVirtualSize(w + MARGIN, h * (int)itemCount() + MARGIN); + SetScrollRate(0, scroll_increment); } // ensure selected item + its margin is visible if (selection < itemCount()) { int x, y, cw, ch; GetViewStart (&x, &y); GetClientSize(&cw, &ch); - cw = (cw - w + 1) / w; ch = (ch - h + 1) / h; - RealPoint pos = itemPos(selection); - x = min(x, (int)selection); - y = min(y, (int)selection); - x = max(x + cw, (int)selection) - cw; - y = max(y + ch, (int)selection) - ch; + cw = (cw - scroll_increment + 1) / scroll_increment; + ch = (ch - scroll_increment + 1) / scroll_increment; + wxPoint pos = itemPos(selection); + x = min(x, (int)(selection * w) / scroll_increment); + y = min(y, (int)(selection * h) / scroll_increment); + x = max(x + cw, (int)(selection * w + w - 1) / scroll_increment) - cw; + y = max(y + ch, (int)(selection * h + h - 1) / scroll_increment) - ch; Scroll(x,y); } // redraw @@ -56,21 +59,21 @@ void GalleryList::update() { size_t GalleryList::findItem(const wxMouseEvent& ev) const { if (direction == wxHORIZONTAL) { - int x, w = (int)item_size.width + MARGIN + 2*BORDER; + int x, w = item_size.x + SPACING; GetViewStart (&x, 0); - return static_cast( x + ev.GetX() / w ); + return static_cast( max(0, x * scroll_increment + ev.GetX() - MARGIN) / w ); } else { // wxVERTICAL - int y, h = (int)item_size.height + MARGIN + 2*BORDER; + int y, h = item_size.y + SPACING; GetViewStart (0, &y); - return static_cast( y + ev.GetY() / h ); + return static_cast( max(0, y * scroll_increment + ev.GetY() - MARGIN) / h ); } } -RealPoint GalleryList::itemPos(size_t item) const { +wxPoint GalleryList::itemPos(size_t item) const { if (direction == wxHORIZONTAL) { - return RealPoint(item * (item_size.width + MARGIN + 2*BORDER) + MARGIN + BORDER, MARGIN + BORDER); + return wxPoint((int)item * (item_size.x + SPACING) + MARGIN + BORDER, MARGIN + BORDER); } else { - return RealPoint(MARGIN + BORDER, item * (item_size.height + MARGIN + 2*BORDER) + MARGIN + BORDER); + return wxPoint(MARGIN + BORDER, (int)item * (item_size.y + SPACING) + MARGIN + BORDER); } } @@ -117,8 +120,8 @@ void GalleryList::onChar(wxKeyEvent& ev) { wxSize GalleryList::DoGetBestSize() const { wxSize ws = GetSize(), cs = GetClientSize(); - const int w = int(item_size.width) + 2*MARGIN + 2*BORDER; - const int h = int(item_size.height) + 2*MARGIN + 2*BORDER; + const int w = item_size.x + SPACING; + const int h = item_size.y + SPACING; return wxSize(w, h) + ws - cs; } @@ -136,15 +139,15 @@ void GalleryList::OnDraw(DC& dc) { GetViewStart(&x, &y); GetClientSize(&cw, &ch); if (direction == wxHORIZONTAL) { - dx = int(item_size.width) + MARGIN + 2*BORDER; + dx = item_size.x + MARGIN + 2*BORDER; dy = 0; - start = (size_t) x; - end = (size_t) (start + cw / dx + 1); + start = (size_t) max(0, x * scroll_increment - MARGIN) / dx; + end = (size_t) max(0, x * scroll_increment - MARGIN + cw + dx) / dx; } else { dx = 0; - dy = int(item_size.height) + MARGIN + 2*BORDER; - start = (size_t) y; - end = (size_t) (start + ch / dy + 1); + dy = item_size.y + MARGIN + 2*BORDER; + start = (size_t) max(0, y * scroll_increment - MARGIN) / dy; + end = (size_t) max(0, y * scroll_increment - MARGIN + ch + dy) / dy; } end = min(end, itemCount()); // clear background @@ -161,10 +164,10 @@ void GalleryList::OnDraw(DC& dc) { Color c = selected ? wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT) : unselected; dc.SetPen(c); dc.SetBrush(saturate(lerp(background, c, 0.3), selected ? 0.5 : 0)); - RealPoint pos = itemPos(i); - dc.DrawRectangle(int(pos.x) - BORDER, int(pos.y) - BORDER, int(item_size.width) + 2*BORDER, int(item_size.height) + 2*BORDER); + wxPoint pos = itemPos(i); + dc.DrawRectangle(pos.x - BORDER, pos.y - BORDER, item_size.x + 2*BORDER, item_size.y + 2*BORDER); // draw item - drawItem(dc, int(pos.x), int(pos.y), i, selected); + drawItem(dc, pos.x, pos.y, i, selected); } } diff --git a/src/gui/control/gallery_list.hpp b/src/gui/control/gallery_list.hpp index 40a31434..bfef1f52 100644 --- a/src/gui/control/gallery_list.hpp +++ b/src/gui/control/gallery_list.hpp @@ -36,9 +36,10 @@ class GalleryList : public wxScrolledWindow { protected: static const size_t NO_SELECTION = (size_t)-1; - size_t selection; ///< The selected item, or NO_SELECTION if there is no selection - RealSize item_size; ///< The size of a single item - int direction; ///< Direction of the list, can be wxHORIZONTAL or wxVERTICAL + size_t selection; ///< The selected item, or NO_SELECTION if there is no selection + wxSize item_size; ///< The size of a single item + int scroll_increment; ///< How large are the scroll steps? + int direction; ///< Direction of the list, can be wxHORIZONTAL or wxVERTICAL /// Redraw the list after changing the selection or the number of items void update(); @@ -63,7 +64,7 @@ class GalleryList : public wxScrolledWindow { /// Find the item corresponding to the given location size_t findItem(const wxMouseEvent&) const; /// Find the coordinates of an item - RealPoint itemPos(size_t item) const; + wxPoint itemPos(size_t item) const; protected: /// Send an event void sendEvent(WXTYPE type); diff --git a/src/gui/control/graph.cpp b/src/gui/control/graph.cpp index d5abfd26..08f0de00 100644 --- a/src/gui/control/graph.cpp +++ b/src/gui/control/graph.cpp @@ -15,8 +15,7 @@ DECLARE_TYPEOF_COLLECTION(GraphAxisP); DECLARE_TYPEOF_COLLECTION(GraphElementP); DECLARE_TYPEOF_COLLECTION(GraphGroup); DECLARE_TYPEOF_COLLECTION(int); -typedef map map_String_UInt; -DECLARE_TYPEOF(map_String_UInt); +DECLARE_TYPEOF2(map); // ----------------------------------------------------------------------------- : Events diff --git a/src/gui/control/native_look_editor.cpp b/src/gui/control/native_look_editor.cpp index ffe7396c..1fb53358 100644 --- a/src/gui/control/native_look_editor.cpp +++ b/src/gui/control/native_look_editor.cpp @@ -12,8 +12,7 @@ #include DECLARE_TYPEOF_COLLECTION(ValueViewerP); -typedef IndexMap IndexMap_FieldP_StyleP; -DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_StyleP); +DECLARE_TYPEOF_NO_REV2(IndexMap); // ----------------------------------------------------------------------------- : NativeLookEditor diff --git a/src/gui/control/package_list.cpp b/src/gui/control/package_list.cpp index 917ed52e..b8029e78 100644 --- a/src/gui/control/package_list.cpp +++ b/src/gui/control/package_list.cpp @@ -15,7 +15,8 @@ PackageList::PackageList(Window* parent, int id, int direction) : GalleryList(parent, id, direction) { - item_size = wxSize(110, 150); + item_size = wxSize(108, 150); + SetThemeEnabled(true); } size_t PackageList::itemCount() const { @@ -29,7 +30,7 @@ void PackageList::drawItem(DC& dc, int x, int y, size_t item, bool selected) { int w, h; // draw image if (d.image.Ok()) { - dc.DrawBitmap(d.image, x + int(align_delta_x(ALIGN_CENTER, item_size.width, d.image.GetWidth())), y + 3); + dc.DrawBitmap(d.image, x + int(align_delta_x(ALIGN_CENTER, item_size.x, d.image.GetWidth())), y + 3, true); } // draw short name dc.SetFont(wxFont(12,wxSWISS,wxNORMAL,wxBOLD,false,_("Arial"))); diff --git a/src/gui/set/cards_panel.cpp b/src/gui/set/cards_panel.cpp index f3250faa..b0d4ede7 100644 --- a/src/gui/set/cards_panel.cpp +++ b/src/gui/set/cards_panel.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -26,19 +27,23 @@ CardsPanel::CardsPanel(Window* parent, int id) { // init controls wxPanel* notesP; - wxSplitterWindow* splitter; editor = new CardEditor(this, ID_EDITOR); splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0); card_list = new ImageCardList(splitter, ID_CARD_LIST); notesP = new Panel(splitter, wxID_ANY); notes = new TextCtrl(notesP, ID_NOTES); + collapse_notes = new HoverButton(notesP, ID_COLLAPSE_NOTES, _("btn_collapse"), wxNullColour); + collapse_notes->SetExtraStyle(wxWS_EX_PROCESS_UI_UPDATES); // init sizer for notes panel wxSizer* sn = new wxBoxSizer(wxVERTICAL); - sn->Add(new wxStaticText(notesP, wxID_ANY, _LABEL_("card notes")), 0, wxEXPAND, 2); + wxSizer* sc = new wxBoxSizer(wxHORIZONTAL); + sc->Add(new wxStaticText(notesP, wxID_ANY, _LABEL_("card notes")), 1, wxEXPAND); + sc->Add(collapse_notes, 0, wxALIGN_CENTER | wxRIGHT, 2); + sn->Add(sc, 0, wxEXPAND, 2); sn->Add(notes, 1, wxEXPAND | wxTOP, 2); notesP->SetSizer(sn); // init splitter - splitter->SetMinimumPaneSize(14); + splitter->SetMinimumPaneSize(15); splitter->SetSashGravity(1.0); splitter->SplitHorizontally(card_list, notesP, -40); // init sizer @@ -162,10 +167,15 @@ void CardsPanel::onUpdateUI(wxUpdateUIEvent& ev) { } break; } + case ID_COLLAPSE_NOTES: { + bool collapse = notes->GetSize().y > 0; + collapse_notes->loadBitmaps(collapse ? _("btn_collapse") : _("btn_expand")); + break; + } case ID_INSERT_SYMBOL: { wxMenu* menu = editor->getMenu(ID_INSERT_SYMBOL); ev.Enable(menu); - if (insertSymbolMenu->GetSubMenu() != menu || menu->GetParent() != menuFormat) { + if (insertSymbolMenu->GetSubMenu() != menu || (menu && menu->GetParent() != menuFormat)) { // re-add the menu menuFormat->Remove(insertSymbolMenu); insertSymbolMenu->SetSubMenu(menu); @@ -211,6 +221,17 @@ void CardsPanel::onCommand(int id) { break; } } + case ID_COLLAPSE_NOTES: { + bool collapse = notes->GetSize().y > 0; + if (collapse) { + splitter->SetSashPosition(-1); + notes->SetFocus(); + } else { + splitter->SetSashPosition(-150); + card_list->SetFocus(); + } + break; + } default: { if (id >= ID_INSERT_SYMBOL_MENU_MIN && id <= ID_INSERT_SYMBOL_MENU_MAX) { // pass on to editor diff --git a/src/gui/set/cards_panel.hpp b/src/gui/set/cards_panel.hpp index b6553cc3..317724b0 100644 --- a/src/gui/set/cards_panel.hpp +++ b/src/gui/set/cards_panel.hpp @@ -17,6 +17,7 @@ class ImageCardList; class DataEditor; class TextCtrl; class IconMenu; +class HoverButton; // ----------------------------------------------------------------------------- : CardsPanel @@ -94,6 +95,7 @@ class CardsPanel : public SetWindowPanel { DataEditor* editor; ImageCardList* card_list; TextCtrl* notes; + HoverButton* collapse_notes; // --------------------------------------------------- : Menus & tools IconMenu* menuCard, *menuFormat; diff --git a/src/gui/set/keywords_panel.cpp b/src/gui/set/keywords_panel.cpp index acb2a06b..b2296765 100644 --- a/src/gui/set/keywords_panel.cpp +++ b/src/gui/set/keywords_panel.cpp @@ -20,10 +20,23 @@ class KeywordList : public wxListView { /// Set the list of keywords to show void setData(vector& dat); + // --------------------------------------------------- : Selection + + inline KeywordP getKeyword() const { return selected_keyword; } + inline void setKeyword(const KeywordP& kw) { /* TODO */ } + bool canSelectPrevious() const; bool canSelectNext() const; void selectPrevious(); void selectNext(); + + protected: + /// Get the text of an item in a specific column + /** Overrides a function from wxListCtrl */ + virtual String OnGetItemText (long pos, long col) const; + private: + KeywordP selected_keyword; + long selected_keyword_pos; }; // ----------------------------------------------------------------------------- : KeywordsPanel diff --git a/src/gui/set/keywords_panel.hpp b/src/gui/set/keywords_panel.hpp index 30b40dbf..2a759d56 100644 --- a/src/gui/set/keywords_panel.hpp +++ b/src/gui/set/keywords_panel.hpp @@ -12,12 +12,16 @@ #include #include +class KeywordList; + // ----------------------------------------------------------------------------- : KeywordsPanel /// A panel for listing and editing the keywords in a set class KeywordsPanel : public SetWindowPanel { public: KeywordsPanel(Window* parent, int id); + private: + KeywordList* list; }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/gui/set/stats_panel.cpp b/src/gui/set/stats_panel.cpp index 2a8cc452..609bacf2 100644 --- a/src/gui/set/stats_panel.cpp +++ b/src/gui/set/stats_panel.cpp @@ -72,7 +72,7 @@ void StatCategoryList::drawItem(DC& dc, int x, int y, size_t item, bool selected dc.DrawBitmap(cat.icon, x+1, y+1); } // draw name - RealRect rect(RealPoint(x + 24, y), RealSize(item_size.width - 30, item_size.height)); + RealRect rect(RealPoint(x + 24, y), RealSize(item_size.x - 30, item_size.y)); String str = capitalize(cat.name); // dc.SetFont(wxFont(9.5 * text_scaling, wxSWISS, wxNORMAL, wxNORMAL, false,_("Arial"))); dc.SetFont(*wxNORMAL_FONT); diff --git a/src/gui/set/window.cpp b/src/gui/set/window.cpp index b6a72d0c..68d5cfec 100644 --- a/src/gui/set/window.cpp +++ b/src/gui/set/window.cpp @@ -135,7 +135,7 @@ SetWindow::SetWindow(Window* parent, const SetP& set) addPanel(menuWindow, tabBar, new KeywordsPanel(this, wxID_ANY), 2, _("F8"), _("Keywords"), _("Keywords"), _("Define extra keywords for this set")); addPanel(menuWindow, tabBar, new StatsPanel (this, wxID_ANY), 3, _("F9"), _("Stats"), _("Statistics"), _("Show statistics about the cards in the set")); // addPanel(*s, *menuWindow, *tabBar, new DraftPanel (&this, wxID_ANY), 4, _("F10")) - selectPanel(ID_WINDOW_MIN + 4); // select cards panel + selectPanel(ID_WINDOW_CARDS); // select cards panel // loose ends tabBar->Realize(); @@ -253,6 +253,7 @@ void SetWindow::onCardSelect(CardSelectEvent& ev) { void SetWindow::fixMinWindowSize() { current_panel->SetMinSize(current_panel->GetSizer()->GetMinSize()); Layout(); + current_panel->Layout(); wxSize s = GetSizer()->GetMinSize(); wxSize ws = GetSize(); wxSize cs = GetClientSize(); @@ -348,6 +349,9 @@ void SetWindow::onUpdateUI(wxUpdateUIEvent& ev) { case ID_EDIT_FIND : ev.Enable(current_panel->canFind()); break; case ID_EDIT_FIND_NEXT : ev.Enable(current_panel->canFind()); break; case ID_EDIT_REPLACE : ev.Enable(current_panel->canReplace());break; + // windows + case ID_WINDOW_KEYWORDS: ev.Enable(set->game->has_keywords); break; + // other default: // items created by the panel, and cut/copy/paste and find/replace if(current_panel) current_panel->onUpdateUI(ev); @@ -600,6 +604,7 @@ BEGIN_EVENT_TABLE(SetWindow, wxFrame) EVT_MENU (ID_HELP_WEBSITE, SetWindow::onHelpWebsite) EVT_MENU (ID_HELP_ABOUT, SetWindow::onHelpAbout) EVT_TOOL_RANGE (ID_CHILD_MIN, ID_CHILD_MAX, SetWindow::onChildMenu) + EVT_COMMAND_RANGE (ID_CHILD_MIN, ID_CHILD_MAX, wxEVT_COMMAND_BUTTON_CLICKED, SetWindow::onChildMenu) EVT_GALLERY_SELECT (ID_FIELD_LIST, SetWindow::onChildMenu) // for StatsPanel, because it is not a EVT_TOOL EVT_UPDATE_UI (wxID_ANY, SetWindow::onUpdateUI) diff --git a/src/render/card/viewer.cpp b/src/render/card/viewer.cpp index 9328174f..f1a252d1 100644 --- a/src/render/card/viewer.cpp +++ b/src/render/card/viewer.cpp @@ -18,8 +18,7 @@ #include // clearDC DECLARE_TYPEOF_COLLECTION(ValueViewerP); -typedef IndexMap IndexMap_FieldP_StyleP; -DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_StyleP); +DECLARE_TYPEOF_NO_REV2(IndexMap); // ----------------------------------------------------------------------------- : DataViewer diff --git a/src/resource/common/btn_collapse_down.png b/src/resource/common/btn_collapse_down.png new file mode 100644 index 0000000000000000000000000000000000000000..5344ccd5df61eef0093d398b86d1d454051c0a78 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^{2>ru6{1-oD!Mu5$eRf6b4^k1u>Qz8PrZ!oa|;Ed1^L6AM+KRt8U3KbLh*2~7a) CJ|b!W literal 0 HcmV?d00001 diff --git a/src/resource/common/btn_expand_down.png b/src/resource/common/btn_expand_down.png new file mode 100644 index 0000000000000000000000000000000000000000..957476a75037442e461dc8e34e08ffd20b21171f GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^{2%Q-?;k&Q`ak*z9K&6qd;>RJYD@<);T3K0RTGCEn@%x literal 0 HcmV?d00001 diff --git a/src/resource/common/btn_expand_focus.png b/src/resource/common/btn_expand_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..85170a474bd8107d4e1c726d899f5842594ee9db GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^{2c)I$ztaD0e0sznGFv|b{ literal 0 HcmV?d00001 diff --git a/src/resource/common/btn_expand_hover.png b/src/resource/common/btn_expand_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..85170a474bd8107d4e1c726d899f5842594ee9db GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^{2c)I$ztaD0e0sznGFv|b{ literal 0 HcmV?d00001 diff --git a/src/resource/common/btn_expand_normal.png b/src/resource/common/btn_expand_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..5ba1c5d3e20c6952f88c61568a4bd21074f5b0b8 GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^{2KYZo9%kiHAOboUggui#%1gQhHGI+ZBxvX typedef map Contexts; -typedef IndexMap IndexMap_FieldP_StyleP; -typedef IndexMap IndexMap_FieldP_ValueP; DECLARE_TYPEOF(Contexts); DECLARE_TYPEOF_COLLECTION(CardP); DECLARE_TYPEOF_COLLECTION(FieldP); DECLARE_TYPEOF_COLLECTION(Dependency); -DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_StyleP); -DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_ValueP); +DECLARE_TYPEOF_NO_REV2(IndexMap); +DECLARE_TYPEOF_NO_REV2(IndexMap); // initialize functions, from functions.cpp void init_script_functions(Context& ctx); diff --git a/src/util/for_each.hpp b/src/util/for_each.hpp index 2b50231e..3378ee07 100644 --- a/src/util/for_each.hpp +++ b/src/util/for_each.hpp @@ -24,6 +24,8 @@ #define DECLARE_TYPEOF_NO_REV(T) #define DECLARE_TYPEOF_CONST(T) #define DECLARE_TYPEOF_COLLECTION(T) + #define DECLARE_TYPEOF2(A,B) + #define DECLARE_TYPEOF_NO_REV2(A,B) #define TYPEOF(Value) __typeof(Value) #define TYPEOF_IT(Value) __typeof(Value.begin()) @@ -83,14 +85,28 @@ typedef T::const_reference reference; \ typedef T::const_reference const_reference; \ } - - + /// Declare typeof magic for a specific std::vector type #define DECLARE_TYPEOF_COLLECTION(T) DECLARE_TYPEOF(vector); \ DECLARE_TYPEOF_CONST(set) + /// Declare typeof magic for a specific type, with two template arguments + /** This is needed because the preprocessor sees MACRO(class) + * as a macro call with two arguments. + */ + #define DECLARE_TYPEOF2(A,B) \ + typedef A,B BOOST_PP_CAT(TypeOfTemp,__LINE__); \ + DECLARE_TYPEOF(BOOST_PP_CAT(TypeOfTemp,__LINE__)) + #define DECLARE_TYPEOF_NO_REV2(A,B) \ + typedef A,B BOOST_PP_CAT(TypeOfTemp,__LINE__); \ + DECLARE_TYPEOF_NO_REV(BOOST_PP_CAT(TypeOfTemp,__LINE__)) + #define DECLARE_TYPEOF_COLLECTION2(A,B) \ + typedef A,B BOOST_PP_CAT(TypeOfTemp,__LINE__); \ + DECLARE_TYPEOF_COLLECTION(BOOST_PP_CAT(TypeOfTemp,__LINE__)) + #endif + // ----------------------------------------------------------------------------- : Looping macros with iterators /// Iterate over a collection, using an iterator it of type Type diff --git a/src/util/window_id.hpp b/src/util/window_id.hpp index 83f6211d..f0b4f594 100644 --- a/src/util/window_id.hpp +++ b/src/util/window_id.hpp @@ -56,6 +56,11 @@ enum MenuID { // Window menu (MainWindow) , ID_WINDOW_NEW = 201 , ID_WINDOW_MIN = 202 +, ID_WINDOW_CARDS = ID_WINDOW_MIN + 4 // see SetWindow::SetWindow +, ID_WINDOW_SET = ID_WINDOW_MIN + 0 +, ID_WINDOW_STYLE = ID_WINDOW_MIN + 1 +, ID_WINDOW_KEYWORDS = ID_WINDOW_MIN + 2 +, ID_WINDOW_STATS = ID_WINDOW_MIN + 3 , ID_WINDOW_MAX = 220 // Help menu (MainWindow) @@ -95,6 +100,9 @@ enum ChildMenuID { , ID_CARD_ROTATE_180 , ID_CARD_ROTATE_270 + // On cards panel +, ID_COLLAPSE_NOTES + // Keyword menu , ID_KEYWORD_ADD = 1101 , ID_KEYWORD_REMOVE