Codebase list gplanarity / cd2e967e-cece-4b7a-b2eb-0accc5988312/main gameboard_draw_vertex.c
cd2e967e-cece-4b7a-b2eb-0accc5988312/main

Tree @cd2e967e-cece-4b7a-b2eb-0accc5988312/main (Download .tar.gz)

gameboard_draw_vertex.c @cd2e967e-cece-4b7a-b2eb-0accc5988312/mainraw · history · blame

/*
 *
 *  gPlanarity: 
 *     The geeky little puzzle game with a big noodly crunch!
 *    
 *     gPlanarity copyright (C) 2005 Monty <monty@xiph.org>
 *     Original Flash game by John Tantalo <john.tantalo@case.edu>
 *     Original game concept by Mary Radcliffe
 *
 *  gPlanarity is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  gPlanarity is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with Postfish; see the file COPYING.  If not, write to the
 *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * 
 */

#define _GNU_SOURCE
#include <gtk/gtk.h>
#include <gtk/gtkmain.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include "graph.h"
#include "gameboard.h"

/* draw/cache vertex surfaces; direct surface copies are faster than
   always redrawing lots of circles */

void draw_vertex(cairo_t *c,vertex *v,cairo_surface_t *s){
  cairo_set_source_surface(c,
			   s,
			   v->x-V_LINE-V_RADIUS,
			   v->y-V_LINE-V_RADIUS);
  cairo_paint(c);
}      

void draw_vertex_with_alpha(cairo_t *c,vertex *v,cairo_surface_t *s,float alpha){
  cairo_set_source_surface(c,
			   s,
			   v->x-V_LINE-V_RADIUS,
			   v->y-V_LINE-V_RADIUS);
  cairo_paint_with_alpha(c,alpha);
}      

// normal unlit vertex
cairo_surface_t *cache_vertex(Gameboard *g){
  cairo_t *wc = gdk_cairo_create(g->w.window);
  cairo_surface_t *ret=
    cairo_surface_create_similar (cairo_get_target (wc),
				  CAIRO_CONTENT_COLOR_ALPHA,
				  (V_RADIUS+V_LINE)*2,
				  (V_RADIUS+V_LINE)*2);
  cairo_t *c = cairo_create(ret);
  cairo_destroy(wc);

  cairo_set_line_width(c,V_LINE);
  cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS,0,2*M_PI);
  cairo_set_source_rgb(c,V_FILL_IDLE_COLOR);
  cairo_fill_preserve(c);
  cairo_set_source_rgb(c,V_LINE_COLOR);
  cairo_stroke(c);

  cairo_destroy(c);
  return ret;
}

// selected vertex
cairo_surface_t *cache_vertex_sel(Gameboard *g){
  cairo_t *wc = gdk_cairo_create(g->w.window);
  cairo_surface_t *ret=
    cairo_surface_create_similar (cairo_get_target (wc),
				  CAIRO_CONTENT_COLOR_ALPHA,
				  (V_RADIUS+V_LINE)*2,
				  (V_RADIUS+V_LINE)*2);
  cairo_t *c = cairo_create(ret);
  cairo_destroy(wc);

  cairo_set_line_width(c,V_LINE);
  cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS,0,2*M_PI);
  cairo_set_source_rgb(c,V_FILL_LIT_COLOR);
  cairo_fill_preserve(c);
  cairo_set_source_rgb(c,V_LINE_COLOR);
  cairo_stroke(c);
  cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS*.5,0,2*M_PI);
  cairo_set_source_rgb(c,V_FILL_IDLE_COLOR);
  cairo_fill(c);

  cairo_destroy(c);
  return ret;
}

// grabbed vertex
cairo_surface_t *cache_vertex_grabbed(Gameboard *g){
  cairo_t *wc = gdk_cairo_create(g->w.window);
  cairo_surface_t *ret=
    cairo_surface_create_similar (cairo_get_target (wc),
				  CAIRO_CONTENT_COLOR_ALPHA,
				  (V_RADIUS+V_LINE)*2,
				  (V_RADIUS+V_LINE)*2);
  cairo_t *c = cairo_create(ret);
  cairo_destroy(wc);

  cairo_set_line_width(c,V_LINE);
  cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS,0,2*M_PI);
  cairo_set_source_rgb(c,V_FILL_LIT_COLOR);
  cairo_fill_preserve(c);
  cairo_set_source_rgb(c,V_LINE_COLOR);
  cairo_stroke(c);
  cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS*.5,0,2*M_PI);
  cairo_set_source_rgb(c,V_FILL_ADJ_COLOR);
  cairo_fill(c);

  cairo_destroy(c);
  return ret;
}

// vertex under mouse rollover
cairo_surface_t *cache_vertex_lit(Gameboard *g){
  cairo_t *wc = gdk_cairo_create(g->w.window);
  cairo_surface_t *ret=
    cairo_surface_create_similar (cairo_get_target (wc),
				  CAIRO_CONTENT_COLOR_ALPHA,
				  (V_RADIUS+V_LINE)*2,
				  (V_RADIUS+V_LINE)*2);
  cairo_t *c = cairo_create(ret);
  cairo_destroy(wc);

  cairo_set_line_width(c,V_LINE);
  cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS,0,2*M_PI);
  cairo_set_source_rgb(c,V_FILL_LIT_COLOR);
  cairo_fill_preserve(c);
  cairo_set_source_rgb(c,V_LINE_COLOR);
  cairo_stroke(c);

  cairo_destroy(c);
  return ret;
}

// verticies attached to grabbed vertex
cairo_surface_t *cache_vertex_attached(Gameboard *g){
  cairo_t *wc = gdk_cairo_create(g->w.window);
  cairo_surface_t *ret=
    cairo_surface_create_similar (cairo_get_target (wc),
				  CAIRO_CONTENT_COLOR_ALPHA,
				  (V_RADIUS+V_LINE)*2,
				  (V_RADIUS+V_LINE)*2);
  cairo_t *c = cairo_create(ret);
  cairo_destroy(wc);

  cairo_set_line_width(c,V_LINE);
  cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS,0,2*M_PI);
  cairo_set_source_rgb(c,V_FILL_ADJ_COLOR);
  cairo_fill_preserve(c);
  cairo_set_source_rgb(c,V_LINE_COLOR);
  cairo_stroke(c);

  cairo_destroy(c);
  return ret;
}

// vertex being dragged in a group
cairo_surface_t *cache_vertex_ghost(Gameboard *g){
  cairo_t *wc = gdk_cairo_create(g->w.window);
  cairo_surface_t *ret=
    cairo_surface_create_similar (cairo_get_target (wc),
				  CAIRO_CONTENT_COLOR_ALPHA,
				  (V_RADIUS+V_LINE)*2,
				  (V_RADIUS+V_LINE)*2);
  cairo_t *c = cairo_create(ret);
  cairo_destroy (wc);

  cairo_set_line_width(c,V_LINE);
  cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS,0,2*M_PI);
  cairo_set_source_rgb(c,V_FILL_LIT_COLOR);
  cairo_fill_preserve(c);
  cairo_set_source_rgb(c,V_LINE_COLOR);
  cairo_stroke(c);
  cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS*.5,0,2*M_PI);
  cairo_set_source_rgb(c,V_FILL_ADJ_COLOR);
  cairo_fill(c);

  cairo_destroy(c);
  return ret;
}


/* region invalidation operations; do exposes efficiently! **********/

// invalidate the box around a single offset vertex
void invalidate_vertex_off(GtkWidget *widget, 
					 vertex *v, int dx, int dy){
  if(v){
    GdkRectangle r;
    r.x = v->x - V_RADIUS - V_LINE + dx;
    r.y = v->y - V_RADIUS - V_LINE + dy;
    r.width =  (V_RADIUS + V_LINE)*2;
    r.height = (V_RADIUS + V_LINE)*2;
    
    gdk_window_invalidate_rect (widget->window, &r, FALSE);
  }
}

// invalidate the box around a single vertex
void invalidate_vertex(Gameboard *g, vertex *v){
  invalidate_vertex_off(&g->w,v,0,0);
}

// invalidate a vertex and any other attached verticies
void invalidate_attached(GtkWidget *widget, vertex *v){
  if(v){
    edge_list *el=v->edges;
    while (el){
      edge *e=el->edge;
      if(e->A != v)invalidate_vertex(GAMEBOARD(widget),e->A);
      if(e->B != v)invalidate_vertex(GAMEBOARD(widget),e->B);
      el=el->next;
    }
    invalidate_vertex(GAMEBOARD(widget),v);
  }
}