#include "snd.h" #if GTK_CHECK_VERSION(3, 96, 0) int snd_strlen(const char *str) { char *tmp = (char *)str; if ((!tmp) || (!(*tmp))) return(0); while (*tmp++) {}; return(tmp - str - 1); } #endif #if (!GTK_CHECK_VERSION(3, 89, 0)) #if GTK_CHECK_VERSION(3, 22, 0) static GdkWindow *last_window = NULL; static GdkDrawingContext *last_context = NULL; #endif #if GTK_CHECK_VERSION(3, 0, 0) cairo_t *make_cairo(GdkWindow *win) #else cairo_t *make_cairo(GdkDrawable *win) #endif { ss->line_width = -1.0; #if GTK_CHECK_VERSION(3, 22, 0) last_window = win; last_context = gdk_window_begin_draw_frame(win, gdk_window_get_visible_region(win)); return(gdk_drawing_context_get_cairo_context(last_context)); #else return(gdk_cairo_create(win)); #endif } void free_cairo(cairo_t *cr) { ss->line_width = -1.0; #if GTK_CHECK_VERSION(3, 22, 0) gdk_window_end_draw_frame(last_window, last_context); #else cairo_destroy(cr); #endif } #endif bool set_tiny_font(const char *font) { PangoFontDescription *fs = NULL; if ((font) && (font[0] == '/')) return(false); /* pango accepts bogus font names, but then cairo segfaults trying to get the font height */ fs = pango_font_description_from_string(font); if (fs) { if (tiny_font(ss)) free(tiny_font(ss)); in_set_tiny_font(mus_strdup(font)); if (TINY_FONT(ss)) pango_font_description_free(TINY_FONT(ss)); TINY_FONT(ss) = fs; return(true); } return(false); } bool set_listener_font(const char *font) { PangoFontDescription *fs = NULL; if ((font) && (font[0] == '/')) return(false); fs = pango_font_description_from_string(font); if (fs) { if (listener_font(ss)) free(listener_font(ss)); in_set_listener_font(mus_strdup(font)); if (LISTENER_FONT(ss)) pango_font_description_free(LISTENER_FONT(ss)); LISTENER_FONT(ss) = fs; set_listener_text_font(); return(true); } return(false); } bool set_peaks_font(const char *font) { PangoFontDescription *fs = NULL; if ((font) && (font[0] == '/')) return(false); fs = pango_font_description_from_string(font); if (fs) { if (peaks_font(ss)) free(peaks_font(ss)); in_set_peaks_font(mus_strdup(font)); if (PEAKS_FONT(ss)) pango_font_description_free(PEAKS_FONT(ss)); PEAKS_FONT(ss) = fs; return(true); } return(false); } bool set_bold_peaks_font(const char *font) { PangoFontDescription *fs = NULL; if ((font) && (font[0] == '/')) return(false); fs = pango_font_description_from_string(font); if (fs) { if (bold_peaks_font(ss)) free(bold_peaks_font(ss)); in_set_bold_peaks_font(mus_strdup(font)); if (BOLD_PEAKS_FONT(ss)) pango_font_description_free(BOLD_PEAKS_FONT(ss)); BOLD_PEAKS_FONT(ss) = fs; return(true); } return(false); } bool set_axis_label_font(const char *font) { PangoFontDescription *fs = NULL; if ((font) && (font[0] == '/')) return(false); fs = pango_font_description_from_string(font); if (fs) { if (axis_label_font(ss)) free(axis_label_font(ss)); in_set_axis_label_font(mus_strdup(font)); if (AXIS_LABEL_FONT(ss)) pango_font_description_free(AXIS_LABEL_FONT(ss)); AXIS_LABEL_FONT(ss) = fs; return(true); } return(false); } bool set_axis_numbers_font(const char *font) { PangoFontDescription *fs = NULL; if ((font) && (font[0] == '/')) return(false); fs = pango_font_description_from_string(font); if (fs) { if (axis_numbers_font(ss)) free(axis_numbers_font(ss)); in_set_axis_numbers_font(mus_strdup(font)); if (AXIS_NUMBERS_FONT(ss)) pango_font_description_free(AXIS_NUMBERS_FONT(ss)); AXIS_NUMBERS_FONT(ss) = fs; return(true); } return(false); } int sg_text_width(const char *txt, PangoFontDescription *font) { int wid = 0; if (!txt) return(0); if (mus_strlen(txt) == 0) return(0); if (!(g_utf8_validate(txt, -1, NULL))) return(0); #if (!GTK_CHECK_VERSION(3, 94, 0)) { PangoLayout *layout = NULL; PangoContext *ctx; ctx = gdk_pango_context_get(); layout = pango_layout_new(ctx); if (layout) { pango_layout_set_font_description(layout, font); pango_layout_set_text(layout, txt, -1); pango_layout_get_pixel_size(layout, &wid, NULL); /* huge (6MBytes!) memleak here */ g_object_unref(G_OBJECT(layout)); } g_object_unref(ctx); } #endif return(wid); } int mark_name_width(const char *txt) { if (txt) return(sg_text_width(txt, PEAKS_FONT(ss))); return(0); } int label_width(const char *txt, bool use_tiny_font) { if (txt) return(sg_text_width(txt, (use_tiny_font) ? TINY_FONT(ss) : AXIS_LABEL_FONT(ss))); else return(0); } int number_width(const char *num, bool use_tiny_font) { if (num) return(sg_text_width(num, (use_tiny_font) ? TINY_FONT(ss) : AXIS_NUMBERS_FONT(ss))); return(0); } #if 0 static int sg_font_width(PangoFontDescription *font) { /* returns size in pixels */ int wid; double dpi; #if HAVE_GTK_LINK_BUTTON_NEW dpi = gdk_screen_get_resolution(gdk_display_get_default_screen(gdk_display_get_default())); /* pixels/inch */ #else dpi = 96.0; /* see below */ #endif #if (!GTK_CHECK_VERSION(3, 94, 0)) { PangoContext *ctx; PangoFontMetrics *m; ctx = gdk_pango_context_get(); m = pango_context_get_metrics(ctx, font, gtk_get_default_language()); /* returns size in pango-scaled points (1024/72 inch) */ wid = (int)((dpi / 72.0) * PANGO_PIXELS(pango_font_metrics_get_approximate_char_width(m))); pango_font_metrics_unref(m); g_object_unref(ctx); } #else wid = (int)(dpi / 72.0); #endif return(wid); } #endif static int sg_font_height(PangoFontDescription *font) { /* returns size in pixels */ double dpi; int hgt; #if HAVE_GTK_LINK_BUTTON_NEW /* gtk 2.1: gdk_display_get_default, gdk_display_get_default_screen */ /* gtk 2.9: gdk_screen_get_resolution */ dpi = gdk_screen_get_resolution(gdk_display_get_default_screen(gdk_display_get_default())); #else dpi = 96.0; /* a plausible guess */ #endif #if (!GTK_CHECK_VERSION(3, 94, 0)) { PangoContext *ctx; PangoFontMetrics *m; ctx = gdk_pango_context_get(); m = pango_context_get_metrics(ctx, font, gtk_get_default_language()); hgt = (int)((dpi / 72.0) * PANGO_PIXELS(pango_font_metrics_get_ascent(m))); pango_font_metrics_unref(m); g_object_unref(ctx); } #else hgt = (int)(dpi / 72.0); #endif return(hgt); } static PangoFontDescription *last_tiny_font = NULL, *last_numbers_font = NULL, *last_label_font = NULL, *last_peaks_font = NULL; static int last_numbers_height = 14, last_tiny_height = 10, last_label_height = 14, last_peaks_height = 10; int number_height(PangoFontDescription *font) { int hgt = 14; if (font == TINY_FONT(ss)) { if (last_tiny_font == TINY_FONT(ss)) return(last_tiny_height); hgt = sg_font_height(TINY_FONT(ss)); last_tiny_font = TINY_FONT(ss); last_tiny_height = hgt; } else { if (font == AXIS_NUMBERS_FONT(ss)) { if (last_numbers_font == AXIS_NUMBERS_FONT(ss)) return(last_numbers_height); hgt = sg_font_height(AXIS_NUMBERS_FONT(ss)); last_numbers_font = AXIS_NUMBERS_FONT(ss); last_numbers_height = hgt; } else { if (last_peaks_font == PEAKS_FONT(ss)) return(last_peaks_height); hgt = sg_font_height(PEAKS_FONT(ss)); last_peaks_font = PEAKS_FONT(ss); last_peaks_height = hgt; } } return(hgt); } int label_height(bool use_tiny_font) { int hgt = 14; if (use_tiny_font) { if (last_tiny_font == TINY_FONT(ss)) return(last_tiny_height); hgt = sg_font_height(TINY_FONT(ss)); last_tiny_font = TINY_FONT(ss); last_tiny_height = hgt; } else { if (last_label_font == AXIS_LABEL_FONT(ss)) return(last_label_height); hgt = sg_font_height(AXIS_LABEL_FONT(ss)); last_label_font = AXIS_LABEL_FONT(ss); last_label_height = hgt; } return(hgt); } void clear_window(graphics_context *ax) { /* if (ax) gdk_window_clear(ax->wn); */ } void raise_dialog(GtkWidget *w) { /* since we're using non-transient message dialogs, the dialog window can become completely * hidden behind other windows, with no easy way to raise it back to the top, so... */ gtk_widget_show(w); gtk_window_present(GTK_WINDOW(w)); } static void set_stock_button_label_1(gpointer w1, gpointer label) { GtkWidget *w = (GtkWidget *)w1; if (GTK_IS_LABEL(w)) { gtk_widget_hide(w); gtk_label_set_text(GTK_LABEL(w), (char *)label); gtk_widget_show(w); } else { if (GTK_IS_CONTAINER(w)) g_list_foreach(gtk_container_get_children(GTK_CONTAINER(w)), set_stock_button_label_1, label); } } void set_stock_button_label(GtkWidget *w, const char *new_label) { set_stock_button_label_1((gpointer)w, (gpointer)new_label); } void set_button_label(GtkWidget *label, const char *str) { GtkWidget *w; w = BIN_CHILD(label); #if (GTK_CHECK_VERSION(3, 92, 0)) if (GTK_IS_LABEL(w)) gtk_label_set_text(GTK_LABEL(w), str); else { if (GTK_IS_ACCEL_LABEL(w)) gtk_accel_label_set_label(GTK_ACCEL_LABEL(w), str); else fprintf(stderr, "unknown widget type in set_button_label\n"); } #else gtk_label_set_text(GTK_LABEL(w), str); #endif } #if GTK_CHECK_VERSION(3, 10, 0) static const char *icon_to_label(const char *label) { /* these are the new-style labels in snd-g0.h */ /* fprintf(stderr, "label: [%s]\n", label); */ switch (label[0]) { case 'A': case 'E': case 'O': case 'P': case 'S': return(label); case 'a': return("Exit"); case 'd': if (mus_strcmp(label, "document-new")) return("New"); else if (mus_strcmp(label, "document-open")) return("Open"); else if (mus_strcmp(label, "document-print")) return("Print"); else if (mus_strcmp(label, "document-revert")) return("Revert"); else if (mus_strcmp(label, "document-save")) return("Save"); else if (mus_strcmp(label, "document-save-as")) return("Save as"); break; case 'e': if (mus_strcmp(label, "edit-clear")) return("Clear"); else if (mus_strcmp(label, "edit-copy")) return("Copy"); else if (mus_strcmp(label, "edit-cut")) return("Cut"); else if (mus_strcmp(label, "edit-find")) return("Find"); else if (mus_strcmp(label, "edit-paste")) return("Paste"); else if (mus_strcmp(label, "edit-redo")) return("Redo"); else if (mus_strcmp(label, "edit-select-all")) return("Select all"); else if (mus_strcmp(label, "edit-undo")) return("Undo"); break; case 'g': if (mus_strcmp(label, "go-first")) return("Go to start"); else if (mus_strcmp(label, "go-last")) return("Go to end"); else if (mus_strcmp(label, "go-next")) return("Next"); else if (mus_strcmp(label, "go-previous")) return("Previous"); break; case 'h': return("Help"); case 'm': if (mus_strcmp(label, "media-playback-start")) return("Play"); else if (mus_strcmp(label, "media-playback-stop")) return("Stop playing"); else if (mus_strcmp(label, "media-playback-forward")) return("Play from cursor"); break; case 'p': return("Stop"); case 'v': if (mus_strcmp(label, "view-fullscreen")) return("Show all"); else if (mus_strcmp(label, "view-refresh")) return("Show again"); break; case 'w': return("Close"); case 'z': if (mus_strcmp(label, "zoom-in")) return("Zoom in"); else if (mus_strcmp(label, "zoom-out")) return("Zoom out"); break; } return(label); } GtkWidget *button_new_with_icon(const gchar *label) { return(gtk_button_new_with_label(icon_to_label(label))); } #endif void set_label(GtkWidget *label, const char *str) { gtk_label_set_text(GTK_LABEL(label), str); } void check_for_event(void) { /* this is needed to force label updates and provide interrupts for long computations * * Valgrind is confused about something here -- it thinks _XEnq malloc in XTranslateCoordinates in gdk_event_translate is never freed * but this way of letting events run is used (for example) in gtktreeview.c and gtkwidget.c, so if it's wrong here... */ int i = 0; if (ss->checking_explicitly) return; ss->checking_explicitly = true; while ((i < 100) && (gtk_events_pending())) { gtk_main_iteration(); i++; /* don't hang! */ } ss->checking_explicitly = false; } void set_title(const char *title) { gtk_window_set_title(GTK_WINDOW(main_shell(ss)), title); } void goto_window(GtkWidget *text) { gtk_widget_grab_focus(text); } /* try to keep track of colors */ void gc_set_foreground(gc_t *gp, color_info *color) { gp->fg_color = color; } void gc_set_background(gc_t *gp, color_info *color) { gp->bg_color = color; } void gc_set_colors(gc_t *gp, color_info *col1, color_info *col2) { gp->fg_color = col1; gp->bg_color = col2; } gc_t *gc_new(void) { gc_t *gp; gp = (gc_t *)calloc(1, sizeof(gc_t)); return(gp); } void color_cursor(color_info *color) { ss->cursor_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->cursor_color_symbol, Xen_wrap_pixel(color)); #endif gc_set_colors(ss->cursor_gc, color, ss->graph_color); gc_set_colors(ss->selected_cursor_gc, color, ss->selected_graph_color); } void color_marks(color_info *color) { ss->mark_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->mark_color_symbol, Xen_wrap_pixel(color)); #endif gc_set_colors(ss->mark_gc, color, ss->graph_color); gc_set_colors(ss->selected_mark_gc, color, ss->selected_graph_color); } void color_selection(color_info *color) { ss->selection_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->selection_color_symbol, Xen_wrap_pixel(color)); #endif gc_set_colors(ss->selection_gc, color, ss->graph_color); gc_set_colors(ss->selected_selection_gc, color, ss->selected_graph_color); } void color_graph(color_info *color) { gc_set_background(ss->basic_gc, color); gc_set_foreground(ss->erase_gc, color); gc_set_colors(ss->selection_gc, ss->selection_color, color); gc_set_colors(ss->cursor_gc, ss->cursor_color, color); gc_set_colors(ss->mark_gc, ss->mark_color, color); } void color_selected_graph(color_info *color) { gc_set_background(ss->selected_basic_gc, color); gc_set_foreground(ss->selected_erase_gc, color); gc_set_colors(ss->selected_selection_gc, ss->selection_color, color); gc_set_colors(ss->selected_cursor_gc, ss->cursor_color, color); gc_set_colors(ss->selected_mark_gc, ss->mark_color, color); } void color_data(color_info *color) { gc_set_foreground(ss->basic_gc, color); gc_set_background(ss->erase_gc, color); } void color_selected_data(color_info *color) { gc_set_foreground(ss->selected_basic_gc, color); gc_set_background(ss->selected_erase_gc, color); } void set_mix_color(color_info *color) { ss->mix_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->mix_color_symbol, Xen_wrap_pixel(color)); #endif gc_set_foreground(ss->mix_gc, color); } color_t rgb_to_color(mus_float_t r, mus_float_t g, mus_float_t b) { color_info *ccolor; ccolor = (color_info *)malloc(sizeof(color_info)); ccolor->red = r; ccolor->green = g; ccolor->blue = b; ccolor->alpha = 1.0; return(ccolor); } #if (!GTK_CHECK_VERSION(3, 0, 0)) GdkColor *rgb_to_gdk_color(color_t col) { GdkColor gcolor; GdkColor *ccolor; gcolor.red = (unsigned short)(col->red * 65535); gcolor.green = (unsigned short)(col->green * 65535); gcolor.blue = (unsigned short)(col->blue * 65535); ccolor = gdk_color_copy(&gcolor); /* gdk_rgb_find_color(gdk_colormap_get_system(), ccolor); */ return(ccolor); } #endif #if (!GTK_CHECK_VERSION(3, 92, 1)) void sg_widget_modify_bg(GtkWidget *w, GtkStateType type, color_t color) { /* the color has to stick around??? */ /* another stop-gap: allocate a color each time... */ #if (!GTK_CHECK_VERSION(3, 0, 0)) gtk_widget_modify_bg(w, type, rgb_to_gdk_color(color)); #else #if (!GTK_CHECK_VERSION(3, 16, 0)) gtk_widget_override_background_color(w, GTK_STATE_FLAG_NORMAL, (GdkRGBA *)color); #endif #endif } void sg_widget_modify_fg(GtkWidget *w, GtkStateType type, color_t color) { #if (!GTK_CHECK_VERSION(3, 0, 0)) gtk_widget_modify_fg(w, type, rgb_to_gdk_color(color)); #else #if (!GTK_CHECK_VERSION(3, 16, 0)) gtk_widget_override_color(w, GTK_STATE_FLAG_NORMAL, (GdkRGBA *)color); #endif #endif } void sg_widget_modify_base(GtkWidget *w, GtkStateType type, color_t color) { #if (!GTK_CHECK_VERSION(3, 0, 0)) gtk_widget_modify_base(w, type, rgb_to_gdk_color(color)); #else #if (!GTK_CHECK_VERSION(3, 16, 0)) gtk_widget_override_background_color(w, GTK_STATE_FLAG_NORMAL, (GdkRGBA *)color); #endif #endif } #endif #if (GTK_CHECK_VERSION(3, 92, 1)) guint sg_event_get_keyval(GdkEvent *e) { guint val = 0; gdk_event_get_keyval(e, &val); return(val); } guint sg_event_get_button(const GdkEvent *e) { guint val = 0; gdk_event_get_button(e, &val); return(val); } #endif void recolor_graph(chan_info *cp, bool selected) { #if (!GTK_CHECK_VERSION(3, 92, 1)) widget_modify_bg(channel_graph(cp), GTK_STATE_NORMAL, (selected) ? ss->selected_graph_color : ss->graph_color); #endif } void set_sensitive(GtkWidget *wid, bool val) { if (wid) gtk_widget_set_sensitive(wid, val); } void set_toggle_button(GtkWidget *wid, bool val, bool passed, void *data) { if (!passed) g_signal_handlers_block_matched((gpointer)wid, G_SIGNAL_MATCH_DATA, 0, 0, NULL, 0, (gpointer)data); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wid), val); if (!passed) g_signal_handlers_unblock_matched((gpointer)wid, G_SIGNAL_MATCH_DATA, 0, 0, NULL, 0, (gpointer)data); } bool cursor_set_blinks(GtkWidget *w, bool blinks) { GtkSettings *settings; settings = gtk_widget_get_settings(w); g_object_set(settings, "gtk-cursor-blink", (gboolean)blinks, NULL); return(blinks); } #if GTK_CHECK_VERSION(3, 0, 0) int widget_height(GtkWidget *w) { return(gtk_widget_get_allocated_height(w)); } int widget_width(GtkWidget *w) { return(gtk_widget_get_allocated_width(w)); } #else guint16 widget_height(GtkWidget *w) { gint x, y; gdk_drawable_get_size(WIDGET_TO_WINDOW(w), &x, &y); return(y); } guint16 widget_width(GtkWidget *w) { gint x, y; gdk_drawable_get_size(WIDGET_TO_WINDOW(w), &x, &y); return(x); } #endif void set_widget_height(GtkWidget *w, guint16 height) { set_widget_size(w, widget_width(w), height); } void set_widget_width(GtkWidget *w, guint16 width) { set_widget_size(w, width, widget_height(w)); } gint16 widget_x(GtkWidget *w) { gint x, y; #if GTK_CHECK_VERSION(3, 94, 0) gdk_surface_get_position(GDK_SURFACE(w), &x, &y); #else gdk_window_get_position(WIDGET_TO_WINDOW(w), &x, &y); #endif return(x); } gint16 widget_y(GtkWidget *w) { gint x, y; #if GTK_CHECK_VERSION(3, 94, 0) gdk_surface_get_position(GDK_SURFACE(w), &x, &y); #else gdk_window_get_position(WIDGET_TO_WINDOW(w), &x, &y); #endif return(y); } void set_widget_x(GtkWidget *w, gint16 x) { #if (!GTK_CHECK_VERSION(3, 96, 0)) gtk_window_move(GTK_WINDOW(w), x, widget_y(w)); #endif } void set_widget_y(GtkWidget *w, gint16 y) { #if (!GTK_CHECK_VERSION(3, 96, 0)) gtk_window_move(GTK_WINDOW(w), widget_x(w), y); #endif } void set_widget_size(GtkWidget *w, guint16 width, guint16 height) { #if GTK_CHECK_VERSION(3, 94, 0) gtk_window_resize(WIDGET_TO_WINDOW(w), width, height); #else gdk_window_resize(WIDGET_TO_WINDOW(w), width, height); #endif #if 0 /* This one doesn't do anything, and prints out errors. */ gtk_window_resize(GTK_WINDOW(w), width, height); #endif } void set_widget_position(GtkWidget *w, gint16 x, gint16 y) { #if (!GTK_CHECK_VERSION(3, 96, 0)) gtk_window_move(GTK_WINDOW(w), x, y); #endif } void set_user_data(GObject *obj, gpointer data) { g_object_set_data(obj, "snd-data", data); } gpointer get_user_data(GObject *obj) { return(g_object_get_data(obj, "snd-data")); } void set_user_int_data(GObject *obj, int data) { int *gdata; gdata = (int *)malloc(sizeof(int)); gdata[0] = data; g_object_set_data(obj, "snd-data", (gpointer)gdata); } int get_user_int_data(GObject *obj) { gpointer gdata; gdata = g_object_get_data(obj, "snd-data"); return(((int *)gdata)[0]); } void reset_user_int_data(GObject *obj, int data) { gpointer gdata; gdata = g_object_get_data(obj, "snd-data"); ((int *)gdata)[0] = data; } char *sg_get_text(GtkWidget *w, int start, int end) /* g_free result */ { GtkTextIter s, e; GtkTextBuffer *buf; buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w)); gtk_text_buffer_get_iter_at_offset(buf, &s, start); gtk_text_buffer_get_iter_at_offset(buf, &e, end); return(gtk_text_buffer_get_text(buf, &s, &e, true)); } void sg_text_insert(GtkWidget *w, const char *text) { if (text) { GtkTextIter pos; GtkTextBuffer *buf; buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w)); gtk_text_buffer_get_end_iter(buf, &pos); gtk_text_buffer_insert(buf, &pos, text, strlen(text)); } else gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(w)), "", 0); } GtkWidget *make_scrolled_text(GtkWidget *parent, bool editable, int add_choice, bool resize) { /* returns new text widget */ GtkWidget *sw, *new_text; GtkTextBuffer *buf; sw = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); /* gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(sw), 1000); * seems to be a no-op -- I think they are maxing this against the current contents window size (see below) */ new_text = gtk_text_view_new(); buf = gtk_text_buffer_new(NULL); gtk_text_view_set_buffer(GTK_TEXT_VIEW(new_text), buf); gtk_text_view_set_editable(GTK_TEXT_VIEW(new_text), editable); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(new_text), GTK_WRAP_NONE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(new_text), editable); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(new_text), 4); gtk_container_add(GTK_CONTAINER(sw), new_text); #if (!GTK_CHECK_VERSION(3, 92, 1)) if (editable) sg_widget_set_events(new_text, GDK_ALL_EVENTS_MASK); #endif gtk_widget_show(new_text); switch (add_choice) { case 0: gtk_container_add(GTK_CONTAINER(parent), sw); break; case 1: gtk_paned_pack2(GTK_PANED(parent), sw, resize, true); break; case 2: default: sg_box_pack_start(GTK_BOX(parent), sw, true, true, 0); break; } gtk_widget_show(sw); return(new_text); } void sg_make_resizable(GtkWidget *w) { if (GTK_IS_DIALOG(w)) { gtk_window_set_default_size(GTK_WINDOW(w), -1, -1); gtk_window_set_resizable(GTK_WINDOW(w), true); } } idle_t add_work_proc(GSourceFunc func, gpointer data) { /* during auto-testing I need to force the background procs to run to completion */ if (with_background_processes(ss)) return(g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, func, data, NULL)); else { while (((*func)(data)) == BACKGROUND_CONTINUE) {}; return((idle_t)0); } } GtkWidget *snd_gtk_dialog_new(void) { GtkWidget *w; w = gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(w), GTK_WINDOW(main_shell(ss))); #endif add_dialog_style(w); g_object_ref(w); return(w); } GtkWidget *snd_gtk_highlight_label_new(const char *label) { char *str; GtkWidget *w; w = gtk_label_new(label); str = mus_format("%s", label); gtk_label_set_markup(GTK_LABEL(w), str); gtk_label_set_use_markup(GTK_LABEL(w), true); free(str); return(w); } void widget_int_to_text(GtkWidget *w, int val) { char *str; str = (char *)calloc(8, sizeof(char)); snprintf(str, 8, "%d", val); gtk_entry_set_text(GTK_ENTRY(w), str); free(str); } void widget_mus_long_t_to_text(GtkWidget *w, mus_long_t val) { char *str; str = (char *)calloc(8, sizeof(char)); snprintf(str, 8, "%" print_mus_long, val); gtk_entry_set_text(GTK_ENTRY(w), str); free(str); } #if HAVE_GTK_ADJUSTMENT_GET_UPPER #define ADJUSTMENT_LOWER(Adjust) gtk_adjustment_get_lower(GTK_ADJUSTMENT(Adjust)) #define ADJUSTMENT_UPPER(Adjust) gtk_adjustment_get_upper(GTK_ADJUSTMENT(Adjust)) #else #define ADJUSTMENT_LOWER(Adjust) ((GTK_ADJUSTMENT(Adjust))->lower) #define ADJUSTMENT_UPPER(Adjust) ((GTK_ADJUSTMENT(Adjust))->upper) #endif void ensure_scrolled_window_row_visible(widget_t list, int row, int num_rows) { /* view files file list */ /* called in snd-file.c on vdat->file_list which is a vbox; its parent is a viewport */ /* also used in slist_moveto below */ GtkWidget *parent; GtkAdjustment *v; gdouble maximum, size, new_value, minimum; parent = gtk_widget_get_parent(list); #if GTK_CHECK_VERSION(3, 0, 0) v = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(parent)); #else v = gtk_viewport_get_vadjustment(GTK_VIEWPORT(parent)); #endif maximum = ADJUSTMENT_UPPER(v); minimum = ADJUSTMENT_LOWER(v); size = ADJUSTMENT_PAGE_SIZE(v); maximum -= size; if (row == 0) new_value = 0.0; else { if (row >= (num_rows - 1)) new_value = maximum; else new_value = ((row + 0.5) * ((maximum - minimum) / (double)(num_rows - 1))); } if (new_value != ADJUSTMENT_VALUE(v)) ADJUSTMENT_SET_VALUE(v, new_value); } /* ---------------- scrolled list replacement ---------------- */ static int slist_row(GtkWidget *item); static void slist_set_row(GtkWidget *item, int row); static void slist_item_clicked(GtkWidget *w, gpointer gp) { slist *lst = (slist *)gp; slist_select(lst, slist_row(w)); if (lst->select_callback) (*(lst->select_callback))((const char *)gtk_button_get_label(GTK_BUTTON(w)), /* do not free this!! */ slist_row(w), lst->select_callback_data); } static gboolean slist_item_button_pressed(GtkWidget *w, GdkEventButton *ev, gpointer data) { slist *lst = (slist *)data; if (lst->button_press_callback) return((*(lst->button_press_callback))(ev, lst->button_press_callback_data)); return(false); } #if (GTK_CHECK_VERSION(3, 0, 0)) static GtkCssProvider *wb_provider, *listener_provider, *dialog_provider, *hl_provider, *tb_provider, *mu_provider; static GtkCssProvider *rsc_provider, *gsc_provider, *bsc_provider, *pd_provider, *cb_provider, *entry_provider; static GtkCssProvider *cl_provider; void add_white_button_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(wb_provider), G_MAXUINT); gtk_widget_set_name(w, "white_button"); } void add_highlight_button_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(hl_provider), G_MAXUINT); gtk_widget_set_name(w, "highlight_button"); } void add_center_button_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(cl_provider), G_MAXUINT); } void add_listener_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(listener_provider), G_MAXUINT); gtk_widget_set_name(w, "listener_text"); } void add_dialog_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(dialog_provider), G_MAXUINT); } void add_toolbar_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(tb_provider), G_MAXUINT); #if 0 /* add_toolbar_style is incompatible with GtkCallback */ if (GTK_IS_CONTAINER(w)) gtk_container_forall(GTK_CONTAINER(w), (GtkCallback)add_toolbar_style, tb_provider); #endif } void add_menu_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(mu_provider), G_MAXUINT); } void add_paned_style(GtkWidget *w) { #if 0 GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(pd_provider), G_MAXUINT); #endif } void add_red_scale_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(rsc_provider), G_MAXUINT); } void add_green_scale_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(gsc_provider), G_MAXUINT); } void add_blue_scale_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(bsc_provider), G_MAXUINT); } void add_check_button_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(cb_provider), G_MAXUINT); } void add_entry_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(entry_provider), G_MAXUINT); } #else void add_red_scale_style(GtkWidget *w) {} void add_green_scale_style(GtkWidget *w) {} void add_blue_scale_style(GtkWidget *w) {} void add_toolbar_style(GtkWidget *w) {} void add_menu_style(GtkWidget *w) {} void add_paned_style(GtkWidget *w) {} void add_highlight_button_style(GtkWidget *w) {} void add_center_button_style(GtkWidget *w) {} void add_white_button_style(GtkWidget *w) {gtk_widget_set_name(w, "white_button");} void add_listener_style(GtkWidget *w) {gtk_widget_set_name(w, "listener_text");} void add_dialog_style(GtkWidget *w) {} void add_check_button_style(GtkWidget *w) {} void add_entry_style(GtkWidget *w) {} #endif static GtkWidget *slist_new_item(slist *lst, const char *label, int row) { GtkWidget *item; item = gtk_button_new_with_label(label); slist_set_row(item, row); gtk_button_set_relief(GTK_BUTTON(item), GTK_RELIEF_NONE); #if GTK_CHECK_VERSION(3, 14, 0) gtk_widget_set_halign(GTK_WIDGET(item), GTK_ALIGN_START); #else gtk_button_set_alignment(GTK_BUTTON(item), 0.05, 1.0); #endif sg_box_pack_start(GTK_BOX(lst->topics), item, false, false, 0); #if (!GTK_CHECK_VERSION(3, 92, 1)) widget_modify_bg(item, GTK_STATE_NORMAL, ss->white); widget_modify_bg(item, GTK_STATE_PRELIGHT, ss->light_blue); #endif add_white_button_style(item); SG_SIGNAL_CONNECT(item, "clicked", slist_item_clicked, (gpointer)lst); SG_SIGNAL_CONNECT(item, "button_press_event", slist_item_button_pressed, (gpointer)lst); gtk_widget_show(item); return(item); } slist *slist_new_with_title_and_table_data(const char *title, GtkWidget *parent, const char **initial_items, int num_items, widget_add_t paned, int t1, int t2, int t3, int t4) { slist *lst; GtkWidget *topw = NULL; lst = (slist *)calloc(1, sizeof(slist)); lst->selected_item = SLIST_NO_ITEM_SELECTED; if (title) { lst->box = gtk_vbox_new(false, 0); widget_set_vexpand(lst->box, true); lst->label = snd_gtk_highlight_label_new(title); sg_box_pack_start(GTK_BOX(lst->box), lst->label, false, false, 0); topw = lst->box; } lst->topics = gtk_vbox_new(false, 2); /* sets list item vertical spacing */ widget_set_vexpand(lst->topics, true); lst->scroller = gtk_scrolled_window_new(NULL, NULL); if (!title) topw = lst->scroller; else sg_box_pack_start(GTK_BOX(lst->box), lst->scroller, true, true, 0); switch (paned) { case PANED_ADD1: gtk_paned_add1(GTK_PANED(parent), topw); break; case BOX_PACK: sg_box_pack_start(GTK_BOX(parent), topw, true, true, 4); break; case TABLE_ATTACH: gtk_table_attach(GTK_TABLE(parent), topw, t1, t2, t3, t4, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)(GTK_FILL | GTK_EXPAND | GTK_SHRINK), 0, 0); break; case CONTAINER_ADD: gtk_container_add(GTK_CONTAINER(parent), topw); break; } gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(lst->scroller), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); #if HAVE_GTK_HEADER_BAR_NEW gtk_container_add(GTK_CONTAINER(lst->scroller), lst->topics); #else gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(lst->scroller), lst->topics); #endif if (title) { gtk_widget_show(lst->label); gtk_widget_show(lst->box); } gtk_widget_show(lst->topics); gtk_widget_show(lst->scroller); if (num_items > 0) { int i; lst->items = (GtkWidget **)calloc(num_items, sizeof(GtkWidget *)); lst->items_size = num_items; lst->num_items = num_items; for (i = 0; i < num_items; i++) lst->items[i] = slist_new_item(lst, initial_items[i], i); } /* gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(lst->scroller), 200); * this actually works! */ return(lst); } slist *slist_new(GtkWidget *parent, const char **initial_items, int num_items, widget_add_t paned) { return(slist_new_with_title_and_table_data(NULL, parent, initial_items, num_items, paned, 0, 0, 0, 0)); } slist *slist_new_with_title(const char *title, GtkWidget *parent, const char **initial_items, int num_items, widget_add_t paned) { return(slist_new_with_title_and_table_data(title, parent, initial_items, num_items, paned, 0, 0, 0, 0)); } void slist_clear(slist *lst) { int i; for (i = 0; i < lst->items_size; i++) if (lst->items[i]) { gtk_widget_hide(lst->items[i]); gtk_button_set_label(GTK_BUTTON(lst->items[i]), " "); } lst->num_items = 0; #if (!GTK_CHECK_VERSION(3, 92, 1)) if (lst->selected_item != SLIST_NO_ITEM_SELECTED) widget_modify_bg(lst->items[lst->selected_item], GTK_STATE_NORMAL, ss->white); #endif lst->selected_item = SLIST_NO_ITEM_SELECTED; } static int slist_row(GtkWidget *item) { gpointer gdata; gdata = g_object_get_data(G_OBJECT(item), "slist-row"); return(((int *)gdata)[0]); } static void slist_set_row(GtkWidget *item, int row) { int *gdata; gdata = (int *)malloc(sizeof(int)); gdata[0] = row; g_object_set_data(G_OBJECT(item), "slist-row", (gpointer)gdata); } #define INITIAL_SLIST_LENGTH 8 void slist_append(slist *lst, const char *name) { int loc = 0; if ((!name) || (!g_utf8_validate(name, -1, NULL))) return; if (lst->items_size == 0) { lst->items = (GtkWidget **)calloc(INITIAL_SLIST_LENGTH, sizeof(GtkWidget *)); lst->items_size = INITIAL_SLIST_LENGTH; lst->num_items = 0; } if (lst->num_items == lst->items_size) { int i; lst->items_size += INITIAL_SLIST_LENGTH; lst->items = (GtkWidget **)realloc(lst->items, lst->items_size * sizeof(GtkWidget *)); for (i = lst->num_items; i < lst->items_size; i++) lst->items[i] = NULL; } loc = lst->num_items++; if (!lst->items[loc]) lst->items[loc] = slist_new_item(lst, name, loc); else { gtk_button_set_label(GTK_BUTTON(lst->items[loc]), name); /* gtkbutton.c strdups name */ gtk_widget_show(lst->items[loc]); } } void slist_moveto(slist *lst, int row) { ensure_scrolled_window_row_visible(lst->topics, row, lst->num_items); } void slist_select(slist *lst, int row) { #if (!GTK_CHECK_VERSION(3, 92, 1)) if (lst->selected_item != SLIST_NO_ITEM_SELECTED) widget_modify_bg(lst->items[lst->selected_item], GTK_STATE_NORMAL, ss->white); if (row != SLIST_NO_ITEM_SELECTED) widget_modify_bg(lst->items[row], GTK_STATE_NORMAL, ss->light_blue); #endif lst->selected_item = row; } #if (!GTK_CHECK_VERSION(3, 0, 0)) void init_gtk(void) { gtk_rc_parse_string("\n\ \n \ style \"default\"\n \ {\n \ fg[NORMAL] = { 0.0, 0.00, 0.0 }\n \ text[NORMAL] = { 0.0, 0.0, 0.0 }\n \ bg[NORMAL] = { 0.96, 0.96, 0.90 }\n \ bg[ACTIVE] = { 0.80, 0.80, 0.75 }\n \ bg[INSENSITIVE] = { 0.96, 0.96, 0.90 }\n \ base[NORMAL] = { 1.00, 1.00, 1.00 }\n \ bg[PRELIGHT] = { 0.70, 0.70, 0.64 }\n \ fg[PRELIGHT] = { 1.0, 0.0, 0.0}\n \ GtkPaned::handle_size = 6\n \ xthickness = 1\n \ ythickness = 1\n \ }\n \ style \"default_button\" = \"default\"\n \ {\n \ GtkButton::default_border = { 1, 0, 1, 0 }\n \ GtkButton::default_outside_border = { 1, 0, 1, 0 }\n \ GtkButton::inner_border = { 1, 0, 1, 0 }\n \ GtkButton::focus_line_width = 0\n \ GtkButton::focus_padding = 0\n \ }\n \ style \"default_pane\" = \"default\"\n \ {\n \ bg[NORMAL] = { 0.56, 0.93, 0.56 }\n \ bg[PRELIGHT] = { 0.26, 0.8, 0.26}\n \ }\n \ style \"default_entry\" = \"default\"\n \ {\n \ base[ACTIVE] = { 0.96, 0.96, 0.90 }\n \ base[SELECTED] = { 0.80, 0.80, 0.75 }\n \ base[PRELIGHT] = { 1.0, 1.0, 1.0}\n \ base[NORMAL] = { 0.96, 0.96, 0.90 }\n \ base[INSENSITIVE] = { 0.96, 0.96, 0.90 }\n \ bg[ACTIVE] = { 1.0, 1.0, 1.0 }\n \ bg[SELECTED] = { 1.0, 1.0, 1.0 }\n \ bg[PRELIGHT] = { 1.0, 1.0, 1.0 }\n \ text[ACTIVE] = { 0.0, 0.0, 0.0 }\n \ text[SELECTED] = { 0.0, 0.0, 0.0 }\n \ text[PRELIGHT] = { 0.0, 0.0, 0.0 }\n \ }\n \ style \"default_text\" = \"default_entry\"\n \ {\n \ base[NORMAL] = { 1.0, 1.0, 1.0 }\n \ }\n \ style \"default_slider\" = \"default\"\n \ {\n \ bg[NORMAL] = { 0.90, 0.90, 0.85 }\n \ bg[ACTIVE] = { 0.70, 0.70, 0.64 }\n \ bg[PRELIGHT] = { 0.90, 0.90, 0.85 }\n \ GtkRange::slider_width = 13\n \ GtkRange::stepper_size = 10\n \ }\n \ style \"prefs_scale\" = \"default_slider\"\n \ {\n \ GtkScale::slider-length = 24\n \ }\n \ widget \"*.prefs_color_scale\" style \"prefs_scale\"\n \ style \"default_frame\" = \"default\"\n \ {\n \ xthickness = 4\n \ ythickness = 4\n \ }\n \ class \"GtkWidget\" style \"default\"\n \ class \"GtkButton\" style \"default_button\"\n \ class \"GtkEntry\" style \"default_entry\"\n \ class \"GtkTextView\" style \"default_text\"\n \ class \"GtkPaned\" style \"default_pane\"\n \ class \"GtkRange\" style \"default_slider\"\n \ class \"GtkFrame\" style \"default_frame\"\n \ \n \ style \"zoom_slider\" = \"default_slider\"\n \ {\n \ bg[NORMAL] = { 0.70, 0.70, 0.64 }\n \ bg[ACTIVE] = { 0.54, 0.54, 0.51 }\n \ bg[PRELIGHT] = { 0.70, 0.70, 0.64 }\n \ \n \ GtkRange::slider_width = 12\n \ GtkRange::stepper_size = 12\n \ }\n \ widget \"*.zx_slider\" style \"zoom_slider\"\n \ widget \"*.zy_slider\" style \"zoom_slider\"\n \ widget \"*.gzy_slider\" style \"zoom_slider\"\n \ style \"default_tree_view\" = \"default\"\n \ {\n \ GtkTreeView::odd-row-color = { 0.94, 0.97, 1.0 }\n \ GtkTreeView::even-row-color = { 1.0, 1.0, 1.0 }\n \ }\n \ class \"GtkTreeView\" style \"default_tree_view\"\n \ style \"dialog_button\" = \"default_button\"\n \ {\n \ bg[NORMAL] = { 1.0, 1.0, 0.94 }\n \ bg[PRELIGHT] = { 1.0, 1.0, 0.94 }\n \ }\n \ widget \"*.dialog_button\" style \"dialog_button\"\n \ style \"white_button\" = \"default_button\"\n \ {\n \ bg[NORMAL] = { 1.0, 1.0, 1.0 }\n \ bg[PRELIGHT] = { 0.94, 0.97, 1.0 }\n \ fg[PRELIGHT] = { 0.0, 0.0, 0.0}\n \ GtkButton::default_border = { 0, 0, 0, 0 }\n \ GtkButton::default_outside_border = { 0, 0, 0, 0 }\n \ GtkButton::inner_border = { 0, 0, 0, 0 }\n \ GtkButton::focus_line_width = 0\n \ GtkButton::focus_padding = 0\n \ xthickness = 0\n \ ythickness = 0\n \ }\n \ widget \"*.white_button\" style \"white_button\"\n"); } #else /* -------------------------------------------------------------------------------- */ #if (GTK_CHECK_VERSION(3, 89, 0)) /* border-width and -gtk-gradient have been removed(??); as far as I can tell, this stuff does not work * see gtkcssstylepropertyimpl.c gtk_css_style_property_register for properties ("background-color" etc) */ void init_gtk(void) { #if (GTK_CHECK_VERSION(3, 93, 0)) GtkCssProvider *dp; dp = gtk_css_provider_new(); gtk_style_context_add_provider_for_display(gdk_display_get_default(), GTK_STYLE_PROVIDER(dp), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); /* copied from gtk-3.96.0/tests/testwidgetfocus.c */ #endif wb_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(wb_provider), "GtkButton#white_button { \n" " padding: 0px;\n" " background-color: #ffffff;\n" "}\n" "GtkButton#white_button:hover { \n" "}\n", -1); hl_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(hl_provider), "GtkEventBox, GtkButton#highlight_button { \n" " padding: 0px;\n" " background-color: #fffff0;\n" "}\n" "GtkButton#highlight_button:hover { \n" "}\n", -1); cl_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(cl_provider), "GtkEventBox, GtkButton { \n" " padding: 0px;\n" " background-color: #fffff0;\n" "}\n" "GtkButton:hover { \n" "}\n", -1); listener_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(listener_provider), "#listener_text { \n" " background-color: #ffffff;\n" " color: #000000;\n" "}\n" "#listener_text:selected { \n" " background-color: darker(rgb(240, 248, 255));\n" " color: #000000;\n" "}\n", -1); entry_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(entry_provider), "GtkEntry:selected { \n" " background-color: darker(rgb(240, 248, 255));\n" " color: #000000;\n" "}\n", -1); dialog_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(dialog_provider), "GtkDialog { \n" "}\n", -1); tb_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(tb_provider), "GtkToolbar, GtkToolButton, GtkToolItem { \n" " border-color: #fffff0;\n" " padding: 8px;\n" "}\n", -1); /* the 8px here refers to the whole bar, not each entry */ mu_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(mu_provider), "GtkMenuBar, GtkMenu, GtkMenuItem { \n" " border-color: #fffff0;\n" " background-color: #fffff0;\n" " padding: 4px;\n" "}\n", -1); rsc_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(rsc_provider), "GtkScale { \n" "}\n", -1); gsc_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(gsc_provider), "GtkScale { \n" "}\n", -1); bsc_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(bsc_provider), "GtkScale { \n" "}\n", -1); /* I wanted to make the handle larger and set its color to #90ee90 -- no way! */ pd_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(pd_provider), "GtkPaned { \n" " background-color: #fffff0;\n" "}\n", -1); cb_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(cb_provider), "GtkRadioButton:hover, GtkCheckButton:hover { \n" " background-color: rgb(200, 200, 190);\n" "}\n", -1); } #else /* -------------------------------------------------------------------------------- */ void init_gtk(void) { #if 0 /* this makes no difference */ GtkCssProvider *provider; GdkDisplay *display; GdkScreen *screen; provider = gtk_css_provider_new(); display = gdk_display_get_default(); screen = gdk_display_get_default_screen(display); gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); #endif wb_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(wb_provider), "GtkButton#white_button { \n" " padding-top: 0px;\n" " padding-bottom: 0px;\n" " border-width: 0px;\n" " background-color: #ffffff;\n" "}\n" #if (!GTK_CHECK_VERSION(3, 18, 8)) "GtkButton#white_button:prelight { \n" #else "GtkButton#white_button:hover { \n" #endif " background-image: -gtk-gradient (linear, left top, right bottom, from(#ffffff), to(rgb(200, 225, 255)));\n" "}\n", -1, NULL); hl_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(hl_provider), "GtkEventBox, GtkButton#highlight_button { \n" " padding-top: 0px;\n" " padding-bottom: 0px;\n" " border-width: 0px;\n" " background-color: #fffff0;\n" "}\n" #if (!GTK_CHECK_VERSION(3, 18, 8)) "GtkButton#highlight_button:prelight { \n" #else "GtkButton#highlight_button:hover { \n" #endif " background-image: -gtk-gradient (linear, left top, right bottom, from(#fffff0), to(rgb(200, 225, 255)));\n" "}\n", -1, NULL); cl_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(cl_provider), "GtkEventBox, GtkButton { \n" " padding-top: 0px;\n" " padding-bottom: 0px;\n" " padding-left: 8px;\n" " padding-right: 8px;\n" " border-width: 1px;\n" " border-color: gray;\n" " background-color: #fffff0;\n" "}\n" #if (!GTK_CHECK_VERSION(3, 18, 8)) "GtkButton:prelight { \n" #else "GtkButton:hover { \n" #endif " background-image: -gtk-gradient (linear, left top, right bottom, from(#fffff0), to(rgb(200, 225, 255)));\n" "}\n", -1, NULL); listener_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(listener_provider), "#listener_text { \n" /* " background-color: rgb(240, 248, 255);\n" */ " background-color: #ffffff;\n" " color: #000000;\n" "}\n" "#listener_text:selected { \n" " background-color: darker(rgb(240, 248, 255));\n" " color: #000000;\n" "}\n", -1, NULL); entry_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(entry_provider), "GtkEntry:selected { \n" " background-color: darker(rgb(240, 248, 255));\n" " color: #000000;\n" "}\n", -1, NULL); dialog_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(dialog_provider), "GtkDialog { \n" " background-image: -gtk-gradient (linear, left top, right bottom, from(rgb(250, 250, 230)), to(rgb(235, 235, 210)));\n" "}\n", -1, NULL); tb_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(tb_provider), "GtkToolbar, GtkToolButton, GtkToolItem { \n" " border-color: #fffff0;\n" /* " background-color: #fffff0;\n" */ " padding-left: 8px;\n" " padding-bottom: 4px;\n" " background-image: -gtk-gradient (linear, left top, right bottom, from(rgb(255, 255, 240)), to(rgb(255, 255, 255)));\n" "}\n", -1, NULL); /* the 8px here refers to the whole bar, not each entry */ mu_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(mu_provider), "GtkMenuBar, GtkMenu, GtkMenuItem { \n" " border-width: 4px;\n" " border-color: #fffff0;\n" " background-color: #fffff0;\n" " padding-bottom: 4px;\n" " padding-left: 8px;\n" "}\n", -1, NULL); rsc_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(rsc_provider), "GtkScale { \n" " background-image: -gtk-gradient (linear, left top, right bottom, from(rgb(250, 250, 230)), to(rgb(160, 0, 0)));\n" "}\n", -1, NULL); gsc_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(gsc_provider), "GtkScale { \n" " background-image: -gtk-gradient (linear, left top, right bottom, from(rgb(250, 250, 230)), to(rgb(0, 160, 0)));\n" "}\n", -1, NULL); bsc_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(bsc_provider), "GtkScale { \n" " background-image: -gtk-gradient (linear, left top, right bottom, from(rgb(250, 250, 230)), to(rgb(0, 0, 160)));\n" "}\n", -1, NULL); /* I wanted to make the handle larger and set its color to #90ee90 -- no way! */ pd_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(pd_provider), "GtkPaned { \n" " background-color: #fffff0;\n" "}\n", -1, NULL); cb_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(cb_provider), "GtkRadioButton:hover, GtkCheckButton:hover { \n" " background-color: rgb(200, 200, 190);\n" "}\n", -1, NULL); /* gtk3 tree view is inaccessible in filechooser and row colors can't be set! */ } #endif #endif