Commit b523d0a5 authored by bitplane's avatar bitplane

Listbox double click now times out. Added scrollbar tray clicks and get/setLargeStep

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@985 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 63f28cf5
...@@ -33,9 +33,17 @@ namespace gui ...@@ -33,9 +33,17 @@ namespace gui
//! gets the small step value //! gets the small step value
virtual s32 getSmallStep() const = 0; virtual s32 getSmallStep() const = 0;
//! sets the small step value //! Sets the small step, the amount that the value changes by when clicking
//! on the buttons or using the cursor keys.
virtual void setSmallStep(s32 step) = 0; virtual void setSmallStep(s32 step) = 0;
//! gets the large step value
virtual s32 getLargeStep() const = 0;
//! Sets the large step, the amount that the value changes by when clicking
//! in the tray, or using the page up and page down keys.
virtual void setLargeStep(s32 step) = 0;
//! gets the current position of the scrollbar //! gets the current position of the scrollbar
virtual s32 getPos() const = 0; virtual s32 getPos() const = 0;
......
...@@ -412,6 +412,7 @@ bool CGUIListBox::OnEvent(const SEvent& event) ...@@ -412,6 +412,7 @@ bool CGUIListBox::OnEvent(const SEvent& event)
void CGUIListBox::selectNew(s32 ypos, bool onlyHover) void CGUIListBox::selectNew(s32 ypos, bool onlyHover)
{ {
u32 now = os::Timer::getTime();
s32 oldSelected = Selected; s32 oldSelected = Selected;
// find new selected item. // find new selected item.
...@@ -433,9 +434,10 @@ void CGUIListBox::selectNew(s32 ypos, bool onlyHover) ...@@ -433,9 +434,10 @@ void CGUIListBox::selectNew(s32 ypos, bool onlyHover)
event.EventType = EET_GUI_EVENT; event.EventType = EET_GUI_EVENT;
event.GUIEvent.Caller = this; event.GUIEvent.Caller = this;
event.GUIEvent.Element = 0; event.GUIEvent.Element = 0;
event.GUIEvent.EventType = (Selected != oldSelected) ? EGET_LISTBOX_CHANGED : EGET_LISTBOX_SELECTED_AGAIN; event.GUIEvent.EventType = (Selected == oldSelected && now < selectTime + 500) ? EGET_LISTBOX_SELECTED_AGAIN : EGET_LISTBOX_CHANGED;
Parent->OnEvent(event); Parent->OnEvent(event);
} }
selectTime = now;
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "CGUIButton.h" #include "CGUIButton.h"
#include "IGUIFont.h" #include "IGUIFont.h"
#include "IGUIFontBitmap.h" #include "IGUIFontBitmap.h"
#include "os.h"
namespace irr namespace irr
{ {
...@@ -23,8 +24,9 @@ CGUIScrollBar::CGUIScrollBar(bool horizontal, IGUIEnvironment* environment, ...@@ -23,8 +24,9 @@ CGUIScrollBar::CGUIScrollBar(bool horizontal, IGUIEnvironment* environment,
IGUIElement* parent, s32 id, IGUIElement* parent, s32 id,
core::rect<s32> rectangle, bool noclip) core::rect<s32> rectangle, bool noclip)
: IGUIScrollBar(environment, parent, id, rectangle), UpButton(0), DownButton(0), : IGUIScrollBar(environment, parent, id, rectangle), UpButton(0), DownButton(0),
Dragging(false), Horizontal(horizontal), Pos(0), DrawPos(0), Dragging(false), DraggedBySlider(false), TrayClick(false),
DrawHeight(0), Max(100), SmallStep(10) Horizontal(horizontal), Pos(0), DrawPos(0), DrawHeight(0), Max(100), SmallStep(10), LargeStep(50),
DesiredPos(0), LastChange(0), SliderRect()
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CGUIScrollBar"); setDebugName("CGUIScrollBar");
...@@ -74,13 +76,17 @@ bool CGUIScrollBar::OnEvent(const SEvent& event) ...@@ -74,13 +76,17 @@ bool CGUIScrollBar::OnEvent(const SEvent& event)
setPos(Pos+SmallStep); setPos(Pos+SmallStep);
break; break;
case KEY_HOME: case KEY_HOME:
case KEY_PRIOR:
setPos(0); setPos(0);
break; break;
case KEY_PRIOR:
setPos(Pos-LargeStep);
break;
case KEY_END: case KEY_END:
case KEY_NEXT:
setPos(Max); setPos(Max);
break; break;
case KEY_NEXT:
setPos(Pos+LargeStep);
break;
default: default:
absorb = false; absorb = false;
} }
...@@ -127,7 +133,7 @@ bool CGUIScrollBar::OnEvent(const SEvent& event) ...@@ -127,7 +133,7 @@ bool CGUIScrollBar::OnEvent(const SEvent& event)
switch(event.MouseInput.Event) switch(event.MouseInput.Event)
{ {
case EMIE_MOUSE_WHEEL: case EMIE_MOUSE_WHEEL:
if (Environment->getFocus() == this) if (Environment->hasFocus(this))
{ // thanks to a bug report by REAPER { // thanks to a bug report by REAPER
setPos(getPos() + (s32)event.MouseInput.Wheel* -SmallStep); setPos(getPos() + (s32)event.MouseInput.Wheel* -SmallStep);
SEvent newEvent; SEvent newEvent;
...@@ -141,28 +147,49 @@ bool CGUIScrollBar::OnEvent(const SEvent& event) ...@@ -141,28 +147,49 @@ bool CGUIScrollBar::OnEvent(const SEvent& event)
break; break;
case EMIE_LMOUSE_PRESSED_DOWN: case EMIE_LMOUSE_PRESSED_DOWN:
{ {
if (AbsoluteClippingRect.isPointInside(core::position2di(event.MouseInput.X, event.MouseInput.Y))) if (AbsoluteClippingRect.isPointInside(core::position2di(event.MouseInput.X, event.MouseInput.Y)))
{ {
Dragging = true; Dragging = true;
Environment->setFocus(this); DraggedBySlider = SliderRect.isPointInside(core::position2di(event.MouseInput.X, event.MouseInput.Y));
DesiredPos = getPosFromMousePos(event.MouseInput.X, event.MouseInput.Y);
return true; return true;
} }
else
{
Environment->removeFocus(this);
}
break; break;
} }
case EMIE_LMOUSE_LEFT_UP: case EMIE_LMOUSE_LEFT_UP:
Dragging = false;
return true;
case EMIE_MOUSE_MOVED: case EMIE_MOUSE_MOVED:
if (Dragging) if (Dragging)
{ {
if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
Dragging = false;
s32 newPos = getPosFromMousePos(event.MouseInput.X, event.MouseInput.Y);
s32 oldPos = Pos; s32 oldPos = Pos;
setPosFromMousePos(event.MouseInput.X, event.MouseInput.Y);
if (!DraggedBySlider)
{
if (AbsoluteClippingRect.isPointInside(core::position2di(event.MouseInput.X, event.MouseInput.Y)))
{
DraggedBySlider = SliderRect.isPointInside(core::position2di(event.MouseInput.X, event.MouseInput.Y));
TrayClick = !DraggedBySlider;
}
else
{
TrayClick = false;
if (event.MouseInput.Event == EMIE_MOUSE_MOVED)
return true;
}
}
if (DraggedBySlider)
{
setPos(newPos);
}
else
{
DesiredPos = newPos;
}
if (Pos != oldPos && Parent) if (Pos != oldPos && Parent)
{ {
SEvent newEvent; SEvent newEvent;
...@@ -174,6 +201,7 @@ bool CGUIScrollBar::OnEvent(const SEvent& event) ...@@ -174,6 +201,7 @@ bool CGUIScrollBar::OnEvent(const SEvent& event)
} }
return true; return true;
} }
break;
default: default:
break; break;
} }
...@@ -195,26 +223,46 @@ void CGUIScrollBar::draw() ...@@ -195,26 +223,46 @@ void CGUIScrollBar::draw()
if (!skin) if (!skin)
return; return;
core::rect<s32> rect = AbsoluteRect; u32 now = os::Timer::getRealTime();
if (Dragging && !DraggedBySlider && TrayClick && now > LastChange + 200)
{
LastChange = now;
if (DesiredPos >= Pos + LargeStep)
setPos(Pos + LargeStep);
else
if (DesiredPos >= Pos + SmallStep)
setPos(Pos + SmallStep);
else
if (DesiredPos <= Pos - LargeStep)
setPos(Pos - LargeStep);
else
if (DesiredPos <= Pos - SmallStep)
setPos(Pos - SmallStep);
}
SliderRect = AbsoluteRect;
// draws the background // draws the background
skin->draw2DRectangle(this, skin->getColor(EGDC_SCROLLBAR), rect, &AbsoluteClippingRect); skin->draw2DRectangle(this, skin->getColor(EGDC_SCROLLBAR), SliderRect, &AbsoluteClippingRect);
if (Max!=0) if (Max!=0)
{ {
// draw thumb // recalculate slider rectangle
if (Horizontal) if (Horizontal)
{ {
rect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X + DrawPos + RelativeRect.getHeight() - DrawHeight/2; SliderRect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X + DrawPos + RelativeRect.getHeight() - DrawHeight/2;
rect.LowerRightCorner.X = rect.UpperLeftCorner.X + DrawHeight; SliderRect.LowerRightCorner.X = SliderRect.UpperLeftCorner.X + DrawHeight;
} }
else else
{ {
rect.UpperLeftCorner.Y = AbsoluteRect.UpperLeftCorner.Y + DrawPos + RelativeRect.getWidth() - DrawHeight/2; SliderRect.UpperLeftCorner.Y = AbsoluteRect.UpperLeftCorner.Y + DrawPos + RelativeRect.getWidth() - DrawHeight/2;
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + DrawHeight; SliderRect.LowerRightCorner.Y = SliderRect.UpperLeftCorner.Y + DrawHeight;
} }
skin->draw3DButtonPaneStandard(this, rect, &AbsoluteClippingRect); skin->draw3DButtonPaneStandard(this, SliderRect, &AbsoluteClippingRect);
} }
// draw buttons // draw buttons
...@@ -244,17 +292,19 @@ void CGUIScrollBar::updateAbsolutePosition() ...@@ -244,17 +292,19 @@ void CGUIScrollBar::updateAbsolutePosition()
} }
} }
void CGUIScrollBar::setPosFromMousePos(s32 x, s32 y) s32 CGUIScrollBar::getPosFromMousePos(s32 x, s32 y) const
{ {
if (Horizontal) if (Horizontal)
{ {
const f32 f = (RelativeRect.getWidth() - ((f32)RelativeRect.getHeight()*3.0f)) / (f32)Max; const f32 w = RelativeRect.getWidth() - f32(RelativeRect.getHeight())*3.0f;
setPos((s32)(((f32)(x - AbsoluteRect.UpperLeftCorner.X - RelativeRect.getHeight())) / f)); const f32 p = x - AbsoluteRect.UpperLeftCorner.X - RelativeRect.getHeight()*1.5f;
return s32( p/w * f32(Max) );
} }
else else
{ {
const f32 f = (RelativeRect.getHeight() - ((f32)RelativeRect.getWidth()*3.0f)) / (f32)Max; const f32 h = RelativeRect.getHeight() - f32(RelativeRect.getWidth())*3.0f;
setPos((s32)(((f32)y - AbsoluteRect.UpperLeftCorner.Y - RelativeRect.getWidth()) / f)); const f32 p = y - AbsoluteRect.UpperLeftCorner.Y - RelativeRect.getWidth()*1.5f;
return s32( p/h * f32(Max) );
} }
} }
...@@ -302,10 +352,26 @@ void CGUIScrollBar::setSmallStep(s32 step) ...@@ -302,10 +352,26 @@ void CGUIScrollBar::setSmallStep(s32 step)
SmallStep = step; SmallStep = step;
else else
SmallStep = 10; SmallStep = 10;
}
//! gets the small step value
s32 CGUIScrollBar::getLargeStep() const
{
return LargeStep;
} }
//! sets the small step value
void CGUIScrollBar::setLargeStep(s32 step)
{
if (step > 0)
LargeStep = step;
else
LargeStep = 50;
}
//! gets the maximum value of the scrollbar. //! gets the maximum value of the scrollbar.
s32 CGUIScrollBar::getMax() const s32 CGUIScrollBar::getMax() const
{ {
...@@ -425,6 +491,7 @@ void CGUIScrollBar::serializeAttributes(io::IAttributes* out, io::SAttributeRead ...@@ -425,6 +491,7 @@ void CGUIScrollBar::serializeAttributes(io::IAttributes* out, io::SAttributeRead
out->addInt ("Value", Pos); out->addInt ("Value", Pos);
out->addInt ("Max", Max); out->addInt ("Max", Max);
out->addInt ("SmallStep", SmallStep); out->addInt ("SmallStep", SmallStep);
out->addInt ("LargeStep", LargeStep);
} }
...@@ -437,6 +504,7 @@ void CGUIScrollBar::deserializeAttributes(io::IAttributes* in, io::SAttributeRea ...@@ -437,6 +504,7 @@ void CGUIScrollBar::deserializeAttributes(io::IAttributes* in, io::SAttributeRea
setMax(in->getAttributeAsInt("Max")); setMax(in->getAttributeAsInt("Max"));
setPos(in->getAttributeAsInt("Value")); setPos(in->getAttributeAsInt("Value"));
setSmallStep(in->getAttributeAsInt("SmallStep")); setSmallStep(in->getAttributeAsInt("SmallStep"));
setLargeStep(in->getAttributeAsInt("LargeStep"));
NoClip = in->getAttributeAsBool("NoClip"); NoClip = in->getAttributeAsBool("NoClip");
refreshControls(); refreshControls();
......
...@@ -46,6 +46,12 @@ namespace gui ...@@ -46,6 +46,12 @@ namespace gui
//! sets the small step value //! sets the small step value
virtual void setSmallStep(s32 step); virtual void setSmallStep(s32 step);
//! gets the large step value
virtual s32 getLargeStep() const;
//! sets the large step value
virtual void setLargeStep(s32 step);
//! gets the current position of the scrollbar //! gets the current position of the scrollbar
virtual s32 getPos() const; virtual s32 getPos() const;
...@@ -64,18 +70,24 @@ namespace gui ...@@ -64,18 +70,24 @@ namespace gui
private: private:
void refreshControls(); void refreshControls();
void setPosFromMousePos(s32 x, s32 y); s32 getPosFromMousePos(s32 x, s32 y) const;
IGUIButton* UpButton; IGUIButton* UpButton;
IGUIButton* DownButton; IGUIButton* DownButton;
bool Dragging; bool Dragging;
bool Horizontal; bool Horizontal;
bool DraggedBySlider;
bool TrayClick;
s32 Pos; s32 Pos;
s32 DrawPos; s32 DrawPos;
s32 DrawHeight; s32 DrawHeight;
s32 Max; s32 Max;
s32 SmallStep; s32 SmallStep;
s32 LargeStep;
s32 DesiredPos;
u32 LastChange;
core::rect<s32> SliderRect;
}; };
} // end namespace gui } // end namespace gui
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment