aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornyamatongwe <unknown>2007-07-07 02:54:22 +0000
committernyamatongwe <unknown>2007-07-07 02:54:22 +0000
commitf6a09392bbf959d95cd112b9ce1378a0f952776f (patch)
tree7681b30a848dc22928a9a8c6fb1b1e71ea2c51fc
parenteaeb779814bcf5487015c8ddc99e8ff5df4ff34f (diff)
downloadscintilla-mirror-f6a09392bbf959d95cd112b9ce1378a0f952776f.tar.gz
Allows the popup to be displayed below as long as it can fit on the monitor
the cursor is on rather than flipping up above the current point when near bottom of window. Implemented for GTK+ by John Ehresman. Partial Windows implementation #ifdefed out because it uses calls unavailable on Windows 95.
-rw-r--r--gtk/PlatGTK.cxx27
-rw-r--r--include/Platform.h1
-rw-r--r--macosx/PlatMacOSX.cxx4
-rw-r--r--src/ScintillaBase.cxx19
-rw-r--r--win32/PlatWin.cxx28
5 files changed, 71 insertions, 8 deletions
diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx
index 72e6eff83..4a7b2ed8d 100644
--- a/gtk/PlatGTK.cxx
+++ b/gtk/PlatGTK.cxx
@@ -1874,6 +1874,33 @@ void Window::SetTitle(const char *s) {
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
diff --git a/include/Platform.h b/include/Platform.h
index 08d71e975..6e6540007 100644
--- a/include/Platform.h
+++ b/include/Platform.h
@@ -405,6 +405,7 @@ public:
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; };
diff --git a/macosx/PlatMacOSX.cxx b/macosx/PlatMacOSX.cxx
index dc80d7036..631e0d95e 100644
--- a/macosx/PlatMacOSX.cxx
+++ b/macosx/PlatMacOSX.cxx
@@ -1059,6 +1059,10 @@ void Window::SetTitle(const char *s) {
CFRelease(title);
}
+PRectangle Window::GetMonitorRect(Point) {
+ return PRectangle();
+}
+
ListBox::ListBox() {}
ListBox::~ListBox() {}
diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx
index e2dd9473e..f8571e962 100644
--- a/src/ScintillaBase.cxx
+++ b/src/ScintillaBase.cxx
@@ -231,6 +231,9 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
PRectangle rcClient = GetClientRectangle();
Point pt = LocationFromPosition(currentPos - lenEntered);
+ PRectangle rcPopupBounds = wMain.GetMonitorRect(pt);
+ if (rcPopupBounds.Height() == 0)
+ rcPopupBounds = rcClient;
int heightLB = 100;
int widthLB = 100;
@@ -241,18 +244,18 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
}
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 +273,8 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
// 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;
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx
index 36479e0f2..948e5e655 100644
--- a/win32/PlatWin.cxx
+++ b/win32/PlatWin.cxx
@@ -1052,6 +1052,34 @@ void Window::SetTitle(const char *s) {
::SetWindowTextA(reinterpret_cast<HWND>(id), s);
}
+/* Returns rectangle of monitor pt is on, both rect and pt are in Window's
+ coordinates */
+#ifdef MULTIPLE_MONITOR_SUPPORT
+PRectangle Window::GetMonitorRect(Point pt) {
+ // MonitorFromPoint and GetMonitorInfoare not available on Windows 95 so are not used.
+ // There could be conditional code and dynamic loading in a future version
+ // so this would work on those platforms where they are available.
+ PRectangle rcPosition = GetPosition();
+ POINT ptDesktop = {pt.x + rcPosition.left, pt.y + rcPosition.top};
+ HMONITOR hMonitor = ::MonitorFromPoint(ptDesktop, MONITOR_DEFAULTTONEAREST);
+ MONITORINFOEX mi;
+ memset(&mi, 0, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ if (::GetMonitorInfo(hMonitor, &mi)) {
+ PRectangle rcMonitor(
+ mi.rcWork.left - rcPosition.left,
+ mi.rcWork.top - rcPosition.top,
+ mi.rcWork.right - rcPosition.left,
+ mi.rcWork.bottom - rcPosition.top);
+ return rcMonitor;
+ }
+}
+#else
+PRectangle Window::GetMonitorRect(Point) {
+ return PRectangle();
+}
+#endif
+
struct ListItemData {
const char *text;
int pixId;