Skip to content

Commit

Permalink
Merge pull request #66 from matwey/feature/flip
Browse files Browse the repository at this point in the history
Flipping
  • Loading branch information
matwey authored Nov 13, 2017
2 parents 25e90d0 + ac4a8a7 commit 43308e5
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 2 deletions.
42 changes: 42 additions & 0 deletions include/flipwidget.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (C) 2017 Matwey V. Kornilov <[email protected]>
* Konstantin Malanchev <[email protected]>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef FLIPWIDGET_H
#define FLIPWIDGET_H

#include <QCheckBox>
#include <QWidget>

#include <memory>

class FlipWidget: public QWidget {
Q_OBJECT
private:
QCheckBox* h_flip_check_box_;
QCheckBox* v_flip_check_box_;
public:
explicit FlipWidget(QWidget *parent = Q_NULLPTR);
inline const QCheckBox* horizontalFlipCheckBox() const { return h_flip_check_box_; }
inline const QCheckBox* verticalFlipCheckBox() const { return v_flip_check_box_; }

public slots:
inline void setHorizontalFlip(bool flipped) { h_flip_check_box_->setChecked(flipped); }
inline void setVerticalFlip(bool flipped) { v_flip_check_box_->setChecked(flipped); }
};

#endif //FLIPWIDGET_H
6 changes: 6 additions & 0 deletions include/opengltransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class OpenGLTransform:

float angle_;
QRectF viewrect_;
bool h_flip_, v_flip_;

virtual void updateTransform() const;
public:
Expand All @@ -46,6 +47,11 @@ class OpenGLTransform:

const QRectF& viewrect() const { return viewrect_; }
void setViewrect(const QRectF& viewrect);

const bool& horizontalFlip() const { return h_flip_; }
void setHorizontalFlip(bool flip);
const bool& verticalFlip() const { return v_flip_; }
void setVerticalFlip(bool flip);
};

class WidgetToFitsOpenGLTransform:
Expand Down
8 changes: 8 additions & 0 deletions include/openglwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,20 @@ private slots:
private:
OpenGLTransform opengl_transform_;
WidgetToFitsOpenGLTransform widget_to_fits_;
protected:
void flipViewrect(Qt::Axis flip_axis);
public:
inline double rotation() const { return opengl_transform_.rotation(); }
inline const bool& horizontalFlip() const { return opengl_transform_.horizontalFlip(); }
inline const bool& verticalFlip() const { return opengl_transform_.verticalFlip(); }
public slots:
void setRotation(double angle);
void setHorizontalFlip(bool flip);
void setVerticalFlip(bool flip);
signals:
void rotationChanged(double angle);
void horizontalFlipChanged(bool flip);
void verticalFlipChanged(bool flip);

private:
std::unique_ptr<OpenGLShaderUniforms> shader_uniforms_;
Expand Down
1 change: 0 additions & 1 deletion include/viewrect.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ class Viewrect: public QObject {

inline const QRectF& view() const { return view_; }
inline const QRect& scroll() const { return scroll_; }
inline QRectF openGLprojection() const { return {view_.left(), -view_.top(), view_.width(), -view_.height()}; }
inline int scrollRange() const { return scroll_range_; } // scroll range should be set to [0, scroll_range_]
void fitToBorder(QSizeF ratio);

Expand Down
33 changes: 33 additions & 0 deletions src/flipwidget.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2017 Matwey V. Kornilov <[email protected]>
* Konstantin Malanchev <[email protected]>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <QVBoxLayout>

#include <flipwidget.h>

FlipWidget::FlipWidget(QWidget *parent):
QWidget(parent),
h_flip_check_box_(new QCheckBox(tr("Horizontal flipping"), this)),
v_flip_check_box_(new QCheckBox(tr("Vertical flipping"), this)) {

std::unique_ptr<QVBoxLayout> widget_layout{new QVBoxLayout(this)};
widget_layout->addWidget(h_flip_check_box_);
widget_layout->addWidget(v_flip_check_box_);
widget_layout->addStretch(1);
setLayout(widget_layout.release());
}
25 changes: 25 additions & 0 deletions src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <QMessageBox>

#include <application.h>
#include <flipwidget.h>
#include <mainwindow.h>
#include <rotationwidget.h>

Expand Down Expand Up @@ -197,6 +198,30 @@ MainWindow::MainWindow(const QString& fits_filename, QWidget *parent):
rotation_dock->setWidget(rotation_widget.release());
addDockWidget(Qt::RightDockWidgetArea, rotation_dock.release());

std::unique_ptr<QDockWidget> flip_dock{new QDockWidget(tr("Flipping"))};
flip_dock->setAllowedAreas(Qt::AllDockWidgetAreas);
view_menu->addAction(flip_dock->toggleViewAction());
flip_dock->toggleViewAction()->setShortcut(tr("Ctrl+F"));
std::unique_ptr<FlipWidget> flip_widget{new FlipWidget(this)};
connect(
scrollZoomArea()->viewport(), SIGNAL(horizontalFlipChanged(bool)),
flip_widget->horizontalFlipCheckBox(), SLOT(setChecked(bool))
);
connect(
scrollZoomArea()->viewport(), SIGNAL(verticalFlipChanged(bool)),
flip_widget->verticalFlipCheckBox(), SLOT(setChecked(bool))
);
connect(
flip_widget->horizontalFlipCheckBox(), SIGNAL(clicked(bool)),
scrollZoomArea()->viewport(), SLOT(setHorizontalFlip(bool))
);
connect(
flip_widget->verticalFlipCheckBox(), SIGNAL(clicked(bool)),
scrollZoomArea()->viewport(), SLOT(setVerticalFlip(bool))
);
flip_dock->setWidget(flip_widget.release());
addDockWidget(Qt::RightDockWidgetArea, flip_dock.release());

std::unique_ptr<QDockWidget> colormap_dock{new QDockWidget(tr("Color map"), this)};
colormap_dock->setAllowedAreas(Qt::AllDockWidgetAreas);
view_menu->addAction(colormap_dock->toggleViewAction());
Expand Down
21 changes: 20 additions & 1 deletion src/opengltransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ OpenGLTransform::OpenGLTransform(QObject* parent):
expired_(true),
matrix_(), // QMatrix4x4() constructs an unity matrix
angle_(0),
h_flip_(false),
v_flip_(false),
viewrect_(-1, -1, 2, 2)
{}
OpenGLTransform::OpenGLTransform(const QRectF& viewrect, QObject* parent):
Expand All @@ -40,6 +42,7 @@ void OpenGLTransform::updateTransform() const {
matrix_.setToIdentity();
matrix_.ortho(QRectF{viewrect_.left(), -viewrect_.top(), viewrect_.width(), -viewrect_.height()});
matrix_.rotate(angle_, static_cast<float>(0), static_cast<float>(0), static_cast<float>(1));
matrix_.scale(h_flip_ ? -1 : 1, v_flip_ ? -1 : 1);

expired_ = false;
}
Expand All @@ -64,6 +67,21 @@ void OpenGLTransform::setViewrect(const QRectF& viewrect) {
expired_ = true;
}

void OpenGLTransform::setHorizontalFlip(bool flip) {
if (h_flip_ == flip) return;

h_flip_ = flip;
expired_ = true;
}

void OpenGLTransform::setVerticalFlip(bool flip) {
if (v_flip_ == flip) return;

v_flip_ = flip;
expired_ = true;
}


WidgetToFitsOpenGLTransform::WidgetToFitsOpenGLTransform(QObject* parent):
OpenGLTransform(parent) {}

Expand All @@ -88,6 +106,8 @@ void WidgetToFitsOpenGLTransform::updateTransform() const {
matrix_.scale(static_cast<float>(0.5)/(scale_*image_size_.width()),
static_cast<float>(0.5)/(scale_*image_size_.height()));

/* flip */
matrix_.scale(h_flip_ ? -1 : 1, v_flip_ ? -1 : 1);
/* world unrotated */
matrix_.rotate(-angle_, static_cast<float>(0), static_cast<float>(0), static_cast<float>(1));
/* viewrect to world */
Expand Down Expand Up @@ -125,4 +145,3 @@ void WidgetToFitsOpenGLTransform::setWidgetSize(const QSize& widget_size) {
widget_size_ = widget_size;
expired_ = true;
}

44 changes: 44 additions & 0 deletions src/openglwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ OpenGLWidget::OpenGLWidget(QWidget *parent, const FITS::HeaderDataUnit& hdu):
connect(&viewrect_, SIGNAL(viewChanged(const QRectF&)), this, SLOT(viewChanged(const QRectF&)));
connect(&viewrect_, SIGNAL(scrollChanged(const QRect&)), this, SLOT(update()));
connect(this, SIGNAL(rotationChanged(double)), this, SLOT(update()));
connect(this, SIGNAL(horizontalFlipChanged(bool)), this, SLOT(update()));
connect(this, SIGNAL(verticalFlipChanged(bool)), this, SLOT(update()));
setMouseTracking(true); // We need it to catch mouseEvent when mouse buttons aren't pressed
}

Expand Down Expand Up @@ -338,4 +340,46 @@ void OpenGLWidget::setRotation(double angle) {
emit rotationChanged(rotation());
}

void OpenGLWidget::flipViewrect(Qt::Axis flip_axis) {
QMatrix4x4 rotation_matrix;
rotation_matrix.rotate(-rotation(), 0, 0, 1);
auto unrotated_view_center = rotation_matrix.transposed().map(viewrect_.view().center());
switch (flip_axis) {
case Qt::XAxis:
unrotated_view_center.setX(-unrotated_view_center.x());
break;
case Qt::YAxis:
unrotated_view_center.setY(-unrotated_view_center.y());
break;
default:
Q_ASSERT(false);
}
const auto view_center = rotation_matrix.map(unrotated_view_center);
auto new_view = viewrect_.view();
new_view.moveCenter(view_center);
viewrect_.setView(new_view);
}

void OpenGLWidget::setHorizontalFlip(bool flip) {
if (horizontalFlip() == flip) return;

flipViewrect(Qt::XAxis);

opengl_transform_.setHorizontalFlip(flip);
widget_to_fits_.setHorizontalFlip(flip);

emit horizontalFlipChanged(horizontalFlip());
}

void OpenGLWidget::setVerticalFlip(bool flip) {
if (verticalFlip() == flip) return;

flipViewrect(Qt::YAxis);

opengl_transform_.setVerticalFlip(flip);
widget_to_fits_.setVerticalFlip(flip);

emit verticalFlipChanged(verticalFlip());
}

constexpr const GLfloat OpenGLWidget::uv_data[];

0 comments on commit 43308e5

Please sign in to comment.