Kstars

skymapevents.cpp
1/*
2 SPDX-FileCopyrightText: 2001 Jason Harris <jharris@30doradus.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7//This file contains Event handlers for the SkyMap class.
8
9#include "skymap.h"
10
11#include "ksplanetbase.h"
12#include "kspopupmenu.h"
13#include "kstars.h"
14#include "observinglist.h"
15#include "Options.h"
16#include "skyglpainter.h"
17#include "skyqpainter.h"
18#include "printing/simplefovexporter.h"
19#include "skycomponents/skylabeler.h"
20#include "skycomponents/skymapcomposite.h"
21#include "skycomponents/starcomponent.h"
22#include "skycomponents/mosaiccomponent.h"
23#ifdef HAVE_INDI
24#include "skyobjects/mosaictiles.h"
25#endif
26#include "widgets/infoboxwidget.h"
27
28#include <QGestureEvent>
29#include <QStatusBar>
30#include <QToolTip>
31
33{
34 computeSkymap = true; // skymap must be new computed
35
36 //FIXME: No equivalent for this line in Qt4 ??
37 // if ( testWState( Qt::WState_AutoMask ) ) updateMask();
38
39 // Resize the widget that draws the sky map.
40 // FIXME: The resize event doesn't pass to children. Any better way of doing this?
41 m_SkyMapDraw->resize(size());
42
43 // Resize infoboxes container.
44 // FIXME: this is not really pretty. Maybe there are some better way to this???
45 m_iboxes->resize(size());
46}
47
49{
50 bool arrowKeyPressed(false);
51 bool shiftPressed(false);
52 float step = 1.0;
54 {
55 step = 10.0;
56 shiftPressed = true;
57 }
58
59 //If the DBus resume key is not empty, then DBus processing is
60 //paused while we wait for a keypress
61 if (!data->resumeKey.isEmpty() && QKeySequence(e->key()) == data->resumeKey)
62 {
63 //The resumeKey was pressed. Signal that it was pressed by
64 //resetting it to empty; this will break the loop in
65 //KStars::waitForKey()
66 data->resumeKey = QKeySequence();
67 return;
68 }
69
70 if (m_previewLegend)
71 {
72 slotCancelLegendPreviewMode();
73 }
74
75 switch (e->key())
76 {
77 case Qt::Key_Left:
78 if (Options::useAltAz())
79 {
80 focus()->setAz(dms(focus()->az().Degrees() - step * MINZOOM / Options::zoomFactor()).reduce());
81 focus()->HorizontalToEquatorial(data->lst(), data->geo()->lat());
82 }
83 else
84 {
85 focus()->setRA(focus()->ra().Hours() + 0.05 * step * MINZOOM / Options::zoomFactor());
86 focus()->EquatorialToHorizontal(data->lst(), data->geo()->lat());
87 }
88
89 arrowKeyPressed = true;
90 slewing = true;
91 break;
92
93 case Qt::Key_Right:
94 if (Options::useAltAz())
95 {
96 focus()->setAz(dms(focus()->az().Degrees() + step * MINZOOM / Options::zoomFactor()).reduce());
97 focus()->HorizontalToEquatorial(data->lst(), data->geo()->lat());
98 }
99 else
100 {
101 focus()->setRA(focus()->ra().Hours() - 0.05 * step * MINZOOM / Options::zoomFactor());
102 focus()->EquatorialToHorizontal(data->lst(), data->geo()->lat());
103 }
104
105 arrowKeyPressed = true;
106 slewing = true;
107 break;
108
109 case Qt::Key_Up:
110 if (Options::useAltAz())
111 {
112 focus()->setAltRefracted(focus()->altRefracted().Degrees() + step * MINZOOM / Options::zoomFactor());
113 if (focus()->alt().Degrees() > 90.0)
114 focus()->setAlt(90.0);
115 focus()->HorizontalToEquatorial(data->lst(), data->geo()->lat());
116 }
117 else
118 {
119 focus()->setDec(focus()->dec().Degrees() + step * MINZOOM / Options::zoomFactor());
120 if (focus()->dec().Degrees() > 90.0)
121 focus()->setDec(90.0);
122 focus()->EquatorialToHorizontal(data->lst(), data->geo()->lat());
123 }
124
125 arrowKeyPressed = true;
126 slewing = true;
127 break;
128
129 case Qt::Key_Down:
130 if (Options::useAltAz())
131 {
132 focus()->setAltRefracted(focus()->altRefracted().Degrees() - step * MINZOOM / Options::zoomFactor());
133 if (focus()->alt().Degrees() < -90.0)
134 focus()->setAlt(-90.0);
135 focus()->HorizontalToEquatorial(data->lst(), data->geo()->lat());
136 }
137 else
138 {
139 focus()->setDec(focus()->dec().Degrees() - step * MINZOOM / Options::zoomFactor());
140 if (focus()->dec().Degrees() < -90.0)
141 focus()->setDec(-90.0);
142 focus()->EquatorialToHorizontal(data->lst(), data->geo()->lat());
143 }
144
145 arrowKeyPressed = true;
146 slewing = true;
147 break;
148
149 case Qt::Key_Plus: //Zoom in
150 case Qt::Key_Equal:
151 zoomInOrMagStep(e->modifiers());
152 break;
153
154 case Qt::Key_Minus: //Zoom out
156 zoomOutOrMagStep(e->modifiers());
157 break;
158
159 case Qt::Key_0: //center on Sun
160 setClickedObject(data->skyComposite()->planet(KSPlanetBase::SUN));
162 slotCenter();
163 break;
164
165 case Qt::Key_1: //center on Mercury
166 setClickedObject(data->skyComposite()->planet(KSPlanetBase::MERCURY));
168 slotCenter();
169 break;
170
171 case Qt::Key_2: //center on Venus
172 setClickedObject(data->skyComposite()->planet(KSPlanetBase::VENUS));
174 slotCenter();
175 break;
176
177 case Qt::Key_3: //center on Moon
178 setClickedObject(data->skyComposite()->planet(KSPlanetBase::MOON));
180 slotCenter();
181 break;
182
183 case Qt::Key_4: //center on Mars
184 setClickedObject(data->skyComposite()->planet(KSPlanetBase::MARS));
186 slotCenter();
187 break;
188
189 case Qt::Key_5: //center on Jupiter
190 setClickedObject(data->skyComposite()->planet(KSPlanetBase::JUPITER));
192 slotCenter();
193 break;
194
195 case Qt::Key_6: //center on Saturn
196 setClickedObject(data->skyComposite()->planet(KSPlanetBase::SATURN));
198 slotCenter();
199 break;
200
201 case Qt::Key_7: //center on Uranus
202 setClickedObject(data->skyComposite()->planet(KSPlanetBase::URANUS));
204 slotCenter();
205 break;
206
207 case Qt::Key_8: //center on Neptune
208 setClickedObject(data->skyComposite()->planet(KSPlanetBase::NEPTUNE));
210 slotCenter();
211 break;
212
213 /*case Qt::Key_9: //center on Pluto
214 setClickedObject( data->skyComposite()->planet( KSPlanetBase::PLUTO ) );
215 setClickedPoint( clickedObject() );
216 slotCenter();
217 break;*/
218
219 case Qt::Key_BracketLeft: // Begin measuring angular distance
220 if (!rulerMode)
222 break;
223 case Qt::Key_Escape: // Cancel angular distance measurement
224 {
225 if (rulerMode)
227
228 if (m_fovCaptureMode)
229 slotFinishFovCaptureMode();
230 break;
231 }
232
233 case Qt::Key_C: //Center clicked object
234 if (clickedObject())
235 slotCenter();
236 break;
237
238 case Qt::Key_D: //Details window for Clicked/Centered object
239 {
240 SkyObject *orig = nullptr;
241 if (shiftPressed)
242 {
243 orig = clickedObject();
245 }
246
247 if (clickedObject())
248 {
249 slotDetail();
250 }
251
252 if (orig)
253 {
254 setClickedObject(orig);
255 }
256 break;
257 }
258
259 case Qt::Key_P: //Show Popup menu for Clicked/Centered object
260 if (shiftPressed)
261 {
262 if (focusObject())
264 }
265 else
266 {
267 if (clickedObject())
269 }
270 break;
271
272 case Qt::Key_O: //Add object to Observing List
273 {
274 SkyObject *orig = nullptr;
275 if (shiftPressed)
276 {
277 orig = clickedObject();
279 }
280
281 if (clickedObject())
282 {
283 data->observingList()->slotAddObject();
284 }
285
286 if (orig)
287 {
288 setClickedObject(orig);
289 }
290 break;
291 }
292
293 case Qt::Key_L: //Toggle User label on Clicked/Centered object
294 {
295 SkyObject *orig = nullptr;
296 if (shiftPressed)
297 {
298 orig = clickedObject();
300 }
301
302 if (clickedObject())
303 {
306 else
308 }
309
310 if (orig)
311 {
312 setClickedObject(orig);
313 }
314 break;
315 }
316
317 case Qt::Key_T: //Toggle planet trail on Clicked/Centered object (if solsys)
318 {
319 SkyObject *orig = nullptr;
320 if (shiftPressed)
321 {
322 orig = clickedObject();
324 }
325
326 KSPlanetBase *planet = dynamic_cast<KSPlanetBase *>(clickedObject());
327 if (planet)
328 {
329 if (planet->hasTrail())
331 else
333 }
334
335 if (orig)
336 {
337 setClickedObject(orig);
338 }
339 break;
340 }
341
342 case Qt::Key_R:
343 {
344 // Toggle relativistic corrections
345 Options::setUseRelativistic(!Options::useRelativistic());
346 qDebug() << Q_FUNC_INFO << "Relativistic corrections: " << Options::useRelativistic();
347 forceUpdate();
348 break;
349 }
350
351 case Qt::Key_A:
352 Options::setUseAntialias(!Options::useAntialias());
353 qDebug() << Q_FUNC_INFO << "Use Antialiasing: " << Options::useAntialias();
354 forceUpdate();
355 break;
356
357 case Qt::Key_K:
358 {
359 if (m_fovCaptureMode)
360 slotCaptureFov();
361 break;
362 }
363
364 case Qt::Key_PageUp:
365 {
366 if (shiftPressed)
367 {
368 KStars::Instance()->selectPreviousView();
369 }
370 else
371 {
372 KStars::Instance()->selectPreviousFov();
373 }
374 break;
375 }
376
377 case Qt::Key_PageDown:
378 {
379 if (shiftPressed)
380 {
381 KStars::Instance()->selectNextView();
382 }
383 else
384 {
385 KStars::Instance()->selectNextFov();
386 }
387 break;
388 }
389
390 default:
391 // We don't want to do anything in this case. Key is unknown
392 return;
393 }
394
395 if (arrowKeyPressed)
396 {
397 stopTracking();
399 }
400
401 forceUpdate(); //need a total update, or slewing with the arrow keys doesn't work.
402}
403
404void SkyMap::stopTracking()
405{
406 KStars *kstars = KStars::Instance();
407
408 emit positionChanged(focus());
409 if (kstars && Options::isTracking())
410 kstars->slotTrack();
411}
412
413bool SkyMap::event(QEvent *event)
414{
415#if !defined(KSTARS_LITE)
416 if (event->type() == QEvent::TouchBegin)
417 {
418 m_touchMode = true;
419 m_pinchScale = -1;
420 }
421
422 if (event->type() == QEvent::Gesture && m_touchMode)
423 {
424 QGestureEvent* gestureEvent = static_cast<QGestureEvent*>(event);
425
426 if (QPinchGesture *pinch = static_cast<QPinchGesture * >(gestureEvent->gesture(Qt::PinchGesture)))
427 {
428 QPinchGesture::ChangeFlags changeFlags = pinch->changeFlags();
429
430 m_pinchMode = true;
431 if (changeFlags & QPinchGesture::ScaleFactorChanged)
432 {
433 if (m_pinchScale == -1)
434 {
435 m_pinchScale = pinch->totalScaleFactor();
436 return true;
437 }
438 if (pinch->totalScaleFactor() - m_pinchScale > 0.1)
439 {
440 m_pinchScale = pinch->totalScaleFactor();
441 zoomInOrMagStep(0);
442 return true;
443 }
444 if (pinch->totalScaleFactor() - m_pinchScale < -0.1)
445 {
446 m_pinchScale = pinch->totalScaleFactor();
447 zoomOutOrMagStep(0);
448 return true;
449 }
450 }
451 }
452 if (QTapAndHoldGesture *tapAndHold = static_cast<QTapAndHoldGesture * >(gestureEvent->gesture(Qt::TapAndHoldGesture)))
453 {
454 m_tapAndHoldMode = true;
455 if (tapAndHold->state() == Qt::GestureFinished)
456 {
457 if (clickedObject())
458 {
459 clickedObject()->showPopupMenu(pmenu, tapAndHold->position().toPoint());
460 }
461 else
462 {
463 pmenu->createEmptyMenu(clickedPoint());
464 pmenu->popup(tapAndHold->position().toPoint());
465 }
466 m_touchMode = false;
467 m_pinchMode = false;
468 m_tapAndHoldMode = false;
469 }
470 }
471 return true;
472 }
473#endif
474 return QGraphicsView::event(event);
475}
476
478{
479 switch (e->key())
480 {
481 case Qt::Key_Plus: //Zoom in
482 case Qt::Key_Equal:
483 case Qt::Key_Minus: //Zoom out
485
486 case Qt::Key_Left: //no break; continue to Qt::Key_Down
487 case Qt::Key_Right: //no break; continue to Qt::Key_Down
488 case Qt::Key_Up: //no break; continue to Qt::Key_Down
489 case Qt::Key_Down:
490 slewing = false;
491
492 if (Options::useAltAz())
493 setDestinationAltAz(focus()->alt(), focus()->az(), false);
494 else
496
498 forceUpdate(); // Need a full update to draw faint objects that are not drawn while slewing.
499 break;
500 }
501}
502
504{
505#if !defined(KSTARS_LITE)
506 // Skip touch points
507 if (m_pinchMode || m_tapAndHoldMode || (m_touchMode && e->globalX() == 0 && e->globalY() == 0))
508 return;
509#endif
510
511 if (Options::useHoverLabel())
512 {
513 //Start a single-shot timer to monitor whether we are currently hovering.
514 //The idea is that whenever a moveEvent occurs, the timer is reset. It
515 //will only timeout if there are no move events for HOVER_INTERVAL ms
516 m_HoverTimer.start(HOVER_INTERVAL);
518 }
519
520 //Are we defining a ZoomRect?
521 if (ZoomRect.center().x() > 0 && ZoomRect.center().y() > 0)
522 {
523 //cancel operation if the user let go of CTRL
524 if (!(e->modifiers() & Qt::ControlModifier))
525 {
526 ZoomRect = QRect(); //invalidate ZoomRect
527 update();
528 }
529 else
530 {
531 //Resize the rectangle so that it passes through the cursor position
532 QPoint pcenter = ZoomRect.center();
533 int dx = abs(e->x() - pcenter.x());
534 int dy = abs(e->y() - pcenter.y());
535 if (dx == 0 || float(dy) / float(dx) > float(height()) / float(width()))
536 {
537 //Size rect by height
538 ZoomRect.setHeight(2 * dy);
539 ZoomRect.setWidth(2 * dy * width() / height());
540 }
541 else
542 {
543 //Size rect by height
544 ZoomRect.setWidth(2 * dx);
545 ZoomRect.setHeight(2 * dx * height() / width());
546 }
547 ZoomRect.moveCenter(pcenter); //reset center
548
549 update();
550 return;
551 }
552 }
553
554 // Are we setting the skymap rotation?
555 if (rotationStart.x() > 0 && rotationStart.y() > 0)
556 {
557 // stop the operation if the user let go of SHIFT
558 if (!(e->modifiers() & Qt::ShiftModifier))
559 {
560 rotationStart = QPoint(); // invalidate
561 rotationStartAngle = dms(); // NaN
562 slewing = false;
563 forceUpdate();
564 return;
565 }
566 else
567 {
568 // Compute the rotation
569 const float start_x = rotationStart.x() - width() / 2.0f;
570 const float start_y = height() / 2.0f - rotationStart.y();
571
572 const float curr_x = e->pos().x() - width() / 2.0f;
573 const float curr_y = height() / 2.0f - e->pos().y();
574
575 const dms angle {(std::atan2(curr_y, curr_x) - std::atan2(start_y, start_x)) / dms::DegToRad };
576 slotSetSkyRotation((rotationStartAngle - angle).Degrees());
577 return;
578 }
579 }
580
581 // Are we setting the fov rotation?
582 if (fovRotationStart.x() > 0 && fovRotationStart.y() > 0)
583 {
584 // stop the operation if the user let go of SHIFT or ALT or CONTROL
586 {
587 fovRotationStart = QPoint(); // invalidate
588 fovRotationStartAngle = dms(); // NaN
589 slewing = false;
590 forceUpdate();
591 return;
592 }
593 else
594 {
595 // Compute the rotation
596 const float start_x = fovRotationStart.x() - width() / 2.0f;
597 const float start_y = height() / 2.0f - fovRotationStart.y();
598
599 const float curr_x = e->pos().x() - width() / 2.0f;
600 const float curr_y = height() / 2.0f - e->pos().y();
601
602 const dms angle {(std::atan2(curr_y, curr_x) - std::atan2(start_y, start_x)) / dms::DegToRad };
603 setExtraFovRotation((fovRotationStartAngle - angle).Degrees());
604 return;
605 }
606 }
607
608 if (projector()->unusablePoint(e->pos()))
609 return; // break if point is unusable
610
611 //determine RA, Dec of mouse pointer
612 m_MousePoint = projector()->fromScreen(e->pos(), data);
613
614 double dyPix = 0.5 * height() - e->y();
615 if (midMouseButtonDown) //zoom according to y-offset
616 {
617 float yoff = dyPix - y0;
618 if (yoff > 10)
619 {
620 y0 = dyPix;
621 slotZoomIn();
622 }
623 if (yoff < -10)
624 {
625 y0 = dyPix;
626 slotZoomOut();
627 }
628 }
629
630 if (mouseButtonDown)
631 {
632#ifdef HAVE_INDI
633 if (Options::showMosaicPanel())
634 {
635 auto tiles = KStarsData::Instance()->skyComposite()->mosaicComponent()->tiles();
636
637 if (tiles->operationMode() == MosaicTiles::MODE_PLANNING)
638 {
639 // Check if mouse point within Mosaic FOV bounds.
640 auto mosaicFOV = tiles->mosaicFOV();
641 auto upperRA = tiles->ra0().Degrees() + mosaicFOV.width() / 60;
642 auto lowerRA = tiles->ra0().Degrees() - mosaicFOV.width() / 60;
643 auto upperDE = tiles->dec0().Degrees() + mosaicFOV.height() / 60;
644 auto lowerDE = tiles->dec0().Degrees() - mosaicFOV.height() / 60;
645
646 auto mouseRA = m_MousePoint.ra().Degrees();
647 auto mouseDE = m_MousePoint.dec().Degrees();
648
649 // If mouse point is within, then behave like drag and drop
650 if (mouseRA > lowerRA && mouseRA < upperRA && mouseDE > lowerDE && mouseDE < upperDE)
651 {
652 if (!mouseDragCursor)
653 setMouseDragCursor();
654
655 dms dRA = m_MousePoint.ra() - clickedPoint()->ra();
656 dms dDec = m_MousePoint.dec() - clickedPoint()->dec();
657
658 // Emit difference between mouse point and clicked point.
659 emit mosaicCenterChanged(dRA, dDec);
660
661 // Update mouse and clicked points.
662 m_MousePoint = projector()->fromScreen(e->pos(), data);
663 setClickedPoint(&m_MousePoint);
664 update();
665 return;
666 }
667 }
668 }
669#endif
670
671 // set the mouseMoveCursor and set slewing=true, if they are not set yet
672 if (!mouseMoveCursor)
673 setMouseMoveCursor();
674 if (!slewing)
675 {
676 slewing = true;
677 stopTracking(); //toggle tracking off
678 }
679
680 //Update focus such that the sky coords at mouse cursor remain approximately constant
681 if (Options::useAltAz())
682 {
683 m_MousePoint.EquatorialToHorizontal(data->lst(), data->geo()->lat());
684 clickedPoint()->EquatorialToHorizontal(data->lst(), data->geo()->lat());
685 dms dAz = m_MousePoint.az() - clickedPoint()->az();
686 dms dAlt = m_MousePoint.altRefracted() - clickedPoint()->altRefracted();
687 focus()->setAz(focus()->az().Degrees() - dAz.Degrees()); //move focus in opposite direction
688 focus()->setAz(focus()->az().reduce());
689 focus()->setAltRefracted(KSUtils::clamp(focus()->altRefracted().Degrees() - dAlt.Degrees(), -90.0, 90.0));
690 focus()->HorizontalToEquatorial(data->lst(), data->geo()->lat());
691 }
692 else
693 {
694 dms dRA = m_MousePoint.ra() - clickedPoint()->ra();
695 dms dDec = m_MousePoint.dec() - clickedPoint()->dec();
696 focus()->setRA(focus()->ra().Hours() - dRA.Hours()); //move focus in opposite direction
697 focus()->setRA(focus()->ra().reduce());
698 focus()->setDec(KSUtils::clamp(focus()->dec().Degrees() - dDec.Degrees(), -90.0, 90.0));
699 focus()->EquatorialToHorizontal(data->lst(), data->geo()->lat());
700 }
702
703 //redetermine RA, Dec of mouse pointer, using new focus
704 m_MousePoint = projector()->fromScreen(e->pos(), data);
705 setClickedPoint(&m_MousePoint);
706 forceUpdate(); // must be new computed
707 }
708 else //mouse button not down
709 {
710 if (Options::useAltAz())
711 m_MousePoint.EquatorialToHorizontal(data->lst(), data->geo()->lat());
712 emit mousePointChanged(&m_MousePoint);
713 }
714}
715
717{
718 if (e->angleDelta().y() > 0)
719 zoomInOrMagStep(e->modifiers());
720 else if (e->angleDelta().y() < 0)
721 zoomOutOrMagStep(e->modifiers());
722}
723
725{
726#if !defined(KSTARS_LITE)
727 if (m_touchMode)
728 {
729 m_touchMode = false;
730 m_pinchMode = false;
731 m_tapAndHoldMode = false;
732 }
733#endif
734
735 if (ZoomRect.isValid())
736 {
737 stopTracking();
738 SkyPoint newcenter = projector()->fromScreen(ZoomRect.center(), data);
739 setFocus(&newcenter);
740 setDestination(newcenter);
741
742 //Zoom in on center of Zoom Circle, by a factor equal to the ratio
743 //of the sky pixmap's width to the Zoom Circle's diameter
744 float factor = float(width()) / float(ZoomRect.width());
745 setZoomFactor(Options::zoomFactor() * factor);
746 }
747
748 setMouseCursorShape(static_cast<Cursor>(Options::defaultCursor()));
749
750 ZoomRect = QRect(); //invalidate ZoomRect
751
752 if (m_previewLegend)
753 {
754 slotCancelLegendPreviewMode();
755 }
756
757 // Are we setting the skymap rotation?
758 if (rotationStart.x() > 0 && rotationStart.y() > 0)
759 {
760 rotationStart = QPoint(); // invalidate
761 rotationStartAngle = dms(); // NaN
762 slewing = false;
764 return;
765 }
766
767 // Are we setting the fov rotation?
768 if (fovRotationStart.x() > 0 && fovRotationStart.y() > 0)
769 {
770 fovRotationStart = QPoint(); // invalidate
771 fovRotationStartAngle = dms(); // NaN
772 slewing = false;
774 return;
775 }
776
777 //false if double-clicked, because it's unset there.
778 if (mouseButtonDown)
779 {
780 mouseButtonDown = false;
781 if (slewing)
782 {
783 slewing = false;
784 if (Options::useAltAz())
785 setDestinationAltAz(focus()->alt(), focus()->az(), false);
786 else
788 }
789 else if (Options::leftClickSelectsObject())
791 forceUpdate(); // is needed because after moving the sky not all stars are shown
792 }
793 // if middle button was pressed unset here
794 midMouseButtonDown = false;
795}
796
798{
800 && (e->button() == Qt::LeftButton))
801 {
802 // FOV rotation mode
803 fovRotationStart = e->pos();
804 fovRotationStartAngle = dms(Options::skyRotation());
805 slewing = true;
806 setFovRotationMouseCursor();
807 forceUpdate();
808 return;
809 }
810
811 m_MousePointPressed = m_MousePoint;
812
813 KStars *kstars = KStars::Instance();
814
815 if ((e->modifiers() & Qt::ControlModifier) && (e->button() == Qt::LeftButton))
816 {
817 ZoomRect.moveCenter(e->pos());
818 setZoomMouseCursor();
819 update(); //refresh without redrawing skymap
820 return;
821 }
822
823 if ((e->modifiers() & Qt::ShiftModifier) && (e->button() == Qt::LeftButton))
824 {
825 // Skymap rotation mode
826 rotationStart = e->pos();
827 rotationStartAngle = dms(Options::skyRotation());
828 slewing = true;
829 setRotationMouseCursor();
830 forceUpdate();
831 return;
832 }
833
834 // if button is down and cursor is not moved set the move cursor after 500 ms
835 //QTimer::singleShot(500, this, SLOT(setMouseMoveCursor()));
836
837 // break if point is unusable
838 if (projector()->unusablePoint(e->pos()))
839 return;
840
841 if (!midMouseButtonDown && e->button() == Qt::MiddleButton)
842 {
843 y0 = 0.5 * height() - e->y(); //record y pixel coordinate for middle-button zooming
844 midMouseButtonDown = true;
845 }
846
847 if (!mouseButtonDown)
848 {
849 if (e->button() == Qt::LeftButton)
850 {
851 mouseButtonDown = true;
852 }
853
854 //determine RA, Dec of mouse pointer
855 m_MousePoint = projector()->fromScreen(e->pos(), data);
856 setClickedPoint(&m_MousePoint);
857
858 //Find object nearest to clickedPoint()
859 double maxrad = 5000.0 / Options::zoomFactor();
860 SkyObject *obj = data->skyComposite()->objectNearest(clickedPoint(), maxrad);
861 setClickedObject(obj);
862 if (obj)
863 setClickedPoint(obj);
864
865 switch (e->button())
866 {
867 case Qt::LeftButton:
868 {
869 QString name;
870 if (clickedObject())
871 {
874 }
875 else
876 name = i18n("Empty sky");
877 //kstars->statusBar()->changeItem(name, 0 );
878 kstars->statusBar()->showMessage(name, 0);
879
880 emit positionClicked(&m_MousePoint);
881 }
882
883 break;
884 case Qt::RightButton:
885 if (rulerMode)
886 {
887 // Compute angular distance.
889 }
890 else
891 {
892 // Show popup menu
893 if (clickedObject())
894 {
896 }
897 else
898 {
899 pmenu->createEmptyMenu(clickedPoint());
900 pmenu->popup(QCursor::pos());
901 }
902 }
903 break;
904 default:
905 ;
906 }
907 }
908}
909
911{
912 if (e->button() == Qt::LeftButton && !projector()->unusablePoint(e->pos()))
913 {
914 mouseButtonDown = false;
915 if (e->x() != width() / 2 || e->y() != height() / 2)
916 slotCenter();
917 }
918}
919
920double SkyMap::zoomFactor(const int modifier)
921{
922 double factor = (modifier & Qt::ControlModifier) ? DZOOM : (Options::zoomScrollFactor() + 1);
923 if (modifier & Qt::ShiftModifier)
924 factor = sqrt(factor);
925 return factor;
926}
927
928void SkyMap::zoomInOrMagStep(const int modifier)
929{
930 if (modifier & Qt::AltModifier)
931 incMagLimit(modifier);
932 else
933 setZoomFactor(Options::zoomFactor() * zoomFactor(modifier));
934}
935
936void SkyMap::zoomOutOrMagStep(const int modifier)
937{
938 if (modifier & Qt::AltModifier)
939 decMagLimit(modifier);
940 else
941 setZoomFactor(Options::zoomFactor() / zoomFactor(modifier));
942}
943
944double SkyMap::magFactor(const int modifier)
945{
946 double factor = (modifier & Qt::ControlModifier) ? 0.1 : 0.5;
947 if (modifier & Qt::ShiftModifier)
948 factor *= 2.0;
949 return factor;
950}
951
952void SkyMap::incMagLimit(const int modifier)
953{
954 double limit = 2.222 * log10(static_cast<double>(Options::starDensity())) + 0.35;
955 limit += magFactor(modifier);
956 if (limit > 5.75954)
957 limit = 5.75954;
958 Options::setStarDensity(pow(10, (limit - 0.35) / 2.222));
959 //printf("maglim set to %3.1f\n", limit);
960 forceUpdate();
961}
962
963void SkyMap::decMagLimit(const int modifier)
964{
965 double limit = 2.222 * log10(static_cast<double>(Options::starDensity())) + 0.35;
966 limit -= magFactor(modifier);
967 if (limit < 1.18778)
968 limit = 1.18778;
969 Options::setStarDensity(pow(10, (limit - 0.35) / 2.222));
970 //printf("maglim set to %3.1f\n", limit);
971 forceUpdate();
972}
A subclass of TrailObject that provides additional information needed for most solar system objects.
This is the main window for KStars.
Definition kstars.h:90
static KStars * Instance()
Definition kstars.h:122
void slotTrack()
action slot: Toggle whether kstars is tracking current position
virtual SkyPoint fromScreen(const QPointF &p, KStarsData *data, bool onlyAltAz=false) const
Determine RA, Dec coordinates of the pixel at (dx, dy), which are the screen pixel coordinate offsets...
void mouseReleaseEvent(QMouseEvent *e) override
set mouseButtonDown==false, slewing==false
void showFocusCoords()
Update object name and coordinates in the Focus InfoBox.
Definition skymap.cpp:360
void setZoomFactor(double factor)
@ Set zoom factor.
Definition skymap.cpp:1207
void setMouseCursorShape(Cursor type)
Sets the shape of the default mouse cursor.
Definition skymap.cpp:1365
SkyPoint * focus()
Retrieve the Focus point; the position on the sky at the center of the skymap.
Definition skymap.h:123
void keyReleaseEvent(QKeyEvent *e) override
When keyRelease is triggered, just set the "slewing" flag to false, and update the display (to draw o...
void resizeEvent(QResizeEvent *) override
If the skymap will be resized, the sky must be new computed.
void setClickedPoint(const SkyPoint *f)
Set the ClickedPoint to the skypoint given as an argument.
Definition skymap.cpp:1052
void slotAddPlanetTrail()
Add a Planet Trail to ClickedObject.
Definition skymap.cpp:928
void slotAddObjectLabel()
Add ClickedObject to KStarsData::ObjLabelList, which stores pointers to SkyObjects which have User La...
Definition skymap.cpp:912
void slotZoomOut()
Zoom out one step.
Definition skymap.cpp:1197
void setClickedObject(SkyObject *o)
Set the ClickedObject pointer to the argument.
Definition skymap.cpp:399
void slotEndRulerMode()
Computes the angular distance, prints the result in the status bar and disables the angular distance ...
Definition skymap.cpp:676
const Projector * projector() const
Get the current projector.
Definition skymap.h:300
void positionChanged(SkyPoint *)
Emitted when pointing changed.
void mouseMoveEvent(QMouseEvent *e) override
This function does several different things depending on the state of the program:
void slotRemoveObjectLabel()
Remove ClickedObject from KStarsData::ObjLabelList, which stores pointers to SkyObjects which have Us...
Definition skymap.cpp:886
void slotCancelRulerMode()
Disables the angular distance measuring mode.
Definition skymap.cpp:782
void forceUpdate(bool now=false)
Recalculates the positions of objects in the sky, and then repaints the sky map.
Definition skymap.cpp:1217
void objectClicked(SkyObject *)
Emitted when a position is clicked.
void slotRemovePlanetTrail()
Remove the PlanetTrail from ClickedObject.
Definition skymap.cpp:918
void mousePointChanged(SkyPoint *)
Emitted when position under mouse changed.
void slotSetSkyRotation(double angle)
Sets the base sky rotation (before correction) to the given angle.
Definition skymap.cpp:1262
void setDestination(const SkyPoint &f)
sets the destination point of the sky map.
Definition skymap.cpp:1024
SkyObject * clickedObject() const
Retrieve the object nearest to a mouse click event.
Definition skymap.h:244
void positionClicked(SkyPoint *)
Emitted when a position is clicked.
void forceUpdateNow()
Convenience function; simply calls forceUpdate(true).
Definition skymap.h:386
bool isObjectLabeled(SkyObject *o)
Definition skymap.cpp:873
void wheelEvent(QWheelEvent *e) override
Zoom in and out with the mouse wheel.
void setDestinationAltAz(const dms &alt, const dms &az, bool altIsRefracted)
sets the destination point of the sky map, using its alt/az coordinates.
Definition skymap.cpp:1036
void setExtraFovRotation(double angle)
Sets the extra rotation applied to FOV symbols (before correction) to the given angle.
Definition skymap.cpp:1286
SkyPoint * clickedPoint()
Retrieve the ClickedPoint position.
Definition skymap.h:217
void mouseDoubleClickEvent(QMouseEvent *e) override
Center SkyMap at double-clicked location.
void slotBeginAngularDistance()
Enables the angular distance measuring mode.
Definition skymap.cpp:640
void slotZoomIn()
Zoom in one step.
Definition skymap.cpp:1192
void keyPressEvent(QKeyEvent *e) override
Process keystrokes:
void slotCenter()
Center the display at the point ClickedPoint.
Definition skymap.cpp:413
SkyObject * focusObject() const
Retrieve the object which is centered in the sky map.
Definition skymap.h:262
void mosaicCenterChanged(dms dRA, dms dDE)
Emitter when mosaic center is dragged in the sky map.
void mousePressEvent(QMouseEvent *e) override
Determine RA, Dec coordinates of clicked location.
void slotDetail()
Popup menu function: Show the Detailed Information window for ClickedObject.
Definition skymap.cpp:938
Provides all necessary information about an object in the sky: its coordinates, name(s),...
Definition skyobject.h:50
void showPopupMenu(KSPopupMenu *pmenu, const QPoint &pos)
Show Type-specific popup menu.
Definition skyobject.cpp:56
QString translatedLongName() const
Definition skyobject.h:190
The sky coordinates of a point in the sky.
Definition skypoint.h:45
const CachingDms & dec() const
Definition skypoint.h:269
void setAltRefracted(dms alt_apparent)
Sets the apparent altitude, checking whether refraction corrections are enabled.
void setDec(dms d)
Sets Dec, the current Declination.
Definition skypoint.h:169
void setRA(dms &r)
Sets RA, the current Right Ascension.
Definition skypoint.h:144
const CachingDms & ra() const
Definition skypoint.h:263
dms altRefracted() const
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
Definition skypoint.cpp:77
const dms & az() const
Definition skypoint.h:275
void setAlt(dms alt)
Sets Alt, the Altitude.
Definition skypoint.h:194
void HorizontalToEquatorial(const dms *LST, const dms *lat)
Determine the (RA, Dec) coordinates of the SkyPoint from its (Altitude, Azimuth) coordinates,...
Definition skypoint.cpp:143
void setAz(dms az)
Sets Az, the Azimuth.
Definition skypoint.h:230
bool hasTrail() const
Definition trailobject.h:36
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
double Hours() const
Definition dms.h:168
const double & Degrees() const
Definition dms.h:141
static constexpr double DegToRad
DegToRad is a const static member equal to the number of radians in one degree (dms::PI/180....
Definition dms.h:390
QString i18n(const char *text, const TYPE &arg...)
QPoint pos()
QGesture * gesture(Qt::GestureType type) const const
virtual bool event(QEvent *event) override
Qt::KeyboardModifiers modifiers() const const
int key() const const
Qt::KeyboardModifiers modifiers() const const
QStatusBar * statusBar() const const
int globalX() const const
int globalY() const const
QPoint pos() const const
int x() const const
int y() const const
typedef ChangeFlags
int x() const const
int y() const const
Qt::MouseButton button() const const
void showMessage(const QString &message, int timeout)
GestureFinished
PinchGesture
Key_Left
ShiftModifier
LeftButton
void hideText()
QPoint angleDelta() const const
void setFocus()
void update()
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 25 2025 11:58:39 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.