mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-12 21:47:00 -04:00
Multiple choice box kept open until mouse out
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@505 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -40,6 +40,10 @@ class DropDownHider : public wxEvtHandler {
|
|||||||
list.hide(false);
|
list.hide(false);
|
||||||
if (nh) nh->ProcessEvent(ev);
|
if (nh) nh->ProcessEvent(ev);
|
||||||
return false;
|
return false;
|
||||||
|
} else if (t == wxEVT_MOTION) {
|
||||||
|
// send along all motion events
|
||||||
|
list.ProcessEvent(ev);
|
||||||
|
return wxEvtHandler::ProcessEvent(ev);
|
||||||
} else {
|
} else {
|
||||||
// if (t !=10093 && t !=10098 && t !=10097 && t !=10099 && t !=10004 && t !=10062
|
// if (t !=10093 && t !=10098 && t !=10097 && t !=10099 && t !=10004 && t !=10062
|
||||||
// && t !=10025 && t !=10035 && t !=10034 && t !=10036 && t !=10042 && t !=10119)
|
// && t !=10025 && t !=10035 && t !=10034 && t !=10036 && t !=10042 && t !=10119)
|
||||||
@@ -64,7 +68,8 @@ DropDownList::DropDownList(Window* parent, bool is_submenu, ValueViewer* viewer)
|
|||||||
, open_sub_menu(nullptr)
|
, open_sub_menu(nullptr)
|
||||||
, parent_menu(nullptr)
|
, parent_menu(nullptr)
|
||||||
, viewer(viewer)
|
, viewer(viewer)
|
||||||
, hider(is_submenu ? nullptr : new DropDownHider(*this))
|
, hider (is_submenu ? nullptr : new DropDownHider(*this))
|
||||||
|
, hider2(is_submenu ? nullptr : new DropDownHider(*this))
|
||||||
{
|
{
|
||||||
if (is_submenu) {
|
if (is_submenu) {
|
||||||
parent_menu = &dynamic_cast<DropDownList&>(*GetParent());
|
parent_menu = &dynamic_cast<DropDownList&>(*GetParent());
|
||||||
@@ -80,6 +85,7 @@ DropDownList::DropDownList(Window* parent, bool is_submenu, ValueViewer* viewer)
|
|||||||
DropDownList::~DropDownList() {
|
DropDownList::~DropDownList() {
|
||||||
realHide(); // restore event handler before deleting it
|
realHide(); // restore event handler before deleting it
|
||||||
delete hider;
|
delete hider;
|
||||||
|
delete hider2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropDownList::show(bool in_place, wxPoint pos) {
|
void DropDownList::show(bool in_place, wxPoint pos) {
|
||||||
@@ -128,8 +134,9 @@ void DropDownList::show(bool in_place, wxPoint pos) {
|
|||||||
Position(pos, wxSize(0, parent_height));
|
Position(pos, wxSize(0, parent_height));
|
||||||
// set event handler
|
// set event handler
|
||||||
if (hider) {
|
if (hider) {
|
||||||
Window* parent = wxGetTopLevelParent(GetParent());
|
assert(hider2);
|
||||||
parent->PushEventHandler(hider);
|
wxGetTopLevelParent(GetParent())->PushEventHandler(hider);
|
||||||
|
GetParent() ->PushEventHandler(hider2);
|
||||||
}
|
}
|
||||||
// show
|
// show
|
||||||
if (selected_item == NO_SELECTION && itemCount() > 0) selected_item = 0; // select first item by default
|
if (selected_item == NO_SELECTION && itemCount() > 0) selected_item = 0; // select first item by default
|
||||||
@@ -139,15 +146,21 @@ void DropDownList::show(bool in_place, wxPoint pos) {
|
|||||||
redrawArrowOnParent();
|
redrawArrowOnParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropDownList::hide(bool event) {
|
void DropDownList::hide(bool event, bool allow_veto) {
|
||||||
|
// send event
|
||||||
|
if (event && selected_item != NO_SELECTION && itemEnabled(selected_item)) {
|
||||||
|
bool close = select(selected_item);
|
||||||
|
if (allow_veto && !close) {
|
||||||
|
Refresh(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
// hide root
|
// hide root
|
||||||
DropDownList* root = this;
|
DropDownList* root = this;
|
||||||
while (root->parent_menu) {
|
while (root->parent_menu) {
|
||||||
root = root->parent_menu;
|
root = root->parent_menu;
|
||||||
}
|
}
|
||||||
root->realHide();
|
root->realHide();
|
||||||
// send event
|
|
||||||
if (event && selected_item != NO_SELECTION && itemEnabled(selected_item)) select(selected_item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropDownList::realHide() {
|
void DropDownList::realHide() {
|
||||||
@@ -160,8 +173,8 @@ void DropDownList::realHide() {
|
|||||||
} else {
|
} else {
|
||||||
redrawArrowOnParent();
|
redrawArrowOnParent();
|
||||||
// disconnect event handler
|
// disconnect event handler
|
||||||
Window* parent = wxGetTopLevelParent(GetParent());
|
GetParent() ->RemoveEventHandler(hider2);
|
||||||
parent->RemoveEventHandler(hider);
|
wxGetTopLevelParent(GetParent())->RemoveEventHandler(hider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,6 +361,11 @@ bool DropDownList::onCharInParent(wxKeyEvent& ev) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WXK_RETURN:
|
case WXK_RETURN:
|
||||||
|
if (!showSubMenu() && (selected_item == NO_SELECTION || itemEnabled(selected_item))) {
|
||||||
|
hide(true, false); // don't veto; always close
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WXK_SPACE:
|
||||||
if (!showSubMenu() && (selected_item == NO_SELECTION || itemEnabled(selected_item))) {
|
if (!showSubMenu() && (selected_item == NO_SELECTION || itemEnabled(selected_item))) {
|
||||||
hide(true);
|
hide(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class DropDownList : public wxPopupWindow {
|
|||||||
/** if in_place, then shows the list at the position pos */
|
/** if in_place, then shows the list at the position pos */
|
||||||
void show(bool in_place, wxPoint pos);
|
void show(bool in_place, wxPoint pos);
|
||||||
/// Close the list, optionally send an onSelect event
|
/// Close the list, optionally send an onSelect event
|
||||||
void hide(bool event);
|
void hide(bool event, bool allow_veto = true);
|
||||||
|
|
||||||
// --------------------------------------------------- : Parent control
|
// --------------------------------------------------- : Parent control
|
||||||
/// Takes all keyboard events from a FieldEditor
|
/// Takes all keyboard events from a FieldEditor
|
||||||
@@ -48,7 +48,9 @@ class DropDownList : public wxPopupWindow {
|
|||||||
static const size_t NO_SELECTION = (size_t)-1;
|
static const size_t NO_SELECTION = (size_t)-1;
|
||||||
|
|
||||||
/// Signal that the list is closed and something is selected
|
/// Signal that the list is closed and something is selected
|
||||||
virtual void select(size_t selection) = 0;
|
/** Returns true if the event was handled and the list should be hidden,
|
||||||
|
* false keeps the list open. */
|
||||||
|
virtual bool select(size_t selection) = 0;
|
||||||
/// When the list is being opened, what should be selected?
|
/// When the list is being opened, what should be selected?
|
||||||
virtual size_t selection() const = 0;
|
virtual size_t selection() const = 0;
|
||||||
|
|
||||||
@@ -86,7 +88,7 @@ class DropDownList : public wxPopupWindow {
|
|||||||
DropDownList* open_sub_menu; ///< The sub menu that is currently shown, if any
|
DropDownList* open_sub_menu; ///< The sub menu that is currently shown, if any
|
||||||
DropDownList* parent_menu; ///< The parent menu, only applies to sub menus
|
DropDownList* parent_menu; ///< The parent menu, only applies to sub menus
|
||||||
ValueViewer* viewer; ///< The parent viewer object (optional)
|
ValueViewer* viewer; ///< The parent viewer object (optional)
|
||||||
DropDownHider* hider; ///< Class to hide this window when we lose focus
|
DropDownHider* hider, *hider2; ///< Class to hide this window when we lose focus
|
||||||
|
|
||||||
// --------------------------------------------------- : Events
|
// --------------------------------------------------- : Events
|
||||||
DECLARE_EVENT_TABLE();
|
DECLARE_EVENT_TABLE();
|
||||||
@@ -94,7 +96,9 @@ class DropDownList : public wxPopupWindow {
|
|||||||
void onPaint(wxPaintEvent&);
|
void onPaint(wxPaintEvent&);
|
||||||
void onLeftDown(wxMouseEvent&);
|
void onLeftDown(wxMouseEvent&);
|
||||||
void onLeftUp (wxMouseEvent&);
|
void onLeftUp (wxMouseEvent&);
|
||||||
void onMotion (wxMouseEvent&);
|
protected:
|
||||||
|
virtual void onMotion(wxMouseEvent&); // allow override
|
||||||
|
private:
|
||||||
|
|
||||||
// --------------------------------------------------- : Privates
|
// --------------------------------------------------- : Privates
|
||||||
|
|
||||||
|
|||||||
@@ -227,13 +227,14 @@ void DropDownChoiceList::onShow() {
|
|||||||
generateThumbnailImages();
|
generateThumbnailImages();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropDownChoiceList::select(size_t item) {
|
bool DropDownChoiceList::select(size_t item) {
|
||||||
if (isFieldDefault(item)) {
|
if (isFieldDefault(item)) {
|
||||||
dynamic_cast<ChoiceValueEditor&>(cve).change( Defaultable<String>() );
|
dynamic_cast<ChoiceValueEditor&>(cve).change( Defaultable<String>() );
|
||||||
} else {
|
} else {
|
||||||
ChoiceField::ChoiceP choice = getChoice(item);
|
ChoiceField::ChoiceP choice = getChoice(item);
|
||||||
dynamic_cast<ChoiceValueEditor&>(cve).change( field().choices->choiceName(choice->first_id) );
|
dynamic_cast<ChoiceValueEditor&>(cve).change( field().choices->choiceName(choice->first_id) );
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DropDownChoiceList::selection() const {
|
size_t DropDownChoiceList::selection() const {
|
||||||
@@ -278,8 +279,6 @@ ChoiceValueEditor::~ChoiceValueEditor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ChoiceValueEditor::onLeftDown(const RealPoint& pos, wxMouseEvent& ev) {
|
bool ChoiceValueEditor::onLeftDown(const RealPoint& pos, wxMouseEvent& ev) {
|
||||||
//HACK TODO REMOVEME
|
|
||||||
//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) {
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ class DropDownChoiceList : public DropDownChoiceListBase {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void onShow();
|
virtual void onShow();
|
||||||
virtual void select(size_t item);
|
virtual bool select(size_t item);
|
||||||
virtual size_t selection() const;
|
virtual size_t selection() const;
|
||||||
virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const;
|
virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class DropDownColorList : public DropDownList {
|
|||||||
virtual String itemText(size_t item) const;
|
virtual String itemText(size_t item) const;
|
||||||
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 void select(size_t item);
|
virtual bool select(size_t item);
|
||||||
virtual size_t selection() const;
|
virtual size_t selection() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -112,7 +112,7 @@ size_t DropDownColorList::selection() const {
|
|||||||
}
|
}
|
||||||
return selection;
|
return selection;
|
||||||
}
|
}
|
||||||
void DropDownColorList::select(size_t item) {
|
bool DropDownColorList::select(size_t item) {
|
||||||
if (isDefault(item)) {
|
if (isDefault(item)) {
|
||||||
cve.change( Defaultable<Color>());
|
cve.change( Defaultable<Color>());
|
||||||
} else if (isCustom(item)) {
|
} else if (isCustom(item)) {
|
||||||
@@ -120,6 +120,7 @@ void DropDownColorList::select(size_t item) {
|
|||||||
} else {
|
} else {
|
||||||
cve.change(field().choices[item - hasDefault()]->color);
|
cve.change(field().choices[item - hasDefault()]->color);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : ColorValueEditor
|
// ----------------------------------------------------------------------------- : ColorValueEditor
|
||||||
|
|||||||
@@ -19,20 +19,26 @@ class DropDownMultipleChoiceList : public DropDownChoiceListBase {
|
|||||||
DropDownMultipleChoiceList(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group);
|
DropDownMultipleChoiceList(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void select(size_t item);
|
virtual void onShow();
|
||||||
|
virtual bool select(size_t item);
|
||||||
virtual size_t selection() const;
|
virtual size_t selection() const;
|
||||||
virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const;
|
virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const;
|
||||||
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 void onMotion(wxMouseEvent&);
|
||||||
|
private:
|
||||||
|
bool kept_open; ///< Was the list kept open after selecting a choice, if so, be eager to close it
|
||||||
};
|
};
|
||||||
|
|
||||||
DropDownMultipleChoiceList::DropDownMultipleChoiceList
|
DropDownMultipleChoiceList::DropDownMultipleChoiceList
|
||||||
(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group)
|
(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group)
|
||||||
: DropDownChoiceListBase(parent, is_submenu, cve, group)
|
: DropDownChoiceListBase(parent, is_submenu, cve, group)
|
||||||
|
, kept_open(false)
|
||||||
{
|
{
|
||||||
icon_size.width += 16;
|
icon_size.width += 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropDownMultipleChoiceList::select(size_t item) {
|
bool DropDownMultipleChoiceList::select(size_t item) {
|
||||||
MultipleChoiceValueEditor& mcve = dynamic_cast<MultipleChoiceValueEditor&>(cve);
|
MultipleChoiceValueEditor& mcve = dynamic_cast<MultipleChoiceValueEditor&>(cve);
|
||||||
if (isFieldDefault(item)) {
|
if (isFieldDefault(item)) {
|
||||||
mcve.toggleDefault();
|
mcve.toggleDefault();
|
||||||
@@ -40,6 +46,10 @@ void DropDownMultipleChoiceList::select(size_t item) {
|
|||||||
ChoiceField::ChoiceP choice = getChoice(item);
|
ChoiceField::ChoiceP choice = getChoice(item);
|
||||||
mcve.toggle(choice->first_id);
|
mcve.toggle(choice->first_id);
|
||||||
}
|
}
|
||||||
|
// keep the box open
|
||||||
|
DropDownChoiceListBase::onShow(); // update 'enabled'
|
||||||
|
kept_open = true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropDownMultipleChoiceList::drawIcon(DC& dc, int x, int y, size_t item, bool selected) const {
|
void DropDownMultipleChoiceList::drawIcon(DC& dc, int x, int y, size_t item, bool selected) const {
|
||||||
@@ -67,17 +77,31 @@ void DropDownMultipleChoiceList::drawIcon(DC& dc, int x, int y, size_t item, boo
|
|||||||
DropDownChoiceListBase::drawIcon(dc, x + 16, y, item, selected);
|
DropDownChoiceListBase::drawIcon(dc, x + 16, y, item, selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DropDownMultipleChoiceList::selection() const {
|
void DropDownMultipleChoiceList::onShow() {
|
||||||
|
DropDownChoiceListBase::onShow();
|
||||||
// we need thumbnail images soon
|
// we need thumbnail images soon
|
||||||
const_cast<DropDownMultipleChoiceList*>(this)->generateThumbnailImages();
|
const_cast<DropDownMultipleChoiceList*>(this)->generateThumbnailImages();
|
||||||
// we don't know the selection
|
kept_open = false;
|
||||||
return NO_SELECTION;
|
}
|
||||||
|
|
||||||
|
size_t DropDownMultipleChoiceList::selection() const {
|
||||||
|
return NO_SELECTION; // we don't know the selection
|
||||||
}
|
}
|
||||||
|
|
||||||
DropDownList* DropDownMultipleChoiceList::createSubMenu(ChoiceField::ChoiceP group) const {
|
DropDownList* DropDownMultipleChoiceList::createSubMenu(ChoiceField::ChoiceP group) const {
|
||||||
return new DropDownMultipleChoiceList(const_cast<DropDownMultipleChoiceList*>(this), true, cve, group);
|
return new DropDownMultipleChoiceList(const_cast<DropDownMultipleChoiceList*>(this), true, cve, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DropDownMultipleChoiceList::onMotion(wxMouseEvent& ev) {
|
||||||
|
if (kept_open) {
|
||||||
|
wxSize cs = GetClientSize();
|
||||||
|
if (ev.GetX() < 0 || ev.GetY() < 0 || ev.GetX() >= cs.x || ev.GetY() >= cs.y) {
|
||||||
|
hide(false); // outside box; hide it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DropDownChoiceListBase::onMotion(ev);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : MultipleChoiceValueEditor
|
// ----------------------------------------------------------------------------- : MultipleChoiceValueEditor
|
||||||
|
|
||||||
IMPLEMENT_VALUE_EDITOR(MultipleChoice) {}
|
IMPLEMENT_VALUE_EDITOR(MultipleChoice) {}
|
||||||
|
|||||||
Reference in New Issue
Block a user