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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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();
		}
	}
}
Beispiel #5
0
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);
}
Beispiel #7
0
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();
		}
	}
}
Beispiel #8
0
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;
}
Beispiel #10
0
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;
			}
		}
	}
	
}