/* This is -*- C -*- */ /* vim: set sw=2: */ /* * guppi-object-title.c * * Copyright (C) 2000 EMC Capital Management, Inc. * Copyright (C) 2001 Free Software Foundation, Inc. * * Developed by Jon Trowbridge * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include #include #include #include #include #include #include "guppi-object-title.h" static GtkObjectClass *parent_class = NULL; enum { ARG_0, ARG_ON_TOP, ARG_TITLE, ARG_SUBTITLE, ARG_TITLE_FONT, ARG_SUBTITLE_FONT, ARG_SUBOBJECT }; static void guppi_object_title_set_arg (GtkObject *obj, GtkArg *arg, guint arg_id) { GuppiObjectTitle *tobj = GUPPI_OBJECT_TITLE (obj); switch (arg_id) { case ARG_ON_TOP: tobj->on_top = GTK_VALUE_BOOL (*arg); break; case ARG_TITLE: guppi_free (tobj->title); tobj->title = guppi_strdup ((gchar *) GTK_VALUE_POINTER (*arg)); break; case ARG_SUBTITLE: guppi_free (tobj->subtitle); tobj->subtitle = guppi_strdup ((gchar *) GTK_VALUE_POINTER (*arg)); break; case ARG_TITLE_FONT: guppi_refcounting_assign (tobj->title_font, GNOME_FONT (GTK_VALUE_POINTER (*arg))); break; case ARG_SUBTITLE_FONT: guppi_refcounting_assign (tobj->subtitle_font, GNOME_FONT (GTK_VALUE_POINTER (*arg))); break; case ARG_SUBOBJECT: guppi_refcounting_assign (tobj->subobject, GUPPI_OBJECT (GTK_VALUE_POINTER (*arg))); guppi_sink (tobj->subobject); break; default: break; }; } static void guppi_object_title_destroy (GtkObject *obj) { if (parent_class->destroy) parent_class->destroy (obj); } static void guppi_object_title_finalize (GtkObject *obj) { GuppiObjectTitle *tobj = GUPPI_OBJECT_TITLE (obj); guppi_free (tobj->title); guppi_free (tobj->subtitle); guppi_unref0 (tobj->title_font); guppi_unref0 (tobj->subtitle_font); guppi_unref0 (tobj->subobject); if (parent_class->finalize) parent_class->finalize (obj); } static void update (GuppiObject *obj) { GuppiObjectTitle *otitle; GuppiElementState *title_state; GuppiElementState *subtitle_state = NULL; g_return_if_fail (obj != NULL); g_return_if_fail (GUPPI_IS_OBJECT_TITLE (obj)); otitle = GUPPI_OBJECT_TITLE (obj); /* FIXME: if the object when built did not have a title or a subtitle, they should be created here if there is new title data. Right now this isn't done. */ if (otitle->title_view && otitle->title) { title_state = guppi_element_view_state (otitle->title_view); guppi_element_state_set (title_state, "text", otitle->title, "font", otitle->title_font, NULL); } if (otitle->subtitle_view && otitle->subtitle) { subtitle_state = guppi_element_view_state (otitle->subtitle_view); guppi_element_state_set (subtitle_state, "text", otitle->subtitle, "font", otitle->subtitle_font, NULL); } } static gpointer build (GuppiObject *obj, double hsize, double vsize) { GuppiObjectTitle *tobj; GuppiElementState *grp_state; GuppiGroupView *grp_view; GuppiElementState *title_state = NULL; GuppiElementView *title_view = NULL; GuppiElementState *subtitle_state = NULL; GuppiElementView *subtitle_view = NULL; GuppiElementView *upper_text = NULL; GuppiElementView *lower_text = NULL; GuppiElementView *subview = NULL; const double outer_margin = 3.6; const double inner_margin = 3.6; tobj = GUPPI_OBJECT_TITLE (obj); grp_state = guppi_group_state_new (); grp_view = GUPPI_GROUP_VIEW (guppi_element_state_make_view (grp_state)); guppi_unref0 (grp_state); if (tobj->title) { title_state = guppi_element_state_new ("text", "text", tobj->title, "font", tobj->title_font, NULL); title_view = guppi_element_state_make_view (title_state); guppi_unref0 (title_state); } if (tobj->subtitle) { subtitle_state = guppi_element_state_new ("text", "text", tobj->subtitle, "font", tobj->subtitle_font, NULL); subtitle_view = guppi_element_state_make_view (subtitle_state); guppi_unref0 (subtitle_state); } g_assert (tobj->subobject); subview = guppi_object_view (tobj->subobject); g_assert (subview); /* do layout */ guppi_group_view_layout_fill_horizontally (grp_view, subview, outer_margin, outer_margin); /* If no titles are specified, the only thing in our group is the subobject. */ if (title_view == NULL || subtitle_view == NULL) { guppi_group_view_layout_fill_vertically (grp_view, subview, outer_margin, outer_margin); return GUPPI_ELEMENT_VIEW (grp_view); } if (title_view) { guppi_group_view_layout_same_horizontal_center (grp_view, title_view, subview); upper_text = title_view; } if (subtitle_view) { guppi_group_view_layout_same_horizontal_center (grp_view, subtitle_view, subview); lower_text = subtitle_view; } if (upper_text == NULL) upper_text = lower_text; if (lower_text == NULL) lower_text = upper_text; if (upper_text != lower_text) guppi_group_view_layout_vertically_adjacent (grp_view, upper_text, lower_text, inner_margin); if (tobj->on_top) { guppi_group_view_layout_flush_top (grp_view, upper_text, outer_margin); guppi_group_view_layout_vertically_adjacent (grp_view, lower_text, subview, inner_margin); guppi_group_view_layout_flush_bottom (grp_view, subview, outer_margin); } else { guppi_group_view_layout_flush_top (grp_view, subview, outer_margin); guppi_group_view_layout_vertically_adjacent (grp_view, subview, upper_text, inner_margin); guppi_group_view_layout_flush_bottom (grp_view, lower_text, outer_margin); } tobj->subtitle_view = subtitle_view; tobj->title_view = title_view; return GUPPI_ELEMENT_VIEW (grp_view); } static void item_init (GuppiObject *obj, GnomeCanvasItem *item) { GuppiObjectTitle *tobj = GUPPI_OBJECT_TITLE (obj); GuppiObjectClass *subclass; /* Forward the item_init call to any subitems */ if (tobj->subobject) { subclass = GUPPI_OBJECT_CLASS (GTK_OBJECT (tobj->subobject)->klass); if (subclass->item_init) subclass->item_init (tobj->subobject, item); } } #define add_arg(str, t, symb) \ gtk_object_add_arg_type("GuppiObjectTitle::" str, t, GTK_ARG_WRITABLE, symb) static void guppi_object_title_class_init (GuppiObjectTitleClass *klass) { GtkObjectClass *object_class = (GtkObjectClass *) klass; GuppiObjectClass *gobj_class = GUPPI_OBJECT_CLASS (klass); parent_class = gtk_type_class (GUPPI_TYPE_OBJECT); object_class->set_arg = guppi_object_title_set_arg; object_class->destroy = guppi_object_title_destroy; object_class->finalize = guppi_object_title_finalize; gobj_class->build = build; gobj_class->item_init = item_init; gobj_class->update = update; add_arg ("title", GTK_TYPE_POINTER, ARG_TITLE); add_arg ("subtitle", GTK_TYPE_POINTER, ARG_SUBTITLE); add_arg ("title_font", GTK_TYPE_POINTER, ARG_TITLE_FONT); add_arg ("subtitle_font", GTK_TYPE_POINTER, ARG_SUBTITLE_FONT); add_arg ("subobject", GTK_TYPE_POINTER, ARG_SUBOBJECT); add_arg ("on_top", GTK_TYPE_BOOL, ARG_ON_TOP); } static void guppi_object_title_init (GuppiObjectTitle *obj) { obj->on_top = TRUE; obj->title_font = gnome_font_new ("Helvetica", 20.0); obj->subtitle_font = gnome_font_new ("Helvetica", 14.0); } GtkType guppi_object_title_get_type (void) { static GtkType guppi_object_title_type = 0; if (!guppi_object_title_type) { static const GtkTypeInfo guppi_object_title_info = { "GuppiObjectTitle", sizeof (GuppiObjectTitle), sizeof (GuppiObjectTitleClass), (GtkClassInitFunc) guppi_object_title_class_init, (GtkObjectInitFunc) guppi_object_title_init, NULL, NULL, (GtkClassInitFunc) NULL }; guppi_object_title_type = gtk_type_unique (GUPPI_TYPE_OBJECT, &guppi_object_title_info); } return guppi_object_title_type; } GtkObject * guppi_object_title_new (void) { return GTK_OBJECT (guppi_type_new (guppi_object_title_get_type ())); }