Example #1
1
bool EventDispatcher::DispatchSDLEvent(const SDL_Event &event)
{
	switch (event.type) {
		case SDL_KEYDOWN:
			return Dispatch(KeyboardEvent(KeyboardEvent::KEY_DOWN, KeySym(event.key.keysym.sym, SDL_Keymod(event.key.keysym.mod))));

		case SDL_KEYUP:
			return Dispatch(KeyboardEvent(KeyboardEvent::KEY_UP, KeySym(event.key.keysym.sym, SDL_Keymod(event.key.keysym.mod))));

		case SDL_TEXTINPUT:
			Uint32 unicode;
			Text::utf8_decode_char(&unicode, event.text.text);
			return Dispatch(TextInputEvent(unicode));

		case SDL_MOUSEWHEEL:
			return Dispatch(MouseWheelEvent(event.wheel.y > 0 ? MouseWheelEvent::WHEEL_UP : MouseWheelEvent::WHEEL_DOWN, m_lastMousePosition));

		case SDL_MOUSEBUTTONDOWN:
			return Dispatch(MouseButtonEvent(MouseButtonEvent::BUTTON_DOWN, MouseButtonFromSDLButton(event.button.button), Point(event.button.x,event.button.y)));

		case SDL_MOUSEBUTTONUP:
			return Dispatch(MouseButtonEvent(MouseButtonEvent::BUTTON_UP, MouseButtonFromSDLButton(event.button.button), Point(event.button.x,event.button.y)));

		case SDL_MOUSEMOTION:
			return Dispatch(MouseMotionEvent(Point(event.motion.x,event.motion.y), Point(event.motion.xrel, event.motion.yrel)));
	}

	return false;
}
Example #2
1
bool EventDispatcher::DispatchSDLEvent(const SDL_Event &event)
{
	switch (event.type) {
		case SDL_KEYDOWN:
			return Dispatch(KeyboardEvent(KeyboardEvent::KEY_DOWN, KeySym(event.key.keysym.sym, SDL_Keymod(event.key.keysym.mod)), event.key.repeat));

		case SDL_KEYUP:
			return Dispatch(KeyboardEvent(KeyboardEvent::KEY_UP, KeySym(event.key.keysym.sym, SDL_Keymod(event.key.keysym.mod)), event.key.repeat));

		case SDL_TEXTINPUT:
			Uint32 unicode;
			Text::utf8_decode_char(&unicode, event.text.text);
			return Dispatch(TextInputEvent(unicode));

		case SDL_MOUSEWHEEL:
			return Dispatch(MouseWheelEvent(event.wheel.y > 0 ? MouseWheelEvent::WHEEL_UP : MouseWheelEvent::WHEEL_DOWN, m_lastMousePosition));

		case SDL_MOUSEBUTTONDOWN:
			return Dispatch(MouseButtonEvent(MouseButtonEvent::BUTTON_DOWN, MouseButtonFromSDLButton(event.button.button), Point(event.button.x,event.button.y)));

		case SDL_MOUSEBUTTONUP:
			return Dispatch(MouseButtonEvent(MouseButtonEvent::BUTTON_UP, MouseButtonFromSDLButton(event.button.button), Point(event.button.x,event.button.y)));

		case SDL_MOUSEMOTION:
			return Dispatch(MouseMotionEvent(Point(event.motion.x,event.motion.y), Point(event.motion.xrel, event.motion.yrel)));

		case SDL_JOYAXISMOTION:
			// SDL joystick axis value is documented to have the range -32768 to 32767
			// unfortunately this places the centre at -0.5, not at zero, which is clearly nuts...
			// so since that doesn't make any sense, we assume the range is *actually* -32767 to +32767,
			// and scale it accordingly, clamping the output so that if we *do* get -32768, it turns into -1
			return Dispatch(JoystickAxisMotionEvent(event.jaxis.which, Clamp(event.jaxis.value * (1.0f / 32767.0f), -1.0f, 1.0f), event.jaxis.axis));

		case SDL_JOYHATMOTION:
			return Dispatch(JoystickHatMotionEvent(event.jhat.which, JoystickHatMotionEvent::JoystickHatDirection(event.jhat.value), event.jhat.hat));

		case SDL_JOYBUTTONDOWN:
			return Dispatch(JoystickButtonEvent(event.jbutton.which, JoystickButtonEvent::BUTTON_DOWN, event.jbutton.button));

		case SDL_JOYBUTTONUP:
			return Dispatch(JoystickButtonEvent(event.jbutton.which, JoystickButtonEvent::BUTTON_UP, event.jbutton.button));
	}

	return false;
}
Example #3
0
/**
 * Example strings:
 *   Key55
 *   Joy{uuid}/Button2
 *   Joy{uuid}/Hat0Dir3
 */
bool KeyBinding::FromString(const char *str, KeyBinding &kb)
{
	const char *digits = "1234567890";
	const char *p = str;

	if (strcmp(p, "disabled") == 0) {
		kb.Clear();
	} else if (strncmp(p, "Key", 3) == 0) {
		kb.type = KEYBOARD_KEY;
		p += 3;

		kb.u.keyboard.key = SDL_Keycode(atoi(p));
		p += strspn(p, digits);

		if (strncmp(p, "Mod", 3) == 0) {
			p += 3;
			kb.u.keyboard.mod = SDL_Keymod(atoi(p));
		} else {
			kb.u.keyboard.mod = KMOD_NONE;
		}
	} else if (strncmp(p, "Joy", 3) == 0) {
		p += 3;

		const int JoyUUIDLength = 33;
		char joyUUIDBuf[JoyUUIDLength];

		// read the UUID
		if (!ReadToTok('/', &p, joyUUIDBuf, JoyUUIDLength)) {
			return false;
		}
		// force terminate
		joyUUIDBuf[JoyUUIDLength-1] = '\0';
		// now, locate the internal ID.		
		int joy = Pi::JoystickFromGUIDString(joyUUIDBuf);
		if (joy == -1) {
			return false;
		}
		if (strncmp(p, "Button", 6) == 0) {
			p += 6;
			kb.type = JOYSTICK_BUTTON;
			kb.u.joystickButton.joystick = joy;
			kb.u.joystickButton.button = atoi(p);
		} else if (strncmp(p, "Hat", 3) == 0) {
			p += 3;
			kb.type = JOYSTICK_HAT;
			kb.u.joystickHat.joystick = joy;
			kb.u.joystickHat.hat = atoi(p);
			p += strspn(p, digits);

			if (strncmp(p, "Dir", 3) != 0)
				return false;

			p += 3;
			kb.u.joystickHat.direction = atoi(p);
		} else
			return false;
	}

	return true;
}
Example #4
0
/**
 * Exampe strings:
 *   Key55
 *   Joy0Button2
 *   Joy0Hat0Dir3
 */
bool KeyBindingFromString(const std::string &str, KeyBinding *kb)
{
	const char *digits = "1234567890";
	const char *p = str.c_str();

	if (strncmp(p, "Key", 3) == 0) {
		kb->type = KEYBOARD_KEY;
		p += 3;

		kb->u.keyboard.key = SDL_Keycode(atoi(p));
		p += strspn(p, digits);

		if (strncmp(p, "Mod", 3) == 0) {
			p += 3;
			kb->u.keyboard.mod = SDL_Keymod(atoi(p));
		} else
			kb->u.keyboard.mod = KMOD_NONE;

		return true;

	} else if (strncmp(p, "Joy", 3) == 0) {
		p += 3;

		int joy = atoi(p);
		p += strspn(p, digits);

		if (strncmp(p, "Button", 6) == 0) {
			p += 6;
			kb->type = JOYSTICK_BUTTON;
			kb->u.joystickButton.joystick = joy;
			kb->u.joystickButton.button = atoi(p);
			return true;
		} else if (strncmp(p, "Hat", 3) == 0) {
			p += 3;
			kb->type = JOYSTICK_HAT;
			kb->u.joystickHat.joystick = joy;
			kb->u.joystickHat.hat = atoi(p);
			p += strspn(p, digits);

			if (strncmp(p, "Dir", 3) != 0)
				return false;

			p += 3;
			kb->u.joystickHat.direction = atoi(p);
			return true;
		}

		return false;
	}

	return false;
}
Example #5
0
KeySym KeySym::FromString(const std::string &spec)
{
    static const std::string delim("+");

    SDL_Keycode sym = SDLK_UNKNOWN;
    Uint32 mod = KMOD_NONE;

    size_t start = 0, end = 0;
    while (end != std::string::npos) {
        // get to the first non-delim char
        start = spec.find_first_not_of(delim, end);

        // read the end, no more to do
        if (start == std::string::npos)
            break;

        // find the end - next delim or end of string
        end = spec.find_first_of(delim, start);

        // extract the fragment
        const std::string token(spec.substr(start, (end == std::string::npos) ? std::string::npos : end - start));

        if (token == "ctrl")
            mod |= KMOD_CTRL;
        else if (token == "shift")
            mod |= KMOD_SHIFT;
        else if (token == "alt")
            mod |= KMOD_ALT;
        else if (token == "meta")
            mod |= KMOD_GUI;

        else {
            if (sym != SDLK_UNKNOWN)
                Output("key spec '%s' has multiple keys, ignoring '%s'\n", spec.c_str(), token.c_str());
            else {
                for (const KeyMap *map = keymap; map->name; map++)
                    if (token == map->name)
                        sym = map->sym;
                if (sym == SDLK_UNKNOWN)
                    Output("key spec '%s' has unkown token '%s', ignoring it\n", spec.c_str(), token.c_str());
            }
        }
    }

    return KeySym(sym, SDL_Keymod(mod));
}
Example #6
0
bool EventDispatcher::Dispatch(const Event &event)
{
	switch (event.type) {

		case Event::KEYBOARD: {
			const KeyboardEvent keyEvent = static_cast<const KeyboardEvent&>(event);
			switch (keyEvent.action) {
				case KeyboardEvent::KEY_DOWN:

					// all key events to the selected widget first
					if (m_selected && m_selected->IsOnTopLayer())
						return m_selected->TriggerKeyDown(keyEvent);

					return m_baseContainer->TriggerKeyDown(keyEvent);

				case KeyboardEvent::KEY_UP: {

					// all key events to the selected widget first
					if (m_selected && m_selected->IsOnTopLayer())
						return m_selected->TriggerKeyUp(keyEvent);

					// any modifier coming in will be a specific key, eg left
					// shift or right shift. shortcuts can't distinguish
					// betwen the two, and so have both set in m_shortcuts. we
					// can't just compare though, because the mods won't
					// match. so we make a new keysym with a new mod that
					// includes both of the type of key
					Uint32 mod = Uint32(keyEvent.keysym.mod);
					if (mod & KMOD_SHIFT) mod |= KMOD_SHIFT;
					if (mod & KMOD_CTRL)  mod |= KMOD_CTRL;
					if (mod & KMOD_ALT)   mod |= KMOD_ALT;
					if (mod & KMOD_GUI)   mod |= KMOD_GUI;
					const KeySym shortcutSym(keyEvent.keysym.sym, SDL_Keymod(mod));

					std::map<KeySym,Widget*>::iterator i = m_shortcuts.find(shortcutSym);
					if (i != m_shortcuts.end()) {
						// DispatchSelect must happen before TriggerClick, so
						// that Click handlers can override the selection
						DispatchSelect((*i).second);
						(*i).second->TriggerClick();
						return true;
					}

					return m_baseContainer->TriggerKeyUp(keyEvent);
				}

			}
			return false;
		}

		case Event::TEXT_INPUT: {

			const TextInputEvent textInputEvent = static_cast<const TextInputEvent&>(event);

			// selected widgets get all the text input events
			if (m_selected && m_selected->IsOnTopLayer())
				return m_selected->TriggerTextInput(textInputEvent);

			return m_baseContainer->TriggerTextInput(textInputEvent);
		}

		case Event::MOUSE_BUTTON: {
			const MouseButtonEvent mouseButtonEvent = static_cast<const MouseButtonEvent&>(event);
			m_lastMousePosition = mouseButtonEvent.pos;

			RefCountedPtr<Widget> target(m_baseContainer->GetWidgetAt(m_lastMousePosition));

			switch (mouseButtonEvent.action) {

				case MouseButtonEvent::BUTTON_DOWN: {

					if (!target->IsOnTopLayer())
						return false;

					if (target->IsDisabled())
						return false;

					// activate widget and remember it
					if (!m_mouseActiveReceiver) {
						m_mouseActiveReceiver = target;
						m_mouseActiveTrigger = mouseButtonEvent.button;
						target->TriggerMouseActivate();
					}

					MouseButtonEvent translatedEvent = MouseButtonEvent(mouseButtonEvent.action, mouseButtonEvent.button, m_lastMousePosition-target->GetAbsolutePosition());
					return target->TriggerMouseDown(translatedEvent);
				}

				case MouseButtonEvent::BUTTON_UP: {

					// if there's an active widget, deactivate it
					if (m_mouseActiveReceiver && m_mouseActiveTrigger == mouseButtonEvent.button) {
						m_mouseActiveReceiver->TriggerMouseDeactivate();

						// if we released over the active widget, then we clicked it
						if (m_mouseActiveReceiver.Get() == target) {
							// DispatchSelect must happen before TriggerClick, so
							// that Click handlers can override the selection
							DispatchSelect(m_mouseActiveReceiver.Get());
							m_mouseActiveReceiver->TriggerClick();
						}

						m_mouseActiveReceiver.Reset();

						// send the straight up event too
						bool ret = false;
						if (!target->IsDisabled()) {
							MouseButtonEvent translatedEvent = MouseButtonEvent(mouseButtonEvent.action, mouseButtonEvent.button, m_lastMousePosition-target->GetAbsolutePosition());
							ret = target->TriggerMouseUp(translatedEvent);
						}

						DispatchMouseOverOut(target.Get(), m_lastMousePosition);

						return ret;
					}

					if (!target->IsOnTopLayer())
						return false;

					MouseButtonEvent translatedEvent = MouseButtonEvent(mouseButtonEvent.action, mouseButtonEvent.button, m_lastMousePosition-target->GetAbsolutePosition());
					return target->TriggerMouseUp(translatedEvent);
				}

				default:
					return false;
			}
		}

		case Event::MOUSE_MOTION: {
			const MouseMotionEvent mouseMotionEvent = static_cast<const MouseMotionEvent&>(event);
			m_lastMousePosition = mouseMotionEvent.pos;

			// if there's a mouse-active widget, just send motion events directly into it
			if (m_mouseActiveReceiver) {
				if (!m_mouseActiveReceiver->IsOnTopLayer())
					return false;

				MouseMotionEvent translatedEvent = MouseMotionEvent(m_lastMousePosition-m_mouseActiveReceiver->GetAbsolutePosition(), mouseMotionEvent.rel);
				return m_mouseActiveReceiver->TriggerMouseMove(translatedEvent);
			}

			// widget directly under the mouse
			RefCountedPtr<Widget> target(m_baseContainer->GetWidgetAt(m_lastMousePosition));

			bool ret = false;
			if (!target->IsDisabled() && target->IsOnTopLayer()) {
				MouseMotionEvent translatedEvent = MouseMotionEvent(m_lastMousePosition-target->GetAbsolutePosition(), mouseMotionEvent.rel);
				ret = target->TriggerMouseMove(translatedEvent);
			}

			DispatchMouseOverOut(target.Get(), m_lastMousePosition);

			return ret;
		}

		case Event::MOUSE_WHEEL: {
			const MouseWheelEvent mouseWheelEvent = static_cast<const MouseWheelEvent&>(event);
			m_lastMousePosition = mouseWheelEvent.pos;

			RefCountedPtr<Widget> target(m_baseContainer->GetWidgetAt(m_lastMousePosition));
			if (!target->IsOnTopLayer())
				return false;

			return target->TriggerMouseWheel(mouseWheelEvent);
		}

		case Event::JOYSTICK_AXIS_MOTION:
			return m_baseContainer->TriggerJoystickAxisMove(static_cast<const JoystickAxisMotionEvent&>(event));

		case Event::JOYSTICK_HAT_MOTION:
			return m_baseContainer->TriggerJoystickHatMove(static_cast<const JoystickHatMotionEvent&>(event));

		case Event::JOYSTICK_BUTTON: {
			const JoystickButtonEvent &joyButtonEvent = static_cast<const JoystickButtonEvent&>(event);
			switch (joyButtonEvent.action) {
				case JoystickButtonEvent::BUTTON_DOWN:
					return m_baseContainer->TriggerJoystickButtonDown(joyButtonEvent);
				case JoystickButtonEvent::BUTTON_UP:
					return m_baseContainer->TriggerJoystickButtonUp(joyButtonEvent);
				default: assert(0); return false;
			}
		}

		default:
			return false;
	}

	return false;
}