1 /*
2  * Copyright (C) 2002-2020 by the Widelands Development Team
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  *
18  */
19 
20 #include "editor/ui_menus/tool_change_resources_options_menu.h"
21 
22 #include "base/i18n.h"
23 #include "base/wexception.h"
24 #include "editor/editorinteractive.h"
25 #include "editor/tools/increase_resources_tool.h"
26 #include "editor/tools/set_resources_tool.h"
27 #include "graphic/graphic.h"
28 #include "logic/map.h"
29 #include "logic/map_objects/world/resource_description.h"
30 #include "logic/map_objects/world/world.h"
31 
32 constexpr int kMaxValue = 63;
33 
eia()34 inline EditorInteractive& EditorToolChangeResourcesOptionsMenu::eia() {
35 	return dynamic_cast<EditorInteractive&>(*get_parent());
36 }
37 
EditorToolChangeResourcesOptionsMenu(EditorInteractive & parent,EditorIncreaseResourcesTool & increase_tool,UI::UniqueWindow::Registry & registry)38 EditorToolChangeResourcesOptionsMenu::EditorToolChangeResourcesOptionsMenu(
39    EditorInteractive& parent,
40    EditorIncreaseResourcesTool& increase_tool,
41    UI::UniqueWindow::Registry& registry)
42    : EditorToolOptionsMenu(parent, registry, 370, 120, _("Resources"), increase_tool),
43      increase_tool_(increase_tool),
44      box_(this, hmargin(), vmargin(), UI::Box::Vertical, 0, 0, vspacing()),
45      change_by_(&box_,
46                 0,
47                 0,
48                 get_inner_w() - 2 * hmargin(),
49                 80,
50                 increase_tool_.get_change_by(),
51                 1,
52                 kMaxValue,
53                 UI::PanelStyle::kWui,
54                 _("Increase/Decrease amount by:"),
55                 UI::SpinBox::Units::kNone,
56                 UI::SpinBox::Type::kSmall),
57      set_to_(&box_,
58              0,
59              0,
60              get_inner_w() - 2 * hmargin(),
61              80,
62              increase_tool_.set_tool().get_set_to(),
63              0,
64              kMaxValue,
65              UI::PanelStyle::kWui,
66              _("Set amount to:"),
67              UI::SpinBox::Units::kNone,
68              UI::SpinBox::Type::kSmall),
69      resources_box_(&box_, 0, 0, UI::Box::Horizontal, 0, 0, 1),
70      cur_selection_(&box_, 0, 0, 0, 0, "", UI::Align::kCenter) {
71 	// Configure spin boxes
72 	change_by_.set_tooltip(
73 	   /** TRANSLATORS: Editor change rseources access keys. **/
74 	   _("Click on the map to increase, "
75 	     "Shift + Click on the map to decrease the amount of the selected resource"));
76 	set_to_.set_tooltip(
77 	   /** TRANSLATORS: Editor set rseources access key. **/
78 	   _("Ctrl + Click on the map to set the amount of the selected resource. This will replace "
79 	     "already set resources."));
80 
81 	change_by_.changed.connect([this]() { update_change_by(); });
82 	set_to_.changed.connect([this]() { update_set_to(); });
83 
84 	box_.add(&change_by_);
85 	box_.add(&set_to_);
86 	box_.set_size(get_inner_w() - 2 * hmargin(), change_by_.get_h() + set_to_.get_h() + vspacing());
87 
88 	// Add resource buttons
89 	resources_box_.add_inf_space();
90 	const Widelands::World& world = parent.egbase().world();
91 	for (Widelands::DescriptionIndex i = 0; i < world.get_nr_resources(); ++i) {
92 		const Widelands::ResourceDescription& resource = *world.get_resource(i);
93 		radiogroup_.add_button(&resources_box_, Vector2i::zero(),
94 		                       g_gr->images().get(resource.representative_image()),
95 		                       resource.descname());
96 		resources_box_.add(radiogroup_.get_first_button(), UI::Box::Resizing::kFillSpace);
97 	}
98 	resources_box_.add_inf_space();
99 
100 	box_.add_space(vspacing());
101 	box_.add(&resources_box_, UI::Box::Resizing::kFullSize);
102 	box_.set_size(box_.get_w(), box_.get_h() + 4 * vspacing() + resources_box_.get_h());
103 
104 	radiogroup_.set_state(increase_tool_.get_cur_res());
105 
106 	radiogroup_.changed.connect([this]() { change_resource(); });
107 	radiogroup_.clicked.connect([this]() { change_resource(); });
108 
109 	// Add label
110 	cur_selection_.set_fixed_width(box_.get_inner_w());
111 	box_.add(&cur_selection_);
112 
113 	box_.set_size(box_.get_w(), box_.get_h() + vspacing() + cur_selection_.get_h());
114 	set_inner_size(get_inner_w(), box_.get_h() + 1 * vmargin());
115 	update();
116 }
117 
update_change_by()118 void EditorToolChangeResourcesOptionsMenu::update_change_by() {
119 	int32_t change_by = change_by_.get_value();
120 	assert(change_by > 0);
121 	assert(change_by <= kMaxValue);
122 	increase_tool_.set_change_by(change_by);
123 	increase_tool_.decrease_tool().set_change_by(change_by);
124 	select_correct_tool();
125 }
126 
update_set_to()127 void EditorToolChangeResourcesOptionsMenu::update_set_to() {
128 	int32_t set_to = set_to_.get_value();
129 	assert(set_to >= 0);
130 	assert(set_to <= kMaxValue);
131 	increase_tool_.set_tool().set_set_to(set_to);
132 	select_correct_tool();
133 }
134 
135 /**
136  * called when a resource has been selected
137  */
change_resource()138 void EditorToolChangeResourcesOptionsMenu::change_resource() {
139 	const int32_t resource_index = radiogroup_.get_state();
140 
141 	increase_tool_.set_tool().set_cur_res(resource_index);
142 	increase_tool_.set_cur_res(resource_index);
143 	increase_tool_.decrease_tool().set_cur_res(resource_index);
144 
145 	select_correct_tool();
146 	update();
147 }
148 
149 /**
150  * Update all the textareas, so that they represent the correct values
151  */
update()152 void EditorToolChangeResourcesOptionsMenu::update() {
153 	cur_selection_.set_text(
154 	   (boost::format(_("Current: %s")) %
155 	    eia().egbase().world().get_resource(increase_tool_.set_tool().get_cur_res())->descname())
156 	      .str());
157 }
158