From d8fb338b86f9c919538ac44c5cf48a6d69c48bbd Mon Sep 17 00:00:00 2001 From: coppro Date: Fri, 6 Jul 2007 17:57:06 +0000 Subject: [PATCH] Fixed sloppy code leading to crashes - card select dialog works on Linux. git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@510 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/gui/value/choice.cpp | 6 ++- src/gui/value/choice.hpp | 3 ++ src/gui/value/multiple_choice.cpp | 86 +++++++++++++++++++++++++++++++ src/gui/value/multiple_choice.hpp | 1 + 4 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/gui/value/choice.cpp b/src/gui/value/choice.cpp index c1b12767..524da8f1 100644 --- a/src/gui/value/choice.cpp +++ b/src/gui/value/choice.cpp @@ -201,7 +201,7 @@ void DropDownChoiceListBase::generateThumbnailImages() { ThumbnailStatus status = style().thumbnails_status[i]; if (i >= image_count || status != THUMB_OK) { // request this thumbnail - thumbnail_thread.request( new_intrusive3(&cve, i, status == THUMB_NOT_MADE) ); + thumbnail_thread.request( createThumbnailRequest(&cve, i, status == THUMB_NOT_MADE)); } } } @@ -270,6 +270,10 @@ DropDownList* DropDownChoiceList::createSubMenu(ChoiceField::ChoiceP group) cons return new DropDownChoiceList(const_cast(this), true, cve, group); } +ThumbnailRequestP DropDownChoiceList::createThumbnailRequest(ValueViewer * e, int index, bool from_disk) const { + return new_intrusive3(e, index, from_disk); +} + // ----------------------------------------------------------------------------- : ChoiceValueEditor IMPLEMENT_VALUE_EDITOR(Choice) diff --git a/src/gui/value/choice.hpp b/src/gui/value/choice.hpp index 1818adee..efedb4f3 100644 --- a/src/gui/value/choice.hpp +++ b/src/gui/value/choice.hpp @@ -15,6 +15,7 @@ #include DECLARE_SHARED_POINTER_TYPE(DropDownList); +DECLARE_POINTER_TYPE(ThumbnailRequest); // ----------------------------------------------------------------------------- : ChoiceValueEditor @@ -59,6 +60,7 @@ class DropDownChoiceListBase : public DropDownList { protected: virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const = 0; + virtual ThumbnailRequestP createThumbnailRequest(ValueViewer * e, int index, bool from_disk) const = 0; private: DECLARE_EVENT_TABLE(); @@ -98,6 +100,7 @@ class DropDownChoiceList : public DropDownChoiceListBase { virtual bool select(size_t item); virtual size_t selection() const; virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const; + virtual ThumbnailRequestP createThumbnailRequest(ValueViewer * e, int index, bool from_disk) const; }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/gui/value/multiple_choice.cpp b/src/gui/value/multiple_choice.cpp index d1c02cbc..953e4013 100644 --- a/src/gui/value/multiple_choice.cpp +++ b/src/gui/value/multiple_choice.cpp @@ -10,6 +10,87 @@ #include #include #include +#include +#include + +// ----------------------------------------------------------------------------- : ChoiceThumbnailRequest + +class MultipleChoiceThumbnailRequest : public ThumbnailRequest { + public: + MultipleChoiceThumbnailRequest(ValueViewer* cve, int id, bool from_disk); + virtual Image generate(); + virtual void store(const Image&); + + bool isThreadSafe; + virtual bool threadSafe() const {return isThreadSafe;} + private: + StyleSheetP stylesheet; + int id; +}; + +MultipleChoiceThumbnailRequest::MultipleChoiceThumbnailRequest(ValueViewer* cve, int id, bool from_disk) + : ThumbnailRequest( + reinterpret_cast (cve), + cve->viewer.stylesheet->name() + _("/") + cve->getField()->name + _("/") << id, + from_disk ? cve->viewer.stylesheet->lastModified() + : wxDateTime::Now() + ) + , stylesheet(cve->viewer.stylesheet) + , id(id) +{ + MultipleChoiceValueEditor* e = dynamic_cast (cve); + if (!e) + throw InternalError(_("Non-editor passed to MultipleChoiceThumbnailRequest")); + String name = cannocial_name_form(e->field().choices->choiceName(id)); + ScriptableImage img = e->style().choice_images[name]; + isThreadSafe = img.threadSafe(); +} + +Image MultipleChoiceThumbnailRequest::generate() { + MultipleChoiceValueEditor* cve = reinterpret_cast (owner); + String name = cannocial_name_form(cve->field().choices->choiceName(id)); + ScriptableImage& img = cve->style().choice_images[name]; + return img.isReady() + ? img.generate(GeneratedImage::Options(16,16, stylesheet.get(), &cve->getSet(), ASPECT_BORDER, true), false) + : wxImage(); +} + +void MultipleChoiceThumbnailRequest::store(const Image& img) { + MultipleChoiceValueEditor* cve = reinterpret_cast (owner); + wxImageList* il = cve->style().thumbnails; + while (id > il->GetImageCount()) { + il->Add(wxBitmap(16,16),*wxBLACK); + } + if (img.Ok()) { + #ifdef __WXMSW__ + // for some reason windows doesn't like completely transparent images if they do not have a mask + // HACK: + if (img.HasAlpha() && img.GetWidth() == 16 && img.GetHeight() == 16) { + // is the image empty? + bool empty = true; + int* b = (int*)img.GetAlpha(); + int* e = b + 16*16/sizeof(int); + while (b != e) { + if (*b++) { + empty = false; + break; + } + } + // if so, use a mask instead + if (empty) { + const_cast(img).ConvertAlphaToMask(); + } + } + // Hack ends here + #endif + if (id == il->GetImageCount()) { + il->Add(img); + } else { + il->Replace(id, img); + } + cve->style().thumbnails_status[id] = THUMB_OK; + } +} // ----------------------------------------------------------------------------- : DropDownMultipleChoiceList @@ -23,6 +104,7 @@ class DropDownMultipleChoiceList : public DropDownChoiceListBase { virtual bool select(size_t item); virtual size_t selection() const; virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const; + virtual ThumbnailRequestP createThumbnailRequest(ValueViewer * e, int index, bool from_disk) const; virtual void drawIcon(DC& dc, int x, int y, size_t item, bool selected) const; virtual void onMotion(wxMouseEvent&); @@ -92,6 +174,10 @@ DropDownList* DropDownMultipleChoiceList::createSubMenu(ChoiceField::ChoiceP gro return new DropDownMultipleChoiceList(const_cast(this), true, cve, group); } +ThumbnailRequestP DropDownMultipleChoiceList::createThumbnailRequest(ValueViewer * e, int index, bool from_disk) const { + return new_intrusive3(e, index, from_disk); +} + void DropDownMultipleChoiceList::onMotion(wxMouseEvent& ev) { if (kept_open) { wxSize cs = GetClientSize(); diff --git a/src/gui/value/multiple_choice.hpp b/src/gui/value/multiple_choice.hpp index 5a295d9e..b63316c9 100644 --- a/src/gui/value/multiple_choice.hpp +++ b/src/gui/value/multiple_choice.hpp @@ -34,6 +34,7 @@ class MultipleChoiceValueEditor : public MultipleChoiceValueViewer, public Value DropDownListP drop_down; vector active; ///< Which choices are active? (note: vector is evil) friend class DropDownMultipleChoiceList; + friend class MultipleChoiceThumbnailRequest; /// Initialize the drop down list DropDownList& initDropDown(); /// Toggle a choice or on or off