2023-12-31 21:55:35 +01:00
# include "lc_global.h"
# include "lc_propertieswidget.h"
2024-01-15 02:41:01 +01:00
# include "lc_keyframewidget.h"
2023-12-31 21:55:35 +01:00
# 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 )
{
2024-01-07 02:33:43 +01:00
CreateWidgets ( ) ;
SetLayoutMode ( LayoutMode : : Empty ) ;
2023-12-31 21:55:35 +01:00
}
2024-01-15 02:41:01 +01:00
lcObjectPropertyId lcPropertiesWidget : : GetEditorWidgetPropertyId ( QWidget * Widget ) const
2023-12-31 21:55:35 +01:00
{
if ( ! Widget )
2024-01-07 20:39:34 +01:00
return lcObjectPropertyId : : Count ;
2023-12-31 21:55:35 +01:00
for ( size_t Index = 0 ; Index < mPropertyWidgets . size ( ) ; Index + + )
2024-01-15 02:41:01 +01:00
if ( mPropertyWidgets [ Index ] . Editor = = Widget )
return static_cast < lcObjectPropertyId > ( Index ) ;
return lcObjectPropertyId : : Count ;
}
lcObjectPropertyId lcPropertiesWidget : : GetKeyFrameWidgetPropertyId ( QWidget * Widget ) const
{
if ( ! Widget )
return lcObjectPropertyId : : Count ;
for ( size_t Index = 0 ; Index < mPropertyWidgets . size ( ) ; Index + + )
if ( mPropertyWidgets [ Index ] . KeyFrame = = Widget )
2024-01-07 20:39:34 +01:00
return static_cast < lcObjectPropertyId > ( Index ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
return lcObjectPropertyId : : Count ;
2023-12-31 21:55:35 +01:00
}
2023-12-31 23:00:33 +01:00
void lcPropertiesWidget : : CategoryStateChanged ( bool Expanded )
2023-12-31 21:55:35 +01:00
{
2023-12-31 23:00:33 +01:00
QObject * Button = sender ( ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 02:33:43 +01:00
for ( CategoryWidgets & Category : mCategoryWidgets )
2023-12-31 23:00:33 +01:00
{
2024-01-07 02:33:43 +01:00
if ( Category . Button = = Button )
2023-12-31 23:00:33 +01:00
{
2024-01-07 02:33:43 +01:00
SetCategoryWidgetsVisible ( Category , Expanded ) ;
2023-12-31 23:00:33 +01:00
break ;
}
}
}
2023-12-31 21:55:35 +01:00
2024-01-07 02:33:43 +01:00
void lcPropertiesWidget : : AddCategory ( CategoryIndex Index , const QString & Title )
2023-12-31 23:00:33 +01:00
{
2024-01-07 02:33:43 +01:00
mCurrentCategory = & mCategoryWidgets [ static_cast < int > ( Index ) ] ;
2024-04-28 01:01:51 +02:00
mCurrentCategory - > Category = Index ;
2023-12-31 23:00:33 +01:00
lcCollapsibleWidgetButton * CategoryButton = new lcCollapsibleWidgetButton ( Title ) ;
mLayout - > addWidget ( CategoryButton , mLayoutRow , 0 , 1 , - 1 ) ;
mCurrentCategory - > Button = CategoryButton ;
connect ( CategoryButton , & lcCollapsibleWidgetButton : : StateChanged , this , & lcPropertiesWidget : : CategoryStateChanged ) ;
2023-12-31 21:55:35 +01:00
2023-12-31 23:00:33 +01:00
mLayoutRow + + ;
2023-12-31 21:55:35 +01:00
}
2023-12-31 23:00:33 +01:00
void lcPropertiesWidget : : AddSpacing ( )
2023-12-31 21:55:35 +01:00
{
2023-12-31 23:00:33 +01:00
mLayout - > setRowMinimumHeight ( mLayoutRow , 5 ) ;
mCurrentCategory - > SpacingRows . push_back ( mLayoutRow ) ;
mLayoutRow + + ;
2023-12-31 21:55:35 +01:00
}
2024-01-07 20:39:34 +01:00
void lcPropertiesWidget : : AddLabel ( lcObjectPropertyId PropertyId , const QString & Text , const QString & ToolTip )
2023-12-31 21:55:35 +01:00
{
QLabel * Label = new QLabel ( Text , this ) ;
Label - > setAlignment ( Qt : : AlignRight | Qt : : AlignVCenter ) ;
Label - > setToolTip ( ToolTip ) ;
2023-12-31 23:00:33 +01:00
mLayout - > addWidget ( Label , mLayoutRow , 1 ) ;
2024-01-07 02:33:43 +01:00
2024-01-07 20:39:34 +01:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Label = Label ;
2023-12-31 21:55:35 +01:00
}
2024-01-15 02:41:01 +01:00
void lcPropertiesWidget : : KeyFrameChanged ( )
{
QCheckBox * Widget = qobject_cast < QCheckBox * > ( sender ( ) ) ;
lcObjectPropertyId PropertyId = GetKeyFrameWidgetPropertyId ( Widget ) ;
if ( PropertyId = = lcObjectPropertyId : : Count )
return ;
lcModel * Model = gMainWindow - > GetActiveModel ( ) ;
if ( ! Model )
return ;
2024-01-21 21:53:18 +01:00
if ( mFocusObject )
Model - > SetObjectsKeyFrame ( { mFocusObject } , PropertyId , Widget - > isChecked ( ) ) ;
else
Model - > SetObjectsKeyFrame ( mSelection , PropertyId , Widget - > isChecked ( ) ) ;
2024-01-15 02:41:01 +01:00
}
void lcPropertiesWidget : : UpdateKeyFrameWidget ( lcObjectPropertyId PropertyId )
{
lcKeyFrameWidget * Widget = mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . KeyFrame ;
if ( Widget )
{
QSignalBlocker Blocker ( Widget ) ;
lcModel * Model = gMainWindow - > GetActiveModel ( ) ;
2024-01-21 21:53:18 +01:00
if ( Model )
{
const lcStep Step = Model - > GetCurrentStep ( ) ;
if ( mFocusObject )
Widget - > setChecked ( mFocusObject - > HasKeyFrame ( PropertyId , Step ) ) ;
else
{
int KeyFrameCount = 0 , NonKeyFrameCount = 0 ;
for ( const lcObject * Object : mSelection )
{
if ( Object - > HasKeyFrame ( PropertyId , Step ) )
KeyFrameCount + + ;
else
NonKeyFrameCount + + ;
}
if ( KeyFrameCount & & NonKeyFrameCount )
Widget - > setCheckState ( Qt : : PartiallyChecked ) ;
else
Widget - > setCheckState ( KeyFrameCount ! = 0 ? Qt : : Checked : Qt : : Unchecked ) ;
}
}
2024-01-15 02:41:01 +01:00
}
}
void lcPropertiesWidget : : AddKeyFrameWidget ( lcObjectPropertyId PropertyId )
{
lcKeyFrameWidget * Widget = new lcKeyFrameWidget ( this ) ;
Widget - > setToolTip ( tr ( " Toggle Key Frame " ) ) ;
2024-01-21 21:53:18 +01:00
connect ( Widget , & QCheckBox : : stateChanged , this , & lcPropertiesWidget : : KeyFrameChanged ) ;
2024-01-15 02:41:01 +01:00
mLayout - > addWidget ( Widget , mLayoutRow , 3 ) ;
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . KeyFrame = Widget ;
}
2024-03-03 02:40:08 +01:00
std : : pair < QVariant , bool > lcPropertiesWidget : : GetUpdateValue ( lcObjectPropertyId PropertyId )
2024-02-20 01:31:02 +01:00
{
2024-03-03 02:40:08 +01:00
QVariant Value ;
2024-02-20 01:31:02 +01:00
bool Partial = false ;
if ( mFocusObject )
Value = mFocusObject - > GetPropertyValue ( PropertyId ) ;
else
{
bool First = true ;
for ( const lcObject * Object : mSelection )
{
const QVariant ObjectValue = Object - > GetPropertyValue ( PropertyId ) ;
if ( First )
{
Value = ObjectValue ;
First = false ;
}
else if ( Value ! = ObjectValue )
{
Partial = true ;
break ;
}
}
}
return { Value , Partial } ;
}
2024-01-06 03:56:43 +01:00
void lcPropertiesWidget : : BoolChanged ( )
{
QCheckBox * Widget = qobject_cast < QCheckBox * > ( sender ( ) ) ;
2024-01-15 02:41:01 +01:00
lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId ( Widget ) ;
2024-01-06 03:56:43 +01:00
2024-01-07 20:39:34 +01:00
if ( PropertyId = = lcObjectPropertyId : : Count )
2024-01-06 03:56:43 +01:00
return ;
lcModel * Model = gMainWindow - > GetActiveModel ( ) ;
if ( ! Model )
return ;
2024-02-19 21:32:19 +01:00
const bool Value = Widget - > isChecked ( ) ;
2024-05-15 05:45:09 +02:00
Model - > SetObjectsProperty ( mFocusObject ? std : : vector < lcObject * > { mFocusObject } : mSelection , PropertyId , Value ) ;
2024-01-06 03:56:43 +01:00
}
2024-02-20 01:45:14 +01:00
void lcPropertiesWidget : : UpdateBool ( lcObjectPropertyId PropertyId )
2024-01-06 03:56:43 +01:00
{
2024-02-19 23:54:45 +01:00
QCheckBox * CheckBox = qobject_cast < QCheckBox * > ( mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor ) ;
2024-01-06 03:56:43 +01:00
2024-02-19 23:54:45 +01:00
if ( ! CheckBox )
return ;
QSignalBlocker Blocker ( CheckBox ) ;
2024-02-20 01:31:02 +01:00
QVariant Value ;
bool Partial ;
2024-02-19 23:54:45 +01:00
2024-03-03 02:40:08 +01:00
std : : tie ( Value , Partial ) = GetUpdateValue ( PropertyId ) ;
2024-01-15 02:41:01 +01:00
2024-02-19 23:54:45 +01:00
if ( Partial )
CheckBox - > setCheckState ( Qt : : PartiallyChecked ) ;
else
2024-02-20 01:31:02 +01:00
CheckBox - > setCheckState ( Value . toBool ( ) ? Qt : : Checked : Qt : : Unchecked ) ;
2024-02-19 23:54:45 +01:00
2024-01-15 02:41:01 +01:00
UpdateKeyFrameWidget ( PropertyId ) ;
2024-01-06 03:56:43 +01:00
}
2024-01-15 02:41:01 +01:00
void lcPropertiesWidget : : AddBoolProperty ( lcObjectPropertyId PropertyId , const QString & Text , const QString & ToolTip , bool SupportsKeyFrames )
2023-12-31 21:55:35 +01:00
{
2024-01-07 20:39:34 +01:00
AddLabel ( PropertyId , Text , ToolTip ) ;
2023-12-31 21:55:35 +01:00
QCheckBox * Widget = new QCheckBox ( this ) ;
Widget - > setToolTip ( ToolTip ) ;
2024-02-19 21:32:19 +01:00
connect ( Widget , & QCheckBox : : stateChanged , this , & lcPropertiesWidget : : BoolChanged ) ;
2023-12-31 21:55:35 +01:00
2023-12-31 23:00:33 +01:00
mLayout - > addWidget ( Widget , mLayoutRow , 2 ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
mCurrentCategory - > Properties . push_back ( PropertyId ) ;
2024-04-28 01:01:51 +02:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Category = mCurrentCategory - > Category ;
2024-01-15 02:41:01 +01:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor = Widget ;
if ( SupportsKeyFrames )
AddKeyFrameWidget ( PropertyId ) ;
2023-12-31 21:55:35 +01:00
2023-12-31 23:00:33 +01:00
mLayoutRow + + ;
2023-12-31 21:55:35 +01:00
}
void lcPropertiesWidget : : FloatChanged ( )
{
QLineEdit * Widget = qobject_cast < QLineEdit * > ( sender ( ) ) ;
2024-01-15 02:41:01 +01:00
lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId ( Widget ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
if ( PropertyId = = lcObjectPropertyId : : Count )
2023-12-31 21:55:35 +01:00
return ;
lcModel * Model = gMainWindow - > GetActiveModel ( ) ;
2024-01-06 03:56:43 +01:00
if ( ! Model )
return ;
2023-12-31 21:55:35 +01:00
lcPiece * Piece = dynamic_cast < lcPiece * > ( mFocusObject ) ;
2024-01-02 03:57:54 +01:00
lcCamera * Camera = dynamic_cast < lcCamera * > ( mFocusObject ) ;
2023-12-31 21:55:35 +01:00
lcLight * Light = dynamic_cast < lcLight * > ( mFocusObject ) ;
float Value = lcParseValueLocalized ( Widget - > text ( ) ) ;
// todo: mouse drag
2024-10-03 23:23:34 +02:00
if ( PropertyId = = lcObjectPropertyId : : ObjectPositionX | | PropertyId = = lcObjectPropertyId : : ObjectPositionY | | PropertyId = = lcObjectPropertyId : : ObjectPositionZ )
2023-12-31 21:55:35 +01:00
{
2024-10-03 23:23:34 +02:00
lcVector3 Center ;
lcMatrix33 RelativeRotation ;
Model - > GetMoveRotateTransform ( Center , RelativeRotation ) ;
lcVector3 Position = Center ;
2024-01-02 03:57:54 +01:00
2024-10-03 23:23:34 +02:00
if ( PropertyId = = lcObjectPropertyId : : ObjectPositionX )
Position [ 0 ] = Value ;
else if ( PropertyId = = lcObjectPropertyId : : ObjectPositionY )
Position [ 1 ] = Value ;
else if ( PropertyId = = lcObjectPropertyId : : ObjectPositionZ )
Position [ 2 ] = Value ;
2024-01-02 03:57:54 +01:00
2024-10-03 23:23:34 +02:00
lcVector3 Distance = Position - Center ;
2024-01-02 03:57:54 +01:00
2024-10-03 23:23:34 +02:00
Model - > MoveSelectedObjects ( Distance , Distance , false , true , true , true ) ;
}
else if ( PropertyId = = lcObjectPropertyId : : ObjectRotationX | | PropertyId = = lcObjectPropertyId : : ObjectRotationY | | PropertyId = = lcObjectPropertyId : : ObjectRotationZ )
{
lcVector3 InitialRotation ( 0.0f , 0.0f , 0.0f ) ;
2023-12-31 21:55:35 +01:00
2024-10-03 23:23:34 +02:00
if ( Piece )
InitialRotation = lcMatrix44ToEulerAngles ( Piece - > mModelWorld ) * LC_RTOD ;
else if ( Light )
InitialRotation = lcMatrix44ToEulerAngles ( Light - > GetWorldMatrix ( ) ) * LC_RTOD ;
2023-12-31 21:55:35 +01:00
2024-10-03 23:23:34 +02:00
lcVector3 Rotation = InitialRotation ;
2023-12-31 21:55:35 +01:00
2024-10-03 23:23:34 +02:00
if ( PropertyId = = lcObjectPropertyId : : ObjectRotationX )
Rotation [ 0 ] = Value ;
else if ( PropertyId = = lcObjectPropertyId : : ObjectRotationY )
Rotation [ 1 ] = Value ;
else if ( PropertyId = = lcObjectPropertyId : : ObjectRotationZ )
Rotation [ 2 ] = Value ;
2024-01-02 03:57:54 +01:00
2024-10-03 23:23:34 +02:00
Model - > RotateSelectedObjects ( Rotation - InitialRotation , true , false , true , true ) ;
}
2024-12-20 00:54:40 +01:00
else if ( Piece | | Light )
2024-10-03 23:23:34 +02:00
{
Model - > SetObjectsProperty ( mFocusObject ? std : : vector < lcObject * > { mFocusObject } : mSelection , PropertyId , Value ) ;
2023-12-31 21:55:35 +01:00
}
2024-01-02 03:57:54 +01:00
2024-10-03 23:23:34 +02:00
if ( PropertyId = = lcObjectPropertyId : : CameraPositionX | | PropertyId = = lcObjectPropertyId : : CameraPositionY | | PropertyId = = lcObjectPropertyId : : CameraPositionZ )
2023-12-31 21:55:35 +01:00
{
2024-10-03 23:23:34 +02:00
lcVector3 Center = Camera - > mPosition ;
lcVector3 Position = Center ;
2023-12-31 21:55:35 +01:00
2024-10-03 23:23:34 +02:00
if ( PropertyId = = lcObjectPropertyId : : CameraPositionX )
Position [ 0 ] = Value ;
else if ( PropertyId = = lcObjectPropertyId : : CameraPositionY )
Position [ 1 ] = Value ;
else if ( PropertyId = = lcObjectPropertyId : : CameraPositionZ )
Position [ 2 ] = Value ;
2023-12-31 21:55:35 +01:00
2024-10-03 23:23:34 +02:00
lcVector3 Distance = Position - Center ;
2023-12-31 21:55:35 +01:00
2024-10-03 23:23:34 +02:00
Model - > MoveSelectedObjects ( Distance , Distance , false , false , true , true ) ;
}
else if ( PropertyId = = lcObjectPropertyId : : CameraTargetX | | PropertyId = = lcObjectPropertyId : : CameraTargetY | | PropertyId = = lcObjectPropertyId : : CameraTargetZ )
{
lcVector3 Center = Camera - > mTargetPosition ;
lcVector3 Position = Center ;
2023-12-31 21:55:35 +01:00
2024-10-03 23:23:34 +02:00
if ( PropertyId = = lcObjectPropertyId : : CameraTargetX )
Position [ 0 ] = Value ;
else if ( PropertyId = = lcObjectPropertyId : : CameraTargetY )
Position [ 1 ] = Value ;
else if ( PropertyId = = lcObjectPropertyId : : CameraTargetZ )
Position [ 2 ] = Value ;
2024-01-02 03:57:54 +01:00
2024-10-03 23:23:34 +02:00
lcVector3 Distance = Position - Center ;
2024-01-02 03:57:54 +01:00
2024-10-03 23:23:34 +02:00
Model - > MoveSelectedObjects ( Distance , Distance , false , false , true , true ) ;
}
else if ( PropertyId = = lcObjectPropertyId : : CameraUpX | | PropertyId = = lcObjectPropertyId : : CameraUpY | | PropertyId = = lcObjectPropertyId : : CameraUpZ )
{
lcVector3 Center = Camera - > mUpVector ;
lcVector3 Position = Center ;
2024-01-02 03:57:54 +01:00
2024-10-03 23:23:34 +02:00
if ( PropertyId = = lcObjectPropertyId : : CameraUpX )
Position [ 0 ] = Value ;
else if ( PropertyId = = lcObjectPropertyId : : CameraUpY )
Position [ 1 ] = Value ;
else if ( PropertyId = = lcObjectPropertyId : : CameraUpZ )
Position [ 2 ] = Value ;
2024-01-02 03:57:54 +01:00
2024-10-03 23:23:34 +02:00
lcVector3 Distance = Position - Center ;
2024-01-02 03:57:54 +01:00
2024-10-03 23:23:34 +02:00
Model - > MoveSelectedObjects ( Distance , Distance , false , false , true , true ) ;
}
else if ( Camera )
{
if ( PropertyId = = lcObjectPropertyId : : CameraFOV )
2024-01-02 03:57:54 +01:00
{
Model - > SetCameraFOV ( Camera , Value ) ;
}
2024-01-07 20:39:34 +01:00
else if ( PropertyId = = lcObjectPropertyId : : CameraNear )
2024-01-02 03:57:54 +01:00
{
Model - > SetCameraZNear ( Camera , Value ) ;
}
2024-01-07 20:39:34 +01:00
else if ( PropertyId = = lcObjectPropertyId : : CameraFar )
2024-01-02 03:57:54 +01:00
{
Model - > SetCameraZFar ( Camera , Value ) ;
}
2023-12-31 21:55:35 +01:00
}
}
2024-01-07 20:39:34 +01:00
void lcPropertiesWidget : : UpdateFloat ( lcObjectPropertyId PropertyId , float Value )
2023-12-31 21:55:35 +01:00
{
2024-01-15 02:41:01 +01:00
QLineEdit * Widget = qobject_cast < QLineEdit * > ( mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor ) ;
2023-12-31 21:55:35 +01:00
if ( Widget )
{
QSignalBlocker Blocker ( Widget ) ;
Widget - > setText ( lcFormatValueLocalized ( Value ) ) ;
}
2024-01-15 02:41:01 +01:00
UpdateKeyFrameWidget ( PropertyId ) ;
2023-12-31 21:55:35 +01:00
}
2024-01-15 02:41:01 +01:00
void lcPropertiesWidget : : AddFloatProperty ( lcObjectPropertyId PropertyId , const QString & Text , const QString & ToolTip , bool SupportsKeyFrames , float Min , float Max )
2023-12-31 21:55:35 +01:00
{
2024-01-07 20:39:34 +01:00
AddLabel ( PropertyId , Text , ToolTip ) ;
2023-12-31 21:55:35 +01:00
QLineEdit * Widget = new QLineEdit ( this ) ;
Widget - > setToolTip ( ToolTip ) ;
Widget - > setValidator ( new QDoubleValidator ( Min , Max , 1 , Widget ) ) ;
connect ( Widget , & QLineEdit : : editingFinished , this , & lcPropertiesWidget : : FloatChanged ) ;
2023-12-31 23:00:33 +01:00
mLayout - > addWidget ( Widget , mLayoutRow , 2 ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
mCurrentCategory - > Properties . push_back ( PropertyId ) ;
2024-01-15 02:41:01 +01:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor = Widget ;
2024-04-28 01:01:51 +02:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Category = mCurrentCategory - > Category ;
2024-01-15 02:41:01 +01:00
if ( SupportsKeyFrames )
AddKeyFrameWidget ( PropertyId ) ;
2023-12-31 21:55:35 +01:00
2023-12-31 23:00:33 +01:00
mLayoutRow + + ;
2023-12-31 21:55:35 +01:00
}
2024-01-06 03:56:43 +01:00
void lcPropertiesWidget : : IntegerChanged ( )
{
2024-02-20 01:31:02 +01:00
// todo: switch to spinner and support mouse drag
QLineEdit * LineEdit = qobject_cast < QLineEdit * > ( sender ( ) ) ;
lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId ( LineEdit ) ;
2024-01-06 03:56:43 +01:00
2024-01-07 20:39:34 +01:00
if ( PropertyId = = lcObjectPropertyId : : Count )
2024-01-06 03:56:43 +01:00
return ;
lcModel * Model = gMainWindow - > GetActiveModel ( ) ;
if ( ! Model )
return ;
2024-02-20 01:31:02 +01:00
const int Value = LineEdit - > text ( ) . toInt ( ) ;
2024-05-15 05:45:09 +02:00
Model - > SetObjectsProperty ( mFocusObject ? std : : vector < lcObject * > { mFocusObject } : mSelection , PropertyId , Value ) ;
2024-02-20 01:31:02 +01:00
}
2024-01-06 03:56:43 +01:00
2024-02-20 01:45:14 +01:00
void lcPropertiesWidget : : UpdateInteger ( lcObjectPropertyId PropertyId )
2024-02-20 01:31:02 +01:00
{
QLineEdit * LineEdit = qobject_cast < QLineEdit * > ( mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor ) ;
2024-01-06 03:56:43 +01:00
2024-02-20 01:31:02 +01:00
if ( ! LineEdit )
return ;
2024-01-06 03:56:43 +01:00
2024-02-20 01:31:02 +01:00
QSignalBlocker Blocker ( LineEdit ) ;
QVariant Value ;
bool Partial ;
2024-01-06 03:56:43 +01:00
2024-03-03 02:40:08 +01:00
std : : tie ( Value , Partial ) = GetUpdateValue ( PropertyId ) ;
2024-01-06 03:56:43 +01:00
2024-02-20 01:31:02 +01:00
if ( Partial )
2024-01-06 03:56:43 +01:00
{
2024-02-20 01:31:02 +01:00
LineEdit - > clear ( ) ;
LineEdit - > setPlaceholderText ( tr ( " Multiple Values " ) ) ;
}
else
{
LineEdit - > setText ( QString : : number ( Value . toInt ( ) ) ) ;
LineEdit - > setPlaceholderText ( QString ( ) ) ;
2024-01-06 03:56:43 +01:00
}
2024-01-15 02:41:01 +01:00
UpdateKeyFrameWidget ( PropertyId ) ;
2024-01-06 03:56:43 +01:00
}
2024-01-15 02:41:01 +01:00
void lcPropertiesWidget : : AddIntegerProperty ( lcObjectPropertyId PropertyId , const QString & Text , const QString & ToolTip , bool SupportsKeyFrames , int Min , int Max )
2023-12-31 21:55:35 +01:00
{
2024-01-07 20:39:34 +01:00
AddLabel ( PropertyId , Text , ToolTip ) ;
2023-12-31 21:55:35 +01:00
2024-01-06 03:56:43 +01:00
QLineEdit * Widget = new QLineEdit ( this ) ;
2023-12-31 21:55:35 +01:00
Widget - > setToolTip ( ToolTip ) ;
2024-01-06 03:56:43 +01:00
Widget - > setValidator ( new QIntValidator ( Min , Max , Widget ) ) ;
connect ( Widget , & QLineEdit : : editingFinished , this , & lcPropertiesWidget : : IntegerChanged ) ;
2023-12-31 23:00:33 +01:00
mLayout - > addWidget ( Widget , mLayoutRow , 2 ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
mCurrentCategory - > Properties . push_back ( PropertyId ) ;
2024-01-15 02:41:01 +01:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor = Widget ;
2024-04-28 01:01:51 +02:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Category = mCurrentCategory - > Category ;
2024-01-15 02:41:01 +01:00
if ( SupportsKeyFrames )
AddKeyFrameWidget ( PropertyId ) ;
2023-12-31 21:55:35 +01:00
2023-12-31 23:00:33 +01:00
mLayoutRow + + ;
2023-12-31 21:55:35 +01:00
}
void lcPropertiesWidget : : StepNumberChanged ( )
{
QLineEdit * Widget = qobject_cast < QLineEdit * > ( sender ( ) ) ;
2024-01-15 02:41:01 +01:00
lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId ( Widget ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
if ( PropertyId = = lcObjectPropertyId : : Count )
2023-12-31 21:55:35 +01:00
return ;
lcModel * Model = gMainWindow - > GetActiveModel ( ) ;
if ( ! Model )
return ;
bool Ok = true ;
QString Text = Widget - > text ( ) ;
2024-01-07 20:39:34 +01:00
lcStep Step = Text . isEmpty ( ) & & PropertyId = = lcObjectPropertyId : : PieceStepHide ? LC_STEP_MAX : Text . toUInt ( & Ok ) ;
2023-12-31 21:55:35 +01:00
if ( ! Ok )
return ;
2024-01-07 20:39:34 +01:00
if ( PropertyId = = lcObjectPropertyId : : PieceStepShow )
2023-12-31 21:55:35 +01:00
{
Model - > SetSelectedPiecesStepShow ( Step ) ;
}
2024-01-07 20:39:34 +01:00
else if ( PropertyId = = lcObjectPropertyId : : PieceStepHide )
2023-12-31 21:55:35 +01:00
{
Model - > SetSelectedPiecesStepHide ( Step ) ;
}
}
2024-01-07 20:39:34 +01:00
void lcPropertiesWidget : : UpdateStepNumber ( lcObjectPropertyId PropertyId , lcStep Step , lcStep Min , lcStep Max )
2023-12-31 21:55:35 +01:00
{
2024-01-15 02:41:01 +01:00
QLineEdit * Widget = qobject_cast < QLineEdit * > ( mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor ) ;
2023-12-31 21:55:35 +01:00
if ( Widget )
{
QSignalBlocker Blocker ( Widget ) ;
2024-01-07 20:39:34 +01:00
Widget - > setValidator ( new lcStepValidator ( Min , Max , PropertyId = = lcObjectPropertyId : : PieceStepHide , Widget ) ) ;
2023-12-31 21:55:35 +01:00
Widget - > setText ( Step = = LC_STEP_MAX ? QString ( ) : QString : : number ( Step ) ) ;
}
2024-01-15 02:41:01 +01:00
UpdateKeyFrameWidget ( PropertyId ) ;
2023-12-31 21:55:35 +01:00
}
2024-01-15 02:41:01 +01:00
void lcPropertiesWidget : : AddStepNumberProperty ( lcObjectPropertyId PropertyId , const QString & Text , const QString & ToolTip , bool SupportsKeyFrames )
2023-12-31 21:55:35 +01:00
{
2024-01-07 20:39:34 +01:00
AddLabel ( PropertyId , Text , ToolTip ) ;
2023-12-31 21:55:35 +01:00
QLineEdit * Widget = new QLineEdit ( this ) ;
Widget - > setToolTip ( ToolTip ) ;
connect ( Widget , & QLineEdit : : editingFinished , this , & lcPropertiesWidget : : StepNumberChanged ) ;
2023-12-31 23:00:33 +01:00
mLayout - > addWidget ( Widget , mLayoutRow , 2 ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
mCurrentCategory - > Properties . push_back ( PropertyId ) ;
2024-01-15 02:41:01 +01:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor = Widget ;
2024-04-28 01:01:51 +02:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Category = mCurrentCategory - > Category ;
2024-01-15 02:41:01 +01:00
if ( SupportsKeyFrames )
AddKeyFrameWidget ( PropertyId ) ;
2023-12-31 21:55:35 +01:00
2023-12-31 23:00:33 +01:00
mLayoutRow + + ;
2023-12-31 21:55:35 +01:00
}
2024-01-02 03:57:54 +01:00
void lcPropertiesWidget : : StringChanged ( )
{
2024-02-20 02:38:04 +01:00
QLineEdit * LineEdit = qobject_cast < QLineEdit * > ( sender ( ) ) ;
lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId ( LineEdit ) ;
2024-01-02 03:57:54 +01:00
2024-01-07 20:39:34 +01:00
if ( PropertyId = = lcObjectPropertyId : : Count )
2024-01-02 03:57:54 +01:00
return ;
lcModel * Model = gMainWindow - > GetActiveModel ( ) ;
2024-01-06 03:56:43 +01:00
if ( ! Model )
2024-01-02 03:57:54 +01:00
return ;
2024-02-20 02:38:04 +01:00
QString Value = LineEdit - > text ( ) ;
2024-05-15 05:45:09 +02:00
Model - > SetObjectsProperty ( mFocusObject ? std : : vector < lcObject * > { mFocusObject } : mSelection , PropertyId , Value ) ;
2024-01-02 03:57:54 +01:00
}
2024-02-20 02:38:04 +01:00
void lcPropertiesWidget : : UpdateString ( lcObjectPropertyId PropertyId )
2024-01-02 03:57:54 +01:00
{
2024-02-20 02:38:04 +01:00
QLineEdit * LineEdit = qobject_cast < QLineEdit * > ( mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor ) ;
2024-01-02 03:57:54 +01:00
2024-02-20 02:38:04 +01:00
if ( ! LineEdit )
return ;
QSignalBlocker Blocker ( LineEdit ) ;
QVariant Value ;
bool Partial ;
2024-01-02 03:57:54 +01:00
2024-03-03 02:40:08 +01:00
std : : tie ( Value , Partial ) = GetUpdateValue ( PropertyId ) ;
2024-02-20 02:38:04 +01:00
if ( Partial )
{
LineEdit - > clear ( ) ;
LineEdit - > setPlaceholderText ( tr ( " Multiple Values " ) ) ;
}
else
{
LineEdit - > setText ( Value . toString ( ) ) ;
LineEdit - > setPlaceholderText ( QString ( ) ) ;
2024-01-02 03:57:54 +01:00
}
2024-01-15 02:41:01 +01:00
UpdateKeyFrameWidget ( PropertyId ) ;
2024-01-02 03:57:54 +01:00
}
2024-01-15 02:41:01 +01:00
void lcPropertiesWidget : : AddStringProperty ( lcObjectPropertyId PropertyId , const QString & Text , const QString & ToolTip , bool SupportsKeyFrames )
2023-12-31 21:55:35 +01:00
{
2024-01-07 20:39:34 +01:00
AddLabel ( PropertyId , Text , ToolTip ) ;
2023-12-31 21:55:35 +01:00
QLineEdit * Widget = new QLineEdit ( this ) ;
Widget - > setToolTip ( ToolTip ) ;
2024-01-02 03:57:54 +01:00
connect ( Widget , & QLineEdit : : editingFinished , this , & lcPropertiesWidget : : StringChanged ) ;
2023-12-31 23:00:33 +01:00
mLayout - > addWidget ( Widget , mLayoutRow , 2 ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
mCurrentCategory - > Properties . push_back ( PropertyId ) ;
2024-01-15 02:41:01 +01:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor = Widget ;
2024-04-28 01:01:51 +02:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Category = mCurrentCategory - > Category ;
2024-01-15 02:41:01 +01:00
if ( SupportsKeyFrames )
AddKeyFrameWidget ( PropertyId ) ;
2023-12-31 21:55:35 +01:00
2023-12-31 23:00:33 +01:00
mLayoutRow + + ;
2023-12-31 21:55:35 +01:00
}
2024-01-02 03:57:54 +01:00
void lcPropertiesWidget : : StringListChanged ( int Value )
{
2024-02-20 01:31:02 +01:00
QComboBox * ComboBox = qobject_cast < QComboBox * > ( sender ( ) ) ;
lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId ( ComboBox ) ;
2024-01-02 03:57:54 +01:00
2024-01-07 20:39:34 +01:00
if ( PropertyId = = lcObjectPropertyId : : Count )
2024-01-02 03:57:54 +01:00
return ;
lcModel * Model = gMainWindow - > GetActiveModel ( ) ;
2024-01-06 03:56:43 +01:00
if ( ! Model )
2024-01-02 03:57:54 +01:00
return ;
2024-05-15 05:45:09 +02:00
Model - > SetObjectsProperty ( mFocusObject ? std : : vector < lcObject * > { mFocusObject } : mSelection , PropertyId , Value ) ;
2024-01-02 03:57:54 +01:00
}
2024-02-20 01:45:14 +01:00
void lcPropertiesWidget : : UpdateStringList ( lcObjectPropertyId PropertyId )
2024-01-02 03:57:54 +01:00
{
2024-02-20 01:31:02 +01:00
QComboBox * ComboBox = qobject_cast < QComboBox * > ( mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor ) ;
2024-01-02 03:57:54 +01:00
2024-02-20 01:31:02 +01:00
if ( ! ComboBox )
return ;
QSignalBlocker Blocker ( ComboBox ) ;
QVariant Value ;
bool Partial ;
2024-03-03 02:40:08 +01:00
std : : tie ( Value , Partial ) = GetUpdateValue ( PropertyId ) ;
2024-02-20 01:31:02 +01:00
bool HasMultiple = ( ComboBox - > itemText ( ComboBox - > count ( ) - 1 ) = = tr ( " Multiple Values " ) ) ;
if ( Partial )
2024-01-02 03:57:54 +01:00
{
2024-02-20 01:31:02 +01:00
if ( ! HasMultiple )
ComboBox - > addItem ( tr ( " Multiple Values " ) ) ;
2024-01-02 03:57:54 +01:00
2024-02-20 01:31:02 +01:00
ComboBox - > setCurrentIndex ( ComboBox - > count ( ) - 1 ) ;
}
else
{
if ( HasMultiple )
ComboBox - > removeItem ( ComboBox - > count ( ) - 1 ) ;
ComboBox - > setCurrentIndex ( Value . toInt ( ) ) ;
2024-01-02 03:57:54 +01:00
}
2024-01-15 02:41:01 +01:00
UpdateKeyFrameWidget ( PropertyId ) ;
2024-01-02 03:57:54 +01:00
}
2024-01-15 02:41:01 +01:00
void lcPropertiesWidget : : AddStringListProperty ( lcObjectPropertyId PropertyId , const QString & Text , const QString & ToolTip , bool SupportsKeyFrames , const QStringList & Strings )
2023-12-31 21:55:35 +01:00
{
2024-01-07 20:39:34 +01:00
AddLabel ( PropertyId , Text , ToolTip ) ;
2023-12-31 21:55:35 +01:00
QComboBox * Widget = new QComboBox ( this ) ;
Widget - > setToolTip ( ToolTip ) ;
Widget - > addItems ( Strings ) ;
2024-01-02 20:28:04 +01:00
connect ( Widget , QOverload < int > : : of ( & QComboBox : : currentIndexChanged ) , this , & lcPropertiesWidget : : StringListChanged ) ;
2023-12-31 21:55:35 +01:00
2023-12-31 23:00:33 +01:00
mLayout - > addWidget ( Widget , mLayoutRow , 2 ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
mCurrentCategory - > Properties . push_back ( PropertyId ) ;
2024-01-15 02:41:01 +01:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor = Widget ;
2024-04-28 01:01:51 +02:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Category = mCurrentCategory - > Category ;
2024-01-15 02:41:01 +01:00
if ( SupportsKeyFrames )
AddKeyFrameWidget ( PropertyId ) ;
2023-12-31 21:55:35 +01:00
2023-12-31 23:00:33 +01:00
mLayoutRow + + ;
2023-12-31 21:55:35 +01:00
}
2024-01-06 03:56:43 +01:00
void lcPropertiesWidget : : ColorButtonClicked ( )
{
QToolButton * ColorButton = qobject_cast < QToolButton * > ( sender ( ) ) ;
2024-02-19 23:54:45 +01:00
lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId ( ColorButton ) ;
2024-01-06 03:56:43 +01:00
2024-02-19 23:54:45 +01:00
if ( PropertyId = = lcObjectPropertyId : : Count )
2024-01-06 03:56:43 +01:00
return ;
2024-03-03 02:37:46 +01:00
QVariant Value ;
bool Partial ;
2024-02-19 23:54:45 +01:00
2024-03-03 02:40:08 +01:00
std : : tie ( Value , Partial ) = GetUpdateValue ( PropertyId ) ;
2024-03-03 02:37:46 +01:00
QColor InitialColor = Partial ? QColor ( 128 , 128 , 128 ) : lcQColorFromVector3 ( Value . value < lcVector3 > ( ) ) ;
2024-02-19 23:54:45 +01:00
2024-08-08 23:37:21 +02:00
QMenu * Menu = new QMenu ( ColorButton ) ;
QWidgetAction * Action = new QWidgetAction ( Menu ) ;
lcColorDialogPopup * Popup = new lcColorDialogPopup ( InitialColor , Menu ) ;
Action - > setDefaultWidget ( Popup ) ;
Menu - > addAction ( Action ) ;
connect ( Popup , & lcColorDialogPopup : : ColorSelected , this , & lcPropertiesWidget : : ColorChanged ) ;
Menu - > exec ( ColorButton - > mapToGlobal ( ColorButton - > rect ( ) . bottomLeft ( ) ) ) ;
delete Menu ;
}
void lcPropertiesWidget : : ColorChanged ( QColor Color )
{
lcColorDialogPopup * Popup = qobject_cast < lcColorDialogPopup * > ( sender ( ) ) ;
QMenu * Menu = qobject_cast < QMenu * > ( Popup - > parent ( ) ) ;
QToolButton * ColorButton = qobject_cast < QToolButton * > ( Menu - > parent ( ) ) ;
lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId ( ColorButton ) ;
2024-01-06 03:56:43 +01:00
if ( ! Color . isValid ( ) )
return ;
2024-02-19 23:54:45 +01:00
lcModel * Model = gMainWindow - > GetActiveModel ( ) ;
if ( ! Model )
return ;
2024-03-03 02:37:46 +01:00
const lcVector3 FloatColor = lcVector3FromQColor ( Color ) ;
2024-05-15 05:45:09 +02:00
Model - > SetObjectsProperty ( mFocusObject ? std : : vector < lcObject * > { mFocusObject } : mSelection , PropertyId , QVariant : : fromValue < lcVector3 > ( FloatColor ) ) ;
2024-01-06 03:56:43 +01:00
}
2024-02-20 01:45:14 +01:00
void lcPropertiesWidget : : UpdateColor ( lcObjectPropertyId PropertyId )
2024-01-06 03:56:43 +01:00
{
2024-01-15 02:41:01 +01:00
QToolButton * ColorButton = qobject_cast < QToolButton * > ( mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor ) ;
2024-01-06 03:56:43 +01:00
if ( ! ColorButton )
return ;
2024-02-19 23:54:45 +01:00
QSignalBlocker Blocker ( ColorButton ) ;
2024-02-20 01:31:02 +01:00
QVariant Value ;
bool Partial ;
2024-02-19 23:54:45 +01:00
2024-03-03 02:40:08 +01:00
std : : tie ( Value , Partial ) = GetUpdateValue ( PropertyId ) ;
2024-02-19 23:54:45 +01:00
2024-02-20 01:31:02 +01:00
QColor Color = Partial ? QColor ( 128 , 128 , 128 ) : lcQColorFromVector3 ( Value . value < lcVector3 > ( ) ) ;
2024-01-06 03:56:43 +01:00
QPixmap Pixmap ( 14 , 14 ) ;
Pixmap . fill ( Color ) ;
ColorButton - > setIcon ( Pixmap ) ;
2024-02-19 23:54:45 +01:00
ColorButton - > setText ( Partial ? tr ( " Multiple Colors " ) : QString ( " " ) + Color . name ( ) ) ;
2024-01-15 02:41:01 +01:00
UpdateKeyFrameWidget ( PropertyId ) ;
2024-01-06 03:56:43 +01:00
}
2024-01-15 02:41:01 +01:00
void lcPropertiesWidget : : AddColorProperty ( lcObjectPropertyId PropertyId , const QString & Text , const QString & ToolTip , bool SupportsKeyFrames )
2023-12-31 21:55:35 +01:00
{
2024-01-07 20:39:34 +01:00
AddLabel ( PropertyId , Text , ToolTip ) ;
2023-12-31 21:55:35 +01:00
2024-01-06 03:56:43 +01:00
QToolButton * Widget = new QToolButton ( this ) ;
2023-12-31 21:55:35 +01:00
Widget - > setToolTip ( ToolTip ) ;
2024-01-06 03:56:43 +01:00
Widget - > setAutoRaise ( true ) ;
Widget - > setToolButtonStyle ( Qt : : ToolButtonTextBesideIcon ) ;
Widget - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Preferred ) ;
2023-12-31 21:55:35 +01:00
2024-01-06 03:56:43 +01:00
connect ( Widget , & QToolButton : : clicked , this , & lcPropertiesWidget : : ColorButtonClicked ) ;
2023-12-31 21:55:35 +01:00
2023-12-31 23:00:33 +01:00
mLayout - > addWidget ( Widget , mLayoutRow , 2 ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
mCurrentCategory - > Properties . push_back ( PropertyId ) ;
2024-01-15 02:41:01 +01:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor = Widget ;
2024-04-28 01:01:51 +02:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Category = mCurrentCategory - > Category ;
2024-01-15 02:41:01 +01:00
if ( SupportsKeyFrames )
AddKeyFrameWidget ( PropertyId ) ;
2023-12-31 21:55:35 +01:00
2023-12-31 23:00:33 +01:00
mLayoutRow + + ;
2023-12-31 21:55:35 +01:00
}
void lcPropertiesWidget : : PieceColorChanged ( int ColorIndex )
{
2024-03-03 02:37:46 +01:00
lcColorPickerPopup * Popup = qobject_cast < lcColorPickerPopup * > ( sender ( ) ) ;
QMenu * Menu = qobject_cast < QMenu * > ( Popup - > parent ( ) ) ;
QToolButton * ColorButton = qobject_cast < QToolButton * > ( Menu - > parent ( ) ) ;
lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId ( ColorButton ) ;
Menu - > close ( ) ;
if ( PropertyId = = lcObjectPropertyId : : Count )
2023-12-31 21:55:35 +01:00
return ;
lcModel * Model = gMainWindow - > GetActiveModel ( ) ;
2024-03-03 02:37:46 +01:00
if ( ! Model )
return ;
2024-05-15 05:45:09 +02:00
Model - > SetObjectsProperty ( mFocusObject ? std : : vector < lcObject * > { mFocusObject } : mSelection , PropertyId , ColorIndex ) ;
2023-12-31 21:55:35 +01:00
}
void lcPropertiesWidget : : PieceColorButtonClicked ( )
{
QToolButton * ColorButton = qobject_cast < QToolButton * > ( sender ( ) ) ;
2024-03-03 02:37:46 +01:00
lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId ( ColorButton ) ;
2023-12-31 21:55:35 +01:00
2024-03-03 02:37:46 +01:00
if ( ! ColorButton )
2023-12-31 21:55:35 +01:00
return ;
2024-03-03 02:37:46 +01:00
QVariant Value ;
bool Partial ;
2024-03-03 02:40:08 +01:00
std : : tie ( Value , Partial ) = GetUpdateValue ( PropertyId ) ;
2024-03-03 02:37:46 +01:00
int ColorIndex = Partial ? gDefaultColor : Value . toInt ( ) ;
QMenu * Menu = new QMenu ( ColorButton ) ;
QWidgetAction * Action = new QWidgetAction ( Menu ) ;
lcColorPickerPopup * Popup = new lcColorPickerPopup ( Menu , ColorIndex ) ;
Action - > setDefaultWidget ( Popup ) ;
Menu - > addAction ( Action ) ;
2023-12-31 21:55:35 +01:00
connect ( Popup , & lcColorPickerPopup : : Selected , this , & lcPropertiesWidget : : PieceColorChanged ) ;
2024-03-03 02:37:46 +01:00
Menu - > exec ( ColorButton - > mapToGlobal ( ColorButton - > rect ( ) . bottomLeft ( ) ) ) ;
delete Menu ;
2023-12-31 21:55:35 +01:00
}
2024-03-03 02:37:46 +01:00
void lcPropertiesWidget : : UpdatePieceColor ( lcObjectPropertyId PropertyId )
2023-12-31 21:55:35 +01:00
{
2024-01-15 02:41:01 +01:00
QToolButton * ColorButton = qobject_cast < QToolButton * > ( mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor ) ;
2023-12-31 21:55:35 +01:00
if ( ! ColorButton )
return ;
2024-03-03 02:37:46 +01:00
QSignalBlocker Blocker ( ColorButton ) ;
QVariant Value ;
bool Partial ;
2024-03-03 02:40:08 +01:00
std : : tie ( Value , Partial ) = GetUpdateValue ( PropertyId ) ;
2024-03-03 02:37:46 +01:00
const int ColorIndex = Value . toInt ( ) ;
QColor Color = Partial ? QColor ( 128 , 128 , 128 ) : QColor : : fromRgbF ( gColorList [ ColorIndex ] . Value [ 0 ] , gColorList [ ColorIndex ] . Value [ 1 ] , gColorList [ ColorIndex ] . Value [ 2 ] ) ;
2023-12-31 21:55:35 +01:00
QPixmap Pixmap ( 14 , 14 ) ;
2024-03-03 02:37:46 +01:00
Pixmap . fill ( Color ) ;
2023-12-31 21:55:35 +01:00
ColorButton - > setIcon ( Pixmap ) ;
2024-03-03 02:37:46 +01:00
ColorButton - > setText ( Partial ? tr ( " Multiple Colors " ) : QString ( " " ) + gColorList [ ColorIndex ] . Name ) ;
2024-01-15 02:41:01 +01:00
UpdateKeyFrameWidget ( PropertyId ) ;
2023-12-31 21:55:35 +01:00
}
2024-01-15 02:41:01 +01:00
void lcPropertiesWidget : : AddPieceColorProperty ( lcObjectPropertyId PropertyId , const QString & Text , const QString & ToolTip , bool SupportsKeyFrames )
2023-12-31 21:55:35 +01:00
{
2024-01-07 20:39:34 +01:00
AddLabel ( PropertyId , Text , ToolTip ) ;
2023-12-31 21:55:35 +01:00
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 ) ;
2023-12-31 23:00:33 +01:00
mLayout - > addWidget ( Widget , mLayoutRow , 2 ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
mCurrentCategory - > Properties . push_back ( PropertyId ) ;
2024-01-15 02:41:01 +01:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor = Widget ;
2024-04-28 01:01:51 +02:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Category = mCurrentCategory - > Category ;
2024-01-15 02:41:01 +01:00
if ( SupportsKeyFrames )
AddKeyFrameWidget ( PropertyId ) ;
2023-12-31 21:55:35 +01:00
2023-12-31 23:00:33 +01:00
mLayoutRow + + ;
2023-12-31 21:55:35 +01:00
}
2024-03-03 02:37:46 +01:00
void lcPropertiesWidget : : UpdatePieceId ( lcObjectPropertyId PropertyId )
2023-12-31 21:55:35 +01:00
{
2024-01-15 02:41:01 +01:00
lcElidableToolButton * PieceIdButton = qobject_cast < lcElidableToolButton * > ( mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor ) ;
2023-12-31 21:55:35 +01:00
if ( ! PieceIdButton )
return ;
2024-03-03 02:37:46 +01:00
QSignalBlocker Blocker ( PieceIdButton ) ;
QVariant Value ;
bool Partial ;
2024-03-03 02:40:08 +01:00
std : : tie ( Value , Partial ) = GetUpdateValue ( PropertyId ) ;
2024-03-03 02:37:46 +01:00
PieceInfo * Info = static_cast < PieceInfo * > ( Value . value < void * > ( ) ) ;
if ( Partial )
PieceIdButton - > setText ( tr ( " Multiple Pieces " ) ) ;
else if ( Info )
PieceIdButton - > setText ( Info - > m_strDescription ) ;
2024-01-15 02:41:01 +01:00
UpdateKeyFrameWidget ( PropertyId ) ;
2023-12-31 21:55:35 +01:00
}
void lcPropertiesWidget : : PieceIdButtonClicked ( )
{
QToolButton * PieceIdButton = qobject_cast < QToolButton * > ( sender ( ) ) ;
2024-03-03 02:37:46 +01:00
lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId ( PieceIdButton ) ;
2023-12-31 21:55:35 +01:00
2024-03-03 02:37:46 +01:00
if ( ! PieceIdButton )
2023-12-31 21:55:35 +01:00
return ;
2024-03-03 02:37:46 +01:00
QVariant Value ;
bool Partial ;
2024-03-03 02:40:08 +01:00
std : : tie ( Value , Partial ) = GetUpdateValue ( PropertyId ) ;
2024-03-03 02:37:46 +01:00
PieceInfo * Info = static_cast < PieceInfo * > ( Value . value < void * > ( ) ) ;
QMenu * Menu = new QMenu ( PieceIdButton ) ;
2023-12-31 21:55:35 +01:00
QWidgetAction * Action = new QWidgetAction ( Menu ) ;
2024-07-25 23:16:23 +02:00
lcPieceIdPickerPopup * Popup = new lcPieceIdPickerPopup ( Partial ? nullptr : Info , Menu ) ;
2023-12-31 21:55:35 +01:00
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 )
{
2024-03-03 02:37:46 +01:00
lcPieceIdPickerPopup * Popup = qobject_cast < lcPieceIdPickerPopup * > ( sender ( ) ) ;
QMenu * Menu = qobject_cast < QMenu * > ( Popup - > parent ( ) ) ;
QToolButton * PieceIdButton = qobject_cast < QToolButton * > ( Menu - > parent ( ) ) ;
lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId ( PieceIdButton ) ;
2023-12-31 21:55:35 +01:00
lcModel * Model = gMainWindow - > GetActiveModel ( ) ;
if ( ! Model | | ! Info )
return ;
2024-05-15 05:45:09 +02:00
Model - > SetObjectsProperty ( mFocusObject ? std : : vector < lcObject * > { mFocusObject } : mSelection , PropertyId , QVariant : : fromValue < void * > ( Info ) ) ;
2023-12-31 21:55:35 +01:00
}
2024-01-15 02:41:01 +01:00
void lcPropertiesWidget : : AddPieceIdProperty ( lcObjectPropertyId PropertyId , const QString & Text , const QString & ToolTip , bool SupportsKeyFrames )
2023-12-31 21:55:35 +01:00
{
2024-01-07 20:39:34 +01:00
AddLabel ( PropertyId , Text , ToolTip ) ;
2023-12-31 21:55:35 +01:00
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 ) ;
2023-12-31 23:00:33 +01:00
mLayout - > addWidget ( Widget , mLayoutRow , 2 ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
mCurrentCategory - > Properties . push_back ( PropertyId ) ;
2024-01-15 02:41:01 +01:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Editor = Widget ;
2024-04-28 01:01:51 +02:00
mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Category = mCurrentCategory - > Category ;
2024-01-15 02:41:01 +01:00
if ( SupportsKeyFrames )
AddKeyFrameWidget ( PropertyId ) ;
2023-12-31 21:55:35 +01:00
2023-12-31 23:00:33 +01:00
mLayoutRow + + ;
2023-12-31 21:55:35 +01:00
}
2024-01-07 02:33:43 +01:00
void lcPropertiesWidget : : CreateWidgets ( )
2023-12-31 21:55:35 +01:00
{
2023-12-31 23:00:33 +01:00
mLayout = new QGridLayout ( this ) ;
mLayout - > setVerticalSpacing ( 1 ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 02:33:43 +01:00
AddCategory ( CategoryIndex : : Piece , tr ( " Piece " ) ) ;
2024-01-15 02:41:01 +01:00
AddPieceIdProperty ( lcObjectPropertyId : : PieceId , tr ( " Part " ) , tr ( " Part Id " ) , false ) ;
AddPieceColorProperty ( lcObjectPropertyId : : PieceColor , tr ( " Color " ) , tr ( " Piece color " ) , false ) ;
2024-01-07 02:33:43 +01:00
AddSpacing ( ) ;
2024-01-15 02:41:01 +01:00
AddStepNumberProperty ( lcObjectPropertyId : : PieceStepShow , tr ( " Show " ) , tr ( " Step when piece is added to the model " ) , false ) ;
AddStepNumberProperty ( lcObjectPropertyId : : PieceStepHide , tr ( " Hide " ) , tr ( " Step when piece is hidden " ) , false ) ;
2024-01-07 02:33:43 +01:00
2024-04-25 01:53:49 +02:00
AddSpacing ( ) ;
2024-01-07 02:33:43 +01:00
AddCategory ( CategoryIndex : : Camera , tr ( " Camera " ) ) ;
2024-01-15 02:41:01 +01:00
AddStringProperty ( lcObjectPropertyId : : CameraName , tr ( " Name " ) , tr ( " Camera name " ) , false ) ;
2024-02-20 01:31:02 +01:00
AddStringListProperty ( lcObjectPropertyId : : CameraType , tr ( " Type " ) , tr ( " Camera type " ) , false , lcCamera : : GetCameraTypeStrings ( ) ) ;
2024-01-07 02:33:43 +01:00
AddSpacing ( ) ;
2024-01-15 02:41:01 +01:00
AddFloatProperty ( lcObjectPropertyId : : CameraFOV , tr ( " FOV " ) , tr ( " Field of view in degrees " ) , false , 0.1f , 179.9f ) ;
AddFloatProperty ( lcObjectPropertyId : : CameraNear , tr ( " Near " ) , tr ( " Near clipping distance " ) , false , 0.001f , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : CameraFar , tr ( " Far " ) , tr ( " Far clipping distance " ) , false , 0.001f , FLT_MAX ) ;
2024-01-07 02:33:43 +01:00
2024-04-25 01:53:49 +02:00
AddSpacing ( ) ;
2024-01-07 02:33:43 +01:00
AddCategory ( CategoryIndex : : CameraTransform , tr ( " Transform " ) ) ;
2024-01-15 02:41:01 +01:00
AddFloatProperty ( lcObjectPropertyId : : CameraPositionX , tr ( " Position X " ) , tr ( " Camera position " ) , true , - FLT_MAX , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : CameraPositionY , tr ( " Y " ) , tr ( " Camera position " ) , true , - FLT_MAX , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : CameraPositionZ , tr ( " Z " ) , tr ( " Camera position " ) , true , - FLT_MAX , FLT_MAX ) ;
2024-01-07 02:33:43 +01:00
AddSpacing ( ) ;
2024-01-15 02:41:01 +01:00
AddFloatProperty ( lcObjectPropertyId : : CameraTargetX , tr ( " Target X " ) , tr ( " Camera target position " ) , true , - FLT_MAX , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : CameraTargetY , tr ( " Y " ) , tr ( " Camera target position " ) , true , - FLT_MAX , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : CameraTargetZ , tr ( " Z " ) , tr ( " Camera target position " ) , true , - FLT_MAX , FLT_MAX ) ;
2024-01-07 02:33:43 +01:00
AddSpacing ( ) ;
2024-01-15 02:41:01 +01:00
AddFloatProperty ( lcObjectPropertyId : : CameraUpX , tr ( " Up X " ) , tr ( " Camera up direction " ) , true , - FLT_MAX , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : CameraUpY , tr ( " Y " ) , tr ( " Camera up direction " ) , true , - FLT_MAX , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : CameraUpZ , tr ( " Z " ) , tr ( " Camera up direction " ) , true , - FLT_MAX , FLT_MAX ) ;
2024-01-07 02:33:43 +01:00
2024-04-25 01:53:49 +02:00
AddSpacing ( ) ;
2024-01-07 02:33:43 +01:00
AddCategory ( CategoryIndex : : Light , tr ( " Light " ) ) ;
2024-01-15 02:41:01 +01:00
AddStringProperty ( lcObjectPropertyId : : LightName , tr ( " Name " ) , tr ( " Light name " ) , false ) ;
AddStringListProperty ( lcObjectPropertyId : : LightType , tr ( " Type " ) , tr ( " Light type " ) , false , lcLight : : GetLightTypeStrings ( ) ) ;
2024-01-07 02:33:43 +01:00
AddSpacing ( ) ;
2024-01-15 02:41:01 +01:00
AddColorProperty ( lcObjectPropertyId : : LightColor , tr ( " Color " ) , tr ( " Light color " ) , true ) ;
AddBoolProperty ( lcObjectPropertyId : : LightCastShadow , tr ( " Cast Shadow " ) , tr ( " Cast a shadow from this light " ) , false ) ;
2024-01-07 02:33:43 +01:00
AddSpacing ( ) ;
2024-04-25 01:53:49 +02:00
AddFloatProperty ( lcObjectPropertyId : : LightSpotConeAngle , tr ( " Cone Angle " ) , tr ( " Angle in degrees of the spot light's beam " ) , true , 0.0f , 179.9f ) ;
AddFloatProperty ( lcObjectPropertyId : : LightSpotPenumbraAngle , tr ( " Penumbra Angle " ) , tr ( " Angle in degrees over which the intensity of the spot light falls off to zero " ) , true , 0.0f , 179.9f ) ;
2024-01-15 02:41:01 +01:00
AddStringListProperty ( lcObjectPropertyId : : LightAreaShape , tr ( " Area Shape " ) , tr ( " The shape of the area light " ) , false , lcLight : : GetAreaShapeStrings ( ) ) ;
AddFloatProperty ( lcObjectPropertyId : : LightAreaSizeX , tr ( " Size X " ) , tr ( " The width of the area light " ) , true , 0.0f , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : LightAreaSizeY , tr ( " Y " ) , tr ( " The height of the area light " ) , true , 0.0f , FLT_MAX ) ;
2024-04-25 01:53:49 +02:00
AddSpacing ( ) ;
AddCategory ( CategoryIndex : : LightBlender , tr ( " Blender Settings " ) ) ;
AddFloatProperty ( lcObjectPropertyId : : LightBlenderPower , tr ( " Power " ) , tr ( " Power of the light in Watts " ) , true , 0.0f , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : LightPointBlenderRadius , tr ( " Radius " ) , tr ( " Shadow soft size " ) , true , 0.0f , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : LightSpotBlenderRadius , tr ( " Radius " ) , tr ( " Shadow soft size " ) , true , 0.0f , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : LightDirectionalBlenderAngle , tr ( " Angle " ) , tr ( " Angular diameter of the light " ) , true , 0.0f , 180.0f ) ;
AddSpacing ( ) ;
AddCategory ( CategoryIndex : : LightPOVRay , tr ( " POV-Ray Settings " ) ) ;
AddFloatProperty ( lcObjectPropertyId : : LightPOVRayPower , tr ( " Power " ) , tr ( " Power of the light (multiplicative factor) " ) , true , 0.0f , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : LightPOVRayFadeDistance , tr ( " Fade Distance " ) , tr ( " The distance at which the full light intensity arrives " ) , true , 0.0f , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : LightPOVRayFadePower , tr ( " Fade Power " ) , tr ( " Light falloff rate " ) , true , 0.0f , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : LightSpotPOVRayTightness , tr ( " Tightness " ) , tr ( " Additional exponential spot light edge softening " ) , true , 0.0f , FLT_MAX ) ;
AddIntegerProperty ( lcObjectPropertyId : : LightAreaPOVRayGridX , tr ( " Grid X " ) , tr ( " Number of point sources along the X axis " ) , true , 1 , INT_MAX ) ;
AddIntegerProperty ( lcObjectPropertyId : : LightAreaPOVRayGridY , tr ( " Y " ) , tr ( " Number of point sources along the Y axis " ) , true , 1 , INT_MAX ) ;
AddSpacing ( ) ;
2024-01-07 02:33:43 +01:00
AddCategory ( CategoryIndex : : ObjectTransform , tr ( " Transform " ) ) ;
2023-12-31 21:55:35 +01:00
2024-01-15 02:41:01 +01:00
AddFloatProperty ( lcObjectPropertyId : : ObjectPositionX , tr ( " Position X " ) , tr ( " Position of the object " ) , true , - FLT_MAX , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : ObjectPositionY , tr ( " Y " ) , tr ( " Position of the object " ) , true , - FLT_MAX , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : ObjectPositionZ , tr ( " Z " ) , tr ( " Position of the object " ) , true , - FLT_MAX , FLT_MAX ) ;
2024-01-07 02:33:43 +01:00
2023-12-31 23:00:33 +01:00
AddSpacing ( ) ;
2024-01-07 02:33:43 +01:00
2024-01-15 02:41:01 +01:00
AddFloatProperty ( lcObjectPropertyId : : ObjectRotationX , tr ( " Rotation X " ) , tr ( " Rotation of the object in degrees " ) , true , - FLT_MAX , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : ObjectRotationY , tr ( " Y " ) , tr ( " Rotation of the object in degrees " ) , true , - FLT_MAX , FLT_MAX ) ;
AddFloatProperty ( lcObjectPropertyId : : ObjectRotationZ , tr ( " Z " ) , tr ( " Rotation of the object in degrees " ) , true , - FLT_MAX , FLT_MAX ) ;
2023-12-31 21:55:35 +01:00
2024-04-25 01:53:49 +02:00
AddSpacing ( ) ;
2023-12-31 23:00:33 +01:00
mLayout - > setRowStretch ( mLayout - > rowCount ( ) , 1 ) ;
2023-12-31 21:55:35 +01:00
}
2024-01-07 02:33:43 +01:00
void lcPropertiesWidget : : SetLayoutMode ( LayoutMode Mode )
2023-12-31 21:55:35 +01:00
{
2024-01-07 02:33:43 +01:00
if ( mLayoutMode = = Mode )
return ;
2023-12-31 21:55:35 +01:00
2024-01-07 02:33:43 +01:00
mLayoutMode = Mode ;
const bool IsPiece = ( mLayoutMode = = LayoutMode : : Piece ) ;
const bool IsCamera = ( mLayoutMode = = LayoutMode : : Camera ) ;
const bool IsLight = ( mLayoutMode = = LayoutMode : : Light ) ;
SetCategoryVisible ( CategoryIndex : : Piece , IsPiece ) ;
SetCategoryVisible ( CategoryIndex : : Camera , IsCamera ) ;
SetCategoryVisible ( CategoryIndex : : CameraTransform , IsCamera ) ;
SetCategoryVisible ( CategoryIndex : : Light , IsLight ) ;
2024-04-25 01:53:49 +02:00
SetCategoryVisible ( CategoryIndex : : LightBlender , IsLight ) ;
SetCategoryVisible ( CategoryIndex : : LightPOVRay , IsLight ) ;
2024-01-07 02:33:43 +01:00
SetCategoryVisible ( CategoryIndex : : ObjectTransform , IsPiece | | IsLight ) ;
2023-12-31 21:55:35 +01:00
}
2024-01-07 02:33:43 +01:00
void lcPropertiesWidget : : SetCategoryWidgetsVisible ( CategoryWidgets & Category , bool Visible )
2023-12-31 21:55:35 +01:00
{
2024-01-07 20:39:34 +01:00
for ( lcObjectPropertyId PropertyId : Category . Properties )
2024-04-25 01:53:49 +02:00
SetPropertyWidgetsVisible ( PropertyId , Visible & & mPropertyWidgets [ static_cast < int > ( PropertyId ) ] . Visible ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 02:33:43 +01:00
for ( int Row : Category . SpacingRows )
mLayout - > setRowMinimumHeight ( Row , Visible ? 5 : 0 ) ;
}
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
void lcPropertiesWidget : : SetPropertyVisible ( lcObjectPropertyId PropertyId , bool Visible )
2024-04-25 01:53:49 +02:00
{
PropertyWidgets & Property = mPropertyWidgets [ static_cast < int > ( PropertyId ) ] ;
Property . Visible = Visible ;
2024-04-28 01:01:51 +02:00
SetPropertyWidgetsVisible ( PropertyId , Visible & & mCategoryWidgets [ static_cast < int > ( Property . Category ) ] . Button - > IsExpanded ( ) ) ;
2024-04-25 01:53:49 +02:00
}
void lcPropertiesWidget : : SetPropertyWidgetsVisible ( lcObjectPropertyId PropertyId , bool Visible )
2024-01-07 02:33:43 +01:00
{
2024-01-07 20:39:34 +01:00
PropertyWidgets & Property = mPropertyWidgets [ static_cast < int > ( PropertyId ) ] ;
2023-12-31 21:55:35 +01:00
2024-01-07 02:33:43 +01:00
if ( Property . Label )
Property . Label - > setVisible ( Visible ) ;
2023-12-31 21:55:35 +01:00
2024-01-15 02:41:01 +01:00
if ( Property . Editor )
Property . Editor - > setVisible ( Visible ) ;
if ( Property . KeyFrame )
Property . KeyFrame - > setVisible ( Visible ) ;
2024-01-07 02:33:43 +01:00
}
2023-12-31 21:55:35 +01:00
2024-01-07 02:33:43 +01:00
void lcPropertiesWidget : : SetCategoryVisible ( CategoryIndex Index , bool Visible )
{
CategoryWidgets & Category = mCategoryWidgets [ static_cast < int > ( Index ) ] ;
Category . Button - > setVisible ( Visible ) ;
SetCategoryWidgetsVisible ( Category , Visible & & Category . Button - > IsExpanded ( ) ) ;
}
2023-12-31 21:55:35 +01:00
2024-01-07 02:33:43 +01:00
void lcPropertiesWidget : : SetEmpty ( )
{
SetLayoutMode ( LayoutMode : : Empty ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 02:33:43 +01:00
mFocusObject = nullptr ;
2024-05-15 05:45:09 +02:00
mSelection . clear ( ) ;
2023-12-31 21:55:35 +01:00
}
2024-05-15 05:45:09 +02:00
void lcPropertiesWidget : : SetPiece ( const std : : vector < lcObject * > & Selection , lcObject * Focus )
2023-12-31 21:55:35 +01:00
{
2024-01-07 02:33:43 +01:00
SetLayoutMode ( LayoutMode : : Piece ) ;
2023-12-31 21:55:35 +01:00
lcPiece * Piece = dynamic_cast < lcPiece * > ( Focus ) ;
2024-01-21 21:53:18 +01:00
mSelection = Selection ;
2023-12-31 21:55:35 +01:00
mFocusObject = Piece ;
lcVector3 Position ;
lcMatrix33 RelativeRotation ;
2024-01-07 02:33:43 +01:00
lcModel * Model = gMainWindow - > GetActiveModel ( ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 02:33:43 +01:00
if ( Model )
Model - > GetMoveRotateTransform ( Position , RelativeRotation ) ;
2023-12-31 21:55:35 +01:00
2024-01-07 20:39:34 +01:00
UpdateFloat ( lcObjectPropertyId : : ObjectPositionX , Position [ 0 ] ) ;
UpdateFloat ( lcObjectPropertyId : : ObjectPositionY , Position [ 1 ] ) ;
UpdateFloat ( lcObjectPropertyId : : ObjectPositionZ , Position [ 2 ] ) ;
2023-12-31 21:55:35 +01:00
lcVector3 Rotation ;
if ( Piece )
Rotation = lcMatrix44ToEulerAngles ( Piece - > mModelWorld ) * LC_RTOD ;
else
Rotation = lcVector3 ( 0.0f , 0.0f , 0.0f ) ;
2024-01-07 20:39:34 +01:00
UpdateFloat ( lcObjectPropertyId : : ObjectRotationX , Rotation [ 0 ] ) ;
UpdateFloat ( lcObjectPropertyId : : ObjectRotationY , Rotation [ 1 ] ) ;
UpdateFloat ( lcObjectPropertyId : : ObjectRotationZ , Rotation [ 2 ] ) ;
2023-12-31 21:55:35 +01:00
lcStep StepShow = 1 ;
lcStep StepHide = LC_STEP_MAX ;
if ( Piece )
{
StepShow = Piece - > GetStepShow ( ) ;
StepHide = Piece - > GetStepHide ( ) ;
}
else
{
bool FirstPiece = true ;
2024-05-15 05:45:09 +02:00
for ( lcObject * Object : Selection )
2023-12-31 21:55:35 +01:00
{
if ( ! Object - > IsPiece ( ) )
continue ;
lcPiece * SelectedPiece = ( lcPiece * ) Object ;
if ( FirstPiece )
{
StepShow = SelectedPiece - > GetStepShow ( ) ;
StepHide = SelectedPiece - > GetStepHide ( ) ;
FirstPiece = false ;
}
else
{
if ( SelectedPiece - > GetStepShow ( ) ! = StepShow )
StepShow = 0 ;
if ( SelectedPiece - > GetStepHide ( ) ! = StepHide )
StepHide = 0 ;
}
}
}
2024-03-03 02:37:46 +01:00
UpdatePieceId ( lcObjectPropertyId : : PieceId ) ;
UpdatePieceColor ( lcObjectPropertyId : : PieceColor ) ;
2024-01-07 20:39:34 +01:00
UpdateStepNumber ( lcObjectPropertyId : : PieceStepShow , StepShow ? StepShow : LC_STEP_MAX , 1 , StepHide - 1 ) ;
UpdateStepNumber ( lcObjectPropertyId : : PieceStepHide , StepHide ? StepHide : LC_STEP_MAX , StepShow + 1 , LC_STEP_MAX ) ;
2023-12-31 21:55:35 +01:00
}
2024-05-15 05:45:09 +02:00
void lcPropertiesWidget : : SetCamera ( const std : : vector < lcObject * > & Selection , lcObject * Focus )
2023-12-31 21:55:35 +01:00
{
2024-01-07 02:33:43 +01:00
SetLayoutMode ( LayoutMode : : Camera ) ;
2024-01-02 03:57:54 +01:00
lcCamera * Camera = dynamic_cast < lcCamera * > ( Focus ) ;
2024-01-21 21:53:18 +01:00
mSelection = Selection ;
2024-01-02 03:57:54 +01:00
mFocusObject = Camera ;
lcVector3 Position ( 0.0f , 0.0f , 0.0f ) ;
lcVector3 Target ( 0.0f , 0.0f , 0.0f ) ;
lcVector3 UpVector ( 0.0f , 0.0f , 0.0f ) ;
float FoV = 60.0f ;
float ZNear = 1.0f ;
float ZFar = 100.0f ;
if ( Camera )
{
Position = Camera - > mPosition ;
Target = Camera - > mTargetPosition ;
UpVector = Camera - > mUpVector ;
FoV = Camera - > m_fovy ;
ZNear = Camera - > m_zNear ;
ZFar = Camera - > m_zFar ;
}
2024-02-20 02:38:04 +01:00
UpdateString ( lcObjectPropertyId : : CameraName ) ;
2024-02-20 01:45:14 +01:00
UpdateStringList ( lcObjectPropertyId : : CameraType ) ;
2024-01-02 03:57:54 +01:00
2024-01-07 20:39:34 +01:00
UpdateFloat ( lcObjectPropertyId : : CameraFOV , FoV ) ;
UpdateFloat ( lcObjectPropertyId : : CameraNear , ZNear ) ;
UpdateFloat ( lcObjectPropertyId : : CameraFar , ZFar ) ;
2024-01-02 03:57:54 +01:00
2024-01-07 20:39:34 +01:00
UpdateFloat ( lcObjectPropertyId : : CameraPositionX , Position [ 0 ] ) ;
UpdateFloat ( lcObjectPropertyId : : CameraPositionY , Position [ 1 ] ) ;
UpdateFloat ( lcObjectPropertyId : : CameraPositionZ , Position [ 2 ] ) ;
2024-01-02 03:57:54 +01:00
2024-01-07 20:39:34 +01:00
UpdateFloat ( lcObjectPropertyId : : CameraTargetX , Target [ 0 ] ) ;
UpdateFloat ( lcObjectPropertyId : : CameraTargetY , Target [ 1 ] ) ;
UpdateFloat ( lcObjectPropertyId : : CameraTargetZ , Target [ 2 ] ) ;
2024-01-02 03:57:54 +01:00
2024-01-07 20:39:34 +01:00
UpdateFloat ( lcObjectPropertyId : : CameraUpX , UpVector [ 0 ] ) ;
UpdateFloat ( lcObjectPropertyId : : CameraUpY , UpVector [ 1 ] ) ;
UpdateFloat ( lcObjectPropertyId : : CameraUpZ , UpVector [ 2 ] ) ;
2023-12-31 21:55:35 +01:00
}
2024-05-15 05:45:09 +02:00
void lcPropertiesWidget : : SetLight ( const std : : vector < lcObject * > & Selection , lcObject * Focus )
2023-12-31 21:55:35 +01:00
{
2024-01-07 02:33:43 +01:00
SetLayoutMode ( LayoutMode : : Light ) ;
2024-01-06 03:56:43 +01:00
lcLight * Light = dynamic_cast < lcLight * > ( Focus ) ;
2024-01-21 21:53:18 +01:00
mSelection = Selection ;
2024-01-06 03:56:43 +01:00
mFocusObject = Light ;
2023-12-31 21:55:35 +01:00
2024-02-20 01:31:02 +01:00
lcLightType LightType = lcLightType : : Count ;
lcLightAreaShape LightAreaShape = lcLightAreaShape : : Count ;
2024-04-07 21:48:41 +02:00
float PointBlenderRadius = 0.0f , SpotBlenderRadius = 0.0f , DirectionalBlenderAngle = 0.0f ;
2024-04-25 01:53:49 +02:00
float AreaSizeX = 0.0f , AreaSizeY = 0.0f ;
2024-04-07 20:28:54 +02:00
float BlenderPower = 0.0f , POVRayPower = 0.0f ;
2024-04-25 01:53:49 +02:00
float POVRayFadeDistance = 0.0f ;
float POVRayFadePower = 0.0f ;
2024-01-06 03:56:43 +01:00
lcVector3 Position ( 0.0f , 0.0f , 0.0f ) ;
lcVector3 Rotation = lcVector3 ( 0.0f , 0.0f , 0.0f ) ;
float SpotConeAngle = 0.0f , SpotPenumbraAngle = 0.0f , SpotTightness = 0.0f ;
if ( Light )
{
LightType = Light - > GetLightType ( ) ;
2024-02-20 01:31:02 +01:00
LightAreaShape = Light - > GetAreaShape ( ) ;
2024-01-06 03:56:43 +01:00
Position = Light - > GetPosition ( ) ;
Rotation = lcMatrix44ToEulerAngles ( Light - > GetWorldMatrix ( ) ) * LC_RTOD ;
2024-04-07 20:28:54 +02:00
BlenderPower = Light - > GetBlenderPower ( ) ;
POVRayPower = Light - > GetPOVRayPower ( ) ;
2024-04-25 01:53:49 +02:00
POVRayFadeDistance = Light - > GetPOVRayFadeDistance ( ) ;
POVRayFadePower = Light - > GetPOVRayFadePower ( ) ;
2024-01-06 03:56:43 +01:00
SpotConeAngle = Light - > GetSpotConeAngle ( ) ;
SpotPenumbraAngle = Light - > GetSpotPenumbraAngle ( ) ;
2024-04-07 03:50:37 +02:00
SpotTightness = Light - > GetSpotPOVRayTightness ( ) ;
2024-04-07 21:48:41 +02:00
PointBlenderRadius = Light - > GetPointBlenderRadius ( ) ;
SpotBlenderRadius = Light - > GetSpotBlenderRadius ( ) ;
DirectionalBlenderAngle = Light - > GetDirectionalBlenderAngle ( ) ;
2024-04-25 01:53:49 +02:00
AreaSizeX = Light - > GetAreaSizeX ( ) ;
AreaSizeY = Light - > GetAreaSizeX ( ) ;
2024-02-20 01:31:02 +01:00
}
else
{
bool First = true ;
bool PartialLightType = false , PartialAreaShape = false ;
for ( const lcObject * Object : mSelection )
{
const lcLight * CurrentLight = dynamic_cast < const lcLight * > ( Object ) ;
if ( ! CurrentLight )
continue ;
if ( First )
{
LightType = CurrentLight - > GetLightType ( ) ;
LightAreaShape = CurrentLight - > GetAreaShape ( ) ;
First = false ;
}
else
{
if ( LightType ! = CurrentLight - > GetLightType ( ) )
PartialLightType = true ;
if ( LightAreaShape ! = CurrentLight - > GetAreaShape ( ) )
PartialAreaShape = true ;
}
}
if ( PartialLightType )
LightType = lcLightType : : Count ;
if ( PartialAreaShape )
LightAreaShape = lcLightAreaShape : : Count ;
2024-01-06 03:56:43 +01:00
}
2024-02-20 02:38:04 +01:00
UpdateString ( lcObjectPropertyId : : LightName ) ;
2024-02-20 01:45:14 +01:00
UpdateStringList ( lcObjectPropertyId : : LightType ) ;
UpdateColor ( lcObjectPropertyId : : LightColor ) ;
2024-01-06 03:56:43 +01:00
2024-04-07 20:28:54 +02:00
UpdateFloat ( lcObjectPropertyId : : LightBlenderPower , BlenderPower ) ;
UpdateFloat ( lcObjectPropertyId : : LightPOVRayPower , POVRayPower ) ;
2024-02-20 01:45:14 +01:00
UpdateBool ( lcObjectPropertyId : : LightCastShadow ) ;
2024-01-06 03:56:43 +01:00
2024-04-25 01:53:49 +02:00
UpdateFloat ( lcObjectPropertyId : : LightPOVRayFadeDistance , POVRayFadeDistance ) ;
UpdateFloat ( lcObjectPropertyId : : LightPOVRayFadePower , POVRayFadePower ) ;
2024-01-06 03:56:43 +01:00
2024-02-20 01:31:02 +01:00
const bool IsPointLight = ( LightType = = lcLightType : : Point ) ;
2024-04-07 21:48:41 +02:00
SetPropertyVisible ( lcObjectPropertyId : : LightPointBlenderRadius , IsPointLight ) ;
2024-01-07 02:33:43 +01:00
2024-01-07 02:42:47 +01:00
if ( IsPointLight )
2024-04-07 21:48:41 +02:00
UpdateFloat ( lcObjectPropertyId : : LightPointBlenderRadius , PointBlenderRadius ) ;
2024-01-07 02:42:47 +01:00
2024-02-20 01:31:02 +01:00
const bool IsSpotLight = ( LightType = = lcLightType : : Spot ) ;
2024-04-07 21:48:41 +02:00
SetPropertyVisible ( lcObjectPropertyId : : LightSpotBlenderRadius , IsSpotLight ) ;
2024-01-07 20:39:34 +01:00
SetPropertyVisible ( lcObjectPropertyId : : LightSpotConeAngle , IsSpotLight ) ;
SetPropertyVisible ( lcObjectPropertyId : : LightSpotPenumbraAngle , IsSpotLight ) ;
2024-04-07 03:50:37 +02:00
SetPropertyVisible ( lcObjectPropertyId : : LightSpotPOVRayTightness , IsSpotLight ) ;
2024-01-07 02:33:43 +01:00
2024-01-07 02:42:47 +01:00
if ( IsSpotLight )
{
2024-04-07 21:48:41 +02:00
UpdateFloat ( lcObjectPropertyId : : LightSpotBlenderRadius , SpotBlenderRadius ) ;
2024-01-07 20:39:34 +01:00
UpdateFloat ( lcObjectPropertyId : : LightSpotConeAngle , SpotConeAngle ) ;
UpdateFloat ( lcObjectPropertyId : : LightSpotPenumbraAngle , SpotPenumbraAngle ) ;
2024-04-07 03:50:37 +02:00
UpdateFloat ( lcObjectPropertyId : : LightSpotPOVRayTightness , SpotTightness ) ;
2024-01-07 02:42:47 +01:00
}
2024-02-20 01:31:02 +01:00
const bool IsDirectionalLight = ( LightType = = lcLightType : : Directional ) ;
2024-04-07 21:48:41 +02:00
SetPropertyVisible ( lcObjectPropertyId : : LightDirectionalBlenderAngle , IsDirectionalLight ) ;
2024-01-07 02:33:43 +01:00
2024-01-07 02:42:47 +01:00
if ( IsDirectionalLight )
2024-04-07 21:48:41 +02:00
UpdateFloat ( lcObjectPropertyId : : LightDirectionalBlenderAngle , DirectionalBlenderAngle ) ;
2024-01-07 02:42:47 +01:00
2024-02-20 01:31:02 +01:00
const bool IsAreaLight = ( LightType = = lcLightType : : Area ) ;
2024-01-07 20:39:34 +01:00
SetPropertyVisible ( lcObjectPropertyId : : LightAreaShape , IsAreaLight ) ;
2024-01-07 02:33:43 +01:00
2024-02-20 01:31:02 +01:00
const bool IsSquare = ( LightAreaShape = = lcLightAreaShape : : Square | | LightAreaShape = = lcLightAreaShape : : Disk ) ;
2024-04-14 20:15:06 +02:00
SetPropertyVisible ( lcObjectPropertyId : : LightAreaSizeX , IsAreaLight ) ;
2024-02-20 01:31:02 +01:00
SetPropertyVisible ( lcObjectPropertyId : : LightAreaSizeY , IsAreaLight & & ! IsSquare ) ;
2024-01-07 02:33:43 +01:00
2024-04-07 03:50:37 +02:00
SetPropertyVisible ( lcObjectPropertyId : : LightAreaPOVRayGridX , IsAreaLight ) ;
SetPropertyVisible ( lcObjectPropertyId : : LightAreaPOVRayGridY , IsAreaLight ) ;
2024-01-06 03:56:43 +01:00
2024-01-07 02:42:47 +01:00
if ( IsAreaLight )
2024-01-06 03:56:43 +01:00
{
2024-02-20 01:45:14 +01:00
UpdateStringList ( lcObjectPropertyId : : LightAreaShape ) ;
2024-04-25 01:53:49 +02:00
UpdateFloat ( lcObjectPropertyId : : LightAreaSizeX , AreaSizeX ) ;
UpdateFloat ( lcObjectPropertyId : : LightAreaSizeY , AreaSizeY ) ;
2024-04-07 03:50:37 +02:00
UpdateInteger ( lcObjectPropertyId : : LightAreaPOVRayGridX ) ;
UpdateInteger ( lcObjectPropertyId : : LightAreaPOVRayGridY ) ;
2024-01-06 03:56:43 +01:00
}
2024-01-07 20:39:34 +01:00
UpdateFloat ( lcObjectPropertyId : : ObjectPositionX , Position [ 0 ] ) ;
UpdateFloat ( lcObjectPropertyId : : ObjectPositionY , Position [ 1 ] ) ;
UpdateFloat ( lcObjectPropertyId : : ObjectPositionZ , Position [ 2 ] ) ;
2024-01-06 03:56:43 +01:00
2024-01-07 20:39:34 +01:00
UpdateFloat ( lcObjectPropertyId : : ObjectRotationX , Rotation [ 0 ] ) ;
UpdateFloat ( lcObjectPropertyId : : ObjectRotationY , Rotation [ 1 ] ) ;
UpdateFloat ( lcObjectPropertyId : : ObjectRotationZ , Rotation [ 2 ] ) ;
2023-12-31 21:55:35 +01:00
}
2024-05-15 05:45:09 +02:00
void lcPropertiesWidget : : Update ( const std : : vector < lcObject * > & Selection , lcObject * Focus )
2023-12-31 21:55:35 +01:00
{
2024-01-21 21:53:18 +01:00
mFocusObject = nullptr ;
2024-05-15 05:45:09 +02:00
mSelection . clear ( ) ;
2024-01-21 21:53:18 +01:00
2023-12-31 21:55:35 +01:00
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
{
2024-05-15 05:45:09 +02:00
for ( size_t ObjectIdx = 0 ; ObjectIdx < Selection . size ( ) ; ObjectIdx + + )
2023-12-31 21:55:35 +01:00
{
switch ( Selection [ ObjectIdx ] - > GetType ( ) )
{
case lcObjectType : : Piece :
if ( Mode = = LayoutMode : : Empty )
Mode = LayoutMode : : Piece ;
else if ( Mode ! = LayoutMode : : Piece )
{
Mode = LayoutMode : : Multiple ;
2024-05-15 05:45:09 +02:00
ObjectIdx = Selection . size ( ) ;
2023-12-31 21:55:35 +01:00
}
break ;
case lcObjectType : : Camera :
2024-02-19 21:32:19 +01:00
if ( Mode = = LayoutMode : : Empty )
Mode = LayoutMode : : Camera ;
else if ( Mode ! = LayoutMode : : Camera )
2023-12-31 21:55:35 +01:00
{
Mode = LayoutMode : : Multiple ;
2024-05-15 05:45:09 +02:00
ObjectIdx = Selection . size ( ) ;
2023-12-31 21:55:35 +01:00
}
break ;
case lcObjectType : : Light :
2024-02-19 21:32:19 +01:00
if ( Mode = = LayoutMode : : Empty )
Mode = LayoutMode : : Light ;
else if ( Mode ! = LayoutMode : : Light )
2023-12-31 21:55:35 +01:00
{
Mode = LayoutMode : : Multiple ;
2024-05-15 05:45:09 +02:00
ObjectIdx = Selection . size ( ) ;
2023-12-31 21:55:35 +01:00
}
break ;
}
}
}
switch ( Mode )
{
case LayoutMode : : Empty :
2024-01-06 03:56:43 +01:00
case LayoutMode : : Multiple :
2024-01-07 02:33:43 +01:00
case LayoutMode : : Count :
2023-12-31 21:55:35 +01:00
SetEmpty ( ) ;
break ;
case LayoutMode : : Piece :
SetPiece ( Selection , Focus ) ;
break ;
case LayoutMode : : Camera :
2024-01-21 21:53:18 +01:00
SetCamera ( Selection , Focus ) ;
2023-12-31 21:55:35 +01:00
break ;
case LayoutMode : : Light :
2024-01-21 21:53:18 +01:00
SetLight ( Selection , Focus ) ;
2023-12-31 21:55:35 +01:00
break ;
}
}