Gui: add function to scale image
This commit is contained in:
@@ -31,8 +31,30 @@ PROPERTY_SOURCE(App::ImagePlane, App::GeoFeature)
|
||||
|
||||
|
||||
ImagePlane::ImagePlane()
|
||||
: XPixelsPerMeter{1000.0}
|
||||
, YPixelsPerMeter{1000.0}
|
||||
{
|
||||
ADD_PROPERTY_TYPE( ImageFile,(nullptr) , "ImagePlane",Prop_None,"File of the image");
|
||||
ADD_PROPERTY_TYPE( XSize, (100), "ImagePlane",Prop_None,"Size of a pixel in X");
|
||||
ADD_PROPERTY_TYPE( YSize, (100), "ImagePlane",Prop_None,"Size of a pixel in Y");
|
||||
}
|
||||
|
||||
int ImagePlane::getXSizeInPixel()
|
||||
{
|
||||
return int(XSize.getValue() * XPixelsPerMeter / 1000);
|
||||
}
|
||||
|
||||
int ImagePlane::getYSizeInPixel()
|
||||
{
|
||||
return int(YSize.getValue() * YPixelsPerMeter / 1000);
|
||||
}
|
||||
|
||||
void ImagePlane::setXSizeInPixel(int value)
|
||||
{
|
||||
XSize.setValue(double(value) * 1000.0 / XPixelsPerMeter);
|
||||
}
|
||||
|
||||
void ImagePlane::setYSizeInPixel(int value)
|
||||
{
|
||||
YSize.setValue(double(value) * 1000.0 / YPixelsPerMeter);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,14 @@ public:
|
||||
App::PropertyLength XSize;
|
||||
App::PropertyLength YSize;
|
||||
|
||||
int getXSizeInPixel();
|
||||
int getYSizeInPixel();
|
||||
void setXSizeInPixel(int);
|
||||
void setYSizeInPixel(int);
|
||||
|
||||
double XPixelsPerMeter;
|
||||
double YPixelsPerMeter;
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
const char* getViewProviderName() const override {
|
||||
return "Gui::ViewProviderImagePlane";
|
||||
|
||||
@@ -345,6 +345,7 @@ SET(Gui_UIC_SRCS
|
||||
Placement.ui
|
||||
TextureMapping.ui
|
||||
TaskView/TaskAppearance.ui
|
||||
TaskView/TaskImageScale.ui
|
||||
TaskView/TaskOrientation.ui
|
||||
TaskView/TaskSelectLinkProperty.ui
|
||||
TaskElementColors.ui
|
||||
@@ -727,6 +728,9 @@ SET(Task_View_SRCS
|
||||
TaskView/TaskAppearance.cpp
|
||||
TaskView/TaskAppearance.h
|
||||
TaskView/TaskAppearance.ui
|
||||
TaskView/TaskImageScale.cpp
|
||||
TaskView/TaskImageScale.h
|
||||
TaskView/TaskImageScale.ui
|
||||
TaskView/TaskOrientation.cpp
|
||||
TaskView/TaskOrientation.h
|
||||
TaskView/TaskOrientation.ui
|
||||
@@ -1239,6 +1243,7 @@ if(MSVC)
|
||||
propertyeditor/PropertyItemDelegate.cpp
|
||||
propertyeditor/PropertyModel.cpp
|
||||
TaskView/TaskAppearance.cpp
|
||||
TaskView/TaskImageScale.cpp
|
||||
TaskView/TaskOrientation.cpp
|
||||
TaskView/TaskSelectLinkProperty.cpp
|
||||
TaskView/TaskEditControl.cpp
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#endif
|
||||
|
||||
#include "TaskDialog.h"
|
||||
#include "TaskView.h"
|
||||
|
||||
using namespace Gui::TaskView;
|
||||
|
||||
@@ -55,6 +56,14 @@ TaskDialog::~TaskDialog()
|
||||
|
||||
//==== Slots ===============================================================
|
||||
|
||||
void TaskDialog::addTaskBox(QWidget* widget)
|
||||
{
|
||||
Gui::TaskView::TaskBox* taskbox = new Gui::TaskView::TaskBox(
|
||||
QPixmap(), widget->windowTitle(), true, nullptr);
|
||||
taskbox->groupLayout()->addWidget(widget);
|
||||
Content.push_back(taskbox);
|
||||
}
|
||||
|
||||
const std::vector<QWidget*> &TaskDialog::getDialogContent() const
|
||||
{
|
||||
return Content;
|
||||
|
||||
@@ -57,6 +57,8 @@ public:
|
||||
TaskDialog();
|
||||
~TaskDialog() override;
|
||||
|
||||
void addTaskBox(QWidget*);
|
||||
|
||||
void setButtonPosition(ButtonPosition p)
|
||||
{ pos = p; }
|
||||
ButtonPosition buttonPosition() const
|
||||
|
||||
88
src/Gui/TaskView/TaskImageScale.cpp
Normal file
88
src/Gui/TaskView/TaskImageScale.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD 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 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD 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 FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <QDialog>
|
||||
# include <map>
|
||||
#endif
|
||||
|
||||
#include <Base/Tools.h>
|
||||
#include <App/Document.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Camera.h>
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
|
||||
#include "TaskImageScale.h"
|
||||
#include "ui_TaskImageScale.h"
|
||||
|
||||
|
||||
using namespace Gui;
|
||||
|
||||
TaskImageScale::TaskImageScale(App::ImagePlane* obj, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui_TaskImageScale)
|
||||
, feature(obj)
|
||||
, aspectRatio{1.0}
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->spinBoxWidth->setValue(obj->getXSizeInPixel());
|
||||
ui->spinBoxHeight->setValue(obj->getYSizeInPixel());
|
||||
|
||||
aspectRatio = obj->XSize.getValue() / obj->YSize.getValue();
|
||||
|
||||
connect(ui->spinBoxWidth, qOverload<int>(&QSpinBox::valueChanged), this, &TaskImageScale::changeWidth);
|
||||
connect(ui->spinBoxHeight, qOverload<int>(&QSpinBox::valueChanged), this, &TaskImageScale::changeHeight);
|
||||
}
|
||||
|
||||
TaskImageScale::~TaskImageScale()
|
||||
{
|
||||
}
|
||||
|
||||
void TaskImageScale::changeWidth()
|
||||
{
|
||||
if (!feature.expired()) {
|
||||
int value = ui->spinBoxWidth->value();
|
||||
feature->setXSizeInPixel(value);
|
||||
|
||||
if (ui->checkBoxRatio->isChecked()) {
|
||||
QSignalBlocker block(ui->spinBoxWidth);
|
||||
ui->spinBoxHeight->setValue(int(double(value) / aspectRatio));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TaskImageScale::changeHeight()
|
||||
{
|
||||
if (!feature.expired()) {
|
||||
int value = ui->spinBoxHeight->value();
|
||||
feature->setYSizeInPixel(value);
|
||||
|
||||
if (ui->checkBoxRatio->isChecked()) {
|
||||
QSignalBlocker block(ui->spinBoxHeight);
|
||||
ui->spinBoxWidth->setValue(int(double(value) * aspectRatio));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_TaskImageScale.cpp"
|
||||
55
src/Gui/TaskView/TaskImageScale.h
Normal file
55
src/Gui/TaskView/TaskImageScale.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD 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 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD 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 FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef GUI_TASKIMAGESCALE_H
|
||||
#define GUI_TASKIMAGESCALE_H
|
||||
|
||||
#include <Gui/TaskView/TaskDialog.h>
|
||||
#include <App/DocumentObserver.h>
|
||||
#include <App/ImagePlane.h>
|
||||
#include <memory>
|
||||
|
||||
namespace Gui {
|
||||
|
||||
class Ui_TaskImageScale;
|
||||
class TaskImageScale : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TaskImageScale(App::ImagePlane* obj, QWidget* parent = nullptr);
|
||||
~TaskImageScale() override;
|
||||
|
||||
private:
|
||||
void changeWidth();
|
||||
void changeHeight();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui_TaskImageScale> ui;
|
||||
App::WeakPtrT<App::ImagePlane> feature;
|
||||
double aspectRatio;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // GUI_TASKIMAGESCALE_H
|
||||
94
src/Gui/TaskView/TaskImageScale.ui
Normal file
94
src/Gui/TaskView/TaskImageScale.ui
Normal file
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Gui::TaskImageScale</class>
|
||||
<widget class="QWidget" name="Gui::TaskImageScale">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>277</width>
|
||||
<height>178</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Scale image</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Image size</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Width:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxWidth">
|
||||
<property name="suffix">
|
||||
<string notr="true"> px</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100000000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Height:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxHeight">
|
||||
<property name="suffix">
|
||||
<string notr="true"> px</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100000000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBoxRatio">
|
||||
<property name="text">
|
||||
<string>Keep aspect ratio</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>18</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Control.h>
|
||||
#include <Gui/TaskView/TaskOrientation.h>
|
||||
#include <Gui/TaskView/TaskImageScale.h>
|
||||
#include <App/ImagePlane.h>
|
||||
|
||||
#include "ViewProviderImagePlane.h"
|
||||
@@ -142,27 +143,30 @@ void ViewProviderImagePlane::onChanged(const App::Property* prop)
|
||||
|
||||
void ViewProviderImagePlane::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
|
||||
{
|
||||
ViewProviderGeometryObject::setupContextMenu(menu, receiver, member);
|
||||
|
||||
Gui::ActionFunction* func = new Gui::ActionFunction(menu);
|
||||
QAction* orient = menu->addAction(QObject::tr("Change orientation..."));
|
||||
func->trigger(orient, std::bind(&ViewProviderImagePlane::changeOrientation, this));
|
||||
QAction* action = menu->addAction(QObject::tr("Change image..."));
|
||||
action->setIcon(QIcon(QLatin1String("images:image-scaling.svg")));
|
||||
func->trigger(action, std::bind(&ViewProviderImagePlane::manipulateImage, this));
|
||||
|
||||
QAction* scale = menu->addAction(QObject::tr("Scale image..."));
|
||||
scale->setIcon(QIcon(QLatin1String("images:image-scaling.svg")));
|
||||
func->trigger(scale, std::bind(&ViewProviderImagePlane::scaleImage, this));
|
||||
ViewProviderGeometryObject::setupContextMenu(menu, receiver, member);
|
||||
}
|
||||
|
||||
void ViewProviderImagePlane::changeOrientation()
|
||||
bool ViewProviderImagePlane::doubleClicked()
|
||||
{
|
||||
Gui::Control().showDialog(new TaskOrientationDialog(
|
||||
manipulateImage();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViewProviderImagePlane::manipulateImage()
|
||||
{
|
||||
auto dialog = new TaskOrientationDialog(
|
||||
dynamic_cast<App::GeoFeature*>(getObject())
|
||||
);
|
||||
dialog->addTaskBox(new TaskImageScale(
|
||||
dynamic_cast<App::ImagePlane*>(getObject())
|
||||
));
|
||||
}
|
||||
|
||||
void ViewProviderImagePlane::scaleImage()
|
||||
{
|
||||
|
||||
Gui::Control().showDialog(dialog);
|
||||
}
|
||||
|
||||
void ViewProviderImagePlane::resizePlane(float xsize, float ysize)
|
||||
@@ -188,6 +192,9 @@ void ViewProviderImagePlane::loadImage()
|
||||
if (!impQ.isNull()) {
|
||||
imagePlane->XSize.setValue(size.width());
|
||||
imagePlane->YSize.setValue(size.height());
|
||||
|
||||
imagePlane->XPixelsPerMeter = impQ.dotsPerMeterX();
|
||||
imagePlane->YPixelsPerMeter = impQ.dotsPerMeterY();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
std::vector<std::string> getDisplayModes() const override;
|
||||
void updateData(const App::Property*) override;
|
||||
void setupContextMenu(QMenu*, QObject*, const char*) override;
|
||||
bool doubleClicked() override;
|
||||
void onChanged(const App::Property* prop) override;
|
||||
|
||||
private:
|
||||
@@ -59,8 +60,7 @@ private:
|
||||
bool loadSvg(const char*, double x, double y, QImage& img);
|
||||
QSizeF loadRaster(const char*, QImage& img);
|
||||
void convertToSFImage(const QImage& img);
|
||||
void changeOrientation();
|
||||
void scaleImage();
|
||||
void manipulateImage();
|
||||
|
||||
private:
|
||||
SoCoordinate3 * pcCoords;
|
||||
|
||||
Reference in New Issue
Block a user