Commit bcf6bdca authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Improve visibilty of bin clip usage (colored icons)

parent 5563df92
......@@ -49,9 +49,10 @@ std::shared_ptr<AbstractProjectItem> AbstractProjectItem::parent() const
return std::static_pointer_cast<AbstractProjectItem>(m_parentItem.lock());
}
void AbstractProjectItem::setRefCount(uint count)
void AbstractProjectItem::setRefCount(uint count, uint audioCount)
{
m_usage = count;
m_AudioUsage = audioCount;
if (auto ptr = m_model.lock())
std::static_pointer_cast<ProjectItemModel>(ptr)->onItemUpdated(std::static_pointer_cast<AbstractProjectItem>(shared_from_this()),
AbstractProjectItem::UsageCount);
......@@ -62,17 +63,23 @@ uint AbstractProjectItem::refCount() const
return m_usage;
}
void AbstractProjectItem::addRef()
void AbstractProjectItem::addRef(bool isAudio)
{
m_usage++;
if (isAudio) {
m_AudioUsage++;
}
if (auto ptr = m_model.lock())
std::static_pointer_cast<ProjectItemModel>(ptr)->onItemUpdated(std::static_pointer_cast<AbstractProjectItem>(shared_from_this()),
AbstractProjectItem::UsageCount);
}
void AbstractProjectItem::removeRef()
void AbstractProjectItem::removeRef(bool isAudio)
{
m_usage--;
if (isAudio) {
m_AudioUsage--;
}
if (auto ptr = m_model.lock())
std::static_pointer_cast<ProjectItemModel>(ptr)->onItemUpdated(std::static_pointer_cast<AbstractProjectItem>(shared_from_this()),
AbstractProjectItem::UsageCount);
......@@ -136,6 +143,9 @@ QVariant AbstractProjectItem::getData(DataType type) const
case UsageCount:
data = QVariant(m_usage);
break;
case AudioUsageCount:
data = QVariant(m_AudioUsage);
break;
case ItemTypeRole:
data = QVariant(m_itemType);
break;
......
......@@ -79,13 +79,13 @@ public:
// TODO refac : these ref counting are probably deprecated by smart ptrs
/** @brief Set current usage count. */
void setRefCount(uint count);
void setRefCount(uint count, uint audioCount);
/** @brief Returns clip's current usage count in timeline. */
uint refCount() const;
/** @brief Increase usage count. */
void addRef();
void addRef(bool isAudio);
/** @brief Decrease usage count. */
void removeRef();
void removeRef(bool isAudio);
enum DataType {
// display name of item
......@@ -102,6 +102,7 @@ public:
DataDescription,
// Number of occurrences used in timeline
UsageCount,
AudioUsageCount,
// Empty if clip has no effect, icon otherwise
IconOverlay,
// item type (clip, subclip, folder)
......@@ -200,6 +201,7 @@ protected:
QDateTime m_date;
QString m_binId;
uint m_usage;
uint m_AudioUsage;
uint m_rating;
QString m_tags;
FileStatus::ClipStatus m_clipStatus;
......
......@@ -53,6 +53,8 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include <KMessageBox>
#include <KXMLGUIFactory>
#include <KIO/OpenFileManagerWindowJob>
#include <KIconTheme>
#include <KIconEffect>
#include <QToolBar>
#include <QCryptographicHash>
......@@ -68,6 +70,11 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include <utility>
#include <jobs/audiolevelstask.h>
static QImage m_videoIcon;
static QImage m_audioIcon;
static QImage m_audioUsedIcon;
static QImage m_videoUsedIcon;
/**
* @class BinItemDelegate
* @brief This class is responsible for drawing items in the QTreeView.
......@@ -270,17 +277,25 @@ public:
painter->drawText(r2, Qt::AlignLeft | Qt::AlignTop, subText, &bounding);
// Add audio/video icons for selective drag
bool hasAudioAndVideo = index.data(AbstractProjectItem::ClipHasAudioAndVideo).toBool();
if (hasAudioAndVideo && (cType == ClipType::AV || cType == ClipType::Playlist) && (opt.state & QStyle::State_MouseOver)) {
if (hasAudioAndVideo && (cType == ClipType::AV || cType == ClipType::Playlist)) {
bounding.moveLeft(bounding.right() + (2 * textMargin));
bounding.adjust(0, textMargin, 0, -textMargin);
QIcon aDrag = QIcon::fromTheme(QStringLiteral("audio-volume-medium"));
m_audioDragRect = bounding.toRect();
m_audioDragRect.setWidth(m_audioDragRect.height());
aDrag.paint(painter, m_audioDragRect, Qt::AlignLeft);
m_videoDragRect = m_audioDragRect;
m_videoDragRect.moveLeft(m_audioDragRect.right());
QIcon vDrag = QIcon::fromTheme(QStringLiteral("kdenlive-show-video"));
vDrag.paint(painter, m_videoDragRect, Qt::AlignLeft);
if (opt.state & QStyle::State_MouseOver) {
painter->drawImage(m_audioDragRect.topLeft(), m_audioIcon);
painter->drawImage(m_videoDragRect.topLeft(), m_videoIcon);
} else if (usage > 0) {
int audioUsage = index.data(AbstractProjectItem::AudioUsageCount).toInt();
if (audioUsage > 0) {
painter->drawImage(m_audioDragRect.topLeft(), m_audioUsedIcon);
}
if (usage - audioUsage > 0) {
painter->drawImage(m_videoDragRect.topLeft(), m_videoUsedIcon);
}
}
} else {
//m_audioDragRect = QRect();
//m_videoDragRect = QRect();
......@@ -420,9 +435,6 @@ public:
initStyleOption(&opt, index);
// Draw usage counter
int usage = index.data(AbstractProjectItem::UsageCount).toInt();
if (usage > 0) {
opt.font.setBold(true);
}
QStyledItemDelegate::paint(painter, opt, index);
int adjust = (opt.rect.width() - opt.decorationSize.width()) / 2;
QRect rect(opt.rect.x(), opt.rect.y(), opt.decorationSize.width(), opt.decorationSize.height());
......@@ -448,22 +460,32 @@ public:
// Add audio/video icons for selective drag
int cType = index.data(AbstractProjectItem::ClipType).toInt();
bool hasAudioAndVideo = index.data(AbstractProjectItem::ClipHasAudioAndVideo).toBool();
if (hasAudioAndVideo && (cType == ClipType::AV || cType == ClipType::Playlist) && (opt.state & QStyle::State_MouseOver)) {
if (hasAudioAndVideo && (cType == ClipType::AV || cType == ClipType::Playlist)) {
QRect thumbRect = m_thumbRect.adjusted(0, 0, 0, 2);
int iconSize = painter->boundingRect(thumbRect, Qt::AlignLeft, QStringLiteral("O")).height();
thumbRect.setLeft(opt.rect.right() - iconSize - 4);
thumbRect.setWidth(iconSize);
QColor bgColor = option.palette.window().color();
bgColor.setAlphaF(.7);
painter->fillRect(thumbRect, bgColor);
if (opt.state & QStyle::State_MouseOver) {
QColor bgColor = option.palette.window().color();
bgColor.setAlphaF(.7);
painter->fillRect(thumbRect, bgColor);
}
thumbRect.setBottom(m_thumbRect.top() + iconSize);
QIcon aDrag = QIcon::fromTheme(QStringLiteral("audio-volume-medium"));
m_audioDragRect = thumbRect;
aDrag.paint(painter, m_audioDragRect, Qt::AlignRight);
m_videoDragRect = m_audioDragRect;
m_videoDragRect.moveTop(thumbRect.bottom());
QIcon vDrag = QIcon::fromTheme(QStringLiteral("kdenlive-show-video"));
vDrag.paint(painter, m_videoDragRect, Qt::AlignRight);
if (opt.state & QStyle::State_MouseOver) {
painter->drawImage(m_audioDragRect.topLeft(), m_audioIcon);
painter->drawImage(m_videoDragRect.topLeft(), m_videoIcon);
} else if (usage > 0) {
int audioUsage = index.data(AbstractProjectItem::AudioUsageCount).toInt();
if (audioUsage > 0) {
painter->drawImage(m_audioDragRect.topLeft(), m_audioUsedIcon);
}
if (usage - audioUsage > 0) {
painter->drawImage(m_videoDragRect.topLeft(), m_videoUsedIcon);
}
}
} else {
//m_audioDragRect = QRect();
//m_videoDragRect = QRect();
......@@ -936,6 +958,16 @@ Bin::Bin(std::shared_ptr<ProjectItemModel> model, QWidget *parent, bool isMainBi
m_toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
m_layout->addWidget(m_toolbar);
// Init icons
QIcon audioIcon = QIcon::fromTheme(QStringLiteral("audio-volume-medium"));
m_audioIcon = audioIcon.pixmap(iconSize).toImage();
m_audioUsedIcon = m_audioIcon;
KIconEffect::toMonochrome(m_audioUsedIcon, palette().highlight().color(), palette().highlight().color(), 1);
QIcon videoIcon = QIcon::fromTheme(QStringLiteral("kdenlive-show-video"));
m_videoIcon = videoIcon.pixmap(iconSize).toImage();
m_videoUsedIcon = m_videoIcon;
KIconEffect::toMonochrome(m_videoUsedIcon, palette().highlight().color(), palette().highlight().color(), 1);
// Tags panel
m_tagsWidget = new TagWidget(this);
connect(m_tagsWidget, &TagWidget::switchTag, this, &Bin::switchTag);
......@@ -1314,6 +1346,7 @@ Bin::Bin(std::shared_ptr<ProjectItemModel> model, QWidget *parent, bool isMainBi
// m_infoMessage->setWordWrap(true);
m_infoMessage->hide();
connect(this, &Bin::requesteInvalidRemoval, this, &Bin::slotQueryRemoval);
connect(pCore.get(), &Core::updatePalette, this, &Bin::slotUpdatePalette);
connect(this, SIGNAL(displayBinMessage(QString,KMessageWidget::MessageType)), this, SLOT(doDisplayMessage(QString,KMessageWidget::MessageType)));
wheelAccumulatedDelta = 0;
}
......@@ -1335,6 +1368,21 @@ Bin::~Bin()
}
}
void Bin::slotUpdatePalette()
{
// Refresh icons
int size = style()->pixelMetric(QStyle::PM_SmallIconSize);
QSize iconSize(size, size);
QIcon audioIcon = QIcon::fromTheme(QStringLiteral("audio-volume-medium"));
m_audioIcon = audioIcon.pixmap(iconSize).toImage();
m_audioUsedIcon = m_audioIcon;
KIconEffect::toMonochrome(m_audioUsedIcon, palette().highlight().color(), palette().highlight().color(), 1);
QIcon videoIcon = QIcon::fromTheme(QStringLiteral("kdenlive-show-video"));
m_videoIcon = videoIcon.pixmap(iconSize).toImage();
m_videoUsedIcon = m_videoIcon;
KIconEffect::toMonochrome(m_videoUsedIcon, palette().highlight().color(), palette().highlight().color(), 1);
}
QDockWidget *Bin::clipPropertiesDock()
{
return m_propertiesDock;
......@@ -4282,7 +4330,7 @@ void Bin::resetUsageCount()
{
const QList<std::shared_ptr<ProjectClip>> clipList = m_itemModel->getRootFolder()->childClips();
for (const std::shared_ptr<ProjectClip> &clip : clipList) {
clip->setRefCount(0);
clip->setRefCount(0, 0);
}
}
......
......@@ -398,6 +398,7 @@ private slots:
/** @brief Switch a tag on a clip list
*/
void editTags(QList <QString> allClips, const QString &tag, bool add);
void slotUpdatePalette();
public slots:
void slotRemoveInvalidClip(const QString &id, bool replace, const QString &errorMessage);
......
......@@ -71,6 +71,7 @@ ProjectClip::ProjectClip(const QString &id, const QIcon &thumb, const std::share
: AbstractProjectItem(AbstractProjectItem::ClipItem, id, model)
, ClipController(id, std::move(producer))
, m_resetTimelineOccurences(false)
, m_audioCount(0)
{
m_markerModel = std::make_shared<MarkerListModel>(id, pCore->projectManager()->undoStack());
if (producer->get_int("_placeholder") == 1) {
......@@ -1659,14 +1660,22 @@ void ProjectClip::registerTimelineClip(std::weak_ptr<TimelineModel> timeline, in
{
Q_ASSERT(m_registeredClips.count(clipId) == 0);
Q_ASSERT(!timeline.expired());
if (auto ptr = timeline.lock()) {
if (ptr->getClipState(clipId) == PlaylistState::AudioOnly) {
m_audioCount++;
}
}
m_registeredClips[clipId] = std::move(timeline);
setRefCount(uint(m_registeredClips.size()));
setRefCount(uint(m_registeredClips.size()), m_audioCount);
}
void ProjectClip::deregisterTimelineClip(int clipId)
void ProjectClip::deregisterTimelineClip(int clipId, bool audioClip)
{
qDebug() << " ** * DEREGISTERING TIMELINE CLIP: " << clipId;
Q_ASSERT(m_registeredClips.count(clipId) > 0);
if (audioClip) {
m_audioCount--;
}
m_registeredClips.erase(clipId);
if (m_videoProducers.count(clipId) > 0) {
m_effectStack->removeService(m_videoProducers[clipId]);
......@@ -1676,7 +1685,7 @@ void ProjectClip::deregisterTimelineClip(int clipId)
m_effectStack->removeService(m_audioProducers[clipId]);
m_audioProducers.erase(clipId);
}
setRefCount(uint(m_registeredClips.size()));
setRefCount(uint(m_registeredClips.size()), m_audioCount);
}
QList<int> ProjectClip::timelineInstances() const
......
......@@ -247,7 +247,7 @@ protected:
/** @brief This is a call-back called by a ClipModel when it is deleted
@param clipId id of the deleted clip
*/
void deregisterTimelineClip(int clipId);
void deregisterTimelineClip(int clipId, bool audioClip);
void emitProducerChanged(const QString &id, const std::shared_ptr<Mlt::Producer> &producer) override { emit producerChanged(id, producer); };
void replaceInTimeline();
......@@ -302,6 +302,7 @@ private:
void createDisabledMasterProducer();
std::map<int, std::weak_ptr<TimelineModel>> m_registeredClips;
uint m_audioCount;
/** @brief the following holds a producer for each audio clip in the timeline
* keys are the id of the clips in the timeline, values are their values */
......
......@@ -358,6 +358,8 @@ signals:
void remapClip(int cid);
/** @brief A monitor property changed, check if we need to reset */
void monitorProfileUpdated();
/** @brief Color theme changed, process refresh */
void updatePalette();
};
#endif
......@@ -152,6 +152,7 @@ void MainWindow::init(const QString &mltPath)
auto themeManager = new ThemeManager(actionCollection());
actionCollection()->addAction(QStringLiteral("themes_menu"), themeManager);
connect(themeManager, &ThemeManager::themeChanged, this, &MainWindow::slotThemeChanged);
emit pCore->updatePalette();
if (!KdenliveSettings::widgetstyle().isEmpty() && QString::compare(desktopStyle, KdenliveSettings::widgetstyle(), Qt::CaseInsensitive) != 0) {
// User wants a custom widget style, init
......@@ -861,6 +862,7 @@ void MainWindow::slotThemeChanged(const QString &name)
if (m_audioSpectrum) {
m_audioSpectrum->refreshPixmap();
}
emit pCore->updatePalette();
KSharedConfigPtr kconfig = KSharedConfig::openConfig();
KConfigGroup initialGroup(kconfig, "version");
......
......@@ -147,7 +147,7 @@ void ClipModel::registerClipToBin(std::shared_ptr<Mlt::Producer> service, bool r
void ClipModel::deregisterClipToBin()
{
std::shared_ptr<ProjectClip> binClip = pCore->projectItemModel()->getClipByBinID(m_binClipId);
binClip->deregisterTimelineClip(m_id);
binClip->deregisterTimelineClip(m_id, isAudioOnly());
}
ClipModel::~ClipModel() = default;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment