Zoom in/out by one step or to a specific zoom value * * Zooming is performed in steps of ZOOM_STEP_FACTOR. However, the zoom factor can not be a multiple * of ZOOM_STEP_FACTOR in two cases: The used pinched the screen or entered a custom zoom value. If * this is the case and a normal zoom operation happens, we "snap back" to a multiple of * ZOOM_STEP_FACTOR. E.g.: If the zoom factor currently
| 165 | * position (zoomPoint) \param newZoomFactor Zoom to this value in case of ZoomMode::TO_VALUE |
| 166 | */ |
| 167 | void MoveAndZoomableView::zoom(MoveAndZoomableView::ZoomMode zoomMode, |
| 168 | QPoint zoomPoint, |
| 169 | double newZoomFactor) |
| 170 | { |
| 171 | double newZoom = 1.0; |
| 172 | if (zoomMode == ZoomMode::IN) |
| 173 | { |
| 174 | if (this->zoomFactor > 1.0) |
| 175 | { |
| 176 | const double inf = std::numeric_limits<double>::infinity(); |
| 177 | while (newZoom <= this->zoomFactor && newZoom < inf) |
| 178 | newZoom *= ZOOM_STEP_FACTOR; |
| 179 | } |
| 180 | else |
| 181 | { |
| 182 | while (newZoom > this->zoomFactor) |
| 183 | newZoom /= ZOOM_STEP_FACTOR; |
| 184 | newZoom *= ZOOM_STEP_FACTOR; |
| 185 | } |
| 186 | } |
| 187 | else if (zoomMode == ZoomMode::OUT) |
| 188 | { |
| 189 | if (this->zoomFactor > 1.0) |
| 190 | { |
| 191 | while (newZoom < zoomFactor) |
| 192 | newZoom *= ZOOM_STEP_FACTOR; |
| 193 | newZoom /= ZOOM_STEP_FACTOR; |
| 194 | } |
| 195 | else |
| 196 | { |
| 197 | while (newZoom >= this->zoomFactor && newZoom > 0.0) |
| 198 | newZoom /= ZOOM_STEP_FACTOR; |
| 199 | } |
| 200 | } |
| 201 | else if (zoomMode == ZoomMode::TO_VALUE) |
| 202 | { |
| 203 | newZoom = newZoomFactor; |
| 204 | } |
| 205 | |
| 206 | if (newZoom < ZOOMINGLIMIT.min || newZoom > ZOOMINGLIMIT.max) |
| 207 | return; |
| 208 | |
| 209 | // So what is the zoom factor that we use in this step? |
| 210 | double stepZoomFactor = newZoom / this->zoomFactor; |
| 211 | |
| 212 | auto viewCenter = this->getMoveOffsetCoordinateSystemOrigin(zoomPoint); |
| 213 | |
| 214 | if (zoomPoint.isNull()) |
| 215 | zoomPoint = viewCenter; |
| 216 | |
| 217 | // The center point has to be moved relative to the zoomPoint |
| 218 | auto origin = viewCenter; |
| 219 | auto centerMoveOffset = origin + this->moveOffset; |
| 220 | |
| 221 | auto movementDelta = centerMoveOffset - zoomPoint; |
| 222 | auto newMoveOffset = this->moveOffset - (1 - stepZoomFactor) * movementDelta; |
| 223 | |
| 224 | DEBUG_VIEW("MoveAndZoomableView::zoom point debug zoomPoint " |
no test coverage detected