ui_misc.c

来自「Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。」· C语言 代码 · 共 1,608 行 · 第 1/3 页

C
1,608
字号
/* * (SLIK) SimpLIstic sKin functions * (C) 2004 John Ellis * * Author: John Ellis * * This software is released under the GNU General Public License (GNU GPL). * Please read the included file COPYING for more information. * This software comes with no warranty of any kind, use at your own risk! */#ifdef HAVE_CONFIG_H#  include "config.h"#endif#include "intl.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <gtk/gtk.h>#include <gdk/gdkkeysyms.h>#include "ui_misc.h"#include "ui_bookmark.h"/* *----------------------------------------------------------------------------- * widget and layout utilities *----------------------------------------------------------------------------- */GtkWidget *pref_box_new(GtkWidget *parent_box, gint fill,			GtkOrientation orientation, gint padding){	GtkWidget *box;	if (orientation == GTK_ORIENTATION_HORIZONTAL)		{		box = gtk_hbox_new(FALSE, padding);		}	else		{		box = gtk_vbox_new(FALSE, padding);		}	gtk_box_pack_start(GTK_BOX(parent_box), box, fill, fill, 0);	gtk_widget_show(box);	return box;}GtkWidget *pref_group_new(GtkWidget *parent_box, gint fill,			  const gchar *text, GtkOrientation orientation){	GtkWidget *box;	GtkWidget *vbox;	GtkWidget *hbox;	GtkWidget *label;	vbox = gtk_vbox_new(FALSE, PREF_PAD_GAP);	/* add additional spacing if necessary */	if (GTK_IS_VBOX(parent_box) && GTK_BOX(parent_box)->children != NULL)		{		pref_spacer(vbox, PREF_PAD_GROUP - PREF_PAD_GAP);		}	gtk_box_pack_start(GTK_BOX(parent_box), vbox, fill, fill, 0);	gtk_widget_show(vbox);	label = gtk_label_new(text);	gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);	pref_label_bold(label, TRUE, FALSE);	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);	gtk_widget_show(label);	hbox = gtk_hbox_new(FALSE, PREF_PAD_INDENT);	gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);	gtk_widget_show(hbox);	/* indent using empty box */	pref_spacer(hbox, 0);	if (orientation == GTK_ORIENTATION_HORIZONTAL)		{		box = gtk_hbox_new(FALSE, PREF_PAD_SPACE);		}	else		{		box = gtk_vbox_new(FALSE, PREF_PAD_GAP);		}	gtk_box_pack_start(GTK_BOX(hbox), box, TRUE, TRUE, 0);	gtk_widget_show(box);	g_object_set_data(G_OBJECT(box), "pref_group", vbox);	return box;}GtkWidget *pref_group_parent(GtkWidget *child){	GtkWidget *parent;	parent = child;	while (parent)		{		GtkWidget *group;		group = g_object_get_data(G_OBJECT(parent), "pref_group");		if (group && GTK_IS_WIDGET(group)) return group;		parent = gtk_widget_get_parent(parent);		}	return child;}GtkWidget *pref_frame_new(GtkWidget *parent_box, gint fill,			  const gchar *text,			  GtkOrientation orientation, gint padding){	GtkWidget *box;	GtkWidget *frame = NULL;	frame = gtk_frame_new(text);	gtk_box_pack_start(GTK_BOX(parent_box), frame, fill, fill, 0);	gtk_widget_show(frame);	if (orientation == GTK_ORIENTATION_HORIZONTAL)		{		box = gtk_hbox_new(FALSE, padding);		}	else		{		box = gtk_vbox_new(FALSE, padding);		}	gtk_container_add(GTK_CONTAINER(frame), box);	gtk_container_set_border_width(GTK_CONTAINER(box), PREF_PAD_BORDER);	gtk_widget_show(box);	return box;}GtkWidget *pref_spacer(GtkWidget *parent_box, gint padding){	GtkWidget *spacer;	spacer = gtk_hbox_new(FALSE, 0);	gtk_box_pack_start(GTK_BOX(parent_box), spacer, FALSE, FALSE, padding / 2);	gtk_widget_show(spacer);	return spacer;}GtkWidget *pref_line(GtkWidget *parent_box, gint padding){	GtkWidget *spacer;	if (GTK_IS_HBOX(parent_box))		{		spacer = gtk_vseparator_new();		}	else		{		spacer = gtk_hseparator_new();		}	gtk_box_pack_start(GTK_BOX(parent_box), spacer, FALSE, FALSE, padding / 2);	gtk_widget_show(spacer);	return spacer;}GtkWidget *pref_label_new(GtkWidget *parent_box, const gchar *text){	GtkWidget *label;	label = gtk_label_new(text);	gtk_box_pack_start(GTK_BOX(parent_box), label, FALSE, FALSE, 0);	gtk_widget_show(label);	return label;}GtkWidget *pref_label_new_mnemonic(GtkWidget *parent_box, const gchar *text, GtkWidget *widget){	GtkWidget *label;	label = gtk_label_new_with_mnemonic(text);	gtk_label_set_mnemonic_widget(GTK_LABEL(label), widget);	gtk_box_pack_start(GTK_BOX(parent_box), label, FALSE, FALSE, 0);	gtk_widget_show(label);	return label;}void pref_label_bold(GtkWidget *label, gint bold, gint increase_size){	PangoAttrList *pal;	PangoAttribute *pa;	if (!bold && !increase_size) return;	pal = pango_attr_list_new();	if (bold)		{		pa = pango_attr_weight_new(PANGO_WEIGHT_BOLD);		pa->start_index = 0;		pa->end_index = G_MAXINT;		pango_attr_list_insert(pal, pa);		}	if (increase_size)		{		pa = pango_attr_scale_new(PANGO_SCALE_LARGE);		pa->start_index = 0;		pa->end_index = G_MAXINT;		pango_attr_list_insert(pal, pa);		}	gtk_label_set_attributes(GTK_LABEL(label), pal);	pango_attr_list_unref(pal);}GtkWidget *pref_button_new(GtkWidget *parent_box, const gchar *stock_id,			   const gchar *text, gint hide_stock_text,			   GCallback func, gpointer data){	GtkWidget *button;	if (stock_id && !text && !hide_stock_text)		{		button = gtk_button_new_from_stock(stock_id);		}	else		{		GtkWidget *image = NULL;		GtkWidget *label = NULL;		button = gtk_button_new();		if (stock_id) image = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_BUTTON);		if (text)			{			label = gtk_label_new_with_mnemonic(text);			gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);			gtk_label_set_mnemonic_widget(GTK_LABEL(label), button);			}		if (image && label)			{			GtkWidget *align;			GtkWidget *hbox;			hbox = gtk_hbox_new (FALSE, PREF_PAD_BUTTON_ICON_GAP);			align = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);			gtk_container_add(GTK_CONTAINER(button), align);			gtk_widget_show(align);			gtk_container_add(GTK_CONTAINER(align), hbox);			gtk_widget_show(hbox);			gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);			gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 0);			}		else			{			if (image)				{				gtk_container_add(GTK_CONTAINER(button), image);				}			else if (label)				{				gtk_container_add(GTK_CONTAINER(button), label);				}			}		if (image) gtk_widget_show(image);		if (label) gtk_widget_show(label);		}	if (func) g_signal_connect(G_OBJECT(button), "clicked", func, data);	if (parent_box)		{		gtk_box_pack_start(GTK_BOX(parent_box), button, FALSE, FALSE, 0);		gtk_widget_show(button);		}	return button;}static GtkWidget *real_pref_checkbox_new(GtkWidget *parent_box, const gchar *text, gint mnemonic_text,					 gint active, GCallback func, gpointer data){	GtkWidget *button;	if (mnemonic_text)		{		button = gtk_check_button_new_with_mnemonic(text);		}	else		{		button = gtk_check_button_new_with_label(text);		}	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), active);	if (func) g_signal_connect(G_OBJECT(button), "clicked", func, data);	gtk_box_pack_start(GTK_BOX(parent_box), button, FALSE, FALSE, 0);	gtk_widget_show(button);	return button;}GtkWidget *pref_checkbox_new(GtkWidget *parent_box, const gchar *text, gint active,			     GCallback func, gpointer data){	return real_pref_checkbox_new(parent_box, text, FALSE, active, func, data);}GtkWidget *pref_checkbox_new_mnemonic(GtkWidget *parent_box, const gchar *text, gint active,				      GCallback func, gpointer data){	return real_pref_checkbox_new(parent_box, text, TRUE, active, func, data);}static void pref_checkbox_int_cb(GtkWidget *widget, gpointer data){	gint *result = data;	*result = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));}GtkWidget *pref_checkbox_new_int(GtkWidget *parent_box, const gchar *text, gint active,				 gint *result){	GtkWidget *button;	button = pref_checkbox_new(parent_box, text, active,				   G_CALLBACK(pref_checkbox_int_cb), result);	*result = active;	return button;}static void pref_checkbox_link_sensitivity_cb(GtkWidget *button, gpointer data){	GtkWidget *widget = data;	gtk_widget_set_sensitive(widget, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)));}void pref_checkbox_link_sensitivity(GtkWidget *button, GtkWidget *widget){	g_signal_connect(G_OBJECT(button), "toggled",			 G_CALLBACK(pref_checkbox_link_sensitivity_cb), widget);	pref_checkbox_link_sensitivity_cb(button, widget);}static void pref_checkbox_link_sensitivity_swap_cb(GtkWidget *button, gpointer data){	GtkWidget *widget = data;	gtk_widget_set_sensitive(widget, !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)));}void pref_checkbox_link_sensitivity_swap(GtkWidget *button, GtkWidget *widget){	g_signal_connect(G_OBJECT(button), "toggled",			 G_CALLBACK(pref_checkbox_link_sensitivity_swap_cb), widget);	pref_checkbox_link_sensitivity_swap_cb(button, widget);}static GtkWidget *real_pref_radiobutton_new(GtkWidget *parent_box, GtkWidget *sibling,					    const gchar *text, gint mnemonic_text, gint active,					    GCallback func, gpointer data){	GtkWidget *button;	GSList* group;	if (sibling)		{		group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(sibling));		}	else		{		group = NULL;		}	if (mnemonic_text)		{		button = gtk_radio_button_new_with_mnemonic(group, text);		}	else		{		button = gtk_radio_button_new_with_label(group, text);		}	if (active) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), active);	if (func) g_signal_connect(G_OBJECT(button), "clicked", func, data);	gtk_box_pack_start(GTK_BOX(parent_box), button, FALSE, FALSE, 0);	gtk_widget_show(button);	return button;}GtkWidget *pref_radiobutton_new(GtkWidget *parent_box, GtkWidget *sibling,				const gchar *text, gint active,				GCallback func, gpointer data){	return real_pref_radiobutton_new(parent_box, sibling, text, FALSE, active, func, data);}GtkWidget *pref_radiobutton_new_mnemonic(GtkWidget *parent_box, GtkWidget *sibling,					 const gchar *text, gint active,					 GCallback func, gpointer data){	return real_pref_radiobutton_new(parent_box, sibling, text, TRUE, active, func, data);}#define PREF_RADIO_VALUE_KEY "pref_radio_value"static void pref_radiobutton_int_cb(GtkWidget *widget, gpointer data){	gint *result = data;	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))		{		*result = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), PREF_RADIO_VALUE_KEY));		}}GtkWidget *pref_radiobutton_new_int(GtkWidget *parent_box, GtkWidget *sibling,				    const gchar *text, gint active,				    gint *result, gint value,				    GCallback func, gpointer data){	GtkWidget *button;	button = pref_radiobutton_new(parent_box, sibling, text, active,				      G_CALLBACK(pref_radiobutton_int_cb), result);	g_object_set_data(G_OBJECT(button), PREF_RADIO_VALUE_KEY, GINT_TO_POINTER(value));	if (active) *result = value;	return button;}static GtkWidget *real_pref_spin_new(GtkWidget *parent_box, const gchar *text, const gchar *suffix,				     gint mnemonic_text,				     gdouble min, gdouble max, gdouble step, gint digits,				     gdouble value,				     GCallback func, gpointer data){	GtkWidget *spin;	GtkWidget *box;	GtkWidget *label;	box = pref_box_new(parent_box, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);	spin = gtk_spin_button_new_with_range(min, max, step);	gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), digits);	gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), value);	if (func)		{		g_signal_connect(G_OBJECT(spin), "value_changed", G_CALLBACK(func), data);		}	if (text)		{		if (mnemonic_text)			{			label = pref_label_new_mnemonic(box, text, spin);			}		else			{			label = pref_label_new(box, text);			}		pref_link_sensitivity(label, spin);		}	gtk_box_pack_start(GTK_BOX(box), spin, FALSE, FALSE, 0);	gtk_widget_show(spin);	/* perhaps this should only be PREF_PAD_GAP distance from spinbutton ? */	if (suffix)		{		label =  pref_label_new(box, suffix);		pref_link_sensitivity(label, spin);		}	return spin;}GtkWidget *pref_spin_new(GtkWidget *parent_box, const gchar *text, const gchar *suffix,			 gdouble min, gdouble max, gdouble step, gint digits,			 gdouble value,			 GCallback func, gpointer data){	return real_pref_spin_new(parent_box, text, suffix, FALSE,				  min, max, step, digits, value, func, data);}GtkWidget *pref_spin_new_mnemonic(GtkWidget *parent_box, const gchar *text, const gchar *suffix,				  gdouble min, gdouble max, gdouble step, gint digits,				  gdouble value,				  GCallback func, gpointer data){	return real_pref_spin_new(parent_box, text, suffix, TRUE,				  min, max, step, digits, value, func, data);}static void pref_spin_int_cb(GtkWidget *widget, gpointer data){	gint *var = data;	*var = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));}GtkWidget *pref_spin_new_int(GtkWidget *parent_box, const gchar *text, const gchar *suffix,			     gint min, gint max, gint step,			     gint value, gint *value_var){	*value_var = value;	return pref_spin_new(parent_box, text, suffix,			     (gdouble)min, (gdouble)max, (gdouble)step, 0,			     value,			     G_CALLBACK(pref_spin_int_cb), value_var);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?