The Battle for Wesnoth  1.15.0-dev
editor_palettes.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2018 by David White <dave@whitevine.net>
3  Part of the Battle for Wesnoth Project https://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 (std::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(
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>
122 void editor_palette<Item>::set_group(const std::string& id)
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 #if 0
131  std::shared_ptr<gui::button> palette_menu_button = gui_.find_menu_button("menu-editor-terrain");
132  if (palette_menu_button) {
133  //palette_menu_button->set_label(group.name);
134  palette_menu_button->set_tooltip_string(group.name);
135  palette_menu_button->set_overlay(group.icon);
136  }
137 #endif
138  }
139  }
140  assert(found);
141 
142  active_group_ = id;
143 
144  if(active_group().empty()) {
145  ERR_ED << "No items found in group with the id: '" << id << "'." << std::endl;
146  }
147 }
148 
149 template<class Item>
151 {
152  assert(groups_.size() > index);
153  set_group(groups_[index].id);
154 }
155 
156 template<class Item>
158 {
159  assert(!active_group_.empty());
160 
161  for (std::size_t i = 0 ; i < groups_.size(); i++) {
162  if (groups_[i].id == active_group_)
163  return i;
164  }
165 
166  return static_cast<std::size_t>(-1);
167 }
168 
169 template<class Item>
170 void editor_palette<Item>::adjust_size(const SDL_Rect& target)
171 {
172  palette_x_ = target.x;
173  palette_y_ = target.y;
174  const int space_for_items = target.h;
175  const int items_fitting = (space_for_items / item_space_) * item_width_;
176  nitems_ = std::min(items_fitting, nmax_items_);
177  if (num_visible_items() != nitems_) {
178  buttons_.resize(nitems_, gui::tristate_button(gui_.video(), this));
179  }
180  set_location(target);
181  set_dirty(true);
182 }
183 
184 template<class Item>
185 void editor_palette<Item>::select_fg_item(const std::string& item_id)
186 {
187  if (selected_fg_item_ != item_id) {
188  selected_fg_item_ = item_id;
189  set_dirty();
190  }
191 }
192 
193 template<class Item>
194 void editor_palette<Item>::select_bg_item(const std::string& item_id)
195 {
196  if (selected_bg_item_ != item_id) {
197  selected_bg_item_ = item_id;
198  set_dirty();
199  }
200 }
201 
202 template<class Item>
204 {
205  std::swap(selected_fg_item_, selected_bg_item_);
206  select_fg_item(selected_fg_item_);
207  select_bg_item(selected_bg_item_);
208  set_dirty();
209 }
210 
211 template<class Item>
213 {
214  return group_map_[active_group_].size();
215 }
216 
217 template<class Item>
218 bool editor_palette<Item>::is_selected_fg_item(const std::string& id)
219 {
220  return selected_fg_item_ == id;
221 }
222 
223 template<class Item>
224 bool editor_palette<Item>::is_selected_bg_item(const std::string& id)
225 {
226  return selected_bg_item_ == id;
227 }
228 
229 template<class Item>
231 {
232  toolkit_.set_mouseover_overlay(gui_);
233 #if 0
234  std::shared_ptr<gui::button> palette_menu_button = gui_.find_menu_button("menu-editor-terrain");
235  if (palette_menu_button) {
236 
237  t_string& name = groups_[active_group_index()].name;
238  std::string& icon = groups_[active_group_index()].icon;
239 
240  palette_menu_button->set_tooltip_string(name);
241  palette_menu_button->set_overlay(icon);
242  }
243 #endif
244  unsigned int y = palette_y_;
245  unsigned int x = palette_x_;
246  int starting = items_start_;
247  int ending = std::min<int>(starting + nitems_, num_items());
248 
249 #if 0
250  std::shared_ptr<gui::button> upscroll_button = gui_.find_action_button("upscroll-button-editor");
251  if (upscroll_button)
252  upscroll_button->enable(starting != 0);
253  std::shared_ptr<gui::button> downscroll_button = gui_.find_action_button("downscroll-button-editor");
254  if (downscroll_button)
255  downscroll_button->enable(ending != num_items());
256 #endif
257 
258  int counter = starting;
259  for (int i = 0, size = num_visible_items(); i < size ; ++i) {
260  //TODO check if the conditions still hold for the counter variable
261  //for (unsigned int counter = starting; counter < ending; counter++)
262 
263  gui::tristate_button& tile = buttons_[i];
264 
265  tile.hide(true);
266 
267  if (i >= ending) continue;
268 
269  const std::string item_id = active_group()[counter];
270  //typedef std::map<std::string, Item> item_map_wurscht;
271  typename item_map::iterator item = item_map_.find(item_id);
272 
273  surface item_image(nullptr);
274  std::stringstream tooltip_text;
275  draw_item((*item).second, item_image, tooltip_text);
276 
277  bool is_core = non_core_items_.find(get_id((*item).second)) == non_core_items_.end();
278  if (!is_core) {
279  tooltip_text << " "
281  << _("(non-core)") << "\n"
282  << _("Will not work in game without extra care.")
283  << "</span>";
284  }
285 
286  const int counter_from_zero = counter - starting;
287  SDL_Rect dstrect;
288  dstrect.x = x + (counter_from_zero % item_width_) * item_space_;
289  dstrect.y = y;
290  dstrect.w = item_size_ + 2;
291  dstrect.h = item_size_ + 2;
292 
293  tile.set_location(dstrect);
294  tile.set_tooltip_string(tooltip_text.str());
295  tile.set_item_image(item_image);
296  tile.set_item_id(item_id);
297 
298 // if (get_id((*item).second) == selected_bg_item_
299 // && get_id((*item).second) == selected_fg_item_) {
300 // tile.set_pressed(gui::tristate_button::BOTH);
301 // } else if (get_id((*item).second) == selected_bg_item_) {
302 // tile.set_pressed(gui::tristate_button::RIGHT);
303 // } else if (get_id((*item).second) == selected_fg_item_) {
304 // tile.set_pressed(gui::tristate_button::LEFT);
305 // } else {
306 // tile.set_pressed(gui::tristate_button::NONE);
307 // }
308 
309  if (is_selected_bg_item(get_id(item->second))
310  && is_selected_fg_item(get_id(item->second))) {
312  } else if (is_selected_bg_item(get_id(item->second))) {
314  } else if (is_selected_fg_item(get_id(item->second))) {
316  } else {
318  }
319 
320  tile.set_dirty(true);
321  tile.hide(false);
322  tile.draw();
323 
324  // Adjust location
325  if (counter_from_zero % item_width_ == item_width_ - 1)
326  y += item_space_;
327  ++counter;
328  }
329 }
330 
331 // Force compilation of the following template instantiations
333 template class editor_palette<const unit_type&>;
334 template class editor_palette<overlay>;
335 
336 } // end namespace editor
std::vector< events::sdl_handler * > sdl_handler_vector
Definition: events.hpp:167
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
std::size_t active_group_index()
void set_item_id(const std::string &id)
virtual bool scroll_down() override
Scroll the editor-palette down one step if possible.
void set_group(std::size_t index) override
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&#39;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.
#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)
Returns a Pango formatting string using the provided color_t object.
void set_dirty(bool dirty=true)
Definition: widget.cpp:210
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:89
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:86
const t_string id
const t_string name
int num_items() override
Return the number of items in the palette.
virtual void hide(bool value=true)
Definition: widget.cpp:155
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:1339
virtual void set_location(const SDL_Rect &rect)
Definition: widget.cpp:79
std::size_t i
Definition: function.cpp:933
Declarations for File-IO.
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
void set_tooltip_string(const std::string &str)
Definition: widget.cpp:291
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
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