1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-11-09 15:39:55 +00:00

correct text handling in SDL2

This commit is contained in:
Zeno Rogue 2024-06-28 12:20:26 +02:00
parent 920ed4bb86
commit 8a45b7e1e7
5 changed files with 74 additions and 11 deletions

View File

@ -1520,6 +1520,7 @@ EX void show() {
dialog::addBack(); dialog::addBack();
dialog::display(); dialog::display();
se.handle_textinput();
keyhandler = [] (int sym, int uni) { keyhandler = [] (int sym, int uni) {
if(symbol_editing && sym == SDLK_RETURN) sym = uni = '/'; if(symbol_editing && sym == SDLK_RETURN) sym = uni = '/';
dialog::handleNavigation(sym, uni); dialog::handleNavigation(sym, uni);

View File

@ -89,7 +89,7 @@ EX unsigned backcolor = 0;
EX unsigned bordcolor = 0; EX unsigned bordcolor = 0;
EX unsigned forecolor = 0xFFFFFF; EX unsigned forecolor = 0xFFFFFF;
int utfsize(char c) { EX int utfsize(char c) {
unsigned char cu = c; unsigned char cu = c;
if(cu < 128) return 1; if(cu < 128) return 1;
if(cu < 224) return 2; if(cu < 224) return 2;
@ -97,6 +97,13 @@ int utfsize(char c) {
return 4; return 4;
} }
EX int utfsize_before(const string& s, int pos) {
if(!pos) return 0;
int npos = pos - 1;
while(npos && ((unsigned char)s[npos]) >= 128 && ((unsigned char)s[npos]) < 192) npos--;
return pos - npos;
}
EX int get_sightrange() { return getDistLimit() + sightrange_bonus; } EX int get_sightrange() { return getDistLimit() + sightrange_bonus; }
EX int get_sightrange_ambush() { EX int get_sightrange_ambush() {

View File

@ -32,6 +32,19 @@ EX int slider_x;
EX function <void(int sym, int uni)> keyhandler = [] (int sym, int uni) {}; EX function <void(int sym, int uni)> keyhandler = [] (int sym, int uni) {};
EX function <bool(SDL_Event &ev)> joyhandler = [] (SDL_Event &ev) {return false;}; EX function <bool(SDL_Event &ev)> joyhandler = [] (SDL_Event &ev) {return false;};
#if CAP_SDL2
EX void ignore_text(const SDL_TextInputEvent&) {}
EX function <void(const SDL_TextInputEvent&)> texthandler = ignore_text;
#endif
EX void reset_handlers() {
keyhandler = [] (int sym, int uni) {};
joyhandler = [] (SDL_Event &ev) {return false;};
#if CAP_SDL2
texthandler = ignore_text;
#endif
}
#if HDR #if HDR
// what part of the compass does 'skip turn' // what part of the compass does 'skip turn'
static constexpr auto SKIPFAC = .4; static constexpr auto SKIPFAC = .4;
@ -1162,6 +1175,12 @@ EX void handle_event(SDL_Event& ev) {
} }
} }
#if CAP_SDL2
if(ev.type == SDL_TEXTINPUT) {
texthandler(ev.text);
}
#endif
dialog::handleZooming(ev); dialog::handleZooming(ev);
if(sym == SDLK_F1 && normal && playermoved) if(sym == SDLK_F1 && normal && playermoved)
@ -1318,6 +1337,7 @@ EX void handle_event(SDL_Event& ev) {
if(sym || uni) { if(sym || uni) {
if(need_refresh) { if(need_refresh) {
just_refreshing = true; just_refreshing = true;
reset_handlers();
screens.back()(); screens.back()();
just_refreshing = false; just_refreshing = false;
} }

View File

@ -1444,15 +1444,25 @@ EX namespace dialog {
display(); display();
#if CAP_SDL2
texthandler = [&ne] (const SDL_TextInputEvent& ev) {
if(key_actions.count(ev.text[0])) return;
ne.s += ev.text;
ne.apply_edit();
};
#endif
keyhandler = [this, &ne] (int sym, int uni) { keyhandler = [this, &ne] (int sym, int uni) {
handleNavigation(sym, uni); handleNavigation(sym, uni);
if((uni >= '0' && uni <= '9') || among(uni, '.', '+', '-', '*', '/', '^', '(', ')', ',', '|', 3) || (uni >= 'a' && uni <= 'z')) { if((uni >= '0' && uni <= '9') || among(uni, '.', '+', '-', '*', '/', '^', '(', ')', ',', '|', 3) || (uni >= 'a' && uni <= 'z')) {
#if !CAP_SDL2
if(uni == 3) ne.s += "pi"; if(uni == 3) ne.s += "pi";
else ne.s += uni; else ne.s += uni;
apply_edit(); apply_edit();
#endif
} }
else if(uni == '\b' || uni == '\t') { else if(uni == '\b' || uni == '\t') {
ne.s = ne.s. substr(0, isize(ne.s)-1); ne.s = ne.s. substr(0, isize(ne.s)-utfsize_before(ne.s, isize(ne.s)));
sscanf(ne.s.c_str(), LDF, ne.editwhat); sscanf(ne.s.c_str(), LDF, ne.editwhat);
apply_edit(); apply_edit();
} }
@ -1770,6 +1780,13 @@ EX namespace dialog {
dialog::addItem("cancel", SDLK_ESCAPE); dialog::addItem("cancel", SDLK_ESCAPE);
dialog::display(); dialog::display();
#if CAP_SDL2
texthandler = [this] (const SDL_TextInputEvent& ev) {
int i = isize(*cfileptr) - (editext?0:4);
cfileptr->insert(i, ev.text);
};
#endif
keyhandler = handleKeyFile; keyhandler = handleKeyFile;
} }
@ -1786,15 +1803,18 @@ EX namespace dialog {
if(ac) popScreen(); if(ac) popScreen();
} }
else if(sym == SDLK_BACKSPACE && i) { else if(sym == SDLK_BACKSPACE && i) {
s.erase(i-1, 1); int len = utfsize_before(s, i);
s.erase(i-len, len);
highlight_text = "//missing"; highlight_text = "//missing";
list_skip = 0; list_skip = 0;
} }
#if !CAP_SDL2
else if(uni >= 32 && uni < 127) { else if(uni >= 32 && uni < 127) {
s.insert(i, s0 + char(uni)); s.insert(i, s0 + char(uni));
highlight_text = "//missing"; highlight_text = "//missing";
list_skip = 0; list_skip = 0;
} }
#endif
return; return;
} }
@ -1880,6 +1900,7 @@ EX namespace dialog {
void draw() override; void draw() override;
void start_editing(string& s); void start_editing(string& s);
bool handle_edit_string(int sym, int uni, function<string(int, int)> checker = editchecker); bool handle_edit_string(int sym, int uni, function<string(int, int)> checker = editchecker);
void handle_textinput();
}; };
#endif #endif
@ -1899,25 +1920,40 @@ EX namespace dialog {
bool string_dialog::handle_edit_string(int sym, int uni, function<string(int, int)> checker) { bool string_dialog::handle_edit_string(int sym, int uni, function<string(int, int)> checker) {
auto& es = *edited_string; auto& es = *edited_string;
string u2; string u2;
if(DKEY == SDLK_LEFT) editpos--; if(DKEY == SDLK_LEFT) editpos -= utfsize_before(es, editpos);
else if(DKEY == SDLK_RIGHT) editpos++; else if(DKEY == SDLK_RIGHT) editpos += utfsize(es[editpos]);
else if(uni == 8) { else if(uni == 8) {
if(editpos == 0) return true; if(editpos == 0) return true;
es.replace(editpos-1, 1, ""); int len = utfsize_before(es, editpos);
editpos--; es.replace(editpos-len, len, "");
editpos -= len;
if(reaction) reaction(); if(reaction) reaction();
} }
else if((u2 = checker(sym, uni)) != "") { else if((u2 = checker(sym, uni)) != "") {
#if !CAP_SDL2
for(char c: u2) { for(char c: u2) {
es.insert(editpos, 1, c); es.insert(editpos, 1, c);
editpos ++; editpos ++;
} }
#endif
if(reaction) reaction(); if(reaction) reaction();
} }
else return false; else return false;
return true; return true;
} }
void string_dialog::handle_textinput() {
#if CAP_SDL2
texthandler = [this] (const SDL_TextInputEvent& ev) {
auto& es = *edited_string;
string txt = ev.text;
es.insert(editpos, txt);
editpos += isize(txt);
if(reaction) reaction();
};
#endif
}
void string_dialog::draw() { void string_dialog::draw() {
cmode = sm::NUMBER | dialogflags; cmode = sm::NUMBER | dialogflags;
gamescreen(); gamescreen();
@ -1942,6 +1978,8 @@ EX namespace dialog {
if(handle_edit_string(sym, uni)) ; if(handle_edit_string(sym, uni)) ;
else if(doexiton(sym, uni)) popfinal(); else if(doexiton(sym, uni)) popfinal();
}; };
handle_textinput();
} }
EX void edit_string(string& s, string title, string help) { EX void edit_string(string& s, string title, string help) {

View File

@ -5925,10 +5925,7 @@ EX void drawscreen() {
mouseovers = " "; mouseovers = " ";
cmode = 0; cmode = 0;
keyhandler = [] (int sym, int uni) {}; reset_handlers();
#if CAP_SDL
joyhandler = [] (SDL_Event& ev) { return false; };
#endif
if(!isize(screens)) pushScreen(normalscreen); if(!isize(screens)) pushScreen(normalscreen);
screens.back()(); screens.back()();