* @brief Handles mouse wheel zooming. */
| 1129 | * @brief Handles mouse wheel zooming. |
| 1130 | */ |
| 1131 | void Widgets::GPS::wheelEvent(QWheelEvent* event) |
| 1132 | { |
| 1133 | const int delta = event->angleDelta().y(); |
| 1134 | if (delta == 0) |
| 1135 | return; |
| 1136 | |
| 1137 | event->accept(); |
| 1138 | |
| 1139 | const bool isTouchpad = |
| 1140 | !event->pixelDelta().isNull() || event->source() == Qt::MouseEventSynthesizedBySystem; |
| 1141 | |
| 1142 | double newZoom; |
| 1143 | if (isTouchpad) { |
| 1144 | const double zoomFactor = 1.05; |
| 1145 | const double deltaNorm = -delta * kInv120; |
| 1146 | const double factor = qPow(zoomFactor, -deltaNorm); |
| 1147 | newZoom = m_zoom * factor; |
| 1148 | } else { |
| 1149 | const double zoomStep = 0.5; |
| 1150 | newZoom = m_zoom + (delta > 0 ? zoomStep : -zoomStep); |
| 1151 | } |
| 1152 | |
| 1153 | newZoom = |
| 1154 | qBound(static_cast<double>(MIN_ZOOM), newZoom, static_cast<double>(m_mapMaxZoom[m_mapType])); |
| 1155 | |
| 1156 | if (qAbs(newZoom - m_zoom) < 0.001) |
| 1157 | return; |
| 1158 | |
| 1159 | if (!autoCenter()) { |
| 1160 | const QPointF cursorPos = event->position(); |
| 1161 | const QPointF cursorTileOffset((cursorPos.x() - width() * 0.5) * kInvTile, |
| 1162 | (cursorPos.y() - height() * 0.5) * kInvTile); |
| 1163 | |
| 1164 | const QPointF cursorTile = m_centerTile + cursorTileOffset; |
| 1165 | const QPointF geo = tileToLatLon(cursorTile, m_zoom); |
| 1166 | m_zoom = newZoom; |
| 1167 | |
| 1168 | const QPointF newTile = latLonToTile(geo.x(), geo.y(), m_zoom); |
| 1169 | m_centerTile = clampCenterTile(newTile - cursorTileOffset); |
| 1170 | |
| 1171 | updateTiles(); |
| 1172 | update(); |
| 1173 | |
| 1174 | Q_EMIT zoomLevelChanged(); |
| 1175 | } |
| 1176 | |
| 1177 | else |
| 1178 | setZoomLevelPrecise(newZoom); |
| 1179 | } |
| 1180 | |
| 1181 | /** |
| 1182 | * @brief Handles map dragging via mouse move. |