зеркало из https://github.com/mozilla/pjs.git
r=pedemont, sr=blizzard (platform specific), a=mkaply Code from Rich Walsh - OS/2 drag drop improvements
This commit is contained in:
Родитель
897e2580c9
Коммит
7bc00c3b09
|
@ -82,6 +82,6 @@ LOCAL_INCLUDES = -I. -I$(srcdir)/../xpwidgets -I$(srcdir)
|
|||
|
||||
export::
|
||||
test -d ./res || mkdir ./res
|
||||
test -f ./res/aliasb.ptr || cp $(srcdir)/res/*.ptr ./res
|
||||
test -f ./res/aliasb.ptr || cp $(srcdir)/res/*.* ./res
|
||||
|
||||
ADD_TO_DEF_FILE = cat < $(srcdir)/extradefs.os2 >>$(DEF_FILE)
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
#include "nsIURL.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsOS2Uni.h"
|
||||
#include "nsdefs.h"
|
||||
#include "resource.h"
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// helper functions
|
||||
|
@ -64,6 +66,11 @@ int UnicodeToCodepage( const nsAString& inString, char **outText);
|
|||
#define DC_PREPAREITEM 0x0040;
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Global data
|
||||
|
||||
static HPOINTER gPtrArray[IDC_DNDCOUNT];
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
nsDragService::nsDragService()
|
||||
|
@ -72,6 +79,11 @@ nsDragService::nsDragService()
|
|||
mDragWnd = WinCreateWindow( HWND_DESKTOP, WC_STATIC, 0, 0, 0, 0, 0, 0,
|
||||
HWND_DESKTOP, HWND_BOTTOM, 0, 0, 0);
|
||||
WinSubclassWindow( mDragWnd, nsDragWindowProc);
|
||||
|
||||
HMODULE hModResources = NULLHANDLE;
|
||||
DosQueryModFromEIP(&hModResources, NULL, 0, NULL, NULL, (ULONG) &gPtrArray);
|
||||
for (int i = 0; i < IDC_DNDCOUNT; i++)
|
||||
gPtrArray[i] = ::WinLoadPointer(HWND_DESKTOP, hModResources, i+IDC_DNDBASE);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
@ -181,6 +193,11 @@ nsDragService::~nsDragService()
|
|||
{
|
||||
/* destructor code */
|
||||
WinDestroyWindow(mDragWnd);
|
||||
|
||||
for (int i = 0; i < IDC_DNDCOUNT; i++) {
|
||||
WinDestroyPointer(gPtrArray[i]);
|
||||
gPtrArray[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
@ -223,6 +240,7 @@ NS_IMETHODIMP nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, nsISupports
|
|||
dragitem.hstrSourceName = NULLHANDLE;
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
ULONG idIcon = 0;
|
||||
|
||||
// reduce our footprint by ensuring any intermediate objects
|
||||
// go out of scope before the drag begins
|
||||
|
@ -249,6 +267,7 @@ NS_IMETHODIMP nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, nsISupports
|
|||
dragitem.hstrRMF = DrgAddStrHandle("<DRM_OS2FILE,DRF_UNKNOWN>");
|
||||
dragitem.hstrTargetName = DrgAddStrHandle(targetName);
|
||||
nsMemory::Free(targetName);
|
||||
idIcon = IDC_DNDURL;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -260,6 +279,7 @@ NS_IMETHODIMP nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, nsISupports
|
|||
dragitem.hstrRMF = DrgAddStrHandle("<DRM_OS2FILE,DRF_TEXT>");
|
||||
dragitem.hstrTargetName = DrgAddStrHandle(targetName);
|
||||
nsMemory::Free(targetName);
|
||||
idIcon = IDC_DNDTEXT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -277,8 +297,15 @@ NS_IMETHODIMP nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, nsISupports
|
|||
DRAGIMAGE dragimage;
|
||||
memset(&dragimage, 0, sizeof(DRAGIMAGE));
|
||||
dragimage.cb = sizeof(DRAGIMAGE);
|
||||
dragimage.hImage = WinQuerySysPointer(HWND_DESKTOP, SPTR_FILE, FALSE);
|
||||
dragimage.fl = DRG_ICON;
|
||||
if (idIcon)
|
||||
dragimage.hImage = gPtrArray[idIcon-IDC_DNDBASE];
|
||||
if (dragimage.hImage) {
|
||||
dragimage.cyOffset = 8;
|
||||
dragimage.cxOffset = 2;
|
||||
}
|
||||
else
|
||||
dragimage.hImage = WinQuerySysPointer(HWND_DESKTOP, SPTR_FILE, FALSE);
|
||||
|
||||
mDoingDrag = PR_TRUE;
|
||||
HWND hwndDest = DrgDrag(mDragWnd, pDragInfo, &dragimage, 1, VK_BUTTON2,
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "nsdefs.h"
|
||||
#include "resource.h"
|
||||
|
||||
#ifdef DEBUG_sobotka
|
||||
|
@ -123,7 +124,10 @@ PRBool gIsDestroyingAny = PR_FALSE;
|
|||
static POINTL gLastMousePoint;
|
||||
static LONG gLastMsgTime = 0;
|
||||
static LONG gLastClickCount = 0;
|
||||
static LONG gLastButtonDown = 0;
|
||||
static POINTS gLastButton1Down = {0,0};
|
||||
|
||||
#define XFROMMP(m) (SHORT(LOUSHORT(m)))
|
||||
#define YFROMMP(m) (SHORT(HIUSHORT(m)))
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
static PRBool gGlobalsInitialized = PR_FALSE;
|
||||
|
@ -131,16 +135,6 @@ static HPOINTER gPtrArray[IDC_COUNT];
|
|||
static PRBool gIsTrackPoint = PR_FALSE;
|
||||
static PRBool gIsDBCS = PR_FALSE;
|
||||
|
||||
/* Older versions of the toolkit, as well as GCC do not have this - from bsedos.h */
|
||||
extern "C" {
|
||||
APIRET APIENTRY DosQueryModFromEIP(HMODULE *phMod,
|
||||
ULONG *pObjNum,
|
||||
ULONG BuffLen,
|
||||
PCHAR pBuff,
|
||||
ULONG *pOffset,
|
||||
ULONG Address);
|
||||
}
|
||||
|
||||
// The last user input event time in milliseconds. If there are any pending
|
||||
// native toolkit input events it returns the current time. The value is
|
||||
// compatible with PR_IntervalToMicroseconds(PR_IntervalNow()).
|
||||
|
@ -1975,7 +1969,7 @@ void nsWindow::FreeNativeData(void * data, PRUint32 aDataType)
|
|||
{
|
||||
case NS_NATIVE_GRAPHIC:
|
||||
if (data) {
|
||||
if (ReleaseDragHPS((HPS)data))
|
||||
if (!ReleaseIfDragHPS((HPS)data))
|
||||
WinReleasePS((HPS)data);
|
||||
}
|
||||
break;
|
||||
|
@ -2034,7 +2028,7 @@ NS_METHOD nsWindow::Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect)
|
|||
Update();
|
||||
|
||||
if (hps)
|
||||
ReleaseDragHPS(hps);
|
||||
ReleaseIfDragHPS(hps);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2053,7 +2047,7 @@ NS_IMETHODIMP nsWindow::ScrollWidgets(PRInt32 aDx, PRInt32 aDy)
|
|||
Update(); // Force synchronous generation of NS_PAINT
|
||||
|
||||
if (hps)
|
||||
ReleaseDragHPS(hps);
|
||||
ReleaseIfDragHPS(hps);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2080,7 +2074,7 @@ NS_IMETHODIMP nsWindow::ScrollRect(nsRect &aRect, PRInt32 aDx, PRInt32 aDy)
|
|||
Update(); // Force synchronous generation of NS_PAINT
|
||||
|
||||
if (hps)
|
||||
ReleaseDragHPS(hps);
|
||||
ReleaseIfDragHPS(hps);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2478,13 +2472,14 @@ PRBool nsWindow::ProcessMessage( ULONG msg, MPARAM mp1, MPARAM mp2, MRESULT &rc)
|
|||
if (!mIsScrollBar)
|
||||
WinSetCapture( HWND_DESKTOP, mWnd);
|
||||
result = DispatchMouseEvent( NS_MOUSE_LEFT_BUTTON_DOWN, mp1, mp2);
|
||||
gLastButtonDown = 1;
|
||||
// there's no need to clear this on button-up
|
||||
gLastButton1Down.x = XFROMMP(mp1);
|
||||
gLastButton1Down.y = YFROMMP(mp1);
|
||||
break;
|
||||
case WM_BUTTON1UP:
|
||||
if (!mIsScrollBar)
|
||||
WinSetCapture( HWND_DESKTOP, 0); // release
|
||||
result = DispatchMouseEvent( NS_MOUSE_LEFT_BUTTON_UP, mp1, mp2);
|
||||
gLastButtonDown = 0;
|
||||
break;
|
||||
case WM_BUTTON1DBLCLK:
|
||||
result = DispatchMouseEvent( NS_MOUSE_LEFT_DOUBLECLICK, mp1, mp2);
|
||||
|
@ -2494,13 +2489,11 @@ PRBool nsWindow::ProcessMessage( ULONG msg, MPARAM mp1, MPARAM mp2, MRESULT &rc)
|
|||
if (!mIsScrollBar)
|
||||
WinSetCapture( HWND_DESKTOP, mWnd);
|
||||
result = DispatchMouseEvent( NS_MOUSE_RIGHT_BUTTON_DOWN, mp1, mp2);
|
||||
gLastButtonDown = 2;
|
||||
break;
|
||||
case WM_BUTTON2UP:
|
||||
if (!mIsScrollBar)
|
||||
WinSetCapture( HWND_DESKTOP, 0); // release
|
||||
result = DispatchMouseEvent( NS_MOUSE_RIGHT_BUTTON_UP, mp1, mp2);
|
||||
gLastButtonDown = 0;
|
||||
break;
|
||||
case WM_BUTTON2DBLCLK:
|
||||
result = DispatchMouseEvent( NS_MOUSE_RIGHT_DOUBLECLICK, mp1, mp2);
|
||||
|
@ -2518,34 +2511,40 @@ PRBool nsWindow::ProcessMessage( ULONG msg, MPARAM mp1, MPARAM mp2, MRESULT &rc)
|
|||
}
|
||||
break;
|
||||
|
||||
// if MB1 & MB2 are both pressed, perform a copy or paste;
|
||||
// see how far the mouse has moved since MB1-down to determine
|
||||
// the operation (this really ought to look for selected content)
|
||||
case WM_CHORD:
|
||||
{
|
||||
if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) &
|
||||
WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) &
|
||||
0x8000) {
|
||||
PRBool isCopy = FALSE;
|
||||
if (abs(XFROMMP(mp1) - gLastButton1Down.x) >
|
||||
(WinQuerySysValue(HWND_DESKTOP, SV_CXMOTIONSTART) / 2) ||
|
||||
abs(YFROMMP(mp1) - gLastButton1Down.y) >
|
||||
(WinQuerySysValue(HWND_DESKTOP, SV_CYMOTIONSTART) / 2))
|
||||
isCopy = TRUE;
|
||||
|
||||
nsKeyEvent event;
|
||||
nsPoint point(0,0);
|
||||
InitEvent( event, NS_KEY_PRESS, &point);
|
||||
|
||||
if (gLastButtonDown == 2) {
|
||||
InitEvent( event, NS_KEY_PRESS, &point);
|
||||
event.keyCode = NS_VK_INSERT;
|
||||
event.keyCode = NS_VK_INSERT;
|
||||
if (isCopy) {
|
||||
event.isShift = PR_FALSE;
|
||||
event.isControl = PR_TRUE;
|
||||
event.isAlt = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.eventStructType = NS_KEY_EVENT;
|
||||
event.charCode = 0;
|
||||
result = DispatchWindowEvent( &event);
|
||||
} else if (gLastButtonDown == 1) {
|
||||
InitEvent( event, NS_KEY_PRESS, &point);
|
||||
event.keyCode = NS_VK_INSERT;
|
||||
} else {
|
||||
event.isShift = PR_TRUE;
|
||||
event.isControl = PR_FALSE;
|
||||
event.isAlt = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.eventStructType = NS_KEY_EVENT;
|
||||
event.charCode = 0;
|
||||
result = DispatchWindowEvent( &event);
|
||||
}
|
||||
event.isAlt = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.eventStructType = NS_KEY_EVENT;
|
||||
event.charCode = 0;
|
||||
result = DispatchWindowEvent( &event);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_BUTTON3DOWN:
|
||||
result = DispatchMouseEvent( NS_MOUSE_MIDDLE_BUTTON_DOWN, mp1, mp2);
|
||||
break;
|
||||
|
@ -2669,22 +2668,24 @@ PRBool nsWindow::ProcessMessage( ULONG msg, MPARAM mp1, MPARAM mp2, MRESULT &rc)
|
|||
break;
|
||||
|
||||
case DM_DRAGOVER:
|
||||
result = OnDragOver(mp1, mp2, rc);
|
||||
OnDragOver(mp1, mp2, rc);
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case DM_DRAGLEAVE:
|
||||
result = OnDragLeave(mp1, mp2);
|
||||
OnDragLeave(mp1, mp2);
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case DM_DROP:
|
||||
result = OnDrop( mp1, mp2);
|
||||
OnDrop( mp1, mp2);
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
// Need to handle this method in order to keep track of whether there
|
||||
// is a drag inside the window; we need to do *this* so that we can
|
||||
// generate DRAGENTER messages [which os/2 doesn't provide].
|
||||
// this cancels a drag - after we do our cleanup
|
||||
// pass this to the default wndproc to do its cleanup
|
||||
case DM_DROPHELP:
|
||||
mNativeDrag = FALSE;
|
||||
OnDragLeave(mp1, mp2);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2919,7 +2920,7 @@ PRBool nsWindow::OnPaint()
|
|||
|
||||
WinEndPaint(hPS);
|
||||
if (hpsDrag)
|
||||
ReleaseDragHPS(hpsDrag);
|
||||
ReleaseIfDragHPS(hpsDrag);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
@ -3764,16 +3765,16 @@ PRUint32 nsWindow::GetDragStatus(PRUint32 aState, HPS * oHps)
|
|||
// if there's an outstanding drag hps & it matches the one
|
||||
// passed in, release it
|
||||
|
||||
HPS nsWindow::ReleaseDragHPS(HPS aHps)
|
||||
PRBool nsWindow::ReleaseIfDragHPS(HPS aHps)
|
||||
{
|
||||
|
||||
if (mDragHps && aHps == mDragHps) {
|
||||
DrgReleasePS(mDragHps);
|
||||
mDragHps = 0;
|
||||
aHps = 0;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return aHps;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
|
|
@ -301,7 +301,7 @@ protected:
|
|||
void ConstrainZLevel(HWND *aAfter);
|
||||
|
||||
PRUint32 GetDragStatus(PRUint32 aState, HPS * oHps);
|
||||
HPS ReleaseDragHPS(HPS hps);
|
||||
PRBool ReleaseIfDragHPS(HPS hps);
|
||||
|
||||
// Enumeration of the methods which are accessable on the PM thread
|
||||
enum {
|
||||
|
|
|
@ -63,12 +63,16 @@
|
|||
|
||||
|
||||
extern "C" {
|
||||
PVOID APIENTRY WinQueryProperty(HWND hwnd, PCSZ pszNameOrAtom);
|
||||
PVOID APIENTRY WinQueryProperty(HWND hwnd, PCSZ pszNameOrAtom);
|
||||
|
||||
PVOID APIENTRY WinRemoveProperty(HWND hwnd, PCSZ pszNameOrAtom);
|
||||
PVOID APIENTRY WinRemoveProperty(HWND hwnd, PCSZ pszNameOrAtom);
|
||||
|
||||
BOOL APIENTRY WinSetProperty(HWND hwnd, PCSZ pszNameOrAtom,
|
||||
PVOID pvData, ULONG ulFlags);
|
||||
BOOL APIENTRY WinSetProperty(HWND hwnd, PCSZ pszNameOrAtom,
|
||||
PVOID pvData, ULONG ulFlags);
|
||||
|
||||
APIRET APIENTRY DosQueryModFromEIP(HMODULE *phMod, ULONG *pObjNum,
|
||||
ULONG BuffLen, PCHAR pBuff,
|
||||
ULONG *pOffset, ULONG Address);
|
||||
}
|
||||
|
||||
#endif // NSDEFS_H
|
||||
|
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -46,3 +46,10 @@
|
|||
|
||||
#define IDC_COUNT IDC_HELP-IDC_BASE+1
|
||||
|
||||
/* drag & drop icons */
|
||||
#define IDC_DNDBASE 4150
|
||||
#define IDC_DNDURL 4150
|
||||
#define IDC_DNDTEXT 4151
|
||||
|
||||
#define IDC_DNDCOUNT IDC_DNDTEXT-IDC_DNDBASE+1
|
||||
|
||||
|
|
|
@ -43,3 +43,6 @@ POINTER IDC_ARROWWAIT res\arrow_wait.ptr
|
|||
POINTER IDC_CROSS res\crosshair.ptr
|
||||
POINTER IDC_HELP res\help.ptr
|
||||
|
||||
ICON IDC_DNDURL res\dndurl.ico
|
||||
ICON IDC_DNDTEXT res\dndtext.ico
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче