diff options
author | nyamatongwe <unknown> | 2011-07-10 12:09:42 +1000 |
---|---|---|
committer | nyamatongwe <unknown> | 2011-07-10 12:09:42 +1000 |
commit | 4b991bfffc9f20740e7911f4141cbbadde03140d (patch) | |
tree | 94c4417823a18a94ead2e6383652cf3b99598a26 | |
parent | aa96f882493d66841cedc55be38693591cbc0eac (diff) | |
download | scintilla-mirror-4b991bfffc9f20740e7911f4141cbbadde03140d.tar.gz |
Made drag image work similar to the Carbon port.
-rw-r--r-- | cocoa/ScintillaCocoa.mm | 91 |
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; } |