Commit 7336c447 authored by cutealien's avatar cutealien

Focus behavior of IGUIEnvironment now controllable (right-click focus,...

Focus behavior of IGUIEnvironment now controllable (right-click focus, mouse-over focus). Disabled elements no longer get the focus unless users enforce it.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4759 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 55508ee4
-------------------------- --------------------------
Changes in 1.9 (not yet released) Changes in 1.9 (not yet released)
- Focus behavior of IGUIEnvironment now controllable (right-click focus, mouse-over focus). Disabled elements no longer get the focus unless users enforce it.
- Buttons can now now have 7 more image-states, 1 more sprite-state and the sprites are now scaleable. - Buttons can now now have 7 more image-states, 1 more sprite-state and the sprites are now scaleable.
- Spritebanks can now draw scaled sprites and are a little easier to use. - Spritebanks can now draw scaled sprites and are a little easier to use.
- Improved i18n key input for X11 (languages like cyrillic work now). - Improved i18n key input for X11 (languages like cyrillic work now).
......
...@@ -640,9 +640,11 @@ public: ...@@ -640,9 +640,11 @@ public:
\param first: element with the highest/lowest known tab order depending on search direction \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 closest: the closest match, depending on tab order and direction
\param includeInvisible: includes invisible elements in the search (default=false) \param includeInvisible: includes invisible elements in the search (default=false)
\param includeDisabled: includes disabled elements in the search (default=false)
\return true if successfully found an element, false to continue searching/fail */ \return true if successfully found an element, false to continue searching/fail */
bool getNextElement(s32 startOrder, bool reverse, bool group, bool getNextElement(s32 startOrder, bool reverse, bool group,
IGUIElement*& first, IGUIElement*& closest, bool includeInvisible=false) const IGUIElement*& first, IGUIElement*& closest, bool includeInvisible=false,
bool includeDisabled=false) const
{ {
// we'll stop searching if we find this number // we'll stop searching if we find this number
s32 wanted = startOrder + ( reverse ? -1 : 1 ); s32 wanted = startOrder + ( reverse ? -1 : 1 );
...@@ -658,6 +660,9 @@ public: ...@@ -658,6 +660,9 @@ public:
// ignore invisible elements and their children // ignore invisible elements and their children
if ( ( (*it)->isVisible() || includeInvisible ) && if ( ( (*it)->isVisible() || includeInvisible ) &&
(group == true || (*it)->isTabGroup() == false) ) (group == true || (*it)->isTabGroup() == false) )
{
// ignore disabled, but children are checked (disabled is currently per element ignoring parent states)
if ( (*it)->isEnabled() || includeDisabled )
{ {
// only check tab stops and those with the same group status // only check tab stops and those with the same group status
if ((*it)->isTabStop() && ((*it)->isTabGroup() == group)) if ((*it)->isTabStop() && ((*it)->isTabGroup() == group))
...@@ -702,6 +707,7 @@ public: ...@@ -702,6 +707,7 @@ public:
first = *it; first = *it;
} }
} }
}
// search within children // search within children
if ((*it)->getNextElement(startOrder, reverse, group, first, closest)) if ((*it)->getNextElement(startOrder, reverse, group, first, closest))
{ {
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "IGUISkin.h" #include "IGUISkin.h"
#include "rect.h" #include "rect.h"
#include "EMessageBoxFlags.h" #include "EMessageBoxFlags.h"
#include "EFocusFlags.h"
#include "IEventReceiver.h" #include "IEventReceiver.h"
#include "IXMLReader.h" #include "IXMLReader.h"
#include "path.h" #include "path.h"
...@@ -262,9 +263,8 @@ public: ...@@ -262,9 +263,8 @@ public:
\param modal Defines if the dialog is modal. This means, that all other \param modal Defines if the dialog is modal. This means, that all other
gui elements which were created before the message box cannot be used gui elements which were created before the message box cannot be used
until this messagebox is removed. until this messagebox is removed.
\param flags Flags specifying the layout of the message box. For example \param flags Flags specifying the layout of the message box using ::EMESSAGE_BOX_FLAG.
to create a message box with an OK and a CANCEL button on it, set this Create a message box with an OK and CANCEL button for example with (EMBF_OK | EMBF_CANCEL).
to (EMBF_OK | EMBF_CANCEL).
\param parent Parent gui element of the message box. \param parent Parent gui element of the message box.
\param id Id with which the gui element can be identified. \param id Id with which the gui element can be identified.
\param image Optional texture which will be displayed beside the text as an image \param image Optional texture which will be displayed beside the text as an image
...@@ -619,6 +619,17 @@ public: ...@@ -619,6 +619,17 @@ public:
\param group When true it will search for the next tab-group (like ctrl+tab) \param group When true it will search for the next tab-group (like ctrl+tab)
*/ */
virtual IGUIElement* getNextElement(bool reverse=false, bool group=false) = 0; virtual IGUIElement* getNextElement(bool reverse=false, bool group=false) = 0;
//! Set the way the gui will handle automatic focus changes
/** The default is (EFF_SET_ON_LMOUSE_DOWN | EFF_SET_ON_TAB).
with the left mouse button.
This does not affect the setFocus function itself - users can still call that whenever they want on any element.
\param flags A bitmask which is a combination of ::EFOCUS_FLAG flags.*/
virtual void setFocusBehavior(u32 flags) = 0;
//! Get the way the gui does handle focus changes
/** \returns A bitmask which is a combination of ::EFOCUS_FLAG flags.*/
virtual u32 getFocusBehavior() const = 0;
}; };
......
...@@ -58,7 +58,7 @@ const io::path CGUIEnvironment::DefaultFontName = "#DefaultFont"; ...@@ -58,7 +58,7 @@ const io::path CGUIEnvironment::DefaultFontName = "#DefaultFont";
CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* driver, IOSOperator* op) CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* driver, IOSOperator* op)
: IGUIElement(EGUIET_ROOT, 0, 0, 0, core::rect<s32>(core::position2d<s32>(0,0), driver ? core::dimension2d<s32>(driver->getScreenSize()) : core::dimension2d<s32>(0,0))), : IGUIElement(EGUIET_ROOT, 0, 0, 0, core::rect<s32>(core::position2d<s32>(0,0), driver ? core::dimension2d<s32>(driver->getScreenSize()) : core::dimension2d<s32>(0,0))),
Driver(driver), Hovered(0), HoveredNoSubelement(0), Focus(0), LastHoveredMousePos(0,0), CurrentSkin(0), Driver(driver), Hovered(0), HoveredNoSubelement(0), Focus(0), LastHoveredMousePos(0,0), CurrentSkin(0),
FileSystem(fs), UserReceiver(0), Operator(op) FileSystem(fs), UserReceiver(0), Operator(op), FocusFlags(EFF_SET_ON_LMOUSE_DOWN|EFF_SET_ON_TAB)
{ {
if (Driver) if (Driver)
Driver->grab(); Driver->grab();
...@@ -574,10 +574,30 @@ bool CGUIEnvironment::postEventFromUser(const SEvent& event) ...@@ -574,10 +574,30 @@ bool CGUIEnvironment::postEventFromUser(const SEvent& event)
updateHoveredElement(core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y)); updateHoveredElement(core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y));
if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) if ( Hovered != Focus )
if ( (Hovered && Hovered != Focus) || !Focus )
{ {
setFocus(Hovered); IGUIElement * focusCandidate = Hovered;
// Only allow enabled elements to be focused (unless EFF_CAN_FOCUS_DISABLED is set)
if ( !Hovered->isEnabled() && !(FocusFlags & EFF_CAN_FOCUS_DISABLED))
focusCandidate = NULL; // we still remove focus from the active element
// Please don't merge this into a single if clause, it's easier to debug the way it is
if (FocusFlags & EFF_SET_ON_LMOUSE_DOWN &&
event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN )
{
setFocus(focusCandidate);
}
else if ( FocusFlags & EFF_SET_ON_RMOUSE_DOWN &&
event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN )
{
setFocus(focusCandidate);
}
else if ( FocusFlags & EFF_SET_ON_MOUSE_OVER &&
event.MouseInput.Event == EMIE_MOUSE_MOVED )
{
setFocus(focusCandidate);
}
} }
// sending input to focus // sending input to focus
...@@ -599,7 +619,8 @@ bool CGUIEnvironment::postEventFromUser(const SEvent& event) ...@@ -599,7 +619,8 @@ bool CGUIEnvironment::postEventFromUser(const SEvent& event)
// For keys we handle the event before changing focus to give elements the chance for catching the TAB // For keys we handle the event before changing focus to give elements the chance for catching the TAB
// Send focus changing event // Send focus changing event
if (event.EventType == EET_KEY_INPUT_EVENT && if (FocusFlags & EFF_SET_ON_TAB &&
event.EventType == EET_KEY_INPUT_EVENT &&
event.KeyInput.PressedDown && event.KeyInput.PressedDown &&
event.KeyInput.Key == KEY_TAB) event.KeyInput.Key == KEY_TAB)
{ {
...@@ -610,7 +631,6 @@ bool CGUIEnvironment::postEventFromUser(const SEvent& event) ...@@ -610,7 +631,6 @@ bool CGUIEnvironment::postEventFromUser(const SEvent& event)
return true; return true;
} }
} }
} }
break; break;
default: default:
...@@ -1640,7 +1660,7 @@ IGUIElement* CGUIEnvironment::getNextElement(bool reverse, bool group) ...@@ -1640,7 +1660,7 @@ IGUIElement* CGUIEnvironment::getNextElement(bool reverse, bool group)
// find the element // find the element
IGUIElement *closest = 0; IGUIElement *closest = 0;
IGUIElement *first = 0; IGUIElement *first = 0;
startPos->getNextElement(startOrder, reverse, group, first, closest); startPos->getNextElement(startOrder, reverse, group, first, closest, false, FocusFlags & EFF_CAN_FOCUS_DISABLED);
if (closest) if (closest)
return closest; // we found an element return closest; // we found an element
...@@ -1652,6 +1672,15 @@ IGUIElement* CGUIEnvironment::getNextElement(bool reverse, bool group) ...@@ -1652,6 +1672,15 @@ IGUIElement* CGUIEnvironment::getNextElement(bool reverse, bool group)
return 0; return 0;
} }
void CGUIEnvironment::setFocusBehavior(u32 flags)
{
FocusFlags = flags;
}
u32 CGUIEnvironment::getFocusBehavior() const
{
return FocusFlags;
}
//! creates an GUI Environment //! creates an GUI Environment
IGUIEnvironment* createGUIEnvironment(io::IFileSystem* fs, IGUIEnvironment* createGUIEnvironment(io::IFileSystem* fs,
......
...@@ -260,7 +260,13 @@ public: ...@@ -260,7 +260,13 @@ public:
virtual void readGUIElement(io::IXMLReader* reader, IGUIElement* node) _IRR_OVERRIDE_; virtual void readGUIElement(io::IXMLReader* reader, IGUIElement* node) _IRR_OVERRIDE_;
//! Find the next element which would be selected when pressing the tab-key //! Find the next element which would be selected when pressing the tab-key
virtual IGUIElement* getNextElement(bool reverse=false, bool group=false); virtual IGUIElement* getNextElement(bool reverse=false, bool group=false) _IRR_OVERRIDE_;
//! Set the way the gui will handle focus changes
virtual void setFocusBehavior(u32 flags) _IRR_OVERRIDE_;
//! Get the way the gui does handle focus changes
virtual u32 getFocusBehavior() const _IRR_OVERRIDE_;
private: private:
...@@ -314,6 +320,7 @@ private: ...@@ -314,6 +320,7 @@ private:
io::IFileSystem* FileSystem; io::IFileSystem* FileSystem;
IEventReceiver* UserReceiver; IEventReceiver* UserReceiver;
IOSOperator* Operator; IOSOperator* Operator;
u32 FocusFlags;
static const io::path DefaultFontName; static const io::path DefaultFontName;
}; };
......
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