Example #1
0
/**************************************************************************
  Refresh (update) the spaceship dialog for the given player.
**************************************************************************/
void refresh_spaceship_dialog(struct player *pPlayer)
{
    struct SMALL_DLG *pSpaceShp;
    struct widget *pBuf;

    if (!(pSpaceShp = get_spaceship_dialog(pPlayer))) {
        return;
    }

    /* launch button */
    pBuf = pSpaceShp->pEndWidgetList->prev->prev;
    if (victory_enabled(VC_SPACERACE)
            && pPlayer == client.conn.playing
            && pPlayer->spaceship.state == SSHIP_STARTED
            && pPlayer->spaceship.success_rate > 0.0) {
        set_wstate(pBuf, FC_WS_NORMAL);
    }

    /* update text info */
    pBuf = pBuf->prev;
    copy_chars_to_string16(pBuf->string16,
                           get_spaceship_descr(&pPlayer->spaceship));
    /* ------------------------------------------ */

    /* redraw */
    redraw_group(pSpaceShp->pBeginWidgetList, pSpaceShp->pEndWidgetList, 0);
    widget_mark_dirty(pSpaceShp->pEndWidgetList);

    flush_dirty();
}
Example #2
0
/****************************************************************************
  Return the size of the given text in the given font.  This size should
  include the ascent and descent of the text.  Either of width or height
  may be NULL in which case those values simply shouldn't be filled out.
****************************************************************************/
void get_text_size(int *width, int *height,
		   enum client_font font, const char *text)
{
  SDL_String16 *pText = create_string16(NULL, 0, *fonts[font]);
  copy_chars_to_string16(pText, text);

  if (width) {
    *width = str16size(pText).w;
  }
  if (height) {
    *height = str16size(pText).h;
  }
  
  FREESTRING16(pText);
}
Example #3
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);
}
Example #4
0
/**************************************************************************
  ...
**************************************************************************/
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);
    
}
Example #5
0
/**************************************************************************
  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();
}
Example #6
0
/**************************************************************************
  Update all information in the player list dialog.
**************************************************************************/
void real_players_dialog_update(void)
{
  if(pPlayers_Dlg) {
    struct widget *pPlayer0, *pPlayer1;
    struct player *pPlayer;
    SDL_Rect dst0, dst1;
    int i;
    struct astring astr = ASTRING_INIT;
          
    /* redraw window */
    widget_redraw(pPlayers_Dlg->pEndWidgetList);
    
    /* exit button -> neutral -> war -> casefire -> peace -> alliance */
    pPlayer0 = pPlayers_Dlg->pEndWidgetList->prev->prev->prev->prev->prev->prev;
    do{
      pPlayer0 = pPlayer0->prev;
      pPlayer1 = pPlayer0;
      pPlayer = pPlayer0->data.player;
      
      for (i = 0; i < num_player_dlg_columns; i++) {
        if (player_dlg_columns[i].show) {
          switch (player_dlg_columns[i].type) {
            case COL_TEXT:
            case COL_RIGHT_TEXT:
              astr_add_line(&astr, "%s: %s", player_dlg_columns[i].title,
                                             player_dlg_columns[i].func(pPlayer));
              break;
            case COL_BOOLEAN:
              astr_add_line(&astr, "%s: %s", player_dlg_columns[i].title,
                            player_dlg_columns[i].bool_func(pPlayer) ? 
                              _("Yes") : _("No"));
              break;
            default:
              break;
          }
        }
      }

      copy_chars_to_string16(pPlayer0->info_label, astr_str(&astr));

      astr_free(&astr);
          
      /* now add some eye candy ... */
      if(pPlayer1 != pPlayers_Dlg->pBeginWidgetList) {
        dst0.x = pPlayer0->size.x + pPlayer0->size.w / 2;
        dst0.y = pPlayer0->size.y + pPlayer0->size.h / 2;

        do{
          pPlayer1 = pPlayer1->prev;
	  if (have_diplomat_info_about(pPlayer) ||
	     have_diplomat_info_about(pPlayer1->data.player)) {
            dst1.x = pPlayer1->size.x + pPlayer1->size.w / 2;
            dst1.y = pPlayer1->size.y + pPlayer1->size.h / 2;

            switch (player_diplstate_get(pPlayer,
                                         pPlayer1->data.player)->type) {
	      case DS_ARMISTICE:
	        if(SDL_Client_Flags & CF_DRAW_PLAYERS_NEUTRAL_STATUS) {
	          putline(pPlayer1->dst->surface,
	                  dst0.x, dst0.y, dst1.x, dst1.y,
	                  get_theme_color(COLOR_THEME_PLRDLG_ARMISTICE));
	        }
	      break;
              case DS_WAR:
	        if(SDL_Client_Flags & CF_DRAW_PLAYERS_WAR_STATUS) {
	          putline(pPlayer1->dst->surface,
	                  dst0.x, dst0.y, dst1.x, dst1.y,
	                  get_theme_color(COLOR_THEME_PLRDLG_WAR));
	        }
              break;
	      case DS_CEASEFIRE:
	        if (SDL_Client_Flags & CF_DRAW_PLAYERS_CEASEFIRE_STATUS) {
	          putline(pPlayer1->dst->surface,
	                  dst0.x, dst0.y, dst1.x, dst1.y,
	                  get_theme_color(COLOR_THEME_PLRDLG_CEASEFIRE));
	        }
              break;
              case DS_PEACE:
	        if (SDL_Client_Flags & CF_DRAW_PLAYERS_PEACE_STATUS) {
	          putline(pPlayer1->dst->surface,
	                  dst0.x, dst0.y, dst1.x, dst1.y,
	                  get_theme_color(COLOR_THEME_PLRDLG_PEACE));
	        }
              break;
	      case DS_ALLIANCE:
	        if (SDL_Client_Flags & CF_DRAW_PLAYERS_ALLIANCE_STATUS) {
	          putline(pPlayer1->dst->surface,
	                  dst0.x, dst0.y, dst1.x, dst1.y,
	                  get_theme_color(COLOR_THEME_PLRDLG_ALLIANCE));
	        }
              break;
              default:
	        /* no contact */
              break;
	    }  
	  }
	  
        } while(pPlayer1 != pPlayers_Dlg->pBeginWidgetList);
      }
      
    } while(pPlayer0 != pPlayers_Dlg->pBeginWidgetList);
    
    /* -------------------- */
    /* redraw */
    redraw_group(pPlayers_Dlg->pBeginWidgetList,
    			pPlayers_Dlg->pEndWidgetList->prev, 0);
    widget_mark_dirty(pPlayers_Dlg->pEndWidgetList);
  
    flush_dirty();
  }
}
Example #7
0
/**************************************************************************
  Do any necessary pre-initialization of the UI, if necessary.
**************************************************************************/
void ui_init(void)
{
    char device[20];
    /*  struct widget *pInit_String = NULL;*/
    SDL_Surface *pBgd;
    Uint32 iSDL_Flags;

    button_behavior.counting = FALSE;
    button_behavior.button_down_ticks = 0;
    button_behavior.hold_state = MB_HOLD_SHORT;
    button_behavior.event = fc_calloc(1, sizeof(SDL_MouseButtonEvent));

    SDL_Client_Flags = 0;
    iSDL_Flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;

    /* auto center new windows in X enviroment */
    putenv((char *)"SDL_VIDEO_CENTERED=yes");

    init_sdl(iSDL_Flags);

    log_normal(_("Using Video Output: %s"),
               SDL_VideoDriverName(device, sizeof(device)));

    /* create splash screen */
#ifdef SMALL_SCREEN
    {
        SDL_Surface *pTmpSurf = load_surf(fileinfoname(get_data_dirs(),
                                          "misc/intro.png"));
        pBgd = zoomSurface(pTmpSurf, DEFAULT_ZOOM, DEFAULT_ZOOM, 0);
        FREESURFACE(pTmpSurf);
    }
#else  /* SMALL_SCREEN */
    pBgd = load_surf(fileinfoname(get_data_dirs(), "misc/intro.png"));
#endif /* SMALL_SCREEN */

    if (pBgd && SDL_GetVideoInfo()->wm_available) {
        set_video_mode(pBgd->w, pBgd->h, SDL_SWSURFACE | SDL_ANYFORMAT);
#if 0
        /*
         * call this for other than X enviroments - currently not supported.
         */
        center_main_window_on_screen();
#endif /* 0 */
        alphablit(pBgd, NULL, Main.map, NULL);
        putframe(Main.map,
                 0, 0, Main.map->w - 1, Main.map->h - 1,
        &(SDL_Color) {
            255, 255, 255, 255
        });
        FREESURFACE(pBgd);
        SDL_WM_SetCaption(_("SDL Client for Freeciv"), _("Freeciv"));
    } else {

#ifndef SMALL_SCREEN
        set_video_mode(640, 480, SDL_SWSURFACE | SDL_ANYFORMAT);
#else  /* SMALL_SCREEN */
        set_video_mode(320, 240, SDL_SWSURFACE | SDL_ANYFORMAT);
#endif /* SMALL_SCREEN */

        if(pBgd) {
            blit_entire_src(pBgd, Main.map, (Main.map->w - pBgd->w) / 2,
                            (Main.map->h - pBgd->h) / 2);
            FREESURFACE(pBgd);
        } else {
            SDL_FillRect(Main.map, NULL, SDL_MapRGB(Main.map->format, 0, 0, 128));
            SDL_WM_SetCaption(_("SDL Client for Freeciv"), _("Freeciv"));
        }
    }

#if 0
    /* create label beackground */
    pBgd = create_surf_alpha(adj_size(350), adj_size(50), SDL_SWSURFACE);

    SDL_FillRect(pBgd, NULL, SDL_MapRGBA(pBgd->format, 255, 255, 255, 128));
    putframe(pBgd, 0, 0, pBgd->w - 1, pBgd->h - 1, SDL_MapRGB(pBgd->format, 0, 0, 0));

    pInit_String = create_iconlabel(pBgd, Main.gui,
                                    create_str16_from_char(_("Initializing Client"), adj_font(20)),
                                    WF_ICON_CENTER|WF_FREE_THEME);
    pInit_String->string16->style |= SF_CENTER;

    draw_label(pInit_String,
               (Main.screen->w - pInit_String->size.w) / 2,
               (Main.screen->h - pInit_String->size.h) / 2);

    flush_all();

    copy_chars_to_string16(pInit_String->string16,
                           _("Waiting for the beginning of the game"));

#endif /* 0 */

    flush_all();
}
Example #8
0
/**************************************************************************
  ...
**************************************************************************/
static int spy_steal_popup(struct widget *pWidget)
{
  struct city *pVcity = pWidget->data.city;
  int id = MAX_ID - pWidget->ID;
  struct player *pVictim = NULL;
  struct CONTAINER *pCont;
  struct widget *pBuf = NULL;
  struct widget *pWindow;
  SDL_String16 *pStr;
  SDL_Surface *pSurf;
  int max_col, max_row, col, i, count = 0;
  SDL_Rect area;

  popdown_diplomat_dialog();
  
  if(pVcity)
  {
    pVictim = city_owner(pVcity);
  }
  
  if (pDiplomat_Dlg || !pVictim) {
    return 1;
  }
  
  count = 0;
  advance_index_iterate(A_FIRST, i) {
    if (player_invention_reachable(client.conn.playing, i, FALSE)
     && TECH_KNOWN == player_invention_state(pVictim, i)
     && (TECH_UNKNOWN == player_invention_state(client.conn.playing, i)
         || TECH_PREREQS_KNOWN ==
              player_invention_state(client.conn.playing, i))) {
      count++;
    }
  } advance_index_iterate_end;
  
  if(!count) {    
    /* if there is no known tech to steal then 
       send steal order at Spy's Discretion */
    int target_id = pVcity->id;

    request_diplomat_action(DIPLOMAT_STEAL, id, target_id, advance_count());
    return -1;
  }
    
  pCont = fc_calloc(1, sizeof(struct CONTAINER));
  pCont->id0 = pVcity->id;
  pCont->id1 = id;/* spy id */
  
  pDiplomat_Dlg = fc_calloc(1, sizeof(struct diplomat_dialog));
  pDiplomat_Dlg->diplomat_id = id;
  pDiplomat_Dlg->diplomat_target_id = pVcity->id;
  pDiplomat_Dlg->pdialog = fc_calloc(1, sizeof(struct ADVANCED_DLG));
      
  pStr = create_str16_from_char(_("Select Advance to Steal"), adj_font(12));
  pStr->style |= TTF_STYLE_BOLD;

  pWindow = create_window_skeleton(NULL, pStr, 0);
  
  pWindow->action = spy_steal_dlg_window_callback;
  set_wstate(pWindow , FC_WS_NORMAL);
  
  add_to_gui_list(ID_DIPLOMAT_DLG_WINDOW, pWindow);
  pDiplomat_Dlg->pdialog->pEndWidgetList = pWindow;
  
  area = pWindow->area;
  area.w = MAX(area.w, adj_size(8));  
  
  /* ------------------ */
  /* 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));
  area.w += pBuf->size.w + adj_size(10);
  pBuf->action = exit_spy_steal_dlg_callback;
  set_wstate(pBuf, FC_WS_NORMAL);
  pBuf->key = SDLK_ESCAPE;
  
  add_to_gui_list(ID_TERRAIN_ADV_DLG_EXIT_BUTTON, pBuf);  
  /* ------------------------- */
  
  count++; /* count + at Spy's Discretion */
  /* max col - 104 is steal tech widget width */
  max_col = (Main.screen->w - (pWindow->size.w - pWindow->area.w) - adj_size(2)) / adj_size(104);
  /* max row - 204 is steal tech widget height */
  max_row = (Main.screen->h - (pWindow->size.h - pWindow->area.h)) / adj_size(204);
  
  /* make space on screen for scrollbar */
  if (max_col * max_row < count) {
    max_col--;
  }

  if (count < max_col + 1) {
    col = count;
  } else {
    if (count < max_col + adj_size(3)) {
      col = max_col - adj_size(2);
    } else {
      if (count < max_col + adj_size(5)) {
        col = max_col - 1;
      } else {
        col = max_col;
      }
    }
  }
  
  pStr = create_string16(NULL, 0, adj_font(10));
  pStr->style |= (TTF_STYLE_BOLD | SF_CENTER);
  
  count = 0;
  advance_index_iterate(A_FIRST, i) {
    if (player_invention_reachable(client.conn.playing, i, FALSE)
     && TECH_KNOWN == player_invention_state(pVictim, i)
     && (TECH_UNKNOWN == player_invention_state(client.conn.playing, i)
         || TECH_PREREQS_KNOWN ==
              player_invention_state(client.conn.playing, i))) {
      count++;

      copy_chars_to_string16(pStr, advance_name_translation(advance_by_number(i)));
      pSurf = create_sellect_tech_icon(pStr, i, FULL_MODE);
      pBuf = create_icon2(pSurf, pWindow->dst,
      		WF_FREE_THEME | WF_RESTORE_BACKGROUND);

      set_wstate(pBuf, FC_WS_NORMAL);
      pBuf->action = spy_steal_callback;
      pBuf->data.cont = pCont;

      add_to_gui_list(MAX_ID - i, pBuf);
    
      if (count > (col * max_row)) {
        set_wflag(pBuf, WF_HIDDEN);
      }
    }
  } advance_index_iterate_end;
  
  /* get spy tech */
  i = advance_number(unit_type(game_unit_by_number(id))->require_advance);
  copy_chars_to_string16(pStr, _("At Spy's Discretion"));
  pSurf = create_sellect_tech_icon(pStr, i, FULL_MODE);
	
  pBuf = create_icon2(pSurf, pWindow->dst,
    	(WF_FREE_THEME | WF_RESTORE_BACKGROUND| WF_FREE_DATA));
  set_wstate(pBuf, FC_WS_NORMAL);
  pBuf->action = spy_steal_callback;
  pBuf->data.cont = pCont;
    
  add_to_gui_list(MAX_ID - advance_count(), pBuf);
  count++;
  
  /* --------------------------------------------------------- */
  FREESTRING16(pStr);
  pDiplomat_Dlg->pdialog->pBeginWidgetList = pBuf;
  pDiplomat_Dlg->pdialog->pBeginActiveWidgetList = pDiplomat_Dlg->pdialog->pBeginWidgetList;
  pDiplomat_Dlg->pdialog->pEndActiveWidgetList = pDiplomat_Dlg->pdialog->pEndWidgetList->prev->prev;
  
  /* -------------------------------------------------------------- */
  
  i = 0;
  if (count > col) {
    count = (count + (col - 1)) / col;
    if (count > max_row) {
      pDiplomat_Dlg->pdialog->pActiveWidgetList = pDiplomat_Dlg->pdialog->pEndActiveWidgetList;
      count = max_row;
      i = create_vertical_scrollbar(pDiplomat_Dlg->pdialog, col, count, TRUE, TRUE);  
    }
  } else {
    count = 1;
  }

  area.w = MAX(area.w, (col * pBuf->size.w + adj_size(2) + i));
  area.h = count * pBuf->size.h + adj_size(2);

  /* alloca window theme and win background buffer */
  pSurf = theme_get_background(theme, BACKGROUND_SPYSTEALDLG);
  if (resize_window(pWindow, pSurf, NULL,
                    (pWindow->size.w - pWindow->area.w) + area.w,
                    (pWindow->size.h - pWindow->area.h) + area.h))
  {
    FREESURFACE(pSurf);
  }
  
  area = pWindow->area;
  
  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);
  
  setup_vertical_widgets_position(col, area.x + 1,
		  area.y, 0, 0,
		  pDiplomat_Dlg->pdialog->pBeginActiveWidgetList,
  		  pDiplomat_Dlg->pdialog->pEndActiveWidgetList);
    
  if(pDiplomat_Dlg->pdialog->pScroll) {
    setup_vertical_scrollbar_area(pDiplomat_Dlg->pdialog->pScroll,
	area.x + area.w, area.y,
    	area.h, TRUE);
  }

  redraw_group(pDiplomat_Dlg->pdialog->pBeginWidgetList, pWindow, FALSE);
  widget_mark_dirty(pWindow);
  
  return -1;
}