Mercurial > pidgin.yaz
diff src/gtkgaim-disclosure.c @ 10297:ec140184437b
[gaim-migrate @ 11480]
"After applying this patch, which modifies the make files and makes the
@file/@ingroup markers at the top of several gtk files more uniform,
the following files should be renamed:
dnd-hints.h -> gtkdnd-hints.h
dnd-hints.c -> gtkdnd-hints.c
gaim-disclosure.h -> gtkgaim-disclosure.h
gaim-disclosure.c -> gtkgaim-disclosure.c
stock.h -> gtkstock.h
stock.c -> gtkstock.c
I believe that completes the renaming of files which are explicitly for
gtkgaim; all files in /gaim/src which depend upon gtk should now have
gtk in their name. There are two candidates which might be considered
part of gtkgaim rather than part of the core, but I didn't modify them:
session.c and log.c. Both are quite gaim-UI specific, it seems,
particularly session, but perhaps other UIs could also make use of
their functionality.
-Evan "
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Thu, 02 Dec 2004 20:34:19 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gtkgaim-disclosure.c Thu Dec 02 20:34:19 2004 +0000 @@ -0,0 +1,308 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * @file gtkgaim-disclosure.c GTK+ Gaim Disclosure + * @ingroup gtkui + * + * gaim + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gtk/gtktogglebutton.h> + +#include "gtkgaim-disclosure.h" + +#ifdef ENABLE_NLS +# include <libintl.h> +# define _(x) gettext(x) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define N_(String) (String) +# define _(x) (x) +#endif + +static GtkCheckButtonClass *parent_class = NULL; + +struct _GaimDisclosurePrivate { + GtkWidget *container; + char *shown; + char *hidden; + + guint32 expand_id; + GtkExpanderStyle style; + + int expander_size; + int direction; +}; + +static void +finalize (GObject *object) +{ + GaimDisclosure *disclosure; + + disclosure = GAIM_DISCLOSURE (object); + if (disclosure->priv == NULL) { + return; + } + + g_free (disclosure->priv->hidden); + g_free (disclosure->priv->shown); + + if (disclosure->priv->container != NULL) { + g_object_unref (G_OBJECT (disclosure->priv->container)); + } + + g_free (disclosure->priv); + disclosure->priv = NULL; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +get_x_y (GaimDisclosure *disclosure, + int *x, + int *y, + GtkStateType *state_type) +{ + GtkCheckButton *check_button; + int indicator_size = 0; + int focus_width; + int focus_pad; + gboolean interior_focus; + GtkWidget *widget = GTK_WIDGET (disclosure); + GtkBin *bin = GTK_BIN (disclosure); + int width; + + if (GTK_WIDGET_VISIBLE (disclosure) && + GTK_WIDGET_MAPPED (disclosure)) { + check_button = GTK_CHECK_BUTTON (disclosure); + + gtk_widget_style_get (widget, + "interior_focus", &interior_focus, + "focus-line-width", &focus_width, + "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; + } + + if (bin->child) { + width = bin->child->allocation.x - widget->allocation.x - (2 * GTK_CONTAINER (widget)->border_width); + } else { + width = widget->allocation.width; + } + + *x = widget->allocation.x + (width) / 2; + *y = widget->allocation.y + widget->allocation.height / 2; + + if (interior_focus == FALSE) { + *x += focus_width + focus_pad; + } + + *state_type = GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE ? GTK_STATE_NORMAL : GTK_WIDGET_STATE (widget); + + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) { + *x = widget->allocation.x + widget->allocation.width - (indicator_size + *x - widget->allocation.x); + } + } else { + *x = 0; + *y = 0; + *state_type = GTK_STATE_NORMAL; + } +} + +static gboolean +expand_collapse_timeout (gpointer data) +{ + GtkWidget *widget = data; + GaimDisclosure *disclosure = data; + GtkStateType state_type; + int x, y; + + gdk_window_invalidate_rect (widget->window, &widget->allocation, TRUE); + get_x_y (disclosure, &x, &y, &state_type); + + gtk_paint_expander (widget->style, + widget->window, + state_type, + &widget->allocation, + widget, + "disclosure", + x, y, + disclosure->priv->style); + + disclosure->priv->style += disclosure->priv->direction; + if ((int) disclosure->priv->style > (int) GTK_EXPANDER_EXPANDED) { + disclosure->priv->style = GTK_EXPANDER_EXPANDED; + + if (disclosure->priv->container != NULL) { + gtk_widget_show (disclosure->priv->container); + } + + g_object_set (G_OBJECT (disclosure), + "label", disclosure->priv->hidden, + NULL); + return FALSE; + } else if ((int) disclosure->priv->style < (int) GTK_EXPANDER_COLLAPSED) { + disclosure->priv->style = GTK_EXPANDER_COLLAPSED; + + if (disclosure->priv->container != NULL) { + gtk_widget_hide (disclosure->priv->container); + } + + g_object_set (G_OBJECT (disclosure), + "label", disclosure->priv->shown, + NULL); + + return FALSE; + } else { + return TRUE; + } +} + +static void +do_animation (GaimDisclosure *disclosure, + gboolean opening) +{ + if (disclosure->priv->expand_id > 0) { + gaim_timeout_remove(disclosure->priv->expand_id); + } + + disclosure->priv->direction = opening ? 1 : -1; + disclosure->priv->expand_id = gaim_timeout_add (50, expand_collapse_timeout, disclosure); +} + +static void +toggled (GtkToggleButton *tb) +{ + GaimDisclosure *disclosure; + + disclosure = GAIM_DISCLOSURE (tb); + do_animation (disclosure, gtk_toggle_button_get_active (tb)); + + if (disclosure->priv->container == NULL) { + return; + } +} + +static void +draw_indicator (GtkCheckButton *check, + GdkRectangle *area) +{ + GtkWidget *widget = GTK_WIDGET (check); + GaimDisclosure *disclosure = GAIM_DISCLOSURE (check); + GtkStateType state_type; + int x, y; + + get_x_y (disclosure, &x, &y, &state_type); + gtk_paint_expander (widget->style, + widget->window, + state_type, + area, + widget, + "treeview", + x, y, + disclosure->priv->style); +} + +static void +class_init (GaimDisclosureClass *klass) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + GtkCheckButtonClass *button_class; + GtkToggleButtonClass *toggle_class; + + object_class = G_OBJECT_CLASS (klass); + widget_class = GTK_WIDGET_CLASS (klass); + button_class = GTK_CHECK_BUTTON_CLASS (klass); + toggle_class = GTK_TOGGLE_BUTTON_CLASS (klass); + + toggle_class->toggled = toggled; + button_class->draw_indicator = draw_indicator; + + object_class->finalize = finalize; + + parent_class = g_type_class_peek_parent (klass); + + gtk_widget_class_install_style_property (widget_class, + g_param_spec_int ("expander_size", + _("Expander Size"), + _("Size of the expander arrow"), + 0, G_MAXINT, + 10, G_PARAM_READABLE)); +} + +static void +init (GaimDisclosure *disclosure) +{ + disclosure->priv = g_new0 (GaimDisclosurePrivate, 1); + disclosure->priv->expander_size = 10; +} + +GType +gaim_disclosure_get_type (void) +{ + static GType type = 0; + + if (type == 0) { + GTypeInfo info = { + sizeof (GaimDisclosureClass), + NULL, NULL, (GClassInitFunc) class_init, NULL, NULL, + sizeof (GaimDisclosure), 0, (GInstanceInitFunc) init + }; + + type = g_type_register_static (GTK_TYPE_CHECK_BUTTON, "GaimDisclosure", &info, 0); + } + + return type; +} + +GtkWidget * +gaim_disclosure_new (const char *shown, + const char *hidden) +{ + GaimDisclosure *disclosure; + + disclosure = g_object_new (gaim_disclosure_get_type (), "label", shown, NULL); + + disclosure->priv->shown = g_strdup (shown); + disclosure->priv->hidden = g_strdup (hidden); + return GTK_WIDGET (disclosure); +} + +void +gaim_disclosure_set_container (GaimDisclosure *disclosure, + GtkWidget *container) +{ + g_object_ref (G_OBJECT (container)); + disclosure->priv->container = container; +}