summaryrefslogtreecommitdiff
path: root/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'window.c')
-rw-r--r--window.c285
1 files changed, 156 insertions, 129 deletions
diff --git a/window.c b/window.c
index 53b5f38..2db2d5c 100644
--- a/window.c
+++ b/window.c
@@ -73,7 +73,7 @@ compute_size (SivWindow *window, int *w, int *h)
if (!w) w = &d;
if (!h) h = &d;
-
+
scale = get_scale (window);
*w = gdk_pixbuf_get_width (window->original) * scale;
@@ -88,7 +88,7 @@ initialize_bg (GtkWidget *drawing_area, GdkRegion *region)
if (gdk_region_empty (region))
return;
-
+
gc = gdk_gc_new (drawing_area->window);
gdk_gc_set_rgb_fg_color (gc, &(private->bg_color));
@@ -116,7 +116,7 @@ paint_rect (GtkWidget *drawing_area, GdkRectangle *area, SivWindow *window)
image.x = image.y = 0;
compute_size (window, &image.width, &image.height);
-
+
if (image.width < window_width)
image.x = (window_width - image.width) / 2;
@@ -132,7 +132,7 @@ paint_rect (GtkWidget *drawing_area, GdkRectangle *area, SivWindow *window)
gdk_region_destroy (bg_reg);
gdk_region_destroy (image_reg);
-
+
if (!gdk_rectangle_intersect (area, &image, &dest))
return;
@@ -173,7 +173,7 @@ paint_rect (GtkWidget *drawing_area, GdkRectangle *area, SivWindow *window)
16, color1, color2);
pixmap = gdk_pixmap_new (drawing_area->window, dest.width, dest.height, -1);
-
+
gdk_draw_pixbuf (pixmap, NULL,
tmp, 0, 0, 0, 0, dest.width, dest.height, GDK_RGB_DITHER_NONE,
0, 0);
@@ -183,7 +183,7 @@ paint_rect (GtkWidget *drawing_area, GdkRectangle *area, SivWindow *window)
0, 0, dest.x, dest.y, dest.width, dest.height);
g_object_unref (gc);
g_object_unref (pixmap);
-
+
g_object_unref (tmp);
}
@@ -193,7 +193,7 @@ on_expose (GtkWidget *drawing_area, GdkEventExpose *expose, SivWindow *window)
GdkRectangle *rects;
int n_rects;
int i;
-
+
if (!GTK_WIDGET_DRAWABLE (get_widget (window, "drawing_area")))
return FALSE;
@@ -206,7 +206,7 @@ on_expose (GtkWidget *drawing_area, GdkEventExpose *expose, SivWindow *window)
#if 0
paint_rect (drawing_area, &(expose->area), window);
#endif
-
+
gdk_region_get_rectangles (expose->region, &rects, &n_rects);
#if 0
@@ -217,12 +217,12 @@ on_expose (GtkWidget *drawing_area, GdkEventExpose *expose, SivWindow *window)
#if 0
g_print (" %d %d %d %d\n", rects[i].x, rects[i].y, rects[i].width, rects[i].height);
#endif
-
+
paint_rect (drawing_area, &(rects[i]), window);
}
-
+
g_free (rects);
-
+
return TRUE;
}
@@ -242,18 +242,18 @@ adjust_adjustment (GtkAdjustment *adj, int old_size, int new_size)
static void
set_sensitivity (SivWindow *window)
-{
+{
gboolean can_zoom_out = FALSE;
gboolean can_zoom_in = FALSE;
int i;
/* List of widgets that are sensitive if and only if a file is loaded */
const char insensitive[][32] =
- {
- "menu_white", "menu_checkerboard", "menu_no", "menu_smooth_image",
- "menu_zoom_normal", "zoom_normal"
- };
-
+ {
+ "menu_white", "menu_checkerboard", "menu_no", "menu_smooth_image",
+ "menu_zoom_normal", "zoom_normal"
+ };
+
for (i = 0; i < G_N_ELEMENTS (insensitive); ++i)
{
GtkWidget *widget = get_widget (window, insensitive[i]);
@@ -263,13 +263,13 @@ set_sensitivity (SivWindow *window)
else
gtk_widget_set_sensitive (widget, FALSE);
}
-
+
if (window->original)
{
int w, h;
compute_size (window, &w, &h);
-
+
can_zoom_in = window->zoom_level < MAX_ZOOM;
can_zoom_out = window->zoom_level > MIN_ZOOM;
@@ -301,6 +301,28 @@ set_title (SivWindow *window)
}
static void
+set_status_bar (SivWindow *window)
+{
+ GtkStatusbar *bar = get_widget (window, "status_bar");
+ gtk_statusbar_pop (bar, 0);
+
+ if (window->original)
+ {
+ char *text;
+ int width, height;
+
+ width = gdk_pixbuf_get_width (window->original);
+ height = gdk_pixbuf_get_height (window->original);
+
+ text = g_strdup_printf (" %d x %d %.0f %%", width, height, 100 * get_scale (window));
+
+ gtk_statusbar_push (bar, 0, text);
+
+ g_free (text);
+ }
+}
+
+static void
save_meta_data (SivWindow *window)
{
int x, y, width, height;
@@ -317,7 +339,7 @@ save_meta_data (SivWindow *window)
gtk_window_get_position (get_widget (window, "main_window"), &x, &y);
gtk_window_get_size (get_widget (window, "main_window"), &width, &height);
-
+
if (gtk_check_menu_item_get_active (get_widget (window, "menu_no")))
{
bg = BG_NONE;
@@ -334,11 +356,11 @@ save_meta_data (SivWindow *window)
{
bg = BG_NONE;
}
-
+
smooth = gtk_check_menu_item_get_active (get_widget (window, "menu_smooth_image"));
show_toolbar = gtk_check_menu_item_get_active (get_widget (window, "menu_toolbar"));
show_status_bar = gtk_check_menu_item_get_active (get_widget (window, "menu_status_bar"));
-
+
app_set_meta_data (window->app,
filename,
x, y, width, height,
@@ -364,11 +386,11 @@ rebuild (SivWindow *window)
int w, h;
GtkAdjustment *vadj, *hadj;
GdkPixbuf *scaled;
-
+
compute_size (window, &w, &h);
gtk_widget_hide (get_widget (window, "scrolled_window"));
-
+
hadj = get_hadj (window);
vadj = get_vadj (window);
@@ -376,7 +398,7 @@ rebuild (SivWindow *window)
{
gtk_adjustment_set_value (hadj, 0.0);
gtk_adjustment_set_value (vadj, 0.0);
-
+
window->first = FALSE;
}
else
@@ -387,7 +409,7 @@ rebuild (SivWindow *window)
if (vadj->page_size < h)
adjust_adjustment (vadj, window->height, h);
}
-
+
gtk_widget_set_size_request (get_widget (window, "drawing_area"), w, h);
/* The documentation for gtk_window_set_icon() says you shouldn't scale
@@ -404,34 +426,34 @@ rebuild (SivWindow *window)
int width = gdk_pixbuf_get_width (tmp);
int height = gdk_pixbuf_get_height (tmp);
GdkPixbuf *t;
-
+
while (width >= 1024 || height >= 1024)
{
width /= 2;
height /= 2;
-
+
t = gdk_pixbuf_scale_simple (tmp, width, height, GDK_INTERP_BILINEAR);
-
+
g_object_unref (tmp);
-
+
tmp = t;
}
t = gdk_pixbuf_scale_simple (tmp, 32, 32, GDK_INTERP_BILINEAR);
g_object_unref (tmp);
-
+
scaled = t;
}
else
{
scaled = g_object_ref (window->original);
}
-
+
gtk_window_set_icon (get_widget (window, "main_window"), scaled);
g_object_unref (scaled);
-
+
gtk_widget_show (get_widget (window, "scrolled_window"));
window->width = w;
@@ -445,6 +467,8 @@ rebuild (SivWindow *window)
set_title (window);
set_sensitivity (window);
+ set_status_bar (window);
+
if (gtk_check_menu_item_get_active (get_widget (window, "menu_toolbar")))
gtk_widget_show (get_widget (window, "toolbar"));
else
@@ -454,7 +478,7 @@ rebuild (SivWindow *window)
gtk_widget_show (get_widget (window, "status_bar"));
else
gtk_widget_hide (get_widget (window, "status_bar"));
-
+
gtk_widget_queue_draw (get_widget (window, "drawing_area"));
}
@@ -523,7 +547,7 @@ on_mouse_press (GtkWidget *widget, GdkEventButton *button, SivWindow *window)
if (button->button == 1)
{
GdkCursor *cursor = gdk_cursor_new (GDK_FLEUR);
-
+
if (gdk_pointer_grab (widget->window, FALSE,
GDK_BUTTON1_MOTION_MASK |
GDK_BUTTON_RELEASE_MASK |
@@ -570,7 +594,7 @@ get_motion_time (Display *dpy,
XPointer arg)
{
EventScannerData *esd = (EventScannerData *)arg;
-
+
if (esd->stop_compressing)
return FALSE;
@@ -592,7 +616,7 @@ get_motion_time (Display *dpy,
esd->last_motion_time = xevent->xcrossing.time;
return FALSE;
}
-
+
return FALSE;
}
@@ -620,7 +644,7 @@ use_this_motion_notify (GdkWindow *window,
else
{
/* There are more motion events already queued up */
-
+
return FALSE;
}
}
@@ -629,9 +653,9 @@ use_this_motion_notify (GdkWindow *window,
Display *dpy = gdk_x11_get_default_xdisplay();
EventScannerData esd = { GDK_WINDOW_XWINDOW (window), 0, FALSE };
XEvent dummy;
-
+
XCheckIfEvent (dpy, &dummy, get_motion_time, (XPointer)&esd);
-
+
if (esd.last_motion_time == 0)
{
return TRUE;
@@ -648,13 +672,13 @@ static void
handle_motion (SivWindow *window, guint32 time, int x, int y)
{
GtkWidget *widget = get_widget (window, "drawing_area");
-
+
if (!use_this_motion_notify (
widget->window, time, &(window->last_motion_time)))
{
return;
}
-
+
if (window->dragging)
{
GtkAdjustment *vadj = get_vadj (window);
@@ -704,7 +728,7 @@ on_size_allocate (GtkWidget *widget, GtkAllocation *allocation, gpointer data)
GdkRectangle new;
GdkRegion *region;
int dx, dy;
-
+
if (!window->original)
return;
@@ -745,9 +769,9 @@ on_size_allocate (GtkWidget *widget, GtkAllocation *allocation, gpointer data)
gdk_window_move_region (widget->window, region, dx, dy);
gdk_region_destroy (region);
-
+
}
-
+
window->allocation = *allocation;
}
@@ -773,7 +797,7 @@ set_busy (GtkWidget *widget,
{
GdkCursor *cursor;
GdkWindow *window;
-
+
if (busy)
cursor = gdk_cursor_new (GDK_WATCH);
else
@@ -783,9 +807,9 @@ set_busy (GtkWidget *widget,
window = gtk_text_view_get_window (GTK_TEXT_VIEW (widget), GTK_TEXT_WINDOW_TEXT);
else
window = widget->window;
-
+
gdk_window_set_cursor (window, cursor);
-
+
if (cursor)
gdk_cursor_unref (cursor);
@@ -814,18 +838,18 @@ on_open (GtkWidget *widget, gpointer data)
SivWindow *window = data;
gchar *filename = NULL;
GtkFileChooser *chooser;
-
+
set_busy (get_widget (window, "main_window"), TRUE);
-
+
chooser = GTK_FILE_CHOOSER (app_get_open_chooser (window->app));
gtk_window_set_transient_for (GTK_WINDOW (chooser),
get_widget (window, "main_window"));
gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
-
+
add_image_filters (chooser);
-
+
set_busy (get_widget (window, "main_window"), FALSE);
-
+
retry:
if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT)
{
@@ -839,7 +863,7 @@ retry:
target = window_new (window->app);
else
target = window;
-
+
filename = gtk_file_chooser_get_filename (chooser);
/* This broke in GTK+ 2.13 */
@@ -859,13 +883,13 @@ retry:
tmp = nul_canonicalize_filename (filename);
g_free (filename);
filename = tmp;
-
+
set_busy (GTK_WIDGET (chooser), TRUE);
success = window_load_file (target, filename, &err);
set_busy (GTK_WIDGET (chooser), FALSE);
-
+
if (success)
{
if (target != window)
@@ -875,7 +899,7 @@ retry:
{
app_show_could_not_open (
get_widget (window, "main_window"), 1, &filename);
-
+
g_error_free (err);
if (window != target)
@@ -883,7 +907,7 @@ retry:
}
g_free (filename);
-
+
if (!success)
goto retry;
}
@@ -909,7 +933,7 @@ static void
connect_signals (SivWindow *window)
{
int i;
-
+
typedef struct
{
char widget[32];
@@ -918,35 +942,35 @@ connect_signals (SivWindow *window)
} Info;
static const Info connections[] =
- {
- { "main_window", "delete_event", G_CALLBACK (on_close_event) },
-
- { "zoom_in", "clicked", G_CALLBACK (on_zoom_in) },
- { "zoom_out", "clicked", G_CALLBACK (on_zoom_out) },
- { "zoom_normal", "clicked", G_CALLBACK (on_zoom_normal) },
-
- { "menu_zoom_in", "activate", G_CALLBACK (on_zoom_in) },
- { "menu_zoom_out", "activate", G_CALLBACK (on_zoom_out) },
- { "menu_zoom_normal", "activate", G_CALLBACK (on_zoom_normal) },
- { "menu_close", "activate", G_CALLBACK (on_close) },
- { "menu_smooth_image", "toggled", G_CALLBACK (on_various) },
-
- { "menu_white", "activate", G_CALLBACK (on_various) },
- { "menu_no", "activate", G_CALLBACK (on_various) },
- { "menu_checkerboard", "activate", G_CALLBACK (on_various) },
- { "menu_toolbar", "activate", G_CALLBACK (on_various) },
- { "menu_status_bar", "activate", G_CALLBACK (on_various) },
- { "drawing_area", "expose_event", G_CALLBACK (on_expose) },
- { "drawing_area", "scroll_event", G_CALLBACK (on_scroll) },
- { "drawing_area", "size_allocate", G_CALLBACK (on_size_allocate) },
- { "drawing_area", "button_press_event", G_CALLBACK (on_mouse_press) },
- { "drawing_area", "button_release_event", G_CALLBACK (on_mouse_release) },
- { "drawing_area", "motion_notify_event", G_CALLBACK (on_motion) },
- { "drawing_area", "leave_notify_event", G_CALLBACK (on_crossing) },
- { "drawing_area", "enter_notify_event", G_CALLBACK (on_crossing) },
- { "menu_open", "activate", G_CALLBACK (on_open) },
- { "menu_about", "activate", G_CALLBACK (on_about) },
- };
+ {
+ { "main_window", "delete_event", G_CALLBACK (on_close_event) },
+
+ { "zoom_in", "clicked", G_CALLBACK (on_zoom_in) },
+ { "zoom_out", "clicked", G_CALLBACK (on_zoom_out) },
+ { "zoom_normal", "clicked", G_CALLBACK (on_zoom_normal) },
+
+ { "menu_zoom_in", "activate", G_CALLBACK (on_zoom_in) },
+ { "menu_zoom_out", "activate", G_CALLBACK (on_zoom_out) },
+ { "menu_zoom_normal", "activate", G_CALLBACK (on_zoom_normal) },
+ { "menu_close", "activate", G_CALLBACK (on_close) },
+ { "menu_smooth_image", "toggled", G_CALLBACK (on_various) },
+
+ { "menu_white", "activate", G_CALLBACK (on_various) },
+ { "menu_no", "activate", G_CALLBACK (on_various) },
+ { "menu_checkerboard", "activate", G_CALLBACK (on_various) },
+ { "menu_toolbar", "activate", G_CALLBACK (on_various) },
+ { "menu_status_bar", "activate", G_CALLBACK (on_various) },
+ { "drawing_area", "expose_event", G_CALLBACK (on_expose) },
+ { "drawing_area", "scroll_event", G_CALLBACK (on_scroll) },
+ { "drawing_area", "size_allocate", G_CALLBACK (on_size_allocate) },
+ { "drawing_area", "button_press_event", G_CALLBACK (on_mouse_press) },
+ { "drawing_area", "button_release_event", G_CALLBACK (on_mouse_release) },
+ { "drawing_area", "motion_notify_event", G_CALLBACK (on_motion) },
+ { "drawing_area", "leave_notify_event", G_CALLBACK (on_crossing) },
+ { "drawing_area", "enter_notify_event", G_CALLBACK (on_crossing) },
+ { "menu_open", "activate", G_CALLBACK (on_open) },
+ { "menu_about", "activate", G_CALLBACK (on_about) },
+ };
for (i = 0; i < G_N_ELEMENTS (connections); ++i)
{
@@ -967,9 +991,9 @@ set_defaults (SivWindow *window)
GdkRectangle monitor;
int monitor_num;
int width, height;
-
+
monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
-
+
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
if (window->original)
@@ -990,7 +1014,7 @@ set_defaults (SivWindow *window)
height = (width * 4) / 3;
}
}
-
+
if (width > monitor.width)
width = monitor.width - 32;
@@ -1001,7 +1025,7 @@ set_defaults (SivWindow *window)
gtk_window_resize (get_widget (window, "main_window"), width, height);
else
gtk_window_set_default_size (get_widget (window, "main_window"), width, height);
-
+
gtk_window_move (get_widget (window, "main_window"),
(monitor.width - width) / 2,
(monitor.height - height) / 2);
@@ -1015,7 +1039,7 @@ set_defaults (SivWindow *window)
static void
apply_meta_data (SivWindow *window, const char *filename)
{
-
+
GtkCheckMenuItem *item;
MetaData data;
@@ -1023,36 +1047,39 @@ apply_meta_data (SivWindow *window, const char *filename)
{
gtk_window_move (get_widget (window, "main_window"),
data.window_x, data.window_y);
-
+
gtk_window_resize (get_widget (window, "main_window"),
data.window_width, data.window_height);
-
+
switch (data.background)
{
default:
case BG_NONE:
item = get_widget (window, "menu_no");
break;
-
+
case BG_CHECKERBOARD:
item = get_widget (window, "menu_checkerboard");
break;
-
+
case BG_WHITE:
item = get_widget (window, "menu_white");
break;
}
-
+
gtk_check_menu_item_set_active (item, TRUE);
-
+
gtk_check_menu_item_set_active (get_widget (window, "menu_smooth_image"),
data.smooth_image);
gtk_check_menu_item_set_active (get_widget (window, "menu_toolbar"),
data.show_toolbar);
-
+
+ gtk_check_menu_item_set_active (get_widget (window, "menu_status_bar"),
+ data.show_status_bar);
+
window->zoom_level = data.zoom_level;
-
+
/* Adjustments have to be set after the window is shown */
window->hadj = data.hadj;
window->vadj = data.vadj;
@@ -1076,9 +1103,9 @@ window_load_file (SivWindow *window, const char *filename, GError **err)
window->filename = g_strdup (filename);
apply_meta_data (window, filename);
-
+
rebuild (window);
-
+
return TRUE;
}
else
@@ -1091,20 +1118,20 @@ SivWindow *
window_new (App *app)
{
SivWindow *window = g_new0 (SivWindow, 1);
-
+
window->xml = glade_xml_new (GLADE_FILE, NULL, NULL);
window->app = app;
-
+
gtk_widget_add_events (get_widget (window, "drawing_area"),
GDK_SCROLL_MASK |
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
gtk_widget_set_double_buffered (get_widget (window, "drawing_area"), FALSE);
-
+
gtk_widget_set_redraw_on_allocate (get_widget (window, "drawing_area"), FALSE);
gtk_widget_realize (get_widget (window, "main_window"));
-
+
/* Connect signals */
connect_signals (window);
@@ -1112,11 +1139,11 @@ window_new (App *app)
window->first = TRUE;
apply_meta_data (window, "no file");
-
+
rebuild (window);
app_register_window (app, window);
-
+
return window;
}
@@ -1124,9 +1151,9 @@ void
window_free (SivWindow *window)
{
save_meta_data (window);
-
+
app_unregister_window (window->app, window);
-
+
gtk_widget_destroy (get_widget (window, "main_window"));
g_object_unref (window->xml);
@@ -1144,24 +1171,24 @@ window_free (SivWindow *window)
static guint32
extract_time_from_startup_id (const gchar* startup_id)
{
- gchar *timestr = g_strrstr (startup_id, "_TIME");
- guint32 retval = GDK_CURRENT_TIME;
+ gchar *timestr = g_strrstr (startup_id, "_TIME");
+ guint32 retval = GDK_CURRENT_TIME;
- if (timestr)
+ if (timestr)
{
- gchar *end;
- guint32 timestamp;
-
- /* Skip past the "_TIME" part */
- timestr += 5;
-
- errno = 0;
- timestamp = strtoul (timestr, &end, 0);
- if (end != timestr && errno == 0)
- retval = timestamp;
+ gchar *end;
+ guint32 timestamp;
+
+ /* Skip past the "_TIME" part */
+ timestr += 5;
+
+ errno = 0;
+ timestamp = strtoul (timestr, &end, 0);
+ if (end != timestr && errno == 0)
+ retval = timestamp;
}
- return retval;
+ return retval;
}
void
@@ -1169,7 +1196,7 @@ window_present (SivWindow *window, const char *startup_id)
{
GtkWindow *w = get_widget (window, "main_window");
guint32 time = GDK_CURRENT_TIME;
-
+
if (startup_id)
{
gtk_window_set_startup_id (w, startup_id);
@@ -1179,7 +1206,7 @@ window_present (SivWindow *window, const char *startup_id)
if (time == GDK_CURRENT_TIME)
time = gtk_get_current_event_time();
-
+
gtk_window_present_with_time (w, time);
}
@@ -1187,13 +1214,13 @@ void
window_show (SivWindow *window, const char *startup_id)
{
GtkAdjustment *vadj, *hadj;
-
+
gtk_widget_show (get_widget (window, "main_window"));
gtk_window_set_focus (get_widget (window, "main_window"), NULL);
/* We have to do this after the window is shown */
-
+
hadj = gtk_scrolled_window_get_hadjustment (
get_widget (window, "scrolled_window"));
vadj = gtk_scrolled_window_get_vadjustment (