Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #define GETTEXT_DOMAIN "wesnoth-lib"
00017
00018 #include "global.hpp"
00019
00020 #include "widgets/combo_drag.hpp"
00021
00022
00023
00024 namespace gui {
00025
00026 const float combo_drag::MIN_DRAG_DISTANCE = 10.0;
00027 const float combo_drag::RETURN_SPEED = 25.0;
00028
00029 combo_drag::combo_drag(display& disp
00030 , const std::vector<std::string>& items
00031 , const drop_group_manager_ptr group)
00032 : combo(disp, items)
00033 , drop_target(group, location())
00034 , drag_target_(-1)
00035 , old_drag_target_(-1)
00036 , old_location_()
00037 , mouse_x_(-1)
00038 , mouse_y_(-1)
00039 , drag_(NONE)
00040 {
00041 }
00042
00043 int combo_drag::get_drop_target()
00044 {
00045 old_drag_target_ = drag_target_;
00046 drag_target_ = -1;
00047 return old_drag_target_;
00048 }
00049
00050 void combo_drag::handle_move(const SDL_MouseMotionEvent& event)
00051 {
00052 if (drag_ == PRESSED)
00053 {
00054 aquire_mouse_lock();
00055 old_location_ = location();
00056 drag_ = PRESSED_MOVE;
00057 }
00058 const int diff_x = event.x - mouse_x_;
00059 const int diff_y = event.y - mouse_y_;
00060 if (drag_ == PRESSED_MOVE
00061 && std::sqrt(static_cast<float>(diff_x*diff_x + diff_y*diff_y)) > MIN_DRAG_DISTANCE)
00062 {
00063 return;
00064 }
00065 drag_ = MOVED;
00066 SDL_Rect loc = old_location_;
00067 loc.x += diff_x;
00068 loc.y += diff_y;
00069
00070
00071
00072
00073 if (clip_rect())
00074 {
00075 const SDL_Rect *clip = clip_rect();
00076 if (loc.x < clip->x)
00077 loc.x = clip->x;
00078 if (loc.x + loc.w > clip->x + clip->w)
00079 loc.x = clip->x + clip->w - loc.w;
00080 if (loc.y < clip->y)
00081 loc.y = clip->y;
00082 if (loc.y + loc.h > clip->y + clip->h)
00083 loc.y = clip->y + clip->h - loc.h;
00084 }
00085
00086 set_location(loc);
00087 }
00088
00089 void combo_drag::process(events::pump_info& )
00090 {
00091 if (drag_ == RETURN)
00092 {
00093 SDL_Rect loc = location();
00094 int x_diff = loc.x - old_location_.x;
00095 int y_diff = loc.y - old_location_.y;
00096 const float length = std::sqrt(static_cast<float>(x_diff*x_diff + y_diff*y_diff));
00097
00098 if (length > RETURN_SPEED)
00099 {
00100 loc.x -= static_cast<Sint16>(x_diff*(RETURN_SPEED/length));
00101 loc.y -= static_cast<Sint16>(y_diff*(RETURN_SPEED/length));
00102 set_location(loc);
00103 }
00104 else
00105 {
00106 drag_ = NONE;
00107 set_location(old_location_);
00108 }
00109 }
00110 }
00111
00112 void combo_drag::handle_drop()
00113 {
00114 drag_target_ = drop_target::handle_drop();
00115 }
00116
00117 void combo_drag::mouse_motion(const SDL_MouseMotionEvent& event)
00118 {
00119 if (drag_ == PRESSED
00120 || drag_ == MOVED
00121 || drag_ == PRESSED_MOVE)
00122 {
00123 handle_move(event);
00124 } else {
00125 button::mouse_motion(event);
00126 }
00127 }
00128
00129 void combo_drag::mouse_up(const SDL_MouseButtonEvent& event)
00130 {
00131 if ((drag_ == PRESSED || drag_ == PRESSED_MOVE || drag_ == MOVED) && event.button == SDL_BUTTON_LEFT)
00132 {
00133 if (drag_ == PRESSED
00134 || drag_ == PRESSED_MOVE)
00135 {
00136 free_mouse_lock();
00137 drag_ = DROP_DOWN;
00138 }
00139 else if (drag_ == MOVED)
00140 {
00141 free_mouse_lock();
00142 handle_drop();
00143 drag_ = RETURN;
00144 hide();
00145 }
00146 }
00147 button::mouse_up(event);
00148
00149 }
00150
00151 void combo_drag::mouse_down(const SDL_MouseButtonEvent& event)
00152 {
00153 if (hit(event.x, event.y) && event.button == SDL_BUTTON_LEFT)
00154 {
00155 drag_ = PRESSED;
00156 mouse_x_ = event.x;
00157 mouse_y_ = event.y;
00158 }
00159 button::mouse_down(event);
00160 }
00161
00162 void combo_drag::process_event()
00163 {
00164 if (drag_ == DROP_DOWN)
00165 {
00166 drag_ = NONE;
00167 make_drop_down_menu();
00168 }
00169 }
00170
00171 }