00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "mouse_handler_base.hpp"
00018
00019 #include "cursor.hpp"
00020 #include "display.hpp"
00021 #include "log.hpp"
00022 #include "preferences.hpp"
00023 #include "tooltips.hpp"
00024
00025 static lg::log_domain log_display("display");
00026 #define WRN_DP LOG_STREAM(warn, log_display)
00027
00028 namespace events {
00029
00030 command_disabler::command_disabler()
00031 {
00032 ++commands_disabled;
00033 }
00034
00035 command_disabler::~command_disabler()
00036 {
00037 --commands_disabled;
00038 }
00039
00040 int commands_disabled= 0;
00041
00042 static bool command_active()
00043 {
00044 #ifdef __APPLE__
00045 return (SDL_GetModState()&KMOD_META) != 0;
00046 #else
00047 return false;
00048 #endif
00049 }
00050
00051 mouse_handler_base::mouse_handler_base() :
00052 simple_warp_(false),
00053 minimap_scrolling_(false),
00054 dragging_left_(false),
00055 dragging_started_(false),
00056 dragging_right_(false),
00057 drag_from_x_(0),
00058 drag_from_y_(0),
00059 drag_from_hex_(),
00060 last_hex_(),
00061 show_menu_(false)
00062 {
00063 }
00064
00065 bool mouse_handler_base::is_dragging() const
00066 {
00067 return dragging_left_ || dragging_right_;
00068 }
00069
00070 void mouse_handler_base::mouse_motion_event(const SDL_MouseMotionEvent& event, const bool browse)
00071 {
00072 mouse_motion(event.x,event.y, browse);
00073 }
00074
00075 void mouse_handler_base::mouse_update(const bool browse, map_location loc)
00076 {
00077 int x, y;
00078 SDL_GetMouseState(&x,&y);
00079 mouse_motion(x, y, browse, true, loc);
00080 }
00081
00082 bool mouse_handler_base::mouse_motion_default(int x, int y, bool )
00083 {
00084 tooltips::process(x, y);
00085
00086 if(simple_warp_) {
00087 return true;
00088 }
00089
00090 if(minimap_scrolling_) {
00091
00092
00093
00094 minimap_scrolling_ = ((SDL_GetMouseState(NULL,NULL) & (SDL_BUTTON(1) | SDL_BUTTON(2))) != 0);
00095 if(minimap_scrolling_) {
00096 const map_location& loc = gui().minimap_location_on(x,y);
00097 if(loc.valid()) {
00098 if(loc != last_hex_) {
00099 last_hex_ = loc;
00100 gui().scroll_to_tile(loc,display::WARP,false);
00101 }
00102 } else {
00103
00104 minimap_scrolling_ = false;
00105 }
00106 }
00107 if(minimap_scrolling_) return true;
00108 }
00109
00110
00111
00112 int mx = drag_from_x_;
00113 int my = drag_from_y_;
00114 if (is_dragging() && !dragging_started_) {
00115 if ((dragging_left_ && (SDL_GetMouseState(&mx,&my) & SDL_BUTTON_LEFT) != 0)
00116 || (dragging_right_ && (SDL_GetMouseState(&mx,&my) & SDL_BUTTON_RIGHT) != 0)) {
00117 const double drag_distance = std::pow(static_cast<double>(drag_from_x_- mx), 2)
00118 + std::pow(static_cast<double>(drag_from_y_- my), 2);
00119 if (drag_distance > drag_threshold()*drag_threshold()) {
00120 dragging_started_ = true;
00121 cursor::set_dragging(true);
00122 }
00123 }
00124 }
00125 return false;
00126 }
00127
00128 void mouse_handler_base::mouse_press(const SDL_MouseButtonEvent& event, const bool browse)
00129 {
00130 if(is_middle_click(event) && !preferences::middle_click_scrolls()) {
00131 simple_warp_ = true;
00132 }
00133 show_menu_ = false;
00134 map_location loc = gui().hex_clicked_on(event.x,event.y);
00135 mouse_update(browse, loc);
00136 int scrollx = 0;
00137 int scrolly = 0;
00138
00139 if (is_left_click(event)) {
00140 if (event.state == SDL_PRESSED) {
00141 cancel_dragging();
00142 init_dragging(dragging_left_);
00143 left_click(event.x, event.y, browse);
00144 } else if (event.state == SDL_RELEASED) {
00145 minimap_scrolling_ = false;
00146 clear_dragging(event, browse);
00147 left_mouse_up(event.x, event.y, browse);
00148 }
00149 } else if (is_right_click(event)) {
00150 if (event.state == SDL_PRESSED) {
00151 cancel_dragging();
00152 init_dragging(dragging_right_);
00153 right_click(event.x, event.y, browse);
00154 } else if (event.state == SDL_RELEASED) {
00155 minimap_scrolling_ = false;
00156 clear_dragging(event, browse);
00157 right_mouse_up(event.x, event.y, browse);
00158 }
00159 } else if (is_middle_click(event)) {
00160 if (event.state == SDL_PRESSED) {
00161 map_location loc = gui().minimap_location_on(event.x,event.y);
00162 minimap_scrolling_ = false;
00163 if(loc.valid()) {
00164 simple_warp_ = false;
00165 minimap_scrolling_ = true;
00166 last_hex_ = loc;
00167 gui().scroll_to_tile(loc,display::WARP,false);
00168 } else if(simple_warp_) {
00169
00170 loc = gui().hex_clicked_on(event.x,event.y);
00171 if(loc.valid()) {
00172 last_hex_ = loc;
00173 gui().scroll_to_tile(loc,display::WARP,false);
00174 }
00175 }
00176 } else if (event.state == SDL_RELEASED) {
00177 minimap_scrolling_ = false;
00178 simple_warp_ = false;
00179 }
00180 } else if (allow_mouse_wheel_scroll(event.x, event.y)) {
00181 if (event.button == SDL_BUTTON_WHEELUP) {
00182 scrolly = - preferences::scroll_speed();
00183 } else if (event.button == SDL_BUTTON_WHEELDOWN) {
00184 scrolly = preferences::scroll_speed();
00185 } else if (event.button == SDL_BUTTON_WHEELLEFT) {
00186 scrollx = - preferences::scroll_speed();
00187 } else if (event.button == SDL_BUTTON_WHEELRIGHT) {
00188 scrollx = preferences::scroll_speed();
00189 }
00190 }
00191
00192 if (scrollx != 0 || scrolly != 0) {
00193 CKey pressed;
00194
00195 if (pressed[SDLK_LALT] || pressed[SDLK_RALT])
00196 gui().scroll(scrolly,scrollx);
00197 else
00198 gui().scroll(scrollx,scrolly);
00199 }
00200 if (!dragging_left_ && !dragging_right_ && dragging_started_) {
00201 dragging_started_ = false;
00202 cursor::set_dragging(false);
00203 }
00204 mouse_update(browse, loc);
00205 }
00206
00207 bool mouse_handler_base::is_left_click(
00208 const SDL_MouseButtonEvent& event) const
00209 {
00210 return event.button == SDL_BUTTON_LEFT && !command_active();
00211 }
00212
00213 bool mouse_handler_base::is_middle_click(
00214 const SDL_MouseButtonEvent& event) const
00215 {
00216 return event.button == SDL_BUTTON_MIDDLE;
00217 }
00218
00219 bool mouse_handler_base::is_right_click(
00220 const SDL_MouseButtonEvent& event) const
00221 {
00222 return event.button == SDL_BUTTON_RIGHT
00223 || (event.button == SDL_BUTTON_LEFT && command_active());
00224 }
00225
00226 bool mouse_handler_base::allow_mouse_wheel_scroll(int , int )
00227 {
00228 return true;
00229 }
00230
00231 bool mouse_handler_base::right_click_show_menu(int , int , const bool )
00232 {
00233 return true;
00234 }
00235
00236 bool mouse_handler_base::left_click(int x, int y, const bool )
00237 {
00238 if(tooltips::click(x,y))
00239 return true;
00240
00241
00242 const map_location& loc = gui().minimap_location_on(x, y);
00243 minimap_scrolling_ = false;
00244 if(loc.valid()) {
00245 minimap_scrolling_ = true;
00246 last_hex_ = loc;
00247 gui().scroll_to_tile(loc,display::WARP, false);
00248 return true;
00249 }
00250 return false;
00251 }
00252
00253 void mouse_handler_base::left_drag_end(int x, int y, const bool browse)
00254 {
00255 left_click(x, y, browse);
00256 }
00257
00258 void mouse_handler_base::left_mouse_up(int , int , const bool )
00259 {
00260 }
00261
00262 bool mouse_handler_base::right_click(int x, int y, const bool browse)
00263 {
00264 if (right_click_show_menu(x, y, browse)) {
00265 gui().draw();
00266 const theme::menu* const m = gui().get_theme().context_menu();
00267 if (m != NULL) {
00268 show_menu_ = true;
00269 } else {
00270 WRN_DP << "no context menu found...\n";
00271 }
00272 return true;
00273 }
00274 return false;
00275 }
00276
00277 void mouse_handler_base::right_drag_end(int , int , const bool )
00278 {
00279
00280
00281 }
00282
00283 void mouse_handler_base::right_mouse_up(int , int , const bool )
00284 {
00285 }
00286
00287 void mouse_handler_base::init_dragging(bool& dragging_flag)
00288 {
00289 dragging_flag = true;
00290 SDL_GetMouseState(&drag_from_x_, &drag_from_y_);
00291 drag_from_hex_ = gui().hex_clicked_on(drag_from_x_, drag_from_y_);
00292 }
00293
00294 void mouse_handler_base::cancel_dragging()
00295 {
00296 dragging_started_ = false;
00297 dragging_left_ = false;
00298 dragging_right_ = false;
00299 cursor::set_dragging(false);
00300 }
00301
00302 void mouse_handler_base::clear_dragging(const SDL_MouseButtonEvent& event, bool browse)
00303 {
00304
00305
00306
00307 cursor::set_dragging(false);
00308 if (dragging_started_) {
00309 dragging_started_ = false;
00310 if (dragging_left_) {
00311 dragging_left_ = false;
00312 left_drag_end(event.x, event.y, browse);
00313 }
00314 if (dragging_right_) {
00315 dragging_right_ = false;
00316 right_drag_end(event.x, event.y, browse);
00317 }
00318 } else {
00319 dragging_left_ = false;
00320 dragging_right_ = false;
00321 }
00322 }
00323
00324
00325 }