void textedit_draw_update ( struct widget *self ) { g_error e; struct cursor * c; if (!DATA->update_clean) { /* Translate to screen coordinates */ DATA->update_x1 += self->in->div->r.x; DATA->update_x2 += self->in->div->r.x; DATA->update_y1 += self->in->div->r.y; DATA->update_y2 += self->in->div->r.y; grop_render(self->in->div, NULL); VID(update) (self->dt->display, DATA->update_x1, DATA->update_y1, DATA->update_x2 - DATA->update_x1, DATA->update_y2 - DATA->update_y1); /* Make sure we show cursors affected by update */ for (c = cursor_get_default(); c; c = c->next) { if ((c->sprite) && (point_in_rect(c->sprite->x, c->sprite->y, DATA->update_x1, DATA->update_y1, DATA->update_x2, DATA->update_y2) || point_in_rect(c->sprite->x + c->sprite->w, c->sprite->y + c->sprite->h, DATA->update_x1, DATA->update_y1, DATA->update_x2, DATA->update_y2))) { VID(sprite_update) (c->sprite); } } DATA->update_clean= 1; } }
/* rect_touching_rect: checks if the two rectangles are touching... */ int rect_touching_rect(size_t x1, size_t y1, size_t w1, size_t h1, size_t x2, size_t y2, size_t w2, size_t h2) { return (point_in_rect(x1, y1, x2, y2, w2, h2) || point_in_rect(x1 + w1, y1, x2, y2, w2, h2) || point_in_rect(x1, y1 + h1, x2, y2, w2, h2) || point_in_rect(x1 + w1, y1 + h1, x2, y2, w2, h2)); }
bool controller_base::handle_scroll(CKey& key, int mousex, int mousey, int mouse_flags, double x_axis, double y_axis) { bool mouse_in_window = (SDL_GetAppState() & SDL_APPMOUSEFOCUS) != 0 || preferences::get("scroll_when_mouse_outside", true); bool keyboard_focus = have_keyboard_focus(); int scroll_speed = preferences::scroll_speed(); int dx = 0, dy = 0; int scroll_threshold = (preferences::mouse_scroll_enabled()) ? preferences::mouse_scroll_threshold() : 0; BOOST_FOREACH(const theme::menu& m, get_display().get_theme().menus()) { if (point_in_rect(mousex, mousey, m.get_location())) { scroll_threshold = 0; } } if ((key[SDLK_UP] && keyboard_focus) || (mousey < scroll_threshold && mouse_in_window)) { dy -= scroll_speed; } if ((key[SDLK_DOWN] && keyboard_focus) || (mousey > get_display().h() - scroll_threshold && mouse_in_window)) { dy += scroll_speed; } if ((key[SDLK_LEFT] && keyboard_focus) || (mousex < scroll_threshold && mouse_in_window)) { dx -= scroll_speed; } if ((key[SDLK_RIGHT] && keyboard_focus) || (mousex > get_display().w() - scroll_threshold && mouse_in_window)) { dx += scroll_speed; } if ((mouse_flags & SDL_BUTTON_MMASK) != 0 && preferences::middle_click_scrolls()) { const SDL_Rect& rect = get_display().map_outside_area(); if (point_in_rect(mousex, mousey,rect)) { // relative distance from the center to the border // NOTE: the view is a rectangle, so can be more sensible in one direction // but seems intuitive to use and it's useful since you must // more often scroll in the direction where the view is shorter const double xdisp = ((1.0*mousex / rect.w) - 0.5); const double ydisp = ((1.0*mousey / rect.h) - 0.5); // 4.0 give twice the normal speed when mouse is at border (xdisp=0.5) int speed = 4 * scroll_speed; dx += round_double(xdisp * speed); dy += round_double(ydisp * speed); } } dx += round_double( x_axis * scroll_speed); dy += round_double( y_axis * scroll_speed); return get_display().scroll(dx, dy); }
void Display::on_motion(SDL_MouseMotionEvent &e) { mouse = e; SDL_Point p = { e.x, e.y }; if(point_in_rect(&p, &grid.rect)) current = &grid; else if(point_in_rect(&p, &thumbs.rect)) current = &thumbs; else current = NULL; update_mouse(); }
base_unit* base_map::unit_clicked_on(const int xclick, const int yclick, const map_location& mloc) const { const int w = gmap_.w(); const display& disp = get_controller().get_display(); int xmap = xclick, ymap = yclick; disp.pixel_screen_to_map(xmap, ymap); base_unit* u; for (int y = mloc.y; y >= 0; y --) { int pitch = y * w_; int max_x = 0; int min_y = INT_MAX; for (int x = mloc.x; x >= 0; x --) { u = coor_map_[pitch + x].overlay; if (u) { const SDL_Rect& rect = u->get_rect(); if (point_in_rect(xmap, ymap, rect)) { return u; } if (max_x < rect.x + rect.w) { max_x = rect.x + rect.w; } if (min_y > rect.y) { min_y = rect.y; } } if (min_y <= ymap) { break; } } for (int x1 = w; x1 < w_; x1 ++) { u = coor_map_[pitch + x1].overlay; if (u) { const SDL_Rect& rect = u->get_rect(); if (point_in_rect(xmap, ymap, rect)) { return u; } if (max_x < rect.x + rect.w) { max_x = rect.x + rect.w; } } } if (y != mloc.y && max_x >= xmap) { break; } } return NULL; }
static int ctrl_tool_response_click(p_void_data_t p_void_data, p_void_ctrl_tool_t p_void_ctrl_tool, const m_evt_code_t *p_m_evt_code) { int i=0; int cur_item=-1; coordinate_t coordinate; p_void_data_t pvd=p_void_data; ctrl_tool_t *ctrl_tool=(ctrl_tool_t *)p_void_ctrl_tool; const m_evt_code_t *m_evt_code=p_m_evt_code; if((NULL==pvd)||(NULL==ctrl_tool)||(NULL==m_evt_code)){ return cur_item; } if(NULL==get_coordinate(&coordinate,&m_evt_code->m_evt_param.mouse_t.mouse)){ return cur_item; } for(i=0; i<ctrl_tool->total_item; i++){ if(FALSE==ctrl_tool->p_ctrl_tool_resource[i].visible){ continue; } if(FALSE!=point_in_rect(&ctrl_tool->left_vertex,&ctrl_tool->p_ctrl_tool_resource[i].ctrl_tool_res.rect,&coordinate)){ ctrl_tool->cur_item=i; if((FALSE!=ctrl_tool->p_ctrl_tool_resource[ctrl_tool->cur_item].visible)&&(NULL!=ctrl_tool->p_ctrl_tool_callback->pf_event_pen_down)){ ctrl_tool->p_ctrl_tool_callback->pf_event_pen_down(pvd,m_evt_code,ctrl_tool->cur_item); cur_item=ctrl_tool->cur_item; } } } return cur_item; }
void wndmgr_hangle_event(Event e) { if(e.type == ET_MouseDown) { if(point_in_rect(e.loc, plusbtn->frame)) { plusbtn->mouse_down(plusbtn, e); } else { window_sref clicked_wnd = _wndmgr_find_clicked(e); if(!clicked_wnd) return; _wndmgr_keywnd = clicked_wnd->wnd; wndmgr_order_front(_wndmgr_keywnd); window_handle_event(_wndmgr_keywnd, e); } } else { if(_wndmgr_keywnd) { window_handle_event(_wndmgr_keywnd, e); } if(e.type == ET_MouseUp) { _wndmgr_keywnd = NULL; } } }
int tilemap_find_tile(int mx, int my, TileMap * map) { int x = 0; int y = 0; int index = 0; if (!map) { return -2; } if (map->tileWidth == 0 || map->tileHeight == 0) { return -3; } if (point_in_rect(mx, my, map->boundingBox)) { //slog("xPos (%i) yPos (%i) tileWidth (%i) tileHeight (%i) \nmx (%d) my (%d)", map->xPos, map->yPos, map->tileWidth, map->tileHeight, mx, my); mx = mx - map->xPos; my = my - map->yPos; x = mx / map->tileWidth; y = my / map->tileHeight; index = x + (y * map->width); //slog("in tile x (%i) y (%i) index (%i)", x, y, index); return index; } return -1; }
foreach(tooltip tip, tips) { if(!tip.action.empty() && point_in_rect(mousex, mousey, tip.rect)) { display* disp = resources::screen; help::show_help(*disp, tip.action); return true; } }
void widget::process_tooltip_string(int mousex, int mousey) { if (!hidden() && point_in_rect(mousex, mousey, rect_)) { if (!tooltip_text_.empty()) tooltips::add_tooltip(rect_, tooltip_text_ ); } }
bool button::click(const SDL_MouseButtonEvent & me) { if(point_in_rect(m_pos, me.x, me.y)) return sample(me.x - m_pos.x, me.y - m_pos.y); else return false; }
void button::motion(const SDL_MouseMotionEvent & me) { if(point_in_rect(m_pos, me.x, me.y)) m_hot = sample(me.x - m_pos.x, me.y - m_pos.y); else m_hot = false; }
BOOST_FOREACH (tooltip tip, tips) { if(!tip.action.empty() && point_in_rect(mousex, mousey, tip.rect)) { #if defined(_KINGDOM_EXE) || !defined(_WIN32) display* disp = resources::screen; help::show_help(*disp, tip.action); #endif return true; } }
bool dropdown_widget::handle_mouseup(const SDL_MouseButtonEvent& event, bool claimed) { point p(event.x, event.y); //int button_state = SDL_GetMouseState(&p.x, &p.y); if(point_in_rect(p, rect(x(), y(), width()+height(), height()))) { claimed = claim_mouse_events(); } return claimed; }
void widget::process_help_string(int mousex, int mousey) { if (!hidden() && point_in_rect(mousex, mousey, rect_)) { if(help_string_ == 0 && help_text_ != "") { //std::cerr << "setting help string to '" << help_text_ << "'\n"; help_string_ = video().set_help_string(help_text_); } } else if(help_string_ > 0) { video().clear_help_string(help_string_); help_string_ = 0; } }
bool controller_base::finger_coordinate_valid(int x, int y) const { const display& disp = get_display(); if (!point_in_rect(x, y, disp.map_outside_area())) { return false; } if (disp.point_in_volatiles(x, y)) { return false; } return true; }
bool iphone_controls::hittest_button(const rect& area) { setup_rects(); //static graphics::texture tex(graphics::texture::get("gui/iphone_controls.png")); foreach(const Mouse& mouse, active_mice) { const point mouse_pos(mouse.x, mouse.y); if(point_in_rect(mouse_pos, area)) { return true; } } return false; }
bool dropdown_widget::handle_mousedown(const SDL_MouseButtonEvent& event, bool claimed) { point p(event.x, event.y); //int button_state = input::sdl_get_mouse_state(&p.x, &p.y); if(point_in_rect(p, rect(x(), y(), width()+height(), height()))) { claimed = claim_mouse_events(); if(dropdown_menu_) { dropdown_menu_->set_visible(!dropdown_menu_->visible()); } } return claimed; }
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 slider::mouse_motion(const SDL_MouseMotionEvent& event) { if (state_ == NORMAL || state_ == ACTIVE) { bool on = point_in_rect(event.x, event.y, slider_area()); state_ = on ? ACTIVE : NORMAL; } else if (state_ == CLICKED || state_ == DRAGGED) { state_ = DRAGGED; bool prev_change = value_change_; value_change_ = false; set_slider_position(event.x); if(value_change_) { sound::play_UI_sound(game_config::sounds::slider_adjust); } else { value_change_ = prev_change; } } }
int main(int argc, char *argv[]) { struct rectangle rect = get_rect(); print_rect(rect); printf("The area of this rectangle: %d\n", rect_area(rect)); printf("Enter a point to check if in the rectangle:"); struct point po = get_point(); if (point_in_rect(po, rect)) { printf("The point is in the rectangle\n"); } else { printf("The point is not in the rectangle\n"); } return 0; }
void slider::mouse_down(const SDL_MouseButtonEvent& event) { if (event.button != SDL_BUTTON_LEFT || !point_in_rect(event.x, event.y, location())) return; state_ = CLICKED; bool prev_change = value_change_; value_change_ = false; set_focus(true); set_slider_position(event.x); if(value_change_) { sound::play_UI_sound(game_config::sounds::slider_adjust); } else { sound::play_UI_sound(game_config::sounds::button_press); value_change_ = prev_change; } }
bool speech_dialog::handle_mouse_move(int x, int y) { translate_mouse_coords(&x, &y); rect box( preferences::virtual_screen_width() - OptionsX - option_width_ - OptionsBorder, preferences::virtual_screen_height() - OptionsY - OptionHeight*options_.size() - OptionsBorder, option_width_ + OptionsBorder*2, OptionHeight*options_.size() + OptionsBorder*2 ); //std::cerr << "Options box: " << box << " : " << x << " : " << y << "\n"; if (point_in_rect(point(x, y), box)) { option_selected_ = (y-box.y())/OptionHeight; return true; } else { option_selected_ = -1; return false; } }
window_sref _wndmgr_find_clicked(Event e) { window_sref sref = window_stack; window_sref clicked_wnd = NULL; if(!sref) return NULL; do { if(point_in_rect(e.loc, sref->wnd->frame)) { clicked_wnd = sref; } } while((sref = sref->next)); return clicked_wnd; }
static int __get_pad_cell(t_CallWindowData *wdata, coord_t x, coord_t y, gui_rect_t *prc) { if(point_in_rect(x, y, &ga_btn_info.rc_pad)){ int r, c; int nr; nr = (wdata->keypad)?4:2; x -= ga_btn_info.rc_pad.x; y -= ga_btn_info.rc_pad.y; r = y*nr/ga_btn_info.rc_pad.dy; c = x*3/ga_btn_info.rc_pad.dx; if(prc){ prc->x = ga_btn_info.rc_pad.x + c*3/ga_btn_info.rc_pad.dx; prc->y = ga_btn_info.rc_pad.y + r*3/ga_btn_info.rc_pad.dy; prc->dx = ga_btn_info.rc_pad.dx/3; prc->dy = ga_btn_info.rc_pad.dy/nr; } return (r*3+c); } return -1; }
void palette_manager::handle_event(const SDL_Event& event) { if (event.type == SDL_MOUSEMOTION) { // If the mouse is inside the palette, give it focus. if (point_in_rect(event.button.x, event.button.y, location())) { if (!focus(&event)) set_focus(true); } // If the mouse is outside, remove focus. else if (focus(&event)) set_focus(false); } if (!focus(&event)) { return; } const SDL_MouseButtonEvent mouse_button_event = event.button; if (mouse_button_event.type == SDL_MOUSEBUTTONDOWN) { if (mouse_button_event.button == SDL_BUTTON_WHEELUP) { scroll_up(); } if (mouse_button_event.button == SDL_BUTTON_WHEELDOWN) { scroll_down(); } if (mouse_button_event.button == SDL_BUTTON_WHEELLEFT) { active_palette().prev_group(); scroll_top(); } if (mouse_button_event.button == SDL_BUTTON_WHEELRIGHT) { active_palette().next_group(); scroll_top(); } //set_dirty(true); } if (mouse_button_event.type == SDL_MOUSEBUTTONUP) { //set_dirty(true); // draw(true); // set_dirty(active_palette().mouse_click()); // gui_.invalidate_game_status(); } }
void mouse_handler_base::mouse_wheel(int scrollx, int scrolly, bool browse) { int x, y; SDL_GetMouseState(&x, &y); int movex = scrollx * preferences::scroll_speed(); int movey = scrolly * preferences::scroll_speed(); // Don't scroll map and map zoom slider at same time gui::slider* s = gui().find_slider("map-zoom-slider"); if (s && point_in_rect(x, y, s->location())) { movex = 0; movey = 0; } if (movex != 0 || movey != 0) { CKey pressed; // Alt + mousewheel do an 90° rotation on the scroll direction if (pressed[SDLK_LALT] || pressed[SDLK_RALT]) { gui().scroll(movey,movex); } else { gui().scroll(movex,-movey); } } if (scrollx < 0) { mouse_wheel_left(x, y, browse); } else if (scrollx > 0) { mouse_wheel_right(x, y, browse); } if (scrolly < 0) { mouse_wheel_down(x, y, browse); } else if (scrolly > 0) { mouse_wheel_up(x, y, browse); } }
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); }
bool level_runner::handle_mouse_events(const SDL_Event &event) { static const int MouseDownEventID = get_object_event_id("mouse_down"); static const int MouseUpEventID = get_object_event_id("mouse_up"); static const int MouseMoveEventID = get_object_event_id("mouse_move"); static const int MouseDownEventAllID = get_object_event_id("mouse_down*"); static const int MouseUpEventAllID = get_object_event_id("mouse_up*"); static const int MouseMoveEventAllID = get_object_event_id("mouse_move*"); static const int MouseEnterID = get_object_event_id("mouse_enter"); static const int MouseLeaveID = get_object_event_id("mouse_leave"); static const int MouseClickID = get_object_event_id("click"); //static const int MouseDblClickID = get_object_event_id("dblclick"); static const int MouseDragID = get_object_event_id("drag"); static const int MouseDragStartID = get_object_event_id("drag_start"); static const int MouseDragEndID = get_object_event_id("drag_end"); if(paused) { // skip mouse event handling when paused. // XXX: when we become unpaused we need to reset the state of drag operations // and partial clicks. return false; } switch(event.type) { #if defined(__ANDROID__) case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: case SDL_JOYBALLMOTION: int x, mx = event.type == SDL_JOYBALLMOTION ? event.jball.xrel : event.jbutton.x; int y, my = event.type == SDL_JOYBALLMOTION ? event.jball.yrel : event.jbutton.y; int i = event.type == SDL_JOYBALLMOTION ? event.jball.ball : event.jbutton.button; int event_button_button = event.jbutton.button; int event_type = event.type == SDL_JOYBALLMOTION ? SDL_MOUSEMOTION : event.type == SDL_JOYBUTTONDOWN ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP; #else case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: case SDL_MOUSEMOTION: int x, mx = event.type == SDL_MOUSEMOTION ? event.motion.x : event.button.x; int y, my = event.type == SDL_MOUSEMOTION ? event.motion.y : event.button.y; int i = event.type == SDL_MOUSEMOTION ? event.motion.which : event.button.which; int event_type = event.type; int event_button_button = event.button.button; #endif const int basic_evt = event_type == SDL_MOUSEBUTTONDOWN ? MouseDownEventID : event_type == SDL_MOUSEMOTION ? MouseMoveEventID : MouseUpEventID; const int catch_all_event = event_type == SDL_MOUSEBUTTONDOWN ? MouseDownEventAllID : event_type == SDL_MOUSEMOTION ? MouseMoveEventAllID : MouseUpEventAllID; Uint8 button_state = SDL_GetMouseState(0,0); if(!lvl_->gui_event(event)) { x = (mx*graphics::screen_width())/preferences::virtual_screen_width() + last_draw_position().x/100; y = (my*graphics::screen_height())/preferences::virtual_screen_height() + last_draw_position().y/100; game_logic::map_formula_callable_ptr callable(new game_logic::map_formula_callable); callable->add("mouse_x", variant(x)); callable->add("mouse_y", variant(y)); callable->add("mouse_index", variant(i)); if(event_type != SDL_MOUSEMOTION) { callable->add("mouse_button", variant(event_button_button)); } else { callable->add("mouse_button", variant(button_state)); } std::vector<variant> items; // Grab characters around point, z-order sort them, so that when // we process them we go from highest to lowest, allowing a higher // object to swallow an event before the lower ones get it. std::vector<entity_ptr> cs = lvl_->get_characters_at_point(x, y, last_draw_position().x/100, last_draw_position().y/100); std::sort(cs.begin(), cs.end(), zorder_compare); std::vector<entity_ptr>::iterator it; bool handled = false; bool click_handled = false; std::set<entity_ptr> mouse_in; for(it = cs.begin(); it != cs.end(); ++it) { rect clip_area; // n.b. clip_area is in level coordinates, not relative to the object. if((*it)->get_clip_area(&clip_area)) { point p(x,y); if((*it)->use_absolute_screen_coordinates()) { p = point(mx,my); } if(point_in_rect(p, clip_area) == false) { continue; } } if(event_type == SDL_MOUSEBUTTONDOWN) { (*it)->set_mouse_buttons((*it)->get_mouse_buttons() | SDL_BUTTON(event_button_button)); } else if(event_type == SDL_MOUSEMOTION) { // handling for mouse_enter if((*it)->is_mouse_over_entity() == false) { (*it)->handle_event(MouseEnterID, callable.get()); (*it)->set_mouse_over_entity(); } mouse_in.insert(*it); } handled |= (*it)->handle_event(basic_evt, callable.get()); // XXX: fix this for dragging(with multiple mice) if(event_type == SDL_MOUSEBUTTONUP && !click_handled && (*it)->is_being_dragged() == false) { (*it)->handle_event(MouseClickID, callable.get()); if((*it)->mouse_event_swallowed()) { click_handled = true; } } items.push_back(variant((*it).get())); } // Handling for "catch all" mouse events. callable->add("handled", variant(handled)); variant obj_ary(&items); callable->add("objects_under_mouse", obj_ary); std::vector<entity_ptr> level_chars(level::current().get_chars()); foreach(entity_ptr object, level_chars) { if(object) { object->handle_event(catch_all_event, callable.get()); // drag handling if(event_type == SDL_MOUSEBUTTONUP) { object->set_mouse_buttons(object->get_mouse_buttons() & ~SDL_BUTTON(event_button_button)); if(object->get_mouse_buttons() == 0 && object->is_being_dragged()) { object->handle_event(MouseDragEndID, callable.get()); object->set_being_dragged(false); } } else if(event_type == SDL_MOUSEMOTION) { // drag check. if(object->is_being_dragged()) { if(object->get_mouse_buttons() & button_state) { object->handle_event(MouseDragID, callable.get()); } else { object->handle_event(MouseDragEndID, callable.get()); object->set_being_dragged(false); } } else if(object->get_mouse_buttons() & button_state) { // start drag. object->handle_event(MouseDragStartID, callable.get()); object->set_being_dragged(); } } } } if(event_type == SDL_MOUSEMOTION) { // handling for mouse_leave level_chars = level::current().get_chars(); foreach(const entity_ptr& e, level_chars) { if(e) { // n.b. clip_area is in level coordinates, not relative to the object. rect clip_area; bool has_clip_area = e->get_clip_area(&clip_area); point p(x,y); if(e->use_absolute_screen_coordinates()) { p = point(mx,my); } if(mouse_in.find(e) == mouse_in.end() && ((has_clip_area == false && e->is_mouse_over_entity()) || (e->is_mouse_over_entity() && has_clip_area && point_in_rect(p, clip_area) == false))) { e->handle_event(MouseLeaveID, callable.get()); e->set_mouse_over_entity(false); } } } } }
bool button::hit(int x, int y) const { return point_in_rect(x,y,location()); }