예제 #1
0
파일: mapctrl.c 프로젝트: jheusala/freeciv
/**************************************************************************
  Put the popup on a smart position, after the real size of the widget is
  known: left of the cursor if within the right half of the map, and vice
  versa; displace the popup so as not to obscure it by the mouse cursor;
  stay always within the map if possible. 
**************************************************************************/
static void popupinfo_positioning_callback(GtkWidget *w, GtkAllocation *alloc, 
					   gpointer data)
{
  struct tmousepos *mousepos = data;
  gint x, y;
  struct tile *ptile;

  ptile = canvas_pos_to_tile(mousepos->x, mousepos->y);
  if (tile_to_canvas_pos(&x, &y, ptile)) {
    gint minx, miny, maxy;

    gdk_window_get_origin(gtk_widget_get_window(map_canvas), &minx, &miny);
    maxy = miny + gtk_widget_get_allocated_height(map_canvas);

    if (x > mapview.width/2) {
      /* right part of the map */
      x += minx;
      y += miny + (tileset_tile_height(tileset) - alloc->height)/2;

      y = CLIP(miny, y, maxy - alloc->height);

      gtk_window_move(GTK_WINDOW(w), x - alloc->width, y);
    } else {
      /* left part of the map */
      x += minx + tileset_tile_width(tileset);
      y += miny + (tileset_tile_height(tileset) - alloc->height)/2;

      y = CLIP(miny, y, maxy - alloc->height);

      gtk_window_move(GTK_WINDOW(w), x, y);
    }
  }
}
예제 #2
0
/****************************************************************************
  Translate from gui to natural coordinate systems.  This provides natural
  coordinates as a floating-point value so there is no loss of information
  in the resulting values.
****************************************************************************/
static void gui_to_natural_pos(const struct tileset *t,
			       double *ntl_x, double *ntl_y,
			       int gui_x, int gui_y)
{
  const double gui_xd = gui_x, gui_yd = gui_y;
  const double W = tileset_tile_width(t) * map_zoom;
  const double H = tileset_tile_height(t) * map_zoom;
  double map_x, map_y;

  /* First convert to map positions.  This ignores hex conversions; we're
   * not looking for an exact tile. */
  if (tileset_is_isometric(t)) {
    /* Includes hex cases. */
    map_x = (gui_xd * H + gui_yd * W) / (W * H);
    map_y = (gui_yd * W - gui_xd * H) / (W * H);
  } else {
    map_x = gui_xd / W;
    map_y = gui_yd / H;
  }

  /* Now convert to natural positions.  Note this assumes the macro form
   * of the conversion will work with floating-point values. */
  MAP_TO_NATURAL_POS(ntl_x, ntl_y, map_x, map_y);

}
예제 #3
0
/**************************************************************************
  FIXME: 
  For now only two food, one shield and two masks can be drawn per unit,
  the proper way to do this is probably something like what Civ II does.
  (One food/shield/mask drawn N times, possibly one top of itself. -- SKi 
**************************************************************************/
void put_unit_pixmap_city_overlays(struct unit *punit, Pixmap pm,
                                   int *upkeep_cost, int happy_cost)
{
  struct canvas store = {pm};
 
  /* wipe the slate clean */
  XSetForeground(display, fill_bg_gc,
		 get_color(tileset, COLOR_MAPVIEW_CITYTEXT)->color.pixel);
  XFillRectangle(display, pm, fill_bg_gc, 0, tileset_tile_width(tileset), 
		 tileset_tile_height(tileset),
		 tileset_tile_height(tileset)
		 + tileset_small_sprite_height(tileset));

  put_unit_city_overlays(punit, &store, 0, tileset_tile_height(tileset),
                         upkeep_cost, happy_cost);
}
예제 #4
0
파일: mapview.c 프로젝트: valisc/freeciv
/**************************************************************************
  FIXME:
  For now only two food, two gold one shield and two masks can be drawn per
  unit, the proper way to do this is probably something like what Civ II does.
  (One food/shield/mask drawn N times, possibly one top of itself. -- SKi 
**************************************************************************/
void put_unit_gpixmap_city_overlays(struct unit *punit, GtkPixcomm *p,
                                    int *upkeep_cost, int happy_cost)
{
  struct canvas store = FC_STATIC_CANVAS_INIT;
 
  store.surface = gtk_pixcomm_get_surface(p);

  put_unit_city_overlays(punit, &store, 0, tileset_tile_height(tileset),
                         upkeep_cost, happy_cost);
}
예제 #5
0
/**************************************************************************
  FIXME:
  For now only two food, two gold one shield and two masks can be drawn per
  unit, the proper way to do this is probably something like what Civ II does.
  (One food/shield/mask drawn N times, possibly one top of itself. -- SKi 
**************************************************************************/
void put_unit_gpixmap_city_overlays(struct unit *punit, GtkPixcomm *p,
                                    int *upkeep_cost, int happy_cost)
{
  struct canvas store;
 
  store.type = CANVAS_PIXCOMM;
  store.v.pixcomm = p;

  gtk_pixcomm_freeze(p);

  put_unit_city_overlays(punit, &store, 0, tileset_tile_height(tileset),
                         upkeep_cost, happy_cost);

  gtk_pixcomm_thaw(p);
}
예제 #6
0
/**************************************************************************
...
**************************************************************************/
static void popit(int xin, int yin, struct tile *ptile)
{
  Position x, y;
  int dw, dh;
  Dimension w, h, b;
  static struct tile *cross_list[2+1];
  struct tile **cross_head = cross_list;
  int i;
  struct unit *punit;
  char *content;
  static bool is_orders;
  
  if (TILE_UNKNOWN != client_tile_get_known(ptile)) {
    Widget p=XtCreatePopupShell("popupinfo", simpleMenuWidgetClass,
				map_canvas, NULL, 0);
    content = (char *) popup_info_text(ptile);
    /* content is provided to us as a single string with multiple lines,
       but xaw doens't support multi-line labels.  So we break it up.
       We mangle it in the process, but who cares?  It's never going to be
       used again anyway. */
    while (1) {
      char *end = strchr(content, '\n'); 
      if (end) {
	*end='\0';
      }
      XtCreateManagedWidget(content, smeBSBObjectClass, p, NULL, 0);
      if (end) {
	content = end+1;
      } else {
	break;
      }
    }

    punit = find_visible_unit(ptile);
    is_orders = show_unit_orders(punit);
    if (punit && punit->goto_tile) {
      *cross_head = punit->goto_tile;
      cross_head++;
    }
    *cross_head = ptile;
    cross_head++;

    xin /= tileset_tile_width(tileset);
    xin *= tileset_tile_width(tileset);
    yin /= tileset_tile_height(tileset);
    yin *= tileset_tile_height(tileset);
    xin += (tileset_tile_width(tileset) / 2);
    XtTranslateCoords(map_canvas, xin, yin, &x, &y);
    dw = XDisplayWidth (display, screen_number);
    dh = XDisplayHeight (display, screen_number);
    XtRealizeWidget(p);
    XtVaGetValues(p, XtNwidth, &w, XtNheight, &h, XtNborderWidth, &b, NULL);
    w += (2 * b);
    h += (2 * b);
    x -= (w / 2);
    y -= h;
    if ((x + w) > dw) x = dw - w;
    if (x < 0) x = 0;
    if ((y + h) > dh) y = dh - h;
    if (y < 0) y = 0;
    XtVaSetValues(p, XtNx, x, XtNy, y, NULL);

    *cross_head = NULL;
    for (i = 0; cross_list[i]; i++) {
      put_cross_overlay_tile(cross_list[i]);
    }
    XtAddCallback(p,XtNpopdownCallback,popupinfo_popdown_callback,
		  (XtPointer)&is_orders);

    XtPopupSpringLoaded(p);
  }
  
}
예제 #7
0
  /* use maximum possible squared city radius. */
  city_map_iterate_without_index(CITY_MAP_MAX_RADIUS_SQ, city_x, city_y) {
    int canvas_x, canvas_y;

    map_to_gui_vector(tileset, &canvas_x, &canvas_y, CITY_ABS2REL(city_x),
                      CITY_ABS2REL(city_y));

    min_x = MIN(canvas_x, min_x);
    max_x = MAX(canvas_x, max_x);
    min_y = MIN(canvas_y, min_y);
    max_y = MAX(canvas_y, max_y);
  } city_map_iterate_without_index_end;

  citydlg_map_width = max_x - min_x + tileset_tile_width(tileset);
  citydlg_map_height = max_y - min_y + tileset_tile_height(tileset);
}

/**************************************************************************
  Converts a (cartesian) city position to citymap canvas coordinates.
  Returns TRUE if the city position is valid.
**************************************************************************/
bool city_to_canvas_pos(int *canvas_x, int *canvas_y, int city_x,
                        int city_y, int city_radius_sq)
{
  const int width = get_citydlg_canvas_width();
  const int height = get_citydlg_canvas_height();

  /* The citymap is centered over the center of the citydlg canvas. */
  map_to_gui_vector(tileset, canvas_x, canvas_y, CITY_ABS2REL(city_x),
                    CITY_ABS2REL(city_y));