void button::handle_event(const SDL_Event& event) { if (hidden() || !enabled()) return; STATE start_state = state_; if (!mouse_locked()) { switch(event.type) { case SDL_MOUSEBUTTONDOWN: mouse_down(event.button); break; case SDL_MOUSEBUTTONUP: mouse_up(event.button); break; case SDL_MOUSEMOTION: mouse_motion(event.motion); break; default: return; } } if (start_state != state_) set_dirty(true); }
void slider::handle_event(const SDL_Event& event) { gui::widget::handle_event(event); if (!enabled() || hidden()) return; STATE start_state = state_; switch(event.type) { case SDL_MOUSEBUTTONUP: if (!mouse_locked()) { bool on = sdl::point_in_rect(event.button.x, event.button.y, slider_area()); state_ = on ? ACTIVE : NORMAL; } break; case SDL_MOUSEBUTTONDOWN: if (!mouse_locked()) mouse_down(event.button); break; case SDL_MOUSEMOTION: if (!mouse_locked()) mouse_motion(event.motion); break; case SDL_KEYDOWN: if(focus(&event) && allow_key_events()) { //allow_key_events is used by zoom_sliders to disable left-right key press, which is buggy for them const SDL_Keysym& key = reinterpret_cast<const SDL_KeyboardEvent&>(event).keysym; const int c = key.sym; if(c == SDLK_LEFT) { sound::play_UI_sound(game_config::sounds::slider_adjust); set_value(value_ - increment_); } else if(c == SDLK_RIGHT) { sound::play_UI_sound(game_config::sounds::slider_adjust); set_value(value_ + increment_); } } break; case SDL_MOUSEWHEEL: if (!mouse_locked()) mouse_wheel(event.wheel); break; default: return; } if (start_state != state_) set_dirty(true); }
void slider::handle_event(const SDL_Event& event) { if (!enabled() || hidden()) return; STATE start_state = state_; switch(event.type) { case SDL_MOUSEBUTTONUP: if (!mouse_locked()) state_ = NORMAL; break; case SDL_MOUSEBUTTONDOWN: if (!mouse_locked()) mouse_down(event.button); break; case SDL_MOUSEMOTION: if (!mouse_locked()) mouse_motion(event.motion); break; case SDL_KEYDOWN: if(focus(&event)) { const SDL_keysym& key = reinterpret_cast<const SDL_KeyboardEvent&>(event).keysym; const int c = key.sym; if(c == SDLK_LEFT) { sound::play_UI_sound(game_config::sounds::slider_adjust); set_value(value_ - increment_); } else if(c == SDLK_RIGHT) { sound::play_UI_sound(game_config::sounds::slider_adjust); set_value(value_ + increment_); } } break; default: return; } if (start_state != state_) set_dirty(true); }
void scrollarea::handle_event(const SDL_Event& event) { if (mouse_locked() || hidden() || event.type != SDL_MOUSEBUTTONDOWN) return; SDL_MouseButtonEvent const &e = event.button; if (point_in_rect(e.x, e.y, inner_location())) { if (e.button == SDL_BUTTON_WHEELDOWN) { scrollbar_.scroll_down(); } else if (e.button == SDL_BUTTON_WHEELUP) { scrollbar_.scroll_up(); } } }
void scrollarea::handle_event(const SDL_Event& event) { gui::widget::handle_event(event); if (mouse_locked() || hidden()) return; if (event.type != SDL_MOUSEWHEEL) return; const SDL_MouseWheelEvent &ev = event.wheel; int x, y; SDL_GetMouseState(&x, &y); if (sdl::point_in_rect(x, y, inner_location())) { if (ev.y > 0) { scrollbar_.scroll_up(); } else if (ev.y < 0) { scrollbar_.scroll_down(); } } }
void textbox::handle_event(const SDL_Event& event) { scrollarea::handle_event(event); if(hidden()) return; bool changed = false; const int old_selstart = selstart_; const int old_selend = selend_; //Sanity check: verify that selection start and end are within text //boundaries if(is_selection() && !(size_t(selstart_) <= text_.size() && size_t(selend_) <= text_.size())) { WRN_DP << "out-of-boundary selection\n"; selstart_ = selend_ = -1; } int mousex, mousey; const Uint8 mousebuttons = SDL_GetMouseState(&mousex,&mousey); if(!(mousebuttons & SDL_BUTTON(1))) { grabmouse_ = false; } SDL_Rect const &loc = inner_location(); bool clicked_inside = !mouse_locked() && (event.type == SDL_MOUSEBUTTONDOWN && (mousebuttons & SDL_BUTTON(1)) && point_in_rect(mousex, mousey, loc)); if(clicked_inside) { set_focus(true); } if ((grabmouse_ && (!mouse_locked() && event.type == SDL_MOUSEMOTION)) || clicked_inside) { const int x = mousex - loc.x + text_pos_; const int y = mousey - loc.y; int pos = 0; int distance = x; for(unsigned int i = 1; i < char_x_.size(); ++i) { if(static_cast<int>(yscroll_) + y < char_y_[i]) { break; } // Check individually each distance (if, one day, we support // RTL languages, char_x_[c] may not be monotonous.) if(abs(x - char_x_[i]) < distance && yscroll_ + y < char_y_[i] + line_height_) { pos = i; distance = abs(x - char_x_[i]); } } cursor_ = pos; if(grabmouse_) selend_ = cursor_; update_text_cache(false); if(!grabmouse_ && mousebuttons & SDL_BUTTON(1)) { grabmouse_ = true; selstart_ = selend_ = cursor_; } else if (! (mousebuttons & SDL_BUTTON(1))) { grabmouse_ = false; } set_dirty(); } if(editable_ == false) { return; } //if we don't have the focus, then see if we gain the focus, //otherwise return if(focus(&event) == false) { if (!mouse_locked() && event.type == SDL_MOUSEMOTION && point_in_rect(mousex, mousey, loc)) events::focus_handler(this); return; } if(event.type != SDL_KEYDOWN || focus(&event) != true) { draw(); return; } const SDL_keysym& key = reinterpret_cast<const SDL_KeyboardEvent&>(event).keysym; const SDLMod modifiers = SDL_GetModState(); const int c = key.sym; const int old_cursor = cursor_; if(c == SDLK_LEFT && cursor_ > 0) --cursor_; if(c == SDLK_RIGHT && cursor_ < static_cast<int>(text_.size())) ++cursor_; // ctrl-a, ctrl-e and ctrl-u are readline style shortcuts, even on Macs if(c == SDLK_END || (c == SDLK_e && (modifiers & KMOD_CTRL))) cursor_ = text_.size(); if(c == SDLK_HOME || (c == SDLK_a && (modifiers & KMOD_CTRL))) cursor_ = 0; if((old_cursor != cursor_) && (modifiers & KMOD_SHIFT)) { if(selstart_ == -1) selstart_ = old_cursor; selend_ = cursor_; } if(c == SDLK_BACKSPACE) { changed = true; if(is_selection()) { erase_selection(); } else if(cursor_ > 0) { --cursor_; text_.erase(text_.begin()+cursor_); } } if(c == SDLK_u && (modifiers & KMOD_CTRL)) { // clear line changed = true; cursor_ = 0; text_.resize(0); } if(c == SDLK_DELETE && !text_.empty()) { changed = true; if(is_selection()) { erase_selection(); } else { if(cursor_ < static_cast<int>(text_.size())) { text_.erase(text_.begin()+cursor_); } } } wchar_t character = key.unicode; //movement characters may have a "Unicode" field on some platforms, so ignore it. if(!(c == SDLK_UP || c == SDLK_DOWN || c == SDLK_LEFT || c == SDLK_RIGHT || c == SDLK_DELETE || c == SDLK_BACKSPACE || c == SDLK_END || c == SDLK_HOME || c == SDLK_PAGEUP || c == SDLK_PAGEDOWN)) { if(character != 0) { DBG_G << "Char: " << character << ", c = " << c << "\n"; } if(event.key.keysym.mod & copypaste_modifier) { switch(c) { case SDLK_v: // paste { changed = true; if(is_selection()) erase_selection(); std::string str = copy_from_clipboard(false); //cut off anything after the first newline str.erase(std::find_if(str.begin(),str.end(),utils::isnewline),str.end()); wide_string s = utils::string_to_wstring(str); if(text_.size() < max_size_) { if(s.size() + text_.size() > max_size_) { s.resize(max_size_ - text_.size()); } text_.insert(text_.begin()+cursor_, s.begin(), s.end()); cursor_ += s.size(); } } break; case SDLK_c: // copy { const size_t beg = std::min<size_t>(size_t(selstart_),size_t(selend_)); const size_t end = std::max<size_t>(size_t(selstart_),size_t(selend_)); wide_string ws = wide_string(text_.begin() + beg, text_.begin() + end); std::string s = utils::wstring_to_string(ws); copy_to_clipboard(s, false); } break; } } else { if(character >= 32 && character != 127) { changed = true; if(is_selection()) erase_selection(); if(text_.size() + 1 <= max_size_) { text_.insert(text_.begin()+cursor_,character); ++cursor_; } } } } if(is_selection() && (selend_ != cursor_)) selstart_ = selend_ = -1; //since there has been cursor activity, make the cursor appear for //at least the next 500ms. show_cursor_ = true; show_cursor_at_ = SDL_GetTicks(); if(changed || old_cursor != cursor_ || old_selstart != selstart_ || old_selend != selend_) { text_image_ = NULL; handle_text_changed(text_); } set_dirty(true); }
void menu::handle_event(const SDL_Event& event) { scrollarea::handle_event(event); if (height()==0 || hidden()) return; if(event.type == SDL_KEYDOWN) { // Only pass key events if we have the focus if (focus(&event)) key_press(event.key.keysym.sym); } else if(!mouse_locked() && ((event.type == SDL_MOUSEBUTTONDOWN && (event.button.button == SDL_BUTTON_LEFT || event.button.button == SDL_BUTTON_RIGHT)) || event.type == DOUBLE_CLICK_EVENT)) { int x = 0; int y = 0; if(event.type == SDL_MOUSEBUTTONDOWN) { x = event.button.x; y = event.button.y; } else { x = reinterpret_cast<long>(event.user.data1); y = reinterpret_cast<long>(event.user.data2); } const int item = hit(x,y); if(item != -1) { set_focus(true); move_selection_to(item); if(click_selects_) { show_result_ = true; } if(event.type == DOUBLE_CLICK_EVENT) { if (ignore_next_doubleclick_) { ignore_next_doubleclick_ = false; } else { double_clicked_ = true; last_was_doubleclick_ = true; if(!silent_) { sound::play_UI_sound(game_config::sounds::button_press); } } } else if (last_was_doubleclick_) { // If we have a double click as the next event, it means // this double click was generated from a click that // already has helped in generating a double click. SDL_Event ev; SDL_PeepEvents(&ev, 1, SDL_PEEKEVENT, SDL_EVENTMASK(DOUBLE_CLICK_EVENT)); if (ev.type == DOUBLE_CLICK_EVENT) { ignore_next_doubleclick_ = true; } last_was_doubleclick_ = false; } } if(sorter_ != NULL) { const int heading = hit_heading(x,y); if(heading >= 0 && sorter_->column_sortable(heading)) { sort_by(heading); } } } else if(!mouse_locked() && event.type == SDL_MOUSEMOTION) { if(click_selects_) { const int item = hit(event.motion.x,event.motion.y); const bool out = (item == -1); if (out_ != out) { out_ = out; invalidate_row_pos(selected_); } if (item != -1) { move_selection_to(item); } } const int heading_item = hit_heading(event.motion.x,event.motion.y); if(heading_item != highlight_heading_) { highlight_heading_ = heading_item; invalidate_heading(); } } }
void scrollbar::handle_event(const SDL_Event& event) { gui::widget::handle_event(event); if (mouse_locked() || hidden()) return; STATE new_state = state_; SDL_Rect const &grip = grip_area(); SDL_Rect const &groove = groove_area(); switch (event.type) { case SDL_MOUSEBUTTONUP: { SDL_MouseButtonEvent const &e = event.button; bool on_grip = sdl::point_in_rect(e.x, e.y, grip); new_state = on_grip ? ACTIVE : NORMAL; break; } case SDL_MOUSEBUTTONDOWN: { SDL_MouseButtonEvent const &e = event.button; bool on_grip = sdl::point_in_rect(e.x, e.y, grip); bool on_groove = sdl::point_in_rect(e.x, e.y, groove); #if !SDL_VERSION_ATLEAST(2,0,0) if (on_groove && e.button == SDL_BUTTON_WHEELDOWN) { move_position(scroll_rate_); } else if (on_groove && e.button == SDL_BUTTON_WHEELUP) { move_position(-scroll_rate_); } else #endif if (on_grip && e.button == SDL_BUTTON_LEFT) { mousey_on_grip_ = e.y - grip.y; new_state = DRAGGED; } else if (on_groove && e.button == SDL_BUTTON_LEFT && groove.h != grip.h) { if (e.y < grip.y) move_position(-static_cast<int>(grip_height_)); else move_position(grip_height_); } else if (on_groove && e.button == SDL_BUTTON_MIDDLE) { int y_dep = e.y - grip.y - grip.h/2; int dep = y_dep * int(full_height_ - grip_height_)/ (groove.h - grip.h); move_position(dep); } break; } case SDL_MOUSEMOTION: { SDL_MouseMotionEvent const &e = event.motion; if (state_ == NORMAL || state_ == ACTIVE) { bool on_grip = sdl::point_in_rect(e.x, e.y, grip); new_state = on_grip ? ACTIVE : NORMAL; } else if (state_ == DRAGGED && groove.h != grip.h) { int y_dep = e.y - grip.y - mousey_on_grip_; int dep = y_dep * static_cast<int>(full_height_ - grip_height_) / (groove.h - grip.h); move_position(dep); } break; } #if SDL_VERSION_ATLEAST(2,0,0) case SDL_MOUSEWHEEL: { const SDL_MouseWheelEvent& e = event.wheel; int x, y; SDL_GetMouseState(&x, &y); bool on_groove = sdl::point_in_rect(x, y, groove); if (on_groove && e.y < 0) { move_position(scroll_rate_); } else if (on_groove && e.y > 0) { move_position(-scroll_rate_); } break; } #endif default: break; } if (new_state != state_) { set_dirty(); mid_scaled_.assign(NULL); state_ = new_state; } }
void scrollbar::handle_event(const SDL_Event& event) { if (mouse_locked() || hidden()) return; STATE new_state = state_; SDL_Rect const &grip = grip_area(); SDL_Rect const &groove = groove_area(); switch (event.type) { case SDL_MOUSEBUTTONUP: { SDL_MouseButtonEvent const &e = event.button; bool on_grip = point_in_rect(e.x, e.y, grip); new_state = on_grip ? ACTIVE : NORMAL; break; } case SDL_MOUSEBUTTONDOWN: { SDL_MouseButtonEvent const &e = event.button; bool on_grip = point_in_rect(e.x, e.y, grip); bool on_groove = point_in_rect(e.x, e.y, groove); if (on_groove && e.button == SDL_BUTTON_WHEELDOWN) { move_position(scroll_rate_); } else if (on_groove && e.button == SDL_BUTTON_WHEELUP) { move_position(-scroll_rate_); } else if (on_grip && e.button == SDL_BUTTON_LEFT) { mousey_on_grip_ = e.y - grip.y; new_state = DRAGGED; } else if (on_groove && e.button == SDL_BUTTON_LEFT && groove.h != grip.h) { if (e.y < grip.y) move_position(-static_cast<int>(grip_height_)); else move_position(grip_height_); } else if (on_groove && e.button == SDL_BUTTON_MIDDLE) { int y_dep = e.y - grip.y - grip.h/2; int dep = y_dep * int(full_height_ - grip_height_)/ int(groove.h - grip.h); move_position(dep); } break; } case SDL_MOUSEMOTION: { SDL_MouseMotionEvent const &e = event.motion; if (state_ == NORMAL || state_ == ACTIVE) { bool on_grip = point_in_rect(e.x, e.y, grip); new_state = on_grip ? ACTIVE : NORMAL; } else if (state_ == DRAGGED && groove.h != grip.h) { int y_dep = e.y - grip.y - mousey_on_grip_; int dep = y_dep * static_cast<int>(full_height_ - grip_height_) / static_cast<int>(groove.h - grip.h); move_position(dep); } break; } default: break; } if ((new_state == NORMAL) ^ (state_ == NORMAL)) { set_dirty(); mid_scaled_.assign(NULL); } state_ = new_state; }
void scrollarea::handle_event(const SDL_Event& event) { gui::widget::handle_event(event); if (mouse_locked() || hidden()) return; if (event.type == SDL_MOUSEWHEEL) { const SDL_MouseWheelEvent &ev = event.wheel; int x, y; SDL_GetMouseState(&x, &y); if (sdl::point_in_rect(x, y, inner_location())) { if (ev.y > 0) { scrollbar_.scroll_up(); } else if (ev.y < 0) { scrollbar_.scroll_down(); } } } if (event.type == SDL_FINGERUP) { swipe_dy_ = 0; } if (event.type == SDL_FINGERDOWN || event.type == SDL_FINGERMOTION) { SDL_Rect r = video().screen_area(); auto tx = static_cast<int>(event.tfinger.x * r.w); auto ty = static_cast<int>(event.tfinger.y * r.h); auto dy = static_cast<int>(event.tfinger.dy * r.h); if (event.type == SDL_FINGERDOWN) { swipe_dy_ = 0; swipe_origin_.x = tx; swipe_origin_.y = ty; } if (event.type == SDL_FINGERMOTION) { swipe_dy_ += dy; if (scrollbar_.get_max_position() == 0) { return; } int scrollbar_step = scrollbar_.height() / scrollbar_.get_max_position(); if (scrollbar_step <= 0) { return; } if (sdl::point_in_rect(swipe_origin_.x, swipe_origin_.y, inner_location()) && abs(swipe_dy_) >= scrollbar_step) { unsigned int pos = std::max( static_cast<int>(scrollbar_.get_position() - swipe_dy_ / scrollbar_step), 0); scrollbar_.set_position(pos); swipe_dy_ %= scrollbar_step; } } } }