Commit f6f927d2 authored by Tim Janik's avatar Tim Janik Committed by Tim Janik

implemented the statusbar widget. my first intend was to fix the code, but

Mon Feb 23 13:44:10 1998  Tim Janik  <timj@gimp.org>

        * gtk/gtkstatusbar.h:
        * gtk/gtkstatusbar.c:
        (re-)implemented the statusbar widget. my first intend was to fix the
        code, but then there was nothing to fix - the whole thing was just a
        big JOKE!
        people who don't even know the semantics of the g_list_* functions
        shouldn't put their hands on widget code and inheritance!



this is the first step to get bug "BUG: statusbar/hbox (redraw?) problem"
worked out, i have to leave now, but will continue work on the resizing code
this evening.
parent 1b656e0d
Mon Feb 23 13:44:10 1998 Tim Janik <timj@gimp.org>
* gtk/gtkstatusbar.h:
* gtk/gtkstatusbar.c:
(re-)implemented the statusbar widget. my first intend was to fix the
code, but then there was nothing to fix - the whole thing was just a
big JOKE!
people who don't even know the semantics of the g_list_* functions
shouldn't put their hands on widget code and inheritance!
Sun Feb 22 20:42:04 1998 Marc Ewing <marc@redhat.com>
* gtk/gtkclist.c (gtk_clist_insert): Allow inserts
......
Mon Feb 23 13:44:10 1998 Tim Janik <timj@gimp.org>
* gtk/gtkstatusbar.h:
* gtk/gtkstatusbar.c:
(re-)implemented the statusbar widget. my first intend was to fix the
code, but then there was nothing to fix - the whole thing was just a
big JOKE!
people who don't even know the semantics of the g_list_* functions
shouldn't put their hands on widget code and inheritance!
Sun Feb 22 20:42:04 1998 Marc Ewing <marc@redhat.com>
* gtk/gtkclist.c (gtk_clist_insert): Allow inserts
......
Mon Feb 23 13:44:10 1998 Tim Janik <timj@gimp.org>
* gtk/gtkstatusbar.h:
* gtk/gtkstatusbar.c:
(re-)implemented the statusbar widget. my first intend was to fix the
code, but then there was nothing to fix - the whole thing was just a
big JOKE!
people who don't even know the semantics of the g_list_* functions
shouldn't put their hands on widget code and inheritance!
Sun Feb 22 20:42:04 1998 Marc Ewing <marc@redhat.com>
* gtk/gtkclist.c (gtk_clist_insert): Allow inserts
......
Mon Feb 23 13:44:10 1998 Tim Janik <timj@gimp.org>
* gtk/gtkstatusbar.h:
* gtk/gtkstatusbar.c:
(re-)implemented the statusbar widget. my first intend was to fix the
code, but then there was nothing to fix - the whole thing was just a
big JOKE!
people who don't even know the semantics of the g_list_* functions
shouldn't put their hands on widget code and inheritance!
Sun Feb 22 20:42:04 1998 Marc Ewing <marc@redhat.com>
* gtk/gtkclist.c (gtk_clist_insert): Allow inserts
......
Mon Feb 23 13:44:10 1998 Tim Janik <timj@gimp.org>
* gtk/gtkstatusbar.h:
* gtk/gtkstatusbar.c:
(re-)implemented the statusbar widget. my first intend was to fix the
code, but then there was nothing to fix - the whole thing was just a
big JOKE!
people who don't even know the semantics of the g_list_* functions
shouldn't put their hands on widget code and inheritance!
Sun Feb 22 20:42:04 1998 Marc Ewing <marc@redhat.com>
* gtk/gtkclist.c (gtk_clist_insert): Allow inserts
......
Mon Feb 23 13:44:10 1998 Tim Janik <timj@gimp.org>
* gtk/gtkstatusbar.h:
* gtk/gtkstatusbar.c:
(re-)implemented the statusbar widget. my first intend was to fix the
code, but then there was nothing to fix - the whole thing was just a
big JOKE!
people who don't even know the semantics of the g_list_* functions
shouldn't put their hands on widget code and inheritance!
Sun Feb 22 20:42:04 1998 Marc Ewing <marc@redhat.com>
* gtk/gtkclist.c (gtk_clist_insert): Allow inserts
......
Mon Feb 23 13:44:10 1998 Tim Janik <timj@gimp.org>
* gtk/gtkstatusbar.h:
* gtk/gtkstatusbar.c:
(re-)implemented the statusbar widget. my first intend was to fix the
code, but then there was nothing to fix - the whole thing was just a
big JOKE!
people who don't even know the semantics of the g_list_* functions
shouldn't put their hands on widget code and inheritance!
Sun Feb 22 20:42:04 1998 Marc Ewing <marc@redhat.com>
* gtk/gtkclist.c (gtk_clist_insert): Allow inserts
......
......@@ -19,14 +19,29 @@
#include "gtkframe.h"
#include "gtklabel.h"
#include "gtksignal.h"
#include "gtkstatusbar.h"
enum
{
SIGNAL_TEXT_PUSHED,
SIGNAL_TEXT_POPPED,
SIGNAL_LAST
};
typedef void (*SignalTextP) (GtkObject *object,
const gchar *text,
gpointer func_data);
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_show_top_msg (GtkStatusbar *statusbar);
static void gtk_statusbar_update (GtkStatusbar *statusbar,
const gchar *text);
static GtkContainerClass *parent_class;
static gint statusbar_signals[SIGNAL_LAST] = { 0 };
guint
gtk_statusbar_get_type ()
......@@ -52,6 +67,19 @@ gtk_statusbar_get_type ()
return statusbar_type;
};
static void
gtk_statusbar_marshal_text_p (GtkObject *object,
GtkSignalFunc func,
gpointer func_data,
GtkArg *args)
{
SignalTextP sfunc = (SignalTextP) func;
(* sfunc) (object,
GTK_VALUE_STRING (args[0]),
func_data);
}
static void
gtk_statusbar_class_init (GtkStatusbarClass *class)
{
......@@ -63,105 +91,196 @@ gtk_statusbar_class_init (GtkStatusbarClass *class)
widget_class = (GtkWidgetClass *) class;
container_class = (GtkContainerClass *) class;
parent_class = gtk_type_class (gtk_box_get_type ());
parent_class = gtk_type_class (gtk_hbox_get_type ());
statusbar_signals[SIGNAL_TEXT_PUSHED] =
gtk_signal_new ("text_pushed",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkStatusbarClass, text_pushed),
gtk_statusbar_marshal_text_p,
GTK_TYPE_NONE, 1,
GTK_TYPE_STRING);
statusbar_signals[SIGNAL_TEXT_POPPED] =
gtk_signal_new ("text_popped",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkStatusbarClass, text_popped),
gtk_statusbar_marshal_text_p,
GTK_TYPE_NONE, 1,
GTK_TYPE_STRING);
gtk_object_class_add_signals (object_class, statusbar_signals, SIGNAL_LAST);
object_class->destroy = gtk_statusbar_destroy;
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;
}
static void
gtk_statusbar_init (GtkStatusbar *statusbar)
{
GTK_BOX (statusbar)->spacing = 2;
GTK_BOX (statusbar)->homogeneous = FALSE;
GtkBox *box;
box = GTK_BOX (statusbar);
box->spacing = 2;
box->homogeneous = FALSE;
statusbar->frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (statusbar->frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (statusbar), statusbar->frame, 1, 1, 0);
gtk_box_pack_start (box, statusbar->frame, TRUE, TRUE, 0);
gtk_widget_show (statusbar->frame);
statusbar->label = gtk_label_new("");
gtk_misc_set_alignment(GTK_MISC(statusbar->label), 0.0, 0.0);
gtk_container_add(GTK_CONTAINER(statusbar->frame), statusbar->label);
statusbar->label = gtk_label_new ("");
gtk_misc_set_alignment (GTK_MISC (statusbar->label), 0.0, 0.0);
gtk_container_add (GTK_CONTAINER (statusbar->frame), statusbar->label);
gtk_widget_show (statusbar->label);
statusbar->next_statusid = 1;
statusbar->msgs = g_list_alloc();
statusbar->seq_status_id = 1;
statusbar->messages = NULL;
}
GtkWidget*
gtk_statusbar_new ()
{
GtkStatusbar *statusbar;
return gtk_type_new (gtk_statusbar_get_type ());
}
static void
gtk_statusbar_update (GtkStatusbar *statusbar,
const gchar *text)
{
g_return_if_fail (statusbar != NULL);
g_return_if_fail (GTK_IS_STATUSBAR (statusbar));
statusbar = gtk_type_new (gtk_statusbar_get_type ());
if (!text)
text = "";
return GTK_WIDGET (statusbar);
gtk_label_set (GTK_LABEL (statusbar->label), text);
}
gint
gtk_statusbar_push (GtkStatusbar *statusbar, gchar *str)
guint
gtk_statusbar_push (GtkStatusbar *statusbar,
const gchar *text)
{
GtkStatusbarMsg *msg;
GList *list;
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);
list = statusbar->msgs;
msg = g_new(GtkStatusbarMsg, 1);
msg->str = g_strdup(str);
msg->statusid = statusbar->next_statusid;
statusbar->next_statusid++;
class = GTK_STATUSBAR_CLASS (GTK_OBJECT (statusbar)->klass);
msg = g_chunk_new (GtkStatusbarMsg, class->messages_mem_chunk);
msg->text = g_strdup (text);
msg->status_id = statusbar->seq_status_id++;
g_list_append(list, msg);
statusbar->messages = g_list_prepend (statusbar->messages, msg);
gtk_statusbar_show_top_msg(statusbar);
gtk_signal_emit (GTK_OBJECT (statusbar), statusbar_signals[SIGNAL_TEXT_PUSHED], msg->text);
return msg->statusid;
return msg->status_id;
}
static void
gtk_statusbar_show_top_msg (GtkStatusbar *statusbar)
void
gtk_statusbar_pop (GtkStatusbar *statusbar)
{
GList *listitem;
listitem = g_list_last(statusbar->msgs);
GtkStatusbarMsg *msg;
g_return_if_fail (statusbar != NULL);
g_return_if_fail (GTK_IS_STATUSBAR (statusbar));
if ((listitem != NULL) && (listitem->data != NULL))
gtk_label_set(GTK_LABEL(statusbar->label), ((GtkStatusbarMsg*) (listitem->data))->str);
if (statusbar->messages)
{
GList *list;
GtkStatusbarClass *class;
list = statusbar->messages;
msg = list->data;
class = GTK_STATUSBAR_CLASS (GTK_OBJECT (statusbar)->klass);
statusbar->messages = g_list_remove_link (statusbar->messages, list);
g_free (msg->text);
g_mem_chunk_free (class->messages_mem_chunk, msg);
g_list_free_1 (list);
}
msg = statusbar->messages ? statusbar->messages->data : NULL;
gtk_signal_emit (GTK_OBJECT (statusbar), statusbar_signals[SIGNAL_TEXT_POPPED],
msg ? msg->text : NULL);
}
void
gtk_statusbar_pop (GtkStatusbar *statusbar, gint statusid)
gtk_statusbar_steal (GtkStatusbar *statusbar,
guint status_id)
{
GList *listitem;
listitem = g_list_last(statusbar->msgs);
GtkStatusbarMsg *msg;
g_return_if_fail (statusbar != NULL);
g_return_if_fail (GTK_IS_STATUSBAR (statusbar));
while ((listitem != NULL) && (listitem->data != NULL)) {
if (((GtkStatusbarMsg*)(listitem->data))->statusid == statusid) {
g_list_remove(listitem, listitem->data);
break;
msg = statusbar->messages ? statusbar->messages->data : NULL;
if (msg)
{
GList *list;
if (msg->status_id == status_id)
{
gtk_statusbar_pop (statusbar);
return;
}
for (list = statusbar->messages; list; list = list->next)
{
msg = list->data;
if (msg->status_id == status_id)
{
GtkStatusbarClass *class;
class = GTK_STATUSBAR_CLASS (GTK_OBJECT (statusbar)->klass);
statusbar->messages = g_list_remove_link (statusbar->messages, list);
g_free (msg->text);
g_mem_chunk_free (class->messages_mem_chunk, msg);
g_list_free_1 (list);
break;
}
}
}
listitem = listitem->prev;
}
gtk_statusbar_show_top_msg(statusbar);
}
static void
gtk_statusbar_destroy (GtkObject *object)
{
GtkStatusbar *statusbar;
GtkStatusbarClass *class;
GList *list;
g_return_if_fail (object != NULL);
g_return_if_fail (GTK_IS_STATUSBAR (object));
statusbar = GTK_STATUSBAR (object);
g_list_free(statusbar->msgs);
class = GTK_STATUSBAR_CLASS (GTK_OBJECT (statusbar)->klass);
for (list = statusbar->messages; list; list = list->next)
{
GtkStatusbarMsg *msg;
msg = list->data;
g_free (msg->text);
g_mem_chunk_free (class->messages_mem_chunk, msg);
}
g_list_free (statusbar->messages);
statusbar->messages = NULL;
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
......@@ -40,31 +40,41 @@ struct _GtkStatusbar
GtkWidget *frame;
GtkWidget *label;
GList *msgs;
gint next_statusid;
GList *messages;
guint seq_status_id;
};
struct _GtkStatusbarClass
{
GtkHBoxClass parent_class;
GMemChunk *messages_mem_chunk;
void (*text_pushed) (GtkStatusbar *statusbar,
const gchar *text);
void (*text_popped) (GtkStatusbar *statusbar,
const gchar *text);
};
struct _GtkStatusbarMsg
{
gchar *str;
gint statusid;
gchar *text;
guint status_id;
};
guint gtk_statusbar_get_type (void);
GtkWidget* gtk_statusbar_new (void);
/* Returns StatusID used for gtk_statusbar_push */
gint gtk_statusbar_push (GtkStatusbar *statusbar,
gchar *text);
guint gtk_statusbar_push (GtkStatusbar *statusbar,
const gchar *text);
void gtk_statusbar_pop (GtkStatusbar *statusbar);
void gtk_statusbar_steal (GtkStatusbar *statusbar,
guint status_id);
void gtk_statusbar_pop (GtkStatusbar *statusbar,
gint statusid);
#ifdef __cplusplus
}
......
......@@ -782,6 +782,154 @@ make_toolbar (GtkWidget *window)
return toolbar;
}
static guint statusbar_counter = 1;
static void
statusbar_push (GtkWidget *button,
GtkStatusbar *statusbar)
{
gchar text[1024];
sprintf (text, "something %d", statusbar_counter++);
gtk_statusbar_push (statusbar, text);
}
static void
statusbar_pop (GtkWidget *button,
GtkStatusbar *statusbar)
{
gtk_statusbar_pop (statusbar);
}
static void
statusbar_steal (GtkWidget *button,
GtkStatusbar *statusbar)
{
gtk_statusbar_steal (statusbar, 4);
}
static void
statusbar_popped (GtkStatusbar *statusbar,
const gchar *text)
{
if (!statusbar->messages)
statusbar_counter = 1;
}
static void
statusbar_dump_stack (GtkWidget *button,
GtkStatusbar *statusbar)
{
GList *list;
for (list = statusbar->messages; list; list = list->next)
{
GtkStatusbarMsg *msg;
msg = list->data;
g_print ("status_id: %d, status_text: \"%s\"\n", msg->status_id, msg->text);
}
}
static void
create_statusbar ()
{
static GtkWidget *window = NULL;
GtkWidget *box1;
GtkWidget *box2;
GtkWidget *button;
GtkWidget *separator;
GtkWidget *statusbar;
if (!window)
{
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_widget_destroyed),
&window);
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (gtk_true),
NULL);
gtk_window_set_title (GTK_WINDOW (window), "statusbar");
gtk_container_border_width (GTK_CONTAINER (window), 0);
box1 = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), box1);
gtk_widget_show (box1);
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);
statusbar = gtk_statusbar_new ();
gtk_box_pack_end (GTK_BOX (box1), statusbar, TRUE, TRUE, 0);
gtk_widget_show (statusbar);
gtk_signal_connect (GTK_OBJECT (statusbar),
"text_popped",
GTK_SIGNAL_FUNC (statusbar_popped),
NULL);
button = gtk_widget_new (gtk_button_get_type (),
"GtkButton::label", "push something",
"GtkWidget::visible", TRUE,
"GtkWidget::parent", box2,
"GtkObject::signal::clicked", statusbar_push, statusbar,
NULL);
button = gtk_widget_new (gtk_button_get_type (),
"GtkButton::label", "pop",
"GtkWidget::visible", TRUE,
"GtkWidget::parent", box2,
"GtkObject::signal::clicked", statusbar_pop, statusbar,
NULL);
button = gtk_widget_new (gtk_button_get_type (),
"GtkButton::label", "steal #4",
"GtkWidget::visible", TRUE,
"GtkWidget::parent", box2,
"GtkObject::signal::clicked", statusbar_steal, statusbar,
NULL);
button = gtk_widget_new (gtk_button_get_type (),
"GtkButton::label", "dump stack",
"GtkWidget::visible", TRUE,
"GtkWidget::parent", box2,
"GtkObject::signal::clicked", statusbar_dump_stack, statusbar,
NULL);
separator = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
gtk_widget_show (separator);
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
gtk_widget_show (box2);
button = gtk_button_new_with_label ("close");
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(gtk_widget_destroy),
GTK_OBJECT (window));
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show (button);
}
if (!GTK_WIDGET_VISIBLE (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
}
static void
create_handle_box ()
{
......@@ -4221,6 +4369,7 @@ create_main_window ()
{ "button box", create_button_box },
{ "toolbar", create_toolbar },
{ "handle box", create_handle_box },
{ "statusbar", create_statusbar },
{ "reparent", create_reparent },
{ "pixmap", create_pixmap },
{ "tooltips", create_tooltips },
......
......@@ -782,6 +782,154 @@ make_toolbar (GtkWidget *window)
return toolbar;
}
static guint statusbar_counter = 1;
static void
statusbar_push (GtkWidget *button,
GtkStatusbar *statusbar)
{
gchar text[1024];
sprintf (text, "something %d", statusbar_counter++);
gtk_statusbar_push (statusbar, text);
}
static void
statusbar_pop (GtkWidget *button,
GtkStatusbar *statusbar)
{
gtk_statusbar_pop (statusbar);
}
static void
statusbar_steal (GtkWidget *button,
GtkStatusbar *statusbar)
{
gtk_statusbar_steal (statusbar, 4);
}
static void
statusbar_popped (GtkStatusbar *statusbar,
const gchar *text)
{
if (!statusbar->messages)
statusbar_counter = 1;
}
static void
statusbar_dump_stack (GtkWidget *button,
GtkStatusbar *statusbar)
{
GList *list;
for (list = statusbar->messages; list; list = list->next)
{
GtkStatusbarMsg *msg;
msg = list->data;
g_print ("status_id: %d, status_text: \"%s\"\n", msg->status_id, msg->text);
}
}
static void
create_statusbar ()
{
static GtkWidget *window = NULL;
GtkWidget *box1;
GtkWidget *box2;
GtkWidget *button;
GtkWidget *separator;
GtkWidget *statusbar;
if (!window)
{
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_widget_destroyed),
&window);
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (gtk_true),
NULL);
gtk_window_set_title (GTK_WINDOW (window), "statusbar");
gtk_container_border_width (GTK_CONTAINER (window), 0);
box1 = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), box1);
gtk_widget_show (box1);
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);
statusbar = gtk_statusbar_new ();
gtk_box_pack_end