16 #define GETTEXT_DOMAIN "wesnoth-lib"
28 #if defined(__ANDROID__) || defined(__IPHONEOS__)
32 #include <SDL3/SDL_timer.h>
35 #define WRN_DP LOG_STREAM(warn, log_display)
36 #define DBG_G LOG_STREAM(debug, lg::general())
40 textbox::textbox(
int width,
const std::string& text,
bool editable, std::size_t max_size,
int font_size,
double alpha,
double alpha_focus,
const bool auto_join)
41 :
scrollarea(auto_join), max_size_(max_size), font_size_(font_size), text_(
unicode_cast<std::u32string>(text)),
42 cursor_(text_.
size()), selstart_(-1), selend_(-1),
43 grabmouse_(false), text_pos_(0), editable_(editable),
44 show_cursor_(true), show_cursor_at_(0), text_image_(nullptr),
45 wrap_(false), line_height_(0), yscroll_(0), alpha_(alpha),
46 alpha_focus_(alpha_focus),
79 const std::string &ret = unicode_cast<std::string>(
text_);
86 text_ = unicode_cast<std::u32string>(
text);
108 const std::u32string& wtext = unicode_cast<std::u32string>(
text);
109 text_.insert(
text_.end(), wtext.begin(), wtext.end());
138 if (selstart < 0 || selend < 0 || std::size_t(selstart) >
text_.size() ||
139 std::size_t(selend) >
text_.size()) {
140 WRN_DP <<
"out-of-boundary selection";
153 if (cursor_pos < 0 || std::size_t(cursor_pos) >
text_.size()) {
154 WRN_DP <<
"out-of-boundary selection";
215 while(starty <= endy) {
216 const std::size_t right = starty == endy ? endx :
text_image_.
w();
217 if(right <= std::size_t(startx)) {
311 std::string visible_string;
312 std::u32string wrapped_text;
314 std::u32string::const_iterator backup_itor =
text.end();
316 std::u32string::const_iterator itor =
text.begin();
317 while(itor !=
text.end()) {
319 if(
char(*itor) ==
' ') {
322 visible_string.append(unicode_cast<std::string>(*itor));
324 if(
char(*itor) ==
'\n') {
325 backup_itor =
text.end();
332 if(backup_itor !=
text.end()) {
333 int backup = itor - backup_itor;
334 itor = backup_itor + 1;
338 wrapped_text.erase(wrapped_text.end()-backup, wrapped_text.end());
341 if (visible_string == std::string(
"").append(unicode_cast<std::string>(*itor))) {
345 backup_itor =
text.end();
346 wrapped_text.push_back(char32_t(
'\n'));
351 wrapped_text.push_back(*itor);
358 const std::string
s = unicode_cast<std::string>(wrapped_text);
404 const unsigned int copypaste_modifier =
406 SDL_KMOD_LGUI | SDL_KMOD_RGUI
418 if(event ==
nullptr) {
423 if(event->type == SDL_EVENT_KEY_DOWN) {
424 SDL_Keycode key =
event->key.key;
449 bool changed =
false;
450 std::string str =
event.text.text;
451 std::u32string
s = unicode_cast<std::u32string>(str);
453 DBG_G <<
"Char: " << str;
473 bool changed =
false;
475 const SDL_Keymod modifiers = SDL_GetModState();
477 const int c =
reinterpret_cast<const SDL_KeyboardEvent&
>(event).key;
478 const int old_cursor =
cursor_;
486 if(
c == SDLK_RIGHT &&
cursor_ <
static_cast<int>(
text_.size()))
490 if(
c == SDLK_END || (
c == SDLK_E && (modifiers & SDL_KMOD_CTRL)))
493 if(
c == SDLK_HOME || (
c == SDLK_A && (modifiers & SDL_KMOD_CTRL)))
496 if((old_cursor !=
cursor_) && (modifiers & SDL_KMOD_SHIFT)) {
501 }
else if(
c == SDLK_LEFT ||
c == SDLK_RIGHT ||
c == SDLK_END ||
c == SDLK_HOME) {
506 if(
c == SDLK_BACKSPACE) {
516 if(
c == SDLK_U && (modifiers & SDL_KMOD_CTRL)) {
522 if(
c == SDLK_DELETE && !
text_.empty()) {
532 }
else if(
c == SDLK_BACKSPACE ||
c == SDLK_DELETE || (
c == SDLK_U && (modifiers & SDL_KMOD_CTRL))) {
538 if(!(
c == SDLK_UP ||
c == SDLK_DOWN ||
c == SDLK_LEFT ||
c == SDLK_RIGHT ||
539 c == SDLK_DELETE ||
c == SDLK_BACKSPACE ||
c == SDLK_END ||
c == SDLK_HOME ||
540 c == SDLK_PAGEUP ||
c == SDLK_PAGEDOWN)) {
541 if((event.key.mod & copypaste_modifier)
564 std::u32string
s = unicode_cast<std::u32string>(str);
582 const std::size_t beg = std::min<std::size_t>(std::size_t(
selstart_),std::size_t(
selend_));
583 const std::size_t end = std::max<std::size_t>(std::size_t(
selstart_),std::size_t(
selend_));
585 std::u32string ws(
text_.begin() + beg,
text_.begin() + end);
586 std::string
s = unicode_cast<std::string>(ws);
596 const std::size_t beg = std::min<std::size_t>(std::size_t(
selstart_),std::size_t(
selend_));
597 const std::size_t end = std::max<std::size_t>(std::size_t(
selstart_),std::size_t(
selend_));
599 std::u32string ws(
text_.begin() + beg,
text_.begin() + end);
600 std::string
s = unicode_cast<std::string>(ws);
630 bool changed =
false;
633 const int old_selend =
selend_;
638 WRN_DP <<
"out-of-boundary selection";
642 float mousex, mousey;
644 if(!(mousebuttons & SDL_BUTTON_MASK(1))) {
650 const bool mouse_inside =
loc.contains(mousex, mousey);
652 #if defined(__ANDROID__) || defined(__IPHONEOS__)
669 bool clicked_inside = !
mouse_locked() && (
event.type == SDL_EVENT_MOUSE_BUTTON_DOWN
670 && (mousebuttons & SDL_BUTTON_MASK(1))
677 const int y = mousey -
loc.
y;
681 for(
unsigned int i = 1;
i <
char_x_.size(); ++
i) {
701 if(!
grabmouse_ && (mousebuttons & SDL_BUTTON_MASK(1))) {
704 }
else if (! (mousebuttons & SDL_BUTTON_MASK(1))) {
713 if(!was_forwarded &&
focus(&event) ==
false) {
714 if (!
mouse_locked() && event.type == SDL_EVENT_MOUSE_MOTION &&
loc.contains(mousex, mousey))
720 const int old_cursor =
cursor_;
722 if (event.type == SDL_EVENT_TEXT_INPUT &&
listening_) {
724 }
else if (event.type == SDL_EVENT_KEY_DOWN) {
bool handle_text_input(const SDL_Event &event)
textbox(int width, const std::string &text="", bool editable=true, std::size_t max_size=256, int font_size=font::SIZE_PLUS, double alpha=0.4, double alpha_focus=0.2, const bool auto_join=true)
virtual void set_inner_location(const rect &) override
virtual void scroll(unsigned int pos) override
const std::string text() const
void set_cursor_pos(const int cursor_pos)
void set_selection(const int selstart, const int selend)
void pass_event_to_target(const SDL_Event &event)
void set_text(const std::string &text, const color_t &color=font::NORMAL_COLOR)
virtual void draw_contents() override
void draw_cursor(int pos) const
void set_font_size(int fs)
void set_editable(bool value)
void handle_event(const SDL_Event &event, bool was_forwarded)
bool handle_key_down(const SDL_Event &event)
std::vector< int > char_x_
bool requires_event_focus(const SDL_Event *event=nullptr) const override
virtual void layout() override
Called by draw_manager to validate layout.
void set_edit_target(textbox *target)
void append_text(const std::string &text, bool auto_scroll=false, const color_t &color=font::NORMAL_COLOR)
void update_text_cache(bool reset=false, const color_t &color=font::NORMAL_COLOR)
std::vector< int > char_y_
virtual void update_location(const rect &rect) override
texture add_text_line(const std::u32string &text, const color_t &color=font::NORMAL_COLOR)
virtual void handle_text_changed(const std::u32string &)
Wrapper class to encapsulate creation and management of an SDL_Texture.
int w() const
The draw-space width of the texture, in pixels.
void reset()
Releases ownership of the managed texture and resets the ptr to null.
void set_src(const rect &r)
Set the source region of the texture used for drawing operations.
int h() const
The draw-space height of the texture, in pixels.
void set_alpha_mod(uint8_t alpha)
Alpha modifier.
void clear_src()
Clear the source region.
Drawing functions, for drawing things on the screen.
static std::string _(const char *str)
Standard logging facilities (interface).
void set(CURSOR_TYPE type)
Use the default parameter to reset cursors.
void copy_to_clipboard(const std::string &text)
Copies text to the clipboard.
std::string copy_from_clipboard()
Copies text from the clipboard.
clip_setter reduce_clip(const ::rect &clip)
Set the clipping area to the intersection of the current clipping area and the given rectangle.
void fill(const ::rect &rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
Fill an area with the given colour.
void blit(const texture &tex, const ::rect &dst)
Draws a texture, or part of a texture, at the given location.
EXIT_STATUS start(bool clear_id, const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
void focus_handler(const sdl_handler *ptr)
int get_max_height(unsigned size, font::family_class fclass, pango_text::FONT_STYLE style)
Returns the maximum glyph height of a font, in pixels.
std::pair< int, int > pango_line_size(const std::string &line, int font_size, font::pango_text::FONT_STYLE font_style)
Determine the width and height of a line of text given a certain font size.
texture pango_render_text(const std::string &text, int size, const color_t &color, font::pango_text::FONT_STYLE style, bool use_markup, int max_width)
Returns a SDL texture containing the rendered text.
uint32_t get_mouse_state(float *x, float *y)
A wrapper for SDL_GetMouseState that gives coordinates in draw space.
std::size_t size(std::string_view str)
Length in characters of a UTF-8 string.
auto * find_if(Container &container, const Predicate &predicate)
Convenience wrapper for using find_if on a container without needing to comare to end()
bool isnewline(const char c)
SDL_Window * get_window()
std::string::const_iterator iterator
Contains the SDL_Rect helper code.
Transitional API for porting SDL_ttf-based code to Pango.
rect src
Non-transparent portion of the surface to compose.
The basic class for representing 8-bit RGB or RGBA colour values.
An abstract description of a rectangle with integer coordinates.
static map_location::direction s
static lg::log_domain log_display("display")
ucs4_convert_impl::enableif< TD, typename TS::value_type >::type unicode_cast(const TS &source)