示例#1
0
文件: menu.cpp 项目: dodikk/iWesnoth
void menu::draw_contents()
{
	
	// KP: now draw a nice frame!
	SDL_Rect frame_rect = inner_location();
	gui::dialog_frame f(video(), "", gui::dialog_frame::preview_style, false);
	f.layout(frame_rect);
//	f.draw_background();
	f.draw_border();
	
	
	SDL_Rect heading_rect = inner_location();
	heading_rect.h = heading_height();
	style_->draw_row(*this,0,heading_rect,HEADING_ROW);
	
	// KP: make sure to clip
	SDL_Rect content_rect = inner_location();
	content_rect.y += heading_rect.h;
	content_rect.h -= heading_rect.h;
	clip_rect_setter clippy(content_rect);
	

	for(size_t i = 0; i != item_pos_.size(); ++i) {
		style_->draw_row(*this,item_pos_[i],get_item_rect(i),
			 (!out_ && item_pos_[i] == selected_) ? SELECTED_ROW : NORMAL_ROW);
	}
}
void textbox::draw_contents()
{
	SDL_Rect const &loc = inner_location();

	surface surf = video().getSurface();
	draw_solid_tinted_rectangle(loc.x,loc.y,loc.w,loc.h,0,0,0,
				    focus(NULL) ? alpha_focus_ : alpha_, surf);

	SDL_Rect src;

	if(text_image_ == NULL) {
		update_text_cache(true);
	}

	if(text_image_ != NULL) {
		src.y = yscroll_;
		src.w = std::min<size_t>(loc.w,text_image_->w);
		src.h = std::min<size_t>(loc.h,text_image_->h);
		src.x = text_pos_;
		SDL_Rect dest = screen_area();
		dest.x = loc.x;
		dest.y = loc.y;

		// Fills the selected area
		if(is_selection()) {
			const int start = std::min<int>(selstart_,selend_);
			const int end = std::max<int>(selstart_,selend_);
			int startx = char_x_[start];
			int starty = char_y_[start];
			const int endx = char_x_[end];
			const int endy = char_y_[end];

			while(starty <= endy) {
				const size_t right = starty == endy ? endx : text_image_->w;
				if(right <= size_t(startx)) {
					break;
				}

				SDL_Rect rect = create_rect(loc.x + startx
						, loc.y + starty - src.y
						, right - startx
						, line_height_);

				const clip_rect_setter clipper(surf, &loc);

				Uint32 color = SDL_MapRGB(surf->format, 0, 0, 160);
				fill_rect_alpha(rect, color, 140, surf);

				starty += int(line_height_);
				startx = 0;
			}
		}

		sdl_blit(text_image_, &src, surf, &dest);
	}

	draw_cursor((cursor_pos_ == 0 ? 0 : cursor_pos_ - 1), video());

	update_rect(loc);
}
示例#3
0
void help_text_area::draw_contents()
{
	SDL_Rect const &loc = inner_location();
	bg_restore();
	surface screen = video().getSurface();
	clip_rect_setter clip_rect_set(screen, &loc);
	for(std::list<item>::const_iterator it = items_.begin(), end = items_.end(); it != end; ++it) {
		SDL_Rect dst = it->rect;
		dst.y -= get_position();
		if (dst.y < static_cast<int>(loc.h) && dst.y + it->rect.h > 0) {
			dst.x += loc.x;
			dst.y += loc.y;
			if (it->box) {
				for (int i = 0; i < box_width; ++i) {
					sdl::draw_rectangle(dst.x, dst.y, it->rect.w - i * 2, it->rect.h - i * 2,
					                    0, screen);
					++dst.x;
					++dst.y;
				}
			}
			sdl_blit(it->surf, NULL, screen, &dst);
		}
	}
	update_rect(loc);
}
示例#4
0
int menu::hit_heading(int x, int y) const
{
	const size_t height = heading_height();
	const SDL_Rect& loc = inner_location();
	if(y >= loc.y && static_cast<size_t>(y) < loc.y + height) {
		return hit_column(x);
	} else {
		return -1;
	}
}
示例#5
0
void menu::draw_contents()
{
	SDL_Rect heading_rect = inner_location();
	heading_rect.h = heading_height();
	style_->draw_row(*this,0,heading_rect,HEADING_ROW);

	for(size_t i = 0; i != item_pos_.size(); ++i) {
		style_->draw_row(*this,item_pos_[i],get_item_rect(i),
			 (!out_ && item_pos_[i] == selected_) ? SELECTED_ROW : NORMAL_ROW);
	}
}
示例#6
0
int menu::hit(int x, int y) const
{
	SDL_Rect const &loc = inner_location();
	if (x >= loc.x  && x < loc.x + loc.w && y >= loc.y && y < loc.y + loc.h) {
		for(size_t i = 0; i != items_.size(); ++i) {
			const SDL_Rect& rect = get_item_rect(i);
			if (y >= rect.y && y < rect.y + rect.h)
				return i;
		}
	}

	return -1;
}
示例#7
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();
		}
	}
}
示例#8
0
文件: menu.cpp 项目: dodikk/iWesnoth
SDL_Rect menu::get_item_rect_internal(size_t item) const
{
	//unsigned int first_item_on_screen = get_position();
	unsigned int first_item_on_screen = get_position() / item_height_;
	unsigned int leftovers = get_position() - (first_item_on_screen * item_height_);
	if (item < first_item_on_screen ||
	    size_t(item) >= first_item_on_screen + max_items_onscreen() + 2) {
		return empty_rect;
	}

	const std::map<int,SDL_Rect>::const_iterator i = itemRects_.find(item);
	if(i != itemRects_.end())
		return i->second;

	SDL_Rect const &loc = inner_location();

	int y = loc.y + heading_height();
	if (item != first_item_on_screen) {
		const SDL_Rect& prev = get_item_rect_internal(item-1);
		y = prev.y + prev.h;
	}
	else
	{
		// KP: sub-item scrolling
		y -= leftovers;
	}

	SDL_Rect res = { loc.x, y, loc.w, get_item_height(item) };

	SDL_Rect const &screen_area = ::screen_area();

	if(res.x > screen_area.w) {
		return empty_rect;
	} else if(res.x + res.w > screen_area.w) {
		res.w = screen_area.w - res.x;
	}

	if(res.y > screen_area.h) {
		return empty_rect;
	} else if(res.y + res.h > screen_area.h) {
		res.h = screen_area.h - res.y;
	}

	//only insert into the cache if the menu's co-ordinates have
	//been initialized
	if (loc.x > 0 && loc.y > 0)
		itemRects_.insert(std::pair<int,SDL_Rect>(item,res));

	return res;
}
示例#9
0
void help_text_area::add_img_item(const std::string& path, const std::string& alignment,
								  const bool floating, const bool box)
{
	surface surf(image::get_image(path));
	if (surf.null())
		return;
	ALIGNMENT align = str_to_align(alignment);
	if (align == HERE && floating) {
		WRN_DP << "Floating image with align HERE, aligning left." << std::endl;
		align = LEFT;
	}
	const int width = surf->w + (box ? box_width * 2 : 0);
	int xpos;
	int ypos = curr_loc_.second;
	int text_width = inner_location().w;
	switch (align) {
	case HERE:
		xpos = curr_loc_.first;
		break;
	case LEFT:
	default:
		xpos = 0;
		break;
	case MIDDLE:
		xpos = text_width / 2 - width / 2 - (box ? box_width : 0);
		break;
	case RIGHT:
		xpos = text_width - width - (box ? box_width * 2 : 0);
		break;
	}
	if (curr_loc_.first != get_min_x(curr_loc_.second, curr_row_height_)
		&& (xpos < curr_loc_.first || xpos + width > text_width)) {
		down_one_line();
		add_img_item(path, alignment, floating, box);
	}
	else {
		if (!floating) {
			curr_loc_.first = xpos;
		}
		else {
			ypos = get_y_for_floating_img(width, xpos, ypos);
		}
		add_item(item(surf, xpos, ypos, floating, box, align));
	}
}
示例#10
0
int help_text_area::get_max_x(const int y, const int height)
{
	int text_width = inner_location().w;
	int max_x = text_width;
	for (std::list<item>::const_iterator it = items_.begin(); it != items_.end(); ++it) {
		const item& itm = *it;
		if (itm.floating) {
			if (itm.rect.y < y + height && itm.rect.y + itm.rect.h > y) {
				if (itm.align == RIGHT) {
					max_x = std::min<int>(max_x, text_width - itm.rect.w - 5);
				} else if (itm.align == MIDDLE) {
					max_x = std::min<int>(max_x, text_width / 2 - itm.rect.w / 2 - 5);
				}
			}
		}
	}
	return max_x;
}
示例#11
0
void menu::draw()
{
	if(hidden()) {
		return;
	}

	if(!dirty()) {

		for(std::set<int>::const_iterator i = invalid_.begin(); i != invalid_.end(); ++i) {
			if(*i == -1) {
				SDL_Rect heading_rect = inner_location();
				heading_rect.h = heading_height();
				bg_restore(heading_rect);
				style_->draw_row(*this,0,heading_rect,HEADING_ROW);
				update_rect(heading_rect);
			} else if(*i >= 0 && *i < int(item_pos_.size())) {
				const unsigned int pos = item_pos_[*i];
				const SDL_Rect& rect = get_item_rect(*i);
				bg_restore(rect);
				style_->draw_row(*this,pos,rect,
					(!out_ && pos == selected_) ? SELECTED_ROW : NORMAL_ROW);
				update_rect(rect);
			}
		}

		invalid_.clear();
		return;
	}

	invalid_.clear();

	bg_restore();

	util::scoped_ptr<clip_rect_setter> clipper(NULL);
	if(clip_rect())
		clipper.assign(new clip_rect_setter(video().getSurface(), *clip_rect()));

	draw_contents();

	update_rect(location());
	set_dirty(false);
}
示例#12
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();
		}
	}
}
示例#13
0
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);
}
示例#14
0
surface textbox::add_text_line(const wide_string& text, const SDL_Color& color)
{
	line_height_ = font::get_max_height(font_size);

	if(char_y_.empty()) {
		char_y_.push_back(0);
	} else {
		char_y_.push_back(char_y_.back() + line_height_);
	}

	char_x_.push_back(0);

	// Re-calculate the position of each glyph. We approximate this by asking the
	// width of each substring, but this is a flawed assumption which won't work with
	// some more complex scripts (that is, RTL languages). This part of the work should
	// actually be done by the font-rendering system.
	std::string visible_string;
	wide_string wrapped_text;

	wide_string::const_iterator backup_itor = text.end();

	wide_string::const_iterator itor = text.begin();
	while(itor != text.end()) {
		//If this is a space, save copies of the current state so we can roll back
		if(char(*itor) == ' ') {
			backup_itor = itor;
		}
		visible_string.append(utils::wchar_to_string(*itor));

		if(char(*itor) == '\n') {
			backup_itor = text.end();
			visible_string = "";
		}

		int w = font::line_width(visible_string, font_size);

		if(wrap_ && w >= inner_location().w) {
			if(backup_itor != text.end()) {
				int backup = itor - backup_itor;
				itor = backup_itor + 1;
				if(backup > 0) {
					char_x_.erase(char_x_.end()-backup, char_x_.end());
					char_y_.erase(char_y_.end()-backup, char_y_.end());
					wrapped_text.erase(wrapped_text.end()-backup, wrapped_text.end());
				}
			}
			backup_itor = text.end();
			wrapped_text.push_back(wchar_t('\n'));
			char_x_.push_back(0);
			char_y_.push_back(char_y_.back() + line_height_);
			visible_string = "";
		} else {
			wrapped_text.push_back(*itor);
			char_x_.push_back(w);
			char_y_.push_back(char_y_.back() + (char(*itor) == '\n' ? line_height_ : 0));
			++itor;
		}
	}

	const std::string s = utils::wstring_to_string(wrapped_text);
	const surface res(font::get_rendered_text(s, font_size, color));

	return res;
}
示例#15
0
void help_text_area::set_items()
{
	last_row_.clear();
	items_.clear();
	curr_loc_.first = 0;
	curr_loc_.second = 0;
	curr_row_height_ = min_row_height_;
	// Add the title item.
	const std::string show_title =
		font::make_text_ellipsis(shown_topic_->title, title_size, inner_location().w);
	surface surf(font::get_rendered_text(show_title, title_size,
					     font::NORMAL_COLOR, TTF_STYLE_BOLD));
	if (surf != NULL) {
		add_item(item(surf, 0, 0, show_title));
		curr_loc_.second = title_spacing_;
		contents_height_ = title_spacing_;
		down_one_line();
	}
	// Parse and add the text.
	std::vector<std::string> const &parsed_items = shown_topic_->text.parsed_text();
	std::vector<std::string>::const_iterator it;
	for (it = parsed_items.begin(); it != parsed_items.end(); ++it) {
		if (*it != "" && (*it)[0] == '[') {
			// Should be parsed as WML.
			try {
				config cfg;
				std::istringstream stream(*it);
				read(cfg, stream);

#define TRY(name) do { \
				if (config &child = cfg.child(#name)) \
					handle_##name##_cfg(child); \
				} while (0)

				TRY(ref);
				TRY(img);
				TRY(bold);
				TRY(italic);
				TRY(header);
				TRY(jump);
				TRY(format);

#undef TRY

			}
			catch (config::error& e) {
				std::stringstream msg;
				msg << "Error when parsing help markup as WML: '" << e.message << "'";
				throw parse_error(msg.str());
			}
		}
		else {
			add_text_item(*it);
		}
	}
	down_one_line(); // End the last line.
	int h = height();
	set_position(0);
	set_full_size(contents_height_);
	set_shown_size(h);
}
示例#16
0
void menu::draw_row(const size_t row_index, const SDL_Rect& rect, ROW_TYPE type)
{
	//called from style, draws one row's contents in a generic and adaptable way
	const std::vector<std::string>& row = (type == HEADING_ROW) ? heading_ : items_[row_index].fields;
	SDL_Rect const &area = screen_area();
	SDL_Rect const &loc = inner_location();
	const std::vector<int>& widths = column_widths();
	bool lang_rtl = current_language_rtl();
	int dir = (lang_rtl) ? -1 : 1;
	SDL_Rect column = loc;

	int xpos = rect.x;
	if(lang_rtl)
		xpos += rect.w;
	for(size_t i = 0; i != row.size(); ++i) {

		if(lang_rtl)
			xpos -= widths[i];
		if(type == HEADING_ROW && highlight_heading_ == int(i)) {
			draw_solid_tinted_rectangle(xpos,rect.y,widths[i],rect.h,255,255,255,0.3,video().getSurface());
		}

		const int last_x = xpos;
		column.w = widths[i];
		std::string str = row[i];
		std::vector<std::string> img_text_items = utils::split(str, IMG_TEXT_SEPARATOR, utils::REMOVE_EMPTY);
		for (std::vector<std::string>::const_iterator it = img_text_items.begin();
			 it != img_text_items.end(); it++) {
			str = *it;
			if (!str.empty() && str[0] == IMAGE_PREFIX) {
				const std::string image_name(str.begin()+1,str.end());
				const surface img = style_->get_item_image(image_name);
				const int remaining_width = max_width_ < 0 ? area.w :
				std::min<int>(max_width_, ((lang_rtl)? xpos - rect.x : rect.x + rect.w - xpos));
				if(img != NULL && img->w <= remaining_width
				&& rect.y + img->h < area.h) {
					const size_t y = rect.y + (rect.h - img->h)/2;
					const size_t w = img->w + 5;
					const size_t x = xpos + ((lang_rtl) ? widths[i] - w : 0);
					video().blit_surface(x,y,img);
					if(!lang_rtl)
						xpos += w;
					column.w -= w;
				}
			} else {
				column.x = xpos;
				const bool has_wrap = (str.find_first_of("\r\n") != std::string::npos);
				//prevent ellipsis calculation if there is any line wrapping
				const std::string to_show =
					(use_ellipsis_ && !has_wrap) ?
						font::make_text_ellipsis(str, style_->get_font_size(),
							loc.w - (xpos - rect.x) - 2*style_->get_thickness(), false, true)
						: str;
				const SDL_Rect& text_size = font::text_area(str,style_->get_font_size());
				const size_t y = rect.y + (rect.h - text_size.h)/2;
				font::draw_text(&video(),column,style_->get_font_size(),font::NORMAL_COLOUR,to_show,xpos,y);

				if(type == HEADING_ROW && sortby_ == int(i)) {
					const surface sort_img = image::get_image(sortreversed_ ? "misc/sort-arrow.png" :
					                                   "misc/sort-arrow-reverse.png");
					if(sort_img != NULL && sort_img->w <= widths[i] && sort_img->h <= rect.h) {
						const size_t sort_x = xpos + widths[i] - sort_img->w;
						const size_t sort_y = rect.y + rect.h/2 - sort_img->h/2;
						video().blit_surface(sort_x,sort_y,sort_img);
					}
				}

				xpos += dir * (text_size.w + 5);
			}
		}
		if(lang_rtl)
			xpos = last_x;
		else
			xpos = last_x + widths[i];
	}
}
示例#17
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;
			}
		}
	}
	
}
示例#18
0
bool scrollarea::handle_drag_event(const SDL_Event& event)
{
	// KP: added content dragging for iPhone
	static bool isDragging = false;
	static int startDrag = 0;
	static int startPos = 0;
	static bool didDrag = false;
	SDL_MouseButtonEvent const &e = event.button;
	if (point_in_rect(e.x, e.y, inner_location()))
	{
		switch(event.type)
		{
			case SDL_MOUSEBUTTONUP:
			{
				isDragging = false;
				break;
			}
			case SDL_MOUSEBUTTONDOWN:
			{
				isDragging = true;
				startDrag = e.y;
				startPos = get_position();
				didDrag = false;
				break;
			}
			case SDL_MOUSEMOTION:
			{
				if (isDragging)
				{
					int changeY = startDrag - e.y;
					//SDL_Rect inner_loc = inner_location();
					//float pixelsPerScroll = item_height_ / ((float) (item_height_ * nitems()) / inner_loc.h);
					//int move = changeY / pixelsPerScroll;
					int move = changeY;
					if (move != 0)
					{
						int newPos = startPos + move;
						if (newPos < 0)
							newPos = 0;
						if (newPos > get_max_position())
							newPos = get_max_position();
						set_position(newPos);
						didDrag = true;
						
						// fixes dragging off of control
						startDrag = e.y;
						startPos = newPos;
					}
				}
				break;
			}
			default:
				break;
		}
	}
	else if (event.type == SDL_MOUSEBUTTONUP)
	{
		isDragging = false;
	}
	
	// do not select after dragging
	if (didDrag == true && isDragging == false)
	{
		didDrag = false;
		return true;
	}
	
	return false;
	// END iPhone content dragging
	
}
示例#19
0
	int multimenu::hit_checkbox(int x, int y) const {
		int cb_width = image::get_image("buttons/checkbox-pressed.png")->w;
		return x > inner_location().x + cb_width ? -1 : hit(x, y);
	}
示例#20
0
文件: menu.cpp 项目: ArtBears/wesnoth
void menu::draw_row(const size_t row_index, const SDL_Rect& rect, ROW_TYPE type)
{
	//called from style, draws one row's contents in a generic and adaptable way
	const std::vector<std::string>& row = (type == HEADING_ROW) ? heading_ : items_[row_index].fields;
	SDL_Rect const &area = screen_area();
	SDL_Rect const &loc = inner_location();
	const std::vector<int>& widths = column_widths();
	bool lang_rtl = current_language_rtl();
	int dir = (lang_rtl) ? -1 : 1;
	SDL_Rect column = loc;

	int xpos = rect.x;
	if(lang_rtl)
		xpos += rect.w;
	for(size_t i = 0; i != row.size(); ++i) {

		if(lang_rtl)
			xpos -= widths[i];
		if(type == HEADING_ROW) {
#ifdef SDL_GPU
			const SDL_Rect pos = sdl::create_rect(xpos, rect.y, widths[i], rect.h);
			if(highlight_heading_ == int(i)) {
				sdl::fill_rect(video(), pos, 255, 255, 255, 75);
			} else if(sortby_ == int(i)) {
				sdl::fill_rect(video(), pos, 255, 255, 255, 25);
			}
		}

		const int last_x = xpos;
		column.w = widths[i];
		std::string str = row[i];
		std::vector<std::string> img_text_items = utils::split(str, IMG_TEXT_SEPARATOR, utils::REMOVE_EMPTY);
		for (std::vector<std::string>::const_iterator it = img_text_items.begin();
			 it != img_text_items.end(); ++it) {
			str = *it;
			if (!str.empty() && str[0] == IMAGE_PREFIX) {
				const std::string image_name(str.begin()+1,str.end());
				sdl::timage img = style_->get_item_image(image_name);
				const int remaining_width = max_width_ < 0 ? area.w :
				std::min<int>(max_width_, ((lang_rtl)? xpos - rect.x : rect.x + rect.w - xpos));
				if(!img.null() && img.width() <= remaining_width
				&& rect.y + img.height() < area.h) {
					const size_t y = rect.y + (rect.h - img.height())/2;
					const size_t w = img.width() + 5;
					const size_t x = xpos + ((lang_rtl) ? widths[i] - w : 0);
					video().draw_texture(img, x, y);
					if(!lang_rtl)
						xpos += w;
					column.w -= w;
				}
			} else {
				column.x = xpos;
				const bool has_wrap = (str.find_first_of("\r\n") != std::string::npos);
				//prevent ellipsis calculation if there is any line wrapping
				std::string to_show = str;
				if (use_ellipsis_ && !has_wrap)
				{
					int fs = style_->get_font_size();
					int style = TTF_STYLE_NORMAL;
					int w = loc.w - (xpos - rect.x) - 2 * style_->get_thickness();
					std::string::const_iterator i_beg = to_show.begin(), i_end = to_show.end(),
						i = font::parse_markup(i_beg, i_end, &fs, nullptr, &style);
					if (i != i_end) {
						std::string tmp(i, i_end);
						to_show.erase(i - i_beg, i_end - i_beg);
						to_show += font::make_text_ellipsis(tmp, fs, w, style);
					}
				}
				const SDL_Rect& text_size = font::text_area(str,style_->get_font_size());
				const size_t y = rect.y + (rect.h - text_size.h)/2;
				const size_t padding = 2;
				sdl::timage text_img = font::draw_text_to_texture(column,style_->get_font_size(),font::NORMAL_COLOR,to_show);
				video().draw_texture(text_img, (type == HEADING_ROW ? xpos+padding : xpos), y);
					if(type == HEADING_ROW && sortby_ == int(i)) {
					sdl::timage sort_img = image::get_texture("buttons/sliders/slider_arrow_blue.png");
					sort_img.set_rotation(sortreversed_ ? 0 : 180);
					if(!sort_img.null() && sort_img.width() <= widths[i] && sort_img.height() <= rect.h) {
						const size_t sort_x = xpos + widths[i] - sort_img.width() - padding;
						const size_t sort_y = rect.y + rect.h/2 - sort_img.height()/2;
						video().draw_texture(sort_img, sort_x, sort_y);
					}
				}
					xpos += dir * (text_size.w + 5);
			}
		}
		if(lang_rtl)
			xpos = last_x;
		else
			xpos = last_x + widths[i];
	}
#else
			if(highlight_heading_ == int(i)) {
				sdl::draw_solid_tinted_rectangle(xpos,rect.y,widths[i],rect.h,255,255,255,0.3,video().getSurface());
			} else if(sortby_ == int(i)) {
				sdl::draw_solid_tinted_rectangle(xpos,rect.y,widths[i],rect.h,255,255,255,0.1,video().getSurface());
			}
		}
示例#21
0
void textbox::draw_contents()
{
	SDL_Rect const &loc = inner_location();

	surface surf = video().getSurface();
	draw_solid_tinted_rectangle(loc.x,loc.y,loc.w,loc.h,0,0,0,
				    focus(NULL) ? alpha_focus_ : alpha_, surf);

	SDL_Rect src;

	if(text_image_ == NULL) {
		update_text_cache(true);
	}

	if(text_image_ != NULL) {
		src.y = yscroll_;
		src.w = std::min<size_t>(loc.w,text_image_->w);
		src.h = std::min<size_t>(loc.h,text_image_->h);
		src.x = text_pos_;
		SDL_Rect dest = screen_area();
		dest.x = loc.x;
		dest.y = loc.y;

		// Fills the selected area
		if(enabled() && is_selection()) {
			const int start = std::min<int>(selstart_,selend_);
			const int end = std::max<int>(selstart_,selend_);
			int startx = char_x_[start];
			int starty = char_y_[start];
			const int endx = char_x_[end];
			const int endy = char_y_[end];

			while(starty <= endy) {
				const size_t right = starty == endy ? endx : text_image_->w;
				if(right <= size_t(startx)) {
					break;
				}

				SDL_Rect rect = create_rect(loc.x + startx
						, loc.y + starty - src.y
						, right - startx
						, line_height_);

				const clip_rect_setter clipper(surf, &loc);

				Uint32 color = SDL_MapRGB(surf->format, 0, 0, 160);
				fill_rect_alpha(rect, color, 140, surf);

				starty += int(line_height_);
				startx = 0;
			}
		}

		if(enabled()) {
			sdl_blit(text_image_, &src, surf, &dest);
		} else {
			// HACK: using 30% opacity allows white text to look as though it is grayed out,
			// while not changing any applicable non-grayscale AA. Actual colored text will
			// not look as good, but this is not currently a concern since GUI1 textboxes
			// are not used much nowadays, and they will eventually all go away.
			sdl_blit(adjust_surface_alpha(text_image_, ftofxp(0.3)), &src, surf, &dest);
		}
	}

	draw_cursor((cursor_pos_ == 0 ? 0 : cursor_pos_ - 1), video());

	update_rect(loc);
}