mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-13 05:57:00 -04:00
MultipleChoiceValueEditor: implemented drop down list
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@252 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
+61
-49
@@ -19,7 +19,7 @@ DECLARE_TYPEOF_COLLECTION(ChoiceField::ChoiceP);
|
|||||||
|
|
||||||
class ChoiceThumbnailRequest : public ThumbnailRequest {
|
class ChoiceThumbnailRequest : public ThumbnailRequest {
|
||||||
public:
|
public:
|
||||||
ChoiceThumbnailRequest(ChoiceValueEditor* cve, int id, bool from_disk);
|
ChoiceThumbnailRequest(ValueViewer* cve, int id, bool from_disk);
|
||||||
virtual Image generate();
|
virtual Image generate();
|
||||||
virtual void store(const Image&);
|
virtual void store(const Image&);
|
||||||
private:
|
private:
|
||||||
@@ -27,10 +27,10 @@ class ChoiceThumbnailRequest : public ThumbnailRequest {
|
|||||||
int id;
|
int id;
|
||||||
};
|
};
|
||||||
|
|
||||||
ChoiceThumbnailRequest::ChoiceThumbnailRequest(ChoiceValueEditor* cve, int id, bool from_disk)
|
ChoiceThumbnailRequest::ChoiceThumbnailRequest(ValueViewer* cve, int id, bool from_disk)
|
||||||
: ThumbnailRequest(
|
: ThumbnailRequest(
|
||||||
cve,
|
cve,
|
||||||
cve->viewer.stylesheet->name() + _("/") + cve->field().name + _("/") << id,
|
cve->viewer.stylesheet->name() + _("/") + cve->getField()->name + _("/") << id,
|
||||||
from_disk ? cve->viewer.stylesheet->lastModified()
|
from_disk ? cve->viewer.stylesheet->lastModified()
|
||||||
: wxDateTime::Now()
|
: wxDateTime::Now()
|
||||||
)
|
)
|
||||||
@@ -82,9 +82,10 @@ void ChoiceThumbnailRequest::store(const Image& img) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : DropDownChoiceList
|
// ----------------------------------------------------------------------------- : DropDownChoiceListBase
|
||||||
|
|
||||||
DropDownChoiceList::DropDownChoiceList(Window* parent, bool is_submenu, ChoiceValueEditor& cve, ChoiceField::ChoiceP group)
|
DropDownChoiceListBase::DropDownChoiceListBase
|
||||||
|
(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group)
|
||||||
: DropDownList(parent, is_submenu, is_submenu ? nullptr : &cve)
|
: DropDownList(parent, is_submenu, is_submenu ? nullptr : &cve)
|
||||||
, cve(cve)
|
, cve(cve)
|
||||||
, group(group)
|
, group(group)
|
||||||
@@ -94,11 +95,11 @@ DropDownChoiceList::DropDownChoiceList(Window* parent, bool is_submenu, ChoiceVa
|
|||||||
item_size.height = max(16., item_size.height);
|
item_size.height = max(16., item_size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DropDownChoiceList::itemCount() const {
|
size_t DropDownChoiceListBase::itemCount() const {
|
||||||
return group->choices.size() + hasDefault();
|
return group->choices.size() + hasDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
ChoiceField::ChoiceP DropDownChoiceList::getChoice(size_t item) const {
|
ChoiceField::ChoiceP DropDownChoiceListBase::getChoice(size_t item) const {
|
||||||
if (isGroupDefault(item)) {
|
if (isGroupDefault(item)) {
|
||||||
return group;
|
return group;
|
||||||
} else {
|
} else {
|
||||||
@@ -106,7 +107,7 @@ ChoiceField::ChoiceP DropDownChoiceList::getChoice(size_t item) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String DropDownChoiceList::itemText(size_t item) const {
|
String DropDownChoiceListBase::itemText(size_t item) const {
|
||||||
if (isFieldDefault(item)) {
|
if (isFieldDefault(item)) {
|
||||||
return field().default_name;
|
return field().default_name;
|
||||||
} else if (isGroupDefault(item)) {
|
} else if (isGroupDefault(item)) {
|
||||||
@@ -116,10 +117,10 @@ String DropDownChoiceList::itemText(size_t item) const {
|
|||||||
return choice->name;
|
return choice->name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool DropDownChoiceList::lineBelow(size_t item) const {
|
bool DropDownChoiceListBase::lineBelow(size_t item) const {
|
||||||
return isDefault(item);
|
return isDefault(item);
|
||||||
}
|
}
|
||||||
DropDownList* DropDownChoiceList::submenu(size_t item) const {
|
DropDownList* DropDownChoiceListBase::submenu(size_t item) const {
|
||||||
if (isDefault(item)) return nullptr;
|
if (isDefault(item)) return nullptr;
|
||||||
item -= hasDefault();
|
item -= hasDefault();
|
||||||
if (item >= submenus.size()) submenus.resize(item + 1);
|
if (item >= submenus.size()) submenus.resize(item + 1);
|
||||||
@@ -127,14 +128,14 @@ DropDownList* DropDownChoiceList::submenu(size_t item) const {
|
|||||||
ChoiceField::ChoiceP choice = group->choices[item];
|
ChoiceField::ChoiceP choice = group->choices[item];
|
||||||
if (choice->isGroup()) {
|
if (choice->isGroup()) {
|
||||||
// create submenu
|
// create submenu
|
||||||
submenus[item].reset(new DropDownChoiceList(const_cast<DropDownChoiceList*>(this), true, cve, choice));
|
submenus[item].reset(createSubMenu(choice));
|
||||||
}
|
}
|
||||||
return submenus[item].get();
|
return submenus[item].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropDownChoiceList::drawIcon(DC& dc, int x, int y, size_t item, bool selected) const {
|
void DropDownChoiceListBase::drawIcon(DC& dc, int x, int y, size_t item, bool selected) const {
|
||||||
// imagelist to use
|
// imagelist to use
|
||||||
wxImageList* il = cve.style().thumbnails;
|
wxImageList* il = style().thumbnails;
|
||||||
assert(il);
|
assert(il);
|
||||||
// find the image for the item
|
// find the image for the item
|
||||||
int image_id;
|
int image_id;
|
||||||
@@ -149,29 +150,68 @@ void DropDownChoiceList::drawIcon(DC& dc, int x, int y, size_t item, bool select
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DropDownChoiceListBase::generateThumbnailImages() {
|
||||||
|
if (!isRoot()) return;
|
||||||
|
if (!style().thumbnails) {
|
||||||
|
style().thumbnails = new wxImageList(16,16);
|
||||||
|
}
|
||||||
|
int image_count = style().thumbnails->GetImageCount();
|
||||||
|
int end = group->lastId();
|
||||||
|
Context& ctx = cve.viewer.getContext();
|
||||||
|
for (int i = 0 ; i < end ; ++i) {
|
||||||
|
String name = cannocial_name_form(group->choiceName(i));
|
||||||
|
ScriptableImage& img = style().choice_images[name];
|
||||||
|
bool up_to_date = img.upToDate(ctx, style().thumbnail_age);
|
||||||
|
if (i >= image_count || !up_to_date) {
|
||||||
|
// TODO : handle the case where image i was previously skipped
|
||||||
|
// request this thumbnail
|
||||||
|
thumbnail_thread.request( new_shared3<ChoiceThumbnailRequest>(&cve, i, up_to_date && !style().invalidated_images) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
style().thumbnail_age.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DropDownChoiceListBase::onIdle(wxIdleEvent& ev) {
|
||||||
|
if (!isRoot()) return;
|
||||||
|
if (thumbnail_thread.done(&cve)) {
|
||||||
|
Refresh(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(DropDownChoiceListBase, DropDownList)
|
||||||
|
EVT_IDLE(DropDownChoiceListBase::onIdle)
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : DropDownChoiceList
|
||||||
|
|
||||||
|
DropDownChoiceList::DropDownChoiceList(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group)
|
||||||
|
: DropDownChoiceListBase(parent, is_submenu, cve, group)
|
||||||
|
{}
|
||||||
|
|
||||||
void DropDownChoiceList::select(size_t item) {
|
void DropDownChoiceList::select(size_t item) {
|
||||||
if (isFieldDefault(item)) {
|
if (isFieldDefault(item)) {
|
||||||
cve.change( Defaultable<String>() );
|
dynamic_cast<ChoiceValueEditor&>(cve).change( Defaultable<String>() );
|
||||||
} else {
|
} else {
|
||||||
ChoiceField::ChoiceP choice = getChoice(item);
|
ChoiceField::ChoiceP choice = getChoice(item);
|
||||||
cve.change( field().choices->choiceName(choice->first_id) );
|
dynamic_cast<ChoiceValueEditor&>(cve).change( field().choices->choiceName(choice->first_id) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DropDownChoiceList::selection() const {
|
size_t DropDownChoiceList::selection() const {
|
||||||
// we need thumbnail images soon
|
// we need thumbnail images soon
|
||||||
const_cast<DropDownChoiceList*>(this)->generateThumbnailImages();
|
const_cast<DropDownChoiceList*>(this)->generateThumbnailImages();
|
||||||
// selected item
|
// selected item
|
||||||
int id = field().choices->choiceId(cve.value().value());
|
const Defaultable<String>& value = dynamic_cast<ChoiceValueEditor&>(cve).value().value();
|
||||||
|
int id = field().choices->choiceId(value);
|
||||||
// id of default item
|
// id of default item
|
||||||
if (hasFieldDefault()) {
|
if (hasFieldDefault()) {
|
||||||
if (cve.value().value.isDefault()) {
|
if (value.isDefault()) {
|
||||||
// default is selected
|
// default is selected
|
||||||
default_id = id;
|
default_id = id;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
// run default script to find out what the default choice would be
|
// run default script to find out what the default choice would be
|
||||||
String default_choice = *cve.field().default_script.invoke( cve.viewer.getContext() );
|
String default_choice = *field().default_script.invoke( cve.viewer.getContext() );
|
||||||
default_id = group->choiceId(default_choice);
|
default_id = group->choiceId(default_choice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,38 +226,10 @@ size_t DropDownChoiceList::selection() const {
|
|||||||
return NO_SELECTION;
|
return NO_SELECTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropDownChoiceList::generateThumbnailImages() {
|
DropDownList* DropDownChoiceList::createSubMenu(ChoiceField::ChoiceP group) const {
|
||||||
if (!isRoot()) return;
|
return new DropDownChoiceList(const_cast<DropDownChoiceList*>(this), true, cve, group);
|
||||||
if (!cve.style().thumbnails) {
|
|
||||||
cve.style().thumbnails = new wxImageList(16,16);
|
|
||||||
}
|
|
||||||
int image_count = cve.style().thumbnails->GetImageCount();
|
|
||||||
int end = group->lastId();
|
|
||||||
Context& ctx = cve.viewer.getContext();
|
|
||||||
for (int i = 0 ; i < end ; ++i) {
|
|
||||||
String name = cannocial_name_form(group->choiceName(i));
|
|
||||||
ScriptableImage& img = cve.style().choice_images[name];
|
|
||||||
bool up_to_date = img.upToDate(ctx, cve.style().thumbnail_age);
|
|
||||||
if (i >= image_count || !up_to_date) {
|
|
||||||
// TODO : handle the case where image i was previously skipped
|
|
||||||
// request this thumbnail
|
|
||||||
thumbnail_thread.request( new_shared3<ChoiceThumbnailRequest>(&cve, i, up_to_date && !cve.style().invalidated_images) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cve.style().thumbnail_age.update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropDownChoiceList::onIdle(wxIdleEvent& ev) {
|
|
||||||
if (!isRoot()) return;
|
|
||||||
if (thumbnail_thread.done(&cve)) {
|
|
||||||
Refresh(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(DropDownChoiceList, DropDownList)
|
|
||||||
EVT_IDLE(DropDownChoiceList::onIdle)
|
|
||||||
END_EVENT_TABLE()
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : ChoiceValueEditor
|
// ----------------------------------------------------------------------------- : ChoiceValueEditor
|
||||||
|
|
||||||
IMPLEMENT_VALUE_EDITOR(Choice)
|
IMPLEMENT_VALUE_EDITOR(Choice)
|
||||||
@@ -230,7 +242,7 @@ ChoiceValueEditor::~ChoiceValueEditor() {
|
|||||||
|
|
||||||
bool ChoiceValueEditor::onLeftDown(const RealPoint& pos, wxMouseEvent& ev) {
|
bool ChoiceValueEditor::onLeftDown(const RealPoint& pos, wxMouseEvent& ev) {
|
||||||
//HACK TODO REMOVEME
|
//HACK TODO REMOVEME
|
||||||
thumbnail_thread.abortAll();
|
//thumbnail_thread.abortAll();
|
||||||
return drop_down->onMouseInParent(ev, style().popup_style == POPUP_DROPDOWN_IN_PLACE && !nativeLook());
|
return drop_down->onMouseInParent(ev, style().popup_style == POPUP_DROPDOWN_IN_PLACE && !nativeLook());
|
||||||
}
|
}
|
||||||
bool ChoiceValueEditor::onChar(wxKeyEvent& ev) {
|
bool ChoiceValueEditor::onChar(wxKeyEvent& ev) {
|
||||||
|
|||||||
@@ -42,10 +42,11 @@ class ChoiceValueEditor : public ChoiceValueViewer, public ValueEditor {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : DropDownChoiceList
|
// ----------------------------------------------------------------------------- : DropDownChoiceList
|
||||||
|
|
||||||
// A drop down list of color choices
|
/// A drop down list of choices
|
||||||
class DropDownChoiceList : public DropDownList {
|
/** This is a base class, used for single and multiple choice fields */
|
||||||
|
class DropDownChoiceListBase : public DropDownList {
|
||||||
public:
|
public:
|
||||||
DropDownChoiceList(Window* parent, bool is_submenu, ChoiceValueEditor& cve, ChoiceField::ChoiceP group);
|
DropDownChoiceListBase(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual size_t itemCount() const;
|
virtual size_t itemCount() const;
|
||||||
@@ -54,23 +55,24 @@ class DropDownChoiceList : public DropDownList {
|
|||||||
virtual void drawIcon(DC& dc, int x, int y, size_t item, bool selected) const;
|
virtual void drawIcon(DC& dc, int x, int y, size_t item, bool selected) const;
|
||||||
virtual DropDownList* submenu(size_t item) const;
|
virtual DropDownList* submenu(size_t item) const;
|
||||||
|
|
||||||
virtual void select(size_t item);
|
protected:
|
||||||
virtual size_t selection() const;
|
virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_EVENT_TABLE();
|
DECLARE_EVENT_TABLE();
|
||||||
|
|
||||||
ChoiceValueEditor& cve;
|
ValueViewer& cve; ///< Editor this list belongs to
|
||||||
ChoiceField::ChoiceP group; ///< Group this menu shows
|
ChoiceField::ChoiceP group; ///< Group this menu shows
|
||||||
mutable vector<DropDownListP> submenus;
|
mutable vector<DropDownListP> submenus;
|
||||||
mutable int default_id; ///< Item id for the default item (if !hasFieldDefault()) this is undefined)
|
mutable int default_id; ///< Item id for the default item (if !hasFieldDefault()) this is undefined)
|
||||||
|
|
||||||
inline const ChoiceField& field() const { return cve.field(); }
|
inline ChoiceField& field() const { return static_cast<ChoiceField&>(*cve.getField()); }
|
||||||
|
inline ChoiceStyle& style() const { return static_cast<ChoiceStyle&>(*cve.getStyle()); }
|
||||||
|
|
||||||
inline bool isRoot() const { return group == field().choices; }
|
inline bool isRoot() const { return group == field().choices; }
|
||||||
inline bool hasFieldDefault() const { return isRoot() && field().default_script; }
|
inline bool hasFieldDefault() const { return isRoot() && field().default_script; }
|
||||||
inline bool hasGroupDefault() const { return group->hasDefault(); }
|
inline bool hasGroupDefault() const { return group->hasDefault(); }
|
||||||
inline bool hasDefault() const { return hasFieldDefault() || hasGroupDefault(); }
|
virtual bool hasDefault() const { return hasFieldDefault() || hasGroupDefault(); }
|
||||||
inline bool isFieldDefault(size_t item) const { return item == 0 && hasFieldDefault(); }
|
inline bool isFieldDefault(size_t item) const { return item == 0 && hasFieldDefault(); }
|
||||||
inline bool isGroupDefault(size_t item) const { return item == 0 && hasGroupDefault(); }
|
inline bool isGroupDefault(size_t item) const { return item == 0 && hasGroupDefault(); }
|
||||||
inline bool isDefault (size_t item) const { return item == 0 && hasDefault(); }
|
inline bool isDefault (size_t item) const { return item == 0 && hasDefault(); }
|
||||||
@@ -82,5 +84,18 @@ class DropDownChoiceList : public DropDownList {
|
|||||||
void onIdle(wxIdleEvent&);
|
void onIdle(wxIdleEvent&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : DropDownChoiceList
|
||||||
|
|
||||||
|
/// A drop down list of color choices
|
||||||
|
class DropDownChoiceList : public DropDownChoiceListBase {
|
||||||
|
public:
|
||||||
|
DropDownChoiceList(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void select(size_t item);
|
||||||
|
virtual size_t selection() const;
|
||||||
|
virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const;
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EOF
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,12 +7,83 @@
|
|||||||
// ----------------------------------------------------------------------------- : Includes
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
#include <gui/value/multiple_choice.hpp>
|
#include <gui/value/multiple_choice.hpp>
|
||||||
|
#include <gui/thumbnail_thread.hpp>
|
||||||
|
#include <gui/util.hpp>
|
||||||
#include <data/action/value.hpp>
|
#include <data/action/value.hpp>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : DropDownMultipleChoiceList
|
||||||
|
|
||||||
|
/// A drop down list of color choices
|
||||||
|
class DropDownMultipleChoiceList : public DropDownChoiceListBase {
|
||||||
|
public:
|
||||||
|
DropDownMultipleChoiceList(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void select(size_t item);
|
||||||
|
virtual size_t selection() const;
|
||||||
|
virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const;
|
||||||
|
virtual void drawIcon(DC& dc, int x, int y, size_t item, bool selected) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
DropDownMultipleChoiceList::DropDownMultipleChoiceList
|
||||||
|
(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group)
|
||||||
|
: DropDownChoiceListBase(parent, is_submenu, cve, group)
|
||||||
|
{
|
||||||
|
icon_size.width += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DropDownMultipleChoiceList::select(size_t item) {
|
||||||
|
if (isFieldDefault(item)) {
|
||||||
|
// should not happen
|
||||||
|
} else {
|
||||||
|
ChoiceField::ChoiceP choice = getChoice(item);
|
||||||
|
dynamic_cast<MultipleChoiceValueEditor&>(cve).toggle(choice->first_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DropDownMultipleChoiceList::drawIcon(DC& dc, int x, int y, size_t item, bool selected) const {
|
||||||
|
// is this item active?
|
||||||
|
bool active = false;
|
||||||
|
if (!isFieldDefault(item)) {
|
||||||
|
ChoiceField::ChoiceP choice = getChoice(item);
|
||||||
|
active = dynamic_cast<MultipleChoiceValueEditor&>(cve).active[choice->first_id];
|
||||||
|
}
|
||||||
|
// draw checkbox
|
||||||
|
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||||
|
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||||
|
dc.DrawRectangle(x,y,16,16);
|
||||||
|
wxRect rect = RealRect(x+2,y+2,12,12);
|
||||||
|
draw_checkbox(nullptr, dc, rect, active);
|
||||||
|
// draw icon
|
||||||
|
DropDownChoiceListBase::drawIcon(dc, x + 16, y, item, selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t DropDownMultipleChoiceList::selection() const {
|
||||||
|
// we need thumbnail images soon
|
||||||
|
const_cast<DropDownMultipleChoiceList*>(this)->generateThumbnailImages();
|
||||||
|
// we don't know the selection
|
||||||
|
return NO_SELECTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
DropDownList* DropDownMultipleChoiceList::createSubMenu(ChoiceField::ChoiceP group) const {
|
||||||
|
return new DropDownMultipleChoiceList(const_cast<DropDownMultipleChoiceList*>(this), true, cve, group);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : MultipleChoiceValueEditor
|
// ----------------------------------------------------------------------------- : MultipleChoiceValueEditor
|
||||||
|
|
||||||
IMPLEMENT_VALUE_EDITOR(MultipleChoice) {}
|
IMPLEMENT_VALUE_EDITOR(MultipleChoice) {}
|
||||||
|
|
||||||
|
MultipleChoiceValueEditor::~MultipleChoiceValueEditor() {
|
||||||
|
thumbnail_thread.abort(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
DropDownList& MultipleChoiceValueEditor::initDropDown() {
|
||||||
|
if (!drop_down) {
|
||||||
|
drop_down.reset(new DropDownMultipleChoiceList(&editor(), false, *this, field().choices));
|
||||||
|
}
|
||||||
|
return *drop_down;
|
||||||
|
}
|
||||||
|
|
||||||
void MultipleChoiceValueEditor::determineSize(bool force_fit) {
|
void MultipleChoiceValueEditor::determineSize(bool force_fit) {
|
||||||
if (!nativeLook()) return;
|
if (!nativeLook()) return;
|
||||||
// item height
|
// item height
|
||||||
@@ -24,7 +95,7 @@ void MultipleChoiceValueEditor::determineSize(bool force_fit) {
|
|||||||
|
|
||||||
bool MultipleChoiceValueEditor::onLeftDown(const RealPoint& pos, wxMouseEvent& ev) {
|
bool MultipleChoiceValueEditor::onLeftDown(const RealPoint& pos, wxMouseEvent& ev) {
|
||||||
// find item under cursor
|
// find item under cursor
|
||||||
if (style().render_style && RENDER_CHECKLIST) {
|
if (style().render_style & RENDER_CHECKLIST) {
|
||||||
int id = (pos.y - style().top) / item_height;
|
int id = (pos.y - style().top) / item_height;
|
||||||
int end = field().choices->lastId();
|
int end = field().choices->lastId();
|
||||||
if (id >= 0 && id < end) {
|
if (id >= 0 && id < end) {
|
||||||
@@ -32,10 +103,39 @@ bool MultipleChoiceValueEditor::onLeftDown(const RealPoint& pos, wxMouseEvent& e
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO
|
// open a drop down menu
|
||||||
|
return initDropDown().onMouseInParent(ev, style().popup_style == POPUP_DROPDOWN_IN_PLACE && !nativeLook());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool MultipleChoiceValueEditor::onChar(wxKeyEvent& ev) {
|
||||||
|
if (style().render_style & RENDER_CHECKLIST) {
|
||||||
|
// todo;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return initDropDown().onCharInParent(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void MultipleChoiceValueEditor::onLoseFocus() {
|
||||||
|
if (drop_down) drop_down->hide(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultipleChoiceValueEditor::onValueChange() {
|
||||||
|
MultipleChoiceValueViewer::onValueChange();
|
||||||
|
// determine active values
|
||||||
|
active.clear();
|
||||||
|
vector<String> selected;
|
||||||
|
value().get(selected);
|
||||||
|
vector<String>::iterator select_it = selected.begin();
|
||||||
|
// for each choice...
|
||||||
|
int end = field().choices->lastId();
|
||||||
|
for (int i = 0 ; i < end ; ++i) {
|
||||||
|
String choice = field().choices->choiceName(i);
|
||||||
|
bool is_active = select_it != selected.end() && *select_it == choice;
|
||||||
|
if (is_active) select_it++;
|
||||||
|
active.push_back(is_active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MultipleChoiceValueEditor::toggle(int id) {
|
void MultipleChoiceValueEditor::toggle(int id) {
|
||||||
String new_value;
|
String new_value;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <util/prec.hpp>
|
#include <util/prec.hpp>
|
||||||
#include <gui/value/editor.hpp>
|
#include <gui/value/editor.hpp>
|
||||||
|
#include <gui/value/choice.hpp>
|
||||||
#include <render/value/multiple_choice.hpp>
|
#include <render/value/multiple_choice.hpp>
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : MultipleChoiceValueEditor
|
// ----------------------------------------------------------------------------- : MultipleChoiceValueEditor
|
||||||
@@ -19,10 +20,22 @@
|
|||||||
class MultipleChoiceValueEditor : public MultipleChoiceValueViewer, public ValueEditor {
|
class MultipleChoiceValueEditor : public MultipleChoiceValueViewer, public ValueEditor {
|
||||||
public:
|
public:
|
||||||
DECLARE_VALUE_EDITOR(MultipleChoice);
|
DECLARE_VALUE_EDITOR(MultipleChoice);
|
||||||
|
~MultipleChoiceValueEditor();
|
||||||
|
|
||||||
|
virtual void onValueChange();
|
||||||
|
|
||||||
virtual void determineSize(bool force_fit);
|
virtual void determineSize(bool force_fit);
|
||||||
|
|
||||||
virtual bool onLeftDown (const RealPoint& pos, wxMouseEvent& ev);
|
virtual bool onLeftDown (const RealPoint& pos, wxMouseEvent& ev);
|
||||||
|
virtual bool onChar(wxKeyEvent& ev);
|
||||||
|
virtual void onLoseFocus();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
DropDownListP drop_down;
|
||||||
|
vector<int> active; ///< Which choices are active? (note: vector<bool> is evil)
|
||||||
|
friend class DropDownMultipleChoiceList;
|
||||||
|
/// Initialize the drop down list
|
||||||
|
DropDownList& initDropDown();
|
||||||
/// Toggle a choice or on or off
|
/// Toggle a choice or on or off
|
||||||
void toggle(int id);
|
void toggle(int id);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user