fixed bugs with listbox automatic visibility of scrollbars, and clicking on listbox scrollbars when in a combo box.

items in a listbox are now selected as you type their text.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@799 dfc29bdd-3216-0410-991c-e03cc46cb475
master
bitplane 2007-07-18 22:47:05 +00:00
parent 3f4fb37f5e
commit 1d6a992ee0
4 changed files with 124 additions and 31 deletions

View File

@ -66,7 +66,7 @@ GUI:
- EGET_ELEMENT_FOCUS_LOST and EGET_ELEMENT_FOCUSED events can now be absorbed
by returning true in OnEvent. Absorbing these events will cancel the focus
change.
change.
- IGUIEnvironment::setFocus and removeFocus now return bools.
@ -124,9 +124,11 @@ GUI:
- IGUIStaticText new methods setDrawBorder and setTextAlignment.
- Added IGUIListBox::setAutoScrollEnabled and isAutoScrollEnabled, for automatic
scrolling when selecting or adding an item. Scrollbars are now only visible
when the list doesn't fit in the visible area.
- IGUIListBox changes:
Added setAutoScrollEnabled and isAutoScrollEnabled, for automatic scrolling
when selecting or adding an item.
Scrollbars are now only visible when the list doesn't fit in the visible area.
You can now type an item's text to select it.
Changes in version 1.3.1 (20 Jun 2007)

View File

@ -199,7 +199,7 @@ bool CGUIComboBox::OnEvent(SEvent event)
if (Selected <0)
Selected = 0;
else
if (Selected >= (s32)Items.size())
Selected = (s32)Items.size() -1;
@ -216,9 +216,12 @@ bool CGUIComboBox::OnEvent(SEvent event)
switch(event.GUIEvent.EventType)
{
case EGET_ELEMENT_FOCUS_LOST:
if (Environment->hasFocus(ListBox) &&
if (ListBox &&
(Environment->hasFocus(ListBox) || ListBox->isMyChild(event.GUIEvent.Caller) ) &&
event.GUIEvent.Element != this &&
event.GUIEvent.Element != ListButton)
event.GUIEvent.Element != ListButton &&
event.GUIEvent.Element != ListBox &&
!ListBox->isMyChild(event.GUIEvent.Element))
{
openCloseMenu();
}
@ -279,6 +282,20 @@ bool CGUIComboBox::OnEvent(SEvent event)
}
}
break;
case EMIE_MOUSE_WHEEL:
{
s32 oldSelected = Selected;
Selected += (event.MouseInput.Wheel < 0) ? 1 : -1;
if (Selected <0)
Selected = 0;
if (Selected >= (s32)Items.size())
Selected = (s32)Items.size() -1;
if (Selected != oldSelected)
sendSelectionChangedEvent();
}
}
break;
}

View File

@ -23,7 +23,8 @@ CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent,
: IGUIListBox(environment, parent, id, rectangle), Selected(-1), ItemHeight(0),
TotalItemHeight(0), ItemsIconWidth(0), Font(0), IconBank(0),
ScrollBar(0), Selecting(false), DrawBack(drawBack),
MoveOverSelect(moveOverSelect), selectTime(0), AutoScroll(true)
MoveOverSelect(moveOverSelect), selectTime(0), AutoScroll(true),
KeyBuffer(), LastKeyTime(0), HighlightWhenNotFocused(true)
{
#ifdef _DEBUG
setDebugName("CGUIListBox");
@ -170,7 +171,7 @@ void CGUIListBox::recalculateItemHeight()
TotalItemHeight = ItemHeight * Items.size();
ScrollBar->setMax(TotalItemHeight - AbsoluteRect.getHeight());
if( TotalItemHeight < AbsoluteRect.getHeight() )
if( TotalItemHeight <= AbsoluteRect.getHeight() )
ScrollBar->setVisible(false);
else
ScrollBar->setVisible(true);
@ -276,6 +277,85 @@ bool CGUIListBox::OnEvent(SEvent event)
}
return true;
}
else if (event.KeyInput.PressedDown && event.KeyInput.Char)
{
// change selection based on text as it is typed.
u32 now = os::Timer::getTime();
if (now - LastKeyTime < 500)
{
// add to key buffer if it isn't a key repeat
if (!(KeyBuffer.size() == 1 && KeyBuffer[0] == event.KeyInput.Char))
{
KeyBuffer += L" ";
KeyBuffer[KeyBuffer.size()-1] = event.KeyInput.Char;
}
}
else
{
KeyBuffer = L" ";
KeyBuffer[0] = event.KeyInput.Char;
}
LastKeyTime = now;
// find the selected item, starting at the current selection
s32 start = Selected;
s32 current = start+1;
// dont change selection if the key buffer matches the current item
if (Selected > -1 && KeyBuffer.size() > 1)
{
if (Items[Selected].text.size() >= KeyBuffer.size() &&
KeyBuffer.equals_ignore_case(Items[Selected].text.subString(0,KeyBuffer.size())))
return true;
}
while (current < (s32)Items.size())
{
if (Items[current].text.size() >= KeyBuffer.size())
{
if (KeyBuffer.equals_ignore_case(Items[current].text.subString(0,KeyBuffer.size())))
{
if (Parent && Selected != current && !Selecting && !MoveOverSelect)
{
SEvent e;
e.EventType = EET_GUI_EVENT;
e.GUIEvent.Caller = this;
e.GUIEvent.Element = 0;
e.GUIEvent.EventType = EGET_LISTBOX_CHANGED;
Parent->OnEvent(e);
}
setSelected(current);
return true;
}
}
current++;
}
current = 0;
while (current <= start)
{
if (Items[current].text.size() >= KeyBuffer.size())
{
if (KeyBuffer.equals_ignore_case(Items[current].text.subString(0,KeyBuffer.size())))
{
if (Parent && Selected != current && !Selecting && !MoveOverSelect)
{
Selected = current;
SEvent e;
e.EventType = EET_GUI_EVENT;
e.GUIEvent.Caller = this;
e.GUIEvent.Element = 0;
e.GUIEvent.EventType = EGET_LISTBOX_CHANGED;
Parent->OnEvent(e);
}
setSelected(current);
return true;
}
}
current++;
}
return true;
}
break;
case EET_GUI_EVENT:
@ -306,26 +386,11 @@ bool CGUIListBox::OnEvent(SEvent event)
case EMIE_LMOUSE_PRESSED_DOWN:
{
IGUIElement *el = Environment->getRootGUIElement()->getElementFromPoint(
core::position2di(event.MouseInput.X, event.MouseInput.Y));
if (Environment->hasFocus(this) &&
ScrollBar == el &&
ScrollBar->OnEvent(event))
{
return true;
}
Selecting = true;
Environment->setFocus(this);
return true;
}
case EMIE_LMOUSE_LEFT_UP:
if (Environment->hasFocus(this) &&
ScrollBar->isPointInside(p) &&
ScrollBar->OnEvent(event))
return true;
if (!isPointInside(p))
{
@ -372,8 +437,9 @@ void CGUIListBox::selectNew(s32 ypos, bool onlyHover)
if (Selected<0)
Selected = 0;
// post the news
recalculateScrollPos();
// post the news
if (Parent && !onlyHover)
{
SEvent event;
@ -413,7 +479,8 @@ void CGUIListBox::draw()
core::rect<s32> clientClip(AbsoluteRect);
clientClip.UpperLeftCorner.Y += 1;
clientClip.UpperLeftCorner.X += 1;
clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
if (ScrollBar->isVisible())
clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
clientClip.LowerRightCorner.Y -= 1;
clientClip.clipAgainst(AbsoluteClippingRect);
@ -425,18 +492,22 @@ void CGUIListBox::draw()
frameRect = AbsoluteRect;
frameRect.UpperLeftCorner.X += 1;
frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
if (ScrollBar->isVisible())
frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight;
frameRect.UpperLeftCorner.Y -= ScrollBar->getPos();
frameRect.LowerRightCorner.Y -= ScrollBar->getPos();
bool hl = (HighlightWhenNotFocused || Environment->hasFocus(this) || Environment->hasFocus(ScrollBar));
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)
if (i == Selected && hl)
skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), frameRect, &clientClip);
core::rect<s32> textRect = frameRect;
@ -450,13 +521,13 @@ void CGUIListBox::draw()
iconPos.Y += textRect.getHeight() / 2;
iconPos.X += ItemsIconWidth/2;
IconBank->draw2DSprite( (u32)Items[i].icon, iconPos, &clientClip,
skin->getColor((i==Selected) ? EGDC_ICON_HIGH_LIGHT : EGDC_ICON),
(i==Selected) ? selectTime : 0 , (i==Selected) ? os::Timer::getTime() : 0, false, true);
skin->getColor((i==Selected && hl) ? EGDC_ICON_HIGH_LIGHT : EGDC_ICON),
(i==Selected && hl) ? selectTime : 0 , (i==Selected) ? os::Timer::getTime() : 0, false, true);
}
textRect.UpperLeftCorner.X += ItemsIconWidth+3;
Font->draw(Items[i].text.c_str(), textRect, skin->getColor((i==Selected) ? EGDC_HIGH_LIGHT_TEXT : EGDC_BUTTON_TEXT), false, true, &clientClip);
Font->draw(Items[i].text.c_str(), textRect, skin->getColor((i==Selected && hl) ? EGDC_HIGH_LIGHT_TEXT : EGDC_BUTTON_TEXT), false, true, &clientClip);
textRect.UpperLeftCorner.X -= ItemsIconWidth+3;
}

View File

@ -113,6 +113,9 @@ namespace gui
bool MoveOverSelect;
u32 selectTime;
bool AutoScroll;
core::stringw KeyBuffer;
u32 LastKeyTime;
bool HighlightWhenNotFocused;
};