16 #define GETTEXT_DOMAIN "wesnoth-lib" 30 #define WRN_DP LOG_STREAM(warn, log_display) 31 #define DBG_G LOG_STREAM(debug, lg::general()) 35 textbox::textbox(
CVideo &video,
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)
37 cursor_(text_.
size()), selstart_(-1), selend_(-1),
38 grabmouse_(false), text_pos_(0), editable_(editable),
39 show_cursor_(true), show_cursor_at_(0), text_image_(nullptr),
40 wrap_(false), line_height_(0), yscroll_(0), alpha_(alpha),
41 alpha_focus_(alpha_focus),
113 SDL_SetSurfaceBlendMode(
text_image_, SDL_BLENDMODE_NONE);
115 SDL_SetSurfaceBlendMode(
text_image_, SDL_BLENDMODE_BLEND);
123 SDL_SetSurfaceBlendMode(new_text, SDL_BLENDMODE_NONE);
124 sdl_blit(new_text,
nullptr,new_surface,&target);
127 text_.insert(
text_.end(), wtext.begin(), wtext.end());
153 if (selstart < 0 || selend < 0 || std::size_t(selstart) >
text_.size() ||
154 std::size_t(selend) >
text_.size()) {
155 WRN_DP <<
"out-of-boundary selection" << std::endl;
168 if (cursor_pos < 0 || std::size_t(cursor_pos) >
text_.size()) {
169 WRN_DP <<
"out-of-boundary selection" << std::endl;
211 src.w = std::min<std::size_t>(loc.w,
text_image_->w);
212 src.h = std::min<std::size_t>(loc.h,
text_image_->h);
227 while(starty <= endy) {
228 const std::size_t right = starty == endy ? endx :
text_image_->w;
229 if(right <= std::size_t(startx)) {
234 , loc.y + starty - src.y
319 std::string visible_string;
320 std::u32string wrapped_text;
322 std::u32string::const_iterator backup_itor = text.end();
324 std::u32string::const_iterator itor = text.begin();
325 while(itor != text.end()) {
327 if(
char(*itor) ==
' ') {
330 visible_string.append(unicode_cast<std::string>(*itor));
332 if(
char(*itor) ==
'\n') {
333 backup_itor = text.end();
340 if(backup_itor != text.end()) {
341 int backup = itor - backup_itor;
342 itor = backup_itor + 1;
346 wrapped_text.erase(wrapped_text.end()-backup, wrapped_text.end());
349 if (visible_string == std::string(
"").append(unicode_cast<std::string>(*itor))) {
353 backup_itor = text.end();
354 wrapped_text.push_back(char32_t(
'\n'));
359 wrapped_text.push_back(*itor);
366 const std::string
s =
unicode_cast<std::string>(wrapped_text);
414 const unsigned int copypaste_modifier =
416 KMOD_LGUI | KMOD_RGUI
428 if(event ==
nullptr) {
433 if(event->type == SDL_KEYDOWN) {
434 SDL_Keycode key =
event->key.keysym.sym;
459 bool changed =
false;
460 std::string str =
event.text.text;
463 DBG_G <<
"Char: " << str <<
"\n";
483 bool changed =
false;
485 const SDL_Keysym& key =
reinterpret_cast<const SDL_KeyboardEvent&
>(event).keysym;
486 const SDL_Keymod modifiers = SDL_GetModState();
488 const int c = key.sym;
489 const int old_cursor =
cursor_;
494 if(c == SDLK_LEFT &&
cursor_ > 0)
497 if(c == SDLK_RIGHT &&
cursor_ < static_cast<int>(
text_.size()))
501 if(c == SDLK_END || (c == SDLK_e && (modifiers & KMOD_CTRL)))
504 if(c == SDLK_HOME || (c == SDLK_a && (modifiers & KMOD_CTRL)))
507 if((old_cursor !=
cursor_) && (modifiers & KMOD_SHIFT)) {
512 }
else if(c == SDLK_LEFT || c == SDLK_RIGHT || c == SDLK_END || c == SDLK_HOME) {
517 if(c == SDLK_BACKSPACE) {
527 if(c == SDLK_u && (modifiers & KMOD_CTRL)) {
533 if(c == SDLK_DELETE && !
text_.empty()) {
543 }
else if(c == SDLK_BACKSPACE || c == SDLK_DELETE || (c == SDLK_u && (modifiers & KMOD_CTRL))) {
549 if(!(c == SDLK_UP || c == SDLK_DOWN || c == SDLK_LEFT || c == SDLK_RIGHT ||
550 c == SDLK_DELETE || c == SDLK_BACKSPACE || c == SDLK_END || c == SDLK_HOME ||
551 c == SDLK_PAGEUP || c == SDLK_PAGEDOWN)) {
552 if((event.key.keysym.mod & copypaste_modifier)
555 && !(event.key.keysym.mod & KMOD_ALT)
593 const std::size_t beg = std::min<std::size_t>(std::size_t(
selstart_),std::size_t(
selend_));
594 const std::size_t end = std::max<std::size_t>(std::size_t(
selstart_),std::size_t(
selend_));
596 std::u32string ws(
text_.begin() + beg,
text_.begin() + end);
610 std::u32string ws(
text_.begin() + beg,
text_.begin() + end);
641 bool changed =
false;
644 const int old_selend =
selend_;
649 WRN_DP <<
"out-of-boundary selection" << std::endl;
655 if(!(mousebuttons & SDL_BUTTON(1))) {
673 bool clicked_inside = !
mouse_locked() && (
event.type == SDL_MOUSEBUTTONDOWN
674 && (mousebuttons & SDL_BUTTON(1))
681 const int y = mousey - loc.y;
685 for(
unsigned int i = 1;
i <
char_x_.size(); ++
i) {
694 distance = std::abs(x -
char_x_[i]);
705 if(!
grabmouse_ && (mousebuttons & SDL_BUTTON(1))) {
708 }
else if (! (mousebuttons & SDL_BUTTON(1))) {
717 if(!was_forwarded &&
focus(&event) ==
false) {
724 const int old_cursor =
cursor_;
726 if (event.type == SDL_TEXTINPUT &&
listening_) {
729 if (event.type == SDL_KEYDOWN) {
733 if(event.type != SDL_KEYDOWN || (!was_forwarded &&
focus(&event) !=
true)) {
void sdl_blit(const surface &src, const SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
SDL_Surface * get() const
std::vector< int > char_x_
virtual void update_location(const SDL_Rect &rect)
void set(CURSOR_TYPE type)
Use the default parameter to reset cursors.
void set_edit_target(textbox *target)
textbox(CVideo &video, 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)
std::string copy_from_clipboard(const bool)
Copies text from the clipboard.
const std::string text() const
void pass_event_to_target(const SDL_Event &event)
void draw_cursor(int pos) const
ucs4_convert_impl::enableif< TD, typename TS::value_type >::type unicode_cast(const TS &source)
clip_setter set_clip(const SDL_Rect &clip)
Set the clipping area.
virtual void draw_contents()
std::vector< int > char_y_
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.
SDL_Rect draw_area() const
Returns the size and location of the current drawing area in pixels.
bool requires_event_focus(const SDL_Event *event=nullptr) const
void set_cursor_pos(const int cursor_pos)
void append_text(const std::string &text, bool auto_scroll=false, const color_t &color=font::NORMAL_COLOR)
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
void focus_handler(const sdl_handler *ptr)
void blit_surface(const surface &surf, SDL_Rect *dst)
Draws a surface at the given location.
EXIT_STATUS start(const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
bool handle_text_input(const SDL_Event &event)
void set_editable(bool value)
bool handle_key_down(const SDL_Event &event)
void update_text_cache(bool reset=false, const color_t &color=font::NORMAL_COLOR)
void set_font_size(int fs)
static lg::log_domain log_display("display")
bool point_in_rect(int x, int y, const SDL_Rect &rect)
Tests whether a point is inside a rectangle.
void handle_event(const SDL_Event &event, bool was_forwarded)
void set_selection(const int selstart, const int selend)
surface add_text_line(const std::u32string &text, const color_t &color=font::NORMAL_COLOR)
static map_location::DIRECTION s
virtual void scroll(unsigned int pos)
bool isnewline(const char c)
void set_text(const std::string &text, const color_t &color=font::NORMAL_COLOR)
SDL_Rect create_rect(const int x, const int y, const int w, const int h)
Creates an SDL_Rect with the given dimensions.
void copy_to_clipboard(const std::string &text, const bool)
Copies text to the clipboard.
Contains the SDL_Rect helper code.
uint32_t get_mouse_state(int *x, int *y)
A wrapper for SDL_GetMouseState that gives coordinates in draw space.
void fill_rectangle(const SDL_Rect &rect, const color_t &color)
Draws a filled rectangle.
Standard logging facilities (interface).
surface 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 surface containing the rendered text.
void adjust_surface_alpha(surface &surf, int32_t amount)
constexpr int32_t floating_to_fixed_point(double n)
Converts a double to a fixed point.
Transitional API for porting SDL_ttf-based code to Pango.
std::string::const_iterator iterator
virtual void set_inner_location(const SDL_Rect &)
virtual void handle_text_changed(const std::u32string &)
int pango_line_width(const std::string &line, int font_size, font::pango_text::FONT_STYLE font_style=font::pango_text::STYLE_NORMAL)
Determine the width of a line of text given a certain font size.