ui_misc.c

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

C
1,608
字号
	g_object_set_data(G_OBJECT(ds->box), DATE_SELECION_KEY, ds);	return ds->box;}                                                                                                                        void date_selection_set(GtkWidget *widget, gint day, gint month, gint year){	DateSelection *ds;	ds = g_object_get_data(G_OBJECT(widget), DATE_SELECION_KEY);	if (!ds) return;	gtk_spin_button_set_value(GTK_SPIN_BUTTON(ds->spin_d), (gdouble)day);	gtk_spin_button_set_value(GTK_SPIN_BUTTON(ds->spin_m), (gdouble)month);	gtk_spin_button_set_value(GTK_SPIN_BUTTON(ds->spin_y), (gdouble)year);}void date_selection_get(GtkWidget *widget, gint *day, gint *month, gint *year){	DateSelection *ds;	ds = g_object_get_data(G_OBJECT(widget), DATE_SELECION_KEY);	if (!ds) return;	if (day) *day = gtk_spin_button_get_value(GTK_SPIN_BUTTON(ds->spin_d));	if (month) *month = gtk_spin_button_get_value(GTK_SPIN_BUTTON(ds->spin_m));	if (year) *year = gtk_spin_button_get_value(GTK_SPIN_BUTTON(ds->spin_y));}                                                                                                                        void date_selection_time_set(GtkWidget *widget, time_t t){	struct tm *lt;	lt = localtime(&t);	if (!lt) return;	date_selection_set(widget, lt->tm_mday, lt->tm_mon + 1, lt->tm_year + 1900);}time_t date_selection_time_get(GtkWidget *widget){	struct tm lt;	gint day = 0;	gint month = 0;	gint year = 0;	date_selection_get(widget, &day, &month ,&year);	lt.tm_sec = 0;	lt.tm_min = 0;	lt.tm_hour = 0;	lt.tm_mday = day;	lt.tm_mon = month - 1;	lt.tm_year = year - 1900;	lt.tm_isdst = 0;	return mktime(&lt);}/* *----------------------------------------------------------------------------- * Sizer, without using a GtkPaned *----------------------------------------------------------------------------- */#define SIZER_DATA_KEY "sizer_data"typedef struct _SizerData SizerData;struct _SizerData{	GtkWidget *sizer;	GtkWidget *parent;	GtkWidget *bounding_widget;	SizerPositionType position;	gint hsize_min;	gint hsize_max;	gint vsize_min;	gint vsize_max;	gint in_drag;	gint press_x;	gint press_y;	gint press_width;	gint press_height;	gint handle_prelit;};static gint sizer_default_handle_size(void){	gint handle_size = 5;	GtkWidget *paned;	GtkStyle *style;	paned = gtk_hpaned_new();	style = gtk_rc_get_style(paned);	gtk_widget_set_style(paned, style);	gtk_widget_style_get(paned, "handle_size", &handle_size, NULL);	gtk_widget_destroy(paned);	return handle_size;}static gint sizer_motion_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){	SizerData *sd = data;	gint x, y;	gint w, h;	if (!sd->in_drag) return FALSE;	x = sd->press_x - bevent->x_root;	y = sd->press_y - bevent->y_root;	w = sd->press_width;	h = sd->press_height;	if (sd->position & SIZER_POS_LEFT)		{		w += x;		}	else if (sd->position & SIZER_POS_RIGHT)		{		w -= x;		}	if (sd->position & SIZER_POS_TOP)		{		h += y;		}	else if (sd->position & SIZER_POS_BOTTOM)		{		h -= y;		}	if (sd->hsize_min >= 0) w = MAX(w, sd->hsize_min);	if (sd->vsize_min >= 0) h = MAX(h, sd->vsize_min);	if (sd->bounding_widget)		{		w = CLAMP(w, sd->sizer->allocation.width, sd->bounding_widget->allocation.width);		h = CLAMP(h, sd->sizer->allocation.height, sd->bounding_widget->allocation.height);		}	else		{		if (w < sd->sizer->allocation.width) w = sd->sizer->allocation.width;		if (h < sd->sizer->allocation.height) h = sd->sizer->allocation.height;		}	if (sd->hsize_max >= 0) w = MIN(w, sd->hsize_max);	if (sd->vsize_max >= 0) h = MIN(h, sd->vsize_max);	if (w == sd->parent->allocation.width) w = -1;	if (h == sd->parent->allocation.height) h = -1;	if (w > 0 || h > 0) gtk_widget_set_size_request(sd->parent, w, h);	return TRUE;}static gint sizer_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){	SizerData *sd = data;	if (bevent->button != 1) return FALSE;	sd->in_drag = TRUE;	sd->press_x = bevent->x_root;	sd->press_y = bevent->y_root;	sd->press_width = sd->parent->allocation.width;	sd->press_height = sd->parent->allocation.height;	gdk_pointer_grab(sd->sizer->window, FALSE,			 GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,			 NULL, NULL, bevent->time);	gtk_grab_add(sd->sizer);	return TRUE;}static gint sizer_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){	SizerData *sd = data;	if (bevent->button != 1) return FALSE;	if (gdk_pointer_is_grabbed() && GTK_WIDGET_HAS_GRAB(sd->sizer))		{		gtk_grab_remove(sd->sizer);		gdk_pointer_ungrab(bevent->time);		}	sd->in_drag = FALSE;	return TRUE;}static void sizer_set_prelight(SizerData *sd, gint prelit){	sd->handle_prelit = prelit;	gtk_widget_queue_draw_area(sd->sizer, 0, 0,				   sd->sizer->allocation.width, sd->sizer->allocation.height);}static gint sizer_enter_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data){	SizerData *sd = data;	sizer_set_prelight(sd, TRUE);	return TRUE;}static gint sizer_leave_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data){	SizerData *sd = data;	sizer_set_prelight(sd, FALSE);	return TRUE;}static gint sizer_expose_cb(GtkWidget *widget, GdkEventExpose *event, gpointer data){	SizerData *sd = data;	GdkRectangle clip;	GtkOrientation orientation;	GtkStateType state;	gdk_region_get_clipbox(event->region, &clip);	if (sd->position & SIZER_POS_LEFT || sd->position & SIZER_POS_RIGHT)		{		orientation = GTK_ORIENTATION_VERTICAL;		}	else		{		orientation = GTK_ORIENTATION_HORIZONTAL;		}	if (sd->handle_prelit)		{		state = GTK_STATE_PRELIGHT;		}	else		{		state = widget->state;		}	gtk_paint_handle(widget->style, widget->window, state,			 GTK_SHADOW_NONE, &clip, widget, "paned",			 0, 0,			 widget->allocation.width, widget->allocation.height,			 orientation);	return TRUE;}static void sizer_realize_cb(GtkWidget *widget, gpointer data){	SizerData *sd = data;	GdkCursorType n;	n = 0;	if (sd->position & SIZER_POS_TOP || sd->position & SIZER_POS_BOTTOM)		{		n = GDK_SB_V_DOUBLE_ARROW;		}	if (sd->position & SIZER_POS_LEFT || sd->position & SIZER_POS_RIGHT)		{		n = (n != 0) ? GDK_FLEUR : GDK_SB_H_DOUBLE_ARROW;		}	if (n != 0 && widget->window)		{		GdkCursor *cursor;		cursor = gdk_cursor_new(n);		gdk_window_set_cursor(widget->window, cursor);		gdk_cursor_unref(cursor);		}}static void sizer_destroy_cb(GtkWidget *widget, gpointer data){	SizerData *sd = data;	g_free(sd);}GtkWidget *sizer_new(GtkWidget *parent, GtkWidget *bounding_widget,		     SizerPositionType position){	SizerData *sd;	gint handle_size;	sd = g_new0(SizerData, 1);	sd->sizer = gtk_event_box_new();	sd->parent = parent;	sd->bounding_widget = bounding_widget;	sd->position = position;	sd->hsize_min = -1;	sd->hsize_max = -1;	sd->vsize_min = -1;	sd->vsize_max = -1;	sd->in_drag = FALSE;	sd->handle_prelit = FALSE;	g_signal_connect(G_OBJECT(sd->sizer), "destroy",			 G_CALLBACK(sizer_destroy_cb), sd);	g_signal_connect(G_OBJECT(sd->sizer), "motion_notify_event",			 G_CALLBACK(sizer_motion_cb), sd);	g_signal_connect(G_OBJECT(sd->sizer), "button_press_event",			 G_CALLBACK(sizer_press_cb), sd);	g_signal_connect(G_OBJECT(sd->sizer), "button_release_event",			 G_CALLBACK(sizer_release_cb), sd);	g_signal_connect(G_OBJECT(sd->sizer), "enter_notify_event",			 G_CALLBACK(sizer_enter_cb), sd);	g_signal_connect(G_OBJECT(sd->sizer), "leave_notify_event",			 G_CALLBACK(sizer_leave_cb), sd);	gtk_widget_set_events(sd->sizer, GDK_POINTER_MOTION_MASK |					 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK |					 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);	g_signal_connect(sd->sizer, "realize",			 G_CALLBACK(sizer_realize_cb), sd);	g_signal_connect(sd->sizer, "expose_event",			 G_CALLBACK(sizer_expose_cb), sd);	handle_size = sizer_default_handle_size();	gtk_widget_set_size_request(sd->sizer, handle_size, handle_size);#if 0	/* use this if you add a shadow border to the handle */	gtk_widget_set_size_request(sd->sizer, handle_size + sd->sizer->style->xthickness * 2,					       handle_size + sd->sizer->style->ythickness * 2);#endif	g_object_set_data(G_OBJECT(sd->sizer), SIZER_DATA_KEY,sd);	return sd->sizer;}void sizer_set_limits(GtkWidget *sizer,		      gint hsize_min, gint hsize_max,		      gint vsize_min, gint vsize_max){	SizerData *sd;	sd = g_object_get_data(G_OBJECT(sizer), SIZER_DATA_KEY);	if (!sd) return;	sd->hsize_min = hsize_min;	sd->hsize_max = hsize_max;	sd->vsize_min = vsize_min;	sd->vsize_max = vsize_max;}/* *----------------------------------------------------------------------------- * storing data in a history list with key,data pairs *----------------------------------------------------------------------------- */#define PREF_LIST_MARKER_INT "[INT]:"#define PREF_LIST_MARKER_DOUBLE "[DOUBLE]:"#define PREF_LIST_MARKER_STRING "[STRING]:"static GList *pref_list_find(const gchar *group, const gchar *token){	GList *work;	gint l;	l = strlen(token);	work = history_list_get_by_key(group);	while (work)		{		const gchar *text = work->data;		if (strncmp(text, token, l) == 0) return work;		work = work->next;		}	return NULL;}static gint pref_list_get(const gchar *group, const gchar *key, const gchar *marker, const gchar **result){	gchar *token;	GList *work;	gint ret;	if (!group || !key || !marker)		{		*result = NULL;		return FALSE;		}	token = g_strconcat(key, marker, NULL);	work = pref_list_find(group, token);	if (work)		{		*result = (const gchar *)work->data + strlen(token);		if (strlen(*result) == 0) *result = NULL;		ret = TRUE;		}	else		{		*result = NULL;		ret = FALSE;		}	g_free(token);	return ret; }static void pref_list_set(const gchar *group, const gchar *key, const gchar *marker, const gchar *text){	gchar *token;	gchar *path;	GList *work;	if (!group || !key || !marker) return;	token = g_strconcat(key, marker, NULL);	path = g_strconcat(token, text, NULL);	work = pref_list_find(group, token);	if (work)		{		gchar *old_path = work->data;		if (text)			{			work->data = path;			path = NULL;			g_free(old_path);			}		else			{			history_list_item_remove(group, old_path);			}		}	else if (text)		{		history_list_add_to_key(group, path, 0);		}	g_free(path);	g_free(token);}void pref_list_int_set(const gchar *group, const gchar *key, gint value){	gchar *text;	text = g_strdup_printf("%d", value);	pref_list_set(group, key, PREF_LIST_MARKER_INT, text);	g_free(text);}gint pref_list_int_get(const gchar *group, const gchar *key, gint *result){	const gchar *text;	if (!group || !key)		{		*result = 0;		return FALSE;		}	if (pref_list_get(group, key, PREF_LIST_MARKER_INT, &text) && text)		{		*result = (gint)strtol(text, NULL, 10);		return TRUE;		}	*result = 0;	return FALSE;}void pref_list_double_set(const gchar *group, const gchar *key, gdouble value){	gchar text[G_ASCII_DTOSTR_BUF_SIZE];	g_ascii_dtostr(text, sizeof(text), value);	pref_list_set(group, key, PREF_LIST_MARKER_DOUBLE, text);}gint pref_list_double_get(const gchar *group, const gchar *key, gdouble *result){	const gchar *text;	if (!group || !key)		{		*result = 0;		return FALSE;		}	if (pref_list_get(group, key, PREF_LIST_MARKER_DOUBLE, &text) && text)		{		*result = g_ascii_strtod(text, NULL);		return TRUE;		}	*result = 0;	return FALSE;}void pref_list_string_set(const gchar *group, const gchar *key, const gchar *value){	pref_list_set(group, key, PREF_LIST_MARKER_STRING, value);}gint pref_list_string_get(const gchar *group, const gchar *key, const gchar **result){	return pref_list_get(group, key, PREF_LIST_MARKER_STRING, result);}

⌨️ 快捷键说明

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