/*************************************************************************** * gui.c - get/set values of all gtk widgets * * Tue Sep 28 02:07:43 2004 * Copyright 2004 imcintosh * ian_mcintosh@linuxadvocate.org ****************************************************************************/ /* * 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 Library 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. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "../include/main.h" #include "../include/gui.h" #include "../include/draw.h" #include "../include/gui_callbacks.h" static GladeXML *g_pXML = NULL; static void gui_set_window_geometry(GtkWindow* pWindow, RulerOrientation eRulerOrientation); // // init // static void gui_configure_new_ruler(GtkWindow* pWindow, RulerOrientation eRulerOrientation) { // add signal handlers to ruler gtk_widget_add_events(GTK_WIDGET(pWindow), GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_POINTER_MOTION_MASK ); g_signal_connect(G_OBJECT(pWindow), "button_press_event", G_CALLBACK (on_button_press_event), NULL); g_signal_connect(G_OBJECT(pWindow), "key_press_event", G_CALLBACK (on_key_press_event), NULL); g_signal_connect(G_OBJECT(pWindow), "delete_event", G_CALLBACK (on_application_delete_event), NULL); g_signal_connect(G_OBJECT(pWindow), "motion_notify_event", G_CALLBACK (on_application_motion_notify_event), NULL); // create drawing area and add to window GtkWidget* pDrawingArea = gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER(pWindow), pDrawingArea); // add signal handlers to drawing area gtk_widget_add_events(GTK_WIDGET(pDrawingArea), GDK_EXPOSURE_MASK); g_signal_connect(G_OBJECT(pDrawingArea), "expose_event", G_CALLBACK(on_expose_event), NULL); g_signal_connect(G_OBJECT(pDrawingArea),"configure_event", G_CALLBACK(on_configure_event), NULL); gui_set_window_geometry(pWindow, eRulerOrientation); gui_set_ruler_length(pWindow, 500); gtk_window_set_resizable(pWindow, TRUE); // mark as visible gtk_widget_show(pDrawingArea); } gboolean gui_init() { glade_gnome_init (); // Load and connect glade file g_pXML = glade_xml_new (PACKAGE_DATA_DIR"/gruler/glade/gruler.glade", NULL, NULL); if(g_pXML == NULL) { // try source directory if user hasn't done a 'make install' (good for development, too!) g_pXML = glade_xml_new (PACKAGE_SOURCE_DIR"/gruler.glade", NULL, NULL); } glade_xml_signal_autoconnect (g_pXML); // load and configure ruler GtkWidget *pRulerWindow = glade_xml_get_widget (g_pXML, "rulerwindow"); g_return_val_if_fail(pRulerWindow!= NULL, FALSE); gui_configure_new_ruler(GTK_WINDOW(pRulerWindow), RulerOrientationHorizontal); // Don't kill dialog(s) when closing; instead, hide them. GtkWidget *pPreferencesWindow = glade_xml_get_widget(g_pXML, "preferenceswindow"); g_return_val_if_fail(pPreferencesWindow != NULL, 1); g_signal_connect(G_OBJECT(pPreferencesWindow), "delete_event", G_CALLBACK(gtk_widget_hide), NULL); return TRUE; } // // show windows // void gui_show() { // Show ruler and start gtk loop GtkWidget *pRulerWindow = glade_xml_get_widget (g_pXML, "rulerwindow"); g_return_if_fail(pRulerWindow != NULL); gtk_widget_show(pRulerWindow); g_timeout_add(MOUSE_UPDATE_INTERVAL_MS, (GSourceFunc)on_watch_mouse_update, (gpointer)pRulerWindow); } void gui_show_preferences_window() { GtkWidget *pPreferencesWindow = glade_xml_get_widget (g_pXML, "preferenceswindow"); g_return_if_fail(pPreferencesWindow != NULL); gtk_widget_show(pPreferencesWindow); gtk_window_present(GTK_WINDOW(pPreferencesWindow)); } void gui_show_help_window() { GtkWidget *pHelpWindow = glade_xml_get_widget (g_pXML, "helpwindow"); g_return_if_fail(pHelpWindow != NULL); gtk_widget_show(pHelpWindow); } GtkWidget* gui_get_popup_widget() { GtkWidget* pPopupMenu = glade_xml_get_widget (g_pXML, "popupmenu"); g_return_val_if_fail(pPopupMenu != NULL, NULL); return pPopupMenu; } // // draw // void gui_redraw_rulers() { // force a redraw of ruler window(s?) GtkWidget *pRulerWindow = glade_xml_get_widget (g_pXML, "rulerwindow"); g_return_if_fail(pRulerWindow != NULL); // Call functions on children of top level windows (there's only 1: the drawing area) // TODO: these callbacks don't take a userdata param.. is that a problem? gtk_container_foreach(GTK_CONTAINER(pRulerWindow), (GtkCallback)draw_ruler_window, NULL); gtk_container_foreach(GTK_CONTAINER(pRulerWindow), (GtkCallback)gtk_widget_queue_draw, NULL); } // // Get/Set settings // // set ruler length and geometry rules static void gui_set_window_geometry(GtkWindow* pWindow, RulerOrientation eRulerOrientation) { // save new orientation g_object_set_data(G_OBJECT(pWindow), KEY_RULER_ORIENTATION, (gpointer)eRulerOrientation); GdkGeometry geometry = {0}; geometry.min_width = (eRulerOrientation == RulerOrientationHorizontal) ? MIN_RULER_LENGTH : MIN_RULER_WIDTH; geometry.min_height = (eRulerOrientation == RulerOrientationVertical) ? MIN_RULER_LENGTH : MIN_RULER_WIDTH; geometry.max_width = (eRulerOrientation == RulerOrientationHorizontal) ? MAX_RULER_LENGTH : MAX_RULER_WIDTH; geometry.max_height = (eRulerOrientation == RulerOrientationVertical) ? MAX_RULER_LENGTH : MAX_RULER_WIDTH; GdkWindowHints geom_mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE; gtk_window_set_geometry_hints(pWindow, GTK_WIDGET(pWindow), &geometry, geom_mask); } const gchar* gui_get_font_string() { GtkFontButton *pFontButton = GTK_FONT_BUTTON(glade_xml_get_widget(g_pXML, "fontbutton")); g_return_val_if_fail(pFontButton != NULL, ""); return gtk_font_button_get_font_name(pFontButton); } // Foreground color void gui_get_foreground_color(GdkColor *pColor) { GtkColorButton *pForegroundColorButton = GTK_COLOR_BUTTON(glade_xml_get_widget(g_pXML, "foregroundcolorbutton")); g_return_if_fail(pForegroundColorButton != NULL); gtk_color_button_get_color(pForegroundColorButton, pColor); } void gui_set_foreground_color(const GdkColor *pColor) { GtkColorButton *pForegroundColorButton = GTK_COLOR_BUTTON(glade_xml_get_widget(g_pXML, "foregroundcolorbutton")); g_return_if_fail(pForegroundColorButton != NULL); gtk_color_button_set_color(pForegroundColorButton, pColor); } // Background color void gui_get_background_color(GdkColor *pColor) { GtkColorButton *pBackgroundColorButton = GTK_COLOR_BUTTON(glade_xml_get_widget(g_pXML, "backgroundcolorbutton")); g_return_if_fail(pBackgroundColorButton != NULL); gtk_color_button_get_color(pBackgroundColorButton, pColor); } void gui_set_background_color(const GdkColor *pColor) { GtkColorButton *pBackgroundColorButton = GTK_COLOR_BUTTON(glade_xml_get_widget(g_pXML, "backgroundcolorbutton")); g_return_if_fail(pBackgroundColorButton != NULL); gtk_color_button_set_color(pBackgroundColorButton, pColor); } // Font string void gui_set_font_string(const gchar* str) { GtkFontButton *pFontButton = GTK_FONT_BUTTON(glade_xml_get_widget(g_pXML, "fontbutton")); g_return_if_fail(pFontButton != NULL); gtk_font_button_set_font_name(pFontButton, str); } // Ruler Length (either the width or height of the ruler window, depending on orientation) gint gui_get_ruler_length(GtkWindow *pRulerWindow) { if(pRulerWindow == NULL) { pRulerWindow = (GtkWindow*)glade_xml_get_widget (g_pXML, "rulerwindow"); g_return_val_if_fail(pRulerWindow != NULL, DEFAULT_RULER_LENGTH); } gint nWindowWidth, nWindowHeight; gtk_window_get_size(GTK_WINDOW(pRulerWindow), &nWindowWidth, &nWindowHeight); RulerOrientation eRulerOrientation = (RulerOrientation)g_object_get_data(G_OBJECT(pRulerWindow), KEY_RULER_ORIENTATION); // return width or height, depending on orientation if(eRulerOrientation == RulerOrientationHorizontal) { return nWindowWidth; } else { return nWindowHeight; } } void gui_set_ruler_length(GtkWindow *pRulerWindow, gint nLength) { // request a redraw of ruler window(s) if(pRulerWindow == NULL) { pRulerWindow = (GtkWindow*)glade_xml_get_widget (g_pXML, "rulerwindow"); g_return_if_fail(pRulerWindow != NULL); } gint nWindowWidth, nWindowHeight; gtk_window_get_size(pRulerWindow, &nWindowWidth, &nWindowHeight); RulerOrientation eRulerOrientation = (RulerOrientation)g_object_get_data(G_OBJECT(pRulerWindow), KEY_RULER_ORIENTATION); if(eRulerOrientation == RulerOrientationHorizontal) { gtk_window_resize(pRulerWindow, nLength, nWindowHeight); } else { gtk_window_resize(pRulerWindow, nWindowWidth, nLength); } } // Draw Measurement Lines Setting gboolean gui_get_draw_mouse_measurement_lines() { GtkWidget *pCheckButton = glade_xml_get_widget(g_pXML, "drawmousemeasurementlines"); g_return_val_if_fail(pCheckButton != NULL, FALSE); return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pCheckButton)); } void gui_set_draw_mouse_measurement_lines(gboolean bDraw) { GtkWidget *pCheckButton = glade_xml_get_widget(g_pXML, "drawmousemeasurementlines"); g_return_if_fail(pCheckButton != NULL); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pCheckButton), bDraw); } // ruler metric ERulerMetric gui_get_ruler_metric() { GtkWidget *pComboBox = glade_xml_get_widget(g_pXML, "metriccombobox"); g_return_val_if_fail(pComboBox != NULL, FALSE); return (ERulerMetric)gtk_combo_box_get_active(GTK_COMBO_BOX(pComboBox)); } void gui_set_ruler_metric(ERulerMetric eMetric) { GtkWidget *pComboBox = glade_xml_get_widget(g_pXML, "metriccombobox"); g_return_if_fail(pComboBox != NULL); gtk_combo_box_set_active(GTK_COMBO_BOX(pComboBox), eMetric); } // Keep-Above setting void gui_toggle_keep_above() { // Since we get the value from the menu checkbox and the checkbox is auto-checked by GTK, // this function can only be called from a menu item callback // Note: GTK does the actual UI checkbox toggle for us gui_set_keep_above(gui_get_keep_above()); } gboolean gui_get_keep_above() { GtkCheckMenuItem *pKeepAboveMenuItem = GTK_CHECK_MENU_ITEM(glade_xml_get_widget(g_pXML, "keep_above_menuitem")); // Get new status of checkbox return gtk_check_menu_item_get_active(pKeepAboveMenuItem); } void gui_set_keep_above(gboolean bAbove) { GtkCheckMenuItem *pKeepAboveMenuItem = GTK_CHECK_MENU_ITEM(glade_xml_get_widget(g_pXML, "keep_above_menuitem")); // set menu checkbox gtk_check_menu_item_set_active(pKeepAboveMenuItem, bAbove); // ruler window GtkWidget *pRulerWindow = glade_xml_get_widget(g_pXML, "rulerwindow"); g_return_if_fail(pRulerWindow != NULL); gtk_window_set_keep_above(GTK_WINDOW(pRulerWindow), bAbove); // preferences window GtkWidget *pPreferencesWindow = glade_xml_get_widget(g_pXML, "preferenceswindow"); g_return_if_fail(pPreferencesWindow != NULL); gtk_window_set_keep_above(GTK_WINDOW(pPreferencesWindow), bAbove); } // Rotation setting void gui_toggle_rotation() { GtkWidget *pRulerWindow = glade_xml_get_widget(g_pXML, "rulerwindow"); g_return_if_fail(pRulerWindow != NULL); // swap width/height gint nWindowWidth, nWindowHeight; gtk_window_get_size(GTK_WINDOW(pRulerWindow), &nWindowWidth, &nWindowHeight); // get current orientation RulerOrientation eRulerOrientation = (RulerOrientation)g_object_get_data(G_OBJECT(pRulerWindow), KEY_RULER_ORIENTATION); g_return_if_fail(eRulerOrientation != 0); eRulerOrientation = TOGGLE_RULER_ORIENTATION(eRulerOrientation); // set rules for new orientation gui_set_window_geometry(GTK_WINDOW(pRulerWindow), eRulerOrientation); // set new window size // NOTE: x,y reversed (y,x) gtk_window_resize(GTK_WINDOW(pRulerWindow), nWindowHeight, nWindowWidth); } // DPI setting gint gui_get_dots_per_inch() { static gint nDotsPerInch = 0; if(nDotsPerInch == 0) { GConfClient* pGConfClient = gconf_client_get_default(); //gconf_client_new(); g_return_val_if_fail(pGConfClient != NULL, DEFAULT_DPI); nDotsPerInch = (gint)gconf_client_get_float(pGConfClient, "/desktop/gnome/font_rendering/dpi", NULL); if(nDotsPerInch == 0) { nDotsPerInch = DEFAULT_DPI; } g_object_unref(pGConfClient); } return nDotsPerInch; } // Get/Set window position void gui_ruler_get_position(gint* pX, gint* pY) { GtkWidget *pRulerWindow = glade_xml_get_widget(g_pXML, "rulerwindow"); g_return_if_fail(pRulerWindow != NULL); gtk_window_get_position(GTK_WINDOW(pRulerWindow), pX, pY); } void gui_ruler_set_position(gint nX, gint nY) { GtkWidget *pRulerWindow = glade_xml_get_widget(g_pXML, "rulerwindow"); g_return_if_fail(pRulerWindow != NULL); gtk_window_move(GTK_WINDOW(pRulerWindow), nX, nY); } // Get/Set orientation RulerOrientation gui_get_ruler_orientation() { GtkWidget *pRulerWindow = glade_xml_get_widget(g_pXML, "rulerwindow"); g_return_val_if_fail(pRulerWindow != NULL, RulerOrientationVertical); return (RulerOrientation)g_object_get_data(G_OBJECT(pRulerWindow), KEY_RULER_ORIENTATION); } void gui_set_ruler_orientation(RulerOrientation eOrientation) { GtkWidget *pRulerWindow = glade_xml_get_widget(g_pXML, "rulerwindow"); g_return_if_fail(pRulerWindow != NULL); if(gui_get_ruler_orientation(pRulerWindow) != eOrientation) { gui_toggle_rotation(); } }