📄 mguru.c
字号:
/* 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 "mguru.h"enum{ CANCEL, APPLY, PREV, NEXT, MGURU_CLICK, LAST_SIGNAL};typedef void (*GnomeMGuruSignal2) (GtkObject *object, gint arg1, gint arg2, gpointer data);typedef void (*GnomeMGuruSignal1) (GtkObject *object, gint arg1, gpointer data);static void gnome_mguru_class_init (GnomeMGuruClass *klass);static void gnome_mguru_init (GnomeMGuru *mguru);static void gnome_mguru_marshal_signal1 (GtkObject *object, GtkSignalFunc func, gpointer func_data, GtkArg *args);static void gnome_mguru_marshal_signal2 (GtkObject *object, GtkSignalFunc func, gpointer func_data, GtkArg *args);static void gnome_mguru_destroy (GtkObject *object);static void mguru_clicked_cb (GtkWidget *widget, gpointer guru);static void gnome_mguru_auto_state(GnomeMGuru *mguru);static GtkVBoxClass *parent_class = NULL;static gint mguru_signals [LAST_SIGNAL] = { 0 };guint gnome_mguru_get_type (void){ static guint mguru_type = 0; if (!mguru_type){ GtkTypeInfo mguru_info = { "GnomeMGuru", sizeof (GnomeMGuru), sizeof (GnomeMGuruClass), (GtkClassInitFunc) gnome_mguru_class_init, (GtkObjectInitFunc) gnome_mguru_init, (GtkArgSetFunc) NULL, (GtkArgGetFunc) NULL }; mguru_type = gtk_type_unique (gtk_vbox_get_type (), &mguru_info); } return mguru_type;}static voidgnome_mguru_class_init (GnomeMGuruClass *klass){ GtkObjectClass *object_class; GtkWidgetClass *widget_class; object_class = (GtkObjectClass*) klass; widget_class = (GtkWidgetClass*) klass; object_class->destroy = gnome_mguru_destroy; parent_class = gtk_type_class (gtk_vbox_get_type ()); mguru_signals[CANCEL] = gtk_signal_new ("cancel", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GnomeMGuruClass, cancel), gnome_mguru_marshal_signal1, GTK_TYPE_NONE, 1, GTK_TYPE_INT); mguru_signals[APPLY] = gtk_signal_new ("apply", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GnomeMGuruClass, apply), gnome_mguru_marshal_signal1, GTK_TYPE_NONE, 1, GTK_TYPE_INT); mguru_signals[PREV] = gtk_signal_new ("prev", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GnomeMGuruClass, prev), gnome_mguru_marshal_signal1, GTK_TYPE_NONE, 1, GTK_TYPE_INT); mguru_signals[NEXT] = gtk_signal_new ("next", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GnomeMGuruClass, next), gnome_mguru_marshal_signal1, GTK_TYPE_NONE, 1, GTK_TYPE_INT); mguru_signals[MGURU_CLICK] = gtk_signal_new ("mguru_click", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GnomeMGuruClass, mguru_click), gnome_mguru_marshal_signal2, GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT); gtk_object_class_add_signals (object_class, mguru_signals, LAST_SIGNAL); klass->mguru_click = NULL; klass->cancel = NULL; klass->apply = NULL; klass->prev = NULL; klass->next = NULL;}static voidgnome_mguru_marshal_signal1 (GtkObject *object, GtkSignalFunc func, gpointer func_data, GtkArg *args){ GnomeMGuruSignal1 rfunc; rfunc = (GnomeMGuruSignal1) func; (* rfunc) (object, GTK_VALUE_INT (args[0]) ,func_data);}static voidgnome_mguru_marshal_signal2 (GtkObject *object, GtkSignalFunc func, gpointer func_data, GtkArg *args){ GnomeMGuruSignal2 rfunc; rfunc = (GnomeMGuruSignal2) func; (* rfunc) (object, GTK_VALUE_INT (args[0]), GTK_VALUE_INT (args[1]),func_data);}static voidgnome_mguru_init (GnomeMGuru *mguru){ mguru->notebook = gtk_notebook_new (); gtk_notebook_set_show_tabs(GTK_NOTEBOOK (mguru->notebook),FALSE); gtk_notebook_set_show_border(GTK_NOTEBOOK (mguru->notebook),FALSE);}static voidgnome_mguru_destroy (GtkObject *object){ GnomeMGuru *mguru; g_return_if_fail (object != NULL); g_return_if_fail (GNOME_IS_MGURU (object)); mguru = GNOME_MGURU (object); GTK_OBJECT_CLASS (parent_class)->destroy (object);}GtkWidget *gnome_mguru_new (gint multiway, GnomeDialog *dialog, GtkWidget * graphic){ GtkWidget *mguru; GList *button_list; gint i=0; GtkWidget *buttonbox; GtkWidget *hbox; mguru = gtk_type_new (gnome_mguru_get_type ()); GNOME_MGURU(mguru)->multi = multiway; hbox=gtk_hbox_new(FALSE,0); gtk_box_pack_start (GTK_BOX(mguru), hbox, TRUE, TRUE, 0); if(!dialog) gtk_container_border_width (GTK_CONTAINER (hbox), 5); gtk_widget_show (hbox); if (graphic) { GtkWidget* frame; frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); gtk_widget_show (frame); gtk_container_add(GTK_CONTAINER(frame), graphic); gtk_widget_show (graphic); gtk_box_pack_start (GTK_BOX(hbox), frame, FALSE, FALSE, 0); } gtk_box_pack_start (GTK_BOX(hbox), GNOME_MGURU(mguru)->notebook, TRUE, TRUE, 0); gtk_widget_show (GNOME_MGURU(mguru)->notebook); if(dialog){ GNOME_MGURU(mguru)->dialog = GTK_WIDGET(dialog); gnome_dialog_append_buttons (GNOME_DIALOG (dialog), GNOME_STOCK_BUTTON_CANCEL, GNOME_STOCK_BUTTON_PREV, GNOME_STOCK_BUTTON_NEXT, GNOME_STOCK_BUTTON_APPLY, NULL); button_list = GNOME_DIALOG(dialog)->buttons; while(button_list){ GNOME_MGURU(mguru)->button[i] = GTK_WIDGET(button_list->data); gtk_signal_connect(GTK_OBJECT(GNOME_MGURU(mguru)->button[i]), "clicked", GTK_SIGNAL_FUNC(mguru_clicked_cb), mguru); button_list = button_list->next; i++; } gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), mguru, TRUE, TRUE, 0); } else{ buttonbox = gtk_hbutton_box_new(); gtk_container_set_border_width(GTK_CONTAINER(buttonbox), GNOME_PAD_SMALL); gtk_box_pack_end(GTK_BOX(mguru), buttonbox, FALSE, FALSE, 0); GNOME_MGURU(mguru)->button[MGURU_BUTTON_CANCEL] = gnome_stock_button(GNOME_STOCK_BUTTON_CANCEL); GNOME_MGURU(mguru)->button[MGURU_BUTTON_PREV] = gnome_stock_button(GNOME_STOCK_BUTTON_PREV); GNOME_MGURU(mguru)->button[MGURU_BUTTON_NEXT] = gnome_stock_button(GNOME_STOCK_BUTTON_NEXT); GNOME_MGURU(mguru)->button[MGURU_BUTTON_APPLY] = gnome_stock_button(GNOME_STOCK_BUTTON_APPLY); for(i=0;i < MGURU_LAST_BUTTON; i++){ gtk_box_pack_start(GTK_BOX(buttonbox), GNOME_MGURU(mguru)->button[i], FALSE, FALSE, 0); gtk_signal_connect(GTK_OBJECT(GNOME_MGURU(mguru)->button[i]), "clicked", GTK_SIGNAL_FUNC(mguru_clicked_cb), mguru); } gtk_widget_show_all(buttonbox); } return mguru; }static voidmguru_clicked_cb(GtkWidget *widget, gpointer guru){ gint page; gint butt; GnomeMGuru *mguru; mguru = GNOME_MGURU (guru); page=gnome_mguru_get_page(mguru); for(butt = 3; butt >= 0; butt--) if(mguru->button[butt] == widget) break; gtk_widget_ref(GTK_WIDGET(mguru)); if(butt == 0) gtk_signal_emit (GTK_OBJECT (mguru), mguru_signals[CANCEL], page); if(butt == 1) gtk_signal_emit (GTK_OBJECT (mguru), mguru_signals[PREV], page); if(butt == 2) gtk_signal_emit (GTK_OBJECT (mguru), mguru_signals[NEXT], page); if(butt == 3) gtk_signal_emit (GTK_OBJECT (mguru), mguru_signals[APPLY], page); gtk_signal_emit (GTK_OBJECT (mguru), mguru_signals[MGURU_CLICK], page, butt); if(!mguru->multi){ switch(butt){ case 1: gnome_mguru_prev_page(mguru); break; case 2: gnome_mguru_next_page(mguru); break; } } gtk_widget_unref(GTK_WIDGET(mguru)); return;} gint gnome_mguru_append_page (GnomeMGuru *mguru, GtkWidget *child, gchar *title){ GtkWidget *frame; g_return_val_if_fail (mguru != NULL, -1); g_return_val_if_fail (GNOME_IS_MGURU (mguru), -1); g_return_val_if_fail (child != NULL, -1); g_return_val_if_fail (GTK_IS_WIDGET (child), -1); frame = gtk_frame_new (title); gtk_container_border_width (GTK_CONTAINER (frame), 10); gtk_notebook_append_page (GTK_NOTEBOOK (mguru->notebook), frame, NULL); gtk_widget_show (frame); gtk_container_add (GTK_CONTAINER (frame), child); if(!mguru->multi) gnome_mguru_auto_state(mguru); return g_list_length ( GTK_NOTEBOOK(mguru->notebook)->children) - 1;}void gnome_mguru_set_page(GnomeMGuru *mguru, gint page){ g_return_if_fail (mguru != NULL); g_return_if_fail (GNOME_IS_MGURU (mguru)); gtk_notebook_set_page(GTK_NOTEBOOK(mguru->notebook),page); if(!mguru->multi) gnome_mguru_auto_state(mguru);return;}gint gnome_mguru_get_page(GnomeMGuru *mguru){ g_return_val_if_fail (mguru != NULL, -1); g_return_val_if_fail (GNOME_IS_MGURU (mguru), -1); return gtk_notebook_get_current_page(GTK_NOTEBOOK(mguru->notebook));}GtkWidget *gnome_mguru_get_page_child(GnomeMGuru *mguru, gint page){ GtkWidget *frame; g_return_val_if_fail (mguru != NULL, NULL); g_return_val_if_fail (GNOME_IS_MGURU (mguru), NULL); frame = gtk_notebook_get_nth_page(GTK_NOTEBOOK(mguru->notebook),page); return GTK_BIN(frame)->child;}void gnome_mguru_next_page(GnomeMGuru *mguru){ g_return_if_fail (mguru != NULL); g_return_if_fail (GNOME_IS_MGURU (mguru)); gtk_notebook_next_page(GTK_NOTEBOOK(mguru->notebook)); if(!mguru->multi) gnome_mguru_auto_state(mguru); return;}void gnome_mguru_prev_page(GnomeMGuru *mguru){ g_return_if_fail (mguru != NULL); g_return_if_fail (GNOME_IS_MGURU (mguru)); gtk_notebook_prev_page(GTK_NOTEBOOK(mguru->notebook)); if(!mguru->multi) gnome_mguru_auto_state(mguru); return;}void gnome_mguru_set_state(GnomeMGuru *mguru, GnomeMGuruState state){ g_return_if_fail (mguru != NULL); g_return_if_fail (GNOME_IS_MGURU (mguru)); switch(state){ case GNOME_MGURU_START: gtk_widget_set_sensitive(mguru->button[1],FALSE); gtk_widget_set_sensitive(mguru->button[2],TRUE); gtk_widget_set_sensitive(mguru->button[3],FALSE); break; case GNOME_MGURU_MIDDLE: gtk_widget_set_sensitive(mguru->button[1],TRUE); gtk_widget_set_sensitive(mguru->button[2],TRUE); gtk_widget_set_sensitive(mguru->button[3],FALSE); break; case GNOME_MGURU_LAST: gtk_widget_set_sensitive(mguru->button[1],TRUE); gtk_widget_set_sensitive(mguru->button[2],FALSE); gtk_widget_set_sensitive(mguru->button[3],TRUE); break; case GNOME_MGURU_ONLY: gtk_widget_set_sensitive(mguru->button[1],FALSE); gtk_widget_set_sensitive(mguru->button[2],FALSE); gtk_widget_set_sensitive(mguru->button[3],TRUE); break; } mguru->state=state;}void gnome_mguru_auto_state(GnomeMGuru *mguru){ int length; int current; length = g_list_length (GTK_NOTEBOOK(mguru->notebook)->children); if(!length) return; if(length == 1){ gnome_mguru_set_state(mguru,GNOME_MGURU_ONLY); return; } current = gnome_mguru_get_page(mguru); if(current < 1) gnome_mguru_set_state(mguru,GNOME_MGURU_START); else if(current == length-1) gnome_mguru_set_state(mguru,GNOME_MGURU_LAST); else gnome_mguru_set_state(mguru,GNOME_MGURU_MIDDLE); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -