/** * SetToTransformFunction is essentially a giant switch statement that fans * out to many smaller helper functions. */ void nsStyleTransformMatrix::SetToTransformFunction(const nsCSSValue::Array * aData, nsStyleContext* aContext, nsPresContext* aPresContext, PRBool& aCanStoreInRuleTree) { NS_PRECONDITION(aData, "Why did you want to get data from a null array?"); NS_PRECONDITION(aContext, "Need a context for unit conversion!"); NS_PRECONDITION(aPresContext, "Need a context for unit conversion!"); /* Reset the matrix to the identity so that each subfunction can just * worry about its own components. */ SetToIdentity(); /* Get the keyword for the transform. */ nsAutoString keyword; aData->Item(0).GetStringValue(keyword); switch (nsCSSKeywords::LookupKeyword(keyword)) { case eCSSKeyword_translatex: ProcessTranslateX(mDelta, mX, aData, aContext, aPresContext, aCanStoreInRuleTree); break; case eCSSKeyword_translatey: ProcessTranslateY(mDelta, mY, aData, aContext, aPresContext, aCanStoreInRuleTree); break; case eCSSKeyword_translate: ProcessTranslate(mDelta, mX, mY, aData, aContext, aPresContext, aCanStoreInRuleTree); break; case eCSSKeyword_scalex: ProcessScaleX(mMain, aData); break; case eCSSKeyword_scaley: ProcessScaleY(mMain, aData); break; case eCSSKeyword_scale: ProcessScale(mMain, aData); break; case eCSSKeyword_skewx: ProcessSkewX(mMain, aData); break; case eCSSKeyword_skewy: ProcessSkewY(mMain, aData); break; case eCSSKeyword_skew: ProcessSkew(mMain, aData); break; case eCSSKeyword_rotate: ProcessRotate(mMain, aData); break; case eCSSKeyword_matrix: ProcessMatrix(mMain, mDelta, mX, mY, aData, aContext, aPresContext, aCanStoreInRuleTree); break; default: NS_NOTREACHED("Unknown transform function!"); } }
// Main function of this class decodes gesture information // in: // hWnd window handle // wParam message parameter (message-specific) // lParam message parameter (message-specific) bool CGestures::ProcessGestureMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult) { if ((uMsg != WM_GESTURENOTIFY) && (uMsg != WM_GESTURE)) return false; if (!_isGestures) { _ASSERTE(_isGestures); gpConEmu->LogString(L"Gesture message received but not allowed, skipping"); return false; } if (uMsg == WM_GESTURENOTIFY) { // This is the right place to define the list of gestures that this // application will support. By populating GESTURECONFIG structure // and calling SetGestureConfig function. We can choose gestures // that we want to handle in our application. In this app we // decide to handle all gestures. GESTURECONFIG gc[] = { {GID_ZOOM, GC_ZOOM}, {GID_ROTATE, GC_ROTATE}, {GID_PAN, GC_PAN|GC_PAN_WITH_GUTTER|GC_PAN_WITH_INERTIA, GC_PAN_WITH_SINGLE_FINGER_VERTICALLY|GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY }, {GID_PRESSANDTAP, GC_PRESSANDTAP}, {GID_TWOFINGERTAP, GC_TWOFINGERTAP}, }; BOOL bResult = _SetGestureConfig(hWnd, 0, countof(gc), gc, sizeof(GESTURECONFIG)); DWORD dwErr = GetLastError(); if (gpSetCls->isAdvLogging) { wchar_t szNotify[60]; _wsprintf(szNotify, SKIPLEN(countof(szNotify)) L"SetGestureConfig -> %u,%u", bResult, dwErr); gpConEmu->LogString(szNotify); } if (!bResult) { DisplayLastError(L"Error in execution of SetGestureConfig", dwErr); } lResult = ::DefWindowProc(hWnd, WM_GESTURENOTIFY, wParam, lParam); return true; } // Остался только WM_GESTURE Assert(uMsg==WM_GESTURE); // helper variables POINT ptZoomCenter; double k; GESTUREINFO gi = {sizeof(gi)}; // Checking for compiler alignment errors if (gi.cbSize != WIN3264TEST(48,56)) { // Struct member alignment must be 8bytes even on x86 Assert(sizeof(GESTUREINFO)==WIN3264TEST(48,56)); _isGestures = false; return false; } BOOL bResult = _GetGestureInfo((HGESTUREINFO)lParam, &gi); if (!bResult) { //_ASSERT(L"_GetGestureInfo failed!" && 0); DWORD dwErr = GetLastError(); DisplayLastError(L"Error in execution of _GetGestureInfo", dwErr); return FALSE; } #ifdef USE_DUMPGEST bool bLog = (gpSetCls->isAdvLogging >= 2); UNREFERENCED_PARAMETER(bLog); bLog = true; #endif #define DUMPGEST(tp) DumpGesture(tp, gi) //#ifdef USE_DUMPGEST // wchar_t szDump[256]; // #define DUMPGEST(tp) // _wsprintf(szDump, SKIPLEN(countof(szDump)) // L"Gesture(x%08X {%i,%i} %s", // (DWORD)gi.hwndTarget, gi.ptsLocation.x, gi.ptsLocation.y, // tp); // if (gi.dwID==GID_PRESSANDTAP) { // DWORD h = LODWORD(gi.ullArguments); _wsprintf(szDump+_tcslen(szDump), SKIPLEN(32) // L" Dist={%i,%i}", (int)(short)LOWORD(h), (int)(short)HIWORD(h)); } // if (gi.dwID==GID_ROTATE) { // DWORD h = LODWORD(gi.ullArguments); _wsprintf(szDump+_tcslen(szDump), SKIPLEN(32) // L" %i", (int)LOWORD(h)); } // if (gi.dwFlags&GF_BEGIN) wcscat_c(szDump, L" GF_BEGIN"); // if (gi.dwFlags&GF_END) wcscat_c(szDump, L" GF_END"); // if (gi.dwFlags&GF_INERTIA) { wcscat_c(szDump, L" GF_INERTIA"); // DWORD h = HIDWORD(gi.ullArguments); _wsprintf(szDump+_tcslen(szDump), SKIPLEN(32) // L" {%i,%i}", (int)(short)LOWORD(h), (int)(short)HIWORD(h)); } // wcscat_c(szDump, L")\n"); // DEBUGSTR(szDump) //#else //#define DUMPGEST(s) //#endif switch (gi.dwID) { case GID_BEGIN: DUMPGEST(L"GID_BEGIN"); break; case GID_END: DUMPGEST(L"GID_END"); break; case GID_ZOOM: DUMPGEST(L"GID_ZOOM"); if (gi.dwFlags & GF_BEGIN) { _dwArguments = LODWORD(gi.ullArguments); _ptFirst.x = gi.ptsLocation.x; _ptFirst.y = gi.ptsLocation.y; ScreenToClient(hWnd,&_ptFirst); } else { // We read here the second point of the gesture. This is middle point between // fingers in this new position. _ptSecond.x = gi.ptsLocation.x; _ptSecond.y = gi.ptsLocation.y; ScreenToClient(hWnd,&_ptSecond); // We have to calculate zoom center point ptZoomCenter.x = (_ptFirst.x + _ptSecond.x)/2; ptZoomCenter.y = (_ptFirst.y + _ptSecond.y)/2; // The zoom factor is the ratio between the new and the old distance. // The new distance between two fingers is stored in gi.ullArguments // (lower DWORD) and the old distance is stored in _dwArguments. k = (double)(LODWORD(gi.ullArguments))/(double)(_dwArguments); // Now we process zooming in/out of the object ProcessZoom(hWnd, k, ptZoomCenter.x, ptZoomCenter.y); // Now we have to store new information as a starting information // for the next step in this gesture. _ptFirst = _ptSecond; _dwArguments = LODWORD(gi.ullArguments); } break; case GID_PAN: DUMPGEST(L"GID_PAN"); if (gi.dwFlags & GF_BEGIN) { _ptFirst.x = gi.ptsLocation.x; _ptFirst.y = gi.ptsLocation.y; _ptBegin.x = gi.ptsLocation.x; _ptBegin.y = gi.ptsLocation.y; ScreenToClient(hWnd, &_ptFirst); } else { // We read the second point of this gesture. It is a middle point // between fingers in this new position _ptSecond.x = gi.ptsLocation.x; _ptSecond.y = gi.ptsLocation.y; ScreenToClient(hWnd, &_ptSecond); if (!(gi.dwFlags & (GF_END/*|GF_INERTIA*/))) { // We apply move operation of the object if (ProcessMove(hWnd, _ptSecond.x-_ptFirst.x, _ptSecond.y-_ptFirst.y)) { // We have to copy second point into first one to prepare // for the next step of this gesture. _ptFirst = _ptSecond; } } } break; case GID_ROTATE: DUMPGEST(L"GID_ROTATE"); if (gi.dwFlags & GF_BEGIN) { _inRotate = false; _dwArguments = LODWORD(gi.ullArguments); // Запомним начальный угол } else { _ptFirst.x = gi.ptsLocation.x; _ptFirst.y = gi.ptsLocation.y; ScreenToClient(hWnd, &_ptFirst); // Пока угол не станет достаточным для смены таба - игнорируем if (ProcessRotate(hWnd, LODWORD(gi.ullArguments) - _dwArguments, _ptFirst.x,_ptFirst.y, ((gi.dwFlags & GF_END) == GF_END))) { _dwArguments = LODWORD(gi.ullArguments); } } break; case GID_TWOFINGERTAP: DUMPGEST(L"GID_TWOFINGERTAP"); _ptFirst.x = gi.ptsLocation.x; _ptFirst.y = gi.ptsLocation.y; ScreenToClient(hWnd,&_ptFirst); ProcessTwoFingerTap(hWnd, _ptFirst.x, _ptFirst.y, LODWORD(gi.ullArguments)); break; case GID_PRESSANDTAP: DUMPGEST(L"GID_PRESSANDTAP"); if (gi.dwFlags & GF_BEGIN) { _ptFirst.x = gi.ptsLocation.x; _ptFirst.y = gi.ptsLocation.y; ScreenToClient(hWnd,&_ptFirst); DWORD nDelta = LODWORD(gi.ullArguments); short nDeltaX = (short)LOWORD(nDelta); short nDeltaY = (short)HIWORD(nDelta); ProcessPressAndTap(hWnd, _ptFirst.x, _ptFirst.y, nDeltaX, nDeltaY); } break; default: DUMPGEST(L"GID_<UNKNOWN>"); } _CloseGestureInfoHandle((HGESTUREINFO)lParam); return TRUE; }