* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
+#include <config.h>
+#include "gtkalias.h"
#include "gtkframe.h"
#include "gtklabel.h"
-#include "gtksignal.h"
+#include "gtkmarshalers.h"
#include "gtkstatusbar.h"
#include "gtkwindow.h"
#include "gtkintl.h"
SIGNAL_LAST
};
-static void gtk_statusbar_class_init (GtkStatusbarClass *class);
-static void gtk_statusbar_init (GtkStatusbar *statusbar);
-static void gtk_statusbar_destroy (GtkObject *object);
-static void gtk_statusbar_update (GtkStatusbar *statusbar,
- guint context_id,
- const gchar *text);
-static void gtk_statusbar_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-static void gtk_statusbar_realize (GtkWidget *widget);
-static void gtk_statusbar_unrealize (GtkWidget *widget);
-static void gtk_statusbar_map (GtkWidget *widget);
-static void gtk_statusbar_unmap (GtkWidget *widget);
-static gboolean gtk_statusbar_button_press (GtkWidget *widget,
- GdkEventButton *event);
-static gboolean gtk_statusbar_expose_event (GtkWidget *widget,
- GdkEventExpose *event);
-static void gtk_statusbar_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
-static void gtk_statusbar_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-static void gtk_statusbar_create_window (GtkStatusbar *statusbar);
-static void gtk_statusbar_destroy_window (GtkStatusbar *statusbar);
+enum
+{
+ PROP_ZERO,
+ PROP_HAS_RESIZE_GRIP
+};
+
+static void gtk_statusbar_class_init (GtkStatusbarClass *class);
+static void gtk_statusbar_init (GtkStatusbar *statusbar);
+static void gtk_statusbar_destroy (GtkObject *object);
+static void gtk_statusbar_update (GtkStatusbar *statusbar,
+ guint context_id,
+ const gchar *text);
+static void gtk_statusbar_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static void gtk_statusbar_realize (GtkWidget *widget);
+static void gtk_statusbar_unrealize (GtkWidget *widget);
+static void gtk_statusbar_map (GtkWidget *widget);
+static void gtk_statusbar_unmap (GtkWidget *widget);
+static gboolean gtk_statusbar_button_press (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean gtk_statusbar_expose_event (GtkWidget *widget,
+ GdkEventExpose *event);
+static void gtk_statusbar_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void gtk_statusbar_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static void gtk_statusbar_direction_changed (GtkWidget *widget,
+ GtkTextDirection prev_dir);
+static void gtk_statusbar_create_window (GtkStatusbar *statusbar);
+static void gtk_statusbar_destroy_window (GtkStatusbar *statusbar);
+static void gtk_statusbar_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gtk_statusbar_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
static GtkContainerClass *parent_class;
static guint statusbar_signals[SIGNAL_LAST] = { 0 };
-GtkType
+GType
gtk_statusbar_get_type (void)
{
- static GtkType statusbar_type = 0;
+ static GType statusbar_type = 0;
if (!statusbar_type)
{
- static const GtkTypeInfo statusbar_info =
+ static const GTypeInfo statusbar_info =
{
- "GtkStatusbar",
- sizeof (GtkStatusbar),
sizeof (GtkStatusbarClass),
- (GtkClassInitFunc) gtk_statusbar_class_init,
- (GtkObjectInitFunc) gtk_statusbar_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) gtk_statusbar_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GtkStatusbar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gtk_statusbar_init,
};
- statusbar_type = gtk_type_unique (GTK_TYPE_HBOX, &statusbar_info);
+ statusbar_type = g_type_register_static (GTK_TYPE_HBOX, "GtkStatusbar",
+ &statusbar_info, 0);
}
return statusbar_type;
static void
gtk_statusbar_class_init (GtkStatusbarClass *class)
{
+ GObjectClass *gobject_class;
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
+ gobject_class = (GObjectClass *) class;
object_class = (GtkObjectClass *) class;
widget_class = (GtkWidgetClass *) class;
container_class = (GtkContainerClass *) class;
- parent_class = gtk_type_class (GTK_TYPE_HBOX);
+ parent_class = g_type_class_peek_parent (class);
+ gobject_class->set_property = gtk_statusbar_set_property;
+ gobject_class->get_property = gtk_statusbar_get_property;
+
object_class->destroy = gtk_statusbar_destroy;
widget_class->realize = gtk_statusbar_realize;
widget_class->size_request = gtk_statusbar_size_request;
widget_class->size_allocate = gtk_statusbar_size_allocate;
+
+ widget_class->direction_changed = gtk_statusbar_direction_changed;
- class->messages_mem_chunk = g_mem_chunk_new ("GtkStatusBar messages mem chunk",
+ class->messages_mem_chunk = g_mem_chunk_new ("GtkStatusbar messages mem chunk",
sizeof (GtkStatusbarMsg),
sizeof (GtkStatusbarMsg) * 64,
G_ALLOC_AND_FREE);
class->text_pushed = gtk_statusbar_update;
class->text_popped = gtk_statusbar_update;
+ /**
+ * GtkStatusbar:has-resize-grip:
+ *
+ * Whether the statusbar has a grip for resizing the toplevel window.
+ *
+ * Since: 2.4
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_HAS_RESIZE_GRIP,
+ g_param_spec_boolean ("has_resize_grip",
+ P_("Has Resize Grip"),
+ P_("Whether the statusbar has a grip for resizing the toplevel"),
+ TRUE,
+ G_PARAM_READWRITE));
statusbar_signals[SIGNAL_TEXT_PUSHED] =
- gtk_signal_new ("text_pushed",
- GTK_RUN_LAST,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkStatusbarClass, text_pushed),
- gtk_marshal_VOID__UINT_STRING,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_UINT,
- GTK_TYPE_STRING);
+ g_signal_new ("text_pushed",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkStatusbarClass, text_pushed),
+ NULL, NULL,
+ _gtk_marshal_VOID__UINT_STRING,
+ G_TYPE_NONE, 2,
+ G_TYPE_UINT,
+ G_TYPE_STRING);
statusbar_signals[SIGNAL_TEXT_POPPED] =
- gtk_signal_new ("text_popped",
- GTK_RUN_LAST,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkStatusbarClass, text_popped),
- gtk_marshal_VOID__UINT_STRING,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_UINT,
- GTK_TYPE_STRING);
+ g_signal_new ("text_popped",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkStatusbarClass, text_popped),
+ NULL, NULL,
+ _gtk_marshal_VOID__UINT_STRING,
+ G_TYPE_NONE, 2,
+ G_TYPE_UINT,
+ G_TYPE_STRING);
gtk_widget_class_install_style_property (widget_class,
g_param_spec_enum ("shadow_type",
- _("Shadow type"),
- _("Style of bevel around the statusbar text"),
+ P_("Shadow type"),
+ P_("Style of bevel around the statusbar text"),
GTK_TYPE_SHADOW_TYPE,
GTK_SHADOW_IN,
G_PARAM_READABLE));
gtk_widget_show (statusbar->frame);
statusbar->label = gtk_label_new ("");
- gtk_misc_set_alignment (GTK_MISC (statusbar->label), 0.0, 0.0);
+ gtk_label_set_single_line_mode (GTK_LABEL (statusbar->label), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (statusbar->label), 0.0, 0.5);
/* don't expand the size request for the label; if we
* do that then toplevels weirdly resize
*/
- gtk_widget_set_usize (statusbar->label, 1, -1);
+ gtk_widget_set_size_request (statusbar->label, 1, -1);
gtk_container_add (GTK_CONTAINER (statusbar->frame), statusbar->label);
gtk_widget_show (statusbar->label);
GtkWidget*
gtk_statusbar_new (void)
{
- return gtk_type_new (GTK_TYPE_STATUSBAR);
+ return g_object_new (GTK_TYPE_STATUSBAR, NULL);
}
static void
guint context_id,
const gchar *text)
{
- g_return_if_fail (statusbar != NULL);
g_return_if_fail (GTK_IS_STATUSBAR (statusbar));
if (!text)
gchar *string;
guint *id;
- g_return_val_if_fail (statusbar != NULL, 0);
g_return_val_if_fail (GTK_IS_STATUSBAR (statusbar), 0);
g_return_val_if_fail (context_description != NULL, 0);
/* we need to preserve namespaces on object datas */
string = g_strconcat ("gtk-status-bar-context:", context_description, NULL);
- id = gtk_object_get_data (GTK_OBJECT (statusbar), string);
+ id = g_object_get_data (G_OBJECT (statusbar), string);
if (!id)
{
id = g_new (guint, 1);
*id = statusbar->seq_context_id++;
- gtk_object_set_data_full (GTK_OBJECT (statusbar), string, id, (GtkDestroyNotify) g_free);
+ g_object_set_data_full (G_OBJECT (statusbar), string, id, g_free);
statusbar->keys = g_slist_prepend (statusbar->keys, string);
}
else
GtkStatusbarMsg *msg;
GtkStatusbarClass *class;
- g_return_val_if_fail (statusbar != NULL, 0);
g_return_val_if_fail (GTK_IS_STATUSBAR (statusbar), 0);
g_return_val_if_fail (text != NULL, 0);
statusbar->messages = g_slist_prepend (statusbar->messages, msg);
- gtk_signal_emit (GTK_OBJECT (statusbar),
- statusbar_signals[SIGNAL_TEXT_PUSHED],
- msg->context_id,
- msg->text);
+ g_signal_emit (statusbar,
+ statusbar_signals[SIGNAL_TEXT_PUSHED],
+ 0,
+ msg->context_id,
+ msg->text);
return msg->message_id;
}
{
GtkStatusbarMsg *msg;
- g_return_if_fail (statusbar != NULL);
g_return_if_fail (GTK_IS_STATUSBAR (statusbar));
if (statusbar->messages)
msg = statusbar->messages ? statusbar->messages->data : NULL;
- gtk_signal_emit (GTK_OBJECT (statusbar),
- statusbar_signals[SIGNAL_TEXT_POPPED],
- (guint) (msg ? msg->context_id : 0),
- msg ? msg->text : NULL);
+ g_signal_emit (statusbar,
+ statusbar_signals[SIGNAL_TEXT_POPPED],
+ 0,
+ (guint) (msg ? msg->context_id : 0),
+ msg ? msg->text : NULL);
}
void
{
GtkStatusbarMsg *msg;
- g_return_if_fail (statusbar != NULL);
g_return_if_fail (GTK_IS_STATUSBAR (statusbar));
g_return_if_fail (message_id > 0);
if (GTK_WIDGET_REALIZED (statusbar))
{
if (statusbar->has_resize_grip && statusbar->grip_window == NULL)
- gtk_statusbar_create_window (statusbar);
+ {
+ gtk_statusbar_create_window (statusbar);
+ gdk_window_show (statusbar->grip_window);
+ }
else if (!statusbar->has_resize_grip && statusbar->grip_window != NULL)
gtk_statusbar_destroy_window (statusbar);
}
+
+ g_object_notify (G_OBJECT (statusbar), "has_resize_grip");
}
}
GtkStatusbarClass *class;
GSList *list;
- g_return_if_fail (object != NULL);
g_return_if_fail (GTK_IS_STATUSBAR (object));
statusbar = GTK_STATUSBAR (object);
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
+static void
+gtk_statusbar_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkStatusbar *statusbar = GTK_STATUSBAR (object);
+
+ switch (prop_id)
+ {
+ case PROP_HAS_RESIZE_GRIP:
+ gtk_statusbar_set_has_resize_grip (statusbar, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_statusbar_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkStatusbar *statusbar = GTK_STATUSBAR (object);
+
+ switch (prop_id)
+ {
+ case PROP_HAS_RESIZE_GRIP:
+ g_value_set_boolean (value, statusbar->has_resize_grip);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static GdkWindowEdge
+get_grip_edge (GtkStatusbar *statusbar)
+{
+ GtkWidget *widget = GTK_WIDGET (statusbar);
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+ return GDK_WINDOW_EDGE_SOUTH_EAST;
+ else
+ return GDK_WINDOW_EDGE_SOUTH_WEST;
+}
+
static void
get_grip_rect (GtkStatusbar *statusbar,
GdkRectangle *rect)
w = 18;
h = 18;
- if (w > (widget->allocation.width))
+ if (w > widget->allocation.width)
w = widget->allocation.width;
- if (h > (widget->allocation.height - widget->style->ythickness))
+ if (h > widget->allocation.height - widget->style->ythickness)
h = widget->allocation.height - widget->style->ythickness;
- rect->x = widget->allocation.x + widget->allocation.width - w;
- rect->y = widget->allocation.y + widget->allocation.height - h;
rect->width = w;
rect->height = h;
+ rect->y = widget->allocation.y + widget->allocation.height - h;
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+ rect->x = widget->allocation.x + widget->allocation.width - w;
+ else
+ rect->x = widget->allocation.x + widget->style->xthickness;
+}
+
+static void
+set_grip_cursor (GtkStatusbar *statusbar)
+{
+ if (statusbar->has_resize_grip)
+ {
+ GtkWidget *widget = GTK_WIDGET (statusbar);
+ GdkDisplay *display = gtk_widget_get_display (widget);
+ GdkCursorType cursor_type;
+ GdkCursor *cursor;
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+ cursor_type = GDK_BOTTOM_RIGHT_CORNER;
+ else
+ cursor_type = GDK_BOTTOM_LEFT_CORNER;
+
+ cursor = gdk_cursor_new_for_display (display, cursor_type);
+ gdk_window_set_cursor (statusbar->grip_window, cursor);
+ gdk_cursor_unref (cursor);
+ }
}
static void
statusbar->grip_window = gdk_window_new (widget->window,
&attributes, attributes_mask);
+
gdk_window_set_user_data (statusbar->grip_window, widget);
+
+ set_grip_cursor (statusbar);
+}
+
+static void
+gtk_statusbar_direction_changed (GtkWidget *widget,
+ GtkTextDirection prev_dir)
+{
+ GtkStatusbar *statusbar = GTK_STATUSBAR (widget);
+
+ set_grip_cursor (statusbar);
}
static void
{
GtkStatusbar *statusbar;
GtkWidget *ancestor;
+ GdkWindowEdge edge;
statusbar = GTK_STATUSBAR (widget);
- if (!statusbar->has_resize_grip)
+ if (!statusbar->has_resize_grip ||
+ event->type != GDK_BUTTON_PRESS)
return FALSE;
ancestor = gtk_widget_get_toplevel (widget);
if (!GTK_IS_WINDOW (ancestor))
return FALSE;
+ edge = get_grip_edge (statusbar);
+
if (event->button == 1)
gtk_window_begin_resize_drag (GTK_WINDOW (ancestor),
- GDK_WINDOW_EDGE_SOUTH_EAST,
+ edge,
event->button,
event->x_root, event->y_root,
event->time);
if (statusbar->has_resize_grip)
{
+ GdkWindowEdge edge;
+
+ edge = get_grip_edge (statusbar);
+
get_grip_rect (statusbar, &rect);
gtk_paint_resize_grip (widget->style,
NULL,
widget,
"statusbar",
- GDK_WINDOW_EDGE_SOUTH_EAST,
+ edge,
rect.x, rect.y,
/* don't draw grip over the frame, though you
* can click on the frame.
gtk_frame_set_shadow_type (GTK_FRAME (statusbar->frame), shadow_type);
GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
-
- if (statusbar->has_resize_grip)
- {
- GdkRectangle rect;
-
- /* x, y in the grip rect depend on size allocation, but
- * w, h do not so this is OK
- */
- get_grip_rect (statusbar, &rect);
-
- requisition->width += rect.width;
- requisition->height = MAX (requisition->height, rect.height);
- }
}
static void
statusbar = GTK_STATUSBAR (widget);
- if (statusbar->has_resize_grip)
+ /* chain up normally */
+ GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
+
+ if (statusbar->has_resize_grip && statusbar->grip_window)
{
GdkRectangle rect;
- GtkAllocation hbox_allocation;
- GtkRequisition saved_req;
- widget->allocation = *allocation; /* get_grip_rect needs this info */
get_grip_rect (statusbar, &rect);
- if (statusbar->grip_window)
gdk_window_move_resize (statusbar->grip_window,
rect.x, rect.y,
rect.width, rect.height);
-
- /* enter the bad hack zone */
- saved_req = widget->requisition;
- widget->requisition.width -= rect.width; /* HBox::size_allocate needs this */
- if (widget->requisition.width < 0)
- widget->requisition.width = 0;
- GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
- widget->requisition = saved_req;
- }
- else
- {
- /* chain up normally */
- GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
}
}
+