walk and key event system rework with some regressions

This commit is contained in:
Eduardo Bart
2012-01-15 19:19:52 -02:00
parent 9ec40f016d
commit 44a20222bb
52 changed files with 542 additions and 346 deletions

View File

@@ -228,6 +228,8 @@ namespace Fw
enum InputEventType {
NoInputEvent = 0,
KeyTextInputEvent,
KeyDownInputEvent,
KeyPressInputEvent,
KeyReleaseInputEvent,
MousePressInputEvent,

View File

@@ -76,10 +76,8 @@ void ConfigManager::setList(const std::string& key, const std::vector<std::strin
return;
OTMLNodePtr child = OTMLNode::create(key, true);
for(const std::string& value : list) {
for(const std::string& value : list)
child->writeIn(value);
dump << "insert" << value;
}
m_confsDoc->addChild(child);
}

View File

@@ -26,14 +26,30 @@
#include "declarations.h"
struct InputEvent {
InputEvent() {
reset();
keyboardModifiers = 0;
}
void reset(Fw::InputEventType eventType = Fw::NoInputEvent) {
type = eventType;
wheelDirection = Fw::MouseNoWheel;
mouseButton = Fw::MouseNoButton;
keyCode = Fw::KeyUnknown;
keyText = "";
mouseMoved = Point();
wouldFilter = false;
};
Fw::InputEventType type;
Fw::MouseWheelDirection wheelDirection;
Fw::MouseButton mouseButton;
int keyboardModifiers;
std::string keyText;
Fw::Key keyCode;
std::string keyText;
int keyboardModifiers;
Point mousePos;
Point mouseMoved;
bool wouldFilter;
};
#endif

View File

@@ -29,7 +29,7 @@ Particle::Particle(const Point& pos, const Size& startSize, const Size& finalSiz
m_colors = colors;
m_colorsStops = colorsStops;
m_position = PointF(pos.x, pos.y);
m_pos = PointF(pos.x, pos.y);
m_startSize = startSize;
m_finalSize = finalSize;
m_velocity = velocity;
@@ -80,18 +80,18 @@ void Particle::updatePosition(double elapsedTime)
PointF delta = m_velocity * elapsedTime;
delta.y *= -1; // painter orientate Y axis in the inverse direction
PointF position = m_position + delta;
PointF position = m_pos + delta;
if(m_position != position) {
if(m_pos != position) {
mustRedraw = true;
m_position += delta;
m_pos += delta;
}
// update acceleration
m_velocity += m_acceleration * elapsedTime;
}
m_rect.move((int)m_position.x - m_size.width() / 2, (int)m_position.y - m_size.height() / 2);
m_rect.move((int)m_pos.x - m_size.width() / 2, (int)m_pos.y - m_size.height() / 2);
}
void Particle::updateSize()

View File

@@ -36,10 +36,10 @@ public:
bool hasFinished() { return m_finished; }
PointF getPos() { return m_position; }
PointF getPos() { return m_pos; }
PointF getVelocity() { return m_velocity; }
void setPos(const PointF& position) { m_position = position; }
void setPos(const PointF& position) { m_pos = position; }
void setVelocity(const PointF& velocity) { m_velocity = velocity; }
private:
@@ -51,7 +51,7 @@ private:
std::vector<Color> m_colors;
std::vector<float> m_colorsStops;
TexturePtr m_texture;
PointF m_position;
PointF m_pos;
PointF m_velocity;
PointF m_acceleration;
Size m_size, m_startSize, m_finalSize;

View File

@@ -115,7 +115,7 @@ bool AttractionAffector::load(const OTMLNodePtr& node)
for(const OTMLNodePtr& childNode : node->children()) {
if(childNode->tag() == "position")
m_position = childNode->value<Point>();
m_pos = childNode->value<Point>();
else if(childNode->tag() == "acceleration")
m_acceleration = childNode->value<float>();
else if(childNode->tag() == "velocity-reduction-percent")
@@ -132,7 +132,7 @@ void AttractionAffector::updateParticle(const ParticlePtr& particle, double elap
return;
PointF pPosition = particle->getPos();
PointF d = PointF(m_position.x - pPosition.x, pPosition.y - m_position.y);
PointF d = PointF(m_pos.x - pPosition.x, pPosition.y - m_pos.y);
if(d.length() == 0)
return;

View File

@@ -57,7 +57,7 @@ public:
void updateParticle(const ParticlePtr& particle, double elapsedTime);
private:
Point m_position;
Point m_pos;
float m_acceleration, m_reduction;
bool m_repelish;
};

View File

@@ -31,7 +31,7 @@ ParticleEmitter::ParticleEmitter(const ParticleSystemPtr& parent)
{
m_parent = parent;
m_position = Point(0, 0);
m_pos = Point(0, 0);
m_duration = -1;
m_delay = 0;
m_burstRate = 1; m_burstCount = 32;
@@ -65,7 +65,7 @@ bool ParticleEmitter::load(const OTMLNodePtr& node)
for(const OTMLNodePtr& childNode : node->children()) {
// self related
if(childNode->tag() == "position")
m_position = childNode->value<Point>();
m_pos = childNode->value<Point>();
else if(childNode->tag() == "duration")
m_duration = childNode->value<float>();
else if(childNode->tag() == "delay")
@@ -199,7 +199,7 @@ void ParticleEmitter::update(double elapsedTime)
float pRadius = Fw::randomRange(m_pMinPositionRadius, m_pMaxPositionRadius);
float pAngle = Fw::randomRange(m_pMinPositionAngle, m_pMaxPositionAngle);
Point pPosition = m_position + Point(pRadius * cos(pAngle), pRadius * sin(pAngle));
Point pPosition = m_pos + Point(pRadius * cos(pAngle), pRadius * sin(pAngle));
for(int p = 0; p < m_burstCount; ++p) {

View File

@@ -44,7 +44,7 @@ private:
ParticleSystemWeakPtr m_parent;
// self related
Point m_position;
Point m_pos;
float m_duration, m_delay;
double m_elapsedTime;
bool m_finished, m_active;

View File

@@ -294,12 +294,12 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIBoxLayout>("setFitChildren", &UIBoxLayout::setFitChildren);
// UIVerticalLayout
g_lua.registerClass<UIVerticalLayout, UILayout>();
g_lua.registerClass<UIVerticalLayout, UIBoxLayout>();
g_lua.bindClassStaticFunction<UIVerticalLayout>("create", [](UIWidgetPtr parent){ return UIVerticalLayoutPtr(new UIVerticalLayout(parent)); } );
g_lua.bindClassMemberFunction<UIVerticalLayout>("setAlignBottom", &UIVerticalLayout::setAlignBottom);
// UIHorizontalLayout
g_lua.registerClass<UIHorizontalLayout, UILayout>();
g_lua.registerClass<UIHorizontalLayout, UIBoxLayout>();
g_lua.bindClassStaticFunction<UIHorizontalLayout>("create", [](UIWidgetPtr parent){ return UIHorizontalLayoutPtr(new UIHorizontalLayout(parent)); } );
g_lua.bindClassMemberFunction<UIHorizontalLayout>("setAlignRight", &UIHorizontalLayout::setAlignRight);
@@ -404,6 +404,7 @@ void Application::registerLuaFunctions()
g_lua.bindClassStaticFunction("g_window", "getY", std::bind(&PlatformWindow::getY, &g_window));
g_lua.bindClassStaticFunction("g_window", "getMousePos", std::bind(&PlatformWindow::getMousePos, &g_window));
g_lua.bindClassStaticFunction("g_window", "getKeyboardModifiers", std::bind(&PlatformWindow::getKeyboardModifiers, &g_window));
g_lua.bindClassStaticFunction("g_window", "isKeyPressed", std::bind(&PlatformWindow::isKeyPressed, &g_window, _1));
g_lua.bindClassStaticFunction("g_window", "isVisible", std::bind(&PlatformWindow::isVisible, &g_window));
g_lua.bindClassStaticFunction("g_window", "isFullscreen", std::bind(&PlatformWindow::isFullscreen, &g_window));
g_lua.bindClassStaticFunction("g_window", "isMaximized", std::bind(&PlatformWindow::isMaximized, &g_window));

View File

@@ -27,6 +27,7 @@
WIN32Window window;
#else
#include "x11window.h"
#include <framework/core/clock.h>
X11Window window;
#endif
@@ -39,3 +40,83 @@ void PlatformWindow::updateUnmaximizedCoords()
m_unmaximizedSize = m_size;
}
}
void PlatformWindow::processKeyDown(Fw::Key keyCode)
{
if(keyCode == Fw::KeyUnknown || m_keysState[keyCode])
return;
m_keysState[keyCode] = true;
m_lastKeysPress[keyCode] = -1;
if(keyCode == Fw::KeyCtrl)
m_inputEvent.keyboardModifiers |= Fw::KeyboardCtrlModifier;
else if(keyCode == Fw::KeyAlt)
m_inputEvent.keyboardModifiers |= Fw::KeyboardAltModifier;
else if(keyCode == Fw::KeyShift)
m_inputEvent.keyboardModifiers |= Fw::KeyboardShiftModifier;
m_inputEvent.reset();
m_inputEvent.type = Fw::KeyDownInputEvent;
m_inputEvent.keyCode = keyCode;
if(m_onInputEvent) {
m_onInputEvent(m_inputEvent);
m_inputEvent.reset(Fw::KeyPressInputEvent);
m_inputEvent.keyCode = keyCode;
m_lastKeysPress[keyCode] = g_clock.ticks();
m_firstKeysPress[keyCode] = g_clock.ticks();
m_onInputEvent(m_inputEvent);
}
}
void PlatformWindow::processKeyRelease(Fw::Key keyCode)
{
if(keyCode == Fw::KeyUnknown || !m_keysState[keyCode])
return;
m_keysState[keyCode] = false;
if(keyCode == Fw::KeyCtrl)
m_inputEvent.keyboardModifiers &= ~Fw::KeyboardCtrlModifier;
else if(keyCode == Fw::KeyAlt)
m_inputEvent.keyboardModifiers &= ~Fw::KeyboardAltModifier;
else if(keyCode == Fw::KeyShift)
m_inputEvent.keyboardModifiers &= ~Fw::KeyboardShiftModifier;
if(m_onInputEvent) {
m_inputEvent.reset(Fw::KeyReleaseInputEvent);
m_onInputEvent(m_inputEvent);
}
}
void PlatformWindow::fireKeysPress()
{
// avoid massive checks
if(m_keyPressTimer.ticksElapsed() < 10)
return;
m_keyPressTimer.restart();
for(auto it : m_keysState) {
Fw::Key keyCode = it.first;
bool pressed = it.second;
if(!pressed)
continue;
ticks_t lastPressTicks = m_lastKeysPress[keyCode];
ticks_t firstKeyPress = m_firstKeysPress[keyCode];
if(g_clock.ticksElapsed(lastPressTicks) >= KEY_PRESS_REPEAT_INTERVAL) {
if(m_onInputEvent) {
m_inputEvent.reset();
m_inputEvent.type = Fw::KeyPressInputEvent;
m_inputEvent.keyCode = keyCode;
m_inputEvent.wouldFilter = g_clock.ticksElapsed(firstKeyPress) < KEY_PRESS_REPEAT_DELAY;
m_onInputEvent(m_inputEvent);
}
m_lastKeysPress[keyCode] = g_clock.ticks();
}
}
}

View File

@@ -25,9 +25,15 @@
#include <framework/global.h>
#include <framework/core/inputevent.h>
#include <framework/core/timer.h>
class PlatformWindow
{
enum {
KEY_PRESS_REPEAT_INTERVAL = 30,
KEY_PRESS_REPEAT_DELAY = 500
};
typedef std::function<void(const Size&)> OnResizeCallback;
typedef std::function<void(const InputEvent&)> OnInputEventCallback;
@@ -72,6 +78,7 @@ public:
int getY() { return m_pos.y; }
Point getMousePos() { return m_inputEvent.mousePos; }
int getKeyboardModifiers() { return m_inputEvent.keyboardModifiers; }
bool isKeyPressed(Fw::Key keyCode) { return m_keysState[keyCode]; }
bool isVisible() { return m_visible; }
bool isFullscreen() { return m_fullscreen; }
@@ -85,6 +92,16 @@ public:
protected:
void updateUnmaximizedCoords();
void processKeyDown(Fw::Key keyCode);
void processKeyRelease(Fw::Key keyCode);
void fireKeysPress();
std::map<int, Fw::Key> m_keyMap;
std::map<Fw::Key, Boolean<false>> m_keysState;
std::map<Fw::Key, ticks_t> m_firstKeysPress;
std::map<Fw::Key, ticks_t> m_lastKeysPress;
Timer m_keyPressTimer;
Size m_size;
Point m_pos;
Size m_unmaximizedSize;

View File

@@ -35,7 +35,6 @@ WIN32Window::WIN32Window()
m_maximized = false;
m_minimumSize = Size(16,16);
m_size = m_minimumSize;
m_inputEvent.keyboardModifiers = 0;
m_keyMap[VK_ESCAPE] = Fw::KeyEscape;
m_keyMap[VK_TAB] = Fw::KeyTab;

View File

@@ -82,7 +82,6 @@ private:
HGLRC m_glContext;
bool m_maximized;
Size m_minimumSize;
std::map<int, Fw::Key> m_keyMap;
};
#endif

View File

@@ -39,7 +39,6 @@ X11Window::X11Window()
m_screen = 0;
m_wmDelete = 0;
m_size = Size(16,16);
m_inputEvent.keyboardModifiers = 0;
#ifndef OPENGL_ES2
m_glxContext = 0;
@@ -526,33 +525,41 @@ void X11Window::poll()
while(XPending(m_display) > 0) {
XNextEvent(m_display, &event);
// check for repeated key releases
bool repatedKeyRelease = false;
if(event.type == KeyRelease && XPending(m_display)) {
XPeekEvent(m_display, &peekEvent);
if((peekEvent.type == KeyPress) && (peekEvent.xkey.keycode == event.xkey.keycode) && ((peekEvent.xkey.time-event.xkey.time) < 2))
repatedKeyRelease = true;
}
// process keydown and keyrelease events first
if(event.type == KeyPress || (event.type == KeyRelease && !repatedKeyRelease)) {
// remove caps lock and shift maks
XKeyEvent xkey = event.xkey;
xkey.state &= ~(ShiftMask | LockMask);
// lookup keysym and translate it
KeySym keysym;
char buf[32];
int len = XLookupString(&xkey, buf, sizeof(buf), &keysym, 0);
Fw::Key keyCode = Fw::KeyUnknown;
if(m_keyMap.find(keysym) != m_keyMap.end())
keyCode = m_keyMap[keysym];
if(event.type == KeyPress)
processKeyDown(keyCode);
else if(event.type == KeyRelease)
processKeyRelease(keyCode);
}
// call filter because xim will discard KeyPress events when keys still composing
if(XFilterEvent(&event, m_window))
continue;
// discard events of repeated key releases
if(event.type == KeyRelease && XPending(m_display)) {
XPeekEvent(m_display, &peekEvent);
if((peekEvent.type == KeyPress) &&
(peekEvent.xkey.keycode == event.xkey.keycode) &&
((peekEvent.xkey.time-event.xkey.time) < 2))
continue;
}
// reset inputEvent values, except keyboardModifiers and mousePos
m_inputEvent.type = Fw::NoInputEvent;
m_inputEvent.mouseButton = Fw::MouseNoButton;
m_inputEvent.keyCode = Fw::KeyUnknown;
m_inputEvent.keyText = "";
m_inputEvent.mouseMoved = Point();
m_inputEvent.wheelDirection = Fw::MouseNoWheel;
m_inputEvent.keyboardModifiers = 0;
if(event.xkey.state & ControlMask)
m_inputEvent.keyboardModifiers |= Fw::KeyboardCtrlModifier;
if(event.xkey.state & ShiftMask)
m_inputEvent.keyboardModifiers |= Fw::KeyboardShiftModifier;
if(event.xkey.state & Mod1Mask)
m_inputEvent.keyboardModifiers |= Fw::KeyboardAltModifier;
// discard repated key releases
if(repatedKeyRelease)
continue;
switch(event.type) {
case ClientMessage: {
@@ -614,55 +621,44 @@ void X11Window::poll()
XFlush(m_display);
break;
}
case KeyPress:
case KeyRelease: {
// process text events
case KeyPress: {
// text cant be insert while holding ctrl or alt
if(event.xkey.state & ControlMask || event.xkey.state & Mod1Mask)
break;
// process key text events
KeySym keysym;
char buf[32];
memset(buf, 0, 32);
int len;
// lookup for keyText
if(event.type == KeyPress && !(event.xkey.state & ControlMask) && !(event.xkey.state & Mod1Mask)) {
if(m_xic) { // with xim we can get latin1 input correctly
Status status;
len = XmbLookupString(m_xic, &event.xkey, buf, sizeof(buf), &keysym, &status);
} else { // otherwise use XLookupString, but often it doesn't work right with dead keys
static XComposeStatus compose = {NULL, 0};
len = XLookupString(&event.xkey, buf, sizeof(buf), &keysym, &compose);
}
if(len > 0 &&
// these keys produces characters that we don't want to capture
keysym != XK_BackSpace &&
keysym != XK_Return &&
keysym != XK_Delete &&
keysym != XK_Escape &&
(uchar)(buf[0]) >= 32
) {
//logDebug("char: ", buf[0], " code: ", (uint)buf[0]);
m_inputEvent.keyText = buf;
}
if(m_xic) { // with xim we can get latin1 input correctly
Status status;
len = XmbLookupString(m_xic, &event.xkey, buf, sizeof(buf), &keysym, &status);
} else { // otherwise use XLookupString, but often it doesn't work right with dead keys
static XComposeStatus compose = {NULL, 0};
len = XLookupString(&event.xkey, buf, sizeof(buf), &keysym, &compose);
}
XKeyEvent xkey = event.xkey;
xkey.state = xkey.state & ~(ShiftMask);
len = XLookupString(&xkey, buf, sizeof(buf), &keysym, 0);
if(len > 0 && m_inputEvent.keyText.length() == 0 && keysym != XK_BackSpace &&
keysym != XK_Return &&
keysym != XK_Delete &&
keysym != XK_Escape)
m_inputEvent.keyText = buf;
// filter unwanted characters
if(len == 0 || (uchar)(buf[0]) < 32 || keysym == XK_BackSpace || keysym == XK_Return || keysym == XK_Delete || keysym == XK_Escape)
break;
std::string text = buf;
if(m_keyMap.find(keysym) != m_keyMap.end())
m_inputEvent.keyCode = m_keyMap[keysym];
//logDebug("char: ", buf[0], " code: ", (int)((uchar)buf[0]));
m_inputEvent.type = (event.type == KeyPress) ? Fw::KeyPressInputEvent : Fw::KeyReleaseInputEvent;
if(m_inputEvent.keyCode != Fw::KeyUnknown || !m_inputEvent.keyText.empty())
if(m_onInputEvent && text.length() > 0) {
m_inputEvent.reset(Fw::KeyTextInputEvent);
m_inputEvent.keyText = text;
m_onInputEvent(m_inputEvent);
}
break;
}
case ButtonPress:
case ButtonRelease: {
m_inputEvent.reset();
m_inputEvent.type = (event.type == ButtonPress) ? Fw::MousePressInputEvent : Fw::MouseReleaseInputEvent;
switch(event.xbutton.button) {
case Button1:
@@ -694,6 +690,7 @@ void X11Window::poll()
}
case MotionNotify: {
m_inputEvent.reset();
m_inputEvent.type = Fw::MouseMoveInputEvent;
Point newMousePos(event.xbutton.x, event.xbutton.y);
m_inputEvent.mouseMoved = newMousePos - m_inputEvent.mousePos;
@@ -722,6 +719,8 @@ void X11Window::poll()
if(needsResizeUpdate && m_onResize)
m_onResize(m_size);
fireKeysPress();
}
void X11Window::swapBuffers()

View File

@@ -93,7 +93,6 @@ private:
int m_screen;
Atom m_wmDelete;
std::string m_clipboardText;
std::map<int, Fw::Key> m_keyMap;
#ifndef OPENGL_ES2
GLXContext m_glxContext;

View File

@@ -389,6 +389,8 @@ void UILineEdit::onStyleApply(const std::string& styleName, const OTMLNodePtr& s
setTextHorizontalMargin(node->value<int>());
else if(node->tag() == "always-active")
setAlwaysActive(node->value<bool>());
//else if(node->tag() == "disable-arrow-navitation")
// setArrowNavigation(node->value<bool>());
}
}
@@ -409,34 +411,41 @@ void UILineEdit::onFocusChange(bool focused, Fw::FocusReason reason)
UIWidget::onFocusChange(focused, reason);
}
bool UILineEdit::onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers)
bool UILineEdit::onKeyPress(uchar keyCode, int keyboardModifiers, bool wouldFilter)
{
if(UIWidget::onKeyPress(keyCode, keyText, keyboardModifiers))
if(UIWidget::onKeyPress(keyCode, keyboardModifiers, wouldFilter))
return true;
if(keyCode == Fw::KeyDelete) // erase right character
removeCharacter(true);
else if(keyCode == Fw::KeyBackspace) // erase left character {
removeCharacter(false);
else if(keyCode == Fw::KeyRight) // move cursor right
moveCursor(true);
else if(keyCode == Fw::KeyLeft) // move cursor left
moveCursor(false);
else if(keyCode == Fw::KeyHome) // move cursor to first character
setCursorPos(0);
else if(keyCode == Fw::KeyEnd) // move cursor to last character
setCursorPos(m_text.length());
else if(keyCode == Fw::KeyV && keyboardModifiers == Fw::KeyboardCtrlModifier)
appendText(g_window.getClipboardText());
else if(keyCode == Fw::KeyTab) {
if(!m_alwaysActive) {
if(UIWidgetPtr parent = getParent())
parent->focusNextChild(Fw::TabFocusReason);
}
} else if(!keyText.empty() && (keyboardModifiers == Fw::KeyboardNoModifier || keyboardModifiers == Fw::KeyboardShiftModifier))
appendText(keyText);
else
return false;
if(!wouldFilter) {
if(keyCode == Fw::KeyDelete) // erase right character
removeCharacter(true);
else if(keyCode == Fw::KeyBackspace) // erase left character {
removeCharacter(false);
else if(keyCode == Fw::KeyRight) // move cursor right
moveCursor(true);
else if(keyCode == Fw::KeyLeft) // move cursor left
moveCursor(false);
else if(keyCode == Fw::KeyHome) // move cursor to first character
setCursorPos(0);
else if(keyCode == Fw::KeyEnd) // move cursor to last character
setCursorPos(m_text.length());
else if(keyCode == Fw::KeyV && keyboardModifiers == Fw::KeyboardCtrlModifier)
appendText(g_window.getClipboardText());
else if(keyCode == Fw::KeyTab) {
if(!m_alwaysActive) {
if(UIWidgetPtr parent = getParent())
parent->focusNextChild(Fw::TabFocusReason);
}
} else
return false;
return true;
}
return false;
}
bool UILineEdit::onKeyText(const std::string& keyText)
{
appendText(keyText);
return true;
}

View File

@@ -61,7 +61,8 @@ protected:
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
virtual void onGeometryChange(const Rect& oldRect, const Rect& newRect);
virtual void onFocusChange(bool focused, Fw::FocusReason reason);
virtual bool onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers);
virtual bool onKeyText(const std::string& keyText);
virtual bool onKeyPress(uchar keyCode, int keyboardModifiers, bool wouldFilter);
virtual bool onMousePress(const Point& mousePos, Fw::MouseButton button);
private:

View File

@@ -59,11 +59,17 @@ void UIManager::inputEvent(const InputEvent& event)
{
m_isOnInputEvent = true;
switch(event.type) {
case Fw::KeyTextInputEvent:
m_keyboardReceiver->propagateOnKeyText(event.keyText);
break;
case Fw::KeyDownInputEvent:
m_keyboardReceiver->propagateOnKeyDown(event.keyCode, event.keyboardModifiers);
break;
case Fw::KeyPressInputEvent:
m_keyboardReceiver->propagateOnKeyPress(event.keyCode, event.keyText, event.keyboardModifiers);
m_keyboardReceiver->propagateOnKeyPress(event.keyCode, event.keyboardModifiers, event.wouldFilter);
break;
case Fw::KeyReleaseInputEvent:
m_keyboardReceiver->propagateOnKeyRelease(event.keyCode, event.keyText, event.keyboardModifiers);
m_keyboardReceiver->propagateOnKeyRelease(event.keyCode, event.keyboardModifiers);
break;
case Fw::MousePressInputEvent:
m_keyboardReceiver->propagateOnMousePress(event.mousePos, event.mouseButton);

View File

@@ -1053,14 +1053,24 @@ void UIWidget::onHoverChange(bool hovered)
g_ui.getRootWidget()->updateState(Fw::HoverState);
}
bool UIWidget::onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers)
bool UIWidget::onKeyText(const std::string& keyText)
{
return callLuaField<bool>("onKeyPress", keyCode, keyText, keyboardModifiers);
return callLuaField<bool>("onKeyText", keyText);
}
bool UIWidget::onKeyRelease(uchar keyCode, std::string keyText, int keyboardModifiers)
bool UIWidget::onKeyDown(uchar keyCode, int keyboardModifiers)
{
return callLuaField<bool>("onKeyRelease", keyCode, keyText, keyboardModifiers);
return callLuaField<bool>("onKeyDown", keyCode, keyboardModifiers);
}
bool UIWidget::onKeyPress(uchar keyCode, int keyboardModifiers, bool wouldFilter)
{
return callLuaField<bool>("onKeyPress", keyCode, keyboardModifiers, wouldFilter);
}
bool UIWidget::onKeyRelease(uchar keyCode, int keyboardModifiers)
{
return callLuaField<bool>("onKeyRelease", keyCode, keyboardModifiers);
}
bool UIWidget::onMousePress(const Point& mousePos, Fw::MouseButton button)
@@ -1086,7 +1096,7 @@ bool UIWidget::onMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direc
return callLuaField<bool>("onMouseWheel", mousePos, direction);
}
bool UIWidget::propagateOnKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers)
bool UIWidget::propagateOnKeyText(const std::string& keyText)
{
// do a backup of children list, because it may change while looping it
UIWidgetList children;
@@ -1101,14 +1111,58 @@ bool UIWidget::propagateOnKeyPress(uchar keyCode, std::string keyText, int keybo
}
for(const UIWidgetPtr& child : children) {
if(child->propagateOnKeyPress(keyCode, keyText, keyboardModifiers))
if(child->propagateOnKeyText(keyText))
return true;
}
return onKeyPress(keyCode, keyText, keyboardModifiers);
return onKeyText(keyText);
}
bool UIWidget::propagateOnKeyRelease(uchar keyCode, std::string keyText, int keyboardModifiers)
bool UIWidget::propagateOnKeyDown(uchar keyCode, int keyboardModifiers)
{
// do a backup of children list, because it may change while looping it
UIWidgetList children;
for(const UIWidgetPtr& child : m_children) {
// events on hidden or disabled widgets are discarded
if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible())
continue;
// key events go only to containers or focused child
if(child->isFocused())
children.push_back(child);
}
for(const UIWidgetPtr& child : children) {
if(child->propagateOnKeyDown(keyCode, keyboardModifiers))
return true;
}
return onKeyDown(keyCode, keyboardModifiers);
}
bool UIWidget::propagateOnKeyPress(uchar keyCode, int keyboardModifiers, bool wouldFilter)
{
// do a backup of children list, because it may change while looping it
UIWidgetList children;
for(const UIWidgetPtr& child : m_children) {
// events on hidden or disabled widgets are discarded
if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible())
continue;
// key events go only to containers or focused child
if(child->isFocused())
children.push_back(child);
}
for(const UIWidgetPtr& child : children) {
if(child->propagateOnKeyPress(keyCode, keyboardModifiers, wouldFilter))
return true;
}
return onKeyPress(keyCode, keyboardModifiers, wouldFilter);
}
bool UIWidget::propagateOnKeyRelease(uchar keyCode, int keyboardModifiers)
{
// do a backup of children list, because it may change while looping it
UIWidgetList children;
@@ -1123,11 +1177,11 @@ bool UIWidget::propagateOnKeyRelease(uchar keyCode, std::string keyText, int key
}
for(const UIWidgetPtr& child : children) {
if(child->propagateOnKeyRelease(keyCode, keyText, keyboardModifiers))
if(child->propagateOnKeyRelease(keyCode, keyboardModifiers))
return true;
}
return onKeyRelease(keyCode, keyText, keyboardModifiers);
return onKeyRelease(keyCode, keyboardModifiers);
}
bool UIWidget::propagateOnMousePress(const Point& mousePos, Fw::MouseButton button)

View File

@@ -161,15 +161,19 @@ protected:
virtual void onGeometryChange(const Rect& oldRect, const Rect& newRect);
virtual void onFocusChange(bool focused, Fw::FocusReason reason);
virtual void onHoverChange(bool hovered);
virtual bool onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers);
virtual bool onKeyRelease(uchar keyCode, std::string keyText, int keyboardModifiers);
virtual bool onKeyText(const std::string& keyText);
virtual bool onKeyDown(uchar keyCode, int keyboardModifiers);
virtual bool onKeyPress(uchar keyCode, int keyboardModifiers, bool wouldFilter);
virtual bool onKeyRelease(uchar keyCode, int keyboardModifiers);
virtual bool onMousePress(const Point& mousePos, Fw::MouseButton button);
virtual void onMouseRelease(const Point& mousePos, Fw::MouseButton button);
virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved);
virtual bool onMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direction);
bool propagateOnKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers);
bool propagateOnKeyRelease(uchar keyCode, std::string keyText, int keyboardModifiers);
bool propagateOnKeyText(const std::string& keyText);
bool propagateOnKeyDown(uchar keyCode, int keyboardModifiers);
bool propagateOnKeyPress(uchar keyCode, int keyboardModifiers, bool wouldFilter);
bool propagateOnKeyRelease(uchar keyCode, int keyboardModifiers);
bool propagateOnMousePress(const Point& mousePos, Fw::MouseButton button);
void propagateOnMouseRelease(const Point& mousePos, Fw::MouseButton button);
bool propagateOnMouseMove(const Point& mousePos, const Point& mouseMoved);