From 477b865da18f6004a5180d924997d9283c20250f Mon Sep 17 00:00:00 2001 From: Alex Merry Date: Mon, 17 Dec 2012 15:50:11 +0000 Subject: Remember the geometry of the utility windows Code largely stolen from the GIMP. --- tikzit/src/gtk/Application.m | 1 + tikzit/src/gtk/PropertiesWindow.m | 19 +++++++++ tikzit/src/gtk/ToolBox.h | 1 + tikzit/src/gtk/ToolBox.m | 25 ++++++++++- tikzit/src/gtk/gtkhelpers.h | 2 + tikzit/src/gtk/gtkhelpers.m | 88 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 135 insertions(+), 1 deletion(-) diff --git a/tikzit/src/gtk/Application.m b/tikzit/src/gtk/Application.m index 7055252..88293a6 100644 --- a/tikzit/src/gtk/Application.m +++ b/tikzit/src/gtk/Application.m @@ -123,6 +123,7 @@ Application* app = nil; selector:@selector(selectedToolChanged:) name:@"ToolSelectionChanged" object:toolBox]; + [toolBox show]; propertiesWindow = [[PropertiesWindow alloc] init]; [propertiesWindow loadConfiguration:configFile]; diff --git a/tikzit/src/gtk/PropertiesWindow.m b/tikzit/src/gtk/PropertiesWindow.m index acf18b2..98e4f4b 100644 --- a/tikzit/src/gtk/PropertiesWindow.m +++ b/tikzit/src/gtk/PropertiesWindow.m @@ -215,6 +215,9 @@ static void edge_node_toggled_cb (GtkToggleButton *widget, PropertiesWindow *pan G_CALLBACK (edge_node_label_changed_cb), self); + // hack to position the props window somewhere sensible + // (upper right) + gtk_window_parse_geometry (GTK_WINDOW (window), "-0+0"); } return self; @@ -289,12 +292,28 @@ static void edge_node_toggled_cb (GtkToggleButton *widget, PropertiesWindow *pan } - (void) loadConfiguration:(Configuration*)config { + if ([config hasGroup:@"PropertiesWindow"]) { + tz_restore_window (GTK_WINDOW (window), + [config integerEntry:@"x" inGroup:@"PropertiesWindow"], + [config integerEntry:@"y" inGroup:@"PropertiesWindow"], + [config integerEntry:@"w" inGroup:@"PropertiesWindow"], + [config integerEntry:@"h" inGroup:@"PropertiesWindow"]); + } [self setVisible:[config booleanEntry:@"visible" inGroup:@"PropertiesWindow" withDefault:YES]]; } - (void) saveConfiguration:(Configuration*)config { + gint x, y, w, h; + + gtk_window_get_position (GTK_WINDOW (window), &x, &y); + gtk_window_get_size (GTK_WINDOW (window), &w, &h); + + [config setIntegerEntry:@"x" inGroup:@"PropertiesWindow" value:x]; + [config setIntegerEntry:@"y" inGroup:@"PropertiesWindow" value:y]; + [config setIntegerEntry:@"w" inGroup:@"PropertiesWindow" value:w]; + [config setIntegerEntry:@"h" inGroup:@"PropertiesWindow" value:h]; [config setBooleanEntry:@"visible" inGroup:@"PropertiesWindow" value:[self visible]]; diff --git a/tikzit/src/gtk/ToolBox.h b/tikzit/src/gtk/ToolBox.h index bf0dc35..87ee225 100644 --- a/tikzit/src/gtk/ToolBox.h +++ b/tikzit/src/gtk/ToolBox.h @@ -33,6 +33,7 @@ - (id) initWithTools:(NSArray*)tools; +- (void) show; - (void) present; - (void) loadConfiguration:(Configuration*)config; diff --git a/tikzit/src/gtk/ToolBox.m b/tikzit/src/gtk/ToolBox.m index b1a70c3..cf512e0 100644 --- a/tikzit/src/gtk/ToolBox.m +++ b/tikzit/src/gtk/ToolBox.m @@ -21,6 +21,7 @@ #import "Configuration.h" #import "Tool.h" +#import "gtkhelpers.h" #import "tztoolpalette.h" static void tool_button_toggled_cb (GtkWidget *widget, ToolBox *toolBox); @@ -130,7 +131,9 @@ static void unretain (gpointer data); gtk_alignment_set_padding (GTK_ALIGNMENT (configWidgetContainer), 5, 5, 5, 5); - gtk_widget_show (window); + // hack to position the toolbox window somewhere sensible + // (upper left) + gtk_window_parse_geometry (GTK_WINDOW (window), "+0+0"); } return self; @@ -194,14 +197,34 @@ static void unretain (gpointer data); [self _setToolWidget:[tool configurationWidget]]; } +- (void) show { + gtk_widget_show (window); +} + - (void) present { gtk_window_present (GTK_WINDOW (window)); } - (void) loadConfiguration:(Configuration*)config { + if ([config hasGroup:@"ToolBox"]) { + tz_restore_window (GTK_WINDOW (window), + [config integerEntry:@"x" inGroup:@"ToolBox"], + [config integerEntry:@"y" inGroup:@"ToolBox"], + [config integerEntry:@"w" inGroup:@"ToolBox"], + [config integerEntry:@"h" inGroup:@"ToolBox"]); + } } - (void) saveConfiguration:(Configuration*)config { + gint x, y, w, h; + + gtk_window_get_position (GTK_WINDOW (window), &x, &y); + gtk_window_get_size (GTK_WINDOW (window), &w, &h); + + [config setIntegerEntry:@"x" inGroup:@"ToolBox" value:x]; + [config setIntegerEntry:@"y" inGroup:@"ToolBox" value:y]; + [config setIntegerEntry:@"w" inGroup:@"ToolBox" value:w]; + [config setIntegerEntry:@"h" inGroup:@"ToolBox" value:h]; } @end diff --git a/tikzit/src/gtk/gtkhelpers.h b/tikzit/src/gtk/gtkhelpers.h index bcdac89..81a4d93 100644 --- a/tikzit/src/gtk/gtkhelpers.h +++ b/tikzit/src/gtk/gtkhelpers.h @@ -38,4 +38,6 @@ gint tz_hijack_key_press (GtkWindow *win, // Equivalent of GTK+3's gdk_pixbuf_get_from_surface() GdkPixbuf * pixbuf_get_from_surface(cairo_surface_t *surface); +void tz_restore_window (GtkWindow *window, gint x, gint y, gint w, gint h); + // vim:ft=objc:sts=2:sw=2:et diff --git a/tikzit/src/gtk/gtkhelpers.m b/tikzit/src/gtk/gtkhelpers.m index da13f54..150af9d 100644 --- a/tikzit/src/gtk/gtkhelpers.m +++ b/tikzit/src/gtk/gtkhelpers.m @@ -133,4 +133,92 @@ GdkPixbuf * pixbuf_get_from_surface(cairo_surface_t *surface) { return pixbuf; } +/* This function mostly lifted from + * gtk+/gdk/gdkscreen.c:gdk_screen_get_monitor_at_window() + */ +static gint +get_appropriate_monitor (GdkScreen *screen, + gint x, + gint y, + gint w, + gint h) +{ + GdkRectangle rect; + gint area = 0; + gint monitor = -1; + gint num_monitors; + gint i; + + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + + num_monitors = gdk_screen_get_n_monitors (screen); + + for (i = 0; i < num_monitors; i++) + { + GdkRectangle geometry; + + gdk_screen_get_monitor_geometry (screen, i, &geometry); + + if (gdk_rectangle_intersect (&rect, &geometry, &geometry) && + geometry.width * geometry.height > area) + { + area = geometry.width * geometry.height; + monitor = i; + } + } + + if (monitor >= 0) + return monitor; + else + return gdk_screen_get_monitor_at_point (screen, + rect.x + rect.width / 2, + rect.y + rect.height / 2); +} + +/* This function mostly lifted from gimp_session_info_apply_geometry + * in gimp-2.6/app/widgets/gimpsessioninfo.c + */ +void tz_restore_window (GtkWindow *window, gint x, gint y, gint w, gint h) +{ + gint forced_w = w; + gint forced_h = h; + if (w <= 0 || h <= 0) { + gtk_window_get_default_size (window, &w, &h); + } + if (w <= 0 || h <= 0) { + gtk_window_get_size (window, &w, &h); + } + + GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (window)); + + gint monitor = 0; + if (w > 0 && h > 0) { + monitor = get_appropriate_monitor (screen, x, y, w, h); + } else { + monitor = gdk_screen_get_monitor_at_point (screen, x, y); + } + + GdkRectangle rect; + gdk_screen_get_monitor_geometry (screen, monitor, &rect); + + x = CLAMP (x, + rect.x, + rect.x + rect.width - (w > 0 ? w : 128)); + y = CLAMP (y, + rect.y, + rect.y + rect.height - (h > 0 ? h : 128)); + + gchar geom[32]; + g_snprintf (geom, sizeof (geom), "%+d%+d", x, y); + + gtk_window_parse_geometry (window, geom); + + if (forced_w > 0 && forced_h > 0) { + gtk_window_set_default_size (window, forced_w, forced_h); + } +} + // vim:ft=objc:ts=8:et:sts=4:sw=4 -- cgit v1.2.3