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