mirror of
https://github.com/leozide/leocad
synced 2024-11-16 07:47:27 +01:00
Replaced piece properties widget.
This commit is contained in:
parent
3c79bbeaa0
commit
ef43c152ad
10 changed files with 1235 additions and 40 deletions
|
@ -3,10 +3,10 @@
|
|||
#include <QPrintDialog>
|
||||
#include <QPrintPreviewDialog>
|
||||
#include "lc_partselectionwidget.h"
|
||||
#include "lc_propertieswidget.h"
|
||||
#include "lc_timelinewidget.h"
|
||||
#include "lc_viewwidget.h"
|
||||
#include "lc_colorlist.h"
|
||||
#include "lc_qpropertiestree.h"
|
||||
#include "lc_qutils.h"
|
||||
#include "lc_qupdatedialog.h"
|
||||
#include "lc_aboutdialog.h"
|
||||
|
@ -738,8 +738,12 @@ void lcMainWindow::CreateToolBars()
|
|||
QVBoxLayout* PropertiesLayout = new QVBoxLayout(PropertiesWidget);
|
||||
PropertiesLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
mPropertiesWidget = new lcQPropertiesTree(PropertiesWidget);
|
||||
PropertiesLayout->addWidget(mPropertiesWidget);
|
||||
QScrollArea* PropertiesScrollArea = new QScrollArea(PropertiesWidget);
|
||||
PropertiesScrollArea->setWidgetResizable(true);
|
||||
PropertiesLayout->addWidget(PropertiesScrollArea);
|
||||
|
||||
mPropertiesWidget = new lcPropertiesWidget(PropertiesScrollArea);
|
||||
PropertiesScrollArea->setWidget(mPropertiesWidget);
|
||||
|
||||
QHBoxLayout* TransformLayout = new QHBoxLayout;
|
||||
QWidget* TransformWidget = new QWidget();
|
||||
|
|
|
@ -11,7 +11,7 @@ class lcPreviewDockWidget;
|
|||
class PiecePreview;
|
||||
class lcQPartsTree;
|
||||
class lcColorList;
|
||||
class lcQPropertiesTree;
|
||||
class lcPropertiesWidget;
|
||||
class lcTimelineWidget;
|
||||
class lcElidedLabel;
|
||||
#ifdef QT_NO_PRINTER
|
||||
|
@ -378,7 +378,7 @@ protected:
|
|||
lcPartSelectionWidget* mPartSelectionWidget;
|
||||
lcColorList* mColorList;
|
||||
QToolButton* mColorButton;
|
||||
lcQPropertiesTree* mPropertiesWidget;
|
||||
lcPropertiesWidget* mPropertiesWidget;
|
||||
lcTimelineWidget* mTimelineWidget;
|
||||
QLineEdit* mTransformXEdit;
|
||||
QLineEdit* mTransformYEdit;
|
||||
|
|
815
common/lc_propertieswidget.cpp
Normal file
815
common/lc_propertieswidget.cpp
Normal file
|
@ -0,0 +1,815 @@
|
|||
#include "lc_global.h"
|
||||
#include "lc_propertieswidget.h"
|
||||
#include "object.h"
|
||||
#include "piece.h"
|
||||
#include "camera.h"
|
||||
#include "light.h"
|
||||
#include "pieceinf.h"
|
||||
#include "lc_mainwindow.h"
|
||||
#include "lc_collapsiblewidget.h"
|
||||
#include "lc_colorpicker.h"
|
||||
#include "lc_qutils.h"
|
||||
|
||||
lcPropertiesWidget::lcPropertiesWidget(QWidget* Parent)
|
||||
: QWidget(Parent)
|
||||
{
|
||||
mLayoutLightType = lcLightType::Count;
|
||||
mLayoutLightAreaShape = lcLightAreaShape::Count;
|
||||
}
|
||||
|
||||
lcPropertiesWidget::PropertyIndex lcPropertiesWidget::GetWidgetIndex(QWidget* Widget) const
|
||||
{
|
||||
if (!Widget)
|
||||
return PropertyIndex::Count;
|
||||
|
||||
for (size_t Index = 0; Index < mPropertyWidgets.size(); Index++)
|
||||
if (mPropertyWidgets[Index] == Widget)
|
||||
return static_cast<PropertyIndex>(Index);
|
||||
|
||||
return PropertyIndex::Count;
|
||||
}
|
||||
|
||||
QGridLayout* lcPropertiesWidget::AddPropertyCategory(const QString& Title, QVBoxLayout* Layout)
|
||||
{
|
||||
lcCollapsibleWidget* CategoryWidget = new lcCollapsibleWidget(Title);
|
||||
|
||||
mCategoryWidgets.push_back(CategoryWidget);
|
||||
Layout->addWidget(CategoryWidget);
|
||||
|
||||
QGridLayout* CategoryLayout = new QGridLayout();
|
||||
CategoryLayout->setContentsMargins(0, 0, 0, 0);
|
||||
CategoryLayout->setColumnMinimumWidth(0, 10);
|
||||
CategoryLayout->setVerticalSpacing(1);
|
||||
CategoryWidget->SetChildLayout(CategoryLayout);
|
||||
|
||||
return CategoryLayout;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::AddSpacing(QGridLayout* Layout, int& Row)
|
||||
{
|
||||
Layout->setRowMinimumHeight(Row, 5);
|
||||
Row++;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::AddLabel(const QString& Text, const QString& ToolTip, QGridLayout* Layout, int Row)
|
||||
{
|
||||
QLabel* Label = new QLabel(Text, this);
|
||||
Label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
// Label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
Label->setToolTip(ToolTip);
|
||||
|
||||
Layout->addWidget(Label, Row, 1);
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::AddBoolProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, QGridLayout* Layout, int& Row)
|
||||
{
|
||||
AddLabel(Text, ToolTip, Layout, Row);
|
||||
|
||||
QCheckBox* Widget = new QCheckBox(this);
|
||||
Widget->setToolTip(ToolTip);
|
||||
// int value = Item->data(0, PropertyValueRole).toInt();
|
||||
|
||||
// updateColorEditor(editor, value);
|
||||
|
||||
// connect(editor, SIGNAL(clicked()), this, SLOT(slotColorButtonClicked()));
|
||||
|
||||
Layout->addWidget(Widget, Row, 2);
|
||||
|
||||
mPropertyWidgets[static_cast<int>(Index)] = Widget;
|
||||
|
||||
Row++;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::FloatChanged()
|
||||
{
|
||||
QLineEdit* Widget = qobject_cast<QLineEdit*>(sender());
|
||||
PropertyIndex Index = GetWidgetIndex(Widget);
|
||||
|
||||
if (Index == PropertyIndex::Count)
|
||||
return;
|
||||
|
||||
lcModel* Model = gMainWindow->GetActiveModel();
|
||||
lcPiece* Piece = dynamic_cast<lcPiece*>(mFocusObject);
|
||||
lcLight* Light = dynamic_cast<lcLight*>(mFocusObject);
|
||||
float Value = lcParseValueLocalized(Widget->text());
|
||||
|
||||
// todo: mouse drag
|
||||
|
||||
if (Index == PropertyIndex::ObjectPositionX || Index == PropertyIndex::ObjectPositionY || Index == PropertyIndex::ObjectPositionZ)
|
||||
{
|
||||
lcVector3 Center;
|
||||
lcMatrix33 RelativeRotation;
|
||||
Model->GetMoveRotateTransform(Center, RelativeRotation);
|
||||
lcVector3 Position = Center;
|
||||
|
||||
if (Index == PropertyIndex::ObjectPositionX)
|
||||
Position[0] = Value;
|
||||
else if (Index == PropertyIndex::ObjectPositionY)
|
||||
Position[1] = Value;
|
||||
else if (Index == PropertyIndex::ObjectPositionZ)
|
||||
Position[2] = Value;
|
||||
|
||||
lcVector3 Distance = Position - Center;
|
||||
|
||||
Model->MoveSelectedObjects(Distance, Distance, false, true, true, true);
|
||||
}
|
||||
else if (Index == PropertyIndex::ObjectRotationX || Index == PropertyIndex::ObjectRotationY || Index == PropertyIndex::ObjectRotationZ)
|
||||
{
|
||||
lcVector3 InitialRotation(0.0f, 0.0f, 0.0f);
|
||||
|
||||
if (Piece)
|
||||
InitialRotation = lcMatrix44ToEulerAngles(Piece->mModelWorld) * LC_RTOD;
|
||||
else if (Light)
|
||||
InitialRotation = lcMatrix44ToEulerAngles(Light->GetWorldMatrix()) * LC_RTOD;
|
||||
|
||||
lcVector3 Rotation = InitialRotation;
|
||||
|
||||
if (Index == PropertyIndex::ObjectRotationX)
|
||||
Rotation[0] = Value;
|
||||
else if (Index == PropertyIndex::ObjectRotationY)
|
||||
Rotation[1] = Value;
|
||||
else if (Index == PropertyIndex::ObjectRotationZ)
|
||||
Rotation[2] = Value;
|
||||
|
||||
Model->RotateSelectedObjects(Rotation - InitialRotation, true, false, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::UpdateFloat(PropertyIndex Index, float Value)
|
||||
{
|
||||
QLineEdit* Widget = qobject_cast<QLineEdit*>(mPropertyWidgets[static_cast<int>(Index)]);
|
||||
|
||||
if (Widget)
|
||||
{
|
||||
QSignalBlocker Blocker(Widget);
|
||||
|
||||
Widget->setText(lcFormatValueLocalized(Value));
|
||||
}
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::AddFloatProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, float Min, float Max, QGridLayout* Layout, int& Row)
|
||||
{
|
||||
AddLabel(Text, ToolTip, Layout, Row);
|
||||
|
||||
QLineEdit* Widget = new QLineEdit(this);
|
||||
Widget->setToolTip(ToolTip);
|
||||
|
||||
Widget->setValidator(new QDoubleValidator(Min, Max, 1, Widget));
|
||||
|
||||
connect(Widget, &QLineEdit::editingFinished, this, &lcPropertiesWidget::FloatChanged);
|
||||
|
||||
Layout->addWidget(Widget, Row, 2);
|
||||
|
||||
mPropertyWidgets[static_cast<int>(Index)] = Widget;
|
||||
|
||||
Row++;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::AddIntegerProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, int Min, int Max, QGridLayout* Layout, int& Row)
|
||||
{
|
||||
AddLabel(Text, ToolTip, Layout, Row);
|
||||
|
||||
QSpinBox* Widget = new QSpinBox(this);
|
||||
Widget->setRange(Min, Max);
|
||||
Widget->setToolTip(ToolTip);
|
||||
|
||||
Layout->addWidget(Widget, Row, 2);
|
||||
|
||||
mPropertyWidgets[static_cast<int>(Index)] = Widget;
|
||||
|
||||
Row++;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::StepNumberChanged()
|
||||
{
|
||||
QLineEdit* Widget = qobject_cast<QLineEdit*>(sender());
|
||||
PropertyIndex Index = GetWidgetIndex(Widget);
|
||||
|
||||
if (Index == PropertyIndex::Count)
|
||||
return;
|
||||
|
||||
lcModel* Model = gMainWindow->GetActiveModel();
|
||||
|
||||
if (!Model)
|
||||
return;
|
||||
|
||||
bool Ok = true;
|
||||
QString Text = Widget->text();
|
||||
lcStep Step = Text.isEmpty() && Index == PropertyIndex::PieceStepHide ? LC_STEP_MAX : Text.toUInt(&Ok);
|
||||
|
||||
if (!Ok)
|
||||
return;
|
||||
|
||||
if (Index == PropertyIndex::PieceStepShow)
|
||||
{
|
||||
Model->SetSelectedPiecesStepShow(Step);
|
||||
}
|
||||
else if (Index == PropertyIndex::PieceStepHide)
|
||||
{
|
||||
Model->SetSelectedPiecesStepHide(Step);
|
||||
}
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::UpdateStepNumber(PropertyIndex Index, lcStep Step, lcStep Min, lcStep Max)
|
||||
{
|
||||
QLineEdit* Widget = qobject_cast<QLineEdit*>(mPropertyWidgets[static_cast<int>(Index)]);
|
||||
|
||||
if (Widget)
|
||||
{
|
||||
QSignalBlocker Blocker(Widget);
|
||||
|
||||
Widget->setValidator(new lcStepValidator(Min, Max, Index == PropertyIndex::PieceStepHide, Widget));
|
||||
Widget->setText(Step == LC_STEP_MAX ? QString() : QString::number(Step));
|
||||
}
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::AddStepNumberProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, QGridLayout* Layout, int& Row)
|
||||
{
|
||||
AddLabel(Text, ToolTip, Layout, Row);
|
||||
|
||||
QLineEdit* Widget = new QLineEdit(this);
|
||||
Widget->setToolTip(ToolTip);
|
||||
|
||||
connect(Widget, &QLineEdit::editingFinished, this, &lcPropertiesWidget::StepNumberChanged);
|
||||
|
||||
Layout->addWidget(Widget, Row, 2);
|
||||
|
||||
mPropertyWidgets[static_cast<int>(Index)] = Widget;
|
||||
|
||||
Row++;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::AddStringProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, QGridLayout* Layout, int& Row)
|
||||
{
|
||||
AddLabel(Text, ToolTip, Layout, Row);
|
||||
|
||||
QLineEdit* Widget = new QLineEdit(this);
|
||||
Widget->setToolTip(ToolTip);
|
||||
|
||||
Layout->addWidget(Widget, Row, 2);
|
||||
|
||||
mPropertyWidgets[static_cast<int>(Index)] = Widget;
|
||||
|
||||
Row++;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::AddStringListProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, const QStringList& Strings, QGridLayout* Layout, int& Row)
|
||||
{
|
||||
AddLabel(Text, ToolTip, Layout, Row);
|
||||
|
||||
QComboBox* Widget = new QComboBox(this);
|
||||
Widget->setToolTip(ToolTip);
|
||||
Widget->addItems(Strings);
|
||||
// int value = Item->data(0, PropertyValueRole).toInt();
|
||||
|
||||
// updateColorEditor(editor, value);
|
||||
|
||||
// connect(editor, SIGNAL(clicked()), this, SLOT(slotColorButtonClicked()));
|
||||
|
||||
Layout->addWidget(Widget, Row, 2);
|
||||
|
||||
mPropertyWidgets[static_cast<int>(Index)] = Widget;
|
||||
|
||||
Row++;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::AddColorProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, QGridLayout* Layout, int& Row)
|
||||
{
|
||||
AddLabel(Text, ToolTip, Layout, Row);
|
||||
|
||||
QPushButton* Widget = new QPushButton(this);
|
||||
Widget->setToolTip(ToolTip);
|
||||
// int value = Item->data(0, PropertyValueRole).toInt();
|
||||
|
||||
// updateColorEditor(editor, value);
|
||||
|
||||
// connect(editor, SIGNAL(clicked()), this, SLOT(slotColorButtonClicked()));
|
||||
|
||||
Layout->addWidget(Widget, Row, 2);
|
||||
|
||||
mPropertyWidgets[static_cast<int>(Index)] = Widget;
|
||||
|
||||
Row++;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::PieceColorChanged(int ColorIndex)
|
||||
{
|
||||
if (!mFocusObject || !mFocusObject->IsPiece())
|
||||
return;
|
||||
|
||||
lcModel* Model = gMainWindow->GetActiveModel();
|
||||
Model->SetSelectedPiecesColorIndex(ColorIndex);
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::PieceColorButtonClicked()
|
||||
{
|
||||
QToolButton* ColorButton = qobject_cast<QToolButton*>(sender());
|
||||
|
||||
if (!ColorButton || !mFocusObject || !mFocusObject->IsPiece())
|
||||
return;
|
||||
|
||||
int ColorIndex = reinterpret_cast<lcPiece*>(mFocusObject)->GetColorIndex();
|
||||
|
||||
lcColorPickerPopup* Popup = new lcColorPickerPopup(ColorButton, ColorIndex);
|
||||
connect(Popup, &lcColorPickerPopup::Selected, this, &lcPropertiesWidget::PieceColorChanged);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
QScreen* Screen = Button->screen();
|
||||
const QRect ScreenRect = Screen ? Screen->geometry() : QRect();
|
||||
#elif (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
QScreen* Screen = QGuiApplication::screenAt(ColorButton->mapToGlobal(ColorButton->rect().bottomLeft()));
|
||||
const QRect ScreenRect = Screen ? Screen->geometry() : QApplication::desktop()->geometry();
|
||||
#else
|
||||
const QRect ScreenRect = QApplication::desktop()->geometry();
|
||||
#endif
|
||||
|
||||
QPoint Pos = ColorButton->mapToGlobal(ColorButton->rect().bottomLeft());
|
||||
|
||||
if (Pos.x() < ScreenRect.left())
|
||||
Pos.setX(ScreenRect.left());
|
||||
if (Pos.y() < ScreenRect.top())
|
||||
Pos.setY(ScreenRect.top());
|
||||
|
||||
Popup->adjustSize();
|
||||
|
||||
if (Pos.x() + Popup->width() > ScreenRect.right())
|
||||
Pos.setX(ScreenRect.right() - Popup->width());
|
||||
if (Pos.y() + Popup->height() > ScreenRect.bottom())
|
||||
Pos.setY(ScreenRect.bottom() - Popup->height());
|
||||
|
||||
Popup->move(Pos);
|
||||
Popup->setFocus();
|
||||
Popup->show();
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::UpdatePieceColor(PropertyIndex Index, int ColorIndex)
|
||||
{
|
||||
QToolButton* ColorButton = qobject_cast<QToolButton*>(mPropertyWidgets[static_cast<int>(Index)]);
|
||||
|
||||
if (!ColorButton)
|
||||
return;
|
||||
|
||||
QPixmap Pixmap(14, 14);
|
||||
Pixmap.fill(QColor::fromRgbF(gColorList[ColorIndex].Value[0], gColorList[ColorIndex].Value[1], gColorList[ColorIndex].Value[2]));
|
||||
|
||||
ColorButton->setIcon(Pixmap);
|
||||
ColorButton->setText(QString(" ") + gColorList[ColorIndex].Name);
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::AddPieceColorProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, QGridLayout* Layout, int& Row)
|
||||
{
|
||||
AddLabel(Text, ToolTip, Layout, Row);
|
||||
|
||||
QToolButton* Widget = new QToolButton(this);
|
||||
Widget->setToolTip(ToolTip);
|
||||
Widget->setAutoRaise(true);
|
||||
Widget->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
Widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
|
||||
connect(Widget, &QToolButton::clicked, this, &lcPropertiesWidget::PieceColorButtonClicked);
|
||||
|
||||
Layout->addWidget(Widget, Row, 2);
|
||||
|
||||
mPropertyWidgets[static_cast<int>(Index)] = Widget;
|
||||
|
||||
Row++;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::UpdatePieceId(PropertyIndex Index, const QString& Name)
|
||||
{
|
||||
lcElidableToolButton* PieceIdButton = qobject_cast<lcElidableToolButton*>(mPropertyWidgets[static_cast<int>(Index)]);
|
||||
|
||||
if (!PieceIdButton)
|
||||
return;
|
||||
|
||||
PieceIdButton->setText(Name);
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::PieceIdButtonClicked()
|
||||
{
|
||||
QToolButton* PieceIdButton = qobject_cast<QToolButton*>(sender());
|
||||
lcPiece* Piece = dynamic_cast<lcPiece*>(mFocusObject);
|
||||
|
||||
if (!PieceIdButton || !Piece)
|
||||
return;
|
||||
|
||||
QMenu* Menu = new QMenu();
|
||||
|
||||
QWidgetAction* Action = new QWidgetAction(Menu);
|
||||
lcPieceIdPickerPopup* Popup = new lcPieceIdPickerPopup(gMainWindow->GetActiveModel(), Piece->mPieceInfo, Menu);
|
||||
Action->setDefaultWidget(Popup);
|
||||
Menu->addAction(Action);
|
||||
|
||||
connect(Popup, &lcPieceIdPickerPopup::PieceIdSelected, this, &lcPropertiesWidget::PieceIdChanged);
|
||||
|
||||
Menu->exec(PieceIdButton->mapToGlobal(PieceIdButton->rect().bottomLeft()));
|
||||
|
||||
delete Menu;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::PieceIdChanged(PieceInfo* Info)
|
||||
{
|
||||
lcModel* Model = gMainWindow->GetActiveModel();
|
||||
|
||||
if (!Model || !Info)
|
||||
return;
|
||||
|
||||
Model->SetSelectedPiecesPieceInfo(Info);
|
||||
|
||||
// int ColorIndex = gDefaultColor;
|
||||
// lcObject* Focus = gMainWindow->GetActiveModel()->GetFocusObject();
|
||||
// if (Focus && Focus->IsPiece())
|
||||
// ColorIndex = ((lcPiece*)Focus)->GetColorIndex();
|
||||
// quint32 ColorCode = lcGetColorCode(ColorIndex);
|
||||
// gMainWindow->PreviewPiece(Info->mFileName, ColorCode, false);
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::AddPieceIdProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, QGridLayout* Layout, int& Row)
|
||||
{
|
||||
AddLabel(Text, ToolTip, Layout, Row);
|
||||
|
||||
lcElidableToolButton* Widget = new lcElidableToolButton(this);
|
||||
Widget->setToolTip(ToolTip);
|
||||
Widget->setAutoRaise(true);
|
||||
Widget->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
Widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
|
||||
QPixmap Pixmap(1, 1);
|
||||
Pixmap.fill(QColor::fromRgba64(0, 0, 0, 0));
|
||||
Widget->setIcon(Pixmap);
|
||||
|
||||
connect(Widget, &QToolButton::clicked, this, &lcPropertiesWidget::PieceIdButtonClicked);
|
||||
|
||||
Layout->addWidget(Widget, Row, 2);
|
||||
|
||||
mPropertyWidgets[static_cast<int>(Index)] = Widget;
|
||||
|
||||
Row++;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::ClearLayout()
|
||||
{
|
||||
for (lcCollapsibleWidget* CategoryWidget : mCategoryWidgets)
|
||||
delete CategoryWidget;
|
||||
|
||||
mCategoryWidgets.clear();
|
||||
mPropertyWidgets.fill(nullptr);
|
||||
|
||||
delete layout();
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::AddTransformCategory(QVBoxLayout* Layout)
|
||||
{
|
||||
QGridLayout* TransformLayout = AddPropertyCategory(tr("Transform"), Layout);
|
||||
int TransformRow = 0;
|
||||
|
||||
AddFloatProperty(PropertyIndex::ObjectPositionX, tr("Position X"), tr("Position of the object"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
AddFloatProperty(PropertyIndex::ObjectPositionY, tr("Y"), tr("Position of the object"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
AddFloatProperty(PropertyIndex::ObjectPositionZ, tr("Z"), tr("Position of the object"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
AddSpacing(TransformLayout, TransformRow);
|
||||
AddFloatProperty(PropertyIndex::ObjectRotationX, tr("Rotation X"), tr("Rotation of the object in degrees"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
AddFloatProperty(PropertyIndex::ObjectRotationY, tr("Y"), tr("Rotation of the object in degrees"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
AddFloatProperty(PropertyIndex::ObjectRotationZ, tr("Z"), tr("Rotation of the object in degrees"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
|
||||
Layout->addStretch(1);
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::SetEmpty()
|
||||
{
|
||||
ClearLayout();
|
||||
|
||||
mFocusObject = nullptr;
|
||||
mLayoutMode = LayoutMode::Empty;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::SetPieceLayout()
|
||||
{
|
||||
if (mLayoutMode == LayoutMode::Piece)
|
||||
return;
|
||||
|
||||
ClearLayout();
|
||||
|
||||
QVBoxLayout* Layout = new QVBoxLayout(this);
|
||||
|
||||
QGridLayout* PieceLayout = AddPropertyCategory(tr("Piece"), Layout);
|
||||
int PieceRow = 0;
|
||||
|
||||
AddPieceIdProperty(PropertyIndex::PieceId, tr("Part"), tr("Part Id"), PieceLayout, PieceRow);
|
||||
AddPieceColorProperty(PropertyIndex::PieceColor, tr("Color"), tr("Piece color"), PieceLayout, PieceRow);
|
||||
|
||||
AddSpacing(PieceLayout, PieceRow);
|
||||
|
||||
AddStepNumberProperty(PropertyIndex::PieceStepShow, tr("Show"), tr("Step when piece is added to the model"), PieceLayout, PieceRow);
|
||||
AddStepNumberProperty(PropertyIndex::PieceStepHide, tr("Hide"), tr("Step when piece is hidden"), PieceLayout, PieceRow);
|
||||
|
||||
AddTransformCategory(Layout);
|
||||
|
||||
mLayoutMode = LayoutMode::Piece;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::SetPiece(const lcArray<lcObject*>& Selection, lcObject* Focus)
|
||||
{
|
||||
SetPieceLayout();
|
||||
|
||||
lcModel* Model = gMainWindow->GetActiveModel();
|
||||
lcPiece* Piece = dynamic_cast<lcPiece*>(Focus);
|
||||
mFocusObject = Piece;
|
||||
|
||||
lcVector3 Position;
|
||||
lcMatrix33 RelativeRotation;
|
||||
|
||||
Model->GetMoveRotateTransform(Position, RelativeRotation);
|
||||
|
||||
UpdateFloat(PropertyIndex::ObjectPositionX, Position[0]);
|
||||
UpdateFloat(PropertyIndex::ObjectPositionY, Position[1]);
|
||||
UpdateFloat(PropertyIndex::ObjectPositionZ, Position[2]);
|
||||
|
||||
lcVector3 Rotation;
|
||||
|
||||
if (Piece)
|
||||
Rotation = lcMatrix44ToEulerAngles(Piece->mModelWorld) * LC_RTOD;
|
||||
else
|
||||
Rotation = lcVector3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
UpdateFloat(PropertyIndex::ObjectRotationX, Rotation[0]);
|
||||
UpdateFloat(PropertyIndex::ObjectRotationY, Rotation[1]);
|
||||
UpdateFloat(PropertyIndex::ObjectRotationZ, Rotation[2]);
|
||||
|
||||
lcStep StepShow = 1;
|
||||
lcStep StepHide = LC_STEP_MAX;
|
||||
PieceInfo* Info = nullptr;
|
||||
int ColorIndex = gDefaultColor;
|
||||
|
||||
if (Piece)
|
||||
{
|
||||
StepShow = Piece->GetStepShow();
|
||||
StepHide = Piece->GetStepHide();
|
||||
ColorIndex = Piece->GetColorIndex();
|
||||
Info = Piece->mPieceInfo;
|
||||
// quint32 ColorCode = lcGetColorCode(ColorIndex);
|
||||
// gMainWindow->PreviewPiece(Info->mFileName, ColorCode, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool FirstPiece = true;
|
||||
|
||||
for (int ObjectIdx = 0; ObjectIdx < Selection.GetSize(); ObjectIdx++)
|
||||
{
|
||||
lcObject* Object = Selection[ObjectIdx];
|
||||
|
||||
if (!Object->IsPiece())
|
||||
continue;
|
||||
|
||||
lcPiece* SelectedPiece = (lcPiece*)Object;
|
||||
|
||||
if (FirstPiece)
|
||||
{
|
||||
StepShow = SelectedPiece->GetStepShow();
|
||||
StepHide = SelectedPiece->GetStepHide();
|
||||
ColorIndex = SelectedPiece->GetColorIndex();
|
||||
Info = SelectedPiece->mPieceInfo;
|
||||
|
||||
FirstPiece = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SelectedPiece->GetStepShow() != StepShow)
|
||||
StepShow = 0;
|
||||
|
||||
if (SelectedPiece->GetStepHide() != StepHide)
|
||||
StepHide = 0;
|
||||
|
||||
if (SelectedPiece->GetColorIndex() != ColorIndex)
|
||||
ColorIndex = gDefaultColor;
|
||||
|
||||
if (SelectedPiece->mPieceInfo != Info)
|
||||
Info = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdatePieceId(PropertyIndex::PieceId, Info ? Info->m_strDescription : QString());
|
||||
UpdatePieceColor(PropertyIndex::PieceColor, ColorIndex);
|
||||
UpdateStepNumber(PropertyIndex::PieceStepShow, StepShow ? StepShow : LC_STEP_MAX, 1, StepHide - 1);
|
||||
UpdateStepNumber(PropertyIndex::PieceStepHide, StepHide ? StepHide : LC_STEP_MAX, StepShow + 1, LC_STEP_MAX);
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::SetCameraLayout()
|
||||
{
|
||||
if (mLayoutMode == LayoutMode::Camera)
|
||||
return;
|
||||
|
||||
ClearLayout();
|
||||
|
||||
QVBoxLayout* Layout = new QVBoxLayout(this);
|
||||
|
||||
QGridLayout* CameraLayout = AddPropertyCategory(tr("Camera"), Layout);
|
||||
int CameraRow = 0;
|
||||
|
||||
AddStringProperty(PropertyIndex::CameraName, tr("Name"), tr("Camera name"), CameraLayout, CameraRow);
|
||||
AddStringListProperty(PropertyIndex::CameraType, tr("Type"), tr("Camera type"), { tr("Perspective"), tr("Orthographic") }, CameraLayout, CameraRow);
|
||||
AddSpacing(CameraLayout, CameraRow);
|
||||
AddFloatProperty(PropertyIndex::CameraFOV, tr("FOV"), tr("Field of view in degrees"), 0.1f, 179.9f, CameraLayout, CameraRow);
|
||||
AddFloatProperty(PropertyIndex::CameraNear, tr("Near"), tr("Near clipping distance"), 0.001f, FLT_MAX, CameraLayout, CameraRow);
|
||||
AddFloatProperty(PropertyIndex::CameraFar, tr("Far"), tr("Far clipping distance"), 0.001f, FLT_MAX, CameraLayout, CameraRow);
|
||||
|
||||
QGridLayout* TransformLayout = AddPropertyCategory(tr("Transform"), Layout);
|
||||
int TransformRow = 0;
|
||||
|
||||
AddFloatProperty(PropertyIndex::CameraPositionX, tr("Position X"), tr("Camera position"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
AddFloatProperty(PropertyIndex::CameraPositionY, tr("Y"), tr("Camera position"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
AddFloatProperty(PropertyIndex::CameraPositionZ, tr("Z"), tr("Camera position"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
AddSpacing(TransformLayout, TransformRow);
|
||||
AddFloatProperty(PropertyIndex::CameraTargetX, tr("Target X"), tr("Camera target position"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
AddFloatProperty(PropertyIndex::CameraTargetY, tr("Y"), tr("Camera target position"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
AddFloatProperty(PropertyIndex::CameraTargetZ, tr("Z"), tr("Camera target position"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
AddSpacing(TransformLayout, TransformRow);
|
||||
AddFloatProperty(PropertyIndex::CameraUpX, tr("Up X"), tr("Camera up direction"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
AddFloatProperty(PropertyIndex::CameraUpY, tr("Y"), tr("Camera up direction"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
AddFloatProperty(PropertyIndex::CameraUpZ, tr("Z"), tr("Camera up direction"), -FLT_MAX, FLT_MAX, TransformLayout, TransformRow);
|
||||
|
||||
// AddTransformCategory(Layout);
|
||||
|
||||
mLayoutMode = LayoutMode::Camera;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::SetCamera(lcObject* Focus)
|
||||
{
|
||||
SetCameraLayout();
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::SetLightLayout(lcLightType LightType, lcLightAreaShape LightAreaShape)
|
||||
{
|
||||
if (mLayoutMode == LayoutMode::Light && mLayoutLightType == LightType)
|
||||
return;
|
||||
|
||||
ClearLayout();
|
||||
|
||||
QVBoxLayout* Layout = new QVBoxLayout(this);
|
||||
|
||||
QGridLayout* LightLayout = AddPropertyCategory(tr("Light"), Layout);
|
||||
int LightRow = 0;
|
||||
|
||||
AddStringProperty(PropertyIndex::LightName, tr("Name"), tr("Light name"), LightLayout, LightRow);
|
||||
AddStringListProperty(PropertyIndex::LightType, tr("Type"), tr("Light type"), lcLight::GetLightTypeStrings(), LightLayout, LightRow);
|
||||
AddColorProperty(PropertyIndex::LightColor, tr("Color"), tr("Light color"), LightLayout, LightRow);
|
||||
AddFloatProperty(PropertyIndex::LightPower, tr("Power"), tr("Power of the light (Watts in Blender, multiplicative factor in POV-Ray)"), 0.0f, FLT_MAX, LightLayout, LightRow);
|
||||
AddBoolProperty(PropertyIndex::LightCastShadow, tr("Cast Shadow"), tr("Cast a shadow from this light"), LightLayout, LightRow);
|
||||
AddFloatProperty(PropertyIndex::LightAttenuationDistance, tr("Fade Distance"), tr("The distance at which the full light intensity arrives (POV-Ray only)"), 0.0f, FLT_MAX, LightLayout, LightRow);
|
||||
AddFloatProperty(PropertyIndex::LightAttenuationPower, tr("Fade Power"), tr("Light falloff rate (POV-Ray only)"), 0.0f, FLT_MAX, LightLayout, LightRow);
|
||||
// AddSpacing(LightLayout, LightRow);
|
||||
|
||||
switch (LightType)
|
||||
{
|
||||
case lcLightType::Point:
|
||||
AddFloatProperty(PropertyIndex::LightSizeX, tr("Radius"), tr("Shadow soft size (Blender only)"), 0.0f, FLT_MAX, LightLayout, LightRow);
|
||||
break;
|
||||
|
||||
case lcLightType::Spot:
|
||||
AddFloatProperty(PropertyIndex::LightSizeX, tr("Radius"), tr("Shadow soft size (Blender only)"), 0.0f, FLT_MAX, LightLayout, LightRow);
|
||||
AddFloatProperty(PropertyIndex::LightSpotConeAngle, tr("Spot Cone Angle"), tr("Angle in degrees of the spot light's beam"), 0.0f, 179.9f, LightLayout, LightRow);
|
||||
AddFloatProperty(PropertyIndex::LightSpotPenumbraAngle, tr("Spot Penumbra Angle"), tr("Angle in degrees over which the intensity of the spot light falls off to zero"), 0.0f, 179.9f, LightLayout, LightRow);
|
||||
AddFloatProperty(PropertyIndex::LightSpotTightness, tr("Spot Tightness"), tr("Additional exponential spot light edge softening (POV-Ray only)"), 0.0f, FLT_MAX, LightLayout, LightRow);
|
||||
break;
|
||||
|
||||
case lcLightType::Directional:
|
||||
AddFloatProperty(PropertyIndex::LightSizeX, tr("Angle"), tr("Angular diameter of the light (Blender only)"), 0.0f, 180.0f, LightLayout, LightRow);
|
||||
break;
|
||||
|
||||
case lcLightType::Area:
|
||||
AddStringListProperty(PropertyIndex::LightAreaShape, tr("Area Shape"), tr("The shape of the area light"), lcLight::GetAreaShapeStrings(), LightLayout, LightRow);
|
||||
|
||||
switch (LightAreaShape)
|
||||
{
|
||||
case lcLightAreaShape::Rectangle:
|
||||
case lcLightAreaShape::Ellipse:
|
||||
AddFloatProperty(PropertyIndex::LightSizeX, tr("Size X"), tr("The width of the area light"), 0.0f, FLT_MAX, LightLayout, LightRow);
|
||||
AddFloatProperty(PropertyIndex::LightSizeY, tr("Y"), tr("The height of the area light"), 0.0f, FLT_MAX, LightLayout, LightRow);
|
||||
break;
|
||||
|
||||
case lcLightAreaShape::Square:
|
||||
case lcLightAreaShape::Disk:
|
||||
AddFloatProperty(PropertyIndex::LightSizeX, tr("Size"), tr("The size of the area light"), 0.0f, FLT_MAX, LightLayout, LightRow);
|
||||
break;
|
||||
|
||||
case lcLightAreaShape::Count:
|
||||
break;
|
||||
}
|
||||
|
||||
AddIntegerProperty(PropertyIndex::LightAreaGridX, tr("Grid X"), tr("Number of point sources along the X axis (POV-Ray only)"), 1, INT_MAX, LightLayout, LightRow);
|
||||
AddIntegerProperty(PropertyIndex::LightAreaGridY, tr("Y"), tr("Number of point sources along the Y axis (POV-Ray only)"), 1, INT_MAX, LightLayout, LightRow);
|
||||
break;
|
||||
|
||||
case lcLightType::Count:
|
||||
break;
|
||||
}
|
||||
|
||||
AddTransformCategory(Layout);
|
||||
|
||||
mLayoutLightType = LightType;
|
||||
mLayoutMode = LayoutMode::Light;
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::SetLight(lcObject* Focus)
|
||||
{
|
||||
lcLight* Light = (Focus && Focus->IsLight()) ? (lcLight*)Focus : nullptr;
|
||||
|
||||
if (Light)
|
||||
SetLightLayout(Light->GetLightType(), Light->GetAreaShape());
|
||||
else
|
||||
SetLightLayout(lcLightType::Count, lcLightAreaShape::Count);
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::SetMultiple()
|
||||
{
|
||||
}
|
||||
|
||||
void lcPropertiesWidget::Update(const lcArray<lcObject*>& Selection, lcObject* Focus)
|
||||
{
|
||||
LayoutMode Mode = LayoutMode::Empty;
|
||||
|
||||
if (Focus)
|
||||
{
|
||||
switch (Focus->GetType())
|
||||
{
|
||||
case lcObjectType::Piece:
|
||||
Mode = LayoutMode::Piece;
|
||||
break;
|
||||
|
||||
case lcObjectType::Camera:
|
||||
Mode = LayoutMode::Camera;
|
||||
break;
|
||||
|
||||
case lcObjectType::Light:
|
||||
Mode = LayoutMode::Light;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ObjectIdx = 0; ObjectIdx < Selection.GetSize(); ObjectIdx++)
|
||||
{
|
||||
switch (Selection[ObjectIdx]->GetType())
|
||||
{
|
||||
case lcObjectType::Piece:
|
||||
if (Mode == LayoutMode::Empty)
|
||||
Mode = LayoutMode::Piece;
|
||||
else if (Mode != LayoutMode::Piece)
|
||||
{
|
||||
Mode = LayoutMode::Multiple;
|
||||
ObjectIdx = Selection.GetSize();
|
||||
}
|
||||
break;
|
||||
|
||||
case lcObjectType::Camera:
|
||||
if (Mode != LayoutMode::Empty)
|
||||
{
|
||||
Mode = LayoutMode::Multiple;
|
||||
ObjectIdx = Selection.GetSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
Mode = LayoutMode::Camera;
|
||||
Focus = Selection[ObjectIdx];
|
||||
}
|
||||
break;
|
||||
|
||||
case lcObjectType::Light:
|
||||
if (Mode != LayoutMode::Empty)
|
||||
{
|
||||
Mode = LayoutMode::Multiple;
|
||||
ObjectIdx = Selection.GetSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
Mode = LayoutMode::Light;
|
||||
Focus = Selection[ObjectIdx];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (Mode)
|
||||
{
|
||||
case LayoutMode::Empty:
|
||||
SetEmpty();
|
||||
break;
|
||||
|
||||
case LayoutMode::Piece:
|
||||
SetPiece(Selection, Focus);
|
||||
break;
|
||||
|
||||
case LayoutMode::Camera:
|
||||
SetCamera(Focus);
|
||||
break;
|
||||
|
||||
case LayoutMode::Light:
|
||||
SetLight(Focus);
|
||||
break;
|
||||
|
||||
case LayoutMode::Multiple:
|
||||
SetMultiple();
|
||||
break;
|
||||
}
|
||||
}
|
127
common/lc_propertieswidget.h
Normal file
127
common/lc_propertieswidget.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
#pragma once
|
||||
|
||||
#include "lc_array.h"
|
||||
|
||||
class lcPropertiesWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
lcPropertiesWidget(QWidget* Parent);
|
||||
|
||||
void Update(const lcArray<lcObject*>& Selection, lcObject* Focus);
|
||||
|
||||
protected slots:
|
||||
void FloatChanged();
|
||||
void StepNumberChanged();
|
||||
void PieceColorButtonClicked();
|
||||
void PieceColorChanged(int ColorIndex);
|
||||
void PieceIdButtonClicked();
|
||||
void PieceIdChanged(PieceInfo* Info);
|
||||
|
||||
protected:
|
||||
enum class PropertyIndex
|
||||
{
|
||||
PieceId,
|
||||
PieceColor,
|
||||
PieceStepShow,
|
||||
PieceStepHide,
|
||||
CameraName,
|
||||
CameraType,
|
||||
CameraFOV,
|
||||
CameraNear,
|
||||
CameraFar,
|
||||
CameraPositionX,
|
||||
CameraPositionY,
|
||||
CameraPositionZ,
|
||||
CameraTargetX,
|
||||
CameraTargetY,
|
||||
CameraTargetZ,
|
||||
CameraUpX,
|
||||
CameraUpY,
|
||||
CameraUpZ,
|
||||
LightName,
|
||||
LightType,
|
||||
LightColor,
|
||||
LightPower,
|
||||
LightCastShadow,
|
||||
LightAttenuationDistance,
|
||||
LightAttenuationPower,
|
||||
LightSizeX,
|
||||
LightSizeY,
|
||||
LightSpotConeAngle,
|
||||
LightSpotPenumbraAngle,
|
||||
LightSpotTightness,
|
||||
LightAreaShape,
|
||||
LightAreaGridX,
|
||||
LightAreaGridY,
|
||||
ObjectPositionX,
|
||||
ObjectPositionY,
|
||||
ObjectPositionZ,
|
||||
ObjectRotationX,
|
||||
ObjectRotationY,
|
||||
ObjectRotationZ,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class PropertyType
|
||||
{
|
||||
Bool,
|
||||
Float,
|
||||
Integer,
|
||||
StepNumber,
|
||||
String,
|
||||
StringList,
|
||||
Color,
|
||||
PieceColor,
|
||||
PieceId
|
||||
};
|
||||
|
||||
enum class LayoutMode
|
||||
{
|
||||
Empty,
|
||||
Piece,
|
||||
Camera,
|
||||
Light,
|
||||
Multiple
|
||||
};
|
||||
|
||||
PropertyIndex GetWidgetIndex(QWidget* Widget) const;
|
||||
|
||||
QGridLayout* AddPropertyCategory(const QString& Title, QVBoxLayout* Layout);
|
||||
void AddSpacing(QGridLayout* Layout, int& Row);
|
||||
void AddLabel(const QString& Text, const QString& ToolTip, QGridLayout* Layout, int Row);
|
||||
void AddBoolProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, QGridLayout* Layout, int& Row);
|
||||
void AddFloatProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, float Min, float Max, QGridLayout* Layout, int& Row);
|
||||
void AddIntegerProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, int Min, int Max, QGridLayout* Layout, int& Row);
|
||||
void AddStepNumberProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, QGridLayout* Layout, int& Row);
|
||||
void AddStringProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, QGridLayout* Layout, int& Row);
|
||||
void AddStringListProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, const QStringList& Strings, QGridLayout* Layout, int& Row);
|
||||
void AddColorProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, QGridLayout* Layout, int& Row);
|
||||
void AddPieceColorProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, QGridLayout* Layout, int& Row);
|
||||
void AddPieceIdProperty(PropertyIndex Index, const QString& Text, const QString& ToolTip, QGridLayout* Layout, int& Row);
|
||||
|
||||
void UpdateFloat(PropertyIndex Index, float Value);
|
||||
void UpdateStepNumber(PropertyIndex Index, lcStep Step, lcStep Min, lcStep Max);
|
||||
void UpdatePieceColor(PropertyIndex Index, int ColorIndex);
|
||||
void UpdatePieceId(PropertyIndex Index, const QString& Name);
|
||||
|
||||
void SetEmpty();
|
||||
void SetPiece(const lcArray<lcObject*>& Selection, lcObject* Focus);
|
||||
void SetCamera(lcObject* Focus);
|
||||
void SetLight(lcObject* Focus);
|
||||
void SetMultiple();
|
||||
|
||||
void ClearLayout();
|
||||
void AddTransformCategory(QVBoxLayout* Layout);
|
||||
void SetPieceLayout();
|
||||
void SetCameraLayout();
|
||||
void SetLightLayout(lcLightType LightType, lcLightAreaShape LightAreaShape);
|
||||
|
||||
LayoutMode mLayoutMode = LayoutMode::Empty;
|
||||
lcLightType mLayoutLightType;
|
||||
lcLightAreaShape mLayoutLightAreaShape;
|
||||
std::array<QWidget*, static_cast<int>(PropertyIndex::Count)> mPropertyWidgets = {};
|
||||
std::vector<lcCollapsibleWidget*> mCategoryWidgets;
|
||||
lcObject* mFocusObject = nullptr;
|
||||
};
|
|
@ -60,16 +60,16 @@ QString lcLight::GetLightTypeString(lcLightType LightType)
|
|||
switch (LightType)
|
||||
{
|
||||
case lcLightType::Point:
|
||||
return QT_TRANSLATE_NOOP("Light Names", "Point Light");
|
||||
return QT_TRANSLATE_NOOP("Light Types", "Point Light");
|
||||
|
||||
case lcLightType::Spot:
|
||||
return QT_TRANSLATE_NOOP("Light Names", "Spot Light");
|
||||
return QT_TRANSLATE_NOOP("Light Types", "Spot Light");
|
||||
|
||||
case lcLightType::Directional:
|
||||
return QT_TRANSLATE_NOOP("Light Names", "Directional Light");
|
||||
return QT_TRANSLATE_NOOP("Light Types", "Directional Light");
|
||||
|
||||
case lcLightType::Area:
|
||||
return QT_TRANSLATE_NOOP("Light Names", "Area Light");
|
||||
return QT_TRANSLATE_NOOP("Light Types", "Area Light");
|
||||
|
||||
case lcLightType::Count:
|
||||
break;
|
||||
|
@ -78,6 +78,16 @@ QString lcLight::GetLightTypeString(lcLightType LightType)
|
|||
return QString();
|
||||
}
|
||||
|
||||
QStringList lcLight::GetLightTypeStrings()
|
||||
{
|
||||
QStringList LightTypes;
|
||||
|
||||
for (int LightTypeIndex = 0; LightTypeIndex < static_cast<int>(lcLightType::Count); LightTypeIndex++)
|
||||
LightTypes.push_back(GetLightTypeString(static_cast<lcLightType>(LightTypeIndex)));
|
||||
|
||||
return LightTypes;
|
||||
}
|
||||
|
||||
QString lcLight::GetAreaShapeString(lcLightAreaShape LightAreaShape)
|
||||
{
|
||||
switch (LightAreaShape)
|
||||
|
@ -101,6 +111,16 @@ QString lcLight::GetAreaShapeString(lcLightAreaShape LightAreaShape)
|
|||
return QString();
|
||||
}
|
||||
|
||||
QStringList lcLight::GetAreaShapeStrings()
|
||||
{
|
||||
QStringList AreaShapes;
|
||||
|
||||
for (int AreaShapeIndex = 0; AreaShapeIndex < static_cast<int>(lcLightAreaShape::Count); AreaShapeIndex++)
|
||||
AreaShapes.push_back(GetAreaShapeString(static_cast<lcLightAreaShape>(AreaShapeIndex)));
|
||||
|
||||
return AreaShapes;
|
||||
}
|
||||
|
||||
void lcLight::SaveLDraw(QTextStream& Stream) const
|
||||
{
|
||||
const QLatin1String LineEnding("\r\n");
|
||||
|
|
|
@ -43,7 +43,9 @@ public:
|
|||
lcLight& operator=(lcLight&&) = delete;
|
||||
|
||||
static QString GetLightTypeString(lcLightType LightType);
|
||||
static QStringList GetLightTypeStrings();
|
||||
static QString GetAreaShapeString(lcLightAreaShape LightAreaShape);
|
||||
static QStringList GetAreaShapeStrings();
|
||||
|
||||
bool IsPointLight() const
|
||||
{
|
||||
|
|
|
@ -205,6 +205,7 @@ SOURCES += \
|
|||
common/lc_partselectionwidget.cpp \
|
||||
common/lc_previewwidget.cpp \
|
||||
common/lc_profile.cpp \
|
||||
common/lc_propertieswidget.cpp \
|
||||
common/lc_scene.cpp \
|
||||
common/lc_shortcuts.cpp \
|
||||
common/lc_stringcache.cpp \
|
||||
|
@ -276,6 +277,7 @@ HEADERS += \
|
|||
common/lc_pagesetupdialog.h \
|
||||
common/lc_previewwidget.h \
|
||||
common/lc_profile.h \
|
||||
common/lc_propertieswidget.h \
|
||||
common/lc_scene.h \
|
||||
common/lc_shortcuts.h \
|
||||
common/lc_stringcache.h \
|
||||
|
|
|
@ -395,34 +395,6 @@ void lcQPropertiesTree::Update(const lcArray<lcObject*>& Selection, lcObject* Fo
|
|||
}
|
||||
}
|
||||
|
||||
class lcStepValidator : public QIntValidator
|
||||
{
|
||||
public:
|
||||
lcStepValidator(lcStep Min, lcStep Max, bool AllowEmpty)
|
||||
: QIntValidator(1, INT_MAX), mMin(Min), mMax(Max), mAllowEmpty(AllowEmpty)
|
||||
{
|
||||
}
|
||||
|
||||
QValidator::State validate(QString& Input, int& Pos) const override
|
||||
{
|
||||
if (mAllowEmpty && Input.isEmpty())
|
||||
return Acceptable;
|
||||
|
||||
bool Ok;
|
||||
lcStep Step = Input.toUInt(&Ok);
|
||||
|
||||
if (Ok)
|
||||
return (Step >= mMin && Step <= mMax) ? Acceptable : Invalid;
|
||||
|
||||
return QIntValidator::validate(Input, Pos);
|
||||
}
|
||||
|
||||
protected:
|
||||
lcStep mMin;
|
||||
lcStep mMax;
|
||||
bool mAllowEmpty;
|
||||
};
|
||||
|
||||
QWidget* lcQPropertiesTree::createEditor(QWidget* Parent, QTreeWidgetItem* Item) const
|
||||
{
|
||||
lcQPropertiesTree::PropertyType PropertyType = (lcQPropertiesTree::PropertyType)Item->data(0, lcQPropertiesTree::PropertyTypeRole).toInt();
|
||||
|
@ -472,12 +444,12 @@ QWidget* lcQPropertiesTree::createEditor(QWidget* Parent, QTreeWidgetItem* Item)
|
|||
if (Show && Hide)
|
||||
{
|
||||
if (Item == partShow)
|
||||
Editor->setValidator(new lcStepValidator(1, Hide - 1, false));
|
||||
Editor->setValidator(new lcStepValidator(1, Hide - 1, false, Editor));
|
||||
else
|
||||
Editor->setValidator(new lcStepValidator(Show + 1, LC_STEP_MAX, true));
|
||||
Editor->setValidator(new lcStepValidator(Show + 1, LC_STEP_MAX, true, Editor));
|
||||
}
|
||||
else
|
||||
Editor->setValidator(new lcStepValidator(1, LC_STEP_MAX, Item == partHide));
|
||||
Editor->setValidator(new lcStepValidator(1, LC_STEP_MAX, Item == partHide, Editor));
|
||||
|
||||
if (Item != partHide || Value != LC_STEP_MAX)
|
||||
Editor->setText(QString::number(Value));
|
||||
|
|
145
qt/lc_qutils.cpp
145
qt/lc_qutils.cpp
|
@ -2,6 +2,7 @@
|
|||
#include "lc_qutils.h"
|
||||
#include "lc_application.h"
|
||||
#include "lc_library.h"
|
||||
#include "lc_model.h"
|
||||
#include "pieceinf.h"
|
||||
|
||||
QString lcFormatValue(float Value, int Precision)
|
||||
|
@ -102,3 +103,147 @@ bool lcQTreeWidgetColumnStretcher::eventFilter(QObject* Object, QEvent* Event)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
lcPieceIdStringModel::lcPieceIdStringModel(lcModel* Model, QObject* Parent)
|
||||
: QAbstractListModel(Parent)
|
||||
{
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
mSortedPieces.reserve(Library->mPieces.size());
|
||||
|
||||
for (const auto& PartIt : Library->mPieces)
|
||||
{
|
||||
PieceInfo* Info = PartIt.second;
|
||||
|
||||
if (!Info->IsModel() || !Info->GetModel()->IncludesModel(Model))
|
||||
mSortedPieces.push_back(PartIt.second);
|
||||
}
|
||||
|
||||
auto PieceCompare = [](PieceInfo* Info1, PieceInfo* Info2)
|
||||
{
|
||||
return strcmp(Info1->m_strDescription, Info2->m_strDescription) < 0;
|
||||
};
|
||||
|
||||
std::sort(mSortedPieces.begin(), mSortedPieces.end(), PieceCompare);
|
||||
}
|
||||
|
||||
QModelIndex lcPieceIdStringModel::Index(PieceInfo* Info) const
|
||||
{
|
||||
for (size_t PieceInfoIndex = 0; PieceInfoIndex < mSortedPieces.size(); PieceInfoIndex++)
|
||||
if (mSortedPieces[PieceInfoIndex] == Info)
|
||||
return index(static_cast<int>(PieceInfoIndex), 0);
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
std::vector<bool> lcPieceIdStringModel::GetFilteredRows(const QString& FilterText) const
|
||||
{
|
||||
const std::string Text = FilterText.toStdString();
|
||||
std::vector<bool> FilteredRows(mSortedPieces.size());
|
||||
|
||||
for (size_t PieceInfoIndex = 0; PieceInfoIndex < mSortedPieces.size(); PieceInfoIndex++)
|
||||
{
|
||||
const PieceInfo* Info = mSortedPieces[PieceInfoIndex];
|
||||
|
||||
FilteredRows[PieceInfoIndex] = (strcasestr(Info->m_strDescription, Text.c_str()) || strcasestr(Info->mFileName, Text.c_str()));
|
||||
}
|
||||
|
||||
return FilteredRows;
|
||||
}
|
||||
|
||||
int lcPieceIdStringModel::rowCount(const QModelIndex& Parent) const
|
||||
{
|
||||
Q_UNUSED(Parent);
|
||||
|
||||
return static_cast<int>(mSortedPieces.size());
|
||||
}
|
||||
|
||||
QVariant lcPieceIdStringModel::data(const QModelIndex& Index, int Role) const
|
||||
{
|
||||
if (Index.row() < static_cast<int>(mSortedPieces.size()))
|
||||
{
|
||||
if (Role == Qt::DisplayRole)
|
||||
return QString::fromLatin1(mSortedPieces[Index.row()]->m_strDescription);
|
||||
else if (Role == Qt::UserRole)
|
||||
return QVariant::fromValue(reinterpret_cast<void*>(mSortedPieces[Index.row()]));
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
lcPieceIdPickerPopup::lcPieceIdPickerPopup(lcModel* Model, PieceInfo* Current, QWidget* Parent)
|
||||
: QWidget(Parent)
|
||||
{
|
||||
QVBoxLayout* Layout = new QVBoxLayout(this);
|
||||
Layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
mListView = new QListView(this);
|
||||
mListView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
mListView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
mListView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
mListView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
mListView->setUniformItemSizes(true);
|
||||
|
||||
mListView->installEventFilter(this);
|
||||
// QShortcut* EnterShortcut = new QShortcut(QKeySequence(Qt::Key_Enter), this, this, &lcPieceIdPickerPopup::ListViewEnterPressed);
|
||||
|
||||
lcPieceIdStringModel* StringModel = new lcPieceIdStringModel(Model, mListView);
|
||||
mListView->setModel(StringModel);
|
||||
|
||||
if (Current)
|
||||
mListView->setCurrentIndex(StringModel->Index(Current));
|
||||
|
||||
Layout->addWidget(mListView);
|
||||
|
||||
connect(mListView, &QListView::doubleClicked, this, &lcPieceIdPickerPopup::ListViewDoubleClicked);
|
||||
|
||||
mFilterEdit = new QLineEdit(this);
|
||||
Layout->addWidget(mFilterEdit);
|
||||
|
||||
connect(mFilterEdit, &QLineEdit::textEdited, this, &lcPieceIdPickerPopup::FilterEdited);
|
||||
}
|
||||
|
||||
bool lcPieceIdPickerPopup::eventFilter(QObject* Object, QEvent* Event)
|
||||
{
|
||||
if (Object == mListView && Event->type() == QEvent::KeyPress)
|
||||
{
|
||||
EmitSelectedEvent(mListView->currentIndex());
|
||||
return true;
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(Object, Event);
|
||||
}
|
||||
|
||||
void lcPieceIdPickerPopup::EmitSelectedEvent(const QModelIndex& Index)
|
||||
{
|
||||
if (!Index.isValid())
|
||||
return;
|
||||
|
||||
lcPieceIdStringModel* StringModel = qobject_cast<lcPieceIdStringModel*>(mListView->model());
|
||||
QVariant Variant = StringModel->data(Index, Qt::UserRole);
|
||||
|
||||
if (Variant.isValid())
|
||||
{
|
||||
emit PieceIdSelected(static_cast<PieceInfo*>(Variant.value<void*>()));
|
||||
}
|
||||
|
||||
QMenu* Menu = qobject_cast<QMenu*>(parent());
|
||||
Menu->close();
|
||||
}
|
||||
|
||||
void lcPieceIdPickerPopup::ListViewDoubleClicked(const QModelIndex& Index)
|
||||
{
|
||||
EmitSelectedEvent(Index);
|
||||
}
|
||||
|
||||
void lcPieceIdPickerPopup::FilterEdited(const QString& Text)
|
||||
{
|
||||
lcPieceIdStringModel* StringModel = qobject_cast<lcPieceIdStringModel*>(mListView->model());
|
||||
std::vector<bool> FilteredRows = StringModel->GetFilteredRows(Text);
|
||||
|
||||
mListView->setUpdatesEnabled(false);
|
||||
|
||||
for (int Row = 0; Row < static_cast<int>(FilteredRows.size()); Row++)
|
||||
mListView->setRowHidden(Row, !FilteredRows[Row]);
|
||||
|
||||
mListView->setUpdatesEnabled(true);
|
||||
}
|
||||
|
|
108
qt/lc_qutils.h
108
qt/lc_qutils.h
|
@ -79,3 +79,111 @@ protected:
|
|||
return QLineEdit::event(Event);
|
||||
}
|
||||
};
|
||||
|
||||
class lcStepValidator : public QIntValidator
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
lcStepValidator(lcStep Min, lcStep Max, bool AllowEmpty, QObject* Parent)
|
||||
: QIntValidator(1, INT_MAX, Parent), mMin(Min), mMax(Max), mAllowEmpty(AllowEmpty)
|
||||
{
|
||||
}
|
||||
|
||||
QValidator::State validate(QString& Input, int& Pos) const override
|
||||
{
|
||||
if (mAllowEmpty && Input.isEmpty())
|
||||
return Acceptable;
|
||||
|
||||
bool Ok;
|
||||
lcStep Step = Input.toUInt(&Ok);
|
||||
|
||||
if (Ok)
|
||||
return (Step >= mMin && Step <= mMax) ? Acceptable : Invalid;
|
||||
|
||||
return QIntValidator::validate(Input, Pos);
|
||||
}
|
||||
|
||||
protected:
|
||||
lcStep mMin;
|
||||
lcStep mMax;
|
||||
bool mAllowEmpty;
|
||||
};
|
||||
|
||||
class lcElidableToolButton : public QToolButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
lcElidableToolButton(QWidget* Parent)
|
||||
: QToolButton(Parent)
|
||||
{
|
||||
}
|
||||
|
||||
QSize sizeHint() const override
|
||||
{
|
||||
QSize Size = QToolButton::sizeHint();
|
||||
|
||||
Size.setWidth(0);
|
||||
|
||||
return Size;
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent*)
|
||||
{
|
||||
QStylePainter Painter(this);
|
||||
QStyleOptionToolButton Option;
|
||||
initStyleOption(&Option);
|
||||
|
||||
QRect Button = style()->subControlRect(QStyle::CC_ToolButton, &Option, QStyle::SC_ToolButton, this);
|
||||
int Frame = style()->proxy()->pixelMetric(QStyle::PixelMetric::PM_DefaultFrameWidth, &Option, this);
|
||||
Button = Button.adjusted(Frame, Frame, -Frame, -Frame);
|
||||
|
||||
QFontMetrics Metrics(font());
|
||||
QString ElidedText = Metrics.elidedText(text(), Qt::ElideMiddle, Button.width());
|
||||
|
||||
Option.text = ElidedText;
|
||||
Painter.drawComplexControl(QStyle::CC_ToolButton, Option);
|
||||
}
|
||||
};
|
||||
|
||||
class lcPieceIdStringModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
lcPieceIdStringModel(lcModel* Model, QObject* Parent);
|
||||
|
||||
QModelIndex Index(PieceInfo* Info) const;
|
||||
std::vector<bool> GetFilteredRows(const QString& FilterText) const;
|
||||
|
||||
int rowCount(const QModelIndex& Parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& Index, int Role = Qt::DisplayRole) const override;
|
||||
|
||||
protected:
|
||||
std::vector<PieceInfo*> mSortedPieces;
|
||||
};
|
||||
|
||||
class lcPieceIdPickerPopup : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
lcPieceIdPickerPopup(lcModel* Model, PieceInfo* Current, QWidget* Parent);
|
||||
|
||||
bool eventFilter(QObject* Object, QEvent* Event) override;
|
||||
|
||||
signals:
|
||||
void PieceIdSelected(PieceInfo* Info);
|
||||
|
||||
protected slots:
|
||||
void ListViewDoubleClicked(const QModelIndex& Index);
|
||||
void FilterEdited(const QString& Text);
|
||||
|
||||
protected:
|
||||
void EmitSelectedEvent(const QModelIndex& Index);
|
||||
|
||||
QListView* mListView = nullptr;
|
||||
QLineEdit* mFilterEdit = nullptr;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue