📄 ui_tree_edit.c
字号:
}gint tree_view_row_get_visibility(GtkTreeView *widget, GtkTreeIter *iter, gint fully_visible){ GtkTreeModel *store; GtkTreePath *tpath; gint cx, cy; GdkRectangle vrect; GdkRectangle crect; if (!GTK_WIDGET_REALIZED(GTK_WIDGET(widget))) return 0; store = gtk_tree_view_get_model(widget); tpath = gtk_tree_model_get_path(store, iter); gtk_tree_view_get_visible_rect(widget, &vrect); gtk_tree_view_get_cell_area(widget, tpath, NULL, &crect); gtk_tree_path_free(tpath); gtk_tree_view_widget_to_tree_coords(widget, crect.x, crect.y, &cx, &cy); if (fully_visible) { if (cy < vrect.y) return -1; if (cy + crect.height > vrect.y + vrect.height) return 1; return 0; } if (cy + crect.height < vrect.y) return -1; if (cy > vrect.y + vrect.height) return 1; return 0;}gint tree_view_row_make_visible(GtkTreeView *widget, GtkTreeIter *iter, gint center){ GtkTreePath *tpath; gint vis; vis = tree_view_row_get_visibility(widget, iter, TRUE); tpath = gtk_tree_model_get_path(gtk_tree_view_get_model(widget), iter); if (center && vis != 0) { gtk_tree_view_scroll_to_cell(widget, tpath, NULL, TRUE, 0.5, 0.0); } else if (vis < 0) { gtk_tree_view_scroll_to_cell(widget, tpath, NULL, TRUE, 0.0, 0.0); } else if (vis > 0) { gtk_tree_view_scroll_to_cell(widget, tpath, NULL, TRUE, 1.0, 0.0); } gtk_tree_path_free(tpath); return vis;}gint tree_view_move_cursor_away(GtkTreeView *widget, GtkTreeIter *iter, gint only_selected){ GtkTreeModel *store; GtkTreePath *tpath; GtkTreePath *fpath; gint move = FALSE; if (!iter) return FALSE; store = gtk_tree_view_get_model(widget); tpath = gtk_tree_model_get_path(store, iter); gtk_tree_view_get_cursor(widget, &fpath, NULL); if (fpath && gtk_tree_path_compare(tpath, fpath) == 0) { GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(widget); if (!only_selected || gtk_tree_selection_path_is_selected(selection, tpath)) { GtkTreeIter current; current = *iter; if (gtk_tree_model_iter_next(store, ¤t)) { gtk_tree_path_next(tpath); move = TRUE; } else if (gtk_tree_path_prev(tpath) && gtk_tree_model_get_iter(store, ¤t, tpath)) { move = TRUE; } if (move) { gtk_tree_view_set_cursor(widget, tpath, NULL, FALSE); } } } gtk_tree_path_free(tpath); if (fpath) gtk_tree_path_free(fpath); return move;}gint tree_path_to_row(GtkTreePath *tpath){ gint *indices; indices = gtk_tree_path_get_indices(tpath); if (indices) return indices[0]; return -1;}/* *------------------------------------------------------------------- * color utilities *------------------------------------------------------------------- */void shift_color(GdkColor *src, gshort val, gint direction){ gshort cs; if (val == -1) { val = STYLE_SHIFT_STANDARD; } else { val = CLAMP(val, 1, 100); } cs = 0xffff / 100 * val; /* up or down ? */ if (direction < 0 || (direction == 0 &&((gint)src->red + (gint)src->green + (gint)src->blue) / 3 > 0xffff / 2)) { src->red = MAX(0 , src->red - cs); src->green = MAX(0 , src->green - cs); src->blue = MAX(0 , src->blue - cs); } else { src->red = MIN(0xffff, src->red + cs); src->green = MIN(0xffff, src->green + cs); src->blue = MIN(0xffff, src->blue + cs); }}/* darkens or lightens a style's color for given state * esp. useful for alternating dark/light in (c)lists */void style_shift_color(GtkStyle *style, GtkStateType type, gshort shift_value, gint direction){ if (!style) return; shift_color(&style->base[type], shift_value, direction); shift_color(&style->bg[type], shift_value, direction);}/* *------------------------------------------------------------------- * auto scroll by mouse position *------------------------------------------------------------------- */#define AUTO_SCROLL_DEFAULT_SPEED 100#define AUTO_SCROLL_DEFAULT_REGION 20typedef struct _AutoScrollData AutoScrollData;struct _AutoScrollData{ gint timer_id; gint region_size; GtkWidget *widget; GtkAdjustment *adj; gint max_step; gint (*notify_func)(GtkWidget *, gint, gint, gpointer); gpointer notify_data;};void widget_auto_scroll_stop(GtkWidget *widget){ AutoScrollData *sd; sd = g_object_get_data(G_OBJECT(widget), "autoscroll"); if (!sd) return; g_object_set_data(G_OBJECT(widget), "autoscroll", NULL); if (sd->timer_id != -1) g_source_remove(sd->timer_id); g_free(sd);}static gint widget_auto_scroll_cb(gpointer data){ AutoScrollData *sd = data; GdkWindow *window; gint x, y; gint w, h; gint amt = 0; if (sd->max_step < sd->region_size) { sd->max_step = MIN(sd->region_size, sd->max_step + 2); } window = sd->widget->window; gdk_window_get_pointer(window, &x, &y, NULL); gdk_drawable_get_size(window, &w, &h); if (x < 0 || x >= w || y < 0 || y >= h) { sd->timer_id = -1; widget_auto_scroll_stop(sd->widget); return FALSE; } if (h < sd->region_size * 3) { /* height is cramped, nicely divide into three equal regions */ if (y < h / 3 || y > h / 3 * 2) { amt = (y < h / 2) ? 0 - ((h / 2) - y) : y - (h / 2); } } else if (y < sd->region_size) { amt = 0 - (sd->region_size - y); } else if (y >= h - sd->region_size) { amt = y - (h - sd->region_size); } if (amt != 0) { amt = CLAMP(amt, 0 - sd->max_step, sd->max_step); if (sd->adj->value != CLAMP(sd->adj->value + amt, sd->adj->lower, sd->adj->upper - sd->adj->page_size)) { /* only notify when scrolling is needed */ if (sd->notify_func && !sd->notify_func(sd->widget, x, y, sd->notify_data)) { sd->timer_id = -1; widget_auto_scroll_stop(sd->widget); return FALSE; } gtk_adjustment_set_value(sd->adj, CLAMP(sd->adj->value + amt, sd->adj->lower, sd->adj->upper - sd->adj->page_size)); } } return TRUE;}gint widget_auto_scroll_start(GtkWidget *widget, GtkAdjustment *v_adj, gint scroll_speed, gint region_size, gint (*notify_func)(GtkWidget *widget, gint x, gint y, gpointer data), gpointer notify_data){ AutoScrollData *sd; if (!widget || !v_adj) return 0; if (g_object_get_data(G_OBJECT(widget), "autoscroll")) return 0; if (scroll_speed < 1) scroll_speed = AUTO_SCROLL_DEFAULT_SPEED; if (region_size < 1) region_size = AUTO_SCROLL_DEFAULT_REGION; sd = g_new0(AutoScrollData, 1); sd->widget = widget; sd->adj = v_adj; sd->region_size = region_size; sd->max_step = 1; sd->timer_id = g_timeout_add(scroll_speed, widget_auto_scroll_cb, sd); sd->notify_func = notify_func; sd->notify_data = notify_data; g_object_set_data(G_OBJECT(widget), "autoscroll", sd); return scroll_speed;}/* *------------------------------------------------------------------- * GList utils *------------------------------------------------------------------- */GList *uig_list_insert_link(GList *list, GList *link, gpointer data){ GList *new_list; if (!list || link == list) return g_list_prepend(list, data); if (!link) return g_list_append(list, data); new_list = g_list_alloc (); new_list->data = data; if (link->prev) { link->prev->next = new_list; new_list->prev = link->prev; } else { list = new_list; } link->prev = new_list; new_list->next = link; return list;}GList *uig_list_insert_list(GList *parent, GList *insert_link, GList *list){ GList *end; if (!insert_link) return g_list_concat(parent, list); if (insert_link == parent) return g_list_concat(list, parent); if (!parent) return list; if (!list) return parent; end = g_list_last(list); if (insert_link->prev) insert_link->prev->next = list; list->prev = insert_link->prev; insert_link->prev = end; end->next = insert_link; return parent;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -