Fix: Listbox was sometimes sending EGET_LISTBOX_SELECTED_AGAIN instead of EGET_LISTBOX_CHANGED.

When pressed mouse was moved over an item before releasing the mouse button it was sending immediately EGET_LISTBOX_SELECTED_AGAIN instead of expected EGET_LISTBOX_CHANGED (mouse  move changes do not send any events).


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6454 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2023-03-06 14:34:16 +00:00
parent 75d485b5cd
commit f989112dcb
3 changed files with 27 additions and 16 deletions

@ -1,6 +1,7 @@
-------------------------- --------------------------
Changes in 1.9 (not yet released) Changes in 1.9 (not yet released)
- Fix: Listbox no longer sending EGET_LISTBOX_SELECTED_AGAIN instead of EGET_LISTBOX_CHANGED when pressed mouse was moved over item before releasing the mouse button
- Listbox items can now change individual background colors - Listbox items can now change individual background colors
- Fix some bitfield sizes in SMaterial which were chosen too small for enums (PolygonOffsetDirection, ZWriteEnable, BlendOperation) - Fix some bitfield sizes in SMaterial which were chosen too small for enums (PolygonOffsetDirection, ZWriteEnable, BlendOperation)
- Add ISceneNode::UpdateAbsolutePosBehavior variable to allow nodes to ignore the scale/rotation parts of their parents transformation. - Add ISceneNode::UpdateAbsolutePosBehavior variable to allow nodes to ignore the scale/rotation parts of their parents transformation.

@ -23,10 +23,10 @@ namespace gui
CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent, CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent,
s32 id, core::rect<s32> rectangle, bool clip, s32 id, core::rect<s32> rectangle, bool clip,
bool drawBack, bool moveOverSelect) bool drawBack, bool moveOverSelect)
: IGUIListBox(environment, parent, id, rectangle), Selected(-1), : IGUIListBox(environment, parent, id, rectangle), Selected(-1), HoverSelected(-1),
ItemHeight(0),ItemHeightOverride(0), ItemHeight(0),ItemHeightOverride(0),
TotalItemHeight(0), ItemsIconWidth(0), Font(0), IconBank(0), TotalItemHeight(0), ItemsIconWidth(0), Font(0), IconBank(0),
ScrollBar(0), selectTime(0), LastKeyTime(0), Selecting(false), DrawBack(drawBack), ScrollBar(0), SelectTime(0), LastKeyTime(0), Selecting(false), DrawBack(drawBack),
MoveOverSelect(moveOverSelect), AutoScroll(true), HighlightWhenNotFocused(true) MoveOverSelect(moveOverSelect), AutoScroll(true), HighlightWhenNotFocused(true)
{ {
#ifdef _DEBUG #ifdef _DEBUG
@ -110,7 +110,7 @@ void CGUIListBox::removeItem(u32 id)
else if ((u32)Selected > id) else if ((u32)Selected > id)
{ {
Selected -= 1; Selected -= 1;
selectTime = os::Timer::getTime(); SelectTime = os::Timer::getTime();
} }
Items.erase(id); Items.erase(id);
@ -142,6 +142,7 @@ void CGUIListBox::clear()
Items.clear(); Items.clear();
ItemsIconWidth = 0; ItemsIconWidth = 0;
Selected = -1; Selected = -1;
HoverSelected = -1;
ScrollBar->setPos(0); ScrollBar->setPos(0);
@ -186,7 +187,7 @@ void CGUIListBox::recalculateItemHeight()
//! returns id of selected item. returns -1 if no item is selected. //! returns id of selected item. returns -1 if no item is selected.
s32 CGUIListBox::getSelected() const s32 CGUIListBox::getSelected() const
{ {
return Selected; return HoverSelected >= 0 ? HoverSelected : Selected;
} }
@ -198,7 +199,8 @@ void CGUIListBox::setSelected(s32 id)
else else
Selected = id; Selected = id;
selectTime = os::Timer::getTime(); HoverSelected = -1;
SelectTime = os::Timer::getTime();
recalculateScrollPos(); recalculateScrollPos();
} }
@ -448,14 +450,19 @@ void CGUIListBox::selectNew(s32 ypos, bool onlyHover)
u32 now = os::Timer::getTime(); u32 now = os::Timer::getTime();
s32 oldSelected = Selected; s32 oldSelected = Selected;
Selected = getItemAt(AbsoluteRect.UpperLeftCorner.X, ypos); HoverSelected = getItemAt(AbsoluteRect.UpperLeftCorner.X, ypos);
if (Selected<0 && !Items.empty()) if (HoverSelected<0 && !Items.empty())
Selected = 0; HoverSelected = 0;
if (!onlyHover)
{
Selected = HoverSelected;
HoverSelected = -1;
}
recalculateScrollPos(); recalculateScrollPos();
gui::EGUI_EVENT_TYPE eventType = (Selected == oldSelected && now < selectTime + 500) ? EGET_LISTBOX_SELECTED_AGAIN : EGET_LISTBOX_CHANGED; gui::EGUI_EVENT_TYPE eventType = (Selected == oldSelected && now < SelectTime + 500) ? EGET_LISTBOX_SELECTED_AGAIN : EGET_LISTBOX_CHANGED;
selectTime = now; SelectTime = now;
// post the news // post the news
if (Parent && !onlyHover) if (Parent && !onlyHover)
{ {
@ -521,13 +528,14 @@ void CGUIListBox::draw()
frameRect.LowerRightCorner.Y -= ScrollBar->getPos(); frameRect.LowerRightCorner.Y -= ScrollBar->getPos();
bool hl = (HighlightWhenNotFocused || Environment->hasFocus(this) || Environment->hasFocus(ScrollBar)); bool hl = (HighlightWhenNotFocused || Environment->hasFocus(this) || Environment->hasFocus(ScrollBar));
const irr::s32 selected = getSelected();
for (s32 i=0; i<(s32)Items.size(); ++i) for (s32 i=0; i<(s32)Items.size(); ++i)
{ {
if (frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y && if (frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y &&
frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y) frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y)
{ {
if (i == Selected && hl) if (i == selected && hl)
{ {
skin->draw2DRectangle(this, hasItemOverrideColor(i, EGUI_LBC_BACKGROUND_HIGHLIGHT) ? getItemOverrideColor(i, EGUI_LBC_BACKGROUND_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_BACKGROUND_HIGHLIGHT), frameRect, &clientClip); skin->draw2DRectangle(this, hasItemOverrideColor(i, EGUI_LBC_BACKGROUND_HIGHLIGHT) ? getItemOverrideColor(i, EGUI_LBC_BACKGROUND_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_BACKGROUND_HIGHLIGHT), frameRect, &clientClip);
} }
@ -547,24 +555,24 @@ void CGUIListBox::draw()
iconPos.Y += textRect.getHeight() / 2; iconPos.Y += textRect.getHeight() / 2;
iconPos.X += ItemsIconWidth/2; iconPos.X += ItemsIconWidth/2;
if ( i==Selected && hl ) if ( i==selected && hl )
{ {
IconBank->draw2DSprite( (u32)Items[i].Icon, iconPos, &clientClip, IconBank->draw2DSprite( (u32)Items[i].Icon, iconPos, &clientClip,
hasItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) ? hasItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) ?
getItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_ICON_HIGHLIGHT), getItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_ICON_HIGHLIGHT),
selectTime, os::Timer::getTime(), false, true); SelectTime, os::Timer::getTime(), false, true);
} }
else else
{ {
IconBank->draw2DSprite( (u32)Items[i].Icon, iconPos, &clientClip, IconBank->draw2DSprite( (u32)Items[i].Icon, iconPos, &clientClip,
hasItemOverrideColor(i, EGUI_LBC_ICON) ? getItemOverrideColor(i, EGUI_LBC_ICON) : getItemDefaultColor(EGUI_LBC_ICON), hasItemOverrideColor(i, EGUI_LBC_ICON) ? getItemOverrideColor(i, EGUI_LBC_ICON) : getItemDefaultColor(EGUI_LBC_ICON),
0 , (i==Selected) ? os::Timer::getTime() : 0, false, true); 0 , (i==selected) ? os::Timer::getTime() : 0, false, true);
} }
} }
textRect.UpperLeftCorner.X += ItemsIconWidth+3; textRect.UpperLeftCorner.X += ItemsIconWidth+3;
if ( i==Selected && hl ) if ( i==selected && hl )
{ {
Font->draw(Items[i].Text.c_str(), textRect, Font->draw(Items[i].Text.c_str(), textRect,
hasItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) ? hasItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) ?
@ -768,6 +776,7 @@ void CGUIListBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadW
} }
} }
Selected = in->getAttributeAsInt("Selected", Selected); Selected = in->getAttributeAsInt("Selected", Selected);
HoverSelected = -1;
recalculateScrollPos(); recalculateScrollPos();
} }

@ -164,6 +164,7 @@ namespace gui
core::array< ListItem > Items; core::array< ListItem > Items;
s32 Selected; s32 Selected;
s32 HoverSelected; // When >= 0 we're in the middle of changing selection while mouse is pressed. We need to know so selected again isn't called too often.
s32 ItemHeight; s32 ItemHeight;
s32 ItemHeightOverride; s32 ItemHeightOverride;
s32 TotalItemHeight; s32 TotalItemHeight;
@ -171,7 +172,7 @@ namespace gui
gui::IGUIFont* Font; gui::IGUIFont* Font;
gui::IGUISpriteBank* IconBank; gui::IGUISpriteBank* IconBank;
gui::IGUIScrollBar* ScrollBar; gui::IGUIScrollBar* ScrollBar;
u32 selectTime; u32 SelectTime;
u32 LastKeyTime; u32 LastKeyTime;
core::stringw KeyBuffer; core::stringw KeyBuffer;
bool Selecting; bool Selecting;