summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2010-03-21 00:19:02 +0100
committerJon Bergli Heier <snakebite@jvnv.net>2010-03-21 00:19:02 +0100
commit5ebed0cd5dc2eb2f71e18b24148903f3c10ebf69 (patch)
tree8da511b975aea9f8e8eb081993a761031a1996e2
parentb6b63a3c51eab072483ac0c7ad07f107bb790788 (diff)
Implemented a very basic configuration dialog.
This code is a bit hackish, all configuration options should be collected in a single place (eg. a config struct) in order to easily keep track of all configuration options.
-rw-r--r--SConstruct8
-rw-r--r--config.ui120
-rw-r--r--config_ui.h126
-rw-r--r--preload.c4
-rw-r--r--wallpapers.c6
-rw-r--r--wallpapers.h2
-rw-r--r--walls.ui15
-rw-r--r--window_config.c100
-rw-r--r--window_config.h15
-rw-r--r--window_main.c19
10 files changed, 409 insertions, 6 deletions
diff --git a/SConstruct b/SConstruct
index f9d3986..7300a29 100644
--- a/SConstruct
+++ b/SConstruct
@@ -36,10 +36,11 @@ env.ParseConfig('pkg-config --cflags --libs gthread-2.0')
def build_ui(target, source, env):
f = open(str(target[0]), 'w')
- f.write('#ifndef _WALLS_UI_H_\n')
- f.write('#define _WALLS_UI_H_\n')
+ uiname = str(target[0]).rsplit('.', 1)[0]
+ f.write('#ifndef _%s_H_\n' % uiname.upper())
+ f.write('#define _%s_H_\n' % uiname.upper())
f.write('#include <gtk/gtk.h>\n')
- f.write('gchar *%s_string = \n' % str(target[0]).rsplit('.', 1)[0])
+ f.write('gchar *%s_string = \n' % uiname)
for line in open(str(source[0]), 'r'):
f.write('"%s"\n' % line.replace('"', '\\"').strip())
f.write(';\n')
@@ -50,6 +51,7 @@ ui_builder = Builder(action = build_ui)
env['BUILDERS']['walls_ui'] = ui_builder
env.walls_ui('walls_ui.h', 'walls.ui')
env.walls_ui('tags_ui.h', 'tags.ui')
+env.walls_ui('config_ui.h', 'config.ui')
walls = env.Program('walls', Glob('*.c'))
destdir = ARGUMENTS.get('DESTDIR', '')
diff --git a/config.ui b/config.ui
new file mode 100644
index 0000000..2a73642
--- /dev/null
+++ b/config.ui
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkDialog" id="config_dialog">
+ <property name="border_width">5</property>
+ <property name="type_hint">normal</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Interpolation Mode:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">interp_combo</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="interp_combo">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Max _Preload:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">preload_scale</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHScale" id="preload_scale">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="digits">0</property>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="button2">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button1">
+ <property name="label">gtk-ok</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">button2</action-widget>
+ <action-widget response="-5">button1</action-widget>
+ </action-widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">32</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">8</property>
+ </object>
+</interface>
diff --git a/config_ui.h b/config_ui.h
new file mode 100644
index 0000000..952aa4b
--- /dev/null
+++ b/config_ui.h
@@ -0,0 +1,126 @@
+#ifndef _CONFIG_UI_H_
+#define _CONFIG_UI_H_
+#include <gtk/gtk.h>
+gchar *config_ui_string =
+"<?xml version=\"1.0\"?>"
+"<interface>"
+"<requires lib=\"gtk+\" version=\"2.16\"/>"
+"<!-- interface-naming-policy project-wide -->"
+"<object class=\"GtkDialog\" id=\"config_dialog\">"
+"<property name=\"border_width\">5</property>"
+"<property name=\"type_hint\">normal</property>"
+"<property name=\"has_separator\">False</property>"
+"<child internal-child=\"vbox\">"
+"<object class=\"GtkVBox\" id=\"dialog-vbox1\">"
+"<property name=\"visible\">True</property>"
+"<property name=\"orientation\">vertical</property>"
+"<property name=\"spacing\">2</property>"
+"<child>"
+"<object class=\"GtkVBox\" id=\"vbox1\">"
+"<property name=\"visible\">True</property>"
+"<property name=\"orientation\">vertical</property>"
+"<child>"
+"<object class=\"GtkLabel\" id=\"label1\">"
+"<property name=\"visible\">True</property>"
+"<property name=\"label\" translatable=\"yes\">_Interpolation Mode:</property>"
+"<property name=\"use_underline\">True</property>"
+"<property name=\"mnemonic_widget\">interp_combo</property>"
+"</object>"
+"<packing>"
+"<property name=\"expand\">False</property>"
+"<property name=\"position\">0</property>"
+"</packing>"
+"</child>"
+"<child>"
+"<object class=\"GtkComboBox\" id=\"interp_combo\">"
+"<property name=\"visible\">True</property>"
+"</object>"
+"<packing>"
+"<property name=\"expand\">False</property>"
+"<property name=\"position\">1</property>"
+"</packing>"
+"</child>"
+"<child>"
+"<object class=\"GtkLabel\" id=\"label2\">"
+"<property name=\"visible\">True</property>"
+"<property name=\"label\" translatable=\"yes\">Max _Preload:</property>"
+"<property name=\"use_underline\">True</property>"
+"<property name=\"mnemonic_widget\">preload_scale</property>"
+"</object>"
+"<packing>"
+"<property name=\"expand\">False</property>"
+"<property name=\"position\">2</property>"
+"</packing>"
+"</child>"
+"<child>"
+"<object class=\"GtkHScale\" id=\"preload_scale\">"
+"<property name=\"visible\">True</property>"
+"<property name=\"can_focus\">True</property>"
+"<property name=\"adjustment\">adjustment1</property>"
+"<property name=\"digits\">0</property>"
+"</object>"
+"<packing>"
+"<property name=\"position\">3</property>"
+"</packing>"
+"</child>"
+"</object>"
+"<packing>"
+"<property name=\"expand\">False</property>"
+"<property name=\"position\">1</property>"
+"</packing>"
+"</child>"
+"<child internal-child=\"action_area\">"
+"<object class=\"GtkHButtonBox\" id=\"dialog-action_area1\">"
+"<property name=\"visible\">True</property>"
+"<property name=\"layout_style\">end</property>"
+"<child>"
+"<object class=\"GtkButton\" id=\"button2\">"
+"<property name=\"label\">gtk-cancel</property>"
+"<property name=\"visible\">True</property>"
+"<property name=\"can_focus\">True</property>"
+"<property name=\"receives_default\">True</property>"
+"<property name=\"use_stock\">True</property>"
+"</object>"
+"<packing>"
+"<property name=\"expand\">False</property>"
+"<property name=\"fill\">False</property>"
+"<property name=\"position\">0</property>"
+"</packing>"
+"</child>"
+"<child>"
+"<object class=\"GtkButton\" id=\"button1\">"
+"<property name=\"label\">gtk-ok</property>"
+"<property name=\"visible\">True</property>"
+"<property name=\"can_focus\">True</property>"
+"<property name=\"receives_default\">True</property>"
+"<property name=\"use_stock\">True</property>"
+"</object>"
+"<packing>"
+"<property name=\"expand\">False</property>"
+"<property name=\"fill\">False</property>"
+"<property name=\"position\">1</property>"
+"</packing>"
+"</child>"
+"</object>"
+"<packing>"
+"<property name=\"expand\">False</property>"
+"<property name=\"pack_type\">end</property>"
+"<property name=\"position\">0</property>"
+"</packing>"
+"</child>"
+"</object>"
+"</child>"
+"<action-widgets>"
+"<action-widget response=\"-6\">button2</action-widget>"
+"<action-widget response=\"-5\">button1</action-widget>"
+"</action-widgets>"
+"</object>"
+"<object class=\"GtkSizeGroup\" id=\"sizegroup1\"/>"
+"<object class=\"GtkAdjustment\" id=\"adjustment1\">"
+"<property name=\"upper\">32</property>"
+"<property name=\"step_increment\">1</property>"
+"<property name=\"page_increment\">8</property>"
+"</object>"
+"</interface>"
+;
+#endif
diff --git a/preload.c b/preload.c
index 3bd2e24..62664cf 100644
--- a/preload.c
+++ b/preload.c
@@ -4,8 +4,9 @@
#include "preload.h"
#include "wallpapers.h"
+#include "walls_conf.h"
-guint preload_max = 6;
+guint preload_max = 2;
static gboolean preload_thread_exit = FALSE;
static GHashTable *hashtable = NULL;
@@ -33,6 +34,7 @@ static void preload_hash_table_free(gpointer data) {
}
void preload_init() {
+ preload_max = conf_get_int("walls", "max_preload", 2);
preload_hashtable_mutex = g_mutex_new();
preload_thread_mutex = g_mutex_new();
diff --git a/wallpapers.c b/wallpapers.c
index dbfb8a1..bc907d5 100644
--- a/wallpapers.c
+++ b/wallpapers.c
@@ -13,6 +13,8 @@
#include "wallpapers.h"
+GdkInterpType interp_type = GDK_INTERP_NEAREST;
+
gboolean wallpapers_add_dir(const gchar *path, sqlite_uint64 parent, GtkStatusbar *statusbar, gboolean recursive ) {
static guint context_id = 0;
GDir *dir;
@@ -210,7 +212,7 @@ GdkPixbuf *resize_pixbuf(GdkPixbuf *orig, gint win_width, gint win_height, gint
}
if(width == 0 || height == 0) return NULL;
pb = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
- gdk_pixbuf_scale(orig, pb, 0, 0, width, height, 0, 0, scalex, scaley, GDK_INTERP_BILINEAR);
+ gdk_pixbuf_scale(orig, pb, 0, 0, width, height, 0, 0, scalex, scaley, interp_type);
} else {
width = img_width;
height = img_height;
@@ -235,6 +237,6 @@ GdkPixbuf *zoom_pixbuf(GdkPixbuf *orig, gdouble zoom) {
height = img_height * zoom;
pb = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
gdk_pixbuf_scale(orig, pb, 0, 0, width, height, 0, 0,
- (gdouble)width / (gdouble)img_width, (gdouble)height / (gdouble)img_height, GDK_INTERP_NEAREST);
+ (gdouble)width / (gdouble)img_width, (gdouble)height / (gdouble)img_height, interp_type);
return pb;
}
diff --git a/wallpapers.h b/wallpapers.h
index fc575b3..38384a0 100644
--- a/wallpapers.h
+++ b/wallpapers.h
@@ -11,4 +11,6 @@ void wallpapers_remove_missing(struct directory_t*, GtkStatusbar*, gboolean);
GdkPixbuf *resize_pixbuf(GdkPixbuf*, gint, gint, gint*, gint*, gdouble*);
GdkPixbuf *zoom_pixbuf(GdkPixbuf*, gdouble);
+extern GdkInterpType interp_type;
+
#endif
diff --git a/walls.ui b/walls.ui
index a355977..6f0a61a 100644
--- a/walls.ui
+++ b/walls.ui
@@ -37,6 +37,21 @@
</object>
</child>
<child>
+ <object class="GtkImageMenuItem" id="file_preferences">
+ <property name="label">gtk-preferences</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ <signal name="activate" handler="on_file_preferences_activate"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparatorMenuItem" id="separatormenuitem2">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ <child>
<object class="GtkImageMenuItem" id="file_quit">
<property name="label">gtk-quit</property>
<property name="visible">True</property>
diff --git a/window_config.c b/window_config.c
new file mode 100644
index 0000000..a8de897
--- /dev/null
+++ b/window_config.c
@@ -0,0 +1,100 @@
+#include "window_config.h"
+#include "config_ui.h"
+#include "walls_conf.h"
+#include "preload.h"
+#include "wallpapers.h"
+
+struct window_config_t *window_config_new(GtkWindow *parent) {
+ GtkBuilder *builder;
+ GtkDialog *dialog;
+ GtkComboBox *interp_combo;
+ GtkHScale *preload_scale;
+ GtkListStore *liststore;
+ GtkTreeIter iter;
+ GError *error = NULL;
+ GtkCellRenderer *cell;
+ struct window_config_t *wct;
+
+ int interp_mode = conf_get_int("walls", "interpolation_mode", GDK_INTERP_NEAREST);
+ int max_preload = conf_get_int("walls", "max_preload", 2);
+
+ builder = gtk_builder_new();
+ if(!gtk_builder_add_from_string(builder, config_ui_string, -1, &error)) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ return NULL;
+ }
+
+ interp_combo = GTK_COMBO_BOX(gtk_builder_get_object(builder, "interp_combo"));
+ liststore = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
+
+ gtk_list_store_append(liststore, &iter);
+ gtk_list_store_set(liststore, &iter, 0, "Nearest", 1, GDK_INTERP_NEAREST, -1);
+
+ gtk_list_store_append(liststore, &iter);
+ gtk_list_store_set(liststore, &iter, 0, "Tiles", 1, GDK_INTERP_TILES, -1);
+
+ gtk_list_store_append(liststore, &iter);
+ gtk_list_store_set(liststore, &iter, 0, "Bilinear", 1, GDK_INTERP_BILINEAR, -1);
+
+ gtk_list_store_append(liststore, &iter);
+ gtk_list_store_set(liststore, &iter, 0, "Hyper", 1, GDK_INTERP_HYPER, -1);
+
+ gtk_combo_box_set_model(interp_combo, GTK_TREE_MODEL(liststore));
+ g_object_unref(liststore);
+
+ cell = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(interp_combo), cell, TRUE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(interp_combo), cell, "text", 0, NULL);
+
+ switch(interp_mode) {
+ case GDK_INTERP_TILES:
+ gtk_combo_box_set_active(interp_combo, 1);
+ break;
+ case GDK_INTERP_BILINEAR:
+ gtk_combo_box_set_active(interp_combo, 2);
+ break;
+ case GDK_INTERP_HYPER:
+ gtk_combo_box_set_active(interp_combo, 3);
+ break;
+ default:
+ gtk_combo_box_set_active(interp_combo, 0);
+ }
+
+ preload_scale = GTK_HSCALE(gtk_builder_get_object(builder, "preload_scale"));
+ gtk_range_set_value(GTK_RANGE(preload_scale), max_preload);
+
+ dialog = GTK_DIALOG(gtk_builder_get_object(builder, "config_dialog"));
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
+ gtk_builder_connect_signals(builder, dialog);
+ g_object_unref(G_OBJECT(builder));
+
+ wct = g_malloc(sizeof(struct window_config_t));
+ wct->dialog = dialog;
+ wct->interp_combo = interp_combo;
+ wct->preload_scale = GTK_RANGE(preload_scale);
+
+ return wct;
+}
+
+void window_config_save(struct window_config_t *wct) {
+ GValue value = {0};
+
+ int interp_mode = GDK_INTERP_NEAREST;
+ int max_preload = 2;
+
+ GtkListStore *liststore = GTK_LIST_STORE(gtk_combo_box_get_model(wct->interp_combo));
+ GtkTreeIter iter;
+ gtk_combo_box_get_active_iter(wct->interp_combo, &iter);
+ gtk_tree_model_get_value(GTK_TREE_MODEL(liststore), &iter, 1, &value);
+ interp_mode = g_value_get_int(&value);
+ g_value_unset(&value);
+
+ max_preload = gtk_range_get_value(wct->preload_scale);
+
+ g_key_file_set_integer(keyfile, "walls", "interpolation_mode", interp_mode);
+ interp_type = interp_mode;
+
+ g_key_file_set_integer(keyfile, "walls", "max_preload", max_preload);
+ preload_max = max_preload;
+}
diff --git a/window_config.h b/window_config.h
new file mode 100644
index 0000000..639a746
--- /dev/null
+++ b/window_config.h
@@ -0,0 +1,15 @@
+#ifndef _WINDOW_CONFIG_H_
+#define _WINDOW_CONFIG_H_
+
+#include <gtk/gtk.h>
+
+struct window_config_t {
+ GtkDialog *dialog;
+ GtkComboBox *interp_combo;
+ GtkRange *preload_scale;
+};
+
+struct window_config_t *window_config_new();
+void window_config_save(struct window_config_t *wct);
+
+#endif
diff --git a/window_main.c b/window_main.c
index ca3d8dc..3262ba9 100644
--- a/window_main.c
+++ b/window_main.c
@@ -10,6 +10,7 @@
#include "walls_conf.h"
#include "window_tag.h"
#include "preload.h"
+#include "window_config.h"
enum zoom_mode_t {
ZOOM_BESTFIT,
@@ -1057,6 +1058,22 @@ void on_file_quit_activate(GtkMenuItem *menuitem, gpointer user_data) {
gtk_main_quit();
}
+void on_file_preferences_activate(GtkMenuItem *menuitem, gpointer user_data) {
+ struct window_config_t *wct;
+
+ wct = window_config_new(window);
+ if(!wct) {
+ return;
+ }
+
+ if(gtk_dialog_run(wct->dialog) == GTK_RESPONSE_OK) {
+ window_config_save(wct);
+ }
+
+ gtk_widget_destroy(GTK_WIDGET(wct->dialog));
+ g_free(wct);
+}
+
static void set_sizes() {
gint width, height, hpane_pos, vpane_pos;
@@ -1069,6 +1086,8 @@ static void set_sizes() {
gtk_paned_set_position(GTK_PANED(window_hpane), hpane_pos);
gtk_paned_set_position(GTK_PANED(window_vpane), vpane_pos);
+
+ interp_type = conf_get_int("walls", "interpolation_mode", interp_type);
}
int gui_main(int argc, char **argv) {