chiark / gitweb /
set explicit colors instead of using rc file
authorRichard Kettlewell <rjk@greenend.org.uk>
Sun, 28 Oct 2007 13:14:22 +0000 (13:14 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sun, 28 Oct 2007 13:14:22 +0000 (13:14 +0000)
12 files changed:
disobedience/Makefile.am
disobedience/appearance.c [new file with mode: 0644]
disobedience/choose.c
disobedience/control.c
disobedience/disobedience.c
disobedience/disobedience.h
disobedience/disobedience.rc [deleted file]
disobedience/help.c
disobedience/menu.c
disobedience/misc.c
disobedience/properties.c
disobedience/queue.c

index 99abd7f..eb257d6 100644 (file)
@@ -25,9 +25,9 @@ AM_CFLAGS=$(GLIB_CFLAGS) $(GTK_CFLAGS)
 PNGS:=$(wildcard ${top_srcdir}/images/*.png)
 
 disobedience_SOURCES=disobedience.h disobedience.c client.c queue.c    \
-                 choose.c misc.c style.h control.c properties.c menu.c \
+                 choose.c misc.c control.c properties.c menu.c \
                  log.c progress.c login.c rtp.c help.c \
-                 ../lib/memgc.c
+                 ../lib/memgc.c appearance.c
 disobedience_LDADD=../lib/libdisorder.a $(LIBPCRE) $(LIBGC) $(LIBGCRYPT)
 disobedience_LDFLAGS=$(GTK_LIBS)
 
@@ -36,12 +36,6 @@ install-exec-hook:
 
 check: check-help
 
-disobedience.o: style.h
-
-style.h: ${srcdir}/disobedience.rc ${top_srcdir}/scripts/text2c
-       ${top_srcdir}/scripts/text2c style ${srcdir}/disobedience.rc > $@.tmp
-       mv $@.tmp $@
-
 help.o: manual.h
 
 manual.html: ../doc/disobedience.1 $(top_srcdir)/scripts/htmlman
@@ -70,8 +64,6 @@ images.h: $(PNGS)
        echo "};"
        mv @$.new $@
 
-EXTRA_DIST=disobedience.rc
-
 # check everything has working --help
 check-help: all
        ./disobedience --version > /dev/null
diff --git a/disobedience/appearance.c b/disobedience/appearance.c
new file mode 100644 (file)
index 0000000..07f39ae
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * This file is part of Disobedience
+ * Copyright (C) 2007 Richard Kettlewell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+/** @file disobedience/appearance.c
+ * @brief Visual appearance of Disobedience
+ *
+ * Originally I attempted to use a built-in rc file to configure
+ * Disobedience's colors.  This is quite convenient but fails in the
+ * face of themes, as the theme settings override the application
+ * ones.
+ *
+ * This file therefore collects all the colors of the Disobedience UI
+ * and (in time) will have a configuration dialog too.
+ */
+
+#include "disobedience.h"
+#include "inputline.h"
+#include "split.h"!
+#include <sys/stat.h>
+
+/** @brief Background colors for tools - menus, icons, etc. */
+GdkColor tool_bg = { 0, 0xDC00, 0xDA00, 0xD500 };
+
+/** @brief Background color for active tool */
+GdkColor tool_active;
+
+/** @brief Foreground colors for tools */
+GdkColor tool_fg = { 0, 0x0000, 0x0000, 0x0000 };
+
+/** @brief Foreground colors for inactive tools */
+GdkColor inactive_tool_fg = { 0, 0x8000, 0x8000, 0x8000 };
+
+/** @brief Background for inactive tools (e.g. noncurrent tabs) */
+GdkColor offtool_bg = { 0, 0xC400, 0xC200, 0xBD00 };
+
+/** @brief Background color for the various layouts */
+GdkColor layout_bg = { 0, 0xFFFF, 0xFFFF, 0xFFFF };
+
+/** @brief Title-row background color */
+GdkColor title_bg = { 0, 0x0000, 0x0000, 0x0000 };
+
+/** @brief Title-row foreground color */
+GdkColor title_fg = { 0, 0xFFFF, 0xFFFF, 0xFFFF };
+
+/** @brief Even-row background color */
+GdkColor even_bg = { 0, 0xFFFF, 0xEC00, 0xEBFF };
+
+/** @brief Odd-row background color */
+GdkColor odd_bg = { 0, 0xFFFF, 0xFFFF, 0xFFFF };
+
+/** @brief Active-row background color */
+GdkColor active_bg = { 0, 0xE000, 0xFFFF, 0xE000 };
+
+/** @brief Item foreground color */
+GdkColor item_fg = { 0, 0x0000, 0x0000, 0x0000 };
+
+/** @brief Selected background color */
+GdkColor selected_bg = { 0, 0x4B00, 0x6900, 0x8300 };
+
+/** @brief Selected foreground color */
+GdkColor selected_fg = { 0, 0xFFFF, 0xFFFF, 0xFFFF };
+
+/** @brief Search results */
+GdkColor search_bg = { 0, 0xFFFF, 0xFFFF, 0x0000 };
+
+/** @brief Drag target color */
+GdkColor drag_target = { 0, 0x6666, 0x6666, 0x6666 };
+
+struct colordesc {
+  GdkColor *color;
+  const char *name;
+  const char *description;
+};
+
+#define COLOR(name, description) { &name, #name, description }
+
+/** @brief Table of configurable colors
+ *
+ * Some of the descriptions could be improve!
+ */
+static const struct colordesc colors[] = {
+  COLOR(tool_bg, "Tool background color"),
+  COLOR(tool_fg, "Tool foreground color"),
+  COLOR(offtool_bg, "Subsiduary tool color"),
+  COLOR(layout_bg, "Layout background color"),
+  COLOR(title_bg, "Title row background color"),
+  COLOR(title_fg, "Title row foreground color"),
+  COLOR(even_bg, "Even row background color"),
+  COLOR(odd_bg, "Odd row background color"),
+  COLOR(active_bg, "Playing row background color"),
+  COLOR(item_fg, "Track foreground color"),
+  COLOR(selected_bg, "Selected item background color"),
+  COLOR(selected_fg, "Selected item foreground color"),
+  COLOR(search_bg, "Search result background color"),
+  COLOR(drag_target, "Drag target color"),
+};
+
+#define NCOLORS (sizeof colors / sizeof *colors)
+
+void save_appearance(void) {
+  char *dir, *path, *tmp;
+  FILE *fp = 0;
+  size_t n;
+
+  byte_xasprintf(&dir, "%s/.disorder", getenv("HOME"));
+  byte_xasprintf(&path, "%s/disobedience", dir);
+  byte_xasprintf(&tmp, "%s.tmp", path);
+  mkdir(dir, 02700);                    /* make sure directory exists */
+  if(!(fp = fopen(tmp, "w"))) {
+    fpopup_msg(GTK_MESSAGE_ERROR, "error opening %s: %s",
+               tmp, strerror(errno));
+    goto done;
+  }
+  for(n = 0; n < NCOLORS; ++n)
+    if(fprintf(fp, "color %-20s 0x%04X 0x%04X 0x%04X\n", colors[n].name,
+               colors[n].color->red,
+               colors[n].color->green,
+               colors[n].color->blue) < 0) {
+      fpopup_msg(GTK_MESSAGE_ERROR, "error writing to %s: %s",
+                 tmp, strerror(errno));
+      goto done;
+    }
+  if(fclose(fp) < 0) {
+    fpopup_msg(GTK_MESSAGE_ERROR, "error writing to %s: %s",
+               tmp, strerror(errno));
+    fp = 0;
+    goto done;
+  }
+  fp = 0;
+  if(rename(tmp, path) < 0)
+    fpopup_msg(GTK_MESSAGE_ERROR, "error renaming %s to %s: %s",
+               tmp, path, strerror(errno));
+done:
+  if(fp)
+    fclose(fp);
+}
+
+static inline unsigned clamp(unsigned n) {
+  return n > 0xFFFF ? 0xFFFF : n;
+}
+
+void load_appearance(void) {
+  char *path, *line;
+  FILE *fp;
+  size_t n;
+  char **vec;
+  int nvec;
+
+  byte_xasprintf(&path, "%s/.disorder/disobedience", getenv("HOME"));
+  if(!(fp = fopen(path, "r"))) {
+    if(errno != ENOENT)
+      fpopup_msg(GTK_MESSAGE_ERROR, "error opening %s: %s",
+                 path, strerror(errno));
+    return;
+  }
+  while(!inputline(path, fp, &line, '\n')) {
+    if(!(vec = split(line, &nvec, SPLIT_COMMENTS|SPLIT_QUOTES, 0, 0))
+       || !nvec)
+      continue;
+    if(!strcmp(vec[0], "color")) {
+      if(nvec != 5) {
+        error(0, "%s: malformed '%s' command", path, vec[0]);
+        continue;
+      }
+      for(n = 0; n < NCOLORS && strcmp(colors[n].name, vec[1]); ++n)
+        ;
+      if(n >= NCOLORS) {
+        error(0, "%s: unknown color '%s'", path, vec[1]);
+        continue;
+      }
+      colors[n].color->red = strtoul(vec[2], 0, 0);
+      colors[n].color->green = strtoul(vec[3], 0, 0);
+      colors[n].color->blue = strtoul(vec[4], 0, 0);
+    } else
+      /* mention errors but otherwise ignore them */
+      error(0, "%s: unknown command '%s'", path, vec[0]);
+  }
+  if(ferror(fp)) {
+    fpopup_msg(GTK_MESSAGE_ERROR, "error reading %s: %s",
+               path, strerror(errno));
+    fclose(fp);
+  }
+  tool_active = tool_bg;
+  tool_active.red = clamp(105 * tool_active.red / 100);
+  tool_active.green = clamp(105 * tool_active.green / 100);
+  tool_active.blue = clamp(105 * tool_active.blue / 100);
+}
+
+/** @brief Callback used by set_tool_colors() */
+static void set_tool_colors_callback(GtkWidget *w,
+                                     gpointer attribute((unused)) data) {
+  set_tool_colors(w);
+}
+
+/** @brief Recursively set tool widget colors */
+void set_tool_colors(GtkWidget *w) {
+  GtkWidget *child;
+
+  gtk_widget_modify_bg(w, GTK_STATE_NORMAL, &tool_bg);
+  gtk_widget_modify_bg(w, GTK_STATE_SELECTED, &selected_bg);
+  gtk_widget_modify_bg(w, GTK_STATE_PRELIGHT, &selected_bg);
+  gtk_widget_modify_bg(w, GTK_STATE_INSENSITIVE, &tool_bg);
+  gtk_widget_modify_fg(w, GTK_STATE_NORMAL, &tool_fg);
+  gtk_widget_modify_fg(w, GTK_STATE_SELECTED, &selected_fg);
+  gtk_widget_modify_fg(w, GTK_STATE_PRELIGHT, &selected_fg);
+  gtk_widget_modify_fg(w, GTK_STATE_INSENSITIVE, &inactive_tool_fg);
+  if(GTK_IS_CONTAINER(w))
+    gtk_container_foreach(GTK_CONTAINER(w), set_tool_colors_callback, 0);
+  if(GTK_IS_MENU_ITEM(w)
+     && (child = gtk_menu_item_get_submenu(GTK_MENU_ITEM(w))))
+    set_tool_colors(child);
+}
+
+/** @brief Set the colors for a slider */
+void set_slider_colors(GtkWidget *w) {
+  if(!w)
+    return;
+  gtk_widget_modify_bg(w, GTK_STATE_NORMAL, &tool_bg);
+  gtk_widget_modify_bg(w, GTK_STATE_ACTIVE, &tool_bg);
+  gtk_widget_modify_bg(w, GTK_STATE_SELECTED, &tool_active);
+  gtk_widget_modify_bg(w, GTK_STATE_PRELIGHT, &tool_active);
+  gtk_widget_modify_fg(w, GTK_STATE_NORMAL, &tool_fg);
+  gtk_widget_modify_fg(w, GTK_STATE_ACTIVE, &tool_fg);
+  gtk_widget_modify_fg(w, GTK_STATE_SELECTED, &tool_fg);
+  gtk_widget_modify_fg(w, GTK_STATE_PRELIGHT, &tool_fg);
+}
+
+/*
+Local Variables:
+c-basic-offset:2
+comment-column:40
+fill-column:79
+indent-tabs-mode:nil
+End:
+*/
index 8aa11e2..e69f4b5 100644 (file)
@@ -805,7 +805,6 @@ static struct displaydata display_tree(struct choosenode *cn, int x, int y) {
   GtkRequisition req;
   struct displaydata d, cd;
   GdkPixbuf *pb;
-  const char *name;
   const int search_result = is_search_result(cn->path);
   
   D(("display_tree %s %d,%d", cn->path, x, y));
@@ -857,12 +856,16 @@ static struct displaydata display_tree(struct choosenode *cn, int x, int y) {
     MTAG_POP();
   }
   assert(cn->container);
-  /* Make sure the widget name is right */
-  name = (cn->flags & CN_EXPANDABLE
-          ? "choose-dir"
-          : search_result ? "choose-search" : "choose");
-  gtk_widget_set_name(cn->label, name);
-  gtk_widget_set_name(cn->container, name);
+  /* Set colors */
+  if(search_result)
+    gtk_widget_modify_bg(cn->container, GTK_STATE_NORMAL, &search_bg);
+  else
+    gtk_widget_modify_bg(cn->container, GTK_STATE_NORMAL, &layout_bg);
+  gtk_widget_modify_bg(cn->container, GTK_STATE_SELECTED, &selected_bg);
+  gtk_widget_modify_bg(cn->container, GTK_STATE_PRELIGHT, &selected_bg);
+  gtk_widget_modify_fg(cn->label, GTK_STATE_NORMAL, &item_fg);
+  gtk_widget_modify_fg(cn->label, GTK_STATE_SELECTED, &selected_fg);
+  gtk_widget_modify_fg(cn->label, GTK_STATE_PRELIGHT, &selected_fg);
   /* Make sure the icon is right */
   if(cn->flags & CN_EXPANDABLE)
     gtk_arrow_set(GTK_ARROW(cn->arrow),
@@ -1077,6 +1080,7 @@ static void clicked_choosenode(GtkWidget attribute((unused)) *widget,
       menuitems[n].handlerid = g_signal_connect
         (menuitems[n].w, "activate", G_CALLBACK(menuitems[n].activate), cn);
     }
+    set_tool_colors(menu);
     /* Pop up the menu */
     gtk_widget_show_all(menu);
     gtk_menu_popup(GTK_MENU(menu), 0, 0, 0, 0,
@@ -1332,6 +1336,10 @@ GtkWidget *choose_widget(void) {
   /* Cancel button to clear the search */
   NW(button);
   clearsearch = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+  gtk_widget_modify_bg(clearsearch, GTK_STATE_NORMAL, &tool_bg);
+  gtk_widget_modify_bg(clearsearch, GTK_STATE_ACTIVE, &tool_active);
+  gtk_widget_modify_bg(clearsearch, GTK_STATE_PRELIGHT, &tool_active);
+  gtk_widget_modify_bg(clearsearch, GTK_STATE_SELECTED, &tool_active);
   g_signal_connect(G_OBJECT(clearsearch), "clicked",
                    G_CALLBACK(clearsearch_clicked), 0);
   gtk_tooltips_set_tip(tips, clearsearch, "Clear search terms", "");
@@ -1342,10 +1350,20 @@ GtkWidget *choose_widget(void) {
   g_signal_connect(G_OBJECT(prevsearch), "clicked",
                    G_CALLBACK(prev_clicked), 0);
   gtk_widget_set_sensitive(prevsearch, 0);
+  gtk_widget_modify_bg(prevsearch, GTK_STATE_NORMAL, &tool_bg);
+  gtk_widget_modify_bg(prevsearch, GTK_STATE_ACTIVE, &tool_active);
+  gtk_widget_modify_bg(prevsearch, GTK_STATE_PRELIGHT, &tool_active);
+  gtk_widget_modify_bg(prevsearch, GTK_STATE_SELECTED, &tool_active);
+  gtk_widget_modify_bg(prevsearch, GTK_STATE_INSENSITIVE, &tool_active);
   nextsearch = iconbutton("down.png", "Next search result");
   g_signal_connect(G_OBJECT(nextsearch), "clicked",
                    G_CALLBACK(next_clicked), 0);
   gtk_widget_set_sensitive(nextsearch, 0);
+  gtk_widget_modify_bg(nextsearch, GTK_STATE_NORMAL, &tool_bg);
+  gtk_widget_modify_bg(nextsearch, GTK_STATE_ACTIVE, &tool_active);
+  gtk_widget_modify_bg(nextsearch, GTK_STATE_PRELIGHT, &tool_active);
+  gtk_widget_modify_bg(nextsearch, GTK_STATE_SELECTED, &tool_active);
+  gtk_widget_modify_bg(nextsearch, GTK_STATE_INSENSITIVE, &tool_active);
 
   /* hbox packs the search tools button together on a line */
   NW(hbox);
@@ -1363,6 +1381,7 @@ GtkWidget *choose_widget(void) {
    * namespace */
   NW(layout);
   chooselayout = gtk_layout_new(0, 0);
+  gtk_widget_modify_bg(chooselayout, GTK_STATE_NORMAL, &layout_bg);
   choose_reset();
   register_reset(choose_reset);
   /* Create the popup menus */
@@ -1389,7 +1408,7 @@ GtkWidget *choose_widget(void) {
                     0, 1, n, n + 1);
   }
   /* The layout is scrollable */
-  scrolled = scroll_widget(chooselayout, "choose");
+  scrolled = scroll_widget(chooselayout);
   vadjust = gtk_layout_get_vadjustment(GTK_LAYOUT(chooselayout));
 
   /* The scrollable layout and the search hbox go together in a vbox */
index 36282cf..92e2b74 100644 (file)
@@ -231,6 +231,10 @@ GtkWidget *control_widget(void) {
   for(n = 0; n < NICONS; ++n) {
     NW(button);
     icons[n].button = gtk_button_new();
+    gtk_widget_modify_bg(icons[n].button, GTK_STATE_NORMAL, &tool_bg);
+    gtk_widget_modify_bg(icons[n].button, GTK_STATE_ACTIVE, &tool_active);
+    gtk_widget_modify_bg(icons[n].button, GTK_STATE_PRELIGHT, &tool_active);
+    gtk_widget_modify_bg(icons[n].button, GTK_STATE_SELECTED, &tool_active);
     if((pb = find_image(icons[n].icon))) {
       NW(image);
       content = gtk_image_new_from_pixbuf(pb);
@@ -279,6 +283,8 @@ GtkWidget *control_widget(void) {
   v = gtk_hscale_new(volume_adj);
   NW(hscale);
   b = gtk_hscale_new(balance_adj);
+  set_slider_colors(v);
+  set_slider_colors(b);
   gtk_scale_set_digits(GTK_SCALE(v), 10);
   gtk_scale_set_digits(GTK_SCALE(b), 10);
   gtk_widget_set_size_request(v, 192, -1);
index d99ecef..291d955 100644 (file)
@@ -30,8 +30,6 @@
 /* Apologies for the numerous de-consting casts, but GLib et al do not seem to
  * have heard of const. */
 
-#include "style.h"                      /* generated style */
-
 /* Variables --------------------------------------------------------------- */
 
 /** @brief Event loop */
@@ -138,6 +136,12 @@ static GtkWidget *report_box(void) {
 /** @brief Create and populate the main tab group */
 static GtkWidget *notebook(void) {
   tabs = gtk_notebook_new();
+  /* The current tab is _NORMAL, the rest are _ACTIVE, which is bizarre but
+   * produces not too dreadful appearance */
+  gtk_widget_modify_bg(tabs, GTK_STATE_NORMAL, &tool_bg);
+  gtk_widget_modify_bg(tabs, GTK_STATE_ACTIVE, &tool_active);
+  gtk_widget_modify_fg(tabs, GTK_STATE_NORMAL, &tool_fg);
+  gtk_widget_modify_fg(tabs, GTK_STATE_ACTIVE, &tool_fg);
   g_signal_connect(tabs, "switch-page", G_CALLBACK(tab_switched), 0);
   gtk_notebook_append_page(GTK_NOTEBOOK(tabs), queue_widget(),
                            gtk_label_new("Queue"));
@@ -182,7 +186,7 @@ static void make_toplevel_window(void) {
                    FALSE,             /* expand */
                    FALSE,             /* fill */
                    0);
-  gtk_widget_set_name(toplevel, "disobedience");
+  gtk_widget_modify_bg(toplevel, GTK_STATE_NORMAL, &tool_bg);
 }
 
 #if MDEBUG
@@ -437,7 +441,6 @@ int main(int argc, char **argv) {
 #endif
   if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
   gtk_init(&argc, &argv);
-  gtk_rc_parse_string(style);
   while((n = getopt_long(argc, argv, "hVc:dtHC", options, 0)) >= 0) {
     switch(n) {
     case 'h': help();
@@ -449,6 +452,7 @@ int main(int argc, char **argv) {
     }
   }
   signal(SIGPIPE, SIG_IGN);
+  load_appearance();
   /* create the event loop */
   D(("create main loop"));
   mainloop = g_main_loop_new(0, 0);
index 293a773..5981229 100644 (file)
@@ -133,7 +133,7 @@ void properties(int ntracks, const char **tracks);
 
 void properties_reset(void);
 
-GtkWidget *scroll_widget(GtkWidget *child, const char *name);
+GtkWidget *scroll_widget(GtkWidget *child);
 /* Wrap a widget up for scrolling */
 
 GdkPixbuf *find_image(const char *name);
@@ -245,6 +245,17 @@ int rtp_running(void);
 void start_rtp(void);
 void stop_rtp(void);
 
+/* Appearance */
+
+extern GdkColor tool_bg, tool_fg, offtool_bg, layout_bg, even_bg, odd_bg;
+extern GdkColor active_bg, selected_bg, selected_fg, search_bg;
+extern GdkColor title_bg, title_fg, item_fg, drag_target, tool_active;
+
+void save_appearance(void);
+void load_appearance(void);
+void set_tool_colors(GtkWidget *w);
+void set_slider_colors(GtkWidget *w);
+
 /* Widget leakage debugging rubbish ---------------------------------------- */
 
 #if MDEBUG
diff --git a/disobedience/disobedience.rc b/disobedience/disobedience.rc
deleted file mode 100644 (file)
index 1cd35b2..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-#
-# This file is part of DisOrder.
-# Copyright (C) 2006, 2007 Richard Kettlewell
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-# USA
-#
-
-# Default style for Disobedience
-#
-# See e.g. http://developer.gnome.org/doc/API/2.0/gtk/gtk-Resource-Files.html
-# for syntax documentation.
-
-style "disobedience-default"
-{
-  bg[NORMAL] = { 1.0, 1.0, 1.0 }
-  fg[NORMAL] = { 0.0, 0.0, 0.0 }
-  bg[PRELIGHT] = { 1.0, 1.0, 1.0 }
-  fg[PRELIGHT] = { 1.0, 1.0, 1.0 }
-}
-
-style "disobedience-playing"
-{
-  bg[NORMAL] = { 0.875, 1.0, 0.875 }
-  fg[NORMAL] = { 0.0, 0.0, 0.0 }
-}
-
-style "disobedience-even"
-{
-  bg[NORMAL] = { 1.0, 0.921875, 0.921875 }
-  fg[NORMAL] = { 0.0, 0.0, 0.0 }
-}
-
-style "disobedience-odd"
-{
-  bg[NORMAL] = { 1.0, 1.0, 1.0 }
-  fg[NORMAL] = { 0.0, 0.0, 0.0 }
-}
-
-style "disobedience-search"
-{
-  bg[NORMAL] = { 1.0, 1.0, 0.0 }
-  fg[NORMAL] = { 0.0, 0.0, 0.0 }
-}
-
-style "disobedience-title"
-{
-  bg[NORMAL] = { 0.0, 0.0, 0.0 }
-  fg[NORMAL] = { 1.0, 1.0, 1.0 }
-  font_name = "Bold"
-}
-
-style "disobedience-drag"
-{
-  bg[NORMAL] = { 0.4, 0.4, 0.4 }
-  fg[NORMAL] = { 1.0, 1.0, 1.0 }
-}
-
-# The main tabs
-widget "disobedience.*.choose" style : application "disobedience-default"
-widget "disobedience.*.choose-dir" style : application "disobedience-default"
-widget "disobedience.*.queue" style : application "disobedience-default"
-widget "disobedience.*.recent" style : application "disobedience-default"
-
-# Drag target
-widget "disobedience.*.queue-drag" style : application "disobedience-drag"
-
-# Rows in the queue/recent tabs
-widget "disobedience.*.row-playing" style : application "disobedience-playing"
-widget "disobedience.*.row-even" style : application "disobedience-even"
-widget "disobedience.*.row-odd" style : application "disobedience-odd"
-widget "disobedience.*.row-title" style : application "disobedience-title"
-
-# Search results
-widget "disobedience.*.choose-search" style : application "disobedience-search"
index 0815bac..06691c7 100644 (file)
@@ -227,9 +227,7 @@ void popup_help(void) {
   gtk_window_set_title(GTK_WINDOW(help_window), "Disobedience Manual Page");
   view = gtk_text_view_new_with_buffer(html_buffer(manual));
   gtk_text_view_set_editable(GTK_TEXT_VIEW(view), FALSE);
-  gtk_container_add(GTK_CONTAINER(help_window),
-                   scroll_widget(view,
-                                 "help"));
+  gtk_container_add(GTK_CONTAINER(help_window), scroll_widget(view));
   gtk_window_set_default_size(GTK_WINDOW(help_window), 512, 512);
   gtk_widget_show_all(help_window);
 }
index c5ace02..8900cf2 100644 (file)
@@ -146,6 +146,8 @@ static void about_popup_got_version(void attribute((unused)) *v,
 
 /** @brief Create the menu bar widget */
 GtkWidget *menubar(GtkWidget *w) {
+  GtkWidget *m;
+
   static const GtkItemFactoryEntry entries[] = {
     {
       (char *)"/File",                  /* path */
@@ -281,9 +283,10 @@ GtkWidget *menubar(GtkWidget *w) {
                                                  "<GdisorderMain>/Edit/Track properties");
   assert(selectall_widget != 0);
   assert(properties_widget != 0);
-  return gtk_item_factory_get_widget(mainmenufactory,
-                                     "<GdisorderMain>");
-  /* menu bar had better not expand vertically if the window is too big */
+  m = gtk_item_factory_get_widget(mainmenufactory,
+                                  "<GdisorderMain>");
+  set_tool_colors(m);
+  return m;
 }
 
 /*
index 2db0173..7e44cc2 100644 (file)
@@ -39,11 +39,9 @@ WT(cached_image);
 
 /** @brief Put scrollbars around a widget
  * @param child Widget to surround
- * @param widgetname Name for (both) widgets
  * @return Scroll widget
  */
-GtkWidget *scroll_widget(GtkWidget *child,
-                         const char *widgetname) {
+GtkWidget *scroll_widget(GtkWidget *child) {
   GtkWidget *scroller = gtk_scrolled_window_new(0, 0);
   GtkAdjustment *adj;
 
@@ -67,9 +65,8 @@ GtkWidget *scroll_widget(GtkWidget *child,
     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroller),
                                           child);
   }
-  /* Apply a name to the widget so it can be recolored */
-  gtk_widget_set_name(GTK_BIN(scroller)->child, widgetname);
-  gtk_widget_set_name(scroller, widgetname);
+  set_slider_colors(GTK_SCROLLED_WINDOW(scroller)->hscrollbar);
+  set_slider_colors(GTK_SCROLLED_WINDOW(scroller)->vscrollbar);
   return scroller;
 }
 
index d306b56..82af9ad 100644 (file)
@@ -266,8 +266,7 @@ void properties(int ntracks, const char **tracks) {
   /* Put it all together */
   vbox = gtk_vbox_new(FALSE, 1);
   gtk_box_pack_start(GTK_BOX(vbox), 
-                     scroll_widget(properties_table,
-                                   "properties"),
+                     scroll_widget(properties_table),
                      TRUE, TRUE, 1);
   gtk_box_pack_start(GTK_BOX(vbox), buttonbox, FALSE, FALSE, 1);
   gtk_container_add(GTK_CONTAINER(properties_window), vbox);
index dc36cea..6de6483 100644 (file)
@@ -174,9 +174,6 @@ struct queue_menuitem {
  * ql_added.
  */
 struct queuelike {
-  /** @brief Name of this queue */
-  const char *name;
-
   /** @brief Called when an update completes */
   void (*notify)(void);
 
@@ -509,9 +506,15 @@ static void update_queue(struct queuelike *ql, struct queue_entry *newq) {
   selection_cleanup(ql->selection);
 }
 
-/** @brief Wrap up a widget for putting into the queue or title */
+/** @brief Wrap up a widget for putting into the queue or title
+ * @param label Label to contain
+ * @param color Pointer to color
+ * @param wp Updated with maximum width (or NULL)
+ * @return New widget
+ */
 static GtkWidget *wrap_queue_cell(GtkWidget *label,
-                                  const char *name,
+                                  const GdkColor *bgcolor,
+                                  const GdkColor *fgcolor,
                                   int *wp) {
   GtkRequisition req;
   GtkWidget *bg;
@@ -529,9 +532,13 @@ static GtkWidget *wrap_queue_cell(GtkWidget *label,
     gtk_widget_size_request(label, &req);
     if(req.width > *wp) *wp = req.width;
   }
-  /* Set widget names */
-  gtk_widget_set_name(bg, name);
-  gtk_widget_set_name(label, name);
+  /* Set colors */
+  gtk_widget_modify_bg(bg, GTK_STATE_NORMAL, bgcolor);
+  gtk_widget_modify_bg(bg, GTK_STATE_SELECTED, &selected_bg);
+  gtk_widget_modify_bg(bg, GTK_STATE_PRELIGHT, &selected_bg);
+  gtk_widget_modify_fg(label, GTK_STATE_NORMAL, fgcolor);
+  gtk_widget_modify_fg(label, GTK_STATE_SELECTED, &selected_fg);
+  gtk_widget_modify_fg(label, GTK_STATE_PRELIGHT, &selected_fg);
   return bg;
 }
 
@@ -540,20 +547,22 @@ static GtkWidget *get_queue_cell(struct queuelike *ql,
                                  const struct queue_entry *q,
                                  int row,
                                  int col,
-                                 const char *name,
+                                 const GdkColor *bgcolor,
+                                 const GdkColor *fgcolor,
                                  int *wp) {
   GtkWidget *label;
   D(("get_queue_cell %d %d", row, col));
   label = ql->columns[col].widget(ql, q, ql->columns[col].data);
   gtk_misc_set_alignment(GTK_MISC(label), ql->columns[col].xalign, 0);
-  return wrap_queue_cell(label, name, wp);
+  return wrap_queue_cell(label, bgcolor, fgcolor, wp);
 }
 
 /** @brief Add a padding cell to the end of a row */
-static GtkWidget *get_padding_cell(const char *name) {
+static GtkWidget *get_padding_cell(const GdkColor *bgcolor,
+                                   const GdkColor *fgcolor) {
   D(("get_padding_cell"));
   NW(label);
-  return wrap_queue_cell(gtk_label_new(""), name, 0);
+  return wrap_queue_cell(gtk_label_new(""), bgcolor, fgcolor, 0);
 }
 
 /* User button press and menu ---------------------------------------------- */
@@ -804,7 +813,7 @@ static gboolean queue_drag_motion(GtkWidget attribute((unused)) *widget,
       g_signal_connect(ql->dragmark, "destroy",
                        G_CALLBACK(gtk_widget_destroyed), &ql->dragmark);
       gtk_widget_set_size_request(ql->dragmark, 10240, row ? 4 : 2);
-      gtk_widget_set_name(ql->dragmark, "queue-drag");
+      gtk_widget_modify_bg(ql->dragmark, GTK_STATE_NORMAL, &drag_target);
       gtk_layout_put(GTK_LAYOUT(ql->mainlayout), ql->dragmark, 0, 
                      (row + 1) * ql->mainrowheight - !!row);
     } else
@@ -906,7 +915,7 @@ static void redisplay_queue(struct queuelike *ql) {
   struct queue_entry *q;
   int row, col;
   GList *c, *children;
-  const char *name;
+  const GdkColor *bgcolor;
   GtkRequisition req;  
   GtkWidget *w;
   int maxwidths[MAXCOLUMNS], x, y, titlerowheight;
@@ -946,15 +955,16 @@ static void redisplay_queue(struct queuelike *ql) {
     /* Construct the widgets */
     for(q = ql->q, row = 0; q; q = q->next, ++row) {
       /* Figure out the widget name for this row */
-      if(q == playing_track) name = "row-playing";
-      else name = row % 2 ? "row-even" : "row-odd";
+      if(q == playing_track) bgcolor = &active_bg;
+      else bgcolor = row % 2 ? &even_bg : &odd_bg;
       /* Make the widget for each column */
       for(col = 0; col <= ql->ncolumns; ++col) {
         /* Create and store the widget */
         if(col < ql->ncolumns)
-          w = get_queue_cell(ql, q, row, col, name, &maxwidths[col]);
+          w = get_queue_cell(ql, q, row, col, bgcolor, &item_fg,
+                             &maxwidths[col]);
         else
-          w = get_padding_cell(name);
+          w = get_padding_cell(bgcolor, &item_fg);
         ql->cells[row * (ql->ncolumns + 1) + col] = w;
         /* Maybe mark it draggable */
         if(draggable_row(q)) {
@@ -1059,7 +1069,6 @@ static GtkWidget *queuelike(struct queuelike *ql,
                             struct queue_entry *(*fixup)(struct queue_entry *),
                             void (*notify)(void),
                             struct queue_menuitem *menuitems,
-                            const char *name,
                             const struct column *columns,
                             int ncolumns) {
   GtkWidget *vbox, *mainscroll, *titlescroll, *label;
@@ -1070,7 +1079,6 @@ static GtkWidget *queuelike(struct queuelike *ql,
   ql->fixup = fixup;
   ql->notify = notify;
   ql->menuitems = menuitems;
-  ql->name = name;
   ql->mainrowheight = !0;                /* else division by 0 */
   ql->selection = selection_new();
   ql->columns = columns;
@@ -1078,11 +1086,12 @@ static GtkWidget *queuelike(struct queuelike *ql,
   /* Create the layouts */
   NW(layout);
   ql->mainlayout = gtk_layout_new(0, 0);
+  gtk_widget_modify_bg(ql->mainlayout, GTK_STATE_NORMAL, &layout_bg);
   NW(layout);
   ql->titlelayout = gtk_layout_new(0, 0);
   /* Scroll the layouts */
-  ql->mainscroll = mainscroll = scroll_widget(ql->mainlayout, name);
-  titlescroll = scroll_widget(ql->titlelayout, name);
+  ql->mainscroll = mainscroll = scroll_widget(ql->mainlayout);
+  titlescroll = scroll_widget(ql->titlelayout);
   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(titlescroll),
                                  GTK_POLICY_NEVER, GTK_POLICY_NEVER);
   mainadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(mainscroll));
@@ -1094,10 +1103,10 @@ static GtkWidget *queuelike(struct queuelike *ql,
     NW(label);
     label = gtk_label_new(ql->columns[col].name);
     gtk_misc_set_alignment(GTK_MISC(label), ql->columns[col].xalign, 0);
-    ql->titlecells[col] = wrap_queue_cell(label, "row-title", 0);
+    ql->titlecells[col] = wrap_queue_cell(label, &title_bg, &title_fg, 0);
     gtk_layout_put(GTK_LAYOUT(ql->titlelayout), ql->titlecells[col], 0, 0);
   }
-  ql->titlecells[col] = get_padding_cell("row-title");
+  ql->titlecells[col] = get_padding_cell(&title_bg, &title_fg);
   gtk_layout_put(GTK_LAYOUT(ql->titlelayout), ql->titlecells[col], 0, 0);
   /* Pack the lot together in a vbox */
   NW(vbox);
@@ -1123,6 +1132,7 @@ static GtkWidget *queuelike(struct queuelike *ql,
   g_signal_connect(ql->mainlayout, "button-press-event",
                    G_CALLBACK(mainlayout_button), ql);
 #endif
+  set_tool_colors(ql->menu);
   return vbox;
 }
 
@@ -1317,7 +1327,7 @@ GtkWidget *queue_widget(void) {
   /* We pass choose_update() as our notify function since the choose screen
    * marks tracks that are playing/in the queue. */
   return queuelike(&ql_queue, fixup_queue, choose_update, queue_menu,
-                   "queue", maincolumns, NMAINCOLUMNS);
+                   maincolumns, NMAINCOLUMNS);
 }
 
 /** @brief Arrange an update of the queue widget
@@ -1369,7 +1379,7 @@ static struct queue_menuitem recent_menu[] = {
 GtkWidget *recent_widget(void) {
   D(("recent_widget"));
   register_reset(recent_update);
-  return queuelike(&ql_recent, fixup_recent, 0, recent_menu, "recent",
+  return queuelike(&ql_recent, fixup_recent, 0, recent_menu,
                    maincolumns, NMAINCOLUMNS);
 }
 
@@ -1402,7 +1412,7 @@ static struct queue_menuitem added_menu[] = {
 GtkWidget *added_widget(void) {
   D(("added_widget"));
   register_reset(added_update);
-  return queuelike(&ql_added, 0/*fixup*/, 0/*notify*/, added_menu, "added",
+  return queuelike(&ql_added, 0/*fixup*/, 0/*notify*/, added_menu,
                    addedcolumns, NADDEDCOLUMNS);
 }