/* mguru.c - Multiway guru widget.
Copyright (C) 1999 Perry Piplani. Idea inspired by Havoc
Pennington's gnome-guru widget, but is a re-implemention
from scratch.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License
as published by the Free Software Foundation; either version 2, 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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 <gnome.h>
#include "choicebox.h"
enum
{
CHOICE_MADE,
LAST_SIGNAL
};
typedef void (*GnomeChoiceBoxSignal) (GtkObject *object,
gpointer data);
static void gnome_choice_box_class_init (GnomeChoiceBoxClass *klass);
static void gnome_choice_box_init (GnomeChoiceBox *choicebox);
static void gnome_choice_box_marshal_signal (GtkObject *object,
GtkSignalFunc func,
gpointer func_data,
GtkArg *args);
static void gnome_choice_box_destroy (GtkObject *object);
static void choice_box_toggled_cb (GtkWidget *radio, gpointer choicebox);
static GtkVBoxClass *parent_class = NULL;
static gint choice_box_signals [LAST_SIGNAL] = { 0 };
guint gnome_choice_box_get_type (void)
{
static guint choice_box_type = 0;
if (!choice_box_type){
GtkTypeInfo choice_box_info = {
"GnomeChoiceBox",
sizeof (GnomeChoiceBox),
sizeof (GnomeChoiceBoxClass),
(GtkClassInitFunc) gnome_choice_box_class_init,
(GtkObjectInitFunc) gnome_choice_box_init,
(GtkArgSetFunc) NULL,
(GtkArgGetFunc) NULL
};
choice_box_type = gtk_type_unique (gtk_vbox_get_type (),
&choice_box_info);
}
return choice_box_type;
}
static void
gnome_choice_box_class_init (GnomeChoiceBoxClass *klass)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass*) klass;
widget_class = (GtkWidgetClass*) klass;
object_class->destroy = gnome_choice_box_destroy;
parent_class = gtk_type_class (gtk_vbox_get_type ());
choice_box_signals[CHOICE_MADE] =
gtk_signal_new ("choice_made",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GnomeChoiceBoxClass,
choice_made),
gnome_choice_box_marshal_signal,
GTK_TYPE_NONE,0);
gtk_object_class_add_signals (object_class, choice_box_signals,
LAST_SIGNAL);
klass->choice_made = NULL;
}
static void
gnome_choice_box_marshal_signal (GtkObject *object,
GtkSignalFunc func,
gpointer func_data,
GtkArg *args)
{
GnomeChoiceBoxSignal rfunc;
rfunc = (GnomeChoiceBoxSignal) func;
(* rfunc) (object, func_data);
}
static void
gnome_choice_box_init (GnomeChoiceBox *choicebox)
{
choicebox->group=NULL;
choicebox->choices=0;
}
static void
gnome_choice_box_destroy (GtkObject *object)
{
GnomeChoiceBox *choicebox;
g_return_if_fail (object != NULL);
g_return_if_fail (GNOME_IS_CHOICE_BOX(object));
choicebox = GNOME_CHOICE_BOX(object);
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
GtkWidget *gnome_choice_box_prep (GtkWidget *choicebox,
ChoiceBoxLayout layout,
gchar *question){
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *label=NULL;
if(question){
label = gtk_label_new(question);
gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_LEFT);
}
switch(layout){
case CHOICE_BOX_VV:
if(question){
gtk_box_pack_start (GTK_BOX (choicebox),
label, TRUE, TRUE, GNOME_PAD_SMALL);
gtk_widget_show (label);
}
return choicebox;
break;
case CHOICE_BOX_VH:
if(question){
gtk_box_pack_start (GTK_BOX (choicebox),
label, TRUE, TRUE, GNOME_PAD_SMALL);
gtk_widget_show (label);
}
hbox=gtk_hbox_new(FALSE,0);
gtk_box_pack_start (GTK_BOX (choicebox),
hbox, TRUE, TRUE, GNOME_PAD_SMALL);
gtk_widget_show (hbox);
return hbox;
break;
case CHOICE_BOX_HV:
if(question){
gtk_label_set_line_wrap(GTK_LABEL(label),TRUE);
hbox=gtk_hbox_new(FALSE,0);
gtk_box_pack_start (GTK_BOX (choicebox),
hbox, TRUE, TRUE, 0);
gtk_widget_show (hbox);
gtk_box_pack_start (GTK_BOX (hbox),
label, TRUE, TRUE, GNOME_PAD_SMALL);
gtk_widget_show (label);
vbox=gtk_vbox_new(FALSE,0);
gtk_box_pack_start (GTK_BOX (hbox),
vbox, TRUE, TRUE, GNOME_PAD_SMALL);
gtk_widget_show (vbox);
return vbox;
}
else
return choicebox;
break;
case CHOICE_BOX_HH:
hbox=gtk_hbox_new(FALSE,0);
gtk_box_pack_start (GTK_BOX (choicebox),
hbox, TRUE, TRUE, 0);
gtk_widget_show (hbox);
if(question){
gtk_box_pack_start (GTK_BOX (hbox),
label, TRUE, TRUE, GNOME_PAD_SMALL);
gtk_widget_show (label);
}
return hbox;
break;
default:
if(question){
gtk_box_pack_start (GTK_BOX (choicebox),
label, TRUE, TRUE, GNOME_PAD_SMALL);
gtk_widget_show (label);
}
return choicebox;
break;
}
return choicebox;
}
GtkWidget *gnome_choice_box_new (ChoiceBoxLayout layout,
gchar *question,...){
GtkWidget *choicebox;
GtkWidget *box;
GtkWidget *radio;
gchar *s;
va_list ap;
choicebox = gtk_type_new (gnome_choice_box_get_type ());
box = gnome_choice_box_prep(choicebox,layout,question);
va_start(ap,question);
while( (s=va_arg(ap,gchar *)) ){
radio =
gtk_radio_button_new_with_label(GNOME_CHOICE_BOX(choicebox)->group,s);
gtk_box_pack_start (GTK_BOX (box),
radio, TRUE, TRUE, GNOME_PAD_SMALL );
gtk_signal_connect(GTK_OBJECT(radio),
"clicked",
GTK_SIGNAL_FUNC(choice_box_toggled_cb),
choicebox);
gtk_widget_show (radio);
GNOME_CHOICE_BOX(choicebox)->group =
gtk_radio_button_group (GTK_RADIO_BUTTON (radio));
GNOME_CHOICE_BOX(choicebox)->choices++;
}
va_end(ap);
return choicebox;
}
GtkWidget *gnome_choice_box_newv (ChoiceBoxLayout layout,
gchar *question,
gchar **options){
GtkWidget *choicebox;
GtkWidget *box;
GtkWidget *radio;
gchar **s;
choicebox = gtk_type_new (gnome_choice_box_get_type ());
box = gnome_choice_box_prep(choicebox,layout,question);
for(s=options;*s;s++){
radio =
gtk_radio_button_new_with_label(GNOME_CHOICE_BOX(choicebox)->group,*s);
gtk_box_pack_start (GTK_BOX (box),
radio, TRUE, TRUE, GNOME_PAD_SMALL );
gtk_signal_connect(GTK_OBJECT(radio),
"clicked",
GTK_SIGNAL_FUNC(choice_box_toggled_cb),
choicebox);
gtk_widget_show (radio);
GNOME_CHOICE_BOX(choicebox)->group =
gtk_radio_button_group (GTK_RADIO_BUTTON (radio));
GNOME_CHOICE_BOX(choicebox)->choices++;
}
return choicebox;
}
static void choice_box_toggled_cb (GtkWidget *radio, gpointer choicebox){
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio)))
gtk_signal_emit (GTK_OBJECT (choicebox),
choice_box_signals[CHOICE_MADE]);
}
gchar *gnome_choice_box_get_choice(GnomeChoiceBox *choicebox){
GSList *list;
GtkWidget *label;
char *s;
g_return_val_if_fail (choicebox != NULL, NULL);
g_return_val_if_fail (GNOME_IS_CHOICE_BOX (choicebox), NULL);
list=choicebox->group;
while(list){
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(list->data))){
label = GTK_BIN(list->data)->child;
gtk_label_get(GTK_LABEL(label),&s);
return s;
}
list=list->next;
}
return NULL;
}
gint gnome_choice_box_get_index(GnomeChoiceBox *choicebox){
gint i;
GSList *list;
g_return_val_if_fail (choicebox != NULL, -1);
g_return_val_if_fail (GNOME_IS_CHOICE_BOX (choicebox), -1);
list=choicebox->group;
i=choicebox->choices-1;
while(list){
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(list->data))){
return i;
}
list=list->next;
i--;
}
return -1;
}
gint gnome_choice_box_set_choice(GnomeChoiceBox *choicebox, gchar *choice){ return -1;}
gint gnome_choice_box_set_index(GnomeChoiceBox *choicebox, gint index){
int i;
GSList *list;
g_return_val_if_fail (choicebox != NULL, -1);
g_return_val_if_fail (GNOME_IS_CHOICE_BOX (choicebox), -1);
list=choicebox->group;
i=(choicebox->choices-1)-index;
if(i<0)
return -1;
for(;list->next && i>0;i--)
list=list->next;
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(list->data),TRUE);
return index;
}
syntax highlighted by Code2HTML, v. 0.9.1