Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F125880
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
31 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/util/events.cpp b/util/events.cpp
index 4a2443a6..75035af5 100644
--- a/util/events.cpp
+++ b/util/events.cpp
@@ -1,525 +1,526 @@
#ifdef USE_SDL
#include <SDL.h>
#endif
#ifdef USE_ALLEGRO5
#include <allegro5/allegro.h>
#endif
#include <vector>
#include "bitmap.h"
#include "events.h"
#include "exceptions/shutdown_exception.h"
#include "configuration.h"
#include "debug.h"
#include "funcs.h"
#include "thread.h"
#include "init.h"
#include "parameter.h"
#include "input/keyboard.h"
#include "input/joystick.h"
#include "input/input-manager.h"
+#include "input/input-source.h"
namespace Util{
EventManager::EventManager():
bufferKeys(false){
#ifdef USE_ALLEGRO5
queue = al_create_event_queue();
if (al_is_keyboard_installed()){
al_register_event_source(queue, al_get_keyboard_event_source());
}
if (Graphics::the_display != NULL){
al_register_event_source(queue, al_get_display_event_source(Graphics::the_display));
}
#endif
}
#ifdef USE_SDL
static void handleKeyDown(Keyboard & keyboard, const SDL_Event & event){
keyboard.press(event.key.keysym.sym, event.key.keysym.unicode);
}
static void handleKeyUp(Keyboard & keyboard, const SDL_Event & event){
keyboard.release(event.key.keysym.sym);
}
static void handleJoystickButtonUp(Joystick * joystick, const SDL_Event & event){
int device = event.jbutton.which;
int button = event.jbutton.button;
if (device == joystick->getDeviceId()){
joystick->releaseButton(button);
}
}
static void handleJoystickHat(Joystick * joystick, const SDL_Event & event){
int device = event.jhat.which;
int motion = event.jhat.value;
if (device == joystick->getDeviceId()){
joystick->hatMotion(motion);
}
#if 0
/* should up/down control left/right -- flip these values? */
#if WII
const int axis_up_down = 0;
const int axis_left_right = 1;
const int up = 1;
const int down = -1;
const int left = -1;
const int right = 1;
#else
const int axis_up_down = 1;
const int axis_left_right = 0;
const int up = -1;
const int down = 1;
const int left = -1;
const int right = 1;
#endif
switch (motion){
case SDL_HAT_CENTERED: break;
case SDL_HAT_UP: joystick->axisMotion(axis_up_down, up); break;
case SDL_HAT_DOWN: joystick->axisMotion(axis_up_down, down); break;
case SDL_HAT_RIGHT: joystick->axisMotion(axis_left_right, right); break;
case SDL_HAT_LEFT: joystick->axisMotion(axis_left_right, left); break;
default: break;
}
#endif
}
static void handleJoystickButtonDown(Joystick * joystick, const SDL_Event & event){
int device = event.jbutton.which;
int button = event.jbutton.button;
if (device == joystick->getDeviceId()){
joystick->pressButton(button);
}
}
static void handleJoystickAxis(Joystick * joystick, const SDL_Event & event){
int device = event.jaxis.which;
int axis = event.jaxis.axis;
int value = event.jaxis.value;
if (device == joystick->getDeviceId()){
joystick->axisMotion(axis, value);
}
}
void EventManager::runSDL(Keyboard & keyboard, Joystick * joystick){
keyboard.poll();
if (joystick){
joystick->poll();
}
SDL_Event event;
while (SDL_PollEvent(&event) == 1){
switch (event.type){
case SDL_QUIT : {
dispatch(CloseWindow);
break;
}
case SDL_KEYDOWN : {
handleKeyDown(keyboard, event);
// dispatch(Key, event.key.keysym.sym);
break;
}
case SDL_KEYUP : {
handleKeyUp(keyboard, event);
break;
}
case SDL_JOYBUTTONDOWN: {
if (joystick != NULL){
handleJoystickButtonDown(joystick, event);
}
break;
}
case SDL_JOYHATMOTION : {
if (joystick != NULL){
handleJoystickHat(joystick, event);
}
break;
}
case SDL_JOYBUTTONUP: {
if (joystick != NULL){
handleJoystickButtonUp(joystick, event);
}
break;
}
case SDL_JOYAXISMOTION: {
if (joystick != NULL){
handleJoystickAxis(joystick, event);
}
break;
}
case SDL_VIDEORESIZE : {
int width = event.resize.w;
int height = event.resize.h;
/* to keep the perspective correct
* 640/480 = 1.33333
*/
double ratio = (double) GFX_X / (double) GFX_Y;
if (width > height){
height = (int)((double) width / ratio);
} else {
width = (int)((double) height * ratio);
}
dispatch(ResizeScreen, width, height);
break;
}
default : {
break;
}
}
}
}
#endif
#ifdef USE_ALLEGRO
void EventManager::runAllegro(Keyboard & keyboard, Joystick * joystick){
keyboard.poll();
}
#endif
#ifdef USE_ALLEGRO5
static void handleKeyDown(Keyboard & keyboard, const ALLEGRO_EVENT & event){
keyboard.press(event.keyboard.keycode, event.keyboard.unichar);
}
static void handleKeyUp(Keyboard & keyboard, const ALLEGRO_EVENT & event){
keyboard.release(event.keyboard.keycode);
}
static void handleResize(const ALLEGRO_EVENT & event){
double width = event.display.width;
double height = event.display.height;
if (width < GFX_X){
width = GFX_X;
}
if (height < GFX_Y){
height = GFX_Y;
}
/* to keep the perspective correct
* 640/480 = 1.33333
*/
double ratio = (double) GFX_X / (double) GFX_Y;
if (width > height){
height = width / ratio;
} else {
width = height * ratio;
}
ALLEGRO_DISPLAY * display = event.display.source;
al_acknowledge_resize(display);
al_resize_display(display, (int) width, (int) height);
ALLEGRO_TRANSFORM transformation;
al_identity_transform(&transformation);
// al_scale_transform(&transformation, (double) al_get_display_width(display) / (double) GFX_X, (double) al_get_display_height(display) / (double) GFX_Y);
al_scale_transform(&transformation, (double) width / (double) GFX_X, (double) height / (double) GFX_Y);
al_set_target_bitmap(Graphics::getScreenBuffer().getData()->getBitmap());
al_use_transform(&transformation);
}
void EventManager::runAllegro5(Keyboard & keyboard, Joystick * joystick){
keyboard.poll();
ALLEGRO_EVENT event;
while (al_get_next_event(queue, &event)){
switch (event.type){
/*
case ALLEGRO_EVENT_KEY_DOWN: {
Global::debug(0) << "Key down " << event.keyboard.keycode << std::endl;
handleKeyDown(keyboard, event);
break;
}
*/
case ALLEGRO_EVENT_DISPLAY_RESIZE: {
handleResize(event);
break;
}
case ALLEGRO_EVENT_KEY_UP: {
handleKeyUp(keyboard, event);
break;
}
case ALLEGRO_EVENT_KEY_CHAR : {
// Global::debug(0) << "Key char " << event.keyboard.keycode << " unicode " << event.keyboard.unichar << std::endl;
handleKeyDown(keyboard, event);
break;
}
}
}
/*
if (joystick){
joystick->poll();
}
SDL_Event event;
while (SDL_PollEvent(&event) == 1){
switch (event.type){
case SDL_QUIT : {
dispatch(CloseWindow);
break;
}
case SDL_KEYDOWN : {
handleKeyDown(keyboard, event);
// dispatch(Key, event.key.keysym.sym);
break;
}
case SDL_KEYUP : {
handleKeyUp(keyboard, event);
break;
}
case SDL_JOYBUTTONDOWN: {
if (joystick != NULL){
handleJoystickButtonDown(joystick, event);
}
break;
}
case SDL_JOYHATMOTION : {
if (joystick != NULL){
handleJoystickHat(joystick, event);
}
break;
}
case SDL_JOYBUTTONUP: {
if (joystick != NULL){
handleJoystickButtonUp(joystick, event);
}
break;
}
case SDL_JOYAXISMOTION: {
if (joystick != NULL){
handleJoystickAxis(joystick, event);
}
break;
}
case SDL_VIDEORESIZE : {
int width = event.resize.w;
int height = event.resize.h;
/ * to keep the perspective correct
* 640/480 = 1.33333
* /
if (width > height){
height = (int)((double) width / 1.3333333333);
} else {
width = (int)((double) height * 1.3333333333);
}
dispatch(ResizeScreen, width, height);
break;
}
default : {
break;
}
}
}
*/
}
#endif
void EventManager::run(Keyboard & keyboard, Joystick * joystick){
#ifdef USE_SDL
runSDL(keyboard, joystick);
#elif USE_ALLEGRO
runAllegro(keyboard, joystick);
#elif USE_ALLEGRO5
runAllegro5(keyboard, joystick);
#endif
}
/* kill the program if the user requests */
void EventManager::waitForThread(WaitThread & thread){
// Keyboard dummy;
while (!thread.isRunning()){
try{
/* input manager will run the event manager */
InputManager::poll();
// run(dummy);
} catch (const ShutdownException & death){
thread.kill();
throw death;
}
Util::rest(10);
}
}
EventManager::~EventManager(){
#ifdef USE_ALLEGRO5
al_destroy_event_queue(queue);
#endif
}
void EventManager::enableKeyBuffer(){
bufferKeys = true;
}
void EventManager::disableKeyBuffer(){
bufferKeys = false;
}
void EventManager::dispatch(Event type, int arg1){
switch (type){
case Key : {
if (bufferKeys){
keys.push_back(KeyType(arg1));
}
break;
}
default : {
break;
}
}
}
void EventManager::dispatch(Event type, int arg1, int arg2){
switch (type){
case ResizeScreen : {
Global::debug(1) << "Resizing screen to " << arg1 << ", " << arg2 << std::endl;
if (Graphics::setGraphicsMode(0, arg1, arg2) == 0){
Configuration::setScreenWidth(arg1);
Configuration::setScreenHeight(arg2);
}
break;
}
default : break;
}
}
void EventManager::dispatch(Event type){
switch (type){
case CloseWindow : {
throw ShutdownException();
}
default : break;
}
}
class LoopDone: public std::exception {
public:
LoopDone(){
}
~LoopDone() throw () {
}
};
Logic::~Logic(){
}
Draw::Draw():
frames(0),
second_counter(Global::second_counter),
fps(0){
}
void Draw::drawFirst(const Graphics::Bitmap & screen){
}
Draw::~Draw(){
}
double Draw::getFps() const {
return fps;
}
void Draw::updateFrames(){
if (second_counter != Global::second_counter){
int difference = Global::second_counter - second_counter;
double alpha = 0.2;
/* unlikely, but just in case */
if (difference == 0){
difference = 1;
}
fps = (alpha * fps) + ((1 - alpha) * (double) frames / difference);
// fps[fps_index] = (double) frames / (double) difference;
// fps_index = (fps_index+1) % max_fps_index;
second_counter = Global::second_counter;
frames = 0;
}
frames += 1;
}
static void changeScreenMode(){
Configuration::setFullscreen(!Configuration::getFullscreen());
int gfx = (Configuration::getFullscreen() ? Global::FULLSCREEN : Global::WINDOWED);
Graphics::setGraphicsMode(gfx, Global::getScreenWidth(), Global::getScreenHeight());
}
static void checkFullscreen(){
InputMap<int> input;
input.set(Keyboard::Key_F11, 0, true, 5);
- std::vector<InputMap<int>::InputEvent> events = InputManager::getEvents(input);
+ std::vector<InputMap<int>::InputEvent> events = InputManager::getEvents(input, InputSource());
for (std::vector<InputMap<int>::InputEvent>::iterator it = events.begin(); it != events.end(); it++){
InputMap<int>::InputEvent event = *it;
if (!event.enabled){
continue;
}
if (event.out == 5){
changeScreenMode();
}
}
}
static void doStandardLoop(Logic & logic, Draw & draw){
const Graphics::Bitmap & screen = *Graphics::screenParameter.current();
draw.drawFirst(screen);
Global::speed_counter4 = 0;
double runCounter = 0;
try{
while (!logic.done()){
if (Global::speed_counter4 > 0){
// Global::debug(0) << "Speed counter " << Global::speed_counter4 << std::endl;
runCounter += logic.ticks(Global::speed_counter4);
Global::speed_counter4 = 0;
bool need_draw = false;
while (runCounter >= 1.0){
need_draw = true;
InputManager::poll();
checkFullscreen();
runCounter -= 1;
logic.run();
if (Global::shutdown()){
throw ShutdownException();
}
if (logic.done()){
/* quit the loop immediately */
throw LoopDone();
}
}
if (need_draw){
draw.updateFrames();
draw.draw(screen);
}
}
while (Global::speed_counter4 == 0){
/* if the fps is limited then don't keep redrawing */
if (Global::rateLimit){
rest(1);
} else {
draw.updateFrames();
draw.draw(screen);
}
}
}
} catch (const LoopDone & done){
}
}
void standardLoop(Logic & logic, Draw & draw){
/* if a screen already exists (because we have nested standardLoops) then
* leave this parameter alone, otherwise set a new parameter.
*/
/*
if (Parameter<Graphics::Bitmap*>::current() == NULL){
doStandardLoop(logic, draw);
} else {
doStandardLoop(logic, draw);
}
*/
doStandardLoop(logic, draw);
}
}
diff --git a/util/input/input-manager.h b/util/input/input-manager.h
index fd9de0cf..0a610177 100644
--- a/util/input/input-manager.h
+++ b/util/input/input-manager.h
@@ -1,291 +1,293 @@
#ifndef _paintown_input_manager
#define _paintown_input_manager
#include <vector>
#include <algorithm>
#include "input.h"
#include "input-map.h"
#include "util/funcs.h"
#include "util/events.h"
#include "keyboard.h"
#include "exceptions/exception.h"
class Configuration;
class Joystick;
+class InputSource;
template <class Output>
class InputHandler{
public:
InputHandler(){
}
virtual ~InputHandler(){
}
virtual void press(const Output & out, Keyboard::unicode_t unicode) = 0;
virtual void release(const Output & out, Keyboard::unicode_t unicode) = 0;
};
/* handles keyboard/joystick/whatever input during the game */
class InputManager{
public:
/* main has one instance of this and thats it.
* should the janitor have the reference instead?
*/
friend int paintown_main(int, char**);
friend int main(int, char **);
/* returns true if any input device is activated (keys pressed, joystick button */
static bool anyInput();
// static std::vector<Input::PaintownInput> getInput(const Configuration & configuration, const int facing);
static void poll();
/*
static void enableBufferInput();
static void disableBufferInput();
*/
static void waitForKeys(int key1, int key2);
static void waitForKeys(int key1);
static int readKey();
static void waitForClear();
/*
template <class X>
static void observeKeyboard(InputMap<X> & input){
manager->keyboard.addObserver(InputMap<X>::observeKey, &input);
}
template <class X>
static void unObserveKeyboard(InputMap<X> & input){
manager->keyboard.removeObserver(InputMap<X>::observeKey, &input);
}
*/
static std::vector<Keyboard::unicode_t> readText(){
return manager->keyboard.readText();
}
template <typename X>
static std::vector<Keyboard::unicode_t> readText(InputMap<X> & input, typename InputMap<X>::Output & output){
return manager->_readText(input, output);
}
template <typename X>
static typename InputMap<X>::Output getMap(InputMap<X> & input){
if (manager){
return manager->_getMap(input);
}
/* just crash hard.. who cares */
throw Exception::Base(__FILE__, __LINE__);
/* make the compiler happy about returning something */
return *(typename InputMap<X>::Output*)1;
}
template <typename X>
- static typename std::vector<typename InputMap<X>::InputEvent> getEvents(InputMap<X> & input){
- return manager->_getEvents(input);
+ static typename std::vector<typename InputMap<X>::InputEvent> getEvents(InputMap<X> & input, const InputSource & source){
+ return manager->_getEvents(input, source);
}
template <typename X>
- static void handleEvents(InputMap<X> & input, InputHandler<X> & handler){
- typename std::vector<typename InputMap<X>::InputEvent> events = getEvents(input);
+ static void handleEvents(InputMap<X> & input, const InputSource & source, InputHandler<X> & handler){
+ typename std::vector<typename InputMap<X>::InputEvent> events = getEvents(input, source);
for (typename std::vector<typename InputMap<X>::InputEvent>::iterator it = events.begin(); it != events.end(); it++){
const typename InputMap<X>::InputEvent & event = *it;
if (event.enabled){
handler.press(event.out, event.unicode);
} else {
handler.release(event.out, event.unicode);
}
}
}
template <typename X>
static bool pressed(InputMap<X> & input, X out){
if (manager){
return manager->_pressed(input, out);
}
return false;
}
/* wait for a key to be released
* really this waits for all inputs that would result in `out'
* being generated to stop.
*/
template <typename X>
static void waitForRelease(InputMap<X> & input, X out){
while (InputManager::pressed(input, out)){
Util::rest(1);
InputManager::poll();
}
}
template <typename X>
static void waitForPress(InputMap<X> & input, X out){
while (!InputManager::pressed(input, out)){
Util::rest(1);
InputManager::poll();
}
}
template <typename X>
static void captureInput(InputMap<X> & input){
manager->_captureInput(input);
}
template <typename X>
static void releaseInput(InputMap<X> & input){
manager->_releaseInput(input);
}
protected:
InputManager();
virtual ~InputManager();
virtual bool _anyInput();
virtual int _readKey();
// virtual std::vector<Input::PaintownInput> _getInput(const Configuration & configuration, const int facing);
template <typename X>
void _captureInput(InputMap<X> & input){
capture = (void*) &input;
}
template <typename X>
void _releaseInput(InputMap<X> & input){
if (capture == (void*) &input){
capture = 0;
}
}
template <typename X>
std::vector<Keyboard::unicode_t> _readText(InputMap<X> & input, typename InputMap<X>::Output & output){
std::vector<Keyboard::unicode_t> text;
std::vector<Keyboard::KeyData> all = keyboard.readData();
for (std::vector<Keyboard::KeyData>::iterator it = all.begin(); it != all.end(); it++){
const Keyboard::KeyData & data = *it;
KeyState<X> * state = input.getState(data.key);
if (state != NULL && output[state->out]){
text.push_back(data.unicode);
}
}
return text;
}
void removeDuplicates(std::vector<int> & storage){
std::vector<int> output;
int last = -1;
for (std::vector<int>::iterator it = storage.begin(); it != storage.end(); it++){
if (*it != last){
output.push_back(*it);
last = *it;
}
}
storage = output;
}
template <typename X>
- typename std::vector<typename InputMap<X>::InputEvent> _getEvents(InputMap<X> & input){
+ typename std::vector<typename InputMap<X>::InputEvent> _getEvents(InputMap<X> & input, const InputSource & source){
+ /* FIXME: get events from the source */
std::vector<typename InputMap<X>::InputEvent> events;
if (capture != NULL && capture != &input){
return events;
}
const std::vector<typename Keyboard::KeyData> & buffer = keyboard.getBufferedKeys();
for (std::vector<Keyboard::KeyData>::const_iterator it = buffer.begin(); it != buffer.end(); it++){
const Keyboard::KeyData & data = *it;
KeyState<X> * state = input.getState(data.key);
if (state != NULL){
events.push_back(typename InputMap<X>::InputEvent(state->out, data.unicode, data.enabled));
}
}
if (joystick){
const std::vector<typename Joystick::Event> & joystickEvents = joystick->getEvents();
for (std::vector<Joystick::Event>::const_iterator it = joystickEvents.begin(); it != joystickEvents.end(); it++){
Joystick::Event event = *it;
JoystickState<X> * state = input.getJoystickState(event.key);
if (state != NULL){
events.push_back(typename InputMap<X>::InputEvent(state->out, -1, event.enabled));
}
}
}
return events;
}
template <typename X>
typename InputMap<X>::Output _getMap(InputMap<X> & input){
typename InputMap<X>::Output output;
if (capture != 0 && capture != &input){
return output;
}
std::vector<int> all_keys;
keyboard.readKeys(all_keys);
keyboard.readBufferedKeys(all_keys);
// all_keys.insert(all_keys.end(), bufferedKeys.begin(), bufferedKeys.end());
// all_keys.insert(all_keys.end(), keyboard.currentKeys().begin(), keyboard.currentKeys.end());
std::sort(all_keys.begin(), all_keys.end());
removeDuplicates(all_keys);
// std::unique(all_keys.begin(), all_keys.end());
// bufferedKeys.clear();
input.read(all_keys, &output);
/*
if (joystick != NULL){
JoystickInput all_joystick = joystick->readAll();
input.read(all_joystick, &output);
}
*/
/* just bumps an internal counter */
input.update();
return output;
}
template <typename X>
bool _pressed(InputMap<X> & input, X result){
if (capture != 0 && capture != &input){
return false;
}
std::vector<int> all_keys;
keyboard.readKeys(all_keys);
// all_keys.insert(all_keys.end(), bufferedKeys.begin(), bufferedKeys.end());
std::sort(all_keys.begin(), all_keys.end());
removeDuplicates(all_keys);
// bufferedKeys.clear();
bool out = false;
out = input.pressed(all_keys, result);
/*
if (joystick != NULL){
JoystickInput all_joystick = joystick->readAll();
out |= input.pressed(all_joystick, result);
}
*/
return out;
}
virtual void _poll();
private:
static InputManager * manager;
void * capture;
Joystick * joystick;
Keyboard keyboard;
Util::EventManager eventManager;
// std::vector<int> bufferedKeys;
// bool bufferKeys;
};
#endif
diff --git a/util/input/input-source.cpp b/util/input/input-source.cpp
new file mode 100644
index 00000000..49290b9f
--- /dev/null
+++ b/util/input/input-source.cpp
@@ -0,0 +1,7 @@
+#include "input-source.h"
+
+InputSource::InputSource(){
+}
+
+InputSource::~InputSource(){
+}
diff --git a/util/input/input-source.h b/util/input/input-source.h
new file mode 100644
index 00000000..28b1bd3d
--- /dev/null
+++ b/util/input/input-source.h
@@ -0,0 +1,14 @@
+#ifndef paintown_input_source_h
+#define paintown_input_source_h
+
+/* this class should abstract over actual devices (keyboard, joystick)
+ * and return a list of events on request.
+ */
+
+class InputSource{
+public:
+ InputSource();
+ virtual ~InputSource();
+};
+
+#endif
diff --git a/util/input/text-input.cpp b/util/input/text-input.cpp
index 5ac3c9c4..1ce63743 100644
--- a/util/input/text-input.cpp
+++ b/util/input/text-input.cpp
@@ -1,210 +1,211 @@
#include "input-map.h"
#include "text-input.h"
#include "input-manager.h"
+#include "input-source.h"
#include "keyboard.h"
#include <string.h>
#include <sstream>
#include <string>
using namespace std;
static const int Shift = 198;
static const int Control = 199;
static const int Backspace = 200;
TextInput::TextInput(const string & start):
InputMap<unsigned char>(),
blockingKeys(false),
enabled(false),
handle(201){
const int delay = 100;
/*
set(Keyboard::Key_TILDE, delay * 2, false, Toggle);
set(Keyboard::Key_ESC, delay, false, Esc);
set(Keyboard::Key_ENTER, 0, false, Enter);
*/
// set(Keyboard::Key_LCONTROL, 0, false, Control);
set(Keyboard::Key_BACKSPACE, delay, false, Backspace);
/*
set(Keyboard::Key_LSHIFT, 0, false, Shift);
set(Keyboard::Key_RSHIFT, 0, false, Shift);
*/
text.str(start);
text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
text.clear();
}
int TextInput::nextHandle(){
int i = handle;
handle += 1;
return i;
}
void TextInput::addBlockingHandle(int key, callback function, void * data){
int handle = nextHandle();
set(key, 1, true, handle);
callbacks[handle] = Callback(function, data);
}
void TextInput::addHandle(int key, int delay, callback function, void * data){
int handle = nextHandle();
set(key, delay, false, handle);
callbacks[handle] = Callback(function, data);
}
bool TextInput::doInput(){
bool modified = false;
/* TODO: ensure these codes are consistent across platforms. So far
* they seem to work in windows xp and linux (ubuntu)
*/
const Keyboard::unicode_t control_u = 21;
const Keyboard::unicode_t control_w = 23;
if (enabled){
- vector<InputEvent> events = InputManager::getEvents(*this);
+ vector<InputEvent> events = InputManager::getEvents(*this, InputSource());
/* the order of reading input is arbitrary right now. I'm not
* sure it matters what order things are done in, but probably
* a few corner cases exist. When they come up please document them.
*/
for (vector<InputEvent>::iterator it = events.begin(); it != events.end(); it++){
InputEvent event = *it;
if (event.enabled){
if (event.out == Backspace){
backspace();
modified = true;
}
if (callbacks.find(event.out) != callbacks.end()){
Callback & callback = callbacks[event.out];
callback.function(callback.data);
}
if (event.unicode == control_u){
clearInput();
modified = true;
}
if (event.unicode == control_w){
deleteLastWord();
modified = true;
}
/* FIXME: whats the maximum unicode value? */
if (event.unicode >= 32 && event.unicode < 0xffffff){
this->text << (unsigned char) event.unicode;
modified = true;
}
}
}
}
return modified;
}
void TextInput::enable(){
InputManager::captureInput(*this);
enabled = true;
Keyboard::pushRepeatState(true);
}
void TextInput::disable(){
InputManager::releaseInput(*this);
enabled = false;
Keyboard::popRepeatState();
}
string TextInput::getText() const {
return text.str();
}
/*
void TextInput::clear(){
text.str("");
text.clear();
}
*/
void TextInput::setText(const std::string & text){
this->text.str(text);
this->text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
this->text.clear();
}
void TextInput::clearInput(){
text.str(string());
text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
text.clear();
}
void TextInput::backspace(){
string now = text.str();
now = now.substr(0, now.size()-1);
text.str(now);
text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
text.clear();
}
void TextInput::deleteLastWord(){
string now = text.str();
// Global::debug(0) << "Delete last word '" << now << "'" << endl;
if (now.size() > 0){
if (now.at(now.size() - 1) != ' '){
int here = now.size() - 1;
while (here > 0 && now.at(here) != ' '){
here -= 1;
}
if (now.at(here) == ' '){
here += 1;
}
now.erase(here);
} else {
int here = now.size() - 1;
while (here > 0 && now.at(here) == ' '){
here -= 1;
}
if (here > 0){
while (here > 0 && now.at(here) != ' '){
here -= 1;
}
if (now.at(here) == ' '){
here += 1;
}
}
now.erase(here);
}
text.str(now);
text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
text.clear();
}
/*
size_t get = now.rfind(" ");
if (get != string::npos){
Global::debug(0) << "get " << get << " size " << now.size() << endl;
if (get == now.size() - 1){
get = now.find_last_not_of(' ');
get = now.rfind(' ', get);
if (get != string::npos){
get = 0;
}
now.erase(get + 1);
} else {
now = now.substr(0, get + 1);
}
text.str(now);
text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
text.clear();
} else {
clearInput();
}
*/
}
TextInput::~TextInput(){
disable();
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jun 11, 10:01 AM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68256
Default Alt Text
(31 KB)
Attached To
Mode
R75 R-Tech1
Attached
Detach File
Event Timeline