Re: Feedback when checkbuttons are depressed



Soeren Sandmann <sandmann daimi au dk> writes:

> Here is a patch that adds visual feedback when check- and radiobuttons
> are depressed.  It also simplifies the logic in
> gtk_{real_check, radio}_button_draw_indicator.
> 
> Inconsistent buttons are not drawn any different from normal buttons;
> I have marked this with FIXME's.

Here is a new try that can be applied to current CVS and fixes two
instances of an embarrassing 'use uninitialized' bug.


Søren

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.2657
diff -u -p -r1.2657 ChangeLog
--- ChangeLog	2001/12/04 16:08:16	1.2657
+++ ChangeLog	2001/12/04 18:00:13
@@ -1,3 +1,19 @@
+Tue Dec  4 18:46:48 2001  Soeren Sandmann  <sandmann daimi au dk>
+
+	* gtk/gtkcheckbutton.c (gtk_real_check_button_draw_indicator):
+	Simplify logic and use GTK_STATE_ACTIVE when the check button is
+	depressed
+
+	* gtk/gtkradiobutton.c (gtk_radio_button_draw_indicator): same
+	here
+	
+	* gtk/gtkstyle.c (gtk_default_draw_check,
+	gtk_default_draw_option): draw base with bg_gc when state is
+	active
+
+	* gtk/gtktogglebutton.c (gtk_toggle_button_update_state): 
+	Use GTK_STATE_ACTIVE when an inconsistent button is depressed
+
 Tue Dec  4 11:06:54 2001  Owen Taylor  <otaylor redhat com>
 
 	* gtk/gtkmenuitem.c: Revert my last mistaken change - 
Index: gtk/gtkstyle.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkstyle.c,v
retrieving revision 1.89
diff -u -p -r1.89 gtkstyle.c
--- gtk/gtkstyle.c	2001/12/04 03:27:29	1.89
+++ gtk/gtkstyle.c	2001/12/04 18:00:13
@@ -3062,17 +3062,26 @@ gtk_default_draw_check (GtkStyle      *s
 	}
       else
 	{
+	  GdkGC *base_gc = style->base_gc[state_type];
+
+	  if (state_type == GTK_STATE_ACTIVE)
+	    base_gc = style->bg_gc[state_type];
+	  
+	  draw_part (window, base_gc, area, x, y, CHECK_BASE);
 	  draw_part (window, style->black_gc, area, x, y, CHECK_BLACK);
 	  draw_part (window, style->dark_gc[state_type], area, x, y, CHECK_DARK);
 	  draw_part (window, style->mid_gc[state_type], area, x, y, CHECK_MID);
 	  draw_part (window, style->light_gc[state_type], area, x, y, CHECK_LIGHT);
-	  draw_part (window, style->base_gc[state_type], area, x, y, CHECK_BASE);
 	  
 	  if (shadow_type == GTK_SHADOW_IN)
 	    {
 	      draw_part (window, style->text_gc[state_type], area, x, y, CHECK_TEXT);
 	      draw_part (window, style->text_aa_gc[state_type], area, x, y, CHECK_AA);
 	    }
+	  else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
+	    {
+	      /* FIXME */
+	    }
 	}
     }
 
@@ -3125,14 +3134,21 @@ gtk_default_draw_option (GtkStyle      *
 	}
       else
 	{
+	  GdkGC *base_gc = style->base_gc[state_type];
+
+	  if (state_type == GTK_STATE_ACTIVE)
+	    base_gc = style->bg_gc[state_type];
+
+	  draw_part (window, base_gc, area, x, y, RADIO_BASE);
 	  draw_part (window, style->black_gc, area, x, y, RADIO_BLACK);
 	  draw_part (window, style->dark_gc[state_type], area, x, y, RADIO_DARK);
 	  draw_part (window, style->mid_gc[state_type], area, x, y, RADIO_MID);
 	  draw_part (window, style->light_gc[state_type], area, x, y, RADIO_LIGHT);
-	  draw_part (window, style->base_gc[state_type], area, x, y, RADIO_BASE);
 	  
 	  if (shadow_type == GTK_SHADOW_IN)
 	    draw_part (window, style->text_gc[state_type], area, x, y, RADIO_TEXT);
+	  else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
+	    ; /* FIXME */
 	}
     }
 }
Index: gtk/gtkcheckbutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcheckbutton.c,v
retrieving revision 1.37
diff -u -p -r1.37 gtkcheckbutton.c
--- gtk/gtkcheckbutton.c	2001/12/04 03:27:28	1.37
+++ gtk/gtkcheckbutton.c	2001/12/04 18:00:13
@@ -381,74 +381,79 @@ gtk_real_check_button_draw_indicator (Gt
   GtkToggleButton *toggle_button;
   GtkStateType state_type;
   GtkShadowType shadow_type;
-  GdkRectangle restrict_area;
-  GdkRectangle new_area;
-  gint width, height;
   gint x, y;
   gint indicator_size;
   gint indicator_spacing;
   gint focus_width;
   gint focus_pad;
   gboolean interior_focus;
-  GdkWindow *window;
   
   g_return_if_fail (GTK_IS_CHECK_BUTTON (check_button));
   
-  widget = GTK_WIDGET (check_button);
-  toggle_button = GTK_TOGGLE_BUTTON (check_button);
-  
   if (GTK_WIDGET_DRAWABLE (check_button))
     {
-      window = widget->window;
-
+      widget = GTK_WIDGET (check_button);
+      toggle_button = GTK_TOGGLE_BUTTON (check_button);
+  
       gtk_widget_style_get (widget, "interior_focus", &interior_focus,
 			    "focus-line-width", &focus_width, 
 			    "focus-padding", &focus_pad, NULL);
 
       _gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
-						    
-      state_type = GTK_WIDGET_STATE (widget);
-      if (state_type != GTK_STATE_NORMAL &&
-	  state_type != GTK_STATE_PRELIGHT)
-	state_type = GTK_STATE_NORMAL;
-      
-      restrict_area.x = widget->allocation.x + GTK_CONTAINER (widget)->border_width;
-      restrict_area.y = widget->allocation.y + GTK_CONTAINER (widget)->border_width;
-      restrict_area.width = widget->allocation.width - ( 2 * GTK_CONTAINER (widget)->border_width);
-      restrict_area.height = widget->allocation.height - ( 2 * GTK_CONTAINER (widget)->border_width);
-      
-      if (gdk_rectangle_intersect (area, &restrict_area, &new_area))
+
+      if (GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT)
 	{
-	  if (state_type != GTK_STATE_NORMAL)
-	    gtk_paint_flat_box (widget->style, window, state_type, 
-				GTK_SHADOW_ETCHED_OUT, 
-				area, widget, "checkbutton",
-				new_area.x, new_area.y,
-				new_area.width, new_area.height);
+	  GdkRectangle restrict_area;
+	  GdkRectangle new_area;
+	      
+	  restrict_area.x = widget->allocation.x + GTK_CONTAINER (widget)->border_width;
+	  restrict_area.y = widget->allocation.y + GTK_CONTAINER (widget)->border_width;
+	  restrict_area.width = widget->allocation.width - ( 2 * GTK_CONTAINER (widget)->border_width);
+	  restrict_area.height = widget->allocation.height - ( 2 * GTK_CONTAINER (widget)->border_width);
+	  
+	  if (gdk_rectangle_intersect (area, &restrict_area, &new_area))
+	    {
+	      gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_PRELIGHT,
+				  GTK_SHADOW_ETCHED_OUT, 
+				  area, widget, "checkbutton",
+				  new_area.x, new_area.y,
+				  new_area.width, new_area.height);
+	    }
 	}
       
       x = widget->allocation.x + indicator_spacing + GTK_CONTAINER (widget)->border_width;
       y = widget->allocation.y + (widget->allocation.height - indicator_size) / 2;
-      width = indicator_size;
-      height = indicator_size;
 
       if (!interior_focus)
 	x += focus_width + focus_pad;      
 
-      state_type = GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE ? GTK_STATE_NORMAL : GTK_WIDGET_STATE (widget);
-      if (GTK_TOGGLE_BUTTON (widget)->inconsistent)
-	shadow_type = GTK_SHADOW_ETCHED_IN;
-      else if (GTK_TOGGLE_BUTTON (widget)->active)
-	shadow_type = GTK_SHADOW_IN;
+      if (toggle_button->inconsistent)
+	{
+	  shadow_type = GTK_SHADOW_ETCHED_IN;
+	  state_type = GTK_WIDGET_STATE (widget);
+	}
+      else if (toggle_button->active)
+	{
+	  shadow_type = GTK_SHADOW_IN;
+	  if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE)
+	    state_type = GTK_STATE_NORMAL;
+	  else if (GTK_WIDGET_STATE (widget) == GTK_STATE_NORMAL)
+	    state_type = GTK_STATE_ACTIVE;
+	  else
+	    state_type = GTK_WIDGET_STATE (widget);
+	}
       else
-	shadow_type = GTK_SHADOW_OUT;
-
+	{
+	  shadow_type = GTK_SHADOW_OUT;
+	  state_type = GTK_WIDGET_STATE (widget);
+	}
+      
       if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
-	x = widget->allocation.x + widget->allocation.width - (width + x - widget->allocation.x);
+	x = widget->allocation.x + widget->allocation.width - (indicator_size + x - widget->allocation.x);
 
-      gtk_paint_check (widget->style, window,
+      gtk_paint_check (widget->style, widget->window,
 		       state_type, shadow_type,
 		       area, widget, "checkbutton",
-		       x, y, width, height);
+		       x, y, indicator_size, indicator_size);
     }
 }
Index: gtk/gtkradiobutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkradiobutton.c,v
retrieving revision 1.38
diff -u -p -r1.38 gtkradiobutton.c
--- gtk/gtkradiobutton.c	2001/12/04 03:27:29	1.38
+++ gtk/gtkradiobutton.c	2001/12/04 18:00:13
@@ -579,12 +579,9 @@ gtk_radio_button_draw_indicator (GtkChec
 				 GdkRectangle   *area)
 {
   GtkWidget *widget;
-  GtkButton *button;
   GtkToggleButton *toggle_button;
   GtkStateType state_type;
   GtkShadowType shadow_type;
-  GdkRectangle restrict_area;
-  GdkRectangle new_area;
   gint x, y;
   gint indicator_size, indicator_spacing;
   gint focus_width;
@@ -593,10 +590,9 @@ gtk_radio_button_draw_indicator (GtkChec
 
   g_return_if_fail (GTK_IS_RADIO_BUTTON (check_button));
 
-  if (GTK_WIDGET_VISIBLE (check_button) && GTK_WIDGET_MAPPED (check_button))
+  if (GTK_WIDGET_DRAWABLE (check_button))
     {
       widget = GTK_WIDGET (check_button);
-      button = GTK_BUTTON (check_button);
       toggle_button = GTK_TOGGLE_BUTTON (check_button);
 
       gtk_widget_style_get (widget,
@@ -605,26 +601,26 @@ gtk_radio_button_draw_indicator (GtkChec
 			    "focus-padding", &focus_pad,
 			    NULL);
 
-      state_type = GTK_WIDGET_STATE (widget);
-      if ((state_type != GTK_STATE_NORMAL) &&
-	  (state_type != GTK_STATE_PRELIGHT))
-	state_type = GTK_STATE_NORMAL;
-
       _gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
-
-      restrict_area.x = widget->allocation.x + GTK_CONTAINER (widget)->border_width;
-      restrict_area.y = widget->allocation.y + GTK_CONTAINER (widget)->border_width;
-      restrict_area.width = widget->allocation.width - ( 2 * GTK_CONTAINER (widget)->border_width);
-      restrict_area.height = widget->allocation.height - ( 2 * GTK_CONTAINER (widget)->border_width);
 
-      if (gdk_rectangle_intersect (area, &restrict_area, &new_area))
+      if (GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT)
 	{
-	   if (state_type != GTK_STATE_NORMAL)
-	     gtk_paint_flat_box(widget->style, widget->window, state_type, 
-				GTK_SHADOW_ETCHED_OUT,
-				area, widget, "radiobutton",
-				new_area.x, new_area.y,
-				new_area.width, new_area.height);
+	  GdkRectangle restrict_area;
+	  GdkRectangle new_area;
+	  
+	  restrict_area.x = widget->allocation.x + GTK_CONTAINER (widget)->border_width;
+	  restrict_area.y = widget->allocation.y + GTK_CONTAINER (widget)->border_width;
+	  restrict_area.width = widget->allocation.width - ( 2 * GTK_CONTAINER (widget)->border_width);
+	  restrict_area.height = widget->allocation.height - ( 2 * GTK_CONTAINER (widget)->border_width);
+
+	  if (gdk_rectangle_intersect (area, &restrict_area, &new_area))
+	    {
+	      gtk_paint_flat_box(widget->style, widget->window, GTK_STATE_PRELIGHT,
+				   GTK_SHADOW_ETCHED_OUT,
+				   area, widget, "radiobutton",
+				   new_area.x, new_area.y,
+				   new_area.width, new_area.height);
+	    }
 	}
       
       x = widget->allocation.x + indicator_spacing + GTK_CONTAINER (widget)->border_width;
@@ -632,16 +628,28 @@ gtk_radio_button_draw_indicator (GtkChec
 
       if (!interior_focus)
 	x += focus_width + focus_pad;      
-      
-      state_type = GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE ? GTK_STATE_NORMAL : GTK_WIDGET_STATE (widget);
-      if (GTK_TOGGLE_BUTTON (widget)->active)
-	shadow_type = GTK_SHADOW_IN;
+
+      if (toggle_button->inconsistent)
+	{
+	  shadow_type = GTK_SHADOW_ETCHED_IN;
+	  state_type = GTK_WIDGET_STATE (widget);
+	}
+      else if (toggle_button->active)
+	{
+	  shadow_type = GTK_SHADOW_IN;
+	  if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE)
+	    state_type = GTK_STATE_NORMAL;
+	  else if (GTK_WIDGET_STATE (widget) == GTK_STATE_NORMAL)
+	    state_type = GTK_STATE_ACTIVE;
+	  else
+	    state_type = GTK_WIDGET_STATE (widget);
+	}
       else
-	shadow_type = GTK_SHADOW_OUT;
+	{
+	  shadow_type = GTK_SHADOW_OUT;
+	  state_type = GTK_WIDGET_STATE (widget);
+	}
 
-      if (GTK_TOGGLE_BUTTON (widget)->inconsistent)
-        shadow_type = GTK_SHADOW_ETCHED_IN;
-      
       if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
 	x = widget->allocation.x + widget->allocation.width - (indicator_size + x - widget->allocation.x);
 
Index: gtk/gtktogglebutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktogglebutton.c,v
retrieving revision 1.45
diff -u -p -r1.45 gtktogglebutton.c
--- gtk/gtktogglebutton.c	2001/12/04 03:27:29	1.45
+++ gtk/gtktogglebutton.c	2001/12/04 18:00:13
@@ -450,8 +450,10 @@ gtk_toggle_button_update_state (GtkButto
       
   if (!button->button_down && button->in_button)
     new_state = GTK_STATE_PRELIGHT;
+  else if (depressed || (toggle_button->inconsistent && button->in_button && button->button_down))
+    new_state = GTK_STATE_ACTIVE;
   else
-    new_state = depressed ? GTK_STATE_ACTIVE: GTK_STATE_NORMAL;
+    new_state = GTK_STATE_NORMAL;
 
   _gtk_button_set_depressed (button, depressed); 
   gtk_widget_set_state (GTK_WIDGET (toggle_button), new_state);




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]