diff --git a/src/gui/control/gallery_list.cpp b/src/gui/control/gallery_list.cpp new file mode 100644 index 00000000..5ce7935b --- /dev/null +++ b/src/gui/control/gallery_list.cpp @@ -0,0 +1,169 @@ +//+----------------------------------------------------------------------------+ +//| 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 + +// ----------------------------------------------------------------------------- : GalleryList + +const int MARGIN = 2; // margin around items + +GalleryList::GalleryList(Window* parent, int id, int direction) + : wxScrolledWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER) + , direction(direction) +{} + +void GalleryList::update() { + const int w = item_size.GetWidth() + 2 * MARGIN; + const int h = item_size.GetHeight() + 2 * MARGIN; + // resize and scroll + if (direction == wxHORIZONTAL) { + // resize window + SetVirtualSize(w, h * (int)itemCount()); + SetScrollRate(w, 0); + // ensure selected item is visible + if (selection < itemCount()) { + int x, cw; + GetViewStart (&x, 0); + GetClientSize(&cw, 0); + cw /= w; + if ((int)selection < x) { + Scroll((int)selection, -1); // scroll up + } else if ((int)selection >= x + cw) { + Scroll((int)selection - cw - 1, -1); // scroll up + } + } + } else { // wxVERTICAL + // resize window + SetVirtualSize(w * (int)itemCount(), h); + SetScrollRate(0, h); + // ensure selected item is visible + if (selection < itemCount()) { + int y, ch; + GetViewStart (0, &y); + GetClientSize(0, &ch); + ch /= w; + if ((int)selection < y) { + Scroll((int)selection, -1); // scroll up + } else if ((int)selection >= y + ch) { + Scroll((int)selection - ch - 1, -1); // scroll down + } + } + } + // redraw + Refresh(false); +} + +size_t GalleryList::findItem(const wxMouseEvent& ev) { + if (direction == wxHORIZONTAL) { + int x, w = item_size.GetWidth() + 2 * MARGIN; + GetViewStart (&x, 0); + return static_cast( x + ev.GetX() / w ); + } else { // wxVERTICAL + int y, h = item_size.GetHeight() + 2 * MARGIN; + GetViewStart (0, &y); + return static_cast( y + ev.GetY() / h ); + } +} + +// ----------------------------------------------------------------------------- : Events + +void GalleryList::onLeftDown(wxMouseEvent& ev) { + size_t item = findItem(ev); + if (item != selection && item < itemCount()) { + selection = item; + update(); + } +} + +void GalleryList::onLeftDClick(wxMouseEvent& ev) { + // activate an item + // TODO +} + +void GalleryList::onKeyDown(wxKeyEvent& ev) { + switch (ev.GetKeyCode()) { + case WXK_LEFT: if (direction == wxHORIZONTAL && selection > 0) { + selection -= 1; + update(); + } break; + case WXK_RIGHT: if (direction == wxHORIZONTAL && selection + 1 < itemCount()) { + selection += 1; + update(); + } break; + case WXK_UP: if (direction == wxVERTICAL && selection > 0) { + selection -= 1; + update(); + } break; + case WXK_DOWN: if (direction == wxVERTICAL && selection + 1 < itemCount()) { + selection += 1; + update(); + } break; + } +} + +// Linear interpolation between colors +Color lerp(const Color& a, const Color& b, double t) { + return Color(a.Red() + (b.Red() - a.Red() ) * t, + a.Green() + (b.Green() - a.Green()) * t, + a.Blue() + (b.Blue() - a.Blue() ) * t); +} + +wxSize GalleryList::DoGetBestSize() const { + wxSize ws = GetSize(), cs = GetClientSize(); + const int w = item_size.GetWidth() + 2 * MARGIN; + const int h = item_size.GetHeight() + 2 * MARGIN; + return wxSize(w, h) + ws - cs; +} + +void GalleryList::OnDraw(DC& dc) { + int x, y; + int cw, ch; + int dx, dy; + size_t start, end; // items to draw + // number of visble items + GetViewStart(&x, &y); + GetClientSize(&cw, &ch); + if (direction == wxHORIZONTAL) { + dx = item_size.GetWidth() + 2 * MARGIN; + dy = 0; + start = (size_t) x; + end = (size_t) (start + cw / dx + 1); + } else { + dx = 0; + dy = item_size.GetHeight() + 2 * MARGIN; + start = (size_t) y; + end = (size_t) (start + ch / dy + 1); + } + end = min(end, itemCount()); + // clear background + dc.SetPen(*wxTRANSPARENT_PEN); + dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + dc.DrawRectangle(0, 0, dx * x + cw, dy * y + ch); + // draw all visible items + Color unselected = lerp(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW), + wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), 0.1); + Color background = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + for (size_t i = start ; i < end ; ++i) { + // draw selection rectangle + bool selected = i == selection; + Color c = selected ? wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT) : unselected; + dc.SetPen(c); + dc.SetBrush(lerp(background, c, 0.3)); + dc.DrawRectangle((int)i * dx + 1, (int)i * dy + 1, item_size.GetWidth() + 2, item_size.GetHeight() + 2); + // draw item + drawItem(dc, (int)i * dx + MARGIN, (int)i * dy + MARGIN, i, selected); + } +} + +// ----------------------------------------------------------------------------- : Event table + +BEGIN_EVENT_TABLE(GalleryList, wxScrolledWindow) + EVT_LEFT_DOWN (GalleryList::onLeftDown) + EVT_LEFT_DCLICK (GalleryList::onLeftDClick) + EVT_KEY_DOWN (GalleryList::onKeyDown) +END_EVENT_TABLE () diff --git a/src/gui/control/gallery_list.hpp b/src/gui/control/gallery_list.hpp new file mode 100644 index 00000000..330176a3 --- /dev/null +++ b/src/gui/control/gallery_list.hpp @@ -0,0 +1,53 @@ +//+----------------------------------------------------------------------------+ +//| 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_GALLERY_LIST +#define HEADER_GUI_CONTROL_GALLERY_LIST + +// ----------------------------------------------------------------------------- : Includes + +#include + +// ----------------------------------------------------------------------------- : GalleryList + +/// A list of items with custom drawing +/** A derived class should implement the abstract members to determine how the items look. + */ +class GalleryList : public wxScrolledWindow { + public: + GalleryList(Window* parent, int id, int direction = wxHORIZONTAL); + + protected: + static const size_t NO_SELECTION = (size_t)-1; + size_t selection; ///< The selected item, or NO_SELECTION if there is no selection + wxSize item_size; ///< The size of a single item + 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(); + + /// Return how many items there are in the list + virtual size_t itemCount() const = 0; + /// Draw an item + virtual void drawItem(DC& dc, int x, int y, size_t item, bool selected) = 0; + + /// Return the desired size of control + virtual wxSize DoGetBestSize() const; + + private: + DECLARE_EVENT_TABLE(); + + void onLeftDown (wxMouseEvent& ev); + void onLeftDClick(wxMouseEvent& ev); + void onKeyDown(wxKeyEvent& ev); + void OnDraw(DC& dc); + + /// Find the item corresponding to the given location + size_t findItem(const wxMouseEvent&); +}; + +// ----------------------------------------------------------------------------- : EOF +#endif diff --git a/src/gui/control/package_list.cpp b/src/gui/control/package_list.cpp new file mode 100644 index 00000000..b8e7c057 --- /dev/null +++ b/src/gui/control/package_list.cpp @@ -0,0 +1,78 @@ +//+----------------------------------------------------------------------------+ +//| 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 + +// ----------------------------------------------------------------------------- : PackageList + +PackageList::PackageList(Window* parent, int id, int direction) + : GalleryList(parent, id, direction) +{ + item_size = wxSize(110, 150); +} + +size_t PackageList::itemCount() const { + return packages.size(); +} + +void PackageList::drawItem(DC& dc, int x, int y, size_t item, bool selected) { + PackageData& d = packages.at(item); + RealRect rect(RealPoint(x,y),item_size); + RealPoint pos; + int w, h; + // draw image + if (d.image.Ok()) { + dc.DrawBitmap(d.image, x + align_delta_x(ALIGN_CENTER, item_size.GetWidth(), d.image.GetWidth()), y + 3); + } + // draw short name + dc.SetFont(wxFont(12,wxSWISS,wxNORMAL,wxBOLD,false,_("Arial"))); + dc.GetTextExtent(capitalize(d.package->name()), &w, &h); + pos = align_in_rect(ALIGN_CENTER, RealSize(w,h), rect); + dc.DrawText(capitalize(d.package->name()), pos.x, pos.y + 110); + // draw name + dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); + dc.GetTextExtent(d.package->fullName(), &w, &h); + RealPoint text_pos = align_in_rect(ALIGN_CENTER, RealSize(w,h), rect); + dc.DrawText(d.package->fullName(), text_pos.x, text_pos.y + 130); +} + +void PackageList::showData(const String& pattern) { + // clear + packages.clear(); + // find matching packages + String f = ::packages.findFirst(pattern); + while (!f.empty()) { + // try to open the package +// try { + PackageP package = ::packages.openAny(f); + // open image + InputStreamP stream = package->openIconFile(); + Bitmap bmp; + if (stream) { + bmp = Bitmap(Image(*stream)); + } + // add to list + packages.push_back(PackageData(package, bmp)); +/* } + // If there are errors we don't add the package to the list + catch (Error e) { + handleError(e, false); + } catch (std::exception e) { + // we don't throw Exceptions ourselfs, so this is probably something serious + handleError(InternalError(String(csconv_(e.what()))), false); + } catch (...) { + handleError(InternalError(_("An unexpected exception occurred, \nplease save your work (use save as to so you don't overwrite things).\n And restart Magic Set Editor")), false); + }*/ + // Next package + f = wxFindNextFile(); + } + // update list + update(); +} diff --git a/src/gui/control/package_list.hpp b/src/gui/control/package_list.hpp new file mode 100644 index 00000000..7419984c --- /dev/null +++ b/src/gui/control/package_list.hpp @@ -0,0 +1,68 @@ +//+----------------------------------------------------------------------------+ +//| 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_PACKAGE_LIST +#define HEADER_GUI_CONTROL_PACKAGE_LIST + +// ----------------------------------------------------------------------------- : Includes + +#include +#include + +DECLARE_POINTER_TYPE(Package); + +// ----------------------------------------------------------------------------- : PackageList + +/// A list of Packages of a specific type +class PackageList : public GalleryList { + public: + PackageList(Window* parent, int id, int direction = wxHORIZONTAL); + + /// Shows packages that match a specific patern, and that are of the given type + template + void showData(const String& pattern = _("*")) { + showData(pattern + _(".mse-") + T::typeNameStatic()); + } + + /// Shows packages that match a specific patern + void showData(const String& pattern = _("*.*")); + + // Is there a package selected? + inline bool hasSelection() const { return selection < itemCount(); } + + /// Get the selected package, T should be the same type used for showData + /** @pre hasSelection() + * Throws if the selection is not of type T */ + template + shared_ptr getSelection() const { + shared_ptr ret = dynamic_pointer_cast(packages.at(selection).package); + if (!ret) throw InternalError(_("PackageList: Selected package has the wrong type")); + return ret; + } + + protected: + /// Return how many items there are in the list + virtual size_t itemCount() const; + /// Draw an item + virtual void drawItem(DC& dc, int x, int y, size_t item, bool selected); + + private: + // The default icon to use +// wxIcon default_icon; + + // Information about a package + struct PackageData { + PackageData() {} + PackageData(const PackageP& package, const Bitmap& image) : package(package), image(image) {} + PackageP package; + Bitmap image; + }; + /// The displayed packages + vector packages; +}; + +// ----------------------------------------------------------------------------- : EOF +#endif