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; } }
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); }
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_); } } }
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; } } } }
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_); } } }
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; }
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); }
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; }
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); }
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; }
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); }
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; }
/** * 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()); }
const SDL_Rect& unit_image_area() const { return theme_.unit_image_location(screen_area()); }
/*! 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; }
static Rect *choose_pointer_monitor(ObClient *c) { return screen_area(c->desktop, screen_monitor_pointer(), NULL); }
(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;
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()); } }
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 */ }
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(); }
const SDL_Rect& palette_area() const { return theme_.palette_location(screen_area()); }
/** * 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()); }
/* 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; }
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); }
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); }
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_; }
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 }
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]; } }
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 }