Пример #1
0
void scrollbar::draw_contents()
{
	surface mid_img;
	surface bottom_img;
	surface top_img;

	switch (state_) {

	case NORMAL:
		top_img.assign(image::get_image(scrollbar_top));
		mid_img.assign(image::get_image(scrollbar_mid));
		bottom_img.assign(image::get_image(scrollbar_bottom));
		break;

	case ACTIVE:
		top_img.assign(image::get_image(scrollbar_top_hl));
		mid_img.assign(image::get_image(scrollbar_mid_hl));
		bottom_img.assign(image::get_image(scrollbar_bottom_hl));
		break;

	case DRAGGED:
		top_img.assign(image::get_image(scrollbar_top_pressed));
		mid_img.assign(image::get_image(scrollbar_mid_pressed));
		bottom_img.assign(image::get_image(scrollbar_bottom_pressed));
		break;

	case UNINIT:
	default:
		break;
	}

	const surface top_grv(image::get_image(groove_top));
	const surface mid_grv(image::get_image(groove_mid));
	const surface bottom_grv(image::get_image(groove_bottom));

	if (mid_img == NULL || bottom_img == NULL || top_img == NULL
	 || top_grv == NULL || bottom_grv == NULL || mid_grv == NULL) {
		std::cerr << "Failure to load scrollbar image.\n";
		return;
	}

	SDL_Rect grip = grip_area();
	int mid_height = grip.h - top_img->h - bottom_img->h;
	if (mid_height <= 0) {
		// For now, minimum size of the middle piece is 1.
		// This should never really be encountered, and if it is,
		// it's a symptom of a larger problem, I think.
		mid_height = 1;
	}

	if(mid_scaled_.null() || mid_scaled_->h != mid_height) {
		mid_scaled_.assign(scale_surface(mid_img, mid_img->w, mid_height));
	}

	SDL_Rect groove = groove_area();
	int groove_height = groove.h - top_grv->h - bottom_grv->h;
	if (groove_height <= 0) {
		groove_height = 1;
	}

	if (groove_scaled_.null() || groove_scaled_->h != groove_height) {
		groove_scaled_.assign(scale_surface(mid_grv, mid_grv->w, groove_height));
	}

	if (mid_scaled_.null() || groove_scaled_.null()) {
		std::cerr << "Failure during scrollbar image scale.\n";
		return;
	}

	if (grip.h > groove.h) {
		std::cerr << "abort draw scrollbar: grip too large\n";
		return;
	}

	// Draw scrollbar "groove"
	video().blit_surface(groove.x, groove.y, top_grv);
	video().blit_surface(groove.x, groove.y + top_grv->h, groove_scaled_);
	video().blit_surface(groove.x, groove.y + top_grv->h + groove_height, bottom_grv);

	// Draw scrollbar "grip"
	video().blit_surface(grip.x, grip.y, top_img);
	video().blit_surface(grip.x, grip.y + top_img->h, mid_scaled_);
	video().blit_surface(grip.x, grip.y + top_img->h + mid_height, bottom_img);

	update_rect(groove);
}
Пример #2
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;
	}
}
Пример #3
0
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;
}