From 29d072e949bcf8392ba07e09bf1e87853bb801bb Mon Sep 17 00:00:00 2001 From: twanvl Date: Wed, 18 Oct 2006 17:48:14 +0000 Subject: [PATCH] Implemented CardList git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@23 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/data/card.hpp | 11 +- src/data/field.cpp | 5 + src/data/field.hpp | 5 +- src/data/field/text.cpp | 3 + src/data/field/text.hpp | 1 + src/data/game.cpp | 10 + src/data/game.hpp | 6 +- src/data/settings.cpp | 22 ++- src/data/settings.hpp | 41 +++-- src/gui/control/card_list.cpp | 313 ++++++++++++++++++++++++++++++++ src/gui/control/card_list.hpp | 152 ++++++++++++++++ src/gui/set/panel.hpp | 25 ++- src/gui/set/set_info_panel.hpp | 7 +- src/gui/set/style_panel.cpp | 15 +- src/gui/set/style_panel.hpp | 7 +- src/gui/set/window.cpp | 17 +- src/gui/set/window.hpp | 3 +- src/mse.vcproj | 46 ++++- src/script/scriptable.hpp | 1 + src/util/alignment.cpp | 22 +++ src/util/alignment.hpp | 5 +- src/util/for_each.hpp | 7 + src/util/io/package.cpp | 6 + src/util/io/package.hpp | 5 + src/util/io/package_manager.cpp | 30 ++- src/util/io/package_manager.hpp | 11 +- src/util/string.cpp | 39 ++++ src/util/string.hpp | 7 + src/util/window_id.hpp | 3 + 29 files changed, 762 insertions(+), 63 deletions(-) create mode 100644 src/gui/control/card_list.cpp create mode 100644 src/gui/control/card_list.hpp diff --git a/src/data/card.hpp b/src/data/card.hpp index 56314e1f..893ce3f1 100644 --- a/src/data/card.hpp +++ b/src/data/card.hpp @@ -16,7 +16,7 @@ class Game; DECLARE_POINTER_TYPE(Field); DECLARE_POINTER_TYPE(Value); -DECLARE_POINTER_TYPE(CardStyle); +DECLARE_POINTER_TYPE(StyleSheet); // ----------------------------------------------------------------------------- : Card @@ -34,17 +34,16 @@ class Card { /// Get an identification of the card, an identification is something like a name, title, etc. String identification() const; - private: - /// The values on the fields of the card - /// The indices should correspond to the cardFields in the Game + /// The values on the fields of the card. + /** The indices should correspond to the cardFields in the Game */ IndexMap data; /// Notes for this card String notes; /// Alternative style to use for this card - /// Optional, if not set use the card style from the set - CardStyleP style; + /** Optional; if not set use the card style from the set */ + StyleSheetP stylesheet; DECLARE_REFLECTION(); }; diff --git a/src/data/field.cpp b/src/data/field.cpp index e6b77e87..84577424 100644 --- a/src/data/field.cpp +++ b/src/data/field.cpp @@ -8,6 +8,11 @@ #include #include +#include +#include +#include +#include +#include #include // ----------------------------------------------------------------------------- : Field diff --git a/src/data/field.hpp b/src/data/field.hpp index 502aa534..c05bb967 100644 --- a/src/data/field.hpp +++ b/src/data/field.hpp @@ -81,7 +81,10 @@ class Value { /// Create a copy of this value virtual ValueP clone() const = 0; - + + /// Convert this value to a string for use in tables + virtual String toString() const = 0; + private: DECLARE_REFLECTION_VIRTUAL(); }; diff --git a/src/data/field/text.cpp b/src/data/field/text.cpp index 858f39c8..e32e449f 100644 --- a/src/data/field/text.cpp +++ b/src/data/field/text.cpp @@ -59,6 +59,9 @@ IMPLEMENT_REFLECTION(TextStyle) { ValueP TextValue::clone() const { return new_shared1(*this); } +String TextValue::toString() const { + return value(); +} IMPLEMENT_REFLECTION(TextValue) { REFLECT_BASE(Value); diff --git a/src/data/field/text.hpp b/src/data/field/text.hpp index cf0a20d6..6d01ed9b 100644 --- a/src/data/field/text.hpp +++ b/src/data/field/text.hpp @@ -71,6 +71,7 @@ class TextValue : public Value { Defaultable value; ///< The text of this value virtual ValueP clone() const; + virtual String toString() const; private: DECLARE_REFLECTION(); }; diff --git a/src/data/game.cpp b/src/data/game.cpp index 9cf81857..b5e86d28 100644 --- a/src/data/game.cpp +++ b/src/data/game.cpp @@ -22,8 +22,18 @@ bool Game::isMagic() const { return name() == _("magic"); } +String Game::typeNameStatic() { return _("game"); } String Game::typeName() const { return _("game"); } +String Game::fullName() const { return full_name; } +InputStreamP Game::openIconFile() { + if (!icon_filename.empty()) { + return openIn(icon_filename); + } else { + return InputStreamP(); + } +} + IMPLEMENT_REFLECTION(Game) { // ioMseVersion(io, fileName, fileVersion); REFLECT(full_name); diff --git a/src/data/game.hpp b/src/data/game.hpp index a58d45f6..5b3c0022 100644 --- a/src/data/game.hpp +++ b/src/data/game.hpp @@ -32,8 +32,12 @@ class Game : public Packaged { /// Is this Magic the Gathering? bool isMagic() const; + static String typeNameStatic(); + virtual String typeName() const; + virtual String fullName() const; + virtual InputStreamP openIconFile(); + protected: - String typeName() const; void validate(); DECLARE_REFLECTION(); diff --git a/src/data/settings.cpp b/src/data/settings.cpp index 27d98542..1b103f1f 100644 --- a/src/data/settings.cpp +++ b/src/data/settings.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -23,6 +24,12 @@ IMPLEMENT_REFLECTION_ENUM(CheckUpdates) { VALUE_N("never", CHECK_NEVER); } +const int COLUMN_NOT_INITIALIZED = -100000; + +ColumnSettings::ColumnSettings() + : width(100), position(COLUMN_NOT_INITIALIZED), visible(false) +{} + IMPLEMENT_REFLECTION(ColumnSettings) { REFLECT(width); REFLECT(position); @@ -37,7 +44,7 @@ IMPLEMENT_REFLECTION(GameSettings) { REFLECT(sort_cards_ascending); } -IMPLEMENT_REFLECTION(StyleSettings) { +IMPLEMENT_REFLECTION(StyleSheetSettings) { // TODO } @@ -75,6 +82,19 @@ GameSettings& Settings::gameSettingsFor(const Game& game) { if (!gs) gs.reset(new GameSettings); return *gs; } +ColumnSettings& Settings::columnSettingsFor(const Game& game, const Field& field) { + // Get game info + GameSettings& gs = gameSettingsFor(game); + // Get column info + ColumnSettings& cs = gs.columns[field.name]; + if (cs.position == COLUMN_NOT_INITIALIZED) { + // column info not set, initialize based on the game + cs.visible = field.card_list_column >= 0; + cs.position = field.card_list_column; + cs.width = field.card_list_width; + } + return cs; +} /* StyleSettings& Settings::styleSettingsFor(const CardStyle& style) { StyleSettingsP& ss = settings.styleSettings#(style.name()); diff --git a/src/data/settings.hpp b/src/data/settings.hpp index ca0405c8..fb0fb069 100644 --- a/src/data/settings.hpp +++ b/src/data/settings.hpp @@ -11,12 +11,14 @@ #include #include +#include class Game; -class CardStyle; +class StyleSheet; +class Field; DECLARE_POINTER_TYPE(GameSettings); -DECLARE_POINTER_TYPE(StyleSettings); +DECLARE_POINTER_TYPE(StyleSheetSettings); // ----------------------------------------------------------------------------- : Extra data structures @@ -30,6 +32,7 @@ enum CheckUpdates /// Settings of a single column in the card list class ColumnSettings { public: + ColumnSettings(); UInt width; int position; bool visible; @@ -49,20 +52,20 @@ class GameSettings { DECLARE_REFLECTION(); }; -/// Settings for a Style -class StyleSettings { +/// Settings for a StyleSheet +class StyleSheetSettings { public: // Rendering/display settings -/* SimpleDefaultable card_zoom = 1.0; - SimpleDefaultable card_angle = 0; - SimpleDefaultable card_anti_alias = true; - SimpleDefaultable card_borders = true; - SimpleDefaultable card_normal_export = true; -*/ + Defaultable card_zoom; + Defaultable card_angle; + Defaultable card_anti_alias; + Defaultable card_borders; + Defaultable card_normal_export; + DECLARE_REFLECTION(); // /// Where the settings are the default, use the value from ss -// void useDefault(const StyleSettings& ss); +// void useDefault(const StyleSheetSettings& ss); }; // ----------------------------------------------------------------------------- : Settings @@ -92,17 +95,19 @@ class Settings { // --------------------------------------------------- : Default pacakge selections String default_game; - // --------------------------------------------------- : Game/style specific + // --------------------------------------------------- : Game/stylesheet specific /// Get the settings object for a specific game - GameSettings& gameSettingsFor(const Game& game); - /// Get the settings object for a specific style - StyleSettings& styleSettingsFor(const CardStyle& style); + GameSettings& gameSettingsFor (const Game& game); + /// Get the settings for a column for a specific field in a game + ColumnSettings& columnSettingsFor (const Game& game, const Field& field); + /// Get the settings object for a specific stylesheet + StyleSheetSettings& styleSheetSettingsFor(const StyleSheet& stylesheet); private: - map game_settings; - map style_settings; - StyleSettings default_style_settings; + map game_settings; + map stylesheet_settings; + StyleSheetSettings default_stylesheet_settings; public: // --------------------------------------------------- : Special game stuff diff --git a/src/gui/control/card_list.cpp b/src/gui/control/card_list.cpp new file mode 100644 index 00000000..ba8c747c --- /dev/null +++ b/src/gui/control/card_list.cpp @@ -0,0 +1,313 @@ +//+----------------------------------------------------------------------------+ +//| Description: Magic Set Editor - Program to make Magic (tm) cards | +//| Copyright: (C) 2001 - 2006 Twan van Laarhoven | +//| License: GNU General Public License 2 or later (see file COPYING) | +//+----------------------------------------------------------------------------+ + +// ----------------------------------------------------------------------------- : Includes + +#include +#include +#include +#include +#include +#include +#include + +DECLARE_TYPEOF_COLLECTION(CardP); +DECLARE_TYPEOF_COLLECTION(FieldP); +typedef map map_int_FieldP; +DECLARE_TYPEOF(map_int_FieldP); + +// ----------------------------------------------------------------------------- : Events + +DEFINE_EVENT_TYPE(EVENT_CARD_SELECT); + +// ----------------------------------------------------------------------------- : CardListBase + +CardListBase::CardListBase(Window* parent, int id, int additional_style) +{} + +CardListBase::~CardListBase() { + storeColumns(); +} + +void CardListBase::onBeforeChangeSet() { + storeColumns(); +} +void CardListBase::onChangeSet() { + rebuild(); +} +void CardListBase::onAction(const Action& action) { + // TODO +} + +vector& CardListBase::getCards() const { + return set->cards; +} + +// ----------------------------------------------------------------------------- : CardListBase : Selection + +void CardListBase::selectCard(const CardP& card, bool focus) { + selected_card = card; + CardSelectEvent ev(card); + ProcessEvent(ev); + if (focus) { + findSelectedCardPos(); + selectCurrentCard(); + } +} +/* +void CardListBase::selectCardPos(size_t pos, bool focus = true, bool force = false) { + if (selectedCardPos == pos && !force) return; // this card is already selected + if (pos < sortedCardList.size()) { + // only if there is something to select + selectCard(getCard(pos), false); + } else { + selectCard(CardP(), false); + } + selectedCardPos = Long(pos); + if (focus) selectCurrentCard(); +} +*/ +void CardListBase::findSelectedCardPos() { + // find the position of the selected card + long count = GetItemCount(); + for (long pos = 0 ; pos < count ; ++pos) { + if (sorted_card_list[pos] == selected_card) { + selected_card_pos = pos; + break; + } + } +} +void CardListBase::selectCurrentCard() { + if (GetItemCount() > 0) { + SetItemState(selected_card_pos, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, + wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); + } +} + +// ----------------------------------------------------------------------------- : CardListBase : Building the list + +// Comparison object for comparing cards +struct CardListBase::CardComparer { + CardComparer(CardListBase& cl) : cl(cl) {} + CardListBase& cl; // 'this' pointer + // Compare two cards using the current criterium and order + bool operator () (const CardP& a, const CardP& b) { + ValueP va = a->data[cl.sort_criterium]; + ValueP vb = b->data[cl.sort_criterium]; + if (cl.sort_ascending) { + if (!va || !vb) return va < vb; // got to do something, compare pointers + return smart_less( va->toString() , vb->toString() ); + } else { + if (!va || !vb) return vb < va; + return smart_less( vb->toString() , va->toString() ); + } + } +}; + +void CardListBase::sortList() { + sorted_card_list.clear(); + FOR_EACH(card, getCards()) { + sorted_card_list.push_back(card); + } + if (sort_criterium) { + sort(sorted_card_list.begin(), sorted_card_list.end(), CardComparer(*this)); + } +} + +void CardListBase::rebuild() { + ClearAll(); + column_fields.clear(); + selected_card_pos = -1; + // determine column order + map new_column_fields; + FOR_EACH(f, set->game->card_fields) { + ColumnSettings& cs = settings.columnSettingsFor(*set->game, *f); + if (cs.visible && f->card_list_allow) { + new_column_fields[cs.position] = f; + } + } + // add columns + FOR_EACH(f, new_column_fields) { + ColumnSettings& cs = settings.columnSettingsFor(*set->game, *f.second); + int align; + if (f.second->card_list_align == ALIGN_RIGHT) align = wxLIST_FORMAT_RIGHT; + else if (f.second->card_list_align == ALIGN_CENTER) align = wxLIST_FORMAT_CENTRE; + else align = wxLIST_FORMAT_LEFT; + InsertColumn((long)column_fields.size(), capitalize(f.second->card_list_name), align, cs.width); + column_fields.push_back(f.second); + } + // find field that determines color + color_style = findColorStyle(); + // determine sort settings + GameSettings& gs = settings.gameSettingsFor(*set->game); + sort_ascending = gs.sort_cards_ascending; + sort_criterium = FieldP(); + int i = 0; + FOR_EACH(f, column_fields) { + if (f->name == gs.sort_cards_by) { + // we are sorting by this column, store the field + sort_criterium = f; + // and display an arrow in the header + wxListItem li; + li.m_mask = wxLIST_MASK_IMAGE; + li.m_image = sort_ascending ? 0 : 1; // arrow up/down + SetColumn(i, li); + } + } + refreshList(); + // select a card if possible +// if (!getCards().empty()) { +// selectCardPos(0, true); +// } +} + +void CardListBase::refreshList() { + // ensure correct list size + long items = (long) getCards().size(); + SetItemCount(items); + // (re)sort the list + sortList(); + // refresh + RefreshItems(0, items - 1); + if (items == 0) Refresh(); + // select + findSelectedCardPos(); + selectCurrentCard(); +} + +ChoiceStyleP CardListBase::findColorStyle() { +/* FOR_EACH(s, set->default_stylesheet->card_style) { + ChoiceStyleP cs = dynamic_cast(s); + if (cs && cs->colors_card_list) { + return cs; + } + } +*/ + return ChoiceStyleP(); +} + +// ----------------------------------------------------------------------------- : CardListBase : Columns + +void CardListBase::storeColumns() { + if (!set) return; + // store column widths + int i = 0; + FOR_EACH(f, column_fields) { + ColumnSettings& cs = settings.columnSettingsFor(*set->game, *f); + cs.width = GetColumnWidth(i++); + } + // store sorting + GameSettings& gs = settings.gameSettingsFor(*set->game); + if (sort_criterium) gs.sort_cards_by = sort_criterium->name; + else gs.sort_cards_by = wxEmptyString; + gs.sort_cards_ascending = sort_ascending; +} +void CardListBase::selectColumns() { +// CardListColumnSelect wnd(this, set->game); +// if (wnd.ShowModal() == wxID_OK) { +// rebuild(); // columns have changed +// } +} + +// ----------------------------------------------------------------------------- : CardListBase : Item 'events' + +String CardListBase::OnGetItemText(long pos, long col) const { + if (col < 0 || (size_t)col >= column_fields.size()) { + // wx may give us non existing columns! + return wxEmptyString; + } + ValueP val = sorted_card_list[pos]->data[column_fields[col]]; + if (val) return val->toString(); + else return wxEmptyString; +} + +int CardListBase::OnGetItemImage(long pos) const { + return -1; +} + +wxListItemAttr* CardListBase::OnGetItemAttr(long pos) const { + if (!color_style) return nullptr; +// ChoiceValueP val = static_cast( sorted_car_list[cardPos]->data[color_field]); +// assert(val); +// itemAttr.textColour = colorStyle->choiceColors#(val->value); // if it doesn't exist we get black + return &itemAttr; +} + +// ----------------------------------------------------------------------------- : CardListBase : Window events + +void CardListBase::onColumnClick(wxListEvent& ev) { + FieldP new_sort_criterium = column_fields[ev.GetColumn()]; + if (sort_criterium == new_sort_criterium) { + if (sort_ascending) { + sort_ascending = false; // 2nd click on same column -> sort descending + } else { + sort_criterium.reset(); // 3rd click on same column -> don't sort + } + } else { + sort_ascending = true; + } + // Change image in column header + int i = 0; + FOR_EACH(f, column_fields) { + if (f == new_sort_criterium) { + wxListItem li; + li.m_mask = wxLIST_MASK_IMAGE; + li.m_image = sort_ascending ? 0 : 1; // arrow up/down + SetColumn(i, li); + } else if (f == sort_criterium) { + wxListItem li; + li.m_mask = wxLIST_MASK_IMAGE; + li.m_image = -1; // no sort icon + SetColumn(i, li); + } + } + sort_criterium = new_sort_criterium; + refreshList(); +} + +void CardListBase::onColumnRightClick(wxListEvent&) { + // show menu + wxMenu* m = new wxMenu; + m->Append(ID_SELECT_COLUMNS, _("&Select Columns..."), _("Select what columns should be shown and in what order.")); + PopupMenu(m); +} + +void CardListBase::onSelectColumns(wxCommandEvent&) { + selectColumns(); +} + +void CardListBase::onItemFocus(wxListEvent& ev) { +// selectCardPos(ev.GetIndex(), false); +} + +void CardListBase::onChar(wxKeyEvent& ev) { + if (ev.GetKeyCode() == WXK_DELETE) { +// set->actions.add(new_shared2(set.get(), card)); + } else if (ev.GetKeyCode() == WXK_TAB) { + // send a navigation event to our parent, to select another control + // we need this because tabs are not handled on the cards panel + wxNavigationKeyEvent nev; + nev.SetDirection(!ev.ShiftDown()); + GetParent()->ProcessEvent(nev); + } else { + ev.Skip(); + } +} + +void CardListBase::onDrag(wxMouseEvent& ev) { +// TODO +} + +// ----------------------------------------------------------------------------- : CardListBase : Event table + +BEGIN_EVENT_TABLE(CardListBase, wxListCtrl) + EVT_LIST_COL_CLICK (wxID_ANY, CardListBase::onColumnClick) + EVT_LIST_COL_RIGHT_CLICK (wxID_ANY, CardListBase::onColumnRightClick) + EVT_LIST_ITEM_FOCUSED (wxID_ANY, CardListBase::onItemFocus) + EVT_CHAR ( CardListBase::onChar) + EVT_MOTION ( CardListBase::onDrag) + EVT_MENU (ID_SELECT_COLUMNS, CardListBase::onSelectColumns) +END_EVENT_TABLE () diff --git a/src/gui/control/card_list.hpp b/src/gui/control/card_list.hpp new file mode 100644 index 00000000..d858ded4 --- /dev/null +++ b/src/gui/control/card_list.hpp @@ -0,0 +1,152 @@ +//+----------------------------------------------------------------------------+ +//| Description: Magic Set Editor - Program to make Magic (tm) cards | +//| Copyright: (C) 2001 - 2006 Twan van Laarhoven | +//| License: GNU General Public License 2 or later (see file COPYING) | +//+----------------------------------------------------------------------------+ + +#ifndef HEADER_GUI_CONTROL_CARD_LIST +#define HEADER_GUI_CONTROL_CARD_LIST + +// ----------------------------------------------------------------------------- : Includes + +#include +#include +#include + +DECLARE_POINTER_TYPE(ChoiceStyle); +DECLARE_POINTER_TYPE(Field); + +// ----------------------------------------------------------------------------- : Events + +DECLARE_EVENT_TYPE(EVENT_CARD_SELECT, ); +/// Handle CardSelectEvents +#define EVT_CARD_SELECT(id, handler) EVT_COMMAND(id, EVENT_CARD_SELECT, handler); + +/// The event of selecting a card +struct CardSelectEvent : public wxCommandEvent { + CardP card; ///< The selected card + inline CardSelectEvent(const CardP& card) + : wxCommandEvent(EVENT_CARD_SELECT), card(card) + {} +}; + +// ----------------------------------------------------------------------------- : CardListBase + +/// A list view of the cards in a set. +/* This class allows the cards to be sorted, and has a _('currentCard'), the selected card + * when a card is selected, it raises a CardSelectEvent, that will propage to the parent window. + * + * Note: (long) pos refers to position in the sorted_card_list, + * (size_t) index refers to the index in the actual card list (as returned by getCards). + * + * This class is an abstract base class for card lists, derived classes must overload: + * - getCard(index) + */ +class CardListBase : public wxListCtrl, public SetView { + public: + CardListBase(Window* parent, int id, int additional_style = 0); + ~CardListBase(); + + // --------------------------------------------------- : Selection + + inline CardP getCard() const { return selected_card; } + inline void setCard(const CardP& card) { selectCard(card); } + + /// Move the selection to the previous card (if possible) + void selectPrevious(); + /// Move the selection to the next card (if possible) + void selectNext(); + /// Is there a previous card to select? + bool canSelectPrevious(); + /// Is there a next card to select? + bool canSelectNext(); + + // --------------------------------------------------- : Clipboard + + bool canCut() const; + bool canCopy() const; + bool canPaste() const; + void doCut(); + void doCopy(); + void doPaste(); + + // --------------------------------------------------- : Set actions + + virtual void onBeforeChangeSet(); + virtual void onChangeSet(); + virtual void onAction(const Action&); + + // --------------------------------------------------- : The cards + protected: + /// What cards should be shown? + virtual vector& getCards() const; + + // --------------------------------------------------- : Item 'events' + + /// Get the text of an item in a specific column + /** Overrides a function from wxListCtrl */ + String OnGetItemText (long pos, long col) const; + /// Get the image of an item, by default no image is used + /** Overrides a function from wxListCtrl */ + int OnGetItemImage(long pos) const; + /// Get the color for an item + wxListItemAttr* OnGetItemAttr(long pos) const; + + // --------------------------------------------------- : Data + private: + CardP selected_card; ///< The currently selected card, or -1 if no card is selected + long selected_card_pos;///< Position of the selected card in the sorted_card_list + // display stuff + ChoiceStyleP color_style; ///< Style (and field) to use for text color (optional) + vector column_fields; ///< The field to use for each column (by column index) + // sorted list stuff + vector sorted_card_list; ///< Sorted list of cards, can be considered a map: pos->card + FieldP sort_criterium; ///< Field to sort by + bool sort_ascending; ///< Sort order + + mutable wxListItemAttr itemAttr; // for OnGetItemAttr + + /// Get a card by position + void getCard(long pos); + + /// Select a card, send an event to the parent + /** If focus then the card is also focused and selected in the actual control. + * This should abviously not be done when the card is selected because it was selected (leading to a loop). + */ + void selectCard(const CardP& card, bool focus = false); + /// Select a card at the specified position + void selectCardPos(long pos); + /// Find the position for the selected_card + void findSelectedCardPos(); + /// Actually select the card at selected_card_pos in the control + void selectCurrentCard(); + + /// Sorts the list by the current sorting criterium + void sortList(); + struct CardComparer; // for comparing cards + /// Rebuild the card list (clear all vectors and fill them again) + void rebuild(); + /// Refresh the card list (resort, refresh and reselect current item) + void refreshList(); + /// Find the field that determines the color, if any. + /** Note: Uses only fields from the set's default style */ + ChoiceStyleP findColorStyle(); + + /// Store the column sizes in the settings + void storeColumns(); + /// Open a dialog for selecting columns to be shown + void selectColumns(); + + // --------------------------------------------------- : Window events + DECLARE_EVENT_TABLE(); + + void onColumnClick (wxListEvent& ev); + void onColumnRightClick(wxListEvent& ev); + void onSelectColumns (wxCommandEvent& ev); + void onItemFocus (wxListEvent& ev); + void onChar (wxKeyEvent& ev); + void onDrag (wxMouseEvent& ev); +}; + +// ----------------------------------------------------------------------------- : EOF +#endif diff --git a/src/gui/set/panel.hpp b/src/gui/set/panel.hpp index 1c700f4a..74dc2a38 100644 --- a/src/gui/set/panel.hpp +++ b/src/gui/set/panel.hpp @@ -26,12 +26,9 @@ class SetWindowPanel : public wxPanel, public SetView { /// We will probably want to respond to set changes virtual void onSetChange() {} - // --------------------------------------------------- : Meta information - - virtual String shortName() { return _(""); } ///< for tab bar - virtual String longName() { return shortName(); } ///< for menu - virtual String description() { return _(""); } ///< for status bar - virtual String helpFile() { return _(""); } ///< help file to use when this panel is active +// // --------------------------------------------------- : Meta information +// +// virtual String helpFile() { return _(""); } ///< help file to use when this panel is active // --------------------------------------------------- : UI @@ -49,29 +46,29 @@ class SetWindowPanel : public wxPanel, public SetView { // --------------------------------------------------- : Actions/Events /// Should return true if this panel wants to get focus to show an action - virtual bool wantsToHandle(const Action&) { return false; } + virtual bool wantsToHandle(const Action&) const { return false; } /// Handle an action that changes the current set virtual void onAction(const Action&) {} /// The settings for rendering cards have changed, refresh card viewers/editors virtual void onRenderSettingsChange() {} // --------------------------------------------------- : Clipboard - virtual bool canPaste() { return false; } ///< Is pasting possible? - virtual bool canCopy() { return false; } ///< Is copying possible? - virtual bool canCut() { return canCopy(); } ///< Is cutting possible? + virtual bool canPaste() const { return false; } ///< Is pasting possible? + virtual bool canCopy() const { return false; } ///< Is copying possible? + virtual bool canCut() const { return canCopy(); } ///< Is cutting possible? virtual void doPaste() {} ///< Paste the contents of the clipboard virtual void doCopy() {} ///< Copy the selection to the clipboard virtual void doCut() {} ///< Cut the selection to the clipboard // --------------------------------------------------- : Searching (find/replace) - virtual bool canFind() { return false; } ///< Is finding possible? - virtual bool canReplace() { return false; } ///< Is replacing possible? + virtual bool canFind() const { return false; } ///< Is finding possible? + virtual bool canReplace() const { return false; } ///< Is replacing possible? virtual bool doFind(wxFindReplaceData&) { return false; } ///< Find the next math virtual bool doReplace(wxFindReplaceData&) { return false; } ///< Replace the next match // --------------------------------------------------- : Selection - virtual CardP selectedCard() { return CardP(); } ///< Return the currently selected card, or CardP() - virtual void selectCard(CardP card) {} ///< Switch the view to another card + virtual CardP selectedCard() const { return CardP(); } ///< Return the currently selected card, or CardP() + virtual void selectCard(CardP card) {} ///< Switch the view to another card protected: // --------------------------------------------------- : Helper functions for UI diff --git a/src/gui/set/set_info_panel.hpp b/src/gui/set/set_info_panel.hpp index 7806fd5e..0ec989f1 100644 --- a/src/gui/set/set_info_panel.hpp +++ b/src/gui/set/set_info_panel.hpp @@ -10,9 +10,14 @@ // ----------------------------------------------------------------------------- : Includes #include +#include -// ----------------------------------------------------------------------------- : +// ----------------------------------------------------------------------------- : SetInfoPanel +class SetInfoPanel : public SetWindowPanel { + public: + SetInfoPanel(Window* parent, int id); +}; // ----------------------------------------------------------------------------- : EOF #endif diff --git a/src/gui/set/style_panel.cpp b/src/gui/set/style_panel.cpp index dafa3d94..86584343 100644 --- a/src/gui/set/style_panel.cpp +++ b/src/gui/set/style_panel.cpp @@ -7,5 +7,18 @@ // ----------------------------------------------------------------------------- : Includes #include +#include +#include -// ----------------------------------------------------------------------------- : +// ----------------------------------------------------------------------------- : StylePanel + +StylePanel::StylePanel(Window* parent, int id) + : SetWindowPanel(parent, id) +{ + PackageList* list = new PackageList(this, wxID_ANY); + list->showData(); + + wxSizer* s = new wxBoxSizer(wxHORIZONTAL); + s->Add(list, 1, wxEXPAND); + SetSizer(s); +} diff --git a/src/gui/set/style_panel.hpp b/src/gui/set/style_panel.hpp index 74fd60bf..5de7ea6d 100644 --- a/src/gui/set/style_panel.hpp +++ b/src/gui/set/style_panel.hpp @@ -10,9 +10,14 @@ // ----------------------------------------------------------------------------- : Includes #include +#include -// ----------------------------------------------------------------------------- : +// ----------------------------------------------------------------------------- : StylePanel +class StylePanel : public SetWindowPanel { + public: + StylePanel(Window* parent, int id); +}; // ----------------------------------------------------------------------------- : EOF #endif diff --git a/src/gui/set/window.cpp b/src/gui/set/window.cpp index 13c2035a..021585e5 100644 --- a/src/gui/set/window.cpp +++ b/src/gui/set/window.cpp @@ -113,16 +113,16 @@ SetWindow::SetWindow(Window* parent, const SetP& set) // NOTE: place the CardsPanel last in the panels list, // this way the card list is the last to be told of a set change // this way everyone else already uses the new set when it sends a CardSelectEvent -// addPanel(menuWindow, tabBar, new CardsPanel (this, wxID_ANY), 4, _("F5")); +// addPanel(menuWindow, tabBar, new CardsPanel (this, wxID_ANY), 4, _("F5"), _("Cards"), _("Cards")); // addPanel(menuWindow, tabBar, new SetInfoPanel (this, wxID_ANY), 0, _("F6")); -// addPanel(menuWindow, tabBar, new StylePanel (this, wxID_ANY), 1, _("F7")); + addPanel(menuWindow, tabBar, new StylePanel (this, wxID_ANY), 1, _("F7"), _("Style"), _("Style"), _("Chnage the style of cards")); // addPanel(menuWindow, tabBar, new KeywordsPanel(this, wxID_ANY), 2, _("F8")); -// addPanel(menuWindow, tabBar, new StatsPanel (this, wxID_ANY), 3, _("F9")); +// 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(idWindowMin + 4); // select cards panel - addPanel(menuWindow, tabBar, new StatsPanel (this, wxID_ANY), 0, _("F9")); - selectPanel(ID_WINDOW_MIN); // test + addPanel(menuWindow, tabBar, new StatsPanel (this, wxID_ANY), 0, _("F9"), _("Stats"), _("Statistics"), _("Show statistics about the cards in the set")); + selectPanel(ID_WINDOW_MIN+1); // test // loose ends tabBar->Realize(); @@ -162,15 +162,16 @@ SetWindow::~SetWindow() { // ----------------------------------------------------------------------------- : Panel managment -void SetWindow::addPanel(wxMenu* windowMenu, wxToolBar* tabBar, SetWindowPanel* panel, UInt pos, const String& shortcut) { +void SetWindow::addPanel(wxMenu* windowMenu, wxToolBar* tabBar, SetWindowPanel* panel, UInt pos, + const String& shortcut, const String& shortName, const String& longName, const String& description) { // insert in list if (panels.size() <= pos) panels.resize(pos + 1); panels[pos] = panel; // add to tab bar int id = ID_WINDOW_MIN + pos; - tabBar->AddTool(id,panel->shortName(), wxNullBitmap, wxNullBitmap, wxITEM_CHECK, panel->longName(), panel->description()); + tabBar->AddTool(id, shortName, wxNullBitmap, wxNullBitmap, wxITEM_CHECK, longName, description); // add to menu bar - windowMenu->AppendCheckItem(id, panel->longName() + _("\t") + shortcut, panel->description()); + windowMenu->AppendCheckItem(id, longName + _("\t") + shortcut, description); // add to sizer GetSizer()->Add(panel, 1, wxEXPAND); } diff --git a/src/gui/set/window.hpp b/src/gui/set/window.hpp index 8ab2aada..4397cbd8 100644 --- a/src/gui/set/window.hpp +++ b/src/gui/set/window.hpp @@ -55,7 +55,8 @@ class SetWindow : public wxFrame, public SetView { /// Add a panel to the window, as well as to the menu and tab bar /** The position only determines the order in which events will be send. */ - void addPanel(wxMenu* windowMenu, wxToolBar* tabBar, SetWindowPanel* panel, UInt pos, const String& shortcut); + void addPanel(wxMenu* windowMenu, wxToolBar* tabBar, SetWindowPanel* panel, UInt pos, + const String& shortcut, const String& shortName, const String& longName, const String& description); /// Select a panel, based on a tab id void selectPanel(int id); diff --git a/src/mse.vcproj b/src/mse.vcproj index b5bee2a4..615ca016 100644 --- a/src/mse.vcproj +++ b/src/mse.vcproj @@ -368,6 +368,18 @@ + + + + + + + + - - @@ -671,12 +679,42 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/script/scriptable.hpp b/src/script/scriptable.hpp index 8ff92849..17e9f100 100644 --- a/src/script/scriptable.hpp +++ b/src/script/scriptable.hpp @@ -12,6 +12,7 @@ #include #include #include +#include