diff --git a/changes.txt b/changes.txt index 7529483..6be4ccc 100644 --- a/changes.txt +++ b/changes.txt @@ -1,6 +1,7 @@ -------------------------- 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 - 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. diff --git a/source/Irrlicht/CGUIListBox.cpp b/source/Irrlicht/CGUIListBox.cpp index ed94541..6aa162c 100644 --- a/source/Irrlicht/CGUIListBox.cpp +++ b/source/Irrlicht/CGUIListBox.cpp @@ -23,10 +23,10 @@ namespace gui CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle, bool clip, bool drawBack, bool moveOverSelect) -: IGUIListBox(environment, parent, id, rectangle), Selected(-1), +: IGUIListBox(environment, parent, id, rectangle), Selected(-1), HoverSelected(-1), ItemHeight(0),ItemHeightOverride(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) { #ifdef _DEBUG @@ -110,7 +110,7 @@ void CGUIListBox::removeItem(u32 id) else if ((u32)Selected > id) { Selected -= 1; - selectTime = os::Timer::getTime(); + SelectTime = os::Timer::getTime(); } Items.erase(id); @@ -142,6 +142,7 @@ void CGUIListBox::clear() Items.clear(); ItemsIconWidth = 0; Selected = -1; + HoverSelected = -1; ScrollBar->setPos(0); @@ -186,7 +187,7 @@ void CGUIListBox::recalculateItemHeight() //! returns id of selected item. returns -1 if no item is selected. s32 CGUIListBox::getSelected() const { - return Selected; + return HoverSelected >= 0 ? HoverSelected : Selected; } @@ -198,7 +199,8 @@ void CGUIListBox::setSelected(s32 id) else Selected = id; - selectTime = os::Timer::getTime(); + HoverSelected = -1; + SelectTime = os::Timer::getTime(); recalculateScrollPos(); } @@ -448,14 +450,19 @@ void CGUIListBox::selectNew(s32 ypos, bool onlyHover) u32 now = os::Timer::getTime(); s32 oldSelected = Selected; - Selected = getItemAt(AbsoluteRect.UpperLeftCorner.X, ypos); - if (Selected<0 && !Items.empty()) - Selected = 0; + HoverSelected = getItemAt(AbsoluteRect.UpperLeftCorner.X, ypos); + if (HoverSelected<0 && !Items.empty()) + HoverSelected = 0; + if (!onlyHover) + { + Selected = HoverSelected; + HoverSelected = -1; + } recalculateScrollPos(); - gui::EGUI_EVENT_TYPE eventType = (Selected == oldSelected && now < selectTime + 500) ? EGET_LISTBOX_SELECTED_AGAIN : EGET_LISTBOX_CHANGED; - selectTime = now; + gui::EGUI_EVENT_TYPE eventType = (Selected == oldSelected && now < SelectTime + 500) ? EGET_LISTBOX_SELECTED_AGAIN : EGET_LISTBOX_CHANGED; + SelectTime = now; // post the news if (Parent && !onlyHover) { @@ -521,13 +528,14 @@ void CGUIListBox::draw() frameRect.LowerRightCorner.Y -= ScrollBar->getPos(); bool hl = (HighlightWhenNotFocused || Environment->hasFocus(this) || Environment->hasFocus(ScrollBar)); + const irr::s32 selected = getSelected(); for (s32 i=0; i<(s32)Items.size(); ++i) { if (frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.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); } @@ -547,24 +555,24 @@ void CGUIListBox::draw() iconPos.Y += textRect.getHeight() / 2; iconPos.X += ItemsIconWidth/2; - if ( i==Selected && hl ) + if ( i==selected && hl ) { IconBank->draw2DSprite( (u32)Items[i].Icon, iconPos, &clientClip, hasItemOverrideColor(i, 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 { IconBank->draw2DSprite( (u32)Items[i].Icon, iconPos, &clientClip, 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; - if ( i==Selected && hl ) + if ( i==selected && hl ) { Font->draw(Items[i].Text.c_str(), textRect, hasItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) ? @@ -768,6 +776,7 @@ void CGUIListBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadW } } Selected = in->getAttributeAsInt("Selected", Selected); + HoverSelected = -1; recalculateScrollPos(); } diff --git a/source/Irrlicht/CGUIListBox.h b/source/Irrlicht/CGUIListBox.h index 10a9e5f..6ba5a25 100644 --- a/source/Irrlicht/CGUIListBox.h +++ b/source/Irrlicht/CGUIListBox.h @@ -164,6 +164,7 @@ namespace gui core::array< ListItem > Items; 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 ItemHeightOverride; s32 TotalItemHeight; @@ -171,7 +172,7 @@ namespace gui gui::IGUIFont* Font; gui::IGUISpriteBank* IconBank; gui::IGUIScrollBar* ScrollBar; - u32 selectTime; + u32 SelectTime; u32 LastKeyTime; core::stringw KeyBuffer; bool Selecting;