rework ImportDialog and remove ImageCropper
This commit is contained in:
parent
23663d389b
commit
d6968792aa
7 changed files with 8 additions and 831 deletions
|
@ -86,7 +86,6 @@ set(GTA5VIEW_SOURCES
|
||||||
src/StringParser.cpp
|
src/StringParser.cpp
|
||||||
src/TranslationClass.cpp
|
src/TranslationClass.cpp
|
||||||
src/UserInterface.cpp
|
src/UserInterface.cpp
|
||||||
src/anpro/imagecropper.cpp
|
|
||||||
src/pcg/pcg_basic.c
|
src/pcg/pcg_basic.c
|
||||||
src/uimod/JSHighlighter.cpp
|
src/uimod/JSHighlighter.cpp
|
||||||
src/uimod/UiModLabel.cpp
|
src/uimod/UiModLabel.cpp
|
||||||
|
@ -127,7 +126,6 @@ set(GTA5VIEW_HEADERS
|
||||||
src/StringParser.h
|
src/StringParser.h
|
||||||
src/TranslationClass.h
|
src/TranslationClass.h
|
||||||
src/UserInterface.h
|
src/UserInterface.h
|
||||||
src/anpro/imagecropper.h
|
|
||||||
src/pcg/pcg_basic.h
|
src/pcg/pcg_basic.h
|
||||||
src/uimod/JSHighlighter.h
|
src/uimod/JSHighlighter.h
|
||||||
src/uimod/UiModLabel.h
|
src/uimod/UiModLabel.h
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "SnapmaticPicture.h"
|
#include "SnapmaticPicture.h"
|
||||||
#include "StandardPaths.h"
|
#include "StandardPaths.h"
|
||||||
#include "ImportDialog.h"
|
#include "ImportDialog.h"
|
||||||
#include "imagecropper.h"
|
|
||||||
#include "AppEnv.h"
|
#include "AppEnv.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <QStringBuilder>
|
#include <QStringBuilder>
|
||||||
|
@ -86,9 +85,9 @@ ImportDialog::ImportDialog(QString profileName, QWidget *parent) :
|
||||||
ui->cbResolution->addItem("GTA V (536p)", QSize(960, 536));
|
ui->cbResolution->addItem("GTA V (536p)", QSize(960, 536));
|
||||||
ui->cbResolution->addItem("FiveM (1072p)", QSize(1920, 1072));
|
ui->cbResolution->addItem("FiveM (1072p)", QSize(1920, 1072));
|
||||||
ui->cbResolution->addItem("RDR 2 (1080p)", QSize(1920, 1080));
|
ui->cbResolution->addItem("RDR 2 (1080p)", QSize(1920, 1080));
|
||||||
ui->cbResolution->addItem("Preset (720p)", QSize(1280, 720));
|
ui->cbResolution->addItem("HD (720p)", QSize(1280, 720));
|
||||||
ui->cbResolution->addItem("Preset (1440p)", QSize(2560, 1440));
|
ui->cbResolution->addItem("WQHD (1440p)", QSize(2560, 1440));
|
||||||
ui->cbResolution->addItem("Preset (2160p)", QSize(3840, 2160));
|
ui->cbResolution->addItem("4K/UHD (2160p)", QSize(3840, 2160));
|
||||||
|
|
||||||
// Set Import Settings
|
// Set Import Settings
|
||||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||||
|
@ -120,11 +119,10 @@ ImportDialog::ImportDialog(QString profileName, QWidget *parent) :
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Options menu
|
// Options menu
|
||||||
optionsMenu.addAction(tr("&Import new Picture..."), this, SLOT(importNewPicture()));
|
optionsMenu.addAction(tr("&Import new Picture..."), this, &ImportDialog::importNewPicture);
|
||||||
optionsMenu.addAction(tr("&Crop Picture..."), this, SLOT(cropPicture()));
|
|
||||||
optionsMenu.addSeparator();
|
optionsMenu.addSeparator();
|
||||||
optionsMenu.addAction(tr("&Load Settings..."), this, SLOT(loadImportSettings()));
|
optionsMenu.addAction(tr("&Load Settings..."), this, &ImportDialog::loadImportSettings);
|
||||||
optionsMenu.addAction(tr("&Save Settings..."), this, SLOT(saveImportSettings()));
|
optionsMenu.addAction(tr("&Save Settings..."), this, &ImportDialog::saveImportSettings);
|
||||||
ui->cmdOptions->setMenu(&optionsMenu);
|
ui->cmdOptions->setMenu(&optionsMenu);
|
||||||
|
|
||||||
const QSize windowSize = sizeHint();
|
const QSize windowSize = sizeHint();
|
||||||
|
@ -439,72 +437,6 @@ void ImportDialog::saveSettings(QString settingsProfile)
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportDialog::cropPicture()
|
|
||||||
{
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
|
|
||||||
QDialog cropDialog(this);
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
cropDialog.setObjectName(QStringLiteral("CropDialog"));
|
|
||||||
#else
|
|
||||||
cropDialog.setObjectName(QString::fromUtf8("CropDialog"));
|
|
||||||
#endif
|
|
||||||
cropDialog.setWindowTitle(tr("Crop Picture..."));
|
|
||||||
cropDialog.setWindowFlags(cropDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
|
||||||
cropDialog.setModal(true);
|
|
||||||
|
|
||||||
QVBoxLayout cropLayout;
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
cropLayout.setObjectName(QStringLiteral("CropLayout"));
|
|
||||||
#else
|
|
||||||
cropLayout.setObjectName(QString::fromUtf8("CropLayout"));
|
|
||||||
#endif
|
|
||||||
cropLayout.setContentsMargins(0, 0, 0, 0);
|
|
||||||
cropLayout.setSpacing(0);
|
|
||||||
cropDialog.setLayout(&cropLayout);
|
|
||||||
|
|
||||||
ImageCropper imageCropper(&cropDialog);
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
imageCropper.setObjectName(QStringLiteral("ImageCropper"));
|
|
||||||
#else
|
|
||||||
imageCropper.setObjectName(QString::fromUtf8("ImageCropper"));
|
|
||||||
#endif
|
|
||||||
imageCropper.setBackgroundColor(Qt::black);
|
|
||||||
imageCropper.setCroppingRectBorderColor(QColor(255, 255, 255, 127));
|
|
||||||
imageCropper.setImage(QPixmap::fromImage(origImage, Qt::AutoColor));
|
|
||||||
imageCropper.setProportion(QSize(1, 1));
|
|
||||||
imageCropper.setFixedSize(workImage.size());
|
|
||||||
cropLayout.addWidget(&imageCropper);
|
|
||||||
|
|
||||||
QHBoxLayout buttonLayout;
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
cropLayout.setObjectName(QStringLiteral("ButtonLayout"));
|
|
||||||
#else
|
|
||||||
cropLayout.setObjectName(QString::fromUtf8("ButtonLayout"));
|
|
||||||
#endif
|
|
||||||
cropLayout.addLayout(&buttonLayout);
|
|
||||||
|
|
||||||
QPushButton cropButton(&cropDialog);
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
cropButton.setObjectName(QStringLiteral("CropButton"));
|
|
||||||
#else
|
|
||||||
cropButton.setObjectName(QString::fromUtf8("CropButton"));
|
|
||||||
#endif
|
|
||||||
cropButton.setMinimumSize(0, 40 * screenRatio);
|
|
||||||
cropButton.setText(tr("&Crop"));
|
|
||||||
cropButton.setToolTip(tr("Crop Picture"));
|
|
||||||
QObject::connect(&cropButton, SIGNAL(clicked(bool)), &cropDialog, SLOT(accept()));
|
|
||||||
|
|
||||||
buttonLayout.addWidget(&cropButton);
|
|
||||||
|
|
||||||
cropDialog.show();
|
|
||||||
cropDialog.setFixedSize(cropDialog.sizeHint());
|
|
||||||
if (cropDialog.exec() == QDialog::Accepted) {
|
|
||||||
QImage *croppedImage = new QImage(imageCropper.cropImage().toImage());
|
|
||||||
setImage(croppedImage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::importNewPicture()
|
void ImportDialog::importNewPicture()
|
||||||
{
|
{
|
||||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||||
|
@ -518,7 +450,7 @@ fileDialogPreOpen: //Work?
|
||||||
fileDialog.setViewMode(QFileDialog::Detail);
|
fileDialog.setViewMode(QFileDialog::Detail);
|
||||||
fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
|
fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
|
||||||
fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog);
|
fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog);
|
||||||
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
fileDialog.setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
||||||
fileDialog.setWindowTitle(QApplication::translate("ProfileInterface", "Import..."));
|
fileDialog.setWindowTitle(QApplication::translate("ProfileInterface", "Import..."));
|
||||||
fileDialog.setLabelText(QFileDialog::Accept, QApplication::translate("ProfileInterface", "Import"));
|
fileDialog.setLabelText(QFileDialog::Accept, QApplication::translate("ProfileInterface", "Import"));
|
||||||
|
|
||||||
|
@ -824,7 +756,7 @@ fileDialogPreOpen:
|
||||||
fileDialog.setViewMode(QFileDialog::Detail);
|
fileDialog.setViewMode(QFileDialog::Detail);
|
||||||
fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
|
fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
|
||||||
fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog);
|
fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog);
|
||||||
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
fileDialog.setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
||||||
fileDialog.setWindowTitle(QApplication::translate("ProfileInterface", "Import..."));
|
fileDialog.setWindowTitle(QApplication::translate("ProfileInterface", "Import..."));
|
||||||
fileDialog.setLabelText(QFileDialog::Accept, QApplication::translate("ProfileInterface", "Import"));
|
fileDialog.setLabelText(QFileDialog::Accept, QApplication::translate("ProfileInterface", "Import"));
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ public:
|
||||||
private slots:
|
private slots:
|
||||||
void processImage();
|
void processImage();
|
||||||
void reworkImage();
|
void reworkImage();
|
||||||
void cropPicture();
|
|
||||||
void importNewPicture();
|
void importNewPicture();
|
||||||
void loadImportSettings();
|
void loadImportSettings();
|
||||||
void saveImportSettings();
|
void saveImportSettings();
|
||||||
|
|
|
@ -1,537 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* ImageCropper Qt Widget for cropping images
|
|
||||||
* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro
|
|
||||||
* Copyright (C) 2020 Syping
|
|
||||||
*
|
|
||||||
* This library 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 any later version.
|
|
||||||
*
|
|
||||||
* This library 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 "imagecropper.h"
|
|
||||||
#include "AppEnv.h"
|
|
||||||
|
|
||||||
#include <QPainterPath>
|
|
||||||
#include <QMouseEvent>
|
|
||||||
#include <QPainter>
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
static const QSize WIDGET_MINIMUM_SIZE(470, 470);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageCropper::ImageCropper(QWidget* parent) :
|
|
||||||
QWidget(parent),
|
|
||||||
pimpl(new ImageCropperPrivate)
|
|
||||||
{
|
|
||||||
setMinimumSize(WIDGET_MINIMUM_SIZE);
|
|
||||||
setMouseTracking(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageCropper::~ImageCropper()
|
|
||||||
{
|
|
||||||
delete pimpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageCropper::setImage(const QPixmap& _image)
|
|
||||||
{
|
|
||||||
pimpl->imageForCropping = _image;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageCropper::setBackgroundColor(const QColor& _backgroundColor)
|
|
||||||
{
|
|
||||||
pimpl->backgroundColor = _backgroundColor;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageCropper::setCroppingRectBorderColor(const QColor& _borderColor)
|
|
||||||
{
|
|
||||||
pimpl->croppingRectBorderColor = _borderColor;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageCropper::setProportion(const QSizeF& _proportion)
|
|
||||||
{
|
|
||||||
// Пропорции хранятся в коэффициентах приращения сторон
|
|
||||||
// Таким образом, при изменении размера области выделения,
|
|
||||||
// размеры сторон изменяются на размер зависящий от
|
|
||||||
// коэффициентов приращения.
|
|
||||||
|
|
||||||
// Сохраним пропорциональную зависимость области выделения в коэффициентах приращения сторон
|
|
||||||
if (pimpl->proportion != _proportion) {
|
|
||||||
pimpl->proportion = _proportion;
|
|
||||||
// ... расчитаем коэффициенты
|
|
||||||
float heightDelta = (float)_proportion.height() / _proportion.width();
|
|
||||||
float widthDelta = (float)_proportion.width() / _proportion.height();
|
|
||||||
// ... сохраним коэффициенты
|
|
||||||
pimpl->deltas.setHeight(heightDelta);
|
|
||||||
pimpl->deltas.setWidth(widthDelta);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обновим пропорции области выделения
|
|
||||||
if ( pimpl->isProportionFixed ) {
|
|
||||||
float croppintRectSideRelation =
|
|
||||||
(float)pimpl->croppingRect.width() / pimpl->croppingRect.height();
|
|
||||||
float proportionSideRelation =
|
|
||||||
(float)pimpl->proportion.width() / pimpl->proportion.height();
|
|
||||||
// Если область выделения не соответствует необходимым пропорциям обновим её
|
|
||||||
if (croppintRectSideRelation != proportionSideRelation) {
|
|
||||||
bool widthShotrerThenHeight =
|
|
||||||
pimpl->croppingRect.width() < pimpl->croppingRect.height();
|
|
||||||
// ... установим размер той стороны, что длиннее
|
|
||||||
if (widthShotrerThenHeight) {
|
|
||||||
pimpl->croppingRect.setHeight(
|
|
||||||
pimpl->croppingRect.width() * pimpl->deltas.height());
|
|
||||||
} else {
|
|
||||||
pimpl->croppingRect.setWidth(
|
|
||||||
pimpl->croppingRect.height() * pimpl->deltas.width());
|
|
||||||
}
|
|
||||||
// ... перерисуем виджет
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageCropper::setProportionFixed(const bool _isFixed)
|
|
||||||
{
|
|
||||||
if (pimpl->isProportionFixed != _isFixed) {
|
|
||||||
pimpl->isProportionFixed = _isFixed;
|
|
||||||
setProportion(pimpl->proportion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const QPixmap ImageCropper::cropImage()
|
|
||||||
{
|
|
||||||
// Получим размер отображаемого изображения
|
|
||||||
QSize scaledImageSize =
|
|
||||||
pimpl->imageForCropping.scaled(
|
|
||||||
size(), Qt::KeepAspectRatio, Qt::SmoothTransformation
|
|
||||||
).size();
|
|
||||||
// Определим расстояние от левого и верхнего краёв
|
|
||||||
float leftDelta = 0;
|
|
||||||
float topDelta = 0;
|
|
||||||
const float HALF_COUNT = 2;
|
|
||||||
if (size().height() == scaledImageSize.height()) {
|
|
||||||
leftDelta = (width() - scaledImageSize.width()) / HALF_COUNT;
|
|
||||||
} else {
|
|
||||||
topDelta = (height() - scaledImageSize.height()) / HALF_COUNT;
|
|
||||||
}
|
|
||||||
// Определим пропорцию области обрезки по отношению к исходному изображению
|
|
||||||
float xScale = (float)pimpl->imageForCropping.width() / scaledImageSize.width();
|
|
||||||
float yScale = (float)pimpl->imageForCropping.height() / scaledImageSize.height();
|
|
||||||
// Расчитаем область обрезки с учётом коррекции размеров исходного изображения
|
|
||||||
QRectF realSizeRect(
|
|
||||||
QPointF(pimpl->croppingRect.left() - leftDelta, pimpl->croppingRect.top() - topDelta),
|
|
||||||
pimpl->croppingRect.size());
|
|
||||||
// ... корректируем левый и верхний края
|
|
||||||
realSizeRect.setLeft((pimpl->croppingRect.left() - leftDelta) * xScale);
|
|
||||||
realSizeRect.setTop ((pimpl->croppingRect.top() - topDelta) * yScale);
|
|
||||||
// ... корректируем размер
|
|
||||||
realSizeRect.setWidth(pimpl->croppingRect.width() * xScale);
|
|
||||||
realSizeRect.setHeight(pimpl->croppingRect.height() * yScale);
|
|
||||||
// Получаем обрезанное изображение
|
|
||||||
return pimpl->imageForCropping.copy(realSizeRect.toRect());
|
|
||||||
}
|
|
||||||
|
|
||||||
// ********
|
|
||||||
// Protected section
|
|
||||||
|
|
||||||
void ImageCropper::paintEvent(QPaintEvent* _event)
|
|
||||||
{
|
|
||||||
QWidget::paintEvent(_event);
|
|
||||||
//
|
|
||||||
QPainter widgetPainter(this);
|
|
||||||
// Рисуем изображение по центру виджета
|
|
||||||
{
|
|
||||||
#if QT_VERSION >= 0x050600
|
|
||||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
// ... подгоним изображение для отображения по размеру виджета
|
|
||||||
QPixmap scaledImage =
|
|
||||||
pimpl->imageForCropping.scaled(qRound((double)width() * screenRatioPR), qRound((double)height() * screenRatioPR), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
||||||
scaledImage.setDevicePixelRatio(screenRatioPR);
|
|
||||||
#else
|
|
||||||
QPixmap scaledImage =
|
|
||||||
pimpl->imageForCropping.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
||||||
#endif
|
|
||||||
// ... заливаем фон
|
|
||||||
widgetPainter.fillRect(rect(), pimpl->backgroundColor);
|
|
||||||
// ... рисуем изображение по центру виджета
|
|
||||||
#if QT_VERSION >= 0x050600
|
|
||||||
if (qRound((double)height() * screenRatioPR) == scaledImage.height()) {
|
|
||||||
widgetPainter.drawPixmap( ( qRound((double)width() * screenRatioPR) - scaledImage.width() ) / 2, 0, scaledImage );
|
|
||||||
} else {
|
|
||||||
widgetPainter.drawPixmap( 0, ( qRound((double)height() * screenRatioPR) - scaledImage.height() ) / 2, scaledImage );
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (height() == scaledImage.height()) {
|
|
||||||
widgetPainter.drawPixmap( ( width()- scaledImage.width() ) / 2, 0, scaledImage );
|
|
||||||
} else {
|
|
||||||
widgetPainter.drawPixmap( 0, ( height() - scaledImage.height() ) / 2, scaledImage );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
// Рисуем область обрезки
|
|
||||||
{
|
|
||||||
// ... если это первое отображение после инициилизации, то центруем областо обрезки
|
|
||||||
if (pimpl->croppingRect.isNull()) {
|
|
||||||
const int cwidth = WIDGET_MINIMUM_SIZE.width()/2;
|
|
||||||
const int cheight = WIDGET_MINIMUM_SIZE.height()/2;
|
|
||||||
pimpl->croppingRect.setSize(QSize(cwidth, cheight));
|
|
||||||
float x = (width() - pimpl->croppingRect.width())/2;
|
|
||||||
float y = (height() - pimpl->croppingRect.height())/2;
|
|
||||||
pimpl->croppingRect.moveTo(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... рисуем затемненную область
|
|
||||||
QPainterPath p;
|
|
||||||
p.addRect(pimpl->croppingRect);
|
|
||||||
p.addRect(rect());
|
|
||||||
widgetPainter.setBrush(QBrush(QColor(0,0,0,120)));
|
|
||||||
widgetPainter.setPen(Qt::transparent);
|
|
||||||
widgetPainter.drawPath(p);
|
|
||||||
// Рамка и контрольные точки
|
|
||||||
widgetPainter.setPen(pimpl->croppingRectBorderColor);
|
|
||||||
// ... рисуем прямоугольник области обрезки
|
|
||||||
{
|
|
||||||
widgetPainter.setBrush(QBrush(Qt::transparent));
|
|
||||||
widgetPainter.drawRect(pimpl->croppingRect);
|
|
||||||
}
|
|
||||||
// ... рисуем контрольные точки
|
|
||||||
{
|
|
||||||
widgetPainter.setBrush(QBrush(pimpl->croppingRectBorderColor));
|
|
||||||
// Вспомогательные X координаты
|
|
||||||
int leftXCoord = pimpl->croppingRect.left() - 2;
|
|
||||||
int centerXCoord = pimpl->croppingRect.center().x() - 3;
|
|
||||||
int rightXCoord = pimpl->croppingRect.right() - 2;
|
|
||||||
// Вспомогательные Y координаты
|
|
||||||
int topYCoord = pimpl->croppingRect.top() - 2;
|
|
||||||
int middleYCoord = pimpl->croppingRect.center().y() - 3;
|
|
||||||
int bottomYCoord = pimpl->croppingRect.bottom() - 2;
|
|
||||||
//
|
|
||||||
const QSize pointSize(6, 6);
|
|
||||||
//
|
|
||||||
QVector<QRect> points;
|
|
||||||
points
|
|
||||||
// левая сторона
|
|
||||||
<< QRect( QPoint(leftXCoord, topYCoord), pointSize )
|
|
||||||
<< QRect( QPoint(leftXCoord, middleYCoord), pointSize )
|
|
||||||
<< QRect( QPoint(leftXCoord, bottomYCoord), pointSize )
|
|
||||||
// центр
|
|
||||||
<< QRect( QPoint(centerXCoord, topYCoord), pointSize )
|
|
||||||
<< QRect( QPoint(centerXCoord, middleYCoord), pointSize )
|
|
||||||
<< QRect( QPoint(centerXCoord, bottomYCoord), pointSize )
|
|
||||||
// правая сторона
|
|
||||||
<< QRect( QPoint(rightXCoord, topYCoord), pointSize )
|
|
||||||
<< QRect( QPoint(rightXCoord, middleYCoord), pointSize )
|
|
||||||
<< QRect( QPoint(rightXCoord, bottomYCoord), pointSize );
|
|
||||||
//
|
|
||||||
widgetPainter.drawRects( points );
|
|
||||||
}
|
|
||||||
// ... рисуем пунктирные линии
|
|
||||||
{
|
|
||||||
QPen dashPen(pimpl->croppingRectBorderColor);
|
|
||||||
dashPen.setStyle(Qt::DashLine);
|
|
||||||
widgetPainter.setPen(dashPen);
|
|
||||||
// ... вертикальная
|
|
||||||
widgetPainter.drawLine(
|
|
||||||
QPoint(pimpl->croppingRect.center().x(), pimpl->croppingRect.top()),
|
|
||||||
QPoint(pimpl->croppingRect.center().x(), pimpl->croppingRect.bottom()) );
|
|
||||||
// ... горизонтальная
|
|
||||||
widgetPainter.drawLine(
|
|
||||||
QPoint(pimpl->croppingRect.left(), pimpl->croppingRect.center().y()),
|
|
||||||
QPoint(pimpl->croppingRect.right(), pimpl->croppingRect.center().y()) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
widgetPainter.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageCropper::mousePressEvent(QMouseEvent* _event)
|
|
||||||
{
|
|
||||||
if (_event->button() == Qt::LeftButton) {
|
|
||||||
pimpl->isMousePressed = true;
|
|
||||||
pimpl->startMousePos = _event->pos();
|
|
||||||
pimpl->lastStaticCroppingRect = pimpl->croppingRect;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
updateCursorIcon(_event->pos());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageCropper::mouseMoveEvent(QMouseEvent* _event)
|
|
||||||
{
|
|
||||||
QPointF mousePos = _event->pos(); // относительно себя (виджета)
|
|
||||||
//
|
|
||||||
if (!pimpl->isMousePressed) {
|
|
||||||
// Обработка обычного состояния, т.е. не изменяется размер
|
|
||||||
// области обрезки, и она не перемещается по виджету
|
|
||||||
pimpl->cursorPosition = cursorPosition(pimpl->croppingRect, mousePos);
|
|
||||||
updateCursorIcon(mousePos);
|
|
||||||
} else if (pimpl->cursorPosition != CursorPositionUndefined) {
|
|
||||||
// Обработка действий над областью обрезки
|
|
||||||
// ... определим смещение курсора мышки
|
|
||||||
QPointF mouseDelta;
|
|
||||||
mouseDelta.setX( mousePos.x() - pimpl->startMousePos.x() );
|
|
||||||
mouseDelta.setY( mousePos.y() - pimpl->startMousePos.y() );
|
|
||||||
//
|
|
||||||
if (pimpl->cursorPosition != CursorPositionMiddle) {
|
|
||||||
// ... изменяем размер области обрезки
|
|
||||||
QRectF newGeometry =
|
|
||||||
calculateGeometry(
|
|
||||||
pimpl->lastStaticCroppingRect,
|
|
||||||
pimpl->cursorPosition,
|
|
||||||
mouseDelta);
|
|
||||||
// ... пользователь пытается вывернуть область обрезки наизнанку
|
|
||||||
if (!newGeometry.isNull()) {
|
|
||||||
pimpl->croppingRect = newGeometry;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// ... перемещаем область обрезки
|
|
||||||
pimpl->croppingRect.moveTo( pimpl->lastStaticCroppingRect.topLeft() + mouseDelta );
|
|
||||||
}
|
|
||||||
// Перерисуем виджет
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageCropper::mouseReleaseEvent(QMouseEvent* _event)
|
|
||||||
{
|
|
||||||
pimpl->isMousePressed = false;
|
|
||||||
updateCursorIcon(_event->pos());
|
|
||||||
}
|
|
||||||
|
|
||||||
// ********
|
|
||||||
// Private section
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
// Находится ли точка рядом с координатой стороны
|
|
||||||
static bool isPointNearSide (const int _sideCoordinate, const int _pointCoordinate)
|
|
||||||
{
|
|
||||||
static const int indent = 10;
|
|
||||||
return (_sideCoordinate - indent) < _pointCoordinate && _pointCoordinate < (_sideCoordinate + indent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CursorPosition ImageCropper::cursorPosition(const QRectF& _cropRect, const QPointF& _mousePosition)
|
|
||||||
{
|
|
||||||
CursorPosition cursorPosition = CursorPositionUndefined;
|
|
||||||
//
|
|
||||||
if ( _cropRect.contains( _mousePosition ) ) {
|
|
||||||
// Двухстороннее направление
|
|
||||||
if (isPointNearSide(_cropRect.top(), _mousePosition.y()) &&
|
|
||||||
isPointNearSide(_cropRect.left(), _mousePosition.x())) {
|
|
||||||
cursorPosition = CursorPositionTopLeft;
|
|
||||||
} else if (isPointNearSide(_cropRect.bottom(), _mousePosition.y()) &&
|
|
||||||
isPointNearSide(_cropRect.left(), _mousePosition.x())) {
|
|
||||||
cursorPosition = CursorPositionBottomLeft;
|
|
||||||
} else if (isPointNearSide(_cropRect.top(), _mousePosition.y()) &&
|
|
||||||
isPointNearSide(_cropRect.right(), _mousePosition.x())) {
|
|
||||||
cursorPosition = CursorPositionTopRight;
|
|
||||||
} else if (isPointNearSide(_cropRect.bottom(), _mousePosition.y()) &&
|
|
||||||
isPointNearSide(_cropRect.right(), _mousePosition.x())) {
|
|
||||||
cursorPosition = CursorPositionBottomRight;
|
|
||||||
// Одностороннее направление
|
|
||||||
} else if (isPointNearSide(_cropRect.left(), _mousePosition.x())) {
|
|
||||||
cursorPosition = CursorPositionLeft;
|
|
||||||
} else if (isPointNearSide(_cropRect.right(), _mousePosition.x())) {
|
|
||||||
cursorPosition = CursorPositionRight;
|
|
||||||
} else if (isPointNearSide(_cropRect.top(), _mousePosition.y())) {
|
|
||||||
cursorPosition = CursorPositionTop;
|
|
||||||
} else if (isPointNearSide(_cropRect.bottom(), _mousePosition.y())) {
|
|
||||||
cursorPosition = CursorPositionBottom;
|
|
||||||
// Без направления
|
|
||||||
} else {
|
|
||||||
cursorPosition = CursorPositionMiddle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
return cursorPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageCropper::updateCursorIcon(const QPointF& _mousePosition)
|
|
||||||
{
|
|
||||||
QCursor cursorIcon;
|
|
||||||
//
|
|
||||||
switch (cursorPosition(pimpl->croppingRect, _mousePosition))
|
|
||||||
{
|
|
||||||
case CursorPositionTopRight:
|
|
||||||
case CursorPositionBottomLeft:
|
|
||||||
cursorIcon = QCursor(Qt::SizeBDiagCursor);
|
|
||||||
break;
|
|
||||||
case CursorPositionTopLeft:
|
|
||||||
case CursorPositionBottomRight:
|
|
||||||
cursorIcon = QCursor(Qt::SizeFDiagCursor);
|
|
||||||
break;
|
|
||||||
case CursorPositionTop:
|
|
||||||
case CursorPositionBottom:
|
|
||||||
cursorIcon = QCursor(Qt::SizeVerCursor);
|
|
||||||
break;
|
|
||||||
case CursorPositionLeft:
|
|
||||||
case CursorPositionRight:
|
|
||||||
cursorIcon = QCursor(Qt::SizeHorCursor);
|
|
||||||
break;
|
|
||||||
case CursorPositionMiddle:
|
|
||||||
cursorIcon = pimpl->isMousePressed ?
|
|
||||||
QCursor(Qt::ClosedHandCursor) :
|
|
||||||
QCursor(Qt::OpenHandCursor);
|
|
||||||
break;
|
|
||||||
case CursorPositionUndefined:
|
|
||||||
default:
|
|
||||||
cursorIcon = QCursor(Qt::ArrowCursor);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
this->setCursor(cursorIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
const QRectF ImageCropper::calculateGeometry(
|
|
||||||
const QRectF& _sourceGeometry,
|
|
||||||
const CursorPosition _cursorPosition,
|
|
||||||
const QPointF& _mouseDelta
|
|
||||||
)
|
|
||||||
{
|
|
||||||
QRectF resultGeometry;
|
|
||||||
//
|
|
||||||
if ( pimpl->isProportionFixed ) {
|
|
||||||
resultGeometry =
|
|
||||||
calculateGeometryWithFixedProportions(
|
|
||||||
_sourceGeometry, _cursorPosition, _mouseDelta, pimpl->deltas);
|
|
||||||
} else {
|
|
||||||
resultGeometry =
|
|
||||||
calculateGeometryWithCustomProportions(
|
|
||||||
_sourceGeometry, _cursorPosition, _mouseDelta);
|
|
||||||
}
|
|
||||||
// Если пользователь пытается вывернуть область обрезки наизнанку,
|
|
||||||
// возвращаем null-прямоугольник
|
|
||||||
if ((resultGeometry.left() >= resultGeometry.right()) ||
|
|
||||||
(resultGeometry.top() >= resultGeometry.bottom())) {
|
|
||||||
resultGeometry = QRect();
|
|
||||||
}
|
|
||||||
//
|
|
||||||
return resultGeometry;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QRectF ImageCropper::calculateGeometryWithCustomProportions(
|
|
||||||
const QRectF& _sourceGeometry,
|
|
||||||
const CursorPosition _cursorPosition,
|
|
||||||
const QPointF& _mouseDelta
|
|
||||||
)
|
|
||||||
{
|
|
||||||
QRectF resultGeometry = _sourceGeometry;
|
|
||||||
//
|
|
||||||
switch ( _cursorPosition )
|
|
||||||
{
|
|
||||||
case CursorPositionTopLeft:
|
|
||||||
resultGeometry.setLeft( _sourceGeometry.left() + _mouseDelta.x() );
|
|
||||||
resultGeometry.setTop ( _sourceGeometry.top() + _mouseDelta.y() );
|
|
||||||
break;
|
|
||||||
case CursorPositionTopRight:
|
|
||||||
resultGeometry.setTop ( _sourceGeometry.top() + _mouseDelta.y() );
|
|
||||||
resultGeometry.setRight( _sourceGeometry.right() + _mouseDelta.x() );
|
|
||||||
break;
|
|
||||||
case CursorPositionBottomLeft:
|
|
||||||
resultGeometry.setBottom( _sourceGeometry.bottom() + _mouseDelta.y() );
|
|
||||||
resultGeometry.setLeft ( _sourceGeometry.left() + _mouseDelta.x() );
|
|
||||||
break;
|
|
||||||
case CursorPositionBottomRight:
|
|
||||||
resultGeometry.setBottom( _sourceGeometry.bottom() + _mouseDelta.y() );
|
|
||||||
resultGeometry.setRight ( _sourceGeometry.right() + _mouseDelta.x() );
|
|
||||||
break;
|
|
||||||
case CursorPositionTop:
|
|
||||||
resultGeometry.setTop( _sourceGeometry.top() + _mouseDelta.y() );
|
|
||||||
break;
|
|
||||||
case CursorPositionBottom:
|
|
||||||
resultGeometry.setBottom( _sourceGeometry.bottom() + _mouseDelta.y() );
|
|
||||||
break;
|
|
||||||
case CursorPositionLeft:
|
|
||||||
resultGeometry.setLeft( _sourceGeometry.left() + _mouseDelta.x() );
|
|
||||||
break;
|
|
||||||
case CursorPositionRight:
|
|
||||||
resultGeometry.setRight( _sourceGeometry.right() + _mouseDelta.x() );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
return resultGeometry;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QRectF ImageCropper::calculateGeometryWithFixedProportions(
|
|
||||||
const QRectF& _sourceGeometry,
|
|
||||||
const CursorPosition _cursorPosition,
|
|
||||||
const QPointF& _mouseDelta,
|
|
||||||
const QSizeF& _deltas
|
|
||||||
)
|
|
||||||
{
|
|
||||||
QRectF resultGeometry = _sourceGeometry;
|
|
||||||
//
|
|
||||||
switch (_cursorPosition)
|
|
||||||
{
|
|
||||||
case CursorPositionLeft:
|
|
||||||
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.x() * _deltas.height());
|
|
||||||
resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.x());
|
|
||||||
break;
|
|
||||||
case CursorPositionRight:
|
|
||||||
resultGeometry.setTop(_sourceGeometry.top() - _mouseDelta.x() * _deltas.height());
|
|
||||||
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.x());
|
|
||||||
break;
|
|
||||||
case CursorPositionTop:
|
|
||||||
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.y());
|
|
||||||
resultGeometry.setRight(_sourceGeometry.right() - _mouseDelta.y() * _deltas.width());
|
|
||||||
break;
|
|
||||||
case CursorPositionBottom:
|
|
||||||
resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.y());
|
|
||||||
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.y() * _deltas.width());
|
|
||||||
break;
|
|
||||||
case CursorPositionTopLeft:
|
|
||||||
if ((_mouseDelta.x() * _deltas.height()) < (_mouseDelta.y())) {
|
|
||||||
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.x() * _deltas.height());
|
|
||||||
resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.x());
|
|
||||||
} else {
|
|
||||||
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.y());
|
|
||||||
resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.y() * _deltas.width());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CursorPositionTopRight:
|
|
||||||
if ((_mouseDelta.x() * _deltas.height() * -1) < (_mouseDelta.y())) {
|
|
||||||
resultGeometry.setTop(_sourceGeometry.top() - _mouseDelta.x() * _deltas.height());
|
|
||||||
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.x() );
|
|
||||||
} else {
|
|
||||||
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.y());
|
|
||||||
resultGeometry.setRight(_sourceGeometry.right() - _mouseDelta.y() * _deltas.width());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CursorPositionBottomLeft:
|
|
||||||
if ((_mouseDelta.x() * _deltas.height()) < (_mouseDelta.y() * -1)) {
|
|
||||||
resultGeometry.setBottom(_sourceGeometry.bottom() - _mouseDelta.x() * _deltas.height());
|
|
||||||
resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.x());
|
|
||||||
} else {
|
|
||||||
resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.y());
|
|
||||||
resultGeometry.setLeft(_sourceGeometry.left() - _mouseDelta.y() * _deltas.width());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CursorPositionBottomRight:
|
|
||||||
if ((_mouseDelta.x() * _deltas.height()) > (_mouseDelta.y())) {
|
|
||||||
resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.x() * _deltas.height());
|
|
||||||
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.x());
|
|
||||||
} else {
|
|
||||||
resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.y());
|
|
||||||
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.y() * _deltas.width());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
return resultGeometry;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,103 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* ImageCropper Qt Widget for cropping images
|
|
||||||
* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro
|
|
||||||
*
|
|
||||||
* This library 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 any later version.
|
|
||||||
*
|
|
||||||
* This library 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 IMAGECROPPER_H
|
|
||||||
#define IMAGECROPPER_H
|
|
||||||
|
|
||||||
#include "imagecropper_p.h"
|
|
||||||
#include "imagecropper_e.h"
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
class ImageCropper : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
ImageCropper(QWidget *parent = 0);
|
|
||||||
~ImageCropper();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
// Установить изображение для обрезки
|
|
||||||
void setImage(const QPixmap& _image);
|
|
||||||
// Установить цвет фона виджета обрезки
|
|
||||||
void setBackgroundColor(const QColor& _backgroundColor);
|
|
||||||
// Установить цвет рамки области обрезки
|
|
||||||
void setCroppingRectBorderColor(const QColor& _borderColor);
|
|
||||||
// Установить пропорции области выделения
|
|
||||||
void setProportion(const QSizeF& _proportion);
|
|
||||||
// Использовать фиксированные пропорции области виделения
|
|
||||||
void setProportionFixed(const bool _isFixed);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Обрезать изображение
|
|
||||||
const QPixmap cropImage();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void paintEvent(QPaintEvent* _event);
|
|
||||||
virtual void mousePressEvent(QMouseEvent* _event);
|
|
||||||
virtual void mouseMoveEvent(QMouseEvent* _event);
|
|
||||||
virtual void mouseReleaseEvent(QMouseEvent* _event);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Определение местоположения курсора над виджетом
|
|
||||||
CursorPosition cursorPosition(const QRectF& _cropRect, const QPointF& _mousePosition);
|
|
||||||
// Обновить иконку курсора соответствующую местоположению мыши
|
|
||||||
void updateCursorIcon(const QPointF& _mousePosition);
|
|
||||||
|
|
||||||
// Получить размер виджета после его изменения мышью
|
|
||||||
// --------
|
|
||||||
// Контракты:
|
|
||||||
// 1. Метод должен вызываться, только при зажатой кнопке мыши
|
|
||||||
// (т.е. при перемещении или изменении размера виджета)
|
|
||||||
// --------
|
|
||||||
// В случае неудачи возвращает null-прямоугольник
|
|
||||||
const QRectF calculateGeometry(
|
|
||||||
const QRectF& _sourceGeometry,
|
|
||||||
const CursorPosition _cursorPosition,
|
|
||||||
const QPointF& _mouseDelta
|
|
||||||
);
|
|
||||||
// Получить размер виджета после его изменения мышью
|
|
||||||
// Метод изменяет виджет не сохраняя начальных пропорций сторон
|
|
||||||
// ------
|
|
||||||
// Контракты:
|
|
||||||
// 1. Метод должен вызываться, только при зажатой кнопке мыши
|
|
||||||
// (т.е. при перемещении или изменении размера виджета)
|
|
||||||
const QRectF calculateGeometryWithCustomProportions(
|
|
||||||
const QRectF& _sourceGeometry,
|
|
||||||
const CursorPosition _cursorPosition,
|
|
||||||
const QPointF& _mouseDelta
|
|
||||||
);
|
|
||||||
// Получить размер виджета после его изменения мышью
|
|
||||||
// Метод изменяет виджет сохраняя начальные пропорции сторон
|
|
||||||
// ------
|
|
||||||
// Контракты:
|
|
||||||
// 1. Метод должен вызываться, только при зажатой кнопке мыши
|
|
||||||
// (т.е. при перемещении или изменении размера виджета)
|
|
||||||
const QRectF calculateGeometryWithFixedProportions(const QRectF &_sourceGeometry,
|
|
||||||
const CursorPosition _cursorPosition,
|
|
||||||
const QPointF &_mouseDelta,
|
|
||||||
const QSizeF &_deltas
|
|
||||||
);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Private data implementation
|
|
||||||
ImageCropperPrivate* pimpl;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // IMAGECROPPER_H
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* ImageCropper Qt Widget for cropping images
|
|
||||||
* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro
|
|
||||||
*
|
|
||||||
* This library 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 any later version.
|
|
||||||
*
|
|
||||||
* This library 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 IMAGECROPPER_E_H
|
|
||||||
#define IMAGECROPPER_E_H
|
|
||||||
|
|
||||||
enum CursorPosition
|
|
||||||
{
|
|
||||||
CursorPositionUndefined,
|
|
||||||
CursorPositionMiddle,
|
|
||||||
CursorPositionTop,
|
|
||||||
CursorPositionBottom,
|
|
||||||
CursorPositionLeft,
|
|
||||||
CursorPositionRight,
|
|
||||||
CursorPositionTopLeft,
|
|
||||||
CursorPositionTopRight,
|
|
||||||
CursorPositionBottomLeft,
|
|
||||||
CursorPositionBottomRight
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // IMAGECROPPER_E_H
|
|
|
@ -1,76 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* ImageCropper Qt Widget for cropping images
|
|
||||||
* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro
|
|
||||||
*
|
|
||||||
* This library 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 any later version.
|
|
||||||
*
|
|
||||||
* This library 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 IMAGECROPPER_P_H
|
|
||||||
#define IMAGECROPPER_P_H
|
|
||||||
|
|
||||||
#include "imagecropper_e.h"
|
|
||||||
|
|
||||||
#include <QtCore/QRect>
|
|
||||||
#include <QtGui/QPixmap>
|
|
||||||
#include <QtGui/QColor>
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
const QRect INIT_CROPPING_RECT = QRect();
|
|
||||||
const QSizeF INIT_PROPORTION = QSizeF(1.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
class ImageCropperPrivate {
|
|
||||||
public:
|
|
||||||
ImageCropperPrivate() :
|
|
||||||
imageForCropping(QPixmap()),
|
|
||||||
croppingRect(INIT_CROPPING_RECT),
|
|
||||||
lastStaticCroppingRect(QRect()),
|
|
||||||
cursorPosition(CursorPositionUndefined),
|
|
||||||
isMousePressed(false),
|
|
||||||
isProportionFixed(false),
|
|
||||||
startMousePos(QPoint()),
|
|
||||||
proportion(INIT_PROPORTION),
|
|
||||||
deltas(INIT_PROPORTION),
|
|
||||||
backgroundColor(Qt::black),
|
|
||||||
croppingRectBorderColor(Qt::white)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Изображение для обрезки
|
|
||||||
QPixmap imageForCropping;
|
|
||||||
// Область обрезки
|
|
||||||
QRectF croppingRect;
|
|
||||||
// Последняя фиксированная область обрезки
|
|
||||||
QRectF lastStaticCroppingRect;
|
|
||||||
// Позиция курсора относительно области обрезки
|
|
||||||
CursorPosition cursorPosition;
|
|
||||||
// Зажата ли левая кнопка мыши
|
|
||||||
bool isMousePressed;
|
|
||||||
// Фиксировать пропорции области обрезки
|
|
||||||
bool isProportionFixed;
|
|
||||||
// Начальная позиция курсора при изменении размера области обрезки
|
|
||||||
QPointF startMousePos;
|
|
||||||
// Пропорции
|
|
||||||
QSizeF proportion;
|
|
||||||
// Приращения
|
|
||||||
// width - приращение по x
|
|
||||||
// height - приращение по y
|
|
||||||
QSizeF deltas;
|
|
||||||
// Цвет заливки фона под изображением
|
|
||||||
QColor backgroundColor;
|
|
||||||
// Цвет рамки области обрезки
|
|
||||||
QColor croppingRectBorderColor;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // IMAGECROPPER_P_H
|
|
Loading…
Reference in a new issue