The Battle for Wesnoth  1.15.7+dev
terrain_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 /**
16  * Terrain-palette in the editor.
17  */
18 
19 #define GETTEXT_DOMAIN "wesnoth-editor"
20 
22 
23 #include "gettext.hpp"
25 #include "game_config_view.hpp"
26 
27 namespace {
28  static t_translation::terrain_code fg_terrain;
29  static t_translation::terrain_code bg_terrain;
30 }
31 
32 namespace editor {
33 
35  return bg_terrain;
36 }
37 
39  return fg_terrain;
40 }
41 
44 
45 
48 }
49 
51  bg_terrain = item_map_[item_id];
53 }
54 
56  fg_terrain = item_map_[item_id];
58 }
59 
61  bg_terrain = terrain;
63 }
64 
66  fg_terrain = terrain;
68 }
69 
70 
72 {
73  // Get the available terrains temporary in items
75 
76  //move "invalid" items to the end
77  std::stable_partition(items.begin(), items.end(), is_valid_terrain);
78 
79  // Get the available groups and add them to the structure
80  std::set<std::string> group_names;
81  for(const config &group : cfg.child_range("terrain_group")) {
82  if(group_names.count(group["id"]) == 0) {
83  config group_cfg;
84  group_cfg["id"] = group["id"];
85  group_cfg["name"] = group["name"];
86 
87  group_cfg["icon"] = group["icon"].str();
88  group_cfg["core"] = group["core"];
89  groups_.emplace_back(group_cfg);
90 
91  group_names.insert(groups_.back().id);
92  }
93  }
94  for(const config &group : cfg.child_range("editor_group")) {
95  if(group_names.count(group["id"]) == 0) {
96  config group_cfg;
97  group_cfg["id"] = group["id"];
98  group_cfg["name"] = group["name"];
99 
100  group_cfg["icon"] = "icons/terrain/terrain_" + group["icon"].str();
101  group_cfg["core"] = group["core"];
102  groups_.emplace_back(group_cfg);
103 
104  group_names.insert(groups_.back().id);
105  }
106  }
107 
108  std::map<std::string, item_group*> id_to_group;
109  for (item_group& group : groups_) {
110  id_to_group.emplace(group.id, &group);
111  }
112 
113  // add the groups for all terrains to the map
114  for (const t_translation::terrain_code& t : items) {
115 
116  const terrain_type& t_info = map().get_terrain_info(t);
117  DBG_ED << "Palette: processing terrain " << t_info.name()
118  << "(editor name: '" << t_info.editor_name() << "') "
119  << "(" << t_info.number() << ")"
120  << ": " << t_info.editor_group() << "\n";
121 
122  // don't display terrains that were automatically created from base+overlay
123  if (t_info.is_combined()) continue;
124  // nor display terrains that have hide_in_editor=true
125  if (t_info.hide_in_editor()) continue;
126 
127  // add the terrain to the requested groups
128  const std::vector<std::string>& keys = utils::split(t_info.editor_group());
129  bool core = false;
130 
131  item_map_[get_id(t)] = t;
132 
133  for (const std::string& k : keys) {
134  group_map_[k].push_back(get_id(t));
135  nmax_items_ = std::max<int>(nmax_items_, group_map_[k].size());
136  std::map<std::string, item_group*>::iterator i = id_to_group.find(k);
137  if (i != id_to_group.end()) {
138  if (i->second->core) {
139  core = true;
140  }
141  }
142  }
143 
144  // A terrain is considered core iff it appears in at least
145  // one core terrain group
146  if (core) {
147  // Add the terrain to the default group
148  group_map_["all"].push_back(get_id(t));
149  nmax_items_ = std::max<int>(nmax_items_, group_map_["all"].size());
150  } else {
151  non_core_items_.insert(get_id(t));
152  }
153 
154  }
155 
156  // Set the default terrain
157  select_fg_item("regular_mountains");
158  select_bg_item("grassland");
159 
160  // Set the default group
161  set_group("all");
162 
163  if(active_group().empty()) {
164  ERR_ED << "No items found." << std::endl;
165  }
166 }
167 
169  surface& image, std::stringstream& tooltip_text) {
170 
171  const t_translation::terrain_code base_terrain = map().get_terrain_info(terrain).default_base();
172 
173  //Draw default base for overlay terrains
174  if(base_terrain != t_translation::NONE_TERRAIN) {
175  const std::string base_filename = map().get_terrain_info(base_terrain).editor_image();
176  surface base_image(image::get_image(base_filename));
177 
178  if(base_image == nullptr) {
179  tooltip_text << "BASE IMAGE NOT FOUND\n";
180  ERR_ED << "image for terrain : '" << base_filename << "' not found" << std::endl;
182  if(base_image == nullptr) {
183  ERR_ED << "Placeholder image not found" << std::endl;
184  return;
185  }
186  }
187 
188  if(base_image->w != item_size_ || base_image->h != item_size_) {
189  base_image = scale_surface(base_image,
191  }
192  }
193 
194  const std::string filename = map().get_terrain_info(terrain).editor_image();
195  image = image::get_image(filename);
196  if(image == nullptr) {
197  tooltip_text << "IMAGE NOT FOUND\n";
198  ERR_ED << "image for terrain: '" << filename << "' not found" << std::endl;
200  if(image == nullptr) {
201  ERR_ED << "Placeholder image not found" << std::endl;
202  return;
203  }
204  }
205 
206  if(image->w != item_size_ || image->h != item_size_) {
207  image = scale_surface(image, item_size_, item_size_);
208  }
209 
210  tooltip_text << map().get_terrain_editor_string(terrain);
212  tooltip_text << " " + font::unicode_em_dash + " " << terrain;
213  }
214 }
215 
217 //TODO avoid magic numbers
218  : editor_palette<t_translation::terrain_code>(gui, cfg, 36, 4, toolkit)
219 {
220 }
221 
223 {
224  const terrain_type& t_info = map().get_terrain_info(terrain);
225  return t_info.id();
226 }
227 
229 {
230  std::ostringstream msg;
231  msg << _("Left-click: ") << map().get_terrain_editor_string(selected_fg_item()) << " | "
232  << _("Right-click: ") << map().get_terrain_editor_string(selected_bg_item()) << "\n";
234  // TRANSLATORS: Similar behavior applies to shift + right-click. This message specifies left-click
235  // because the logic of whether to show the "overlay only" or "base only" version depends on the
236  // terrain currently selected for the left button.
237  msg << _("Shift + left-click: paint overlay layer only") << " | ";
238  } else {
239  msg << _("Shift + left-click: paint base layer only") << " | ";
240  }
241 #ifdef __APPLE__
242  msg << _("Cmd + click: copy terrain") << std::endl;
243 #else
244  msg << _("Ctrl + click: copy terrain") << std::endl;
245 #endif
246  return msg.str();
247 }
248 
249 
250 }
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
Definition: picture.cpp:833
virtual const std::string & get_id(const t_translation::terrain_code &terrain)
const t_translation::terrain_code & get_selected_bg_terrain()
terrain_palette(editor_display &gui, const game_config_view &cfg, editor_toolkit &toolkit)
const terrain_code NONE_TERRAIN
Definition: translation.hpp:59
virtual void select_fg_item(const std::string &item_id) override
Select a foreground item.
const gamemap & map() const
Stores the info about the groups in a nice format.
virtual void select_bg_item(const std::string &item_id) override
config_array_view child_range(config_key_type key) const
const t_translation::ter_list & get_terrain_list() const
Gets the list of terrains.
Definition: map.cpp:41
General purpose widgets.
const t_translation::terrain_code & selected_bg_item() const
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:50
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) const
Definition: map.cpp:95
const std::vector< std::string > & active_group()
const ter_layer NO_LAYER
Definition: translation.hpp:41
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
const std::vector< std::string > items
surface scale_surface(const surface &surf, int w, int h)
Scale a surface using alpha-weighted modified bilinear filtering Note: causes artifacts with alpha gr...
Definition: utils.cpp:196
const std::string & editor_image() const
Definition: terrain.hpp:46
const t_translation::terrain_code & get_selected_fg_terrain()
const terrain_code VOID_TERRAIN
VOID_TERRAIN is used for shrouded hexes.
void select_bg_item(const t_translation::terrain_code &terrain)
virtual std::string get_help_string()
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:100
const t_string & editor_name() const
Definition: terrain.hpp:48
t_translation::terrain_code default_base() const
Definition: terrain.hpp:169
bool is_combined() const
True for instances created by the terrain_code(base, overlay) constructor.
Definition: terrain.hpp:167
const terrain_code FOGGED
static const ::game_config_view * terrain
The terrain used to create the cache.
Definition: minimap.cpp:130
std::map< std::string, std::vector< std::string > > group_map_
Manage the empty-palette in the editor.
Definition: action.cpp:29
void select_fg_item(const t_translation::terrain_code &terrain)
std::size_t i
Definition: function.cpp:933
std::string get_terrain_editor_string(const map_location &loc) const
Definition: map.cpp:60
t_translation::terrain_code number() const
Definition: terrain.hpp:65
static bool is_valid_terrain(const t_translation::terrain_code &c)
bool hide_in_editor() const
Definition: terrain.hpp:61
const t_string & name() const
Definition: terrain.hpp:47
virtual void setup(const game_config_view &cfg)
Setup the internal data structure.
double t
Definition: astarsearch.cpp:64
std::vector< std::string > split(const config_attribute_value &val)
const std::string unicode_em_dash
Definition: constants.cpp:40
#define ERR_ED
this module manages the cache of images.
const std::string & id() const
Definition: terrain.hpp:51
std::vector< terrain_code > ter_list
Definition: translation.hpp:78
virtual void draw_item(const t_translation::terrain_code &terrain, surface &item_image, std::stringstream &tooltip_text)
const t_translation::terrain_code & selected_fg_item() const
std::vector< item_group > groups_
The editor_groups as defined in editor-groups.cfg.
bool get_draw_terrain_codes() const
Getter for the terrain code debug overlay on tiles.
Definition: display.hpp:358
#define DBG_ED
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
mock_char c
std::string::const_iterator iterator
Definition: tokenizer.hpp:24
const std::string & editor_group() const
Definition: terrain.hpp:152