Hi,
Scintilla's autocomplete popup appears above the current line if there
isn't room in the client rectangle below the current line and there is
room above. The client rectangle is where the text is drawn. This
means that the popup appears above the current line even when there is
space below on the monitor.
The attached patch allows the popup to be displayed below as long as it
can fit on the monitor the cursor is on. It's only implemented on the
gtk platform, but hopefully isn't too difficult to implement on other
platforms. The same positioning behavior might also be applied to
calltips and other popups.
Cheers,
John
Index: include/Platform.h
===================================================================
--- include/Platform.h (revision 15788)
+++ include/Platform.h (working copy)
@@ -405,6 +405,7 @@
enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp,
cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand };
void SetCursor(Cursor curs);
void SetTitle(const char *s);
+ PRectangle GetMonitorRect(Point pt);
#if PLAT_MACOSX
void SetWindow(void *ref) { windowRef = ref; };
void SetControl(void *_control) { control = _control; };
Index: gtk/PlatGTK.cxx
===================================================================
--- gtk/PlatGTK.cxx (revision 15769)
+++ gtk/PlatGTK.cxx (working copy)
@@ -1930,6 +1930,33 @@
gtk_window_set_title(GTK_WINDOW(id), s);
}
+/* Returns rectangle of monitor pt is on, both rect and pt are in Window's
+ gdk window coordinates */
+PRectangle Window::GetMonitorRect(Point pt) {
+ gint x_offset, y_offset;
+
+ gdk_window_get_origin(PWidget(id)->window, &x_offset, &y_offset);
+
+// gtk 2.2+
+#if GTK_MAJOR_VERSION > 2 || (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 2)
+ {
+ GdkScreen* screen;
+ gint monitor_num;
+ GdkRectangle rect;
+
+ screen = gtk_widget_get_screen(PWidget(id));
+ monitor_num = gdk_screen_get_monitor_at_point(screen, pt.x +
x_offset, pt.y + y_offset);
+ gdk_screen_get_monitor_geometry(screen, monitor_num, &rect);
+ rect.x -= x_offset;
+ rect.y -= y_offset;
+ return PRectangle(rect.x, rect.y, rect.x + rect.width, rect.y +
rect.height);
+ }
+#else
+ return PRectangle(-x_offset, -y_offset, (-x_offset) +
gdk_screen_width(),
+ (-y_offset) + gdk_screen_height());
+#endif
+}
+
struct ListImage {
const char *xpm_data;
#if GTK_MAJOR_VERSION < 2
Index: src/ScintillaBase.cxx
===================================================================
--- src/ScintillaBase.cxx (revision 15760)
+++ src/ScintillaBase.cxx (working copy)
@@ -231,6 +231,7 @@
PRectangle rcClient = GetClientRectangle();
Point pt = LocationFromPosition(currentPos - lenEntered);
+ PRectangle rcPopupBounds = wMain.GetMonitorRect(pt);
int heightLB = 100;
int widthLB = 100;
@@ -241,18 +242,18 @@
}
PRectangle rcac;
rcac.left = pt.x - ac.lb->CaretFromEdge();
- if (pt.y >= rcClient.bottom - heightLB && // Wont fit below.
- pt.y >= (rcClient.bottom + rcClient.top) / 2) { // and there is
more room above.
+ if (pt.y >= rcPopupBounds.bottom - heightLB && // Wont fit below.
+ pt.y >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2) { //
and there is more room above.
rcac.top = pt.y - heightLB;
- if (rcac.top < 0) {
- heightLB += rcac.top;
- rcac.top = 0;
+ if (rcac.top < rcPopupBounds.top) {
+ heightLB -= (rcPopupBounds.top - rcac.top);
+ rcac.top = rcPopupBounds.top;
}
} else {
rcac.top = pt.y + vs.lineHeight;
}
rcac.right = rcac.left + widthLB;
- rcac.bottom = Platform::Minimum(rcac.top + heightLB, rcClient.bottom);
+ rcac.bottom = Platform::Minimum(rcac.top + heightLB,
rcPopupBounds.bottom);
ac.lb->SetPositionRelative(rcac, wMain);
ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font);
unsigned int aveCharWidth = vs.styles[STYLE_DEFAULT].aveCharWidth;
@@ -270,8 +271,8 @@
// Make an allowance for large strings in list
rcList.left = pt.x - ac.lb->CaretFromEdge();
rcList.right = rcList.left + widthLB;
- if (((pt.y + vs.lineHeight) >= (rcClient.bottom - heightAlloced)) &&
// Wont fit below.
- ((pt.y + vs.lineHeight / 2) >= (rcClient.bottom + rcClient.top)
/ 2)) { // and there is more room above.
+ if (((pt.y + vs.lineHeight) >= (rcPopupBounds.bottom - heightAlloced))
&& // Wont fit below.
+ ((pt.y + vs.lineHeight / 2) >= (rcPopupBounds.bottom +
rcPopupBounds.top) / 2)) { // and there is more room above.
rcList.top = pt.y - heightAlloced;
} else {
rcList.top = pt.y + vs.lineHeight;
_______________________________________________
Scintilla-interest mailing list
[email protected]
http://mailman.lyra.org/mailman/listinfo/scintilla-interest