| 85 | } |
| 86 | |
| 87 | LRESULT TGFXWindow::handleMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) noexcept { |
| 88 | switch (message) { |
| 89 | case WM_ACTIVATE: |
| 90 | isDrawing = (LOWORD(wparam) != WA_INACTIVE); |
| 91 | break; |
| 92 | case WM_DESTROY: |
| 93 | destroy(); |
| 94 | PostQuitMessage(0); |
| 95 | break; |
| 96 | case WM_PAINT: { |
| 97 | if (isDrawing) { |
| 98 | draw(); |
| 99 | } |
| 100 | break; |
| 101 | } |
| 102 | case WM_LBUTTONDOWN: { |
| 103 | currentDrawerIndex++; |
| 104 | zoomScale = 1.0f; |
| 105 | contentOffset = {0.0f, 0.0f}; |
| 106 | ::InvalidateRect(windowHandle, nullptr, TRUE); |
| 107 | break; |
| 108 | } |
| 109 | case WM_MOUSEWHEEL: { |
| 110 | POINT mousePoint = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)}; |
| 111 | ScreenToClient(hwnd, &mousePoint); |
| 112 | bool isCtrlPressed = (GetKeyState(VK_CONTROL) & 0x8000) != 0; |
| 113 | bool isShiftPressed = (GetKeyState(VK_SHIFT) & 0x8000) != 0; |
| 114 | if (isCtrlPressed) { |
| 115 | float zoomStep = std::exp(GET_WHEEL_DELTA_WPARAM(wparam) / WHEEL_RATIO); |
| 116 | float newZoom = std::clamp(zoomScale * zoomStep, MIN_ZOOM, MAX_ZOOM); |
| 117 | contentOffset.x = mousePoint.x - ((mousePoint.x - contentOffset.x) / zoomScale) * newZoom; |
| 118 | contentOffset.y = mousePoint.y - ((mousePoint.y - contentOffset.y) / zoomScale) * newZoom; |
| 119 | zoomScale = newZoom; |
| 120 | } else { |
| 121 | float wheelDelta = static_cast<float>(GET_WHEEL_DELTA_WPARAM(wparam)); |
| 122 | if (isShiftPressed) { |
| 123 | contentOffset.x += wheelDelta; |
| 124 | } else { |
| 125 | contentOffset.y -= wheelDelta; |
| 126 | } |
| 127 | } |
| 128 | ::InvalidateRect(windowHandle, nullptr, TRUE); |
| 129 | break; |
| 130 | } |
| 131 | case WM_GESTURE: { |
| 132 | GESTUREINFO gestureInfo{}; |
| 133 | gestureInfo.cbSize = sizeof(GESTUREINFO); |
| 134 | if (GetGestureInfo(reinterpret_cast<HGESTUREINFO>(lparam), &gestureInfo)) { |
| 135 | if (gestureInfo.dwID == GID_ZOOM) { |
| 136 | double currentArgument = gestureInfo.ullArguments; |
| 137 | if (lastZoomArgument != 0.0) { |
| 138 | double zoomFactor = currentArgument / lastZoomArgument; |
| 139 | POINT mousePoint = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)}; |
| 140 | ScreenToClient(hwnd, &mousePoint); |
| 141 | float newZoom = |
| 142 | std::clamp(zoomScale * static_cast<float>(zoomFactor), MIN_ZOOM, MAX_ZOOM); |
| 143 | contentOffset.x = |
| 144 | mousePoint.x - ((mousePoint.x - contentOffset.x) / zoomScale) * newZoom; |