/* prefs.c Copyright (C) 2005-2007 Mark Tyler and Dmitry Groshev This file is part of mtPaint. mtPaint 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. mtPaint 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 mtPaint in the file COPYING. */ #include #include #include #include "global.h" #include "mygtk.h" #include "memory.h" #include "png.h" #include "canvas.h" #include "inifile.h" #include "viewer.h" #include "mainwindow.h" #include "prefs.h" /// PREFERENCES WINDOW GtkWidget *prefs_window, *prefs_status[STATUS_ITEMS]; static GtkWidget *spinbutton_maxmem, *spinbutton_greys, *spinbutton_nudge, *spinbutton_pan; static GtkWidget *spinbutton_trans, *spinbutton_hotx, *spinbutton_hoty, *spinbutton_jpeg, *spinbutton_recent, *spinbutton_silence; static GtkWidget *checkbutton_paste, *checkbutton_cursor, *checkbutton_exit, *checkbutton_quit; static GtkWidget *checkbutton_zoom[4], // zoom 100%, wheel, optimize cheq, disable trans *checkbutton_commit, *checkbutton_center, *checkbutton_gamma; GtkWidget *clipboard_entry, *entry_handbook[2]; static GtkWidget *spinbutton_grid[4]; static GtkWidget *check_tablet[3], *hscale_tablet[3], *label_tablet_device, *label_tablet_pressure; static char *tablet_ini[] = { "tablet_value_size", "tablet_value_flow", "tablet_value_opacity" }, *tablet_ini2[] = { "tablet_use_size", "tablet_use_flow", "tablet_use_opacity" }, *tablet_ini3[] = { "tablet_name", "tablet_mode", "tablet_axes_v" }; #if GTK_MAJOR_VERSION == 1 static GdkDeviceInfo *tablet_device = NULL; #endif #if GTK_MAJOR_VERSION == 2 static GdkDevice *tablet_device = NULL; #endif gboolean tablet_working = FALSE; // Has the device been initialized? gboolean tablet_tool_use[3]; // Size, flow, opacity float tablet_tool_factor[3]; // Size, flow, opacity #ifdef U_NLS #define PREF_LANGS 12 char *pref_lang_ini_code[PREF_LANGS] = { "system", "zh_TW.utf8", "cs_CZ", "en_GB", "fr_FR", "de_DE", "pl_PL", "pt_PT", "pt_BR", "sk_SK", "es_ES", "tr_TR" }; int pref_lang; #endif static gint expose_tablet_preview( GtkWidget *widget, GdkEventExpose *event ) { unsigned char *rgb; int i, x = event->area.x, y = event->area.y, w = event->area.width, h = event->area.height; rgb = malloc( w*h*3 ); if ( rgb == NULL ) return FALSE; for ( i=0; i<(w*h*3); i++ ) rgb[i] = 255; // Pure white gdk_draw_rgb_image (widget->window, widget->style->black_gc, x, y, w, h, GDK_RGB_DITHER_NONE, rgb, w*3 ); free( rgb ); return FALSE; } void click_file_browse( GtkWidget *widget, gpointer data ) { file_selector( (int) data ); } static GtkWidget *inputd = NULL; gint delete_inputd( GtkWidget *widget, GdkEvent *event, gpointer data ) { int i, j; char txt[32]; #if GTK_MAJOR_VERSION == 1 GdkDeviceInfo *dev = tablet_device; #endif #if GTK_MAJOR_VERSION == 2 GdkDevice *dev = GTK_INPUT_DIALOG (inputd)->current_device; #endif if ( tablet_working ) // Store tablet settings in INI file for future session { inifile_set( tablet_ini3[0], dev->name ); inifile_set_gint32( tablet_ini3[1], dev->mode ); for ( i=0; inum_axes; i++ ) { #if GTK_MAJOR_VERSION == 1 j = dev->axes[i]; #endif #if GTK_MAJOR_VERSION == 2 j = dev->axes[i].use; #endif sprintf(txt, "%s%i", tablet_ini3[2], i); inifile_set_gint32( txt, j ); } } inifile_set_gboolean( "tablet_USE", tablet_working ); gtk_widget_destroy(inputd); inputd = NULL; return FALSE; } static void delete_prefs(GtkWidget *widget) { if ( inputd != NULL ) delete_inputd( NULL, NULL, NULL ); gtk_widget_destroy(prefs_window); men_item_state( menu_prefs, TRUE ); clipboard_entry = NULL; } static void tablet_update_pressure( double pressure ) { char txt[64]; sprintf(txt, "%s = %.2f", _("Pressure"), pressure); gtk_label_set_text( GTK_LABEL(label_tablet_pressure), txt ); } static void tablet_update_device( char *device ) { char txt[64]; sprintf(txt, "%s = %s", _("Current Device"), device); gtk_label_set_text( GTK_LABEL(label_tablet_device), txt ); } #if GTK_MAJOR_VERSION == 1 static void tablet_gtk1_newdevice(devid) // Get new device info { GList *dlist = gdk_input_list_devices(); GdkDeviceInfo *device = NULL; tablet_device = NULL; while ( dlist != NULL ) { device = dlist->data; if ( device->deviceid == devid ) // Device found { tablet_device = device; break; } dlist = dlist->next; } } static void tablet_enable_device(GtkInputDialog *inputdialog, guint32 devid) { tablet_gtk1_newdevice(devid); if ( tablet_device != NULL ) { tablet_working = TRUE; tablet_update_device( tablet_device->name ); } else tablet_working = FALSE; } static void tablet_disable_device(GtkInputDialog *inputdialog, guint32 devid) { tablet_working = FALSE; tablet_update_device( "NONE" ); } #endif #if GTK_MAJOR_VERSION == 2 static void tablet_enable_device(GtkInputDialog *inputdialog, GdkDevice *deviceid, gpointer user_data) { tablet_working = TRUE; tablet_update_device( deviceid->name ); tablet_device = deviceid; } static void tablet_disable_device(GtkInputDialog *inputdialog, GdkDevice *deviceid, gpointer user_data) { tablet_working = FALSE; tablet_update_device( "NONE" ); } #endif gint conf_tablet( GtkWidget *widget, GdkEvent *event, gpointer data ) { GtkAccelGroup* ag = gtk_accel_group_new(); if (inputd != NULL) return FALSE; // Stops multiple dialogs being opened inputd = gtk_input_dialog_new(); gtk_window_set_position( GTK_WINDOW(inputd), GTK_WIN_POS_CENTER ); gtk_signal_connect(GTK_OBJECT (GTK_INPUT_DIALOG (inputd)->close_button), "clicked", GTK_SIGNAL_FUNC(delete_inputd), (gpointer) inputd); gtk_widget_add_accelerator (GTK_INPUT_DIALOG (inputd)->close_button, "clicked", ag, GDK_Escape, 0, (GtkAccelFlags) 0); gtk_signal_connect(GTK_OBJECT (inputd), "destroy", GTK_SIGNAL_FUNC(delete_inputd), (gpointer) inputd); gtk_signal_connect(GTK_OBJECT (inputd), "enable-device", GTK_SIGNAL_FUNC(tablet_enable_device), (gpointer) inputd); gtk_signal_connect(GTK_OBJECT (inputd), "disable-device", GTK_SIGNAL_FUNC(tablet_disable_device), (gpointer) inputd); if ( GTK_INPUT_DIALOG (inputd)->keys_list != NULL ) gtk_widget_hide (GTK_INPUT_DIALOG (inputd)->keys_list); if ( GTK_INPUT_DIALOG (inputd)->keys_listbox != NULL ) gtk_widget_hide (GTK_INPUT_DIALOG (inputd)->keys_listbox); gtk_widget_hide (GTK_INPUT_DIALOG (inputd)->save_button); gtk_widget_show (inputd); gtk_window_add_accel_group(GTK_WINDOW (inputd), ag); return FALSE; } static void prefs_apply(GtkWidget *widget) { int i, j; char txt[64]; for ( i=0; ibutton == 1) { #if GTK_MAJOR_VERSION == 1 pressure = event->pressure; #endif #if GTK_MAJOR_VERSION == 2 gdk_event_get_axis ((GdkEvent *)event, GDK_AXIS_PRESSURE, &pressure); #endif tablet_update_pressure( pressure ); } return TRUE; } static gint tablet_preview_motion(GtkWidget *widget, GdkEventMotion *event) { gdouble pressure = 0.0; GdkModifierType state; #if GTK_MAJOR_VERSION == 1 if (event->is_hint) { gdk_input_window_get_pointer (event->window, event->deviceid, NULL, NULL, &pressure, NULL, NULL, &state); } else { pressure = event->pressure; state = event->state; } #endif #if GTK_MAJOR_VERSION == 2 if (event->is_hint) gdk_device_get_state (event->device, event->window, NULL, &state); else state = event->state; gdk_event_get_axis ((GdkEvent *)event, GDK_AXIS_PRESSURE, &pressure); #endif if (state & GDK_BUTTON1_MASK) tablet_update_pressure( pressure ); return TRUE; } static GtkWidget *path_box(char *name, GtkWidget *box, int fsmode) { GtkWidget *hbox, *label, *entry, *button; label = gtk_label_new(name); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 2); hbox = gtk_hbox_new(FALSE, 0); gtk_widget_show(hbox); gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 2); entry = gtk_entry_new(); gtk_widget_show(entry); gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 5); button = add_a_button(_("Browse"), 2, hbox, FALSE); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(click_file_browse), (gpointer)fsmode); return (entry); } void pressed_preferences( GtkMenuItem *menu_item, gpointer user_data ) { int i; #ifdef U_NLS char *pref_langs[PREF_LANGS] = { _("Default System Language"), _("Chinese (Taiwanese)"), _("Czech"), _("English (UK)"), _("French"), _("German"), _("Polish"), _("Portuguese"), _("Portuguese (Brazilian)"), _("Slovak"), _("Spanish"), _("Turkish") }; #endif GtkWidget *vbox3, *hbox4, *table3, *table4, *table5, *drawingarea_tablet; GtkWidget *button1, *notebook1, *vbox_1, *vbox_2, *vbox_3, *label; char *tab_tex[] = { _("Max memory used for undo (MB)"), _("Greyscale backdrop"), _("Selection nudge pixels"), _("Max Pan Window Size") }; char *tab_tex2[] = { _("Transparency index"), _("XBM X hotspot"), _("XBM Y hotspot"), _("JPEG Save Quality (100=High) "), _("Recently Used Files"), _("Progress bar silence limit") }; char *tab_tex3[] = { _("Minimum grid zoom"), _("Grid colour RGB") }; char *stat_tex[] = { _("Canvas Geometry"), _("Cursor X,Y"), _("Pixel [I] {RGB}"), _("Selection Geometry"), _("Undo / Redo") }, *tablet_txt[] = { _("Size"), _("Flow"), _("Opacity") }; char txt[64]; men_item_state( menu_prefs, FALSE ); // Make sure the user can only open 1 prefs window prefs_window = add_a_window( GTK_WINDOW_TOPLEVEL, _("Preferences"), GTK_WIN_POS_CENTER, FALSE ); vbox3 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox3); gtk_container_add (GTK_CONTAINER (prefs_window), vbox3); /// SETUP NOTEBOOK notebook1 = gtk_notebook_new (); gtk_box_pack_start (GTK_BOX (vbox3), notebook1, TRUE, TRUE, 0); gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook1), GTK_POS_TOP); gtk_widget_show (notebook1); /// ---- TAB1 - GENERAL vbox_1 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox_1); gtk_container_add (GTK_CONTAINER (notebook1), vbox_1); label = gtk_label_new( _("General") ); gtk_widget_show (label); gtk_notebook_set_tab_label(GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 0), label); table3 = add_a_table( 3, 2, 10, vbox_1 ); /// TABLE TEXT for ( i=0; i<4; i++ ) add_to_table( tab_tex[i], table3, i, 0, 5 ); /// TABLE SPINBUTTONS spinbutton_maxmem = spin_to_table(table3, 0, 1, 5, inifile_get_gint32("undoMBlimit", 32 ), 1, 1000); spinbutton_greys = spin_to_table(table3, 1, 1, 5, inifile_get_gint32("backgroundGrey", 180 ), 0, 255); spinbutton_nudge = spin_to_table(table3, 2, 1, 5, inifile_get_gint32("pixelNudge", 8 ), 2, 512); spinbutton_pan = spin_to_table(table3, 3, 1, 5, inifile_get_gint32("panSize", 128 ), 64, 256); checkbutton_paste = add_a_toggle( _("Display clipboard while pasting"), vbox_1, inifile_get_gboolean("pasteToggle", TRUE) ); checkbutton_cursor = add_a_toggle( _("Mouse cursor = Tool"), vbox_1, inifile_get_gboolean("cursorToggle", TRUE) ); checkbutton_exit = add_a_toggle( _("Confirm Exit"), vbox_1, inifile_get_gboolean("exitToggle", FALSE) ); checkbutton_quit = add_a_toggle( _("Q key quits mtPaint"), vbox_1, inifile_get_gboolean("quitToggle", TRUE) ); checkbutton_commit = add_a_toggle( _("Changing tool commits paste"), vbox_1, inifile_get_gboolean("pasteCommit", FALSE) ); checkbutton_center = add_a_toggle(_("Centre tool settings dialogs"), vbox_1, inifile_get_gboolean("centerSettings", TRUE)); checkbutton_gamma = add_a_toggle(_("Use gamma correction by default"), vbox_1, inifile_get_gboolean("defaultGamma", FALSE)); /// ---- TAB2 - FILES vbox_2 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox_2); gtk_container_add (GTK_CONTAINER (notebook1), vbox_2); label = gtk_label_new( _("Files") ); gtk_widget_show (label); gtk_notebook_set_tab_label(GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 1), label); table4 = add_a_table( 5, 2, 10, vbox_2 ); for ( i=0; i<6; i++ ) add_to_table( tab_tex2[i], table4, i, 0, 0 ); spinbutton_trans = spin_to_table(table4, 0, 1, 4, mem_xpm_trans, -1, mem_cols - 1); spinbutton_hotx = spin_to_table(table4, 1, 1, 4, mem_xbm_hot_x, -1, mem_width - 1); spinbutton_hoty = spin_to_table(table4, 2, 1, 4, mem_xbm_hot_y, -1, mem_height - 1); spinbutton_jpeg = spin_to_table(table4, 3, 1, 4, mem_jpeg_quality, 0, 100); spinbutton_recent = spin_to_table(table4, 4, 1, 4, recent_files, 0, MAX_RECENT); spinbutton_silence = spin_to_table(table4, 5, 1, 4, silence_limit, 0, 28); // add_hseparator( vbox_2, -2, 10 ); clipboard_entry = path_box(_("Clipboard Files"), vbox_2, FS_CLIP_FILE); gtk_entry_set_text(GTK_ENTRY(clipboard_entry), mem_clip_file); // add_hseparator( vbox_2, -2, 10 ); entry_handbook[0] = path_box(_("HTML Browser Program"), vbox_2, FS_BROWSER_PROG); gtk_entry_set_text(GTK_ENTRY(entry_handbook[0]), inifile_get(HANDBOOK_BROWSER_INI, "")); entry_handbook[1] = path_box(_("Location of Handbook index"), vbox_2, FS_HANDBOOK_INDEX); gtk_entry_set_text(GTK_ENTRY(entry_handbook[1]), inifile_get(HANDBOOK_LOCATION_INI, "")); /// ---- TAB3 - STATUS BAR vbox_3 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox_3); gtk_container_add (GTK_CONTAINER (notebook1), vbox_3); label = gtk_label_new( _("Status Bar") ); gtk_widget_show (label); gtk_notebook_set_tab_label(GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 2), label); for ( i=0; iname ); } else tablet_update_device( "NONE" ); } void init_tablet() // Set up variables { int i; char *devname, txt[32]; gboolean use_tablet; GList *dlist; #if GTK_MAJOR_VERSION == 1 GdkDeviceInfo *device = NULL; gint use; #endif #if GTK_MAJOR_VERSION == 2 GdkDevice *device = NULL; GdkAxisUse use; #endif use_tablet = inifile_get_gboolean( "tablet_USE", FALSE ); if ( use_tablet ) // User has got tablet working in past so try to initialize it { devname = inifile_get( tablet_ini3[0], "?" ); // Device name last used #if GTK_MAJOR_VERSION == 1 dlist = gdk_input_list_devices(); #endif #if GTK_MAJOR_VERSION == 2 dlist = gdk_devices_list(); #endif while ( dlist != NULL ) { device = dlist->data; if ( strcmp(device->name, devname ) == 0 ) { // Previously used device was found #if GTK_MAJOR_VERSION == 1 gdk_input_set_mode(device->deviceid, inifile_get_gint32( tablet_ini3[1], 0 ) ); #endif #if GTK_MAJOR_VERSION == 2 gdk_device_set_mode(device, inifile_get_gint32( tablet_ini3[1], 0 ) ); #endif for ( i=0; inum_axes; i++ ) { sprintf(txt, "%s%i", tablet_ini3[2], i); use = inifile_get_gint32( txt, GDK_AXIS_IGNORE ); #if GTK_MAJOR_VERSION == 1 device->axes[i] = use; gdk_input_set_axes(device->deviceid, device->axes); #endif #if GTK_MAJOR_VERSION == 2 gdk_device_set_axis_use(device, i, use); #endif } tablet_device = device; tablet_working = TRUE; // Success! break; } dlist = dlist->next; // Not right device so look for next one } } for ( i=0; i<3; i++ ) { tablet_tool_use[i] = inifile_get_gboolean( tablet_ini2[i], FALSE ); tablet_tool_factor[i] = ((float) inifile_get_gint32( tablet_ini[i], 100 )) / 100; } }