Hello,

The attached patch replaces the hard-coded divider logic with one based on 
GtkPaned.

Features:
  - less code
  - dynamic change of the layout is still there
  - flicker when resizing the main editor window is greatly reduced
  - GtkPaned is themeable which means better interaction with the desktop 
environment

Notes:
  - cursorLast and the related code was removed because it did not work
    with dynamically destroyed/created windows. This removal should not affect 
the win32 code.

Developed under libgtk2.0, version 2.8.20.

Please check.

With best regards,
Stanislav
diff -urN scite-1.74-orig/scintilla/gtk/PlatGTK.cxx scite-1.74/scintilla/gtk/PlatGTK.cxx
--- scite-1.74-orig/scintilla/gtk/PlatGTK.cxx	2007-06-15 15:24:38.000000000 +0400
+++ scite-1.74/scintilla/gtk/PlatGTK.cxx	2007-08-16 20:35:58.000000000 +0400
@@ -1833,12 +1833,6 @@
 }
 
 void Window::SetCursor(Cursor curs) {
-	// We don't set the cursor to same value numerous times under gtk because
-	// it stores the cursor in the window once it's set
-	if (curs == cursorLast)
-		return;
-
-	cursorLast = curs;
 	GdkCursor *gdkCurs;
 	switch (curs) {
 	case cursorText:
@@ -1861,7 +1855,6 @@
 		break;
 	default:
 		gdkCurs = gdk_cursor_new(GDK_LEFT_PTR);
-		cursorLast = cursorArrow;
 		break;
 	}
 
diff -urN scite-1.74-orig/scintilla/include/Platform.h scite-1.74/scintilla/include/Platform.h
--- scite-1.74-orig/scintilla/include/Platform.h	2007-06-01 04:57:21.000000000 +0400
+++ scite-1.74/scintilla/include/Platform.h	2007-08-16 20:37:00.000000000 +0400
@@ -373,13 +373,13 @@
 	void *control;
 #endif
 public:
-	Window() : id(0), cursorLast(cursorInvalid) {
+	Window() : id(0) {
 #ifdef PLAT_MACOSX
 	  windowRef = 0;
 	  control = 0;
 #endif
 	}
-	Window(const Window &source) : id(source.id), cursorLast(cursorInvalid) {
+	Window(const Window &source) : id(source.id) {
 #ifdef PLAT_MACOSX
 	  windowRef = 0;
 	  control = 0;
@@ -409,8 +409,6 @@
 	void SetWindow(void *ref) { windowRef = ref; };
 	void SetControl(void *_control) { control = _control; };
 #endif
-private:
-	Cursor cursorLast;
 };
 
 /**
diff -urN scite-1.74-orig/scite/gtk/SciTEGTK.cxx scite-1.74/scite/gtk/SciTEGTK.cxx
--- scite-1.74-orig/scite/gtk/SciTEGTK.cxx	2007-06-13 18:09:09.000000000 +0400
+++ scite-1.74/scite/gtk/SciTEGTK.cxx	2007-08-18 17:59:52.000000000 +0400
@@ -307,11 +307,9 @@
 
 protected:
 
-	Window wDivider;
+	GtkWidget *splitPane;
 	Point ptOld;
 	GdkGC *xor_gc;
-	bool focusEditor;
-	bool focusOutput;
 
 	guint sbContextID;
 	Window wToolBarBox;
@@ -497,11 +495,6 @@
 	static gint MousePress(GtkWidget *widget, GdkEventButton *event, SciTEGTK *scitew);
 	gint Mouse(GdkEventButton *event);
 
-	void DividerXOR(Point pt);
-	static gint DividerExpose(GtkWidget *widget, GdkEventExpose *ose, SciTEGTK *scitew);
-	static gint DividerMotion(GtkWidget *widget, GdkEventMotion *event, SciTEGTK *scitew);
-	static gint DividerPress(GtkWidget *widget, GdkEventButton *event, SciTEGTK *scitew);
-	static gint DividerRelease(GtkWidget *widget, GdkEventButton *event, SciTEGTK *scitew);
 	static void DragDataReceived(GtkWidget *widget, GdkDragContext *context,
 	                             gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, SciTEGTK *scitew);
 
@@ -538,6 +531,7 @@
 	                          int startID = 0, const char *radioStart = 0);
 	void CreateMenu();
 	void CreateUI();
+	void LayoutUI();
 	void Run(int argc, char *argv[]);
 	void ProcessExecute();
 	virtual void Execute();
@@ -595,6 +589,8 @@
 	btnBuild = 0;
 	btnStop = 0;
 	itemFactory = 0;
+	splitPane = 0;
+	heightBar = 0;
 
 	fileSelectorWidth = 580;
 	fileSelectorHeight = 480;
@@ -835,6 +831,13 @@
 		SizeSubWindows();
 		CheckMenus();
 		break;
+	// override base class
+	case IDM_SPLITVERTICAL:
+		splitVertical = !splitVertical;
+		heightBar = 0;
+		LayoutUI();
+		CheckMenus();
+		break;
 
 	default:
 		SciTEBase::MenuCommand(cmdID, menuSource);
@@ -888,30 +891,45 @@
 }
 
 void SciTEGTK::SizeContentWindows() {
-	PRectangle rcClient = GetClientRectangle();
-#if GTK_MAJOR_VERSION < 2
-	int left = 0;
-	int top = 0;
-#else
-	int left = rcClient.left;
-	int top = rcClient.top;
-#endif
-	int w = rcClient.right - rcClient.left;
-	int h = rcClient.bottom - rcClient.top;
-	heightOutput = NormaliseSplit(heightOutput);
+//	printf("SizeContentWindows: heightOutput = %d, prevHeightOutput = %d, heightBar = %d\n",
+//			heightOutput, previousHeightOutput, heightBar);
+	// we come here when receiving resizing signals
+	int height, bar;
 	if (splitVertical) {
-		wEditor.SetPosition(PRectangle(left, top, w - heightOutput - heightBar + left, h + top));
-		wDivider.SetPosition(PRectangle(w - heightOutput - heightBar + left, top, w - heightOutput + left, h + top));
-		wOutput.SetPosition(PRectangle(w - heightOutput + left, top, w + left, h + top));
+		height = PWidget(wOutput)->allocation.width;
+		bar = splitPane->allocation.width - PWidget(wEditor)->allocation.width - height;
 	} else {
-		wEditor.SetPosition(PRectangle(left, top, w + left, h - heightOutput - heightBar + top));
-		wDivider.SetPosition(PRectangle(left, h - heightOutput - heightBar + top, w + left, h - heightOutput + top));
-		wOutput.SetPosition(PRectangle(left, h - heightOutput + top, w + left, h + top));
+		height = PWidget(wOutput)->allocation.height;
+		bar = splitPane->allocation.height - PWidget(wEditor)->allocation.height - height;
 	}
+	// minimum widget allocation size returned by GTK is 1, not 0, therefore
+	if (height > 1)
+		heightOutput = height;
+	else
+		heightOutput = 0;
+	// shall we update heightBar?
+	if (!heightBar)
+		// this is needed for correct geometry calculations when heightOutput = 0
+		if (heightOutput > 0)
+			heightBar = bar;
+		else
+			heightBar = height + bar;
+	// shall we touch previousHeightOutput?
+	if (heightOutput > 0)
+		previousHeightOutput = heightOutput;
+	// check the menu item (needed when gutter reaches the edge)
+	CheckAMenuItem(IDM_TOGGLEOUTPUT, heightOutput > 0);
+//	printf("\ton leave: a.w = %d, a.h = %d, heightOutput = %d, prevHeightOutput = %d, heightBar = %d\n",
+//			splitPane->allocation.width, splitPane->allocation.height, heightOutput, previousHeightOutput, heightBar);
 }
 
 void SciTEGTK::SizeSubWindows() {
-	SizeContentWindows();
+//	printf("SizeSubWindows: heightOutput = %d, prevHeightOutput = %d, heightBar = %d\n",
+//			heightOutput, previousHeightOutput, heightBar);
+	if (splitVertical)
+		gtk_paned_set_position(GTK_PANED(splitPane), splitPane->allocation.width - heightOutput - heightBar);
+	else
+		gtk_paned_set_position(GTK_PANED(splitPane), splitPane->allocation.height - heightOutput - heightBar);
 }
 
 void SciTEGTK::SetMenuItem(int, int, int itemID, const char *text, const char *mnemonic) {
@@ -2127,7 +2145,7 @@
 
 gint SciTEGTK::MoveResize(GtkWidget *, GtkAllocation * /*allocation*/, SciTEGTK *scitew) {
 	//Platform::DebugPrintf("SciTEGTK move resize %d %d\n", allocation->width, allocation->height);
-	scitew->SizeSubWindows();
+	scitew->SizeContentWindows();
 	return TRUE;
 }
 
@@ -2331,129 +2349,6 @@
 	return FALSE;
 }
 
-void SciTEGTK::DividerXOR(Point pt) {
-	if (!xor_gc) {
-		GdkGCValues values;
-		values.foreground = PWidget(wSciTE)->style->white;
-		values.function = GDK_XOR;
-		values.subwindow_mode = GDK_INCLUDE_INFERIORS;
-		xor_gc = gdk_gc_new_with_values(PWidget(wSciTE)->window,
-		                                &values,
-		                                static_cast<GdkGCValuesMask>(
-		                                    GDK_GC_FOREGROUND | GDK_GC_FUNCTION | GDK_GC_SUBWINDOW));
-	}
-	if (splitVertical) {
-		gdk_draw_line(PWidget(wSciTE)->window, xor_gc,
-		              pt.x,
-		              PWidget(wDivider)->allocation.y,
-		              pt.x,
-		              PWidget(wDivider)->allocation.y + PWidget(wDivider)->allocation.height - 1);
-	} else {
-		gdk_draw_line(PWidget(wSciTE)->window, xor_gc,
-		              PWidget(wDivider)->allocation.x,
-		              pt.y,
-		              PWidget(wDivider)->allocation.x + PWidget(wDivider)->allocation.width - 1,
-		              pt.y);
-	}
-	ptOld = pt;
-}
-
-gint SciTEGTK::DividerExpose(GtkWidget *widget, GdkEventExpose *, SciTEGTK *sciThis) {
-	//GtkStyle style = gtk_widget_get_default_style();
-	GdkRectangle area;
-	area.x = 0;
-	area.y = 0;
-	area.width = widget->allocation.width;
-	area.height = widget->allocation.height;
-	gdk_window_clear_area(widget->window,
-	                      area.x, area.y, area.width, area.height);
-	if (widget->allocation.width > widget->allocation.height) {
-		// Horizontal divider
-		gtk_paint_hline(widget->style, widget->window, GTK_STATE_NORMAL,
-		                &area, widget, const_cast<char *>("vpaned"),
-		                0, widget->allocation.width - 1,
-		                area.height / 2 - 1);
-		gtk_paint_box (widget->style, widget->window,
-		               GTK_STATE_NORMAL,
-		               GTK_SHADOW_OUT,
-		               &area, widget, const_cast<char *>("paned"),
-		               area.width - sciThis->heightBar * 2, 1,
-		               sciThis->heightBar - 2, sciThis->heightBar - 2);
-	} else {
-		// Vertical divider
-		gtk_paint_vline(widget->style, widget->window, GTK_STATE_NORMAL,
-		                &area, widget, const_cast<char *>("hpaned"),
-		                0, widget->allocation.height - 1,
-		                area.width / 2 - 1);
-		gtk_paint_box (widget->style, widget->window,
-		               GTK_STATE_NORMAL,
-		               GTK_SHADOW_OUT,
-		               &area, widget, const_cast<char *>("paned"),
-		               1, area.height - sciThis->heightBar * 2,
-		               sciThis->heightBar - 2, sciThis->heightBar - 2);
-	}
-	return TRUE;
-}
-
-gint SciTEGTK::DividerMotion(GtkWidget *, GdkEventMotion *event, SciTEGTK *scitew) {
-	if (scitew->capturedMouse) {
-		int x = 0;
-		int y = 0;
-		GdkModifierType state;
-		if (event->is_hint) {
-			gdk_window_get_pointer(PWidget(scitew->wSciTE)->window, &x, &y, &state);
-			if (state & GDK_BUTTON1_MASK) {
-				scitew->DividerXOR(scitew->ptOld);
-				scitew->DividerXOR(Point(x, y));
-			}
-		}
-	}
-	return TRUE;
-}
-
-gint SciTEGTK::DividerPress(GtkWidget *, GdkEventButton *event, SciTEGTK *scitew) {
-	if (event->type == GDK_BUTTON_PRESS) {
-		int x = 0;
-		int y = 0;
-		GdkModifierType state;
-		gdk_window_get_pointer(PWidget(scitew->wSciTE)->window, &x, &y, &state);
-		scitew->ptStartDrag = Point(x, y);
-		scitew->capturedMouse = true;
-		scitew->heightOutputStartDrag = scitew->heightOutput;
-		scitew->focusEditor = scitew->SendEditor(SCI_GETFOCUS) != 0;
-		if (scitew->focusEditor) {
-			scitew->SendEditor(SCI_SETFOCUS, 0);
-		}
-		scitew->focusOutput = scitew->SendOutput(SCI_GETFOCUS) != 0;
-		if (scitew->focusOutput) {
-			scitew->SendOutput(SCI_SETFOCUS, 0);
-		}
-		gtk_widget_grab_focus(GTK_WIDGET(PWidget(scitew->wDivider)));
-		gtk_grab_add(GTK_WIDGET(PWidget(scitew->wDivider)));
-		gtk_widget_draw(PWidget(scitew->wDivider), NULL);
-		scitew->DividerXOR(scitew->ptStartDrag);
-	}
-	return TRUE;
-}
-
-gint SciTEGTK::DividerRelease(GtkWidget *, GdkEventButton *, SciTEGTK *scitew) {
-	if (scitew->capturedMouse) {
-		scitew->capturedMouse = false;
-		gtk_grab_remove(GTK_WIDGET(PWidget(scitew->wDivider)));
-		scitew->DividerXOR(scitew->ptOld);
-		int x = 0;
-		int y = 0;
-		GdkModifierType state;
-		gdk_window_get_pointer(PWidget(scitew->wSciTE)->window, &x, &y, &state);
-		scitew->MoveSplit(Point(x, y));
-		if (scitew->focusEditor)
-			scitew->SendEditor(SCI_SETFOCUS, 1);
-		if (scitew->focusOutput)
-			scitew->SendOutput(SCI_SETFOCUS, 1);
-	}
-	return TRUE;
-}
-
 void SciTEGTK::DragDataReceived(GtkWidget *, GdkDragContext *context,
                                 gint /*x*/, gint /*y*/, GtkSelectionData *seldata, guint /*info*/, guint time, SciTEGTK *scitew) {
 	scitew->OpenUriList(reinterpret_cast<const char *>(seldata->data));
@@ -2947,6 +2842,27 @@
 #endif
 }
 
+void SciTEGTK::LayoutUI() {
+	if (splitPane) {
+		gtk_container_remove(GTK_CONTAINER(splitPane), PWidget(wEditor));
+		gtk_container_remove(GTK_CONTAINER(splitPane), PWidget(wOutput));
+		gtk_widget_destroy(GTK_WIDGET(splitPane));
+	}
+	if (splitVertical) {
+		splitPane = gtk_hpaned_new();
+		gtk_widget_set_size_request(PWidget(wOutput), heightOutput, -1);
+	} else {
+		splitPane = gtk_vpaned_new();
+		gtk_widget_set_size_request(PWidget(wOutput), -1, heightOutput);
+	}
+	gtk_container_add(GTK_CONTAINER(PWidget(wContent)), GTK_WIDGET(splitPane));
+	gtk_paned_pack1(GTK_PANED(splitPane), PWidget(wEditor), TRUE, TRUE);
+	gtk_paned_pack2(GTK_PANED(splitPane), PWidget(wOutput), FALSE, TRUE);
+	if (!heightOutput)
+		gtk_paned_set_position(GTK_PANED(splitPane), G_MAXINT32);
+	gtk_widget_show(GTK_WIDGET(splitPane));
+}
+
 void SciTEGTK::CreateUI() {
 	CreateBuffers();
 	wSciTE = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@@ -3044,7 +2960,7 @@
 #endif
 	tabVisible = false;
 
-	wContent = gtk_fixed_new();
+	wContent = gtk_alignment_new(0, 0, 1, 1);
 	GTK_WIDGET_UNSET_FLAGS(PWidget(wContent), GTK_CAN_FOCUS);
 	gtk_box_pack_start(GTK_BOX(boxMain), PWidget(wContent), TRUE, TRUE, 0);
 
@@ -3052,52 +2968,38 @@
 	                   GTK_SIGNAL_FUNC(MoveResize), gthis);
 
 	wEditor = scintilla_new();
+	gtk_widget_ref(PWidget(wEditor));
+
 	scintilla_set_id(SCINTILLA(PWidget(wEditor)), IDM_SRCWIN);
 	fnEditor = reinterpret_cast<SciFnDirect>(Platform::SendScintilla(
 	               PWidget(wEditor), SCI_GETDIRECTFUNCTION, 0, 0));
 	ptrEditor = Platform::SendScintilla(PWidget(wEditor),
 	                                    SCI_GETDIRECTPOINTER, 0, 0);
 	SendEditor(SCI_USEPOPUP, 0);
-	gtk_fixed_put(GTK_FIXED(PWidget(wContent)), PWidget(wEditor), 0, 0);
 
 	gtk_signal_connect(GTK_OBJECT(PWidget(wEditor)), "command",
 	                   GtkSignalFunc(CommandSignal), this);
 	gtk_signal_connect(GTK_OBJECT(PWidget(wEditor)), SCINTILLA_NOTIFY,
 	                   GtkSignalFunc(NotifySignal), this);
 
-	wDivider = gtk_drawing_area_new();
-	gtk_signal_connect(GTK_OBJECT(PWidget(wDivider)), "expose_event",
-	                   GtkSignalFunc(DividerExpose), this);
-	gtk_signal_connect(GTK_OBJECT(PWidget(wDivider)), "motion_notify_event",
-	                   GtkSignalFunc(DividerMotion), this);
-	gtk_signal_connect(GTK_OBJECT(PWidget(wDivider)), "button_press_event",
-	                   GtkSignalFunc(DividerPress), this);
-	gtk_signal_connect(GTK_OBJECT(PWidget(wDivider)), "button_release_event",
-	                   GtkSignalFunc(DividerRelease), this);
-	gtk_widget_set_events(PWidget(wDivider),
-	                      GDK_EXPOSURE_MASK
-	                      | GDK_LEAVE_NOTIFY_MASK
-	                      | GDK_BUTTON_PRESS_MASK
-	                      | GDK_BUTTON_RELEASE_MASK
-	                      | GDK_POINTER_MOTION_MASK
-	                      | GDK_POINTER_MOTION_HINT_MASK
-	                     );
-	gtk_drawing_area_size(GTK_DRAWING_AREA(PWidget(wDivider)), (width == useDefault) ? 100 : width, 10);
-	gtk_fixed_put(GTK_FIXED(PWidget(wContent)), PWidget(wDivider), 0, 600);
-
 	wOutput = scintilla_new();
+	gtk_widget_ref(PWidget(wOutput));
+	
 	scintilla_set_id(SCINTILLA(PWidget(wOutput)), IDM_RUNWIN);
 	fnOutput = reinterpret_cast<SciFnDirect>(Platform::SendScintilla(
 	               PWidget(wOutput), SCI_GETDIRECTFUNCTION, 0, 0));
 	ptrOutput = Platform::SendScintilla(PWidget(wOutput),
 	                                    SCI_GETDIRECTPOINTER, 0, 0);
 	SendOutput(SCI_USEPOPUP, 0);
-	gtk_fixed_put(GTK_FIXED(PWidget(wContent)), PWidget(wOutput), (width == useDefault) ? 100 : width, 0);
+
 	gtk_signal_connect(GTK_OBJECT(PWidget(wOutput)), "command",
 	                   GtkSignalFunc(CommandSignal), this);
 	gtk_signal_connect(GTK_OBJECT(PWidget(wOutput)), SCINTILLA_NOTIFY,
 	                   GtkSignalFunc(NotifySignal), this);
 
+	splitVertical = props.GetInt("split.vertical", 0);
+	LayoutUI();
+
 	Table table(1, 2);
 	wIncrementPanel = table.Widget();
 	table.PackInto(GTK_BOX(boxMain), false);
_______________________________________________
Scite-interest mailing list
[email protected]
http://mailman.lyra.org/mailman/listinfo/scite-interest

Reply via email to