Commit 57d5ead3 authored by twanvl's avatar twanvl

Changed scroll size of PackageList;

Added 'collapse' option for card notes;
Made variant of  DECLARE_TYPEOF for maps (two template arguments).
parent deafb39a
...@@ -9,10 +9,8 @@ ...@@ -9,10 +9,8 @@
#include <data/action/symbol.hpp> #include <data/action/symbol.hpp>
#include <data/action/symbol_part.hpp> #include <data/action/symbol_part.hpp>
typedef pair<SymbolPartP,SymbolPartCombine> pair_part_combine_t; DECLARE_TYPEOF_COLLECTION2(pair<SymbolPartP,SymbolPartCombine>);
typedef pair<SymbolPartP,size_t > pair_part_size_t; DECLARE_TYPEOF_COLLECTION2(pair<SymbolPartP,size_t >);
DECLARE_TYPEOF_COLLECTION(pair_part_combine_t);
DECLARE_TYPEOF_COLLECTION(pair_part_size_t);
DECLARE_TYPEOF_COLLECTION(SymbolPartP); DECLARE_TYPEOF_COLLECTION(SymbolPartP);
DECLARE_TYPEOF_COLLECTION(ControlPointP); DECLARE_TYPEOF_COLLECTION(ControlPointP);
......
...@@ -13,8 +13,7 @@ ...@@ -13,8 +13,7 @@
#include <util/reflect.hpp> #include <util/reflect.hpp>
DECLARE_TYPEOF_COLLECTION(FieldP); DECLARE_TYPEOF_COLLECTION(FieldP);
typedef IndexMap<FieldP,ValueP> IndexMap_FieldP_ValueP; DECLARE_TYPEOF_NO_REV2(IndexMap<FieldP,ValueP>);
DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_ValueP);
// ----------------------------------------------------------------------------- : Card // ----------------------------------------------------------------------------- : Card
......
...@@ -10,8 +10,7 @@ ...@@ -10,8 +10,7 @@
#include <util/io/package.hpp> #include <util/io/package.hpp>
DECLARE_TYPEOF_COLLECTION(ChoiceField::ChoiceP); DECLARE_TYPEOF_COLLECTION(ChoiceField::ChoiceP);
typedef map<String,ScriptableImage> map_String_ScriptableImage; DECLARE_TYPEOF2(map<String,ScriptableImage>);
DECLARE_TYPEOF(map_String_ScriptableImage);
// ----------------------------------------------------------------------------- : ChoiceField // ----------------------------------------------------------------------------- : ChoiceField
......
...@@ -22,6 +22,7 @@ IMPLEMENT_DYNAMIC_ARG(Game*, game_for_reading, nullptr); ...@@ -22,6 +22,7 @@ IMPLEMENT_DYNAMIC_ARG(Game*, game_for_reading, nullptr);
Game::Game() Game::Game()
: dependencies_initialized(false) : dependencies_initialized(false)
, has_keywords(false)
{} {}
GameP Game::byName(const String& name) { GameP Game::byName(const String& name) {
...@@ -42,6 +43,7 @@ IMPLEMENT_REFLECTION(Game) { ...@@ -42,6 +43,7 @@ IMPLEMENT_REFLECTION(Game) {
REFLECT(card_fields); REFLECT(card_fields);
REFLECT(statistics_dimensions); REFLECT(statistics_dimensions);
REFLECT(statistics_categories); REFLECT(statistics_categories);
REFLECT(has_keywords);
REFLECT(keyword_parameter_types); REFLECT(keyword_parameter_types);
REFLECT(keyword_modes); REFLECT(keyword_modes);
REFLECT(keywords); REFLECT(keywords);
......
...@@ -39,6 +39,7 @@ class Game : public Packaged { ...@@ -39,6 +39,7 @@ class Game : public Packaged {
vector<StatsDimensionP> statistics_dimensions; ///< (Additional) statistics dimensions vector<StatsDimensionP> statistics_dimensions; ///< (Additional) statistics dimensions
vector<StatsCategoryP> statistics_categories; ///< (Additional) statistics categories vector<StatsCategoryP> statistics_categories; ///< (Additional) statistics categories
bool has_keywords; ///< Does this game use keywords?
vector<KeywordParamP> keyword_parameter_types;///< Types of keyword parameters vector<KeywordParamP> keyword_parameter_types;///< Types of keyword parameters
vector<KeywordModeP> keyword_modes; ///< Modes of keywords vector<KeywordModeP> keyword_modes; ///< Modes of keywords
vector<KeywordP> keywords; ///< Keywords for use in text vector<KeywordP> keywords; ///< Keywords for use in text
......
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
// ----------------------------------------------------------------------------- : Includes // ----------------------------------------------------------------------------- : Includes
#include <data/keyword.hpp> #include <data/keyword.hpp>
#include <util/tagged_string.hpp>
class KeywordTrie;
DECLARE_TYPEOF2(map<Char, KeywordTrie*>);
// ----------------------------------------------------------------------------- : Reflection // ----------------------------------------------------------------------------- : Reflection
...@@ -57,4 +61,106 @@ IMPLEMENT_REFLECTION(Keyword) { ...@@ -57,4 +61,106 @@ IMPLEMENT_REFLECTION(Keyword) {
REFLECT(mode); REFLECT(mode);
} }
// ----------------------------------------------------------------------------- : KeywordTrie
/// A node in a trie to match keywords
class KeywordTrie {
public:
KeywordTrie();
~KeywordTrie();
map<Char, KeywordTrie*> 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 // ----------------------------------------------------------------------------- : Using keywords
KeywordDatabaseP new_keyword_database() {
return new_shared<KeywordDatabase>();
}
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, _("<atom-keyword>"));
// 2. Process keywords
// TODO
return s;
}
...@@ -27,6 +27,7 @@ class KeywordParam { ...@@ -27,6 +27,7 @@ class KeywordParam {
String match; ///< Uncompiled regex String match; ///< Uncompiled regex
wxRegEx matchRe; ///< Regular expression to match wxRegEx matchRe; ///< Regular expression to match
OptionalScript script; ///< Transformation of the value for showing in the reminder text OptionalScript script; ///< Transformation of the value for showing in the reminder text
String example; ///< Example for preview dialog
DECLARE_REFLECTION(); DECLARE_REFLECTION();
}; };
...@@ -68,10 +69,24 @@ class Keyword { ...@@ -68,10 +69,24 @@ class Keyword {
DECLARE_REFLECTION(); DECLARE_REFLECTION();
}; };
// ----------------------------------------------------------------------------- : Using keywords // ----------------------------------------------------------------------------- : 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 /// Expand/update all keywords in the given string
String expand_keywords(const String& text); String expand_keywords(const KeywordDatabase& db, const String& text);
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
#endif #endif
...@@ -19,8 +19,7 @@ ...@@ -19,8 +19,7 @@
#include <wx/sstream.h> #include <wx/sstream.h>
DECLARE_TYPEOF_COLLECTION(CardP); DECLARE_TYPEOF_COLLECTION(CardP);
typedef IndexMap<FieldP,ValueP> IndexMap_FieldP_ValueP; DECLARE_TYPEOF_NO_REV2(IndexMap<FieldP,ValueP>);
DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_ValueP);
// ----------------------------------------------------------------------------- : Set // ----------------------------------------------------------------------------- : Set
......
...@@ -64,18 +64,26 @@ END_EVENT_TABLE () ...@@ -64,18 +64,26 @@ END_EVENT_TABLE ()
// ----------------------------------------------------------------------------- : Button with image and hover effect // ----------------------------------------------------------------------------- : Button with image and hover effect
HoverButton::HoverButton(Window* parent, int id, const String& name) HoverButton::HoverButton(Window* parent, int id, const String& name, const Color& background)
: wxControl(parent, id, wxDefaultPosition, wxDefaultSize, wxNO_BORDER) : 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")))
, hover(false), focus(false), mouse_down(false), key_down(false) , hover(false), focus(false), mouse_down(false), key_down(false)
, last_drawn(nullptr) , last_drawn(nullptr)
, background(background)
{ {
loadBitmaps(name);
SetSize(DoGetBestSize()); 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&) { void HoverButton::onMouseEnter(wxMouseEvent&) {
hover = true; hover = true;
refreshIfNeeded(); refreshIfNeeded();
...@@ -151,10 +159,10 @@ void HoverButton::draw(DC& dc) { ...@@ -151,10 +159,10 @@ void HoverButton::draw(DC& dc) {
// clear background (for transparent button images) // clear background (for transparent button images)
wxSize ws = GetClientSize(); wxSize ws = GetClientSize();
dc.SetPen(*wxTRANSPARENT_PEN); 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()); dc.DrawRectangle(0, 0, ws.GetWidth(), ws.GetHeight());
// draw button // draw button
dc.DrawBitmap(*toDraw(), 0, 0); dc.DrawBitmap(*toDraw(), 0, 0, true);
last_drawn = toDraw(); last_drawn = toDraw();
} }
int HoverButton::drawDelta() const { int HoverButton::drawDelta() const {
......
...@@ -30,16 +30,25 @@ class AboutWindow : public wxDialog { ...@@ -30,16 +30,25 @@ class AboutWindow : public wxDialog {
// ----------------------------------------------------------------------------- : Button with image and hover effect // ----------------------------------------------------------------------------- : 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 { class HoverButton : public wxControl {
public: 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: private:
DECLARE_EVENT_TABLE(); 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; bool hover, focus, mouse_down, key_down;
Color background;
void onMouseEnter(wxMouseEvent&); void onMouseEnter(wxMouseEvent&);
void onMouseLeave(wxMouseEvent&); void onMouseLeave(wxMouseEvent&);
......
...@@ -26,10 +26,8 @@ ...@@ -26,10 +26,8 @@
DECLARE_TYPEOF_COLLECTION(CardP); DECLARE_TYPEOF_COLLECTION(CardP);
DECLARE_TYPEOF_COLLECTION(FieldP); DECLARE_TYPEOF_COLLECTION(FieldP);
DECLARE_POINTER_TYPE(ChoiceValue); DECLARE_POINTER_TYPE(ChoiceValue);
typedef map<int,FieldP> map_int_FieldP; DECLARE_TYPEOF2(map<int,FieldP>);
DECLARE_TYPEOF(map_int_FieldP); DECLARE_TYPEOF_NO_REV2(IndexMap<FieldP,StyleP>);
typedef IndexMap<FieldP,StyleP> IndexMap_FieldP_StyleP;
DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_StyleP);
// ----------------------------------------------------------------------------- : Events // ----------------------------------------------------------------------------- : Events
......
...@@ -17,37 +17,40 @@ DEFINE_EVENT_TYPE(EVENT_GALLERY_ACTIVATE); ...@@ -17,37 +17,40 @@ DEFINE_EVENT_TYPE(EVENT_GALLERY_ACTIVATE);
// ----------------------------------------------------------------------------- : GalleryList // ----------------------------------------------------------------------------- : GalleryList
const int MARGIN = 1; // margin between items const int MARGIN = 1; // margin between items (excluding border)
const int BORDER = 1; // margin between items const int BORDER = 1; // border aroung items
const int SPACING = MARGIN + 2*BORDER; // distance between items
GalleryList::GalleryList(Window* parent, int id, int direction) GalleryList::GalleryList(Window* parent, int id, int direction)
: wxScrolledWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | (direction == wxHORIZONTAL ? wxHSCROLL : wxVSCROLL) ) : wxScrolledWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | (direction == wxHORIZONTAL ? wxHSCROLL : wxVSCROLL) )
, selection(NO_SELECTION) , selection(NO_SELECTION)
, direction(direction) , direction(direction)
, scroll_increment(10)
{} {}
void GalleryList::update() { void GalleryList::update() {
const int w = (int)item_size.width + MARGIN + 2*BORDER; const int w = item_size.x + SPACING;
const int h = (int)item_size.height + MARGIN + 2*BORDER; const int h = item_size.y + SPACING;
// resize and scroll // resize and scroll
if (direction == wxHORIZONTAL) { if (direction == wxHORIZONTAL) {
SetVirtualSize(w * (int)itemCount() + MARGIN, h + MARGIN); SetVirtualSize(w * (int)itemCount() + MARGIN, h + MARGIN);
SetScrollRate(w, 0); SetScrollRate(scroll_increment, 0);
} else { // wxVERTICAL } else { // wxVERTICAL
SetVirtualSize(w, h * (int)itemCount() + MARGIN + MARGIN); SetVirtualSize(w + MARGIN, h * (int)itemCount() + MARGIN);
SetScrollRate(0, h); SetScrollRate(0, scroll_increment);
} }
// ensure selected item + its margin is visible // ensure selected item + its margin is visible
if (selection < itemCount()) { if (selection < itemCount()) {
int x, y, cw, ch; int x, y, cw, ch;
GetViewStart (&x, &y); GetViewStart (&x, &y);
GetClientSize(&cw, &ch); GetClientSize(&cw, &ch);
cw = (cw - w + 1) / w; ch = (ch - h + 1) / h; cw = (cw - scroll_increment + 1) / scroll_increment;
RealPoint pos = itemPos(selection); ch = (ch - scroll_increment + 1) / scroll_increment;
x = min(x, (int)selection); wxPoint pos = itemPos(selection);
y = min(y, (int)selection); x = min(x, (int)(selection * w) / scroll_increment);
x = max(x + cw, (int)selection) - cw; y = min(y, (int)(selection * h) / scroll_increment);
y = max(y + ch, (int)selection) - ch; 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); Scroll(x,y);
} }
// redraw // redraw
...@@ -56,21 +59,21 @@ void GalleryList::update() { ...@@ -56,21 +59,21 @@ void GalleryList::update() {
size_t GalleryList::findItem(const wxMouseEvent& ev) const { size_t GalleryList::findItem(const wxMouseEvent& ev) const {
if (direction == wxHORIZONTAL) { if (direction == wxHORIZONTAL) {
int x, w = (int)item_size.width + MARGIN + 2*BORDER; int x, w = item_size.x + SPACING;
GetViewStart (&x, 0); GetViewStart (&x, 0);
return static_cast<size_t>( x + ev.GetX() / w ); return static_cast<size_t>( max(0, x * scroll_increment + ev.GetX() - MARGIN) / w );
} else { // wxVERTICAL } else { // wxVERTICAL
int y, h = (int)item_size.height + MARGIN + 2*BORDER; int y, h = item_size.y + SPACING;
GetViewStart (0, &y); GetViewStart (0, &y);
return static_cast<size_t>( y + ev.GetY() / h ); return static_cast<size_t>( 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) { 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 { } 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) { ...@@ -117,8 +120,8 @@ void GalleryList::onChar(wxKeyEvent& ev) {
wxSize GalleryList::DoGetBestSize() const { wxSize GalleryList::DoGetBestSize() const {
wxSize ws = GetSize(), cs = GetClientSize(); wxSize ws = GetSize(), cs = GetClientSize();
const int w = int(item_size.width) + 2*MARGIN + 2*BORDER; const int w = item_size.x + SPACING;
const int h = int(item_size.height) + 2*MARGIN + 2*BORDER; const int h = item_size.y + SPACING;
return wxSize(w, h) + ws - cs; return wxSize(w, h) + ws - cs;
} }
...@@ -136,15 +139,15 @@ void GalleryList::OnDraw(DC& dc) { ...@@ -136,15 +139,15 @@ void GalleryList::OnDraw(DC& dc) {
GetViewStart(&x, &y); GetViewStart(&x, &y);
GetClientSize(&cw, &ch); GetClientSize(&cw, &ch);
if (direction == wxHORIZONTAL) { if (direction == wxHORIZONTAL) {
dx = int(item_size.width) + MARGIN + 2*BORDER; dx = item_size.x + MARGIN + 2*BORDER;
dy = 0; dy = 0;
start = (size_t) x; start = (size_t) max(0, x * scroll_increment - MARGIN) / dx;
end = (size_t) (start + cw / dx + 1); end = (size_t) max(0, x * scroll_increment - MARGIN + cw + dx) / dx;
} else { } else {
dx = 0; dx = 0;
dy = int(item_size.height) + MARGIN + 2*BORDER; dy = item_size.y + MARGIN + 2*BORDER;
start = (size_t) y; start = (size_t) max(0, y * scroll_increment - MARGIN) / dy;
end = (size_t) (start + ch / dy + 1); end = (size_t) max(0, y * scroll_increment - MARGIN + ch + dy) / dy;
} }
end = min(end, itemCount()); end = min(end, itemCount());
// clear background // clear background
...@@ -161,10 +164,10 @@ void GalleryList::OnDraw(DC& dc) { ...@@ -161,10 +164,10 @@ void GalleryList::OnDraw(DC& dc) {
Color c = selected ? wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT) : unselected; Color c = selected ? wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT) : unselected;
dc.SetPen(c); dc.SetPen(c);
dc.SetBrush(saturate(lerp(background, c, 0.3), selected ? 0.5 : 0)); dc.SetBrush(saturate(lerp(background, c, 0.3), selected ? 0.5 : 0));
RealPoint pos = itemPos(i); wxPoint 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); dc.DrawRectangle(pos.x - BORDER, pos.y - BORDER, item_size.x + 2*BORDER, item_size.y + 2*BORDER);
// draw item // draw item
drawItem(dc, int(pos.x), int(pos.y), i, selected); drawItem(dc, pos.x, pos.y, i, selected);
} }
} }
......
...@@ -36,9 +36,10 @@ class GalleryList : public wxScrolledWindow { ...@@ -36,9 +36,10 @@ class GalleryList : public wxScrolledWindow {
protected: protected:
static const size_t NO_SELECTION = (size_t)-1; static const size_t NO_SELECTION = (size_t)-1;
size_t selection; ///< The selected item, or NO_SELECTION if there is no selection size_t selection; ///< The selected item, or NO_SELECTION if there is no selection
RealSize item_size; ///< The size of a single item wxSize item_size; ///< The size of a single item
int direction; ///< Direction of the list, can be wxHORIZONTAL or wxVERTICAL 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 /// Redraw the list after changing the selection or the number of items
void update(); void update();
...@@ -63,7 +64,7 @@ class GalleryList : public wxScrolledWindow { ...@@ -63,7 +64,7 @@ class GalleryList : public wxScrolledWindow {
/// Find the item corresponding to the given location /// Find the item corresponding to the given location
size_t findItem(const wxMouseEvent&) const; size_t findItem(const wxMouseEvent&) const;
/// Find the coordinates of an item /// Find the coordinates of an item
RealPoint itemPos(size_t item) const; wxPoint itemPos(size_t item) const;
protected: protected:
/// Send an event /// Send an event
void sendEvent(WXTYPE type); void sendEvent(WXTYPE type);
......
...@@ -15,8 +15,7 @@ DECLARE_TYPEOF_COLLECTION(GraphAxisP); ...@@ -15,8 +15,7 @@ DECLARE_TYPEOF_COLLECTION(GraphAxisP);
DECLARE_TYPEOF_COLLECTION(GraphElementP); DECLARE_TYPEOF_COLLECTION(GraphElementP);
DECLARE_TYPEOF_COLLECTION(GraphGroup); DECLARE_TYPEOF_COLLECTION(GraphGroup);
DECLARE_TYPEOF_COLLECTION(int); DECLARE_TYPEOF_COLLECTION(int);
typedef map<String,UInt> map_String_UInt; DECLARE_TYPEOF2(map<String,UInt>);
DECLARE_TYPEOF(map_String_UInt);
// ----------------------------------------------------------------------------- : Events // ----------------------------------------------------------------------------- : Events
......
...@@ -12,8 +12,7 @@ ...@@ -12,8 +12,7 @@
#include <data/stylesheet.hpp> #include <data/stylesheet.hpp>
DECLARE_TYPEOF_COLLECTION(ValueViewerP); DECLARE_TYPEOF_COLLECTION(ValueViewerP);
typedef IndexMap<FieldP,StyleP> IndexMap_FieldP_StyleP; DECLARE_TYPEOF_NO_REV2(IndexMap<FieldP,StyleP>);
DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_StyleP);
// ----------------------------------------------------------------------------- : NativeLookEditor // ----------------------------------------------------------------------------- : NativeLookEditor
......
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
PackageList::PackageList(Window* parent, int id, int direction) PackageList::PackageList(Window* parent, int id, int direction)
: GalleryList(parent, id, direction) : GalleryList(parent, id, direction)
{ {
item_size = wxSize(110, 150); item_size = wxSize(108, 150);
SetThemeEnabled(true);
} }
size_t PackageList::itemCount() const { size_t PackageList::itemCount() const {
...@@ -29,7 +30,7 @@ void PackageList::drawItem(DC& dc, int x, int y, size_t item, bool selected) { ...@@ -29,7 +30,7 @@ void PackageList::drawItem(DC& dc, int x, int y, size_t item, bool selected) {
int w, h; int w, h;
// draw image // draw image
if (d.image.Ok()) { 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 // draw short name
dc.SetFont(wxFont(12,wxSWISS,wxNORMAL,wxBOLD,false,_("Arial"))); dc.SetFont(wxFont(12,wxSWISS,wxNORMAL,wxBOLD,false,_("Arial")));
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <gui/control/image_card_list.hpp> #include <gui/control/image_card_list.hpp>
#include <gui/control/card_editor.hpp> #include <gui/control/card_editor.hpp>
#include <gui/control/text_ctrl.hpp> #include <gui/control/text_ctrl.hpp>
#include <gui/about_window.hpp>
#include <gui/icon_menu.hpp> #include <gui/icon_menu.hpp>
#include <gui/util.hpp> #include <gui/util.hpp>
#include <data/set.hpp> #include <data/set.hpp>
...@@ -26,19 +27,23 @@ CardsPanel::CardsPanel(Window* parent, int id) ...@@ -26,19 +27,23 @@ CardsPanel::CardsPanel(Window* parent, int id)
{ {
// init controls // init controls
wxPanel* notesP; wxPanel* notesP;
wxSplitterWindow* splitter;
editor = new CardEditor(this, ID_EDITOR); editor = new CardEditor(this, ID_EDITOR);
splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0); splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
card_list = new ImageCardList(splitter, ID_CARD_LIST); card_list = new ImageCardList(splitter, ID_CARD_LIST);
notesP = new Panel(splitter, wxID_ANY); notesP = new Panel(splitter, wxID_ANY);
notes = new TextCtrl(notesP, ID_NOTES); 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 // init sizer for notes panel
wxSizer* sn = new wxBoxSizer(wxVERTICAL); 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); sn->Add(notes, 1, wxEXPAND | wxTOP, 2);
notesP->SetSizer(sn); notesP->SetSizer(sn);
// init splitter // init splitter
splitter->SetMinimumPaneSize(14); splitter->SetMinimumPaneSize(15);
splitter->SetSashGravity(1.0); splitter->SetSashGravity(1.0);
splitter->SplitHorizontally(card_list, notesP, -40); splitter->SplitHorizontally(card_list, notesP, -40);
// init sizer // init sizer
...@@ -162,10 +167,15 @@ void CardsPanel::onUpdateUI(wxUpdateUIEvent& ev) { ...@@ -162,10 +167,15 @@ void CardsPanel::onUpdateUI(wxUpdateUIEvent& ev) {
} }
break; break;
} }
case ID_COLLAPSE_NOTES: {
bool collapse = notes->GetSize().y > 0;
collapse_notes->loadBitmaps(collapse ? _("btn_collapse") : _("btn_expand"));
break;
}
case ID_INSERT_SYMBOL: { case ID_INSERT_SYMBOL: {
wxMenu* menu = editor->getMenu(ID_INSERT_SYMBOL); wxMenu* menu = editor->getMenu(ID_INSERT_SYMBOL);
ev.Enable(menu); ev.Enable(menu);
if (insertSymbolMenu->GetSubMenu() != menu || menu->GetParent() != menuFormat) { if (insertSymbolMenu->GetSubMenu() != menu || (menu && menu->GetParent() != menuFormat)) {
// re-add the menu // re-add the menu
menuFormat->Remove(insertSymbolMenu); menuFormat->Remove(insertSymbolMenu);
insertSymbolMenu->SetSubMenu(menu); insertSymbolMenu->SetSubMenu(menu);
...@@ -211,6 +221,17 @@ void CardsPanel::onCommand(int id) { ...@@ -211,6 +221,17 @@ void CardsPanel::onCommand(int id) {
break; 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: { default: {
if (id >= ID_INSERT_SYMBOL_MENU_MIN && id <= ID_INSERT_SYMBOL_MENU_MAX) { if (id >= ID_INSERT_SYMBOL_MENU_MIN && id <= ID_INSERT_SYMBOL_MENU_MAX) {
// pass on to editor // pass on to editor
......
...@@ -17,6 +17,7 @@ class ImageCardList; ...@@ -17,6 +17,7 @@ class ImageCardList;
class DataEditor; class DataEditor;
class TextCtrl; class TextCtrl;
class IconMenu; class IconMenu;
class HoverButton;
// ----------------------------------------------------------------------------- : CardsPanel // ----------------------------------------------------------------------------- : CardsPanel
...@@ -94,6 +95,7 @@ class CardsPanel : public SetWindowPanel { ...@@ -94,6 +95,7 @@ class CardsPanel : public SetWindowPanel {
DataEditor* editor; DataEditor* editor;
ImageCardList* card_list; ImageCardList* card_list;
TextCtrl* notes; TextCtrl* notes;
HoverButton* collapse_notes;
// --------------------------------------------------- : Menus & tools // --------------------------------------------------- : Menus & tools
IconMenu* menuCard, *menuFormat; IconMenu* menuCard, *menuFormat;
......
...@@ -20,10 +20,23 @@ class KeywordList : public wxListView { ...@@ -20,10 +20,23 @@ class KeywordList : public wxListView {
/// Set the list of keywords to show /// Set the list of keywords to show
void setData(vector<KeywordP>& dat); void setData(vector<KeywordP>& dat);
// --------------------------------------------------- : Selection
inline KeywordP getKeyword() const { return selected_keyword; }
inline void setKeyword(const KeywordP& kw) { /* TODO */ }
bool canSelectPrevious() const; bool canSelectPrevious() const;
bool canSelectNext() const; bool canSelectNext() const;
void selectPrevious(); void selectPrevious();
void selectNext(); 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 // ----------------------------------------------------------------------------- : KeywordsPanel
......
...@@ -12,12 +12,16 @@ ...@@ -12,12 +12,16 @@
#include <util/prec.hpp> #include <util/prec.hpp>
#include <gui/set/panel.hpp> #include <gui/set/panel.hpp>
class KeywordList;
// ----------------------------------------------------------------------------- : KeywordsPanel // ----------------------------------------------------------------------------- : KeywordsPanel
/// A panel for listing and editing the keywords in a set /// A panel for listing and editing the keywords in a set
class KeywordsPanel : public SetWindowPanel { class KeywordsPanel : public SetWindowPanel {
public: public:
KeywordsPanel(Window* parent, int id); KeywordsPanel(Window* parent, int id);
private:
KeywordList* list;
}; };
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
......
...@@ -72,7 +72,7 @@ void StatCategoryList::drawItem(DC& dc, int x, int y, size_t item, bool selected ...@@ -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); dc.DrawBitmap(cat.icon, x+1, y+1);
} }
// draw name // 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); String str = capitalize(cat.name);
// dc.SetFont(wxFont(9.5 * text_scaling, wxSWISS, wxNORMAL, wxNORMAL, false,_("Arial"))); // dc.SetFont(wxFont(9.5 * text_scaling, wxSWISS, wxNORMAL, wxNORMAL, false,_("Arial")));
dc.SetFont(*wxNORMAL_FONT); dc.SetFont(*wxNORMAL_FONT);
......
...@@ -135,7 +135,7 @@ SetWindow::SetWindow(Window* parent, const SetP& set) ...@@ -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 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(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")) // 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 // loose ends
tabBar->Realize(); tabBar->Realize();
...@@ -253,6 +253,7 @@ void SetWindow::onCardSelect(CardSelectEvent& ev) { ...@@ -253,6 +253,7 @@ void SetWindow::onCardSelect(CardSelectEvent& ev) {
void SetWindow::fixMinWindowSize() { void SetWindow::fixMinWindowSize() {
current_panel->SetMinSize(current_panel->GetSizer()->GetMinSize()); current_panel->SetMinSize(current_panel->GetSizer()->GetMinSize());
Layout(); Layout();
current_panel->Layout();
wxSize s = GetSizer()->GetMinSize(); wxSize s = GetSizer()->GetMinSize();
wxSize ws = GetSize(); wxSize ws = GetSize();
wxSize cs = GetClientSize(); wxSize cs = GetClientSize();
...@@ -348,6 +349,9 @@ void SetWindow::onUpdateUI(wxUpdateUIEvent& ev) { ...@@ -348,6 +349,9 @@ void SetWindow::onUpdateUI(wxUpdateUIEvent& ev) {
case ID_EDIT_FIND : ev.Enable(current_panel->canFind()); break; case ID_EDIT_FIND : ev.Enable(current_panel->canFind()); break;
case ID_EDIT_FIND_NEXT : 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; case ID_EDIT_REPLACE : ev.Enable(current_panel->canReplace());break;
// windows
case ID_WINDOW_KEYWORDS: ev.Enable(set->game->has_keywords); break;
// other
default: default:
// items created by the panel, and cut/copy/paste and find/replace // items created by the panel, and cut/copy/paste and find/replace
if(current_panel) current_panel->onUpdateUI(ev); if(current_panel) current_panel->onUpdateUI(ev);
...@@ -600,6 +604,7 @@ BEGIN_EVENT_TABLE(SetWindow, wxFrame) ...@@ -600,6 +604,7 @@ BEGIN_EVENT_TABLE(SetWindow, wxFrame)
EVT_MENU (ID_HELP_WEBSITE, SetWindow::onHelpWebsite) EVT_MENU (ID_HELP_WEBSITE, SetWindow::onHelpWebsite)
EVT_MENU (ID_HELP_ABOUT, SetWindow::onHelpAbout) EVT_MENU (ID_HELP_ABOUT, SetWindow::onHelpAbout)
EVT_TOOL_RANGE (ID_CHILD_MIN, ID_CHILD_MAX, SetWindow::onChildMenu) 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_GALLERY_SELECT (ID_FIELD_LIST, SetWindow::onChildMenu) // for StatsPanel, because it is not a EVT_TOOL
EVT_UPDATE_UI (wxID_ANY, SetWindow::onUpdateUI) EVT_UPDATE_UI (wxID_ANY, SetWindow::onUpdateUI)
......
...@@ -18,8 +18,7 @@ ...@@ -18,8 +18,7 @@
#include <gui/util.hpp> // clearDC #include <gui/util.hpp> // clearDC
DECLARE_TYPEOF_COLLECTION(ValueViewerP); DECLARE_TYPEOF_COLLECTION(ValueViewerP);
typedef IndexMap<FieldP,StyleP> IndexMap_FieldP_StyleP; DECLARE_TYPEOF_NO_REV2(IndexMap<FieldP,StyleP>);
DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_StyleP);
// ----------------------------------------------------------------------------- : DataViewer // ----------------------------------------------------------------------------- : DataViewer
......
...@@ -117,6 +117,14 @@ btn_ok_normal IMAGE "../common/btn_ok_normal.png" ...@@ -117,6 +117,14 @@ btn_ok_normal IMAGE "../common/btn_ok_normal.png"
btn_ok_hover IMAGE "../common/btn_ok_hover.png" btn_ok_hover IMAGE "../common/btn_ok_hover.png"
btn_ok_focus IMAGE "../common/btn_ok_focus.png" btn_ok_focus IMAGE "../common/btn_ok_focus.png"
btn_ok_down IMAGE "../common/btn_ok_down.png" btn_ok_down IMAGE "../common/btn_ok_down.png"
btn_collapse_normal IMAGE "../common/btn_collapse_normal.png"
btn_collapse_hover IMAGE "../common/btn_collapse_hover.png"
btn_collapse_focus IMAGE "../common/btn_collapse_focus.png"
btn_collapse_down IMAGE "../common/btn_collapse_down.png"
btn_expand_normal IMAGE "../common/btn_expand_normal.png"
btn_expand_hover IMAGE "../common/btn_expand_hover.png"
btn_expand_focus IMAGE "../common/btn_expand_focus.png"
btn_expand_down IMAGE "../common/btn_expand_down.png"
//about_xmas IMAGE "about-xmas.png" //about_xmas IMAGE "about-xmas.png"
//two_xmas IMAGE "two_beta-xmas.png" //two_xmas IMAGE "two_beta-xmas.png"
......
...@@ -18,14 +18,12 @@ ...@@ -18,14 +18,12 @@
#include <util/error.hpp> #include <util/error.hpp>
typedef map<const StyleSheet*,Context*> Contexts; typedef map<const StyleSheet*,Context*> Contexts;
typedef IndexMap<FieldP,StyleP> IndexMap_FieldP_StyleP;
typedef IndexMap<FieldP,ValueP> IndexMap_FieldP_ValueP;
DECLARE_TYPEOF(Contexts); DECLARE_TYPEOF(Contexts);
DECLARE_TYPEOF_COLLECTION(CardP); DECLARE_TYPEOF_COLLECTION(CardP);
DECLARE_TYPEOF_COLLECTION(FieldP); DECLARE_TYPEOF_COLLECTION(FieldP);
DECLARE_TYPEOF_COLLECTION(Dependency); DECLARE_TYPEOF_COLLECTION(Dependency);
DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_StyleP); DECLARE_TYPEOF_NO_REV2(IndexMap<FieldP,StyleP>);
DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_ValueP); DECLARE_TYPEOF_NO_REV2(IndexMap<FieldP,ValueP>);
// initialize functions, from functions.cpp // initialize functions, from functions.cpp
void init_script_functions(Context& ctx); void init_script_functions(Context& ctx);
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#define DECLARE_TYPEOF_NO_REV(T) #define DECLARE_TYPEOF_NO_REV(T)
#define DECLARE_TYPEOF_CONST(T) #define DECLARE_TYPEOF_CONST(T)
#define DECLARE_TYPEOF_COLLECTION(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(Value) __typeof(Value)
#define TYPEOF_IT(Value) __typeof(Value.begin()) #define TYPEOF_IT(Value) __typeof(Value.begin())
...@@ -83,14 +85,28 @@ ...@@ -83,14 +85,28 @@
typedef T::const_reference reference; \ typedef T::const_reference reference; \
typedef T::const_reference const_reference; \ typedef T::const_reference const_reference; \
} }
/// Declare typeof magic for a specific std::vector type /// Declare typeof magic for a specific std::vector type
#define DECLARE_TYPEOF_COLLECTION(T) DECLARE_TYPEOF(vector<T>); \ #define DECLARE_TYPEOF_COLLECTION(T) DECLARE_TYPEOF(vector<T>); \
DECLARE_TYPEOF_CONST(set<T>) DECLARE_TYPEOF_CONST(set<T>)
/// Declare typeof magic for a specific type, with two template arguments
/** This is needed because the preprocessor sees MACRO(class<a,b>)
* 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 #endif
// ----------------------------------------------------------------------------- : Looping macros with iterators // ----------------------------------------------------------------------------- : Looping macros with iterators
/// Iterate over a collection, using an iterator it of type Type /// Iterate over a collection, using an iterator it of type Type
......
...@@ -56,6 +56,11 @@ enum MenuID { ...@@ -56,6 +56,11 @@ enum MenuID {
// Window menu (MainWindow) // Window menu (MainWindow)
, ID_WINDOW_NEW = 201 , ID_WINDOW_NEW = 201
, ID_WINDOW_MIN = 202 , 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 , ID_WINDOW_MAX = 220
// Help menu (MainWindow) // Help menu (MainWindow)
...@@ -95,6 +100,9 @@ enum ChildMenuID { ...@@ -95,6 +100,9 @@ enum ChildMenuID {
, ID_CARD_ROTATE_180 , ID_CARD_ROTATE_180
, ID_CARD_ROTATE_270 , ID_CARD_ROTATE_270
// On cards panel
, ID_COLLAPSE_NOTES
// Keyword menu // Keyword menu
, ID_KEYWORD_ADD = 1101 , ID_KEYWORD_ADD = 1101
, ID_KEYWORD_REMOVE , ID_KEYWORD_REMOVE
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment