00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #define GETTEXT_DOMAIN "wesnoth-editor"
00016
00017 #include "editor/action/action.hpp"
00018 #include "editor/toolkit/brush.hpp"
00019 #include "../../editor_display.hpp"
00020 #include "mouse_action.hpp"
00021
00022 #include "construct_dialog.hpp"
00023 #include "gettext.hpp"
00024 #include "gui/dialogs/editor_set_starting_position.hpp"
00025 #include "editor/palette/terrain_palettes.hpp"
00026
00027 namespace editor {
00028
00029 bool mouse_action::has_context_menu() const
00030 {
00031 return false;
00032 }
00033
00034 void mouse_action::move(editor_display& disp, const map_location& hex)
00035 {
00036 if (hex != previous_move_hex_) {
00037 update_brush_highlights(disp, hex);
00038 previous_move_hex_ = hex;
00039 }
00040 }
00041
00042 void mouse_action::update_brush_highlights(editor_display& disp, const map_location& hex)
00043 {
00044 disp.set_brush_locs(affected_hexes(disp, hex));
00045 }
00046
00047 std::set<map_location> mouse_action::affected_hexes(
00048 editor_display& , const map_location& hex)
00049 {
00050 std::set<map_location> res;
00051 res.insert(hex);
00052 return res;
00053 }
00054
00055 editor_action* mouse_action::drag_left(editor_display& ,
00056 int , int , bool& , editor_action* )
00057 {
00058 return NULL;
00059 }
00060
00061 editor_action* mouse_action::drag_right(editor_display& ,
00062 int , int , bool& , editor_action* )
00063 {
00064 return NULL;
00065 }
00066
00067 editor_action* mouse_action::drag_end(
00068 editor_display& , int , int )
00069 {
00070 return NULL;
00071 }
00072
00073 editor_action* mouse_action::up_right(
00074 editor_display& , int , int )
00075 {
00076 return NULL;
00077 }
00078
00079 editor_action* mouse_action::up_left(
00080 editor_display& , int , int )
00081 {
00082 return NULL;
00083 }
00084
00085 editor_action* mouse_action::key_event(
00086 editor_display& disp, const SDL_Event& event)
00087 {
00088 if (!has_alt_modifier() && (event.key.keysym.sym >= '1' && event.key.keysym.sym <= '9')) {
00089 int side = event.key.keysym.sym - '0';
00090 if (side >= 1 && side <= gamemap::MAX_PLAYERS) {
00091 map_location pos = disp.get_map().starting_position(side);
00092 if (pos.valid()) {
00093 disp.scroll_to_tile(pos, display::WARP);
00094 }
00095 }
00096 return NULL;
00097 }
00098 if (!disp.map().on_board(previous_move_hex_) || event.type != SDL_KEYUP) {
00099 return NULL;
00100 }
00101 editor_action* a = NULL;
00102 if ((has_alt_modifier() && (event.key.keysym.sym >= '1' && event.key.keysym.sym <= '9'))
00103 || event.key.keysym.sym == SDLK_DELETE) {
00104 int res = event.key.keysym.sym - '0';
00105 if (res > gamemap::MAX_PLAYERS || event.key.keysym.sym == SDLK_DELETE) res = 0;
00106 int player_starting_at_hex = disp.map().is_starting_position(previous_move_hex_) + 1;
00107 if (res == 0 && player_starting_at_hex != -1) {
00108 a = new editor_action_starting_position(map_location(), player_starting_at_hex);
00109 } else if (res > 0 && res != player_starting_at_hex) {
00110 a = new editor_action_starting_position(previous_move_hex_, res);
00111 }
00112 }
00113 return a;
00114 }
00115
00116 void mouse_action::set_mouse_overlay(editor_display& disp)
00117 {
00118 disp.set_mouseover_hex_overlay(NULL);
00119 }
00120
00121 bool mouse_action::has_alt_modifier() const
00122 {
00123 return key_[SDLK_RALT] || key_[SDLK_LALT];
00124 }
00125
00126 bool mouse_action::has_shift_modifier() const
00127 {
00128 return key_[SDLK_RSHIFT] || key_[SDLK_LSHIFT];
00129 }
00130
00131 bool mouse_action::has_ctrl_modifier() const
00132 {
00133 #ifdef __APPLE__
00134 return key_[SDLK_RMETA] || key_[SDLK_LMETA];
00135 #else
00136 return key_[SDLK_RCTRL] || key_[SDLK_LCTRL];
00137 #endif
00138 }
00139
00140 void mouse_action::set_terrain_mouse_overlay(editor_display& disp, t_translation::t_terrain fg,
00141 t_translation::t_terrain bg)
00142 {
00143 surface image_fg(image::get_image("terrain/"
00144 + disp.get_map().get_terrain_info(fg).editor_image() + ".png"));
00145 surface image_bg(image::get_image("terrain/"
00146 + disp.get_map().get_terrain_info(bg).editor_image() + ".png"));
00147
00148 if (image_fg == NULL || image_bg == NULL) {
00149 ERR_ED << "Missing terrain icon\n";
00150 disp.set_mouseover_hex_overlay(NULL);
00151 return;
00152 }
00153
00154
00155 surface image = create_compatible_surface(image_fg, image_fg->w, image_fg->h);
00156 sdl_fill_rect(image,NULL,SDL_MapRGBA(image->format,0,0,0, 0));
00157
00158
00159
00160
00161
00162
00163
00164 static const Uint8 alpha = 196;
00165 static const int size = image_fg->w;
00166 static const int half_size = size / 2;
00167 static const int quarter_size = size / 4;
00168 static const int offset = 2;
00169 static const int new_size = half_size - 2;
00170 const int zoom = static_cast<int>(size * disp.get_zoom_factor());
00171
00172
00173 image_fg = scale_surface(image_fg, new_size, new_size);
00174 SDL_Rect rcDestLeft = create_rect(offset, quarter_size, 0, 0);
00175 sdl_blit ( image_fg, NULL, image, &rcDestLeft );
00176
00177
00178 image_bg = scale_surface(image_bg, new_size, new_size);
00179 SDL_Rect rcDestRight = create_rect(half_size, quarter_size, 0, 0);
00180 sdl_blit ( image_bg, NULL, image, &rcDestRight );
00181
00182
00183 image = mask_surface(image, image::get_hexmask());
00184
00185
00186 image = scale_surface(adjust_surface_alpha(image, alpha), zoom, zoom);
00187
00188
00189 disp.set_mouseover_hex_overlay(image);
00190 }
00191
00192 std::set<map_location> brush_drag_mouse_action::affected_hexes(
00193 editor_display& , const map_location& hex)
00194 {
00195 return get_brush().project(hex);
00196 }
00197
00198 editor_action* brush_drag_mouse_action::click_left(editor_display& disp, int x, int y)
00199 {
00200 map_location hex = disp.hex_clicked_on(x, y);
00201 previous_drag_hex_ = hex;
00202 return click_perform_left(disp, affected_hexes(disp, hex));
00203 }
00204
00205 editor_action* brush_drag_mouse_action::click_right(editor_display& disp, int x, int y)
00206 {
00207 map_location hex = disp.hex_clicked_on(x, y);
00208 previous_drag_hex_ = hex;
00209 return click_perform_right(disp, affected_hexes(disp, hex));
00210 }
00211
00212 editor_action* brush_drag_mouse_action::drag_left(editor_display& disp,
00213 int x, int y, bool& partial, editor_action* last_undo)
00214 {
00215 return drag_generic<&brush_drag_mouse_action::click_perform_left>(disp, x, y, partial, last_undo);
00216 }
00217
00218 editor_action* brush_drag_mouse_action::drag_right(editor_display& disp,
00219 int x, int y, bool& partial, editor_action* last_undo)
00220 {
00221 return drag_generic<&brush_drag_mouse_action::click_perform_right>(disp, x, y, partial, last_undo);
00222 }
00223
00224 editor_action* brush_drag_mouse_action::drag_end(
00225 editor_display& , int , int )
00226 {
00227 return NULL;
00228 }
00229
00230 template <editor_action* (brush_drag_mouse_action::*perform_func)(editor_display&, const std::set<map_location>&)>
00231 editor_action* brush_drag_mouse_action::drag_generic(editor_display& disp, int x, int y, bool& partial, editor_action* last_undo)
00232 {
00233 map_location hex = disp.hex_clicked_on(x, y);
00234 move(disp, hex);
00235 if (hex != previous_drag_hex_) {
00236 std::set<map_location> current_step_locs = affected_hexes(disp, hex);
00237 editor_action_extendable* last_undo_x = dynamic_cast<editor_action_extendable*>(last_undo);
00238 LOG_ED << "Last undo is " << last_undo << " and as x " << last_undo_x << "\n";
00239 partial = true;
00240 editor_action* a = (this->*perform_func)(disp, affected_hexes(disp, hex));
00241 previous_drag_hex_ = hex;
00242 return a;
00243 } else {
00244 return NULL;
00245 }
00246 }
00247
00248 const brush& brush_drag_mouse_action::get_brush()
00249 {
00250 assert(brush_);
00251 assert(*brush_);
00252 return **brush_;
00253 }
00254
00255
00256 editor_action* mouse_action_paint::click_left(editor_display& disp, int x, int y)
00257 {
00258 if (has_ctrl_modifier()) {
00259 map_location hex = disp.hex_clicked_on(x, y);
00260 set_selected_fg_terrain(disp.map().get_terrain(hex));
00261 return NULL;
00262 } else {
00263 return brush_drag_mouse_action::click_left(disp, x, y);
00264 }
00265 }
00266
00267 editor_action* mouse_action_paint::click_right(editor_display& disp, int x, int y)
00268 {
00269 if (has_ctrl_modifier()) {
00270 map_location hex = disp.hex_clicked_on(x, y);
00271 set_selected_bg_terrain(disp.map().get_terrain(hex));
00272 return NULL;
00273 } else {
00274 return brush_drag_mouse_action::click_right(disp, x, y);
00275 }
00276 }
00277
00278 editor_action* mouse_action_paint::click_perform_left(
00279 editor_display& , const std::set<map_location>& hexes)
00280 {
00281 if (has_ctrl_modifier()) return NULL;
00282 return new editor_action_chain(new editor_action_paint_area(
00283 hexes, terrain_palette_.selected_fg_item(), has_shift_modifier()));
00284 }
00285
00286 editor_action* mouse_action_paint::click_perform_right(
00287 editor_display& , const std::set<map_location>& hexes)
00288 {
00289 if (has_ctrl_modifier()) return NULL;
00290 return new editor_action_chain(new editor_action_paint_area(
00291 hexes, terrain_palette_.selected_bg_item(), has_shift_modifier()));
00292 }
00293
00294 void mouse_action_paint::set_mouse_overlay(editor_display& disp)
00295 {
00296 set_terrain_mouse_overlay(disp, terrain_palette_.selected_fg_item(),
00297 terrain_palette_.selected_bg_item());
00298 }
00299
00300
00301 std::set<map_location> mouse_action_select::affected_hexes(
00302 editor_display& disp, const map_location& hex)
00303 {
00304 if (has_shift_modifier()) {
00305 return disp.map().get_contiguous_terrain_tiles(hex);
00306 } else {
00307 return brush_drag_mouse_action::affected_hexes(disp, hex);
00308 }
00309 }
00310
00311 editor_action* mouse_action_select::key_event(
00312 editor_display& disp, const SDL_Event& event)
00313 {
00314 editor_action* ret = mouse_action::key_event(disp, event);
00315 update_brush_highlights(disp, previous_move_hex_);
00316 return ret;
00317 }
00318
00319 editor_action* mouse_action_select::click_perform_left(
00320 editor_display& , const std::set<map_location>& hexes)
00321 {
00322 return new editor_action_chain(new editor_action_select(hexes));
00323 }
00324
00325 editor_action* mouse_action_select::click_perform_right(
00326 editor_display& , const std::set<map_location>& hexes)
00327 {
00328 return new editor_action_chain(new editor_action_deselect(hexes));
00329 }
00330
00331 void mouse_action_select::set_mouse_overlay(editor_display& disp)
00332 {
00333 surface image;
00334 if (has_shift_modifier()) {
00335 image = image::get_image("editor/tool-overlay-select-wand.png");
00336 } else {
00337 image = image::get_image("editor/tool-overlay-select-brush.png");
00338 }
00339 Uint8 alpha = 196;
00340 int size = image->w;
00341 int zoom = static_cast<int>(size * disp.get_zoom_factor());
00342
00343
00344 image = scale_surface(adjust_surface_alpha(image, alpha), zoom, zoom);
00345 disp.set_mouseover_hex_overlay(image);
00346 }
00347
00348
00349 bool mouse_action_paste::has_context_menu() const
00350 {
00351 return true;
00352 }
00353
00354 std::set<map_location> mouse_action_paste::affected_hexes(
00355 editor_display& , const map_location& hex)
00356 {
00357 return paste_.get_offset_area(hex);
00358 }
00359
00360 editor_action* mouse_action_paste::click_left(editor_display& disp, int x, int y)
00361 {
00362 map_location hex = disp.hex_clicked_on(x, y);
00363 editor_action_paste* a = new editor_action_paste(paste_, hex);
00364 return a;
00365 }
00366
00367 editor_action* mouse_action_paste::click_right(editor_display& , int , int )
00368 {
00369 return NULL;
00370 }
00371
00372 void mouse_action_paste::set_mouse_overlay(editor_display& disp)
00373 {
00374 disp.set_mouseover_hex_overlay(NULL);
00375 }
00376
00377 std::set<map_location> mouse_action_fill::affected_hexes(
00378 editor_display& disp, const map_location& hex)
00379 {
00380 return disp.map().get_contiguous_terrain_tiles(hex);
00381 }
00382
00383 editor_action* mouse_action_fill::click_left(editor_display& disp, int x, int y)
00384 {
00385 map_location hex = disp.hex_clicked_on(x, y);
00386 if (has_ctrl_modifier()) {
00387 set_selected_fg_terrain(disp.map().get_terrain(hex));
00388 return NULL;
00389 } else {
00390
00391
00392 editor_action_fill* a = new editor_action_fill(hex, terrain_palette_.selected_fg_item(),
00393 has_shift_modifier());
00394 return a;
00395 }
00396 }
00397
00398 editor_action* mouse_action_fill::click_right(editor_display& disp, int x, int y)
00399 {
00400 map_location hex = disp.hex_clicked_on(x, y);
00401 if (has_ctrl_modifier()) {
00402 set_selected_bg_terrain(disp.map().get_terrain(hex));
00403 return NULL;
00404 } else {
00405
00406
00407 editor_action_fill* a = new editor_action_fill(hex, terrain_palette_.selected_bg_item(),
00408 has_shift_modifier());
00409 return a;
00410 }
00411 }
00412
00413 void mouse_action_fill::set_mouse_overlay(editor_display& disp)
00414 {
00415 set_terrain_mouse_overlay(disp, terrain_palette_.selected_fg_item(),
00416 terrain_palette_.selected_bg_item());
00417 }
00418
00419 editor_action* mouse_action_starting_position::up_left(editor_display& disp, int x, int y)
00420 {
00421 if (!click_) return NULL;
00422 click_ = false;
00423 map_location hex = disp.hex_clicked_on(x, y);
00424 if (!disp.map().on_board(hex)) {
00425 return NULL;
00426 }
00427
00428 const unsigned player_starting_at_hex =
00429 static_cast<unsigned>(disp.map().is_starting_position(hex) + 1);
00430
00431 std::vector<map_location> starting_positions;
00432
00433 for(int i = 1; i <= gamemap::MAX_PLAYERS; ++i) {
00434 starting_positions.push_back(disp.map().starting_position(i));
00435 }
00436
00437 gui2::teditor_set_starting_position dlg(
00438 player_starting_at_hex, gamemap::MAX_PLAYERS, starting_positions);
00439 dlg.show(disp.video());
00440
00441 unsigned new_player_at_hex = dlg.result();
00442 editor_action* a = NULL;
00443
00444 if(new_player_at_hex != player_starting_at_hex) {
00445 if(!new_player_at_hex) {
00446
00447 a = new editor_action_starting_position(map_location(), player_starting_at_hex);
00448 } else {
00449
00450 a = new editor_action_starting_position(hex, new_player_at_hex);
00451 }
00452 }
00453
00454 update_brush_highlights(disp, hex);
00455
00456 return a;
00457 }
00458
00459 editor_action* mouse_action_starting_position::click_left(editor_display& , int , int )
00460 {
00461 click_ = true;
00462 return NULL;
00463 }
00464
00465 editor_action* mouse_action_starting_position::up_right(editor_display& disp, int x, int y)
00466 {
00467 map_location hex = disp.hex_clicked_on(x, y);
00468 int player_starting_at_hex = disp.map().is_starting_position(hex) + 1;
00469 if (player_starting_at_hex != -1) {
00470 return new editor_action_starting_position(map_location(), player_starting_at_hex);
00471 } else {
00472 return NULL;
00473 }
00474 }
00475
00476 editor_action* mouse_action_starting_position::click_right(editor_display& , int , int )
00477 {
00478 return NULL;
00479 }
00480
00481 void mouse_action_starting_position::set_mouse_overlay(editor_display& disp)
00482 {
00483 surface image = image::get_image("editor/tool-overlay-starting-position.png");
00484 Uint8 alpha = 196;
00485 int size = image->w;
00486 int zoom = static_cast<int>(size * disp.get_zoom_factor());
00487
00488
00489 image = scale_surface(adjust_surface_alpha(image, alpha), zoom, zoom);
00490 disp.set_mouseover_hex_overlay(image);
00491 }
00492
00493
00494 }