QuickToolBar: implement preview and BorderImage

There is now a nice preview for images and the
properties and borders of a BorderImage can
be visually edited
This commit is contained in:
Thomas Hartmann
2010-07-30 14:31:34 +02:00
parent 3e4e0f80db
commit a2189bfdbf
2 changed files with 692 additions and 103 deletions

View File

@@ -1,14 +1,19 @@
#include "contextpanewidgetimage.h"
#include "ui_contextpanewidgetimage.h"
#include "ui_contextpanewidgetborderimage.h"
#include <qmljs/qmljspropertyreader.h>
#include <QFile>
#include <QPixmap>
#include <QPainter>
#include <QGraphicsEffect>
#include <QMouseEvent>
#include <QScrollArea>
#include <QSlider>
#include <QDebug>
namespace QmlDesigner {
bool LabelFilter::eventFilter(QObject *, QEvent *event)
bool LabelFilter::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress) {
return true;
@@ -20,80 +25,177 @@ bool LabelFilter::eventFilter(QObject *, QEvent *event)
emit doubleClicked();
event->accept();
return true;
}
return false;
}
return QObject::eventFilter(obj, event);
}
ContextPaneWidgetImage::ContextPaneWidgetImage(QWidget *parent) :
bool WheelFilter::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::Wheel) {
if (obj
&& obj->isWidgetType()
&& obj != m_target) {
QApplication::sendEvent(m_target, event);
return true;
}
}
return QObject::eventFilter(obj, event);
}
ContextPaneWidgetImage::ContextPaneWidgetImage(QWidget *parent, bool borderImage) :
QWidget(parent),
ui(new Ui::ContextPaneWidgetImage)
ui(0), uiBorderImage(0), previewWasVisible(false)
{
LabelFilter *labelFilter = new LabelFilter(this);
ui->setupUi(this);
ui->fileWidget->setShowComboBox(true);
ui->fileWidget->setFilter("*.png *.gif *.jpg");
ui->label->setToolTip(tr("double click for preview"));
ui->label->installEventFilter(labelFilter);
m_previewDialog = new PreviewDialog(this);
m_previewDialog->hide();
m_borderImage = borderImage;
connect(ui->stretchRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
connect(ui->tileRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
connect(ui->horizontalStretchRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
connect(ui->verticalStretchRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
connect(ui->preserveAspectFitRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
connect(ui->cropAspectFitRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
if (m_borderImage) {
uiBorderImage = new Ui::ContextPaneWidgetBorderImage;
uiBorderImage->setupUi(this);
m_fileWidget = uiBorderImage->fileWidget;
m_sizeLabel = uiBorderImage->sizeLabel;
uiBorderImage->label->setToolTip(tr("double click for preview"));
uiBorderImage->label->installEventFilter(labelFilter);
connect(ui->fileWidget, SIGNAL(fileNameChanged(QUrl)), this, SLOT(onFileNameChanged()));
connect(uiBorderImage->verticalTileRadioButton, SIGNAL(toggled(bool)), this, SLOT(onVerticalStretchChanged()));
connect(uiBorderImage->verticalStretchRadioButton, SIGNAL(toggled(bool)), this, SLOT(onVerticalStretchChanged()));
connect(uiBorderImage->verticalTileRadioButtonNoCrop, SIGNAL(toggled(bool)), this, SLOT(onVerticalStretchChanged()));
connect(uiBorderImage->horizontalTileRadioButton, SIGNAL(toggled(bool)), this, SLOT(onHorizontalStretchChanged()));
connect(uiBorderImage->horizontalStretchRadioButton, SIGNAL(toggled(bool)), this, SLOT(onHorizontalStretchChanged()));
connect(uiBorderImage->horizontalTileRadioButtonNoCrop, SIGNAL(toggled(bool)), this, SLOT(onHorizontalStretchChanged()));
connect(previewDialog()->previewLabel(), SIGNAL(leftMarginChanged()), this, SLOT(onLeftMarginsChanged()));
connect(previewDialog()->previewLabel(), SIGNAL(rightMarginChanged()), this, SLOT(onRightMarginsChanged()));
connect(previewDialog()->previewLabel(), SIGNAL(topMarginChanged()), this, SLOT(onTopMarginsChanged()));
connect(previewDialog()->previewLabel(), SIGNAL(bottomMarginChanged()), this, SLOT(onBottomMarginsChanged()));
} else {
ui = new Ui::ContextPaneWidgetImage;
ui->setupUi(this);
ui->label->setToolTip(tr("double click for preview"));
ui->label->installEventFilter(labelFilter);
m_fileWidget = ui->fileWidget;
m_sizeLabel = ui->sizeLabel;
connect(ui->stretchRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
connect(ui->tileRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
connect(ui->horizontalStretchRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
connect(ui->verticalStretchRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
connect(ui->preserveAspectFitRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
connect(ui->cropAspectFitRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
}
previewDialog();
m_fileWidget->setShowComboBox(true);
m_fileWidget->setFilter("*.png *.gif *.jpg");
connect(m_fileWidget, SIGNAL(fileNameChanged(QUrl)), this, SLOT(onFileNameChanged()));
connect(labelFilter, SIGNAL(doubleClicked()), this, SLOT(onPixmapDoubleClicked()));
}
ContextPaneWidgetImage::~ContextPaneWidgetImage()
{
delete ui;
if (ui)
delete ui;
if (uiBorderImage)
delete uiBorderImage;
}
void ContextPaneWidgetImage::setProperties(QmlJS::PropertyReader *propertyReader)
{
if (m_borderImage) {
if (propertyReader->hasProperty(QLatin1String("horizontalTileMode"))) {
QString fillMode = propertyReader->readProperty(QLatin1String("horizontalTileMode")).toString();
if (fillMode.contains("BorderImage."))
fillMode.remove("BorderImage.");
if (propertyReader->hasProperty(QLatin1String("fillMode"))) {
QString fillMode = propertyReader->readProperty(QLatin1String("fillMode")).toString();
if (fillMode.contains("Image."))
fillMode.remove("Image.");
uiBorderImage->horizontalStretchRadioButton->setChecked(true);
ui->stretchRadioButton->setChecked(true);
if (fillMode == "Stretch")
uiBorderImage->horizontalStretchRadioButton->setChecked(true);
if (fillMode == "Repeat")
uiBorderImage->horizontalTileRadioButton->setChecked(true);
if (fillMode == "Round")
uiBorderImage->horizontalTileRadioButtonNoCrop->setChecked(true);
} else {
//uiBorderImage
uiBorderImage->horizontalStretchRadioButton->setChecked(true);
}
if (propertyReader->hasProperty(QLatin1String("verticalTileMode"))) {
QString fillMode = propertyReader->readProperty(QLatin1String("verticalTileMode")).toString();
if (fillMode.contains("BorderImage."))
fillMode.remove("BorderImage.");
if (fillMode == "Image.Tile" || fillMode == "Tile")
ui->tileRadioButton->setChecked(true);
if (fillMode == "Image.TileVertically" || fillMode == "TileVertically")
ui->horizontalStretchRadioButton->setChecked(true);
if (fillMode == "Image.TileHorizontally" || fillMode == "TileHorizontally")
ui->verticalStretchRadioButton->setChecked(true);
if (fillMode == "Image.PreserveAspectFit" || fillMode == "PreserveAspectFit")
ui->preserveAspectFitRadioButton->setChecked(true);
if (fillMode == "Image.PreserveAspectCrop" || fillMode == "PreserveAspectCrop")
ui->cropAspectFitRadioButton->setChecked(true);
uiBorderImage->verticalStretchRadioButton->setChecked(true);
if (fillMode == "Stretch")
uiBorderImage->verticalStretchRadioButton->setChecked(true);
if (fillMode == "Repeat")
uiBorderImage->verticalTileRadioButton->setChecked(true);
if (fillMode == "Round")
uiBorderImage->verticalTileRadioButtonNoCrop->setChecked(true);
} else {
//uiBorderImage
uiBorderImage->verticalStretchRadioButton->setChecked(true);
}
} else {
ui->stretchRadioButton->setChecked(true);
}
if (propertyReader->hasProperty(QLatin1String("fillMode"))) {
QString fillMode = propertyReader->readProperty(QLatin1String("fillMode")).toString();
if (fillMode.contains("Image."))
fillMode.remove("Image.");
ui->stretchRadioButton->setChecked(true);
if (fillMode == "Image.Tile" || fillMode == "Tile")
ui->tileRadioButton->setChecked(true);
if (fillMode == "Image.TileVertically" || fillMode == "TileVertically")
ui->horizontalStretchRadioButton->setChecked(true);
if (fillMode == "Image.TileHorizontally" || fillMode == "TileHorizontally")
ui->verticalStretchRadioButton->setChecked(true);
if (fillMode == "Image.PreserveAspectFit" || fillMode == "PreserveAspectFit")
ui->preserveAspectFitRadioButton->setChecked(true);
if (fillMode == "Image.PreserveAspectCrop" || fillMode == "PreserveAspectCrop")
ui->cropAspectFitRadioButton->setChecked(true);
} else {
ui->stretchRadioButton->setChecked(true);
}
}
if (propertyReader->hasProperty(QLatin1String("source"))) {
QString source = propertyReader->readProperty(QLatin1String("source")).toString();
ui->fileWidget->setFileName(source);
m_fileWidget->setFileName(source);
if (QFile::exists(m_path + '/' + source))
setPixmap(m_path + '/' + source);
else
setPixmap(source);
} else {
ui->sizeLabel->setText("");
m_sizeLabel->setText("");
}
}
void ContextPaneWidgetImage::setPath(const QString& path)
{
m_path = path;
ui->fileWidget->setPath(QUrl::fromLocalFile(m_path));
m_fileWidget->setPath(QUrl::fromLocalFile(m_path));
}
void PreviewDialog::setZoom(int z)
{
m_zoom = z;
m_label->setZoom(z);
setPixmap(m_pixmap, m_zoom);
}
void PreviewDialog::setIsBorderImage(bool b)
{
m_borderImage = b;
m_label->setIsBorderImage(b);
}
PreviewLabel *PreviewDialog::previewLabel() const
{
return m_label;
}
void ContextPaneWidgetImage::onStretchChanged()
@@ -118,78 +220,189 @@ void ContextPaneWidgetImage::onStretchChanged()
emit propertyChanged(QLatin1String("fillMode"), stretch);
}
void ContextPaneWidgetImage::onHorizontalStretchChanged()
{
QString stretch;
if (uiBorderImage->horizontalStretchRadioButton->isChecked())
stretch = QLatin1String("BorderImage.Stretch");
if (uiBorderImage->horizontalTileRadioButton->isChecked())
stretch = QLatin1String("BorderImage.Repeat");
if (uiBorderImage->horizontalTileRadioButtonNoCrop->isChecked())
stretch = QLatin1String("BorderImage.Round");
if (stretch == QLatin1String("BorderImage.Stretch"))
emit removeProperty(QLatin1String("horizontalTileMode"));
else
emit propertyChanged(QLatin1String("horizontalTileMode"), stretch);
}
void ContextPaneWidgetImage::onVerticalStretchChanged()
{
QString stretch;
if (uiBorderImage->verticalStretchRadioButton->isChecked())
stretch = QLatin1String("BorderImage.Stretch");
if (uiBorderImage->verticalTileRadioButton->isChecked())
stretch = QLatin1String("BorderImage.Repeat");
if (uiBorderImage->verticalTileRadioButtonNoCrop->isChecked())
stretch = QLatin1String("BorderImage.Round");
if (stretch == QLatin1String("BorderImage.Stretch"))
emit removeProperty(QLatin1String("verticalTileMode"));
else
emit propertyChanged(QLatin1String("verticalTileMode"), stretch);
}
void ContextPaneWidgetImage::onFileNameChanged()
{
if (ui->fileWidget->fileName().isNull())
if (m_fileWidget->fileName().isNull())
emit removeProperty(QLatin1String("source"));
else
emit propertyChanged(QLatin1String("source"), QString(QLatin1Char('\"') + ui->fileWidget->fileName() + QLatin1Char('\"')));
emit propertyChanged(QLatin1String("source"), QString(QLatin1Char('\"') + m_fileWidget->fileName() + QLatin1Char('\"')));
}
void ContextPaneWidgetImage::onPixmapDoubleClicked()
{
m_previewDialog->setParent(parentWidget()->parentWidget());
{
previewDialog()->setParent(parentWidget()->parentWidget());
previewDialog()->setMaximumSize(previewDialog()->parentWidget()->size() - QSize(150, 100));
if (m_borderImage)
previewDialog()->setZoom(4);
previewDialog()->setIsBorderImage(m_borderImage);
QPoint p = parentWidget()->pos();
p = p + QPoint(-20, -20);
m_previewDialog->show();
m_previewDialog->update();
m_previewDialog->move(p);
m_previewDialog->resize(m_previewDialog->sizeHint());
if ((m_previewDialog->pos().x() + m_previewDialog->width()) > m_previewDialog->parentWidget()->width())
m_previewDialog->move(m_previewDialog->parentWidget()->width() - (m_previewDialog->width()) - 40, p.y());
p = p + QPoint(-2, -2);
previewDialog()->show();
previewDialog()->update();
previewDialog()->move(p);
//previewDialog()->adjustSize();
if ((previewDialog()->pos().x() + previewDialog()->width()) > previewDialog()->parentWidget()->width())
previewDialog()->move(previewDialog()->parentWidget()->width() - (previewDialog()->width()) - 40, p.y());
if ((m_previewDialog->pos().y() + m_previewDialog->height()) > m_previewDialog->parentWidget()->height())
m_previewDialog->move(m_previewDialog->pos().x(), m_previewDialog->parentWidget()->height() - (m_previewDialog->height()) - 40);
if ((previewDialog()->pos().y() + previewDialog()->height()) > previewDialog()->parentWidget()->height())
previewDialog()->move(previewDialog()->pos().x(), previewDialog()->parentWidget()->height() - (previewDialog()->height()) - 40);
if (m_previewDialog->pos().x() < 0)
m_previewDialog->move(0, m_previewDialog->pos().y());
if (m_previewDialog->pos().y() < 0)
m_previewDialog->move(m_previewDialog->pos().x(), 0);
if (previewDialog()->pos().x() < 0)
previewDialog()->move(0, previewDialog()->pos().y());
if (previewDialog()->pos().y() < 0)
previewDialog()->move(previewDialog()->pos().x(), 0);
m_previewDialog->raise();
previewDialog()->raise();
}
void ContextPaneWidgetImage::onLeftMarginsChanged()
{
if (previewDialog()->previewLabel()->leftMarging())
propertyChanged(QLatin1String("border.left"), previewDialog()->previewLabel()->leftMarging());
else
emit removeProperty(QLatin1String("border.left"));
}
void ContextPaneWidgetImage::onRightMarginsChanged()
{
if (previewDialog()->previewLabel()->rightMarging())
propertyChanged(QLatin1String("border.right"), previewDialog()->previewLabel()->rightMarging());
else
emit removeProperty(QLatin1String("border.right"));
}
void ContextPaneWidgetImage::onTopMarginsChanged()
{
if (previewDialog()->previewLabel()->topMarging())
propertyChanged(QLatin1String("border.top"), previewDialog()->previewLabel()->topMarging());
else
emit removeProperty(QLatin1String("border.top"));
}
void ContextPaneWidgetImage::onBottomMarginsChanged()
{
if (previewDialog()->previewLabel()->bottomMarging())
propertyChanged(QLatin1String("border.bottom"), previewDialog()->previewLabel()->bottomMarging());
else
emit removeProperty(QLatin1String("border.bottom"));
}
void ContextPaneWidgetImage::setPixmap(const QString &fileName)
{
QPixmap pix(76,76);
pix.fill(Qt::black);
if (QFile(fileName).exists()) {
QPixmap source(fileName);
m_previewDialog->setPixmap(source);
ui->sizeLabel->setText(QString::number(source.width()) + 'x' + QString::number(source.height()));
QPainter p(&pix);
if (ui->stretchRadioButton->isChecked()) {
p.drawPixmap(0,0,76,76, source);
} else if (ui->tileRadioButton->isChecked()) {
QPixmap small = source.scaled(38,38);
p.drawTiledPixmap(0,0,76,76, small);
} else if (ui->horizontalStretchRadioButton->isChecked()) {
QPixmap small = source.scaled(38,38);
QPixmap half = pix.scaled(38, 76);
QPainter p2(&half);
p2.drawTiledPixmap(0,0,38,76, small);
p.drawPixmap(0,0,76,76, half);
} else if (ui->verticalStretchRadioButton->isChecked()) {
QPixmap small = source.scaled(38,38);
QPixmap half = pix.scaled(76, 38);
QPainter p2(&half);
p2.drawTiledPixmap(0,0,76,38, small);
p.drawPixmap(0,0,76,76, half);
} else if (ui->preserveAspectFitRadioButton->isChecked()) {
QPixmap preserved = source.scaledToWidth(76);
int offset = (76 - preserved.height()) / 2;
p.drawPixmap(0, offset, 76, preserved.height(), source);
} else if (ui->cropAspectFitRadioButton->isChecked()) {
QPixmap cropped = source.scaledToHeight(76);
int offset = (76 - cropped.width()) / 2;
p.drawPixmap(offset, 0, cropped.width(), 76, source);
if (m_borderImage) {
if (QFile(fileName).exists()) {
QPixmap source(fileName);
previewDialog()->setPixmap(source, previewDialog()->zoom());
uiBorderImage->sizeLabel->setText(QString::number(source.width()) + 'x' + QString::number(source.height()));
QPainter p(&pix);
Qt::TileRule horizontalTileMode = Qt::StretchTile;
Qt::TileRule verticalTileMode = Qt::StretchTile;
if (uiBorderImage->horizontalTileRadioButton->isChecked())
horizontalTileMode =Qt::RepeatTile;
if (uiBorderImage->horizontalTileRadioButtonNoCrop->isChecked())
horizontalTileMode =Qt::RoundTile;
if (uiBorderImage->verticalTileRadioButton->isChecked())
verticalTileMode =Qt::RepeatTile;
if (uiBorderImage->verticalTileRadioButtonNoCrop->isChecked())
verticalTileMode =Qt::RoundTile;
QTileRules rules(horizontalTileMode, verticalTileMode);
QMargins margins(previewDialog()->previewLabel()->leftMarging() ,previewDialog()->previewLabel()->topMarging() ,previewDialog()->previewLabel()->rightMarging(), previewDialog()->previewLabel()->bottomMarging());
qDrawBorderPixmap(&p, QRect(0, 0, 76, 76), margins, source, source.rect(), margins, rules);
//p.drawPixmap(0,0,76,76, source);
} else {
uiBorderImage->sizeLabel->setText("");
}
uiBorderImage->label->setPixmap(pix);
} else {
ui->sizeLabel->setText("");
if (QFile(fileName).exists()) {
QPixmap source(fileName);
previewDialog()->setPixmap(source, 1);
ui->sizeLabel->setText(QString::number(source.width()) + 'x' + QString::number(source.height()));
QPainter p(&pix);
if (ui->stretchRadioButton->isChecked()) {
p.drawPixmap(0,0,76,76, source);
} else if (ui->tileRadioButton->isChecked()) {
QPixmap small = source.scaled(38,38);
p.drawTiledPixmap(0,0,76,76, small);
} else if (ui->horizontalStretchRadioButton->isChecked()) {
QPixmap small = source.scaled(38,38);
QPixmap half = pix.scaled(38, 76);
QPainter p2(&half);
p2.drawTiledPixmap(0,0,38,76, small);
p.drawPixmap(0,0,76,76, half);
} else if (ui->verticalStretchRadioButton->isChecked()) {
QPixmap small = source.scaled(38,38);
QPixmap half = pix.scaled(76, 38);
QPainter p2(&half);
p2.drawTiledPixmap(0,0,76,38, small);
p.drawPixmap(0,0,76,76, half);
} else if (ui->preserveAspectFitRadioButton->isChecked()) {
QPixmap preserved = source.scaledToWidth(76);
int offset = (76 - preserved.height()) / 2;
p.drawPixmap(0, offset, 76, preserved.height(), source);
} else if (ui->cropAspectFitRadioButton->isChecked()) {
QPixmap cropped = source.scaledToHeight(76);
int offset = (76 - cropped.width()) / 2;
p.drawPixmap(offset, 0, cropped.width(), 76, source);
}
} else {
ui->sizeLabel->setText("");
}
ui->label->setPixmap(pix);
}
}
PreviewDialog* ContextPaneWidgetImage::previewDialog()
{
if (!m_previewDialog) {
m_previewDialog = new PreviewDialog(this);
m_previewDialog->hide();
}
ui->label->setPixmap(pix);
return m_previewDialog.data();
}
void ContextPaneWidgetImage::changeEvent(QEvent *e)
@@ -204,29 +417,324 @@ void ContextPaneWidgetImage::changeEvent(QEvent *e)
}
}
void ContextPaneWidgetImage::hideEvent(QHideEvent * event)
{
previewWasVisible = previewDialog()->isVisible();
previewDialog()->hide();
QWidget::hideEvent(event);
}
void ContextPaneWidgetImage::showEvent(QShowEvent* event)
{
if (previewWasVisible)
previewDialog()->show();
QWidget::showEvent(event);
}
PreviewLabel::PreviewLabel(QWidget *parent) : QLabel(parent), m_dragging_top(false), m_dragging_bottom(false),
m_dragging_left(false), m_dragging_right(false)
{
m_zoom = 1;
m_showBorders = false;
m_left = 2;
m_right = 2;
m_top = 2;
m_bottom = 2;
setMouseTracking(true);
setCursor(QCursor(Qt::ArrowCursor));
}
void PreviewLabel::setZoom(int z)
{
m_zoom = z;
}
void PreviewLabel::setIsBorderImage(bool b)
{
m_borderImage = b;
}
void PreviewLabel::setMargins(int left, int top, int right, int bottom)
{
m_left = left;
m_top = top;
m_right = right;
m_bottom = bottom;
}
void PreviewLabel::paintEvent(QPaintEvent *event)
{
QLabel::paintEvent(event);
if (m_borderImage) {
QPainter p(this);
p.setOpacity(0.5);
p.setBackgroundMode(Qt::TransparentMode);
{
QPen pen(Qt::SolidLine);
pen.setColor("#F0F0F0");
p.setPen(pen);
p.drawLine(m_left * m_zoom, 4, m_left * m_zoom, height() - 4);
p.drawLine(width() - m_right * m_zoom, 4, width() - m_right * m_zoom, height() - 4);
p.drawLine(4, m_top * m_zoom, width() - 4, m_top * m_zoom);
p.drawLine(4, height() - m_bottom * m_zoom, width() - 4, height() - m_bottom * m_zoom);
}
{
QBrush brush(Qt::Dense4Pattern);
brush.setColor("#101010");
QPen pen(brush, 1, Qt::DotLine);
pen.setColor("#101010");
p.setPen(pen);
p.drawLine(m_left * m_zoom, 4, m_left * m_zoom, height() - 4);
p.drawLine(width() - m_right * m_zoom, 4, width() - m_right * m_zoom, height() - 4);
p.drawLine(4, m_top * m_zoom, width() - 4, m_top * m_zoom);
p.drawLine(4, height() - m_bottom * m_zoom, width() - 4, height() - m_bottom * m_zoom);
}
}
}
static inline bool rangeCheck(int target, int pos)
{
return (target - 10 < pos) && (target + 10 > pos);
}
void PreviewLabel::mousePressEvent(QMouseEvent * event)
{
if (!m_borderImage)
return QLabel::mouseMoveEvent(event);
if (event->button() == Qt::LeftButton) {
if (QApplication::overrideCursor())
QApplication::restoreOverrideCursor();
if (rangeCheck(m_left * m_zoom, event->pos().x())) {
QApplication::setOverrideCursor(QCursor(Qt::SizeHorCursor));
m_dragging_left = true;
event->accept();
} else if (rangeCheck(m_top * m_zoom, event->pos().y())) {
QApplication::setOverrideCursor(QCursor(Qt::SizeVerCursor));
m_dragging_top = true;
event->accept();
} else if (rangeCheck(m_right * m_zoom, width() - event->pos().x())) {
QApplication::setOverrideCursor(QCursor(Qt::SizeHorCursor));
m_dragging_right = true;
event->accept();
} else if (rangeCheck(m_bottom * m_zoom, height() - event->pos().y())) {
QApplication::setOverrideCursor(QCursor(Qt::SizeVerCursor));
m_dragging_bottom = true;
event->accept();
} else {
QLabel::mousePressEvent(event);
}
m_startPos = event->pos();
}
}
void PreviewLabel::mouseReleaseEvent(QMouseEvent * event)
{
if (!m_borderImage)
return QLabel::mouseMoveEvent(event);
if (m_dragging_left || m_dragging_top || m_dragging_right|| m_dragging_bottom) {
if (m_dragging_left)
emit leftMarginChanged();
if (m_dragging_top)
emit topMarginChanged();
if (m_dragging_bottom)
emit bottomMarginChanged();
if (m_dragging_right)
emit rightMarginChanged();
m_dragging_left = false;
m_dragging_top = false;
m_dragging_right = false;
m_dragging_bottom = false;
QApplication::restoreOverrideCursor();
event->accept();
} else {
QLabel::mouseReleaseEvent(event);
}
}
static inline int limit(int i, int zoom)
{
static bool flag1 = 1;
static bool flag2 = 1;
if (zoom == 1)
return i;
if (i < 0) {
int v = i / zoom;
if (v)
return v;
if (zoom == 2) {
flag1 =!flag1;
return flag1 ? -1 : 0;
}
flag1 =!flag1;
if (flag1)
flag2 =!flag2;
return flag1 && flag2 ? -1 : 0;
}
if (i > 0) {
int v = i / zoom;
if (v)
return v;
if (zoom == 2) {
flag1 =!flag1;
return flag1 ? 1 : 0;
}
flag1 =!flag1;
if (flag1)
flag2 =!flag2;
return flag1 && flag2 ? 1 : 0;
}
return 0;
}
void PreviewLabel::mouseMoveEvent(QMouseEvent * event)
{
if (!m_borderImage)
return QLabel::mouseMoveEvent(event);
QPoint p = event->pos();
if (m_dragging_left) {
m_left += limit(p.x() - m_startPos.x(), m_zoom);
event->accept();
update();
} else if (m_dragging_top) {
m_top += limit(p.y() - m_startPos.y(), m_zoom);
event->accept();
update();
} else if (m_dragging_right) {
m_right += limit(m_startPos.x() - p.x(), m_zoom);
event->accept();
update();
} else if (m_dragging_bottom) {
m_bottom += limit(m_startPos.y() - p.y(), m_zoom);
event->accept();
update();
} else if (rangeCheck(m_left * m_zoom, p.x())) {
QApplication::setOverrideCursor(QCursor(Qt::SizeHorCursor));
event->accept();
} else if (rangeCheck(m_top * m_zoom, p.y())) {
QApplication::setOverrideCursor(QCursor(Qt::SizeVerCursor));
event->accept();
} else if (rangeCheck(m_right * m_zoom, width() - p.x())) {
QApplication::setOverrideCursor(QCursor(Qt::SizeHorCursor));
event->accept();
} else if (rangeCheck(m_bottom * m_zoom, height() - p.y())) {
QApplication::setOverrideCursor(QCursor(Qt::SizeVerCursor));
event->accept();
} else {
if (QApplication::overrideCursor())
QApplication::restoreOverrideCursor();
QLabel::mouseMoveEvent(event);
}
m_startPos = p;
}
void PreviewLabel::leaveEvent(QEvent* event )
{
while (QApplication::overrideCursor())
QApplication::restoreOverrideCursor();
QLabel::leaveEvent(event);
}
PreviewDialog::PreviewDialog(QWidget *parent) : DragWidget(parent)
{
m_zoom = 1;
m_borderImage = false;
setAutoFillBackground(true);
m_label = new QLabel(this);
m_label = new PreviewLabel(this);
m_slider = new QSlider(this);
QGridLayout *layout = new QGridLayout(this);
layout->setMargin(0);
layout->setContentsMargins(1, 1, 1, 1);
layout->setSpacing(0);
layout->setContentsMargins(2, 2, 2, 6);
layout->setSpacing(4);
QToolButton *toolButton = new QToolButton(this);
QIcon icon(style()->standardIcon(QStyle::SP_DockWidgetCloseButton));
toolButton->setIcon(icon);
toolButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
toolButton->setFixedSize(icon.availableSizes().value(0) + QSize(4, 4));
connect(toolButton, SIGNAL(clicked()), this, SLOT(onTogglePane()));
layout->addWidget(toolButton, 0, 0, 1, 1);
layout->addWidget(m_label, 0, 1, 2, 2);
layout->addWidget(toolButton, 0, 0, 1, 1);
QScrollArea *scrollArea = new QScrollArea(this);
WheelFilter *wheelFilter = new WheelFilter(scrollArea);
//scrollArea->installEventFilter(wheelFilter);
scrollArea->setWidget(m_label);
scrollArea->setFrameStyle(QFrame::NoFrame);
m_slider->setOrientation(Qt::Horizontal);
m_slider->setMaximumWidth(120);
//layout->addItem(new QSpacerItem(10, 10), 0, 1, 1, 1);
layout->addWidget(m_slider, 0, 1, 1, 2);
layout->addWidget(scrollArea, 1, 1, 2, 2);
wheelFilter->setTarget(this);
foreach (QWidget *childWidget, findChildren<QWidget*>()) {
childWidget->installEventFilter(wheelFilter);
}
}
void PreviewDialog::setPixmap(const QPixmap &p)
void PreviewDialog::setPixmap(const QPixmap &p, int zoom)
{
m_label->setPixmap(p);
m_pixmap = p;
m_label->setPixmap(p.scaled(p.width() * zoom, p.height() * zoom));
m_label->adjustSize();
m_zoom = zoom;
m_label->setZoom(m_zoom);
QSize size = m_label->pixmap()->size() + QSize(44, 44);
if (size.width() < 140)
size.setWidth(140);
resize(size);
}
void PreviewDialog::wheelEvent(QWheelEvent* event)
{
int delta = event->delta();
event->accept();
if (delta > 0) {
if (m_zoom == 1)
m_zoom = 2;
else if (m_zoom == 2)
m_zoom = 4;
else if (m_zoom == 4)
m_zoom = 6;
else if (m_zoom == 6)
m_zoom = 8;
else if (m_zoom == 8)
m_zoom = 10;
} else {
if (m_zoom == 10)
m_zoom = 8;
else if (m_zoom == 8)
m_zoom = 6;
else if (m_zoom == 6)
m_zoom = 4;
else if (m_zoom == 4)
m_zoom = 2;
else if (m_zoom == 2)
m_zoom = 1;
}
setPixmap(m_pixmap, m_zoom);
}
void PreviewDialog::onTogglePane()

View File

@@ -3,20 +3,63 @@
#include <QWidget>
#include <QFrame>
#include <QLabel>
#include <qdrawutil.h>
#include <contextpanewidget.h>
QT_BEGIN_NAMESPACE
namespace Ui {
class ContextPaneWidgetImage;
class ContextPaneWidgetBorderImage;
}
class QLabel;
class QSlider;
class FileWidget;
QT_END_NAMESPACE
namespace QmlJS {
class PropertyReader;
}
namespace QmlDesigner {
namespace QmlDesigner {
class PreviewLabel : public QLabel
{
Q_OBJECT
public:
PreviewLabel(QWidget *parent = 0);
void setZoom(int);
void setIsBorderImage(bool b);
void setMargins(int left, int top, int right, int bottom);
int leftMarging() const { return m_left; }
int topMarging() const { return m_top; }
int rightMarging() const { return m_right; }
int bottomMarging() const { return m_bottom; }
signals:
void leftMarginChanged();
void topMarginChanged();
void bottomMarginChanged();
void rightMarginChanged();
protected:
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent * event);
void mouseReleaseEvent(QMouseEvent * event);
void mouseMoveEvent(QMouseEvent * event);
void leaveEvent(QEvent* event );
private:
bool m_showBorders;
int m_left, m_right, m_top, m_bottom;
bool m_dragging_left;
bool m_dragging_right;
bool m_dragging_top;
bool m_dragging_bottom;
QPoint m_startPos;
int m_zoom;
bool m_borderImage;
};
class PreviewDialog : public DragWidget
{
@@ -24,12 +67,24 @@ class PreviewDialog : public DragWidget
public:
PreviewDialog(QWidget *parent = 0);
void setPixmap(const QPixmap &p);
void setPixmap(const QPixmap &p, int zoom = 1);
void setZoom(int z);
void setIsBorderImage(bool b);
PreviewLabel *previewLabel() const;
int zoom() { return m_zoom; }
public slots:
void onTogglePane();
protected:
void wheelEvent(QWheelEvent* event);
private:
QLabel * m_label;
PreviewLabel *m_label;
QSlider *m_slider;
int m_zoom;
QPixmap m_pixmap;
bool m_borderImage;
};
class ContextPaneWidgetImage : public QWidget
@@ -37,10 +92,11 @@ class ContextPaneWidgetImage : public QWidget
Q_OBJECT
public:
explicit ContextPaneWidgetImage(QWidget *parent = 0);
explicit ContextPaneWidgetImage(QWidget *parent = 0, bool borderImage = false);
~ContextPaneWidgetImage();
void setProperties(QmlJS::PropertyReader *propertyReader);
void setPath(const QString& path);
void setPath(const QString& path);
PreviewDialog* previewDialog();
signals:
void propertyChanged(const QString &, const QVariant &);
@@ -49,17 +105,30 @@ signals:
public slots:
void onStretchChanged();
void onVerticalStretchChanged();
void onHorizontalStretchChanged();
void onFileNameChanged();
void onPixmapDoubleClicked();
void setPixmap(const QString &fileName);
void onLeftMarginsChanged();
void onTopMarginsChanged();
void onBottomMarginsChanged();
void onRightMarginsChanged();
protected:
void changeEvent(QEvent *e);
void hideEvent(QHideEvent* event);
void showEvent(QShowEvent* event);
private:
Ui::ContextPaneWidgetImage *ui;
Ui::ContextPaneWidgetBorderImage *uiBorderImage;
QString m_path;
PreviewDialog *m_previewDialog;
QWeakPointer<PreviewDialog> m_previewDialog;
FileWidget *m_fileWidget;
QLabel *m_sizeLabel;
bool m_borderImage;
bool previewWasVisible;
};
class LabelFilter: public QObject {
@@ -73,6 +142,18 @@ protected:
bool eventFilter(QObject *obj, QEvent *event);
};
class WheelFilter: public QObject {
Q_OBJECT
public:
WheelFilter(QObject* parent =0) : QObject(parent) {}
void setTarget(QObject *target) { m_target = target; }
protected:
bool eventFilter(QObject *obj, QEvent *event);
QObject *m_target;
};