Added navigation through the GUI using tab and the shift and control keys. Added keyboard navigation for most elements. Fixed that annoying bug where you had to click twice to change focus.
Added IGUIElement::isMyChild, isPointInside, SEvent.GUIEvent.Element. Changed setFocus and removeFocus to return bools. changed quaternion::toAngleAxis to use iszero. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@763 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
8ab9af9d2e
commit
e5dbed93dd
39
changes.txt
39
changes.txt
|
@ -37,6 +37,18 @@ Changes in version 1.4 (... 2007)
|
|||
|
||||
GUI:
|
||||
|
||||
- Added IGUISkin::draw2dRectangle, so skins can override the default highlight.
|
||||
|
||||
- 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.
|
||||
|
||||
- IGUIEnvironment::setFocus and removeFocus now return bools.
|
||||
|
||||
- New SEvent.GUIEvent.Element. Points to a second element that is being
|
||||
used in the event. During a EGET_ELEMENT_FOCUS_LOST event it points
|
||||
to the element which would like the focus.
|
||||
|
||||
- Fixed the default font icons so they have a black border and are not
|
||||
invisible in default listboxes. Old font tool textures now keep their color
|
||||
so colorful fonts are possible by editing the font's texture. The colors of
|
||||
|
@ -44,9 +56,36 @@ GUI:
|
|||
from an image. Added builtInFont.bmp for ease of editing.
|
||||
|
||||
- IGUIElement changes:
|
||||
|
||||
Most elements can now be accessed using the keyboard. Use space and return
|
||||
to select or deselect, escape to cancel selection (ie while pressing a
|
||||
button with space or return), and the cursor keys where appropriate.
|
||||
|
||||
Added navigation through the GUI using tab and the shift and control keys.
|
||||
Use these new methods to control tab navigation:
|
||||
setTabStop - set this to true if the focus will vist the element.
|
||||
isTabStop - returns true if the focus will visit the element.
|
||||
setTabOrder - Sets the order of focus within this tab group,
|
||||
Only one element in each group should have the same TabOrder number.
|
||||
Set to -1 to add to the end of the group.
|
||||
setTabGroup - set this to true if the element is a group that contains
|
||||
other elements, and can be navigated with ctrl+tab/ctrl+shift+tab.
|
||||
isTabGroup - returns true if the element is a tab group.
|
||||
getTabGroup - returns the tab group that the element belongs to.
|
||||
getNextElement - searches for the next element which would be focused
|
||||
within the element's children, only useful if you are doing your own
|
||||
custom navigation.
|
||||
|
||||
Added isMychild, to check if an element is descended from this one.
|
||||
|
||||
Added isPointInside, which is called by getElementFromPoint. Override this
|
||||
when making non-rectangular elements.
|
||||
|
||||
OnEvent no longer absorbs events by default.
|
||||
|
||||
Serialize/deserialize now call getter and setter functions, in case people
|
||||
override these and don't use the internal protected variables.
|
||||
|
||||
added getAbsoluteClippingRect, returns the visible area of an element.
|
||||
|
||||
- Added IGUISpinBox, by Michael Zeilfelder (CuteAlien).
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#ifndef __E_MESSAGE_BOX_FLAGS_H_INCLUDED__
|
||||
#define __E_MESSAGE_BOX_FLAGS_H_INCLUDED__
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
|
||||
//! enumeration for message box layout flags
|
||||
enum EMESSAGE_BOX_FLAG
|
||||
{
|
||||
//! Flag for the ok button
|
||||
EMBF_OK = 0x1,
|
||||
|
||||
//! Flag for the cancel button
|
||||
EMBF_CANCEL = 0x2,
|
||||
|
||||
//! Flag for the yes button
|
||||
EMBF_YES = 0x4,
|
||||
|
||||
//! Flag for the no button
|
||||
EMBF_NO = 0x8,
|
||||
|
||||
//! This value is not used. It only forces this enumeration to compile in 32 bit.
|
||||
EMBF_FORCE_32BIT = 0x7fffffff
|
||||
};
|
||||
|
||||
} // namespace gui
|
||||
} // namespace irr
|
||||
|
||||
#endif
|
|
@ -72,6 +72,7 @@ namespace irr
|
|||
enum EGUI_EVENT_TYPE
|
||||
{
|
||||
//! A gui element has lost its focus.
|
||||
//! GUIEvent.Caller is losing the focus to GUIEvent.Element
|
||||
EGET_ELEMENT_FOCUS_LOST = 0,
|
||||
|
||||
//! A gui element has got the focus.
|
||||
|
@ -130,11 +131,12 @@ namespace irr
|
|||
|
||||
//! The value of a spin box has changed
|
||||
EGET_SPINBOX_CHANGED
|
||||
|
||||
};
|
||||
} // end namespace gui
|
||||
|
||||
|
||||
//! Struct for holding event data. An event can be a gui, mouse or keyboard event.
|
||||
//! SEvents hold information about an event.
|
||||
struct SEvent
|
||||
{
|
||||
EEVENT_TYPE EventType;
|
||||
|
@ -146,6 +148,9 @@ struct SEvent
|
|||
//! IGUIElement who called the event
|
||||
gui::IGUIElement* Caller;
|
||||
|
||||
//! If the event has something to do with another element, it will be held here.
|
||||
gui::IGUIElement* Element;
|
||||
|
||||
//! Type of GUI Event
|
||||
gui::EGUI_EVENT_TYPE EventType;
|
||||
|
||||
|
@ -217,7 +222,8 @@ public:
|
|||
|
||||
virtual ~IEventReceiver() {};
|
||||
|
||||
//! called if an event happened. returns true if event was processed
|
||||
//! called if an event happened.
|
||||
//! \return Returns true if the event was processed
|
||||
virtual bool OnEvent(SEvent event) = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace irr
|
|||
{
|
||||
namespace gui
|
||||
{
|
||||
|
||||
class IGUIEnvironment;
|
||||
|
||||
enum EGUI_ALIGNMENT
|
||||
|
@ -52,10 +53,14 @@ public:
|
|||
: Parent(0), RelativeRect(rectangle), AbsoluteRect(rectangle),
|
||||
AbsoluteClippingRect(rectangle), DesiredRect(rectangle),
|
||||
MaxSize(0,0), MinSize(1,1), IsVisible(true), IsEnabled(true),
|
||||
IsSubElement(false), NoClip(false), ID(id),
|
||||
IsSubElement(false), NoClip(false), ID(id), IsTabStop(false), TabOrder(-1), IsTabGroup(false),
|
||||
AlignLeft(EGUIA_UPPERLEFT), AlignRight(EGUIA_UPPERLEFT), AlignTop(EGUIA_UPPERLEFT), AlignBottom(EGUIA_UPPERLEFT),
|
||||
Environment(environment), Type(type)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("IGUIElement");
|
||||
#endif
|
||||
|
||||
// if we were given a parent to attach to
|
||||
if (parent)
|
||||
parent->addChild(this);
|
||||
|
@ -346,7 +351,8 @@ public:
|
|||
{
|
||||
IGUIElement* target = 0;
|
||||
|
||||
// we have to search from back to front.
|
||||
// we have to search from back to front, because later children
|
||||
// might be drawn over the top of earlier ones.
|
||||
|
||||
core::list<IGUIElement*>::Iterator it = Children.getLast();
|
||||
|
||||
|
@ -360,12 +366,19 @@ public:
|
|||
--it;
|
||||
}
|
||||
|
||||
if (AbsoluteClippingRect.isPointInside(point) && IsVisible)
|
||||
if (IsVisible && isPointInside(point))
|
||||
target = this;
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
//! Returns true if a point is within this element.
|
||||
//! Elements with a shape other than a rectangle will override this method
|
||||
virtual bool isPointInside(const core::position2d<s32>& point) const
|
||||
{
|
||||
return AbsoluteClippingRect.isPointInside(point);
|
||||
}
|
||||
|
||||
|
||||
//! Adds a GUI element as new child of this element.
|
||||
virtual void addChild(IGUIElement* child)
|
||||
|
@ -464,6 +477,84 @@ public:
|
|||
IsSubElement = subElement;
|
||||
}
|
||||
|
||||
//! If set to true, the focus will visit this element when using
|
||||
//! the tab key to cycle through elements.
|
||||
//! If this element is a tab group (see isTabGroup/setTabGroup) then
|
||||
//! ctrl+tab will be used instead.
|
||||
void setTabStop(bool enable)
|
||||
{
|
||||
IsTabStop = enable;
|
||||
}
|
||||
|
||||
//! Returns true if this element can be focused by navigating with the tab key
|
||||
bool isTabStop()
|
||||
{
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
return IsTabStop;
|
||||
}
|
||||
|
||||
//! Sets the priority of focus when using the tab key to navigate between a group
|
||||
//! of elements. See setTabGroup, isTabGroup and getTabGroup for information on tab groups.
|
||||
//! Elements with a lower number are focused first
|
||||
void setTabOrder(s32 index)
|
||||
{
|
||||
// negative = autonumber
|
||||
if (index < 0)
|
||||
{
|
||||
TabOrder = 0;
|
||||
IGUIElement *el = getTabGroup();
|
||||
while (IsTabGroup && el && el->Parent)
|
||||
el = el->Parent;
|
||||
|
||||
IGUIElement *first=0, *closest=0;
|
||||
if (el)
|
||||
{
|
||||
// find the highest element number
|
||||
el->getNextElement(-1, true, IsTabGroup, first, closest, true);
|
||||
if (first)
|
||||
{
|
||||
TabOrder = first->getTabOrder() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
TabOrder = index;
|
||||
}
|
||||
|
||||
//! Returns the number in the tab order sequence
|
||||
s32 getTabOrder()
|
||||
{
|
||||
return TabOrder;
|
||||
}
|
||||
|
||||
//! Sets whether this element is a container for a group of elements which
|
||||
//! can be navigated using the tab key. For example, windows are tab groups.
|
||||
//! Groups can be navigated using ctrl+tab, providing isTabStop is true.
|
||||
void setTabGroup(bool isGroup)
|
||||
{
|
||||
IsTabGroup = isGroup;
|
||||
}
|
||||
|
||||
//! Returns true if this element is a tab group.
|
||||
bool isTabGroup()
|
||||
{
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
return IsTabGroup;
|
||||
}
|
||||
|
||||
//! Returns the container element which holds all elements in this element's
|
||||
//! tab group.
|
||||
IGUIElement* getTabGroup()
|
||||
{
|
||||
IGUIElement *ret=this;
|
||||
|
||||
while (ret && !ret->isTabGroup())
|
||||
ret = ret->getParent();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! Returns true if element is enabled.
|
||||
virtual bool isEnabled()
|
||||
{
|
||||
|
@ -578,6 +669,105 @@ public:
|
|||
return e;
|
||||
}
|
||||
|
||||
//! returns true if the given element is a child of this one.
|
||||
//! \param child: The child element to check
|
||||
bool isMyChild(IGUIElement* child)
|
||||
{
|
||||
if (!child)
|
||||
return false;
|
||||
do
|
||||
{
|
||||
if (child->Parent)
|
||||
child = child->Parent;
|
||||
|
||||
} while (child->Parent && child != this)
|
||||
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
return child == this;
|
||||
}
|
||||
|
||||
//! searches elements to find the closest next element to tab to
|
||||
//! \param startOrder: The TabOrder of the current element, -1 if none
|
||||
//! \param reverse: true if searching for a lower number
|
||||
//! \param group: true if searching for a higher one
|
||||
//! \param first: element with the highest/lowest known tab order depending on search direction
|
||||
//! \param closest: the closest match, depending on tab order and direction
|
||||
//! \param includeInvisible: includes invisible elements in the search (default=false)
|
||||
//! \return true if successfully found an element, false to continue searching/fail
|
||||
bool getNextElement(s32 startOrder, bool reverse, bool group,
|
||||
IGUIElement*& first, IGUIElement*& closest, bool includeInvisible=false)
|
||||
{
|
||||
// we'll stop searching if we find this number
|
||||
s32 wanted = startOrder + ( reverse ? -1 : 1 );
|
||||
if (wanted==-2)
|
||||
wanted = 1073741824; // maximum s32
|
||||
|
||||
core::list<IGUIElement*>::Iterator it = Children.begin();
|
||||
|
||||
s32 closestOrder, currentOrder;
|
||||
|
||||
while(it != Children.end())
|
||||
{
|
||||
// ignore invisible elements and their children
|
||||
if ( ( (*it)->isVisible() || includeInvisible ) &&
|
||||
(group == true || (*it)->isTabGroup() == false) )
|
||||
{
|
||||
// only check tab stops and those with the same group status
|
||||
if ((*it)->isTabStop() && ((*it)->isTabGroup() == group))
|
||||
{
|
||||
currentOrder = (*it)->getTabOrder();
|
||||
|
||||
// is this what we're looking for?
|
||||
if (currentOrder == wanted)
|
||||
{
|
||||
closest = *it;
|
||||
return true;
|
||||
}
|
||||
|
||||
// is it closer than the current closest?
|
||||
if (closest)
|
||||
{
|
||||
closestOrder = closest->getTabOrder();
|
||||
if ( ( reverse && currentOrder > closestOrder && currentOrder < startOrder)
|
||||
||(!reverse && currentOrder < closestOrder && currentOrder > startOrder))
|
||||
{
|
||||
closest = *it;
|
||||
}
|
||||
}
|
||||
else
|
||||
if ( (reverse && currentOrder < startOrder) || (!reverse && currentOrder > startOrder) )
|
||||
{
|
||||
closest = *it;
|
||||
}
|
||||
|
||||
// is it before the current first?
|
||||
if (first)
|
||||
{
|
||||
closestOrder = first->getTabOrder();
|
||||
|
||||
if ( (reverse && closestOrder < currentOrder) || (!reverse && closestOrder > currentOrder) )
|
||||
{
|
||||
first = *it;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
first = *it;
|
||||
}
|
||||
}
|
||||
// search within children
|
||||
if ((*it)->getNextElement(startOrder, reverse, group, first, closest))
|
||||
{
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
++it;
|
||||
}
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
return false;
|
||||
}
|
||||
|
||||
//! Returns the type of the gui element.
|
||||
/** This is needed for the .NET wrapper but will be used
|
||||
later for serializing and deserializing.
|
||||
|
@ -611,8 +801,11 @@ public:
|
|||
out->addEnum("RightAlign", AlignRight, GUIAlignmentNames);
|
||||
out->addEnum("TopAlign", AlignTop, GUIAlignmentNames);
|
||||
out->addEnum("BottomAlign", AlignBottom, GUIAlignmentNames);
|
||||
out->addBool("Visible", IsVisible );
|
||||
out->addBool("Enabled", IsEnabled );
|
||||
out->addBool("Visible", IsVisible);
|
||||
out->addBool("Enabled", IsEnabled);
|
||||
out->addBool("TabStop", IsTabStop);
|
||||
out->addBool("TabGroup", IsTabGroup);
|
||||
out->addInt("TabOrder", TabOrder);
|
||||
}
|
||||
|
||||
//! Reads attributes of the scene node.
|
||||
|
@ -624,6 +817,9 @@ public:
|
|||
setText(in->getAttributeAsStringW("Caption").c_str());
|
||||
setVisible(in->getAttributeAsBool("Visible"));
|
||||
setEnabled(in->getAttributeAsBool("Enabled"));
|
||||
IsTabStop = in->getAttributeAsBool("TabStop");
|
||||
IsTabGroup = in->getAttributeAsBool("TabGroup");
|
||||
TabOrder = in->getAttributeAsBool("TabOrder");
|
||||
|
||||
core::position2di p = in->getAttributeAsPosition2d("MaxSize");
|
||||
setMaxSize(core::dimension2di(p.X,p.Y));
|
||||
|
@ -691,6 +887,15 @@ protected:
|
|||
//! id
|
||||
s32 ID;
|
||||
|
||||
//! tab stop like in windows
|
||||
bool IsTabStop;
|
||||
|
||||
//! tab order
|
||||
s32 TabOrder;
|
||||
|
||||
//! tab groups are containers like windows, use ctrl+tab to navigate
|
||||
bool IsTabGroup;
|
||||
|
||||
//! tells the element how to act when its parent is resized
|
||||
EGUI_ALIGNMENT AlignLeft, AlignRight, AlignTop, AlignBottom;
|
||||
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
#define __I_GUI_ENVIRONMENT_H_INCLUDED__
|
||||
|
||||
#include "IUnknown.h"
|
||||
#include "IGUIWindow.h"
|
||||
#include "IGUISkin.h"
|
||||
#include "rect.h"
|
||||
#include "EMessageBoxFlags.h"
|
||||
#include "IEventReceiver.h"
|
||||
#include "IXMLReader.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
@ -50,6 +52,8 @@ class IGUITab;
|
|||
class IGUIContextMenu;
|
||||
class IGUIComboBox;
|
||||
class IGUIToolBar;
|
||||
class IGUIButton;
|
||||
class IGUIWindow;
|
||||
class IGUIElementFactory;
|
||||
|
||||
//! GUI Environment. Used as factory and manager of all other GUI elements.
|
||||
|
@ -64,13 +68,19 @@ public:
|
|||
virtual void drawAll() = 0;
|
||||
|
||||
//! Sets the focus to an element.
|
||||
virtual void setFocus(IGUIElement* element) = 0;
|
||||
/** Causes a EGET_ELEMENT_FOCUS_LOST event followed by a EGET_ELEMENT_FOCUSED event.
|
||||
If someone absorbed either of the events, then the focus will not be changed.
|
||||
\return Returns true on success, false on failure */
|
||||
virtual bool setFocus(IGUIElement* element) = 0;
|
||||
|
||||
//! Returns the element with the focus
|
||||
virtual IGUIElement* getFocus() = 0;
|
||||
|
||||
//! Removes the focus from an element.
|
||||
virtual void removeFocus(IGUIElement* element) = 0;
|
||||
/** Causes a EGET_ELEMENT_FOCUS_LOST event. If the event is absorbed then the focus
|
||||
will not be changed.
|
||||
\return Returns true on success, false on failure */
|
||||
virtual bool removeFocus(IGUIElement* element) = 0;
|
||||
|
||||
//! Returns if the element has focus
|
||||
virtual bool hasFocus(IGUIElement* element) = 0;
|
||||
|
|
|
@ -470,6 +470,18 @@ namespace gui
|
|||
const core::position2di position, u32 starttime=0, u32 currenttime=0,
|
||||
bool loop=false, const core::rect<s32>* clip=0) = 0;
|
||||
|
||||
//! draws a 2d rectangle.
|
||||
/** \param element: Pointer to the element which wishes to draw this icon.
|
||||
This parameter is usually not used by IGUISkin, but can be used for example
|
||||
by more complex implementations to find out how to draw the part exactly.
|
||||
\param color: Color of the rectangle to draw. The alpha component specifies how
|
||||
transparent the rectangle will be.
|
||||
\param pos: Position of the rectangle.
|
||||
\param clip: Pointer to rectangle against which the rectangle will be clipped.
|
||||
If the pointer is null, no clipping will be performed. */
|
||||
virtual void draw2DRectangle(IGUIElement* element, video::SColor &color,
|
||||
const core::rect<s32>& pos, const core::rect<s32>* clip = 0) = 0;
|
||||
|
||||
//! get the type of this skin
|
||||
virtual EGUI_SKIN_TYPE getType() const { return EGST_UNKNOWN; };
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#define __I_GUI_WINDOW_H_INCLUDED__
|
||||
|
||||
#include "IGUIElement.h"
|
||||
#include "EMessageBoxFlags.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
@ -13,25 +14,6 @@ namespace gui
|
|||
{
|
||||
class IGUIButton;
|
||||
|
||||
//! enumeration for message box layout flags
|
||||
enum EMESSAGE_BOX_FLAG
|
||||
{
|
||||
//! Flag for the ok button
|
||||
EMBF_OK = 0x1,
|
||||
|
||||
//! Flag for the cancel button
|
||||
EMBF_CANCEL = 0x2,
|
||||
|
||||
//! Flag for the yes button
|
||||
EMBF_YES = 0x4,
|
||||
|
||||
//! Flag for the no button
|
||||
EMBF_NO = 0x8,
|
||||
|
||||
//! This value is not used. It only forces this enumeration to compile in 32 bit.
|
||||
EMBF_FORCE_32BIT = 0x7fffffff
|
||||
};
|
||||
|
||||
//! Default moveable window GUI element with border, caption and close icons.
|
||||
class IGUIWindow : public IGUIElement
|
||||
{
|
||||
|
|
|
@ -473,7 +473,7 @@ inline void quaternion::toAngleAxis(f32 &angle, core::vector3df &axis) const
|
|||
{
|
||||
f32 scale = sqrt (X*X + Y*Y + Z*Z);
|
||||
|
||||
if (core::equals(scale,0.0f) || W > 1.0f || W < -1.0f)
|
||||
if (core::iszero(scale) || W > 1.0f || W < -1.0f)
|
||||
{
|
||||
angle = 0.0f;
|
||||
axis.X = 0.0f;
|
||||
|
|
|
@ -30,6 +30,10 @@ CGUIButton::CGUIButton(IGUIEnvironment* environment, IGUIElement* parent,
|
|||
// reset sprites
|
||||
for (u32 i=0; i<EGBS_COUNT; ++i)
|
||||
ButtonSprites[i].Index = -1;
|
||||
|
||||
// this element can be tabbed to
|
||||
setTabStop(true);
|
||||
setTabOrder(-1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,12 +105,17 @@ bool CGUIButton::OnEvent(SEvent event)
|
|||
|
||||
return true;
|
||||
}
|
||||
if (Pressed && !IsPushButton && event.KeyInput.PressedDown && event.KeyInput.Key == KEY_ESCAPE)
|
||||
{
|
||||
setPressed(false);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (!event.KeyInput.PressedDown && Pressed &&
|
||||
(event.KeyInput.Key == KEY_RETURN ||
|
||||
event.KeyInput.Key == KEY_SPACE))
|
||||
{
|
||||
Environment->removeFocus(this);
|
||||
//Environment->removeFocus(this);
|
||||
|
||||
if (!IsPushButton)
|
||||
setPressed(false);
|
||||
|
@ -116,6 +125,7 @@ bool CGUIButton::OnEvent(SEvent event)
|
|||
SEvent newEvent;
|
||||
newEvent.EventType = EET_GUI_EVENT;
|
||||
newEvent.GUIEvent.Caller = this;
|
||||
newEvent.GUIEvent.Element = 0;
|
||||
newEvent.GUIEvent.EventType = EGET_BUTTON_CLICKED;
|
||||
Parent->OnEvent(newEvent);
|
||||
}
|
||||
|
@ -125,7 +135,7 @@ bool CGUIButton::OnEvent(SEvent event)
|
|||
case EET_GUI_EVENT:
|
||||
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
|
||||
{
|
||||
if (event.GUIEvent.Caller == (IGUIElement*) this && !IsPushButton)
|
||||
if (event.GUIEvent.Caller == this && !IsPushButton)
|
||||
setPressed(false);
|
||||
}
|
||||
break;
|
||||
|
@ -149,7 +159,7 @@ bool CGUIButton::OnEvent(SEvent event)
|
|||
if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
|
||||
{
|
||||
bool wasPressed = Pressed;
|
||||
Environment->removeFocus(this);
|
||||
//Environment->removeFocus(this);
|
||||
|
||||
if ( !AbsoluteClippingRect.isPointInside( core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y ) ) )
|
||||
{
|
||||
|
@ -171,6 +181,7 @@ bool CGUIButton::OnEvent(SEvent event)
|
|||
SEvent newEvent;
|
||||
newEvent.EventType = EET_GUI_EVENT;
|
||||
newEvent.GUIEvent.Caller = this;
|
||||
newEvent.GUIEvent.Element = 0;
|
||||
newEvent.GUIEvent.EventType = EGET_BUTTON_CLICKED;
|
||||
Parent->OnEvent(newEvent);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@ CGUICheckBox::CGUICheckBox(bool checked, IGUIEnvironment* environment, IGUIEleme
|
|||
#ifdef _DEBUG
|
||||
setDebugName("CGUICheckBox");
|
||||
#endif
|
||||
|
||||
// this element can be tabbed into
|
||||
setTabStop(true);
|
||||
setTabOrder(-1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,10 +41,43 @@ bool CGUICheckBox::OnEvent(SEvent event)
|
|||
{
|
||||
switch(event.EventType)
|
||||
{
|
||||
case EET_KEY_INPUT_EVENT:
|
||||
if (event.KeyInput.PressedDown &&
|
||||
(event.KeyInput.Key == KEY_RETURN ||
|
||||
event.KeyInput.Key == KEY_SPACE))
|
||||
{
|
||||
Pressed = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (Pressed && event.KeyInput.PressedDown && event.KeyInput.Key == KEY_ESCAPE)
|
||||
{
|
||||
Pressed = false;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (!event.KeyInput.PressedDown && Pressed &&
|
||||
(event.KeyInput.Key == KEY_RETURN ||
|
||||
event.KeyInput.Key == KEY_SPACE))
|
||||
{
|
||||
Pressed = false;
|
||||
if (Parent)
|
||||
{
|
||||
SEvent newEvent;
|
||||
newEvent.EventType = EET_GUI_EVENT;
|
||||
newEvent.GUIEvent.Caller = this;
|
||||
newEvent.GUIEvent.Element = 0;
|
||||
Checked = !Checked;
|
||||
newEvent.GUIEvent.EventType = EGET_CHECKBOX_CHANGED;
|
||||
Parent->OnEvent(newEvent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case EET_GUI_EVENT:
|
||||
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
|
||||
{
|
||||
if (event.GUIEvent.Caller == (IGUIElement*)this)
|
||||
if (event.GUIEvent.Caller == this)
|
||||
Pressed = false;
|
||||
}
|
||||
break;
|
||||
|
@ -70,6 +107,7 @@ bool CGUICheckBox::OnEvent(SEvent event)
|
|||
SEvent newEvent;
|
||||
newEvent.EventType = EET_GUI_EVENT;
|
||||
newEvent.GUIEvent.Caller = this;
|
||||
newEvent.GUIEvent.Element = 0;
|
||||
Checked = !Checked;
|
||||
newEvent.GUIEvent.EventType = EGET_CHECKBOX_CHANGED;
|
||||
Parent->OnEvent(newEvent);
|
||||
|
|
|
@ -73,6 +73,7 @@ CGUIColorSelectDialog::CGUIColorSelectDialog( const wchar_t* title, IGUIEnvironm
|
|||
CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), skin->getColor(EGDC_WINDOW_SYMBOL));
|
||||
}
|
||||
CloseButton->setSubElement(true);
|
||||
CloseButton->setTabStop(false);
|
||||
CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
|
||||
CloseButton->grab();
|
||||
|
||||
|
@ -463,6 +464,7 @@ void CGUIColorSelectDialog::sendSelectedEvent()
|
|||
SEvent event;
|
||||
event.EventType = EET_GUI_EVENT;
|
||||
event.GUIEvent.Caller = this;
|
||||
event.GUIEvent.Element = 0;
|
||||
event.GUIEvent.EventType = EGET_FILE_SELECTED;
|
||||
Parent->OnEvent(event);
|
||||
}
|
||||
|
@ -473,6 +475,7 @@ void CGUIColorSelectDialog::sendCancelEvent()
|
|||
SEvent event;
|
||||
event.EventType = EET_GUI_EVENT;
|
||||
event.GUIEvent.Caller = this;
|
||||
event.GUIEvent.Element = 0;
|
||||
event.GUIEvent.EventType = EGET_FILE_CHOOSE_DIALOG_CANCELLED;
|
||||
Parent->OnEvent(event);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace gui
|
|||
CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
|
||||
s32 id, core::rect<s32> rectangle)
|
||||
: IGUIComboBox(environment, parent, id, rectangle),
|
||||
ListButton(0), ListBox(0), Selected(-1)
|
||||
ListButton(0), ListBox(0), Selected(-1), HasFocus(false), LastFocus(0)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CGUICheckBox");
|
||||
|
@ -48,8 +48,14 @@ CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
|
|||
ListButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL));
|
||||
}
|
||||
ListButton->setSubElement(true);
|
||||
ListButton->setTabStop(false);
|
||||
|
||||
setNotClipped(true);
|
||||
|
||||
// this element can be tabbed to
|
||||
setTabStop(true);
|
||||
setTabOrder(-1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -148,10 +154,75 @@ bool CGUIComboBox::OnEvent(SEvent event)
|
|||
{
|
||||
switch(event.EventType)
|
||||
{
|
||||
|
||||
case EET_KEY_INPUT_EVENT:
|
||||
if (ListBox && event.KeyInput.PressedDown && event.KeyInput.Key == KEY_ESCAPE)
|
||||
{
|
||||
// hide list box
|
||||
openCloseMenu();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE)
|
||||
{
|
||||
if (!event.KeyInput.PressedDown)
|
||||
openCloseMenu();
|
||||
|
||||
ListButton->setPressed(ListBox == 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (event.KeyInput.PressedDown)
|
||||
{
|
||||
s32 oldSelected = Selected;
|
||||
bool absorb = true;
|
||||
switch (event.KeyInput.Key)
|
||||
{
|
||||
case KEY_DOWN:
|
||||
Selected += 1;
|
||||
break;
|
||||
case KEY_UP:
|
||||
Selected -= 1;
|
||||
break;
|
||||
case KEY_HOME:
|
||||
case KEY_PRIOR:
|
||||
Selected = 0;
|
||||
break;
|
||||
case KEY_END:
|
||||
case KEY_NEXT:
|
||||
Selected = (s32)Items.size()-1;
|
||||
break;
|
||||
default:
|
||||
absorb = false;
|
||||
}
|
||||
|
||||
if (Selected <0)
|
||||
Selected = 0;
|
||||
else
|
||||
if (Selected >= (s32)Items.size())
|
||||
Selected = (s32)Items.size() -1;
|
||||
|
||||
if (Selected != oldSelected)
|
||||
sendSelectionChangedEvent();
|
||||
|
||||
if (absorb)
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case EET_GUI_EVENT:
|
||||
|
||||
switch(event.GUIEvent.EventType)
|
||||
{
|
||||
case EGET_ELEMENT_FOCUS_LOST:
|
||||
if (Environment->hasFocus(ListBox) &&
|
||||
event.GUIEvent.Element != this &&
|
||||
event.GUIEvent.Element != ListButton)
|
||||
{
|
||||
openCloseMenu();
|
||||
}
|
||||
break;
|
||||
case EGET_BUTTON_CLICKED:
|
||||
if (event.GUIEvent.Caller == ListButton)
|
||||
{
|
||||
|
@ -179,22 +250,12 @@ bool CGUIComboBox::OnEvent(SEvent event)
|
|||
{
|
||||
case EMIE_LMOUSE_PRESSED_DOWN:
|
||||
{
|
||||
if (!ListBox)
|
||||
Environment->removeFocus(this);
|
||||
|
||||
core::position2d<s32> p(event.MouseInput.X, event.MouseInput.Y);
|
||||
|
||||
// send to list box
|
||||
if (ListBox && ListBox->getAbsolutePosition().isPointInside(p) &&
|
||||
ListBox->OnEvent(event))
|
||||
if (ListBox && ListBox->isPointInside(p) && ListBox->OnEvent(event))
|
||||
return true;
|
||||
|
||||
// check if it is outside
|
||||
if (!AbsoluteClippingRect.isPointInside(p))
|
||||
{
|
||||
Environment->removeFocus(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
case EMIE_LMOUSE_LEFT_UP:
|
||||
|
@ -235,6 +296,7 @@ void CGUIComboBox::sendSelectionChangedEvent()
|
|||
|
||||
event.EventType = EET_GUI_EVENT;
|
||||
event.GUIEvent.Caller = this;
|
||||
event.GUIEvent.Element = 0;
|
||||
event.GUIEvent.EventType = EGET_COMBO_BOX_CHANGED;
|
||||
Parent->OnEvent(event);
|
||||
}
|
||||
|
@ -249,6 +311,12 @@ void CGUIComboBox::draw()
|
|||
return;
|
||||
|
||||
IGUISkin* skin = Environment->getSkin();
|
||||
IGUIElement *currentFocus = Environment->getFocus();
|
||||
if (currentFocus != LastFocus)
|
||||
{
|
||||
HasFocus = currentFocus == this || isMyChild(currentFocus);
|
||||
LastFocus = currentFocus;
|
||||
}
|
||||
|
||||
core::rect<s32> frameRect(AbsoluteRect);
|
||||
|
||||
|
@ -263,11 +331,16 @@ void CGUIComboBox::draw()
|
|||
{
|
||||
frameRect = AbsoluteRect;
|
||||
frameRect.UpperLeftCorner.X += 2;
|
||||
frameRect.UpperLeftCorner.Y += 2;
|
||||
frameRect.LowerRightCorner.X -= ListButton->getAbsolutePosition().getWidth() + 2;
|
||||
frameRect.LowerRightCorner.Y -= 2;
|
||||
if (HasFocus)
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), frameRect, &AbsoluteClippingRect);
|
||||
|
||||
IGUIFont* font = skin->getFont();
|
||||
if (font)
|
||||
font->draw(Items[Selected].c_str(), frameRect,
|
||||
skin->getColor(EGDC_BUTTON_TEXT),
|
||||
skin->getColor(HasFocus ? EGDC_HIGH_LIGHT_TEXT : EGDC_BUTTON_TEXT),
|
||||
false, true, &AbsoluteClippingRect);
|
||||
}
|
||||
|
||||
|
@ -281,6 +354,7 @@ void CGUIComboBox::openCloseMenu()
|
|||
if (ListBox)
|
||||
{
|
||||
// close list box
|
||||
Environment->setFocus(this);
|
||||
ListBox->remove();
|
||||
ListBox = 0;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,9 @@ namespace gui
|
|||
IGUIButton* ListButton;
|
||||
IGUIListBox* ListBox;
|
||||
core::array< core::stringw > Items;
|
||||
s32 Selected;
|
||||
s32 Selected;
|
||||
bool HasFocus;
|
||||
IGUIElement *LastFocus;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace gui
|
|||
CGUIContextMenu::CGUIContextMenu(IGUIEnvironment* environment,
|
||||
IGUIElement* parent, s32 id,
|
||||
core::rect<s32> rectangle, bool getFocus)
|
||||
: IGUIContextMenu(environment, parent, id, rectangle), HighLighted(-1), ChangeTime(0)
|
||||
: IGUIContextMenu(environment, parent, id, rectangle), HighLighted(-1), ChangeTime(0), EventParent(0)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CGUIContextMenu");
|
||||
|
@ -210,11 +210,13 @@ bool CGUIContextMenu::OnEvent(SEvent event)
|
|||
case EET_GUI_EVENT:
|
||||
switch(event.GUIEvent.EventType)
|
||||
{
|
||||
case gui::EGET_ELEMENT_FOCUS_LOST:
|
||||
if (event.GUIEvent.Caller == (IGUIElement*)this)
|
||||
case EGET_ELEMENT_FOCUS_LOST:
|
||||
if (event.GUIEvent.Caller == this)
|
||||
{
|
||||
// set event parent of submenus
|
||||
setEventParent(Parent);
|
||||
remove();
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -286,7 +288,7 @@ s32 CGUIContextMenu::sendClick(core::position2d<s32> p)
|
|||
}
|
||||
|
||||
// check click on myself
|
||||
if (AbsoluteClippingRect.isPointInside(p) &&
|
||||
if (isPointInside(p) &&
|
||||
HighLighted >= 0 && HighLighted <(s32)Items.size())
|
||||
{
|
||||
if (!Items[HighLighted].Enabled ||
|
||||
|
@ -297,8 +299,13 @@ s32 CGUIContextMenu::sendClick(core::position2d<s32> p)
|
|||
SEvent event;
|
||||
event.EventType = EET_GUI_EVENT;
|
||||
event.GUIEvent.Caller = this;
|
||||
event.GUIEvent.Element = 0;
|
||||
event.GUIEvent.EventType = EGET_MENU_ITEM_SELECTED;
|
||||
Parent->OnEvent(event);
|
||||
if (Parent)
|
||||
Parent->OnEvent(event);
|
||||
else
|
||||
if (EventParent)
|
||||
EventParent->OnEvent(event);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -385,8 +392,6 @@ void CGUIContextMenu::draw()
|
|||
IGUIFont* font = skin->getFont(EGDF_MENU);
|
||||
IGUISpriteBank* sprites = skin->getSpriteBank();
|
||||
|
||||
video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||
|
||||
core::rect<s32> rect = AbsoluteRect;
|
||||
core::rect<s32>* clip = 0;
|
||||
|
||||
|
@ -408,11 +413,11 @@ void CGUIContextMenu::draw()
|
|||
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1;
|
||||
rect.UpperLeftCorner.X += 5;
|
||||
rect.LowerRightCorner.X -= 5;
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_3D_SHADOW), rect, clip);
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), rect, clip);
|
||||
|
||||
rect.LowerRightCorner.Y += 1;
|
||||
rect.UpperLeftCorner.Y += 1;
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT), rect, clip);
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), rect, clip);
|
||||
|
||||
y += 10;
|
||||
}
|
||||
|
@ -429,7 +434,7 @@ void CGUIContextMenu::draw()
|
|||
r.UpperLeftCorner.Y = rect.UpperLeftCorner.Y;
|
||||
r.LowerRightCorner.X -= 5;
|
||||
r.UpperLeftCorner.X += 5;
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_HIGH_LIGHT), r, clip);
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), r, clip);
|
||||
}
|
||||
|
||||
// draw text
|
||||
|
@ -663,6 +668,18 @@ void CGUIContextMenu::deserializeAttributes(io::IAttributes* in, io::SAttributeR
|
|||
|
||||
}
|
||||
|
||||
// because sometimes the element has no parent at click time
|
||||
void CGUIContextMenu::setEventParent(IGUIElement *parent)
|
||||
{
|
||||
EventParent = parent;
|
||||
|
||||
for (u32 i=0; i<(s32)Items.size(); ++i)
|
||||
if (Items[i].SubMenu)
|
||||
{
|
||||
Items[i].SubMenu->setEventParent(parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end namespace
|
||||
} // end namespace
|
||||
|
|
|
@ -87,6 +87,12 @@ namespace gui
|
|||
//! Adds a sub menu from an element that already exists.
|
||||
virtual void setSubMenu(s32 index, CGUIContextMenu* menu);
|
||||
|
||||
//! Writes attributes of the element.
|
||||
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options);
|
||||
|
||||
//! Reads attributes of the element
|
||||
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options);
|
||||
|
||||
protected:
|
||||
|
||||
struct SItem
|
||||
|
@ -118,16 +124,13 @@ namespace gui
|
|||
//! Gets drawing rect of Item
|
||||
virtual core::rect<s32> getRect(const SItem& i, const core::rect<s32>& absolute);
|
||||
|
||||
//! Writes attributes of the element.
|
||||
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options);
|
||||
|
||||
//! Reads attributes of the element
|
||||
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options);
|
||||
void setEventParent(IGUIElement *parent);
|
||||
|
||||
s32 HighLighted;
|
||||
core::array<SItem> Items;
|
||||
core::position2d<s32> Pos;
|
||||
u32 ChangeTime;
|
||||
IGUIElement* EventParent;
|
||||
};
|
||||
|
||||
} // end namespace gui
|
||||
|
|
|
@ -48,6 +48,10 @@ CGUIEditBox::CGUIEditBox(const wchar_t* text, bool border, IGUIEnvironment* envi
|
|||
if (Operator)
|
||||
Operator->grab();
|
||||
|
||||
// this element can be tabbed to
|
||||
setTabStop(true);
|
||||
setTabOrder(-1);
|
||||
|
||||
breakText();
|
||||
}
|
||||
|
||||
|
@ -146,7 +150,7 @@ bool CGUIEditBox::OnEvent(SEvent event)
|
|||
case EET_GUI_EVENT:
|
||||
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
|
||||
{
|
||||
if (event.GUIEvent.Caller == (IGUIElement*)this)
|
||||
if (event.GUIEvent.Caller == this)
|
||||
{
|
||||
MouseMarking = false;
|
||||
MarkBegin = 0;
|
||||
|
@ -377,6 +381,7 @@ bool CGUIEditBox::processKey(const SEvent& event)
|
|||
SEvent e;
|
||||
e.EventType = EET_GUI_EVENT;
|
||||
e.GUIEvent.Caller = this;
|
||||
e.GUIEvent.Element = 0;
|
||||
e.GUIEvent.EventType = EGET_EDITBOX_ENTER;
|
||||
Parent->OnEvent(e);
|
||||
}
|
||||
|
@ -424,6 +429,7 @@ bool CGUIEditBox::processKey(const SEvent& event)
|
|||
BlinkStartTime = os::Timer::getTime();
|
||||
break;
|
||||
case KEY_UP:
|
||||
if (MultiLine || (WordWrap && BrokenText.size() > 1) )
|
||||
{
|
||||
s32 lineNo = getLineFromPos(CursorPos);
|
||||
s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin > MarkEnd ? MarkBegin : MarkEnd);
|
||||
|
@ -448,8 +454,13 @@ bool CGUIEditBox::processKey(const SEvent& event)
|
|||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if (MultiLine || (WordWrap && BrokenText.size() > 1) )
|
||||
{
|
||||
s32 lineNo = getLineFromPos(CursorPos);
|
||||
s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin < MarkEnd ? MarkBegin : MarkEnd);
|
||||
|
@ -474,6 +485,10 @@ bool CGUIEditBox::processKey(const SEvent& event)
|
|||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_BACK:
|
||||
|
@ -717,7 +732,7 @@ void CGUIEditBox::draw()
|
|||
CurrentTextRect.LowerRightCorner.X = CurrentTextRect.UpperLeftCorner.X + mend - mbegin;
|
||||
|
||||
// draw mark
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_HIGH_LIGHT), CurrentTextRect, &localClipRect);
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), CurrentTextRect, &localClipRect);
|
||||
|
||||
// draw marked text
|
||||
s = txtLine->subString(lineStartPos, lineEndPos - lineStartPos);
|
||||
|
@ -870,8 +885,6 @@ bool CGUIEditBox::processMouse(const SEvent& event)
|
|||
if (!AbsoluteClippingRect.isPointInside(
|
||||
core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y)))
|
||||
{
|
||||
// remove focus
|
||||
Environment->removeFocus(this);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -80,6 +80,10 @@ CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* drive
|
|||
ToolTip.LastTime = 0;
|
||||
ToolTip.LaunchTime = 1000;
|
||||
ToolTip.Element = 0;
|
||||
|
||||
// environment is root tab group
|
||||
Environment = this;
|
||||
setTabGroup(true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -194,30 +198,79 @@ void CGUIEnvironment::drawAll()
|
|||
|
||||
|
||||
//! sets the focus to an element
|
||||
void CGUIEnvironment::setFocus(IGUIElement* element)
|
||||
bool CGUIEnvironment::setFocus(IGUIElement* element)
|
||||
{
|
||||
if (Focus == element)
|
||||
return;
|
||||
{
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
return false;
|
||||
}
|
||||
|
||||
// GUI Environment should not get the focus
|
||||
if (element == this)
|
||||
element = 0;
|
||||
|
||||
removeFocus(Focus);
|
||||
|
||||
Focus = element;
|
||||
// stop element from being deleted
|
||||
if (element)
|
||||
element->grab();
|
||||
|
||||
// focus may change or be removed in this call
|
||||
IGUIElement *currentFocus = 0;
|
||||
if (Focus)
|
||||
{
|
||||
Focus->grab();
|
||||
currentFocus = Focus;
|
||||
currentFocus->grab();
|
||||
SEvent e;
|
||||
e.EventType = EET_GUI_EVENT;
|
||||
e.GUIEvent.Caller = Focus;
|
||||
e.GUIEvent.Element = element;
|
||||
e.GUIEvent.EventType = EGET_ELEMENT_FOCUS_LOST;
|
||||
if (Focus->OnEvent(e))
|
||||
{
|
||||
if (element)
|
||||
element->drop();
|
||||
currentFocus->drop();
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
return false;
|
||||
}
|
||||
currentFocus->drop();
|
||||
currentFocus = 0;
|
||||
}
|
||||
|
||||
if (element)
|
||||
{
|
||||
currentFocus = Focus;
|
||||
if (currentFocus)
|
||||
currentFocus->grab();
|
||||
|
||||
// send focused event
|
||||
SEvent e;
|
||||
e.EventType = EET_GUI_EVENT;
|
||||
e.GUIEvent.Caller = Focus;
|
||||
e.GUIEvent.Caller = element;
|
||||
e.GUIEvent.Element = Focus;
|
||||
e.GUIEvent.EventType = EGET_ELEMENT_FOCUSED;
|
||||
Focus->OnEvent(e);
|
||||
if (element->OnEvent(e))
|
||||
{
|
||||
if (element)
|
||||
element->drop();
|
||||
if (currentFocus)
|
||||
currentFocus->drop();
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentFocus)
|
||||
currentFocus->drop();
|
||||
|
||||
if (Focus)
|
||||
Focus->drop();
|
||||
|
||||
// element is the new focus so it doesn't have to be dropped
|
||||
Focus = element;
|
||||
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
return true;
|
||||
}
|
||||
|
||||
//! returns the element with the focus
|
||||
|
@ -228,19 +281,29 @@ IGUIElement* CGUIEnvironment::getFocus()
|
|||
|
||||
|
||||
//! removes the focus from an element
|
||||
void CGUIEnvironment::removeFocus(IGUIElement* element)
|
||||
bool CGUIEnvironment::removeFocus(IGUIElement* element)
|
||||
{
|
||||
if (Focus && Focus==element)
|
||||
{
|
||||
SEvent e;
|
||||
e.EventType = EET_GUI_EVENT;
|
||||
e.GUIEvent.Caller = Focus;
|
||||
e.GUIEvent.Element = 0;
|
||||
e.GUIEvent.EventType = EGET_ELEMENT_FOCUS_LOST;
|
||||
Focus->OnEvent(e);
|
||||
if (Focus)
|
||||
Focus->drop();
|
||||
if (Focus->OnEvent(e))
|
||||
{
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (Focus)
|
||||
{
|
||||
Focus->drop();
|
||||
Focus = 0;
|
||||
}
|
||||
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -429,23 +492,40 @@ bool CGUIEnvironment::postEventFromUser(SEvent event)
|
|||
break;
|
||||
case EET_MOUSE_INPUT_EVENT:
|
||||
|
||||
// sending input to focus, stopping of focus processed input
|
||||
|
||||
updateHoveredElement(core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y));
|
||||
|
||||
if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
|
||||
if ( (Hovered && Hovered != Focus) || !Focus )
|
||||
{
|
||||
setFocus(Hovered);
|
||||
}
|
||||
|
||||
// sending input to focus
|
||||
if (Focus && Focus->OnEvent(event))
|
||||
return true;
|
||||
|
||||
if (!Focus) // focus could have died in last call
|
||||
{
|
||||
// trying to send input to hovered element
|
||||
updateHoveredElement(core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y));
|
||||
// focus could have died in last call
|
||||
if (!Focus && Hovered)
|
||||
return Hovered->OnEvent(event);
|
||||
|
||||
if (Hovered && Hovered != this)
|
||||
return Hovered->OnEvent(event);
|
||||
}
|
||||
break;
|
||||
case EET_KEY_INPUT_EVENT:
|
||||
if (Focus && Focus != this)
|
||||
return Focus->OnEvent(event);
|
||||
{
|
||||
// send focus changing event
|
||||
if (event.EventType == EET_KEY_INPUT_EVENT &&
|
||||
event.KeyInput.PressedDown &&
|
||||
event.KeyInput.Key == KEY_TAB)
|
||||
{
|
||||
IGUIElement *next = getNextElement(event.KeyInput.Shift, event.KeyInput.Control);
|
||||
if (next && next != Focus)
|
||||
{
|
||||
if (setFocus(next))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (Focus)
|
||||
return Focus->OnEvent(event);
|
||||
}
|
||||
break;
|
||||
} // end switch
|
||||
|
||||
|
@ -1351,6 +1431,56 @@ IGUIElement* CGUIEnvironment::getRootGUIElement()
|
|||
return this;
|
||||
}
|
||||
|
||||
//! Returns the next element in the tab group starting at the focused element
|
||||
IGUIElement* CGUIEnvironment::getNextElement(bool reverse, bool group)
|
||||
{
|
||||
// start the search at the root of the current tab group
|
||||
IGUIElement *startPos = Focus ? Focus->getTabGroup() : 0;
|
||||
s32 startOrder = -1;
|
||||
|
||||
// if we're searching for a group
|
||||
if (group && startPos)
|
||||
{
|
||||
startOrder = startPos->getTabOrder();
|
||||
}
|
||||
else
|
||||
if (!group && Focus && !Focus->isTabGroup())
|
||||
{
|
||||
startOrder = Focus->getTabOrder();
|
||||
if (startOrder == -1)
|
||||
{
|
||||
// this element is not part of the tab cycle,
|
||||
// but its parent might be...
|
||||
IGUIElement *el = Focus;
|
||||
while (el && el->getParent() && startOrder == -1)
|
||||
{
|
||||
el = el->getParent();
|
||||
startOrder = el->getTabOrder();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (group || !startPos)
|
||||
startPos = this; // start at the root
|
||||
|
||||
// find the element
|
||||
IGUIElement *closest = 0;
|
||||
IGUIElement *first = 0;
|
||||
startPos->getNextElement(startOrder, reverse, group, first, closest);
|
||||
|
||||
IGUIElement *ret = 0;
|
||||
|
||||
if (closest)
|
||||
ret = closest; // we found an element
|
||||
else if (first)
|
||||
ret = first; // go to the end or the start
|
||||
else if (group)
|
||||
ret = this; // no group found? root group
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! creates an GUI Environment
|
||||
|
|
|
@ -151,10 +151,10 @@ public:
|
|||
IGUIElement* parent=0, s32 id=-1);
|
||||
|
||||
//! sets the focus to an element
|
||||
virtual void setFocus(IGUIElement* element);
|
||||
virtual bool setFocus(IGUIElement* element);
|
||||
|
||||
//! removes the focus from an element
|
||||
virtual void removeFocus(IGUIElement* element);
|
||||
virtual bool removeFocus(IGUIElement* element);
|
||||
|
||||
//! Returns if the element has focus
|
||||
virtual bool hasFocus(IGUIElement* element);
|
||||
|
@ -229,6 +229,8 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
IGUIElement* getNextElement(bool reverse=false, bool group=false);
|
||||
|
||||
struct SFont
|
||||
{
|
||||
core::stringc Filename;
|
||||
|
|
|
@ -52,6 +52,7 @@ CGUIFileOpenDialog::CGUIFileOpenDialog(const wchar_t* title, IGUIEnvironment* en
|
|||
CloseButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
|
||||
L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close");
|
||||
CloseButton->setSubElement(true);
|
||||
CloseButton->setTabStop(false);
|
||||
if (sprites)
|
||||
{
|
||||
CloseButton->setSpriteBank(sprites);
|
||||
|
@ -90,6 +91,8 @@ CGUIFileOpenDialog::CGUIFileOpenDialog(const wchar_t* title, IGUIEnvironment* en
|
|||
if (FileSystem)
|
||||
FileSystem->grab();
|
||||
|
||||
setTabGroup(true);
|
||||
|
||||
fillListBox();
|
||||
}
|
||||
|
||||
|
@ -202,7 +205,6 @@ bool CGUIFileOpenDialog::OnEvent(SEvent event)
|
|||
return true;
|
||||
case EMIE_LMOUSE_LEFT_UP:
|
||||
Dragging = false;
|
||||
Environment->removeFocus(this);
|
||||
return true;
|
||||
case EMIE_MOUSE_MOVED:
|
||||
if (Dragging)
|
||||
|
@ -293,6 +295,7 @@ void CGUIFileOpenDialog::sendSelectedEvent()
|
|||
SEvent event;
|
||||
event.EventType = EET_GUI_EVENT;
|
||||
event.GUIEvent.Caller = this;
|
||||
event.GUIEvent.Element = 0;
|
||||
event.GUIEvent.EventType = EGET_FILE_SELECTED;
|
||||
Parent->OnEvent(event);
|
||||
}
|
||||
|
@ -303,6 +306,7 @@ void CGUIFileOpenDialog::sendCancelEvent()
|
|||
SEvent event;
|
||||
event.EventType = EET_GUI_EVENT;
|
||||
event.GUIEvent.Caller = this;
|
||||
event.GUIEvent.Element = 0;
|
||||
event.GUIEvent.EventType = EGET_FILE_CHOOSE_DIALOG_CANCELLED;
|
||||
Parent->OnEvent(event);
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ void CGUIImage::draw()
|
|||
}
|
||||
else
|
||||
{
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_3D_DARK_SHADOW), AbsoluteRect, &AbsoluteClippingRect);
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_3D_DARK_SHADOW), AbsoluteRect, &AbsoluteClippingRect);
|
||||
}
|
||||
|
||||
IGUIElement::draw();
|
||||
|
|
|
@ -36,6 +36,7 @@ CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent,
|
|||
core::rect<s32>(RelativeRect.getWidth() - s, 0, RelativeRect.getWidth(), RelativeRect.getHeight()),
|
||||
!clip);
|
||||
ScrollBar->setSubElement(true);
|
||||
ScrollBar->setTabStop(false);
|
||||
ScrollBar->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||||
ScrollBar->drop();
|
||||
|
||||
|
@ -43,6 +44,10 @@ CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent,
|
|||
ScrollBar->grab();
|
||||
|
||||
setNotClipped(!clip);
|
||||
|
||||
// this element can be tabbed to
|
||||
setTabStop(true);
|
||||
setTabOrder(-1);
|
||||
|
||||
updateAbsolutePosition();
|
||||
}
|
||||
|
@ -182,6 +187,8 @@ void CGUIListBox::setSelected(s32 id)
|
|||
Selected = id;
|
||||
|
||||
selectTime = os::Timer::getTime();
|
||||
|
||||
recalculateScrollPos();
|
||||
}
|
||||
|
||||
|
||||
|
@ -191,19 +198,84 @@ bool CGUIListBox::OnEvent(SEvent event)
|
|||
{
|
||||
switch(event.EventType)
|
||||
{
|
||||
case EET_KEY_INPUT_EVENT:
|
||||
if (event.KeyInput.PressedDown &&
|
||||
(event.KeyInput.Key == KEY_DOWN ||
|
||||
event.KeyInput.Key == KEY_UP ||
|
||||
event.KeyInput.Key == KEY_HOME ||
|
||||
event.KeyInput.Key == KEY_END ||
|
||||
event.KeyInput.Key == KEY_NEXT ||
|
||||
event.KeyInput.Key == KEY_PRIOR ) )
|
||||
{
|
||||
s32 oldSelected = Selected;
|
||||
switch (event.KeyInput.Key)
|
||||
{
|
||||
case KEY_DOWN:
|
||||
Selected += 1;
|
||||
break;
|
||||
case KEY_UP:
|
||||
Selected -= 1;
|
||||
break;
|
||||
case KEY_HOME:
|
||||
Selected = 0;
|
||||
break;
|
||||
case KEY_END:
|
||||
Selected = (s32)Items.size()-1;
|
||||
break;
|
||||
case KEY_NEXT:
|
||||
Selected += AbsoluteRect.getHeight() / ItemHeight;
|
||||
break;
|
||||
case KEY_PRIOR:
|
||||
Selected -= AbsoluteRect.getHeight() / ItemHeight;
|
||||
}
|
||||
if (Selected >= (s32)Items.size())
|
||||
Selected = Items.size() - 1;
|
||||
else
|
||||
if (Selected<0)
|
||||
Selected = 0;
|
||||
|
||||
recalculateScrollPos();
|
||||
|
||||
// post the news
|
||||
|
||||
if (oldSelected != Selected && Parent && !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);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (!event.KeyInput.PressedDown && ( event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE ) )
|
||||
{
|
||||
if (Parent)
|
||||
{
|
||||
SEvent e;
|
||||
e.EventType = EET_GUI_EVENT;
|
||||
e.GUIEvent.Caller = this;
|
||||
e.GUIEvent.Element = 0;
|
||||
e.GUIEvent.EventType = EGET_LISTBOX_SELECTED_AGAIN;
|
||||
Parent->OnEvent(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case EET_GUI_EVENT:
|
||||
switch(event.GUIEvent.EventType)
|
||||
{
|
||||
case gui::EGET_SCROLL_BAR_CHANGED:
|
||||
if (event.GUIEvent.Caller == ScrollBar)
|
||||
{
|
||||
// s32 pos = ((gui::IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case gui::EGET_ELEMENT_FOCUS_LOST:
|
||||
{
|
||||
if (event.GUIEvent.Caller == (IGUIElement*)this)
|
||||
if (event.GUIEvent.Caller == this)
|
||||
Selecting = false;
|
||||
}
|
||||
}
|
||||
|
@ -226,35 +298,36 @@ bool CGUIListBox::OnEvent(SEvent event)
|
|||
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->getAbsolutePosition().isPointInside(p) &&
|
||||
ScrollBar->isPointInside(p) &&
|
||||
ScrollBar->OnEvent(event))
|
||||
return true;
|
||||
|
||||
if (!AbsoluteRect.isPointInside(p))
|
||||
if (!isPointInside(p))
|
||||
{
|
||||
Selecting = false;
|
||||
Environment->removeFocus(this);
|
||||
//Environment->removeFocus(this);
|
||||
break;
|
||||
}
|
||||
|
||||
Selecting = false;
|
||||
Environment->removeFocus(this);
|
||||
Selecting = false;
|
||||
selectNew(event.MouseInput.Y);
|
||||
return true;
|
||||
|
||||
case EMIE_MOUSE_MOVED:
|
||||
if (Selecting || MoveOverSelect)
|
||||
{
|
||||
if (getAbsolutePosition().isPointInside(p))
|
||||
if (isPointInside(p))
|
||||
{
|
||||
selectNew(event.MouseInput.Y, true);
|
||||
return true;
|
||||
|
@ -291,6 +364,7 @@ void CGUIListBox::selectNew(s32 ypos, bool onlyHover)
|
|||
SEvent event;
|
||||
event.EventType = EET_GUI_EVENT;
|
||||
event.GUIEvent.Caller = this;
|
||||
event.GUIEvent.Element = 0;
|
||||
event.GUIEvent.EventType = (Selected != oldSelected) ? EGET_LISTBOX_CHANGED : EGET_LISTBOX_SELECTED_AGAIN;
|
||||
Parent->OnEvent(event);
|
||||
}
|
||||
|
@ -313,7 +387,6 @@ void CGUIListBox::draw()
|
|||
recalculateItemHeight(); // if the font changed
|
||||
|
||||
IGUISkin* skin = Environment->getSkin();
|
||||
irr::video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||
|
||||
core::rect<s32>* clipRect = 0;
|
||||
|
||||
|
@ -349,7 +422,7 @@ void CGUIListBox::draw()
|
|||
frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y)
|
||||
{
|
||||
if (i == Selected)
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_HIGH_LIGHT), frameRect, &clientClip);
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), frameRect, &clientClip);
|
||||
|
||||
core::rect<s32> textRect = frameRect;
|
||||
textRect.UpperLeftCorner.X += 3;
|
||||
|
@ -419,6 +492,20 @@ void CGUIListBox::setSpriteBank(IGUISpriteBank* bank)
|
|||
if (IconBank)
|
||||
IconBank->grab();
|
||||
}
|
||||
void CGUIListBox::recalculateScrollPos()
|
||||
{
|
||||
s32 selPos = Selected * ItemHeight - ScrollBar->getPos();
|
||||
|
||||
if (selPos < 0)
|
||||
{
|
||||
ScrollBar->setPos(ScrollBar->getPos() + selPos);
|
||||
}
|
||||
else
|
||||
if (selPos > AbsoluteRect.getHeight() - ItemHeight)
|
||||
{
|
||||
ScrollBar->setPos(ScrollBar->getPos() + selPos - AbsoluteRect.getHeight() + ItemHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! Writes attributes of the element.
|
||||
|
|
|
@ -92,6 +92,7 @@ namespace gui
|
|||
|
||||
void recalculateItemHeight();
|
||||
void selectNew(s32 ypos, bool onlyHover=false);
|
||||
void recalculateScrollPos();
|
||||
|
||||
core::array< ListItem > Items;
|
||||
s32 Selected;
|
||||
|
|
|
@ -99,9 +99,13 @@ bool CGUIMenu::OnEvent(SEvent event)
|
|||
switch(event.GUIEvent.EventType)
|
||||
{
|
||||
case gui::EGET_ELEMENT_FOCUS_LOST:
|
||||
if (event.GUIEvent.Caller == (IGUIElement*)this)
|
||||
if (event.GUIEvent.Caller == this)
|
||||
closeAllSubMenus();
|
||||
return true;
|
||||
break;
|
||||
case gui::EGET_ELEMENT_FOCUSED:
|
||||
if (event.GUIEvent.Caller == this && Parent)
|
||||
Parent->bringToFront(this);
|
||||
|
||||
}
|
||||
break;
|
||||
case EET_MOUSE_INPUT_EVENT:
|
||||
|
|
|
@ -111,20 +111,20 @@ void CGUIMeshViewer::draw()
|
|||
|
||||
core::rect<s32> frameRect(AbsoluteRect);
|
||||
frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + 1;
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_3D_SHADOW), frameRect, &AbsoluteClippingRect);
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), frameRect, &AbsoluteClippingRect);
|
||||
|
||||
frameRect.LowerRightCorner.Y = AbsoluteRect.LowerRightCorner.Y;
|
||||
frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + 1;
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_3D_SHADOW), frameRect, &AbsoluteClippingRect);
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), frameRect, &AbsoluteClippingRect);
|
||||
|
||||
frameRect = AbsoluteRect;
|
||||
frameRect.UpperLeftCorner.X = frameRect.LowerRightCorner.X - 1;
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect);
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect);
|
||||
|
||||
frameRect = AbsoluteRect;
|
||||
frameRect.UpperLeftCorner.Y = AbsoluteRect.LowerRightCorner.Y - 1;
|
||||
frameRect.LowerRightCorner.Y = AbsoluteRect.LowerRightCorner.Y;
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect);
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect);
|
||||
|
||||
// draw the mesh
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ CGUIMessageBox::CGUIMessageBox(IGUIEnvironment* environment, const wchar_t* capt
|
|||
IGUIElement* parent, s32 id, core::rect<s32> rectangle)
|
||||
: CGUIWindow(environment, parent, id, rectangle),
|
||||
OkButton(0), CancelButton(0), YesButton(0), NoButton(0), StaticText(0),
|
||||
Flags(flags), MessageText(text)
|
||||
Flags(flags), MessageText(text), Pressed(false)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CGUIMessageBox");
|
||||
|
@ -220,7 +220,7 @@ void CGUIMessageBox::refreshControls()
|
|||
NoButton = 0;
|
||||
}
|
||||
|
||||
if (Environment->getFocus() == this && focusMe)
|
||||
if (Environment->hasFocus(this) && focusMe)
|
||||
Environment->setFocus(focusMe);
|
||||
}
|
||||
|
||||
|
@ -251,9 +251,97 @@ bool CGUIMessageBox::OnEvent(SEvent event)
|
|||
SEvent outevent;
|
||||
outevent.EventType = EET_GUI_EVENT;
|
||||
outevent.GUIEvent.Caller = this;
|
||||
outevent.GUIEvent.Element = 0;
|
||||
|
||||
switch(event.EventType)
|
||||
{
|
||||
case EET_KEY_INPUT_EVENT:
|
||||
|
||||
if (event.KeyInput.PressedDown)
|
||||
{
|
||||
switch (event.KeyInput.Key)
|
||||
{
|
||||
case KEY_RETURN:
|
||||
if (OkButton)
|
||||
{
|
||||
OkButton->setPressed(true);
|
||||
Pressed = true;
|
||||
}
|
||||
break;
|
||||
case KEY_KEY_Y:
|
||||
if (YesButton)
|
||||
{
|
||||
YesButton->setPressed(true);
|
||||
Pressed = true;
|
||||
}
|
||||
break;
|
||||
case KEY_KEY_N:
|
||||
if (NoButton)
|
||||
{
|
||||
NoButton->setPressed(true);
|
||||
Pressed = true;
|
||||
}
|
||||
break;
|
||||
case KEY_ESCAPE:
|
||||
if (Pressed)
|
||||
{
|
||||
// cancel press
|
||||
if (OkButton) OkButton->setPressed(false);
|
||||
if (YesButton) OkButton->setPressed(false);
|
||||
if (NoButton) OkButton->setPressed(false);
|
||||
Pressed = false;
|
||||
}
|
||||
else
|
||||
if (CancelButton)
|
||||
{
|
||||
CancelButton->setPressed(true);
|
||||
Pressed = true;
|
||||
}
|
||||
else
|
||||
if (CloseButton && CloseButton->isVisible())
|
||||
{
|
||||
CloseButton->setPressed(true);
|
||||
Pressed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (Pressed)
|
||||
{
|
||||
|
||||
if (OkButton && event.KeyInput.Key == KEY_RETURN)
|
||||
{
|
||||
outevent.GUIEvent.EventType = EGET_MESSAGEBOX_OK;
|
||||
Parent->OnEvent(outevent);
|
||||
remove();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if ((CancelButton || CloseButton) && event.KeyInput.Key == KEY_ESCAPE)
|
||||
{
|
||||
outevent.GUIEvent.EventType = EGET_MESSAGEBOX_CANCEL;
|
||||
Parent->OnEvent(outevent);
|
||||
remove();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (YesButton && event.KeyInput.Key == KEY_KEY_Y)
|
||||
{
|
||||
outevent.GUIEvent.EventType = EGET_MESSAGEBOX_YES;
|
||||
Parent->OnEvent(outevent);
|
||||
remove();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (NoButton && event.KeyInput.Key == KEY_KEY_N)
|
||||
{
|
||||
outevent.GUIEvent.EventType = EGET_MESSAGEBOX_NO;
|
||||
Parent->OnEvent(outevent);
|
||||
remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EET_GUI_EVENT:
|
||||
if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
|
||||
{
|
||||
|
|
|
@ -46,6 +46,7 @@ namespace gui
|
|||
|
||||
s32 Flags;
|
||||
core::stringw MessageText;
|
||||
bool Pressed;
|
||||
};
|
||||
|
||||
} // end namespace gui
|
||||
|
|
|
@ -22,6 +22,9 @@ CGUIModalScreen::CGUIModalScreen(IGUIEnvironment* environment, IGUIElement* pare
|
|||
setDebugName("CGUIModalScreen");
|
||||
#endif
|
||||
setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||||
|
||||
// this element is a tab group
|
||||
setTabGroup(true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,6 +39,24 @@ bool CGUIModalScreen::OnEvent(SEvent event)
|
|||
{
|
||||
switch(event.EventType)
|
||||
{
|
||||
case EET_GUI_EVENT:
|
||||
switch(event.GUIEvent.EventType)
|
||||
{
|
||||
case EGET_ELEMENT_FOCUSED:
|
||||
if (event.GUIEvent.Caller != this && !isMyChild(event.GUIEvent.Caller))
|
||||
Environment->setFocus(this);
|
||||
return false;
|
||||
case EGET_ELEMENT_FOCUS_LOST:
|
||||
if (!(isMyChild(event.GUIEvent.Element) || event.GUIEvent.Element == this))
|
||||
{
|
||||
MouseDownTime = os::Timer::getTime();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return IGUIElement::OnEvent(event);
|
||||
|
||||
break;
|
||||
}
|
||||
case EET_MOUSE_INPUT_EVENT:
|
||||
switch(event.MouseInput.Event)
|
||||
{
|
||||
|
@ -44,22 +65,25 @@ bool CGUIModalScreen::OnEvent(SEvent event)
|
|||
}
|
||||
}
|
||||
|
||||
if (Parent)
|
||||
Parent->OnEvent(event);
|
||||
IGUIElement::OnEvent(event);
|
||||
|
||||
return true;
|
||||
return true; // absorb everything
|
||||
}
|
||||
|
||||
|
||||
//! draws the element and its children
|
||||
void CGUIModalScreen::draw()
|
||||
{
|
||||
IGUISkin *skin = Environment->getSkin();
|
||||
|
||||
if (!skin)
|
||||
return;
|
||||
|
||||
u32 now = os::Timer::getTime();
|
||||
if (now - MouseDownTime < 300 && (now / 70)%2)
|
||||
{
|
||||
core::list<IGUIElement*>::Iterator it = Children.begin();
|
||||
core::rect<s32> r;
|
||||
video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||
video::SColor c = Environment->getSkin()->getColor(gui::EGDC_3D_HIGH_LIGHT);
|
||||
|
||||
for (; it != Children.end(); ++it)
|
||||
|
@ -70,7 +94,7 @@ void CGUIModalScreen::draw()
|
|||
r.UpperLeftCorner.X -= 1;
|
||||
r.UpperLeftCorner.Y -= 1;
|
||||
|
||||
driver->draw2DRectangle(c, r, &AbsoluteClippingRect);
|
||||
skin->draw2DRectangle(this, c, r, &AbsoluteClippingRect);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,6 +112,13 @@ void CGUIModalScreen::removeChild(IGUIElement* child)
|
|||
remove();
|
||||
}
|
||||
|
||||
//! adds a child
|
||||
void CGUIModalScreen::addChild(IGUIElement* child)
|
||||
{
|
||||
IGUIElement::addChild(child);
|
||||
Environment->setFocus(child);
|
||||
}
|
||||
|
||||
|
||||
void CGUIModalScreen::updateAbsolutePosition()
|
||||
{
|
||||
|
|
|
@ -28,6 +28,10 @@ namespace gui
|
|||
//! Removes a child.
|
||||
virtual void removeChild(IGUIElement* child);
|
||||
|
||||
//! Adds a child
|
||||
virtual void addChild(IGUIElement* child);
|
||||
|
||||
|
||||
//! draws the element and its children
|
||||
virtual void draw();
|
||||
|
||||
|
|
|
@ -32,6 +32,10 @@ CGUIScrollBar::CGUIScrollBar(bool horizontal, IGUIEnvironment* environment,
|
|||
|
||||
setNotClipped(noclip);
|
||||
|
||||
// this element can be tabbed to
|
||||
setTabStop(true);
|
||||
setTabOrder(-1);
|
||||
|
||||
setPos(0);
|
||||
}
|
||||
|
||||
|
@ -52,6 +56,46 @@ bool CGUIScrollBar::OnEvent(SEvent event)
|
|||
{
|
||||
switch(event.EventType)
|
||||
{
|
||||
case EET_KEY_INPUT_EVENT:
|
||||
if (event.KeyInput.PressedDown)
|
||||
{
|
||||
s32 oldPos = Pos;
|
||||
bool absorb = true;
|
||||
switch (event.KeyInput.Key)
|
||||
{
|
||||
case KEY_LEFT:
|
||||
case KEY_UP:
|
||||
setPos(Pos-SmallStep);
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
case KEY_DOWN:
|
||||
setPos(Pos+SmallStep);
|
||||
break;
|
||||
case KEY_HOME:
|
||||
case KEY_PRIOR:
|
||||
setPos(0);
|
||||
break;
|
||||
case KEY_END:
|
||||
case KEY_NEXT:
|
||||
setPos(Max);
|
||||
break;
|
||||
default:
|
||||
absorb = false;
|
||||
}
|
||||
|
||||
if (Pos != oldPos)
|
||||
{
|
||||
SEvent newEvent;
|
||||
newEvent.EventType = EET_GUI_EVENT;
|
||||
newEvent.GUIEvent.Caller = this;
|
||||
newEvent.GUIEvent.Element = 0;
|
||||
newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED;
|
||||
Parent->OnEvent(newEvent);
|
||||
}
|
||||
if (absorb)
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case EET_GUI_EVENT:
|
||||
if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
|
||||
{
|
||||
|
@ -64,6 +108,7 @@ bool CGUIScrollBar::OnEvent(SEvent event)
|
|||
SEvent newEvent;
|
||||
newEvent.EventType = EET_GUI_EVENT;
|
||||
newEvent.GUIEvent.Caller = this;
|
||||
newEvent.GUIEvent.Element = 0;
|
||||
newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED;
|
||||
Parent->OnEvent(newEvent);
|
||||
|
||||
|
@ -72,7 +117,7 @@ bool CGUIScrollBar::OnEvent(SEvent event)
|
|||
else
|
||||
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
|
||||
{
|
||||
if (event.GUIEvent.Caller == (IGUIElement*)this)
|
||||
if (event.GUIEvent.Caller == this)
|
||||
Dragging = false;
|
||||
}
|
||||
break;
|
||||
|
@ -86,6 +131,7 @@ bool CGUIScrollBar::OnEvent(SEvent event)
|
|||
SEvent newEvent;
|
||||
newEvent.EventType = EET_GUI_EVENT;
|
||||
newEvent.GUIEvent.Caller = this;
|
||||
newEvent.GUIEvent.Element = 0;
|
||||
newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED;
|
||||
Parent->OnEvent(newEvent);
|
||||
return true;
|
||||
|
@ -121,6 +167,7 @@ bool CGUIScrollBar::OnEvent(SEvent event)
|
|||
SEvent newEvent;
|
||||
newEvent.EventType = EET_GUI_EVENT;
|
||||
newEvent.GUIEvent.Caller = this;
|
||||
newEvent.GUIEvent.Element = 0;
|
||||
newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED;
|
||||
Parent->OnEvent(newEvent);
|
||||
}
|
||||
|
@ -130,7 +177,7 @@ bool CGUIScrollBar::OnEvent(SEvent event)
|
|||
break;
|
||||
}
|
||||
|
||||
return Parent ? Parent->OnEvent(event) : false;
|
||||
return IGUIElement::OnEvent(event);
|
||||
}
|
||||
|
||||
//! draws the element and its children
|
||||
|
@ -143,12 +190,10 @@ void CGUIScrollBar::draw()
|
|||
if (!skin)
|
||||
return;
|
||||
|
||||
irr::video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||
|
||||
core::rect<s32> rect = AbsoluteRect;
|
||||
|
||||
// draws the background
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_SCROLLBAR), rect, &AbsoluteClippingRect);
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_SCROLLBAR), rect, &AbsoluteClippingRect);
|
||||
|
||||
if (Max!=0)
|
||||
{
|
||||
|
@ -305,6 +350,7 @@ void CGUIScrollBar::refreshControls()
|
|||
{
|
||||
UpButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,0, h, h), NoClip);
|
||||
UpButton->setSubElement(true);
|
||||
UpButton->setTabStop(false);
|
||||
}
|
||||
if (sprites)
|
||||
{
|
||||
|
@ -318,6 +364,7 @@ void CGUIScrollBar::refreshControls()
|
|||
{
|
||||
DownButton = new CGUIButton(Environment, this, -1, core::rect<s32>(RelativeRect.getWidth()-h, 0, RelativeRect.getWidth(), h), NoClip);
|
||||
DownButton->setSubElement(true);
|
||||
DownButton->setTabStop(false);
|
||||
}
|
||||
if (sprites)
|
||||
{
|
||||
|
@ -335,6 +382,7 @@ void CGUIScrollBar::refreshControls()
|
|||
{
|
||||
UpButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,0, w, w), NoClip);
|
||||
UpButton->setSubElement(true);
|
||||
UpButton->setTabStop(false);
|
||||
}
|
||||
if (sprites)
|
||||
{
|
||||
|
@ -348,6 +396,7 @@ void CGUIScrollBar::refreshControls()
|
|||
{
|
||||
DownButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,RelativeRect.getHeight()-w, w, RelativeRect.getHeight()), NoClip);
|
||||
DownButton->setSubElement(true);
|
||||
DownButton->setTabStop(false);
|
||||
}
|
||||
if (sprites)
|
||||
{
|
||||
|
|
|
@ -770,6 +770,13 @@ EGUI_SKIN_TYPE CGUISkin::getType() const
|
|||
return Type;
|
||||
}
|
||||
|
||||
//! draws a 2d rectangle.
|
||||
void CGUISkin::draw2DRectangle(IGUIElement* element, video::SColor &color, const core::rect<s32>& pos,
|
||||
const core::rect<s32>* clip)
|
||||
{
|
||||
Driver->draw2DRectangle(color, pos, clip);
|
||||
}
|
||||
|
||||
//! Writes attributes of the object.
|
||||
//! Implement this to expose the attributes of your scene node animator for
|
||||
//! scripting languages, editors, debuggers or xml serialization purposes.
|
||||
|
|
|
@ -189,6 +189,20 @@ namespace gui
|
|||
const core::position2di position, u32 starttime=0, u32 currenttime=0,
|
||||
bool loop=false, const core::rect<s32>* clip=0);
|
||||
|
||||
|
||||
//! draws a 2d rectangle.
|
||||
/** \param element: Pointer to the element which wishes to draw this icon.
|
||||
This parameter is usually not used by IGUISkin, but can be used for example
|
||||
by more complex implementations to find out how to draw the part exactly.
|
||||
\param color: Color of the rectangle to draw. The alpha component specifies how
|
||||
transparent the rectangle will be.
|
||||
\param pos: Position of the rectangle.
|
||||
\param clip: Pointer to rectangle against which the rectangle will be clipped.
|
||||
If the pointer is null, no clipping will be performed. */
|
||||
virtual void draw2DRectangle(IGUIElement* element, video::SColor &color,
|
||||
const core::rect<s32>& pos, const core::rect<s32>* clip = 0);
|
||||
|
||||
|
||||
//! get the type of this skin
|
||||
virtual EGUI_SKIN_TYPE getType() const;
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ CGUISpinBox::CGUISpinBox(const wchar_t* text, IGUIEnvironment* environment,
|
|||
rectangle.getWidth(), rectangle.getHeight()), this);
|
||||
ButtonSpinDown->grab();
|
||||
ButtonSpinDown->setSubElement(true);
|
||||
ButtonSpinDown->setTabStop(false);
|
||||
ButtonSpinDown->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_CENTER, EGUIA_LOWERRIGHT);
|
||||
|
||||
ButtonSpinUp = Environment->addButton(
|
||||
|
@ -45,6 +46,7 @@ CGUISpinBox::CGUISpinBox(const wchar_t* text, IGUIEnvironment* environment,
|
|||
rectangle.getWidth(), rectangle.getHeight()/2), this);
|
||||
ButtonSpinUp->grab();
|
||||
ButtonSpinUp->setSubElement(true);
|
||||
ButtonSpinUp->setTabStop(false);
|
||||
ButtonSpinUp->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_CENTER);
|
||||
if (sb)
|
||||
{
|
||||
|
@ -67,8 +69,6 @@ CGUISpinBox::CGUISpinBox(const wchar_t* text, IGUIEnvironment* environment,
|
|||
EditBox->grab();
|
||||
EditBox->setSubElement(true);
|
||||
EditBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||||
|
||||
// verifyValueRange();
|
||||
}
|
||||
|
||||
//! destructor
|
||||
|
@ -188,13 +188,15 @@ bool CGUISpinBox::OnEvent(SEvent event)
|
|||
SEvent e;
|
||||
e.EventType = EET_GUI_EVENT;
|
||||
e.GUIEvent.Caller = this;
|
||||
//fprintf(stderr, "EGET_SPINBOX_CHANGED caller:%p id: %d\n", e.GUIEvent.Caller, e.GUIEvent.Caller->getID() );
|
||||
e.GUIEvent.Element = 0;
|
||||
|
||||
e.GUIEvent.EventType = EGET_SPINBOX_CHANGED;
|
||||
if ( Parent )
|
||||
Parent->OnEvent(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return IGUIElement::OnEvent(event);
|
||||
}
|
||||
|
||||
void CGUISpinBox::verifyValueRange()
|
||||
|
|
|
@ -61,10 +61,10 @@ void CGUITab::draw()
|
|||
if (!IsVisible)
|
||||
return;
|
||||
|
||||
video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||
IGUISkin *skin = Environment->getSkin();
|
||||
|
||||
if (DrawBackground)
|
||||
driver->draw2DRectangle(BackColor, AbsoluteRect, &AbsoluteClippingRect);
|
||||
if (skin && DrawBackground)
|
||||
skin->draw2DRectangle(this, BackColor, AbsoluteRect, &AbsoluteClippingRect);
|
||||
|
||||
IGUIElement::draw();
|
||||
}
|
||||
|
@ -135,6 +135,9 @@ CGUITabControl::CGUITabControl(IGUIEnvironment* environment,
|
|||
: IGUITabControl(environment, parent, id, rectangle), ActiveTab(-1),
|
||||
Border(border), FillBackground(fillbackground)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CGUITabControl");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -240,14 +243,6 @@ bool CGUITabControl::OnEvent(SEvent event)
|
|||
|
||||
switch(event.EventType)
|
||||
{
|
||||
case EET_GUI_EVENT:
|
||||
switch(event.GUIEvent.EventType)
|
||||
{
|
||||
case gui::EGET_ELEMENT_FOCUS_LOST:
|
||||
if (event.GUIEvent.Caller == (IGUIElement*)this)
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case EET_MOUSE_INPUT_EVENT:
|
||||
switch(event.MouseInput.Event)
|
||||
{
|
||||
|
@ -313,12 +308,11 @@ void CGUITabControl::draw()
|
|||
return;
|
||||
|
||||
IGUIFont* font = skin->getFont();
|
||||
video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||
|
||||
core::rect<s32> frameRect(AbsoluteRect);
|
||||
|
||||
if (Tabs.empty())
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT),
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT),
|
||||
frameRect, &AbsoluteClippingRect);
|
||||
|
||||
if (!font)
|
||||
|
@ -382,11 +376,11 @@ void CGUITabControl::draw()
|
|||
tr.LowerRightCorner.X = left - 1;
|
||||
tr.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - 1;
|
||||
tr.LowerRightCorner.Y = frameRect.LowerRightCorner.Y;
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect);
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect);
|
||||
|
||||
tr.UpperLeftCorner.X = right;
|
||||
tr.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X;
|
||||
driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect);
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect);
|
||||
}
|
||||
|
||||
skin->draw3DTabBody(this, Border, FillBackground, AbsoluteRect, &AbsoluteClippingRect);
|
||||
|
@ -429,6 +423,7 @@ bool CGUITabControl::setActiveTab(s32 idx)
|
|||
SEvent event;
|
||||
event.EventType = EET_GUI_EVENT;
|
||||
event.GUIEvent.Caller = this;
|
||||
event.GUIEvent.Element = 0;
|
||||
event.GUIEvent.EventType = EGET_TAB_CHANGED;
|
||||
Parent->OnEvent(event);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ CGUIWindow::CGUIWindow(IGUIEnvironment* environment, IGUIElement* parent, s32 id
|
|||
CloseButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
|
||||
L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close" );
|
||||
CloseButton->setSubElement(true);
|
||||
CloseButton->setTabStop(false);
|
||||
CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
|
||||
if (sprites)
|
||||
{
|
||||
|
@ -55,6 +56,7 @@ CGUIWindow::CGUIWindow(IGUIEnvironment* environment, IGUIElement* parent, s32 id
|
|||
L"", skin ? skin->getDefaultText(EGDT_WINDOW_RESTORE) : L"Restore" );
|
||||
RestoreButton->setVisible(false);
|
||||
RestoreButton->setSubElement(true);
|
||||
RestoreButton->setTabStop(false);
|
||||
RestoreButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
|
||||
if (sprites)
|
||||
{
|
||||
|
@ -68,6 +70,7 @@ CGUIWindow::CGUIWindow(IGUIEnvironment* environment, IGUIElement* parent, s32 id
|
|||
L"", skin ? skin->getDefaultText(EGDT_WINDOW_MINIMIZE) : L"Minimize" );
|
||||
MinButton->setVisible(false);
|
||||
MinButton->setSubElement(true);
|
||||
MinButton->setTabStop(false);
|
||||
MinButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
|
||||
if (sprites)
|
||||
{
|
||||
|
@ -79,6 +82,11 @@ CGUIWindow::CGUIWindow(IGUIEnvironment* environment, IGUIElement* parent, s32 id
|
|||
MinButton->grab();
|
||||
RestoreButton->grab();
|
||||
CloseButton->grab();
|
||||
|
||||
// this element is a tab group
|
||||
setTabGroup(true);
|
||||
setTabStop(true);
|
||||
setTabOrder(-1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,10 +114,14 @@ bool CGUIWindow::OnEvent(SEvent event)
|
|||
case EET_GUI_EVENT:
|
||||
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
|
||||
{
|
||||
if (event.GUIEvent.Caller == (IGUIElement*)this)
|
||||
Dragging = false;
|
||||
}
|
||||
else
|
||||
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED)
|
||||
{
|
||||
if (event.GUIEvent.Caller == this && Parent)
|
||||
{
|
||||
Dragging = false;
|
||||
return true;
|
||||
Parent->bringToFront(this);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -128,9 +140,9 @@ bool CGUIWindow::OnEvent(SEvent event)
|
|||
case EMIE_LMOUSE_PRESSED_DOWN:
|
||||
DragStart.X = event.MouseInput.X;
|
||||
DragStart.Y = event.MouseInput.Y;
|
||||
Dragging = true;
|
||||
if (!Environment->hasFocus(this))
|
||||
{
|
||||
Dragging = true;
|
||||
Environment->setFocus(this);
|
||||
if (Parent)
|
||||
Parent->bringToFront(this);
|
||||
|
@ -138,7 +150,6 @@ bool CGUIWindow::OnEvent(SEvent event)
|
|||
return true;
|
||||
case EMIE_LMOUSE_LEFT_UP:
|
||||
Dragging = false;
|
||||
Environment->removeFocus(this);
|
||||
return true;
|
||||
case EMIE_MOUSE_MOVED:
|
||||
if (Dragging)
|
||||
|
@ -162,7 +173,7 @@ bool CGUIWindow::OnEvent(SEvent event)
|
|||
}
|
||||
}
|
||||
|
||||
return Parent ? Parent->OnEvent(event) : false;
|
||||
return IGUIElement::OnEvent(event);
|
||||
}
|
||||
|
||||
//! Updates the absolute position.
|
||||
|
|
|
@ -732,6 +732,10 @@
|
|||
RelativePath=".\..\..\include\EGUIElementTypes.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\EMessageBoxFlags.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\..\include\ICursorControl.h"
|
||||
>
|
||||
|
|
|
@ -64,12 +64,15 @@ namespace gui
|
|||
switch (e.GUIEvent.EventType)
|
||||
{
|
||||
case EGET_ELEMENT_FOCUSED:
|
||||
if (Parent)
|
||||
if (Parent && isMyChild(e.GUIEvent.Caller))
|
||||
Parent->bringToFront(this);
|
||||
break;
|
||||
case EGET_ELEMENT_HOVERED:
|
||||
case EGET_ELEMENT_LEFT:
|
||||
return true;
|
||||
return IGUIElement::OnEvent(e);
|
||||
case EGET_ELEMENT_FOCUS_LOST:
|
||||
updateAttrib();
|
||||
return IGUIElement::OnEvent(e);
|
||||
default:
|
||||
return updateAttrib();
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@ CGUIAttributeEditor::CGUIAttributeEditor(IGUIEnvironment* environment, s32 id, I
|
|||
// create attributes
|
||||
Attribs = environment->getFileSystem()->createEmptyAttributes(Environment->getVideoDriver());
|
||||
|
||||
calculateClientArea();
|
||||
resizeInnerPane();
|
||||
|
||||
// refresh attrib list
|
||||
refreshAttribs();
|
||||
|
||||
|
@ -72,7 +75,7 @@ void CGUIAttributeEditor::refreshAttribs()
|
|||
position2di top(10, 5);
|
||||
rect<s32> r(top.X,
|
||||
top.Y,
|
||||
AbsoluteRect.getWidth() - 10,
|
||||
getClientArea().getWidth() - 10,
|
||||
5 + Environment->getSkin()->getFont()->getDimension(L"A").Height);
|
||||
|
||||
// add attribute elements
|
||||
|
|
|
@ -108,9 +108,8 @@ namespace gui
|
|||
AttribSliderR->setPos(col.getRed());
|
||||
AttribSliderG->setPos(col.getGreen());
|
||||
AttribSliderB->setPos(col.getBlue());
|
||||
|
||||
return updateAttrib();
|
||||
}
|
||||
break;
|
||||
case EGET_SCROLL_BAR_CHANGED:
|
||||
{
|
||||
// update editbox from scrollbars
|
||||
|
|
|
@ -23,6 +23,13 @@ CGUIEditWindow::CGUIEditWindow(IGUIEnvironment* environment, core::rect<s32> rec
|
|||
setDebugName("CGUIEditWindow");
|
||||
#endif
|
||||
|
||||
// we can't tab out of this window
|
||||
setTabGroup(true);
|
||||
// we can ctrl+tab to it
|
||||
setTabStop(true);
|
||||
// the tab order number is auto-assigned
|
||||
setTabOrder(-1);
|
||||
|
||||
// set window text
|
||||
setText(L"GUI Editor");
|
||||
|
||||
|
@ -177,13 +184,12 @@ bool CGUIEditWindow::OnEvent(SEvent event)
|
|||
switch(event.GUIEvent.EventType)
|
||||
{
|
||||
case EGET_ELEMENT_FOCUS_LOST:
|
||||
Dragging = false;
|
||||
Resizing = false;
|
||||
return true;
|
||||
|
||||
break;
|
||||
|
||||
case EGET_BUTTON_CLICKED:
|
||||
if (event.GUIEvent.Caller == this ||
|
||||
event.GUIEvent.Caller == ResizeButton)
|
||||
{
|
||||
Dragging = false;
|
||||
Resizing = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -202,7 +208,7 @@ bool CGUIEditWindow::OnEvent(SEvent event)
|
|||
if (clickedElement == this)
|
||||
{
|
||||
Dragging = true;
|
||||
Environment->setFocus(this);
|
||||
//Environment->setFocus(this);
|
||||
if (Parent)
|
||||
Parent->bringToFront(this);
|
||||
return true;
|
||||
|
@ -210,7 +216,7 @@ bool CGUIEditWindow::OnEvent(SEvent event)
|
|||
else if (clickedElement == ResizeButton)
|
||||
{
|
||||
Resizing = true;
|
||||
Environment->setFocus(this);
|
||||
//Environment->setFocus(this);
|
||||
if (Parent)
|
||||
Parent->bringToFront(this);
|
||||
return true;
|
||||
|
@ -221,7 +227,7 @@ bool CGUIEditWindow::OnEvent(SEvent event)
|
|||
if (Dragging || Resizing)
|
||||
{
|
||||
Dragging = false;
|
||||
Environment->removeFocus(this);
|
||||
Resizing = false;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -143,22 +143,6 @@ IGUIElement* CGUIEditWorkspace::getEditableElementFromPoint(IGUIElement *start,
|
|||
return target;
|
||||
}
|
||||
|
||||
bool CGUIEditWorkspace::isMyChild(IGUIElement* target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
IGUIElement *current = target;
|
||||
while(current->getParent())
|
||||
{
|
||||
current = current->getParent();
|
||||
if (current == this)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGUIEditWorkspace::setSelectedElement(IGUIElement *sel)
|
||||
{
|
||||
IGUIElement* focus = Environment->getFocus();
|
||||
|
@ -700,8 +684,9 @@ bool CGUIEditWorkspace::OnEvent(SEvent e)
|
|||
break;
|
||||
}
|
||||
|
||||
// even if we didn't absorb the event,
|
||||
// we never pass events back to the GUI we're editing!
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -89,8 +89,6 @@ namespace gui
|
|||
|
||||
private:
|
||||
|
||||
bool isMyChild(IGUIElement* target);
|
||||
|
||||
enum EGUIEDIT_MODE
|
||||
{
|
||||
// when we are currently selecting an element
|
||||
|
|
|
@ -38,6 +38,7 @@ CGUIPanel::CGUIPanel( IGUIEnvironment* environment, IGUIElement* parent, s32 id,
|
|||
|
||||
VScrollBar = environment->addScrollBar( false, rct, 0, id );
|
||||
VScrollBar->setSubElement(true);
|
||||
VScrollBar->setTabStop(false);
|
||||
VScrollBar->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||||
VScrollBar->grab();
|
||||
IGUIElement::addChild(VScrollBar);
|
||||
|
@ -46,6 +47,7 @@ CGUIPanel::CGUIPanel( IGUIEnvironment* environment, IGUIElement* parent, s32 id,
|
|||
|
||||
HScrollBar = environment->addScrollBar( true, rct, 0, id );
|
||||
HScrollBar->setSubElement(true);
|
||||
HScrollBar->setTabStop(false);
|
||||
HScrollBar->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT);
|
||||
HScrollBar->grab();
|
||||
IGUIElement::addChild(HScrollBar);
|
||||
|
@ -181,7 +183,6 @@ bool CGUIPanel::OnEvent( SEvent event )
|
|||
HScrollBar->OnEvent(event);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -192,11 +193,9 @@ bool CGUIPanel::OnEvent( SEvent event )
|
|||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return IGUIElement::OnEvent( event );
|
||||
}
|
||||
|
||||
return false;
|
||||
return IGUIElement::OnEvent(event);
|
||||
}
|
||||
|
||||
void CGUIPanel::moveInnerPane()
|
||||
|
|
|
@ -216,7 +216,7 @@ bool CGUITextureCacheBrowser::OnEvent(SEvent event)
|
|||
if (!Environment->hasFocus(this))
|
||||
{
|
||||
Dragging = true;
|
||||
Environment->setFocus(this);
|
||||
//Environment->setFocus(this);
|
||||
if (Parent)
|
||||
Parent->bringToFront(this);
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ bool CGUITextureCacheBrowser::OnEvent(SEvent event)
|
|||
break;
|
||||
case EMIE_LMOUSE_LEFT_UP:
|
||||
Dragging = false;
|
||||
Environment->removeFocus(this);
|
||||
//Environment->removeFocus(this);
|
||||
return true;
|
||||
case EMIE_MOUSE_MOVED:
|
||||
if (Dragging)
|
||||
|
|
Loading…
Reference in New Issue