changeset 127:271afad04d07

implemented split windows TODO: menus and hotkeys, connected zoom, activating on drag
author nadvornik
date Fri, 29 Jun 2007 15:16:46 +0000
parents 021a4d0de67b
children 98e2632b5d3d
files src/image.c src/image.h src/layout.c src/layout.h src/layout_image.c src/layout_image.h src/typedefs.h
diffstat 7 files changed, 509 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/image.c	Wed Jan 17 21:52:24 2007 +0000
+++ b/src/image.c	Fri Jun 29 15:16:46 2007 +0000
@@ -1277,6 +1277,38 @@
 	pixbuf_renderer_move(PIXBUF_RENDERER(imd->pr), PIXBUF_RENDERER(source->pr));
 }
 
+void image_sync_scroll_from_image_absolute(ImageWindow *imd, ImageWindow *source)
+{
+	gint src_width, src_height, dst_width, dst_height;
+	gint src_x, src_y;
+	gfloat dst_x, dst_y;
+	GdkRectangle src_rect;
+	GdkRectangle dst_rect;
+	gfloat dst_scale = pixbuf_renderer_zoom_get_scale(PIXBUF_RENDERER(imd->pr));
+	
+	pixbuf_renderer_get_virtual_rect(PIXBUF_RENDERER(source->pr), &src_rect);
+	pixbuf_renderer_get_scaled_size(PIXBUF_RENDERER(source->pr), &src_width, &src_height);
+	pixbuf_renderer_get_virtual_rect(PIXBUF_RENDERER(imd->pr), &dst_rect);
+	pixbuf_renderer_get_scaled_size(PIXBUF_RENDERER(imd->pr), &dst_width, &dst_height);
+
+	src_x = src_rect.x + src_rect.width / 2;
+	src_y = src_rect.y + src_rect.height / 2;
+
+	dst_x = (gfloat)src_x * dst_width / src_width - dst_rect.width / 2;
+	dst_y = (gfloat)src_y * dst_height / src_height - dst_rect.height / 2;
+
+	
+
+	image_scroll_to_point(imd, dst_x / dst_scale, dst_y / dst_scale, 0, 0);
+}
+
+void image_sync_zoom_from_image(ImageWindow *imd, ImageWindow *source)
+{
+	image_zoom_set(imd, image_zoom_get(source));
+}
+
+
+
 /* manipulation */
 
 void image_area_changed(ImageWindow *imd, gint x, gint y, gint width, gint height)
@@ -1627,6 +1659,24 @@
 	gdk_flush();
 }
 
+void image_select(ImageWindow *imd, gboolean select)
+{
+	if (imd->has_frame)
+		{
+		if (select)
+			{
+			gtk_frame_set_shadow_type(GTK_FRAME(imd->inner_frame), GTK_SHADOW_IN);
+			gtk_frame_set_shadow_type(GTK_FRAME(imd->widget), GTK_SHADOW_OUT);
+			}
+		else
+			{
+			gtk_frame_set_shadow_type(GTK_FRAME(imd->inner_frame), GTK_SHADOW_NONE);
+			gtk_frame_set_shadow_type(GTK_FRAME(imd->widget), GTK_SHADOW_IN);
+			}
+		}
+}
+
+
 /*
  *-------------------------------------------------------------------
  * prefs sync
@@ -1743,9 +1793,18 @@
 
 	if (imd->has_frame)
 		{
+		imd->inner_frame = gtk_frame_new(NULL);
+		gtk_frame_set_shadow_type(GTK_FRAME(imd->inner_frame), GTK_SHADOW_NONE);
+		gtk_container_add(GTK_CONTAINER(imd->inner_frame), imd->pr);
+		
+		
 		imd->widget = gtk_frame_new(NULL);
 		gtk_frame_set_shadow_type(GTK_FRAME(imd->widget), GTK_SHADOW_IN);
-		gtk_container_add(GTK_CONTAINER(imd->widget), imd->pr);
+		gtk_container_add(GTK_CONTAINER(imd->widget), imd->inner_frame);
+
+		gtk_container_set_border_width (GTK_CONTAINER (imd->inner_frame), 1);
+
+		gtk_widget_show(imd->inner_frame);
 		gtk_widget_show(imd->pr);
 
 		GTK_WIDGET_SET_FLAGS(imd->widget, GTK_CAN_FOCUS);
--- a/src/image.h	Wed Jan 17 21:52:24 2007 +0000
+++ b/src/image.h	Fri Jun 29 15:16:46 2007 +0000
@@ -38,6 +38,8 @@
 			  void (*func)(ImageWindow *imd, ImageState state, gpointer data),
 			  gpointer data);
 
+void image_select(ImageWindow *imd, gboolean select);
+
 /* path, name */
 const gchar *image_get_path(ImageWindow *imd);
 const gchar *image_get_name(ImageWindow *imd);
@@ -54,6 +56,9 @@
 
 GdkPixbuf *image_get_pixbuf(ImageWindow *imd);
 
+
+void image_sync_scroll_from_image_absolute(ImageWindow *imd, ImageWindow *source);
+void image_sync_zoom_from_image(ImageWindow *imd, ImageWindow *source);
 /* manipulation */
 void image_area_changed(ImageWindow *imd, gint x, gint y, gint width, gint height);
 void image_reload(ImageWindow *imd);
--- a/src/layout.c	Wed Jan 17 21:52:24 2007 +0000
+++ b/src/layout.c	Fri Jun 29 15:16:46 2007 +0000
@@ -1432,6 +1432,28 @@
 		}
 }
 
+void layout_split_change(LayoutWindow *lw, ImageSplitMode mode)
+{
+	GtkWidget *image;
+	gint i;
+	for (i=0; i < MAX_SPLIT_IMAGES; i++)
+		{
+		if (lw->split_images[i])
+			{
+			gtk_widget_hide(lw->split_images[i]->widget);
+			if (lw->split_images[i]->widget->parent != lw->utility_box) 
+				gtk_container_remove(GTK_CONTAINER(lw->split_images[i]->widget->parent), lw->split_images[i]->widget);
+			}
+		}
+	gtk_container_remove(GTK_CONTAINER(lw->utility_box), lw->split_image_widget);
+
+	image = layout_image_setup_split(lw, mode);
+
+	gtk_box_pack_start(GTK_BOX(lw->utility_box), image, TRUE, TRUE, 0);
+	gtk_box_reorder_child(GTK_BOX(lw->utility_box), image, 0);
+	gtk_widget_show(image);
+}
+
 static void layout_grid_setup(LayoutWindow *lw)
 {
 	gint priority_location;
@@ -1452,7 +1474,9 @@
 
 	priority_location = layout_grid_compass(lw);
 
-	image = layout_image_new(lw, NULL);
+	image = layout_image_setup_split(lw, lw->split_mode);
+	
+	
 	tools = layout_tools_new(lw);
 	files = layout_list_new(lw);
 
@@ -1538,7 +1562,7 @@
 void layout_style_set(LayoutWindow *lw, gint style, const gchar *order)
 {
 	gchar *path;
-	ImageWindow *old_image;
+	gint i;
 
 	if (!layout_valid(&lw)) return;
 
@@ -1564,7 +1588,6 @@
 
 	path = lw->path;
 	lw->path = NULL;
-	old_image = lw->image;
 	lw->image = NULL;
 	lw->utility_box = NULL;
 
@@ -1572,9 +1595,14 @@
 
 	/* clear it all */
 
-	gtk_widget_hide(old_image->widget);
-	gtk_widget_ref(old_image->widget);
-	gtk_container_remove(GTK_CONTAINER(old_image->widget->parent), old_image->widget);
+	for (i=0; i < MAX_SPLIT_IMAGES; i++)
+		{
+		if (lw->split_images[i])
+			{
+			gtk_widget_hide(lw->split_images[i]->widget);
+			gtk_container_remove(GTK_CONTAINER(lw->split_images[i]->widget->parent), lw->split_images[i]->widget);
+			}
+		}
 
 	lw->h_pane = NULL;
 	lw->v_pane = NULL;
@@ -1616,20 +1644,18 @@
 
 	/* sync */
 
-	if (image_get_path(old_image))
+	if (image_get_path(lw->image))
 		{
-		layout_set_path(lw, image_get_path(old_image));
+		layout_set_path(lw, image_get_path(lw->image));
 		}
 	else
 		{
 		layout_set_path(lw, path);
 		}
-	image_change_from_image(lw->image, old_image);
 	image_top_window_set_sync(lw->image, (lw->tools_float || lw->tools_hidden));
 
 	/* clean up */
 
-	gtk_widget_unref(old_image->widget);
 	g_free(path);
 }
 
--- a/src/layout.h	Wed Jan 17 21:52:24 2007 +0000
+++ b/src/layout.h	Fri Jun 29 15:16:46 2007 +0000
@@ -82,6 +82,7 @@
 void layout_toolbar_toggle(LayoutWindow *lw);
 gint layout_toolbar_hidden(LayoutWindow *lw);
 
+void layout_split_change(LayoutWindow *lw, ImageSplitMode mode);
 
 void layout_maint_renamed(const gchar *source, const gchar *dest);
 void layout_maint_removed(const gchar *path, GList *ignore_list);
--- a/src/layout_image.c	Wed Jan 17 21:52:24 2007 +0000
+++ b/src/layout_image.c	Fri Jun 29 15:16:46 2007 +0000
@@ -703,6 +703,43 @@
 	layout_tools_hide_toggle(lw);
 }
 
+static void li_pop_menu_split_none_cb(GtkWidget *widget, gpointer data)
+{
+	LayoutWindow *lw = data;
+	layout_split_change(lw, SPLIT_NONE);
+}
+
+static void li_pop_menu_split_hor_cb(GtkWidget *widget, gpointer data)
+{
+	LayoutWindow *lw = data;
+	layout_split_change(lw, SPLIT_HOR);
+}
+
+static void li_pop_menu_split_vert_cb(GtkWidget *widget, gpointer data)
+{
+	LayoutWindow *lw = data;
+	layout_split_change(lw, SPLIT_VERT);
+}
+
+static void li_pop_menu_split_quad_cb(GtkWidget *widget, gpointer data)
+{
+	LayoutWindow *lw = data;
+	layout_split_change(lw, SPLIT_QUAD);
+}
+
+static void li_pop_menu_connect_scroll_cb(GtkWidget *widget, gpointer data)
+{
+	LayoutWindow *lw = data;
+	lw->connect_scroll = !lw->connect_scroll;
+}
+
+static void li_pop_menu_connect_zoom_cb(GtkWidget *widget, gpointer data)
+{
+	LayoutWindow *lw = data;
+	lw->connect_zoom = !lw->connect_zoom;
+}
+
+
 static GtkWidget *layout_image_pop_menu(LayoutWindow *lw)
 {
 	GtkWidget *menu;
@@ -721,6 +758,18 @@
 	menu_item_add_stock(menu, _("Zoom _1:1"), GTK_STOCK_ZOOM_100, G_CALLBACK(li_pop_menu_zoom_1_1_cb), lw);
 	menu_item_add_stock(menu, _("Fit image to _window"), GTK_STOCK_ZOOM_FIT, G_CALLBACK(li_pop_menu_zoom_fit_cb), lw);
 	menu_item_add_divider(menu);
+	if (!fullscreen)
+		{
+		menu_item_add(menu, _("No split"), G_CALLBACK(li_pop_menu_split_none_cb), lw);
+		menu_item_add(menu, _("Split horizontaly"), G_CALLBACK(li_pop_menu_split_hor_cb), lw);
+		menu_item_add(menu, _("Split verticaly"), G_CALLBACK(li_pop_menu_split_vert_cb), lw);
+		menu_item_add(menu, _("Split quad"), G_CALLBACK(li_pop_menu_split_quad_cb), lw);
+		menu_item_add_check(menu, _("Connected scroll"), lw->connect_scroll,
+				   G_CALLBACK(li_pop_menu_connect_scroll_cb), lw);
+		menu_item_add_check(menu, _("Connected zoom"), lw->connect_zoom,
+				   G_CALLBACK(li_pop_menu_connect_zoom_cb), lw);
+		menu_item_add_divider(menu);
+		}
 
 	submenu = submenu_add_edit(menu, &item, G_CALLBACK(li_pop_menu_edit_cb), lw);
 	if (!path) gtk_widget_set_sensitive(item, FALSE);
@@ -815,6 +864,20 @@
 				     guint time, gpointer data)
 {
 	LayoutWindow *lw = data;
+	gint i;
+	
+	
+	for (i=0; i < MAX_SPLIT_IMAGES; i++) 
+		{
+		if (lw->split_images[i] && lw->split_images[i]->pr == widget)
+			break;
+		}
+	if (i < MAX_SPLIT_IMAGES)
+		{
+		printf("dnd image activate %d\n", i);
+		layout_image_activate(lw, i);
+		}
+
 
 	if (info == TARGET_URI_LIST || info == TARGET_APP_COLLECTION_MEMBER)
 		{
@@ -883,8 +946,21 @@
 {
 	LayoutWindow *lw = data;
 	const gchar *path;
-
-	path = layout_image_get_path(lw);
+	gint i;
+	
+	
+	for (i=0; i < MAX_SPLIT_IMAGES; i++) 
+		{
+		if (lw->split_images[i] && lw->split_images[i]->pr == widget)
+			break;
+		}
+	if (i < MAX_SPLIT_IMAGES)
+		{
+		printf("dnd get from %d\n", i);
+		path = image_get_path(lw->split_images[i]);
+		}
+	else
+		path = layout_image_get_path(lw);
 
 	if (path)
 		{
@@ -947,21 +1023,23 @@
 		}
 }
 
-static void layout_image_dnd_init(LayoutWindow *lw)
+static void layout_image_dnd_init(LayoutWindow *lw, gint i)
 {
-	gtk_drag_source_set(lw->image->pr, GDK_BUTTON2_MASK,
+	ImageWindow *imd = lw->split_images[i];
+
+	gtk_drag_source_set(imd->pr, GDK_BUTTON2_MASK,
 			    dnd_file_drag_types, dnd_file_drag_types_count,
 			    GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
-	g_signal_connect(G_OBJECT(lw->image->pr), "drag_data_get",
+	g_signal_connect(G_OBJECT(imd->pr), "drag_data_get",
 			 G_CALLBACK(layout_image_dnd_get), lw);
-	g_signal_connect(G_OBJECT(lw->image->pr), "drag_end",
+	g_signal_connect(G_OBJECT(imd->pr), "drag_end",
 			 G_CALLBACK(layout_image_dnd_end), lw);
 
-	gtk_drag_dest_set(lw->image->pr,
+	gtk_drag_dest_set(imd->pr,
 			  GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
 			  dnd_file_drop_types, dnd_file_drop_types_count,
                           GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
-	g_signal_connect(G_OBJECT(lw->image->pr), "drag_data_received",
+	g_signal_connect(G_OBJECT(imd->pr), "drag_data_received",
 			 G_CALLBACK(layout_image_dnd_receive), lw);
 }
 
@@ -1065,14 +1143,14 @@
 {
 	if (!layout_valid(&lw)) return;
 
-	if (path)
+/*	if (path)
 		{
 		const gchar *old_path;
 
 		old_path = layout_image_get_path(lw);
 		if (old_path && strcmp(path, old_path) == 0) return;
 		}
-
+*/
 	layout_image_set_path(lw, path);
 	if (enable_read_ahead) image_prebuffer_set(lw->image, read_ahead_path);
 }
@@ -1340,6 +1418,23 @@
  *----------------------------------------------------------------------------
  */
 
+static gint image_idx(LayoutWindow *lw, ImageWindow *imd)
+{
+	gint i;
+	
+	for (i=0; i < MAX_SPLIT_IMAGES; i++) 
+		{
+		if (lw->split_images[i] == imd)
+			break;
+		}
+	if (i < MAX_SPLIT_IMAGES)
+		{
+		return i;
+		}
+	return -1;
+}
+
+
 static void layout_image_button_cb(ImageWindow *imd, gint button, guint32 time,
 				   gdouble x, gdouble y, guint state, gpointer data)
 {
@@ -1372,6 +1467,15 @@
 {
 	LayoutWindow *lw = data;
 
+	gint i = image_idx(lw, imd);
+	
+	if (i != -1)
+		{
+		printf("image activate scroll %d\n", i);
+		layout_image_activate(lw, i);
+		}
+
+
 	if (state & GDK_CONTROL_MASK)
 		{
 		switch (direction)
@@ -1422,12 +1526,55 @@
 		}
 }
 
+static void layout_image_scroll_notify_cb(ImageWindow *imd, gint x, gint y, gint width, gint height, gpointer data)
+{
+	gint i;
+	printf("scroll cb %d %d %d %d\n", x,y,width, height);
+	LayoutWindow *lw = data;
+
+
+	for (i=0; i < MAX_SPLIT_IMAGES; i++)
+		{
+		if (lw->split_images[i] && lw->split_images[i] != imd)
+//			if (lw->connect_zoom)
+//				image_sync_zoom_from_image(lw->split_images[i], imd);
+			if (lw->connect_scroll)
+				image_sync_scroll_from_image_absolute(lw->split_images[i], imd);
+		}
+}
+
+static gint layout_image_mouse_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data)
+{
+
+	printf("mouse press\n");
+
+}
+
+static void layout_image_button_inactive_cb(ImageWindow *imd, gint button, guint32 time,
+				   gdouble x, gdouble y, guint state, gpointer data)
+{
+	LayoutWindow *lw = data;
+	gint i = image_idx(lw, imd);
+	
+	if (i != -1)
+		{
+		printf("image activate %d\n", i);
+		layout_image_activate(lw, i);
+		}
+}
+
 static void layout_image_set_buttons(LayoutWindow *lw)
 {
 	image_set_button_func(lw->image, layout_image_button_cb, lw);
 	image_set_scroll_func(lw->image, layout_image_scroll_cb, lw);
 }
 
+static void layout_image_set_buttons_inactive(LayoutWindow *lw, gint i)
+{
+	image_set_button_func(lw->split_images[i], layout_image_button_inactive_cb, lw);
+	image_set_scroll_func(lw->split_images[i], layout_image_scroll_cb, lw);
+}
+
 /*
  *----------------------------------------------------------------------------
  * setup
@@ -1440,29 +1587,247 @@
 	layout_status_update_image(lw);
 }
 
-GtkWidget *layout_image_new(LayoutWindow *lw, const gchar *path)
+GtkWidget *layout_image_new(LayoutWindow *lw, gint i)
 {
-	if (!lw->image) 
+	if (!lw->split_images[i]) 
 		{
-		lw->image = image_new( (!lw->tools_float && !lw->tools_hidden) );
-		if (black_window_background) image_background_set_black(lw->image, TRUE);
-		image_set_update_func(lw->image, layout_image_update_cb, lw);
-		layout_image_set_buttons(lw);
-		layout_image_dnd_init(lw);
+		lw->split_images[i] = image_new(TRUE);
+
+		gtk_widget_ref(lw->split_images[i]->widget);
 
-		image_attach_window(lw->image, lw->window, NULL, "GQview", FALSE);
+		g_signal_connect(G_OBJECT(lw->split_images[i]->widget), "button_press_event",
+                         G_CALLBACK(layout_image_mouse_press_cb), lw);
+
+
+		if (black_window_background) image_background_set_black(lw->split_images[i], TRUE);
 
 		image_auto_refresh(lw->image, 0);
 
+		layout_image_dnd_init(lw, i);
 		image_color_profile_set(lw->image,
 					color_profile_input_type, color_profile_screen_type,
 					color_profile_use_image);
 		image_color_profile_set_use(lw->image, color_profile_enabled);
 		}
 
-	return lw->image->widget;
+	return lw->split_images[i]->widget;
+}
+
+void layout_image_deactivate(LayoutWindow *lw, gint i)
+{
+
+	if (!lw->split_images[i]) return;
+	image_set_update_func(lw->split_images[i], NULL, NULL);
+	layout_image_set_buttons_inactive(lw, i);
+	image_set_scroll_notify_func(lw->split_images[i], NULL, NULL);
+
+	image_attach_window(lw->split_images[i], NULL, NULL, NULL, FALSE);
+	image_select(lw->split_images[i], FALSE);
+}
+
+
+void layout_image_activate(LayoutWindow *lw, gint i)
+{
+	const gchar *path;
+
+	gchar *base;
+	gint row;
+	gint j;
+	
+	if (!lw->split_images[i]) return;
+
+	/* deactivate currently active */
+	if (lw->active_split_image != i)
+		layout_image_deactivate(lw, lw->active_split_image);
+
+	lw->image = lw->split_images[i];
+	lw->active_split_image = i;
+	
+	image_set_update_func(lw->image, layout_image_update_cb, lw);
+	layout_image_set_buttons(lw);
+	image_set_scroll_notify_func(lw->image, layout_image_scroll_notify_cb, lw);
+
+	image_attach_window(lw->image, lw->window, NULL, "GQview", FALSE);
+
+	image_select(lw->split_images[i], TRUE);
+
+	path = image_get_path(lw->image);
+
+        if (path)
+		{
+//		layout_list_sync_path(lw, path);
+		layout_set_path(lw, path);
+		}
+}
+
+
+GtkWidget *layout_image_setup_split_none(LayoutWindow *lw)
+{
+	gint i;
+	
+	if (!lw->split_images[0])
+		{
+		layout_image_new(lw, 0);
+		layout_image_activate(lw, 0);
+		}
+		
+	for (i=1; i < MAX_SPLIT_IMAGES; i++)
+		{
+		if (lw->split_images[i])
+			{
+			gtk_widget_unref(lw->split_images[i]->widget);
+			lw->split_images[i] = NULL;
+			}
+		}
+		
+        if (!lw->image || lw->active_split_image != 0)
+		{
+		layout_image_activate(lw, 0);
+		}
+	
+	lw->split_mode = SPLIT_NONE;
+	
+	lw->split_image_widget = lw->split_images[0]->widget;
+			
+	return lw->split_image_widget;
+
 }
 
+GtkWidget *layout_image_setup_split_hv(LayoutWindow *lw, gboolean horizontal)
+{
+	GtkWidget *paned;
+	gint i;
+	
+	if (!lw->split_images[0])
+		{
+		layout_image_new(lw, 0);
+		layout_image_activate(lw, 0);
+		}
+
+	if (!lw->split_images[1])
+		{
+		layout_image_new(lw, 1);
+		if (lw->image)
+			image_change_path(lw->split_images[1], 
+				image_get_path(lw->image), image_zoom_get_real(lw->image));
+		layout_image_deactivate(lw, 1);
+		}
+
+	
+	for (i=2; i < MAX_SPLIT_IMAGES; i++)
+		{
+		if (lw->split_images[i])
+			{
+			gtk_widget_unref(lw->split_images[i]->widget);
+			lw->split_images[i] = NULL;
+			}
+		}
+
+        if (!lw->image || lw->active_split_image < 0 || lw->active_split_image > 1)
+		{
+		layout_image_activate(lw, 0);
+		}
+
+	if (horizontal)
+		paned = gtk_hpaned_new ();
+	else
+		paned = gtk_vpaned_new ();
+
+	gtk_paned_pack1 (GTK_PANED (paned), lw->split_images[0]->widget, TRUE, TRUE);
+	gtk_paned_pack2 (GTK_PANED (paned), lw->split_images[1]->widget, TRUE, TRUE);
+	
+	gtk_widget_show (lw->split_images[0]->widget);
+	gtk_widget_show (lw->split_images[1]->widget);
+	
+
+	lw->split_mode = horizontal ? SPLIT_HOR : SPLIT_VERT;
+	lw->split_image_widget = paned;
+			
+	return lw->split_image_widget;
+
+}
+
+GtkWidget *layout_image_setup_split_quad(LayoutWindow *lw)
+{
+	GtkWidget *hpaned;
+	GtkWidget *vpaned1;
+	GtkWidget *vpaned2;
+	gint i;
+	
+	if (!lw->split_images[0])
+		{
+		layout_image_new(lw, 0);
+		layout_image_activate(lw, 0);
+		}
+
+	for (i=1; i < 4; i++)
+		if (!lw->split_images[i])
+			{
+			layout_image_new(lw, i);
+			if (lw->image)
+				image_change_path(lw->split_images[i], 
+					image_get_path(lw->image), image_zoom_get_real(lw->image));
+			layout_image_deactivate(lw, i);
+			}
+
+	for (i=4; i < MAX_SPLIT_IMAGES; i++)
+		{
+		if (lw->split_images[i])
+			{
+			gtk_widget_unref(lw->split_images[i]->widget);
+			lw->split_images[i] = NULL;
+			}
+		}
+
+        if (!lw->image || lw->active_split_image < 0 || lw->active_split_image > 3)
+		{
+		layout_image_activate(lw, 0);
+		}
+
+	hpaned = gtk_hpaned_new ();
+	vpaned1 = gtk_vpaned_new ();
+	vpaned2 = gtk_vpaned_new ();
+
+	gtk_paned_pack1 (GTK_PANED (vpaned1), lw->split_images[0]->widget, TRUE, TRUE);
+	gtk_paned_pack2 (GTK_PANED (vpaned1), lw->split_images[2]->widget, TRUE, TRUE);
+
+	gtk_paned_pack1 (GTK_PANED (vpaned2), lw->split_images[1]->widget, TRUE, TRUE);
+	gtk_paned_pack2 (GTK_PANED (vpaned2), lw->split_images[3]->widget, TRUE, TRUE);
+
+	gtk_paned_pack1 (GTK_PANED (hpaned), vpaned1, TRUE, TRUE);
+	gtk_paned_pack2 (GTK_PANED (hpaned), vpaned2, TRUE, TRUE);
+
+	
+	for (i=0; i < 4; i++)
+		gtk_widget_show (lw->split_images[i]->widget);
+	gtk_widget_show (vpaned1);
+	gtk_widget_show (vpaned2);
+	
+
+	lw->split_mode = SPLIT_QUAD;
+	lw->split_image_widget = hpaned;
+			
+	return lw->split_image_widget;
+
+}
+
+GtkWidget *layout_image_setup_split(LayoutWindow *lw, ImageSplitMode mode)
+{
+	switch (mode)
+		{
+		case SPLIT_HOR: 
+			return layout_image_setup_split_hv(lw, TRUE);
+		case SPLIT_VERT:
+			return layout_image_setup_split_hv(lw, FALSE);
+		case SPLIT_QUAD:
+			return layout_image_setup_split_quad(lw);
+		case SPLIT_NONE:
+		default:
+			return layout_image_setup_split_none(lw);
+		}
+}
+
+
 /*
  *-----------------------------------------------------------------------------
  * maintenance (for rename, move, remove)
--- a/src/layout_image.h	Wed Jan 17 21:52:24 2007 +0000
+++ b/src/layout_image.h	Fri Jun 29 15:16:46 2007 +0000
@@ -13,7 +13,11 @@
 #define LAYOUT_IMAGE_H
 
 
-GtkWidget *layout_image_new(LayoutWindow *lw, const gchar *path);
+GtkWidget *layout_image_new(LayoutWindow *lw, gint i);
+void layout_image_activate(LayoutWindow *lw, gint i);
+GtkWidget *layout_image_setup_split_none(LayoutWindow *lw);
+GtkWidget *layout_image_setup_split_hv(LayoutWindow *lw, gboolean horizontal);
+GtkWidget *layout_image_setup_split(LayoutWindow *lw, ImageSplitMode mode);
 
 void layout_image_set_path(LayoutWindow *lw, const gchar *path);
 void layout_image_set_with_ahead(LayoutWindow *lw, const gchar *path, const gchar *read_ahead_path);
--- a/src/typedefs.h	Wed Jan 17 21:52:24 2007 +0000
+++ b/src/typedefs.h	Fri Jun 29 15:16:46 2007 +0000
@@ -53,6 +53,15 @@
 	IMAGE_STATE_DELAY_FLIP	= 1 << 6
 } ImageState;
 
+typedef enum {
+	SPLIT_NONE = 0,
+	SPLIT_VERT,
+	SPLIT_HOR,
+	SPLIT_QUAD,
+} ImageSplitMode;
+
+#define MAX_SPLIT_IMAGES 4
+
 typedef struct _ImageLoader ImageLoader;
 typedef struct _ThumbLoader ThumbLoader;
 
@@ -233,6 +242,7 @@
 	GtkWidget *widget;	/* use this to add it and show it */
 	GtkWidget *pr;
 	GtkWidget *frame;
+	GtkWidget *inner_frame;
 
 	gchar *image_path;
 	const gchar *image_name;
@@ -343,6 +353,14 @@
 
 	ImageWindow *image;
 
+	ImageWindow *split_images[MAX_SPLIT_IMAGES];
+        ImageSplitMode split_mode;
+	gint active_split_image;
+
+        GtkWidget *split_image_widget;
+	
+	gint connect_zoom, connect_scroll;
+	
 	/* tools window (float) */
 
 	GtkWidget *tools;