Kstars

skymapevents.cpp
1 /*
2  SPDX-FileCopyrightText: 2001 Jason Harris <[email protected]>
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;
53  if (e->modifiers() & Qt::ShiftModifier)
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
155  case Qt::Key_Underscore:
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  KStars::Instance()->selectPreviousFov();
367  break;
368  }
369 
370  case Qt::Key_PageDown:
371  {
372  KStars::Instance()->selectNextFov();
373  break;
374  }
375 
376  default:
377  // We don't want to do anything in this case. Key is unknown
378  return;
379  }
380 
381  if (arrowKeyPressed)
382  {
383  stopTracking();
384  setDestination(*focus());
385  }
386 
387  forceUpdate(); //need a total update, or slewing with the arrow keys doesn't work.
388 }
389 
390 void SkyMap::stopTracking()
391 {
392  KStars *kstars = KStars::Instance();
393 
394  emit positionChanged(focus());
395  if (kstars && Options::isTracking())
396  kstars->slotTrack();
397 }
398 
399 bool SkyMap::event(QEvent *event)
400 {
401 #if !defined(KSTARS_LITE)
402  if (event->type() == QEvent::TouchBegin)
403  {
404  m_touchMode = true;
405  m_pinchScale = -1;
406  }
407 
408  if (event->type() == QEvent::Gesture && m_touchMode)
409  {
410  QGestureEvent* gestureEvent = static_cast<QGestureEvent*>(event);
411 
412  if (QPinchGesture *pinch = static_cast<QPinchGesture*>(gestureEvent->gesture(Qt::PinchGesture)))
413  {
414  QPinchGesture::ChangeFlags changeFlags = pinch->changeFlags();
415 
416  m_pinchMode = true;
417  if (changeFlags & QPinchGesture::ScaleFactorChanged)
418  {
419  if (m_pinchScale == -1)
420  {
421  m_pinchScale = pinch->totalScaleFactor();
422  return true;
423  }
424  if (pinch->totalScaleFactor() - m_pinchScale > 0.1)
425  {
426  m_pinchScale = pinch->totalScaleFactor();
427  zoomInOrMagStep(0);
428  return true;
429  }
430  if (pinch->totalScaleFactor() - m_pinchScale < -0.1)
431  {
432  m_pinchScale = pinch->totalScaleFactor();
433  zoomOutOrMagStep(0);
434  return true;
435  }
436  }
437  }
438  if (QTapAndHoldGesture *tapAndHold = static_cast<QTapAndHoldGesture*>(gestureEvent->gesture(Qt::TapAndHoldGesture)))
439  {
440  m_tapAndHoldMode = true;
441  if (tapAndHold->state() == Qt::GestureFinished)
442  {
443  if (clickedObject())
444  {
445  clickedObject()->showPopupMenu(pmenu, tapAndHold->position().toPoint());
446  }
447  else
448  {
449  pmenu->createEmptyMenu(clickedPoint());
450  pmenu->popup(tapAndHold->position().toPoint());
451  }
452  m_touchMode = false;
453  m_pinchMode = false;
454  m_tapAndHoldMode = false;
455  }
456  }
457  return true;
458  }
459 #endif
460  return QGraphicsView::event(event);
461 }
462 
464 {
465  switch (e->key())
466  {
467  case Qt::Key_Plus: //Zoom in
468  case Qt::Key_Equal:
469  case Qt::Key_Minus: //Zoom out
470  case Qt::Key_Underscore:
471 
472  case Qt::Key_Left: //no break; continue to Qt::Key_Down
473  case Qt::Key_Right: //no break; continue to Qt::Key_Down
474  case Qt::Key_Up: //no break; continue to Qt::Key_Down
475  case Qt::Key_Down:
476  slewing = false;
477 
478  if (Options::useAltAz())
479  setDestinationAltAz(focus()->alt(), focus()->az(), false);
480  else
481  setDestination(*focus());
482 
483  showFocusCoords();
484  forceUpdate(); // Need a full update to draw faint objects that are not drawn while slewing.
485  break;
486  }
487 }
488 
490 {
491 #if !defined(KSTARS_LITE)
492  // Skip touch points
493  if (m_pinchMode || m_tapAndHoldMode || (m_touchMode && e->globalX() == 0 && e->globalY() == 0))
494  return;
495 #endif
496 
497  if (Options::useHoverLabel())
498  {
499  //Start a single-shot timer to monitor whether we are currently hovering.
500  //The idea is that whenever a moveEvent occurs, the timer is reset. It
501  //will only timeout if there are no move events for HOVER_INTERVAL ms
502  m_HoverTimer.start(HOVER_INTERVAL);
504  }
505 
506  //Are we defining a ZoomRect?
507  if (ZoomRect.center().x() > 0 && ZoomRect.center().y() > 0)
508  {
509  //cancel operation if the user let go of CTRL
510  if (!(e->modifiers() & Qt::ControlModifier))
511  {
512  ZoomRect = QRect(); //invalidate ZoomRect
513  update();
514  }
515  else
516  {
517  //Resize the rectangle so that it passes through the cursor position
518  QPoint pcenter = ZoomRect.center();
519  int dx = abs(e->x() - pcenter.x());
520  int dy = abs(e->y() - pcenter.y());
521  if (dx == 0 || float(dy) / float(dx) > float(height()) / float(width()))
522  {
523  //Size rect by height
524  ZoomRect.setHeight(2 * dy);
525  ZoomRect.setWidth(2 * dy * width() / height());
526  }
527  else
528  {
529  //Size rect by height
530  ZoomRect.setWidth(2 * dx);
531  ZoomRect.setHeight(2 * dx * height() / width());
532  }
533  ZoomRect.moveCenter(pcenter); //reset center
534 
535  update();
536  return;
537  }
538  }
539 
540  // Are we setting the skymap rotation?
541  if (rotationStart.x() > 0 && rotationStart.y() > 0)
542  {
543  // stop the operation if the user let go of SHIFT
544  if (!(e->modifiers() & Qt::ShiftModifier))
545  {
546  rotationStart = QPoint(); // invalidate
547  rotationStartAngle = dms(); // NaN
548  slewing = false;
549  forceUpdate();
550  return;
551  }
552  else
553  {
554  // Compute the rotation
555  const float start_x = rotationStart.x() - width() / 2.0f;
556  const float start_y = height() / 2.0f - rotationStart.y();
557 
558  const float curr_x = e->pos().x() - width() / 2.0f;
559  const float curr_y = height() / 2.0f - e->pos().y();
560 
561  const dms angle {(std::atan2(curr_y, curr_x) - std::atan2(start_y, start_x)) / dms::DegToRad };
562  slotSetSkyRotation((rotationStartAngle - angle).Degrees());
563  return;
564  }
565  }
566 
567  if (projector()->unusablePoint(e->pos()))
568  return; // break if point is unusable
569 
570  //determine RA, Dec of mouse pointer
571  m_MousePoint = projector()->fromScreen(e->pos(), data->lst(), data->geo()->lat());
572 
573  double dyPix = 0.5 * height() - e->y();
574  if (midMouseButtonDown) //zoom according to y-offset
575  {
576  float yoff = dyPix - y0;
577  if (yoff > 10)
578  {
579  y0 = dyPix;
580  slotZoomIn();
581  }
582  if (yoff < -10)
583  {
584  y0 = dyPix;
585  slotZoomOut();
586  }
587  }
588 
589  if (mouseButtonDown)
590  {
591 #ifdef HAVE_INDI
592  if (Options::showMosaicPanel())
593  {
594  auto tiles = KStarsData::Instance()->skyComposite()->mosaicComponent()->tiles();
595 
596  if (tiles->operationMode() == MosaicTiles::MODE_PLANNING)
597  {
598  // Check if mouse point within Mosaic FOV bounds.
599  auto mosaicFOV = tiles->mosaicFOV();
600  auto upperRA = tiles->ra0().Degrees() + mosaicFOV.width() / 60;
601  auto lowerRA = tiles->ra0().Degrees() - mosaicFOV.width() / 60;
602  auto upperDE = tiles->dec0().Degrees() + mosaicFOV.height() / 60;
603  auto lowerDE = tiles->dec0().Degrees() - mosaicFOV.height() / 60;
604 
605  auto mouseRA = m_MousePoint.ra().Degrees();
606  auto mouseDE = m_MousePoint.dec().Degrees();
607 
608  // If mouse point is within, then behave like drag and drop
609  if (mouseRA > lowerRA && mouseRA < upperRA && mouseDE > lowerDE && mouseDE < upperDE)
610  {
611  if (!mouseDragCursor)
612  setMouseDragCursor();
613 
614  dms dRA = m_MousePoint.ra() - clickedPoint()->ra();
615  dms dDec = m_MousePoint.dec() - clickedPoint()->dec();
616 
617  // Emit difference between mouse point and clicked point.
618  emit mosaicCenterChanged(dRA, dDec);
619 
620  // Update mouse and clicked points.
621  m_MousePoint = projector()->fromScreen(e->pos(), data->lst(), data->geo()->lat());
622  setClickedPoint(&m_MousePoint);
623  update();
624  return;
625  }
626  }
627  }
628 #endif
629 
630  // set the mouseMoveCursor and set slewing=true, if they are not set yet
631  if (!mouseMoveCursor)
632  setMouseMoveCursor();
633  if (!slewing)
634  {
635  slewing = true;
636  stopTracking(); //toggle tracking off
637  }
638 
639  //Update focus such that the sky coords at mouse cursor remain approximately constant
640  if (Options::useAltAz())
641  {
642  m_MousePoint.EquatorialToHorizontal(data->lst(), data->geo()->lat());
643  clickedPoint()->EquatorialToHorizontal(data->lst(), data->geo()->lat());
644  dms dAz = m_MousePoint.az() - clickedPoint()->az();
645  dms dAlt = m_MousePoint.altRefracted() - clickedPoint()->altRefracted();
646  focus()->setAz(focus()->az().Degrees() - dAz.Degrees()); //move focus in opposite direction
647  focus()->setAz(focus()->az().reduce());
648  focus()->setAltRefracted(KSUtils::clamp(focus()->altRefracted().Degrees() - dAlt.Degrees(), -90.0, 90.0));
649  focus()->HorizontalToEquatorial(data->lst(), data->geo()->lat());
650  }
651  else
652  {
653  dms dRA = m_MousePoint.ra() - clickedPoint()->ra();
654  dms dDec = m_MousePoint.dec() - clickedPoint()->dec();
655  focus()->setRA(focus()->ra().Hours() - dRA.Hours()); //move focus in opposite direction
656  focus()->setRA(focus()->ra().reduce());
657  focus()->setDec(KSUtils::clamp(focus()->dec().Degrees() - dDec.Degrees(), -90.0, 90.0));
658  focus()->EquatorialToHorizontal(data->lst(), data->geo()->lat());
659  }
660  showFocusCoords();
661 
662  //redetermine RA, Dec of mouse pointer, using new focus
663  m_MousePoint = projector()->fromScreen(e->pos(), data->lst(), data->geo()->lat());
664  setClickedPoint(&m_MousePoint);
665  forceUpdate(); // must be new computed
666  }
667  else //mouse button not down
668  {
669  if (Options::useAltAz())
670  m_MousePoint.EquatorialToHorizontal(data->lst(), data->geo()->lat());
671  emit mousePointChanged(&m_MousePoint);
672  }
673 }
674 
676 {
677  if (e->angleDelta().y() > 0)
678  zoomInOrMagStep(e->modifiers());
679  else if (e->angleDelta().y() < 0)
680  zoomOutOrMagStep(e->modifiers());
681 }
682 
684 {
685 #if !defined(KSTARS_LITE)
686  if (m_touchMode)
687  {
688  m_touchMode = false;
689  m_pinchMode = false;
690  m_tapAndHoldMode = false;
691  }
692 #endif
693 
694  if (ZoomRect.isValid())
695  {
696  stopTracking();
697  SkyPoint newcenter = projector()->fromScreen(ZoomRect.center(), data->lst(), data->geo()->lat());
698  setFocus(&newcenter);
699  setDestination(newcenter);
700 
701  //Zoom in on center of Zoom Circle, by a factor equal to the ratio
702  //of the sky pixmap's width to the Zoom Circle's diameter
703  float factor = float(width()) / float(ZoomRect.width());
704  setZoomFactor(Options::zoomFactor() * factor);
705  }
706 
707  setMouseCursorShape(static_cast<Cursor>(Options::defaultCursor()));
708 
709  ZoomRect = QRect(); //invalidate ZoomRect
710 
711  if (m_previewLegend)
712  {
713  slotCancelLegendPreviewMode();
714  }
715 
716  // Are we setting the skymap rotation?
717  if (rotationStart.x() > 0 && rotationStart.y() > 0)
718  {
719  rotationStart = QPoint(); // invalidate
720  rotationStartAngle = dms(); // NaN
721  slewing = false;
722  forceUpdateNow();
723  return;
724  }
725 
726  //false if double-clicked, because it's unset there.
727  if (mouseButtonDown)
728  {
729  mouseButtonDown = false;
730  if (slewing)
731  {
732  slewing = false;
733  if (Options::useAltAz())
734  setDestinationAltAz(focus()->alt(), focus()->az(), false);
735  else
736  setDestination(*focus());
737  }
738  else if (Options::leftClickSelectsObject())
740  forceUpdate(); // is needed because after moving the sky not all stars are shown
741  }
742  // if middle button was pressed unset here
743  midMouseButtonDown = false;
744 }
745 
747 {
748  KStars *kstars = KStars::Instance();
749 
750  if ((e->modifiers() & Qt::ControlModifier) && (e->button() == Qt::LeftButton))
751  {
752  ZoomRect.moveCenter(e->pos());
753  setZoomMouseCursor();
754  update(); //refresh without redrawing skymap
755  return;
756  }
757 
758  if ((e->modifiers() & Qt::ShiftModifier) && (e->button() == Qt::LeftButton))
759  {
760  // Skymap rotation mode
761  rotationStart = e->pos();
762  rotationStartAngle = dms(Options::skyRotation());
763  slewing = true;
764  setRotationMouseCursor();
765  forceUpdate();
766  return;
767  }
768 
769  // if button is down and cursor is not moved set the move cursor after 500 ms
770  //QTimer::singleShot(500, this, SLOT(setMouseMoveCursor()));
771 
772  // break if point is unusable
773  if (projector()->unusablePoint(e->pos()))
774  return;
775 
776  if (!midMouseButtonDown && e->button() == Qt::MidButton)
777  {
778  y0 = 0.5 * height() - e->y(); //record y pixel coordinate for middle-button zooming
779  midMouseButtonDown = true;
780  }
781 
782  if (!mouseButtonDown)
783  {
784  if (e->button() == Qt::LeftButton)
785  {
786  mouseButtonDown = true;
787  }
788 
789  //determine RA, Dec of mouse pointer
790  m_MousePoint = projector()->fromScreen(e->pos(), data->lst(), data->geo()->lat());
791  setClickedPoint(&m_MousePoint);
792 
793  //Find object nearest to clickedPoint()
794  double maxrad = 5000.0 / Options::zoomFactor();
795  SkyObject *obj = data->skyComposite()->objectNearest(clickedPoint(), maxrad);
796  setClickedObject(obj);
797  if (obj)
798  setClickedPoint(obj);
799 
800  switch (e->button())
801  {
802  case Qt::LeftButton:
803  {
804  QString name;
805  if (clickedObject())
806  {
807  name = clickedObject()->translatedLongName();
809  }
810  else
811  name = i18n("Empty sky");
812  //kstars->statusBar()->changeItem(name, 0 );
813  kstars->statusBar()->showMessage(name, 0);
814 
815  emit positionClicked(&m_MousePoint);
816  }
817 
818  break;
819  case Qt::RightButton:
820  if (rulerMode)
821  {
822  // Compute angular distance.
824  }
825  else
826  {
827  // Show popup menu
828  if (clickedObject())
829  {
831  }
832  else
833  {
834  pmenu->createEmptyMenu(clickedPoint());
835  pmenu->popup(QCursor::pos());
836  }
837  }
838  break;
839  default:
840  ;
841  }
842  }
843 }
844 
846 {
847  if (e->button() == Qt::LeftButton && !projector()->unusablePoint(e->pos()))
848  {
849  mouseButtonDown = false;
850  if (e->x() != width() / 2 || e->y() != height() / 2)
851  slotCenter();
852  }
853 }
854 
855 double SkyMap::zoomFactor(const int modifier)
856 {
857  double factor = (modifier & Qt::ControlModifier) ? DZOOM : (Options::zoomScrollFactor() + 1);
858  if (modifier & Qt::ShiftModifier)
859  factor = sqrt(factor);
860  return factor;
861 }
862 
863 void SkyMap::zoomInOrMagStep(const int modifier)
864 {
865  if (modifier & Qt::AltModifier)
866  incMagLimit(modifier);
867  else
868  setZoomFactor(Options::zoomFactor() * zoomFactor(modifier));
869 }
870 
871 void SkyMap::zoomOutOrMagStep(const int modifier)
872 {
873  if (modifier & Qt::AltModifier)
874  decMagLimit(modifier);
875  else
876  setZoomFactor(Options::zoomFactor() / zoomFactor(modifier));
877 }
878 
879 double SkyMap::magFactor(const int modifier)
880 {
881  double factor = (modifier & Qt::ControlModifier) ? 0.1 : 0.5;
882  if (modifier & Qt::ShiftModifier)
883  factor *= 2.0;
884  return factor;
885 }
886 
887 void SkyMap::incMagLimit(const int modifier)
888 {
889  double limit = 2.222 * log10(static_cast<double>(Options::starDensity())) + 0.35;
890  limit += magFactor(modifier);
891  if (limit > 5.75954)
892  limit = 5.75954;
893  Options::setStarDensity(pow(10, (limit - 0.35) / 2.222));
894  //printf("maglim set to %3.1f\n", limit);
895  forceUpdate();
896 }
897 
898 void SkyMap::decMagLimit(const int modifier)
899 {
900  double limit = 2.222 * log10(static_cast<double>(Options::starDensity())) + 0.35;
901  limit -= magFactor(modifier);
902  if (limit < 1.18778)
903  limit = 1.18778;
904  Options::setStarDensity(pow(10, (limit - 0.35) / 2.222));
905  //printf("maglim set to %3.1f\n", limit);
906  forceUpdate();
907 }
void objectClicked(SkyObject *)
Emitted when a position is clicked.
void mousePressEvent(QMouseEvent *e) override
Determine RA, Dec coordinates of clicked location.
QPoint pos() const const
void setAlt(dms alt)
Sets Alt, the Altitude.
Definition: skypoint.h:194
GestureFinished
void setWidth(int width)
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:995
void slotZoomOut()
Zoom out one step.
Definition: skymap.cpp:1156
void forceUpdateNow()
Convenience function; simply calls forceUpdate(true).
Definition: skymap.h:378
QString translatedLongName() const
Definition: skyobject.h:169
void mosaicCenterChanged(dms dRA, dms dDE)
Emitter when mosaic center is dragged in the sky map.
SkyPoint * clickedPoint()
Retrieve the ClickedPoint position.
Definition: skymap.h:217
void createEmptyMenu(SkyPoint *nullObj)
Create a popup menu for empty sky.
Qt::MouseButton button() const const
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
void mouseMoveEvent(QMouseEvent *e) override
This function does several different things depending on the state of the program:
void setZoomFactor(double factor)
@ Set zoom factor.
Definition: skymap.cpp:1166
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
void update()
void setClickedPoint(const SkyPoint *f)
Set the ClickedPoint to the skypoint given as an argument.
Definition: skymap.cpp:1011
void resizeEvent(QResizeEvent *) override
If the skymap will be resized, the sky must be new computed.
QPoint angleDelta() const const
CachingDms * lst()
Definition: kstarsdata.h:224
void showFocusCoords()
Update object name and coordinates in the Focus InfoBox.
Definition: skymap.cpp:324
SkyObject * clickedObject() const
Retrieve the object nearest to a mouse click event.
Definition: skymap.h:244
int width() const const
bool isObjectLabeled(SkyObject *o)
Definition: skymap.cpp:830
void slotAddObjectLabel()
Add ClickedObject to KStarsData::ObjLabelList, which stores pointers to SkyObjects which have User La...
Definition: skymap.cpp:871
int x() const const
int y() const const
virtual bool event(QEvent *event) override
LeftButton
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
void slotEndRulerMode()
Computes the angular distance, prints the result in the status bar and disables the angular distance ...
Definition: skymap.cpp:646
dms altRefracted() const
Definition: skypoint.cpp:1050
void showPopupMenu(KSPopupMenu *pmenu, const QPoint &pos)
Show Type-specific popup menu.
Definition: skyobject.cpp:56
void setMouseCursorShape(Cursor type)
Sets the shape of the default mouse cursor.
Definition: skymap.cpp:1300
static KStars * Instance()
Definition: kstars.h:123
void showMessage(const QString &message, int timeout)
void setDestination(const SkyPoint &f)
sets the destination point of the sky map.
Definition: skymap.cpp:983
void keyPressEvent(QKeyEvent *e) override
Process keystrokes:
Qt::KeyboardModifiers modifiers() const const
void start(int msec)
QString i18n(const char *text, const TYPE &arg...)
const CachingDms & dec() const
Definition: skypoint.h:269
const CachingDms * lat() const
Definition: geolocation.h:70
void slotRemoveObjectLabel()
Remove ClickedObject from KStarsData::ObjLabelList, which stores pointers to SkyObjects which have Us...
Definition: skymap.cpp:845
SkyPoint * focus()
Retrieve the Focus point; the position on the sky at the center of the skymap.
Definition: skymap.h:123
void wheelEvent(QWheelEvent *e) override
Zoom in and out with the mouse wheel.
void setHeight(int height)
void positionChanged(SkyPoint *)
Emitted when pointing changed.
void setAltRefracted(dms alt_apparent)
Sets the apparent altitude, checking whether refraction corrections are enabled.
Definition: skypoint.cpp:1055
GeoLocation * geo()
Definition: kstarsdata.h:230
SkyObject * objectNearest(SkyPoint *p, double &maxrad) override
bool isValid() const const
void mouseDoubleClickEvent(QMouseEvent *e) override
Center SkyMap at double-clicked location
int x() const const
int y() const const
typedef ChangeFlags
void setClickedObject(SkyObject *o)
Set the ClickedObject pointer to the argument.
Definition: skymap.cpp:363
int globalX() const const
int globalY() const const
QPoint center() const const
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
void positionClicked(SkyPoint *)
Emitted when a position is clicked.
void slotRemovePlanetTrail()
Remove the PlanetTrail from ClickedObject.
Definition: skymap.cpp:877
This is the main window for KStars. In addition to the GUI elements, the class contains the program c...
Definition: kstars.h:90
void slotDetail()
Popup menu function: Show the Detailed Information window for ClickedObject.
Definition: skymap.cpp:897
Key_Left
QPoint pos()
void slotAddPlanetTrail()
Add a Planet Trail to ClickedObject.
Definition: skymap.cpp:887
void moveCenter(const QPoint &position)
PinchGesture
void slotCenter()
Center the display at the point ClickedPoint.
Definition: skymap.cpp:377
QStatusBar * statusBar() const const
Qt::KeyboardModifiers modifiers() const const
SkyMapComposite * skyComposite()
Definition: kstarsdata.h:166
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
void resize(int w, int h)
void popup(const QPoint &p, QAction *atAction)
void slotTrack()
action slot: Toggle whether kstars is tracking current position
void setAz(dms az)
Sets Az, the Azimuth.
Definition: skypoint.h:230
const CachingDms & ra() const
Definition: skypoint.h:263
SkyObject * focusObject() const
Retrieve the object which is centered in the sky map.
Definition: skymap.h:262
void slotBeginAngularDistance()
Enables the angular distance measuring mode.
Definition: skymap.cpp:610
int key() const const
virtual SkyPoint fromScreen(const QPointF &p, dms *LST, const dms *lat, bool onlyAltAz=false) const
Determine RA, Dec coordinates of the pixel at (dx, dy), which are the screen pixel coordinate offsets...
Definition: projector.cpp:449
void slotCancelRulerMode()
Disables the angular distance measuring mode.
Definition: skymap.cpp:752
const double & Degrees() const
Definition: dms.h:141
bool hasTrail() const
Definition: trailobject.h:36
void setDec(dms d)
Sets Dec, the current Declination.
Definition: skypoint.h:169
void hideText()
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 setRA(dms &r)
Sets RA, the current Right Ascension.
Definition: skypoint.h:144
void mouseReleaseEvent(QMouseEvent *e) override
set mouseButtonDown==false, slewing==false
void forceUpdate(bool now=false)
Recalculates the positions of objects in the sky, and then repaints the sky map.
Definition: skymap.cpp:1176
void slotSetSkyRotation(double angle)
Sets the base sky rotation (before correction) to the given angle.
Definition: skymap.cpp:1215
void slotZoomIn()
Zoom in one step.
Definition: skymap.cpp:1151
const Projector * projector() const
Get the current projector.
Definition: skymap.h:300
void mousePointChanged(SkyPoint *)
Emitted when position under mouse changed.
void keyReleaseEvent(QKeyEvent *e) override
When keyRelease is triggered, just set the "slewing" flag to false, and update the display (to draw o...
ShiftModifier
bool isEmpty() const const
void setFocus()
Information about an object in the sky.
Definition: skyobject.h:41
QGesture * gesture(Qt::GestureType type) const const
double Hours() const
Definition: dms.h:168
Provides necessary information about objects in the solar system.
Definition: ksplanetbase.h:49
const dms & az() const
Definition: skypoint.h:275
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Sep 27 2023 04:02:14 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.