[gtk-list] My problem with labels



is still unresolved, I have a (very long) test case here if anyone feels up
to debugging it.  It's GtkButton with the function names and stuff renamed
to OrchidCellbox.  That, and a short main proceedure at the end.  It works
fine with gtk+-971109 but with gtk+-0.99.0 the label doesn't appear.

I spliced the .h file in too, it's boundaries should be fairly evident.

GtkButtons work.

Any clues?

(I'll try and cut the example size down some, but thought it wouldn't
hurt too much to post this until I can figure out how, 'cause frankly,
I've got no clue :)
------------------------------------------------------------------------------
#ifndef __ORCHID_CELLBOX_H__
#define __ORCHID_CELLBOX_H__


#include <gdk/gdk.h>
#include <gtk/gtkcontainer.h>


#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */


#define ORCHID_CELLBOX(obj)          GTK_CHECK_CAST (obj, orchid_cellbox_get_type (), OrchidCellbox)
#define ORCHID_CELLBOX_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, orchid_cellbox_get_type (), OrchidCellboxClass)
#define ORCHID_IS_CELLBOX(obj)       GTK_CHECK_TYPE (obj, orchid_cellbox_get_type ())


typedef struct _OrchidCellbox       OrchidCellbox;
typedef struct _OrchidCellboxClass  OrchidCellboxClass;

struct _OrchidCellbox
{
  GtkContainer container;

  GtkWidget *child;

  guint in_cellbox : 1;
  guint cellbox_down : 1;
};

struct _OrchidCellboxClass
{
  GtkContainerClass parent_class;

  void (* pressed)  (OrchidCellbox *cellbox);
  void (* released) (OrchidCellbox *cellbox);
  void (* clicked)  (OrchidCellbox *cellbox);
  void (* enter)    (OrchidCellbox *cellbox);
  void (* leave)    (OrchidCellbox *cellbox);
};


guint      orchid_cellbox_get_type       (void);
GtkWidget* orchid_cellbox_new            (void);
GtkWidget* orchid_cellbox_new_with_label (const gchar *label);
void       orchid_cellbox_pressed        (OrchidCellbox *cellbox);
void       orchid_cellbox_released       (OrchidCellbox *cellbox);
void       orchid_cellbox_clicked        (OrchidCellbox *cellbox);
void       orchid_cellbox_enter          (OrchidCellbox *cellbox);
void       orchid_cellbox_leave          (OrchidCellbox *cellbox);


#ifdef __cplusplus
}
#endif /* __cplusplus */


#endif /* __ORCHID_CELLBOX_H__ */

#include <gtk/gtk.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkmain.h>
#include <gtk/gtksignal.h>

#define CHILD_SPACING     1
#define DEFAULT_LEFT_POS  4
#define DEFAULT_TOP_POS   4
#define DEFAULT_SPACING   7


enum
  {
    PRESSED,
    RELEASED,
    CLICKED,
    ENTER,
    LEAVE,
    LAST_SIGNAL
  };


static void orchid_cellbox_class_init (OrchidCellboxClass * klass);
static void orchid_cellbox_init (OrchidCellbox * cellbox);
static void orchid_cellbox_arg (OrchidCellbox * cellbox,
				GtkArg * arg);
static void orchid_cellbox_destroy (GtkObject * object);
static void orchid_cellbox_map (GtkWidget * widget);
static void orchid_cellbox_unmap (GtkWidget * widget);
static void orchid_cellbox_realize (GtkWidget * widget);
static void orchid_cellbox_size_request (GtkWidget * widget,
					 GtkRequisition * requisition);
static void orchid_cellbox_size_allocate (GtkWidget * widget,
					  GtkAllocation * allocation);
static void orchid_cellbox_paint (GtkWidget * widget,
				  GdkRectangle * area);
static void orchid_cellbox_draw (GtkWidget * widget,
				 GdkRectangle * area);
static void orchid_cellbox_draw_focus (GtkWidget * widget);
static void orchid_cellbox_draw_default (GtkWidget * widget);
static gint orchid_cellbox_expose (GtkWidget * widget,
				   GdkEventExpose * event);
static gint orchid_cellbox_button_press (GtkWidget * widget,
					 GdkEventButton * event);
static gint orchid_cellbox_button_release (GtkWidget * widget,
					   GdkEventButton * event);
static gint orchid_cellbox_enter_notify (GtkWidget * widget,
					 GdkEventCrossing * event);
static gint orchid_cellbox_leave_notify (GtkWidget * widget,
					 GdkEventCrossing * event);
static gint orchid_cellbox_focus_in (GtkWidget * widget,
				     GdkEventFocus * event);
static gint orchid_cellbox_focus_out (GtkWidget * widget,
				      GdkEventFocus * event);
static void orchid_cellbox_add (GtkContainer * container,
				GtkWidget * widget);
static void orchid_cellbox_remove (GtkContainer * container,
				   GtkWidget * widget);
static void orchid_cellbox_foreach (GtkContainer * container,
				    GtkCallback callback,
				    gpointer callback_data);
static void gtk_real_cellbox_pressed (OrchidCellbox * cellbox);
static void gtk_real_cellbox_released (OrchidCellbox * cellbox);
static void gtk_real_cellbox_enter (OrchidCellbox * cellbox);
static void gtk_real_cellbox_leave (OrchidCellbox * cellbox);


static GtkContainerClass *parent_class;
static gint cellbox_signals[LAST_SIGNAL] =
{0};


guint
orchid_cellbox_get_type ()
{
  static guint cellbox_type = 0;

  if (!cellbox_type)
    {
      GtkTypeInfo cellbox_info =
      {
	"OrchidCellbox",
	sizeof (OrchidCellbox),
	sizeof (OrchidCellboxClass),
	(GtkClassInitFunc) orchid_cellbox_class_init,
	(GtkObjectInitFunc) orchid_cellbox_init,
	(GtkArgFunc) orchid_cellbox_arg,
      };

      cellbox_type = gtk_type_unique (gtk_container_get_type (), &cellbox_info);
    }

  return cellbox_type;
}

static void
orchid_cellbox_class_init (OrchidCellboxClass * klass)
{
  GtkObjectClass *object_class;
  GtkWidgetClass *widget_class;
  GtkContainerClass *container_class;

  object_class = (GtkObjectClass *) klass;
  widget_class = (GtkWidgetClass *) klass;
  container_class = (GtkContainerClass *) klass;

  parent_class = gtk_type_class (gtk_container_get_type ());

  gtk_object_add_arg_type ("OrchidCellbox::label", GTK_TYPE_STRING);

  cellbox_signals[PRESSED] =
    gtk_signal_new ("pressed",
		    GTK_RUN_FIRST,
		    object_class->type,
		    GTK_SIGNAL_OFFSET (OrchidCellboxClass, pressed),
		    gtk_signal_default_marshaller,
		    GTK_TYPE_NONE, 0);
  cellbox_signals[RELEASED] =
    gtk_signal_new ("released",
		    GTK_RUN_FIRST,
		    object_class->type,
		    GTK_SIGNAL_OFFSET (OrchidCellboxClass, released),
		    gtk_signal_default_marshaller,
		    GTK_TYPE_NONE, 0);
  cellbox_signals[CLICKED] =
    gtk_signal_new ("clicked",
		    GTK_RUN_FIRST,
		    object_class->type,
		    GTK_SIGNAL_OFFSET (OrchidCellboxClass, clicked),
		    gtk_signal_default_marshaller,
		    GTK_TYPE_NONE, 0);
  cellbox_signals[ENTER] =
    gtk_signal_new ("enter",
		    GTK_RUN_FIRST,
		    object_class->type,
		    GTK_SIGNAL_OFFSET (OrchidCellboxClass, enter),
		    gtk_signal_default_marshaller,
		    GTK_TYPE_NONE, 0);
  cellbox_signals[LEAVE] =
    gtk_signal_new ("leave",
		    GTK_RUN_FIRST,
		    object_class->type,
		    GTK_SIGNAL_OFFSET (OrchidCellboxClass, leave),
		    gtk_signal_default_marshaller,
		    GTK_TYPE_NONE, 0);

  gtk_object_class_add_signals (object_class, cellbox_signals, LAST_SIGNAL);

  object_class->destroy = orchid_cellbox_destroy;

  widget_class->activate_signal = cellbox_signals[CLICKED];
  widget_class->map = orchid_cellbox_map;
  widget_class->unmap = orchid_cellbox_unmap;
  widget_class->realize = orchid_cellbox_realize;
  widget_class->draw = orchid_cellbox_draw;
  widget_class->draw_focus = orchid_cellbox_draw_focus;
  widget_class->draw_default = orchid_cellbox_draw_default;
  widget_class->size_request = orchid_cellbox_size_request;
  widget_class->size_allocate = orchid_cellbox_size_allocate;
  widget_class->expose_event = orchid_cellbox_expose;
  widget_class->button_press_event = orchid_cellbox_button_press;
  widget_class->button_release_event = orchid_cellbox_button_release;
  widget_class->enter_notify_event = orchid_cellbox_enter_notify;
  widget_class->leave_notify_event = orchid_cellbox_leave_notify;
  widget_class->focus_in_event = orchid_cellbox_focus_in;
  widget_class->focus_out_event = orchid_cellbox_focus_out;

  container_class->add = orchid_cellbox_add;
  container_class->remove = orchid_cellbox_remove;
  container_class->foreach = orchid_cellbox_foreach;

  klass->pressed = gtk_real_cellbox_pressed;
  klass->released = gtk_real_cellbox_released;
  klass->clicked = NULL;
  klass->enter = gtk_real_cellbox_enter;
  klass->leave = gtk_real_cellbox_leave;
}

static void
orchid_cellbox_init (OrchidCellbox * cellbox)
{
  GTK_WIDGET_SET_FLAGS (cellbox, GTK_CAN_FOCUS);

  cellbox->child = NULL;
  cellbox->in_cellbox = FALSE;
  cellbox->cellbox_down = FALSE;
}

static void
orchid_cellbox_arg (OrchidCellbox * cellbox,
		    GtkArg * arg)
{
  if (strcmp (arg->name, "label") == 0)
    {
      GtkWidget *label;

      gtk_container_disable_resize (GTK_CONTAINER (cellbox));

      if (cellbox->child)
	gtk_widget_destroy (cellbox->child);

      label = gtk_label_new (GTK_VALUE_STRING (*arg));
      gtk_widget_show (label);

      gtk_container_add (GTK_CONTAINER (cellbox), label);
      gtk_container_enable_resize (GTK_CONTAINER (cellbox));
    }
}

GtkWidget *
orchid_cellbox_new ()
{
  return GTK_WIDGET (gtk_type_new (orchid_cellbox_get_type ()));
}

GtkWidget *
orchid_cellbox_new_with_label (const gchar * label)
{
  GtkWidget *cellbox;
  GtkWidget *label_widget;

  cellbox = orchid_cellbox_new ();
  label_widget = gtk_label_new (label);
  gtk_misc_set_alignment (GTK_MISC (label_widget), 0.5, 0.5);

  gtk_container_add (GTK_CONTAINER (cellbox), label_widget);
  gtk_widget_show (label_widget);

  return cellbox;
}

void
orchid_cellbox_pressed (OrchidCellbox * cellbox)
{
  gtk_signal_emit (GTK_OBJECT (cellbox), cellbox_signals[PRESSED]);
}

void
orchid_cellbox_released (OrchidCellbox * cellbox)
{
  gtk_signal_emit (GTK_OBJECT (cellbox), cellbox_signals[RELEASED]);
}

void
orchid_cellbox_clicked (OrchidCellbox * cellbox)
{
  gtk_signal_emit (GTK_OBJECT (cellbox), cellbox_signals[CLICKED]);
}

void
orchid_cellbox_enter (OrchidCellbox * cellbox)
{
  gtk_signal_emit (GTK_OBJECT (cellbox), cellbox_signals[ENTER]);
}

void
orchid_cellbox_leave (OrchidCellbox * cellbox)
{
  gtk_signal_emit (GTK_OBJECT (cellbox), cellbox_signals[LEAVE]);
}

static void
orchid_cellbox_destroy (GtkObject * object)
{
  OrchidCellbox *cellbox;

  g_return_if_fail (object != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (object));

  cellbox = ORCHID_CELLBOX (object);

  if (cellbox->child)
    {
      cellbox->child->parent = NULL;
      gtk_object_unref (GTK_OBJECT (cellbox->child));
      gtk_widget_destroy (cellbox->child);
    }

  if (GTK_OBJECT_CLASS (parent_class)->destroy)
    (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}

static void
orchid_cellbox_map (GtkWidget * widget)
{
  OrchidCellbox *cellbox;

  g_return_if_fail (widget != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (widget));

  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
  gdk_window_show (widget->window);

  cellbox = ORCHID_CELLBOX (widget);

  if (cellbox->child &&
      GTK_WIDGET_VISIBLE (cellbox->child) &&
      !GTK_WIDGET_MAPPED (cellbox->child))
    gtk_widget_map (cellbox->child);
}

static void
orchid_cellbox_unmap (GtkWidget * widget)
{
  g_return_if_fail (widget != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (widget));

  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
  gdk_window_hide (widget->window);
}

static void
orchid_cellbox_realize (GtkWidget * widget)
{
  OrchidCellbox *cellbox;
  GdkWindowAttr attributes;
  gint attributes_mask;

  g_return_if_fail (widget != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (widget));

  cellbox = ORCHID_CELLBOX (widget);
  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);

  attributes.window_type = GDK_WINDOW_CHILD;
  attributes.x = widget->allocation.x;
  attributes.y = widget->allocation.y;
  attributes.width = widget->allocation.width;
  attributes.height = widget->allocation.height;
  attributes.wclass = GDK_INPUT_OUTPUT;
  attributes.visual = gtk_widget_get_visual (widget);
  attributes.colormap = gtk_widget_get_colormap (widget);
  attributes.event_mask = gtk_widget_get_events (widget);
  attributes.event_mask |= (GDK_EXPOSURE_MASK |
			    GDK_BUTTON_PRESS_MASK |
			    GDK_BUTTON_RELEASE_MASK |
			    GDK_ENTER_NOTIFY_MASK |
			    GDK_LEAVE_NOTIFY_MASK);

  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;

  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
  gdk_window_set_user_data (widget->window, cellbox);

  widget->style = gtk_style_attach (widget->style, widget->window);
  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
}

static void
orchid_cellbox_size_request (GtkWidget * widget,
			     GtkRequisition * requisition)
{
  OrchidCellbox *cellbox;

  g_return_if_fail (widget != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (widget));
  g_return_if_fail (requisition != NULL);

  cellbox = ORCHID_CELLBOX (widget);

  requisition->width = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING +
			GTK_WIDGET (widget)->style->klass->xthickness) * 2;
  requisition->height = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING +
			 GTK_WIDGET (widget)->style->klass->ythickness) * 2;

  if (GTK_WIDGET_CAN_DEFAULT (widget))
    {
      requisition->width += (GTK_WIDGET (widget)->style->klass->xthickness * 2 +
			     DEFAULT_SPACING);
      requisition->height += (GTK_WIDGET (widget)->style->klass->ythickness * 2 +
			      DEFAULT_SPACING);
    }

  if (cellbox->child && GTK_WIDGET_VISIBLE (cellbox->child))
    {
      gtk_widget_size_request (cellbox->child, &cellbox->child->requisition);

      requisition->width += cellbox->child->requisition.width;
      requisition->height += cellbox->child->requisition.height;
    }
}

static void
orchid_cellbox_size_allocate (GtkWidget * widget,
			      GtkAllocation * allocation)
{
  OrchidCellbox *cellbox;
  GtkAllocation child_allocation;
  gint border_width;

  g_return_if_fail (widget != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (widget));
  g_return_if_fail (allocation != NULL);

  widget->allocation = *allocation;
  border_width = GTK_CONTAINER (widget)->border_width;

  if (GTK_WIDGET_REALIZED (widget))
    gdk_window_move_resize (widget->window,
			    widget->allocation.x + border_width,
			    widget->allocation.y + border_width,
			    widget->allocation.width - border_width * 2,
			    widget->allocation.height - border_width * 2);

  cellbox = ORCHID_CELLBOX (widget);

  if (cellbox->child && GTK_WIDGET_VISIBLE (cellbox->child))
    {
      child_allocation.x = (CHILD_SPACING + GTK_WIDGET (widget)->style->klass->xthickness);
      child_allocation.y = (CHILD_SPACING + GTK_WIDGET (widget)->style->klass->ythickness);

      child_allocation.width = widget->allocation.width - child_allocation.x * 2 -
	border_width * 2;
      child_allocation.height = widget->allocation.height - child_allocation.y * 2 -
	border_width * 2;

      if (GTK_WIDGET_CAN_DEFAULT (cellbox))
	{
	  child_allocation.x += (GTK_WIDGET (widget)->style->klass->xthickness +
				 DEFAULT_LEFT_POS);
	  child_allocation.y += (GTK_WIDGET (widget)->style->klass->ythickness +
				 DEFAULT_TOP_POS);
	  child_allocation.width -= (GTK_WIDGET (widget)->style->klass->xthickness * 2 +
				     DEFAULT_SPACING);
	  child_allocation.height -= (GTK_WIDGET (widget)->style->klass->xthickness * 2 +
				      DEFAULT_SPACING);
	}

      gtk_widget_size_allocate (cellbox->child, &child_allocation);
    }
}

static void
orchid_cellbox_paint (GtkWidget * widget,
		      GdkRectangle * area)
{
  GdkRectangle restrict_area;
  GdkRectangle new_area;

  g_return_if_fail (widget != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (widget));

  if (GTK_WIDGET_DRAWABLE (widget))
    {
      restrict_area.x = GTK_WIDGET (widget)->style->klass->xthickness;
      restrict_area.y = GTK_WIDGET (widget)->style->klass->ythickness;
      restrict_area.width = (GTK_WIDGET (widget)->allocation.width - restrict_area.x * 2 -
			     GTK_CONTAINER (widget)->border_width * 2);
      restrict_area.height = (GTK_WIDGET (widget)->allocation.height - restrict_area.y * 2 -
			      GTK_CONTAINER (widget)->border_width * 2);

      if (GTK_WIDGET_CAN_DEFAULT (widget))
	{
	  restrict_area.x += DEFAULT_LEFT_POS;
	  restrict_area.y += DEFAULT_TOP_POS;
	  restrict_area.width -= DEFAULT_SPACING;
	  restrict_area.height -= DEFAULT_SPACING;
	}

      if (gdk_rectangle_intersect (area, &restrict_area, &new_area))
	{
	  gtk_style_set_background (widget->style, widget->window, GTK_WIDGET_STATE (widget));
	  gdk_window_clear_area (widget->window,
				 new_area.x, new_area.y,
				 new_area.width, new_area.height);
	}
    }
}

static void
orchid_cellbox_draw (GtkWidget * widget,
		     GdkRectangle * area)
{
  OrchidCellbox *cellbox;
  GdkRectangle child_area;

  g_return_if_fail (widget != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (widget));
  g_return_if_fail (area != NULL);

  if (GTK_WIDGET_DRAWABLE (widget))
    {
      cellbox = ORCHID_CELLBOX (widget);

      orchid_cellbox_paint (widget, area);

      if (cellbox->child && gtk_widget_intersect (cellbox->child, area, &child_area))
	gtk_widget_draw (cellbox->child, &child_area);

      gtk_widget_draw_default (widget);
      gtk_widget_draw_focus (widget);
    }
}

static void
orchid_cellbox_draw_focus (GtkWidget * widget)
{
  OrchidCellbox *cellbox;
  GtkShadowType shadow_type;
  gint width, height;
  gint x, y;

  g_return_if_fail (widget != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (widget));

  if (GTK_WIDGET_DRAWABLE (widget))
    {
      cellbox = ORCHID_CELLBOX (widget);

      x = 0;
      y = 0;
      width = widget->allocation.width - GTK_CONTAINER (widget)->border_width * 2;
      height = widget->allocation.height - GTK_CONTAINER (widget)->border_width * 2;

      if (GTK_WIDGET_CAN_DEFAULT (widget))
	{
	  x += widget->style->klass->xthickness;
	  y += widget->style->klass->ythickness;
	  width -= 2 * x + DEFAULT_SPACING;
	  height -= 2 * y + DEFAULT_SPACING;
	  x += DEFAULT_LEFT_POS;
	  y += DEFAULT_TOP_POS;
	}

      if (GTK_WIDGET_HAS_FOCUS (widget))
	{
	  x += 1;
	  y += 1;
	  width -= 2;
	  height -= 2;
	}
      else
	{
	  if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE)
	    gdk_draw_rectangle (widget->window,
		     widget->style->bg_gc[GTK_WIDGET_STATE (widget)], FALSE,
				x + 1, y + 1, width - 4, height - 4);
	  else
	    gdk_draw_rectangle (widget->window,
		     widget->style->bg_gc[GTK_WIDGET_STATE (widget)], FALSE,
				x + 2, y + 2, width - 5, height - 5);
	}

      if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE)
	shadow_type = GTK_SHADOW_IN;
      else
	shadow_type = GTK_SHADOW_OUT;

      gtk_draw_shadow (widget->style, widget->window,
		       GTK_WIDGET_STATE (widget), shadow_type,
		       x, y, width, height);

      if (GTK_WIDGET_HAS_FOCUS (widget))
	{
	  x -= 1;
	  y -= 1;
	  width += 2;
	  height += 2;

	  gdk_draw_rectangle (widget->window,
			      widget->style->black_gc, FALSE,
			      x, y, width - 1, height - 1);
	}
    }
}

static void
orchid_cellbox_draw_default (GtkWidget * widget)
{
  gint width, height;
  gint x, y;

  g_return_if_fail (widget != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (widget));

  if (GTK_WIDGET_DRAWABLE (widget))
    {
      x = 0;
      y = 0;
      width = widget->allocation.width - GTK_CONTAINER (widget)->border_width * 2;
      height = widget->allocation.height - GTK_CONTAINER (widget)->border_width * 2;

      if (GTK_WIDGET_HAS_DEFAULT (widget))
	{
	  gtk_draw_shadow (widget->style, widget->window,
			   GTK_STATE_NORMAL, GTK_SHADOW_IN,
			   x, y, width, height);
	}
      else
	{
	  gdk_draw_rectangle (widget->window, widget->style->bg_gc[GTK_STATE_NORMAL],
			      FALSE, x, y, width - 1, height - 1);
	  gdk_draw_rectangle (widget->window, widget->style->bg_gc[GTK_STATE_NORMAL],
			      FALSE, x + 1, y + 1, width - 3, height - 3);
	}
    }
}

static gint
orchid_cellbox_expose (GtkWidget * widget,
		       GdkEventExpose * event)
{
  OrchidCellbox *cellbox;
  GdkEventExpose child_event;

  g_return_val_if_fail (widget != NULL, FALSE);
  g_return_val_if_fail (ORCHID_IS_CELLBOX (widget), FALSE);
  g_return_val_if_fail (event != NULL, FALSE);

  if (GTK_WIDGET_DRAWABLE (widget))
    {
      cellbox = ORCHID_CELLBOX (widget);

      orchid_cellbox_paint (widget, &event->area);

      child_event = *event;
      if (cellbox->child && GTK_WIDGET_NO_WINDOW (cellbox->child) &&
      gtk_widget_intersect (cellbox->child, &event->area, &child_event.area))
	gtk_widget_event (cellbox->child, (GdkEvent *) & child_event);

      gtk_widget_draw_default (widget);
      gtk_widget_draw_focus (widget);
    }

  return FALSE;
}

static gint
orchid_cellbox_button_press (GtkWidget * widget,
			     GdkEventButton * event)
{
  OrchidCellbox *cellbox;

  g_return_val_if_fail (widget != NULL, FALSE);
  g_return_val_if_fail (ORCHID_IS_CELLBOX (widget), FALSE);
  g_return_val_if_fail (event != NULL, FALSE);

  if (event->type == GDK_BUTTON_PRESS)
    {
      cellbox = ORCHID_CELLBOX (widget);

      if (GTK_WIDGET_CAN_DEFAULT (widget) && (event->button == 1))
	gtk_widget_grab_default (widget);
      if (!GTK_WIDGET_HAS_FOCUS (widget))
	gtk_widget_grab_focus (widget);

      if (event->button == 1)
	{
	  gtk_grab_add (GTK_WIDGET (cellbox));
	  orchid_cellbox_pressed (cellbox);
	}
    }

  return TRUE;
}

static gint
orchid_cellbox_button_release (GtkWidget * widget,
			       GdkEventButton * event)
{
  OrchidCellbox *cellbox;

  g_return_val_if_fail (widget != NULL, FALSE);
  g_return_val_if_fail (ORCHID_IS_CELLBOX (widget), FALSE);
  g_return_val_if_fail (event != NULL, FALSE);

  if (event->button == 1)
    {
      cellbox = ORCHID_CELLBOX (widget);
      gtk_grab_remove (GTK_WIDGET (cellbox));
      orchid_cellbox_released (cellbox);
    }

  return TRUE;
}

static gint
orchid_cellbox_enter_notify (GtkWidget * widget,
			     GdkEventCrossing * event)
{
  OrchidCellbox *cellbox;
  GtkWidget *event_widget;

  g_return_val_if_fail (widget != NULL, FALSE);
  g_return_val_if_fail (ORCHID_IS_CELLBOX (widget), FALSE);
  g_return_val_if_fail (event != NULL, FALSE);

  cellbox = ORCHID_CELLBOX (widget);
  event_widget = gtk_get_event_widget ((GdkEvent *) event);

  if ((event_widget == widget) &&
      (event->detail != GDK_NOTIFY_INFERIOR))
    {
      cellbox->in_cellbox = TRUE;
      orchid_cellbox_enter (cellbox);
    }

  return FALSE;
}

static gint
orchid_cellbox_leave_notify (GtkWidget * widget,
			     GdkEventCrossing * event)
{
  OrchidCellbox *cellbox;
  GtkWidget *event_widget;

  g_return_val_if_fail (widget != NULL, FALSE);
  g_return_val_if_fail (ORCHID_IS_CELLBOX (widget), FALSE);
  g_return_val_if_fail (event != NULL, FALSE);

  cellbox = ORCHID_CELLBOX (widget);
  event_widget = gtk_get_event_widget ((GdkEvent *) event);

  if ((event_widget == widget) &&
      (event->detail != GDK_NOTIFY_INFERIOR))
    {
      cellbox->in_cellbox = FALSE;
      orchid_cellbox_leave (cellbox);
    }

  return FALSE;
}

static gint
orchid_cellbox_focus_in (GtkWidget * widget,
			 GdkEventFocus * event)
{
  g_return_val_if_fail (widget != NULL, FALSE);
  g_return_val_if_fail (ORCHID_IS_CELLBOX (widget), FALSE);
  g_return_val_if_fail (event != NULL, FALSE);

  GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
  gtk_widget_draw_focus (widget);

  return FALSE;
}

static gint
orchid_cellbox_focus_out (GtkWidget * widget,
			  GdkEventFocus * event)
{
  g_return_val_if_fail (widget != NULL, FALSE);
  g_return_val_if_fail (ORCHID_IS_CELLBOX (widget), FALSE);
  g_return_val_if_fail (event != NULL, FALSE);

  GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
  gtk_widget_draw_focus (widget);

  return FALSE;
}

static void
orchid_cellbox_add (GtkContainer * container,
		    GtkWidget * widget)
{
  OrchidCellbox *cellbox;

  g_return_if_fail (container != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (container));
  g_return_if_fail (widget != NULL);
  g_return_if_fail (gtk_widget_basic (widget));

  cellbox = ORCHID_CELLBOX (container);

  if (!cellbox->child)
    {
      gtk_widget_set_parent (widget, GTK_WIDGET (container));

      if (GTK_WIDGET_VISIBLE (widget->parent))
	{
	  if (GTK_WIDGET_REALIZED (widget->parent) &&
	      !GTK_WIDGET_REALIZED (widget))
	    gtk_widget_realize (widget);

	  if (GTK_WIDGET_MAPPED (widget->parent) &&
	      !GTK_WIDGET_MAPPED (widget))
	    gtk_widget_map (widget);
	}

      cellbox->child = widget;

      if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
	gtk_widget_queue_resize (widget);
    }
}

static void
orchid_cellbox_remove (GtkContainer * container,
		       GtkWidget * widget)
{
  OrchidCellbox *cellbox;

  g_return_if_fail (container != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (container));

  cellbox = ORCHID_CELLBOX (container);

  if (cellbox->child == widget)
    {
      gtk_widget_unparent (widget);

      cellbox->child = NULL;

      if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
	gtk_widget_queue_resize (GTK_WIDGET (container));
    }
}

static void
orchid_cellbox_foreach (GtkContainer * container,
			GtkCallback callback,
			gpointer callback_data)
{
  OrchidCellbox *cellbox;

  g_return_if_fail (container != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (container));
  g_return_if_fail (callback != NULL);

  cellbox = ORCHID_CELLBOX (container);

  if (cellbox->child)
    (*callback) (cellbox->child, callback_data);
}

static void
gtk_real_cellbox_pressed (OrchidCellbox * cellbox)
{
  GtkStateType new_state;

  g_return_if_fail (cellbox != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (cellbox));

  cellbox->cellbox_down = TRUE;

  new_state = (cellbox->in_cellbox ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL);

  if (GTK_WIDGET_STATE (cellbox) != new_state)
    {
      gtk_widget_set_state (GTK_WIDGET (cellbox), new_state);
      gtk_widget_queue_draw (GTK_WIDGET (cellbox));
    }
}

static void
gtk_real_cellbox_released (OrchidCellbox * cellbox)
{
  GtkStateType new_state;

  g_return_if_fail (cellbox != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (cellbox));

  if (cellbox->cellbox_down)
    {
      cellbox->cellbox_down = FALSE;

      if (cellbox->in_cellbox)
	orchid_cellbox_clicked (cellbox);

      new_state = (cellbox->in_cellbox ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);

      if (GTK_WIDGET_STATE (cellbox) != new_state)
	{
	  gtk_widget_set_state (GTK_WIDGET (cellbox), new_state);
	  gtk_widget_queue_draw (GTK_WIDGET (cellbox));
	}
    }
}

static void
gtk_real_cellbox_enter (OrchidCellbox * cellbox)
{
  GtkStateType new_state;

  g_return_if_fail (cellbox != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (cellbox));

  new_state = (cellbox->cellbox_down ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT);

  if (GTK_WIDGET_STATE (cellbox) != new_state)
    {
      gtk_widget_set_state (GTK_WIDGET (cellbox), new_state);
      gtk_widget_queue_draw (GTK_WIDGET (cellbox));
    }
}

static void
gtk_real_cellbox_leave (OrchidCellbox * cellbox)
{
  g_return_if_fail (cellbox != NULL);
  g_return_if_fail (ORCHID_IS_CELLBOX (cellbox));

  if (GTK_WIDGET_STATE (cellbox) != GTK_STATE_NORMAL)
    {
      gtk_widget_set_state (GTK_WIDGET (cellbox), GTK_STATE_NORMAL);
      gtk_widget_queue_draw (GTK_WIDGET (cellbox));
    }
}

void
orchid_cellbox_deactivate (OrchidCellbox * cellbox)
{
}

void
orchid_cellbox_activate (OrchidCellbox * cellbox)
{
}

void
destroy (void)
{
  gtk_exit (0);
}
     
void
main (int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *sheet;
  GtkWidget *label;
  
  gtk_init (&argc, &argv);
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  gtk_signal_connect (GTK_OBJECT (window), "destroy_event",
     		      GTK_SIGNAL_FUNC (destroy), NULL);
  gtk_signal_connect (GTK_OBJECT (window), "delete_event",
     		      GTK_SIGNAL_FUNC (destroy), NULL);
  gtk_container_border_width (GTK_CONTAINER (window), 10);
  gtk_window_set_title (GTK_WINDOW(window), "Orchid");

  sheet = orchid_cellbox_new();

  label = gtk_label_new ("nothing");

  gtk_container_add (GTK_CONTAINER(sheet),label);

  gtk_widget_show (label);

  gtk_container_add (GTK_CONTAINER(window),sheet);
  
  gtk_widget_show (sheet);

  gtk_widget_show (window);
     
  gtk_main ();
     
  exit(0);
}



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