[Freeciv-Dev] (PR#2708) patch: backing rectangle for city descriptions i
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=2708 >
Here's an updated patch. No new changes really.
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.225
diff -u -r1.225 mapview_common.c
--- client/mapview_common.c 31 Mar 2005 17:28:02 -0000 1.225
+++ client/mapview_common.c 17 Apr 2005 02:32:09 -0000
@@ -1158,6 +1158,10 @@
canvas_x, canvas_y, width, height);
mapview_layer_iterate(layer) {
+ if (layer == LAYER_CITYBAR) {
+ show_city_descriptions(canvas_x, canvas_y, width, height);
+ continue;
+ }
gui_rect_iterate(gui_x0, gui_y0, width,
height + (tileset_is_isometric(tileset)
? (tileset_tile_height(tileset) / 2) : 0),
@@ -1197,8 +1201,6 @@
} adjc_dir_iterate_end;
} gui_rect_iterate_end;
- show_city_descriptions(canvas_x, canvas_y, width, height);
-
if (!full) {
/* Swap store and tmp_store back. */
tmp = mapview.store;
@@ -1251,62 +1253,167 @@
city's tile).
****************************************************************************/
static void show_city_desc(struct canvas *pcanvas,
- int canvas_x, int canvas_y,
+ const int canvas_x0, const int canvas_y0,
struct city *pcity, int *width, int *height)
{
- static char name[512], growth[32], prod[512];
- enum color_std growth_color;
+ const struct citybar_sprites *citybar = get_citybar_sprites(tileset);
+ const bool line1 = draw_city_names;
+ const bool line2 = ((draw_city_productions || draw_city_growth)
+ && pcity->owner == game.player_idx);
+ static char name[512], growth[32], prod[512], size[32];
+ enum color_std growth_color, owner_color;
struct {
int x, y, w, h;
} name_rect = {0, 0, 0, 0}, growth_rect = {0, 0, 0, 0},
- prod_rect = {0, 0, 0, 0};
- int extra_width = 0, total_width, total_height;
+ prod_rect = {0, 0, 0, 0}, size_rect = {0, 0, 0, 0},
+ flag_rect = {0, 0, 0, 0}, occupy_rect = {0, 0, 0, 0},
+ food_rect = {0, 0, 0, 0}, shield_rect = {0, 0, 0, 0};
+ int width1 = 0, width2 = 0, height1 = 0, height2 = 0;
+ struct sprite *bg = citybar->background;
+ struct sprite *flag = get_city_flag_sprite(tileset, pcity);
+ struct sprite *occupy = NULL;
+ int bg_w, bg_h, x, y;
+ const int canvas_x = canvas_x0 + tileset_tile_width(tileset) / 2;
+ const int canvas_y = canvas_y0 + tileset_citybar_offset_y(tileset);
+ const int border = 6;
+ const enum client_font FONT_CITY_SIZE = FONT_CITY_NAME; /* TODO: new font */
+ get_sprite_dimensions(bg, &bg_w, &bg_h);
*width = *height = 0;
- canvas_x += tileset_tile_width(tileset) / 2;
- canvas_y += tileset_citybar_offset_y(tileset);
+ if (!line1 && !line2) {
+ return;
+ }
- if (draw_city_names) {
- get_city_mapview_name_and_growth(pcity, name, sizeof(name),
- growth, sizeof(growth), &growth_color);
+ /* First: calculate rect dimensions (but not positioning). */
+ get_city_mapview_name_and_growth(pcity, name, sizeof(name),
+ growth, sizeof(growth), &growth_color);
+ if (line1) {
+ my_snprintf(size, sizeof(size), "%d", pcity->size);
+ get_text_size(&size_rect.w, &size_rect.h, FONT_CITY_SIZE, size);
get_text_size(&name_rect.w, &name_rect.h, FONT_CITY_NAME, name);
- if (growth[0] != '\0') {
- get_text_size(&growth_rect.w, &growth_rect.h, FONT_CITY_PROD, growth);
- /* HACK: put a character's worth of space between the two strings. */
- get_text_size(&extra_width, NULL, FONT_CITY_NAME, "M");
- }
- total_width = name_rect.w + extra_width + growth_rect.w;
- total_height = MAX(name_rect.h, growth_rect.h);
- canvas_put_text(pcanvas,
- canvas_x - total_width / 2, canvas_y,
- FONT_CITY_NAME, COLOR_STD_WHITE, name);
- if (growth[0] != '\0') {
- canvas_put_text(pcanvas,
- canvas_x - total_width / 2 + name_rect.w + extra_width,
- canvas_y + total_height - growth_rect.h,
- FONT_CITY_PROD, growth_color, growth);
+ if (can_player_see_units_in_city(game.player_ptr, pcity)) {
+ int count = unit_list_size(pcity->tile->units);
+
+ count = CLIP(0, count, citybar->occupancy.size - 1);
+ occupy = citybar->occupancy.p[count];
+ } else {
+ if (pcity->client.occupied) {
+ occupy = citybar->occupied;
+ } else {
+ occupy = citybar->occupancy.p[0];
+ }
}
- canvas_y += total_height + 3;
- *width = MAX(*width, total_width);
- *height += total_height + 3;
+ get_sprite_dimensions(flag, &flag_rect.w, &flag_rect.h);
+ get_sprite_dimensions(occupy, &occupy_rect.w, &occupy_rect.h);
+
+ width1 = (flag_rect.w + occupy_rect.w + name_rect.w
+ + 2 * border + size_rect.w);
+ height1 = MAX(flag_rect.h,
+ MAX(occupy_rect.h,
+ MAX(name_rect.h + border,
+ size_rect.h + border)));
}
- if (draw_city_productions && pcity->owner == game.player_idx) {
+ if (line2) {
get_city_mapview_production(pcity, prod, sizeof(prod));
get_text_size(&prod_rect.w, &prod_rect.h, FONT_CITY_PROD, prod);
- total_width = prod_rect.w;
- total_height = prod_rect.h;
+ get_sprite_dimensions(citybar->shields, &shield_rect.w, &shield_rect.h);
- canvas_put_text(pcanvas, canvas_x - total_width / 2, canvas_y,
- FONT_CITY_PROD, COLOR_STD_WHITE, prod);
+ get_text_size(&growth_rect.w, &growth_rect.h, FONT_CITY_PROD, growth);
+ get_sprite_dimensions(citybar->food, &food_rect.w, &food_rect.h);
+
+ width2 = (prod_rect.w + growth_rect.w + shield_rect.w + food_rect.w
+ + 2 * border);
+ height2 = MAX(shield_rect.h,
+ MAX(prod_rect.h + border,
+ MAX(growth_rect.h + border,
+ food_rect.h)));
+ }
+
+ *width = MAX(width1, width2);
+ *height = height1 + height2;
+
+ /* Next fill in X and Y locations. */
+ if (line1) {
+ flag_rect.x = canvas_x - *width / 2;
+ flag_rect.y = canvas_y + (height1 - flag_rect.h) / 2;
+
+ occupy_rect.x = flag_rect.x + flag_rect.w;
+ occupy_rect.y = canvas_y + (height1 - occupy_rect.h) / 2;
- canvas_y += total_height;
- *width = MAX(*width, total_width);
- *height += total_height;
+ name_rect.x = canvas_x + (flag_rect.w + occupy_rect.w
+ - name_rect.w - size_rect.w - border) / 2;
+ name_rect.y = canvas_y + (height1 - name_rect.h) / 2;
+
+ size_rect.x = canvas_x + (*width + 1) / 2 - size_rect.w - border / 2;
+ size_rect.y = canvas_y + (height1 - size_rect.h) / 2;
+ }
+ if (line2) {
+ shield_rect.x = canvas_x - *width / 2;
+ shield_rect.y = canvas_y + height1 + (height2 - shield_rect.h) / 2;
+
+ prod_rect.x = shield_rect.x + shield_rect.w + border / 2;
+ prod_rect.y = canvas_y + height1 + (height2 - prod_rect.h) / 2;
+
+ growth_rect.x = canvas_x + (*width + 1) / 2 - growth_rect.w - border / 2;
+ growth_rect.y = canvas_y + height1 + (height2 - growth_rect.h) / 2;
+
+ food_rect.x = growth_rect.x - border / 2 - food_rect.w;
+ food_rect.y = canvas_y + height1 + (height2 - food_rect.h) / 2;
+ }
+
+ /* Now draw. */
+ for (x = 0; x < *width; x += bg_w) {
+ for (y = 0; y < *height; y += bg_h) {
+ canvas_put_sprite(pcanvas, canvas_x - *width / 2 + x, canvas_y + y,
+ bg, 0, 0, *width - x, *height - y);
+ }
+ }
+ owner_color = player_color(city_owner(pcity));
+ if (line1) {
+ canvas_put_sprite_full(pcanvas, flag_rect.x, flag_rect.y, flag);
+ canvas_put_line(pcanvas, owner_color, LINE_NORMAL,
+ flag_rect.x + flag_rect.w - 1, canvas_y,
+ 0, height1);
+ canvas_put_sprite_full(pcanvas, occupy_rect.x, occupy_rect.y, occupy);
+ canvas_put_text(pcanvas, name_rect.x, name_rect.y,
+ FONT_CITY_NAME, COLOR_STD_WHITE, name);
+
+ canvas_put_rectangle(pcanvas, owner_color,
+ size_rect.x - border / 2, canvas_y,
+ size_rect.w + border, height1);
+ canvas_put_text(pcanvas, size_rect.x, size_rect.y,
+ FONT_CITY_NAME, COLOR_STD_WHITE, size);
+ }
+ if (line2) {
+ canvas_put_sprite_full(pcanvas, shield_rect.x, shield_rect.y,
+ citybar->shields);
+ canvas_put_text(pcanvas, prod_rect.x, prod_rect.y,
+ FONT_CITY_PROD, COLOR_STD_WHITE, prod);
+ canvas_put_sprite_full(pcanvas, food_rect.x, food_rect.y, citybar->food);
+ canvas_put_text(pcanvas, growth_rect.x, growth_rect.y,
+ FONT_CITY_PROD, growth_color, growth);
+ }
+ canvas_put_line(pcanvas, owner_color, LINE_NORMAL,
+ canvas_x - *width / 2, canvas_y,
+ *width, 0);
+ canvas_put_line(pcanvas, owner_color, LINE_NORMAL,
+ canvas_x - *width / 2, canvas_y,
+ 0, *height);
+ canvas_put_line(pcanvas, owner_color, LINE_NORMAL,
+ canvas_x - *width / 2, canvas_y + *height - 1,
+ *width, 0);
+ canvas_put_line(pcanvas, owner_color, LINE_NORMAL,
+ canvas_x - *width / 2 + *width, canvas_y,
+ 0, *height);
+ if (line1 && line2) {
+ canvas_put_line(pcanvas, owner_color, LINE_NORMAL,
+ canvas_x - *width / 2, canvas_y + height1 - 1,
+ *width, 0);
}
}
@@ -1919,7 +2026,7 @@
/**************************************************************************
Fill the two buffers which information about the city which is shown
- below it. It takes draw_city_names and draw_city_growth into account.
+ below it. It does not take draw_city_names/draw_city_growth into account.
**************************************************************************/
void get_city_mapview_name_and_growth(struct city *pcity,
char *name_buffer,
@@ -1928,16 +2035,9 @@
size_t growth_buffer_len,
enum color_std *growth_color)
{
- if (!draw_city_names) {
- name_buffer[0] = '\0';
- growth_buffer[0] = '\0';
- *growth_color = COLOR_STD_WHITE;
- return;
- }
-
my_snprintf(name_buffer, name_buffer_len, pcity->name);
- if (draw_city_growth && pcity->owner == game.player_idx) {
+ if (pcity->owner == game.player_idx) {
int turns = city_turns_to_grow(pcity);
if (turns == 0) {
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.293
diff -u -r1.293 tilespec.c
--- client/tilespec.c 15 Apr 2005 05:40:49 -0000 1.293
+++ client/tilespec.c 17 Apr 2005 02:32:10 -0000
@@ -209,6 +209,7 @@
struct sprite_vector worked_tile_overlay;
struct sprite_vector unworked_tile_overlay;
} city;
+ struct citybar_sprites citybar;
struct {
struct sprite
*turns[NUM_TILES_DIGITS],
@@ -1965,6 +1966,26 @@
}
}
+ SET_SPRITE(citybar.shields, "citybar.shields");
+ SET_SPRITE(citybar.food, "citybar.food");
+ SET_SPRITE(citybar.occupied, "citybar.occupied");
+ SET_SPRITE(citybar.background, "citybar.background");
+ sprite_vector_init(&t->sprites.citybar.occupancy);
+ for (i = 0; ; i++) {
+ struct sprite *sprite;
+
+ my_snprintf(buffer, sizeof(buffer), "citybar.occupancy_%d", i);
+ sprite = load_sprite(t, buffer);
+ if (!sprite) {
+ break;
+ }
+ sprite_vector_append(&t->sprites.citybar.occupancy, &sprite);
+ }
+ if (t->sprites.citybar.occupancy.size < 2) {
+ freelog(LOG_FATAL, "Missing necessary citybar.occupancy_N sprites.");
+ exit(EXIT_FAILURE);
+ }
+
SET_SPRITE(city.disorder, "city.disorder");
for(i=0; i<NUM_TILES_DIGITS; i++) {
@@ -2571,8 +2592,8 @@
/**********************************************************************
Return the flag graphic to be used by the city.
***********************************************************************/
-static struct sprite *get_city_nation_flag_sprite(const struct tileset *t,
- const struct city *pcity)
+struct sprite *get_city_flag_sprite(const struct tileset *t,
+ const struct city *pcity)
{
return get_nation_flag_sprite(t, city_owner(pcity)->nation);
}
@@ -2623,6 +2644,7 @@
return t->sprites.city.tile[style][city_styles[style].tiles_num];
}
+#if 0
/**************************************************************************
Return the sprite needed to draw the occupied tile
**************************************************************************/
@@ -2633,6 +2655,7 @@
return t->sprites.city.tile[style][city_styles[style].tiles_num + 1];
}
+#endif
#define FULL_TILE_X_OFFSET ((t->normal_tile_width - t->full_tile_width) / 2)
#define FULL_TILE_Y_OFFSET (t->normal_tile_height - t->full_tile_height)
@@ -3833,15 +3856,19 @@
case LAYER_CITY1:
/* City. Some city sprites are drawn later. */
if (pcity && draw_cities) {
+#if 0
if (!solid_color_behind_units) {
- ADD_SPRITE(get_city_nation_flag_sprite(t, pcity), TRUE,
+ ADD_SPRITE(get_city_flag_sprite(t, pcity), TRUE,
FULL_TILE_X_OFFSET + t->flag_offset_x,
FULL_TILE_Y_OFFSET + t->flag_offset_y);
}
+#endif
ADD_SPRITE_FULL(get_city_sprite(t, pcity));
+#if 0
if (pcity->client.occupied) {
ADD_SPRITE_FULL(get_city_occupied_sprite(t, pcity));
}
+#endif
if (!t->is_isometric && city_got_citywalls(pcity)) {
/* In iso-view the city wall is a part of the city sprite. */
ADD_SPRITE_SIMPLE(get_city_wall_sprite(t, pcity));
@@ -3872,6 +3899,7 @@
break;
case LAYER_CITY2:
+#if 0
/* City size. Drawing this under fog makes it hard to read. */
if (pcity && draw_cities) {
if (pcity->size >= 10) {
@@ -3881,6 +3909,7 @@
ADD_SPRITE(t->sprites.city.size[pcity->size % 10],
FALSE, FULL_TILE_X_OFFSET, FULL_TILE_Y_OFFSET);
}
+#endif
break;
case LAYER_UNIT:
@@ -3926,6 +3955,10 @@
}
break;
+ case LAYER_CITYBAR:
+ /* Nothing. This is just a placeholder. */
+ break;
+
case LAYER_GOTO:
sprs += fill_goto_sprite_array(t, sprs, ptile, pedge, pcorner);
break;
@@ -4215,6 +4248,7 @@
sprite_vector_free(&t->sprites.explode.unit);
sprite_vector_free(&t->sprites.nation_flag);
+ sprite_vector_free(&t->sprites.citybar.occupancy);
}
/**************************************************************************
@@ -4381,6 +4415,14 @@
}
/**************************************************************************
+ Return all the sprites used for citybar drawing.
+**************************************************************************/
+const struct citybar_sprites *get_citybar_sprites(const struct tileset *t)
+{
+ return &t->sprites.citybar;
+}
+
+/**************************************************************************
Returns a sprite for the given cursor. The "hot" coordinates (the
active coordinates of the mouse relative to the sprite) are placed int
(*hot_x, *hot_y).
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.148
diff -u -r1.148 tilespec.h
--- client/tilespec.h 15 Apr 2005 05:08:09 -0000 1.148
+++ client/tilespec.h 17 Apr 2005 02:32:10 -0000
@@ -79,6 +79,7 @@
LAYER_SPECIAL3,
LAYER_GRID2,
LAYER_OVERLAYS,
+ LAYER_CITYBAR,
LAYER_FOCUS_UNIT,
LAYER_GOTO,
LAYER_COUNT
@@ -173,12 +174,23 @@
SPACESHIP_COUNT
};
+struct citybar_sprites {
+ struct sprite
+ *shields,
+ *food,
+ *occupied,
+ *background;
+ struct sprite_vector occupancy;
+};
+
struct sprite *get_spaceship_sprite(const struct tileset *t,
enum spaceship_part part);
struct sprite *get_citizen_sprite(const struct tileset *t,
struct citizen_type type,
int citizen_index,
const struct city *pcity);
+struct sprite *get_city_flag_sprite(const struct tileset *t,
+ const struct city *pcity);
struct sprite *get_nation_flag_sprite(const struct tileset *t,
Nation_Type_id nation);
struct sprite *get_tech_sprite(const struct tileset *t, Tech_Type_id tech);
@@ -197,6 +209,7 @@
struct sprite *get_cursor_sprite(const struct tileset *t,
enum cursor_type cursor,
int *hot_x, int *hot_y);
+const struct citybar_sprites *get_citybar_sprites(const struct tileset *t);
struct sprite *get_icon_sprite(const struct tileset *t, enum icon_type icon);
struct sprite *get_attention_crosshair_sprite(const struct tileset *t);
struct sprite *get_indicator_sprite(const struct tileset *t,
- [Freeciv-Dev] (PR#2708) patch: backing rectangle for city descriptions in gtk2 client,
Jason Short <=
|
|