summaryrefslogtreecommitdiffstats
path: root/maccaml/drag.c
diff options
context:
space:
mode:
Diffstat (limited to 'maccaml/drag.c')
-rw-r--r--maccaml/drag.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/maccaml/drag.c b/maccaml/drag.c
new file mode 100644
index 000000000..7d7b4630c
--- /dev/null
+++ b/maccaml/drag.c
@@ -0,0 +1,239 @@
+/***********************************************************************/
+/* */
+/* Objective Caml */
+/* */
+/* Damien Doligez, projet Para, INRIA Rocquencourt */
+/* */
+/* Copyright 1997 Institut National de Recherche en Informatique et */
+/* en Automatique. Distributed only by permission. */
+/* */
+/***********************************************************************/
+
+/* $Id$ */
+
+#include "main.h"
+
+static DragTrackingHandlerUPP MyTrackingHandlerUPP = NULL;
+static DragReceiveHandlerUPP MyReceiveHandlerUPP = NULL;
+
+static OSErr ToplevelTrackDrag (DragTrackingMessage message, DragReference drag)
+{
+ static int canacceptdrag = 0;
+ static int hilited = 0;
+ WEReference we = WinGetWE (winToplevel);
+ short readonly;
+ Point mouse;
+ RgnHandle rgn = NewRgn ();
+ Rect viewrect;
+ LongRect lviewrect;
+ OSErr err;
+ DragAttributes attributes;
+
+ Assert (we != NULL);
+ switch (message){
+
+ case kDragTrackingEnterWindow:
+ readonly = WEFeatureFlag (weFReadOnly, weBitTest, we);
+ WEFeatureFlag (weFReadOnly, weBitClear, we);
+ canacceptdrag = WECanAcceptDrag (drag, we);
+ if (readonly) WEFeatureFlag (weFReadOnly, weBitSet, we);
+ break;
+
+ case kDragTrackingInWindow:
+ if (canacceptdrag){
+ err = GetDragAttributes (drag, &attributes);
+ if (err != noErr) goto failed;
+ err = GetDragMouse (drag, &mouse, nil);
+ if (err != noErr) goto failed;
+ GlobalToLocal (&mouse);
+ WEGetViewRect (&lviewrect, we);
+ WELongRectToRect (&lviewrect, &viewrect);
+ InsetRect (&viewrect, -kTextMarginH, 0);
+ if (PtInRect (mouse, &viewrect)){
+ if (!hilited && (attributes & kDragHasLeftSenderWindow)){
+ RectRgn (rgn, &viewrect);
+ InsetRgn (rgn, 0, -kTextMarginV);
+ ShowDragHilite (drag, rgn, true);
+ DisposeRgn (rgn);
+ hilited = 1;
+ }
+ }else{
+ if (hilited){
+ HideDragHilite (drag);
+ hilited = 0;
+ }
+ }
+ }
+ break;
+
+ case kDragTrackingLeaveWindow:
+ if (hilited){
+ HideDragHilite (drag);
+ hilited = 0;
+ }
+ break;
+
+ default: break;
+ }
+ return noErr;
+
+ failed: return err;
+}
+
+static pascal OSErr MyTrackingHandler (DragTrackingMessage message, WindowPtr w,
+ void *refCon, DragReference drag)
+{
+ #pragma unused (refCon)
+ WEReference we;
+
+ switch (WinGetKind (w)){
+ case kWinUnknown:
+ case kWinUninitialised:
+ case kWinAbout:
+ case kWinGraphics:
+ case kWinPrefs:
+ case kWinClipboard:
+ return noErr;
+
+ case kWinToplevel:
+ return ToplevelTrackDrag (message, drag);
+
+ case kWinDocument:
+ we = WinGetWE (w); Assert (we != NULL);
+ return WETrackDrag (message, drag, we);
+
+ default:
+ Assert (0);
+ return noErr;
+ }
+}
+
+static OSErr ToplevelReceiveDrag (DragReference drag, WEReference we)
+{
+ GrafPtr (saveport);
+ short readonly = 0;
+ Boolean canaccept;
+ OSErr err;
+ Point mouse;
+ LongRect lviewrect;
+ Rect viewrect;
+ UInt16 nitems;
+ UInt16 i;
+ ItemReference itemref;
+ Handle h = NULL;
+ Size sz, curlen;
+ long dest, selstart, selend = -1;
+
+ GetPort (&saveport);
+ SetPortWindowPort (winToplevel);
+
+ readonly = WEFeatureFlag (weFReadOnly, weBitTest, we);
+ if (readonly) WEFeatureFlag (weFReadOnly, weBitClear, we);
+ canaccept = WECanAcceptDrag (drag, we);
+ if (!canaccept){ err = badDragFlavorErr; goto failed; }
+
+ err = GetDragMouse (drag, &mouse, nil);
+ if (err != noErr) goto failed;
+ GlobalToLocal (&mouse);
+ WEGetViewRect (&lviewrect, we);
+ WELongRectToRect (&lviewrect, &viewrect);
+ if (!PtInRect (mouse, &viewrect)){ err = dragNotAcceptedErr; goto failed; }
+
+ /* XXX Ne pas coller si le drag vient de la mme fentre et la souris
+ est revenue dans la slection. */
+
+ h = NewHandle (0);
+ err = MemError (); if (err != noErr) goto failed;
+ curlen = 0;
+
+ err = CountDragItems (drag, &nitems);
+ if (err != noErr) goto failed;
+
+ for (i = 1; i <= nitems; i++){
+ err = GetDragItemReferenceNumber (drag, i, &itemref);
+ if (err != noErr) goto failed;
+ err = GetFlavorDataSize (drag, itemref, kTypeText, &sz);
+ if (err != noErr) goto failed;
+ SetHandleSize (h, curlen + sz);
+ err = MemError (); if (err != noErr) goto failed;
+ HLock (h);
+ err = GetFlavorData (drag, itemref, kTypeText, (*h)+curlen, &sz, 0);
+ HUnlock (h);
+ if (err != noErr) goto failed;
+ curlen += sz;
+ }
+ dest = WEGetTextLength (we);
+ WEGetSelection (&selstart, &selend, we);
+ WESetSelection (dest, dest, we);
+ WESetStyle (weDoFont + weDoFace + weDoSize + weDoColor + weDoReplaceFace,
+ &prefs.unread, we);
+ HLock (h);
+ err = WEInsert (*h, curlen, NULL, NULL, we);
+ HUnlock (h);
+ if (err != noErr) goto failed;
+ WESetSelection (dest + curlen, dest + curlen, we);
+
+ DisposeHandle (h);
+ SetPort (saveport);
+ return noErr;
+
+ failed:
+ if (h != NULL) DisposeHandle (h);
+ if (selend != -1) WESetSelection (selstart, selend, we);
+ if (readonly) WEFeatureFlag (weFReadOnly, weBitSet, we);
+ SetPort (saveport);
+ return err;
+}
+
+static pascal OSErr MyReceiveHandler (WindowPtr w, void *refCon,
+ DragReference drag)
+{
+ #pragma unused (refCon)
+ WEReference we;
+
+ switch (WinGetKind (w)){
+ case kWinUnknown:
+ case kWinUninitialised:
+ case kWinAbout:
+ case kWinGraphics:
+ case kWinPrefs:
+ case kWinClipboard:
+ return noErr;
+ case kWinToplevel:
+ we = WinGetWE (w); Assert (we != NULL);
+ return ToplevelReceiveDrag (drag, we);
+ case kWinDocument:
+ we = WinGetWE (w); Assert (we != NULL);
+ return WEReceiveDrag (drag, we);
+ default:
+ Assert (0);
+ return noErr;
+ }
+}
+
+OSErr InstallDragHandlers (void)
+{
+ OSErr err;
+
+ MyTrackingHandlerUPP = NewDragTrackingHandlerProc (MyTrackingHandler);
+ MyReceiveHandlerUPP = NewDragReceiveHandlerProc (MyReceiveHandler);
+
+ err = InstallTrackingHandler (MyTrackingHandlerUPP, NULL, NULL);
+ if (err != noErr) return err;
+ err = InstallReceiveHandler (MyReceiveHandlerUPP, NULL, NULL);
+ if (err != noErr){
+ RemoveTrackingHandler (MyTrackingHandlerUPP, NULL);
+ return err;
+ }
+ return noErr;
+}
+
+OSErr RemoveDragHandlers (void)
+{
+ OSErr err1, err2;
+
+ err1 = RemoveTrackingHandler (MyTrackingHandlerUPP, NULL);
+ err2 = RemoveReceiveHandler (MyReceiveHandlerUPP, NULL);
+ if (err2 != noErr && err1 == noErr) return err2;
+ return err1;
+}