Hello,

Here goes the 3rd version of the patch (attached).
  - focus behaviour corrected (finally?)
  - LayoutUI() is now called after the properties have been read
  - set minimum size hint to wContent

Please check.

-- 
Stanislav

On Tue, Aug 21, 2007 at 09:33:33AM +1000, Neil Hodgson wrote:
> Stanislav Maslovski:
> 
> >   - problem with cursors solved.
> 
>    Using cursorInvalid in this way is good.
> 
> > >   - focus issues fixed.
> >
> > Oops, not all of them. When the output window is opened to
> > the maximum width the focus goes nowhere...
> 
>    Its OK to be a bit heavy-handed, forcing the focus into a visible
> window even if it doesn't seem to be currently associated with an
> editing pane. That's better than any situation where typing goes
> nowhere.
> 
>   Neil
> _______________________________________________
> Scite-interest mailing list
> Scite-interest@lyra.org
> http://mailman.lyra.org/mailman/listinfo/scite-interest

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-23 11:53:24.847560293 +0400
@@ -1841,6 +1841,8 @@
 	cursorLast = curs;
 	GdkCursor *gdkCurs;
 	switch (curs) {
+	case cursorInvalid:
+		return;
 	case cursorText:
 		gdkCurs = gdk_cursor_new(GDK_XTERM);
 		break;
diff -urN scite-1.74-orig/scintilla/gtk/ScintillaGTK.cxx scite-1.74/scintilla/gtk/ScintillaGTK.cxx
--- scite-1.74-orig/scintilla/gtk/ScintillaGTK.cxx	2007-06-12 07:55:11.000000000 +0400
+++ scite-1.74/scintilla/gtk/ScintillaGTK.cxx	2007-08-23 11:53:24.847560721 +0400
@@ -568,6 +568,9 @@
 	gtk_widget_unmap(PWidget(wText));
 	gtk_widget_unmap(PWidget(scrollbarh));
 	gtk_widget_unmap(PWidget(scrollbarv));
+	wText.SetCursor(Window::cursorInvalid);
+	scrollbarv.SetCursor(Window::cursorInvalid);
+	scrollbarh.SetCursor(Window::cursorInvalid);
 }
 
 void ScintillaGTK::UnMap(GtkWidget *widget) {
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-23 14:18:04.023497756 +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,50 @@
 }
 
 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);
-	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));
-	} 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));
+	if (splitPane) {
+		// we come here when receiving resizing signals
+		int height, heightEditor, bar;
+		if (splitVertical) {
+			height = PWidget(wOutput)->allocation.width;
+			heightEditor = PWidget(wEditor)->allocation.width;
+			bar = splitPane->allocation.width - heightEditor - height;
+		} else {
+			height = PWidget(wOutput)->allocation.height;
+			heightEditor = PWidget(wEditor)->allocation.height;
+			bar = splitPane->allocation.height - heightEditor - height;
+		}
+		// minimum widget allocation size returned by GTK is 1, not 0
+		if (height > 1) {
+			previousHeightOutput = heightOutput = height;
+		} else {
+			// shall we touch previousHeightOutput?
+			if (heightOutput > 0)
+				previousHeightOutput = 0;
+			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;
+		// do we need focus change?
+		if (heightEditor <= 1 && !wOutput.HasFocus())
+			WindowSetFocus(wOutput);
+		if (heightOutput <= 1 && !wEditor.HasFocus())
+			WindowSetFocus(wEditor);
+		// update menu item (needed when gutter reaches the edge)
+		CheckAMenuItem(IDM_TOGGLEOUTPUT, heightOutput > 0);
 	}
 }
 
 void SciTEGTK::SizeSubWindows() {
-	SizeContentWindows();
+	if (splitPane)
+		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 +2150,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 +2354,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 +2847,35 @@
 #endif
 }
 
+void SciTEGTK::LayoutUI() {
+	bool focusEditor = false;
+	bool focusOutput = false;
+	if (splitPane) {
+		focusEditor = wEditor.HasFocus();
+		focusOutput = wOutput.HasFocus();
+		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);
+	if (focusEditor)
+		WindowSetFocus(wEditor);
+	if (focusOutput)
+		WindowSetFocus(wOutput);
+	gtk_widget_show_all(GTK_WIDGET(splitPane));
+}
+
 void SciTEGTK::CreateUI() {
 	CreateBuffers();
 	wSciTE = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@@ -3044,7 +2973,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,47 +2981,28 @@
 	                   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,
@@ -3132,6 +3042,10 @@
 
 	SetFocus(PWidget(wOutput));
 
+	GdkGeometry hint;
+	hint.min_height = 50;
+	hint.min_width = 50;
+	gtk_window_set_geometry_hints(GTK_WINDOW(PWidget(wSciTE)), PWidget(wContent), &hint, GDK_HINT_MIN_SIZE);
 	if ((left != useDefault) && (top != useDefault))
 		gtk_widget_set_uposition(GTK_WIDGET(PWidget(wSciTE)), left, top);
 	if ((width != useDefault) && (height != useDefault))
@@ -3343,6 +3257,7 @@
 	// Process remaining switches and files
 	ProcessCommandLine(args, 1);
 
+	LayoutUI();
 	CheckMenus();
 	SizeSubWindows();
 	SetFocus(PWidget(wEditor));
_______________________________________________
Scite-interest mailing list
Scite-interest@lyra.org
http://mailman.lyra.org/mailman/listinfo/scite-interest

Reply via email to