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-e03cc46cb475master
parent
3f4fb37f5e
commit
1d6a992ee0
|
@ -124,9 +124,11 @@ GUI:
|
||||||
|
|
||||||
- IGUIStaticText new methods setDrawBorder and setTextAlignment.
|
- IGUIStaticText new methods setDrawBorder and setTextAlignment.
|
||||||
|
|
||||||
- Added IGUIListBox::setAutoScrollEnabled and isAutoScrollEnabled, for automatic
|
- IGUIListBox changes:
|
||||||
scrolling when selecting or adding an item. Scrollbars are now only visible
|
Added setAutoScrollEnabled and isAutoScrollEnabled, for automatic scrolling
|
||||||
when the list doesn't fit in the visible area.
|
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)
|
Changes in version 1.3.1 (20 Jun 2007)
|
||||||
|
|
|
@ -199,7 +199,7 @@ bool CGUIComboBox::OnEvent(SEvent event)
|
||||||
|
|
||||||
if (Selected <0)
|
if (Selected <0)
|
||||||
Selected = 0;
|
Selected = 0;
|
||||||
else
|
|
||||||
if (Selected >= (s32)Items.size())
|
if (Selected >= (s32)Items.size())
|
||||||
Selected = (s32)Items.size() -1;
|
Selected = (s32)Items.size() -1;
|
||||||
|
|
||||||
|
@ -216,9 +216,12 @@ bool CGUIComboBox::OnEvent(SEvent event)
|
||||||
switch(event.GUIEvent.EventType)
|
switch(event.GUIEvent.EventType)
|
||||||
{
|
{
|
||||||
case EGET_ELEMENT_FOCUS_LOST:
|
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 != this &&
|
||||||
event.GUIEvent.Element != ListButton)
|
event.GUIEvent.Element != ListButton &&
|
||||||
|
event.GUIEvent.Element != ListBox &&
|
||||||
|
!ListBox->isMyChild(event.GUIEvent.Element))
|
||||||
{
|
{
|
||||||
openCloseMenu();
|
openCloseMenu();
|
||||||
}
|
}
|
||||||
|
@ -279,6 +282,20 @@ bool CGUIComboBox::OnEvent(SEvent event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,8 @@ CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent,
|
||||||
: IGUIListBox(environment, parent, id, rectangle), Selected(-1), ItemHeight(0),
|
: IGUIListBox(environment, parent, id, rectangle), Selected(-1), ItemHeight(0),
|
||||||
TotalItemHeight(0), ItemsIconWidth(0), Font(0), IconBank(0),
|
TotalItemHeight(0), ItemsIconWidth(0), Font(0), IconBank(0),
|
||||||
ScrollBar(0), Selecting(false), DrawBack(drawBack),
|
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
|
#ifdef _DEBUG
|
||||||
setDebugName("CGUIListBox");
|
setDebugName("CGUIListBox");
|
||||||
|
@ -170,7 +171,7 @@ void CGUIListBox::recalculateItemHeight()
|
||||||
TotalItemHeight = ItemHeight * Items.size();
|
TotalItemHeight = ItemHeight * Items.size();
|
||||||
ScrollBar->setMax(TotalItemHeight - AbsoluteRect.getHeight());
|
ScrollBar->setMax(TotalItemHeight - AbsoluteRect.getHeight());
|
||||||
|
|
||||||
if( TotalItemHeight < AbsoluteRect.getHeight() )
|
if( TotalItemHeight <= AbsoluteRect.getHeight() )
|
||||||
ScrollBar->setVisible(false);
|
ScrollBar->setVisible(false);
|
||||||
else
|
else
|
||||||
ScrollBar->setVisible(true);
|
ScrollBar->setVisible(true);
|
||||||
|
@ -276,6 +277,85 @@ bool CGUIListBox::OnEvent(SEvent event)
|
||||||
}
|
}
|
||||||
return true;
|
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;
|
break;
|
||||||
|
|
||||||
case EET_GUI_EVENT:
|
case EET_GUI_EVENT:
|
||||||
|
@ -306,26 +386,11 @@ bool CGUIListBox::OnEvent(SEvent event)
|
||||||
|
|
||||||
case EMIE_LMOUSE_PRESSED_DOWN:
|
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;
|
Selecting = true;
|
||||||
Environment->setFocus(this);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case EMIE_LMOUSE_LEFT_UP:
|
case EMIE_LMOUSE_LEFT_UP:
|
||||||
if (Environment->hasFocus(this) &&
|
|
||||||
ScrollBar->isPointInside(p) &&
|
|
||||||
ScrollBar->OnEvent(event))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (!isPointInside(p))
|
if (!isPointInside(p))
|
||||||
{
|
{
|
||||||
|
@ -372,8 +437,9 @@ void CGUIListBox::selectNew(s32 ypos, bool onlyHover)
|
||||||
if (Selected<0)
|
if (Selected<0)
|
||||||
Selected = 0;
|
Selected = 0;
|
||||||
|
|
||||||
// post the news
|
recalculateScrollPos();
|
||||||
|
|
||||||
|
// post the news
|
||||||
if (Parent && !onlyHover)
|
if (Parent && !onlyHover)
|
||||||
{
|
{
|
||||||
SEvent event;
|
SEvent event;
|
||||||
|
@ -413,6 +479,7 @@ void CGUIListBox::draw()
|
||||||
core::rect<s32> clientClip(AbsoluteRect);
|
core::rect<s32> clientClip(AbsoluteRect);
|
||||||
clientClip.UpperLeftCorner.Y += 1;
|
clientClip.UpperLeftCorner.Y += 1;
|
||||||
clientClip.UpperLeftCorner.X += 1;
|
clientClip.UpperLeftCorner.X += 1;
|
||||||
|
if (ScrollBar->isVisible())
|
||||||
clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
|
clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
|
||||||
clientClip.LowerRightCorner.Y -= 1;
|
clientClip.LowerRightCorner.Y -= 1;
|
||||||
clientClip.clipAgainst(AbsoluteClippingRect);
|
clientClip.clipAgainst(AbsoluteClippingRect);
|
||||||
|
@ -425,18 +492,22 @@ void CGUIListBox::draw()
|
||||||
|
|
||||||
frameRect = AbsoluteRect;
|
frameRect = AbsoluteRect;
|
||||||
frameRect.UpperLeftCorner.X += 1;
|
frameRect.UpperLeftCorner.X += 1;
|
||||||
|
if (ScrollBar->isVisible())
|
||||||
frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
|
frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
|
||||||
|
|
||||||
frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight;
|
frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight;
|
||||||
|
|
||||||
frameRect.UpperLeftCorner.Y -= ScrollBar->getPos();
|
frameRect.UpperLeftCorner.Y -= ScrollBar->getPos();
|
||||||
frameRect.LowerRightCorner.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)
|
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)
|
if (i == Selected && hl)
|
||||||
skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), frameRect, &clientClip);
|
skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), frameRect, &clientClip);
|
||||||
|
|
||||||
core::rect<s32> textRect = frameRect;
|
core::rect<s32> textRect = frameRect;
|
||||||
|
@ -450,13 +521,13 @@ void CGUIListBox::draw()
|
||||||
iconPos.Y += textRect.getHeight() / 2;
|
iconPos.Y += textRect.getHeight() / 2;
|
||||||
iconPos.X += ItemsIconWidth/2;
|
iconPos.X += ItemsIconWidth/2;
|
||||||
IconBank->draw2DSprite( (u32)Items[i].icon, iconPos, &clientClip,
|
IconBank->draw2DSprite( (u32)Items[i].icon, iconPos, &clientClip,
|
||||||
skin->getColor((i==Selected) ? EGDC_ICON_HIGH_LIGHT : EGDC_ICON),
|
skin->getColor((i==Selected && hl) ? EGDC_ICON_HIGH_LIGHT : EGDC_ICON),
|
||||||
(i==Selected) ? selectTime : 0 , (i==Selected) ? os::Timer::getTime() : 0, false, true);
|
(i==Selected && hl) ? selectTime : 0 , (i==Selected) ? os::Timer::getTime() : 0, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
textRect.UpperLeftCorner.X += ItemsIconWidth+3;
|
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;
|
textRect.UpperLeftCorner.X -= ItemsIconWidth+3;
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,9 @@ namespace gui
|
||||||
bool MoveOverSelect;
|
bool MoveOverSelect;
|
||||||
u32 selectTime;
|
u32 selectTime;
|
||||||
bool AutoScroll;
|
bool AutoScroll;
|
||||||
|
core::stringw KeyBuffer;
|
||||||
|
u32 LastKeyTime;
|
||||||
|
bool HighlightWhenNotFocused;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue