Improved zoom and scrolling
This commit is contained in:
parent
74aee15f80
commit
26666ee36d
@ -162,7 +162,9 @@ void ImageWidget::setImage(std::shared_ptr<RawImage> image, int index)
|
||||
f->glDeleteTextures(1, &m_debayerTex);
|
||||
m_debayerTex = 0;
|
||||
}
|
||||
update();
|
||||
|
||||
if(m_bestFit)bestFit();
|
||||
else setOffset(m_dx, m_dy);
|
||||
}
|
||||
|
||||
void ImageWidget::setWCS(std::shared_ptr<WCSData> wcs)
|
||||
@ -170,10 +172,35 @@ void ImageWidget::setWCS(std::shared_ptr<WCSData> wcs)
|
||||
m_wcs = wcs;
|
||||
}
|
||||
|
||||
void ImageWidget::setScale(float scale)
|
||||
void ImageWidget::zoom(int zoom, const QPointF &mousePos)
|
||||
{
|
||||
m_scale = scale;
|
||||
update();
|
||||
m_bestFit = false;
|
||||
if(zoom != 0)
|
||||
m_scaleStop = std::clamp(m_scaleStop + (zoom > 0 ? 1 : -1), -10, 10);
|
||||
else
|
||||
m_scaleStop = 0;
|
||||
|
||||
QPointF focus(m_width * 0.5f, m_height * 0.5f);
|
||||
if(!mousePos.isNull())
|
||||
focus = mousePos;
|
||||
|
||||
if(width() > m_image->width() * m_scale)
|
||||
m_dx = -width() * 0.5f + m_image->width() * m_scale * 0.5f;
|
||||
if(height() > m_image->height() * m_scale)
|
||||
m_dy = -height() * 0.5f + m_image->height() * m_scale * 0.5f;
|
||||
|
||||
float newScale = std::sqrt(std::pow(2.0f, (float)m_scaleStop));
|
||||
float r = newScale / m_scale;
|
||||
m_scale = newScale;
|
||||
|
||||
setOffset(m_dx * r + focus.x() * (r - 1), m_dy * r + focus.y() * (r - 1));
|
||||
}
|
||||
|
||||
void ImageWidget::bestFit()
|
||||
{
|
||||
m_bestFit = true;
|
||||
m_scale = std::min((float)m_width/m_imgWidth, (float)m_height/m_imgHeight);
|
||||
setOffset(0, 0);
|
||||
}
|
||||
|
||||
void ImageWidget::blockRepaint(bool block)
|
||||
@ -203,6 +230,19 @@ void ImageWidget::allocateThumbnails(const QStringList &paths)
|
||||
m_thumbnailTexture->allocateStorage();
|
||||
}
|
||||
|
||||
QVector2D ImageWidget::getImagePixelCoord(const QVector2D &pos)
|
||||
{
|
||||
float dx = m_dx;
|
||||
float dy = m_dy;
|
||||
if(m_width > m_image->width()*m_scale)
|
||||
dx = -width()*0.5f + m_image->width()*m_scale*0.5f;
|
||||
if(m_height > m_image->height()*m_scale)
|
||||
dy = -height()*0.5f + m_image->height()*m_scale*0.5f;
|
||||
|
||||
QVector2D offset(dx, dy);
|
||||
return (pos + offset) / m_scale;
|
||||
}
|
||||
|
||||
void ImageWidget::setMTFParams(float low, float mid, float high)
|
||||
{
|
||||
m_low = low;
|
||||
@ -211,10 +251,14 @@ void ImageWidget::setMTFParams(float low, float mid, float high)
|
||||
update();
|
||||
}
|
||||
|
||||
void ImageWidget::setOffset(int dx, int dy)
|
||||
void ImageWidget::setOffset(float dx, float dy)
|
||||
{
|
||||
m_dx = dx;
|
||||
m_dy = dy;
|
||||
m_dx = std::clamp(dx, 0.0f, m_imgWidth * m_scale - m_width);
|
||||
if(m_showThumbnails)
|
||||
m_dy = std::clamp(dy, 0.0f, (float)((m_thumbnailCount / (m_width / THUMB_SIZE_BORDER) + 2) * THUMB_SIZE_BORDER_Y - m_height));
|
||||
else
|
||||
m_dy = std::clamp(dy, 0.0f, m_imgHeight * m_scale - m_height);
|
||||
updateScrollBars();
|
||||
update();
|
||||
}
|
||||
|
||||
@ -269,6 +313,7 @@ void ImageWidget::thumbnailLoaded(const Image *image)
|
||||
void ImageWidget::showThumbnail(bool enable)
|
||||
{
|
||||
m_showThumbnails = enable;
|
||||
updateScrollBars();
|
||||
update();
|
||||
}
|
||||
|
||||
@ -278,10 +323,10 @@ void ImageWidget::paintGL()
|
||||
|
||||
float dx = m_dx;
|
||||
float dy = m_dy;
|
||||
if(width() > m_image->width()*m_scale)
|
||||
dx = -width()*0.5f + m_image->width()*m_scale*0.5f;
|
||||
if(height() > m_image->height()*m_scale)
|
||||
dy = -height()*0.5f + m_image->height()*m_scale*0.5f;
|
||||
if(m_width > m_image->width() * m_scale)
|
||||
dx = -width() * 0.5f + m_image->width() * m_scale * 0.5f;
|
||||
if(m_height > m_image->height() * m_scale)
|
||||
dy = -height() * 0.5f + m_image->height() * m_scale * 0.5f;
|
||||
QBrush highlight = style()->standardPalette().highlight();
|
||||
|
||||
if(m_showThumbnails)
|
||||
@ -374,6 +419,8 @@ void ImageWidget::resizeGL(int w, int h)
|
||||
m_width = w;
|
||||
m_height = h;
|
||||
f->glViewport(0, 0, w, h);
|
||||
if(m_bestFit)bestFit();
|
||||
updateScrollBars();
|
||||
}
|
||||
|
||||
void ImageWidget::initializeGL()
|
||||
@ -536,7 +583,10 @@ void ImageWidget::mousePressEvent(QMouseEvent *event)
|
||||
thumbSelect(event);
|
||||
}
|
||||
else
|
||||
event->ignore();
|
||||
{
|
||||
if(event->button() == Qt::LeftButton)
|
||||
m_lastPos = event->localPos();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
@ -545,21 +595,17 @@ void ImageWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
thumbSelect(event);
|
||||
}
|
||||
else
|
||||
event->ignore();
|
||||
else if(!m_lastPos.isNull())
|
||||
{
|
||||
QPointF off = event->localPos() - m_lastPos;
|
||||
m_lastPos = event->localPos();
|
||||
setOffset(m_dx - off.x(), m_dy - off.y());
|
||||
return;
|
||||
}
|
||||
|
||||
if(!m_showThumbnails && m_rawImage)
|
||||
{
|
||||
float dx = m_dx;
|
||||
float dy = m_dy;
|
||||
if(width() > m_image->width()*m_scale)
|
||||
dx = -width()*0.5f + m_image->width()*m_scale*0.5f;
|
||||
if(height() > m_image->height()*m_scale)
|
||||
dy = -height()*0.5f + m_image->height()*m_scale*0.5f;
|
||||
|
||||
QVector2D offset(dx, dy);
|
||||
QVector2D pos = QVector2D(event->pos());
|
||||
QVector2D pix = (pos + offset) / m_scale;
|
||||
QVector2D pix = getImagePixelCoord(QVector2D(event->pos()));
|
||||
QVector3D rgb;
|
||||
|
||||
SkyPoint sky;
|
||||
@ -604,7 +650,24 @@ void ImageWidget::mouseReleaseEvent(QMouseEvent *event)
|
||||
m_database->unmark(unmark);
|
||||
}
|
||||
else
|
||||
event->ignore();
|
||||
{
|
||||
m_lastPos = QPointF();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageWidget::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if(m_showThumbnails)
|
||||
{
|
||||
m_dy = std::clamp(m_dy - event->angleDelta().y(), 0.0f, (float)m_thumbnailCount / (width() / THUMB_SIZE_BORDER) * THUMB_SIZE_BORDER_Y);
|
||||
update();
|
||||
updateScrollBars();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(event->angleDelta().y() != 0)
|
||||
zoom(event->angleDelta().y(), event->modifiers() & Qt::ShiftModifier ? QPointF() : event->posF());
|
||||
}
|
||||
}
|
||||
|
||||
void ImageWidget::thumbSelect(QMouseEvent *event)
|
||||
@ -671,6 +734,16 @@ void ImageWidget::debayer()
|
||||
m_whiteBalance[2] = maxRGB / pixel[2];
|
||||
}
|
||||
|
||||
void ImageWidget::updateScrollBars()
|
||||
{
|
||||
if(m_showThumbnails)
|
||||
emit scrollBarsUpdate(0, 0, -1, m_dy, m_height, (m_thumbnailCount / (m_width / THUMB_SIZE_BORDER) + 2) * THUMB_SIZE_BORDER_Y - m_height);
|
||||
else
|
||||
{
|
||||
emit scrollBarsUpdate(m_dx, m_width, m_imgWidth * m_scale - m_width, m_dy, m_height, m_imgHeight * m_scale - m_height);
|
||||
}
|
||||
}
|
||||
|
||||
ImageScrollAreaGL::ImageScrollAreaGL(Database *database, QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
@ -680,9 +753,6 @@ ImageScrollAreaGL::ImageScrollAreaGL(Database *database, QWidget *parent) : QWid
|
||||
|
||||
m_verticalScrollBar = new QScrollBar(Qt::Vertical, this);
|
||||
m_horizontalScrollBar = new QScrollBar(Qt::Horizontal, this);
|
||||
m_scale = 1.0f;
|
||||
m_bestFit = false;
|
||||
m_thumbCount = 0;
|
||||
|
||||
layout->setSpacing(0);
|
||||
layout->addWidget(m_imageWidget, 0, 0);
|
||||
@ -691,6 +761,7 @@ ImageScrollAreaGL::ImageScrollAreaGL(Database *database, QWidget *parent) : QWid
|
||||
|
||||
connect(m_verticalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollEvent()));
|
||||
connect(m_horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollEvent()));
|
||||
connect(m_imageWidget, &ImageWidget::scrollBarsUpdate, this, &ImageScrollAreaGL::updateScrollbars);
|
||||
}
|
||||
|
||||
ImageScrollAreaGL::~ImageScrollAreaGL()
|
||||
@ -704,10 +775,6 @@ void ImageScrollAreaGL::setImage(Image *image)
|
||||
{
|
||||
m_imageWidget->setImage(image->rawImage(), image->number());
|
||||
m_imageWidget->setWCS(image->info().wcs);
|
||||
m_imgWidth = image->rawImage()->width();
|
||||
m_imgHeight = image->rawImage()->height();
|
||||
if(m_bestFit)bestFit();
|
||||
updateScrollbars();
|
||||
}
|
||||
}
|
||||
|
||||
@ -716,124 +783,49 @@ ImageWidget *ImageScrollAreaGL::imageWidget()
|
||||
return m_imageWidget;
|
||||
}
|
||||
|
||||
void ImageScrollAreaGL::setThumbnails(int count)
|
||||
void ImageScrollAreaGL::updateScrollbars(int valueH, int stepH, int maxH, int valueV, int stepV, int maxV)
|
||||
{
|
||||
m_thumbCount = count;
|
||||
if(m_thumbCount)
|
||||
if(maxH > 0)
|
||||
{
|
||||
m_verticalScrollBar->setRange(0, m_thumbCount / (m_imageWidget->width() / THUMB_SIZE_BORDER) * THUMB_SIZE_BORDER_Y);
|
||||
m_verticalScrollBar->setPageStep(THUMB_SIZE_BORDER_Y);
|
||||
m_horizontalScrollBar->show();
|
||||
m_horizontalScrollBar->setRange(0, maxH);
|
||||
m_horizontalScrollBar->setPageStep(stepH);
|
||||
m_horizontalScrollBar->setValue(valueH);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_verticalScrollBar->setPageStep(m_imageWidget->height());
|
||||
m_horizontalScrollBar->setPageStep(m_imageWidget->width());
|
||||
}
|
||||
updateScrollbars();
|
||||
}
|
||||
|
||||
void ImageScrollAreaGL::updateScrollbars(bool zoom)
|
||||
{
|
||||
if(m_thumbCount)
|
||||
{
|
||||
m_horizontalScrollBar->hide();
|
||||
|
||||
if(maxV > 0)
|
||||
{
|
||||
m_verticalScrollBar->show();
|
||||
m_verticalScrollBar->setRange(0, m_thumbCount / (m_imageWidget->width() / THUMB_SIZE_BORDER) * THUMB_SIZE_BORDER_Y);
|
||||
m_verticalScrollBar->setPageStep(THUMB_SIZE_BORDER_Y);
|
||||
m_verticalScrollBar->setRange(0, maxV);
|
||||
m_verticalScrollBar->setPageStep(stepV);
|
||||
m_verticalScrollBar->setValue(valueV);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(zoom)
|
||||
{
|
||||
setScrollRange(m_verticalScrollBar, m_imgHeight*m_scale);
|
||||
setScrollRange(m_horizontalScrollBar, m_imgWidth*m_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_verticalScrollBar->setRange(0, m_imgHeight*m_scale - m_verticalScrollBar->pageStep());
|
||||
m_horizontalScrollBar->setRange(0, m_imgWidth*m_scale - m_horizontalScrollBar->pageStep());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImageScrollAreaGL::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
if(m_thumbCount)
|
||||
{
|
||||
m_verticalScrollBar->setRange(0, m_thumbCount / (m_imageWidget->width() / THUMB_SIZE_BORDER) * THUMB_SIZE_BORDER_Y);
|
||||
m_verticalScrollBar->setPageStep(THUMB_SIZE_BORDER_Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_verticalScrollBar->setPageStep(m_imageWidget->height());
|
||||
m_horizontalScrollBar->setPageStep(m_imageWidget->width());
|
||||
}
|
||||
updateScrollbars();
|
||||
}
|
||||
|
||||
void ImageScrollAreaGL::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
QPoint delta = m_lastPos - event->pos();
|
||||
if(m_thumbCount == 0)m_horizontalScrollBar->setValue(m_horizontalScrollBar->value() + delta.x());
|
||||
m_verticalScrollBar->setValue(m_verticalScrollBar->value() + delta.y());
|
||||
m_lastPos = event->pos();
|
||||
}
|
||||
|
||||
void ImageScrollAreaGL::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
m_lastPos = event->pos();
|
||||
}
|
||||
|
||||
void ImageScrollAreaGL::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if(m_thumbCount)
|
||||
{
|
||||
m_verticalScrollBar->setValue(m_verticalScrollBar->value() - event->angleDelta().y());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bestFit = false;
|
||||
if(event->angleDelta().y() != 0)
|
||||
zoom(event->angleDelta().y() / 1200.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void ImageScrollAreaGL::zoom(float delta)
|
||||
{
|
||||
if((m_scale >= 8.0f && delta > 0) || (m_scale <= 0.1f && delta < 0))return;
|
||||
|
||||
m_scale += delta;
|
||||
m_imageWidget->blockRepaint(true);
|
||||
m_imageWidget->setScale(m_scale);
|
||||
updateScrollbars(true);
|
||||
m_imageWidget->blockRepaint(false);
|
||||
m_verticalScrollBar->hide();
|
||||
}
|
||||
|
||||
void ImageScrollAreaGL::zoomIn()
|
||||
{
|
||||
zoom(0.1f);
|
||||
m_bestFit = false;
|
||||
m_imageWidget->zoom(1);
|
||||
}
|
||||
|
||||
void ImageScrollAreaGL::zoomOut()
|
||||
{
|
||||
zoom(-0.1f);
|
||||
m_bestFit = false;
|
||||
m_imageWidget->zoom(-1);
|
||||
}
|
||||
|
||||
void ImageScrollAreaGL::bestFit()
|
||||
{
|
||||
m_bestFit = true;
|
||||
m_scale = std::min((float)m_imageWidget->width()/m_imgWidth, (float)m_imageWidget->height()/m_imgHeight);
|
||||
zoom(0.0f);
|
||||
m_horizontalScrollBar->hide();
|
||||
m_verticalScrollBar->hide();
|
||||
m_imageWidget->bestFit();
|
||||
}
|
||||
|
||||
void ImageScrollAreaGL::oneToOne()
|
||||
{
|
||||
m_scale = 1.0f;
|
||||
zoom(0.0f);
|
||||
m_bestFit = false;
|
||||
m_imageWidget->zoom(0);
|
||||
}
|
||||
|
||||
void ImageScrollAreaGL::scrollEvent()
|
||||
|
@ -52,6 +52,8 @@ class ImageWidget : public QOpenGLWidget
|
||||
float m_range;
|
||||
float m_dx, m_dy;
|
||||
float m_scale;
|
||||
int m_scaleStop = 0;
|
||||
bool m_bestFit = false;
|
||||
float m_whiteBalance[3] = {1.0f, 1.0f, 1.0f};
|
||||
bool m_blockRepaint;
|
||||
bool m_bwImg;
|
||||
@ -66,18 +68,21 @@ class ImageWidget : public QOpenGLWidget
|
||||
int m_maxArrayLayers;
|
||||
QVector<ImageThumb> m_thumnails;
|
||||
Database *m_database;
|
||||
QPointF m_lastPos;
|
||||
public:
|
||||
explicit ImageWidget(Database *database, QWidget *parent = nullptr);
|
||||
~ImageWidget() override;
|
||||
void setImage(std::shared_ptr<RawImage> image, int index);
|
||||
void setImage(const QPixmap &pixmap);
|
||||
void setWCS(std::shared_ptr<WCSData> wcs);
|
||||
void setScale(float scale);
|
||||
void zoom(int zoom, const QPointF &mousePos = QPointF());
|
||||
void bestFit();
|
||||
void blockRepaint(bool block);
|
||||
void allocateThumbnails(const QStringList &paths);
|
||||
QVector2D getImagePixelCoord(const QVector2D &pos);
|
||||
public slots:
|
||||
void setMTFParams(float low, float mid, float high);
|
||||
void setOffset(int dx, int dy);
|
||||
void setOffset(float dx, float dy);
|
||||
void superPixel(bool enable);
|
||||
void invert(bool enable);
|
||||
QImage renderToImage();
|
||||
@ -92,11 +97,14 @@ protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void wheelEvent(QWheelEvent *event) override;
|
||||
void thumbSelect(QMouseEvent *event);
|
||||
void debayer();
|
||||
void updateScrollBars();
|
||||
signals:
|
||||
void fileDropped(const QString &path);
|
||||
void status(const QString &value, const QString &pixelCoords, const QString &celestialCoords);
|
||||
void scrollBarsUpdate(int valueH, int stepH, int maxH, int valueV, int stepV, int maxV);
|
||||
};
|
||||
|
||||
class ImageScrollAreaGL : public QWidget
|
||||
@ -105,24 +113,13 @@ class ImageScrollAreaGL : public QWidget
|
||||
QScrollBar *m_verticalScrollBar;
|
||||
QScrollBar *m_horizontalScrollBar;
|
||||
ImageWidget *m_imageWidget;
|
||||
int m_imgWidth, m_imgHeight;
|
||||
QPoint m_lastPos;
|
||||
float m_scale;
|
||||
bool m_bestFit;
|
||||
int m_thumbCount;
|
||||
public:
|
||||
explicit ImageScrollAreaGL(Database *database, QWidget *parent = nullptr);
|
||||
~ImageScrollAreaGL() override;
|
||||
void setImage(Image *image);
|
||||
ImageWidget* imageWidget();
|
||||
void setThumbnails(int count);
|
||||
protected:
|
||||
void updateScrollbars(bool zoom = false);
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void wheelEvent(QWheelEvent *event) override;
|
||||
void zoom(float delta);
|
||||
void updateScrollbars(int valueH, int stepH, int maxH, int valueV, int stepV, int maxV);
|
||||
public slots:
|
||||
void zoomIn();
|
||||
void zoomOut();
|
||||
|
@ -160,7 +160,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
if(SettingsDialog::loadThumbsizes())m_ringList->clearThumbnails();
|
||||
m_imageGL->imageWidget()->allocateThumbnails(m_ringList->imageNames());
|
||||
m_imageGL->imageWidget()->showThumbnail(checked);
|
||||
m_imageGL->setThumbnails(checked ? m_ringList->imageCount() : 0);
|
||||
if(checked)m_ringList->loadThumbnails();
|
||||
else m_ringList->stopLoading();
|
||||
}, Qt::Key_F2);
|
||||
|
Loading…
x
Reference in New Issue
Block a user