aboutsummaryrefslogtreecommitdiffhomepage
path: root/cocoa/ScintillaCocoa.mm
diff options
context:
space:
mode:
Diffstat (limited to 'cocoa/ScintillaCocoa.mm')
-rw-r--r--cocoa/ScintillaCocoa.mm91
1 files changed, 84 insertions, 7 deletions
diff --git a/cocoa/ScintillaCocoa.mm b/cocoa/ScintillaCocoa.mm
index 6f3e711a3..c0667cf4e 100644
--- a/cocoa/ScintillaCocoa.mm
+++ b/cocoa/ScintillaCocoa.mm
@@ -895,13 +895,84 @@ void ScintillaCocoa::StartDrag()
CopySelectionRange(&selectedText);
SetPasteboardData(pasteboard, selectedText);
+ // calculate the bounds of the selection
+ PRectangle client = GetTextRectangle();
+ int selStart = sel.RangeMain().Start().Position();
+ int selEnd = sel.RangeMain().End().Position();
+ int startLine = pdoc->LineFromPosition(selStart);
+ int endLine = pdoc->LineFromPosition(selEnd);
+ Point pt;
+ int startPos, endPos, ep;
+ Rect rcSel;
+
+ if (startLine==endLine && WndProc(SCI_GETWRAPMODE, 0, 0) != SC_WRAP_NONE) {
+ // Komodo bug http://bugs.activestate.com/show_bug.cgi?id=87571
+ // Scintilla bug https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3040200&group_id=2439
+ // If the width on a wrapped-line selection is negative,
+ // find a better bounding rectangle.
+
+ Point ptStart, ptEnd;
+ startPos = WndProc(SCI_GETLINESELSTARTPOSITION, startLine, 0);
+ endPos = WndProc(SCI_GETLINESELENDPOSITION, startLine, 0);
+ // step back a position if we're counting the newline
+ ep = WndProc(SCI_GETLINEENDPOSITION, startLine, 0);
+ if (endPos > ep) endPos = ep;
+ ptStart = LocationFromPosition(startPos);
+ ptEnd = LocationFromPosition(endPos);
+ if (ptStart.y == ptEnd.y) {
+ // We're just selecting part of one visible line
+ rcSel.left = ptStart.x;
+ rcSel.right = ptEnd.x < client.right ? ptEnd.x : client.right;
+ } else {
+ // Find the bounding box.
+ startPos = WndProc(SCI_POSITIONFROMLINE, startLine, 0);
+ rcSel.left = LocationFromPosition(startPos).x;
+ rcSel.right = client.right;
+ }
+ rcSel.top = ptStart.y;
+ rcSel.bottom = ptEnd.y + vs.lineHeight;
+ if (rcSel.bottom > client.bottom) {
+ rcSel.bottom = client.bottom;
+ }
+ } else {
+ rcSel.top = rcSel.bottom = rcSel.right = rcSel.left = -1;
+ for (int l = startLine; l <= endLine; l++) {
+ startPos = WndProc(SCI_GETLINESELSTARTPOSITION, l, 0);
+ endPos = WndProc(SCI_GETLINESELENDPOSITION, l, 0);
+ if (endPos == startPos) continue;
+ // step back a position if we're counting the newline
+ ep = WndProc(SCI_GETLINEENDPOSITION, l, 0);
+ if (endPos > ep) endPos = ep;
+ pt = LocationFromPosition(startPos); // top left of line selection
+ if (pt.x < rcSel.left || rcSel.left < 0) rcSel.left = pt.x;
+ if (pt.y < rcSel.top || rcSel.top < 0) rcSel.top = pt.y;
+ pt = LocationFromPosition(endPos); // top right of line selection
+ pt.y += vs.lineHeight; // get to the bottom of the line
+ if (pt.x > rcSel.right || rcSel.right < 0) {
+ if (pt.x > client.right)
+ rcSel.right = client.right;
+ else
+ rcSel.right = pt.x;
+ }
+ if (pt.y > rcSel.bottom || rcSel.bottom < 0) {
+ if (pt.y > client.bottom)
+ rcSel.bottom = client.bottom;
+ else
+ rcSel.bottom = pt.y;
+ }
+ }
+ }
+ // must convert to global coordinates for drag regions, but also save the
+ // image rectangle for further calculations and copy operations
+ PRectangle localRectangle = PRectangle(rcSel.left, rcSel.top, rcSel.right, rcSel.bottom);
+
// Prepare drag image.
- PRectangle localRectangle = RectangleFromRange(sel.RangeMain().Start().Position(), sel.RangeMain().End().Position());
NSRect selectionRectangle = PRectangleToNSRect(localRectangle);
NSView* content = ContentView();
+
+#if 1
-#if 0 // TODO: fix initialization of the drag image with CGImageRef.
// To get a bitmap of the text we're dragging, we just use Paint on a pixmap surface.
SurfaceImpl *sw = new SurfaceImpl();
SurfaceImpl *pixmap = NULL;
@@ -916,16 +987,20 @@ void ScintillaCocoa::StartDrag()
PRectangle client = GetClientRectangle();
PRectangle imageRect = NSRectToPRectangle(selectionRectangle);
paintState = painting;
- //sw->InitPixMap(client.Width(), client.Height(), NULL, NULL);
- sw->InitPixMap(imageRect.Width(), imageRect.Height(), NULL, NULL);
+ sw->InitPixMap(client.Width(), client.Height(), NULL, NULL);
paintingAllText = true;
- Paint(sw, imageRect);
+ // Have to create a new context and make current as text drawing goes
+ // to the current context, not a passed context.
+ CGContextRef gcsw = sw->GetContext();
+ NSGraphicsContext *nsgc = [NSGraphicsContext graphicsContextWithGraphicsPort: gcsw
+ flipped: YES];
+ [NSGraphicsContext setCurrentContext:nsgc];
+ Paint(sw, client);
paintState = notPainting;
pixmap->InitPixMap(imageRect.Width(), imageRect.Height(), NULL, NULL);
CGContextRef gc = pixmap->GetContext();
-
// To make Paint() work on a bitmap, we have to flip our coordinates and translate the origin
CGContextTranslateCTM(gc, 0, imageRect.Height());
CGContextScaleCTM(gc, 1.0, -1.0);
@@ -943,7 +1018,9 @@ void ScintillaCocoa::StartDrag()
NSBitmapImageRep* bitmap = NULL;
if (pixmap)
{
- bitmap = [[[NSBitmapImageRep alloc] initWithCGImage: pixmap->GetImage()] autorelease];
+ CGImageRef imagePixmap = pixmap->GetImage();
+ bitmap = [[[NSBitmapImageRep alloc] initWithCGImage: imagePixmap] autorelease];
+ CGImageRelease(imagePixmap);
pixmap->Release();
delete pixmap;
}