/************************************************************************** ... **************************************************************************/ SDL_Surface * create_text_surf_smaller_that_w(SDL_String16 *pString, int w) { fc_assert_ret_val(pString != NULL, NULL); SDL_Surface *pText = create_text_surf_from_str16(pString); if(pText && pText->w > w - 4) { /* cut string length to w length by replacing space " " with new line "\n" */ int ptsize = pString->ptsize; Uint16 pNew_Line[2], pSpace[2]; Uint16 *ptr = pString->text; convertcopy_to_utf16(pNew_Line, sizeof(pNew_Line), "\n"); convertcopy_to_utf16(pSpace, sizeof(pSpace), " "); do { if (*ptr) { if(*ptr == *pSpace) { *ptr = *pNew_Line;/* "\n" */ FREESURFACE(pText); pText = create_text_surf_from_str16(pString); } ptr++; } else { FREESURFACE(pText); if (pString->ptsize > 8) { change_ptsize16(pString, pString->ptsize - 1); pText = create_text_surf_from_str16(pString); } else { fc_assert_ret_val(pText != NULL, NULL); } } } while (pText->w > w - 4); if(pString->ptsize != ptsize) { change_ptsize16(pString, ptsize); } } return pText; }
/************************************************************************** ... **************************************************************************/ void setup_auxiliary_tech_icons(void) { SDL_Color bg_color = {255, 255, 255, 136}; SDL_Surface *pSurf; SDL_String16 *pStr = create_str16_from_char(_("None"), adj_font(10)); pStr->style |= (TTF_STYLE_BOLD | SF_CENTER); /* create icons */ pSurf = create_surf_alpha(adj_size(50), adj_size(50), SDL_SWSURFACE); SDL_FillRect(pSurf, NULL, map_rgba(pSurf->format, bg_color)); putframe(pSurf, 0 , 0, pSurf->w - 1, pSurf->h - 1, map_rgba(pSurf->format, *get_game_colorRGB(COLOR_THEME_SCIENCEDLG_FRAME))); pNeutral_Tech_Icon = SDL_DisplayFormatAlpha(pSurf); pNone_Tech_Icon = SDL_DisplayFormatAlpha(pSurf); pFuture_Tech_Icon = SDL_DisplayFormatAlpha(pSurf); FREESURFACE(pSurf); /* None */ pSurf = create_text_surf_from_str16(pStr); blit_entire_src(pSurf, pNone_Tech_Icon , (adj_size(50) - pSurf->w) / 2 , (adj_size(50) - pSurf->h) / 2); FREESURFACE(pSurf); /* TRANS: Future Technology */ copy_chars_to_string16(pStr, _("FT")); pSurf = create_text_surf_from_str16(pStr); blit_entire_src(pSurf, pFuture_Tech_Icon, (adj_size(50) - pSurf->w) / 2 , (adj_size(50) - pSurf->h) / 2); FREESURFACE(pSurf); FREESTRING16(pStr); }
/************************************************************************** ... **************************************************************************/ SDL_Surface * create_text_surf_smaller_that_w(SDL_String16 *pString, int w) { int ptsize; SDL_Surface *pText; fc_assert_ret_val(pString != NULL, NULL); ptsize = pString->ptsize; convert_string_to_const_surface_width(pString, w); pText = create_text_surf_from_str16(pString); if(pString->ptsize != ptsize) { change_ptsize16(pString, ptsize); } return pText; }
/************************************************************************** ... **************************************************************************/ int write_text16(SDL_Surface * pDest, Sint16 x, Sint16 y, SDL_String16 * pString) { SDL_Rect dst_rect = { x, y, 0, 0 }; SDL_Surface *pText = create_text_surf_from_str16(pString); if (alphablit(pText, NULL, pDest, &dst_rect) < 0) { log_error("write_text16: couldn't blit text to display: %s", SDL_GetError()); FREESURFACE(pText); return -1; } FREESURFACE(pText); return 0; }
/**************************************************************************** Draw the text onto the canvas in the given color and font. The canvas position does not account for the ascent of the text; this function must take care of this manually. The text will not be NULL but may be empty. ****************************************************************************/ void canvas_put_text(struct canvas *pcanvas, int canvas_x, int canvas_y, enum client_font font, struct color *pcolor, const char *text) { SDL_Surface *pTmp; SDL_String16 *pText = create_string16(NULL, 0, *fonts[font]); copy_chars_to_string16(pText, text); pText->fgcol = *pcolor->color; pText->bgcol = (SDL_Color) {0, 0, 0, 0}; pTmp = create_text_surf_from_str16(pText); blit_entire_src(pTmp, pcanvas->surf, canvas_x, canvas_y); FREESTRING16(pText); FREESURFACE(pTmp); }
/************************************************************************** Create Icon Button image with text and Icon then blit to Dest(ination) on positon pIButton->size.x , pIButton->size.y. WARRING: pDest must exist. Text with atributes is taken from pIButton->string16 parameter. Graphic for button is taken from pIButton->theme surface and blit to new created image. Graphic for Icon is taken from pIButton->theme2 surface and blit to new created image. function return (-1) if there are no Icon and Text. Else return 0. **************************************************************************/ static int redraw_ibutton(struct widget *pIButton) { SDL_Rect dest = { 0, 0, 0, 0 }; SDL_String16 TMPString; SDL_Surface *pButton = NULL, *pText = NULL, *pIcon = pIButton->theme2; Uint16 Ix, Iy, x; Uint16 y = 0; /* FIXME: possibly uninitialized */ int ret; ret = (*baseclass_redraw)(pIButton); if (ret != 0) { return ret; } if (pIButton->string16) { /* make copy of string16 */ TMPString = *pIButton->string16; if (get_wstate(pIButton) == FC_WS_NORMAL) { TMPString.fgcol = *get_theme_color(COLOR_THEME_WIDGET_NORMAL_TEXT); } else if (get_wstate(pIButton) == FC_WS_SELLECTED) { TMPString.fgcol = *get_theme_color(COLOR_THEME_WIDGET_SELECTED_TEXT); TMPString.style |= TTF_STYLE_BOLD; } else if (get_wstate(pIButton) == FC_WS_PRESSED) { TMPString.fgcol = *get_theme_color(COLOR_THEME_WIDGET_PRESSED_TEXT); } else if (get_wstate(pIButton) == FC_WS_DISABLED) { TMPString.fgcol = *get_theme_color(COLOR_THEME_WIDGET_DISABLED_TEXT); } pText = create_text_surf_from_str16(&TMPString); } if (!pText && !pIcon) { return -1; } /* create Button graphic */ pButton = create_bcgnd_surf(pIButton->theme, get_wstate(pIButton), pIButton->size.w, pIButton->size.h); clear_surface(pIButton->dst->surface, &pIButton->size); alphablit(pButton, NULL, pIButton->dst->surface, &pIButton->size); FREESURFACE(pButton); if (pIcon) { /* Icon */ if (pText) { if (get_wflags(pIButton) & WF_ICON_CENTER_RIGHT) { Ix = pIButton->size.w - pIcon->w - 5; } else { if (get_wflags(pIButton) & WF_ICON_CENTER) { Ix = (pIButton->size.w - pIcon->w) / 2; } else { Ix = 5; } } if (get_wflags(pIButton) & WF_ICON_ABOVE_TEXT) { Iy = 3; y = 3 + pIcon->h + 3 + (pIButton->size.h - (pIcon->h + 6) - pText->h) / 2; } else { if (get_wflags(pIButton) & WF_ICON_UNDER_TEXT) { y = 3 + (pIButton->size.h - (pIcon->h + 3) - pText->h) / 2; Iy = y + pText->h + 3; } else { /* center */ Iy = (pIButton->size.h - pIcon->h) / 2; y = (pIButton->size.h - pText->h) / 2; } } } else { /* no text */ Iy = (pIButton->size.h - pIcon->h) / 2; Ix = (pIButton->size.w - pIcon->w) / 2; } if (get_wstate(pIButton) == FC_WS_PRESSED) { Ix += 1; Iy += 1; } dest.x = pIButton->size.x + Ix; dest.y = pIButton->size.y + Iy; ret = alphablit(pIcon, NULL, pIButton->dst->surface, &dest); if (ret) { FREESURFACE(pText); return ret - 10; } } if (pText) { if (pIcon) { if (!(get_wflags(pIButton) & WF_ICON_ABOVE_TEXT) && !(get_wflags(pIButton) & WF_ICON_UNDER_TEXT)) { if (get_wflags(pIButton) & WF_ICON_CENTER_RIGHT) { if (pIButton->string16->style & SF_CENTER) { x = (pIButton->size.w - (pIcon->w + 5) - pText->w) / 2; } else { if (pIButton->string16->style & SF_CENTER_RIGHT) { x = pIButton->size.w - (pIcon->w + 7) - pText->w; } else { x = 5; } } } /* end WF_ICON_CENTER_RIGHT */ else { if (get_wflags(pIButton) & WF_ICON_CENTER) { /* text is blit on icon */ goto Alone; } /* end WF_ICON_CENTER */ else { /* icon center left - default */ if (pIButton->string16->style & SF_CENTER) { x = 5 + pIcon->w + ((pIButton->size.w - (pIcon->w + 5) - pText->w) / 2); } else { if (pIButton->string16->style & SF_CENTER_RIGHT) { x = pIButton->size.w - pText->w - 5; } else { /* text center left */ x = 5 + pIcon->w + 3; } } } /* end icon center left - default */ } /* 888888888888888888 */ } else { goto Alone; } } else { /* !pIcon */ y = (pIButton->size.h - pText->h) / 2; Alone: if (pIButton->string16->style & SF_CENTER) { x = (pIButton->size.w - pText->w) / 2; } else { if (pIButton->string16->style & SF_CENTER_RIGHT) { x = pIButton->size.w - pText->w - 5; } else { x = 5; } } } if (get_wstate(pIButton) == FC_WS_PRESSED) { x += 1; } else { y -= 1; } dest.x = pIButton->size.x + x; dest.y = pIButton->size.y + y; ret = alphablit(pText, NULL, pIButton->dst->surface, &dest); } FREESURFACE(pText); return 0; }
/************************************************************************** Create Edit Field surface ( with Text) and blit them to Main.screen, on position 'pEdit_Widget->size.x , pEdit_Widget->size.y' Graphic is taken from 'pEdit_Widget->theme' Text is taken from 'pEdit_Widget->sting16' if flag 'FW_DRAW_THEME_TRANSPARENT' is set theme will be blit transparent ( Alpha = 128 ) function return Hight of created surfaces or (-1) if theme surface can't be created. **************************************************************************/ static int redraw_edit(struct widget *pEdit_Widget) { int ret; if (get_wstate(pEdit_Widget) == FC_WS_PRESSED) { return redraw_edit_chain((struct EDIT *)pEdit_Widget->data.ptr); } else { int iRet = 0; SDL_Rect rDest = {pEdit_Widget->size.x, pEdit_Widget->size.y, 0, 0}; SDL_Surface *pEdit = NULL; SDL_Surface *pText; ret = (*baseclass_redraw)(pEdit_Widget); if (ret != 0) { return ret; } if (pEdit_Widget->string16->text && get_wflags(pEdit_Widget) & WF_PASSWD_EDIT) { Uint16 *backup = pEdit_Widget->string16->text; size_t len = unistrlen(backup) + 1; char *cBuf = fc_calloc(1, len); memset(cBuf, '*', len - 1); cBuf[len - 1] = '\0'; pEdit_Widget->string16->text = convert_to_utf16(cBuf); pText = create_text_surf_from_str16(pEdit_Widget->string16); FC_FREE(pEdit_Widget->string16->text); FC_FREE(cBuf); pEdit_Widget->string16->text = backup; } else { pText = create_text_surf_from_str16(pEdit_Widget->string16); } pEdit = create_bcgnd_surf(pEdit_Widget->theme, get_wstate(pEdit_Widget), pEdit_Widget->size.w, pEdit_Widget->size.h); if (!pEdit) { return -1; } /* blit theme */ alphablit(pEdit, NULL, pEdit_Widget->dst->surface, &rDest); /* set position and blit text */ if (pText) { rDest.y += (pEdit->h - pText->h) / 2; /* blit centred text to botton */ if (pEdit_Widget->string16->style & SF_CENTER) { rDest.x += (pEdit->w - pText->w) / 2; } else { if (pEdit_Widget->string16->style & SF_CENTER_RIGHT) { rDest.x += pEdit->w - pText->w - adj_size(5); } else { rDest.x += adj_size(5); /* cennter left */ } } alphablit(pText, NULL, pEdit_Widget->dst->surface, &rDest); } /* pText */ iRet = pEdit->h; /* Free memory */ FREESURFACE(pText); FREESURFACE(pEdit); return iRet; } return 0; }
/************************************************************************** ... **************************************************************************/ void redraw_widget_info_label(SDL_Rect *rect) { SDL_Surface *pText, *pBcgd; SDL_Rect srcrect, dstrect; SDL_Color color; struct widget *pWidget = pSellected_Widget; if (!pWidget || !pWidget->info_label) { return; } if (!pInfo_Label) { pInfo_Area = fc_calloc(1, sizeof(SDL_Rect)); color = pWidget->info_label->fgcol; pWidget->info_label->style |= TTF_STYLE_BOLD; pWidget->info_label->fgcol = *get_theme_color(COLOR_THEME_QUICK_INFO_TEXT); /* create string and bcgd theme */ pText = create_text_surf_from_str16(pWidget->info_label); pWidget->info_label->fgcol = color; pBcgd = create_filled_surface(pText->w + adj_size(10), pText->h + adj_size(6), SDL_SWSURFACE, get_theme_color(COLOR_THEME_QUICK_INFO_BG), TRUE); /* calculate start position */ if ((pWidget->dst->dest_rect.y + pWidget->size.y) - pBcgd->h - adj_size(6) < 0) { pInfo_Area->y = (pWidget->dst->dest_rect.y + pWidget->size.y) + pWidget->size.h + adj_size(3); } else { pInfo_Area->y = (pWidget->dst->dest_rect.y + pWidget->size.y) - pBcgd->h - adj_size(5); } if ((pWidget->dst->dest_rect.x + pWidget->size.x) + pBcgd->w + adj_size(5) > Main.screen->w) { pInfo_Area->x = (pWidget->dst->dest_rect.x + pWidget->size.x) - pBcgd->w - adj_size(5); } else { pInfo_Area->x = (pWidget->dst->dest_rect.x + pWidget->size.x) + adj_size(3); } pInfo_Area->w = pBcgd->w + adj_size(2); pInfo_Area->h = pBcgd->h + adj_size(3); pInfo_Label = SDL_DisplayFormatAlpha(pBcgd); FREESURFACE(pBcgd); /* draw text */ dstrect.x = adj_size(6); dstrect.y = adj_size(3); alphablit(pText, NULL, pInfo_Label, &dstrect); FREESURFACE(pText); /* draw frame */ putframe(pInfo_Label, 0, 0, pInfo_Label->w - 1, pInfo_Label->h - 1, get_theme_color(COLOR_THEME_QUICK_INFO_FRAME)); } if (rect) { dstrect.x = MAX(rect->x, pInfo_Area->x); dstrect.y = MAX(rect->y, pInfo_Area->y); srcrect.x = dstrect.x - pInfo_Area->x; srcrect.y = dstrect.y - pInfo_Area->y; srcrect.w = MIN((pInfo_Area->x + pInfo_Area->w), (rect->x + rect->w)) - dstrect.x; srcrect.h = MIN((pInfo_Area->y + pInfo_Area->h), (rect->y + rect->h)) - dstrect.y; alphablit(pInfo_Label, &srcrect, Main.screen, &dstrect); } else { alphablit(pInfo_Label, NULL, Main.screen, pInfo_Area); } if (correct_rect_region(pInfo_Area)) { SDL_UpdateRect(Main.screen, pInfo_Area->x, pInfo_Area->y, pInfo_Area->w, pInfo_Area->h); } return; }
/************************************************************************** Popup (or raise) the player list dialog. **************************************************************************/ void popup_players_dialog(bool raise) { struct widget *pWindow = NULL, *pBuf = NULL; SDL_Surface *pLogo = NULL, *pZoomed = NULL; SDL_String16 *pStr; SDL_Rect dst; int i, n, h; double a, b, r; SDL_Rect area; if (pPlayers_Dlg) { return; } n = 0; players_iterate(pPlayer) { if(is_barbarian(pPlayer)) { continue; } n++; } players_iterate_end; if(n < 2) { return; } pPlayers_Dlg = fc_calloc(1, sizeof(struct SMALL_DLG)); pStr = create_str16_from_char(_("Players"), adj_font(12)); pStr->style |= TTF_STYLE_BOLD; pWindow = create_window_skeleton(NULL, pStr, 0); pWindow->action = players_window_dlg_callback; set_wstate(pWindow, FC_WS_NORMAL); add_to_gui_list(ID_WINDOW, pWindow); pPlayers_Dlg->pEndWidgetList = pWindow; /* ---------- */ /* exit button */ pBuf = create_themeicon(pTheme->Small_CANCEL_Icon, pWindow->dst, WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND); pBuf->info_label = create_str16_from_char(_("Close Dialog (Esc)"), adj_font(12)); pBuf->action = exit_players_dlg_callback; set_wstate(pBuf, FC_WS_NORMAL); pBuf->key = SDLK_ESCAPE; add_to_gui_list(ID_BUTTON, pBuf); /* ---------- */ for(i = 0; i<DS_LAST; i++) { switch (i) { case DS_ARMISTICE: pBuf = create_checkbox(pWindow->dst, (SDL_Client_Flags & CF_DRAW_PLAYERS_NEUTRAL_STATUS), WF_RESTORE_BACKGROUND); pBuf->action = toggle_draw_neutral_status_callback; pBuf->key = SDLK_n; break; case DS_WAR: pBuf = create_checkbox(pWindow->dst, (SDL_Client_Flags & CF_DRAW_PLAYERS_WAR_STATUS), WF_RESTORE_BACKGROUND); pBuf->action = toggle_draw_war_status_callback; pBuf->key = SDLK_w; break; case DS_CEASEFIRE: pBuf = create_checkbox(pWindow->dst, (SDL_Client_Flags & CF_DRAW_PLAYERS_CEASEFIRE_STATUS), WF_RESTORE_BACKGROUND); pBuf->action = toggle_draw_ceasefire_status_callback; pBuf->key = SDLK_c; break; case DS_PEACE: pBuf = create_checkbox(pWindow->dst, (SDL_Client_Flags & CF_DRAW_PLAYERS_PEACE_STATUS), WF_RESTORE_BACKGROUND); pBuf->action = toggle_draw_pease_status_callback; pBuf->key = SDLK_p; break; case DS_ALLIANCE: pBuf = create_checkbox(pWindow->dst, (SDL_Client_Flags & CF_DRAW_PLAYERS_ALLIANCE_STATUS), WF_RESTORE_BACKGROUND); pBuf->action = toggle_draw_alliance_status_callback; pBuf->key = SDLK_a; break; default: /* no contact */ continue; break; } set_wstate(pBuf, FC_WS_NORMAL); add_to_gui_list(ID_CHECKBOX, pBuf); } /* ---------- */ players_iterate(pPlayer) { if(is_barbarian(pPlayer)) { continue; } pStr = create_string16(NULL, 0, adj_font(10)); pStr->style |= (TTF_STYLE_BOLD|SF_CENTER); pLogo = get_nation_flag_surface(nation_of_player(pPlayer)); { /* Aim for a flag height of 60 pixels, but draw smaller flags if there * are more players */ double zoom = DEFAULT_ZOOM * (60.0 - n) / pLogo->h; pZoomed = zoomSurface(pLogo, zoom, zoom, 1); } pBuf = create_icon2(pZoomed, pWindow->dst, WF_RESTORE_BACKGROUND | WF_WIDGET_HAS_INFO_LABEL | WF_FREE_THEME); pBuf->info_label = pStr; if(!pPlayer->is_alive) { pStr = create_str16_from_char(_("R.I.P.") , adj_font(10)); pStr->style |= TTF_STYLE_BOLD; pStr->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_TEXT); pLogo = create_text_surf_from_str16(pStr); FREESTRING16(pStr); dst.x = (pZoomed->w - pLogo->w) / 2; dst.y = (pZoomed->h - pLogo->h) / 2; alphablit(pLogo, NULL, pZoomed, &dst); FREESURFACE(pLogo); } if(pPlayer->is_alive) { set_wstate(pBuf, FC_WS_NORMAL); } pBuf->data.player = pPlayer; pBuf->action = player_callback; add_to_gui_list(ID_LABEL, pBuf); } players_iterate_end; pPlayers_Dlg->pBeginWidgetList = pBuf; resize_window(pWindow, NULL, NULL, adj_size(500), adj_size(400)); area = pWindow->area; r = MIN(area.w, area.h); r -= ((MAX(pBuf->size.w, pBuf->size.h) * 2)); r /= 2; a = (2.0 * M_PI) / n; widget_set_position(pWindow, (Main.screen->w - pWindow->size.w) / 2, (Main.screen->h - pWindow->size.h) / 2); /* exit button */ pBuf = pWindow->prev; pBuf->size.x = area.x + area.w - pBuf->size.w - 1; pBuf->size.y = pWindow->size.y + adj_size(2); n = area.y; pStr = create_string16(NULL, 0, adj_font(10)); pStr->style |= TTF_STYLE_BOLD; pStr->bgcol = (SDL_Color) {0, 0, 0, 0}; for(i = 0; i<DS_LAST; i++) { switch (i) { case DS_ARMISTICE: pStr->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_ARMISTICE); break; case DS_WAR: pStr->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_WAR); break; case DS_CEASEFIRE: pStr->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_CEASEFIRE); break; case DS_PEACE: pStr->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_PEACE); break; case DS_ALLIANCE: pStr->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_ALLIANCE); break; default: /* no contact */ continue; break; } copy_chars_to_string16(pStr, diplstate_type_translated_name(i)); pLogo = create_text_surf_from_str16(pStr); pBuf = pBuf->prev; h = MAX(pBuf->size.h, pLogo->h); pBuf->size.x = area.x + adj_size(5); pBuf->size.y = n + (h - pBuf->size.h) / 2; dst.x = adj_size(5) + pBuf->size.w + adj_size(6); dst.y = n + (h - pLogo->h) / 2; alphablit(pLogo, NULL, pWindow->theme, &dst); n += h; FREESURFACE(pLogo); } FREESTRING16(pStr); /* first player shield */ pBuf = pBuf->prev; pBuf->size.x = area.x + area.w / 2 - pBuf->size.w / 2; pBuf->size.y = area.y + area.h / 2 - r - pBuf->size.h / 2; n = 1; if(pBuf != pPlayers_Dlg->pBeginWidgetList) { do{ pBuf = pBuf->prev; b = M_PI_2 + n * a; pBuf->size.x = area.x + area.w / 2 - r * cos(b) - pBuf->size.w / 2; pBuf->size.y = area.y + area.h / 2 - r * sin(b) - pBuf->size.h / 2; n++; } while(pBuf != pPlayers_Dlg->pBeginWidgetList); } players_dialog_update(); }