The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
editor_palettes.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2017 by David White <dave@whitevine.net>
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 
18 
19 #include "gettext.hpp"
20 #include "font/text_formatting.hpp"
21 #include "tooltips.hpp"
22 #include "overlay.hpp"
23 #include "filesystem.hpp"
24 #include "units/types.hpp"
25 
27 
28 namespace editor {
29 
30 template<class Item>
32 {
34  for (gui::widget& b : buttons_) {
35  h.push_back(&b);
36  }
37  return h;
38 }
39 
40 template<class Item>
42 {
43  auto pos = items.erase(items.begin() + i);
44 
45  std::vector<config> groups;
46  const std::vector<item_group>& item_groups = get_groups();
47 
48  for (size_t mci = 0; mci < item_groups.size(); ++mci) {
49  std::string groupname = item_groups[mci].name;
50  if (groupname.empty()) {
51  groupname = _("(Unknown Group)");
52  }
53  std::string img = item_groups[mci].icon + "_30";
54  if (mci == active_group_index()) {
55  std::string pressed_img = img + "-pressed.png";
56  if(!filesystem::get_binary_file_location("images", pressed_img).empty()) {
57  img = pressed_img;
58  } else {
59  img += ".png~CS(70,70,0)";
60  }
61  } else {
62  img += ".png";
63  }
64 
65  groups.emplace_back(config {
66  "label", groupname,
67  "icon", img,
68  });
69  }
70 
71  items.insert(pos, groups.begin(), groups.end());
72 }
73 
74 template<class Item>
76 {
77  int decrement = item_width_;
78  if (items_start_ + num_visible_items() == num_items() && num_items() % item_width_ != 0) {
79  decrement = num_items() % item_width_;
80  }
81  if(items_start_ >= decrement) {
82  items_start_ -= decrement;
83  draw();
84  return true;
85  }
86  return false;
87 }
88 
89 template<class Item>
91 {
92  return (items_start_ != 0);
93 }
94 
95 template<class Item>
97 {
98  return (items_start_ + nitems_ + item_width_ <= num_items());
99 }
100 
101 template<class Item>
103 {
104  bool end_reached = (!(items_start_ + nitems_ + item_width_ <= num_items()));
105  bool scrolled = false;
106 
107  // move downwards
108  if(!end_reached) {
109  items_start_ += item_width_;
110  scrolled = true;
111  }
112  else if (items_start_ + nitems_ + (num_items() % item_width_) <= num_items()) {
113  items_start_ += num_items() % item_width_;
114  scrolled = true;
115  }
116  set_dirty(scrolled);
117  draw();
118  return scrolled;
119 }
120 
121 template<class Item>
123 {
124  assert(!id.empty());
125 
126  bool found = false;
127  for (const item_group& group : groups_) {
128  if (group.id == id) {
129  found = true;
130  std::shared_ptr<gui::button> palette_menu_button = gui_.find_menu_button("menu-editor-terrain");
131  if (palette_menu_button) {
132  //palette_menu_button->set_label(group.name);
133  palette_menu_button->set_tooltip_string(group.name);
134  palette_menu_button->set_overlay(group.icon);
135  }
136  }
137  }
138  assert(found);
139 
140  active_group_ = id;
141 
142  if(active_group().empty()) {
143  ERR_ED << "No items found in group with the id: '" << id << "'." << std::endl;
144  }
145 }
146 
147 template<class Item>
149 {
150  assert(groups_.size() > index);
151  set_group(groups_[index].id);
152 }
153 
154 template<class Item>
156 {
157  assert(!active_group_.empty());
158 
159  for (size_t i = 0 ; i < groups_.size(); i++) {
160  if (groups_[i].id == active_group_)
161  return i;
162  }
163 
164  return static_cast<size_t>(-1);
165 }
166 
167 template<class Item>
168 void editor_palette<Item>::adjust_size(const SDL_Rect& target)
169 {
170  palette_x_ = target.x;
171  palette_y_ = target.y;
172  const int space_for_items = target.h;
173  const int items_fitting = (space_for_items / item_space_) * item_width_;
174  nitems_ = std::min(items_fitting, nmax_items_);
175  if (num_visible_items() != nitems_) {
176  buttons_.resize(nitems_, gui::tristate_button(gui_.video(), this));
177  }
178  set_location(target);
179  set_dirty(true);
180  gui_.video().clear_help_string(help_handle_);
181  help_handle_ = gui_.video().set_help_string(get_help_string());
182 }
183 
184 template<class Item>
186 {
187  if (selected_fg_item_ != item_id) {
188  selected_fg_item_ = item_id;
189  set_dirty();
190  }
191  gui_.video().clear_help_string(help_handle_);
192  help_handle_ = gui_.video().set_help_string(get_help_string());
193 }
194 
195 template<class Item>
197 {
198  if (selected_bg_item_ != item_id) {
199  selected_bg_item_ = item_id;
200  set_dirty();
201  }
202  gui_.video().clear_help_string(help_handle_);
203  help_handle_ = gui_.video().set_help_string(get_help_string());
204 }
205 
206 template<class Item>
208 {
209  std::swap(selected_fg_item_, selected_bg_item_);
210  select_fg_item(selected_fg_item_);
211  select_bg_item(selected_bg_item_);
212  set_dirty();
213 }
214 
215 template<class Item>
217 {
218  return group_map_[active_group_].size();
219 }
220 
221 template<class Item>
223 {
224  return selected_fg_item_ == id;
225 }
226 
227 template<class Item>
229 {
230  return selected_bg_item_ == id;
231 }
232 
233 template<class Item>
235 {
236  toolkit_.set_mouseover_overlay(gui_);
237 
238  std::shared_ptr<gui::button> palette_menu_button = gui_.find_menu_button("menu-editor-terrain");
239  if (palette_menu_button) {
240 
241  t_string& name = groups_[active_group_index()].name;
242  std::string& icon = groups_[active_group_index()].icon;
243 
244  palette_menu_button->set_tooltip_string(name);
245  palette_menu_button->set_overlay(icon);
246  }
247 
248  unsigned int y = palette_y_;
249  unsigned int x = palette_x_;
250  int starting = items_start_;
251  int ending = std::min<int>(starting + nitems_, num_items());
252 
253  std::shared_ptr<gui::button> upscroll_button = gui_.find_action_button("upscroll-button-editor");
254  if (upscroll_button)
255  upscroll_button->enable(starting != 0);
256  std::shared_ptr<gui::button> downscroll_button = gui_.find_action_button("downscroll-button-editor");
257  if (downscroll_button)
258  downscroll_button->enable(ending != num_items());
259 
260 
261  int counter = starting;
262  for (int i = 0, size = num_visible_items(); i < size ; ++i) {
263  //TODO check if the conditions still hold for the counter variable
264  //for (unsigned int counter = starting; counter < ending; counter++)
265 
266  gui::tristate_button& tile = buttons_[i];
267 
268  tile.hide(true);
269 
270  if (i >= ending) continue;
271 
272  const std::string item_id = active_group()[counter];
273  //typedef std::map<std::string, Item> item_map_wurscht;
274  typename item_map::iterator item = item_map_.find(item_id);
275 
276  surface item_image(nullptr);
277  std::stringstream tooltip_text;
278  draw_item((*item).second, item_image, tooltip_text);
279 
280  bool is_core = non_core_items_.find(get_id((*item).second)) == non_core_items_.end();
281  if (!is_core) {
282  tooltip_text << " "
284  << _("(non-core)") << "\n"
285  << _("Will not work in game without extra care.")
286  << "</span>";
287  }
288 
289  const int counter_from_zero = counter - starting;
290  SDL_Rect dstrect;
291  dstrect.x = x + (counter_from_zero % item_width_) * item_space_;
292  dstrect.y = y;
293  dstrect.w = item_size_ + 2;
294  dstrect.h = item_size_ + 2;
295 
296  tile.set_location(dstrect);
297  tile.set_tooltip_string(tooltip_text.str());
298  tile.set_item_image(item_image);
299  tile.set_item_id(item_id);
300 
301 // if (get_id((*item).second) == selected_bg_item_
302 // && get_id((*item).second) == selected_fg_item_) {
303 // tile.set_pressed(gui::tristate_button::BOTH);
304 // } else if (get_id((*item).second) == selected_bg_item_) {
305 // tile.set_pressed(gui::tristate_button::RIGHT);
306 // } else if (get_id((*item).second) == selected_fg_item_) {
307 // tile.set_pressed(gui::tristate_button::LEFT);
308 // } else {
309 // tile.set_pressed(gui::tristate_button::NONE);
310 // }
311 
312  if (is_selected_bg_item(get_id(item->second))
313  && is_selected_fg_item(get_id(item->second))) {
315  } else if (is_selected_bg_item(get_id(item->second))) {
317  } else if (is_selected_fg_item(get_id(item->second))) {
319  } else {
321  }
322 
323  tile.set_dirty(true);
324  tile.hide(false);
325  tile.draw();
326 
327  // Adjust location
328  if (counter_from_zero % item_width_ == item_width_ - 1)
329  y += item_space_;
330  ++counter;
331  }
332 }
333 
334 // Force compilation of the following template instantiations
336 template class editor_palette<unit_type>;
337 template class editor_palette<overlay>;
338 
339 } // end namespace editor
std::vector< char_t > string
size_t index(const utf8::string &str, const size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
std::vector< events::sdl_handler * > sdl_handler_vector
Definition: events.hpp:176
virtual sdl_handler_vector handler_members() override
virtual void select_fg_item(const std::string &item_id) override
Select a foreground item.
Stores the info about the groups in a nice format.
virtual void select_bg_item(const std::string &item_id) override
void set_item_id(const std::string &id)
virtual bool scroll_down() override
Scroll the editor-palette down one step if possible.
virtual bool scroll_up() override
Scroll the editor-palette up one step if possible.
virtual bool is_selected_bg_item(const std::string &id)
#define h
std::string get_binary_file_location(const std::string &type, const std::string &filename)
Returns a complete path to the actual file of a given type or an empty string if the file isn't prese...
const std::vector< std::string > items
virtual bool can_scroll_up() override
void expand_palette_groups_menu(std::vector< config > &items, int i) override
Menu expanding for palette group list.
void set_group(size_t index) override
#define b
void set_pressed(PRESSED_STATE new_pressed_state)
virtual bool is_selected_fg_item(const std::string &id)
std::string span_color(const color_t &color)
Retuns a Pango formatting string using the provided color_t object.
void set_dirty(bool dirty=true)
Definition: widget.cpp:215
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:89
int num_items() override
Return the number of items in the palette.
virtual void hide(bool value=true)
Definition: widget.cpp:160
virtual bool can_scroll_down() override
Manage the empty-palette in the editor.
Definition: action.cpp:29
void swap(config &lhs, config &rhs)
Implement non-member swap function for std::swap (calls config::swap).
Definition: config.cpp:1301
size_t size(const utf8::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:86
size_t i
Definition: function.cpp:933
Declarations for File-IO.
void set_tooltip_string(const std::string &str)
Definition: widget.cpp:312
void draw() override
virtual void draw_contents() override
void adjust_size(const SDL_Rect &target) override
Update the size of this widget.
#define ERR_ED
virtual void set_location(SDL_Rect const &rect)
Definition: widget.cpp:83
static const char * name(const std::vector< SDL_Joystick * > &joysticks, const size_t index)
Definition: joystick.cpp:48
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:93
std::string::const_iterator iterator
Definition: tokenizer.hpp:24
HOTKEY_COMMAND get_id(const std::string &command)
returns get_hotkey_command(command).id
void set_item_image(const surface &image)
const color_t BAD_COLOR