Thread for generating thumbnail images;

Used for card list;
Implemented reordering from card list

git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@115 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
twanvl
2006-12-18 19:30:44 +00:00
parent 0e77c55525
commit 4c10107dbb
17 changed files with 660 additions and 82 deletions
+27 -9
View File
@@ -14,6 +14,7 @@
#include <data/set.hpp>
#include <data/card.hpp>
#include <data/settings.hpp>
#include <data/stylesheet.hpp>
#include <data/format/clipboard.hpp>
#include <data/action/set.hpp>
#include <util/window_id.hpp>
@@ -24,6 +25,8 @@ DECLARE_TYPEOF_COLLECTION(FieldP);
DECLARE_POINTER_TYPE(ChoiceValue);
typedef map<int,FieldP> map_int_FieldP;
DECLARE_TYPEOF(map_int_FieldP);
typedef IndexMap<FieldP,StyleP> IndexMap_FieldP_StyleP;
DECLARE_TYPEOF_NO_REV(IndexMap_FieldP_StyleP);
// ----------------------------------------------------------------------------- : Events
@@ -85,7 +88,7 @@ void CardListBase::onAction(const Action& action, bool undone) {
if (sort_criterium) return; // nothing changes for us
if ((long)action.card_id1 == selected_card_pos || (long)action.card_id2 == selected_card_pos) {
// Selected card has moved; also move in the sorted card list
swap(sorted_card_list[action.card_id1] ,sorted_card_list[action.card_id2]);
swap(sorted_card_list[action.card_id1],sorted_card_list[action.card_id2]);
// reselect the current card, it has moved
selected_card_pos = (long)action.card_id1 == selected_card_pos ? (long)action.card_id2 : (long)action.card_id1;
// select the right card
@@ -99,6 +102,9 @@ void CardListBase::onAction(const Action& action, bool undone) {
const vector<CardP>& CardListBase::getCards() const {
return set->cards;
}
const CardP& CardListBase::getCard(long pos) const {
return sorted_card_list[pos];
}
// ----------------------------------------------------------------------------- : CardListBase : Selection
@@ -135,7 +141,7 @@ void CardListBase::selectCardPos(long pos, bool focus) {
if (selected_card_pos == pos && !focus) return; // this card is already selected
if ((size_t)pos < sorted_card_list.size()) {
// only if there is something to select
selectCard(sorted_card_list[pos], false, true);
selectCard(getCard(pos), false, true);
} else {
selectCard(CardP(), false, true);
}
@@ -148,7 +154,7 @@ void CardListBase::findSelectedCardPos() {
long count = GetItemCount();
selected_card_pos = -1;
for (long pos = 0 ; pos < count ; ++pos) {
if (sorted_card_list[pos] == selected_card) {
if (getCard(pos) == selected_card) {
selected_card_pos = pos;
break;
}
@@ -298,13 +304,12 @@ void CardListBase::refreshList() {
}
ChoiceStyleP CardListBase::findColorStyle() {
/* FOR_EACH(s, set->default_stylesheet->card_style) {
ChoiceStyleP cs = dynamic_cast<ChoiceStyleP>(s);
FOR_EACH(s, set->stylesheet->card_style) {
ChoiceStyleP cs = dynamic_pointer_cast<ChoiceStyle>(s);
if (cs && cs->colors_card_list) {
return cs;
}
}
*/
return ChoiceStyleP();
}
@@ -338,7 +343,7 @@ String CardListBase::OnGetItemText(long pos, long col) const {
// wx may give us non existing columns!
return wxEmptyString;
}
ValueP val = sorted_card_list[pos]->data[column_fields[col]];
ValueP val = getCard(pos)->data[column_fields[col]];
if (val) return val->toString();
else return wxEmptyString;
}
@@ -349,7 +354,7 @@ int CardListBase::OnGetItemImage(long pos) const {
wxListItemAttr* CardListBase::OnGetItemAttr(long pos) const {
if (!color_style) return nullptr;
ChoiceValueP val = static_pointer_cast<ChoiceValue>( sorted_card_list[pos]->data[color_style->fieldP]);
ChoiceValueP val = static_pointer_cast<ChoiceValue>( getCard(pos)->data[color_style->fieldP]);
assert(val);
item_attr.SetTextColour(color_style->choice_colors[val->value()]); // if it doesn't exist we get black
return &item_attr;
@@ -412,7 +417,20 @@ void CardListBase::onChar(wxKeyEvent& ev) {
}
void CardListBase::onDrag(wxMouseEvent& ev) {
// TODO
if (ev.Dragging() && selected_card && !sort_criterium) {
// reorder card list
int flags;
long item = HitTest(ev.GetPosition(), flags);
if (flags & wxLIST_HITTEST_ONITEM) {
if (item > 0) EnsureVisible(item-1);
if (item < GetItemCount()-1) EnsureVisible(item+1);
findSelectedCardPos();
if (item != selected_card_pos) {
// move card in the set
set->actions.add(new ReorderCardsAction(*set, item, selected_card_pos));
}
}
}
}
// ----------------------------------------------------------------------------- : CardListBase : Event table
+6 -7
View File
@@ -41,9 +41,6 @@ struct CardSelectEvent : public wxCommandEvent {
*
* 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 wxListView, public SetView {
public:
@@ -84,24 +81,26 @@ class CardListBase : public wxListView, public SetView {
protected:
/// What cards should be shown?
virtual const vector<CardP>& getCards() const;
/// Return the card at the given position in the sorted card list
const CardP& getCard(long pos) const;
/// Rebuild the card list (clear all vectors and fill them again)
void rebuild();
/// Do some additional updating before rebuilding the list
virtual void onRebuild() {}
/// Can the card list be modified?
virtual bool allowModify() const { return true; }
virtual bool allowModify() const { return false; }
// --------------------------------------------------- : Item 'events'
/// Get the text of an item in a specific column
/** Overrides a function from wxListCtrl */
String OnGetItemText (long pos, long col) const;
virtual 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;
virtual int OnGetItemImage(long pos) const;
/// Get the color for an item
wxListItemAttr* OnGetItemAttr(long pos) const;
virtual wxListItemAttr* OnGetItemAttr(long pos) const;
// --------------------------------------------------- : Data
private:
+2 -2
View File
@@ -20,8 +20,8 @@ const vector<CardP>& FilteredCardList::getCards() const {
return cards;
}
void FilteredCardList::setFilter(const CardListFilterP& filter_) {
filter = filter_;
void FilteredCardList::setFilter(const CardListFilterP& filter) {
this->filter = filter;
rebuild();
}
+1 -3
View File
@@ -32,15 +32,13 @@ class FilteredCardList : public CardListBase {
FilteredCardList(Window* parent, int id, long style = 0);
/// Change the filter to use
void setFilter(const CardListFilterP& filter_);
void setFilter(const CardListFilterP& filter);
protected:
/// Get only the subset of the cards
virtual const vector<CardP>& getCards() const;
/// Rebuild the filtered card list
virtual void onRebuild();
// /// Don't reorder
// virtual void onDrag(wxMouseEvent& ev);
private:
CardListFilterP filter; ///< Filter with which this.cards is made
+110
View File
@@ -0,0 +1,110 @@
//+----------------------------------------------------------------------------+
//| 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 <gui/control/image_card_list.hpp>
#include <gui/thumbnail_thread.hpp>
#include <data/field/image.hpp>
#include <data/game.hpp>
#include <data/card.hpp>
#include <gfx/gfx.hpp>
DECLARE_TYPEOF_COLLECTION(FieldP);
// ----------------------------------------------------------------------------- : ImageCardList
ImageCardList::ImageCardList(Window* parent, int id, long additional_style)
: CardListBase(parent, id, additional_style)
{}
ImageCardList::~ImageCardList() {
thumbnail_thread.abort(this);
}
void ImageCardList::onRebuild() {
image_field = findImageField();
}
void ImageCardList::onBeforeChangeSet() {
CardListBase::onBeforeChangeSet();
// remove all but the first two (sort asc/desc) images from image list
wxImageList* il = GetImageList(wxIMAGE_LIST_SMALL);
while (il && il->GetImageCount() > 2) {
il->Remove(2);
}
thumbnail_thread.abort(this);
thumbnails.clear();
}
ImageFieldP ImageCardList::findImageField() {
FOR_EACH(f, set->game->card_fields) {
ImageFieldP imgf = dynamic_pointer_cast<ImageField>(f);
if (imgf) return imgf;
}
return ImageFieldP();
}
/// A request for a thumbnail of a card image
class CardThumbnailRequest : public ThumbnailRequest {
public:
CardThumbnailRequest(ImageCardList* parent, const String& filename)
: ThumbnailRequest(
parent,
_("card") + parent->set->absoluteFilename() + _("-") + filename,
wxDateTime::Now()) // TODO: Find mofication time of card image
, filename(filename)
{}
virtual Image generate() {
ImageCardList* parent = (ImageCardList*)owner;
Image image;
if (image.LoadFile(*parent->set->openIn(filename))) {
// two step anti aliased resampling
image.Rescale(36, 28); // step 1: no anti aliassing
Image image2(18, 14, false); // step 2: with anti aliassing
resample(image, image2);
return image2;
} else {
return Image();
}
}
virtual void store(const Image& img) {
// add finished bitmap to the imagelist
ImageCardList* parent = (ImageCardList*)owner;
if (img.Ok()) {
wxImageList* il = parent->GetImageList(wxIMAGE_LIST_SMALL);
int id = il->Add(wxBitmap(img));
parent->thumbnails.insert(make_pair(filename, id));
parent->Refresh(false);
}
}
private:
String filename;
};
int ImageCardList::OnGetItemImage(long pos) const {
if (image_field) {
// Image = thumbnail of first image field of card
ImageValue& val = static_cast<ImageValue&>(*getCard(pos)->data[image_field]);
if (!val.filename) return -1; // no image
// is there already a thumbnail?
map<String,int>::const_iterator it = thumbnails.find(val.filename);
if (it != thumbnails.end()) {
return it->second;
} else {
// request a thumbnail
thumbnail_thread.request(new_shared2<CardThumbnailRequest>(const_cast<ImageCardList*>(this), val.filename));
}
}
return -1;
}
void ImageCardList::onIdle(wxIdleEvent&) {
thumbnail_thread.done(this);
}
BEGIN_EVENT_TABLE(ImageCardList, CardListBase)
EVT_IDLE (ImageCardList::onIdle)
END_EVENT_TABLE ()
+43
View File
@@ -0,0 +1,43 @@
//+----------------------------------------------------------------------------+
//| 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_IMAGE_CARD_LIST
#define HEADER_GUI_CONTROL_IMAGE_CARD_LIST
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <gui/control/card_list.hpp>
DECLARE_POINTER_TYPE(ImageField);
// ----------------------------------------------------------------------------- : ImageCardList
/// A card list that allows the shows thumbnails of card images
/** This card list also allows the list to be modified */
class ImageCardList : public CardListBase {
public:
~ImageCardList();
ImageCardList(Window* parent, int id, long additional_style = 0);
protected:
virtual int OnGetItemImage(long pos) const;
virtual void onRebuild();
virtual void onBeforeChangeSet();
virtual bool allowModify() const { return true; }
private:
DECLARE_EVENT_TABLE();
void onIdle(wxIdleEvent&);
ImageFieldP image_field; ///< Field to use for card images
mutable map<String,int> thumbnails; ///< image thumbnails, based on image_field
ImageFieldP findImageField();
friend class CardThumbnailRequest;
};
// ----------------------------------------------------------------------------- : EOF
#endif
+13
View File
@@ -0,0 +1,13 @@
//+----------------------------------------------------------------------------+
//| 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 <gui/control/select_card_list.hpp>
// ----------------------------------------------------------------------------- : SelectCardList
// TODO
+42
View File
@@ -0,0 +1,42 @@
//+----------------------------------------------------------------------------+
//| 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_SELECT_CARD_LIST
#define HEADER_GUI_CONTROL_SELECT_CARD_LIST
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <gui/control/card_list.hpp>
// ----------------------------------------------------------------------------- : SelectCardList
/// A card list with check boxes
class SelectCardList : public CardListBase {
public:
SelectCardList(Window* parent, int id, long additional_style = 0);
/// Select all cards
void selectAll();
/// Deselect all cards
void selectNone();
/// Is the given card selected?
bool isSelected(const CardP& card) const;
protected:
int OnGetItemImage(long pos) const;
private:
DECLARE_EVENT_TABLE();
set<CardP> selected; ///< which cards are selected?
void toggle(const CardP& card);
void onKeyDown(wxKeyEvent&);
void onLeftDown(wxMouseEvent&);
};
// ----------------------------------------------------------------------------- : EOF
#endif