mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-09-10 03:53:23 +02:00
calloverlay: keep the recording action visible while recording
Gitlab: #411 Change-Id: Id987ad1b3c0c583425a53b85735ab7eb3f434036
This commit is contained in:
parent
2267c046d8
commit
378ab7cb93
4 changed files with 126 additions and 103 deletions
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (C) 2021 by Savoir-faire Linux
|
||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -22,70 +23,6 @@
|
|||
#include <QMouseEvent>
|
||||
#include <QQuickWindow>
|
||||
|
||||
CallControlListModel::CallControlListModel(QObject* parent)
|
||||
: QAbstractListModel(parent)
|
||||
{}
|
||||
|
||||
int
|
||||
CallControlListModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
return data_.size();
|
||||
}
|
||||
|
||||
QVariant
|
||||
CallControlListModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
using namespace CallControl;
|
||||
auto item = data_.at(index.row());
|
||||
|
||||
switch (role) {
|
||||
case Role::ItemAction:
|
||||
return QVariant::fromValue(item.itemAction);
|
||||
case Role::BadgeCount:
|
||||
return QVariant::fromValue(item.badgeCount);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray>
|
||||
CallControlListModel::roleNames() const
|
||||
{
|
||||
using namespace CallControl;
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[ItemAction] = "ItemAction";
|
||||
roles[BadgeCount] = "BadgeCount";
|
||||
return roles;
|
||||
}
|
||||
|
||||
void
|
||||
CallControlListModel::setBadgeCount(int row, int count)
|
||||
{
|
||||
if (row >= rowCount())
|
||||
return;
|
||||
data_[row].badgeCount = count;
|
||||
auto idx = index(row, 0);
|
||||
Q_EMIT dataChanged(idx, idx);
|
||||
}
|
||||
|
||||
void
|
||||
CallControlListModel::addItem(const CallControl::Item& item)
|
||||
{
|
||||
beginResetModel();
|
||||
data_.append(item);
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void
|
||||
CallControlListModel::clearData()
|
||||
{
|
||||
data_.clear();
|
||||
}
|
||||
|
||||
IndexRangeFilterProxyModel::IndexRangeFilterProxyModel(QAbstractListModel* parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
|
@ -188,13 +125,13 @@ PendingConferenceesListModel::connectSignals()
|
|||
disconnect(beginRemovePendingConferencesRows_);
|
||||
disconnect(endRemovePendingConferencesRows_);
|
||||
|
||||
using namespace PendingConferences;
|
||||
callsStatusChanged_ = connect(lrcInstance_->getCurrentCallModel(),
|
||||
&NewCallModel::callStatusChanged,
|
||||
this,
|
||||
[this]() {
|
||||
dataChanged(index(0, 0),
|
||||
index(rowCount() - 1),
|
||||
{PendingConferences::Role::CallStatus});
|
||||
[this](const QString&, int) {
|
||||
Q_EMIT dataChanged(index(0, 0),
|
||||
index(rowCount() - 1),
|
||||
{Role::CallStatus});
|
||||
});
|
||||
|
||||
beginInsertPendingConferencesRows_ = connect(
|
||||
|
@ -233,6 +170,77 @@ PendingConferenceesListModel::connectSignals()
|
|||
endResetModel();
|
||||
}
|
||||
|
||||
CallControlListModel::CallControlListModel(QObject* parent)
|
||||
: QAbstractListModel(parent)
|
||||
{}
|
||||
|
||||
int
|
||||
CallControlListModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
return data_.size();
|
||||
}
|
||||
|
||||
QVariant
|
||||
CallControlListModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
using namespace CallControl;
|
||||
auto item = data_.at(index.row());
|
||||
|
||||
switch (role) {
|
||||
case Role::ItemAction:
|
||||
return QVariant::fromValue(item.itemAction);
|
||||
case Role::UrgentCount:
|
||||
return QVariant::fromValue(item.urgentCount);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray>
|
||||
CallControlListModel::roleNames() const
|
||||
{
|
||||
using namespace CallControl;
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[ItemAction] = "ItemAction";
|
||||
roles[UrgentCount] = "UrgentCount";
|
||||
return roles;
|
||||
}
|
||||
|
||||
void
|
||||
CallControlListModel::setUrgentCount(QVariant item, int count)
|
||||
{
|
||||
const auto* obj = item.value<QObject*>();
|
||||
auto it = std::find_if(data_.cbegin(), data_.cend(), [obj](const auto& item) {
|
||||
return item.itemAction == obj;
|
||||
});
|
||||
if (it != data_.cend()) {
|
||||
auto row = std::distance(data_.cbegin(), it);
|
||||
if (row >= rowCount())
|
||||
return;
|
||||
data_[row].urgentCount = count;
|
||||
auto idx = index(row, 0);
|
||||
Q_EMIT dataChanged(idx, idx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CallControlListModel::addItem(const CallControl::Item& item)
|
||||
{
|
||||
beginResetModel();
|
||||
data_.append(item);
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void
|
||||
CallControlListModel::clearData()
|
||||
{
|
||||
data_.clear();
|
||||
}
|
||||
|
||||
CallOverlayModel::CallOverlayModel(LRCInstance* instance, QObject* parent)
|
||||
: QObject(parent)
|
||||
, lrcInstance_(instance)
|
||||
|
@ -247,7 +255,7 @@ CallOverlayModel::CallOverlayModel(LRCInstance* instance, QObject* parent)
|
|||
&CallOverlayModel::overflowIndexChanged,
|
||||
this,
|
||||
&CallOverlayModel::setControlRanges);
|
||||
overflowVisibleModel_->setFilterRole(CallControl::Role::BadgeCount);
|
||||
overflowVisibleModel_->setFilterRole(CallControl::Role::UrgentCount);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -264,9 +272,9 @@ CallOverlayModel::addSecondaryControl(const QVariant& action)
|
|||
}
|
||||
|
||||
void
|
||||
CallOverlayModel::setBadgeCount(int row, int count)
|
||||
CallOverlayModel::setUrgentCount(QVariant row, int count)
|
||||
{
|
||||
secondaryModel_->setBadgeCount(row, count);
|
||||
secondaryModel_->setUrgentCount(row, count);
|
||||
}
|
||||
|
||||
QVariant
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (C) 2021 by Savoir-faire Linux
|
||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -35,13 +36,13 @@
|
|||
|
||||
namespace CallControl {
|
||||
Q_NAMESPACE
|
||||
enum Role { ItemAction = Qt::UserRole + 1, BadgeCount };
|
||||
enum Role { ItemAction = Qt::UserRole + 1, UrgentCount };
|
||||
Q_ENUM_NS(Role)
|
||||
|
||||
struct Item
|
||||
{
|
||||
QObject* itemAction;
|
||||
int badgeCount {0};
|
||||
int urgentCount {0};
|
||||
};
|
||||
} // namespace CallControl
|
||||
|
||||
|
@ -56,24 +57,6 @@ enum Role {
|
|||
Q_ENUM_NS(Role)
|
||||
} // namespace PendingConferences
|
||||
|
||||
class CallControlListModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CallControlListModel(QObject* parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
void setBadgeCount(int row, int count);
|
||||
void addItem(const CallControl::Item& item);
|
||||
void clearData();
|
||||
|
||||
private:
|
||||
QList<CallControl::Item> data_;
|
||||
};
|
||||
|
||||
class IndexRangeFilterProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -112,6 +95,24 @@ private:
|
|||
QMetaObject::Connection endRemovePendingConferencesRows_;
|
||||
};
|
||||
|
||||
class CallControlListModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CallControlListModel(QObject* parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
void setUrgentCount(QVariant item, int count);
|
||||
void addItem(const CallControl::Item& item);
|
||||
void clearData();
|
||||
|
||||
private:
|
||||
QList<CallControl::Item> data_;
|
||||
};
|
||||
|
||||
class CallOverlayModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -122,7 +123,7 @@ public:
|
|||
|
||||
Q_INVOKABLE void addPrimaryControl(const QVariant& action);
|
||||
Q_INVOKABLE void addSecondaryControl(const QVariant& action);
|
||||
Q_INVOKABLE void setBadgeCount(int row, int count);
|
||||
Q_INVOKABLE void setUrgentCount(QVariant item, int count);
|
||||
Q_INVOKABLE void clearControls();
|
||||
|
||||
Q_INVOKABLE QVariant primaryModel();
|
||||
|
|
|
@ -210,6 +210,10 @@ Control {
|
|||
text: !checked ? JamiStrings.startRec : JamiStrings.stopRec
|
||||
property bool blinksWhenChecked: true
|
||||
property real size: 28
|
||||
onCheckedChanged: {
|
||||
CallOverlayModel.setUrgentCount(recordAction,
|
||||
checked ? -1 : 0)
|
||||
}
|
||||
},
|
||||
Action {
|
||||
id: pluginsAction
|
||||
|
@ -345,9 +349,10 @@ Control {
|
|||
"#80777777" :
|
||||
"#80444444"
|
||||
type: {
|
||||
if ((overflowItemListView.count &&
|
||||
!urgentOverflowListView.count) ||
|
||||
overflowHiddenListView.count) {
|
||||
if (overflowItemListView.count ||
|
||||
urgentOverflowListView.count ||
|
||||
(overflowHiddenListView.count &&
|
||||
overflowButton.popup.visible)) {
|
||||
return HalfPill.None
|
||||
} else {
|
||||
return HalfPill.Left
|
||||
|
@ -370,7 +375,10 @@ Control {
|
|||
|
||||
spacing: itemSpacing
|
||||
anchors.fill: parent
|
||||
model: CallOverlayModel.overflowVisibleModel()
|
||||
model: !overflowButton.popup.visible ?
|
||||
CallOverlayModel.overflowVisibleModel() :
|
||||
null
|
||||
|
||||
delegate: buttonDelegate
|
||||
ScrollIndicator.vertical: ScrollIndicator {}
|
||||
|
||||
|
|
|
@ -115,13 +115,15 @@ ItemDelegate {
|
|||
|
||||
anchors.centerIn: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
source: ItemAction.icon.source
|
||||
color: ItemAction.icon.color
|
||||
source: ItemAction ? ItemAction.icon.source : ""
|
||||
color: ItemAction ? ItemAction.icon.color : null
|
||||
|
||||
SequentialAnimation on opacity {
|
||||
loops: Animation.Infinite
|
||||
running: ItemAction.blinksWhenChecked !== undefined &&
|
||||
running: ItemAction !== undefined &&
|
||||
ItemAction.blinksWhenChecked !== undefined &&
|
||||
ItemAction.blinksWhenChecked && checked
|
||||
onStopped: icon.opacity = 1
|
||||
NumberAnimation { from: 1; to: 0; duration: JamiTheme.recordBlinkDuration }
|
||||
NumberAnimation { from: 0; to: 1; duration: JamiTheme.recordBlinkDuration }
|
||||
}
|
||||
|
@ -142,7 +144,9 @@ ItemDelegate {
|
|||
id: toolTip
|
||||
parent: parent
|
||||
visible: text.length > 0 && (wrapper.hovered || menu.hovered)
|
||||
text: menu.hovered ? menuAction.text : ItemAction.text
|
||||
text: menu.hovered ?
|
||||
menuAction.text :
|
||||
(ItemAction !== undefined ? ItemAction.text : null)
|
||||
verticalPadding: 1
|
||||
font.pointSize: 9
|
||||
}
|
||||
|
@ -155,7 +159,7 @@ ItemDelegate {
|
|||
|
||||
indicator: null
|
||||
|
||||
visible: menuAction !== undefined && !BadgeCount
|
||||
visible: menuAction !== undefined && !UrgentCount
|
||||
|
||||
y: isVertical ? 0 : -4
|
||||
x: isVertical ? -4 : 0
|
||||
|
@ -256,6 +260,7 @@ ItemDelegate {
|
|||
property real menuItemWidth: 0
|
||||
property real menuItemHeight: 39
|
||||
|
||||
pixelAligned: true
|
||||
orientation: ListView.Vertical
|
||||
implicitWidth: menuItemWidth
|
||||
implicitHeight: Math.min(contentHeight,
|
||||
|
@ -306,7 +311,8 @@ ItemDelegate {
|
|||
BadgeNotifier {
|
||||
id: badge
|
||||
|
||||
count: BadgeCount
|
||||
visible: count > 0
|
||||
count: UrgentCount
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 18
|
||||
height: width
|
||||
|
|
Loading…
Add table
Reference in a new issue