Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: mackron/GTGUI
base: 21e8a65e50
...
head fork: mackron/GTGUI
compare: 9da594e3b7
  • 2 commits
  • 7 files changed
  • 0 commit comments
  • 1 contributor
Commits on Apr 07, 2012
Dave Reid Added OnMouseMove event handling on the scripting and C++ side.
Added double-click and key event handlers to the C++ side.
25ddf6b
Dave Reid Added mouse wheel event handlers to both the C++ and Lua environments. 9da594e
View
81 include/GTGUI/Element.hpp
@@ -533,6 +533,87 @@ namespace GTGUI
}
+ /// OnLMBDoubleClick
+ void OnLMBDoubleClick(int x, int y)
+ {
+ for (auto i = this->eventHandlers.root; i != nullptr; i = i->next)
+ {
+ i->value->OnLMBDoubleClick(*this, x, y);
+ }
+ }
+
+ /// OnRMBDoubleClick
+ void OnRMBDoubleClick(int x, int y)
+ {
+ for (auto i = this->eventHandlers.root; i != nullptr; i = i->next)
+ {
+ i->value->OnRMBDoubleClick(*this, x, y);
+ }
+ }
+
+ /// OnMMBDoubleClick
+ void OnMMBDoubleClick(int x, int y)
+ {
+ for (auto i = this->eventHandlers.root; i != nullptr; i = i->next)
+ {
+ i->value->OnMMBDoubleClick(*this, x, y);
+ }
+ }
+
+
+ /// OnMouseMove
+ void OnMouseMove(int x, int y)
+ {
+ for (auto i = this->eventHandlers.root; i != nullptr; i = i->next)
+ {
+ i->value->OnMouseMove(*this, x, y);
+ }
+ }
+
+ /// OnMouseWheel
+ void OnMouseWheel(int delta, int x, int y)
+ {
+ for (auto i = this->eventHandlers.root; i != nullptr; i = i->next)
+ {
+ i->value->OnMouseWheel(*this, delta, x, y);
+ }
+ }
+
+
+ /// OnKeyPressed.
+ void OnKeyPressed(GTCore::Key key)
+ {
+ for (auto i = this->eventHandlers.root; i != nullptr; i = i->next)
+ {
+ i->value->OnKeyPressed(*this, key);
+ }
+ }
+
+ /// OnKeyDown.
+ bool OnKeyDown(GTCore::Key key)
+ {
+ bool retValue = true;
+
+ for (auto i = this->eventHandlers.root; i != nullptr; i = i->next)
+ {
+ if (!i->value->OnKeyDown(*this, key))
+ {
+ retValue = false;
+ }
+ }
+
+ return retValue;
+ }
+
+ /// OnKeyUp.
+ void OnKeyUp(GTCore::Key key)
+ {
+ for (auto i = this->eventHandlers.root; i != nullptr; i = i->next)
+ {
+ i->value->OnKeyUp(*this, key);
+ }
+ }
+
/// OnTextChanged.
void OnTextChanged()
{
View
44 include/GTGUI/ElementEventHandler.hpp
@@ -1,6 +1,8 @@
#ifndef __GTGUI_ElementEventHandler_hpp_
#define __GTGUI_ElementEventHandler_hpp_
+#include <GTCore/Windowing/Keys.hpp>
+
namespace GTGUI
{
class Element;
@@ -22,25 +24,35 @@ namespace GTGUI
virtual void OnDraw(Element &element);
- /// Called when the left mouse button is pressed on this element.
+ /// Called when the left mouse button is pressed on the element.
virtual void OnLMBDown(Element &element, int x, int y);
- /// Called when the left mouse button is raised on this element.
+ /// Called when the left mouse button is raised on the element.
virtual void OnLMBUp(Element &element, int x, int y);
- /// Called when the right mouse button is pressed on this element.
+ /// Called when the right mouse button is pressed on the element.
virtual void OnRMBDown(Element &element, int x, int y);
- /// Called when the right mouse button is raised on this element.
+ /// Called when the right mouse button is raised on the element.
virtual void OnRMBUp(Element &element, int x, int y);
- /// Called when the middle mouse button is pressed on this element.
+ /// Called when the middle mouse button is pressed on the element.
virtual void OnMMBDown(Element &element, int x, int y);
- /// Called when the middle mouse button is raised on this element.
+ /// Called when the middle mouse button is raised on the element.
virtual void OnMMBUp(Element &element, int x, int y);
+ /// Called when the left mouse button is double clicked on the element.
+ virtual void OnLMBDoubleClick(Element &element, int x, int y);
+
+ /// Called when the right mouse button is double clicked on the element.
+ virtual void OnRMBDoubleClick(Element &element, int x, int y);
+
+ /// Called when the middle mouse button is double clicked on the element.
+ virtual void OnMMBDoubleClick(Element &element, int x, int y);
+
+
/// Called when the mouse enters the element.
virtual void OnMouseEnter(Element &element);
@@ -57,6 +69,26 @@ namespace GTGUI
virtual void OnPressed(Element &element);
+ /// Called when the mouse is moved while over the given element.
+ virtual void OnMouseMove(Element &element, int x, int y);
+
+ /// Called when the mouse wheel is moved while over the given element.
+ virtual void OnMouseWheel(Element &element, int delta, int x, int y);
+
+
+ /// Called when a key is pressed. This is different to OnKeyDown in that it will not be called for repeating keys.
+ virtual void OnKeyPressed(Element &element, GTCore::Key key);
+
+ /// Called when a key is pushed down.
+ ///
+ /// @remarks
+ /// To cancel the key input, return false. Otherwise, return true. This is a good way to selectively ignore keys.
+ virtual bool OnKeyDown(Element &element, GTCore::Key key);
+
+ /// Called when a key is released.
+ virtual void OnKeyUp(Element &element, GTCore::Key key);
+
+
/// Called when the element's text has changed.
virtual void OnTextChanged(Element &element);
};
View
13 include/GTGUI/Server.hpp
@@ -238,6 +238,7 @@ namespace GTGUI
* \brief Applications should call this when the mouse has moved. This will allow GTGUI to send and handle mouse events.
*/
void OnMouseMove(int x, int y);
+ void OnMouseWheel(int delta, int x, int y);
void OnLMBDown();
void OnRMBDown();
void OnMMBDown();
@@ -579,16 +580,22 @@ namespace GTGUI
/// The caret for this server. There is only ever one of these, and it will be shared across elements.
mutable Caret caret;
+ /// Keeps track of whether or not we're currently inside HandleEvents(). We need this so that we don't use PostEvent()
+ /// while running PostEvent(), since 1) it isn't needed and 2) we'll get stuck in a deadlock.
+ bool handlingEvents;
+
/// Keeps track of whether or not the mouse is valid.
bool isMouseValid;
+ /// Keeps track of whether or not the mouse has moved. We use this in determining whether or not to post mouse-move events
+ /// to elements when the mouse is validated.
+ bool mouseMoved;
+
/// The position of the mouse from the last mouse move.
int mousePosX;
int mousePosY;
- /// Keeps track of whether or not we're currently inside HandleEvents(). We need this so that we don't use PostEvent()
- /// while running PostEvent(), since 1) it isn't needed and 2) we'll get stuck in a deadlock.
- bool handlingEvents;
+
/// The list of images currently loaded by the server.
View
6 include/GTGUI/Server/ScriptServer.hpp
@@ -136,6 +136,12 @@ namespace GTGUI
void PostEvent_OnRMBDoubleClick(Element *receiver);
void PostEvent_OnMMBDoubleClick(Element *receiver);
+ /// Posts the OnMouseMove event to the given receiver.
+ void PostEvent_OnMouseMove(Element* element, int relativePosX, int relativePosY);
+
+ /// Posts the OnMouseWheel event to the given receiver.
+ void PostEvent_OnMouseWheel(Element* element, int delta, int relativePosX, int relativePosY);
+
private:
View
37 source/ElementEventHandler.cpp
@@ -39,6 +39,20 @@ namespace GTGUI
{
}
+
+ void ElementEventHandler::OnLMBDoubleClick(Element &, int, int)
+ {
+ }
+
+ void ElementEventHandler::OnRMBDoubleClick(Element &, int, int)
+ {
+ }
+
+ void ElementEventHandler::OnMMBDoubleClick(Element &, int, int)
+ {
+ }
+
+
void ElementEventHandler::OnMouseEnter(Element &)
{
}
@@ -59,6 +73,29 @@ namespace GTGUI
{
}
+
+ void ElementEventHandler::OnMouseMove(Element &, int, int)
+ {
+ }
+
+ void ElementEventHandler::OnMouseWheel(Element &, int, int, int)
+ {
+ }
+
+
+ void ElementEventHandler::OnKeyPressed(Element &, GTCore::Key)
+ {
+ }
+
+ bool ElementEventHandler::OnKeyDown(Element &, GTCore::Key)
+ {
+ return true;
+ }
+
+ void ElementEventHandler::OnKeyUp(Element &, GTCore::Key)
+ {
+ }
+
void ElementEventHandler::OnTextChanged(Element &)
{
}
View
73 source/Server.cpp
@@ -155,9 +155,10 @@ namespace GTGUI
fontServer(nullptr), defaultFont(nullptr),
hoveredElements(), pushedElement(nullptr), focusedElement(nullptr),
caret(),
+ handlingEvents(false),
isMouseValid(false),
- mousePosX(0), mousePosY(0),
- handlingEvents(false)
+ mouseMoved(false),
+ mousePosX(0), mousePosY(0)
{
// We need some event handlers on the sub-servers.
this->scripting.SetEventHandler(*(new ScriptingEventHandler(*this)));
@@ -711,7 +712,7 @@ namespace GTGUI
void Server::OnMouseMove(int x, int y)
{
- // We intentionally dont have a receiver element here. Instead we
+ // We intentionally dont have a receiver element here. Instead we post mouse-move events to elements when the mouse is validated.
Event e;
e.code = EventCode_OnMouseMove;
e.element = nullptr;
@@ -721,6 +722,18 @@ namespace GTGUI
this->PostEvent(e);
}
+ void Server::OnMouseWheel(int delta, int x, int y)
+ {
+ Event e;
+ e.code = EventCode_OnMouseWheel;
+ e.element = nullptr;
+ e.mousewheel.delta = delta;
+ e.mousewheel.x = x;
+ e.mousewheel.y = y;
+
+ this->PostEvent(e);
+ }
+
void Server::OnLMBDown()
{
Event e;
@@ -1241,11 +1254,28 @@ namespace GTGUI
this->mousePosX = e.mousemove.x;
this->mousePosY = e.mousemove.y;
+ this->mouseMoved = true;
+
this->InvalidateMouse();
}
- void Server::HandleEvent_OnMouseWheel(Event &)
+ void Server::HandleEvent_OnMouseWheel(Event &e)
{
+ if (this->hoveredElements.root != nullptr)
+ {
+ auto receiver = this->hoveredElements.root->value;
+ if (receiver != nullptr)
+ {
+ Rect rect;
+ receiver->GetAbsoluteRect(rect);
+
+ int relativeX = e.mousewheel.x - rect.left;
+ int relativeY = e.mousewheel.y - rect.top;
+
+ receiver->OnMouseWheel(e.mousewheel.delta, relativeX, relativeY);
+ this->scripting.PostEvent_OnMouseWheel(receiver, e.mousewheel.delta, relativeX, relativeY);
+ }
+ }
}
void Server::HandleEvent_OnLMBDown(Event &e)
@@ -1361,37 +1391,40 @@ namespace GTGUI
}
}
- void Server::HandleEvent_OnLMBDoubleClick(Event &)
+ void Server::HandleEvent_OnLMBDoubleClick(Event &e)
{
if (this->hoveredElements.root != nullptr)
{
Element *receiver = this->hoveredElements.root->value;
if (receiver != nullptr)
{
+ receiver->OnLMBDoubleClick(e.mousedoubleclick.x, e.mousedoubleclick.y);
this->scripting.PostEvent_OnLMBDoubleClick(receiver);
}
}
}
- void Server::HandleEvent_OnRMBDoubleClick(Event &)
+ void Server::HandleEvent_OnRMBDoubleClick(Event &e)
{
if (this->hoveredElements.root != nullptr)
{
Element *receiver = this->hoveredElements.root->value;
if (receiver != nullptr)
{
+ receiver->OnRMBDoubleClick(e.mousedoubleclick.x, e.mousedoubleclick.y);
this->scripting.PostEvent_OnRMBDoubleClick(receiver);
}
}
}
- void Server::HandleEvent_OnMMBDoubleClick(Event &)
+ void Server::HandleEvent_OnMMBDoubleClick(Event &e)
{
if (this->hoveredElements.root != nullptr)
{
Element *receiver = this->hoveredElements.root->value;
if (receiver != nullptr)
{
+ receiver->OnMMBDoubleClick(e.mousedoubleclick.x, e.mousedoubleclick.y);
this->scripting.PostEvent_OnMMBDoubleClick(receiver);
}
}
@@ -1401,6 +1434,7 @@ namespace GTGUI
{
if (this->focusedElement != nullptr)
{
+ this->focusedElement->OnKeyPressed(e.keypressed.key);
this->scripting.PostEvent_OnKeyPressed(this->focusedElement, e.keypressed.key);
}
}
@@ -1411,7 +1445,8 @@ namespace GTGUI
if (this->focusedElement != nullptr)
{
// Here we only want to modify the text if the event handlers have returned true.
- if (this->scripting.PostEvent_OnKeyDown(this->focusedElement, e.keydown.key))
+ if (this->focusedElement->OnKeyDown(e.keydown.key) &&
+ this->scripting.PostEvent_OnKeyDown(this->focusedElement, e.keydown.key))
{
if (e.keydown.key == GTCore::Keys::Backspace)
{
@@ -1446,6 +1481,7 @@ namespace GTGUI
{
if (this->focusedElement != nullptr)
{
+ this->focusedElement->OnKeyUp(e.keyup.key);
this->scripting.PostEvent_OnKeyUp(this->focusedElement, e.keyup.key);
}
}
@@ -1627,8 +1663,29 @@ namespace GTGUI
this->pushedElement = nullptr;
}
+
+ // If the mouse was moved, we need to post a mouse-move event to the hovered element.
+ if (this->mouseMoved)
+ {
+ if (hoveredElement != nullptr)
+ {
+ Rect rect;
+ hoveredElement->GetAbsoluteRect(rect);
+
+ int relativePosX = this->mousePosX - rect.left;
+ int relativePosY = this->mousePosY - rect.top;
+
+ hoveredElement->OnMouseMove(relativePosX, relativePosY);
+ this->scripting.PostEvent_OnMouseMove(hoveredElement, relativePosX, relativePosY);
+ }
+ }
+
+
// The mouse is now valid...
this->isMouseValid = true;
+
+ // From here on, we can make ourselves think that the mouse hasn't moved...
+ this->mouseMoved = false;
}
}
View
112 source/Server/ScriptServer.cpp
@@ -588,6 +588,99 @@ namespace GTGUI
}
this->script.Pop(1);
}
+
+
+ void ScriptServer::PostEvent_OnMouseMove(Element* receiver, int relativePosX, int relativePosY)
+ {
+ // Server._Elems[element->id]:OnMouseMove()
+
+ this->script.GetGlobal("Server");
+ if (this->script.IsTable(-1))
+ {
+ this->script.Push("_Elems");
+ this->script.GetTableValue(-2);
+ if (this->script.IsTable(-1))
+ {
+ this->script.Push(receiver->id);
+ this->script.GetTableValue(-2);
+ if (this->script.IsTable(-1))
+ {
+ this->script.Push("OnMouseMove");
+ this->script.GetTableValue(-2);
+ if (this->script.IsFunction(-1))
+ {
+ // Push 'self'.
+ this->script.PushValue(-2);
+
+ // Push 'data'.
+ this->script.PushNewTable();
+
+ this->script.Push("x");
+ this->script.Push(relativePosX);
+ this->script.SetTableValue(-3);
+
+ this->script.Push("y");
+ this->script.Push(relativePosY);
+ this->script.SetTableValue(-3);
+
+ // Now make the call...
+ this->script.Call(2);
+ }
+ }
+ this->script.Pop(1);
+ }
+ this->script.Pop(1);
+ }
+ this->script.Pop(1);
+ }
+
+ void ScriptServer::PostEvent_OnMouseWheel(Element* receiver, int delta, int relativePosX, int relativePosY)
+ {
+ // Server._Elems[element->id]:OnMouseWheeel()
+
+ this->script.GetGlobal("Server");
+ if (this->script.IsTable(-1))
+ {
+ this->script.Push("_Elems");
+ this->script.GetTableValue(-2);
+ if (this->script.IsTable(-1))
+ {
+ this->script.Push(receiver->id);
+ this->script.GetTableValue(-2);
+ if (this->script.IsTable(-1))
+ {
+ this->script.Push("OnMouseWheel");
+ this->script.GetTableValue(-2);
+ if (this->script.IsFunction(-1))
+ {
+ // Push 'self'.
+ this->script.PushValue(-2);
+
+ // Push 'data'.
+ this->script.PushNewTable();
+
+ this->script.Push("delta");
+ this->script.Push(delta);
+ this->script.SetTableValue(-3);
+
+ this->script.Push("x");
+ this->script.Push(relativePosX);
+ this->script.SetTableValue(-3);
+
+ this->script.Push("y");
+ this->script.Push(relativePosY);
+ this->script.SetTableValue(-3);
+
+ // Now make the call...
+ this->script.Call(2);
+ }
+ }
+ this->script.Pop(1);
+ }
+ this->script.Pop(1);
+ }
+ this->script.Pop(1);
+ }
bool ScriptServer::LoadDefaults()
@@ -976,6 +1069,23 @@ namespace GTGUI
"end;\n"
+ "function Server.Element:OnMouseMove(arg1)\n"
+ " if arg1 and type(arg1) == 'function' then\n" // <-- Is arg1 a callback? If so, we're binding.
+ " self:BindEvent(arg1, 'OnMouseMove');\n"
+ " else\n"
+ " self:CallEvent('OnMouseMove', arg1);\n"
+ " end;\n"
+ "end;\n"
+
+ "function Server.Element:OnMouseWheel(arg1)\n"
+ " if arg1 and type(arg1) == 'function' then\n" // <-- Is arg1 a callback? If so, we're binding.
+ " self:BindEvent(arg1, 'OnMouseWheel');\n"
+ " else\n"
+ " self:CallEvent('OnMouseWheel', arg1);\n"
+ " end;\n"
+ "end;\n"
+
+
"function Server.Element:OnSize(callback)\n"
" if callback then\n"
" self:BindEvent(callback, 'OnSize');\n"
@@ -1022,7 +1132,7 @@ namespace GTGUI
"end;\n"
"function Server.Element:CallEvent(name, data)\n"
- " local result = nil;\n"
+ " local result = true;\n"
" local handlerList = self.EventHandlers[name];\n"
" if handlerList then\n"
" for i, value in ipairs(handlerList) do\n"

No commit comments for this range

Something went wrong with that request. Please try again.