[xiph-commits] r9647 - trunk/planarity

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Fri Jul 29 23:15:49 PDT 2005


Author: xiphmont
Date: 2005-07-29 23:15:44 -0700 (Fri, 29 Jul 2005)
New Revision: 9647

Modified:
   trunk/planarity/Makefile
   trunk/planarity/buttonbar.c
   trunk/planarity/buttons.c
   trunk/planarity/buttons.h
   trunk/planarity/gameboard.c
   trunk/planarity/gameboard.h
   trunk/planarity/gamestate.c
   trunk/planarity/version.h
Log:
prepare buttons for being used in dialogs as well
add dimming 'curatin' for end-of-board dialogs



Modified: trunk/planarity/Makefile
===================================================================
--- trunk/planarity/Makefile	2005-07-29 23:28:57 UTC (rev 9646)
+++ trunk/planarity/Makefile	2005-07-30 06:15:44 UTC (rev 9647)
@@ -16,9 +16,9 @@
 # work for on most modern linux distros without any of the
 # bleeding-edge GTK 2.7/2.8 libs installed.
 
-SRC  = graph.c arrange.c gameboard.c generate.c gamestate.c\
+SRC  = graph.c arrange.c gameboard.c generate.c gamestate.c button_base.c\
 	buttons.c buttonbar.c box.c
-OBJ  = graph.o arrange.o gameboard.o generate.o gamestate.o\
+OBJ  = graph.o arrange.o gameboard.o generate.o gamestate.o button_base.o\
 	buttons.o buttonbar.o box.o
 GCF  = `pkg-config --static --cflags "gtk+-2.0 >= 2.7.2"`
 

Modified: trunk/planarity/buttonbar.c
===================================================================
--- trunk/planarity/buttonbar.c	2005-07-29 23:28:57 UTC (rev 9646)
+++ trunk/planarity/buttonbar.c	2005-07-30 06:15:44 UTC (rev 9647)
@@ -6,404 +6,30 @@
 #include "graph.h"
 #include "gameboard.h"
 #include "gamestate.h"
-#include "buttons.h"
-#include "box.h"
+#include "button_base.h"
+#include "buttonbar.h"
 
-
 /************************ the lower button bar *********************/
 
-#define NUMBUTTONS 10
-
-typedef struct {
-  int target_x;
-  int target_x_inactive;
-  int target_x_active;
-
-  int x;
-  int x_inactive;
-  int x_active;
-  int y;
-
-  cairo_surface_t *idle;
-  cairo_surface_t *lit;
-
-  char *rollovertext;
-  cairo_text_extents_t ex;
-
-  int alphad;
-  double alpha;
-
-  int rollover;
-  int press;
-
-  void (*callback)();
-} buttonstate;
-
-static buttonstate states[NUMBUTTONS];
-
-static int width=0;
-static int height=0;
-static int deployed=0;
+static int checkbutton_deployed=0;
 static int sweeper=0;
 static gint timer = 0;
-static int checkbutton_deployed=0;
-static int allclear=1; // actually just a shirt-circuit
-static buttonstate *grabbed=0;
 static void (*undeploy_callback)(Gameboard *g);
 
-/*********************** static housekeeping *****************/
-
-/* initialize the rather weird little animation engine */
-static void buttons_initial_placement(int w, int h){
-  
-  int count=BUTTON_BORDER;
-  int i;
-
-  width=w;
-  height=h;
-  
-  for(i=0;i<BUTTON_LEFT;i++){
-    buttonstate *b=states+i;
-    b->x=0;
-    b->target_x=count;
-    b->x_active=b->target_x_active=count;
-    b->x_inactive=b->target_x_inactive=count-BUTTON_EXPOSE;
-    b->y = h - BUTTON_Y_FROM_BOTTOM;
-    count += BUTTON_SPACING;
-  }
-  count -= BUTTON_SPACING;
-
-  // assumes we will always have at least as many buttons left as right
-  sweeper=count;
-  
-  count=width-BUTTON_BORDER;
-  for(i=0;i<BUTTON_RIGHT;i++){
-    buttonstate *b=states+NUMBUTTONS-i-1;
-    b->x=width;
-    b->target_x=count;
-    b->x_active=b->target_x_active=count;
-    b->x_inactive=b->target_x_inactive=count+BUTTON_EXPOSE;
-    b->y = h - BUTTON_Y_FROM_BOTTOM;
-    if(i>0) // special-case the checkbutton
-      count -= BUTTON_SPACING;
-  }
-  
-  // special-case the checkbutton
-  states[9].target_x_inactive=states[9].target_x_active+BUTTON_SPACING;
-  states[9].x_inactive=states[9].target_x_inactive;
-  states[9].target_x=states[9].target_x_inactive;
-
-}
-
-/* cache buttons as small surfaces */
-static cairo_surface_t *cache_button(Gameboard *g,
-				     void (*draw)(cairo_t *c, 
-						  double x, 
-						  double y),
-				     double pR,double pG,double pB,double pA,
-				     double fR,double fG,double fB,double fA){
-  cairo_surface_t *ret = 
-    cairo_surface_create_similar (cairo_get_target (g->wc),
-				  CAIRO_CONTENT_COLOR_ALPHA,
-				  BUTTON_RADIUS*2+1,
-				  BUTTON_RADIUS*2+1);
-  
-  cairo_t *c = cairo_create(ret);
-
-  cairo_save(c);
-  cairo_set_operator(c,CAIRO_OPERATOR_CLEAR);
-  cairo_set_source_rgba (c, 1,1,1,1);
-  cairo_paint(c);
-  cairo_restore(c);
-     
-  cairo_set_source_rgba(c,fR,fG,fB,fA);
-  cairo_set_line_width(c,BUTTON_LINE_WIDTH);
-  draw(c,BUTTON_RADIUS+.5,BUTTON_RADIUS+.5);
-
-  cairo_set_source_rgba(c,pR,pG,pB,pA);
-  cairo_stroke(c);
-  
-  cairo_destroy(c);
-  return ret;
-}
-
-/* determine the x/y/w/h box around a button */
-static GdkRectangle button_box(buttonstate *b){
-  GdkRectangle r;
-
-  int x = b->x - BUTTON_RADIUS-1;
-  int y = b->y - BUTTON_RADIUS-1;
-  r.x=x;
-  r.y=y;
-  r.width = BUTTON_RADIUS*2+2;
-  r.height= BUTTON_RADIUS*2+2;
-
-  return r;
-}
-
-/* determine the x/y/w/h box around the rollover text */
-static GdkRectangle rollover_box(buttonstate *b){
-  GdkRectangle r;
-
-  int x = b->x - b->ex.width/2 + b->ex.x_bearing -2;
-  int y = b->y - BUTTON_RADIUS - BUTTON_TEXT_BORDER + b->ex.y_bearing -2;
-
-  if(x<BUTTON_TEXT_BORDER)x=BUTTON_TEXT_BORDER;
-  if(y<BUTTON_TEXT_BORDER)y=BUTTON_TEXT_BORDER;
-  if(x+b->ex.width >= width - BUTTON_TEXT_BORDER)
-    x = width - BUTTON_TEXT_BORDER - b->ex.width;
-  if(y+b->ex.height >= height - BUTTON_TEXT_BORDER)
-    y = height - BUTTON_TEXT_BORDER - b->ex.height;
-
-  r.x=x;
-  r.y=y;
-  r.width=b->ex.width+5;
-  r.height=b->ex.height+5;
-
-  return r;
-}
-
-/* draw the actual rollover */
-static void stroke_rollover(Gameboard *g, buttonstate *b, cairo_t *c){
-  cairo_matrix_t m;
-
-  cairo_select_font_face (c, "Arial",
-			  CAIRO_FONT_SLANT_NORMAL,
-			  CAIRO_FONT_WEIGHT_BOLD);
-
-  cairo_matrix_init_scale (&m, BUTTON_TEXT_SIZE);
-  cairo_set_font_matrix (c,&m);
-  
-  {
-    GdkRectangle r=rollover_box(b);
-
-    cairo_move_to (c, r.x - b->ex.x_bearing +2, r.y -b->ex.y_bearing+2 );
-
-    cairo_set_line_width(c,3);
-    cairo_set_source_rgba(c,1,1,1,.9);
-    cairo_text_path (c, b->rollovertext);  
-    cairo_stroke(c);
-
-    cairo_set_source_rgba(c,BUTTON_TEXT_COLOR);
-    cairo_move_to (c, r.x - b->ex.x_bearing +2, r.y -b->ex.y_bearing+2 );
-    
-
-    cairo_show_text (c, b->rollovertext);  
-
-  }
-}
-
-/* cache the text extents of a rollover */
-static void rollover_extents(Gameboard *g, buttonstate *b){
-  
-  cairo_matrix_t m;
-
-  cairo_t *c = cairo_create(g->foreground);
-  cairo_select_font_face (c, "Arial",
-			  CAIRO_FONT_SLANT_NORMAL,
-			  CAIRO_FONT_WEIGHT_BOLD);
-  
-  cairo_matrix_init_scale (&m, BUTTON_TEXT_SIZE);
-  cairo_set_font_matrix (c,&m);
-  
-  cairo_text_extents (c, b->rollovertext, &b->ex);
-
-
-  cairo_destroy(c);
-}
-
-/* request an expose for a button region*/
-static void invalidate_button(Gameboard *g,buttonstate *b){
-  GdkRectangle r;
-
-  r.x=b->x-BUTTON_RADIUS-1;
-  r.y=b->y-BUTTON_RADIUS-1;
-  r.width=BUTTON_RADIUS*2+2;
-  r.height=BUTTON_RADIUS*2+2;
-
-  gdk_window_invalidate_rect(g->w.window,&r,FALSE);
-}
-
-/* request an expose for a rollover region*/
-static void invalidate_rollover(Gameboard *g,buttonstate *b){
-  GdkRectangle r = rollover_box(b);
-  invalidate_button(g,b);
-  gdk_window_invalidate_rect(g->w.window,&r,FALSE);
-}
-
-/* like invalidation, but just expands a rectangular region */
-static void expand_rectangle_button(buttonstate *b,GdkRectangle *r){
-  int x=b->x-BUTTON_RADIUS-1;
-  int y=b->y-BUTTON_RADIUS-1;
-  int x2=x+BUTTON_RADIUS*2+2;
-  int y2=y+BUTTON_RADIUS*2+2;
-
-  int rx2=r->x+r->width;
-  int ry2=r->y+r->height;
-
-  if(r->width==0 || r->height==0){
-    r->x=x;
-    r->y=y;
-    r->width=x2-x;
-    r->height=y2-y;
-  }
-
-  if(x<r->x)
-    r->x=x;
-  if(y<r->y)
-    r->y=y;
-  if(rx2<x2)
-    rx2=x2;
-  r->width=rx2-r->x;
-  if(ry2<y2)
-    ry2=y2;
-  r->height=ry2-r->y;
-}
-
-/* like invalidation, but just expands a rectangular region */
-static void expand_rectangle_rollover(buttonstate *b,GdkRectangle *r){
-  GdkRectangle rr = rollover_box(b);
-  int x=rr.x;
-  int y=rr.y;
-  int x2=x+rr.width;
-  int y2=y+rr.height;
-
-  int rx2=r->x+r->width;
-  int ry2=r->y+r->height;
-
-  if(r->width==0 || r->height==0){
-    r->x=x;
-    r->y=y;
-    r->width=x2-x;
-    r->height=y2-y;
-  }
-
-  if(x<r->x)
-    r->x=x;
-  if(y<r->y)
-    r->y=y;
-  if(rx2<x2)
-    rx2=x2;
-  r->width=rx2-r->x;
-  if(ry2<y2)
-    ry2=y2;
-  r->height=ry2-r->y;
-}
-
-/* do the animation math for one button for one frame */
-static int animate_one(buttonstate *b, GdkRectangle *r){
-  int ret=0;
-  int w2=width/2;
-
-  if(b->target_x>w2 && width-sweeper>b->target_x)
-    b->target_x=width-sweeper;
-  if(b->target_x<w2 && sweeper<b->target_x)
-    b->target_x=sweeper;
-
-  if(b->target_x_active != b->x_active){
-    ret=1;
-    if(b->target_x_active > b->x_active){
-      b->x_active+=BUTTON_DELTA;
-      if(b->x_active>b->target_x_active)
-	b->x_active=b->target_x_active;
-    }else{
-      b->x_active-=BUTTON_DELTA;
-      if(b->x_active<b->target_x_active)
-	b->x_active=b->target_x_active;
-    }
-  }
-
-  if(b->target_x_inactive != b->x_inactive){
-    ret=1;
-    if(b->target_x_inactive > b->x_inactive){
-      b->x_inactive+=BUTTON_DELTA;
-      if(b->x_inactive>b->target_x_inactive)
-	b->x_inactive=b->target_x_inactive;
-    }else{
-      b->x_inactive-=BUTTON_DELTA;
-      if(b->x_inactive<b->target_x_inactive)
-	b->x_inactive=b->target_x_inactive;
-    }
-  }
-
-  if(b->target_x != b->x){
-    ret=1;
-    expand_rectangle_button(b,r);
-    if(b->rollover)
-      expand_rectangle_rollover(b,r);
-
-    if(b->target_x > b->x){
-      b->x+=BUTTON_DELTA;
-      if(b->x>b->target_x)b->x=b->target_x;
-    }else{
-      b->x-=BUTTON_DELTA;
-      if(b->x<b->target_x)b->x=b->target_x;
-    }
-    expand_rectangle_button(b,r);
-    if(b->rollover)
-      expand_rectangle_rollover(b,r);
-  }
-
-  if(b->alphad != b->x_active - b->x){
-    double alpha=0;
-    if(b->x_inactive>b->x_active){
-      if(b->x<=b->x_active)
-	alpha=1.;
-      else if (b->x>=b->x_inactive)
-	alpha=0.;
-      else
-	alpha = (double)(b->x_inactive-b->x)/(b->x_inactive-b->x_active);
-    }else if (b->x_inactive<b->x_active){
-      if(b->x>=b->x_active)
-	alpha=1.;
-      else if (b->x<=b->x_inactive)
-	alpha=0.;
-      else
-	alpha = (double)(b->x_inactive-b->x)/(b->x_inactive-b->x_active);
-    }
-    if(alpha != b->alpha){
-      ret=1;
-      expand_rectangle_button(b,r);
-      b->alpha=alpha;
-    }
-    b->alphad = b->x_active - b->x;
-  }
-  return ret;
-}
-
 /* perform a single frame of animation for all buttons/rollovers */
-static gboolean animate_buttons(gpointer ptr){
+static gboolean buttonbar_animate_buttons(gpointer ptr){
   Gameboard *g=(Gameboard *)ptr;
-  GdkRectangle expose;
-  int ret=0,i;
+  int ret=0;
 
   if(!g->first_expose)return 1;
-  
-  memset(&expose,0,sizeof(expose));
-  for(i=0;i<BUTTON_LEFT;i++)
-    ret|=animate_one(states+i,&expose);
-  
-  /* avoid the normal expose event mechanism
-     during the button animations.  This direct method is much faster as
-     it won't accidentally combine exposes over long stretches of
-     alpha-blended surfaces. */
-  run_immediate_expose(g,
-		       expose.x,
-  	       expose.y,
-  	       expose.width,
-  	       expose.height);
-  
 
+  if(get_curtain(g)>0.){
+    set_curtain(g,get_curtain(g)-.25);
+    return 1;
+  }
+  set_curtain(g,0);
 
-  memset(&expose,0,sizeof(expose));
-  for(i=BUTTON_LEFT;i<NUMBUTTONS;i++)
-    ret|=animate_one(states+i,&expose);
-    
-  run_immediate_expose(g,
-		       expose.x,
-		       expose.y,
-		       expose.width,
-		       expose.height);
+  ret=animate_button_frame(g);
 
   if(!ret && timer!=0){
     g_source_remove(timer);
@@ -414,192 +40,56 @@
 
 /* helper that wraps animate-buttons for removing the buttons at the
    end of a level */
-static gboolean deanimate_buttons(gpointer ptr){
+static gboolean buttonbar_deanimate_buttons(gpointer ptr){
   Gameboard *g=(Gameboard *)ptr;
-  int ret=0;
+  int ret=0,i;
   sweeper-=BUTTON_DELTA;
   if(sweeper< -(BUTTON_RADIUS +1)){
     sweeper= -(BUTTON_RADIUS +1);
   }else
     ret=1;
 
-  ret|=animate_buttons(ptr);
+  if(get_curtain(g)==0.){
 
-  if(!ret)
-    // undeploy finished... call the undeploy callback
-    undeploy_callback(g);
+    int width=get_board_width();
+    int w2=width/2;
 
-  return ret;
-}
-
-/* the normal expose method for all buttons; called from the master
-   widget's expose */
-void expose_buttons(Gameboard *g,cairo_t *c, int x,int y,int w,int h){
-  int i;
-  
-  for(i=0;i<NUMBUTTONS;i++){
-
-    buttonstate *b=states+i;
-    GdkRectangle r = rollover_box(b);
-    GdkRectangle br = button_box(b);
-
-    if(x < br.x+br.width &&
-       y < br.y+br.height &&
-       x+w > br.x &&
-       y+h > br.y) {
-
-      cairo_set_source_surface(c,
-			       (b->rollover || b->press ? b->lit : b->idle),
-			       br.x,
-			       br.y);
-      
-      if(b->press)
-	cairo_paint_with_alpha(c,b->alpha);
-      cairo_paint_with_alpha(c,b->alpha);
-
-    }
-
-    if(b->rollover || b->press)
-      if(x < r.x+r.width &&
-	 y < r.y+r.height &&
-	 x+w > r.x &&
-	 y+h > r.y)
-	
-	stroke_rollover(g,b,c);
-
-  }
-}
-
-/* match x/y to a button if any */
-static buttonstate *find_button(int x,int y){
-  int i;
-  for(i=0;i<NUMBUTTONS;i++){
-    buttonstate *b=states+i;
-    if( (b->x-x)*(b->x-x) + (b->y-y)*(b->y-y) <= BUTTON_RADIUS*BUTTON_RADIUS+4)
-      if(b->x != b->x_inactive)
-	return b;
-  }
-  return 0;
-}
-
-/* clear all buttons to unpressed/unlit */
-static void button_clear_state(Gameboard *g){
-  int i;
-  if(!allclear){
     for(i=0;i<NUMBUTTONS;i++){
-      buttonstate *bb=states+i;
-      if(bb->rollover)
-	invalidate_rollover(g,bb);
-      if(bb->press)
-	invalidate_button(g,bb);
-      
-      bb->rollover=0;
-      bb->press=0;
+      buttonstate *b=states+i;
+      if(b->position){
+	if(b->target_x>w2 && width-sweeper>b->target_x)
+	  b->target_x=width-sweeper;
+	if(b->target_x<w2 && sweeper<b->target_x)
+	  b->target_x=sweeper;
+      }
     }
+    ret|=animate_button_frame(ptr);
   }
-  allclear=1;
-  grabbed=0;
-}
-
-/* set a button to pressed or lit */
-static void button_set_state(Gameboard *g, buttonstate *b, int rollover, int press){
-  int i;
   
-  if(b->rollover == rollover && b->press == press)return;
-
-  for(i=0;i<NUMBUTTONS;i++){
-    buttonstate *bb=states+i;
-    if(bb!=b){
-      if(bb->rollover)
-	invalidate_rollover(g,bb);
-      if(bb->press)
-	invalidate_button(g,bb);
-
-      bb->rollover=0;
-      bb->press=0;
-    }else{
-      if(bb->rollover != rollover)
-	invalidate_rollover(g,bb);
-      if(bb->press != press)
-	invalidate_button(g,bb);
-      
-      bb->rollover=rollover;
-      bb->press=press;
+  if(!ret){
+    if(get_curtain(g)<.625){
+      set_curtain(g,get_curtain(g)+.25);
+      ret=1;
     }
   }
-  allclear=0;
+
+  if(!ret)
+    // undeploy finished... call the undeploy callback
+    undeploy_callback(g);
+
+  return ret;
 }
 
 /******************** toplevel abstraction calls *********************/
 
-/* initialize the persistent caches; called once when gameboard is
-   first created */
-void init_buttons(Gameboard *g){
+/* initialize the rather weird little animation engine */
+void setup_buttonbar(Gameboard *g){
+  
+  int count=BUTTONBAR_BORDER;
   int i;
-  memset(states,0,sizeof(states));
+  int w=get_board_width();
+  int h=get_board_height();
 
-  states[0].idle = cache_button(g, path_button_exit, 
-				BUTTON_QUIT_IDLE_PATH, 
-				BUTTON_QUIT_IDLE_FILL);
-  states[0].lit  = cache_button(g, path_button_exit, 
-				BUTTON_QUIT_LIT_PATH, 
-				BUTTON_QUIT_LIT_FILL);
-
-  states[1].idle = cache_button(g, path_button_back, 
-				BUTTON_IDLE_PATH,
-				BUTTON_IDLE_FILL);
-  states[1].lit  = cache_button(g, path_button_back, 
-				BUTTON_LIT_PATH,
-				BUTTON_LIT_FILL);
-  states[2].idle = cache_button(g, path_button_reset, 
-				BUTTON_IDLE_PATH,
-				BUTTON_IDLE_FILL);
-  states[2].lit  = cache_button(g, path_button_reset, 
-				BUTTON_LIT_PATH,
-				BUTTON_LIT_FILL);
-  states[3].idle = cache_button(g, path_button_pause, 
-				BUTTON_IDLE_PATH,
-				BUTTON_IDLE_FILL);
-  states[3].lit  = cache_button(g, path_button_pause, 
-				BUTTON_LIT_PATH,
-				BUTTON_LIT_FILL);
-  states[4].idle = cache_button(g, path_button_help, 
-				BUTTON_IDLE_PATH,
-				BUTTON_IDLE_FILL);
-  states[4].lit  = cache_button(g, path_button_help, 
-				BUTTON_LIT_PATH,
-				BUTTON_LIT_FILL);
-  states[5].idle = cache_button(g, path_button_expand, 
-				BUTTON_IDLE_PATH,
-				BUTTON_IDLE_FILL);
-  states[5].lit  = cache_button(g, path_button_expand, 
-				BUTTON_LIT_PATH,
-				BUTTON_LIT_FILL);
-  states[6].idle = cache_button(g, path_button_shrink, 
-				BUTTON_IDLE_PATH,
-				BUTTON_IDLE_FILL);
-  states[6].lit  = cache_button(g, path_button_shrink, 
-				BUTTON_LIT_PATH,
-				BUTTON_LIT_FILL);
-  states[7].idle = cache_button(g, path_button_lines, 
-				BUTTON_IDLE_PATH,
-				BUTTON_IDLE_FILL);
-  states[7].lit  = cache_button(g, path_button_lines, 
-				BUTTON_LIT_PATH,
-				BUTTON_LIT_FILL);
-  states[8].idle = cache_button(g, path_button_int, 
-				BUTTON_IDLE_PATH,
-				BUTTON_IDLE_FILL);
-  states[8].lit  = cache_button(g, path_button_int, 
-				BUTTON_LIT_PATH,
-				BUTTON_LIT_FILL);
-  states[9].idle = cache_button(g, path_button_check, 
-				BUTTON_CHECK_IDLE_PATH,
-				BUTTON_CHECK_IDLE_FILL);
-  states[9].lit  = cache_button(g, path_button_check, 
-				BUTTON_CHECK_LIT_PATH,
-				BUTTON_CHECK_LIT_FILL);
-
   states[0].rollovertext="exit gPlanarity";
   states[1].rollovertext="back to menu";
   states[2].rollovertext="reset board";
@@ -620,15 +110,66 @@
   states[9].callback = finish_board;
 
   for(i=0;i<NUMBUTTONS;i++)
-    rollover_extents(g,states+i);
+    states[i].position=0;
+
+  states[0].position = 1; //left;
+  states[1].position = 1; //left;
+  states[2].position = 1; //left;
+  states[3].position = 1; //left;
+  states[4].position = 1; //left;
+  states[5].position = 3; //right
+  states[6].position = 3; //right
+  states[7].position = 3; //right
+  states[8].position = 3; //right
+  states[9].position = 3; //right
+
+  for(i=0;i<NUMBUTTONS;i++){
+    buttonstate *b=states+i;
+    if(b->position == 1){
+      b->x=0;
+      b->target_x=count;
+      b->x_active=b->target_x_active=count;
+      b->x_inactive=b->target_x_inactive=count-BUTTON_EXPOSE;
+      b->y = h - BUTTONBAR_Y_FROM_BOTTOM;
+      count += BUTTONBAR_SPACING;
+    }
+  }
+  count -= BUTTONBAR_SPACING;
+
+  // assumes we will always have at least as many buttons left as right
+  sweeper=count;
+  
+  count=w-BUTTONBAR_BORDER;
+  for(i=NUMBUTTONS-1;i>=0;i--){
+    buttonstate *b=states+i;
+    if(b->position == 3){
+      b->x=w;
+      b->target_x=count;
+      b->x_active=b->target_x_active=count;
+      b->x_inactive=b->target_x_inactive=count+BUTTON_EXPOSE;
+      b->y = h - BUTTONBAR_Y_FROM_BOTTOM;
+      if(i!=9) // special-case the checkbutton
+	count -= BUTTONBAR_SPACING;
+    }
+  }
+  
+  // special-case the checkbutton
+  states[9].target_x_inactive=states[9].target_x_active+BUTTONBAR_SPACING;
+  states[9].x_inactive=states[9].target_x_inactive;
+  states[9].target_x=states[9].target_x_inactive;
+
+  for(i=0;i<NUMBUTTONS;i++)
+    if(states[i].position)
+      rollover_extents(g,states+i);
+  
 }
 
 /* effects animated 'rollout' of buttons when level begins */
-void deploy_buttons(Gameboard *g){
-  if(!deployed ){
-    buttons_initial_placement(get_board_width(),get_board_height());
-    timer = g_timeout_add(BUTTON_ANIM_INTERVAL, animate_buttons, (gpointer)g);
-    deployed=1;
+void deploy_buttonbar(Gameboard *g){
+  if(!buttons_ready ){
+    setup_buttonbar(g);
+    timer = g_timeout_add(BUTTON_ANIM_INTERVAL, buttonbar_animate_buttons, (gpointer)g);
+    buttons_ready=1;
     checkbutton_deployed=0;
   }
 
@@ -636,17 +177,17 @@
 
 /* effects animated rollout of 'check' button */
 void deploy_check(Gameboard *g){
-  if(deployed && !checkbutton_deployed){
+  if(buttons_ready && !checkbutton_deployed){
     int i;
-    for(i=BUTTON_LEFT;i<NUMBUTTONS-1;i++){
-      states[i].target_x-=BUTTON_SPACING;
-      states[i].target_x_active-=BUTTON_SPACING;
-      states[i].target_x_inactive-=BUTTON_SPACING;
+    for(i=5;i<9;i++){
+      states[i].target_x-=BUTTONBAR_SPACING;
+      states[i].target_x_active-=BUTTONBAR_SPACING;
+      states[i].target_x_inactive-=BUTTONBAR_SPACING;
     }
     states[9].target_x=states[9].target_x_active;
     if(timer!=0)
       g_source_remove(timer);
-    timer = g_timeout_add(BUTTON_ANIM_INTERVAL, animate_buttons, (gpointer)g);
+    timer = g_timeout_add(BUTTON_ANIM_INTERVAL, buttonbar_animate_buttons, (gpointer)g);
     checkbutton_deployed=1;
   }
 }
@@ -655,117 +196,31 @@
 void undeploy_check(Gameboard *g){
   if(checkbutton_deployed){
     int i;
-    for(i=BUTTON_LEFT;i<NUMBUTTONS-1;i++){
-      states[i].target_x+=BUTTON_SPACING;
-      states[i].target_x_active+=BUTTON_SPACING;
-      states[i].target_x_inactive+=BUTTON_SPACING;
+    for(i=5;i<9;i++){
+      states[i].target_x+=BUTTONBAR_SPACING;
+      states[i].target_x_active+=BUTTONBAR_SPACING;
+      states[i].target_x_inactive+=BUTTONBAR_SPACING;
     }
     states[9].target_x=states[9].target_x_inactive;
     if(timer!=0)
       g_source_remove(timer);
-    timer = g_timeout_add(BUTTON_ANIM_INTERVAL, animate_buttons, (gpointer)g);
+    timer = g_timeout_add(BUTTON_ANIM_INTERVAL, buttonbar_animate_buttons, (gpointer)g);
     checkbutton_deployed=0;
   }
 }
 
 /* effects animated rollback of buttons at end of level */
-void undeploy_buttons(Gameboard *g, void (*callback)(Gameboard *g)){
+void undeploy_buttonbar(Gameboard *g, void (*callback)(Gameboard *g)){
   if(timer!=0)
     g_source_remove(timer);
-
+  
   button_clear_state(g);
-  grabbed=0;
-  deployed=0;
+  buttons_ready=0;
   undeploy_callback=callback;
   checkbutton_deployed=0;
 
-  g_timeout_add(BUTTON_ANIM_INTERVAL, deanimate_buttons, (gpointer)g);
+  g_timeout_add(BUTTON_ANIM_INTERVAL, buttonbar_deanimate_buttons, (gpointer)g);
 
 
 }
 
-/* resize the button bar; called from master resize in gameboard */
-void resize_buttons(int w,int h){
-  int i;
-  int dx=w-width;
-  int dy=h-height;
-
-  for(i=BUTTON_LEFT;i<NUMBUTTONS;i++){
-    states[i].x+=dx;
-    states[i].target_x+=dx;
-    states[i].x_active+=dx;
-    states[i].target_x_active+=dx;
-    states[i].x_inactive+=dx;
-    states[i].target_x_inactive+=dx;
-    states[i].y+=dy;
-  }
-  width=w;
-}
-
-
-/* handles mouse motion events; called out of gameboard's master
-   motion handler; returns nonzero if it used focus */
-int button_motion_event(Gameboard *g, GdkEventMotion *event, int focusable){
-  buttonstate *b = find_button((int)event->x,(int)event->y);
-
-  if(deployed){
-    if(grabbed){
-      if(grabbed==b)
-	button_set_state(g,grabbed,1,1);
-      else
-	button_set_state(g,grabbed,0,0);
-      return 1;
-    }
-    
-    if(focusable && !grabbed){
-      
-      if(b){
-	button_set_state(g,b,1,0);
-	return 1;
-      }
-    }
-    
-    button_clear_state(g);
-  }
-  return 0;
-}
-
-/* handles mouse button press events; called out of gameboard's master
-   mouse handler.  returns nonzero if grabbing focus */
-int button_button_press(Gameboard *g, GdkEventButton *event, int focusable){
-
-  if(deployed){
-    if(focusable && deployed){
-      
-      buttonstate *b = find_button((int)event->x,(int)event->y);
-      if(b){
-	button_set_state(g,b,1,1);
-      grabbed = b;
-      return 1;
-      }
-    }
-    
-    button_clear_state(g);
-  }
-  return 0;  
-}
-
-/* handles mouse button press events; called out of gameboard's master
-   mouse handler. returns nonzero if grabbing focus */
-int button_button_release(Gameboard *g, GdkEventButton *event, int focusable){
-  if(focusable && deployed){
-    
-    buttonstate *b = find_button((int)event->x,(int)event->y);
-    if(b && grabbed==b){
-      button_set_state(g,b,1,0);
-      
-      if(b->callback)
-	b->callback(g);
-      
-      
-    }
-  }
-  
-  grabbed=0;
-  return 0;  
-}

Modified: trunk/planarity/buttons.c
===================================================================
--- trunk/planarity/buttons.c	2005-07-29 23:28:57 UTC (rev 9646)
+++ trunk/planarity/buttons.c	2005-07-30 06:15:44 UTC (rev 9647)
@@ -252,3 +252,22 @@
 
 }
 
+void path_button_play(cairo_t *c, double x, double y){
+  
+  cairo_save(c);
+  cairo_translate(c,x,y);
+  cairo_set_fill_rule(c,CAIRO_FILL_RULE_EVEN_ODD);
+  cairo_set_line_width(c,1);
+
+  cairo_arc(c,0,0,14,0,2*M_PI);
+
+  cairo_move_to(c,-10,-8);
+  cairo_line_to(c,0,10);
+  cairo_line_to(c,-10,8);
+  cairo_close_path(c);
+ 
+  cairo_fill_preserve(c);
+  cairo_restore(c);
+
+}
+

Modified: trunk/planarity/buttons.h
===================================================================
--- trunk/planarity/buttons.h	2005-07-29 23:28:57 UTC (rev 9646)
+++ trunk/planarity/buttons.h	2005-07-30 06:15:44 UTC (rev 9647)
@@ -23,6 +23,7 @@
 extern void path_button_lines(cairo_t *c, double x, double y);
 extern void path_button_int(cairo_t *c, double x, double y);
 extern void path_button_check(cairo_t *c, double x, double y);
+extern void path_button_play(cairo_t *c, double x, double y);
  
 
 #define BUTTON_QUIT_IDLE_FILL   .7,.1,.1,.3

Modified: trunk/planarity/gameboard.c
===================================================================
--- trunk/planarity/gameboard.c	2005-07-29 23:28:57 UTC (rev 9646)
+++ trunk/planarity/gameboard.c	2005-07-30 06:15:44 UTC (rev 9647)
@@ -494,6 +494,59 @@
   }
 }
 
+#define CW 4
+static void cache_curtain(Gameboard *g){
+  cairo_surface_t *ret=
+    cairo_surface_create_similar (cairo_get_target (g->wc),
+				  CAIRO_CONTENT_COLOR_ALPHA,
+				  CW,CW);
+
+  g->curtains=ret;
+  g->curtain_alpha=0.;
+}
+
+void set_curtain(Gameboard *g, double alpha){
+  if(alpha != g->curtain_alpha){
+
+    if(g->curtainp)
+      cairo_pattern_destroy(g->curtainp);
+    g->curtainp=0;
+
+    if(alpha<1.){
+      cairo_t *c = cairo_create(g->curtains);
+      int x,y;
+      
+      cairo_save(c);
+      cairo_set_operator(c,CAIRO_OPERATOR_CLEAR);
+      cairo_set_source_rgba (c, 1,1,1,1);
+      cairo_paint(c);
+      cairo_restore(c);
+      
+      cairo_set_line_width(c,1);
+      cairo_set_source_rgba (c, 0,0,0,alpha);
+      
+      for(y=0;y<CW;y++){
+	for(x=y&1;x<CW;x+=2){
+	  cairo_move_to(c,x+.5,y);
+	  cairo_rel_line_to(c,0,1);
+	}
+      }
+      cairo_stroke(c);
+      cairo_destroy(c);
+      
+      g->curtainp=cairo_pattern_create_for_surface (g->curtains);
+      cairo_pattern_set_extend (g->curtainp, CAIRO_EXTEND_REPEAT);
+    }
+    
+    run_immediate_expose(g,0,0,get_board_width(),get_board_height());
+    g->curtain_alpha=alpha;
+  }
+}
+
+double get_curtain(Gameboard *g){
+  return g->curtain_alpha;
+}
+
 static gint mouse_motion(GtkWidget        *widget,
 			 GdkEventMotion   *event){
   Gameboard *g = GAMEBOARD (widget);
@@ -782,8 +835,15 @@
   }
   expose_buttons(g,c,x,y,w,h);
 
-  expose_intersections(g,c,x,y,w,h);
+  if(g->curtain_alpha>0.){ 
+    cairo_set_source (c, g->curtainp);
+    cairo_rectangle (c, 0, 0, get_board_width(), get_board_height());
+    cairo_fill (c);
 
+  }else{
+    expose_intersections(g,c,x,y,w,h);
+  }
+
   cairo_destroy(c);
   
   // blit to window
@@ -889,6 +949,7 @@
   score_update(g);
   paint_bottom_box(g);
   init_buttons(g);
+  cache_curtain(g);
 }
 
 static void gameboard_size_allocate (GtkWidget     *widget,

Modified: trunk/planarity/gameboard.h
===================================================================
--- trunk/planarity/gameboard.h	2005-07-29 23:28:57 UTC (rev 9646)
+++ trunk/planarity/gameboard.h	2005-07-30 06:15:44 UTC (rev 9647)
@@ -46,6 +46,9 @@
   cairo_surface_t *forebutton;
   cairo_surface_t *background;
   cairo_surface_t *foreground;
+  cairo_pattern_t *curtainp;
+  cairo_surface_t *curtains;
+  double curtain_alpha;
   int delayed_background;
 
   vertex *grabbed_vertex;
@@ -71,6 +74,7 @@
 
   int first_expose;
   int show_intersections;
+
 };
 
 struct _GameboardClass{
@@ -94,3 +98,5 @@
 extern void invalidate_region_vertex(Gameboard *g, vertex *v);
 extern int selected(Gameboard *g);
 extern void update_full(Gameboard *g);
+extern double get_curtain(Gameboard *g);
+extern void set_curtain(Gameboard *g, double alpha);

Modified: trunk/planarity/gamestate.c
===================================================================
--- trunk/planarity/gamestate.c	2005-07-29 23:28:57 UTC (rev 9646)
+++ trunk/planarity/gamestate.c	2005-07-30 06:15:44 UTC (rev 9647)
@@ -6,6 +6,7 @@
 #include "generate.h"
 #include "gamestate.h"
 #include "buttons.h"
+#include "buttonbar.h"
 
 Gameboard *gameboard;
 
@@ -48,7 +49,7 @@
   gameboard_reset(gameboard);
 
   //gdk_flush();
-  deploy_buttons(gameboard);
+  deploy_buttonbar(gameboard);
 }
 
 #define RESET_DELTA 2;
@@ -183,12 +184,12 @@
   if(get_num_intersections()<=initial_intersections){
     score+=initial_intersections;
     level++;
-    undeploy_buttons(gameboard,setup_board);
+    undeploy_buttonbar(gameboard,setup_board);
   }
 }
 
 void quit(){
-  undeploy_buttons(gameboard,gtk_main_quit);
+  undeploy_buttonbar(gameboard,gtk_main_quit);
 }
 
 int get_score(){

Modified: trunk/planarity/version.h
===================================================================
--- trunk/planarity/version.h	2005-07-29 23:28:57 UTC (rev 9646)
+++ trunk/planarity/version.h	2005-07-30 06:15:44 UTC (rev 9647)
@@ -1,2 +1,2 @@
 /* DO NOT EDIT: Automated versioning hack [Thu Jul 21 05:46:15 EDT 2005] */
-/* DO NOT EDIT: Automated versioning hack [Thu Jul 28 00:39:04 EDT 2005] */
+/* DO NOT EDIT: Automated versioning hack [Sat Jul 30 02:12:52 EDT 2005] */



More information about the commits mailing list