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(<);}/* *----------------------------------------------------------------------------- * 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 + -
显示快捷键?