Пример #1
0
void the_end(display &disp, std::string text, unsigned int duration)
{
	//
	// Some sane defaults.
	//
	if(text.empty())
		text = _("The End");
	if(!duration)
		duration = 3500;

	SDL_Rect area = screen_area();
	CVideo &video = disp.video();
	sdl_fill_rect(video.getSurface(),&area,0);

	update_whole_screen();
	disp.flip();

	const size_t font_size = font::SIZE_XLARGE;

	area = font::text_area(text,font_size);
	area.x = screen_area().w/2 - area.w/2;
	area.y = screen_area().h/2 - area.h/2;

	for(size_t n = 0; n < 255; n += 5) {
		if(n)
			sdl_fill_rect(video.getSurface(),&area,0);

		const SDL_Color col = create_color(n, n, n, n);
		font::draw_text(&video,area,font_size,col,text,area.x,area.y);
		update_rect(area);

		events::pump();
		events::raise_process_event();
		events::raise_draw_event();
		disp.flip();
		disp.delay(10);
	}

	//
	// Delay after the end of fading.
	// Rounded to multiples of 10.
	//
	unsigned int count = duration/10;
	while(count) {
		events::pump();
		events::raise_process_event();
		events::raise_draw_event();
		disp.flip();
		disp.delay(10);
		--count;
	}
}
Пример #2
0
SDL_Rect dialog_frame::draw_title(CVideo* video)
{
	SDL_Rect rect = {0, 0, 10000, 10000};
	rect = screen_area();
	return font::draw_text(video, rect, font::SIZE_LARGE, font::TITLE_COLOR,
	                       title_, dim_.title.x, dim_.title.y, false, TTF_STYLE_BOLD);
}
Пример #3
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(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);
}
void button::calculate_size()
{
	if (type_ == TYPE_IMAGE){
		SDL_Rect loc_image = location();
		loc_image.h = image_->h;
		loc_image.w = image_->w;
		set_location(loc_image);
		return;
	}
	SDL_Rect const &loc = location();
	bool change_size = loc.h == 0 || loc.w == 0;

	if (!change_size) {
		unsigned w = loc.w - (type_ == TYPE_PRESS ? horizontal_padding : checkbox_horizontal_padding + base_width_);
		if (type_ != TYPE_IMAGE)
		{
			int fs = font_size;
			int style = TTF_STYLE_NORMAL;
			std::string::const_iterator i_beg = label_.begin(), i_end = label_.end(),
				i = font::parse_markup(i_beg, i_end, &fs, NULL, &style);
			if (i != i_end) {
				std::string tmp(i, i_end);
				label_.erase(i - i_beg, i_end - i_beg);
				label_ += font::make_text_ellipsis(tmp, fs, w, style);
			}
		}
	}

	if (type_ != TYPE_IMAGE){
		textRect_ = font::draw_text(NULL, screen_area(), font_size,
		                            font::BUTTON_COLOR, label_, 0, 0);
	}

	if (!change_size)
		return;

#ifdef USE_TINY_GUI
	set_height(textRect_.h+vertical_padding);
#else
	set_height(std::max(textRect_.h+vertical_padding,base_height_));
#endif
	if(type_ == TYPE_PRESS) {
#ifdef USE_TINY_GUI
		set_width(textRect_.w + horizontal_padding);
#else
		if(spacing_ == MINIMUM_SPACE) {
			set_width(textRect_.w + horizontal_padding);
		} else {
			set_width(std::max(textRect_.w+horizontal_padding,base_width_));
		}
#endif
	} else {
		if(label_.empty()) {
			set_width(base_width_);
		} else {
			set_width(checkbox_horizontal_padding + textRect_.w + base_width_);
		}
	}
}
Пример #5
0
void part_ui::render_story_box_borders(SDL_Rect& update_area)
{
	const part::BLOCK_LOCATION tbl = p_.story_text_location();

	if(has_background_) {
		surface border_top = NULL;
		surface border_bottom = NULL;

		if(tbl == part::BLOCK_BOTTOM || tbl == part::BLOCK_MIDDLE) {
			border_top = image::get_image(storybox_top_border_path);
		}

		if(tbl == part::BLOCK_TOP || tbl == part::BLOCK_MIDDLE) {
			border_bottom = image::get_image(storybox_bottom_border_path);
		}

		//
		// If one of those are null at this point, it means that either we
		// don't need that border pic, or it is missing (in such case get_image()
		// would report).
		//

		if(border_top.null() != true) {
			if((border_top = scale_surface_blended(border_top, screen_area().w, border_top->h)).null()) {
				WARN_NG << "storyscreen got a null top border surface after rescaling\n";
			}
			else {
				update_area.y -= border_top->h;
				update_area.h += border_top->h;
				blur_area(video_, update_area.y, border_top->h);
				video_.blit_surface(0, update_area.y, border_top);
			}
		}

		if(border_bottom.null() != true) {
			if((border_bottom = scale_surface_blended(border_bottom, screen_area().w, border_bottom->h)).null()) {
				WARN_NG << "storyscreen got a null bottom border surface after rescaling\n";
			}
			else {
				blur_area(video_, update_area.h, border_bottom->h);
				video_.blit_surface(0, update_area.y+update_area.h, border_bottom);
				update_area.h += border_bottom->h;
			}
		}
	}
}
Пример #6
0
void button::calculate_size()
{
	if (type_ == TYPE_IMAGE){
		SDL_Rect loc_image = location();
		loc_image.h = image_->h;
		loc_image.w = image_->w;
		set_location(loc_image);
		return;
	}
	SDL_Rect const &loc = location();
	bool change_size = loc.h == 0 || loc.w == 0;

	if (!change_size) {
		unsigned w = loc.w - (type_ == TYPE_PRESS ? horizontal_padding : checkbox_horizontal_padding + base_width_);
		if (type_ != TYPE_IMAGE){
			label_ = font::make_text_ellipsis(label_, font_size, w, false);
		}
	}

	if (type_ != TYPE_IMAGE){
		textRect_ = font::draw_text(NULL, screen_area(), font_size,
		                            font::BUTTON_COLOUR, label_, 0, 0);
	}

	if (!change_size)
		return;

#ifdef USE_TINY_GUI
	set_height(textRect_.h+vertical_padding);
#else
	set_height(std::max(textRect_.h+vertical_padding,base_height_));
#endif
	if(type_ == TYPE_PRESS) {
#ifdef USE_TINY_GUI
		set_width(textRect_.w + horizontal_padding);
#else
		if(spacing_ == MINIMUM_SPACE) {
			set_width(textRect_.w + horizontal_padding);
		} else {
			set_width(std::max(textRect_.w+horizontal_padding,base_width_));
		}
#endif
	} else {
		if(label_.empty()) {
			set_width(base_width_);
		} else {
			set_width(checkbox_horizontal_padding + textRect_.w + base_width_);
		}
	}
}
Пример #7
0
static bool fullscreen(CVideo& video)
{
	preferences::set_fullscreen(video , !preferences::fullscreen());

	// Setting to fullscreen doesn't seem to generate a resize event.
	const SDL_Rect& rect = screen_area();

	SDL_Event event;
	event.type = SDL_VIDEORESIZE;
	event.resize.type = SDL_VIDEORESIZE;
	event.resize.w = rect.w;
	event.resize.h = rect.h;

	SDL_PushEvent(&event);

	return true;
}
Пример #8
0
static void show_tooltip(const tooltip& tip)
{
	if(video_ == NULL) {
		return;
	}

	clear_tooltip();

	const SDL_Color bgcolor = {0,0,0,160};
#if defined(_KINGDOM_EXE) || !defined(_WIN32)
	SDL_Rect area = screen_area();
#else
	SDL_Rect area = create_rect(0, 0, 800, 600);
#endif

	unsigned int border = 10;

	font::floating_label flabel(tip.message);
	flabel.set_font_size(font_size);
	flabel.set_color(font::NORMAL_COLOR);
	flabel.set_clip_rect(area);
	flabel.set_width(text_width);
	flabel.set_bg_color(bgcolor);
	flabel.set_border_size(border);

	tooltip_handle = font::add_floating_label(flabel);

	SDL_Rect rect = font::get_floating_label_rect(tooltip_handle);

	//see if there is enough room to fit it above the tip area
	if(tip.rect.y > rect.h) {
		rect.y = tip.rect.y - rect.h;
	} else {
		rect.y = tip.rect.y + tip.rect.h;
	}

	rect.x = tip.rect.x;
	if(rect.x < 0) {
		rect.x = 0;
	} else if(rect.x + rect.w > area.w) {
		rect.x = area.w - rect.w;
	}

	font::move_floating_label(tooltip_handle,rect.x,rect.y);
}
Пример #9
0
static void do_preferences_dialog(game_display& disp, const config& game_config)
{
	const preferences::display_manager disp_manager(&disp);
	preferences::show_preferences_dialog(disp,game_config);

	/**
	 * The screen size might have changed force an update of the size.
	 *
	 * @todo This might no longer be needed when gui2 is done.
	 */
	const SDL_Rect rect = screen_area();
	preferences::set_resolution(disp.video(), rect.w, rect.h);

	gui2::settings::gamemap_width += rect.w - gui2::settings::screen_width ;
	gui2::settings::gamemap_height += rect.h - gui2::settings::screen_height ;
	gui2::settings::screen_width = rect.w;
	gui2::settings::screen_height = rect.h;
}
Пример #10
0
static void show_tooltip(const tooltip& tip)
{
	if(video_ == NULL) {
		return;
	}

	clear_tooltip();

	const SDL_Color bgcolor = {0,0,0,160};
	SDL_Rect area = screen_area();

	unsigned int border = 10;

	font::floating_label flabel(tip.message, tip.foreground);
	flabel.use_markup(tip.markup);
	flabel.set_font_size(font_size);
	flabel.set_color(font::NORMAL_COLOR);
	flabel.set_clip_rect(area);
	flabel.set_width(text_width);
	flabel.set_alignment(font::LEFT_ALIGN);
	flabel.set_bg_color(bgcolor);
	flabel.set_border_size(border);

	tooltip_handle = font::add_floating_label(flabel);

	SDL_Rect rect = font::get_floating_label_rect(tooltip_handle);

	//see if there is enough room to fit it above the tip area
	if(tip.rect.y > rect.h) {
		rect.y = tip.rect.y - rect.h;
	} else {
		rect.y = tip.rect.y + tip.rect.h;
	}

	rect.x = tip.rect.x;
	if(rect.x < 0) {
		rect.x = 0;
	} else if(rect.x + rect.w > area.w) {
		rect.x = area.w - rect.w;
	}

	font::move_floating_label(tooltip_handle,rect.x,rect.y);
}
Пример #11
0
static bool fullscreen(CVideo& video)
{
	video.set_fullscreen(!preferences::fullscreen());

#if !SDL_VERSION_ATLEAST(2, 0, 0)
	// Setting to fullscreen doesn't seem to generate a resize event.
	const SDL_Rect& rect = screen_area();

	SDL_Event event;
	event.type = SDL_VIDEORESIZE;
	event.resize.type = SDL_VIDEORESIZE;
	event.resize.w = rect.w;
	event.resize.h = rect.h;

	SDL_PushEvent(&event);
#endif

	return true;
}
Пример #12
0
static void show_tooltip(const tooltip& tip)
{
	if(video_ == NULL) {
		return;
	}

	clear_tooltip();

	const SDL_Color bgcolour = {0,0,0,128};
	SDL_Rect area = screen_area();

#ifdef USE_TINY_GUI
	unsigned int border = 2;
#else
	unsigned int border = 10;
#endif

	const std::string wrapped_message = font::word_wrap_text(tip.message, font_size, text_width);
	tooltip_handle = font::add_floating_label(wrapped_message,font_size,tip.color,
	                                          0,0,0,0,-1,area,font::LEFT_ALIGN,&bgcolour,border);

	SDL_Rect rect = font::get_floating_label_rect(tooltip_handle);

	//see if there is enough room to fit it above the tip area
	if(tip.rect.y > rect.h) {
		rect.y = tip.rect.y - rect.h;
	} else {
		rect.y = tip.rect.y + tip.rect.h;
	}

	rect.x = tip.rect.x;
	if(rect.x < 0) {
		rect.x = 0;
	} else if(rect.x + rect.w > area.w) {
		rect.x = area.w - rect.w;
	}

	font::move_floating_label(tooltip_handle,rect.x,rect.y);
}
Пример #13
0
static bool fullscreen(CVideo& video)
{
	preferences::set_fullscreen(video, !preferences::fullscreen());

	// Setting to fullscreen doesn't seem to generate a resize event.
	const SDL_Rect& rect = screen_area();

	SDL_Event event;
#if SDL_VERSION_ATLEAST(2, 0, 0)
	event.type = SDL_WINDOWEVENT;
	event.window.event = SDL_WINDOWEVENT_RESIZED;
	event.window.data1 = rect.w;
	event.window.data2 = rect.h;
#else
	event.type = SDL_VIDEORESIZE;
	event.resize.type = SDL_VIDEORESIZE;
	event.resize.w = rect.w;
	event.resize.h = rect.h;
#endif

	SDL_PushEvent(&event);

	return true;
}
Пример #14
0
	/**
	 * the dimensions of the display. x and y are width/height.
	 * mapx is the width of the portion of the display which shows the game area.
	 * Between mapx and x is the sidebar region.
	 */
	int w() const { return screen_.getx(); }	/**< width */
	int h() const { return screen_.gety(); }	/**< height */
	const SDL_Rect& minimap_area() const
		{ return theme_.mini_map_location(screen_area()); }
Пример #15
0
	const SDL_Rect& unit_image_area() const
		{ return theme_.unit_image_location(screen_area()); }
Пример #16
0
/*! Pick a monitor to place a window on. */
static Rect* choose_monitor(ObClient *c, gboolean client_to_be_foregrounded,
                            ObAppSettings *settings)
{
    Rect *area;
    ObPlaceHead *choice;
    guint i;
    ObClient *p;
    GSList *it;

    choice = g_new(ObPlaceHead, screen_num_monitors);
    for (i = 0; i < screen_num_monitors; ++i) {
        choice[i].monitor = i;
        choice[i].flags = 0;
    }

    /* find monitors with group members */
    if (c->group) {
        for (it = c->group->members; it; it = g_slist_next(it)) {
            ObClient *itc = it->data;
            if (itc != c) {
                guint m = client_monitor(itc);

                if (m < screen_num_monitors) {
                    if (screen_compare_desktops(itc->desktop, c->desktop))
                        choice[m].flags |= HEAD_GROUP_DESK;
                    else
                        choice[m].flags |= HEAD_GROUP;
                }
            }
        }
    }

    i = screen_monitor_primary(FALSE);
    if (i < screen_num_monitors) {
        choice[i].flags |= HEAD_PRIMARY;
        if (config_place_monitor == OB_PLACE_MONITOR_PRIMARY)
            choice[i].flags |= HEAD_PLACED;
        if (settings &&
            settings->monitor_type == OB_PLACE_MONITOR_PRIMARY)
            choice[i].flags |= HEAD_PERAPP;
    }

    i = screen_monitor_active();
    if (i < screen_num_monitors) {
        if (config_place_monitor == OB_PLACE_MONITOR_ACTIVE)
            choice[i].flags |= HEAD_PLACED;
        if (settings &&
            settings->monitor_type == OB_PLACE_MONITOR_ACTIVE)
            choice[i].flags |= HEAD_PERAPP;
    }

    i = screen_monitor_pointer();
    if (i < screen_num_monitors) {
        if (config_place_monitor == OB_PLACE_MONITOR_MOUSE)
            choice[i].flags |= HEAD_PLACED;
        if (settings &&
            settings->monitor_type == OB_PLACE_MONITOR_MOUSE)
            choice[i].flags |= HEAD_PERAPP;
    }

    if (settings) {
        i = settings->monitor - 1;
        if (i < screen_num_monitors)
            choice[i].flags |= HEAD_PERAPP;
    }

    /* direct parent takes highest precedence */
    if ((p = client_direct_parent(c))) {
        i = client_monitor(p);
        if (i < screen_num_monitors)
            choice[i].flags |= HEAD_PARENT;
    }

    qsort(choice, screen_num_monitors, sizeof(ObPlaceHead),
          client_to_be_foregrounded ? cmp_foreground : cmp_background);

    /* save the areas of the monitors in order of their being chosen */
    for (i = 0; i < screen_num_monitors; ++i)
    {
        ob_debug("placement choice %d is monitor %d", i, choice[i].monitor);
        if (choice[i].flags & HEAD_PARENT)
            ob_debug("  - parent on monitor");
        if (choice[i].flags & HEAD_PLACED)
            ob_debug("  - placement choice");
        if (choice[i].flags & HEAD_PRIMARY)
            ob_debug("  - primary monitor");
        if (choice[i].flags & HEAD_GROUP_DESK)
            ob_debug("  - group on same desktop");
        if (choice[i].flags & HEAD_GROUP)
            ob_debug("  - group on other desktop");
    }

    area = screen_area(c->desktop, choice[0].monitor, NULL);

    g_free(choice);

    /* return the area for the chosen monitor */
    return area;
}
Пример #17
0
static Rect *choose_pointer_monitor(ObClient *c)
{
    return screen_area(c->desktop, screen_monitor_pointer(), NULL);
}
Пример #18
0
	    (const FcChar8*)mc->dispstr, strlen(mc->dispstr), &extents);
	mc->geom.w = extents.xOff;
	mc->geom.h = sc->xftfont->height + 1;
	mc->num = 1;

	TAILQ_FOREACH(mi, resultq, resultentry) {
		(*mc->print)(mi, mc->listing);
		XftTextExtentsUtf8(X_Dpy, sc->xftfont,
		    (const FcChar8*)mi->print,
		    MIN(strlen(mi->print), MENU_MAXENTRY), &extents);
		mc->geom.w = MAX(mc->geom.w, extents.xOff);
		mc->geom.h += sc->xftfont->height + 1;
		mc->num++;
	}

	area = screen_area(sc, mc->geom.x, mc->geom.y, CWM_GAP);
	area.w += area.x - Conf.bwidth * 2;
	area.h += area.y - Conf.bwidth * 2;

	xsave = mc->geom.x;
	ysave = mc->geom.y;

	/* Never hide the top, or left side, of the menu. */
	if (mc->geom.x + mc->geom.w >= area.w)
		mc->geom.x = area.w - mc->geom.w;
	if (mc->geom.x < area.x) {
		mc->geom.x = area.x;
		mc->geom.w = MIN(mc->geom.w, (area.w - area.x));
	}
	if (mc->geom.y + mc->geom.h >= area.h)
		mc->geom.y = area.h - mc->geom.h;
Пример #19
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) {
#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());
			}
		}
Пример #20
0
void
mousefunc_client_move(void *ctx, union arg *arg, enum xev xev)
{
	struct client_ctx	*cc = ctx;
	XEvent			 ev;
	Time			 ltime = 0;
	struct screen_ctx	*sc = cc->sc;
	struct geom		 area;
	int			 px, py;

	client_raise(cc);

	if (cc->flags & CLIENT_FREEZE)
		return;

	xu_ptr_getpos(cc->win, &px, &py);
	if (px < 0) 
		px = 0;
	else if (px > cc->geom.w)
		px = cc->geom.w;
	if (py < 0)
		py = 0;
	else if (py > cc->geom.h)
		py = cc->geom.h;

	xu_ptr_setpos(cc->win, px, py);

	if (XGrabPointer(X_Dpy, cc->win, False, MOUSEMASK,
	    GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_MOVE],
	    CurrentTime) != GrabSuccess)
		return;

	menu_windraw(sc, cc->win, "%4d, %-4d", cc->geom.x, cc->geom.y);

	for (;;) {
		XWindowEvent(X_Dpy, cc->win, MOUSEMASK, &ev);

		switch (ev.type) {
		case MotionNotify:
			/* not more than 60 times / second */
			if ((ev.xmotion.time - ltime) <= (1000 / 60))
				continue;
			ltime = ev.xmotion.time;

			cc->geom.x = ev.xmotion.x_root - px - cc->bwidth;
			cc->geom.y = ev.xmotion.y_root - py - cc->bwidth;

			area = screen_area(sc,
			    cc->geom.x + cc->geom.w / 2,
			    cc->geom.y + cc->geom.h / 2, CWM_GAP);
			cc->geom.x += client_snapcalc(cc->geom.x,
			    cc->geom.x + cc->geom.w + (cc->bwidth * 2),
			    area.x, area.x + area.w, sc->snapdist);
			cc->geom.y += client_snapcalc(cc->geom.y,
			    cc->geom.y + cc->geom.h + (cc->bwidth * 2),
			    area.y, area.y + area.h, sc->snapdist);
			client_move(cc);
			menu_windraw(sc, cc->win,
			    "%4d, %-4d", cc->geom.x, cc->geom.y);
			break;
		case ButtonRelease:
			client_move(cc);
			XUnmapWindow(X_Dpy, sc->menu.win);
			XReparentWindow(X_Dpy, sc->menu.win, sc->rootwin, 0, 0);
			XUngrabPointer(X_Dpy, CurrentTime);
			return;
		}
	}
	/* NOTREACHED */
}
Пример #21
0
void default_map_generator::user_config(display& disp)
{
	const resize_lock prevent_resizing;
	const events::event_context dialog_events_context;

	CVideo& screen = disp.video();

	const int width = 600;
	const int height = 400;
	const int xpos = screen.getx()/2 - width/2;
	int ypos = screen.gety()/2 - height/2;

	gui::button close_button(screen,_("Close"));
	std::vector<gui::button*> buttons(1,&close_button);

	gui::dialog_frame f(screen,_("Map Generator"),gui::dialog_frame::default_style,true,&buttons);
	f.layout(xpos,ypos,width,height);
	f.draw();

	SDL_Rect dialog_rect = sdl::create_rect(xpos, ypos, width, height);
	surface_restorer dialog_restorer(&screen,dialog_rect);

	const std::string& players_label = _("Players:");
	const std::string& width_label = _("Width:");
	const std::string& height_label = _("Height:");
	const std::string& iterations_label = _("Number of hills:");
	const std::string& hillsize_label = _("Max hill size:");
	const std::string& villages_label = _("Villages:");
	const std::string& castlesize_label = _("Castle size:");
	const std::string& landform_label = _("Landform:");

	SDL_Rect players_rect = font::draw_text(NULL,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,players_label,0,0);
	SDL_Rect width_rect = font::draw_text(NULL,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,width_label,0,0);
	SDL_Rect height_rect = font::draw_text(NULL,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,height_label,0,0);
	SDL_Rect iterations_rect = font::draw_text(NULL,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,iterations_label,0,0);
	SDL_Rect hillsize_rect = font::draw_text(NULL,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,hillsize_label,0,0);
	SDL_Rect villages_rect = font::draw_text(NULL,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,villages_label,0,0);
	SDL_Rect castlesize_rect = font::draw_text(NULL,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,castlesize_label,0,0);
	SDL_Rect landform_rect = font::draw_text(NULL,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,landform_label,0,0);

	const int horz_margin = 15;
	const int text_right = xpos + horz_margin +
	        std::max<int>(std::max<int>(std::max<int>(std::max<int>(std::max<int>(std::max<int>(
		         players_rect.w,width_rect.w),height_rect.w),iterations_rect.w),hillsize_rect.w),villages_rect.w),castlesize_rect.w);

	players_rect.x = text_right - players_rect.w;
	width_rect.x = text_right - width_rect.w;
	height_rect.x = text_right - height_rect.w;
	iterations_rect.x = text_right - iterations_rect.w;
	hillsize_rect.x = text_right - hillsize_rect.w;
	villages_rect.x = text_right - villages_rect.w;
	castlesize_rect.x = text_right - castlesize_rect.w;
	landform_rect.x = text_right - landform_rect.w;

	const int vertical_margin = 20;
	players_rect.y = ypos + vertical_margin*2;
	width_rect.y = players_rect.y + players_rect.h + vertical_margin;
	height_rect.y = width_rect.y + width_rect.h + vertical_margin;
	iterations_rect.y = height_rect.y + height_rect.h + vertical_margin;
	hillsize_rect.y = iterations_rect.y + iterations_rect.h + vertical_margin;
	villages_rect.y = hillsize_rect.y + hillsize_rect.h + vertical_margin;
	castlesize_rect.y = villages_rect.y + iterations_rect.h + vertical_margin;
	landform_rect.y = castlesize_rect.y + villages_rect.h + vertical_margin;

	const int right_space = 150;

	const int slider_left = text_right + 10;
	const int slider_right = xpos + width - horz_margin - right_space;
	SDL_Rect slider_rect = sdl::create_rect(slider_left
			, players_rect.y
			, slider_right - slider_left
			, players_rect.h);

	gui::slider players_slider(screen);
	players_slider.set_location(slider_rect);
	players_slider.set_min(2);
	players_slider.set_max(gamemap::MAX_PLAYERS);
	players_slider.set_value(nplayers_);

	const int min_width = 20;
	const int max_width = 100;
	const int max_height = 100;
	const int extra_size_per_player = 2;

	slider_rect.y = width_rect.y;
	gui::slider width_slider(screen);
	width_slider.set_location(slider_rect);
	width_slider.set_min(min_width+(players_slider.value()-2)*extra_size_per_player);
	width_slider.set_max(max_width);
	width_slider.set_value(width_);

	slider_rect.y = height_rect.y;
	gui::slider height_slider(screen);
	height_slider.set_location(slider_rect);
	height_slider.set_min(min_width+(players_slider.value()-2)*extra_size_per_player);
	height_slider.set_max(max_height);
	height_slider.set_value(height_);

	const int min_iterations = 10;
	const int max_iterations = 3000;

	slider_rect.y = iterations_rect.y;
	gui::slider iterations_slider(screen);
	iterations_slider.set_location(slider_rect);
	iterations_slider.set_min(min_iterations);
	iterations_slider.set_max(max_iterations);
	iterations_slider.set_value(iterations_);

	const int min_hillsize = 1;
	const int max_hillsize = 50;

	slider_rect.y = hillsize_rect.y;
	gui::slider hillsize_slider(screen);
	hillsize_slider.set_location(slider_rect);
	hillsize_slider.set_min(min_hillsize);
	hillsize_slider.set_max(max_hillsize);
	hillsize_slider.set_value(hill_size_);

	const int min_villages = 0;
	const int max_villages = 50;

	slider_rect.y = villages_rect.y;
	gui::slider villages_slider(screen);
	villages_slider.set_location(slider_rect);
	villages_slider.set_min(min_villages);
	villages_slider.set_max(max_villages);
	villages_slider.set_value(nvillages_);

	const int min_castlesize = 2;
	const int max_castlesize = 14;

	slider_rect.y = castlesize_rect.y;
	gui::slider castlesize_slider(screen);
	castlesize_slider.set_location(slider_rect);
	castlesize_slider.set_min(min_castlesize);
	castlesize_slider.set_max(max_castlesize);
	castlesize_slider.set_value(castle_size_);


	const int min_landform = 0;
	const int max_landform = int(max_island);
	slider_rect.y = landform_rect.y;
	gui::slider landform_slider(screen);
	landform_slider.set_location(slider_rect);
	landform_slider.set_min(min_landform);
	landform_slider.set_max(max_landform);
	landform_slider.set_value(island_size_);

	SDL_Rect link_rect = slider_rect;
	link_rect.y = link_rect.y + link_rect.h + vertical_margin;

	gui::button link_castles(screen,_("Roads between castles"),gui::button::TYPE_CHECK);
	link_castles.set_check(link_castles_);
	link_castles.set_location(link_rect);

	SDL_Rect labels_rect = link_rect;
	labels_rect.y = labels_rect.y + labels_rect.h + vertical_margin;

	gui::button show_labels(screen,_("Show labels"),gui::button::TYPE_CHECK);
	show_labels.set_check(show_labels_);
	show_labels.set_location(labels_rect);

	while(true) {
		nplayers_ = players_slider.value();
		width_ = width_slider.value();
		height_ = height_slider.value();
		iterations_ = iterations_slider.value();
		hill_size_ = hillsize_slider.value();
		nvillages_ = villages_slider.value();
		castle_size_ = castlesize_slider.value();
		island_size_ = landform_slider.value();

		dialog_restorer.restore();
		close_button.set_dirty(true);
		if (close_button.pressed())
			break;

		players_slider.set_dirty();
		width_slider.set_dirty();
		height_slider.set_dirty();
		iterations_slider.set_dirty();
		hillsize_slider.set_dirty();
		villages_slider.set_dirty();
		castlesize_slider.set_dirty();
		landform_slider.set_dirty();
		link_castles.set_dirty();
		show_labels.set_dirty();

		width_slider.set_min(min_width+(players_slider.value()-2)*extra_size_per_player);
		height_slider.set_min(min_width+(players_slider.value()-2)*extra_size_per_player);

		events::raise_process_event();
		events::raise_draw_event();

		font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,players_label,players_rect.x,players_rect.y);
		font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,width_label,width_rect.x,width_rect.y);
		font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,height_label,height_rect.x,height_rect.y);
		font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,iterations_label,iterations_rect.x,iterations_rect.y);
		font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,hillsize_label,hillsize_rect.x,hillsize_rect.y);
		font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,villages_label,villages_rect.x,villages_rect.y);
		font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,castlesize_label,castlesize_rect.x,castlesize_rect.y);
		font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,landform_label,landform_rect.x,landform_rect.y);

		font::draw_text(&screen, screen_area(), font::SIZE_NORMAL,
			font::NORMAL_COLOR, str_cast(nplayers_),
			slider_right + horz_margin, players_rect.y);

		font::draw_text(&screen, screen_area(), font::SIZE_NORMAL,
			font::NORMAL_COLOR, str_cast(width_),
			slider_right + horz_margin, width_rect.y);

		font::draw_text(&screen, screen_area(), font::SIZE_NORMAL,
			font::NORMAL_COLOR, str_cast(height_),
			slider_right+horz_margin,height_rect.y);

		std::stringstream villages_str;
		villages_str << nvillages_ << _("/1000 tiles");
		font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,villages_str.str(),
		                slider_right+horz_margin,villages_rect.y);

		font::draw_text(&screen, screen_area(), font::SIZE_NORMAL,
			font::NORMAL_COLOR, str_cast(castle_size_),
			slider_right + horz_margin, castlesize_rect.y);

		std::stringstream landform_str;
		landform_str << gettext(island_size_ == 0 ? N_("Inland") : (island_size_ < max_coastal ? N_("Coastal") : N_("Island")));
		font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,landform_str.str(),
			            slider_right+horz_margin,landform_rect.y);

		update_rect(xpos,ypos,width,height);

		disp.update_display();
		disp.delay(100);
		events::pump();
	}

	link_castles_ = link_castles.checked();
	show_labels_ = show_labels.checked();
}
Пример #22
0
	const SDL_Rect& palette_area() const
		{ return theme_.palette_location(screen_area()); }
Пример #23
0
	/**
	 * Returns the available area for a map, this may differ
	 * from the above. This area will get the background area
	 * applied to it.
	 */
	const SDL_Rect& map_outside_area() const { return map_screenshot_ ?
		max_map_area() : theme_.main_map_location(screen_area()); }
Пример #24
0
/* Always return FALSE because its not interactive */
static gboolean run_func(ObActionsData *data, gpointer options)
{
    Options *o = options;

    if (data->client) {
        Rect *area, *carea;
        ObClient *c;
        guint mon, cmon;
        gint x, y, lw, lh, w, h;

        c = data->client;
        mon = o->monitor;
        cmon = client_monitor(c);
        switch (mon) {
        case CURRENT_MONITOR:
            mon = cmon; break;
        case ALL_MONITORS:
            mon = SCREEN_AREA_ALL_MONITORS; break;
        case NEXT_MONITOR:
            mon = (cmon + 1 > screen_num_monitors - 1) ? 0 : (cmon + 1); break;
        case PREV_MONITOR:
            mon = (cmon == 0) ? (screen_num_monitors - 1) : (cmon - 1); break;
        default:
            g_assert_not_reached();
        }

        area = screen_area(c->desktop, mon, NULL);
        carea = screen_area(c->desktop, cmon, NULL);

        w = o->w;
        if (w == G_MININT) w = c->area.width;
        else if (o->w_denom) w = (w * area->width) / o->w_denom;

        h = o->h;
        if (h == G_MININT) h = c->area.height;
        else if (o->h_denom) h = (h * area->height) / o->h_denom;

        /* it might not be able to resize how they requested, so find out what
           it will actually be resized to */
        x = c->area.x;
        y = c->area.y;
        client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE);

        /* get the frame's size */
        w += c->frame->size.left + c->frame->size.right;
        h += c->frame->size.top + c->frame->size.bottom;

        x = o->x.pos;
        if (o->x.denom)
            x = (x * area->width) / o->x.denom;
        if (o->x.center) x = (area->width - w) / 2;
        else if (x == G_MININT) x = c->frame->area.x - carea->x;
        else if (o->x.opposite) x = area->width - w - x;
        x += area->x;

        y = o->y.pos;
        if (o->y.denom)
            y = (y * area->height) / o->y.denom;
        if (o->y.center) y = (area->height - h) / 2;
        else if (y == G_MININT) y = c->frame->area.y - carea->y;
        else if (o->y.opposite) y = area->height - h - y;
        y += area->y;

        /* get the client's size back */
        w -= c->frame->size.left + c->frame->size.right;
        h -= c->frame->size.top + c->frame->size.bottom;

        frame_frame_gravity(c->frame, &x, &y); /* get the client coords */
        client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE);
        /* force it on screen if its moving to another monitor */
        client_find_onscreen(c, &x, &y, w, h, mon != cmon);

        actions_client_move(data, TRUE);
        client_configure(c, x, y, w, h, TRUE, TRUE, FALSE);
        actions_client_move(data, FALSE);

        g_slice_free(Rect, area);
        g_slice_free(Rect, carea);
    }

    return FALSE;
}
Пример #25
0
SDL_Rect dialog_frame::draw_title(CVideo* video)
{
	SDL_Rect rect = screen_area();
	return font::draw_text(video, rect, font::SIZE_TITLE, font::TITLE_COLOR,
	                       title_, dim_.title.x, dim_.title.y, false, TTF_STYLE_NORMAL);
}
Пример #26
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);
}
Пример #27
0
dialog_frame::dimension_measurements dialog_frame::layout(int x, int y, int w, int h) {
	dim_ = dimension_measurements();
	if(!title_.empty()) {
		dim_.title = draw_title(NULL);
		dim_.title.w += title_border_w;
	}
	if(buttons_ != NULL) {
		for(std::vector<button*>::const_iterator b = buttons_->begin(); b != buttons_->end(); ++b) {
			dim_.button_row.w += (**b).width() + ButtonHPadding;
			dim_.button_row.h = std::max<int>((**b).height() + ButtonVPadding,dim_.button_row.h);
		}

		dim_.button_row.x = -dim_.button_row.w;
		dim_.button_row.y = y + h;

		dim_.button_row.w += ButtonHPadding;
	}

	size_t buttons_width = dim_.button_row.w;

	if(help_button_ != NULL) {
		buttons_width += help_button_->width() + ButtonHPadding*2;
		dim_.button_row.y = y + h;
	}

	y -= dim_.title.h;
	w = std::max<int>(w,std::max<int>(int(dim_.title.w),int(buttons_width)));
	h += dim_.title.h + dim_.button_row.h;
	dim_.button_row.x += x + w;

	SDL_Rect bounds = screen_area();
	if(have_border_) {
		bounds.x += left_->w;
		bounds.y += top_->h;
		bounds.w -= left_->w;
		bounds.h -= top_->h;
	}
	if(x < bounds.x) {
		w += x;
		x = bounds.x;
	}
	if(y < bounds.y) {
		h += y;
		y = bounds.y;
	}
	if(x > bounds.w) {
		w = 0;
	} else if(x + w > bounds.w) {
		w = bounds.w - x;
	}
	if(y > bounds.h) {
		h = 0;
	} else if(y + h > bounds.h) {
		h = bounds.h - y;
	}
	dim_.interior.x = x;
	dim_.interior.y = y;
	dim_.interior.w = w;
	dim_.interior.h = h;
	if(have_border_) {
		dim_.exterior.x = dim_.interior.x - left_->w;
		dim_.exterior.y = dim_.interior.y - top_->h;
		dim_.exterior.w = dim_.interior.w + left_->w + right_->w;
		dim_.exterior.h = dim_.interior.h + top_->h + bot_->h;
	} else {
		dim_.exterior = dim_.interior;
	}
	dim_.title.x = dim_.interior.x + title_border_w;
	dim_.title.y = dim_.interior.y + title_border_h;
	return dim_;
}
Пример #28
0
void part_ui::render_story_box_borders(SDL_Rect& update_area)
{
#ifdef SDL_GPU
	const part::BLOCK_LOCATION tbl = p_.story_text_location();

	if(has_background_) {
		sdl::timage border_top;
		sdl::timage border_bottom;

		if(tbl == part::BLOCK_BOTTOM || tbl == part::BLOCK_MIDDLE) {
			border_top = image::get_texture(storybox_top_border_path);
		}

		if(tbl == part::BLOCK_TOP || tbl == part::BLOCK_MIDDLE) {
			border_bottom = image::get_texture(storybox_bottom_border_path);
		}

		//
		// If one of those are null at this point, it means that either we
		// don't need that border pic, or it is missing (in such case get_image()
		// would report).
		//

		if(border_top.null() != true) {
			const float xscale = float(screen_area().w) / border_top.base_width();
			border_top.set_hscale(xscale);
			//TODO: blurring
			video_.draw_texture(border_top, 0,
								update_area.y - border_top.base_height());
		}

		if(border_bottom.null() != true) {
			const float xscale = float(screen_area().w) / border_bottom.base_width();
			border_bottom.set_hscale(xscale);
			//TODO: blurring
			video_.draw_texture(border_bottom, 0,
								update_area.y - border_top.base_height());
		}

	}
#else
	const part::BLOCK_LOCATION tbl = p_.story_text_location();

	if(has_background_) {
		surface border_top = NULL;
		surface border_bottom = NULL;

		if(tbl == part::BLOCK_BOTTOM || tbl == part::BLOCK_MIDDLE) {
			border_top = image::get_image(storybox_top_border_path);
		}

		if(tbl == part::BLOCK_TOP || tbl == part::BLOCK_MIDDLE) {
			border_bottom = image::get_image(storybox_bottom_border_path);
		}

		//
		// If one of those are null at this point, it means that either we
		// don't need that border pic, or it is missing (in such case get_image()
		// would report).
		//

		if(border_top.null() != true) {
			if((border_top = scale_surface(border_top, screen_area().w, border_top->h)).null()) {
				WARN_NG << "storyscreen got a null top border surface after rescaling" << std::endl;
			}
			else {
				update_area.y -= border_top->h;
				update_area.h += border_top->h;
				blur_area(video_, update_area.y, border_top->h);
				video_.blit_surface(0, update_area.y, border_top);
			}
		}

		if(border_bottom.null() != true) {
			if((border_bottom = scale_surface(border_bottom, screen_area().w, border_bottom->h)).null()) {
				WARN_NG << "storyscreen got a null bottom border surface after rescaling" << std::endl;
			}
			else {
				blur_area(video_, update_area.h, border_bottom->h);
				video_.blit_surface(0, update_area.y+update_area.h, border_bottom);
				update_area.h += border_bottom->h;
			}
		}
	}
#endif
}
Пример #29
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];
	}
}
Пример #30
0
void part_ui::render_story_box()
{
#ifdef SDL_GPU
	LOG_NG << "ENTER part_ui()::render_story_box()\n";

	GPU_Target *target = get_render_target();

	const std::string& storytxt = p_.text();
	if(storytxt.empty()) {
		video_.flip();
		wait_for_input();
		return;
	}

	const part::BLOCK_LOCATION tbl = p_.story_text_location();
	const int max_width = buttons_x_ - storybox_padding - text_x_;
	const int max_height = screen_area().h - storybox_padding;

	skip_ = false;
	last_key_ = true;

	font::ttext t;
	if(!t.set_text(p_.text(), true)) {
		ERR_NG << "Text: Invalid markup in '"
				<< p_.text() << "' rendered as is.\n";
		t.set_text(p_.text(), false);
	}
	t.set_font_style(font::ttext::STYLE_NORMAL)
		 .set_font_size(storybox_font_size)
		 .set_foreground_color(storybox_font_color)
		 .set_maximum_width(max_width)
		 .set_maximum_height(max_height, true);
	sdl::timage txttxt = t.render_as_texture();

	if(txttxt.null()) {
		ERR_NG << "storyscreen text area rendering resulted in a null texture" << std::endl;
		return;
	}

	int fix_text_y = text_y_;
	if(fix_text_y + 2*(storybox_padding+1) + txttxt.height() > screen_area().h && tbl != part::BLOCK_TOP) {
		fix_text_y =
			(screen_area().h > txttxt.height() + 1) ?
			(std::max(0, screen_area().h - txttxt.height() - 2*(storybox_padding+1))) :
			(0);
	}
	int fix_text_h;
	switch(tbl) {
	case part::BLOCK_TOP:
		fix_text_h = std::max(txttxt.height() + 2*storybox_padding, screen_area().h/4);
		break;
	case part::BLOCK_MIDDLE:
		fix_text_h = std::max(txttxt.height() + 2*storybox_padding, screen_area().h/3);
		break;
	default:
		fix_text_h = screen_area().h - fix_text_y;
		break;
	}

	SDL_Rect update_area = sdl::create_rect(0
			, fix_text_y
			, screen_area().w
			, fix_text_h);

	/* do */ {
		// this should kill the tiniest flickering caused
		// by the buttons being hidden and unhidden in this scope.
		update_locker locker(video_);

		next_button_.hide();
		back_button_.hide();
		play_button_.hide();

		//TODO: blurring

		const SDL_Rect box = sdl::create_rect(0, fix_text_y, screen_area().w,
											  fix_text_h);

		sdl::fill_rect(*target, box, storyshadow_r, storyshadow_g,
					   storyshadow_b, storyshadow_a);

		render_story_box_borders(update_area); // no-op if LOW_MEM is defined

		next_button_.hide(false);
		back_button_.hide(false);
		play_button_.hide(false);
	}

	// Time to do some f*****g visual effect.
	const int scan_height = 1, scan_width = txttxt.width();
	SDL_Rect scan = sdl::create_rect(0, 0, scan_width, scan_height);
	SDL_Rect dstrect = sdl::create_rect(text_x_, 0, scan_width, scan_height);
	bool scan_finished = false;
	while(true) {
		scan_finished = scan.y >= txttxt.base_height();
		if (!scan_finished)
		{
			dstrect.y = fix_text_y + scan.y + storybox_padding;
			txttxt.set_clip(scan);
			video_.draw_texture(txttxt, dstrect.x, dstrect.y);
			video_.flip();
			++scan.y;
		}
		else skip_ = true;

		if (handle_interface()) break;

		if (!skip_ || scan_finished) {
			disp_.delay(20);
		}
	}

	const SDL_Rect rect = sdl::create_rect(0, 0, video_.getx(), video_.gety());
	sdl::fill_rect(*target, rect, 0, 0, 0, 255);
#else
	LOG_NG << "ENTER part_ui()::render_story_box()\n";

	const std::string& storytxt = p_.text();
	if(storytxt.empty()) {
		update_whole_screen();
		wait_for_input();
		return;
	}

	const part::BLOCK_LOCATION tbl = p_.story_text_location();
	const int max_width = buttons_x_ - storybox_padding - text_x_;
	const int max_height = screen_area().h - storybox_padding;

	skip_ = false;
	last_key_ = true;

	font::ttext t;
	if(!t.set_text(p_.text(), true)) {
		ERR_NG << "Text: Invalid markup in '"
				<< p_.text() << "' rendered as is.\n";
		t.set_text(p_.text(), false);
	}
	t.set_font_style(font::ttext::STYLE_NORMAL)
	     .set_font_size(storybox_font_size)
		 .set_foreground_color(storybox_font_color)
		 .set_maximum_width(max_width)
		 .set_maximum_height(max_height, true);
	surface txtsurf = t.render();

	if(txtsurf.null()) {
		ERR_NG << "storyscreen text area rendering resulted in a null surface" << std::endl;
		return;
	}

	int fix_text_y = text_y_;
	if(fix_text_y + 2*(storybox_padding+1) + txtsurf->h > screen_area().h && tbl != part::BLOCK_TOP) {
		fix_text_y =
			(screen_area().h > txtsurf->h + 1) ?
			(std::max(0, screen_area().h - txtsurf->h - 2*(storybox_padding+1))) :
			(0);
	}
	int fix_text_h;
	switch(tbl) {
	case part::BLOCK_TOP:
		fix_text_h = std::max(txtsurf->h + 2*storybox_padding, screen_area().h/4);
		break;
	case part::BLOCK_MIDDLE:
		fix_text_h = std::max(txtsurf->h + 2*storybox_padding, screen_area().h/3);
		break;
	default:
		fix_text_h = screen_area().h - fix_text_y;
		break;
	}

	SDL_Rect update_area = sdl::create_rect(0
			, fix_text_y
			, screen_area().w
			, fix_text_h);

	/* do */ {
		// this should kill the tiniest flickering caused
		// by the buttons being hidden and unhidden in this scope.
		update_locker locker(video_);

		next_button_.hide();
		back_button_.hide();
		play_button_.hide();

#ifndef LOW_MEM
		blur_area(video_, fix_text_y, fix_text_h);
#endif

		sdl::draw_solid_tinted_rectangle(
			0, fix_text_y, screen_area().w, fix_text_h,
			storyshadow_r, storyshadow_g, storyshadow_b,
			storyshadow_opacity,
			video_.getSurface()
		);

		render_story_box_borders(update_area); // no-op if LOW_MEM is defined

		next_button_.hide(false);
		back_button_.hide(false);
		play_button_.hide(false);
	}

	if(imgs_.empty()) {
		update_whole_screen();
	} else if(update_area.h > 0) {
		update_rect(update_area);
	}

	// Time to do some f*****g visual effect.
	const int scan_height = 1, scan_width = txtsurf->w;
	SDL_Rect scan = sdl::create_rect(0, 0, scan_width, scan_height);
	SDL_Rect dstrect = sdl::create_rect(text_x_, 0, scan_width, scan_height);
	surface scan_dst = video_.getSurface();
	bool scan_finished = false;
	while(true) {
		scan_finished = scan.y >= txtsurf->h;
		if (!scan_finished)
		{
			//dstrect.x = text_x_;
			dstrect.y = fix_text_y + scan.y + storybox_padding;
			// NOTE: ::blit_surface() screws up with antialiasing and hinting when
			//       on backgroundless (e.g. black) screens; ttext::draw()
			//       uses it nonetheless, no idea why...
			//       Here we'll use CVideo::blit_surface() instead.
			video_.blit_surface(dstrect.x, dstrect.y, txtsurf, &scan);
			update_rect(dstrect);
			++scan.y;
		}
		else skip_ = true;

		if (handle_interface()) break;

		if (!skip_ || scan_finished) {
			disp_.delay(20);
		}
	}

	sdl::draw_solid_tinted_rectangle(
		0, 0, video_.getx(), video_.gety(), 0, 0, 0,
		1.0, video_.getSurface()
	);
#endif
}