10#include "config-kstars.h"
14#include "kspopupmenu.h"
16#include "kstarsdata.h"
19#include "ksnotification.h"
20#include <QGuiApplication>
23#include "basedevice.h"
24#include "indi/indilistener.h"
25#include "indi/indiconcretedevice.h"
26#include "indi/indimount.h"
33#define ZOOM_DEFAULT 100.0
36#define ZOOM_LOW_INCR 10
37#define ZOOM_HIGH_INCR 50
53 roiRB->setPalette(pal);
58void FITSLabel::setSize(
double w,
double h)
65bool FITSLabel::getMouseButtonDown()
67 return mouseButtonDown;
76 float scale = (view->getCurrentZoom() / ZOOM_DEFAULT);
78 double x = round(e->
x() / scale);
79 double y = round(e->
y() / scale);
84 if (view->getCursorMode() == FITSView::dragCursor)
86 mouseButtonDown =
false;
87 view->updateMouseCursor();
88 if( isRoiSelected && view->isSelectionRectShown())
90 QRect roiRaw = roiRB->geometry();
91 emit rectangleSelected(roiRaw.
topLeft() / prevscale, roiRaw.
bottomRight() / prevscale,
true);
96 QRect roiRaw = roiRB->geometry();
97 emit rectangleSelected(roiRaw.
topLeft() / prevscale, roiRaw.
bottomRight() / prevscale,
true);
100 isRoiSelected =
false;
103 emit circleSelected(m_p1, m_p2);
108void FITSLabel::leaveEvent(
QEvent *e)
111 view->updateMagnifyingGlass(-1, -1);
112 emit mouseOverPixel(-1, -1);
124 const QSharedPointer<FITSData> &imageData = view->imageData();
128 float scale = (view->getCurrentZoom() / ZOOM_DEFAULT);
130 double x = round(e->
x() / scale);
131 double y = round(e->
y() / scale);
137 int dx = newPoint.
x() - lastMousePoint.x();
138 int dy = newPoint.
y() - lastMousePoint.y();
139 view->horizontalScrollBar()->setValue(view->horizontalScrollBar()->value() - dx);
140 view->verticalScrollBar()->setValue(view->verticalScrollBar()->value() - dy);
142 lastMousePoint = newPoint;
147 if(isRoiSelected && !mouseButtonDown)
150 int xdiff =
x - prevPoint.x();
151 int ydiff =
y - prevPoint.y();
152 roiRB->setGeometry(roiRB->geometry().translated(round(xdiff * scale), round(ydiff * scale)));
153 prevPoint = QPoint(
x,
y);
155 QRect roiRaw = roiRB->geometry();
157 if(!view->isLargeImage())
159 emit rectangleSelected(roiRaw.
topLeft() / prevscale, roiRaw.
bottomRight() / prevscale,
true);
166 roiRB->setGeometry(QRect(m_p1 * scale, QPoint(
x,
y)*scale).normalized());
168 QRect roiRaw = roiRB->geometry();
170 if(!view->isLargeImage())
172 emit rectangleSelected(roiRaw.
topLeft() / prevscale, roiRaw.
bottomRight() / prevscale,
true);
178 uint8_t
const *buffer = imageData->getImageBuffer();
180 if (buffer ==
nullptr)
183 x = round(e->
x() / scale);
184 y = round(e->
y() / scale);
187 view->updateMagnifyingGlass(
x,
y);
189 view->updateMagnifyingGlass(-1, -1);
191 x = KSUtils::clamp(
x, 1.0, m_Width);
192 y = KSUtils::clamp(
y, 1.0, m_Height);
194 emit newStatus(QString(
"X:%1 Y:%2").arg(
static_cast<int>(
x)).arg(
static_cast<int>(
y)), FITS_POSITION);
200 emit mouseOverPixel(
x,
y);
202 int index =
y * m_Width +
x;
205 switch (imageData->getStatistics().dataType)
208 stringValue = QLocale().toString(buffer[index]);
212 stringValue = QLocale().toString((
reinterpret_cast<int16_t const*
>(buffer))[index]);
216 stringValue = QLocale().toString((
reinterpret_cast<uint16_t const*
>(buffer))[index]);
220 stringValue = QLocale().toString((
reinterpret_cast<int32_t const*
>(buffer))[index]);
224 stringValue = QLocale().toString((
reinterpret_cast<uint32_t const*
>(buffer))[index]);
228 stringValue = QLocale().toString((
reinterpret_cast<float const*
>(buffer))[index],
'f', 5);
232 stringValue = QLocale().toString(
static_cast<int>((
reinterpret_cast<int64_t const*
>(buffer))[index]));
236 stringValue = QLocale().toString((
reinterpret_cast<float const*
>(buffer))[index],
'f', 5);
245 if(view->isSelectionRectShown())
247 if (roiRB->geometry().contains(e->
pos()))
253 emit newStatus(stringValue, FITS_VALUE);
255 if (imageData->hasWCS() &&
256 !view->isSelectionRectShown() &&
257 view->getCursorMode() != FITSView::selectCursor)
259 QPointF wcsPixelPoint(
x,
y);
261 if(imageData->pixelToWCS(wcsPixelPoint, wcsCoord))
263 m_RA = wcsCoord.
ra0();
264 m_DE = wcsCoord.
dec0();
265 emit newStatus(QString(
"%1 , %2").arg(m_RA.toHMSString(), m_DE.toDMSString()), FITS_WCS);
268 bool objFound =
false;
269 for (
auto &listObject : imageData->getSkyObjects())
271 if ((std::abs(listObject->x() -
x) < 5 / scale) && (std::abs(listObject->y() -
y) < 5 / scale))
274 QToolTip::text() +
'\n' + listObject->skyObject()->name() +
'\n' + listObject->skyObject()->longname(),
this);
279 if (!objFound && !view->isSelectionRectShown())
283 double HFR = view->imageData()->getHFR(
x + 1,
y + 1, scale);
290 QString hfrStr = QString(
"HFR: %1").arg(HFR, 4,
'f', 2);
291 if (tip.
isEmpty() || tip == hfrStr)
295 QRegularExpression hfrRegEx(
"HFR\\: \\d+\\.\\d\\d");
316 float scale = (view->getCurrentZoom() / ZOOM_DEFAULT);
318 double x = round(e->
x() / scale);
319 double y = round(e->
y() / scale);
323 prevPoint = QPoint(
x,
y);
325 x = KSUtils::clamp(
x, 1.0, m_Width);
326 y = KSUtils::clamp(
y, 1.0, m_Height);
330 if(roiRB->geometry().contains(
x * scale,
y * scale))
331 isRoiSelected =
true;
334 if (view->getCursorMode() == FITSView::dragCursor && !isRoiSelected)
336 mouseButtonDown =
true;
338 view->updateMouseCursor();
343 const QSharedPointer<FITSData> &view_data = view->imageData();
344 if (view_data->hasWCS())
346 QPointF wcsPixelPoint(
x,
y);
348 if(view_data->pixelToWCS(wcsPixelPoint, wcsCoord))
350 auto ra = wcsCoord.
ra0();
354 "Slewing to Coordinates: \nRA: " + ra.toHMSString() +
355 "\nDec: " +
dec.toDMSString(),
359 centerTelescope(ra.Hours(),
dec.Degrees());
360 view->setCursorMode(view->lastMouseMode);
361 view->updateScopeButton();
370 const QSharedPointer<FITSData> &view_data = view->imageData();
374 mouseReleaseEvent(e);
375 if (view_data->hasWCS())
377 for (
auto &listObject : view_data->getSkyObjects())
379 if ((std::abs(listObject->x() -
x) < 10 / scale) && (std::abs(listObject->y() -
y) < 10 / scale))
381 SkyObject *
object = listObject->skyObject();
383 pmenu =
new KSPopupMenu();
384 object->initPopupMenu(pmenu);
388 if (action->text().left(7) ==
"Starhop")
390 if (action->text().left(7) ==
"Angular")
392 if (action->text().left(8) ==
"Add flag")
394 if (action->text().left(12) ==
"Attach Label")
404 if (fabs(view->markerCrosshair.x() -
x) <= 15 && fabs(view->markerCrosshair.y() -
y) <= 15)
405 emit markerSelected(0, 0);
411 if (view->getCursorMode() == FITSView::selectCursor)
412 emit pointSelected(
x,
y);
413 else if (view->getCursorMode() == FITSView::crosshairCursor)
414 emit pointSelected(
x + 5 / scale,
y + 5 / scale);
415 else if (view->showObjects)
416 emit highlightSelected(
x,
y);
420void FITSLabel::mouseDoubleClickEvent(
QMouseEvent *e)
424 x = round(e->
x() / (view->getCurrentZoom() / ZOOM_DEFAULT));
425 y = round(e->
y() / (view->getCurrentZoom() / ZOOM_DEFAULT));
427 x = KSUtils::clamp(
x, 1.0, m_Width);
428 y = KSUtils::clamp(
y, 1.0, m_Height);
430 emit markerSelected(
x,
y);
435void FITSLabel::centerTelescope(
double raJ2000,
double decJ2000)
439 if (INDIListener::Instance()->
size() == 0)
441 KSNotification::sorry(
i18n(
"KStars did not find any active mounts."));
445 for (
auto &oneDevice : INDIListener::devices())
447 if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE))
450 if (oneDevice->isConnected() ==
false)
452 KSNotification::error(
i18n(
"Mount %1 is offline. Please connect and retry again.", oneDevice->getDeviceName()));
456 auto mount = oneDevice->getMount();
460 SkyPoint selectedObject;
461 selectedObject.
setRA0(raJ2000);
462 selectedObject.
setDec0(decJ2000);
463 selectedObject.
apparentCoord(J2000, KStarsData::Instance()->ut().djd());
464 mount->Slew(&selectedObject);
468 KSNotification::sorry(
i18n(
"KStars did not find any active mounts."));
478void FITSLabel::showRubberBand(
bool on)
491void FITSLabel::zoomRubberBand(
double scale)
493 QRect r = roiRB->geometry() ;
495 if(prevscale == 0.0 )
499 double ow = r.
width() * scale / prevscale;
500 double oh = r.
height() * scale / prevscale;
503 rx = round(r.
topLeft().
x() * scale / prevscale);
504 ry = round(r.
topLeft().
y() * scale / prevscale);
516 roiRB->setGeometry(r);
520void FITSLabel::setRubberBand(
QRect rect)
522 float scale = (view->getCurrentZoom() / ZOOM_DEFAULT);
525 rx = round(
rect.topLeft().x() * scale );
526 ry = round(
rect.topLeft().y() * scale );
527 rect.setTopLeft(QPoint(rx, ry));
529 rx = round(
rect.bottomRight().x() * scale );
530 ry = round(
rect.bottomRight().y() * scale );
531 rect.setBottomRight(QPoint(rx, ry));
533 roiRB->setGeometry(
rect);
537void FITSLabel::updateROIToolTip(
const QPoint p)
539 auto result = QString(
"σ %1").arg(
QString::number(view->imageData()->getAverageStdDev(
true),
'f', 2));
540 result +=
"\nx̄ " +
QString::number(view->imageData()->getAverageMean(
true),
'f', 2);
541 result +=
"\nM " +
QString::number(view->imageData()->getAverageMedian(
true),
'f', 2);
static KStars * Instance()
void setClickedObject(SkyObject *o)
Set the ClickedObject pointer to the argument.
void apparentCoord(long double jd0, long double jdf)
Computes the apparent coordinates for this SkyPoint for any epoch, accounting for the effects of prec...
const CachingDms & ra0() const
void setRA0(dms r)
Sets RA0, the catalog Right Ascension.
const CachingDms & dec0() const
void setDec0(dms d)
Sets Dec0, the catalog Declination.
QString i18n(const char *text, const TYPE &arg...)
KIOCORE_EXPORT SimpleJob * mount(bool ro, const QByteArray &fstype, const QString &dev, const QString &point, JobFlags flags=DefaultFlags)
ButtonCode warningContinueCancel(QWidget *parent, const QString &text, const QString &title=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
void setAlphaF(float alpha)
Qt::KeyboardModifiers queryKeyboardModifiers()
QPoint globalPos() const const
void setBrush(ColorGroup group, ColorRole role, const QBrush &brush)
QPoint bottomRight() const const
void setBottomRight(const QPoint &position)
void setSize(const QSize &size)
void setTopLeft(const QPoint &position)
QPoint topLeft() const const
bool isNull() const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString number(double n, char format, int precision)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
QTextStream & dec(QTextStream &stream)
void showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect, int msecDisplayTime)