1 /*
2    Copyright (C) 2012 - 2018 by Fabian Mueller <fabianmueller5@gmx.de>
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 #include "editor/toolkit/editor_toolkit.hpp"
16 #include "config.hpp"
17 
18 #include "editor/action/mouse/mouse_action.hpp"
19 #include "editor/action/mouse/mouse_action_map_label.hpp"
20 #include "editor/action/mouse/mouse_action_unit.hpp"
21 #include "editor/action/mouse/mouse_action_village.hpp"
22 #include "editor/action/mouse/mouse_action_item.hpp"
23 #include "editor/action/mouse/mouse_action_select.hpp"
24 
25 namespace editor {
26 
editor_toolkit(editor_display & gui,const CKey & key,const config & game_config,context_manager & c_manager)27 editor_toolkit::editor_toolkit(editor_display& gui, const CKey& key,
28 		const config& game_config, context_manager& c_manager)
29 	: gui_(gui)
30 	, key_(key)
31 	, palette_manager_()
32 	, mouse_action_(nullptr)  // Will be set before this constructor ends.
33 	, mouse_actions_()
34 	, brush_(nullptr)
35 	, brushes_()
36 {
37 	init_brushes(game_config);
38 	init_sidebar(game_config);
39 	init_mouse_actions(c_manager);
40 }
41 
42 editor_toolkit::~editor_toolkit() = default;
43 
init_brushes(const config & game_config)44 void editor_toolkit::init_brushes(const config& game_config)
45 {
46 	for (const config &i : game_config.child_range("brush")) {
47 		brushes_.emplace_back(i);
48 	}
49 	if (brushes_.empty()) {
50 		ERR_ED << "No brushes defined!";
51 		brushes_.emplace_back();
52 		brushes_[0].add_relative_location(0, 0);
53 	}
54 	brush_ = &brushes_[0];
55 }
56 
init_sidebar(const config & game_config)57 void editor_toolkit::init_sidebar(const config& game_config)
58 {
59 	palette_manager_.reset(new palette_manager(gui_, game_config, *this));
60 }
61 
init_mouse_actions(context_manager & cmanager)62 void editor_toolkit::init_mouse_actions(context_manager& cmanager)
63 {
64 	mouse_actions_.emplace(hotkey::HOTKEY_EDITOR_TOOL_PAINT,
65 		std::make_shared<mouse_action_paint>(&brush_, key_, *palette_manager_->terrain_palette_.get()));
66 	mouse_actions_.emplace(hotkey::HOTKEY_EDITOR_TOOL_FILL,
67 		std::make_shared<mouse_action_fill>(key_, *palette_manager_->terrain_palette_.get()));
68 	mouse_actions_.emplace(hotkey::HOTKEY_EDITOR_TOOL_SELECT,
69 		std::make_shared<mouse_action_select>(&brush_, key_, *palette_manager_->empty_palette_.get()));
70 	mouse_actions_.emplace(hotkey::HOTKEY_EDITOR_TOOL_STARTING_POSITION,
71 		std::make_shared<mouse_action_starting_position>(key_, *palette_manager_->location_palette_.get()));
72 	mouse_actions_.emplace(hotkey::HOTKEY_EDITOR_TOOL_LABEL,
73 		std::make_shared<mouse_action_map_label>(key_, *palette_manager_->empty_palette_.get()));
74 	mouse_actions_.emplace(hotkey::HOTKEY_EDITOR_TOOL_UNIT,
75 		std::make_shared<mouse_action_unit>(key_, *palette_manager_->unit_palette_.get()));
76 	mouse_actions_.emplace(hotkey::HOTKEY_EDITOR_TOOL_VILLAGE,
77 		std::make_shared<mouse_action_village>(key_, *palette_manager_->empty_palette_.get()));
78 	mouse_actions_.emplace(hotkey::HOTKEY_EDITOR_CLIPBOARD_PASTE,
79 		std::make_shared<mouse_action_paste>(cmanager.get_clipboard(), key_, *palette_manager_->empty_palette_.get()));
80 	mouse_actions_.emplace(hotkey::HOTKEY_EDITOR_TOOL_ITEM,
81 		std::make_shared<mouse_action_item>(key_, *palette_manager_->item_palette_.get()));
82 
83 	for (const theme::menu& menu : gui_.get_theme().menus()) {
84 		if (menu.items().size() == 1) {
85 			hotkey::HOTKEY_COMMAND hk = hotkey::get_id(menu.items().front()["id"]);
86 			mouse_action_map::iterator i = mouse_actions_.find(hk);
87 			if (i != mouse_actions_.end()) {
88 				i->second->set_toolbar_button(&menu);
89 			}
90 		}
91 	}
92 
93 	mouse_action_ = (mouse_actions_.find(hotkey::HOTKEY_EDITOR_TOOL_PAINT))->second;
94 	set_mouseover_overlay();
95 }
96 
97 
hotkey_set_mouse_action(hotkey::HOTKEY_COMMAND command)98 void editor_toolkit::hotkey_set_mouse_action(hotkey::HOTKEY_COMMAND command)
99 {
100 	mouse_action_map::iterator i = mouse_actions_.find(command);
101 	if (i != mouse_actions_.end()) {
102 		palette_manager_->active_palette().hide(true);
103 		mouse_action_ = i->second;
104 		palette_manager_->adjust_size();
105 
106 		set_mouseover_overlay();
107 		gui_.invalidate_game_status();
108 		palette_manager_->active_palette().hide(false);
109 	} else {
110 		ERR_ED << "Invalid hotkey command ("
111 			<< static_cast<int>(command) << ") passed to set_mouse_action\n";
112 	}
113 
114 }
115 
is_mouse_action_set(hotkey::HOTKEY_COMMAND command) const116 bool editor_toolkit::is_mouse_action_set(hotkey::HOTKEY_COMMAND command) const
117 {
118 	mouse_action_map::const_iterator i = mouse_actions_.find(command);
119 	return (i != mouse_actions_.end()) && (i->second == mouse_action_);
120 }
121 
get_palette()122 common_palette& editor_toolkit::get_palette()
123 {
124 	return get_mouse_action().get_palette();
125 }
126 
update_mouse_action_highlights()127 void editor_toolkit::update_mouse_action_highlights()
128 {
129 	DBG_ED << __func__ << "\n";
130 	int x, y;
131 	SDL_GetMouseState(&x, &y);
132 	map_location hex_clicked = gui_.hex_clicked_on(x,y);
133 	get_mouse_action().update_brush_highlights(gui_, hex_clicked);
134 }
135 
set_mouseover_overlay(editor_display & gui)136 void editor_toolkit::set_mouseover_overlay(editor_display& gui)
137 {
138 	get_mouse_action().set_mouse_overlay(gui);
139 }
140 
clear_mouseover_overlay()141 void editor_toolkit::clear_mouseover_overlay()
142 {
143 	gui_.clear_mouseover_hex_overlay();
144 }
145 
set_brush(std::string id)146 void editor_toolkit::set_brush(std::string id) {
147 
148 	for (brush& i : brushes_) {
149 		if (i.id() == id) {
150 			brush_ = &i;
151 		}
152 	}
153 }
154 
cycle_brush()155 void editor_toolkit::cycle_brush()
156 {
157 	if (brush_ == &brushes_.back()) {
158 		brush_ = &brushes_.front();
159 	} else {
160 		++brush_;
161 	}
162 
163 	update_mouse_action_highlights();
164 }
165 
adjust_size()166 void editor_toolkit::adjust_size()
167 {
168 	palette_manager_->adjust_size();
169 }
170 
171 
172 } //Namespace editor
173