void ElExtendedPlaylistEditorDelegate::measureItem(
QStyleOptionViewItemV4 const& option,
QRect& item,
QRect& thumbnail,
QRect& nameHeaderLabel,
QRect& nameDataLabel,
QRect& lengthHeaderLabel,
QRect& lengthDataLabel,
QRect& videoEffectImageRect
) const
{
// More or less arbitrarily selected values.
// Margins within the item in which components will be laid out.
QMargins padding( 2, 2, 2, 2 );
// Enough to show a reasonable icon.
int minimumThumbnailHeight = 64;
// HD aspect ratio.
boost::rational< int > thumbnailAspectRatio( 1920, 1080 );
int thumbnailLabelsMargin =
stylePtr->layoutSpacing(
Qt::Horizontal,
&option,
option.widget
);
if ( thumbnailLabelsMargin == -1 )
thumbnailLabelsMargin = 5;
int labelsVerticalMargin =
stylePtr->layoutSpacing(
Qt::Vertical,
&option,
option.widget
);
if ( labelsVerticalMargin == -1 )
labelsVerticalMargin = 2;
// Obtain/reformat some data.
EbTimecode length =
index.data(
sps::spsGUI::PlaylistModel::CustomRole::ITEM_LENGTH
).value< EbTimecode >();
QString lengthString
= length.
getTimecodeString();
// Measure components which are not flexible.
// Note that the measuring includes a space between header and data. This way
// margin is scaled well with the font that is used rather than fixed to given
// pixels value.
nameHeaderLabel =
stylePtr->itemTextRect(
option.fontMetrics,
Qt::AlignLeft | Qt::AlignBottom,
( option.
state & QStyle::State_Enabled ) != 0,
tr( "Name:" ) + " "
);
nameDataLabel =
stylePtr->itemTextRect(
option.fontMetrics,
Qt::AlignLeft | Qt::AlignBottom,
( option.
state & QStyle::State_Enabled ) != 0,
option.text
);
lengthHeaderLabel =
stylePtr->itemTextRect(
option.fontMetrics,
Qt::AlignLeft | Qt::AlignBottom,
( option.
state & QStyle::State_Enabled ) != 0,
tr( "Length:" ) + " "
);
lengthDataLabel =
stylePtr->itemTextRect(
option.fontMetrics,
Qt::AlignLeft | Qt::AlignBottom,
( option.
state & QStyle::State_Enabled ) != 0,
lengthString
);
// it will be changed after demo:)
videoEffectImageRect
= QRect( 0,
0,
30,
20 );
// Now start laying out the components with labels.
nameHeaderLabel.translate(
-nameHeaderLabel.left(),
-nameHeaderLabel.top()
+ option.rect.top()
+ padding.top()
);
nameDataLabel.translate(
-nameDataLabel.left(),
-nameDataLabel.top()
+ option.rect.top()
+ padding.top()
);
Q_ASSERT( nameHeaderLabel.height() == nameDataLabel.height() );
int nameJoinedLabelHeight =
( std::max )( nameHeaderLabel.height(), nameDataLabel.height() );
lengthHeaderLabel.translate(
-lengthHeaderLabel.left(),
-lengthHeaderLabel.top()
+ option.rect.top()
+ padding.top()
+ nameJoinedLabelHeight
+ labelsVerticalMargin
);
lengthDataLabel.translate(
-lengthDataLabel.left(),
-lengthDataLabel.top()
+ option.rect.top()
+ padding.top()
+ nameJoinedLabelHeight
+ labelsVerticalMargin
);
videoEffectImageRect.translate(
-videoEffectImageRect.left(),
-videoEffectImageRect.top()
+ option.rect.top()
+ padding.top()
+ nameJoinedLabelHeight
+ labelsVerticalMargin
+ labelsVerticalMargin
);
Q_ASSERT( lengthHeaderLabel.height() == lengthDataLabel.height() );
int lengthJoinedLabelHeight =
( std::max )( lengthHeaderLabel.height(), lengthDataLabel.height() );
int headersWidth =
( std::max )( nameHeaderLabel.width(), lengthHeaderLabel.width() );
nameHeaderLabel.translate(
option.rect.left()
+ padding.left(),
0
);
nameDataLabel.translate(
option.rect.left()
+ padding.left()
+ headersWidth,
0
);
lengthHeaderLabel.translate(
option.rect.left()
+ padding.left(),
0
);
lengthDataLabel.translate(
option.rect.left()
+ padding.left()
+ headersWidth,
0
);
videoEffectImageRect.translate(
option.rect.left()
+ padding.left()
+ headersWidth
+ lengthDataLabel.width(),
0
);
int labelsWidth =
headersWidth
+ ( std::max )( nameDataLabel.width(), lengthDataLabel.width() );
int labelsHeight =
nameJoinedLabelHeight
+ labelsVerticalMargin
+ lengthJoinedLabelHeight;
// Now that the labels are laid out we have to include the thumbnail.
int thumbnailHeight =
(std::max )( minimumThumbnailHeight, labelsHeight );
auto thumbnailWidthExact = thumbnailAspectRatio * thumbnailHeight;
int thumbnailWidth = boost::rational_cast< int >( thumbnailWidthExact );
Q_ASSERT( thumbnailHeight >= labelsHeight );
int itemContentsHeight = thumbnailHeight;
int itemContentsWidth =
thumbnailWidth
+ thumbnailLabelsMargin
+ labelsWidth;
thumbnail.setCoords(
option.rect.left()
+ padding.left(),
option.rect.top()
+ padding.top(),
option.rect.left()
+ padding.left()
+ thumbnailWidth,
option.rect.top()
+ padding.top()
+ itemContentsHeight
);
// Offset labels by the thumbnail width (plus margin).
nameHeaderLabel.translate(
thumbnailWidth + thumbnailLabelsMargin,
0
);
nameDataLabel.translate(
thumbnailWidth + thumbnailLabelsMargin,
0
);
lengthHeaderLabel.translate(
thumbnailWidth + thumbnailLabelsMargin,
0
);
lengthDataLabel.translate(
thumbnailWidth + thumbnailLabelsMargin,
0
);
videoEffectImageRect.translate(
thumbnailWidth + thumbnailLabelsMargin,
0
);
// Finally item size itself.
item.setCoords(
option.rect.left(),
option.rect.top(),
option.rect.left()
+ padding.left()
+ itemContentsWidth
+ padding.right(),
option.rect.top()
+ padding.top()
+ itemContentsHeight
+ padding.bottom()
);
}