The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
textbox.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #define GETTEXT_DOMAIN "wesnoth-lib"
16 
17 #include "global.hpp"
18 
19 #include "widgets/textbox.hpp"
20 #include "desktop/clipboard.hpp"
21 #include "log.hpp"
22 #include "sdl/alpha.hpp"
23 #include "sdl/rect.hpp"
25 #include "video.hpp"
26 
27 static lg::log_domain log_display("display");
28 #define WRN_DP LOG_STREAM(warn, log_display)
29 #define DBG_G LOG_STREAM(debug, lg::general())
30 
31 namespace gui {
32 
33 textbox::textbox(CVideo &video, int width, const std::string& text, bool editable, size_t max_size, int font_size, double alpha, double alpha_focus, const bool auto_join)
34  : scrollarea(video, auto_join), max_size_(max_size), font_size_(font_size), text_(unicode_cast<ucs4::string>(text)),
35  cursor_(text_.size()), selstart_(-1), selend_(-1),
36  grabmouse_(false), text_pos_(0), editable_(editable),
37  show_cursor_(true), show_cursor_at_(0), text_image_(nullptr),
38  wrap_(false), line_height_(0), yscroll_(0), alpha_(alpha),
39  alpha_focus_(alpha_focus),
40  edit_target_(nullptr)
41  ,listening_(false)
42 {
43  // static const SDL_Rect area = d.screen_area();
44  // const int height = font::draw_text(nullptr,area,font_size,font::NORMAL_COLOR,"ABCD",0,0).h;
47  update_text_cache(true);
48 }
49 
51 {
52 }
53 
54 void textbox::update_location(SDL_Rect const &rect)
55 {
57  update_text_cache(true);
58  set_dirty(true);
59 }
60 
61 void textbox::set_inner_location(SDL_Rect const &rect)
62 {
63  bg_register(rect);
64  if (text_image_.null()) return;
65  text_pos_ = 0;
66  update_text_cache(false);
67 }
68 
70 {
72  return ret;
73 }
74 
75 // set_text does not respect max_size_
76 void textbox::set_text(const std::string& text, const SDL_Color& color)
77 {
79  cursor_ = text_.size();
80  text_pos_ = 0;
81  selstart_ = -1;
82  selend_ = -1;
83  set_dirty(true);
84  update_text_cache(true, color);
86 }
87 
88 void textbox::append_text(const std::string& text, bool auto_scroll, const SDL_Color& color)
89 {
90  if(text_image_.get() == nullptr) {
91  set_text(text, color);
92  return;
93  }
94 
95  //disallow adding multi-line text to a single-line text box
96  if(wrap_ == false && std::find_if(text.begin(),text.end(),utils::isnewline) != text.end()) {
97  return;
98  }
99  const bool is_at_bottom = get_position() == get_max_position();
100  const ucs4::string& wtext = unicode_cast<ucs4::string>(text);
101 
102  const surface new_text = add_text_line(wtext, color);
103  surface new_surface = create_compatible_surface(text_image_,std::max<size_t>(text_image_->w,new_text->w),text_image_->h+new_text->h);
104 
105  SDL_SetAlpha(new_text.get(),0,0);
107  SDL_SetSurfaceBlendMode(text_image_, SDL_BLENDMODE_NONE);
108  sdl_blit(text_image_,nullptr,new_surface,nullptr);
109  SDL_SetSurfaceBlendMode(text_image_, SDL_BLENDMODE_BLEND);
110 
111  SDL_Rect target = sdl::create_rect(0
112  , text_image_->h
113  , new_text->w
114  , new_text->h);
115  SDL_SetSurfaceBlendMode(new_text, SDL_BLENDMODE_NONE);
116  sdl_blit(new_text,nullptr,new_surface,&target);
117  text_image_.assign(new_surface);
118 
119  text_.insert(text_.end(), wtext.begin(), wtext.end());
120 
121  set_dirty(true);
122  update_text_cache(false);
123  if(auto_scroll && is_at_bottom) scroll_to_bottom();
125 }
126 
128 {
129  text_.clear();
130  cursor_ = 0;
131  cursor_pos_ = 0;
132  text_pos_ = 0;
133  selstart_ = -1;
134  selend_ = -1;
135  set_dirty(true);
136  update_text_cache(true);
138 }
139 
140 void textbox::set_selection(const int selstart, const int selend)
141 {
142  if (!editable_) {
143  return;
144  }
145  if (selstart < 0 || selend < 0 || size_t(selstart) > text_.size() ||
146  size_t(selend) > text_.size()) {
147  WRN_DP << "out-of-boundary selection" << std::endl;
148  return;
149  }
150  selstart_= selstart;
151  selend_ = selend;
152  set_dirty(true);
153 }
154 
155 void textbox::set_cursor_pos(const int cursor_pos)
156 {
157  if (!editable_) {
158  return;
159  }
160  if (cursor_pos < 0 || size_t(cursor_pos) > text_.size()) {
161  WRN_DP << "out-of-boundary selection" << std::endl;
162  return;
163  }
164 
165  cursor_ = cursor_pos;
166  update_text_cache(false);
167  set_dirty(true);
168 }
169 
170 void textbox::draw_cursor(int pos, CVideo &video) const
171 {
172  if(show_cursor_ && editable_ && enabled()) {
173  SDL_Rect rect = sdl::create_rect(location().x + pos
174  , location().y
175  , 1
176  , location().h);
177 
178  surface frame_buffer = video.getSurface();
179  sdl::fill_rect(frame_buffer,&rect,SDL_MapRGB(frame_buffer->format,255,255,255));
180  }
181 }
182 
184 {
185  SDL_Rect const &loc = inner_location();
186 
187  surface& surf = video().getSurface();
188  sdl::draw_solid_tinted_rectangle(loc.x,loc.y,loc.w,loc.h,0,0,0,
189  focus(nullptr) ? alpha_focus_ : alpha_, surf);
190 
191  SDL_Rect src;
192 
193  if(text_image_ == nullptr) {
194  update_text_cache(true);
195  }
196 
197  if(text_image_ != nullptr) {
198  src.y = yscroll_;
199  src.w = std::min<size_t>(loc.w,text_image_->w);
200  src.h = std::min<size_t>(loc.h,text_image_->h);
201  src.x = text_pos_;
202  SDL_Rect dest = screen_area();
203  dest.x = loc.x;
204  dest.y = loc.y;
205 
206  // Fills the selected area
207  if(enabled() && is_selection()) {
208  const int start = std::min<int>(selstart_,selend_);
209  const int end = std::max<int>(selstart_,selend_);
210  int startx = char_x_[start];
211  int starty = char_y_[start];
212  const int endx = char_x_[end];
213  const int endy = char_y_[end];
214 
215  while(starty <= endy) {
216  const size_t right = starty == endy ? endx : text_image_->w;
217  if(right <= size_t(startx)) {
218  break;
219  }
220 
221  SDL_Rect rect = sdl::create_rect(loc.x + startx
222  , loc.y + starty - src.y
223  , right - startx
224  , line_height_);
225 
226  const clip_rect_setter clipper(surf, &loc);
227 
228  Uint32 color = SDL_MapRGB(surf->format, 0, 0, 160);
229  sdl::fill_rect_alpha(rect, color, 140, surf);
230 
231  starty += int(line_height_);
232  startx = 0;
233  }
234  }
235 
236  if(enabled()) {
237  sdl_blit(text_image_, &src, surf, &dest);
238  } else {
239  // HACK: using 30% opacity allows white text to look as though it is grayed out,
240  // while not changing any applicable non-grayscale AA. Actual colored text will
241  // not look as good, but this is not currently a concern since GUI1 textboxes
242  // are not used much nowadays, and they will eventually all go away.
243  sdl_blit(adjust_surface_alpha(text_image_, ftofxp(0.3)), &src, surf, &dest);
244  }
245  }
246 
247  draw_cursor((cursor_pos_ == 0 ? 0 : cursor_pos_ - 1), video());
248 
249  update_rect(loc);
250 }
251 
253 {
254  editable_ = value;
255 }
256 
257 bool textbox::editable() const
258 {
259  return editable_;
260 }
261 
263 {
264  return font_size_;
265 }
266 
268 {
269  font_size_ = fs;
270 }
271 
273 {
275 }
276 
278 {
279  if(wrap_ != val) {
280  wrap_ = val;
281  update_text_cache(true);
282  set_dirty(true);
283  }
284 }
285 
286 void textbox::scroll(unsigned int pos)
287 {
288  yscroll_ = pos;
289  set_dirty(true);
290 }
291 
292 surface textbox::add_text_line(const ucs4::string& text, const SDL_Color& color)
293 {
295 
296  if(char_y_.empty()) {
297  char_y_.push_back(0);
298  } else {
299  char_y_.push_back(char_y_.back() + line_height_);
300  }
301 
302  char_x_.push_back(0);
303 
304  // Re-calculate the position of each glyph. We approximate this by asking the
305  // width of each substring, but this is a flawed assumption which won't work with
306  // some more complex scripts (that is, RTL languages). This part of the work should
307  // actually be done by the font-rendering system.
308  std::string visible_string;
309  ucs4::string wrapped_text;
310 
311  ucs4::string::const_iterator backup_itor = text.end();
312 
313  ucs4::string::const_iterator itor = text.begin();
314  while(itor != text.end()) {
315  //If this is a space, save copies of the current state so we can roll back
316  if(char(*itor) == ' ') {
317  backup_itor = itor;
318  }
319  visible_string.append(unicode_cast<utf8::string>(*itor));
320 
321  if(char(*itor) == '\n') {
322  backup_itor = text.end();
323  visible_string = "";
324  }
325 
326  int w = font::line_width(visible_string, font_size_);
327 
328  if(wrap_ && w >= inner_location().w) {
329  if(backup_itor != text.end()) {
330  int backup = itor - backup_itor;
331  itor = backup_itor + 1;
332  if(backup > 0) {
333  char_x_.erase(char_x_.end()-backup, char_x_.end());
334  char_y_.erase(char_y_.end()-backup, char_y_.end());
335  wrapped_text.erase(wrapped_text.end()-backup, wrapped_text.end());
336  }
337  } else {
338  if (visible_string == std::string("").append(unicode_cast<utf8::string>(*itor))) {
339  break; //breaks infinite loop where when running with a fake display, we word wrap a single character infinitely.
340  }
341  }
342  backup_itor = text.end();
343  wrapped_text.push_back(ucs4::char_t('\n'));
344  char_x_.push_back(0);
345  char_y_.push_back(char_y_.back() + line_height_);
346  visible_string = "";
347  } else {
348  wrapped_text.push_back(*itor);
349  char_x_.push_back(w);
350  char_y_.push_back(char_y_.back() + (char(*itor) == '\n' ? line_height_ : 0));
351  ++itor;
352  }
353  }
354 
355  const std::string s = unicode_cast<utf8::string>(wrapped_text);
356  const surface res(font::get_rendered_text(s, font_size_, color));
357 
358  return res;
359 }
360 
361 
362 void textbox::update_text_cache(bool changed, const SDL_Color& color)
363 {
364  if(changed) {
365  char_x_.clear();
366  char_y_.clear();
367 
369  }
370 
371  int cursor_x = char_x_[cursor_];
372 
373  if(cursor_x - text_pos_ > location().w) {
374  text_pos_ = cursor_x - location().w;
375  } else if(cursor_x - text_pos_ < 0) {
376  text_pos_ = cursor_x;
377  }
378  cursor_pos_ = cursor_x - text_pos_;
379 
380  if (!text_image_.null()) {
383  }
384 }
385 
387 {
388  return (selstart_ != -1) && (selend_ != -1) && (selstart_ != selend_);
389 }
390 
392 {
393  if(!is_selection())
394  return;
395 
396  ucs4::string::iterator itor = text_.begin() + std::min(selstart_, selend_);
397  text_.erase(itor, itor + abs(selend_ - selstart_));
398  cursor_ = std::min(selstart_, selend_);
399  selstart_ = selend_ = -1;
400 }
401 
402 namespace {
403  const unsigned int copypaste_modifier =
404 #ifdef __APPLE__
406 #else
407  KMOD_CTRL
408 #endif
409  ;
410 }
411 
412 bool textbox::requires_event_focus(const SDL_Event* event) const
413 {
414  if(!focus_ || hidden() || !enabled()) {
415  return false;
416  }
417  if(event == nullptr) {
418  //when event is not specified, signal that focus may be desired later
419  return true;
420  }
421 
422  if(event->type == SDL_KEYDOWN) {
423  SDLKey key = event->key.keysym.sym;
424  switch(key) {
425  case SDLK_UP:
426  case SDLK_DOWN:
427  case SDLK_PAGEUP:
428  case SDLK_PAGEDOWN:
429  //in the future we may need to check for input history or multi-line support
430  //for now, just return false since these events are not handled.
431  return false;
432  default:
433  return true;
434  }
435  }
436  //mouse events are processed regardless of focus
437  return false;
438 }
439 
440 void textbox::handle_event(const SDL_Event& event)
441 {
443  handle_event(event, false);
444 }
445 
446 bool textbox::handle_text_input(const SDL_Event& event)
447 {
448  bool changed = false;
449  utf8::string str = event.text.text;
451 
452  DBG_G << "Char: " << str << "\n";
453 
454  if (editable_) {
455  changed = true;
456  if (is_selection())
457  erase_selection();
458 
459  if (text_.size() + 1 <= max_size_) {
460 
461  text_.insert(text_.begin() + cursor_, s.begin(), s.end());
462  cursor_ += s.size();
463  }
464  } else {
465  pass_event_to_target(event);
466  }
467  return changed;
468 }
469 
470 bool textbox::handle_key_down(const SDL_Event &event)
471 {
472  bool changed = false;
473 
474  const SDL_keysym& key = reinterpret_cast<const SDL_KeyboardEvent&>(event).keysym;
475  const SDLMod modifiers = SDL_GetModState();
476 
477  const int c = key.sym;
478  const int old_cursor = cursor_;
479 
480  listening_ = true;
481 
482  if(editable_) {
483  if(c == SDLK_LEFT && cursor_ > 0)
484  --cursor_;
485 
486  if(c == SDLK_RIGHT && cursor_ < static_cast<int>(text_.size()))
487  ++cursor_;
488 
489  // ctrl-a, ctrl-e and ctrl-u are readline style shortcuts, even on Macs
490  if(c == SDLK_END || (c == SDLK_e && (modifiers & KMOD_CTRL)))
491  cursor_ = text_.size();
492 
493  if(c == SDLK_HOME || (c == SDLK_a && (modifiers & KMOD_CTRL)))
494  cursor_ = 0;
495 
496  if((old_cursor != cursor_) && (modifiers & KMOD_SHIFT)) {
497  if(selstart_ == -1)
498  selstart_ = old_cursor;
499  selend_ = cursor_;
500  }
501  } else if(c == SDLK_LEFT || c == SDLK_RIGHT || c == SDLK_END || c == SDLK_HOME) {
502  pass_event_to_target(event);
503  }
504 
505  if(editable_) {
506  if(c == SDLK_BACKSPACE) {
507  changed = true;
508  if(is_selection()) {
509  erase_selection();
510  } else if(cursor_ > 0) {
511  --cursor_;
512  text_.erase(text_.begin()+cursor_);
513  }
514  }
515 
516  if(c == SDLK_u && (modifiers & KMOD_CTRL)) { // clear line
517  changed = true;
518  cursor_ = 0;
519  text_.resize(0);
520  }
521 
522  if(c == SDLK_DELETE && !text_.empty()) {
523  changed = true;
524  if(is_selection()) {
525  erase_selection();
526  } else {
527  if(cursor_ < static_cast<int>(text_.size())) {
528  text_.erase(text_.begin()+cursor_);
529  }
530  }
531  }
532  } else if(c == SDLK_BACKSPACE || c == SDLK_DELETE || (c == SDLK_u && (modifiers & KMOD_CTRL))) {
533  pass_event_to_target(event);
534  }
535 
536 
537  //movement characters may have a "Unicode" field on some platforms, so ignore it.
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.keysym.mod & copypaste_modifier)
542  //on windows SDL fires for AltGr lctrl+ralt (needed to access @ etc on certain keyboards)
543 #ifdef _WIN32
544  && !(event.key.keysym.mod & KMOD_ALT)
545 #endif
546  ) {
547  switch(c) {
548  case SDLK_v: // paste
549  {
550  if(!editable()) {
551  pass_event_to_target(event);
552  break;
553  }
554 
555  changed = true;
556  if(is_selection())
557  erase_selection();
558 
560 
561  //cut off anything after the first newline
562  str.erase(std::find_if(str.begin(),str.end(),utils::isnewline),str.end());
563 
565 
566  if(text_.size() < max_size_) {
567  if(s.size() + text_.size() > max_size_) {
568  s.resize(max_size_ - text_.size());
569  }
570  text_.insert(text_.begin()+cursor_, s.begin(), s.end());
571  cursor_ += s.size();
572  }
573 
574  }
575 
576  break;
577 
578  case SDLK_c: // copy
579  {
580  if(is_selection())
581  {
582  const size_t beg = std::min<size_t>(size_t(selstart_),size_t(selend_));
583  const size_t end = std::max<size_t>(size_t(selstart_),size_t(selend_));
584 
585  ucs4::string ws(text_.begin() + beg, text_.begin() + end);
588  }
589  }
590  break;
591  }
592  }
593  else {
594  pass_event_to_target(event);
595  }
596  }
597 
598  return changed;
599 }
600 
601 void textbox::handle_event(const SDL_Event& event, bool was_forwarded)
602 {
603  if(!enabled())
604  return;
605 
607  if(hidden())
608  return;
609 
610  bool changed = false;
611 
612  const int old_selstart = selstart_;
613  const int old_selend = selend_;
614 
615  //Sanity check: verify that selection start and end are within text
616  //boundaries
617  if(is_selection() && !(size_t(selstart_) <= text_.size() && size_t(selend_) <= text_.size())) {
618  WRN_DP << "out-of-boundary selection" << std::endl;
619  selstart_ = selend_ = -1;
620  }
621 
622  int mousex, mousey;
623  const Uint8 mousebuttons = SDL_GetMouseState(&mousex,&mousey);
624  if(!(mousebuttons & SDL_BUTTON(1))) {
625  grabmouse_ = false;
626  }
627 
628  SDL_Rect const &loc = inner_location();
629  bool clicked_inside = !mouse_locked() && (event.type == SDL_MOUSEBUTTONDOWN
630  && (mousebuttons & SDL_BUTTON(1))
631  && sdl::point_in_rect(mousex, mousey, loc));
632  if(clicked_inside) {
633  set_focus(true);
634  }
635  if ((grabmouse_ && (!mouse_locked() && event.type == SDL_MOUSEMOTION)) || clicked_inside) {
636  const int x = mousex - loc.x + text_pos_;
637  const int y = mousey - loc.y;
638  int pos = 0;
639  int distance = x;
640 
641  for(unsigned int i = 1; i < char_x_.size(); ++i) {
642  if(static_cast<int>(yscroll_) + y < char_y_[i]) {
643  break;
644  }
645 
646  // Check individually each distance (if, one day, we support
647  // RTL languages, char_x_[c] may not be monotonous.)
648  if(abs(x - char_x_[i]) < distance && yscroll_ + y < char_y_[i] + line_height_) {
649  pos = i;
650  distance = abs(x - char_x_[i]);
651  }
652  }
653 
654  cursor_ = pos;
655 
656  if(grabmouse_)
657  selend_ = cursor_;
658 
659  update_text_cache(false);
660 
661  if(!grabmouse_ && (mousebuttons & SDL_BUTTON(1))) {
662  grabmouse_ = true;
664  } else if (! (mousebuttons & SDL_BUTTON(1))) {
665  grabmouse_ = false;
666  }
667 
668  set_dirty();
669  }
670 
671  //if we don't have the focus, then see if we gain the focus,
672  //otherwise return
673  if(!was_forwarded && focus(&event) == false) {
674  if (!mouse_locked() && event.type == SDL_MOUSEMOTION && sdl::point_in_rect(mousex, mousey, loc))
675  events::focus_handler(this);
676 
677  return;
678  }
679 
680  const int old_cursor = cursor_;
681 
682  if (event.type == SDL_TEXTINPUT && listening_) {
683  changed = handle_text_input(event);
684  } else
685  if (event.type == SDL_KEYDOWN) {
686  changed = handle_key_down(event);
687  }
688  else {
689  if(event.type != SDL_KEYDOWN || (!was_forwarded && focus(&event) != true)) {
690  draw();
691  return;
692  }
693  }
694 
695 
696  if(is_selection() && (selend_ != cursor_))
697  selstart_ = selend_ = -1;
698 
699  //since there has been cursor activity, make the cursor appear for
700  //at least the next 500ms.
701  show_cursor_ = true;
702  show_cursor_at_ = SDL_GetTicks();
703 
704  if(changed || old_cursor != cursor_ || old_selstart != selstart_ || old_selend != selend_) {
705  text_image_ = nullptr;
707  }
708 
709  set_dirty(true);
710 }
711 
712 void textbox::pass_event_to_target(const SDL_Event& event)
713 {
715  edit_target_->handle_event(event, true);
716  }
717 }
718 
720 {
722 }
723 
724 } //end namespace gui
bool is_selection()
Definition: textbox.cpp:386
double alpha_focus_
Definition: textbox.hpp:91
static unsigned int max_size_
Definition: font.cpp:773
#define SDL_keysym
Definition: compat.hpp:31
int font_size() const
Definition: textbox.cpp:262
std::vector< int > char_x_
Definition: textbox.hpp:74
bool null() const
Definition: utils.hpp:104
std::vector< char_t > string
virtual void handle_text_changed(const ucs4::string &)
Definition: textbox.hpp:58
void set_shown_size(unsigned h)
Definition: scrollarea.cpp:110
#define SDLMod
Definition: compat.hpp:30
SDL_Surface * get() const
Definition: utils.hpp:98
void fill_rect(surface &dst, SDL_Rect *dst_rect, const Uint32 color)
Fill a rectangle on a given surface.
Definition: rect.hpp:143
void set_edit_target(textbox *target)
Definition: textbox.cpp:719
bool enabled() const
Definition: widget.cpp:212
int cursor_pos_
Definition: textbox.hpp:73
void draw_cursor(int pos, CVideo &video) const
Definition: textbox.cpp:170
std::string copy_from_clipboard(const bool)
Copies text from the clipboard.
Definition: clipboard.cpp:45
#define DBG_G
Definition: textbox.cpp:29
const GLfloat * c
Definition: glew.h:12741
int pos
Definition: formula.cpp:800
void pass_event_to_target(const SDL_Event &event)
Definition: textbox.cpp:712
Definition: video.hpp:58
void bg_register(SDL_Rect const &rect)
Definition: widget.cpp:109
ucs4_convert_impl::enableif< TD, typename TS::value_type >::type unicode_cast(const TS &source)
bool grabmouse_
Definition: textbox.hpp:70
CVideo & video() const
Definition: widget.hpp:83
General purpose widgets.
int selstart_
Definition: textbox.hpp:68
GLuint const GLfloat * val
Definition: glew.h:2614
void set_text(const std::string &text, const SDL_Color &color=font::NORMAL_COLOR)
Definition: textbox.cpp:76
bool editable() const
Definition: textbox.cpp:257
void set_focus(bool focus)
Definition: widget.cpp:149
virtual void draw_contents()
Definition: textbox.cpp:183
virtual ~textbox()
Definition: textbox.cpp:50
void set_scroll_rate(unsigned r)
Definition: scrollarea.cpp:124
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1220
GLenum src
Definition: glew.h:2392
const std::string text() const
Definition: textbox.cpp:69
textbox(CVideo &video, int width, const std::string &text="", bool editable=true, 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)
Definition: textbox.cpp:33
surface text_image_
Definition: textbox.hpp:84
std::vector< int > char_y_
Definition: textbox.hpp:74
void update_text_cache(bool reset=false, const SDL_Color &color=font::NORMAL_COLOR)
Definition: textbox.cpp:362
tformula< t_string > text_
The text to draw.
Definition: canvas.cpp:1268
-file util.hpp
textbox * edit_target_
Definition: textbox.hpp:93
#define SDLKey
Definition: compat.hpp:29
surface & getSurface()
Definition: dummy_video.cpp:22
SDL_Rect screen_area()
Definition: video.cpp:135
void set_measurements(int w, int h)
Definition: widget.cpp:129
void set_cursor_pos(const int cursor_pos)
Definition: textbox.cpp:155
bool hidden() const
Definition: widget.cpp:198
void set_full_size(unsigned h)
Definition: scrollarea.cpp:117
void set_dirty(bool dirty=true)
Definition: widget.cpp:217
size_t max_size_
Definition: textbox.hpp:60
void focus_handler(const sdl_handler *ptr)
Definition: events.cpp:262
GLuint GLuint end
Definition: glew.h:1221
void set_wrap(bool val)
Definition: textbox.cpp:277
void set_position(unsigned pos)
Definition: scrollarea.cpp:95
SDL_Rect inner_location() const
Definition: scrollarea.cpp:138
void draw_solid_tinted_rectangle(int x, int y, int w, int h, int r, int g, int b, double alpha, surface target)
Fills a specified rectangle area of a surface with a given color and opacity.
Definition: rect.cpp:117
#define WRN_DP
Definition: textbox.cpp:28
bool focus(const SDL_Event *event)
Definition: widget.cpp:157
int show_cursor_at_
Definition: textbox.hpp:83
bool handle_text_input(const SDL_Event &event)
Definition: textbox.cpp:446
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1858
GLsizei const GLfloat * value
Definition: glew.h:1817
surface adjust_surface_alpha(const surface &surf, fixed_t amount, bool optimize)
Definition: utils.cpp:1202
void set_editable(bool value)
Definition: textbox.cpp:252
GLuint start
Definition: glew.h:1221
void erase_selection()
Definition: textbox.cpp:391
void scroll_to_bottom()
Definition: textbox.cpp:272
bool handle_key_down(const SDL_Event &event)
Definition: textbox.cpp:470
GLclampf GLclampf GLclampf alpha
Definition: glew.h:1488
void set_font_size(int fs)
Definition: textbox.cpp:267
bool listening_
Definition: textbox.hpp:99
size_t line_height_
Definition: textbox.hpp:88
static lg::log_domain log_display("display")
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
void append_text(const std::string &text, bool auto_scroll=false, const SDL_Color &color=font::NORMAL_COLOR)
Definition: textbox.cpp:88
surf
Definition: filter.cpp:143
GLuint color
Definition: glew.h:5801
int get_max_height(int size)
Definition: font.cpp:960
bool point_in_rect(int x, int y, const SDL_Rect &rect)
Tests whether a point is inside a rectangle.
Definition: rect.cpp:47
#define KMOD_RMETA
Definition: compat.hpp:36
lu_byte right
Definition: lparser.cpp:1020
int text_pos_
Definition: textbox.hpp:72
bool show_cursor_
Definition: textbox.hpp:78
unsigned get_position() const
Definition: scrollarea.cpp:85
void handle_event(const SDL_Event &event, bool was_forwarded)
Definition: textbox.cpp:601
surface add_text_line(const ucs4::string &text, const SDL_Color &color=font::NORMAL_COLOR)
Definition: textbox.cpp:292
GLuint res
Definition: glew.h:9258
void set_selection(const int selstart, const int selend)
Definition: textbox.cpp:140
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
virtual void update_location(SDL_Rect const &rect)
Definition: textbox.cpp:54
ucs4::string text_
Definition: textbox.hpp:64
boost::uint32_t char_t
virtual void handle_event(const SDL_Event &event)
Definition: scrollarea.cpp:151
bool focus_
Definition: widget.hpp:94
void clear()
Definition: textbox.cpp:127
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:5910
size_t i
Definition: function.cpp:1057
GLint GLint GLint GLint GLint x
Definition: glew.h:1220
virtual void draw()
Definition: widget.cpp:283
unsigned get_max_position() const
Definition: scrollarea.cpp:90
virtual void scroll(unsigned int pos)
Definition: textbox.cpp:286
int font_size_
Definition: font.cpp:604
bool isnewline(const char c)
size_t yscroll_
Definition: textbox.hpp:88
SDL_Rect create_rect(const int x, const int y, const int w, const int h)
Creates an empty SDL_Rect.
Definition: rect.cpp:28
GLsizeiptr size
Definition: glew.h:1649
virtual void set_inner_location(SDL_Rect const &)
Definition: textbox.cpp:61
void copy_to_clipboard(const std::string &text, const bool)
Copies text to the clipboard.
Definition: clipboard.cpp:40
Contains the SDL_Rect helper code.
void fill_rect_alpha(SDL_Rect &rect, Uint32 color, Uint8 alpha, surface target)
Fills a specified area of a surface with a given color and opacity.
Definition: rect.cpp:83
cl_event event
Definition: glew.h:3070
bool editable_
Definition: textbox.hpp:76
Standard logging facilities (interface).
bool mouse_locked() const
Definition: widget.cpp:72
void assign(const surface &o)
Definition: utils.hpp:83
surface create_compatible_surface(const surface &surf, int width, int height)
Definition: utils.cpp:2166
bool requires_event_focus(const SDL_Event *event=nullptr) const
Definition: textbox.cpp:412
#define KMOD_LMETA
Definition: compat.hpp:35
GLint GLint GLint GLint GLint GLint GLsizei width
Definition: glew.h:1220
virtual void handle_event(SDL_Event const &)
Definition: widget.cpp:345
bool wrap_
Definition: textbox.hpp:86
SDL_Rect const & location() const
Definition: widget.cpp:144
void sdl_blit(const surface &src, SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
Definition: utils.hpp:112
int SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha)
Definition: alpha.cpp:18
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
surface get_rendered_text(const std::string &str, int size, const SDL_Color &color, int style)
Definition: font.cpp:886
Compatibility layer for using SDL 1.2 and 2.0.
GLdouble s
Definition: glew.h:1358
const int font_size
void update_rect(const SDL_Rect &)
Definition: dummy_video.cpp:27
GLsizei const GLcharARB ** string
Definition: glew.h:4503
int line_width(const std::string &line, int font_size, int style)
Determine the width of a line of text given a certain font size.
Definition: font.cpp:969
#define ftofxp(x)
IN: float or int - OUT: fixed_t.
Definition: util.hpp:503
std::string string
GLenum target
Definition: glew.h:5190
int font_size_
Definition: textbox.hpp:62
virtual void update_location(SDL_Rect const &rect)
Definition: scrollarea.cpp:47
double alpha_
Definition: textbox.hpp:90