The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
location_palette.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-editor"
16 
17 #include "location_palette.hpp"
18 
19 #include "gettext.hpp"
20 #include "marked-up_text.hpp"
21 #include "tooltips.hpp"
22 
25 
26 #include "wml_separators.hpp"
27 #include "formula/string_utils.hpp"
29 {
30 public:
31  struct tstate {
33  : selected(false)
34  , mouseover(false)
35  {}
36  bool selected;
37  bool mouseover;
38  friend bool operator==(tstate r, tstate l)
39  {
40  return r.selected == l.selected && r.mouseover == l.mouseover;
41  }
42 
43  };
45  : gui::widget(video, true)
46  , parent_(parent)
47  {
48  }
49 
50  void draw_contents() override
51  {
52  if (state_.mouseover) {
53  sdl::draw_solid_tinted_rectangle(location().x, location().y, location().w, location().h, 200, 200, 200, 0.1, video().getSurface());
54  }
55  if (state_.selected) {
56  sdl::draw_rectangle(location().x, location().y, location().w, location().h, -1, video().getSurface());
57  }
58  font::draw_text(&video(), location(), 16, font::NORMAL_COLOR, desc_.empty() ? id_ : desc_, location().x + 2, location().y, 0);
59  }
60 
61  //TODO move to widget
62  bool hit(int x, int y) const
63  {
64  return sdl::point_in_rect(x, y, location());
65  }
66 
67  void mouse_up(SDL_MouseButtonEvent const &e)
68  {
69  if (!(hit(e.x, e.y)))
70  return;
71  if (e.button == SDL_BUTTON_LEFT) {
73  }
74  if (e.button == SDL_BUTTON_RIGHT) {
75  //TODO: add a context menu with the follwing options:
76  // 1) 'copy it to clipboard'
77  // 2) 'jump to item'
78  // 3) 'delete item'.
79  }
80  }
81 
82  void handle_event(const SDL_Event& e) override
83  {
85 
86  if (hidden() || !enabled() || mouse_locked())
87  return;
88 
89  tstate start_state = state_;
90 
91  switch (e.type) {
92  case SDL_MOUSEBUTTONUP:
93  mouse_up(e.button);
94  break;
95  case SDL_MOUSEMOTION:
96  state_.mouseover = hit(e.motion.x, e.motion.y);
97  break;
98  default:
99  return;
100  }
101 
102  if (!(start_state == state_))
103  set_dirty(true);
104  }
105 
106  void set_item_id(const std::string& id)
107  {
108  id_ = id;
109  bool is_number = std::find_if(id.begin(), id.end(), [](char c) { return !std::isdigit(c); }) == id.end();
110  if (is_number) {
111  desc_ = vgettext("Player $side_num", utils::string_map{ {"side_num", id} });
112  }
113  else {
114  desc_ = "";
115  }
116  }
118  {
120  }
121  void draw() { gui::widget::draw(); }
122 private:
127 };
128 
130 {
131 public:
132  location_palette_button(CVideo& video, const SDL_Rect& location, const std::string& text, const std::function<void (void)>& callback)
133  : gui::button(video, text)
134  , callback_(callback)
135  {
136  this->set_location(location.x, location.y);
137  this->hide(false);
138  }
139 protected:
140  virtual void mouse_up(const SDL_MouseButtonEvent& e) override
141  {
143  if (callback_) {
144  if (this->pressed()) {
145  callback_();
146  }
147  }
148  }
149  std::function<void (void)> callback_;
150 
151 };
152 namespace editor {
154  : common_palette(gui)
155  , gui_(gui)
156  , item_size_(20)
157  //TODO avoid magic number
158  , item_space_(20 + 3)
159  , palette_y_(0)
160  , palette_x_(0)
161  , items_start_(0)
162  , selected_item_()
163  , items_()
164  , active_mouse_action_(active_mouse_action)
165  , buttons_()
166  , button_add_()
167  , button_delete_()
168  , button_goto_()
169  , help_handle_(-1)
170  , disp_(gui)
171  {
172  for (int i = 1; i < 10; ++i) {
173  items_.push_back(std::to_string(i));
174  }
175  selected_item_ = items_[0];
176  }
177 
179 {
181  for (gui::widget& b : buttons_) {
182  h.push_back(&b);
183  }
184  if (button_add_) { h.push_back(button_add_.get()); }
185  if (button_delete_) { h.push_back(button_delete_.get()); }
186  if (button_goto_) { h.push_back(button_goto_.get()); }
187  return h;
188 }
189 
190 void location_palette::hide(bool hidden) {
191  widget::hide(hidden);
192  if (!hidden) {
194  }
195  else {
197  }
198  for (auto& w : handler_members()) {
199  static_cast<gui::widget&>(*w).hide(hidden);
200  }
201 }
202 
204 {
205  int decrement = 1;
206  if(items_start_ >= decrement) {
207  items_start_ -= decrement;
208  draw();
209  return true;
210  }
211  return false;
212 }
214 {
215  return (items_start_ != 0);
216 }
217 
219 {
220  return (items_start_ + num_visible_items() + 1 <= num_items());
221 }
222 
224 {
225  bool end_reached = (!(items_start_ + num_visible_items() + 1 <= num_items()));
226  bool scrolled = false;
227 
228  // move downwards
229  if(!end_reached) {
230  items_start_ += 1;
231  scrolled = true;
232  set_dirty(true);
233  }
234  draw();
235  return scrolled;
236 }
237 
239 {
240  palette_x_ = target.x;
241  palette_y_ = target.y;
242  const int button_height = 30;
243  int bottom = target.y + target.h;
244 
245 
246  button_add_.reset();
247  button_delete_.reset();
248  button_goto_.reset();
249 
250  button_goto_.reset(new location_palette_button(video(), SDL_Rect{ target.x , bottom -= button_height, target.w - 10, button_height }, _("Go To"), [this]() {
251  //static_cast<mouse_action_starting_position&>(**active_mouse_action_).
253  if (pos.valid()) {
255  }
256  }));
257  button_add_.reset(new location_palette_button(video(), SDL_Rect{ target.x , bottom -= button_height, target.w - 10, button_height }, _("Add"), [this]() {
258  std::string newid;
259  if (gui2::tedit_text::execute(_("New Location Identifer"), "", newid, video())) {
260  add_item(newid);
261  }
262  }));
263  button_delete_.reset(new location_palette_button(video(), SDL_Rect{ target.x , bottom -= button_height, target.w - 10, button_height }, _("Delete"), nullptr));
264 
265  const int space_for_items = bottom - target.y;
266  const int items_fitting = space_for_items / item_space_;
267  if (num_visible_items() != items_fitting) {
268  location_palette_item lpi(gui_.video(), *this);
269  //Why does this need a pointer to a non-const as second paraeter?
270  //TODO: we should write our own ptr_vector class, boost::ptr_vector has a lot of flaws.
271  buttons_.resize(items_fitting, &lpi);
272  }
273  set_location(target);
274  set_dirty(true);
277 }
278 
280 {
281  if (selected_item_ != item_id) {
282  selected_item_ = item_id;
283  set_dirty();
284  }
287 }
288 
290 {
291  return items_.size();
292 }
294 {
295  return buttons_.size();
296 }
297 
299 {
300  return selected_item_ == id;
301 }
302 
304 {
306  (*active_mouse_action_)->set_mouse_overlay(gui_);
307  int y = palette_y_;
308  const int x = palette_x_;
309  const int starting = items_start_;
310  int ending = std::min<int>(starting + num_visible_items(), num_items());
311  std::shared_ptr<gui::button> upscroll_button = gui_.find_action_button("upscroll-button-editor");
312  if (upscroll_button)
313  upscroll_button->enable(starting != 0);
314  std::shared_ptr<gui::button> downscroll_button = gui_.find_action_button("downscroll-button-editor");
315  if (downscroll_button)
316  downscroll_button->enable(ending != num_items());
317 
318  if (button_goto_) {
319  button_goto_->set_dirty(true);
320  }
321  if (button_add_) {
322  button_add_->set_dirty(true);
323  }
324  if (button_delete_) {
325  button_delete_->set_dirty(true);
326  }
327  for (int i = 0, size = num_visible_items(); i < size; i++) {
328 
329  location_palette_item & tile = buttons_[i];
330 
331  tile.hide(true);
332 
333  if (i >= ending) {
334  //We want to hide all follwing buttons to we cannot use break here.
335  continue;
336  }
337 
338  const std::string item_id = items_[starting + i];
339 
340  std::stringstream tooltip_text;
341 
342  SDL_Rect dstrect;
343  dstrect.x = x;
344  dstrect.y = y;
345  dstrect.w = location().w - 10;
346  dstrect.h = item_size_ + 2;
347 
348  tile.set_location(dstrect);
349  tile.set_tooltip_string(tooltip_text.str());
350  tile.set_item_id(item_id);
351  tile.set_selected(is_selected_item(item_id));
352  tile.set_dirty(true);
353  tile.hide(false);
354  tile.draw();
355 
356  // Adjust location
357  y += item_space_;
358  }
360 }
361 
362 std::vector<std::string> location_palette::action_pressed() const
363 {
364  std::vector<std::string> res;
365  if (button_delete_ && button_delete_->pressed()) {
366  res.push_back("editor-remove-location");
367  }
368  return res;
369 }
370 
372 {
373 }
374 
376 {
377  int pos;
378  const auto itor = std::find(items_.begin(), items_.end(), id);
379  if (itor == items_.end()) {
380  items_.push_back(id);
381  pos = items_.size() - 1;
382  }
383  else {
384  pos = itor - items_.begin();
385  }
386  selected_item_ = id;
387  items_start_ = std::max(pos - num_visible_items() + 1, items_start_);
388  items_start_ = std::min(pos, items_start_);
390 }
391 
392 } // end namespace editor
std::shared_ptr< gui::button > find_action_button(const std::string &id)
Retrieves a pointer to a theme UI button.
Definition: display.cpp:826
virtual void mouse_up(const SDL_MouseButtonEvent &event)
Definition: button.cpp:689
button(CVideo &video, const std::string &label, TYPE type=TYPE_PRESS, std::string button_image="", SPACE_CONSUMPTION spacing=DEFAULT_SPACE, const bool auto_join=true, std::string overlay_image="")
Definition: button.cpp:47
friend bool operator==(tstate r, tstate l)
bool enabled() const
Definition: widget.cpp:212
std::vector< events::sdl_handler * > sdl_handler_vector
Definition: events.hpp:163
const GLfloat * c
Definition: glew.h:12741
int pos
Definition: formula.cpp:800
virtual bool scroll_up()
Scroll the editor-palette up one step if possible.
location_palette_item(CVideo &video, editor::location_palette &parent)
Definition: video.hpp:58
boost::ptr_vector< location_palette_item > buttons_
CVideo & video() const
Definition: widget.hpp:83
General purpose widgets.
virtual bool is_selected_item(const std::string &id)
#define h
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1220
virtual std::vector< std::string > action_pressed() const override
virtual void mouse_up(const SDL_MouseButtonEvent &e) override
const SDL_Color NORMAL_COLOR
Definition: font.cpp:564
mouse_action ** active_mouse_action_
editor::location_palette & parent_
GLdouble l
Definition: glew.h:6966
std::unique_ptr< location_palette_button > button_goto_
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
bool hidden() const
Definition: widget.cpp:198
void set_dirty(bool dirty=true)
Definition: widget.cpp:217
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
static bool execute(const std::string &title, const std::string &label, std::string &text, CVideo &video)
Executes the dialog.
Definition: edit_text.hpp:51
GLuint GLuint end
Definition: glew.h:1221
std::map< std::string, t_string > string_map
location_palette(editor_display &gui, const config &, mouse_action **active_mouse_action)
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
void adjust_size(const SDL_Rect &target)
Update the size of this widget.
bool valid() const
Definition: location.hpp:69
virtual sdl_handler_vector handler_members()
virtual void hide(bool value=true)
Definition: widget.cpp:162
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1858
std::string selected
Definition: game_config.cpp:84
location_palette_button(CVideo &video, const SDL_Rect &location, const std::string &text, const std::function< void(void)> &callback)
virtual std::string get_help_string()
Manage the empty-palette in the editor.
Definition: action.cpp:28
bool pressed()
Definition: button.cpp:770
int num_visible_items()
Return the maximum number of items shown at the same time.
void set_item_id(const std::string &id)
bool point_in_rect(int x, int y, const SDL_Rect &rect)
Tests whether a point is inside a rectangle.
Definition: rect.cpp:47
void set_selected(bool selected)
Encapsulates the map of the game.
Definition: location.hpp:38
SDL_Rect draw_text(surface &dst, const SDL_Rect &area, int size, const SDL_Color &color, const std::string &txt, int x, int y, bool use_tooltips, int style)
Function to draw text on a surface.
GLuint res
Definition: glew.h:9258
map_location special_location(const std::string &id) const
Definition: map.cpp:409
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
void add_item(const std::string &id)
void scroll_to_tile(const map_location &loc, SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true, bool force=true)
Scroll such that location loc is on-screen.
Definition: display.cpp:2434
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
GLdouble GLdouble GLdouble r
Definition: glew.h:1374
std::vector< expression_ptr > items_
Definition: formula.cpp:119
std::unique_ptr< location_palette_button > button_add_
void set_tooltip_string(const std::string &str)
Definition: widget.cpp:319
std::string vgettext(const char *msgid, const utils::string_map &symbols)
int set_help_string(const std::string &str)
Definition: video.cpp:625
GLsizeiptr size
Definition: glew.h:1649
std::unique_ptr< location_palette_button > button_delete_
const gamemap & get_map() const
Definition: display.hpp:92
bool find(E event, F functor)
Tests whether an event handler is available.
display & disp_
Definition: dialogs.cpp:98
std::function< void(void)> callback_
bool mouse_locked() const
Definition: widget.cpp:72
CVideo & video()
Gets the underlying screen object.
Definition: display.hpp:202
GLint GLint bottom
Definition: glew.h:5907
void draw_contents() override
bool hit(int x, int y) const
virtual void set_location(SDL_Rect const &rect)
Definition: widget.cpp:85
virtual bool scroll_down()
Scroll the editor-palette down one step if possible.
#define e
virtual void handle_event(SDL_Event const &)
Definition: widget.cpp:345
virtual void select_item(const std::string &item_id)
A mouse action receives events from the controller, and responds to them by creating an appropriate e...
SDL_Rect const & location() const
Definition: widget.cpp:144
widget(widget const &o)
Definition: widget.cpp:35
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
int num_items()
Return the number of items in the palette.
void mouse_up(SDL_MouseButtonEvent const &e)
void update_rect(const SDL_Rect &)
Definition: dummy_video.cpp:27
GLsizei const GLcharARB ** string
Definition: glew.h:4503
void hide(bool hidden) override
void draw_rectangle(int x, int y, int w, int h, Uint32 color, surface target)
Draw a colored rectangle on a surface.
Definition: rect.cpp:103
void handle_event(const SDL_Event &e) override
const std::string & id() const
Definition: widget.cpp:232
std::vector< std::string > items_
GLenum target
Definition: glew.h:5190
void clear_help_string(int handle)
Definition: video.cpp:656